Skip to content
Projects
Groups
Snippets
Help
Loading...
Sign in
Toggle navigation
U
urv-core
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
3
Issues
3
List
Board
Labels
Milestones
Merge Requests
2
Merge Requests
2
Wiki
Wiki
image/svg+xml
Discourse
Discourse
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Commits
Issue Boards
Open sidebar
Projects
urv-core
Commits
4ad34eca
Commit
4ad34eca
authored
Aug 24, 2015
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
rtl: passes RV32IM test suite
parent
7630ec3a
Show whitespace changes
Inline
Side-by-side
Showing
8 changed files
with
211 additions
and
158 deletions
+211
-158
Manifest.py
rtl/Manifest.py
+1
-0
rv_cpu.v
rtl/rv_cpu.v
+17
-5
rv_defs.v
rtl/rv_defs.v
+6
-0
rv_exceptions.v
rtl/rv_exceptions.v
+54
-37
rv_exec.v
rtl/rv_exec.v
+60
-33
rv_multiply.v
rtl/rv_multiply.v
+15
-13
rv_predecode.v
rtl/rv_predecode.v
+30
-13
rv_writeback.v
rtl/rv_writeback.v
+28
-57
No files found.
rtl/Manifest.py
View file @
4ad34eca
...
...
@@ -14,6 +14,7 @@ files = [ "rv_cpu.v",
"rv_writeback.v"
,
"rv_shifter.v"
,
"rv_multiply.v"
,
"rv_divide.v"
,
"rv_csr.v"
,
"rv_timer.v"
,
"rv_exceptions.v"
,
...
...
rtl/rv_cpu.v
View file @
4ad34eca
...
...
@@ -100,6 +100,9 @@ module rv_cpu
wire
[
4
:
0
]
d2x_opcode
;
wire
d2x_shifter_sign
;
wire
d2x_is_load
,
d2x_is_store
,
d2x_is_undef
;
wire
[
31
:
0
]
d2x_imm
;
wire
d2x_is_signed_compare
;
wire
d2x_is_signed_alu_op
;
...
...
@@ -210,6 +213,10 @@ module rv_cpu
.
x_is_signed_alu_op_o
(
d2x_is_signed_alu_op
)
,
.
x_is_add_o
(
d2x_is_add
)
,
.
x_is_shift_o
(
d2x_is_shift
)
,
.
x_is_load_o
(
d2x_is_load
)
,
.
x_is_store_o
(
d2x_is_store
)
,
.
x_is_undef_o
(
d2x_is_undef
)
,
.
x_rd_source_o
(
d2x_rd_source
)
,
.
x_rd_write_o
(
d2x_rd_write
)
,
...
...
@@ -240,9 +247,10 @@ module rv_cpu
wire
rf_rd_write
;
wire
x2w_valid
;
wire
[
31
:
0
]
rf_bypass_rd_value
=
x2w_rd_value
;
wire
rf_bypass_rd_write
=
rf_rd_write
&&
!
x2w_load
;
wire
rf_bypass_rd_write
=
rf_rd_write
&&
!
x2w_load
;
// multiply/shift too?
rv_regfile
regfile
(
...
...
@@ -284,7 +292,6 @@ module rv_cpu
.
irq_i
(
irq_i
)
,
.
x_stall_req_o
(
x_stall_req
)
,
.
w_stall_req_i
(
w_stall_req
)
,
.
d_valid_i
(
d2x_valid
)
,
...
...
@@ -302,6 +309,10 @@ module rv_cpu
.
d_is_signed_alu_op_i
(
d2x_is_signed_alu_op
)
,
.
d_is_add_i
(
d2x_is_add
)
,
.
d_is_shift_i
(
d2x_is_shift
)
,
.
d_is_load_i
(
d2x_is_load
)
,
.
d_is_store_i
(
d2x_is_store
)
,
.
d_is_undef_i
(
d2x_is_undef
)
,
.
d_rd_source_i
(
d2x_rd_source
)
,
.
d_rd_write_i
(
d2x_rd_write
)
,
...
...
@@ -321,7 +332,7 @@ module rv_cpu
.
w_fun_o
(
x2w_fun
)
,
.
w_load_o
(
x2w_load
)
,
.
w_store_o
(
x2w_store
)
,
.
w_valid_o
(
x2w_valid
)
,
.
w_dm_addr_o
(
x2w_dm_addr
)
,
.
w_rd_o
(
x2w_rd
)
,
.
w_rd_value_o
(
x2w_rd_value
)
,
...
...
@@ -359,6 +370,7 @@ module rv_cpu
.
x_load_hazard_i
(
x2w_load_hazard
)
,
.
x_store_i
(
x2w_store
)
,
.
x_valid_i
(
x2w_valid
)
,
.
x_rd_i
(
x2w_rd
)
,
.
x_rd_source_i
(
x2w_rd_source
)
,
.
x_rd_value_i
(
x2w_rd_value
)
,
...
...
rtl/rv_defs.v
View file @
4ad34eca
...
...
@@ -28,6 +28,7 @@
`define
OPC_LOAD 5
'
b00000
`define
OPC_STORE 5
'
b01000
`define
OPC_SYSTEM 5
'
b11100
`define
OPC_MULDIV 5
'
b
`define
BRA_EQ 3
'
b000
`define
BRA_NEQ 3
'
b001
...
...
@@ -56,6 +57,11 @@
`define
FUNC_MULHSU 3
'
b010
`define
FUNC_MULHU 3
'
b011
`define
FUNC_DIV 3
'
b100
`define
FUNC_DIVU 3
'
b101
`define
FUNC_REM 3
'
b110
`define
FUNC_REMU 3
'
b111
`define
RD_SOURCE_ALU 3
'
b000
`define
RD_SOURCE_SHIFTER 3
'
b010
`define
RD_SOURCE_MULTIPLY 3
'
b001
...
...
rtl/rv_exceptions.v
View file @
4ad34eca
...
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
*/
`include
"rv_defs.v"
...
...
@@ -49,7 +49,7 @@ module rv_exceptions
output
x_exception_o
,
input
[
31
:
0
]
x_exception_pc_i
,
output
[
31
:
0
]
x_exception_pc_o
,
output
[
31
:
0
]
x_exception_vector_o
,
output
[
31
:
0
]
csr_mstatus_o
,
output
[
31
:
0
]
csr_mip_o
,
...
...
@@ -65,12 +65,14 @@ module rv_exceptions
reg
[
31
:
0
]
csr_mie
;
reg
csr_ie
;
reg
[
3
:
0
]
csr_mcause
;
reg
exception
;
reg
[
3
:
0
]
cause
;
reg
[
5
:
0
]
except_vec_masked
;
assign
csr_mcause_o
=
0
;
assign
csr_mcause_o
=
{
28'h0
,
csr_mcause
}
;
assign
csr_mepc_o
=
csr_mepc
;
assign
csr_mie_o
=
csr_mie
;
assign
csr_mstatus_o
[
0
]
=
csr_ie
;
...
...
@@ -107,31 +109,45 @@ module rv_exceptions
except_vec_masked
[
5
]
<=
x_csr_write_value_i
[
`EXCEPT_IRQ
]
;
end
else
begin
if
(
exp_invalid_insn_i
)
except_vec_masked
[
0
]
<=
csr_mie
[
`EXCEPT_ILLEGAL_INSN
]
;
except_vec_masked
[
0
]
<=
1'b1
;
if
(
exp_breakpoint_i
)
except_vec_masked
[
1
]
<=
csr_mie
[
`EXCEPT_BREAKPOINT
]
;
except_vec_masked
[
1
]
<=
1'b1
;
if
(
exp_unaligned_load_i
)
except_vec_masked
[
2
]
<=
csr_mie
[
`EXCEPT_UNALIGNED_LOAD
]
;
except_vec_masked
[
2
]
<=
1'b1
;
if
(
exp_unaligned_store_i
)
except_vec_masked
[
3
]
<=
csr_mie
[
`EXCEPT_UNALIGNED_STORE
]
;
except_vec_masked
[
3
]
<=
1'b1
;
if
(
exp_tick_i
)
except_vec_masked
[
4
]
<=
csr_mie
[
`EXCEPT_TIMER
]
;
except_vec_masked
[
4
]
<=
csr_mie
[
`EXCEPT_TIMER
]
&
csr_ie
;
if
(
exp_irq_i
)
except_vec_masked
[
5
]
<=
csr_mie
[
`EXCEPT_IRQ
]
;
except_vec_masked
[
5
]
<=
csr_mie
[
`EXCEPT_IRQ
]
&
csr_ie
;
end
// else: !if(!x_stall_i && !x_kill_i && d_is_csr_i && d_csr_sel_i == `CSR_ID_MIP)
end
// else: !if(rst_i)
always
@*
exception
<=
|
except_vec_masked
;
exception
<=
|
except_vec_masked
|
exp_invalid_insn_i
;
reg
exception_pending
;
assign
x_exception_vector_o
=
'h8
;
always
@*
if
(
exp_invalid_insn_i
||
except_vec_masked
[
0
])
cause
<=
`EXCEPT_ILLEGAL_INSN
;
else
if
(
except_vec_masked
[
1
])
cause
<=
`EXCEPT_BREAKPOINT
;
else
if
(
except_vec_masked
[
2
])
cause
<=
`EXCEPT_UNALIGNED_LOAD
;
else
if
(
except_vec_masked
[
3
])
cause
<=
`EXCEPT_UNALIGNED_STORE
;
else
if
(
except_vec_masked
[
4
])
cause
<=
`EXCEPT_TIMER
;
else
cause
<=
`EXCEPT_IRQ
;
always
@
(
posedge
clk_i
)
if
(
rst_i
)
...
...
@@ -145,9 +161,10 @@ module rv_exceptions
if
(
d_is_eret_i
)
exception_pending
<=
0
;
if
(
!
exception_pending
&&
exception
&&
csr_ie
)
if
(
!
exception_pending
&&
exception
)
begin
csr_mepc
<=
x_exception_pc_i
;
csr_mcause
<=
cause
;
exception_pending
<=
1
;
end
...
...
@@ -159,10 +176,10 @@ module rv_exceptions
csr_mepc
<=
x_csr_write_value_i
;
`CSR_ID_MIE
:
begin
csr_mie
[
`EXCEPT_ILLEGAL_INSN
]
<=
x_csr_write_value_i
[
`EXCEPT_ILLEGAL_INSN
]
;
csr_mie
[
`EXCEPT_BREAKPOINT
]
<=
x_csr_write_value_i
[
`EXCEPT_BREAKPOINT
]
;
csr_mie
[
`EXCEPT_UNALIGNED_LOAD
]
<=
x_csr_write_value_i
[
`EXCEPT_UNALIGNED_LOAD
]
;
csr_mie
[
`EXCEPT_UNALIGNED_STORE
]
<=
x_csr_write_value_i
[
`EXCEPT_UNALIGNED_STORE
]
;
csr_mie
[
`EXCEPT_ILLEGAL_INSN
]
<=
1
;
csr_mie
[
`EXCEPT_BREAKPOINT
]
<=
1
;
csr_mie
[
`EXCEPT_UNALIGNED_LOAD
]
<=
1
;
csr_mie
[
`EXCEPT_UNALIGNED_STORE
]
<=
1
;
csr_mie
[
`EXCEPT_TIMER
]
<=
x_csr_write_value_i
[
`EXCEPT_TIMER
]
;
csr_mie
[
`EXCEPT_IRQ
]
<=
x_csr_write_value_i
[
`EXCEPT_IRQ
]
;
end
...
...
@@ -173,9 +190,9 @@ module rv_exceptions
assign
x_exception_pc_o
=
csr_mepc
;
assign
x_exception_o
=
exception
&
csr_ie
&
!
exception_pending
;
assign
x_exception_o
=
exception
&
!
exception_pending
;
endmodule
// rv_exceptions
endmodule
// rv_exceptions
rtl/rv_exec.v
View file @
4ad34eca
...
...
@@ -30,7 +30,6 @@ module rv_exec
input
x_stall_i
,
input
x_kill_i
,
output
reg
x_stall_req_o
,
input
w_stall_req_i
,
input
[
31
:
0
]
d_pc_i
,
...
...
@@ -59,6 +58,12 @@ module rv_exec
input
d_is_signed_alu_op_i
,
input
d_is_add_i
,
input
d_is_shift_i
,
input
d_is_load_i
,
input
d_is_store_i
,
input
d_is_divide_i
,
input
d_is_undef_i
,
input
[
2
:
0
]
d_rd_source_i
,
input
d_rd_write_i
,
...
...
@@ -74,6 +79,7 @@ module rv_exec
output
reg
w_load_o
,
output
reg
w_store_o
,
output
reg
w_valid_o
,
output
reg
[
4
:
0
]
w_rd_o
,
output
reg
[
31
:
0
]
w_rd_value_o
,
output
reg
w_rd_write_o
,
...
...
@@ -97,8 +103,6 @@ module rv_exec
)
;
parameter
g_exception_vector
=
'h40
;
wire
[
31
:
0
]
rs1
,
rs2
;
assign
rs1
=
rf_rs1_value_i
;
...
...
@@ -124,10 +128,6 @@ module rv_exec
reg
f_branch_take
;
wire
x_stall_req_shifter
=
0
;
wire
x_stall_req_multiply
=
0
;
wire
x_stall_req_divide
=
0
;
wire
[
31
:
0
]
rd_shifter
;
wire
[
31
:
0
]
rd_csr
;
wire
[
31
:
0
]
rd_mul
;
...
...
@@ -136,7 +136,7 @@ module rv_exec
wire
exception
;
wire
[
31
:
0
]
csr_mie
,
csr_mip
,
csr_mepc
,
csr_mstatus
,
csr_mcause
;
wire
[
31
:
0
]
csr_write_value
;
wire
[
31
:
0
]
exception_address
;
wire
[
31
:
0
]
exception_address
,
exception_vector
;
rv_csr
csr_regs
...
...
@@ -165,7 +165,7 @@ module rv_exec
.
csr_mip_i
(
csr_mip
)
,
.
csr_mie_i
(
csr_mie
)
,
.
csr_mepc_i
(
csr_mepc
)
,
.
csr_mcause_i
(
csr_m
m
ause
)
.
csr_mcause_i
(
csr_m
c
ause
)
)
;
rv_exceptions
exception_unit
...
...
@@ -188,12 +188,12 @@ module rv_exec
.
exp_breakpoint_i
(
1'b0
)
,
.
exp_unaligned_load_i
(
1'b0
)
,
.
exp_unaligned_store_i
(
1'b0
)
,
.
exp_invalid_insn_i
(
1'b0
)
,
.
exp_invalid_insn_i
(
d_is_undef_i
&&
!
x_stall_i
&&
!
x_kill_i
&&
d_valid_i
)
,
.
x_exception_o
(
exception
)
,
.
x_exception_pc_i
(
d_pc_i
)
,
.
x_exception_pc_o
(
exception_address
)
,
.
x_exception_vector_o
(
exception_vector
)
,
.
csr_mstatus_o
(
csr_mstatus
)
,
.
csr_mip_o
(
csr_mip
)
,
...
...
@@ -220,7 +220,7 @@ module rv_exec
if
(
d_is_eret_i
)
branch_target
<=
exception_address
;
else
if
(
exception
)
branch_target
<=
g_
exception_vector
;
branch_target
<=
exception_vector
;
else
case
(
d_opcode_i
)
`OPC_JAL
:
branch_target
<=
d_pc_i
+
d_imm_i
;
`OPC_JALR
:
branch_target
<=
rs1
+
d_imm_i
;
...
...
@@ -302,6 +302,8 @@ module rv_exec
.
w_rd_o
(
w_rd_shifter_o
)
)
;
wire
divider_stall_req
=
0
;
rv_multiply
multiplier
(
.
clk_i
(
clk_i
)
,
...
...
@@ -314,10 +316,35 @@ module rv_exec
.
w_rd_o
(
w_rd_multiply_o
)
)
;
/* wire divider_stall_req;
wire [31:0] rd_divide;
rv_divide divider
(
.clk_i(clk_i),
.rst_i(rst_i),
.x_stall_i(x_stall_i),
.x_kill_i(x_kill_i),
.x_stall_req_o(divider_stall_req),
.d_valid_i(d_valid_i),
.d_is_divide_i(d_is_divide_i),
.d_rs1_i(rs1),
.d_rs2_i(rs2),
.d_fun_i(d_fun_i),
.x_rd_o(rd_divide)
);
-----/\----- EXCLUDED -----/\----- */
always
@*
case
(
d_rd_source_i
)
`RD_SOURCE_ALU
:
rd_value
<=
alu_result
;
`RD_SOURCE_CSR
:
rd_value
<=
rd_csr
;
// `RD_SOURCE_DIVIDE: rd_value <= rd_divide;
default:
rd_value
<=
32
'
hx
;
endcase
// case (x_rd_source_i)
...
...
@@ -406,16 +433,19 @@ module rv_exec
assign
dm_data_s_o
=
dm_data_s
;
assign
dm_data_select_o
=
dm_select_s
;
/* -----\/----- EXCLUDED -----\/-----
wire is_load = (d_opcode_i == `OPC_LOAD ? 1: 0) && d_valid_i && !x_kill_i;
wire is_store = (d_opcode_i == `OPC_STORE ? 1: 0) && d_valid_i && !x_kill_i;
-----/\----- EXCLUDED -----/\----- */
assign
dm_load_o
=
is_load
&&
!
x_stall_i
;
assign
dm_store_o
=
is_store
&&
!
x_stall_i
;
assign
dm_load_o
=
d_is_load_i
&
d_valid_i
&
!
x_kill_i
&
!
x_stall_i
&
!
exception
;
assign
dm_store_o
=
d_is_store_i
&
d_valid_i
&
!
x_kill_i
&
!
x_stall_i
&
!
exception
;
/* -----\/----- EXCLUDED -----\/-----
wire trig_ent = (d_pc_i == 'h264 && !x_kill_i);
wire trig_ret = (d_pc_i == 'h2bc && !x_kill_i);
wire trig_wr = (dm_addr == 'hf368 && is_store && !x_stall_i);
-----/\----- EXCLUDED -----/\----- */
always
@
(
posedge
clk_i
)
...
...
@@ -429,8 +459,7 @@ module rv_exec
w_store_o
<=
0
;
w_dm_addr_o
<=
0
;
w_rd_source_o
<=
0
;
w_valid_o
<=
0
;
end
else
if
(
!
x_stall_i
)
begin
f_branch_target_o
<=
branch_target
;
...
...
@@ -438,32 +467,30 @@ module rv_exec
w_rd_o
<=
d_rd_i
;
// if(!shifter_stall_req)
w_rd_value_o
<=
rd_value
;
w_rd_write_o
<=
d_rd_write_i
&&
!
x_kill_i
&&
d_valid_i
&&
!
exception
;
w_rd_write_o
<=
d_rd_write_i
&&
!
x_kill_i
&&
!
exception
;
w_rd_source_o
<=
d_rd_source_i
;
w_fun_o
<=
d_fun_i
;
w_load_o
<=
is_load
&&
!
exception
;
w_store_o
<=
is_store
&&
!
exception
;
w_load_o
<=
d_is_load_i
&
d_valid_i
&&
!
x_kill_i
&&
!
exception
;
w_store_o
<=
d_is_store_i
&
d_valid_i
&&
!
x_kill_i
&&
!
exception
;
if
(
(
is_load
||
is_store
)
&&
!
exception
&&
unaligned_addr
)
/* -----\/----- EXCLUDED -----\/-----
if ( (d_is_load_i || is_store) && !exception && unaligned_addr)
begin
$error("Unaligned address!");
$stop;
end
-----/\----- EXCLUDED -----/\----- */
w_dm_addr_o
<=
dm_addr
;
w_valid_o
<=
d_valid_i
&&
!
x_kill_i
&&
!
exception
;
end
else
begin
// if (!x_stall_i)
// f_branch_take <= 0;
w_rd_write_o
<=
0
;
w_load_o
<=
0
;
w_store_o
<=
0
;
end
// else: !if(rst_i)
w_valid_o
<=
0
;
end
// else: !if(rst_i)
assign
f_branch_take_o
=
f_branch_take
;
...
...
@@ -471,9 +498,9 @@ end // else: !if(rst_i)
always
@*
if
(
f_branch_take
)
x_stall_req_o
<=
0
;
else
if
(
x_stall_req_shifter
||
x_stall_req_multiply
||
x_stall_req_divide
)
else
if
(
divider_stall_req
)
x_stall_req_o
<=
1
;
else
if
((
is_store
||
is_load
)
&&
!
dm_ready_i
)
else
if
((
d_is_load_i
||
d_is_store_i
)
&&
d_valid_i
&&
!
x_kill_i
&&
!
dm_ready_i
)
x_stall_req_o
<=
1
;
else
x_stall_req_o
<=
0
;
...
...
rtl/rv_multiply.v
View file @
4ad34eca
...
...
@@ -15,28 +15,30 @@ module rv_multiply
output
reg
[
31
:
0
]
w_rd_o
)
;
wire
sign_a
=
(
d_fun_i
==
`FUNC_MUL
||
d_fun_i
==
`FUNC_MULHSU
)
?
d_rs1_i
[
31
]
:
1'b0
;
wire
sign_b
=
(
d_fun_i
==
`FUNC_MUL
)
?
d_rs2_i
[
31
]
:
1'b0
;
reg
[
31
:
0
]
yl_xl
,
yl_xh
,
yh_xl
;
wire
[
32
:
0
]
a
=
{
sign_a
,
d_rs1_i
};
wire
[
32
:
0
]
b
=
{
sign_b
,
d_rs2_i
};
reg
[
65
:
0
]
stage0
,
stage1
;
reg
[
2
:
0
]
s2_fun
;
wire
[
17
:
0
]
xl
=
d_rs1_i
[
17
:
0
]
;
wire
[
13
:
0
]
xh
=
d_rs1_i
[
31
:
18
]
;
wire
[
17
:
0
]
yl
=
d_rs2_i
[
17
:
0
]
;
wire
[
13
:
0
]
yh
=
d_rs2_i
[
31
:
18
]
;
always
@
(
posedge
clk_i
)
if
(
!
x_stall_i
)
begin
stage0
<=
$
signed
(
a
)
*
$
signed
(
b
)
;
s2_fun
<=
d_fun_i
;
yh_xl
<=
$
signed
(
yh
)
*
$
signed
(
xl
)
;
yl_xh
<=
$
signed
(
yl
)
*
$
signed
(
xh
)
;
yl_xl
<=
$
unsigned
(
yl
)
*
$
unsigned
(
xl
)
;
end
// stage0 <= $signed(d_rs1_i) * $signed(d_rs2_i);
always
@*
if
(
s2_fun
!=
`FUNC_MUL
)
w_rd_o
<=
stage0
[
63
:
32
]
;
else
w_rd_o
<=
stage0
[
31
:
0
]
;
w_rd_o
<=
yl_xl
+
{
yl_xh
[
13
:
0
]
,
18'h0
}
+
{
yh_xl
[
13
:
0
]
,
18'h0
};
endmodule
// rv_multiply
...
...
rtl/rv_predecode.v
View file @
4ad34eca
...
...
@@ -62,8 +62,13 @@ module rv_decode
output
reg
x_is_signed_alu_op_o
,
output
reg
x_is_add_o
,
output
x_is_shift_o
,
output
reg
x_is_load_o
,
output
reg
x_is_store_o
,
output
reg
x_is_undef_o
,
output
reg
[
2
:
0
]
x_rd_source_o
,
output
reg
x_rd_write_o
,
output
x_rd_write_o
,
output
reg
[
11
:
0
]
x_csr_sel_o
,
output
reg
[
4
:
0
]
x_csr_imm_o
,
...
...
@@ -82,6 +87,7 @@ module rv_decode
reg
[
4
:
0
]
x_opcode
;
reg
x_valid
;
reg
x_is_shift
;
reg
x_rd_write
;
assign
x_rs1_o
=
x_rs1
;
...
...
@@ -126,13 +132,19 @@ module rv_decode
wire
d_is_shift
=
(
d_fun
==
`FUNC_SL
||
d_fun
==
`FUNC_SR
)
&&
(
d_opcode
==
`OPC_OP
||
d_opcode
==
`OPC_OP_IMM
)
;
reg
x_is_mul
;
wire
d_is_mul
=
(
f_ir_i
[
25
]
&&
d_fun
==
3'b000
)
;
always
@*
if
(
x_valid
&&
f_valid_i
&&
(
(
f_rs1
==
x_rd
)
||
(
f_rs2
==
x_rd
)
)
&&
(
!
d_kill_i
)
)
begin
case
(
x_opcode
)
`OPC_LOAD
:
load_hazard
<=
1
;
`OPC_OP
,
`OPC_OP
:
load_hazard
<=
x_is_shift
|
x_is_mul
;
`OPC_OP_IMM
:
load_hazard
<=
x_is_shift
;
default:
...
...
@@ -141,8 +153,6 @@ module rv_decode
end
else
load_hazard
<=
0
;
//wire load_hazard = x_valid && f_valid_i && ( (f_rs1 == x_rd) || (f_rs2 == x_rd) ) && (!d_kill_i) && (x_opcode == `OPC_LOAD);
reg
inserting_nop
=
0
;
always
@
(
posedge
clk_i
)
...
...
@@ -165,8 +175,8 @@ module rv_decode
begin
x_rs1
<=
f_rs1
;
x_rs2
<=
f_rs2
;
x_rd
<=
load_hazard
?
0
:
f_ir_i
[
11
:
7
]
;
x_opcode
<=
load_hazard
?
`OPC_OP
:
d_opcode
;
x_rd
<=
(
load_hazard
&&
!
inserting_nop
)
?
0
:
f_ir_i
[
11
:
7
]
;
x_opcode
<=
(
load_hazard
&&
!
inserting_nop
)
?
`OPC_OP
:
d_opcode
;
load_hazard_d
<=
load_hazard
;
x_shamt_o
<=
f_ir_i
[
24
:
20
]
;
end
...
...
@@ -220,9 +230,13 @@ module rv_decode
begin
x_is_shift
<=
d_is_shift
;
x_is_load_o
<=
(
d_opcode
==
`OPC_LOAD
&&
!
load_hazard
)
?
1'b1
:
1'b0
;
x_is_store_o
<=
(
d_opcode
==
`OPC_STORE
&&
!
load_hazard
)
?
1'b1
:
1'b0
;
x_is_signed_compare_o
<=
(
(
d_opcode
==
`OPC_BRANCH
)
&&
(
(
d_fun
==
`BRA_GE
)
||
(
d_fun
==
`BRA_LT
)
)
)
||
(
(
(
d_opcode
==
`OPC_OP
)
||
(
d_opcode
==
`OPC_OP_IMM
)
)
&&
(
d_fun
==
`FUNC_SLT
)
)
;
x_is_mul
<=
d_is_mul
;
...
...
@@ -232,6 +246,8 @@ module rv_decode
x_is_signed_alu_op_o
<=
(
d_fun
==
`FUNC_SLT
)
;
// all multiply/divide instructions except MUL
x_is_undef_o
<=
(
d_opcode
==
`OPC_OP
&&
f_ir_i
[
25
]
&&
d_fun
!=
3'b000
)
;
if
(
d_is_shift
)
x_rd_source_o
<=
`RD_SOURCE_SHIFTER
;
...
...
@@ -247,11 +263,11 @@ module rv_decode
// rdest write value
case
(
d_opcode
)
`OPC_OP_IMM
,
`OPC_OP
,
`OPC_JAL
,
`OPC_JALR
,
`OPC_LUI
,
`OPC_AUIPC
:
x_rd_write
_o
<=
1
;
x_rd_write
<=
1
;
`OPC_SYSTEM
:
x_rd_write
_o
<=
(
d_fun
!=
0
)
;
// CSR instructions write to RD
x_rd_write
<=
(
d_fun
!=
0
)
;
// CSR instructions write to RD
default:
x_rd_write
_o
<=
0
;
x_rd_write
<=
0
;
endcase
// case (d_opcode)
end
// if (!d_stall_i)
...
...
@@ -271,6 +287,7 @@ module rv_decode
end
assign
x_is_shift_o
=
x_is_shift
;
assign
x_rd_write_o
=
x_rd_write
;
...
...
rtl/rv_writeback.v
View file @
4ad34eca
...
...
@@ -40,6 +40,8 @@ module rv_writeback
input
[
4
:
0
]
x_rd_i
,
input
[
31
:
0
]
x_rd_value_i
,
input
x_rd_write_i
,
input
x_valid_i
,
input
[
31
:
0
]
x_shifter_rd_value_i
,
input
[
31
:
0
]
x_multiply_rd_value_i
,
...
...
@@ -102,31 +104,8 @@ module rv_writeback
endcase
// case (d_fun_i)
end
// always@ *
reg
pending_load
,
pending_store
;
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
pending_load
<=
0
;
pending_store
<=
0
;
end
else
begin
if
(
x_load_i
&&
!
dm_load_done_i
)
begin
pending_load
<=
1
;
end
else
if
(
dm_load_done_i
)
begin
pending_load
<=
0
;
end
if
(
x_store_i
&&
!
dm_store_done_i
)
pending_store
<=
1
;
else
if
(
dm_store_done_i
)
pending_store
<=
0
;
end
always
@*
if
(
x_load_i
||
pending_load
)
if
(
x_load_i
)
rf_rd_value_o
<=
load_value
;
else
if
(
x_rd_source_i
==
`RD_SOURCE_SHIFTER
)
rf_rd_value_o
<=
x_shifter_rd_value_i
;
...
...
@@ -135,28 +114,20 @@ module rv_writeback
else
rf_rd_value_o
<=
x_rd_value_i
;
always
@*
if
(
w_stall_i
)
rf_rd_write_o
<=
0
;
else
if
(
(
x_load_i
||
pending_load
)
&&
dm_load_done_i
)
else
if
(
x_load_i
&&
dm_load_done_i
)
rf_rd_write_o
<=
1
;
else
rf_rd_write_o
<=
x_rd_write_i
;
rf_rd_write_o
<=
x_rd_write_i
&
x_valid_i
;
// assign rf_rd_value_o = (x_load_i || pending_load ? load_value : x_rd_value_i );
assign
rf_rd_o
=
(
x_rd_i
)
;
assign
w_stall_req_o
=
((
x_load_i
||
pending_load
)
&&
!
dm_load_done_i
)
||
((
x_store_i
||
pending_store
)
&&
!
dm_store_done_i
)
;
assign
w_stall_req_o
=
(
x_load_i
&&
!
dm_load_done_i
)
||
(
x_store_i
&&
!
dm_store_done_i
)
;
assign
TRIG2
[
6
]
=
x_load_i
;
assign
TRIG2
[
7
]
=
pending_load
;
assign
TRIG2
[
8
]
=
dm_load_done_i
;
assign
TRIG2
[
9
]
=
x_store_i
;
assign
TRIG2
[
10
]
=
pending_store
;
assign
TRIG2
[
11
]
=
dm_store_done_i
;
assign
TRIG2
[
15
]
=
w_stall_req_o
;
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment