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
014209e9
Commit
014209e9
authored
Sep 25, 2015
by
Tomasz Wlostowski
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
code cleanup & relicensing
parent
695e8467
Expand all
Show whitespace changes
Inline
Side-by-side
Showing
19 changed files
with
1242 additions
and
502 deletions
+1242
-502
Manifest.py
rtl/Manifest.py
+13
-19
rv_top_test.v
rtl/new/rv_top_test.v
+0
-0
rv_wishbone.v
rtl/new/rv_wishbone.v
+0
-0
urv_cpu.v
rtl/urv_cpu.v
+120
-213
urv_csr.v
rtl/urv_csr.v
+5
-4
urv_debug.v
rtl/urv_debug.v
+191
-0
urv_decode.v
rtl/urv_decode.v
+45
-80
urv_defs.v
rtl/urv_defs.v
+5
-2
urv_divide.v
rtl/urv_divide.v
+144
-0
urv_exceptions.v
rtl/urv_exceptions.v
+6
-5
urv_exec.v
rtl/urv_exec.v
+70
-65
urv_fetch.v
rtl/urv_fetch.v
+9
-9
urv_iram.v
rtl/urv_iram.v
+110
-3
urv_multiply.v
rtl/urv_multiply.v
+181
-0
urv_regfile.v
rtl/urv_regfile.v
+161
-0
urv_shifter.v
rtl/urv_shifter.v
+92
-0
urv_timer.v
rtl/urv_timer.v
+7
-6
urv_writeback.v
rtl/urv_writeback.v
+9
-22
xurv_core.vhd
rtl/xurv_core.vhd
+74
-74
No files found.
rtl/Manifest.py
View file @
014209e9
sim_tool
=
"modelsim"
top_module
=
"main"
syn_device
=
"xc6slx150t"
action
=
"simulation"
target
=
"xilinx"
include_dirs
=
[
"."
]
files
=
[
"rv_cpu.v"
,
"rv_exec.v"
,
"rv_fetch.v"
,
"
rv_pre
decode.v"
,
"rv_regfile.v"
,
"rv_writeback.v"
,
"rv_shifter.v"
,
"rv_multiply.v"
,
"rv_divide.v"
,
"
rv_csr.v"
,
"rv_timer.v"
,
"rv_exceptions.v"
,
files
=
[
"
u
rv_cpu.v"
,
"
u
rv_exec.v"
,
"
u
rv_fetch.v"
,
"
urv_
decode.v"
,
"
u
rv_regfile.v"
,
"
u
rv_writeback.v"
,
"
u
rv_shifter.v"
,
"
u
rv_multiply.v"
,
"
u
rv_divide.v"
,
"u
rv_csr.v"
,
"
u
rv_timer.v"
,
"
u
rv_exceptions.v"
,
"urv_iram.v"
,
"x
rv_core.vhd"
];
"xu
rv_core.vhd"
];
# "../sim/rv_icache_model.sv"];
rtl/rv_top_test.v
→
rtl/
new/
rv_top_test.v
View file @
014209e9
File moved
rtl/rv_wishbone.v
→
rtl/
new/
rv_wishbone.v
View file @
014209e9
File moved
rtl/rv_cpu.v
→
rtl/
u
rv_cpu.v
View file @
014209e9
This diff is collapsed.
Click to expand it.
rtl/rv_csr.v
→
rtl/
u
rv_csr.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,11 +19,11 @@
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_csr
module
u
rv_csr
(
input
clk_i
,
input
rst_i
,
...
...
rtl/urv_debug.v
0 → 100644
View file @
014209e9
`timescale
1
ns
/
1
ps
`include
"urv_defs.v"
module
urv_debug
(
input
clk_i
,
input
rst_i
,
input
x_kill_i
,
input
x_stall_i
,
output
x_stall_req_o
,
output
d_kill_req_o
,
output
f_kill_req_o
,
output
halt_o
,
input
x_valid_i
,
input
[
31
:
0
]
x_pc_i
,
input
x_dm_load_i
,
input
x_dm_store_i
,
input
[
31
:
0
]
x_dm_addr_i
,
input
[
31
:
0
]
x_dm_data_s_i
,
input
[
3
:
0
]
x_dm_data_select_i
,
output
[
31
:
0
]
w_dm_data_l_o
,
output
w_dm_store_done_o
,
output
w_dm_load_done_o
,
output
x_dm_ready_o
,
output
dm_load_o
,
output
dm_store_o
,
output
[
31
:
0
]
dm_addr_o
,
output
[
31
:
0
]
dm_data_s_o
,
output
[
3
:
0
]
dm_data_select_o
,
input
[
31
:
0
]
dm_data_l_i
,
input
dm_store_done_i
,
input
dm_load_done_i
,
input
dm_ready_i
,
output
[
4
:
0
]
rf_index_o
,
input
[
31
:
0
]
rf_data_r_i
output
[
31
:
0
]
rf_data_w_o
,
output
rf_write_o
,
output
[
31
:
0
]
f_pc_restore_o
,
output
f_pc_restore_load_o
,
input
[
6
:
0
]
dbg_adr_i
,
input
[
7
:
0
]
dbg_dat_i
,
input
dbg_stb_i
,
input
dbg_we_i
,
output
[
7
:
0
]
dbg_dat_o
,
output
dbg_irq_o
)
;
parameter
g_num_breakpoints
=
4
;
`define
BREAK_SRC_PC 0
`define
BREAK_SRC_MEM_ADDR 1
`define
BREAK_SRC_MEM_ST_DATA 2
`define
BREAK_SRC_MEM_LD_DATA 3
reg
[
31
:
0
]
break_compare_hi
[
0
:
g_num_breakpoints
-
1
]
;
reg
[
31
:
0
]
break_compare_lo
[
0
:
g_num_breakpoints
-
1
]
;
reg
[
1
:
0
]
break_src
[
0
:
g_num_breakpoints
-
1
]
;
reg
break_valid
[
0
:
g_num_breakpoints
-
1
]
;
reg
[
31
:
0
]
in_muxed
[
0
:
g_num_breakpoints
-
1
]
;
reg
in_valid
[
0
:
g_num_breakpoints
-
1
]
;
reg
break_hit
[
0
:
g_num_breakpoints
-
1
]
;
`define
ST_IDLE 0
generate
genvar
gg
;
for
(
gg
=
0
;
gg
<
g_num_breakpoints
;
gg
=
gg
+
1
)
begin
always
@*
case
(
break_src
[
gg
])
`BREAK_SRC_PC
:
in_muxed
[
gg
]
<=
x_pc_i
;
`BREAK_SRC_MEM_ADDR
:
in_muxed
[
gg
]
<=
x_dm_addr_i
;
`BREAK_SRC_MEM_ST_DATA
:
in_muxed
[
gg
]
<=
x_dm_data_s_i
;
`BREAK_SRC_MEM_ST_DATA
:
in_muxed
[
gg
]
<=
dm_data_l_i
;
endcase
// case (break_src[gg])
case
(
break_src
[
gg
])
`BREAK_SRC_PC
:
begin
in_muxed
[
gg
]
<=
x_pc_i
;
in_valid
[
gg
]
<=
x_valid_i
;
end
`BREAK_SRC_MEM_ADDR
:
begin
in_muxed
[
gg
]
<=
x_dm_addr_i
;
in_valid
[
gg
]
<=
x_dm_load_i
||
x_dm_store_i
;
end
`BREAK_SRC_MEM_ST_DATA
:
begin
in_muxed
[
gg
]
<=
x_dm_data_s_i
;
in_valid
[
gg
]
<=
x_dm_store_i
;
end
`BREAK_SRC_MEM_LD_DATA
:
begin
in_muxed
[
gg
]
<=
dm_data_l_i
;
in_valid
[
gg
]
<=
dm_load_done_i
;
end
endcase
// case (break_src[gg])
break_hit
[
gg
]
<=
(
in_muxed
[
gg
]
>=
break_comp1
[
gg
]
&&
in_muxed
[
gg
]
<=
break_comp
[
gg
]
)
?
in_valid
[
gg
]
:
1'b0
;
end
endgenerate
reg
trigger_reload_pc
;
reg
trigger_halt
;
reg
trigger_resume
;
reg
[
31
:
0
]
reload_pc_value
;
`define
DBG_REG_PC0 0
`define
DBG_REG_PC1 1
`define
DBG_REG_PC2 2
`define
DBG_REG_PC3 3
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
reload_pc
<=
0
;
end
else
begin
trigger_halt
<=
0
;
trigger_resume
<=
0
;
trigger_reload_pc
<=
0
;
if
(
dbg_we_i
)
begin
case
(
dbg_adr_i
)
`DBG_REG_PCO
:
reload_pc_value
[
7
:
0
]
<=
dbg_dat_i
;
`DBG_REG_PC1
:
reload_pc_value
[
15
:
8
]
<=
dbg_dat_i
;
`DBG_REG_PC2
:
reload_pc_value
[
23
:
16
]
<=
dbg_dat_i
;
`DBG_REG_PC3
:
reload_pc_value
[
31
:
24
]
<=
dbg_dat_i
;
`DBG_CTL
:
begin
trigger_halt
<=
dbg_dat_i
[
0
]
;
trigger_resume
<=
dbg_dat_i
[
1
]
;
trigger_reload_pc
<=
dbg_dat_i
[
2
]
;
end
endcase
// case (dbg_adr_i)
end
else
begin
// if ( dbg_we_i )
case
(
dbg_adr_i
)
`DBG_REG_PCO
:
dbg_dat_o
<=
x_pc_i
[
7
:
0
]
;
`DBG_REG_PC1
:
dbg_dat_o
<=
x_pc_i
[
15
:
8
]
;
`DBG_REG_PC2
:
dbg_dat_o
<=
x_pc_i
[
23
:
16
]
;
`DBG_REG_PC3
:
dbg_dat_o
<=
x_pc_i
[
31
:
24
]
;
end
// else: !if( dbg_we_i )
end
// else: !if( dbg_we_i )
end
end
rtl/
rv_pre
decode.v
→
rtl/
urv_
decode.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,50 +19,40 @@
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_decode
module
urv_decode
(
input
clk_i
,
input
rst_i
,
// pipeline control
input
d_stall_i
,
input
d_kill_i
,
output
d_stall_req_o
,
output
reg
x_load_hazard_o
,
// from Fetch stage
input
[
31
:
0
]
f_ir_i
,
input
[
31
:
0
]
f_pc_i
,
input
f_valid_i
,
output
x_valid_o
,
output
reg
[
31
:
0
]
x_pc_o
,
input
d_x_rs1_bypass_i
,
input
d_x_rs2_bypass_i
,
input
d_w_rs1_bypass_i
,
input
d_w_rs2_bypass_i
,
// to Register File
output
[
4
:
0
]
rf_rs1_o
,
output
[
4
:
0
]
rf_rs2_o
,
// to Execute 1 stage
output
x_valid_o
,
output
reg
[
31
:
0
]
x_pc_o
,
output
[
4
:
0
]
x_rs1_o
,
output
[
4
:
0
]
x_rs2_o
,
output
[
4
:
0
]
x_rd_o
,
output
reg
[
4
:
0
]
x_shamt_o
,
output
reg
[
2
:
0
]
x_fun_o
,
output
[
4
:
0
]
x_opcode_o
,
output
reg
x_shifter_sign_o
,
output
reg
x_is_signed_compare_o
,
output
reg
x_is_signed_alu_op_o
,
output
reg
x_is_add_o
,
...
...
@@ -69,32 +60,27 @@ module rv_decode
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
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
,
output
reg
[
31
:
0
]
x_imm_o
,
output
reg
[
31
:
0
]
x_alu_op1_o
,
output
reg
[
31
:
0
]
x_alu_op2_o
,
output
reg
x_use_op1_o
,
output
reg
x_use_op2_o
,
output
reg
[
1
:
0
]
x_op1_sel_o
,
output
reg
[
1
:
0
]
x_op2_sel_o
)
;
wire
[
4
:
0
]
f_rs1
=
f_ir_i
[
19
:
15
]
;
wire
[
4
:
0
]
f_rs2
=
f_ir_i
[
24
:
20
]
;
wire
[
4
:
0
]
f_rd
=
f_ir_i
[
11
:
7
]
;
wire
[
4
:
0
]
d_opcode
=
f_ir_i
[
6
:
2
]
;
wire
[
2
:
0
]
d_fun
=
f_ir_i
[
14
:
12
]
;
reg
[
4
:
0
]
x_rs1
;
reg
[
4
:
0
]
x_rs2
;
...
...
@@ -114,26 +100,19 @@ module rv_decode
assign
rf_rs2_o
=
f_rs2
;
reg
[
31
:
0
]
x_ir
;
wire
[
4
:
0
]
d_opcode
=
f_ir_i
[
6
:
2
]
;
reg
load_hazard
;
// attempt to reuse ALU for jump address generation
wire
[
2
:
0
]
d_fun
=
f_ir_i
[
14
:
12
]
;
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
==
`FUNC_MUL
)
;
wire
d_is_mul
=
(
f_ir_i
[
25
]
&&
d_fun
==
3'b000
)
;
// hazzard detect combinatorial logic
always
@*
if
(
x_valid
&&
f_valid_i
&&
(
(
f_rs1
==
x_rd
)
||
(
f_rs2
==
x_rd
)
)
&&
(
!
d_kill_i
)
)
if
(
x_valid
&&
f_valid_i
&&
(
(
f_rs1
==
x_rd
)
||
(
f_rs2
==
x_rd
)
)
&&
(
!
d_kill_i
)
)
begin
case
(
x_opcode
)
`OPC_LOAD
:
...
...
@@ -150,12 +129,12 @@ module rv_decode
reg
inserting_nop
;
// bubble insertion following a hazzard
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
if
(
rst_i
)
inserting_nop
<=
0
;
e
nd
e
lse
if
(
!
d_stall_i
)
else
if
(
!
d_stall_i
)
begin
if
(
inserting_nop
)
inserting_nop
<=
0
;
else
...
...
@@ -164,8 +143,6 @@ module rv_decode
assign
d_stall_req_o
=
load_hazard
&&
!
inserting_nop
;
wire
[
4
:
0
]
f_rd
=
f_ir_i
[
11
:
7
]
;
assign
x_valid_o
=
x_valid
;
...
...
@@ -182,8 +159,6 @@ module rv_decode
else
x_valid
<=
f_valid_i
;
x_ir
<=
f_ir_i
;
x_rs1
<=
f_rs1
;
x_rs2
<=
f_rs2
;
x_rd
<=
f_rd
;
...
...
@@ -192,7 +167,7 @@ module rv_decode
x_shamt_o
<=
f_ir_i
[
24
:
20
]
;
end
// ALU function decoding
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
case
(
d_opcode
)
...
...
@@ -218,6 +193,7 @@ module rv_decode
reg
[
31
:
0
]
d_imm
;
// Immediate decode, comb part
always
@*
case
(
d_opcode
)
`OPC_LUI
,
`OPC_AUIPC
:
d_imm
<=
d_imm_u
;
...
...
@@ -229,11 +205,13 @@ module rv_decode
default:
d_imm
<=
32
'
hx
;
endcase
// case (opcode)
// Immediate decode, seq part
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
x_imm_o
<=
d_imm
;
// ALU operand decoding
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
begin
...
...
@@ -296,7 +274,6 @@ module rv_decode
x_is_mul
<=
d_is_mul
;
case
(
d_opcode
)
`OPC_BRANCH
:
x_is_signed_alu_op_o
<=
(
d_fun
==
`BRA_GE
||
d_fun
==
`BRA_LT
)
;
...
...
@@ -304,9 +281,6 @@ module rv_decode
x_is_signed_alu_op_o
<=
(
d_fun
==
`FUNC_SLT
)
;
endcase
// case (d_opcode)
case
(
d_opcode
)
`OPC_OP
:
x_is_add_o
<=
~
f_ir_i
[
30
]
&&
!
(
d_fun
==
`FUNC_SLT
||
d_fun
==
`FUNC_SLTU
)
;
...
...
@@ -318,9 +292,8 @@ module rv_decode
x_is_add_o
<=
1
;
endcase
// case (d_opcode)
// all multiply/divide instructions except MUL
x_is_undef_o
<=
(
d_opcode
==
`OPC_OP
&&
f_ir_i
[
25
]
&&
d_fun
!=
3'b000
)
;
x_is_undef_o
<=
(
d_opcode
==
`OPC_OP
&&
f_ir_i
[
25
]
&&
d_fun
!=
`FUNC_MUL
)
;
if
(
d_is_shift
)
x_rd_source_o
<=
`RD_SOURCE_SHIFTER
;
...
...
@@ -331,8 +304,6 @@ module rv_decode
else
x_rd_source_o
<=
`RD_SOURCE_ALU
;
// rdest write value
case
(
d_opcode
)
`OPC_OP_IMM
,
`OPC_OP
,
`OPC_JAL
,
`OPC_JALR
,
`OPC_LUI
,
`OPC_AUIPC
:
...
...
@@ -345,26 +316,20 @@ module rv_decode
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
assign
x_is_shift_o
=
x_is_shift
;
assign
x_rd_write_o
=
x_rd_write
;
endmodule
// rv_predecode
endmodule
// rv_decode
rtl/rv_defs.v
→
rtl/
u
rv_defs.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,6 +19,8 @@
*/
`include
"urv_config.v"
`define
OPC_OP_IMM 5
'
b00100
`define
OPC_LUI 5
'
b01101
`define
OPC_AUIPC 5
'
b00101
...
...
rtl/rv_divide.v
→
rtl/
u
rv_divide.v
View file @
014209e9
`include
"rv_defs.v"
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
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
"urv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_divide
module
u
rv_divide
(
input
clk_i
,
input
rst_i
,
input
x_stall_i
,
input
x_kill_i
,
output
x_stall_req_o
,
...
...
@@ -120,132 +142,3 @@ module rv_divide
endmodule
// rv_divide
module
rv_divide_nonrestoring
(
input
clk_i
,
input
rst_i
,
input
x_stall_i
,
input
x_kill_i
,
output
x_stall_req_o
,
input
d_valid_i
,
input
d_is_divide_i
,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_rs2_i
,
input
[
2
:
0
]
d_fun_i
,
output
reg
[
31
:
0
]
x_rd_o
)
;
reg
[
31
:
0
]
a
,
n
,
d
,
q
;
reg
n_sign
,
d_sign
;
reg
[
5
:
0
]
state
;
wire
[
32
:
0
]
alu_result
;
reg
[
31
:
0
]
alu_op1
;
reg
[
31
:
0
]
alu_op2
;
reg
is_rem
;
wire
[
31
:
0
]
a_next
=
{
a
[
30
:
0
]
,
1'b0
};
always
@*
case
(
state
)
// synthesis full_case parallel_case
0
:
begin
alu_op1
<=
'
hx
;
alu_op2
<=
'
hx
;
end
1
:
begin
alu_op1
<=
0
;
alu_op2
<=
d_rs1_i
;
end
2
:
begin
alu_op1
<=
0
;
alu_op2
<=
d_rs2_i
;
end
35
:
begin
alu_op1
<=
a
;
alu_op2
<=
d
;
end
36
:
begin
alu_op1
<=
0
;
alu_op2
<=
q
;
end
37
:
begin
alu_op1
<=
0
;
alu_op2
<=
a
;
end
default:
begin
alu_op1
<=
a_next
;
alu_op2
<=
d
;
end
endcase
// case (state)
reg
alu_sub
;
assign
alu_result
=
alu_sub
?
{
1'b0
,
alu_op1
}
-
{
1'b0
,
alu_op2
}
:
{
1'b0
,
alu_op1
}
+
{
1'b0
,
alu_op2
};
wire
alu_ge
=
~
alu_result
[
32
]
;
wire
start_divide
=
!
x_stall_i
&&
!
x_kill_i
&&
d_valid_i
&&
d_is_divide_i
;
wire
done
=
(
is_rem
?
state
==
38
:
state
==
37
)
;
assign
x_stall_req_o
=
(
start_divide
||
!
done
)
;
always
@*
case
(
state
)
// synthesis full_case parallel_case
1
:
alu_sub
<=
n_sign
;
2
:
alu_sub
<=
d_sign
;
35
:
alu_sub
<=
0
;
36
:
alu_sub
<=
n_sign
^
d_sign
;
37
:
alu_sub
<=
n_sign
;
default:
alu_sub
<=
~
a_next
[
31
]
;
endcase
// case (state)
always
@
(
posedge
clk_i
)
if
(
rst_i
||
done
)
state
<=
0
;
else
if
(
state
!=
0
||
start_divide
)
state
<=
state
+
1
;
always
@
(
posedge
clk_i
)
case
(
state
)
// synthesis full_case parallel_case
0
:
if
(
start_divide
)
begin
//q <= 0;
a
<=
0
;
is_rem
<=
(
d_fun_i
==
`FUNC_REM
||
d_fun_i
==
`FUNC_REMU
)
;
n_sign
<=
d_rs1_i
[
31
]
;
d_sign
<=
d_rs2_i
[
31
]
;
end
1
:
q
<=
alu_result
[
31
:
0
]
;
2
:
d
<=
alu_result
[
31
:
0
]
;
35
:
// correction step
if
(
a
[
31
])
a
<=
alu_result
;
36
:
x_rd_o
<=
alu_result
;
// quotient
37
:
x_rd_o
<=
alu_result
;
// remainder
default:
// 3..34: 32 divider iterations
begin
a
<=
alu_result
;
q
<=
{
q
[
30
:
0
]
,
~
alu_result
[
31
]
};
// r <= alu_ge ? alu_result : r_next;
end
endcase
// case ( state )
endmodule
// rv_divide_nonrestoring
rtl/rv_exceptions.v
→
rtl/
u
rv_exceptions.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -16,13 +17,13 @@
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_exceptions
module
u
rv_exceptions
(
input
clk_i
,
input
rst_i
,
...
...
@@ -192,7 +193,7 @@ module rv_exceptions
assign
x_exception_pc_o
=
csr_mepc
;
assign
x_exception_o
=
exception
&
!
exception_pending
;
endmodule
// rv_exceptions
endmodule
//
u
rv_exceptions
rtl/rv_exec.v
→
rtl/
u
rv_exec.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,11 +19,11 @@
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_exec
module
u
rv_exec
(
input
clk_i
,
input
rst_i
,
...
...
@@ -124,19 +125,16 @@ module rv_exec
reg
[
31
:
0
]
dm_addr
,
dm_data_s
,
dm_select_s
;
// Comparator
wire
[
32
:
0
]
cmp_op1
=
{
d_is_signed_alu_op_i
?
rs1
[
31
]
:
1'b0
,
rs1
};
wire
[
32
:
0
]
cmp_op2
=
{
d_is_signed_alu_op_i
?
rs2
[
31
]
:
1'b0
,
rs2
};
wire
[
32
:
0
]
cmp_rs
=
cmp_op1
-
cmp_op2
;
wire
cmp_equal
=
(
cmp_op1
==
cmp_op2
)
;
wire
cmp_lt
=
cmp_rs
[
32
]
;
reg
f_branch_take
;
wire
[
31
:
0
]
rd_shifter
;
wire
[
31
:
0
]
rd_csr
;
wire
[
31
:
0
]
rd_mul
;
wire
[
31
:
0
]
rd_div
;
wire
exception
;
...
...
@@ -144,8 +142,7 @@ module rv_exec
wire
[
31
:
0
]
csr_write_value
;
wire
[
31
:
0
]
exception_address
,
exception_vector
;
rv_csr
csr_regs
urv_csr
csr_regs
(
.
clk_i
(
clk_i
)
,
...
...
@@ -174,7 +171,7 @@ module rv_exec
.
csr_mcause_i
(
csr_mcause
)
)
;
rv_exceptions
exception_unit
u
rv_exceptions
exception_unit
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
...
...
@@ -226,6 +223,7 @@ module rv_exec
always
@*
dm_addr
<=
d_imm_i
+
(
(
d_opcode_i
==
`OPC_JALR
||
d_opcode_i
==
`OPC_LOAD
||
d_opcode_i
==
`OPC_STORE
)
?
rs1
:
d_pc_i
)
;
// calculate branch target address
always
@*
if
(
d_is_eret_i
)
branch_target
<=
exception_address
;
...
...
@@ -241,9 +239,10 @@ module rv_exec
alu_op2
<=
d_use_op2_i
?
d_alu_op2_i
:
rs2
;
end
// ALU adder/subtractor
wire
[
32
:
0
]
alu_addsub_op1
=
{
d_is_signed_alu_op_i
?
alu_op1
[
31
]
:
1'b0
,
alu_op1
};
wire
[
32
:
0
]
alu_addsub_op2
=
{
d_is_signed_alu_op_i
?
alu_op2
[
31
]
:
1'b0
,
alu_op2
};
reg
[
32
:
0
]
alu_addsub_result
;
always
@*
...
...
@@ -253,7 +252,7 @@ module rv_exec
alu_addsub_result
<=
alu_addsub_op1
-
alu_addsub_op2
;
// the
ALU itself
// the
rest of the ALU
always
@*
begin
case
(
d_fun_i
)
...
...
@@ -273,8 +272,8 @@ module rv_exec
endcase
// case (d_fun_i)
end
// always@ *
rv_shifter
shifter
// barel shifter
u
rv_shifter
shifter
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
...
...
@@ -292,7 +291,7 @@ module rv_exec
wire
divider_stall_req
=
0
;
rv_multiply
multiplier
u
rv_multiply
multiplier
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
...
...
@@ -307,7 +306,7 @@ module rv_exec
/* wire divider_stall_req;
wire [31:0] rd_divide;
rv_divide divider
u
rv_divide divider
(
.clk_i(clk_i),
.rst_i(rst_i),
...
...
@@ -415,11 +414,11 @@ module rv_exec
assign
dm_data_s_o
=
dm_data_s
;
assign
dm_data_select_o
=
dm_select_s
;
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
;
// X/W pipeline registers
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
f_branch_take
<=
0
;
...
...
@@ -432,11 +431,13 @@ module rv_exec
f_branch_take
<=
branch_take
&&
!
x_kill_i
&&
d_valid_i
;
w_rd_o
<=
d_rd_i
;
w_rd_value_o
<=
rd_value
;
w_rd_write_o
<=
d_rd_write_i
&&
!
x_kill_i
&&
d_valid_i
&&
!
exception
;
w_rd_source_o
<=
d_rd_source_i
;
w_fun_o
<=
d_fun_i
;
w_load_o
<=
d_is_load_i
&&
!
x_kill_i
&&
d_valid_i
&&
!
exception
;
w_store_o
<=
d_is_store_i
&&
!
x_kill_i
&&
d_valid_i
&&
!
exception
;
w_rd_source_o
<=
d_rd_source_i
;
w_fun_o
<=
d_fun_i
;
w_dm_addr_o
<=
dm_addr
;
w_valid_o
<=
!
exception
;
end
// else: !if(rst_i)
...
...
@@ -444,18 +445,22 @@ module rv_exec
assign
f_branch_take_o
=
f_branch_take
;
// pipeline control: generate stall request signal
always
@*
// never stall on taken branch
if
(
f_branch_take
)
x_stall_req_o
<=
0
;
else
if
(
divider_stall_req
)
x_stall_req_o
<=
1
;
// stall if memory request pending, but memory not ready
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
;
endmodule
endmodule
// urv_exec
...
...
rtl/rv_fetch.v
→
rtl/
u
rv_fetch.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -20,24 +21,23 @@
`timescale
1
ns
/
1
ps
module
rv_fetch
module
u
rv_fetch
(
input
clk_i
,
input
rst_i
,
input
f_stall_i
,
input
f_kill_i
,
output
[
31
:
0
]
im_addr_o
,
input
[
31
:
0
]
im_data_i
,
input
im_valid_i
,
input
f_stall_i
,
input
f_kill_i
,
output
reg
f_valid_o
,
output
[
31
:
0
]
f_ir_o
,
output
reg
[
31
:
0
]
f_pc_o
,
output
reg
[
31
:
0
]
f_pc_plus_4_o
,
output
reg
f_valid_o
,
input
[
31
:
0
]
x_pc_bra_i
,
input
x_bra_i
)
;
...
...
@@ -93,7 +93,7 @@ module rv_fetch
end
end
// else: !if(rst_i)
endmodule
// urv_fetch
endmodule
rtl/urv_iram.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
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.
*/
`timescale
1
ns
/
1
ps
`include
"urv_defs.v"
`ifdef
URV_PLATFORM_SPARTAN6
module
urv_iram
#(
parameter
g_size
=
65536
,
...
...
@@ -92,7 +117,7 @@ module urv_iram
`RAM_INST
(
64
K_31
,
RAMB16_S1_S1
,
15
:
2
,
31
,
3
)
end
// if (g_size == 65536)
if
(
g_size
==
16384
)
begin
else
if
(
g_size
==
16384
)
begin
`RAM_INST
(
16
K_0
,
RAMB16_S4_S4
,
13
:
2
,
3
:
0
,
0
)
`RAM_INST
(
16
K_1
,
RAMB16_S4_S4
,
13
:
2
,
7
:
4
,
0
)
`RAM_INST
(
16
K_2
,
RAMB16_S4_S4
,
13
:
2
,
11
:
8
,
1
)
...
...
@@ -101,7 +126,10 @@ module urv_iram
`RAM_INST
(
16
K_5
,
RAMB16_S4_S4
,
13
:
2
,
23
:
20
,
2
)
`RAM_INST
(
16
K_6
,
RAMB16_S4_S4
,
13
:
2
,
27
:
24
,
3
)
`RAM_INST
(
16
K_7
,
RAMB16_S4_S4
,
13
:
2
,
31
:
28
,
3
)
end
end
else
begin
$
fatal
(
"Unsupported Spartan-6 IRAM size: %d"
,
g_size
)
;
end
// else: !if(g_size == 16384)
end
else
begin
// if (!g_simulation)
...
...
@@ -195,3 +223,82 @@ module urv_iram
endmodule
// urv_iram
`endif
// `ifdef URV_PLATFORM_SPARTAN6
`ifdef
URV_PLATFORM_GENERIC
module
urv_iram
#(
parameter
g_size
=
65536
,
parameter
g_init_file
=
""
,
parameter
g_simulation
=
0
)
(
input
clk_i
,
input
ena_i
,
input
wea_i
,
input
[
31
:
0
]
aa_i
,
input
[
3
:
0
]
bwea_i
,
input
[
31
:
0
]
da_i
,
output
[
31
:
0
]
qa_o
,
input
enb_i
,
input
web_i
,
input
[
31
:
0
]
ab_i
,
input
[
3
:
0
]
bweb_i
,
input
[
31
:
0
]
db_i
,
output
[
31
:
0
]
qb_o
)
;
genvar
i
;
reg
[
31
:
0
]
mem
[
0
:
g_size
/
4
-
1
]
;
reg
[
31
:
0
]
qa_int
,
qb_int
;
always
@
(
posedge
clk_i
)
begin
if
(
ena_i
)
begin
qa_int
<=
mem
[(
aa_i
/
4
)]
;
if
(
wea_i
&&
bwea_i
[
0
])
mem
[(
aa_i
/
4
)][
7
:
0
]
<=
da_i
[
7
:
0
]
;
if
(
wea_i
&&
bwea_i
[
1
])
mem
[(
aa_i
/
4
)][
15
:
8
]
<=
da_i
[
15
:
8
]
;
if
(
wea_i
&&
bwea_i
[
2
])
mem
[(
aa_i
/
4
)][
23
:
16
]
<=
da_i
[
23
:
16
]
;
if
(
wea_i
&&
bwea_i
[
3
])
mem
[(
aa_i
/
4
)][
31
:
24
]
<=
da_i
[
31
:
24
]
;
end
if
(
enb_i
)
begin
qb_int
<=
mem
[(
ab_i
/
4
)
%
g_size
]
;
if
(
web_i
&&
bweb_i
[
0
])
mem
[(
ab_i
/
4
)][
7
:
0
]
<=
db_i
[
7
:
0
]
;
if
(
web_i
&&
bweb_i
[
1
])
mem
[(
ab_i
/
4
)][
15
:
8
]
<=
db_i
[
15
:
8
]
;
if
(
web_i
&&
bweb_i
[
2
])
mem
[(
ab_i
/
4
)][
23
:
16
]
<=
db_i
[
23
:
16
]
;
if
(
web_i
&&
bweb_i
[
3
])
mem
[(
ab_i
/
4
)][
31
:
24
]
<=
db_i
[
31
:
24
]
;
end
end
// always@ (posedge clk_i)
assign
qa_o
=
qa_int
;
assign
qb_o
=
qb_int
;
// synthesis translate_on
end
// else: !if(!g_simulation)
`endif
rtl/rv_multiply.v
→
rtl/
u
rv_multiply.v
View file @
014209e9
`include
"rv_defs.v"
/*
`timescale
1
ns
/
1
ps
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
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.
*/
`
define
ARCH_VIRTEX6
`
include
"urv_defs.v"
`ifdef
ARCH_SPARTAN6
`timescale
1
ns
/
1
ps
`ifdef
URV_PLATFORM_SPARTAN6
module
rv_mult18x18
module
u
rv_mult18x18
(
input
clk_i
,
input
rst_i
,
...
...
@@ -33,7 +52,7 @@ module rv_mult18x18
.
OPMODEREG
(
0
)
,
.
PREG
(
0
)
,
.
RSTTYPE
(
"SYNC"
)
)
D1
(
)
D1
(
.
BCOUT
()
,
.
PCOUT
()
,
.
CARRYOUT
()
,
...
...
@@ -64,14 +83,14 @@ module rv_mult18x18
.
RSTM
(
rst_i
)
,
.
RSTOPMODE
(
1'b0
)
,
.
RSTP
(
1'b0
)
)
;
)
;
endmodule
// rv_mult18x18
`endif
// `i
// fdef ARCH_SPARTAN6
endmodule
// urv_mult18x18
`endif
// `ifdef PLATFORM_SPARTAN6
`ifdef
ARCH_VIRTEX6
module
rv_mult18x18
`ifdef
URV_PLATFORM_GENERIC
module
urv_mult18x18
(
input
clk_i
,
input
rst_i
,
...
...
@@ -89,12 +108,11 @@ module rv_mult18x18
if
(
!
stall_i
)
q_o
<=
x_i
*
y_i
;
endmodule
// rv_mult18x18
`endif
// `ifdef ARCH_VIRTEX6
endmodule
// urv_mult18x18
`endif
// `ifdef URV_PLATFORM_GENERIC
module
rv_multiply
module
u
rv_multiply
(
input
clk_i
,
input
rst_i
,
...
...
@@ -108,8 +126,6 @@ module rv_multiply
)
;
wire
[
17
:
0
]
xl_u
=
{
1'b0
,
d_rs1_i
[
16
:
0
]
};
wire
[
17
:
0
]
yl_u
=
{
1'b0
,
d_rs2_i
[
16
:
0
]
};
...
...
@@ -121,7 +137,7 @@ module rv_multiply
wire
[
35
:
0
]
yl_xl
,
yl_xh
,
yh_xl
;
rv_mult18x18
U_
mul0
urv_mult18x18
mul0
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
...
...
@@ -132,7 +148,7 @@ module rv_multiply
.
q_o
(
yl_xl
)
)
;
rv_mult18x18
U_
mul1
urv_mult18x18
mul1
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
...
...
@@ -143,7 +159,7 @@ module rv_multiply
.
q_o
(
yh_xl
)
)
;
rv_mult18x18
U_
mul2
urv_mult18x18
mul2
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
...
...
@@ -154,29 +170,12 @@ module rv_multiply
.
q_o
(
yl_xh
)
)
;
/* -----\/----- EXCLUDED -----\/-----
always@(posedge clk_i)
if(!x_stall_i)
begin
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
@*
w_rd_o
<=
yl_xl
+
{
yl_xh
[
14
:
0
]
,
17'h0
}
+
{
yh_xl
[
14
:
0
]
,
17'h0
};
endmodule
// urv_multiply
endmodule
// rv_multiply
rtl/rv_regfile.v
→
rtl/
u
rv_regfile.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,17 +19,16 @@
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_regmem
(
module
u
rv_regmem
(
input
clk_i
,
input
rst_i
,
input
en1_i
,
input
[
4
:
0
]
a1_i
,
output
reg
[
31
:
0
]
q1_o
,
...
...
@@ -38,12 +38,6 @@ module rv_regmem
)
;
reg
[
31
:
0
]
ram
[
0
:
31
]
;
reg
[
31
:
0
]
bypass_r
;
reg
bypass
;
reg
[
31
:
0
]
q1_int
;
always
@
(
posedge
clk_i
)
if
(
en1_i
)
...
...
@@ -53,20 +47,19 @@ module rv_regmem
if
(
we2_i
)
ram
[
a2_i
]
<=
d2_i
;
// synthesis translate_off
initial
begin
:
ram_init
// synthesis translate_off
initial
begin
:
ram_init
integer
i
;
for
(
i
=
0
;
i
<
32
;
i
=
i
+
1
)
begin
ram
[
i
]
=
0
;
end
end
// synthesis translate_on
endmodule
// rv_regmem2
end
// synthesis translate_on
endmodule
module
rv_regfile
module
u
rv_regfile
(
input
clk_i
,
input
rst_i
,
...
...
@@ -96,7 +89,8 @@ module rv_regfile
wire
[
31
:
0
]
rs2_regfile
;
wire
write
=
(
w_rd_store_i
&&
(
w_rd_i
!=
0
))
;
rv_regmem
bank0
(
urv_regmem
bank0
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
en1_i
(
!
d_stall_i
)
,
...
...
@@ -108,7 +102,8 @@ module rv_regfile
.
we2_i
(
write
))
;
rv_regmem
bank1
(
urv_regmem
bank1
(
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
en1_i
(
!
d_stall_i
)
,
...
...
@@ -162,129 +157,5 @@ module rv_regfile
endcase
// case ( {rs2_bypass_x, rs2_bypass_w } )
end
// always@ *
endmodule
// rv_regfile
module
rv_regmem_distram
(
input
clk_i
,
input
[
4
:
0
]
a1_i
,
output
[
31
:
0
]
q1_o
,
input
[
4
:
0
]
a2_i
,
input
[
31
:
0
]
d2_i
,
input
we2_i
)
;
reg
[
31
:
0
]
ram
[
0
:
31
]
;
assign
q1_o
=
ram
[
a1_i
]
;
always
@
(
posedge
clk_i
)
if
(
we2_i
)
ram
[
a2_i
]
<=
d2_i
;
// synthesis translate_off
initial
begin
:
ram_init
integer
i
;
for
(
i
=
0
;
i
<
32
;
i
=
i
+
1
)
begin
ram
[
i
]
=
0
;
end
end
// synthesis translate_on
endmodule
// rv_regmem2
module
rv_regfile_distram
(
input
clk_i
,
input
rst_i
,
input
d_stall_i
,
input
[
4
:
0
]
rf_rs1_i
,
input
[
4
:
0
]
rf_rs2_i
,
input
[
4
:
0
]
d_rs1_i
,
input
[
4
:
0
]
d_rs2_i
,
output
reg
[
31
:
0
]
x_rs1_value_o
,
output
reg
[
31
:
0
]
x_rs2_value_o
,
input
[
4
:
0
]
w_rd_i
,
input
[
31
:
0
]
w_rd_value_i
,
input
w_rd_store_i
,
input
w_bypass_rd_write_i
,
input
[
31
:
0
]
w_bypass_rd_value_i
)
;
wire
[
31
:
0
]
rs1_regfile
;
wire
[
31
:
0
]
rs2_regfile
;
wire
write
=
(
w_rd_store_i
&&
(
w_rd_i
!=
0
))
;
rv_regmem_distram
bank0
(
.
clk_i
(
clk_i
)
,
.
a1_i
(
rf_rs1_i
)
,
.
q1_o
(
rs1_regfile
)
,
.
a2_i
(
w_rd_i
)
,
.
d2_i
(
w_rd_value_i
)
,
.
we2_i
(
write
))
;
rv_regmem_distram
bank1
(
.
clk_i
(
clk_i
)
,
.
a1_i
(
rf_rs2_i
)
,
.
q1_o
(
rs2_regfile
)
,
.
a2_i
(
w_rd_i
)
,
.
d2_i
(
w_rd_value_i
)
,
.
we2_i
(
write
)
)
;
wire
rs1_bypass_x
=
w_bypass_rd_write_i
&&
(
w_rd_i
==
d_rs1_i
)
&&
(
w_rd_i
!=
0
)
;
wire
rs2_bypass_x
=
w_bypass_rd_write_i
&&
(
w_rd_i
==
d_rs2_i
)
&&
(
w_rd_i
!=
0
)
;
reg
rs1_bypass_w
,
rs2_bypass_w
;
always
@*
begin
rs1_bypass_w
<=
write
&&
(
rf_rs1_i
==
w_rd_i
)
;
rs2_bypass_w
<=
write
&&
(
rf_rs2_i
==
w_rd_i
)
;
end
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
begin
case
(
{
rs1_bypass_x
,
rs1_bypass_w
}
)
// synthesis parallel_case full_case
2'b10
,
2'b11
:
x_rs1_value_o
<=
w_bypass_rd_value_i
;
2'b01
:
x_rs1_value_o
<=
w_rd_value_i
;
default:
x_rs1_value_o
<=
rs1_regfile
;
endcase
// case ( {rs1_bypass_x, rs1_bypass_w } )
case
(
{
rs2_bypass_x
,
rs2_bypass_w
}
)
// synthesis parallel_case full_case
2'b10
,
2'b11
:
x_rs2_value_o
<=
w_bypass_rd_value_i
;
2'b01
:
x_rs2_value_o
<=
w_rd_value_i
;
default:
x_rs2_value_o
<=
rs2_regfile
;
endcase
// case ( {rs2_bypass_x, rs2_bypass_w } )
end
// always@ *
endmodule
// rv_regfile
endmodule
// urv_regfile
rtl/rv_shifter.v
→
rtl/
u
rv_shifter.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,7 +19,7 @@
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
...
...
@@ -28,7 +29,7 @@
x
[
16
],
x
[
17
],
x
[
18
],
x
[
19
],
x
[
20
],
x
[
21
],
x
[
22
],
x
[
23
],
\
x
[
24
],
x
[
25
],
x
[
26
],
x
[
27
],
x
[
28
],
x
[
29
],
x
[
30
],
x
[
31
]
}
module
rv_shifter
module
u
rv_shifter
(
input
clk_i
,
input
rst_i
,
...
...
@@ -37,16 +38,16 @@ module rv_shifter
input
d_valid_i
,
input
[
31
:
0
]
d_rs1_i
,
output
reg
[
31
:
0
]
w_rd_o
,
output
reg
[
31
:
0
]
w_rd_o
,
input
[
4
:
0
]
d_shamt_i
,
input
[
2
:
0
]
d_fun_i
,
input
d_shifter_sign_i
,
input
d_is_shift_i
)
;
input
d_is_shift_i
)
;
wire
extend_sign
=
((
d_fun_i
==
`FUNC_SR
)
&&
d_shifter_sign_i
)
?
d_rs1_i
[
31
]
:
1'b0
;
reg
[
31
:
0
]
shift_pre
,
shift_16
,
shift_8
,
s1_out
;
// stage 1
...
...
@@ -73,16 +74,6 @@ module rv_shifter
s1_out
<=
shift_8
;
end
/* -----\/----- EXCLUDED -----\/-----
always@*
begin
s2_extend_sign <= extend_sign;
s2_shift <= d_shamt_i;
s2_func <= d_fun_i;
s1_out <= shift_8;
end
-----/\----- EXCLUDED -----/\----- */
reg
[
31
:
0
]
shift_4
,
shift_2
,
shift_1
,
shift_post
;
// stage 2
...
...
@@ -94,109 +85,8 @@ module rv_shifter
shift_post
<=
(
s2_func
==
`FUNC_SL
)
?
`reverse_bits
(
shift_1
)
:
shift_1
;
end
/* -----\/----- EXCLUDED -----\/-----
always@(posedge clk_i)
if(!x_stall_i)
w_rd_o <= shift_post;
-----/\----- EXCLUDED -----/\----- */
always
@*
w_rd_o
<=
shift_post
;
endmodule
// rv_shifter
module
rv_shifter2
(
input
clk_i
,
input
rst_i
,
input
x_stall_i
,
input
w_stall_req_i
,
output
x_stall_req_o
,
input
d_valid_i
,
input
[
31
:
0
]
d_rs1_i
,
output
[
31
:
0
]
x_rd_o
,
input
[
4
:
0
]
d_shamt_i
,
input
[
2
:
0
]
d_fun_i
,
input
d_shifter_sign_i
,
input
d_is_shift_i
)
;
wire
extend_sign
=
((
d_fun_i
==
`FUNC_SR
)
&&
d_shifter_sign_i
)
?
d_rs1_i
[
31
]
:
1'b0
;
wire
shifter_req
=
!
w_stall_req_i
&&
d_valid_i
&&
d_is_shift_i
;
reg
shifter_req_d0
;
always
@
(
posedge
clk_i
)
if
(
shifter_req_d0
&&
!
x_stall_i
)
shifter_req_d0
<=
0
;
else
shifter_req_d0
<=
shifter_req
;
assign
x_stall_req_o
=
shifter_req
&&
!
shifter_req_d0
;
reg
[
31
:
0
]
shift_pre
,
shift_16
,
shift_8
,
s1_out
;
reg
[
31
:
0
]
s2_mask
;
// stage 1
always
@*
begin
shift_16
<=
d_shamt_i
[
4
]
?
{
d_rs1_i
[
15
:
0
]
,
d_rs1_i
[
31
:
16
]
}
:
d_rs1_i
;
shift_8
<=
d_shamt_i
[
3
]
?
{
shift_16
[
7
:
0
]
,
shift_16
[
31
:
8
]
}
:
shift_16
;
end
reg
[
4
:
0
]
s2_shift
;
reg
[
2
:
0
]
s2_func
;
reg
s2_extend_sign
;
// stage 1 pipe register
always
@
(
posedge
clk_i
)
begin
:
stage1
integer
i
;
for
(
i
=
0
;
i
<
32
;
i
=
i
+
1
)
begin
if
(
d_fun_i
==
`FUNC_SL
)
s2_mask
[
i
]
<=
(
d_shamt_i
<
i
)
?
1'b1
:
1'b0
;
else
s2_mask
[
i
]
<=
(
d_shamt_i
<
(
31
-
i
))
?
1'b1
:
1'b0
;
end
s2_extend_sign
<=
extend_sign
;
s2_shift
<=
d_shamt_i
;
s2_func
<=
d_fun_i
;
s1_out
<=
shift_8
;
end
reg
[
31
:
0
]
shift_4
,
shift_2
,
shift_1
,
shift_post
;
// stage 2
always
@*
begin
:
stage2
integer
i
;
shift_4
<=
s2_shift
[
2
]
?
{
s1_out
[
3
:
0
]
,
s1_out
[
31
:
4
]
}
:
s1_out
;
shift_2
<=
s2_shift
[
1
]
?
{
s1_out
[
1
:
0
]
,
shift_4
[
31
:
2
]
}
:
shift_4
;
shift_1
<=
s2_shift
[
0
]
?
{
s1_out
[
0
]
,
shift_2
[
31
:
1
]
}
:
shift_2
;
for
(
i
=
0
;
i
<
32
;
i
=
i
+
1
)
begin
if
(
s2_extend_sign
)
shift_post
<=
s2_mask
[
i
]
?
1'b1
:
shift_1
[
i
]
;
else
shift_post
<=
s2_mask
[
i
]
?
1'b0
:
shift_1
[
i
]
;
end
end
assign
x_rd_o
=
shift_post
;
endmodule
// rv_shifter
endmodule
// urv_shifter
rtl/rv_timer.v
→
rtl/
u
rv_timer.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,11 +19,11 @@
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_timer
module
u
rv_timer
(
input
clk_i
,
input
rst_i
,
...
...
@@ -76,4 +77,4 @@ module rv_timer
assign
csr_cycles_o
=
cycles
;
assign
sys_tick_o
=
presc_tick
;
endmodule
// rv_timer
endmodule
//
u
rv_timer
rtl/rv_writeback.v
→
rtl/
u
rv_writeback.v
View file @
014209e9
/*
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
...
...
@@ -18,17 +19,16 @@
*/
`include
"rv_defs.v"
`include
"
u
rv_defs.v"
`timescale
1
ns
/
1
ps
module
rv_writeback
module
u
rv_writeback
(
input
clk_i
,
input
rst_i
,
input
w_stall_i
,
output
w_stall_req_o
,
input
[
2
:
0
]
x_fun_i
,
...
...
@@ -54,17 +54,11 @@ module rv_writeback
output
[
31
:
0
]
rf_rd_value_o
,
output
[
4
:
0
]
rf_rd_o
,
output
rf_rd_write_o
,
output
[
31
:
0
]
TRIG2
output
rf_rd_write_o
)
;
reg
[
31
:
0
]
load_value
;
// generate load value
always
@*
begin
...
...
@@ -110,7 +104,6 @@ module rv_writeback
reg
rf_rd_write
;
reg
[
31
:
0
]
rf_rd_value
;
always
@*
if
(
x_load_i
)
rf_rd_value
<=
load_value
;
...
...
@@ -139,10 +132,4 @@ module rv_writeback
assign
rf_rd_o
=
x_rd_i
;
assign
w_stall_req_o
=
x_valid_i
&&
((
x_load_i
&&
!
dm_load_done_i
)
||
(
x_store_i
&&
!
dm_store_done_i
))
;
assign
TRIG2
[
6
]
=
x_load_i
;
assign
TRIG2
[
8
]
=
dm_load_done_i
;
assign
TRIG2
[
9
]
=
x_store_i
;
assign
TRIG2
[
11
]
=
dm_store_done_i
;
assign
TRIG2
[
15
]
=
w_stall_req_o
;
endmodule
// rv_writeback
endmodule
// urv_writeback
rtl/xrv_core.vhd
→
rtl/x
u
rv_core.vhd
View file @
014209e9
...
...
@@ -24,7 +24,7 @@ use ieee.numeric_std.all;
use
work
.
wishbone_pkg
.
all
;
use
work
.
genram_pkg
.
all
;
entity
xrv_core
is
entity
x
u
rv_core
is
generic
(
g_internal_ram_size
:
integer
:
=
65536
;
g_internal_ram_init_file
:
string
:
=
""
;
...
...
@@ -47,13 +47,13 @@ entity xrv_core is
host_slave_i
:
in
t_wishbone_slave_in
:
=
cc_dummy_slave_in
;
host_slave_o
:
out
t_wishbone_slave_out
);
end
xrv_core
;
end
x
u
rv_core
;
architecture
wrapper
of
xrv_core
is
architecture
wrapper
of
x
u
rv_core
is
constant
c_mem_address_bits
:
integer
:
=
f_ceil_log2
(
g_internal_ram_size
/
4
);
component
rv_cpu
is
component
u
rv_cpu
is
port
(
clk_i
:
in
std_logic
;
rst_i
:
in
std_logic
;
...
...
@@ -90,13 +90,13 @@ architecture wrapper of xrv_core is
aa_i
:
in
std_logic_vector
(
31
downto
0
);
bwea_i
:
in
std_logic_vector
(
3
downto
0
);
da_i
:
in
std_logic_vector
(
31
downto
0
);
qa_o
:
out
std_logic_vector
(
31
downto
0
);
qa_o
:
out
std_logic_vector
(
31
downto
0
);
enb_i
:
in
std_logic
;
web_i
:
in
std_logic
;
ab_i
:
in
std_logic_vector
(
31
downto
0
);
bweb_i
:
in
std_logic_vector
(
3
downto
0
);
db_i
:
in
std_logic_vector
(
31
downto
0
);
qb_o
:
out
std_logic_vector
(
31
downto
0
)
qb_o
:
out
std_logic_vector
(
31
downto
0
)
);
end
component
;
...
...
@@ -232,7 +232,7 @@ begin
im_addr_muxed
<=
ha_im_addr
when
ha_im_access
=
'1'
else
im_addr
(
g_address_bits
-1
downto
0
);
dm_ready
<=
'1'
;
cpu_core
:
rv_cpu
cpu_core
:
u
rv_cpu
port
map
(
clk_i
=>
clk_sys_i
,
rst_i
=>
cpu_rst
,
...
...
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