Commit 014209e9 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

code cleanup & relicensing

parent 695e8467
sim_tool = "modelsim"
top_module="main"
syn_device="xc6slx150t"
action = "simulation"
target = "xilinx"
include_dirs=["."] include_dirs=["."]
files = [ "rv_cpu.v", files = [ "urv_cpu.v",
"rv_exec.v", "urv_exec.v",
"rv_fetch.v", "urv_fetch.v",
"rv_predecode.v", "urv_decode.v",
"rv_regfile.v", "urv_regfile.v",
"rv_writeback.v", "urv_writeback.v",
"rv_shifter.v", "urv_shifter.v",
"rv_multiply.v", "urv_multiply.v",
"rv_divide.v", "urv_divide.v",
"rv_csr.v", "urv_csr.v",
"rv_timer.v", "urv_timer.v",
"rv_exceptions.v", "urv_exceptions.v",
"urv_iram.v", "urv_iram.v",
"xrv_core.vhd" ]; "xurv_core.vhd" ];
# "../sim/rv_icache_model.sv"]; # "../sim/rv_icache_model.sv"];
This diff is collapsed.
/* /*
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 CERN
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
...@@ -18,11 +19,11 @@ ...@@ -18,11 +19,11 @@
*/ */
`include "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
module rv_csr module urv_csr
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
......
`timescale 1ns/1ps
`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
/* /*
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 CERN
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
...@@ -18,50 +19,40 @@ ...@@ -18,50 +19,40 @@
*/ */
`include "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
module urv_decode
module rv_decode
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
// pipeline control
input d_stall_i, input d_stall_i,
input d_kill_i, input d_kill_i,
output d_stall_req_o, output d_stall_req_o,
output reg x_load_hazard_o, // from Fetch stage
input [31:0] f_ir_i, input [31:0] f_ir_i,
input [31:0] f_pc_i, input [31:0] f_pc_i,
input f_valid_i, input f_valid_i,
output x_valid_o, // to Register File
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,
output [4:0] rf_rs1_o, output [4:0] rf_rs1_o,
output [4:0] rf_rs2_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_rs1_o,
output [4:0] x_rs2_o, output [4:0] x_rs2_o,
output [4:0] x_rd_o, output [4:0] x_rd_o,
output reg [4:0] x_shamt_o, output reg [4:0] x_shamt_o,
output reg [2:0] x_fun_o, output reg [2:0] x_fun_o,
output [4:0] x_opcode_o, output [4:0] x_opcode_o,
output reg x_shifter_sign_o, output reg x_shifter_sign_o,
output reg x_is_signed_compare_o, output reg x_is_signed_compare_o,
output reg x_is_signed_alu_op_o, output reg x_is_signed_alu_op_o,
output reg x_is_add_o, output reg x_is_add_o,
...@@ -69,40 +60,35 @@ module rv_decode ...@@ -69,40 +60,35 @@ module rv_decode
output reg x_is_load_o, output reg x_is_load_o,
output reg x_is_store_o, output reg x_is_store_o,
output reg x_is_undef_o, output reg x_is_undef_o,
output reg [2:0] x_rd_source_o, output reg [2:0] x_rd_source_o,
output x_rd_write_o, output x_rd_write_o,
output reg [11:0] x_csr_sel_o, output reg [11:0] x_csr_sel_o,
output reg [4:0] x_csr_imm_o, output reg [4:0] x_csr_imm_o,
output reg x_is_csr_o, output reg x_is_csr_o,
output reg x_is_eret_o, output reg x_is_eret_o,
output reg [31:0] x_imm_o, output reg [31:0] x_imm_o,
output reg [31:0] x_alu_op1_o, output reg [31:0] x_alu_op1_o,
output reg [31:0] x_alu_op2_o, output reg [31:0] x_alu_op2_o,
output reg x_use_op1_o, output reg x_use_op1_o,
output reg x_use_op2_o, output reg x_use_op2_o,
output reg [1:0] x_op1_sel_o,
output reg [1:0] x_op1_sel_o, output reg [1:0] x_op2_sel_o
output reg [1:0] x_op2_sel_o
); );
wire [4:0] f_rs1 = f_ir_i[19:15]; wire [4:0] f_rs1 = f_ir_i[19:15];
wire [4:0] f_rs2 = f_ir_i[24:20]; 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_rs1;
reg [4:0] x_rs2; reg [4:0] x_rs2;
reg [4:0] x_rd; reg [4:0] x_rd;
reg [4:0] x_opcode; reg [4:0] x_opcode;
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;
...@@ -114,26 +100,19 @@ module rv_decode ...@@ -114,26 +100,19 @@ module rv_decode
assign rf_rs2_o = f_rs2; assign rf_rs2_o = f_rs2;
reg [31:0] x_ir;
wire [4:0] d_opcode = f_ir_i[6:2];
reg load_hazard; reg load_hazard;
// attempt to reuse ALU for jump address generation // 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) && wire d_is_shift = (d_fun == `FUNC_SL || d_fun == `FUNC_SR) &&
(d_opcode == `OPC_OP || d_opcode == `OPC_OP_IMM ); (d_opcode == `OPC_OP || d_opcode == `OPC_OP_IMM );
reg x_is_mul; 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@* 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 begin
case (x_opcode) case (x_opcode)
`OPC_LOAD: `OPC_LOAD:
...@@ -149,13 +128,13 @@ module rv_decode ...@@ -149,13 +128,13 @@ module rv_decode
load_hazard <= 0; load_hazard <= 0;
reg inserting_nop; reg inserting_nop;
// bubble insertion following a hazzard
always@(posedge clk_i) always@(posedge clk_i)
if(rst_i) begin if(rst_i)
inserting_nop <= 0; inserting_nop <= 0;
end else if (!d_stall_i) else if (!d_stall_i)
begin begin
if (inserting_nop) if (inserting_nop)
inserting_nop <= 0; inserting_nop <= 0;
else else
...@@ -164,9 +143,7 @@ module rv_decode ...@@ -164,9 +143,7 @@ module rv_decode
assign d_stall_req_o = load_hazard && !inserting_nop; 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; assign x_valid_o = x_valid;
always@(posedge clk_i) always@(posedge clk_i)
...@@ -174,7 +151,7 @@ module rv_decode ...@@ -174,7 +151,7 @@ module rv_decode
begin begin
x_pc_o <= 0; x_pc_o <= 0;
x_valid <= 0; x_valid <= 0;
end else if(!d_stall_i) begin end else if(!d_stall_i) begin
x_pc_o <= f_pc_i; x_pc_o <= f_pc_i;
if (load_hazard && !inserting_nop) if (load_hazard && !inserting_nop)
...@@ -182,8 +159,6 @@ module rv_decode ...@@ -182,8 +159,6 @@ module rv_decode
else else
x_valid <= f_valid_i; x_valid <= f_valid_i;
x_ir <= f_ir_i;
x_rs1 <= f_rs1; x_rs1 <= f_rs1;
x_rs2 <= f_rs2; x_rs2 <= f_rs2;
x_rd <= f_rd; x_rd <= f_rd;
...@@ -192,7 +167,7 @@ module rv_decode ...@@ -192,7 +167,7 @@ module rv_decode
x_shamt_o <= f_ir_i[24:20]; x_shamt_o <= f_ir_i[24:20];
end end
// ALU function decoding
always@(posedge clk_i) always@(posedge clk_i)
if(!d_stall_i) if(!d_stall_i)
case (d_opcode) case (d_opcode)
...@@ -200,7 +175,7 @@ module rv_decode ...@@ -200,7 +175,7 @@ module rv_decode
x_fun_o <= `FUNC_ADD; x_fun_o <= `FUNC_ADD;
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)
...@@ -217,7 +192,8 @@ module rv_decode ...@@ -217,7 +192,8 @@ module rv_decode
reg [31:0] d_imm; reg [31:0] d_imm;
// Immediate decode, comb part
always@* always@*
case(d_opcode) case(d_opcode)
`OPC_LUI, `OPC_AUIPC: d_imm <= d_imm_u; `OPC_LUI, `OPC_AUIPC: d_imm <= d_imm_u;
...@@ -229,11 +205,13 @@ module rv_decode ...@@ -229,11 +205,13 @@ module rv_decode
default: d_imm <= 32'hx; default: d_imm <= 32'hx;
endcase // case (opcode) endcase // case (opcode)
// Immediate decode, seq part
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
always@(posedge clk_i) always@(posedge clk_i)
if(!d_stall_i) if(!d_stall_i)
begin begin
...@@ -295,7 +273,6 @@ module rv_decode ...@@ -295,7 +273,6 @@ module rv_decode
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)
`OPC_BRANCH: `OPC_BRANCH:
...@@ -303,9 +280,6 @@ module rv_decode ...@@ -303,9 +280,6 @@ module rv_decode
default: default:
x_is_signed_alu_op_o <= (d_fun == `FUNC_SLT); x_is_signed_alu_op_o <= (d_fun == `FUNC_SLT);
endcase // case (d_opcode) endcase // case (d_opcode)
case (d_opcode) case (d_opcode)
`OPC_OP: `OPC_OP:
...@@ -317,10 +291,9 @@ module rv_decode ...@@ -317,10 +291,9 @@ module rv_decode
default: default:
x_is_add_o <= 1; x_is_add_o <= 1;
endcase // case (d_opcode) endcase // case (d_opcode)
// 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 != 3'b000); 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;
...@@ -330,8 +303,6 @@ module rv_decode ...@@ -330,8 +303,6 @@ module rv_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)
...@@ -345,26 +316,20 @@ module rv_decode ...@@ -345,26 +316,20 @@ module rv_decode
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)
begin begin
x_csr_imm_o <= f_ir_i[19:15]; x_csr_imm_o <= f_ir_i[19:15];
x_csr_sel_o <= f_ir_i[31:20]; x_csr_sel_o <= f_ir_i[31:20];
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_predecode endmodule // rv_decode
/* /*
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 CERN
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
...@@ -18,6 +19,8 @@ ...@@ -18,6 +19,8 @@
*/ */
`include "urv_config.v"
`define OPC_OP_IMM 5'b00100 `define OPC_OP_IMM 5'b00100
`define OPC_LUI 5'b01101 `define OPC_LUI 5'b01101
`define OPC_AUIPC 5'b00101 `define OPC_AUIPC 5'b00101
......
`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 1ns/1ps `timescale 1ns/1ps
module rv_divide module urv_divide
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
input x_stall_i, input x_stall_i,
input x_kill_i, input x_kill_i,
output x_stall_req_o, output x_stall_req_o,
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,
...@@ -120,132 +142,3 @@ module rv_divide ...@@ -120,132 +142,3 @@ module rv_divide
endmodule // 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
/* /*
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 CERN
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
...@@ -16,13 +17,13 @@ ...@@ -16,13 +17,13 @@
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 "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
module rv_exceptions module urv_exceptions
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
...@@ -192,7 +193,7 @@ module rv_exceptions ...@@ -192,7 +193,7 @@ module rv_exceptions
assign x_exception_pc_o = csr_mepc; assign x_exception_pc_o = csr_mepc;
assign x_exception_o = exception & !exception_pending; assign x_exception_o = exception & !exception_pending;
endmodule // rv_exceptions endmodule // urv_exceptions
/* /*
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 CERN
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
...@@ -18,11 +19,11 @@ ...@@ -18,11 +19,11 @@
*/ */
`include "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
module rv_exec module urv_exec
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
...@@ -124,28 +125,24 @@ module rv_exec ...@@ -124,28 +125,24 @@ module rv_exec
reg [31:0] dm_addr, dm_data_s, dm_select_s; reg [31:0] dm_addr, dm_data_s, dm_select_s;
wire [32:0] cmp_op1 = { d_is_signed_alu_op_i ? rs1[31] : 1'b0, rs1 }; // Comparator
wire [32:0] cmp_op2 = { d_is_signed_alu_op_i ? rs2[31] : 1'b0, rs2 }; 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];
wire [32:0] cmp_rs = cmp_op1 - cmp_op2; reg f_branch_take;
wire cmp_equal = (cmp_op1 == cmp_op2); wire [31:0] rd_csr;
wire cmp_lt = cmp_rs[32]; wire [31:0] rd_div;
reg f_branch_take; wire exception;
wire [31:0] csr_mie, csr_mip, csr_mepc, csr_mstatus,csr_mcause;
wire [31:0] rd_shifter; wire [31:0] csr_write_value;
wire [31:0] rd_csr; wire [31:0] exception_address, exception_vector;
wire [31:0] rd_mul;
wire [31:0] rd_div;
wire exception;
wire [31:0] csr_mie, csr_mip, csr_mepc, csr_mstatus,csr_mcause;
wire [31:0] csr_write_value;
wire [31:0] exception_address, exception_vector;
rv_csr csr_regs urv_csr csr_regs
( (
.clk_i(clk_i), .clk_i(clk_i),
...@@ -174,7 +171,7 @@ module rv_exec ...@@ -174,7 +171,7 @@ module rv_exec
.csr_mcause_i(csr_mcause) .csr_mcause_i(csr_mcause)
); );
rv_exceptions exception_unit urv_exceptions exception_unit
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
...@@ -225,7 +222,8 @@ module rv_exec ...@@ -225,7 +222,8 @@ module rv_exec
// generate load/store address // generate load/store address
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
always@* always@*
if(d_is_eret_i ) if(d_is_eret_i )
branch_target <= exception_address; branch_target <= exception_address;
...@@ -234,16 +232,17 @@ module rv_exec ...@@ -234,16 +232,17 @@ module rv_exec
else else
branch_target <= dm_addr; branch_target <= dm_addr;
// decode ALU operands // decode ALU operands
always@* always@*
begin begin
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
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 };
wire [32:0] alu_addsub_op2 = {d_is_signed_alu_op_i ? alu_op2[31] : 1'b0, alu_op2 }; 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; reg [32:0] alu_addsub_result;
always@* always@*
...@@ -253,7 +252,7 @@ module rv_exec ...@@ -253,7 +252,7 @@ module rv_exec
alu_addsub_result <= alu_addsub_op1 - alu_addsub_op2; alu_addsub_result <= alu_addsub_op1 - alu_addsub_op2;
// the ALU itself // the rest of the ALU
always@* always@*
begin begin
case (d_fun_i) case (d_fun_i)
...@@ -273,8 +272,8 @@ module rv_exec ...@@ -273,8 +272,8 @@ module rv_exec
endcase // case (d_fun_i) endcase // case (d_fun_i)
end // always@ * end // always@ *
// barel shifter
rv_shifter shifter urv_shifter shifter
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
...@@ -288,26 +287,26 @@ module rv_exec ...@@ -288,26 +287,26 @@ module rv_exec
.d_is_shift_i(d_is_shift_i), .d_is_shift_i(d_is_shift_i),
.w_rd_o(w_rd_shifter_o) .w_rd_o(w_rd_shifter_o)
); );
wire divider_stall_req = 0; wire divider_stall_req = 0;
rv_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), .d_fun_i(d_fun),
.w_rd_o (w_rd_multiply_o) .w_rd_o (w_rd_multiply_o)
); );
/* wire divider_stall_req; /* wire divider_stall_req;
wire [31:0] rd_divide; wire [31:0] rd_divide;
rv_divide divider urv_divide divider
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
...@@ -415,47 +414,53 @@ module rv_exec ...@@ -415,47 +414,53 @@ module rv_exec
assign dm_data_s_o = dm_data_s; assign dm_data_s_o = dm_data_s;
assign dm_data_select_o = dm_select_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_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
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; f_branch_take <= branch_take && !x_kill_i && d_valid_i;
w_rd_o <= d_rd_i; w_rd_o <= d_rd_i;
w_rd_value_o <= rd_value; 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_rd_write_o <= d_rd_write_i && !x_kill_i && d_valid_i && !exception;
w_fun_o <= d_fun_i; w_load_o <= d_is_load_i && !x_kill_i && d_valid_i && !exception;
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_store_o <= d_is_store_i && !x_kill_i && d_valid_i && !exception;
w_dm_addr_o <= dm_addr; w_rd_source_o <= d_rd_source_i;
w_valid_o <= !exception; w_fun_o <= d_fun_i;
end // else: !if(rst_i) w_dm_addr_o <= dm_addr;
w_valid_o <= !exception;
end // else: !if(rst_i)
assign f_branch_take_o = f_branch_take; assign f_branch_take_o = f_branch_take;
// pipeline control: generate stall request signal
always@* always@*
// never stall on taken branch
if(f_branch_take) if(f_branch_take)
x_stall_req_o <= 0; x_stall_req_o <= 0;
else if(divider_stall_req) else if(divider_stall_req)
x_stall_req_o <= 1; 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) else if ((d_is_load_i || d_is_store_i) && d_valid_i && !x_kill_i && !dm_ready_i)
x_stall_req_o <= 1; x_stall_req_o <= 1;
else else
x_stall_req_o <= 0; x_stall_req_o <= 0;
endmodule endmodule // urv_exec
......
/* /*
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 CERN
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
...@@ -20,23 +21,22 @@ ...@@ -20,23 +21,22 @@
`timescale 1ns/1ps `timescale 1ns/1ps
module rv_fetch module urv_fetch
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
input f_stall_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,
input f_stall_i, output reg f_valid_o,
input f_kill_i,
output [31:0] f_ir_o, output [31:0] f_ir_o,
output reg [31:0] f_pc_o, output reg [31:0] f_pc_o,
output reg [31:0] f_pc_plus_4_o, output reg [31:0] f_pc_plus_4_o,
output reg f_valid_o,
input [31:0] x_pc_bra_i, input [31:0] x_pc_bra_i,
input x_bra_i input x_bra_i
...@@ -93,7 +93,7 @@ module rv_fetch ...@@ -93,7 +93,7 @@ module rv_fetch
end end
end // else: !if(rst_i) end // else: !if(rst_i)
endmodule // urv_fetch
endmodule
/*
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 1ns/1ps `timescale 1ns/1ps
`include "urv_defs.v"
`ifdef URV_PLATFORM_SPARTAN6
module urv_iram module urv_iram
#( #(
parameter g_size = 65536, parameter g_size = 65536,
...@@ -28,7 +53,7 @@ module urv_iram ...@@ -28,7 +53,7 @@ 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
...@@ -92,7 +117,7 @@ module urv_iram ...@@ -92,7 +117,7 @@ module urv_iram
`RAM_INST(64K_31, RAMB16_S1_S1, 15:2, 31, 3) `RAM_INST(64K_31, RAMB16_S1_S1, 15:2, 31, 3)
end // if (g_size == 65536) end // if (g_size == 65536)
if(g_size == 16384) begin else if(g_size == 16384) begin
`RAM_INST(16K_0, RAMB16_S4_S4, 13:2, 3:0, 0) `RAM_INST(16K_0, RAMB16_S4_S4, 13:2, 3:0, 0)
`RAM_INST(16K_1, RAMB16_S4_S4, 13:2, 7:4, 0) `RAM_INST(16K_1, RAMB16_S4_S4, 13:2, 7:4, 0)
`RAM_INST(16K_2, RAMB16_S4_S4, 13:2, 11:8, 1) `RAM_INST(16K_2, RAMB16_S4_S4, 13:2, 11:8, 1)
...@@ -101,7 +126,10 @@ module urv_iram ...@@ -101,7 +126,10 @@ module urv_iram
`RAM_INST(16K_5, RAMB16_S4_S4, 13:2, 23:20, 2) `RAM_INST(16K_5, RAMB16_S4_S4, 13:2, 23:20, 2)
`RAM_INST(16K_6, RAMB16_S4_S4, 13:2, 27:24, 3) `RAM_INST(16K_6, RAMB16_S4_S4, 13:2, 27:24, 3)
`RAM_INST(16K_7, RAMB16_S4_S4, 13:2, 31:28, 3) `RAM_INST(16K_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) end else begin // if (!g_simulation)
...@@ -195,3 +223,82 @@ module urv_iram ...@@ -195,3 +223,82 @@ module urv_iram
endmodule // 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
`include "rv_defs.v" /*
`timescale 1ns/1ps 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.
`define ARCH_VIRTEX6 You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
`include "urv_defs.v"
`ifdef ARCH_SPARTAN6 `timescale 1ns/1ps
module rv_mult18x18 `ifdef URV_PLATFORM_SPARTAN6
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,
...@@ -20,58 +39,58 @@ module rv_mult18x18 ...@@ -20,58 +39,58 @@ module rv_mult18x18
); );
DSP48A1 #( DSP48A1 #(
.A0REG(0), .A0REG(0),
.A1REG(0), .A1REG(0),
.B0REG(0), .B0REG(0),
.B1REG(0), .B1REG(0),
.CARRYINREG(0), .CARRYINREG(0),
.CARRYINSEL("OPMODE5"), .CARRYINSEL("OPMODE5"),
.CARRYOUTREG(0), .CARRYOUTREG(0),
.CREG(0), .CREG(0),
.DREG(0), .DREG(0),
.MREG(1), .MREG(1),
.OPMODEREG(0), .OPMODEREG(0),
.PREG(0), .PREG(0),
.RSTTYPE("SYNC") .RSTTYPE("SYNC")
) D1 ( ) D1 (
.BCOUT(), .BCOUT(),
.PCOUT(), .PCOUT(),
.CARRYOUT(), .CARRYOUT(),
.CARRYOUTF(), .CARRYOUTF(),
.M(q_o), .M(q_o),
.P(), .P(),
.PCIN(), .PCIN(),
.CLK(clk_i), .CLK(clk_i),
.OPMODE(8'd1), .OPMODE(8'd1),
.A(x_i), .A(x_i),
.B(y_i), .B(y_i),
.C(48'h0), .C(48'h0),
.CARRYIN(), .CARRYIN(),
.D(18'b0), .D(18'b0),
.CEA(1'b0), .CEA(1'b0),
.CEB(1'b0), .CEB(1'b0),
.CEC(1'b0), .CEC(1'b0),
.CECARRYIN(1'b0), .CECARRYIN(1'b0),
.CED(1'b0), .CED(1'b0),
.CEM(~stall_i), .CEM(~stall_i),
.CEOPMODE(1'b0), .CEOPMODE(1'b0),
.CEP(1'b1), .CEP(1'b1),
.RSTA(rst_i), .RSTA(rst_i),
.RSTB(rst_i), .RSTB(rst_i),
.RSTC(1'b0), .RSTC(1'b0),
.RSTCARRYIN(1'b0), .RSTCARRYIN(1'b0),
.RSTD(1'b0), .RSTD(1'b0),
.RSTM(rst_i), .RSTM(rst_i),
.RSTOPMODE(1'b0), .RSTOPMODE(1'b0),
.RSTP(1'b0) .RSTP(1'b0)
); );
endmodule // rv_mult18x18 endmodule // urv_mult18x18
`endif // `i `endif // `ifdef PLATFORM_SPARTAN6
// fdef ARCH_SPARTAN6
`ifdef ARCH_VIRTEX6 `ifdef URV_PLATFORM_GENERIC
module rv_mult18x18 module urv_mult18x18
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
...@@ -89,12 +108,11 @@ module rv_mult18x18 ...@@ -89,12 +108,11 @@ module rv_mult18x18
if(!stall_i) if(!stall_i)
q_o <= x_i * y_i; q_o <= x_i * y_i;
endmodule // rv_mult18x18 endmodule // urv_mult18x18
`endif // `ifdef ARCH_VIRTEX6 `endif // `ifdef URV_PLATFORM_GENERIC
module urv_multiply
module rv_multiply
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
...@@ -108,8 +126,6 @@ module rv_multiply ...@@ -108,8 +126,6 @@ module rv_multiply
); );
wire[17:0] xl_u = {1'b0, d_rs1_i[16:0] }; wire[17:0] xl_u = {1'b0, d_rs1_i[16:0] };
wire[17:0] yl_u = {1'b0, d_rs2_i[16:0] }; wire[17:0] yl_u = {1'b0, d_rs2_i[16:0] };
...@@ -121,7 +137,7 @@ module rv_multiply ...@@ -121,7 +137,7 @@ module rv_multiply
wire [35:0] yl_xl, yl_xh, yh_xl; wire [35:0] yl_xl, yl_xh, yh_xl;
rv_mult18x18 U_mul0 urv_mult18x18 mul0
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
...@@ -132,7 +148,7 @@ module rv_multiply ...@@ -132,7 +148,7 @@ module rv_multiply
.q_o(yl_xl) .q_o(yl_xl)
); );
rv_mult18x18 U_mul1 urv_mult18x18 mul1
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
...@@ -143,7 +159,7 @@ module rv_multiply ...@@ -143,7 +159,7 @@ module rv_multiply
.q_o(yh_xl) .q_o(yh_xl)
); );
rv_mult18x18 U_mul2 urv_mult18x18 mul2
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
...@@ -154,28 +170,11 @@ module rv_multiply ...@@ -154,28 +170,11 @@ module rv_multiply
.q_o(yl_xh) .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@* 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 // rv_multiply
......
/* /*
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 CERN
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
...@@ -18,32 +19,25 @@ ...@@ -18,32 +19,25 @@
*/ */
`include "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
module rv_regmem module urv_regmem
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
input en1_i,
input [4:0] a1_i,
output reg [31:0] q1_o,
input [4:0] a2_i,
input [31:0] d2_i,
input we2_i
);
reg [31:0] ram [0:31]; input en1_i,
reg [31:0] bypass_r; input [4:0] a1_i,
reg bypass; output reg [31:0] q1_o,
input [4:0] a2_i,
input [31:0] d2_i,
input we2_i
);
reg [31:0] ram [0:31];
reg [31:0] q1_int;
always@(posedge clk_i) always@(posedge clk_i)
if(en1_i) if(en1_i)
...@@ -51,22 +45,21 @@ module rv_regmem ...@@ -51,22 +45,21 @@ module rv_regmem
always@(posedge clk_i) always@(posedge clk_i)
if(we2_i) if(we2_i)
ram[a2_i] <= d2_i; ram[a2_i] <= d2_i;
// synthesis translate_off // synthesis translate_off
initial begin : ram_init initial begin : ram_init
integer i; integer i;
for(i=0;i<32; i=i+1) begin for(i=0;i<32; i=i+1) begin
ram[i] = 0; ram[i] = 0;
end
end end
end // synthesis translate_on
// synthesis translate_on
endmodule // rv_regmem2 endmodule
module rv_regfile module urv_regfile
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
...@@ -94,37 +87,39 @@ module rv_regfile ...@@ -94,37 +87,39 @@ module rv_regfile
wire [31:0] rs1_regfile; wire [31:0] rs1_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));
rv_regmem bank0 ( urv_regmem bank0
.clk_i(clk_i), (
.rst_i (rst_i ), .clk_i(clk_i),
.en1_i(!d_stall_i), .rst_i (rst_i ),
.a1_i(rf_rs1_i), .en1_i(!d_stall_i),
.q1_o(rs1_regfile), .a1_i(rf_rs1_i),
.q1_o(rs1_regfile),
.a2_i(w_rd_i),
.d2_i(w_rd_value_i), .a2_i(w_rd_i),
.we2_i (write)); .d2_i(w_rd_value_i),
.we2_i (write));
rv_regmem bank1 (
.clk_i(clk_i),
.rst_i (rst_i ),
.en1_i(!d_stall_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); urv_regmem bank1
(
.clk_i(clk_i),
.rst_i (rst_i ),
.en1_i(!d_stall_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; reg rs1_bypass_w, rs2_bypass_w;
always@(posedge clk_i) always@(posedge clk_i)
if(rst_i) if(rst_i)
begin begin
...@@ -161,130 +156,6 @@ module rv_regfile ...@@ -161,130 +156,6 @@ module rv_regfile
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 // 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
/* /*
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 CERN
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
...@@ -18,7 +19,7 @@ ...@@ -18,7 +19,7 @@
*/ */
`include "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
...@@ -28,25 +29,25 @@ ...@@ -28,25 +29,25 @@
x[16], x[17], x[18], x[19], x[20], x[21], x[22], x[23], \ 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] } x[24], x[25], x[26], x[27], x[28], x[29], x[30], x[31] }
module rv_shifter module urv_shifter
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
input x_stall_i, input x_stall_i,
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,
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; 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; reg [31:0] shift_pre, shift_16, shift_8, s1_out;
// stage 1 // stage 1
...@@ -73,16 +74,6 @@ module rv_shifter ...@@ -73,16 +74,6 @@ module rv_shifter
s1_out <= shift_8; s1_out <= shift_8;
end 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; reg [31:0] shift_4, shift_2, shift_1, shift_post;
// stage 2 // stage 2
...@@ -94,109 +85,8 @@ module rv_shifter ...@@ -94,109 +85,8 @@ module rv_shifter
shift_post <= (s2_func == `FUNC_SL) ? `reverse_bits(shift_1) : shift_1; shift_post <= (s2_func == `FUNC_SL) ? `reverse_bits(shift_1) : shift_1;
end end
/* -----\/----- EXCLUDED -----\/-----
always@(posedge clk_i)
if(!x_stall_i)
w_rd_o <= shift_post;
-----/\----- EXCLUDED -----/\----- */
always@* always@*
w_rd_o <= shift_post; w_rd_o <= shift_post;
endmodule // rv_shifter endmodule // urv_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
/* /*
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 CERN
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
...@@ -18,18 +19,18 @@ ...@@ -18,18 +19,18 @@
*/ */
`include "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
module rv_timer module urv_timer
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
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
); );
...@@ -76,4 +77,4 @@ module rv_timer ...@@ -76,4 +77,4 @@ module rv_timer
assign csr_cycles_o = cycles; assign csr_cycles_o = cycles;
assign sys_tick_o = presc_tick; assign sys_tick_o = presc_tick;
endmodule // rv_timer endmodule // urv_timer
/* /*
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 CERN
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
...@@ -18,17 +19,16 @@ ...@@ -18,17 +19,16 @@
*/ */
`include "rv_defs.v" `include "urv_defs.v"
`timescale 1ns/1ps `timescale 1ns/1ps
module rv_writeback module urv_writeback
( (
input clk_i, input clk_i,
input rst_i, input rst_i,
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,
...@@ -52,19 +52,13 @@ module rv_writeback ...@@ -52,19 +52,13 @@ module rv_writeback
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
output [31:0] TRIG2
); );
reg [31:0] load_value; reg [31:0] load_value;
// generate load value // generate load value
always@* always@*
begin begin
...@@ -109,8 +103,7 @@ module rv_writeback ...@@ -109,8 +103,7 @@ module rv_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;
...@@ -139,10 +132,4 @@ module rv_writeback ...@@ -139,10 +132,4 @@ module rv_writeback
assign rf_rd_o = x_rd_i; 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 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; endmodule // urv_writeback
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
...@@ -24,12 +24,12 @@ use ieee.numeric_std.all; ...@@ -24,12 +24,12 @@ use ieee.numeric_std.all;
use work.wishbone_pkg.all; use work.wishbone_pkg.all;
use work.genram_pkg.all; use work.genram_pkg.all;
entity xrv_core is entity xurv_core is
generic ( generic (
g_internal_ram_size : integer := 65536; g_internal_ram_size : integer := 65536;
g_internal_ram_init_file : string := ""; g_internal_ram_init_file : string := "";
g_simulation : boolean := false; g_simulation : boolean := false;
g_address_bits : integer := 32 g_address_bits : integer := 32
); );
port ( port (
...@@ -47,65 +47,65 @@ entity xrv_core is ...@@ -47,65 +47,65 @@ entity xrv_core is
host_slave_i : in t_wishbone_slave_in := cc_dummy_slave_in; host_slave_i : in t_wishbone_slave_in := cc_dummy_slave_in;
host_slave_o : out t_wishbone_slave_out host_slave_o : out t_wishbone_slave_out
); );
end xrv_core; end xurv_core;
architecture wrapper of xrv_core is architecture wrapper of xurv_core is
constant c_mem_address_bits : integer := f_ceil_log2(g_internal_ram_size / 4); constant c_mem_address_bits : integer := f_ceil_log2(g_internal_ram_size / 4);
component rv_cpu is component urv_cpu is
port( port(
clk_i : in std_logic; clk_i : in std_logic;
rst_i : in std_logic; rst_i : in std_logic;
irq_i : in std_logic; irq_i : in std_logic;
im_addr_o : out std_logic_vector(31 downto 0); im_addr_o : out std_logic_vector(31 downto 0);
im_data_i : in std_logic_vector(31 downto 0); im_data_i : in std_logic_vector(31 downto 0);
im_valid_i : in std_logic; im_valid_i : in std_logic;
dm_addr_o : out std_logic_vector(31 downto 0); dm_addr_o : out std_logic_vector(31 downto 0);
dm_data_s_o : out std_logic_vector(31 downto 0); dm_data_s_o : out std_logic_vector(31 downto 0);
dm_data_l_i : in std_logic_vector(31 downto 0); dm_data_l_i : in std_logic_vector(31 downto 0);
dm_data_select_o : out std_logic_vector(3 downto 0); dm_data_select_o : out std_logic_vector(3 downto 0);
dm_ready_i : in std_logic; dm_ready_i : in std_logic;
dm_store_o : out std_logic; dm_store_o : out std_logic;
dm_load_o : out std_logic; dm_load_o : out std_logic;
dm_load_done_i : in std_logic; dm_load_done_i : in std_logic;
dm_store_done_i : in std_logic dm_store_done_i : in std_logic
); );
end component; end component;
component urv_iram component urv_iram
generic ( generic (
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;
ena_i : in std_logic; ena_i : in std_logic;
wea_i : in std_logic; wea_i : in std_logic;
aa_i : in std_logic_vector(31 downto 0); aa_i : in std_logic_vector(31 downto 0);
bwea_i : in std_logic_vector(3 downto 0); bwea_i : in std_logic_vector(3 downto 0);
da_i : in std_logic_vector(31 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; enb_i : in std_logic;
web_i : in std_logic; web_i : in std_logic;
ab_i : in std_logic_vector(31 downto 0); ab_i : in std_logic_vector(31 downto 0);
bweb_i : in std_logic_vector(3 downto 0); bweb_i : in std_logic_vector(3 downto 0);
db_i : in std_logic_vector(31 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; end component;
signal cpu_rst, cpu_rst_d : std_logic;
signal im_addr : std_logic_vector(31 downto 0); signal cpu_rst, cpu_rst_d : std_logic;
signal im_data : std_logic_vector(31 downto 0); signal im_addr : std_logic_vector(31 downto 0);
signal im_valid : std_logic; signal im_data : std_logic_vector(31 downto 0);
signal im_valid : std_logic;
signal ha_im_addr : std_logic_vector(g_address_bits-1 downto 0); signal ha_im_addr : std_logic_vector(g_address_bits-1 downto 0);
signal ha_im_wdata, ha_im_rdata : std_logic_vector(31 downto 0); signal ha_im_wdata, ha_im_rdata : std_logic_vector(31 downto 0);
...@@ -121,7 +121,7 @@ architecture wrapper of xrv_core is ...@@ -121,7 +121,7 @@ architecture wrapper of xrv_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
...@@ -155,7 +155,7 @@ begin ...@@ -155,7 +155,7 @@ begin
end process; end process;
-- dm_is_wishbone <= '1' when unsigned(dm_addr(20g_address_bits-1 downto 0)) >= g_wishbone_start else '0'; -- dm_is_wishbone <= '1' when unsigned(dm_addr(20g_address_bits-1 downto 0)) >= g_wishbone_start else '0';
dm_is_wishbone <= dm_addr(31); dm_is_wishbone <= dm_addr(31);
-- Wishbone bus arbitration / internal RAM access -- Wishbone bus arbitration / internal RAM access
process(clk_sys_i) process(clk_sys_i)
...@@ -232,42 +232,42 @@ begin ...@@ -232,42 +232,42 @@ begin
im_addr_muxed <= ha_im_addr when ha_im_access = '1' else im_addr(g_address_bits-1 downto 0); im_addr_muxed <= ha_im_addr when ha_im_access = '1' else im_addr(g_address_bits-1 downto 0);
dm_ready <= '1'; dm_ready <= '1';
cpu_core : rv_cpu cpu_core : urv_cpu
port map ( port map (
clk_i => clk_sys_i, clk_i => clk_sys_i,
rst_i => cpu_rst, rst_i => cpu_rst,
irq_i => '0', irq_i => '0',
im_addr_o => im_addr, im_addr_o => im_addr,
im_data_i => im_data, im_data_i => im_data,
im_valid_i => im_valid, im_valid_i => im_valid,
dm_addr_o => dm_addr, dm_addr_o => dm_addr,
dm_data_s_o => dm_data_s, dm_data_s_o => dm_data_s,
dm_data_l_i => dm_data_l, dm_data_l_i => dm_data_l,
dm_data_select_o => dm_data_select, dm_data_select_o => dm_data_select,
dm_ready_i => dm_ready, dm_ready_i => dm_ready,
dm_store_o => dm_store, dm_store_o => dm_store,
dm_load_o => dm_load, dm_load_o => dm_load,
dm_load_done_i => dm_load_done, dm_load_done_i => dm_load_done,
dm_store_done_i => dm_store_done); dm_store_done_i => dm_store_done);
dm_data_write <= not dm_is_wishbone and dm_store; dm_data_write <= not dm_is_wishbone and dm_store;
U_iram : urv_iram U_iram : urv_iram
generic map ( generic map (
g_size => g_internal_ram_size, g_size => g_internal_ram_size,
g_init_file => g_internal_ram_init_file, g_init_file => g_internal_ram_init_file,
g_simulation => g_simulation) g_simulation => g_simulation)
port map ( port map (
clk_i => clk_sys_i, clk_i => clk_sys_i,
ena_i => '1', ena_i => '1',
wea_i => '0', wea_i => '0',
bwea_i => "0000", bwea_i => "0000",
aa_i => im_addr_muxed, aa_i => im_addr_muxed,
da_i => ha_im_wdata, da_i => ha_im_wdata,
qa_o => im_data, qa_o => im_data,
enb_i => '1', enb_i => '1',
bweb_i => dm_data_select, bweb_i => dm_data_select,
web_i => dm_data_write, web_i => dm_data_write,
ab_i => dm_addr, ab_i => dm_addr,
...@@ -279,15 +279,15 @@ begin ...@@ -279,15 +279,15 @@ begin
begin begin
if rising_edge(clk_sys_i) then if rising_edge(clk_sys_i) then
if(cpu_rst = '1') then if(cpu_rst = '1') then
im_valid <= '0'; im_valid <= '0';
cpu_rst_d <= '1'; cpu_rst_d <= '1';
else else
cpu_rst_d <= cpu_rst; cpu_rst_d <= cpu_rst;
im_valid <= not ha_im_access and (not cpu_rst_d); im_valid <= not ha_im_access and (not cpu_rst_d);
end if; end if;
end if; end if;
end process; end process;
host_slave_o.stall <= '0'; host_slave_o.stall <= '0';
host_slave_o.err <= '0'; host_slave_o.err <= '0';
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment