Commit 2512ebf0 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

will add D stage

parent 79a000cb
......@@ -127,6 +127,15 @@ module rv_cpu
.x_imm_j_o(d2x_imm_j)
);
wire [4:0] x2w_rd;
wire [31:0] x2w_rd_value;
wire [31:0] x2w_dm_addr;
wire x2w_rd_write;
wire [2:0] x2w_fun;
wire x2w_store;
wire x2w_load;
wire [31:0] x_rs2_value, x_rs1_value;
wire [4:0] rf_rd;
......@@ -134,6 +143,13 @@ module rv_cpu
wire rf_rd_write;
wire [31:0] rf_bypass_rd_value = rf_rd_value;
//x2w_rd_value;
wire rf_bypass_rd_write = rf_rd_write && !x2w_load;
// x2w_rd_write && !w_stall;
rv_regfile regfile
(
.clk_i(clk_i),
......@@ -153,15 +169,14 @@ module rv_cpu
.w_rd_i(rf_rd),
.w_rd_value_i(rf_rd_value),
.w_rd_store_i(rf_rd_write)
.w_rd_store_i(rf_rd_write),
.w_bypass_rd_write_i(rf_bypass_rd_write),
.w_bypass_rd_value_i(rf_bypass_rd_value)
);
wire [4:0] x2w_rd;
wire [31:0] x2w_rd_value;
wire [31:0] x2w_dm_addr;
wire x2w_rd_write;
wire [2:0] x2w_fun;
wire x2w_store;
wire x_load_comb;
......@@ -194,6 +209,8 @@ module rv_cpu
.f_branch_target_o (x2f_pc_bra), // fixme: consistent naming
.f_branch_take_o (x2f_bra),
.x_load_o(x_load_comb),
// Writeback stage I/F
.w_fun_o(x2w_fun),
.w_load_o(x2w_load),
......@@ -250,9 +267,22 @@ module rv_cpu
else if (!x_stall)
x2f_bra_d0 <= x2f_bra;
// load to Rd in W stage while Rs1/Rs2==RD in fetch stage: assert interlock
reg interlock_load;
reg interlock_load_d0 = 0;
assign f_stall = x_stall_req || w_stall_req;
always@*
interlock_load <= x_load_comb && ((d2x_rd == rf_rs1) || (d2x_rd == rf_rs2));
always@(posedge clk_i)
interlock_load_d0 <= interlock_load;
assign f_stall = x_stall_req || w_stall_req || (interlock_load && !interlock_load_d0);
assign x_stall = x_stall_req || w_stall_req;
// || (interlock_load && !interlock_load_d0);
// || (!f2d_ir_valid);
assign w_stall = 0;
//x_stall_req;
......@@ -262,6 +292,8 @@ module rv_cpu
//&& ~x_bra_d0;
......
......@@ -35,6 +35,7 @@ module rv_exec
input [4:0] d_rd_i,
input [2:0] d_fun_i,
input [31:0] rf_rs1_value_i,
input [31:0] rf_rs2_value_i,
......@@ -52,6 +53,8 @@ module rv_exec
output reg [31:0] f_branch_target_o,
output reg f_branch_take_o,
output x_load_o,
// Writeback stage I/F
output reg [2:0 ] w_fun_o,
output reg w_load_o,
......@@ -92,13 +95,13 @@ module rv_exec
wire cmp_sign_ext = ( ( d_opcode_i == `OPC_BRANCH) && ( ( d_fun_i == `BRA_GE )|| (d_fun_i == `BRA_LT ) ) )
|| ( ( (d_opcode_i == `OPC_OP) || (d_opcode_i == `OPC_OP_IMM) ) && (d_fun_i == `FUNC_SLT ) );
wire [32:0] cmp_op1 = { cmp_sign_ext ? alu_op1[31] : 1'b0, alu_op1 };
wire [32:0] cmp_op2 = { cmp_sign_ext ? alu_op2[31] : 1'b0, alu_op2 };
wire cmp_equal = (cmp_op1 == cmp_op2);
wire cmp_lt = ($signed(cmp_op1) < $signed(cmp_op2));
wire [32:0] cmp_op1 = { cmp_sign_ext ? rs1[31] : 1'b0, rs1 };
wire [32:0] cmp_op2 = { cmp_sign_ext ? 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];
// branch condition decoding
always@*
......@@ -112,20 +115,6 @@ module rv_exec
default: branch_condition_met <= 0;
endcase // case (d_fun_i)
/* -----\/----- EXCLUDED -----\/-----
// branch condition decoding
always@*
case (d_fun_i)
`BRA_EQ: branch_condition_met <= (rs1 == rs2);
`BRA_NEQ: branch_condition_met <= ~(rs1 == rs2);
`BRA_GE: branch_condition_met <= ($signed(rs1) >= $signed(rs2));
`BRA_LT: branch_condition_met <= ($signed(rs1) < $signed(rs2));
`BRA_GEU: branch_condition_met <= (rs1 >= rs2);
`BRA_LTU: branch_condition_met <= (rs1 < rs2);
default: branch_condition_met <= 0;
endcase // case (d_fun_i)
-----/\----- EXCLUDED -----/\----- */
always@*
case (d_opcode_i)
`OPC_JAL: branch_target <= d_pc_i + d_imm_j_i;
......@@ -135,24 +124,6 @@ module rv_exec
default: branch_target<= 32'hx;
endcase // case (d_opcode_i)
/* -----\/----- EXCLUDED -----\/-----
rd_value <= d_pc_i + 4;
rd_write <= 1;
end
-----/\----- EXCLUDED -----/\----- *-/
`OPC_LUI:
begin
rd_value <= { d_imm_u_i[31:12] , 12'h0 };
rd_write <= 1;
end
`OPC_AUIPC:
begin
rd_value <= d_pc_i + { d_imm_u_i[31:12], 12'h0 };
-----/\----- EXCLUDED -----/\----- */
// decode ALU operands
always@*
begin
......@@ -165,9 +136,6 @@ module rv_exec
endcase // case (d_opcode_i)
//alu_op1 <= rs1;
case (d_opcode_i)
`OPC_LUI: alu_op2 <= 0;
`OPC_AUIPC: alu_op2 <= d_pc_i;
......@@ -177,40 +145,42 @@ module rv_exec
default: alu_op2 <= rs2;
endcase // case (d_opcode_i)
//alu_op2 <= (d_opcode_i == `OPC_OP_IMM) ? d_imm_i_i : rs2;
//endcase
end
wire is_subtract = (d_opcode_i == `OPC_OP && d_shifter_sign_i);
wire is_add = !((d_opcode_i == `OPC_OP && d_fun_i == `FUNC_ADD && d_shifter_sign_i) || (d_fun_i == `FUNC_SLT) || (d_fun_i == `FUNC_SLTU));
wire[31:0] shifter_result;
wire alu_op_signext = (d_fun_i == `FUNC_SLT);
wire [32:0] alu_addsub_op1 = {alu_op_signext ? alu_op1[31] : 1'b0, alu_op1 };
wire [32:0] alu_addsub_op2 = {alu_op_signext ? alu_op2[31] : 1'b0, alu_op2 };
reg [32:0] alu_addsub_result;
always@*
if(is_add)
alu_addsub_result <= alu_addsub_op1 + alu_addsub_op2;
else
alu_addsub_result <= alu_addsub_op1 - alu_addsub_op2;
// the ALU itself
always@*
begin
case (d_fun_i)
`FUNC_ADD:
if(is_subtract)
alu_result <= alu_op1 - alu_op2;
else
alu_result <= alu_op1 + alu_op2;
alu_result <= alu_addsub_result[31:0];
`FUNC_XOR: alu_result <= alu_op1 ^ alu_op2;
`FUNC_OR: alu_result <= alu_op1 | alu_op2;
`FUNC_AND: alu_result <= alu_op1 & alu_op2;
`FUNC_SLT: alu_result <= cmp_lt ? 1 : 0;
`FUNC_SLTU: alu_result <= cmp_lt ? 1 : 0;
`FUNC_SLT: alu_result <= alu_addsub_result[32]?1:0;
`FUNC_SLTU: alu_result <= alu_addsub_result[32]?1:0;
`FUNC_SL, `FUNC_SR: alu_result <= shifter_result;
/* `FUNC_SL: alu_result <= alu_op1 << alu_op2[4:0];
`FUNC_SR:
begin
if(d_shifter_sign_i)
alu_result <= $signed(alu_op1) >>> alu_op2[4:0];
else
alu_result <= alu_op1 >> alu_op2[4:0];
end*/
default: alu_result <= 32'hx;
endcase // case (d_fun_i)
......@@ -366,7 +336,10 @@ module rv_exec
w_store_o <= 0;
end
assign x_stall_req_o = shifter_stall_req || ((is_store || is_load) && !dm_ready_i);
assign x_load_o = is_load;
endmodule
......
......@@ -44,13 +44,23 @@ module rv_fetch
);
reg [31:0] pc;
reg [31:0] ir;
reg [31:0] ir, ir_d0;
reg rst_d;
reg im_valid_d0;
// wire [31:0] pc_next = (x_bra_i ? x_pc_bra_i : ( ( f_stall_i || !im_valid_i ) ? pc : pc + 4));
reg [31:0] pc_next;
always@*
if( x_bra_i )
pc_next <= x_pc_bra_i;
else if (f_stall_i || !im_valid_i)
pc_next <= pc;
else
pc_next <= pc + 4;
wire [31:0] pc_next = (x_bra_i ? x_pc_bra_i : ( ( f_stall_i || !im_valid_i ) ? pc : pc + 4));
assign f_ir_o = ir;
......@@ -76,6 +86,8 @@ module rv_fetch
if(im_valid_i) begin
ir <= im_data_i; // emit nop
ir_d0 <= ir;
f_valid_o <= (rst_d && !f_kill_i);
end else begin// if (i_valid_i)
......
......@@ -61,9 +61,8 @@ module rv_predecode
wire [4:0] f_opcode = f_ir_i[6:2];
assign rf_rs1_o = f_stall_i ? f_ir_i[19:15] : im_data_i [19:15];
assign rf_rs2_o = f_stall_i ? f_ir_i[24:20] : im_data_i [24:20];
assign rf_rs1_o = im_data_i [19:15];
assign rf_rs2_o = im_data_i [24:20];
assign x_rs1_o = f_ir_i [19:15];
assign x_rs2_o = f_ir_i [24:20];
......@@ -95,17 +94,10 @@ module rv_predecode
assign x_imm_b_o = { {20{ f_ir_i[31] }}, f_ir_i[7], f_ir_i[30:25], f_ir_i[11:8], 1'b0 };
assign x_imm_u_o = { f_ir_i[31], f_ir_i[30:20], f_ir_i[19:12], 12'h000 };
assign x_imm_j_o = { {12{f_ir_i[31]}},
f_ir_i[19:12],
f_ir_i[20], f_ir_i[30:25], f_ir_i[24:21], 1'b0};
f_ir_i[19:12],
f_ir_i[20], f_ir_i[30:25], f_ir_i[24:21], 1'b0};
assign x_pc_o = f_pc_i;
endmodule // rv_predecode
......
......@@ -107,7 +107,11 @@ module rv_regfile
input [4:0] w_rd_i,
input [31:0] w_rd_value_i,
input w_rd_store_i
input w_rd_store_i,
input w_bypass_rd_write_i,
input [31:0] w_bypass_rd_value_i
);
......@@ -140,12 +144,11 @@ module rv_regfile
wire rs1_bypass = write && (/*(w_rd_i == rf_rs1_i) ||*/ (w_rd_i == d_rs1_i));
wire rs2_bypass = write && (/*(w_rd_i == rf_rs2_i) ||*/ (w_rd_i == d_rs2_i));
wire rs1_bypass = w_bypass_rd_write_i && (w_rd_i == d_rs1_i);
wire rs2_bypass = w_bypass_rd_write_i && (w_rd_i == d_rs2_i);
assign x_rs1_value_o = rs1_bypass ? w_rd_value_i : rs1_regfile;
assign x_rs2_value_o = rs2_bypass ? w_rd_value_i : rs2_regfile;
assign x_rs1_value_o = rs1_bypass ? w_bypass_rd_value_i : rs1_regfile;
assign x_rs2_value_o = rs2_bypass ? w_bypass_rd_value_i : rs2_regfile;
endmodule // rv_regfile
......
......@@ -34,6 +34,7 @@ add wave -noupdate -expand -group cpu /main/DUT/d2x_imm_s
add wave -noupdate -expand -group cpu /main/DUT/d2x_imm_b
add wave -noupdate -expand -group cpu /main/DUT/d2x_imm_u
add wave -noupdate -expand -group cpu /main/DUT/d2x_imm_j
add wave -noupdate /main/DUT/interlock_load
add wave -noupdate -expand -group fetch /main/DUT/fetch/clk_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/rst_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_addr_o
......@@ -81,8 +82,11 @@ add wave -noupdate -expand -group regfile /main/DUT/regfile/x_rs2_value_o
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_rd_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_rd_value_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_rd_store_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_bypass_rd_write_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/w_bypass_rd_value_i
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs1_regfile
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs2_regfile
add wave -noupdate -expand -group regfile /main/DUT/regfile/write
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs1_bypass
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs2_bypass
add wave -noupdate /main/DUT/regfile/bank0/ram
......@@ -156,7 +160,6 @@ add wave -noupdate -expand -group execute /main/DUT/execute/cmp_op1
add wave -noupdate -expand -group execute /main/DUT/execute/cmp_op2
add wave -noupdate -expand -group execute /main/DUT/execute/cmp_equal
add wave -noupdate -expand -group execute /main/DUT/execute/cmp_lt
add wave -noupdate -expand -group execute /main/DUT/execute/is_subtract
add wave -noupdate -expand -group execute /main/DUT/execute/shifter_result
add wave -noupdate -expand -group execute /main/DUT/execute/shifter_req_d0
add wave -noupdate -expand -group execute /main/DUT/execute/shifter_req
......@@ -182,7 +185,7 @@ add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_write_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/load_value
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {13680175 ps} 0}
WaveRestoreCursors {{Cursor 1} {13948780 ps} 0}
configure wave -namecolwidth 250
configure wave -valuecolwidth 100
configure wave -justifyvalue left
......@@ -197,4 +200,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ps
update
WaveRestoreZoom {13606882 ps} {13751520 ps}
WaveRestoreZoom {13882681 ps} {14027319 ps}
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