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
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
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
7dc634dc
Commit
7dc634dc
authored
Aug 10, 2015
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
working on exceptions
parent
b57333c6
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
25 changed files
with
817 additions
and
395 deletions
+817
-395
Manifest.py
rtl/Manifest.py
+4
-1
rv_cpu.v
rtl/rv_cpu.v
+45
-6
rv_csr.v
rtl/rv_csr.v
+121
-16
rv_defs.v
rtl/rv_defs.v
+36
-4
rv_exec.v
rtl/rv_exec.v
+123
-29
rv_fetch.v
rtl/rv_fetch.v
+2
-3
rv_multiply.v
rtl/rv_multiply.v
+26
-39
rv_predecode.v
rtl/rv_predecode.v
+26
-3
rv_shifter.v
rtl/rv_shifter.v
+95
-0
xrv_core.vhd
rtl/xrv_core.vhd
+3
-0
board.h
sw/common/board.h
+2
-0
crt0.S
sw/common/crt0.S
+17
-0
ram2.ld
sw/common/ram2.ld
+3
-1
Makefile
sw/hello/Makefile
+2
-2
main.c
sw/hello/main.c
+13
-1
Makefile
sw/test2/Makefile
+2
-2
main.c
sw/test2/main.c
+27
-1
boot.c
sw/uart_bootloader/boot.c
+5
-0
boot.ld
sw/uart_bootloader/boot.ld
+5
-1
crt0.S
sw/uart_bootloader/crt0.S
+0
-21
uart.c
sw/uart_bootloader/uart.c
+0
-76
rv_core_test.xise
syn/spec/rv_core_test.xise
+50
-33
main.sv
tb/cpu/main.sv
+67
-4
run.do
tb/cpu/run.do
+2
-2
wave.do
tb/cpu/wave.do
+141
-150
No files found.
rtl/Manifest.py
View file @
7dc634dc
...
...
@@ -13,4 +13,7 @@ files = [ "rv_cpu.v",
"rv_regfile.v"
,
"rv_writeback.v"
,
"rv_shifter.v"
,
"rv_multiply.v"
];
"rv_multiply.v"
,
"rv_csr.v"
,
"rv_timer.v"
,
"rv_exceptions.v"
];
rtl/rv_cpu.v
View file @
7dc634dc
...
...
@@ -27,6 +27,8 @@ module rv_cpu
input
clk_i
,
input
rst_i
,
input
irq_i
,
// instruction mem I/F
output
[
31
:
0
]
im_addr_o
,
input
[
31
:
0
]
im_data_i
,
...
...
@@ -51,7 +53,7 @@ module rv_cpu
wire
x_kill
;
wire
f_kill
;
wire
[
31
:
0
]
f2d_pc
,
f2d_
pc_plus_4
,
f2d_
ir
;
wire
[
31
:
0
]
f2d_pc
,
f2d_ir
;
wire
f2d_ir_valid
;
wire
[
31
:
0
]
x2f_pc_bra
;
wire
x2f_bra
;
...
...
@@ -77,13 +79,17 @@ module rv_cpu
wire
d2x_is_signed_alu_op
;
wire
d2x_is_add_o
;
wire
d2x_is_shift_o
;
wire
[
1
:
0
]
d2x_rd_source
;
wire
[
2
:
0
]
d2x_rd_source
;
wire
d2x_rd_write
;
wire
[
11
:
0
]
d2x_csr_sel
;
wire
[
4
:
0
]
d2x_csr_imm
;
wire
d2x_is_csr
,
d2x_is_eret
,
d2x_csr_load_en
;
wire
d2x_load_hazard
;
wire
d_stall
,
d_kill
;
wire
[
39
:
0
]
csr_time
,
csr_cycles
;
rv_fetch
fetch
(
...
...
@@ -142,7 +148,14 @@ module rv_cpu
.
x_is_add_o
(
d2x_is_add
)
,
.
x_is_shift_o
(
d2x_is_shift
)
,
.
x_rd_source_o
(
d2x_rd_source
)
,
.
x_rd_write_o
(
d2x_rd_write
)
.
x_rd_write_o
(
d2x_rd_write
)
,
.
x_csr_sel_o
(
d2x_csr_sel
)
,
.
x_csr_imm_o
(
d2x_csr_imm
)
,
.
x_is_csr_o
(
d2x_is_csr
)
,
.
x_is_eret_o
(
d2x_is_eret
)
)
;
wire
[
4
:
0
]
x2w_rd
;
...
...
@@ -196,6 +209,8 @@ module rv_cpu
wire
w_stall_req
;
rv_exec
execute
(
...
...
@@ -204,11 +219,19 @@ module rv_cpu
.
x_stall_i
(
x_stall
)
,
.
x_kill_i
(
x_kill
)
,
.
irq_i
(
irq_i
)
,
.
x_stall_req_o
(
x_stall_req
)
,
.
w_stall_req_i
(
w_stall_req
)
,
.
d_valid_i
(
d2x_valid
)
,
.
d_is_csr_i
(
d2x_is_csr
)
,
.
d_is_eret_i
(
d2x_is_eret
)
,
.
d_csr_imm_i
(
d2x_csr_imm
)
,
.
d_csr_sel_i
(
d2x_csr_sel
)
,
.
d_load_hazard_i
(
d2x_load_hazard
)
,
.
d_pc_i
(
d2x_pc
)
,
.
d_rd_i
(
d2x_rd
)
,
...
...
@@ -248,7 +271,12 @@ module rv_cpu
.
dm_data_select_o
(
dm_data_select_o
)
,
.
dm_store_o
(
dm_store_o
)
,
.
dm_load_o
(
dm_load_o
)
,
.
dm_ready_i
(
dm_ready_i
)
.
dm_ready_i
(
dm_ready_i
)
,
.
csr_time_i
(
csr_time
)
,
.
csr_cycles_i
(
csr_cycles
)
,
.
timer_tick_i
(
sys_tick
)
)
;
...
...
@@ -281,6 +309,17 @@ module rv_cpu
.
rf_rd_write_o
(
rf_rd_write
)
)
;
rv_timer
ctimer
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
csr_time_o
(
csr_time
)
,
.
csr_cycles_o
(
csr_cycles
)
,
.
sys_tick_o
(
sys_tick
)
)
;
reg
x2f_bra_d0
,
x2f_bra_d1
;
always
@
(
posedge
clk_i
)
...
...
rtl/rv_csr.v
View file @
7dc634dc
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
version 3.0 of the License, or (at your option) any later version.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
`include
"rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_csr
(
input
clk_i
,
input
rst_i
,
input
x_stall_i
,
input
d_csr_write_rd_i
,
input
x_kill_i
,
input
d_is_csr_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_pc_i
,
// for exception strage
output
reg
[
31
:
0
]
x_rd_o
,
output
reg
x_rd_write_o
,
input
x_exception_i
,
input
x_exception_irq_i
,
input
[
2
:
0
]
x_exception_id_i
input
[
39
:
0
]
csr_time_i
,
input
[
39
:
0
]
csr_cycles_i
,
// interrupt management
output
[
31
:
0
]
x_csr_write_value_o
,
input
[
31
:
0
]
csr_mstatus_i
,
input
[
31
:
0
]
csr_mip_i
,
input
[
31
:
0
]
csr_mie_i
,
input
[
31
:
0
]
csr_mepc_i
,
input
[
31
:
0
]
csr_mcause_i
output
[
31
:
0
]
x_exception_pc_o
)
;
reg
[
31
:
0
]
csr_mepc
;
reg
[
31
:
0
]
csr_mscratch
;
reg
[
31
:
0
]
csr_mcause
;
reg
[
31
:
0
]
csr_mstatus
;
reg
[
31
:
0
]
csr_mscratch
=
0
;
wire
csr_mie
;
reg
[
31
:
0
]
csr_in1
;
reg
[
31
:
0
]
csr_in2
;
reg
[
31
:
0
]
csr_out
;
always
@*
case
(
d_csr_sel_i
)
`CSR_ID_CYCLESL
:
csr_in1
<=
csr_cycles_i
[
31
:
0
]
;
`CSR_ID_CYCLESH
:
csr_in1
<=
{
24'h0
,
csr_cycles_i
[
39
:
32
]
};
`CSR_ID_TIMEL
:
csr_in1
<=
csr_time_i
[
31
:
0
]
;
`CSR_ID_TIMEH
:
csr_in1
<=
{
24'h0
,
csr_time_i
[
39
:
32
]
};
`CSR_ID_MSCRATCH
:
csr_in1
<=
csr_mscratch
;
`CSR_ID_MEPC
:
csr_in1
<=
csr_mepc_i
;
`CSR_ID_MSTATUS
:
csr_in1
<=
csr_mstatus_i
;
`CSR_ID_MCAUSE
:
csr_in1
<=
csr_mcause_i
;
`CSR_ID_MIP
:
csr_in1
<=
csr_mip_i
;
`CSR_ID_MIE
:
csr_in1
<=
csr_mie_i
;
default:
csr_in1
<=
32
'
hx
;
endcase
// case (d_csr_sel_i)
always
@*
x_rd_o
<=
csr_in1
;
genvar
i
;
assign
x_exception_pc_o
=
csr_mepc
;
always
@*
case
(
d_fun_i
)
`CSR_OP_CSRRWI
,
`CSR_OP_CSRRSI
,
`CSR_OP_CSRRCI
:
csr_in2
<=
{
27'b0
,
d_csr_imm_i
};
default:
csr_in2
<=
d_rs1_i
;
endcase
// case (d_fun_i)
generate
for
(
i
=
0
;
i
<
32
;
i
=
i
+
1
)
begin
always
@*
case
(
d_fun_i
)
`CSR_OP_CSRRWI
,
`CSR_OP_CSRRW
:
csr_out
[
i
]
<=
csr_in2
[
i
]
;
`CSR_OP_CSRRCI
,
`CSR_OP_CSRRC
:
csr_out
[
i
]
<=
csr_in2
[
i
]
?
1'b0
:
csr_in1
[
i
]
;
`CSR_OP_CSRRSI
,
`CSR_OP_CSRRS
:
csr_out
[
i
]
<=
csr_in2
[
i
]
?
1'b1
:
csr_in1
[
i
]
;
default:
csr_out
[
i
]
<=
32
'
hx
;
endcase
// case (d_csr_op_i)
end
// for (i=0;i<32;i=i+1)
endgenerate
always
@
(
posedge
clk_i
)
if
(
rst_i
)
csr_mscratch
<=
0
;
else
if
(
!
x_stall_i
&&
!
x_kill_i
&&
d_is_csr_i
)
case
(
d_csr_sel_i
)
`CSR_ID_MSCRATCH
:
csr_mscratch
<=
csr_out
;
endcase
// case (d_csr_sel_i)
assign
x_csr_write_value_o
=
csr_out
;
endmodule
rtl/rv_defs.v
View file @
7dc634dc
...
...
@@ -27,6 +27,7 @@
`define
OPC_BRANCH 5
'
b11000
`define
OPC_LOAD 5
'
b00000
`define
OPC_STORE 5
'
b01000
`define
OPC_SYSTEM 5
'
b11100
`define
BRA_EQ 3
'
b000
`define
BRA_NEQ 3
'
b001
...
...
@@ -55,7 +56,38 @@
`define
FUNC_MULHSU 3
'
b010
`define
FUNC_MULHU 3
'
b011
`define
RD_SOURCE_ALU 2
'
b00
`define
RD_SOURCE_SHIFTER 2
'
b10
`define
RD_SOURCE_MULTIPLY 2
'
b01
`define
RD_SOURCE_DIVIDE 2
'
b11
`define
RD_SOURCE_ALU 3
'
b000
`define
RD_SOURCE_SHIFTER 3
'
b010
`define
RD_SOURCE_MULTIPLY 3
'
b001
`define
RD_SOURCE_DIVIDE 3
'
b011
`define
RD_SOURCE_CSR 3
'
b011
`define
CSR_ID_CYCLESH 12
'
hc80
`define
CSR_ID_CYCLESL 12
'
hc00
`define
CSR_ID_TIMEH 12
'
hc81
`define
CSR_ID_TIMEL 12
'
hc01
`define
CSR_ID_MSCRATCH 12
'
h340
`define
CSR_ID_MEPC 12
'
h341
`define
CSR_ID_MSTATUS 12
'
h300
`define
CSR_ID_MCAUSE 12
'
h342
`define
CSR_ID_MIP 12
'
h344
`define
CSR_ID_MIE 12
'
h304
`define
CSR_OP_CSRRW 3
'
b001
`define
CSR_OP_CSRRS 3
'
b010
`define
CSR_OP_CSRRC 3
'
b011
`define
CSR_OP_CSRRWI 3
'
b101
`define
CSR_OP_CSRRSI 3
'
b110
`define
CSR_OP_CSRRCI 3
'
b111
`define
URV_RESET_VECTOR 32
'
h00000000
`define
URV_TRAP_VECTOR 32
'
h00000040
`define
EXCEPT_ILLEGAL_INSN 2
`define
EXCEPT_BREAKPOINT 3
`define
EXCEPT_UNALIGNED_LOAD 4
`define
EXCEPT_UNALIGNED_STORE 6
`define
EXCEPT_TIMER 9
`define
EXCEPT_IRQ 10
rtl/rv_exec.v
View file @
7dc634dc
...
...
@@ -41,6 +41,7 @@ module rv_exec
input
[
31
:
0
]
rf_rs1_value_i
,
input
[
31
:
0
]
rf_rs2_value_i
,
input
d_valid_i
,
input
d_load_hazard_i
,
...
...
@@ -48,18 +49,25 @@ module rv_exec
input
[
4
:
0
]
d_opcode_i
,
input
d_shifter_sign_i
,
input
d_is_csr_i
,
input
d_is_eret_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
[
31
:
0
]
d_imm_i
,
input
d_is_signed_compare_i
,
input
d_is_signed_alu_op_i
,
input
d_is_add_i
,
input
d_is_shift_i
,
input
[
1
:
0
]
d_rd_source_i
,
input
[
2
:
0
]
d_rd_source_i
,
input
d_rd_write_i
,
output
reg
[
31
:
0
]
f_branch_target_o
,
output
f_branch_take_o
,
output
w_load_hazard_o
,
input
irq_i
,
// Writeback stage I/F
output
reg
[
2
:
0
]
w_fun_o
,
...
...
@@ -77,9 +85,16 @@ module rv_exec
output
[
3
:
0
]
dm_data_select_o
,
output
dm_store_o
,
output
dm_load_o
,
input
dm_ready_i
input
dm_ready_i
,
input
[
39
:
0
]
csr_time_i
,
input
[
39
:
0
]
csr_cycles_i
,
input
timer_tick_i
)
;
parameter
g_exception_vector
=
'h40
;
wire
[
31
:
0
]
rs1
,
rs2
;
assign
rs1
=
rf_rs1_value_i
;
...
...
@@ -87,8 +102,7 @@ module rv_exec
reg
[
31
:
0
]
alu_op1
,
alu_op2
,
alu_result
;
reg
[
31
:
0
]
rd_value
;
reg
branch_take
;
reg
branch_condition_met
;
...
...
@@ -106,6 +120,85 @@ module rv_exec
reg
f_branch_take
;
wire
x_stall_req_shifter
;
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
;
wire
[
31
:
0
]
rd_div
;
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
;
rv_csr
csr_regs
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
x_kill_i
(
x_kill_i
)
,
.
d_is_csr_i
(
d_is_csr_i
)
,
.
d_fun_i
(
d_fun_i
)
,
.
d_csr_imm_i
(
d_csr_imm_i
)
,
.
d_csr_sel_i
(
d_csr_sel_i
)
,
.
d_rs1_i
(
rs1
)
,
.
x_rd_o
(
rd_csr
)
,
.
x_csr_write_value_o
(
csr_write_value
)
,
.
csr_time_i
(
csr_time_i
)
,
.
csr_cycles_i
(
csr_cycles_i
)
,
.
csr_mstatus_i
(
csr_mstatus
)
,
.
csr_mip_i
(
csr_mip
)
,
.
csr_mie_i
(
csr_mie
)
,
.
csr_mepc_i
(
csr_mepc
)
,
.
csr_mcause_i
(
csr_mmause
)
)
;
rv_exceptions
exception_unit
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
x_kill_i
(
x_kill_i
)
,
.
d_is_csr_i
(
d_is_csr_i
)
,
.
d_is_eret_i
(
d_is_eret_i
)
,
.
d_fun_i
(
d_fun_i
)
,
.
d_csr_imm_i
(
d_csr_imm_i
)
,
.
d_csr_sel_i
(
d_csr_sel_i
)
,
.
x_csr_write_value_i
(
csr_write_value
)
,
.
exp_irq_i
(
irq_i
)
,
.
exp_tick_i
(
timer_tick_i
)
,
.
exp_breakpoint_i
(
1'b0
)
,
.
exp_unaligned_load_i
(
1'b0
)
,
.
exp_unaligned_store_i
(
1'b0
)
,
.
exp_invalid_insn_i
(
1'b0
)
,
.
x_exception_o
(
exception
)
,
.
x_exception_pc_i
(
d_pc_i
)
,
.
x_exception_pc_o
(
exception_address
)
,
.
csr_mstatus_o
(
csr_mstatus
)
,
.
csr_mip_o
(
csr_mip
)
,
.
csr_mie_o
(
csr_mie
)
,
.
csr_mepc_o
(
csr_mepc
)
,
.
csr_mcause_o
(
csr_mcause
)
)
;
// branch condition decoding
always
@*
...
...
@@ -120,13 +213,16 @@ module rv_exec
endcase
// case (d_fun_i)
always
@*
case
(
d_opcode_i
)
`OPC_JAL
:
branch_target
<=
d_pc_i
+
d_imm_i
;
`OPC_JALR
:
branch_target
<=
rs1
+
d_imm_i
;
`OPC_BRANCH
:
branch_target
<=
d_pc_i
+
d_imm_i
;
default:
branch_target
<=
32
'
hx
;
endcase
// case (d_opcode_i)
if
(
d_is_eret_i
)
branch_target
<=
exception_address
;
else
if
(
exception
)
branch_target
<=
g_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
;
`OPC_BRANCH
:
branch_target
<=
d_pc_i
+
d_imm_i
;
default:
branch_target
<=
32
'
hx
;
endcase
// case (d_opcode_i)
// decode ALU operands
always
@*
...
...
@@ -185,12 +281,6 @@ module rv_exec
endcase
// case (d_fun_i)
end
// always@ *
wire
x_stall_req_shifter
;
wire
x_stall_req_multiply
=
0
;
wire
x_stall_req_divide
=
0
;
wire
[
31
:
0
]
rd_shifter
;
rv_shifter
shifter
(
...
...
@@ -215,6 +305,7 @@ module rv_exec
case
(
d_rd_source_i
)
`RD_SOURCE_ALU
:
rd_value
<=
alu_result
;
`RD_SOURCE_SHIFTER
:
rd_value
<=
rd_shifter
;
`RD_SOURCE_CSR
:
rd_value
<=
rd_csr
;
default:
rd_value
<=
32
'
hx
;
endcase
// case (x_rd_source_i)
...
...
@@ -266,14 +357,17 @@ module rv_exec
//branch decision
always
@*
case
(
d_opcode_i
)
`OPC_JAL
,
`OPC_JALR
:
branch_take
<=
1
;
`OPC_BRANCH
:
branch_take
<=
branch_condition_met
;
default:
branch_take
<=
0
;
endcase
// case (d_opcode_i)
if
(
exception
||
d_is_eret_i
)
branch_take
<=
1
;
else
case
(
d_opcode_i
)
`OPC_JAL
,
`OPC_JALR
:
branch_take
<=
1
;
`OPC_BRANCH
:
branch_take
<=
branch_condition_met
;
default:
branch_take
<=
0
;
endcase
// case (d_opcode_i)
// generate load/store requests
...
...
@@ -287,6 +381,7 @@ module rv_exec
assign
dm_load_o
=
is_load
;
assign
dm_store_o
=
is_store
;
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
...
...
@@ -308,12 +403,11 @@ module rv_exec
// if(!shifter_stall_req)
w_rd_value_o
<=
rd_value
;
w_rd_write_o
<=
d_rd_write_i
&&
!
x_kill_i
&&
d_valid_i
;
w_rd_write_o
<=
d_rd_write_i
&&
!
x_kill_i
&&
d_valid_i
&&
!
exception
;
w_fun_o
<=
d_fun_i
;
w_load_o
<=
is_load
;
w_store_o
<=
is_store
;
w_load_o
<=
is_load
&&
!
exception
;
w_store_o
<=
is_store
&&
!
exception
;
w_dm_addr_o
<=
dm_addr
;
...
...
rtl/rv_fetch.v
View file @
7dc634dc
...
...
@@ -51,13 +51,12 @@ module rv_fetch
always
@*
if
(
x_bra_i
)
pc_next
<=
x_pc_bra_i
;
else
if
(
f_stall_i
||
!
im_valid_i
)
else
if
(
!
rst_d
||
f_stall_i
||
!
im_valid_i
)
pc_next
<=
pc
;
else
pc_next
<=
pc
+
4
;
assign
f_ir_o
=
ir
;
assign
im_addr_o
=
pc_next
;
...
...
@@ -78,7 +77,7 @@ module rv_fetch
f_pc_o
<=
pc
;
if
(
im_valid_i
)
begin
ir
<=
im_data_i
;
// emit nop
ir
<=
im_data_i
;
f_valid_o
<=
(
rst_d
&&
!
f_kill_i
)
;
end
else
begin
// if (i_valid_i)
f_valid_o
<=
0
;
...
...
rtl/rv_multiply.v
View file @
7dc634dc
/*
`include
"rv_defs.v"
`timescale
1
ns
/
1
ps
...
...
@@ -8,60 +7,48 @@ module rv_multiply
input
clk_i
,
input
rst_i
,
input
x_stall_i
,
input
w_stall_req_i
,
input
d_valid_i
,
input
d_is_mul_i
,
input [31:0] x_rs1_i,
input [31:0] x_rs2_i,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_rs2_i
,
input [4:0]
x
_opcode_i,
input [2:0]
x
_fun_i,
input
[
4
:
0
]
d
_opcode_i
,
input
[
2
:
0
]
d
_fun_i
,
output [31:0] x_rd_o,
output x_rd_valid_o,
output
reg
[
31
:
0
]
x_rd_o
,
output
x_stall_req_o
)
;
parameter
g_latency
=
2
;
wire sign_a = (
x_fun_i == `FUNC_MUL || x_fun_i == `FUNC_MULHSU ) ? x
_rs1_i[31] : 1'b0;
wire sign_b = (
x_fun_i == `FUNC_MUL ) ? x
_rs2_i[31] : 1'b0;
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
;
wire [32:0] a = { sign_a, x_rs1_i };
wire [32:0] b = { sign_b, x_rs2_i };
reg [65:0] stage0;
wire
[
32
:
0
]
a
=
{
sign_a
,
d_rs1_i
};
wire
[
32
:
0
]
b
=
{
sign_b
,
d_rs2_i
};
reg [3:0] pipe;
always@(posedge clk_i)
if(rst_i)
pipe <= 0;
else if (x_opcode_i = `OPC_MUL )
pipe <= (1<<g_latency);
else
pipe <= {1'b0, pipe [3:1]};
reg
[
65
:
0
]
stage0
,
stage1
;
always
@
(
posedge
clk_i
)
begin
stage0 <= $signed(a) * $signed(b);
if( d_fun_i != `FUNC_MUL )
x_rd_o <= stage0[63:32];
else
x_rd_o <= stage0[31:0];
end
if
(
!
x_stall_i
)
begin
stage0
<=
$
signed
(
a
)
*
$
signed
(
b
)
;
stage1
<=
stage0
;
end
always
@*
if
(
d_fun_i
!=
`FUNC_MUL
)
x_rd_o
<=
stage1
[
63
:
32
]
;
else
x_rd_o
<=
stage1
[
31
:
0
]
;
endmodule
// rv_multiply
*/
rtl/rv_predecode.v
View file @
7dc634dc
...
...
@@ -60,9 +60,14 @@ module rv_decode
output
reg
x_is_signed_alu_op_o
,
output
reg
x_is_add_o
,
output
reg
x_is_shift_o
,
output
reg
[
1
:
0
]
x_rd_source_o
,
output
reg
x_rd_write_o
output
reg
[
2
:
0
]
x_rd_source_o
,
output
reg
x_rd_write_o
,
output
reg
[
11
:
0
]
x_csr_sel_o
,
output
reg
[
4
:
0
]
x_csr_imm_o
,
output
reg
x_is_csr_o
,
output
reg
x_is_eret_o
)
;
...
...
@@ -181,6 +186,8 @@ module rv_decode
if
(
d_is_shift
)
x_rd_source_o
<=
`RD_SOURCE_SHIFTER
;
else
if
(
d_opcode
==
`OPC_SYSTEM
)
x_rd_source_o
<=
`RD_SOURCE_CSR
;
else
x_rd_source_o
<=
`RD_SOURCE_ALU
;
...
...
@@ -188,12 +195,28 @@ module rv_decode
case
(
d_opcode
)
`OPC_OP_IMM
,
`OPC_OP
,
`OPC_JAL
,
`OPC_JALR
,
`OPC_LUI
,
`OPC_AUIPC
:
x_rd_write_o
<=
1
;
`OPC_SYSTEM
:
x_rd_write_o
<=
(
d_fun
!=
0
)
;
// CSR instructions write to RD
default:
x_rd_write_o
<=
0
;
endcase
// case (d_opcode)
end
// if (!d_stall_i)
// CSR/supervisor instructions
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
begin
x_csr_imm_o
<=
f_ir_i
[
19
:
15
]
;
x_csr_sel_o
<=
f_ir_i
[
31
:
20
]
;
x_is_csr_o
<=
(
d_opcode
==
`OPC_SYSTEM
)
&&
(
d_fun
!=
0
)
;
x_is_eret_o
<=
(
d_opcode
==
`OPC_SYSTEM
)
&&
(
d_fun
==
0
)
&&
(
f_ir_i
[
31
:
20
]
==
12'b000100000000
)
;
end
...
...
rtl/rv_shifter.v
View file @
7dc634dc
...
...
@@ -101,3 +101,98 @@ module rv_shifter
endmodule
// rv_shifter
module
rv_shifter2
(
input
clk_i
,
input
rst_i
,