Commit 4ad34eca authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

rtl: passes RV32IM test suite

parent 7630ec3a
......@@ -14,6 +14,7 @@ files = [ "rv_cpu.v",
"rv_writeback.v",
"rv_shifter.v",
"rv_multiply.v",
"rv_divide.v",
"rv_csr.v",
"rv_timer.v",
"rv_exceptions.v",
......
......@@ -100,6 +100,9 @@ module rv_cpu
wire [4:0] d2x_opcode;
wire d2x_shifter_sign;
wire d2x_is_load, d2x_is_store, d2x_is_undef;
wire [31:0] d2x_imm;
wire d2x_is_signed_compare;
wire d2x_is_signed_alu_op;
......@@ -210,6 +213,10 @@ module rv_cpu
.x_is_signed_alu_op_o(d2x_is_signed_alu_op),
.x_is_add_o(d2x_is_add),
.x_is_shift_o(d2x_is_shift),
.x_is_load_o(d2x_is_load),
.x_is_store_o(d2x_is_store),
.x_is_undef_o(d2x_is_undef),
.x_rd_source_o(d2x_rd_source),
.x_rd_write_o(d2x_rd_write),
......@@ -240,9 +247,10 @@ module rv_cpu
wire rf_rd_write;
wire x2w_valid;
wire [31:0] rf_bypass_rd_value = x2w_rd_value;
wire rf_bypass_rd_write = rf_rd_write && !x2w_load;
wire rf_bypass_rd_write = rf_rd_write && !x2w_load; // multiply/shift too?
rv_regfile regfile
(
......@@ -284,7 +292,6 @@ module rv_cpu
.irq_i ( irq_i ),
.x_stall_req_o(x_stall_req),
.w_stall_req_i(w_stall_req),
.d_valid_i(d2x_valid),
......@@ -302,6 +309,10 @@ module rv_cpu
.d_is_signed_alu_op_i(d2x_is_signed_alu_op),
.d_is_add_i(d2x_is_add),
.d_is_shift_i(d2x_is_shift),
.d_is_load_i(d2x_is_load),
.d_is_store_i(d2x_is_store),
.d_is_undef_i(d2x_is_undef),
.d_rd_source_i(d2x_rd_source),
.d_rd_write_i(d2x_rd_write),
......@@ -321,7 +332,7 @@ module rv_cpu
.w_fun_o(x2w_fun),
.w_load_o(x2w_load),
.w_store_o(x2w_store),
.w_valid_o(x2w_valid),
.w_dm_addr_o(x2w_dm_addr),
.w_rd_o(x2w_rd),
.w_rd_value_o(x2w_rd_value),
......@@ -358,7 +369,8 @@ module rv_cpu
.x_load_i(x2w_load),
.x_load_hazard_i(x2w_load_hazard),
.x_store_i(x2w_store),
.x_valid_i(x2w_valid),
.x_rd_i(x2w_rd),
.x_rd_source_i(x2w_rd_source),
.x_rd_value_i(x2w_rd_value),
......
......@@ -28,6 +28,7 @@
`define OPC_LOAD 5'b00000
`define OPC_STORE 5'b01000
`define OPC_SYSTEM 5'b11100
`define OPC_MULDIV 5'b
`define BRA_EQ 3'b000
`define BRA_NEQ 3'b001
......@@ -56,6 +57,11 @@
`define FUNC_MULHSU 3'b010
`define FUNC_MULHU 3'b011
`define FUNC_DIV 3'b100
`define FUNC_DIVU 3'b101
`define FUNC_REM 3'b110
`define FUNC_REMU 3'b111
`define RD_SOURCE_ALU 3'b000
`define RD_SOURCE_SHIFTER 3'b010
`define RD_SOURCE_MULTIPLY 3'b001
......
......@@ -16,7 +16,7 @@
You should have received a copy of the GNU Lesser General Public
License along with this library.
*/
*/
`include "rv_defs.v"
......@@ -29,14 +29,14 @@ module rv_exceptions
input x_stall_i,
input x_kill_i,
input d_is_csr_i,
input d_is_eret_i,
input [2:0] d_fun_i,
input [4:0] d_csr_imm_i,
input [11:0] d_csr_sel_i,
input exp_irq_i,
input exp_tick_i,
input exp_breakpoint_i,
......@@ -45,38 +45,40 @@ module rv_exceptions
input exp_invalid_insn_i,
input [31:0] x_csr_write_value_i,
output x_exception_o,
input [31:0] x_exception_pc_i,
output [31:0] x_exception_pc_o,
output [31:0] x_exception_vector_o,
output [31:0] csr_mstatus_o,
output [31:0] csr_mip_o,
output [31:0] csr_mie_o,
output [31:0] csr_mepc_o,
output [31:0] csr_mcause_o
);
);
reg [31:0] csr_mepc;
reg [31:0] csr_mie;
reg csr_ie;
reg [31:0] csr_mepc;
reg [31:0] csr_mie;
reg csr_ie;
reg exception;
reg [3:0] cause;
reg [3:0] csr_mcause;
reg exception;
reg [3:0] cause;
reg [5:0] except_vec_masked;
reg [5:0] except_vec_masked;
assign csr_mcause_o = 0;
assign csr_mcause_o = {28'h0, csr_mcause};
assign csr_mepc_o = csr_mepc;
assign csr_mie_o = csr_mie;
assign csr_mstatus_o[0] = csr_ie;
assign csr_mstatus_o[31:1] = 0;
reg [31:0] csr_mip;
reg [31:0] csr_mip;
always@*
begin
......@@ -92,7 +94,7 @@ module rv_exceptions
assign csr_mip_o = csr_mip;
always@(posedge clk_i)
if (rst_i)
......@@ -107,31 +109,45 @@ module rv_exceptions
except_vec_masked[5] <= x_csr_write_value_i [`EXCEPT_IRQ];
end else begin
if ( exp_invalid_insn_i )
except_vec_masked[0] <= csr_mie[`EXCEPT_ILLEGAL_INSN];
except_vec_masked[0] <= 1'b1;
if ( exp_breakpoint_i )
except_vec_masked[1] <= csr_mie[`EXCEPT_BREAKPOINT];
except_vec_masked[1] <= 1'b1;
if ( exp_unaligned_load_i )
except_vec_masked[2] <= csr_mie[`EXCEPT_UNALIGNED_LOAD];
except_vec_masked[2] <= 1'b1;
if ( exp_unaligned_store_i )
except_vec_masked[3] <= csr_mie[`EXCEPT_UNALIGNED_STORE];
except_vec_masked[3] <= 1'b1;
if ( exp_tick_i )
except_vec_masked[4] <= csr_mie[`EXCEPT_TIMER];
except_vec_masked[4] <= csr_mie[`EXCEPT_TIMER] & csr_ie;
if( exp_irq_i )
except_vec_masked[5] <= csr_mie[`EXCEPT_IRQ];
except_vec_masked[5] <= csr_mie[`EXCEPT_IRQ] & csr_ie;
end // else: !if(!x_stall_i && !x_kill_i && d_is_csr_i && d_csr_sel_i == `CSR_ID_MIP)
end // else: !if(rst_i)
always@*
exception <= |except_vec_masked;
exception <= |except_vec_masked | exp_invalid_insn_i;
reg exception_pending;
assign x_exception_vector_o = 'h8;
always@*
if(exp_invalid_insn_i || except_vec_masked[0])
cause <= `EXCEPT_ILLEGAL_INSN;
else if (except_vec_masked[1])
cause <= `EXCEPT_BREAKPOINT;
else if (except_vec_masked[2])
cause <= `EXCEPT_UNALIGNED_LOAD;
else if (except_vec_masked[3])
cause <= `EXCEPT_UNALIGNED_STORE;
else if (except_vec_masked[4])
cause <= `EXCEPT_TIMER;
else
cause <= `EXCEPT_IRQ;
always@(posedge clk_i)
if(rst_i)
......@@ -145,9 +161,10 @@ module rv_exceptions
if ( d_is_eret_i )
exception_pending <= 0;
if ( !exception_pending && exception && csr_ie )
if ( !exception_pending && exception )
begin
csr_mepc <= x_exception_pc_i;
csr_mcause <= cause;
exception_pending <= 1;
end
......@@ -159,10 +176,10 @@ module rv_exceptions
csr_mepc <= x_csr_write_value_i;
`CSR_ID_MIE:
begin
csr_mie[`EXCEPT_ILLEGAL_INSN] <= x_csr_write_value_i [`EXCEPT_ILLEGAL_INSN];
csr_mie[`EXCEPT_BREAKPOINT] <= x_csr_write_value_i [`EXCEPT_BREAKPOINT];
csr_mie[`EXCEPT_UNALIGNED_LOAD] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_LOAD];
csr_mie[`EXCEPT_UNALIGNED_STORE] <= x_csr_write_value_i [`EXCEPT_UNALIGNED_STORE];
csr_mie[`EXCEPT_ILLEGAL_INSN] <= 1;
csr_mie[`EXCEPT_BREAKPOINT] <= 1;
csr_mie[`EXCEPT_UNALIGNED_LOAD] <= 1;
csr_mie[`EXCEPT_UNALIGNED_STORE] <= 1;
csr_mie[`EXCEPT_TIMER] <= x_csr_write_value_i [`EXCEPT_TIMER];
csr_mie[`EXCEPT_IRQ] <= x_csr_write_value_i [`EXCEPT_IRQ];
end
......@@ -172,10 +189,10 @@ module rv_exceptions
end // if (!x_stall_i && !x_kill_i)
assign x_exception_pc_o = csr_mepc;
assign x_exception_o = exception & csr_ie & !exception_pending;
endmodule // rv_exceptions
assign x_exception_pc_o = csr_mepc;
assign x_exception_o = exception & !exception_pending;
endmodule // rv_exceptions
......@@ -30,7 +30,6 @@ module rv_exec
input x_stall_i,
input x_kill_i,
output reg x_stall_req_o,
input w_stall_req_i,
input [31:0] d_pc_i,
......@@ -59,6 +58,12 @@ module rv_exec
input d_is_signed_alu_op_i,
input d_is_add_i,
input d_is_shift_i,
input d_is_load_i,
input d_is_store_i,
input d_is_divide_i,
input d_is_undef_i,
input [2:0] d_rd_source_i,
input d_rd_write_i,
......@@ -73,7 +78,8 @@ module rv_exec
output reg [2:0 ] w_fun_o,
output reg w_load_o,
output reg w_store_o,
output reg w_valid_o,
output reg [4:0] w_rd_o,
output reg [31:0] w_rd_value_o,
output reg w_rd_write_o,
......@@ -97,8 +103,6 @@ module rv_exec
);
parameter g_exception_vector = 'h40;
wire [31:0] rs1, rs2;
assign rs1 = rf_rs1_value_i;
......@@ -124,10 +128,6 @@ module rv_exec
reg f_branch_take;
wire x_stall_req_shifter = 0;
wire x_stall_req_multiply = 0;
wire x_stall_req_divide = 0;
wire [31:0] rd_shifter;
wire [31:0] rd_csr;
wire [31:0] rd_mul;
......@@ -136,7 +136,7 @@ module rv_exec
wire exception;
wire [31:0] csr_mie, csr_mip, csr_mepc, csr_mstatus,csr_mcause;
wire [31:0] csr_write_value;
wire [31:0] exception_address;
wire [31:0] exception_address, exception_vector;
rv_csr csr_regs
......@@ -165,7 +165,7 @@ module rv_exec
.csr_mip_i(csr_mip),
.csr_mie_i(csr_mie),
.csr_mepc_i(csr_mepc),
.csr_mcause_i(csr_mmause)
.csr_mcause_i(csr_mcause)
);
rv_exceptions exception_unit
......@@ -188,12 +188,12 @@ module rv_exec
.exp_breakpoint_i(1'b0),
.exp_unaligned_load_i(1'b0),
.exp_unaligned_store_i(1'b0),
.exp_invalid_insn_i(1'b0),
.exp_invalid_insn_i(d_is_undef_i && !x_stall_i && !x_kill_i && d_valid_i),
.x_exception_o(exception),
.x_exception_pc_i(d_pc_i),
.x_exception_pc_o(exception_address),
.x_exception_vector_o(exception_vector),
.csr_mstatus_o(csr_mstatus),
.csr_mip_o(csr_mip),
......@@ -220,7 +220,7 @@ module rv_exec
if(d_is_eret_i )
branch_target <= exception_address;
else if ( exception )
branch_target <= g_exception_vector;
branch_target <= exception_vector;
else case (d_opcode_i)
`OPC_JAL: branch_target <= d_pc_i + d_imm_i;
`OPC_JALR: branch_target <= rs1 + d_imm_i;
......@@ -300,7 +300,9 @@ module rv_exec
.d_is_shift_i(d_is_shift_i),
.w_rd_o(w_rd_shifter_o)
);
);
wire divider_stall_req = 0;
rv_multiply multiplier
(
......@@ -314,10 +316,35 @@ module rv_exec
.w_rd_o (w_rd_multiply_o)
);
/* wire divider_stall_req;
wire [31:0] rd_divide;
rv_divide divider
(
.clk_i(clk_i),
.rst_i(rst_i),
.x_stall_i(x_stall_i),
.x_kill_i(x_kill_i),
.x_stall_req_o(divider_stall_req),
.d_valid_i(d_valid_i),
.d_is_divide_i(d_is_divide_i),
.d_rs1_i(rs1),
.d_rs2_i(rs2),
.d_fun_i(d_fun_i),
.x_rd_o(rd_divide)
);
-----/\----- EXCLUDED -----/\----- */
always@*
case (d_rd_source_i)
`RD_SOURCE_ALU: rd_value <= alu_result;
`RD_SOURCE_CSR: rd_value <= rd_csr;
// `RD_SOURCE_DIVIDE: rd_value <= rd_divide;
default: rd_value <= 32'hx;
endcase // case (x_rd_source_i)
......@@ -406,16 +433,19 @@ module rv_exec
assign dm_data_s_o = dm_data_s;
assign dm_data_select_o = dm_select_s;
/* -----\/----- EXCLUDED -----\/-----
wire is_load = (d_opcode_i == `OPC_LOAD ? 1: 0) && d_valid_i && !x_kill_i;
wire is_store = (d_opcode_i == `OPC_STORE ? 1: 0) && d_valid_i && !x_kill_i;
-----/\----- EXCLUDED -----/\----- */
assign dm_load_o = is_load && !x_stall_i;
assign dm_store_o = is_store && !x_stall_i;
assign dm_load_o = d_is_load_i & d_valid_i & !x_kill_i & !x_stall_i & !exception;
assign dm_store_o = d_is_store_i & d_valid_i & !x_kill_i & !x_stall_i & !exception;
/* -----\/----- EXCLUDED -----\/-----
wire trig_ent = (d_pc_i == 'h264 && !x_kill_i);
wire trig_ret = (d_pc_i == 'h2bc && !x_kill_i);
wire trig_wr = (dm_addr == 'hf368 && is_store && !x_stall_i);
-----/\----- EXCLUDED -----/\----- */
always@(posedge clk_i)
......@@ -429,8 +459,7 @@ module rv_exec
w_store_o <= 0;
w_dm_addr_o <= 0;
w_rd_source_o <= 0;
w_valid_o <= 0;
end else if (!x_stall_i) begin
f_branch_target_o <= branch_target;
......@@ -438,32 +467,30 @@ module rv_exec
w_rd_o <= d_rd_i;
// if(!shifter_stall_req)
w_rd_value_o <= rd_value;
w_rd_write_o <= d_rd_write_i && !x_kill_i && d_valid_i && !exception;
w_rd_write_o <= d_rd_write_i && !x_kill_i && !exception;
w_rd_source_o <= d_rd_source_i;
w_fun_o <= d_fun_i;
w_load_o <= is_load && !exception;
w_store_o <= is_store && !exception;
w_load_o <= d_is_load_i & d_valid_i && !x_kill_i && !exception;
w_store_o <= d_is_store_i & d_valid_i && !x_kill_i && !exception;
if ( (is_load || is_store) && !exception && unaligned_addr)
/* -----\/----- EXCLUDED -----\/-----
if ( (d_is_load_i || is_store) && !exception && unaligned_addr)
begin
$error("Unaligned address!");
$stop;
end
-----/\----- EXCLUDED -----/\----- */
w_dm_addr_o <= dm_addr;
w_valid_o <= d_valid_i && !x_kill_i && !exception;
end else begin // if (!x_stall_i)
// f_branch_take <= 0;
w_rd_write_o <= 0;
w_load_o <= 0;
w_store_o <= 0;
end // else: !if(rst_i)
w_valid_o <= 0;
end // else: !if(rst_i)
assign f_branch_take_o = f_branch_take;
......@@ -471,9 +498,9 @@ end // else: !if(rst_i)
always@*
if(f_branch_take)
x_stall_req_o <= 0;
else if (x_stall_req_shifter || x_stall_req_multiply || x_stall_req_divide)
else if(divider_stall_req)
x_stall_req_o <= 1;
else if ((is_store || is_load) && !dm_ready_i)
else if ((d_is_load_i || d_is_store_i) && d_valid_i && !x_kill_i && !dm_ready_i)
x_stall_req_o <= 1;
else
x_stall_req_o <= 0;
......
......@@ -15,28 +15,30 @@ module rv_multiply
output reg [31:0] w_rd_o
);
wire sign_a = ( d_fun_i == `FUNC_MUL || d_fun_i == `FUNC_MULHSU ) ? d_rs1_i[31] : 1'b0;
wire sign_b = ( d_fun_i == `FUNC_MUL ) ? d_rs2_i[31] : 1'b0;
wire [32:0] a = { sign_a, d_rs1_i };
wire [32:0] b = { sign_b, d_rs2_i };
reg [31:0] yl_xl, yl_xh, yh_xl;
reg [65:0] stage0, stage1;
reg [2:0] s2_fun;
wire[17:0] xl = d_rs1_i[17:0];
wire[13:0] xh = d_rs1_i[31:18];
wire[17:0] yl = d_rs2_i[17:0];
wire[13:0] yh = d_rs2_i[31:18];
always@(posedge clk_i)
if(!x_stall_i)
begin
stage0 <= $signed(a) * $signed(b);
s2_fun <= d_fun_i;
yh_xl <= $signed(yh) * $signed(xl);
yl_xh <= $signed(yl) * $signed(xh);
yl_xl <= $unsigned(yl) * $unsigned(xl);
end
// stage0 <= $signed(d_rs1_i) * $signed(d_rs2_i);
always@*
if( s2_fun != `FUNC_MUL )
w_rd_o <= stage0[63:32];
else
w_rd_o <= stage0[31:0];
w_rd_o <= yl_xl + {yl_xh[13:0], 18'h0} + {yh_xl[13:0], 18'h0};
endmodule // rv_multiply
......
......@@ -39,7 +39,7 @@ module rv_decode
input [31:0] f_pc_i,
input f_valid_i,
output x_valid_o,
output x_valid_o,
output reg [31:0] x_pc_o,
......@@ -62,8 +62,13 @@ module rv_decode
output reg x_is_signed_alu_op_o,
output reg x_is_add_o,
output x_is_shift_o,
output reg x_is_load_o,
output reg x_is_store_o,
output reg x_is_undef_o,
output reg [2:0] x_rd_source_o,
output reg x_rd_write_o,
output x_rd_write_o,
output reg [11:0] x_csr_sel_o,
output reg [4:0] x_csr_imm_o,
......@@ -75,13 +80,14 @@ module rv_decode
wire [4:0] f_rs1 = f_ir_i[19:15];
wire [4:0] f_rs2 = f_ir_i[24:20];
reg [4:0] x_rs1;
reg [4:0] x_rs1;
reg [4:0] x_rs2;
reg [4:0] x_rd;
reg [4:0] x_opcode;
reg x_valid;
reg x_is_shift;
reg x_rd_write;
assign x_rs1_o = x_rs1;
......@@ -126,13 +132,19 @@ module rv_decode
wire d_is_shift = (d_fun == `FUNC_SL || d_fun == `FUNC_SR) &&
(d_opcode == `OPC_OP || d_opcode == `OPC_OP_IMM );
reg x_is_mul;
wire d_is_mul = (f_ir_i[25] && d_fun == 3'b000);
always@*
if (x_valid && f_valid_i && ( (f_rs1 == x_rd) || (f_rs2 == x_rd) ) && (!d_kill_i) )
begin
case (x_opcode)
`OPC_LOAD:
load_hazard <= 1;
`OPC_OP,
`OPC_OP:
load_hazard <= x_is_shift | x_is_mul;
`OPC_OP_IMM:
load_hazard <= x_is_shift;
default:
......@@ -141,8 +153,6 @@ module rv_decode
end else
load_hazard <= 0;
//wire load_hazard = x_valid && f_valid_i && ( (f_rs1 == x_rd) || (f_rs2 == x_rd) ) && (!d_kill_i) && (x_opcode == `OPC_LOAD);
reg inserting_nop = 0;
always@(posedge clk_i)
......@@ -165,8 +175,8 @@ module rv_decode
begin
x_rs1 <= f_rs1;
x_rs2 <= f_rs2;
x_rd <= load_hazard ? 0 : f_ir_i [11:7];
x_opcode <= load_hazard ? `OPC_OP : d_opcode;
x_rd <= (load_hazard && !inserting_nop) ? 0 : f_ir_i [11:7];
x_opcode <= (load_hazard && !inserting_nop) ? `OPC_OP : d_opcode;
load_hazard_d <= load_hazard;
x_shamt_o <= f_ir_i[24:20];
end
......@@ -219,11 +229,15 @@ module rv_decode
if(!d_stall_i)
begin
x_is_shift <= d_is_shift;
x_is_load_o <= ( d_opcode == `OPC_LOAD && !load_hazard) ? 1'b1 : 1'b0;
x_is_store_o <= ( d_opcode == `OPC_STORE && !load_hazard) ? 1'b1 : 1'b0;
x_is_signed_compare_o <= ( ( d_opcode == `OPC_BRANCH) && ( ( d_fun == `BRA_GE )|| (d_fun == `BRA_LT ) ) )
|| ( ( (d_opcode == `OPC_OP) || (d_opcode == `OPC_OP_IMM) ) && (d_fun == `FUNC_SLT ) );
x_is_mul <= d_is_mul;
x_is_add_o <= (d_opcode == `OPC_AUIPC) || (d_opcode == `OPC_JAL) ||
......@@ -232,6 +246,8 @@ module rv_decode
x_is_signed_alu_op_o <= (d_fun == `FUNC_SLT);
// all multiply/divide instructions except MUL
x_is_undef_o <= (d_opcode == `OPC_OP && f_ir_i[25] && d_fun != 3'b000);
if(d_is_shift)
x_rd_source_o <= `RD_SOURCE_SHIFTER;
......@@ -247,11 +263,11 @@ module rv_decode
// rdest write value
case (d_opcode)
`OPC_OP_IMM, `OPC_OP, `OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
x_rd_write_o <= 1;
x_rd_write <= 1;
`OPC_SYSTEM:
x_rd_write_o <= (d_fun != 0); // CSR instructions write to RD
x_rd_write <= (d_fun != 0); // CSR instructions write to RD
default:
x_rd_write_o <= 0;
x_rd_write <= 0;
endcase // case (d_opcode)
end // if (!d_stall_i)
......@@ -271,6 +287,7 @@ module rv_decode
end
assign x_is_shift_o = x_is_shift;
assign x_rd_write_o = x_rd_write;
......
......@@ -24,36 +24,38 @@
module rv_writeback
(
input clk_i,
input rst_i,
input clk_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 x_load_i,
input x_store_i,
input [2:0] x_fun_i,
input x_load_i,
input x_store_i,
input x_load_hazard_i,
input [31:0] x_dm_addr_i,
input [4:0] x_rd_i,
input [31:0] x_rd_value_i,
input x_rd_write_i,
input [31:0] x_shifter_rd_value_i,
input [31:0] x_multiply_rd_value_i,
input [1:0] x_rd_source_i,
input x_load_hazard_i,
input [31:0] x_dm_addr_i,
input [4:0] x_rd_i,
input [31:0] x_rd_value_i,
input x_rd_write_i,
input x_valid_i,
input [31:0] dm_data_l_i,
input dm_load_done_i,
input dm_store_done_i,
input [31:0] x_shifter_rd_value_i,
input [31:0] x_multiply_rd_value_i,
input [1:0] x_rd_source_i,
input [31:0] dm_data_l_i,
input dm_load_done_i,
input dm_store_done_i,
output reg [31:0] rf_rd_value_o,
output [4:0] rf_rd_o,
output reg rf_rd_write_o,
output [4:0] rf_rd_o,
output reg rf_rd_write_o,
output [31:0] TRIG2
output [31:0] TRIG2
);
reg [31:0] load_value;
......@@ -102,31 +104,8 @@ module rv_writeback
endcase // case (d_fun_i)
end // always@ *
reg pending_load, pending_store;
always@(posedge clk_i)
if(rst_i) begin
pending_load <= 0;
pending_store <= 0;
end else begin
if(x_load_i && !dm_load_done_i) begin
pending_load <= 1;
end else if (dm_load_done_i) begin
pending_load <= 0;
end
if(x_store_i && !dm_store_done_i)
pending_store <= 1;
else if (dm_store_done_i)
pending_store <= 0;
end
always@*
if( x_load_i || pending_load )
if( x_load_i )
rf_rd_value_o <= load_value;
else if ( x_rd_source_i == `RD_SOURCE_SHIFTER )
rf_rd_value_o <= x_shifter_rd_value_i;
......@@ -135,28 +114,20 @@ module rv_writeback
else
rf_rd_value_o <= x_rd_value_i;
always@*
if (w_stall_i)
rf_rd_write_o <= 0;
else if ( (x_load_i || pending_load) && dm_load_done_i)
else if (x_load_i && dm_load_done_i)
rf_rd_write_o <= 1;
else
rf_rd_write_o <= x_rd_write_i;
rf_rd_write_o <= x_rd_write_i & x_valid_i;
// assign rf_rd_value_o = (x_load_i || pending_load ? load_value : x_rd_value_i );
assign rf_rd_o = (x_rd_i);
assign w_stall_req_o = ((x_load_i || pending_load) && !dm_load_done_i) || ((x_store_i || pending_store) && !dm_store_done_i);
assign w_stall_req_o = (x_load_i && !dm_load_done_i) || (x_store_i && !dm_store_done_i);
assign TRIG2[6] = x_load_i;
assign TRIG2[7] = pending_load;
assign TRIG2[8] = dm_load_done_i;
assign TRIG2[9] = x_store_i;
assign TRIG2[10] = pending_store;
assign TRIG2[11] = dm_store_done_i;
assign TRIG2[15] = w_stall_req_o;
......
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