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
8efd2565
Commit
8efd2565
authored
Mar 07, 2018
by
Tristan Gingold
Committed by
Dimitris Lampridis
Mar 19, 2018
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
Remove trailing spaces.
parent
82b33448
Hide whitespace changes
Inline
Side-by-side
Showing
16 changed files
with
351 additions
and
388 deletions
+351
-388
urv_csr.v
rtl/urv_csr.v
+22
-29
urv_debug.v
rtl/urv_debug.v
+36
-38
urv_decode.v
rtl/urv_decode.v
+32
-35
urv_defs.v
rtl/urv_defs.v
+4
-4
urv_divide.v
rtl/urv_divide.v
+18
-19
urv_exceptions.v
rtl/urv_exceptions.v
+23
-26
urv_exec.v
rtl/urv_exec.v
+61
-68
urv_fetch.v
rtl/urv_fetch.v
+15
-18
urv_iram.v
rtl/urv_iram.v
+48
-50
urv_multiply.v
rtl/urv_multiply.v
+14
-19
urv_regfile.v
rtl/urv_regfile.v
+12
-13
urv_shifter.v
rtl/urv_shifter.v
+7
-8
urv_timer.v
rtl/urv_timer.v
+9
-9
urv_writeback.v
rtl/urv_writeback.v
+9
-9
xurv_core.vhd
rtl/xurv_core.vhd
+9
-11
main.sv
tb/isa-testsuite/main.sv
+32
-32
No files found.
rtl/urv_csr.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -30,17 +30,17 @@ module urv_csr
...
@@ -30,17 +30,17 @@ module urv_csr
input
x_stall_i
,
input
x_stall_i
,
input
x_kill_i
,
input
x_kill_i
,
input
d_is_csr_i
,
input
d_is_csr_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_rs1_i
,
output
reg
[
31
:
0
]
x_rd_o
,
output
reg
[
31
:
0
]
x_rd_o
,
input
[
39
:
0
]
csr_time_i
,
input
[
39
:
0
]
csr_time_i
,
input
[
39
:
0
]
csr_cycles_i
,
input
[
39
:
0
]
csr_cycles_i
,
...
@@ -55,14 +55,14 @@ module urv_csr
...
@@ -55,14 +55,14 @@ module urv_csr
input
[
31
:
0
]
csr_mcause_i
input
[
31
:
0
]
csr_mcause_i
)
;
)
;
reg
[
31
:
0
]
csr_mscratch
;
reg
[
31
:
0
]
csr_mscratch
;
reg
[
31
:
0
]
csr_in1
;
reg
[
31
:
0
]
csr_in1
;
reg
[
31
:
0
]
csr_in2
;
reg
[
31
:
0
]
csr_in2
;
reg
[
31
:
0
]
csr_out
;
reg
[
31
:
0
]
csr_out
;
always
@*
always
@*
case
(
d_csr_sel_i
)
// synthesis full_case parallel_case
case
(
d_csr_sel_i
)
// synthesis full_case parallel_case
`CSR_ID_CYCLESL
:
csr_in1
<=
csr_cycles_i
[
31
:
0
]
;
`CSR_ID_CYCLESL
:
csr_in1
<=
csr_cycles_i
[
31
:
0
]
;
...
@@ -83,7 +83,7 @@ module urv_csr
...
@@ -83,7 +83,7 @@ module urv_csr
genvar
i
;
genvar
i
;
always
@*
always
@*
case
(
d_fun_i
)
case
(
d_fun_i
)
`CSR_OP_CSRRWI
,
`CSR_OP_CSRRWI
,
...
@@ -96,13 +96,13 @@ module urv_csr
...
@@ -96,13 +96,13 @@ module urv_csr
generate
generate
for
(
i
=
0
;
i
<
32
;
i
=
i
+
1
)
for
(
i
=
0
;
i
<
32
;
i
=
i
+
1
)
begin
:
gen_csr_bits
begin
:
gen_csr_bits
always
@*
always
@*
case
(
d_fun_i
)
// synthesis full_case parallel_case
case
(
d_fun_i
)
// synthesis full_case parallel_case
`CSR_OP_CSRRWI
,
`CSR_OP_CSRRWI
,
`CSR_OP_CSRRW
:
`CSR_OP_CSRRW
:
csr_out
[
i
]
<=
csr_in2
[
i
]
;
csr_out
[
i
]
<=
csr_in2
[
i
]
;
`CSR_OP_CSRRCI
,
`CSR_OP_CSRRCI
,
...
@@ -115,28 +115,21 @@ module urv_csr
...
@@ -115,28 +115,21 @@ module urv_csr
csr_out
[
i
]
<=
32
'
hx
;
csr_out
[
i
]
<=
32
'
hx
;
endcase
// case (d_csr_op_i)
endcase
// case (d_csr_op_i)
end
// for (i=0;i<32;i=i+1)
end
// for (i=0;i<32;i=i+1)
endgenerate
endgenerate
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
if
(
rst_i
)
csr_mscratch
<=
0
;
csr_mscratch
<=
0
;
else
if
(
!
x_stall_i
&&
!
x_kill_i
&&
d_is_csr_i
)
else
if
(
!
x_stall_i
&&
!
x_kill_i
&&
d_is_csr_i
)
case
(
d_csr_sel_i
)
case
(
d_csr_sel_i
)
`CSR_ID_MSCRATCH
:
`CSR_ID_MSCRATCH
:
csr_mscratch
<=
csr_out
;
csr_mscratch
<=
csr_out
;
endcase
// case (d_csr_sel_i)
endcase
// case (d_csr_sel_i)
assign
x_csr_write_value_o
=
csr_out
;
assign
x_csr_write_value_o
=
csr_out
;
endmodule
endmodule
rtl/urv_debug.v
View file @
8efd2565
...
@@ -17,7 +17,7 @@ module urv_debug
...
@@ -17,7 +17,7 @@ module urv_debug
input
x_valid_i
,
input
x_valid_i
,
input
[
31
:
0
]
x_pc_i
,
input
[
31
:
0
]
x_pc_i
,
input
x_dm_load_i
,
input
x_dm_load_i
,
input
x_dm_store_i
,
input
x_dm_store_i
,
input
[
31
:
0
]
x_dm_addr_i
,
input
[
31
:
0
]
x_dm_addr_i
,
...
@@ -46,7 +46,7 @@ module urv_debug
...
@@ -46,7 +46,7 @@ module urv_debug
output
[
31
:
0
]
f_pc_restore_o
,
output
[
31
:
0
]
f_pc_restore_o
,
output
f_pc_restore_load_o
,
output
f_pc_restore_load_o
,
input
[
6
:
0
]
dbg_adr_i
,
input
[
6
:
0
]
dbg_adr_i
,
input
[
7
:
0
]
dbg_dat_i
,
input
[
7
:
0
]
dbg_dat_i
,
input
dbg_stb_i
,
input
dbg_stb_i
,
...
@@ -62,22 +62,22 @@ module urv_debug
...
@@ -62,22 +62,22 @@ module urv_debug
`define
BREAK_SRC_MEM_ST_DATA 2
`define
BREAK_SRC_MEM_ST_DATA 2
`define
BREAK_SRC_MEM_LD_DATA 3
`define
BREAK_SRC_MEM_LD_DATA 3
reg
[
31
:
0
]
break_compare_hi
[
0
:
g_num_breakpoints
-
1
]
;
reg
[
31
:
0
]
break_compare_hi
[
0
:
g_num_breakpoints
-
1
]
;
reg
[
31
:
0
]
break_compare_lo
[
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
[
1
:
0
]
break_src
[
0
:
g_num_breakpoints
-
1
]
;
reg
break_valid
[
0
:
g_num_breakpoints
-
1
]
;
reg
break_valid
[
0
:
g_num_breakpoints
-
1
]
;
reg
[
31
:
0
]
in_muxed
[
0
:
g_num_breakpoints
-
1
]
;
reg
[
31
:
0
]
in_muxed
[
0
:
g_num_breakpoints
-
1
]
;
reg
in_valid
[
0
:
g_num_breakpoints
-
1
]
;
reg
in_valid
[
0
:
g_num_breakpoints
-
1
]
;
reg
break_hit
[
0
:
g_num_breakpoints
-
1
]
;
reg
break_hit
[
0
:
g_num_breakpoints
-
1
]
;
`define
ST_IDLE 0
`define
ST_IDLE 0
generate
generate
genvar
gg
;
genvar
gg
;
for
(
gg
=
0
;
gg
<
g_num_breakpoints
;
gg
=
gg
+
1
)
for
(
gg
=
0
;
gg
<
g_num_breakpoints
;
gg
=
gg
+
1
)
begin
begin
always
@*
always
@*
...
@@ -90,30 +90,30 @@ module urv_debug
...
@@ -90,30 +90,30 @@ module urv_debug
endcase
// case (break_src[gg])
endcase
// case (break_src[gg])
case
(
break_src
[
gg
])
case
(
break_src
[
gg
])
`BREAK_SRC_PC
:
`BREAK_SRC_PC
:
begin
begin
in_muxed
[
gg
]
<=
x_pc_i
;
in_muxed
[
gg
]
<=
x_pc_i
;
in_valid
[
gg
]
<=
x_valid_i
;
in_valid
[
gg
]
<=
x_valid_i
;
end
end
`BREAK_SRC_MEM_ADDR
:
`BREAK_SRC_MEM_ADDR
:
begin
begin
in_muxed
[
gg
]
<=
x_dm_addr_i
;
in_muxed
[
gg
]
<=
x_dm_addr_i
;
in_valid
[
gg
]
<=
x_dm_load_i
||
x_dm_store_i
;
in_valid
[
gg
]
<=
x_dm_load_i
||
x_dm_store_i
;
end
end
`BREAK_SRC_MEM_ST_DATA
:
`BREAK_SRC_MEM_ST_DATA
:
begin
begin
in_muxed
[
gg
]
<=
x_dm_data_s_i
;
in_muxed
[
gg
]
<=
x_dm_data_s_i
;
in_valid
[
gg
]
<=
x_dm_store_i
;
in_valid
[
gg
]
<=
x_dm_store_i
;
end
end
`BREAK_SRC_MEM_LD_DATA
:
`BREAK_SRC_MEM_LD_DATA
:
begin
begin
in_muxed
[
gg
]
<=
dm_data_l_i
;
in_muxed
[
gg
]
<=
dm_data_l_i
;
in_valid
[
gg
]
<=
dm_load_done_i
;
in_valid
[
gg
]
<=
dm_load_done_i
;
end
end
endcase
// case (break_src[gg])
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
;
break_hit
[
gg
]
<=
(
in_muxed
[
gg
]
>=
break_comp1
[
gg
]
&&
in_muxed
[
gg
]
<=
break_comp
[
gg
]
)
?
in_valid
[
gg
]
:
1'b0
;
...
@@ -125,14 +125,14 @@ module urv_debug
...
@@ -125,14 +125,14 @@ module urv_debug
reg
trigger_reload_pc
;
reg
trigger_reload_pc
;
reg
trigger_halt
;
reg
trigger_halt
;
reg
trigger_resume
;
reg
trigger_resume
;
reg
[
31
:
0
]
reload_pc_value
;
reg
[
31
:
0
]
reload_pc_value
;
`define
DBG_REG_PC0 0
`define
DBG_REG_PC0 0
`define
DBG_REG_PC1 1
`define
DBG_REG_PC1 1
`define
DBG_REG_PC2 2
`define
DBG_REG_PC2 2
`define
DBG_REG_PC3 3
`define
DBG_REG_PC3 3
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
if
(
rst_i
)
begin
...
@@ -142,25 +142,25 @@ module urv_debug
...
@@ -142,25 +142,25 @@ module urv_debug
trigger_halt
<=
0
;
trigger_halt
<=
0
;
trigger_resume
<=
0
;
trigger_resume
<=
0
;
trigger_reload_pc
<=
0
;
trigger_reload_pc
<=
0
;
if
(
dbg_we_i
)
begin
if
(
dbg_we_i
)
begin
case
(
dbg_adr_i
)
case
(
dbg_adr_i
)
`DBG_REG_PCO
:
reload_pc_value
[
7
:
0
]
<=
dbg_dat_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_PC1
:
reload_pc_value
[
15
:
8
]
<=
dbg_dat_i
;
`DBG_REG_PC2
:
reload_pc_value
[
23
:
16
]
<=
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_REG_PC3
:
reload_pc_value
[
31
:
24
]
<=
dbg_dat_i
;
`DBG_CTL
:
`DBG_CTL
:
begin
begin
trigger_halt
<=
dbg_dat_i
[
0
]
;
trigger_halt
<=
dbg_dat_i
[
0
]
;
trigger_resume
<=
dbg_dat_i
[
1
]
;
trigger_resume
<=
dbg_dat_i
[
1
]
;
trigger_reload_pc
<=
dbg_dat_i
[
2
]
;
trigger_reload_pc
<=
dbg_dat_i
[
2
]
;
end
end
endcase
// case (dbg_adr_i)
endcase
// case (dbg_adr_i)
end
else
begin
// if ( dbg_we_i )
end
else
begin
// if ( dbg_we_i )
case
(
dbg_adr_i
)
case
(
dbg_adr_i
)
...
@@ -169,23 +169,21 @@ module urv_debug
...
@@ -169,23 +169,21 @@ module urv_debug
`DBG_REG_PC2
:
dbg_dat_o
<=
x_pc_i
[
23
:
16
]
;
`DBG_REG_PC2
:
dbg_dat_o
<=
x_pc_i
[
23
:
16
]
;
`DBG_REG_PC3
:
dbg_dat_o
<=
x_pc_i
[
31
:
24
]
;
`DBG_REG_PC3
:
dbg_dat_o
<=
x_pc_i
[
31
:
24
]
;
end
// else: !if( dbg_we_i )
end
// else: !if( dbg_we_i )
end
// else: !if( dbg_we_i )
end
// else: !if( dbg_we_i )
end
end
end
end
rtl/urv_decode.v
View file @
8efd2565
...
@@ -16,14 +16,14 @@
...
@@ -16,14 +16,14 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
`timescale
1
ns
/
1
ps
`timescale
1
ns
/
1
ps
module
urv_decode
module
urv_decode
(
(
input
clk_i
,
input
clk_i
,
input
rst_i
,
input
rst_i
,
...
@@ -79,7 +79,7 @@ module urv_decode
...
@@ -79,7 +79,7 @@ module urv_decode
wire
[
4
:
0
]
d_opcode
=
f_ir_i
[
6
:
2
]
;
wire
[
4
:
0
]
d_opcode
=
f_ir_i
[
6
:
2
]
;
wire
[
2
:
0
]
d_fun
=
f_ir_i
[
14
:
12
]
;
wire
[
2
:
0
]
d_fun
=
f_ir_i
[
14
:
12
]
;
reg
[
4
:
0
]
x_rs1
;
reg
[
4
:
0
]
x_rs1
;
reg
[
4
:
0
]
x_rs2
;
reg
[
4
:
0
]
x_rs2
;
reg
[
4
:
0
]
x_rd
;
reg
[
4
:
0
]
x_rd
;
...
@@ -87,8 +87,8 @@ module urv_decode
...
@@ -87,8 +87,8 @@ module urv_decode
reg
x_valid
;
reg
x_valid
;
reg
x_is_shift
;
reg
x_is_shift
;
reg
x_rd_write
;
reg
x_rd_write
;
assign
x_rs1_o
=
x_rs1
;
assign
x_rs1_o
=
x_rs1
;
assign
x_rs2_o
=
x_rs2
;
assign
x_rs2_o
=
x_rs2
;
assign
x_rd_o
=
x_rd
;
assign
x_rd_o
=
x_rd
;
...
@@ -124,7 +124,7 @@ module urv_decode
...
@@ -124,7 +124,7 @@ module urv_decode
endcase
// case (x_opcode)
endcase
// case (x_opcode)
end
else
end
else
load_hazard
<=
0
;
load_hazard
<=
0
;
reg
inserting_nop
;
reg
inserting_nop
;
// bubble insertion following a hazzard
// bubble insertion following a hazzard
...
@@ -141,9 +141,9 @@ module urv_decode
...
@@ -141,9 +141,9 @@ module urv_decode
assign
d_stall_req_o
=
load_hazard
&&
!
inserting_nop
;
assign
d_stall_req_o
=
load_hazard
&&
!
inserting_nop
;
assign
x_valid_o
=
x_valid
;
assign
x_valid_o
=
x_valid
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
||
d_kill_i
)
if
(
rst_i
||
d_kill_i
)
begin
begin
...
@@ -161,10 +161,10 @@ module urv_decode
...
@@ -161,10 +161,10 @@ module urv_decode
x_rs2
<=
f_rs2
;
x_rs2
<=
f_rs2
;
x_rd
<=
f_rd
;
x_rd
<=
f_rd
;
x_opcode
<=
d_opcode
;
x_opcode
<=
d_opcode
;
x_shamt_o
<=
f_ir_i
[
24
:
20
]
;
x_shamt_o
<=
f_ir_i
[
24
:
20
]
;
end
end
// ALU function decoding
// ALU function decoding
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
if
(
!
d_stall_i
)
...
@@ -174,7 +174,7 @@ module urv_decode
...
@@ -174,7 +174,7 @@ module urv_decode
default:
default:
x_fun_o
<=
d_fun
;
x_fun_o
<=
d_fun
;
endcase
// case (f_opcode)
endcase
// case (f_opcode)
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
if
(
!
d_stall_i
)
x_shifter_sign_o
<=
f_ir_i
[
30
]
;
x_shifter_sign_o
<=
f_ir_i
[
30
]
;
...
@@ -183,13 +183,13 @@ module urv_decode
...
@@ -183,13 +183,13 @@ module urv_decode
wire
[
31
:
0
]
d_imm_s
=
{
{
21
{
f_ir_i
[
31
]
}},
f_ir_i
[
30
:
25
]
,
f_ir_i
[
11
:
8
]
,
f_ir_i
[
7
]
};
wire
[
31
:
0
]
d_imm_s
=
{
{
21
{
f_ir_i
[
31
]
}},
f_ir_i
[
30
:
25
]
,
f_ir_i
[
11
:
8
]
,
f_ir_i
[
7
]
};
wire
[
31
:
0
]
d_imm_b
=
{
{
20
{
f_ir_i
[
31
]
}},
f_ir_i
[
7
]
,
f_ir_i
[
30
:
25
]
,
f_ir_i
[
11
:
8
]
,
1'b0
};
wire
[
31
:
0
]
d_imm_b
=
{
{
20
{
f_ir_i
[
31
]
}},
f_ir_i
[
7
]
,
f_ir_i
[
30
:
25
]
,
f_ir_i
[
11
:
8
]
,
1'b0
};
wire
[
31
:
0
]
d_imm_u
=
{
f_ir_i
[
31
]
,
f_ir_i
[
30
:
20
]
,
f_ir_i
[
19
:
12
]
,
12'h000
};
wire
[
31
:
0
]
d_imm_u
=
{
f_ir_i
[
31
]
,
f_ir_i
[
30
:
20
]
,
f_ir_i
[
19
:
12
]
,
12'h000
};
wire
[
31
:
0
]
d_imm_j
=
{
{
12
{
f_ir_i
[
31
]
}},
wire
[
31
:
0
]
d_imm_j
=
{
{
12
{
f_ir_i
[
31
]
}},
f_ir_i
[
19
:
12
]
,
f_ir_i
[
19
:
12
]
,
f_ir_i
[
20
]
,
f_ir_i
[
30
:
25
]
,
f_ir_i
[
24
:
21
]
,
1'b0
};
f_ir_i
[
20
]
,
f_ir_i
[
30
:
25
]
,
f_ir_i
[
24
:
21
]
,
1'b0
};
reg
[
31
:
0
]
d_imm
;
reg
[
31
:
0
]
d_imm
;
// Immediate decode, comb part
// Immediate decode, comb part
always
@*
always
@*
...
@@ -207,27 +207,27 @@ module urv_decode
...
@@ -207,27 +207,27 @@ module urv_decode
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
if
(
!
d_stall_i
)
x_imm_o
<=
d_imm
;
x_imm_o
<=
d_imm
;
// ALU operand decoding
// ALU operand decoding
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
if
(
!
d_stall_i
)
begin
begin
case
(
d_opcode
)
case
(
d_opcode
)
`OPC_LUI
,
`OPC_AUIPC
:
`OPC_LUI
,
`OPC_AUIPC
:
begin
begin
x_alu_op1_o
<=
d_imm
;
x_alu_op1_o
<=
d_imm
;
x_use_op1_o
<=
1
;
x_use_op1_o
<=
1
;
end
end
`OPC_JAL
,
`OPC_JALR
:
`OPC_JAL
,
`OPC_JALR
:
begin
begin
x_alu_op1_o
<=
4
;
x_alu_op1_o
<=
4
;
x_use_op1_o
<=
1
;
x_use_op1_o
<=
1
;
end
end
default:
default:
begin
begin
x_alu_op1_o
<=
32
'
hx
;
x_alu_op1_o
<=
32
'
hx
;
x_use_op1_o
<=
0
;
x_use_op1_o
<=
0
;
end
end
endcase
// case (d_opcode)
endcase
// case (d_opcode)
...
@@ -243,7 +243,7 @@ module urv_decode
...
@@ -243,7 +243,7 @@ module urv_decode
x_alu_op2_o
<=
f_pc_i
;
x_alu_op2_o
<=
f_pc_i
;
x_use_op2_o
<=
1
;
x_use_op2_o
<=
1
;
end
end
`OPC_OP_IMM
:
`OPC_OP_IMM
:
begin
begin
x_alu_op2_o
<=
d_imm
;
x_alu_op2_o
<=
d_imm
;
...
@@ -252,15 +252,15 @@ module urv_decode
...
@@ -252,15 +252,15 @@ module urv_decode
default:
default:
begin
begin
x_alu_op2_o
<=
32
'
hx
;
x_alu_op2_o
<=
32
'
hx
;
x_use_op2_o
<=
0
;
x_use_op2_o
<=
0
;
end
end
endcase
// case (d_opcode_i)
endcase
// case (d_opcode_i)
end
// if (!d_stall_i)
end
// if (!d_stall_i)
wire
d_rd_nonzero
=
(
f_rd
!=
0
)
;
wire
d_rd_nonzero
=
(
f_rd
!=
0
)
;
// misc decoding
// misc decoding
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
if
(
!
d_stall_i
)
...
@@ -269,7 +269,7 @@ module urv_decode
...
@@ -269,7 +269,7 @@ module urv_decode
x_is_load_o
<=
(
d_opcode
==
`OPC_LOAD
&&
!
load_hazard
)
?
1'b1
:
1'b0
;
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_store_o
<=
(
d_opcode
==
`OPC_STORE
&&
!
load_hazard
)
?
1'b1
:
1'b0
;
x_is_mul
<=
d_is_mul
;
x_is_mul
<=
d_is_mul
;
case
(
d_opcode
)
case
(
d_opcode
)
...
@@ -292,7 +292,7 @@ module urv_decode
...
@@ -292,7 +292,7 @@ module urv_decode
// all multiply/divide instructions except MUL
// all multiply/divide instructions except MUL
x_is_undef_o
<=
(
d_opcode
==
`OPC_OP
&&
f_ir_i
[
25
]
&&
d_fun
!=
`FUNC_MUL
)
;
x_is_undef_o
<=
(
d_opcode
==
`OPC_OP
&&
f_ir_i
[
25
]
&&
d_fun
!=
`FUNC_MUL
)
;
if
(
d_is_shift
)
if
(
d_is_shift
)
x_rd_source_o
<=
`RD_SOURCE_SHIFTER
;
x_rd_source_o
<=
`RD_SOURCE_SHIFTER
;
else
if
(
d_opcode
==
`OPC_SYSTEM
)
else
if
(
d_opcode
==
`OPC_SYSTEM
)
...
@@ -301,7 +301,7 @@ module urv_decode
...
@@ -301,7 +301,7 @@ module urv_decode
x_rd_source_o
<=
`RD_SOURCE_MULTIPLY
;
x_rd_source_o
<=
`RD_SOURCE_MULTIPLY
;
else
else
x_rd_source_o
<=
`RD_SOURCE_ALU
;
x_rd_source_o
<=
`RD_SOURCE_ALU
;
// rdest write value
// rdest write value
case
(
d_opcode
)
case
(
d_opcode
)
`OPC_OP_IMM
,
`OPC_OP
,
`OPC_JAL
,
`OPC_JALR
,
`OPC_LUI
,
`OPC_AUIPC
:
`OPC_OP_IMM
,
`OPC_OP
,
`OPC_JAL
,
`OPC_JALR
,
`OPC_LUI
,
`OPC_AUIPC
:
...
@@ -312,8 +312,8 @@ module urv_decode
...
@@ -312,8 +312,8 @@ module urv_decode
x_rd_write
<=
0
;
x_rd_write
<=
0
;
endcase
// case (d_opcode)
endcase
// case (d_opcode)
end
// if (!d_stall_i)
end
// if (!d_stall_i)
// CSR/supervisor instructions
// CSR/supervisor instructions
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
d_stall_i
)
if
(
!
d_stall_i
)
...
@@ -323,11 +323,8 @@ module urv_decode
...
@@ -323,11 +323,8 @@ module urv_decode
x_is_csr_o
<=
(
d_opcode
==
`OPC_SYSTEM
)
&&
(
d_fun
!=
0
)
;
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
)
;
x_is_eret_o
<=
(
d_opcode
==
`OPC_SYSTEM
)
&&
(
d_fun
==
0
)
&&
(
f_ir_i
[
31
:
20
]
==
12'b000100000000
)
;
end
end
assign
x_is_shift_o
=
x_is_shift
;
assign
x_is_shift_o
=
x_is_shift
;
assign
x_rd_write_o
=
x_rd_write
;
assign
x_rd_write_o
=
x_rd_write
;
endmodule
// rv_decode
endmodule
// rv_decode
rtl/urv_defs.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_config.v"
`include
"urv_config.v"
...
@@ -65,16 +65,16 @@
...
@@ -65,16 +65,16 @@
`define
FUNC_REM 3
'
b110
`define
FUNC_REM 3
'
b110
`define
FUNC_REMU 3
'
b111
`define
FUNC_REMU 3
'
b111
`define
RD_SOURCE_ALU 3
'
b000
`define
RD_SOURCE_ALU 3
'
b000
`define
RD_SOURCE_SHIFTER 3
'
b010
`define
RD_SOURCE_SHIFTER 3
'
b010
`define
RD_SOURCE_MULTIPLY 3
'
b001
`define
RD_SOURCE_MULTIPLY 3
'
b001
`define
RD_SOURCE_DIVIDE 3
'
b011
`define
RD_SOURCE_DIVIDE 3
'
b011
`define
RD_SOURCE_CSR 3
'
b011
`define
RD_SOURCE_CSR 3
'
b011
`define
CSR_ID_CYCLESH 12
'
hc80
`define
CSR_ID_CYCLESH 12
'
hc80
`define
CSR_ID_CYCLESL 12
'
hc00
`define
CSR_ID_CYCLESL 12
'
hc00
`define
CSR_ID_TIMEH 12
'
hc81
`define
CSR_ID_TIMEH 12
'
hc81
`define
CSR_ID_TIMEL 12
'
hc01
`define
CSR_ID_TIMEL 12
'
hc01
`define
CSR_ID_MSCRATCH 12
'
h340
`define
CSR_ID_MSCRATCH 12
'
h340
`define
CSR_ID_MEPC 12
'
h341
`define
CSR_ID_MEPC 12
'
h341
`define
CSR_ID_MSTATUS 12
'
h300
`define
CSR_ID_MSTATUS 12
'
h300
...
...
rtl/urv_divide.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -34,7 +34,7 @@ module urv_divide
...
@@ -34,7 +34,7 @@ module urv_divide
input
d_valid_i
,
input
d_valid_i
,
input
d_is_divide_i
,
input
d_is_divide_i
,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_rs2_i
,
input
[
31
:
0
]
d_rs2_i
,
...
@@ -49,7 +49,7 @@ module urv_divide
...
@@ -49,7 +49,7 @@ module urv_divide
wire
[
32
:
0
]
alu_result
;
wire
[
32
:
0
]
alu_result
;
reg
[
31
:
0
]
alu_op1
;
reg
[
31
:
0
]
alu_op1
;
reg
[
31
:
0
]
alu_op2
;
reg
[
31
:
0
]
alu_op2
;
...
@@ -57,7 +57,7 @@ module urv_divide
...
@@ -57,7 +57,7 @@ module urv_divide
wire
[
31
:
0
]
r_next
=
{
r
[
30
:
0
]
,
n
[
31
-
(
state
-
3
)]
};
wire
[
31
:
0
]
r_next
=
{
r
[
30
:
0
]
,
n
[
31
-
(
state
-
3
)]
};
always
@*
always
@*
case
(
state
)
// synthesis full_case parallel_case
case
(
state
)
// synthesis full_case parallel_case
0
:
begin
alu_op1
<=
'
hx
;
alu_op2
<=
'
hx
;
end
0
:
begin
alu_op1
<=
'
hx
;
alu_op2
<=
'
hx
;
end
...
@@ -69,13 +69,13 @@ module urv_divide
...
@@ -69,13 +69,13 @@ module urv_divide
endcase
// case (state)
endcase
// case (state)
reg
alu_sub
;
reg
alu_sub
;
assign
alu_result
=
alu_sub
?
{
1'b0
,
alu_op1
}
-
{
1'b0
,
alu_op2
}
:
{
1'b0
,
alu_op1
}
+
{
1'b0
,
alu_op2
};
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
alu_ge
=
~
alu_result
[
32
]
;
wire
start_divide
=
!
x_stall_i
&&
!
x_kill_i
&&
d_valid_i
&&
d_is_divide_i
;
wire
start_divide
=
!
x_stall_i
&&
!
x_kill_i
&&
d_valid_i
&&
d_is_divide_i
;
wire
done
=
(
is_rem
?
state
==
37
:
state
==
36
)
;
wire
done
=
(
is_rem
?
state
==
37
:
state
==
36
)
;
...
@@ -94,7 +94,7 @@ module urv_divide
...
@@ -94,7 +94,7 @@ module urv_divide
default:
default:
alu_sub
<=
1
;
alu_sub
<=
1
;
endcase
// case (state)
endcase
// case (state)
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
...
@@ -102,7 +102,7 @@ module urv_divide
...
@@ -102,7 +102,7 @@ module urv_divide
state
<=
0
;
state
<=
0
;
else
if
(
state
!=
0
||
start_divide
)
else
if
(
state
!=
0
||
start_divide
)
state
<=
state
+
1
;
state
<=
state
+
1
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
case
(
state
)
// synthesis full_case parallel_case
case
(
state
)
// synthesis full_case parallel_case
0
:
0
:
...
@@ -112,15 +112,15 @@ module urv_divide
...
@@ -112,15 +112,15 @@ module urv_divide
r
<=
0
;
r
<=
0
;
is_rem
<=
(
d_fun_i
==
`FUNC_REM
||
d_fun_i
==
`FUNC_REMU
)
;
is_rem
<=
(
d_fun_i
==
`FUNC_REM
||
d_fun_i
==
`FUNC_REMU
)
;
n_sign
<=
d_rs1_i
[
31
]
;
n_sign
<=
d_rs1_i
[
31
]
;
d_sign
<=
d_rs2_i
[
31
]
;
d_sign
<=
d_rs2_i
[
31
]
;
end
end
1
:
1
:
n
<=
alu_result
[
31
:
0
]
;
n
<=
alu_result
[
31
:
0
]
;
2
:
2
:
d
<=
alu_result
[
31
:
0
]
;
d
<=
alu_result
[
31
:
0
]
;
35
:
35
:
...
@@ -131,14 +131,13 @@ module urv_divide
...
@@ -131,14 +131,13 @@ module urv_divide
default:
// 3..34: 32 divider iterations
default:
// 3..34: 32 divider iterations
begin
begin
q
<=
{
q
[
30
:
0
]
,
alu_ge
};
q
<=
{
q
[
30
:
0
]
,
alu_ge
};
r
<=
alu_ge
?
alu_result
:
r_next
;
r
<=
alu_ge
?
alu_result
:
r_next
;
end
end
endcase
// case ( state )
endcase
// case ( state )
endmodule
// rv_divide
endmodule
// rv_divide
rtl/urv_exceptions.v
View file @
8efd2565
/*
/*
uRV - a tiny and dumb RISC-V core
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -30,14 +30,14 @@ module urv_exceptions
...
@@ -30,14 +30,14 @@ module urv_exceptions
input
x_stall_i
,
input
x_stall_i
,
input
x_kill_i
,
input
x_kill_i
,
input
d_is_csr_i
,
input
d_is_csr_i
,
input
d_is_eret_i
,
input
d_is_eret_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
exp_irq_i
,
input
exp_irq_i
,
input
exp_tick_i
,
input
exp_tick_i
,
input
exp_breakpoint_i
,
input
exp_breakpoint_i
,
...
@@ -46,13 +46,13 @@ module urv_exceptions
...
@@ -46,13 +46,13 @@ module urv_exceptions
input
exp_invalid_insn_i
,
input
exp_invalid_insn_i
,
input
[
31
:
0
]
x_csr_write_value_i
,
input
[
31
:
0
]
x_csr_write_value_i
,
output
reg
x_exception_o
,
output
reg
x_exception_o
,
input
[
31
:
0
]
x_exception_pc_i
,
input
[
31
:
0
]
x_exception_pc_i
,
output
[
31
:
0
]
x_exception_pc_o
,
output
[
31
:
0
]
x_exception_pc_o
,
output
[
31
:
0
]
x_exception_vector_o
,
output
[
31
:
0
]
x_exception_vector_o
,
input
x_exception_taken_i
,
input
x_exception_taken_i
,
output
[
31
:
0
]
csr_mstatus_o
,
output
[
31
:
0
]
csr_mstatus_o
,
output
[
31
:
0
]
csr_mip_o
,
output
[
31
:
0
]
csr_mip_o
,
output
[
31
:
0
]
csr_mie_o
,
output
[
31
:
0
]
csr_mie_o
,
...
@@ -60,14 +60,14 @@ module urv_exceptions
...
@@ -60,14 +60,14 @@ module urv_exceptions
output
[
31
:
0
]
csr_mcause_o
output
[
31
:
0
]
csr_mcause_o
)
;
)
;
reg
[
31
:
0
]
csr_mepc
;
reg
[
31
:
0
]
csr_mepc
;
reg
[
31
:
0
]
csr_mie
;
reg
[
31
:
0
]
csr_mie
;
reg
csr_ie
;
reg
csr_ie
;
reg
[
3
:
0
]
csr_mcause
;
reg
[
3
:
0
]
csr_mcause
;
reg
exception
;
reg
exception
;
reg
[
3
:
0
]
cause
;
reg
[
3
:
0
]
cause
;
...
@@ -79,9 +79,9 @@ module urv_exceptions
...
@@ -79,9 +79,9 @@ module urv_exceptions
assign
csr_mie_o
=
csr_mie
;
assign
csr_mie_o
=
csr_mie
;
assign
csr_mstatus_o
[
0
]
=
csr_ie
;
assign
csr_mstatus_o
[
0
]
=
csr_ie
;
assign
csr_mstatus_o
[
31
:
1
]
=
0
;
assign
csr_mstatus_o
[
31
:
1
]
=
0
;
reg
[
31
:
0
]
csr_mip
;
reg
[
31
:
0
]
csr_mip
;
always
@*
always
@*
begin
begin
csr_mip
<=
0
;
csr_mip
<=
0
;
...
@@ -95,7 +95,7 @@ module urv_exceptions
...
@@ -95,7 +95,7 @@ module urv_exceptions
assign
csr_mip_o
=
csr_mip
;
assign
csr_mip_o
=
csr_mip
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
if
(
rst_i
)
except_vec_masked
<=
0
;
except_vec_masked
<=
0
;
...
@@ -127,13 +127,13 @@ module urv_exceptions
...
@@ -127,13 +127,13 @@ module urv_exceptions
except_vec_masked
[
5
]
<=
csr_mie
[
`EXCEPT_IRQ
]
&
csr_ie
;
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(!x_stall_i && !x_kill_i && d_is_csr_i && d_csr_sel_i == `CSR_ID_MIP)
end
// else: !if(rst_i)
end
// else: !if(rst_i)
always
@*
always
@*
exception
<=
|
except_vec_masked
|
exp_invalid_insn_i
;
exception
<=
|
except_vec_masked
|
exp_invalid_insn_i
;
assign
x_exception_vector_o
=
'h8
;
assign
x_exception_vector_o
=
'h8
;
always
@*
always
@*
if
(
exp_invalid_insn_i
||
except_vec_masked
[
0
])
if
(
exp_invalid_insn_i
||
except_vec_masked
[
0
])
cause
<=
`EXCEPT_ILLEGAL_INSN
;
cause
<=
`EXCEPT_ILLEGAL_INSN
;
...
@@ -147,15 +147,15 @@ module urv_exceptions
...
@@ -147,15 +147,15 @@ module urv_exceptions
cause
<=
`EXCEPT_TIMER
;
cause
<=
`EXCEPT_TIMER
;
else
else
cause
<=
`EXCEPT_IRQ
;
cause
<=
`EXCEPT_IRQ
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
if
(
rst_i
)
begin
begin
csr_mepc
<=
0
;
csr_mepc
<=
0
;
csr_mie
<=
0
;
csr_mie
<=
0
;
csr_ie
<=
0
;
csr_ie
<=
0
;
exception_pending
<=
0
;
exception_pending
<=
0
;
end
else
if
(
!
x_stall_i
&&
!
x_kill_i
)
begin
end
else
if
(
!
x_stall_i
&&
!
x_kill_i
)
begin
if
(
d_is_eret_i
)
if
(
d_is_eret_i
)
exception_pending
<=
0
;
exception_pending
<=
0
;
...
@@ -164,13 +164,13 @@ module urv_exceptions
...
@@ -164,13 +164,13 @@ module urv_exceptions
csr_mepc
<=
x_exception_pc_i
;
csr_mepc
<=
x_exception_pc_i
;
csr_mcause
<=
cause
;
csr_mcause
<=
cause
;
exception_pending
<=
1
;
exception_pending
<=
1
;
end
end
if
(
d_is_csr_i
)
begin
if
(
d_is_csr_i
)
begin
case
(
d_csr_sel_i
)
case
(
d_csr_sel_i
)
`CSR_ID_MSTATUS
:
`CSR_ID_MSTATUS
:
csr_ie
<=
x_csr_write_value_i
[
0
]
;
csr_ie
<=
x_csr_write_value_i
[
0
]
;
`CSR_ID_MEPC
:
`CSR_ID_MEPC
:
csr_mepc
<=
x_csr_write_value_i
;
csr_mepc
<=
x_csr_write_value_i
;
`CSR_ID_MIE
:
`CSR_ID_MIE
:
begin
begin
...
@@ -185,7 +185,7 @@ module urv_exceptions
...
@@ -185,7 +185,7 @@ module urv_exceptions
end
// if (d_is_csr_i)
end
// if (d_is_csr_i)
end
// if (!x_stall_i && !x_kill_i)
end
// if (!x_stall_i && !x_kill_i)
assign
x_exception_pc_o
=
csr_mepc
;
assign
x_exception_pc_o
=
csr_mepc
;
...
@@ -196,8 +196,5 @@ module urv_exceptions
...
@@ -196,8 +196,5 @@ module urv_exceptions
x_exception_o
<=
0
;
x_exception_o
<=
0
;
else
if
(
exception
&&
!
exception_pending
)
else
if
(
exception
&&
!
exception_pending
)
x_exception_o
<=
1
;
x_exception_o
<=
1
;
endmodule
// urv_exceptions
endmodule
// urv_exceptions
rtl/urv_exec.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -31,13 +31,13 @@ module urv_exec
...
@@ -31,13 +31,13 @@ module urv_exec
input
x_stall_i
,
input
x_stall_i
,
input
x_kill_i
,
input
x_kill_i
,
output
reg
x_stall_req_o
,
output
reg
x_stall_req_o
,
input
[
31
:
0
]
d_pc_i
,
input
[
31
:
0
]
d_pc_i
,
input
[
4
:
0
]
d_rd_i
,
input
[
4
:
0
]
d_rd_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
31
:
0
]
rf_rs1_value_i
,
input
[
31
:
0
]
rf_rs1_value_i
,
input
[
31
:
0
]
rf_rs2_value_i
,
input
[
31
:
0
]
rf_rs2_value_i
,
...
@@ -51,7 +51,7 @@ module urv_exec
...
@@ -51,7 +51,7 @@ module urv_exec
input
d_is_eret_i
,
input
d_is_eret_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
4
:
0
]
d_csr_imm_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
[
11
:
0
]
d_csr_sel_i
,
input
[
31
:
0
]
d_imm_i
,
input
[
31
:
0
]
d_imm_i
,
input
d_is_signed_compare_i
,
input
d_is_signed_compare_i
,
input
d_is_signed_alu_op_i
,
input
d_is_signed_alu_op_i
,
...
@@ -67,16 +67,16 @@ module urv_exec
...
@@ -67,16 +67,16 @@ module urv_exec
input
d_use_op1_i
,
input
d_use_op1_i
,
input
d_use_op2_i
,
input
d_use_op2_i
,
input
[
2
:
0
]
d_rd_source_i
,
input
[
2
:
0
]
d_rd_source_i
,
input
d_rd_write_i
,
input
d_rd_write_i
,
output
reg
[
31
:
0
]
f_branch_target_o
,
output
reg
[
31
:
0
]
f_branch_target_o
,
output
f_branch_take_o
,
output
f_branch_take_o
,
input
irq_i
,
input
irq_i
,
// Writeback stage I/F
// Writeback stage I/F
output
reg
[
2
:
0
]
w_fun_o
,
output
reg
[
2
:
0
]
w_fun_o
,
output
reg
w_load_o
,
output
reg
w_load_o
,
...
@@ -90,8 +90,8 @@ module urv_exec
...
@@ -90,8 +90,8 @@ module urv_exec
output
reg
[
1
:
0
]
w_rd_source_o
,
output
reg
[
1
:
0
]
w_rd_source_o
,
output
[
31
:
0
]
w_rd_shifter_o
,
output
[
31
:
0
]
w_rd_shifter_o
,
output
[
31
:
0
]
w_rd_multiply_o
,
output
[
31
:
0
]
w_rd_multiply_o
,
// Data memory I/F (address/store)
// Data memory I/F (address/store)
output
[
31
:
0
]
dm_addr_o
,
output
[
31
:
0
]
dm_addr_o
,
output
[
31
:
0
]
dm_data_s_o
,
output
[
31
:
0
]
dm_data_s_o
,
...
@@ -103,22 +103,22 @@ module urv_exec
...
@@ -103,22 +103,22 @@ module urv_exec
input
[
39
:
0
]
csr_time_i
,
input
[
39
:
0
]
csr_time_i
,
input
[
39
:
0
]
csr_cycles_i
,
input
[
39
:
0
]
csr_cycles_i
,
input
timer_tick_i
input
timer_tick_i
)
;
)
;
wire
[
31
:
0
]
rs1
,
rs2
;
wire
[
31
:
0
]
rs1
,
rs2
;
assign
rs1
=
rf_rs1_value_i
;
assign
rs1
=
rf_rs1_value_i
;
assign
rs2
=
rf_rs2_value_i
;
assign
rs2
=
rf_rs2_value_i
;
reg
[
31
:
0
]
alu_op1
,
alu_op2
,
alu_result
;
reg
[
31
:
0
]
alu_op1
,
alu_op2
,
alu_result
;
reg
[
31
:
0
]
rd_value
;
reg
[
31
:
0
]
rd_value
;
wire
exception_taken
;
wire
exception_taken
;
reg
branch_take
;
reg
branch_take
;
reg
branch_condition_met
;
reg
branch_condition_met
;
reg
[
31
:
0
]
branch_target
;
reg
[
31
:
0
]
branch_target
;
reg
[
31
:
0
]
dm_addr
,
dm_data_s
,
dm_select_s
;
reg
[
31
:
0
]
dm_addr
,
dm_data_s
,
dm_select_s
;
...
@@ -131,7 +131,7 @@ module urv_exec
...
@@ -131,7 +131,7 @@ module urv_exec
wire
cmp_lt
=
cmp_rs
[
32
]
;
wire
cmp_lt
=
cmp_rs
[
32
]
;
reg
f_branch_take
;
reg
f_branch_take
;
wire
[
31
:
0
]
rd_csr
;
wire
[
31
:
0
]
rd_csr
;
wire
[
31
:
0
]
rd_div
;
wire
[
31
:
0
]
rd_div
;
...
@@ -144,18 +144,18 @@ module urv_exec
...
@@ -144,18 +144,18 @@ module urv_exec
urv_csr
csr_regs
urv_csr
csr_regs
(
(
.
clk_i
(
clk_i
)
,
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
rst_i
(
rst_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
x_kill_i
(
x_kill_i
)
,
.
x_kill_i
(
x_kill_i
)
,
.
d_is_csr_i
(
d_is_csr_i
)
,
.
d_is_csr_i
(
d_is_csr_i
)
,
.
d_fun_i
(
d_fun_i
)
,
.
d_fun_i
(
d_fun_i
)
,
.
d_csr_imm_i
(
d_csr_imm_i
)
,
.
d_csr_imm_i
(
d_csr_imm_i
)
,
.
d_csr_sel_i
(
d_csr_sel_i
)
,
.
d_csr_sel_i
(
d_csr_sel_i
)
,
.
d_rs1_i
(
rs1
)
,
.
d_rs1_i
(
rs1
)
,
.
x_rd_o
(
rd_csr
)
,
.
x_rd_o
(
rd_csr
)
,
...
@@ -171,21 +171,21 @@ module urv_exec
...
@@ -171,21 +171,21 @@ module urv_exec
.
csr_mcause_i
(
csr_mcause
)
.
csr_mcause_i
(
csr_mcause
)
)
;
)
;
urv_exceptions
exception_unit
urv_exceptions
exception_unit
(
(
.
clk_i
(
clk_i
)
,
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
rst_i
(
rst_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
x_kill_i
(
x_kill_i
)
,
.
x_kill_i
(
x_kill_i
)
,
.
d_is_csr_i
(
d_is_csr_i
)
,
.
d_is_csr_i
(
d_is_csr_i
)
,
.
d_is_eret_i
(
d_is_eret_i
)
,
.
d_is_eret_i
(
d_is_eret_i
)
,
.
d_fun_i
(
d_fun_i
)
,
.
d_fun_i
(
d_fun_i
)
,
.
d_csr_imm_i
(
d_csr_imm_i
)
,
.
d_csr_imm_i
(
d_csr_imm_i
)
,
.
d_csr_sel_i
(
d_csr_sel_i
)
,
.
d_csr_sel_i
(
d_csr_sel_i
)
,
.
x_csr_write_value_i
(
csr_write_value
)
,
.
x_csr_write_value_i
(
csr_write_value
)
,
.
exp_irq_i
(
irq_i
)
,
.
exp_irq_i
(
irq_i
)
,
.
exp_tick_i
(
timer_tick_i
)
,
.
exp_tick_i
(
timer_tick_i
)
,
.
exp_breakpoint_i
(
1'b0
)
,
.
exp_breakpoint_i
(
1'b0
)
,
...
@@ -205,9 +205,9 @@ module urv_exec
...
@@ -205,9 +205,9 @@ module urv_exec
.
csr_mepc_o
(
csr_mepc
)
,
.
csr_mepc_o
(
csr_mepc
)
,
.
csr_mcause_o
(
csr_mcause
)
.
csr_mcause_o
(
csr_mcause
)
)
;
)
;
// branch condition decoding
// branch condition decoding
always
@*
always
@*
case
(
d_fun_i
)
// synthesis parallel_case full_case
case
(
d_fun_i
)
// synthesis parallel_case full_case
`BRA_EQ
:
branch_condition_met
<=
cmp_equal
;
`BRA_EQ
:
branch_condition_met
<=
cmp_equal
;
...
@@ -223,13 +223,13 @@ module urv_exec
...
@@ -223,13 +223,13 @@ module urv_exec
always
@*
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
)
;
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
// calculate branch target address
always
@*
always
@*
if
(
d_is_eret_i
)
if
(
d_is_eret_i
)
branch_target
<=
exception_address
;
branch_target
<=
exception_address
;
else
if
(
exception
)
else
if
(
exception
)
branch_target
<=
exception_vector
;
branch_target
<=
exception_vector
;
else
else
branch_target
<=
dm_addr
;
branch_target
<=
dm_addr
;
// decode ALU operands
// decode ALU operands
...
@@ -238,7 +238,7 @@ module urv_exec
...
@@ -238,7 +238,7 @@ module urv_exec
alu_op1
<=
d_use_op1_i
?
d_alu_op1_i
:
rs1
;
alu_op1
<=
d_use_op1_i
?
d_alu_op1_i
:
rs1
;
alu_op2
<=
d_use_op2_i
?
d_alu_op2_i
:
rs2
;
alu_op2
<=
d_use_op2_i
?
d_alu_op2_i
:
rs2
;
end
end
// ALU adder/subtractor
// 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_op1
=
{
d_is_signed_alu_op_i
?
alu_op1
[
31
]
:
1'b0
,
alu_op1
};
...
@@ -251,29 +251,29 @@ module urv_exec
...
@@ -251,29 +251,29 @@ module urv_exec
else
else
alu_addsub_result
<=
alu_addsub_op1
-
alu_addsub_op2
;
alu_addsub_result
<=
alu_addsub_op1
-
alu_addsub_op2
;
// the rest of the ALU
// the rest of the ALU
always
@*
always
@*
begin
begin
case
(
d_fun_i
)
case
(
d_fun_i
)
`FUNC_ADD
:
`FUNC_ADD
:
alu_result
<=
alu_addsub_result
[
31
:
0
]
;
alu_result
<=
alu_addsub_result
[
31
:
0
]
;
`FUNC_XOR
:
`FUNC_XOR
:
alu_result
<=
alu_op1
^
alu_op2
;
alu_result
<=
alu_op1
^
alu_op2
;
`FUNC_OR
:
`FUNC_OR
:
alu_result
<=
alu_op1
|
alu_op2
;
alu_result
<=
alu_op1
|
alu_op2
;
`FUNC_AND
:
`FUNC_AND
:
alu_result
<=
alu_op1
&
alu_op2
;
alu_result
<=
alu_op1
&
alu_op2
;
`FUNC_SLT
:
`FUNC_SLT
:
alu_result
<=
alu_addsub_result
[
32
]
?
1
:
0
;
alu_result
<=
alu_addsub_result
[
32
]
?
1
:
0
;
`FUNC_SLTU
:
`FUNC_SLTU
:
alu_result
<=
alu_addsub_result
[
32
]
?
1
:
0
;
alu_result
<=
alu_addsub_result
[
32
]
?
1
:
0
;
default:
alu_result
<=
32
'
hx
;
default:
alu_result
<=
32
'
hx
;
endcase
// case (d_fun_i)
endcase
// case (d_fun_i)
end
// always@ *
end
// always@ *
// barel shifter
// barel shifter
urv_shifter
shifter
urv_shifter
shifter
(
(
.
clk_i
(
clk_i
)
,
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
rst_i
(
rst_i
)
,
...
@@ -291,12 +291,12 @@ module urv_exec
...
@@ -291,12 +291,12 @@ module urv_exec
wire
divider_stall_req
=
0
;
wire
divider_stall_req
=
0
;
urv_multiply
multiplier
urv_multiply
multiplier
(
(
.
clk_i
(
clk_i
)
,
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
rst_i
(
rst_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
x_stall_i
(
x_stall_i
)
,
.
d_rs1_i
(
rs1
)
,
.
d_rs1_i
(
rs1
)
,
.
d_rs2_i
(
rs2
)
,
.
d_rs2_i
(
rs2
)
,
.
d_fun_i
(
d_fun_i
)
,
.
d_fun_i
(
d_fun_i
)
,
...
@@ -305,7 +305,7 @@ module urv_exec
...
@@ -305,7 +305,7 @@ module urv_exec
/* wire divider_stall_req;
/* wire divider_stall_req;
wire [31:0] rd_divide;
wire [31:0] rd_divide;
urv_divide divider
urv_divide divider
(
(
.clk_i(clk_i),
.clk_i(clk_i),
...
@@ -316,7 +316,7 @@ module urv_exec
...
@@ -316,7 +316,7 @@ module urv_exec
.d_valid_i(d_valid_i),
.d_valid_i(d_valid_i),
.d_is_divide_i(d_is_divide_i),
.d_is_divide_i(d_is_divide_i),
.d_rs1_i(rs1),
.d_rs1_i(rs1),
.d_rs2_i(rs2),
.d_rs2_i(rs2),
...
@@ -331,37 +331,37 @@ module urv_exec
...
@@ -331,37 +331,37 @@ module urv_exec
case
(
d_rd_source_i
)
case
(
d_rd_source_i
)
`RD_SOURCE_ALU
:
rd_value
<=
alu_result
;
`RD_SOURCE_ALU
:
rd_value
<=
alu_result
;
`RD_SOURCE_CSR
:
rd_value
<=
rd_csr
;
`RD_SOURCE_CSR
:
rd_value
<=
rd_csr
;
// `RD_SOURCE_DIVIDE: rd_value <= rd_divide;
// `RD_SOURCE_DIVIDE: rd_value <= rd_divide;
default:
rd_value
<=
32
'
hx
;
default:
rd_value
<=
32
'
hx
;
endcase
// case (x_rd_source_i)
endcase
// case (x_rd_source_i)
reg
unaligned_addr
;
reg
unaligned_addr
;
always
@*
always
@*
case
(
d_fun_i
)
case
(
d_fun_i
)
`LDST_B
,
`LDST_B
,
`LDST_BU
:
`LDST_BU
:
unaligned_addr
<=
0
;
unaligned_addr
<=
0
;
`LDST_H
,
`LDST_H
,
`LDST_HU
:
`LDST_HU
:
unaligned_addr
<=
(
dm_addr
[
0
])
;
unaligned_addr
<=
(
dm_addr
[
0
])
;
`LDST_L
:
`LDST_L
:
unaligned_addr
<=
(
dm_addr
[
1
:
0
]
!=
2'b00
)
;
unaligned_addr
<=
(
dm_addr
[
1
:
0
]
!=
2'b00
)
;
default:
default:
unaligned_addr
<=
0
;
unaligned_addr
<=
0
;
endcase
// case (d_fun_i)
endcase
// case (d_fun_i)
// generate store value/select
// generate store value/select
always
@*
always
@*
begin
begin
case
(
d_fun_i
)
case
(
d_fun_i
)
`LDST_B
:
`LDST_B
:
begin
begin
dm_data_s
<=
{
rs2
[
7
:
0
]
,
rs2
[
7
:
0
]
,
rs2
[
7
:
0
]
,
rs2
[
7
:
0
]
};
dm_data_s
<=
{
rs2
[
7
:
0
]
,
rs2
[
7
:
0
]
,
rs2
[
7
:
0
]
,
rs2
[
7
:
0
]
};
dm_select_s
[
0
]
<=
(
dm_addr
[
1
:
0
]
==
2'b00
)
;
dm_select_s
[
0
]
<=
(
dm_addr
[
1
:
0
]
==
2'b00
)
;
...
@@ -369,7 +369,7 @@ module urv_exec
...
@@ -369,7 +369,7 @@ module urv_exec
dm_select_s
[
2
]
<=
(
dm_addr
[
1
:
0
]
==
2'b10
)
;
dm_select_s
[
2
]
<=
(
dm_addr
[
1
:
0
]
==
2'b10
)
;
dm_select_s
[
3
]
<=
(
dm_addr
[
1
:
0
]
==
2'b11
)
;
dm_select_s
[
3
]
<=
(
dm_addr
[
1
:
0
]
==
2'b11
)
;
end
end
`LDST_H
:
`LDST_H
:
begin
begin
dm_data_s
<=
{
rs2
[
15
:
0
]
,
rs2
[
15
:
0
]
};
dm_data_s
<=
{
rs2
[
15
:
0
]
,
rs2
[
15
:
0
]
};
...
@@ -384,7 +384,7 @@ module urv_exec
...
@@ -384,7 +384,7 @@ module urv_exec
dm_data_s
<=
rs2
;
dm_data_s
<=
rs2
;
dm_select_s
<=
4'b1111
;
dm_select_s
<=
4'b1111
;
end
end
default:
default:
begin
begin
dm_data_s
<=
32
'
hx
;
dm_data_s
<=
32
'
hx
;
...
@@ -399,15 +399,15 @@ module urv_exec
...
@@ -399,15 +399,15 @@ module urv_exec
branch_take
<=
1
;
branch_take
<=
1
;
else
else
case
(
d_opcode_i
)
case
(
d_opcode_i
)
`OPC_JAL
,
`OPC_JALR
:
`OPC_JAL
,
`OPC_JALR
:
branch_take
<=
1
;
branch_take
<=
1
;
`OPC_BRANCH
:
`OPC_BRANCH
:
branch_take
<=
branch_condition_met
;
branch_take
<=
branch_condition_met
;
default:
default:
branch_take
<=
0
;
branch_take
<=
0
;
endcase
// case (d_opcode_i)
endcase
// case (d_opcode_i)
// generate load/store requests
// generate load/store requests
assign
dm_addr_o
=
dm_addr
;
assign
dm_addr_o
=
dm_addr
;
...
@@ -417,15 +417,15 @@ module urv_exec
...
@@ -417,15 +417,15 @@ module urv_exec
assign
dm_load_o
=
d_is_load_i
&
d_valid_i
&
!
x_kill_i
&
!
x_stall_i
&
!
exception
;
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
;
assign
dm_store_o
=
d_is_store_i
&
d_valid_i
&
!
x_kill_i
&
!
x_stall_i
&
!
exception
;
// X/W pipeline registers
// X/W pipeline registers
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
if
(
rst_i
)
begin
f_branch_take
<=
0
;
f_branch_take
<=
0
;
w_load_o
<=
0
;
w_load_o
<=
0
;
w_store_o
<=
0
;
w_store_o
<=
0
;
w_valid_o
<=
0
;
w_valid_o
<=
0
;
end
else
if
(
!
x_stall_i
)
begin
end
else
if
(
!
x_stall_i
)
begin
f_branch_target_o
<=
branch_target
;
f_branch_target_o
<=
branch_target
;
f_branch_take
<=
branch_take
&&
!
x_kill_i
&&
(
d_valid_i
||
exception
)
;
f_branch_take
<=
branch_take
&&
!
x_kill_i
&&
(
d_valid_i
||
exception
)
;
...
@@ -439,15 +439,15 @@ module urv_exec
...
@@ -439,15 +439,15 @@ module urv_exec
w_rd_source_o
<=
d_rd_source_i
;
w_rd_source_o
<=
d_rd_source_i
;
w_fun_o
<=
d_fun_i
;
w_fun_o
<=
d_fun_i
;
w_dm_addr_o
<=
dm_addr
;
w_dm_addr_o
<=
dm_addr
;
w_valid_o
<=
!
exception
;
w_valid_o
<=
!
exception
;
end
// else: !if(rst_i)
end
// else: !if(rst_i)
always
@*
always
@*
exception_pc
<=
d_pc_i
;
exception_pc
<=
d_pc_i
;
assign
f_branch_take_o
=
f_branch_take
;
assign
f_branch_take_o
=
f_branch_take
;
assign
exception_taken
=
exception
&&
(
branch_take
&&
!
x_kill_i
&&
(
d_valid_i
||
exception
))
;
assign
exception_taken
=
exception
&&
(
branch_take
&&
!
x_kill_i
&&
(
d_valid_i
||
exception
))
;
// pipeline control: generate stall request signal
// pipeline control: generate stall request signal
always
@*
always
@*
// never stall on taken branch
// never stall on taken branch
...
@@ -463,10 +463,3 @@ module urv_exec
...
@@ -463,10 +463,3 @@ module urv_exec
endmodule
// urv_exec
endmodule
// urv_exec
rtl/urv_fetch.v
View file @
8efd2565
...
@@ -16,19 +16,19 @@
...
@@ -16,19 +16,19 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`timescale
1
ns
/
1
ps
`timescale
1
ns
/
1
ps
module
urv_fetch
module
urv_fetch
(
(
input
clk_i
,
input
clk_i
,
input
rst_i
,
input
rst_i
,
input
f_stall_i
,
input
f_stall_i
,
input
f_kill_i
,
input
f_kill_i
,
output
[
31
:
0
]
im_addr_o
,
output
[
31
:
0
]
im_addr_o
,
input
[
31
:
0
]
im_data_i
,
input
[
31
:
0
]
im_data_i
,
input
im_valid_i
,
input
im_valid_i
,
...
@@ -47,8 +47,8 @@ module urv_fetch
...
@@ -47,8 +47,8 @@ module urv_fetch
reg
[
31
:
0
]
pc_next
;
reg
[
31
:
0
]
pc_next
;
reg
[
31
:
0
]
pc_plus_4
;
reg
[
31
:
0
]
pc_plus_4
;
always
@*
always
@*
if
(
x_bra_i
)
if
(
x_bra_i
)
pc_next
<=
x_pc_bra_i
;
pc_next
<=
x_pc_bra_i
;
...
@@ -56,43 +56,40 @@ module urv_fetch
...
@@ -56,43 +56,40 @@ module urv_fetch
pc_next
<=
pc
;
pc_next
<=
pc
;
else
else
pc_next
<=
pc_plus_4
;
pc_next
<=
pc_plus_4
;
assign
f_ir_o
=
ir
;
assign
f_ir_o
=
ir
;
assign
im_addr_o
=
pc_next
;
assign
im_addr_o
=
pc_next
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
begin
if
(
rst_i
)
begin
pc
<=
0
;
pc
<=
0
;
pc_plus_4
<=
4
;
pc_plus_4
<=
4
;
ir
<=
0
;
ir
<=
0
;
f_valid_o
<=
0
;
f_valid_o
<=
0
;
rst_d
<=
0
;
rst_d
<=
0
;
end
else
begin
end
else
begin
rst_d
<=
1
;
rst_d
<=
1
;
if
(
!
f_stall_i
)
begin
if
(
!
f_stall_i
)
begin
if
(
im_valid_i
)
if
(
im_valid_i
)
pc_plus_4
<=
(
x_bra_i
?
x_pc_bra_i
:
pc_plus_4
)
+
4
;
pc_plus_4
<=
(
x_bra_i
?
x_pc_bra_i
:
pc_plus_4
)
+
4
;
pc
<=
pc_next
;
pc
<=
pc_next
;
f_pc_o
<=
pc
;
f_pc_o
<=
pc
;
if
(
im_valid_i
)
begin
if
(
im_valid_i
)
begin
ir
<=
im_data_i
;
ir
<=
im_data_i
;
f_valid_o
<=
(
rst_d
&&
!
f_kill_i
)
;
f_valid_o
<=
(
rst_d
&&
!
f_kill_i
)
;
end
else
begin
// if (i_valid_i)
end
else
begin
// if (i_valid_i)
f_valid_o
<=
0
;
f_valid_o
<=
0
;
end
end
end
end
end
// else: !if(rst_i)
end
// else: !if(rst_i)
endmodule
// urv_fetch
endmodule
// urv_fetch
rtl/urv_iram.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`timescale
1
ns
/
1
ps
`timescale
1
ns
/
1
ps
...
@@ -30,7 +30,7 @@ module urv_iram
...
@@ -30,7 +30,7 @@ module urv_iram
parameter
g_size
=
65536
,
parameter
g_size
=
65536
,
parameter
g_init_file
=
""
,
parameter
g_init_file
=
""
,
parameter
g_simulation
=
0
parameter
g_simulation
=
0
)
)
(
(
input
clk_i
,
input
clk_i
,
...
@@ -39,7 +39,7 @@ module urv_iram
...
@@ -39,7 +39,7 @@ module urv_iram
input
[
31
:
0
]
aa_i
,
input
[
31
:
0
]
aa_i
,
input
[
3
:
0
]
bwea_i
,
input
[
3
:
0
]
bwea_i
,
input
[
31
:
0
]
da_i
,
input
[
31
:
0
]
da_i
,
output
[
31
:
0
]
qa_o
,
output
[
31
:
0
]
qa_o
,
input
enb_i
,
input
enb_i
,
input
web_i
,
input
web_i
,
input
[
31
:
0
]
ab_i
,
input
[
31
:
0
]
ab_i
,
...
@@ -53,12 +53,12 @@ module urv_iram
...
@@ -53,12 +53,12 @@ module urv_iram
// synthesis translate_off
// synthesis translate_off
reg
[
31
:
0
]
mem
[
0
:
g_size
/
4
-
1
]
;
reg
[
31
:
0
]
mem
[
0
:
g_size
/
4
-
1
]
;
reg
[
31
:
0
]
qa_int
,
qb_int
;
reg
[
31
:
0
]
qa_int
,
qb_int
;
// synthesis translate_on
// synthesis translate_on
`define
RAM_INST
(
id
,
entity
,
range_a
,
range_d
,
range_bw
)
\
`define
RAM_INST
(
id
,
entity
,
range_a
,
range_d
,
range_bw
)
\
entity RV_IRAM_BLK_
``
id \
entity RV_IRAM_BLK_
``
id \
(
\
(
\
...
@@ -97,9 +97,9 @@ module urv_iram
...
@@ -97,9 +97,9 @@ module urv_iram
.
WEB
((
enb
)
&
web_i
&
bweb_i
[
range_bw
])
\
.
WEB
((
enb
)
&
web_i
&
bweb_i
[
range_bw
])
\
)
;
)
;
generate
generate
if
(
!
g_simulation
)
begin
if
(
!
g_simulation
)
begin
if
(
g_size
==
65536
)
begin
if
(
g_size
==
65536
)
begin
`RAM_INST
(
64
K_0
,
RAMB16_S1_S1
,
15
:
2
,
0
,
0
)
`RAM_INST
(
64
K_0
,
RAMB16_S1_S1
,
15
:
2
,
0
,
0
)
...
@@ -138,7 +138,7 @@ module urv_iram
...
@@ -138,7 +138,7 @@ module urv_iram
else
if
(
g_size
==
32768
)
begin
else
if
(
g_size
==
32768
)
begin
wire
[
31
:
0
]
qa_h
,
qb_h
,
qa_l
,
qb_l
;
wire
[
31
:
0
]
qa_h
,
qb_h
,
qa_l
,
qb_l
;
reg
a14a_d
,
a14b_d
;
reg
a14a_d
,
a14b_d
;
`RAM_INST_MUXED
(
32
K_H0
,
RAMB16_S4_S4
,
13
:
2
,
3
:
0
,
0
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H0
,
RAMB16_S4_S4
,
13
:
2
,
3
:
0
,
0
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H1
,
RAMB16_S4_S4
,
13
:
2
,
7
:
4
,
0
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H1
,
RAMB16_S4_S4
,
13
:
2
,
7
:
4
,
0
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H2
,
RAMB16_S4_S4
,
13
:
2
,
11
:
8
,
1
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H2
,
RAMB16_S4_S4
,
13
:
2
,
11
:
8
,
1
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
...
@@ -147,7 +147,7 @@ module urv_iram
...
@@ -147,7 +147,7 @@ module urv_iram
`RAM_INST_MUXED
(
32
K_H5
,
RAMB16_S4_S4
,
13
:
2
,
23
:
20
,
2
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H5
,
RAMB16_S4_S4
,
13
:
2
,
23
:
20
,
2
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H6
,
RAMB16_S4_S4
,
13
:
2
,
27
:
24
,
3
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H6
,
RAMB16_S4_S4
,
13
:
2
,
27
:
24
,
3
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H7
,
RAMB16_S4_S4
,
13
:
2
,
31
:
28
,
3
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_H7
,
RAMB16_S4_S4
,
13
:
2
,
31
:
28
,
3
,
qa_h
,
qb_h
,
aa_i
[
14
]
,
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_L0
,
RAMB16_S4_S4
,
13
:
2
,
3
:
0
,
0
,
qa_l
,
qb_l
,
~
aa_i
[
14
]
,
~
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_L0
,
RAMB16_S4_S4
,
13
:
2
,
3
:
0
,
0
,
qa_l
,
qb_l
,
~
aa_i
[
14
]
,
~
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_L1
,
RAMB16_S4_S4
,
13
:
2
,
7
:
4
,
0
,
qa_l
,
qb_l
,
~
aa_i
[
14
]
,
~
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_L1
,
RAMB16_S4_S4
,
13
:
2
,
7
:
4
,
0
,
qa_l
,
qb_l
,
~
aa_i
[
14
]
,
~
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_L2
,
RAMB16_S4_S4
,
13
:
2
,
11
:
8
,
1
,
qa_l
,
qb_l
,
~
aa_i
[
14
]
,
~
ab_i
[
14
])
`RAM_INST_MUXED
(
32
K_L2
,
RAMB16_S4_S4
,
13
:
2
,
11
:
8
,
1
,
qa_l
,
qb_l
,
~
aa_i
[
14
]
,
~
ab_i
[
14
])
...
@@ -165,12 +165,12 @@ module urv_iram
...
@@ -165,12 +165,12 @@ module urv_iram
assign
qa_o
=
a14a_d
?
qa_h
:
qa_l
;
assign
qa_o
=
a14a_d
?
qa_h
:
qa_l
;
assign
qb_o
=
a14b_d
?
qb_h
:
qb_l
;
assign
qb_o
=
a14b_d
?
qb_h
:
qb_l
;
end
else
if
(
g_size
==
16384
)
begin
end
else
if
(
g_size
==
16384
)
begin
`RAM_INST
(
16
K_0
,
RAMB16_S4_S4
,
13
:
2
,
3
:
0
,
0
)
`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_1
,
RAMB16_S4_S4
,
13
:
2
,
7
:
4
,
0
)
`RAM_INST
(
16
K_2
,
RAMB16_S4_S4
,
13
:
2
,
11
:
8
,
1
)
`RAM_INST
(
16
K_2
,
RAMB16_S4_S4
,
13
:
2
,
11
:
8
,
1
)
`RAM_INST
(
16
K_3
,
RAMB16_S4_S4
,
13
:
2
,
15
:
12
,
1
)
`RAM_INST
(
16
K_3
,
RAMB16_S4_S4
,
13
:
2
,
15
:
12
,
1
)
`RAM_INST
(
16
K_4
,
RAMB16_S4_S4
,
13
:
2
,
19
:
16
,
2
)
`RAM_INST
(
16
K_4
,
RAMB16_S4_S4
,
13
:
2
,
19
:
16
,
2
)
`RAM_INST
(
16
K_5
,
RAMB16_S4_S4
,
13
:
2
,
23
:
20
,
2
)
`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_6
,
RAMB16_S4_S4
,
13
:
2
,
27
:
24
,
3
)
...
@@ -180,18 +180,18 @@ module urv_iram
...
@@ -180,18 +180,18 @@ module urv_iram
$
error
(
"Unsupported Spartan-6 IRAM size: %d"
,
g_size
)
;
$
error
(
"Unsupported Spartan-6 IRAM size: %d"
,
g_size
)
;
$
stop
;
$
stop
;
end
end
end
// else: !if(g_size == 16384)
end
// else: !if(g_size == 16384)
end
else
begin
// if (!g_simulation)
end
else
begin
// if (!g_simulation)
// synthesis translate_off
// synthesis translate_off
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
begin
begin
if
(
ena_i
)
if
(
ena_i
)
begin
begin
...
@@ -221,14 +221,14 @@ module urv_iram
...
@@ -221,14 +221,14 @@ module urv_iram
mem
[(
ab_i
/
4
)
%
g_size
][
31
:
24
]
<=
db_i
[
31
:
24
]
;
mem
[(
ab_i
/
4
)
%
g_size
][
31
:
24
]
<=
db_i
[
31
:
24
]
;
end
end
end
// always@ (posedge clk_i)
end
// always@ (posedge clk_i)
assign
qa_o
=
qa_int
;
assign
qa_o
=
qa_int
;
assign
qb_o
=
qb_int
;
assign
qb_o
=
qb_int
;
// synthesis translate_on
// synthesis translate_on
end
// else: !if(!g_simulation)
end
// else: !if(!g_simulation)
...
@@ -237,7 +237,6 @@ module urv_iram
...
@@ -237,7 +237,6 @@ module urv_iram
endgenerate
endgenerate
// synthesis translate_off
// synthesis translate_off
...
@@ -245,30 +244,30 @@ module urv_iram
...
@@ -245,30 +244,30 @@ module urv_iram
integer
tmp
,
f
,
addr
;
integer
tmp
,
f
,
addr
;
reg
[
31
:
0
]
data
;
reg
[
31
:
0
]
data
;
reg
[
8
*
20
-
1
:
0
]
cmd
;
reg
[
8
*
20
-
1
:
0
]
cmd
;
initial
begin
initial
begin
if
(
g_simulation
&&
g_init_file
!=
""
)
begin
:
init_ram_contents
if
(
g_simulation
&&
g_init_file
!=
""
)
begin
:
init_ram_contents
$
display
(
"Initializing RAM contents from %s"
,
g_init_file
)
;
$
display
(
"Initializing RAM contents from %s"
,
g_init_file
)
;
f
=
$
fopen
(
g_init_file
,
"r"
)
;
f
=
$
fopen
(
g_init_file
,
"r"
)
;
if
(
f
==
0
)
if
(
f
==
0
)
begin
begin
$
error
(
"can't open: %s"
,
g_init_file
)
;
$
error
(
"can't open: %s"
,
g_init_file
)
;
$
stop
;
$
stop
;
end
end
while
(
!
$
feof
(
f
))
while
(
!
$
feof
(
f
))
begin
begin
tmp
=
$
fscanf
(
f
,
"%s %08x %08x"
,
cmd
,
addr
,
data
)
;
tmp
=
$
fscanf
(
f
,
"%s %08x %08x"
,
cmd
,
addr
,
data
)
;
if
(
cmd
==
"write"
)
if
(
cmd
==
"write"
)
begin
begin
mem
[
addr
%
g_size
][
31
:
24
]
=
data
[
31
:
24
]
;
mem
[
addr
%
g_size
][
31
:
24
]
=
data
[
31
:
24
]
;
...
@@ -279,10 +278,10 @@ module urv_iram
...
@@ -279,10 +278,10 @@ module urv_iram
end
end
end
// if (g_simulation && g_init_file != "")
end
// if (g_simulation && g_init_file != "")
end
end
// synthesis translate_on
// synthesis translate_on
endmodule
// urv_iram
endmodule
// urv_iram
...
@@ -295,7 +294,7 @@ module urv_iram
...
@@ -295,7 +294,7 @@ module urv_iram
parameter
g_size
=
65536
,
parameter
g_size
=
65536
,
parameter
g_init_file
=
""
,
parameter
g_init_file
=
""
,
parameter
g_simulation
=
0
parameter
g_simulation
=
0
)
)
(
(
input
clk_i
,
input
clk_i
,
...
@@ -304,7 +303,7 @@ module urv_iram
...
@@ -304,7 +303,7 @@ module urv_iram
input
[
31
:
0
]
aa_i
,
input
[
31
:
0
]
aa_i
,
input
[
3
:
0
]
bwea_i
,
input
[
3
:
0
]
bwea_i
,
input
[
31
:
0
]
da_i
,
input
[
31
:
0
]
da_i
,
output
[
31
:
0
]
qa_o
,
output
[
31
:
0
]
qa_o
,
input
enb_i
,
input
enb_i
,
input
web_i
,
input
web_i
,
input
[
31
:
0
]
ab_i
,
input
[
31
:
0
]
ab_i
,
...
@@ -317,11 +316,11 @@ module urv_iram
...
@@ -317,11 +316,11 @@ module urv_iram
reg
[
31
:
0
]
mem
[
0
:
g_size
/
4
-
1
]
;
reg
[
31
:
0
]
mem
[
0
:
g_size
/
4
-
1
]
;
reg
[
31
:
0
]
qa_int
,
qb_int
;
reg
[
31
:
0
]
qa_int
,
qb_int
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
begin
begin
if
(
ena_i
)
if
(
ena_i
)
begin
begin
...
@@ -351,17 +350,17 @@ module urv_iram
...
@@ -351,17 +350,17 @@ module urv_iram
mem
[(
ab_i
/
4
)][
31
:
24
]
<=
db_i
[
31
:
24
]
;
mem
[(
ab_i
/
4
)][
31
:
24
]
<=
db_i
[
31
:
24
]
;
end
end
end
// always@ (posedge clk_i)
end
// always@ (posedge clk_i)
assign
qa_o
=
qa_int
;
assign
qa_o
=
qa_int
;
assign
qb_o
=
qb_int
;
assign
qb_o
=
qb_int
;
// end // else: !if(!g_simulation)
// end // else: !if(!g_simulation)
endmodule
endmodule
`endif
`endif
`ifdef
URV_PLATFORM_ALTERA
`ifdef
URV_PLATFORM_ALTERA
...
@@ -370,7 +369,7 @@ module urv_iram
...
@@ -370,7 +369,7 @@ module urv_iram
parameter
g_size
=
65536
,
parameter
g_size
=
65536
,
parameter
g_init_file
=
""
,
parameter
g_init_file
=
""
,
parameter
g_simulation
=
0
parameter
g_simulation
=
0
)
)
(
(
input
clk_i
,
input
clk_i
,
...
@@ -379,7 +378,7 @@ module urv_iram
...
@@ -379,7 +378,7 @@ module urv_iram
input
[
31
:
0
]
aa_i
,
input
[
31
:
0
]
aa_i
,
input
[
3
:
0
]
bwea_i
,
input
[
3
:
0
]
bwea_i
,
input
[
31
:
0
]
da_i
,
input
[
31
:
0
]
da_i
,
output
[
31
:
0
]
qa_o
,
output
[
31
:
0
]
qa_o
,
input
enb_i
,
input
enb_i
,
input
web_i
,
input
web_i
,
input
[
31
:
0
]
ab_i
,
input
[
31
:
0
]
ab_i
,
...
@@ -389,7 +388,7 @@ module urv_iram
...
@@ -389,7 +388,7 @@ module urv_iram
)
;
)
;
localparam
g_addr_width
=
(
g_size
==
65536
?
14
:
0
)
;
localparam
g_addr_width
=
(
g_size
==
65536
?
14
:
0
)
;
altsyncram
altsyncram
ram
(
ram
(
.
address_a
(
aa_i
[
g_addr_width
+
1
:
2
])
,
.
address_a
(
aa_i
[
g_addr_width
+
1
:
2
])
,
...
@@ -454,4 +453,3 @@ endmodule // urv_iram
...
@@ -454,4 +453,3 @@ endmodule // urv_iram
`endif
// `ifdef URV_PLATFORM_ALTERA
`endif
// `ifdef URV_PLATFORM_ALTERA
rtl/urv_multiply.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -29,9 +29,9 @@ module urv_mult18x18
...
@@ -29,9 +29,9 @@ module urv_mult18x18
(
(
input
clk_i
,
input
clk_i
,
input
rst_i
,
input
rst_i
,
input
stall_i
,
input
stall_i
,
input
[
17
:
0
]
x_i
,
input
[
17
:
0
]
x_i
,
input
[
17
:
0
]
y_i
,
input
[
17
:
0
]
y_i
,
...
@@ -99,9 +99,9 @@ module urv_mult18x18
...
@@ -99,9 +99,9 @@ module urv_mult18x18
(
(
input
clk_i
,
input
clk_i
,
input
rst_i
,
input
rst_i
,
input
stall_i
,
input
stall_i
,
input
[
17
:
0
]
x_i
,
input
[
17
:
0
]
x_i
,
input
[
17
:
0
]
y_i
,
input
[
17
:
0
]
y_i
,
...
@@ -112,7 +112,7 @@ module urv_mult18x18
...
@@ -112,7 +112,7 @@ module urv_mult18x18
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
stall_i
)
if
(
!
stall_i
)
q_o
<=
x_i
*
y_i
;
q_o
<=
x_i
*
y_i
;
endmodule
// urv_mult18x18
endmodule
// urv_mult18x18
`endif
// `ifdef URV_PLATFORM_GENERIC
`endif
// `ifdef URV_PLATFORM_GENERIC
...
@@ -122,9 +122,9 @@ module urv_mult18x18
...
@@ -122,9 +122,9 @@ module urv_mult18x18
(
(
input
clk_i
,
input
clk_i
,
input
rst_i
,
input
rst_i
,
input
stall_i
,
input
stall_i
,
input
[
17
:
0
]
x_i
,
input
[
17
:
0
]
x_i
,
input
[
17
:
0
]
y_i
,
input
[
17
:
0
]
y_i
,
...
@@ -155,12 +155,12 @@ endmodule // urv_mult18x18
...
@@ -155,12 +155,12 @@ endmodule // urv_mult18x18
`endif
`endif
module
urv_multiply
module
urv_multiply
(
(
input
clk_i
,
input
clk_i
,
input
rst_i
,
input
rst_i
,
input
x_stall_i
,
input
x_stall_i
,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_rs1_i
,
input
[
31
:
0
]
d_rs2_i
,
input
[
31
:
0
]
d_rs2_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
2
:
0
]
d_fun_i
,
...
@@ -179,8 +179,8 @@ module urv_multiply
...
@@ -179,8 +179,8 @@ module urv_multiply
wire
[
17
:
0
]
yh
=
{
{
3
{
d_rs2_i
[
31
]
}},
d_rs2_i
[
31
:
17
]
};
wire
[
17
:
0
]
yh
=
{
{
3
{
d_rs2_i
[
31
]
}},
d_rs2_i
[
31
:
17
]
};
wire
[
35
:
0
]
yl_xl
,
yl_xh
,
yh_xl
;
wire
[
35
:
0
]
yl_xl
,
yl_xh
,
yh_xl
;
urv_mult18x18
mul0
urv_mult18x18
mul0
(
(
.
clk_i
(
clk_i
)
,
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
rst_i
(
rst_i
)
,
...
@@ -212,13 +212,8 @@ module urv_multiply
...
@@ -212,13 +212,8 @@ module urv_multiply
.
y_i
(
xh
)
,
.
y_i
(
xh
)
,
.
q_o
(
yl_xh
)
.
q_o
(
yl_xh
)
)
;
)
;
always
@*
always
@*
w_rd_o
<=
yl_xl
+
{
yl_xh
[
14
:
0
]
,
17'h0
}
+
{
yh_xl
[
14
:
0
]
,
17'h0
};
w_rd_o
<=
yl_xl
+
{
yl_xh
[
14
:
0
]
,
17'h0
}
+
{
yh_xl
[
14
:
0
]
,
17'h0
};
endmodule
// urv_multiply
endmodule
// urv_multiply
rtl/urv_regfile.v
View file @
8efd2565
/*
/*
uRV - a tiny and dumb RISC-V core
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 CERN
Copyright (c) 2015 CERN
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -38,7 +38,7 @@ module urv_regmem
...
@@ -38,7 +38,7 @@ module urv_regmem
)
;
)
;
reg
[
31
:
0
]
ram
[
0
:
31
]
;
reg
[
31
:
0
]
ram
[
0
:
31
]
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
en1_i
)
if
(
en1_i
)
q1_o
<=
ram
[
a1_i
]
;
q1_o
<=
ram
[
a1_i
]
;
...
@@ -56,7 +56,7 @@ module urv_regmem
...
@@ -56,7 +56,7 @@ module urv_regmem
end
end
end
end
// synthesis translate_on
// synthesis translate_on
endmodule
endmodule
module
urv_regfile
module
urv_regfile
...
@@ -81,7 +81,7 @@ module urv_regfile
...
@@ -81,7 +81,7 @@ module urv_regfile
input
w_bypass_rd_write_i
,
input
w_bypass_rd_write_i
,
input
[
31
:
0
]
w_bypass_rd_value_i
input
[
31
:
0
]
w_bypass_rd_value_i
)
;
)
;
...
@@ -89,7 +89,7 @@ module urv_regfile
...
@@ -89,7 +89,7 @@ module urv_regfile
wire
[
31
:
0
]
rs2_regfile
;
wire
[
31
:
0
]
rs2_regfile
;
wire
write
=
(
w_rd_store_i
&&
(
w_rd_i
!=
0
))
;
wire
write
=
(
w_rd_store_i
&&
(
w_rd_i
!=
0
))
;
urv_regmem
bank0
urv_regmem
bank0
(
(
.
clk_i
(
clk_i
)
,
.
clk_i
(
clk_i
)
,
.
rst_i
(
rst_i
)
,
.
rst_i
(
rst_i
)
,
...
@@ -100,8 +100,8 @@ module urv_regfile
...
@@ -100,8 +100,8 @@ module urv_regfile
.
a2_i
(
w_rd_i
)
,
.
a2_i
(
w_rd_i
)
,
.
d2_i
(
w_rd_value_i
)
,
.
d2_i
(
w_rd_value_i
)
,
.
we2_i
(
write
))
;
.
we2_i
(
write
))
;
urv_regmem
bank1
urv_regmem
bank1
(
(
.
clk_i
(
clk_i
)
,
.
clk_i
(
clk_i
)
,
...
@@ -114,12 +114,12 @@ module urv_regfile
...
@@ -114,12 +114,12 @@ module urv_regfile
.
d2_i
(
w_rd_value_i
)
,
.
d2_i
(
w_rd_value_i
)
,
.
we2_i
(
write
)
.
we2_i
(
write
)
)
;
)
;
wire
rs1_bypass_x
=
w_bypass_rd_write_i
&&
(
w_rd_i
==
d_rs1_i
)
&&
(
w_rd_i
!=
0
)
;
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
)
;
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
;
reg
rs1_bypass_w
,
rs2_bypass_w
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
if
(
rst_i
)
begin
begin
...
@@ -129,7 +129,7 @@ module urv_regfile
...
@@ -129,7 +129,7 @@ module urv_regfile
rs1_bypass_w
<=
write
&&
(
rf_rs1_i
==
w_rd_i
)
;
rs1_bypass_w
<=
write
&&
(
rf_rs1_i
==
w_rd_i
)
;
rs2_bypass_w
<=
write
&&
(
rf_rs2_i
==
w_rd_i
)
;
rs2_bypass_w
<=
write
&&
(
rf_rs2_i
==
w_rd_i
)
;
end
end
reg
[
31
:
0
]
bypass_w
;
reg
[
31
:
0
]
bypass_w
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
...
@@ -153,9 +153,8 @@ module urv_regfile
...
@@ -153,9 +153,8 @@ module urv_regfile
2'b01
:
2'b01
:
x_rs2_value_o
<=
bypass_w
;
x_rs2_value_o
<=
bypass_w
;
default:
default:
x_rs2_value_o
<=
rs2_regfile
;
x_rs2_value_o
<=
rs2_regfile
;
endcase
// case ( {rs2_bypass_x, rs2_bypass_w } )
endcase
// case ( {rs2_bypass_x, rs2_bypass_w } )
end
// always@ *
end
// always@ *
endmodule
// urv_regfile
endmodule
// urv_regfile
rtl/urv_shifter.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -39,7 +39,7 @@ module urv_shifter
...
@@ -39,7 +39,7 @@ module urv_shifter
input
d_valid_i
,
input
d_valid_i
,
input
[
31
:
0
]
d_rs1_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
[
4
:
0
]
d_shamt_i
,
input
[
2
:
0
]
d_fun_i
,
input
[
2
:
0
]
d_fun_i
,
input
d_shifter_sign_i
,
input
d_shifter_sign_i
,
...
@@ -61,9 +61,9 @@ module urv_shifter
...
@@ -61,9 +61,9 @@ module urv_shifter
reg
s2_extend_sign
;
reg
s2_extend_sign
;
reg
[
4
:
0
]
s2_shift
;
reg
[
4
:
0
]
s2_shift
;
reg
[
2
:
0
]
s2_func
;
reg
[
2
:
0
]
s2_func
;
// stage 1 pipe register
// stage 1 pipe register
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
!
x_stall_i
)
if
(
!
x_stall_i
)
...
@@ -73,9 +73,9 @@ module urv_shifter
...
@@ -73,9 +73,9 @@ module urv_shifter
s2_func
<=
d_fun_i
;
s2_func
<=
d_fun_i
;
s1_out
<=
shift_8
;
s1_out
<=
shift_8
;
end
end
reg
[
31
:
0
]
shift_4
,
shift_2
,
shift_1
,
shift_post
;
reg
[
31
:
0
]
shift_4
,
shift_2
,
shift_1
,
shift_post
;
// stage 2
// stage 2
always
@*
always
@*
begin
begin
...
@@ -89,4 +89,3 @@ module urv_shifter
...
@@ -89,4 +89,3 @@ module urv_shifter
w_rd_o
<=
shift_post
;
w_rd_o
<=
shift_post
;
endmodule
// urv_shifter
endmodule
// urv_shifter
rtl/urv_timer.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -30,7 +30,7 @@ module urv_timer
...
@@ -30,7 +30,7 @@ module urv_timer
output
[
39
:
0
]
csr_time_o
,
output
[
39
:
0
]
csr_time_o
,
output
[
39
:
0
]
csr_cycles_o
,
output
[
39
:
0
]
csr_cycles_o
,
output
sys_tick_o
output
sys_tick_o
)
;
)
;
...
@@ -38,13 +38,13 @@ module urv_timer
...
@@ -38,13 +38,13 @@ module urv_timer
parameter
g_clock_frequency
=
62500000
;
parameter
g_clock_frequency
=
62500000
;
localparam
g_prescaler
=
(
g_clock_frequency
/
g_timer_frequency
)
-
1
;
localparam
g_prescaler
=
(
g_clock_frequency
/
g_timer_frequency
)
-
1
;
reg
[
23
:
0
]
presc
;
reg
[
23
:
0
]
presc
;
reg
presc_tick
;
reg
presc_tick
;
reg
[
39
:
0
]
cycles
;
reg
[
39
:
0
]
cycles
;
reg
[
39
:
0
]
ticks
;
reg
[
39
:
0
]
ticks
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
if
(
rst_i
)
begin
begin
...
@@ -65,16 +65,16 @@ module urv_timer
...
@@ -65,16 +65,16 @@ module urv_timer
ticks
<=
0
;
ticks
<=
0
;
else
if
(
presc_tick
)
else
if
(
presc_tick
)
ticks
<=
ticks
+
1
;
ticks
<=
ticks
+
1
;
always
@
(
posedge
clk_i
)
always
@
(
posedge
clk_i
)
if
(
rst_i
)
if
(
rst_i
)
cycles
<=
0
;
cycles
<=
0
;
else
else
cycles
<=
cycles
+
1
;
cycles
<=
cycles
+
1
;
assign
csr_time_o
=
ticks
;
assign
csr_time_o
=
ticks
;
assign
csr_cycles_o
=
cycles
;
assign
csr_cycles_o
=
cycles
;
assign
sys_tick_o
=
presc_tick
;
assign
sys_tick_o
=
presc_tick
;
endmodule
// urv_timer
endmodule
// urv_timer
rtl/urv_writeback.v
View file @
8efd2565
...
@@ -16,7 +16,7 @@
...
@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -30,17 +30,17 @@ module urv_writeback
...
@@ -30,17 +30,17 @@ module urv_writeback
input
w_stall_i
,
input
w_stall_i
,
output
w_stall_req_o
,
output
w_stall_req_o
,
input
[
2
:
0
]
x_fun_i
,
input
[
2
:
0
]
x_fun_i
,
input
x_load_i
,
input
x_load_i
,
input
x_store_i
,
input
x_store_i
,
input
[
31
:
0
]
x_dm_addr_i
,
input
[
31
:
0
]
x_dm_addr_i
,
input
[
4
:
0
]
x_rd_i
,
input
[
4
:
0
]
x_rd_i
,
input
[
31
:
0
]
x_rd_value_i
,
input
[
31
:
0
]
x_rd_value_i
,
input
x_rd_write_i
,
input
x_rd_write_i
,
input
x_valid_i
,
input
x_valid_i
,
input
[
31
:
0
]
x_shifter_rd_value_i
,
input
[
31
:
0
]
x_shifter_rd_value_i
,
input
[
31
:
0
]
x_multiply_rd_value_i
,
input
[
31
:
0
]
x_multiply_rd_value_i
,
...
@@ -49,7 +49,7 @@ module urv_writeback
...
@@ -49,7 +49,7 @@ module urv_writeback
input
[
31
:
0
]
dm_data_l_i
,
input
[
31
:
0
]
dm_data_l_i
,
input
dm_load_done_i
,
input
dm_load_done_i
,
input
dm_store_done_i
,
input
dm_store_done_i
,
output
[
31
:
0
]
rf_rd_value_o
,
output
[
31
:
0
]
rf_rd_value_o
,
output
[
4
:
0
]
rf_rd_o
,
output
[
4
:
0
]
rf_rd_o
,
output
rf_rd_write_o
output
rf_rd_write_o
...
@@ -69,7 +69,7 @@ module urv_writeback
...
@@ -69,7 +69,7 @@ module urv_writeback
2'b11
:
load_value
<=
{{
24
{
dm_data_l_i
[
31
]
}},
dm_data_l_i
[
31
:
24
]
};
2'b11
:
load_value
<=
{{
24
{
dm_data_l_i
[
31
]
}},
dm_data_l_i
[
31
:
24
]
};
default:
load_value
<=
32
'
hx
;
default:
load_value
<=
32
'
hx
;
endcase
// case ( x_dm_addr_i [1:0] )
endcase
// case ( x_dm_addr_i [1:0] )
`LDST_BU
:
`LDST_BU
:
case
(
x_dm_addr_i
[
1
:
0
]
)
case
(
x_dm_addr_i
[
1
:
0
]
)
2'b00
:
load_value
<=
{
24'h0
,
dm_data_l_i
[
7
:
0
]
};
2'b00
:
load_value
<=
{
24'h0
,
dm_data_l_i
[
7
:
0
]
};
...
@@ -78,7 +78,7 @@ module urv_writeback
...
@@ -78,7 +78,7 @@ module urv_writeback
2'b11
:
load_value
<=
{
24'h0
,
dm_data_l_i
[
31
:
24
]
};
2'b11
:
load_value
<=
{
24'h0
,
dm_data_l_i
[
31
:
24
]
};
default:
load_value
<=
32
'
hx
;
default:
load_value
<=
32
'
hx
;
endcase
// case ( x_dm_addr_i [1:0] )
endcase
// case ( x_dm_addr_i [1:0] )
`LDST_H
:
`LDST_H
:
case
(
x_dm_addr_i
[
1
:
0
]
)
case
(
x_dm_addr_i
[
1
:
0
]
)
2'b00
,
2'b01
:
load_value
<=
{{
16
{
dm_data_l_i
[
15
]
}},
dm_data_l_i
[
15
:
0
]
};
2'b00
,
2'b01
:
load_value
<=
{{
16
{
dm_data_l_i
[
15
]
}},
dm_data_l_i
[
15
:
0
]
};
...
@@ -92,7 +92,7 @@ module urv_writeback
...
@@ -92,7 +92,7 @@ module urv_writeback
2'b10
,
2'b11
:
load_value
<=
{
16'h0
,
dm_data_l_i
[
31
:
16
]
};
2'b10
,
2'b11
:
load_value
<=
{
16'h0
,
dm_data_l_i
[
31
:
16
]
};
default:
load_value
<=
32
'
hx
;
default:
load_value
<=
32
'
hx
;
endcase
// case ( x_dm_addr_i [1:0] )
endcase
// case ( x_dm_addr_i [1:0] )
`LDST_L
:
load_value
<=
dm_data_l_i
;
`LDST_L
:
load_value
<=
dm_data_l_i
;
default:
load_value
<=
32
'
hx
;
default:
load_value
<=
32
'
hx
;
...
@@ -101,7 +101,7 @@ module urv_writeback
...
@@ -101,7 +101,7 @@ module urv_writeback
reg
rf_rd_write
;
reg
rf_rd_write
;
reg
[
31
:
0
]
rf_rd_value
;
reg
[
31
:
0
]
rf_rd_value
;
always
@*
always
@*
if
(
x_load_i
)
if
(
x_load_i
)
rf_rd_value
<=
load_value
;
rf_rd_value
<=
load_value
;
...
...
rtl/xurv_core.vhd
View file @
8efd2565
--
--
-- uRV - a tiny and dumb RISC-V core
-- uRV - a tiny and dumb RISC-V core
-- Copyright (c) 2015 CERN
-- Copyright (c) 2015 CERN
-- Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
-- Author: Tomasz Włostowski <tomasz.wlostowski@cern.ch>
--
--
-- This library is free software; you can redistribute it and/or
-- This library is free software; you can redistribute it and/or
-- modify it under the terms of the GNU Lesser General Public
-- modify it under the terms of the GNU Lesser General Public
-- License as published by the Free Software Foundation; either
-- License as published by the Free Software Foundation; either
-- version 3.0 of the License, or (at your option) any later version.
-- 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,
-- This library is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
-- Lesser General Public License for more details.
-- Lesser General Public License for more details.
--
--
-- You should have received a copy of the GNU Lesser General Public
-- You should have received a copy of the GNU Lesser General Public
-- License along with this library.
-- License along with this library.
--
--
...
@@ -82,7 +82,7 @@ architecture wrapper of xurv_core is
...
@@ -82,7 +82,7 @@ architecture wrapper of xurv_core is
g_size
:
integer
;
g_size
:
integer
;
g_init_file
:
string
;
g_init_file
:
string
;
g_simulation
:
boolean
g_simulation
:
boolean
);
);
port
(
port
(
clk_i
:
in
std_logic
;
clk_i
:
in
std_logic
;
...
@@ -123,7 +123,7 @@ architecture wrapper of xurv_core is
...
@@ -123,7 +123,7 @@ architecture wrapper of xurv_core is
signal
dm_mem_rdata
,
dm_wb_rdata
:
std_logic_vector
(
31
downto
0
);
signal
dm_mem_rdata
,
dm_wb_rdata
:
std_logic_vector
(
31
downto
0
);
signal
dm_wb_write
,
dm_select_wb
:
std_logic
;
signal
dm_wb_write
,
dm_select_wb
:
std_logic
;
signal
dm_data_write
:
std_logic
;
signal
dm_data_write
:
std_logic
;
begin
begin
cpu_rst
<=
(
not
rst_n_i
)
or
cpu_rst_i
;
cpu_rst
<=
(
not
rst_n_i
)
or
cpu_rst_i
;
...
@@ -137,7 +137,7 @@ begin
...
@@ -137,7 +137,7 @@ begin
ha_im_access_d
<=
'0'
;
ha_im_access_d
<=
'0'
;
ha_im_write
<=
'0'
;
ha_im_write
<=
'0'
;
else
else
ha_im_access
<=
host_slave_i
.
cyc
and
host_slave_i
.
stb
;
ha_im_access
<=
host_slave_i
.
cyc
and
host_slave_i
.
stb
;
ha_im_access_d
<=
ha_im_access
;
ha_im_access_d
<=
ha_im_access
;
...
@@ -169,7 +169,7 @@ begin
...
@@ -169,7 +169,7 @@ begin
dm_store_done
<=
'0'
;
dm_store_done
<=
'0'
;
dm_select_wb
<=
'0'
;
dm_select_wb
<=
'0'
;
else
else
if
(
dm_cycle_in_progress
=
'0'
)
then
-- access to internal memory
if
(
dm_cycle_in_progress
=
'0'
)
then
-- access to internal memory
if
(
dm_is_wishbone
=
'0'
)
then
if
(
dm_is_wishbone
=
'0'
)
then
if
(
dm_store
=
'1'
)
then
if
(
dm_store
=
'1'
)
then
...
@@ -294,7 +294,5 @@ begin
...
@@ -294,7 +294,5 @@ begin
host_slave_o
.
err
<=
'0'
;
host_slave_o
.
err
<=
'0'
;
host_slave_o
.
rty
<=
'0'
;
host_slave_o
.
rty
<=
'0'
;
end
wrapper
;
end
wrapper
;
tb/isa-testsuite/main.sv
View file @
8efd2565
/*
/*
uRV - a tiny and dumb RISC-V core
uRV - a tiny and dumb RISC-V core
Copyright (c) 2015 twl <twlostow@printf.cc>.
Copyright (c) 2015 twl <twlostow@printf.cc>.
...
@@ -15,7 +15,7 @@
...
@@ -15,7 +15,7 @@
You should have received a copy of the GNU Lesser General Public
You should have received a copy of the GNU Lesser General Public
License along with this library.
License along with this library.
*/
*/
`include
"urv_defs.v"
`include
"urv_defs.v"
...
@@ -24,14 +24,14 @@
...
@@ -24,14 +24,14 @@
module
main
;
module
main
;
reg
clk
=
0
;
reg
clk
=
0
;
reg
rst
=
1
;
reg
rst
=
1
;
wire
[
31
:
0
]
im_addr
;
wire
[
31
:
0
]
im_addr
;
reg
[
31
:
0
]
im_data
;
reg
[
31
:
0
]
im_data
;
reg
im_valid
;
reg
im_valid
;
wire
[
31
:
0
]
dm_addr
;
wire
[
31
:
0
]
dm_addr
;
wire
[
31
:
0
]
dm_data_s
;
wire
[
31
:
0
]
dm_data_s
;
...
@@ -40,9 +40,9 @@ module main;
...
@@ -40,9 +40,9 @@ module main;
wire
dm_write
;
wire
dm_write
;
reg
dm_valid_l
=
1
;
reg
dm_valid_l
=
1
;
reg
dm_ready
;
reg
dm_ready
;
localparam
int
mem_size
=
16384
;
localparam
int
mem_size
=
16384
;
reg
[
31
:
0
]
mem
[
0
:
mem_size
-
1
]
;
reg
[
31
:
0
]
mem
[
0
:
mem_size
-
1
]
;
task
automatic
load_ram
(
string
filename
)
;
task
automatic
load_ram
(
string
filename
)
;
...
@@ -54,9 +54,9 @@ module main;
...
@@ -54,9 +54,9 @@ module main;
$
error
(
"can't open: %s"
,
filename
)
;
$
error
(
"can't open: %s"
,
filename
)
;
$
stop
;
$
stop
;
end
end
while
(
!
$
feof
(
f
))
while
(
!
$
feof
(
f
))
begin
begin
int
addr
,
data
;
int
addr
,
data
;
...
@@ -68,13 +68,13 @@ module main;
...
@@ -68,13 +68,13 @@ module main;
mem
[
addr
%
mem_size
]
=
data
;
mem
[
addr
%
mem_size
]
=
data
;
end
end
end
end
endtask
// load_ram
endtask
// load_ram
int
seed
;
int
seed
;
always
@
(
posedge
clk
)
always
@
(
posedge
clk
)
begin
begin
if
(
$
dist_uniform
(
seed
,
0
,
100
)
<=
100
)
begin
if
(
$
dist_uniform
(
seed
,
0
,
100
)
<=
100
)
begin
...
@@ -82,8 +82,8 @@ module main;
...
@@ -82,8 +82,8 @@ module main;
im_valid
<=
1
;
im_valid
<=
1
;
end
else
end
else
im_valid
<=
0
;
im_valid
<=
0
;
if
(
dm_write
&&
dm_data_select
[
0
])
if
(
dm_write
&&
dm_data_select
[
0
])
mem
[(
dm_addr
/
4
)
%
mem_size
][
7
:
0
]
<=
dm_data_s
[
7
:
0
]
;
mem
[(
dm_addr
/
4
)
%
mem_size
][
7
:
0
]
<=
dm_data_s
[
7
:
0
]
;
...
@@ -93,23 +93,23 @@ module main;
...
@@ -93,23 +93,23 @@ module main;
mem
[(
dm_addr
/
4
)
%
mem_size
][
23
:
16
]
<=
dm_data_s
[
23
:
16
]
;
mem
[(
dm_addr
/
4
)
%
mem_size
][
23
:
16
]
<=
dm_data_s
[
23
:
16
]
;
if
(
dm_write
&&
dm_data_select
[
3
])
if
(
dm_write
&&
dm_data_select
[
3
])
mem
[(
dm_addr
/
4
)
%
mem_size
][
31
:
24
]
<=
dm_data_s
[
31
:
24
]
;
mem
[(
dm_addr
/
4
)
%
mem_size
][
31
:
24
]
<=
dm_data_s
[
31
:
24
]
;
// dm_data_l <= mem[(dm_addr/4) % mem_size];
// dm_data_l <= mem[(dm_addr/4) % mem_size];
end
// always@ (posedge clk)
end
// always@ (posedge clk)
always
@
(
posedge
clk
)
always
@
(
posedge
clk
)
begin
begin
dm_ready
<=
1'b1
;
// $dist_uniform(seed, 0, 100 ) <= 50;
dm_ready
<=
1'b1
;
// $dist_uniform(seed, 0, 100 ) <= 50;
dm_data_l
<=
mem
[(
dm_addr
/
4
)
%
mem_size
]
;
dm_data_l
<=
mem
[(
dm_addr
/
4
)
%
mem_size
]
;
end
end
urv_cpu
DUT
urv_cpu
DUT
(
(
...
@@ -117,7 +117,7 @@ module main;
...
@@ -117,7 +117,7 @@ module main;
.
rst_i
(
rst
)
,
.
rst_i
(
rst
)
,
.
irq_i
(
irq
)
,
.
irq_i
(
irq
)
,
// instruction mem I/F
// instruction mem I/F
.
im_addr_o
(
im_addr
)
,
.
im_addr_o
(
im_addr
)
,
.
im_data_i
(
im_data
)
,
.
im_data_i
(
im_data
)
,
...
@@ -134,13 +134,13 @@ module main;
...
@@ -134,13 +134,13 @@ module main;
.
dm_load_done_i
(
1'b1
)
,
.
dm_load_done_i
(
1'b1
)
,
.
dm_ready_i
(
dm_ready
)
.
dm_ready_i
(
dm_ready
)
)
;
)
;
always
#
5
ns
clk
<=
~
clk
;
always
#
5
ns
clk
<=
~
clk
;
integer
f_console
,
f_exec_log
;
integer
f_console
,
f_exec_log
;
reg
test_complete
=
0
;
reg
test_complete
=
0
;
initial
begin
initial
begin
string
tests
[$]
;
string
tests
[$]
;
const
string
test_dir
=
"../../sw/testsuite/isa"
;
const
string
test_dir
=
"../../sw/testsuite/isa"
;
...
@@ -158,8 +158,8 @@ module main;
...
@@ -158,8 +158,8 @@ module main;
void
'
($
fscanf
(
f
,
"%s"
,
fname
))
;
void
'
($
fscanf
(
f
,
"%s"
,
fname
))
;
tests
.
push_back
(
fname
)
;
tests
.
push_back
(
fname
)
;
end
end
...
@@ -172,16 +172,16 @@ module main;
...
@@ -172,16 +172,16 @@ module main;
repeat
(
3
)
@
(
posedge
clk
)
;
repeat
(
3
)
@
(
posedge
clk
)
;
rst
=
0
;
rst
=
0
;
test_complete
=
0
;
test_complete
=
0
;
while
(
!
test_complete
)
while
(
!
test_complete
)
#
1u
s
;
#
1u
s
;
end
end
end
// initial begin
end
// initial begin
always
@
(
posedge
clk
)
always
@
(
posedge
clk
)
if
(
dm_write
)
if
(
dm_write
)
begin
begin
...
@@ -199,5 +199,5 @@ module main;
...
@@ -199,5 +199,5 @@ module main;
test_complete
=
1
;
test_complete
=
1
;
end
end
end
end
endmodule
// main
endmodule
// main
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