Commit b2bc141b authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

shifter refactor

parent 1cc11f80
...@@ -13,4 +13,5 @@ files = [ "main.sv", ...@@ -13,4 +13,5 @@ files = [ "main.sv",
"rv_predecode.v", "rv_predecode.v",
"rv_regfile.v", "rv_regfile.v",
"rv_writeback.v", "rv_writeback.v",
"rv_shifter.v"]; "rv_shifter.v",
"rv_multiply.v"];
...@@ -77,6 +77,9 @@ module rv_cpu ...@@ -77,6 +77,9 @@ module rv_cpu
wire d2x_is_signed_alu_op; wire d2x_is_signed_alu_op;
wire d2x_is_add_o; wire d2x_is_add_o;
wire d2x_is_shift_o; wire d2x_is_shift_o;
wire [1:0] d2x_rd_source;
wire d2x_rd_write;
wire d2x_load_hazard; wire d2x_load_hazard;
wire d_stall, d_kill; wire d_stall, d_kill;
...@@ -137,7 +140,9 @@ module rv_cpu ...@@ -137,7 +140,9 @@ module rv_cpu
.x_is_signed_compare_o(d2x_is_signed_compare), .x_is_signed_compare_o(d2x_is_signed_compare),
.x_is_signed_alu_op_o(d2x_is_signed_alu_op), .x_is_signed_alu_op_o(d2x_is_signed_alu_op),
.x_is_add_o(d2x_is_add), .x_is_add_o(d2x_is_add),
.x_is_shift_o(d2x_is_shift) .x_is_shift_o(d2x_is_shift),
.x_rd_source_o(d2x_rd_source),
.x_rd_write_o(d2x_rd_write)
); );
wire [4:0] x2w_rd; wire [4:0] x2w_rd;
...@@ -213,6 +218,8 @@ module rv_cpu ...@@ -213,6 +218,8 @@ module rv_cpu
.d_is_signed_alu_op_i(d2x_is_signed_alu_op), .d_is_signed_alu_op_i(d2x_is_signed_alu_op),
.d_is_add_i(d2x_is_add), .d_is_add_i(d2x_is_add),
.d_is_shift_i(d2x_is_shift), .d_is_shift_i(d2x_is_shift),
.d_rd_source_i(d2x_rd_source),
.d_rd_write_i(d2x_rd_write),
.rf_rs1_value_i(x_rs1_value), .rf_rs1_value_i(x_rs1_value),
.rf_rs2_value_i(x_rs2_value), .rf_rs2_value_i(x_rs2_value),
......
...@@ -50,3 +50,12 @@ ...@@ -50,3 +50,12 @@
`define FUNC_SL 3'b001 `define FUNC_SL 3'b001
`define FUNC_SR 3'b101 `define FUNC_SR 3'b101
`define FUNC_MUL 3'b000
`define FUNC_MULH 3'b001
`define FUNC_MULHSU 3'b010
`define FUNC_MULHU 3'b011
`define RD_SOURCE_ALU 2'b00
`define RD_SOURCE_SHIFTER 2'b10
`define RD_SOURCE_MULTIPLY 2'b01
`define RD_SOURCE_DIVIDE 2'b11
...@@ -29,8 +29,8 @@ module rv_exec ...@@ -29,8 +29,8 @@ module rv_exec
input x_stall_i, input x_stall_i,
input x_kill_i, input x_kill_i,
output x_stall_req_o, output reg x_stall_req_o,
input w_stall_req_i, input w_stall_req_i,
input [31:0] d_pc_i, input [31:0] d_pc_i,
...@@ -53,9 +53,11 @@ input w_stall_req_i, ...@@ -53,9 +53,11 @@ input w_stall_req_i,
input d_is_signed_alu_op_i, input d_is_signed_alu_op_i,
input d_is_add_i, input d_is_add_i,
input d_is_shift_i, input d_is_shift_i,
input [1:0] d_rd_source_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,
output w_load_hazard_o, output w_load_hazard_o,
...@@ -94,8 +96,6 @@ input w_stall_req_i, ...@@ -94,8 +96,6 @@ input w_stall_req_i,
reg [31:0] dm_addr, dm_data_s, dm_select_s; reg [31:0] dm_addr, dm_data_s, dm_select_s;
reg rd_write;
wire [32:0] cmp_op1 = { d_is_signed_compare_i ? rs1[31] : 1'b0, rs1 }; wire [32:0] cmp_op1 = { d_is_signed_compare_i ? rs1[31] : 1'b0, rs1 };
wire [32:0] cmp_op2 = { d_is_signed_compare_i ? rs2[31] : 1'b0, rs2 }; wire [32:0] cmp_op2 = { d_is_signed_compare_i ? rs2[31] : 1'b0, rs2 };
...@@ -153,8 +153,6 @@ input w_stall_req_i, ...@@ -153,8 +153,6 @@ input w_stall_req_i,
wire[31:0] shifter_result;
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 };
...@@ -182,61 +180,49 @@ input w_stall_req_i, ...@@ -182,61 +180,49 @@ input w_stall_req_i,
`FUNC_AND: alu_result <= alu_op1 & alu_op2; `FUNC_AND: alu_result <= alu_op1 & alu_op2;
`FUNC_SLT: alu_result <= alu_addsub_result[32]?1:0; `FUNC_SLT: alu_result <= alu_addsub_result[32]?1:0;
`FUNC_SLTU: 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;
default: alu_result <= 32'hx; default: alu_result <= 32'hx;
endcase // case (d_fun_i) endcase // case (d_fun_i)
end // always@ * end // always@ *
reg shifter_req_d0; wire x_stall_req_shifter;
wire shifter_req = !w_stall_req_i && (d_valid_i) && d_is_shift_i; wire x_stall_req_multiply = 0;
wire x_stall_req_divide = 0;
wire [31:0] rd_shifter;
rv_shifter shifter rv_shifter shifter
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
.d_i(alu_op1), .x_stall_i(x_stall_i),
.q_o(shifter_result), .w_stall_req_i(w_stall_req_i),
.shift_i(alu_op2[4:0]), .d_valid_i(d_valid_i),
.func_i(d_fun_i), .d_rs1_i(rs1),
.arith_i(d_shifter_sign_i) .d_shamt_i(alu_op2[4:0]),
.d_fun_i(d_fun_i),
.d_shifter_sign_i(d_shifter_sign_i),
.d_is_shift_i(d_is_shift_i),
.x_stall_req_o(x_stall_req_shifter),
.x_rd_o(rd_shifter)
); );
always@(posedge clk_i)
if(shifter_req_d0 && !x_stall_i)
shifter_req_d0 <= 0;
else
shifter_req_d0 <= shifter_req;
wire shifter_stall_req = shifter_req && !shifter_req_d0;
// rdest write value
always@* always@*
begin case (d_rd_source_i)
case (d_opcode_i) `RD_SOURCE_ALU: rd_value <= alu_result;
`OPC_OP_IMM, `OPC_OP, `OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC: `RD_SOURCE_SHIFTER : rd_value <= rd_shifter;
begin default: rd_value <= 32'hx;
rd_value <= alu_result; endcase // case (x_rd_source_i)
rd_write <= 1;
end
default:
begin
rd_value <= 32'hx;
rd_write <= 0;
end
endcase
end
// generate load/store address // generate load/store address
always@* always@*
begin begin
dm_addr <= rs1 + d_imm_i; dm_addr <= rs1 + d_imm_i;
//[11:0]); //[11:0]);
end end
...@@ -322,7 +308,7 @@ input w_stall_req_i, ...@@ -322,7 +308,7 @@ input w_stall_req_i,
// if(!shifter_stall_req) // if(!shifter_stall_req)
w_rd_value_o <= rd_value; w_rd_value_o <= rd_value;
w_rd_write_o <= rd_write && !x_kill_i && d_valid_i; w_rd_write_o <= d_rd_write_i && !x_kill_i && d_valid_i;
w_fun_o <= d_fun_i; w_fun_o <= d_fun_i;
w_load_o <= is_load; w_load_o <= is_load;
...@@ -342,13 +328,17 @@ end // else: !if(rst_i) ...@@ -342,13 +328,17 @@ end // else: !if(rst_i)
assign f_branch_take_o = f_branch_take; assign f_branch_take_o = f_branch_take;
always@*
assign x_stall_req_o = !f_branch_take && (shifter_stall_req || ((is_store || is_load) && !dm_ready_i)); if(f_branch_take)
assign w_load_hazard_o = d_load_hazard_i; x_stall_req_o <= 0;
else if (x_stall_req_shifter || x_stall_req_multiply || x_stall_req_divide)
x_stall_req_o <= 1;
else if ((is_store || is_load) && !dm_ready_i)
x_stall_req_o <= 1;
else
x_stall_req_o <= 0;
assign w_load_hazard_o = d_load_hazard_i;
endmodule endmodule
......
...@@ -52,14 +52,17 @@ module rv_decode ...@@ -52,14 +52,17 @@ module rv_decode
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 [31:0] x_imm_o, output reg [31:0] x_imm_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,
output reg x_is_shift_o output reg x_is_shift_o,
output reg [1:0] x_rd_source_o,
output reg x_rd_write_o
); );
...@@ -158,21 +161,38 @@ module rv_decode ...@@ -158,21 +161,38 @@ module rv_decode
default: x_imm_o <= 32'hx; default: x_imm_o <= 32'hx;
endcase // case (opcode) endcase // case (opcode)
end // always@ (posedge clk_i) end // always@ (posedge clk_i)
wire d_is_shift = (d_fun == `FUNC_SL || d_fun == `FUNC_SR) &&
(d_opcode == `OPC_OP || d_opcode == `OPC_OP_IMM );
// misc decoding // misc decoding
always@(posedge clk_i) always@(posedge clk_i)
if(!d_stall_i) if(!d_stall_i)
begin begin
x_is_shift_o <= (d_fun == `FUNC_SL || d_fun == `FUNC_SR) && x_is_shift_o <= d_is_shift;
(d_opcode == `OPC_OP || d_opcode == `OPC_OP_IMM );
x_is_signed_compare_o <= ( ( d_opcode == `OPC_BRANCH) && ( ( d_fun == `BRA_GE )|| (d_fun == `BRA_LT ) ) ) 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 ) ); || ( ( (d_opcode == `OPC_OP) || (d_opcode == `OPC_OP_IMM) ) && (d_fun == `FUNC_SLT ) );
x_is_add_o <= !((d_opcode == `OPC_OP && d_fun == `FUNC_ADD && f_ir_i[30]) || (d_fun == `FUNC_SLT) || (d_fun == `FUNC_SLTU));
x_is_add_o <= !((d_opcode == `OPC_OP && d_fun == `FUNC_ADD && f_ir_i[30]) || (d_fun == `FUNC_SLT) || (d_fun == `FUNC_SLTU)); x_is_signed_alu_op_o <= (d_fun == `FUNC_SLT);
x_is_signed_alu_op_o <= (d_fun == `FUNC_SLT);
end if(d_is_shift)
x_rd_source_o <= `RD_SOURCE_SHIFTER;
else
x_rd_source_o <= `RD_SOURCE_ALU;
// rdest write value
case (d_opcode)
`OPC_OP_IMM, `OPC_OP, `OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
x_rd_write_o <= 1;
default:
x_rd_write_o <= 0;
endcase // case (d_opcode)
end // if (!d_stall_i)
......
...@@ -64,16 +64,26 @@ add wave -noupdate -expand -group X /main/DUT/execute/rst_i ...@@ -64,16 +64,26 @@ add wave -noupdate -expand -group X /main/DUT/execute/rst_i
add wave -noupdate -expand -group X /main/DUT/execute/x_stall_i add wave -noupdate -expand -group X /main/DUT/execute/x_stall_i
add wave -noupdate -expand -group X /main/DUT/execute/x_kill_i add wave -noupdate -expand -group X /main/DUT/execute/x_kill_i
add wave -noupdate -expand -group X /main/DUT/execute/x_stall_req_o add wave -noupdate -expand -group X /main/DUT/execute/x_stall_req_o
add wave -noupdate -expand -group X /main/DUT/execute/w_stall_req_i
add wave -noupdate -expand -group X /main/DUT/execute/d_pc_i add wave -noupdate -expand -group X /main/DUT/execute/d_pc_i
add wave -noupdate -expand -group X /main/DUT/execute/d_rd_i add wave -noupdate -expand -group X /main/DUT/execute/d_rd_i
add wave -noupdate -expand -group X /main/DUT/execute/d_fun_i add wave -noupdate -expand -group X /main/DUT/execute/d_fun_i
add wave -noupdate -expand -group X /main/DUT/execute/rf_rs1_value_i add wave -noupdate -expand -group X /main/DUT/execute/rf_rs1_value_i
add wave -noupdate -expand -group X /main/DUT/execute/rf_rs2_value_i add wave -noupdate -expand -group X /main/DUT/execute/rf_rs2_value_i
add wave -noupdate -expand -group X /main/DUT/execute/d_valid_i add wave -noupdate -expand -group X /main/DUT/execute/d_valid_i
add wave -noupdate -expand -group X /main/DUT/execute/d_load_hazard_i
add wave -noupdate -expand -group X /main/DUT/execute/d_opcode_i add wave -noupdate -expand -group X /main/DUT/execute/d_opcode_i
add wave -noupdate -expand -group X /main/DUT/execute/d_shifter_sign_i add wave -noupdate -expand -group X /main/DUT/execute/d_shifter_sign_i
add wave -noupdate -expand -group X /main/DUT/execute/d_imm_i
add wave -noupdate -expand -group X /main/DUT/execute/d_is_signed_compare_i
add wave -noupdate -expand -group X /main/DUT/execute/d_is_signed_alu_op_i
add wave -noupdate -expand -group X /main/DUT/execute/d_is_add_i
add wave -noupdate -expand -group X /main/DUT/execute/d_is_shift_i
add wave -noupdate -expand -group X /main/DUT/execute/d_rd_source_i
add wave -noupdate -expand -group X /main/DUT/execute/d_rd_write_i
add wave -noupdate -expand -group X /main/DUT/execute/f_branch_target_o add wave -noupdate -expand -group X /main/DUT/execute/f_branch_target_o
add wave -noupdate -expand -group X /main/DUT/execute/f_branch_take_o add wave -noupdate -expand -group X /main/DUT/execute/f_branch_take_o
add wave -noupdate -expand -group X /main/DUT/execute/w_load_hazard_o
add wave -noupdate -expand -group X /main/DUT/execute/w_fun_o add wave -noupdate -expand -group X /main/DUT/execute/w_fun_o
add wave -noupdate -expand -group X /main/DUT/execute/w_load_o add wave -noupdate -expand -group X /main/DUT/execute/w_load_o
add wave -noupdate -expand -group X /main/DUT/execute/w_store_o add wave -noupdate -expand -group X /main/DUT/execute/w_store_o
...@@ -99,19 +109,22 @@ add wave -noupdate -expand -group X /main/DUT/execute/branch_target ...@@ -99,19 +109,22 @@ add wave -noupdate -expand -group X /main/DUT/execute/branch_target
add wave -noupdate -expand -group X /main/DUT/execute/dm_addr add wave -noupdate -expand -group X /main/DUT/execute/dm_addr
add wave -noupdate -expand -group X /main/DUT/execute/dm_data_s add wave -noupdate -expand -group X /main/DUT/execute/dm_data_s
add wave -noupdate -expand -group X /main/DUT/execute/dm_select_s add wave -noupdate -expand -group X /main/DUT/execute/dm_select_s
add wave -noupdate -expand -group X /main/DUT/execute/rd_write
add wave -noupdate -expand -group X /main/DUT/execute/cmp_op1 add wave -noupdate -expand -group X /main/DUT/execute/cmp_op1
add wave -noupdate -expand -group X /main/DUT/execute/cmp_op2 add wave -noupdate -expand -group X /main/DUT/execute/cmp_op2
add wave -noupdate -expand -group X /main/DUT/execute/cmp_rs add wave -noupdate -expand -group X /main/DUT/execute/cmp_rs
add wave -noupdate -expand -group X /main/DUT/execute/cmp_equal add wave -noupdate -expand -group X /main/DUT/execute/cmp_equal
add wave -noupdate -expand -group X /main/DUT/execute/cmp_lt add wave -noupdate -expand -group X /main/DUT/execute/cmp_lt
add wave -noupdate -expand -group X /main/DUT/execute/f_branch_take
add wave -noupdate -expand -group X /main/DUT/execute/shifter_result add wave -noupdate -expand -group X /main/DUT/execute/shifter_result
add wave -noupdate -expand -group X /main/DUT/execute/alu_addsub_op1 add wave -noupdate -expand -group X /main/DUT/execute/alu_addsub_op1
add wave -noupdate -expand -group X /main/DUT/execute/alu_addsub_op2 add wave -noupdate -expand -group X /main/DUT/execute/alu_addsub_op2
add wave -noupdate -expand -group X /main/DUT/execute/alu_addsub_result add wave -noupdate -expand -group X /main/DUT/execute/alu_addsub_result
add wave -noupdate -expand -group X /main/DUT/execute/shifter_req_d0 add wave -noupdate -expand -group X /main/DUT/execute/x_stall_req_shifter
add wave -noupdate -expand -group X /main/DUT/execute/shifter_req add wave -noupdate -expand -group X /main/DUT/execute/x_stall_req_multiply
add wave -noupdate -expand -group X /main/DUT/execute/shifter_stall_req add wave -noupdate -expand -group X /main/DUT/execute/x_stall_req_divide
add wave -noupdate -expand -group X /main/DUT/execute/rd_shifter
add wave -noupdate -expand -group X /main/DUT/execute/d_shamt_i
add wave -noupdate -expand -group X /main/DUT/execute/d_is_arith_i
add wave -noupdate -expand -group X /main/DUT/execute/is_load add wave -noupdate -expand -group X /main/DUT/execute/is_load
add wave -noupdate -expand -group X /main/DUT/execute/is_store add wave -noupdate -expand -group X /main/DUT/execute/is_store
add wave -noupdate -group W /main/DUT/writeback/clk_i add wave -noupdate -group W /main/DUT/writeback/clk_i
...@@ -195,7 +208,7 @@ add wave -noupdate -group Top /main/DUT/w_stall_req ...@@ -195,7 +208,7 @@ add wave -noupdate -group Top /main/DUT/w_stall_req
add wave -noupdate -group Top /main/DUT/x2f_bra_d0 add wave -noupdate -group Top /main/DUT/x2f_bra_d0
add wave -noupdate -group Top /main/DUT/x2f_bra_d1 add wave -noupdate -group Top /main/DUT/x2f_bra_d1
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {31985000 ps} 0} WaveRestoreCursors {{Cursor 1} {32345000 ps} 0}
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 100 configure wave -valuecolwidth 100
configure wave -justifyvalue left configure wave -justifyvalue left
...@@ -210,4 +223,4 @@ configure wave -griddelta 40 ...@@ -210,4 +223,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ps configure wave -timelineunits ps
update update
WaveRestoreZoom {13501336 ps} {50528664 ps} WaveRestoreZoom {31531345 ps} {33845553 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