Commit 18f2be72 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

attempt to pipeline decoding even more

parent 15333cd6
...@@ -294,7 +294,7 @@ module main; ...@@ -294,7 +294,7 @@ module main;
begin begin
opc = "auipc"; opc = "auipc";
fun = ""; fun = "";
args = $sformatf("%-3s %-3s %s", rd, " ", s_hex(DUT.d2x_imm_u)); args = $sformatf("%-3s %-3s %s", rd, " ", s_hex(DUT.d2x_imm));
end end
...@@ -302,7 +302,7 @@ module main; ...@@ -302,7 +302,7 @@ module main;
begin begin
opc = "lui"; opc = "lui";
fun = ""; fun = "";
args = $sformatf("%-3s %-3s %s", rd, " ", s_hex(DUT.d2x_imm_u)); args = $sformatf("%-3s %-3s %s", rd, " ", s_hex(DUT.d2x_imm));
end end
...@@ -310,7 +310,7 @@ module main; ...@@ -310,7 +310,7 @@ module main;
begin begin
opc = "op-imm"; opc = "op-imm";
fun = decode_op(DUT.d2x_fun); fun = decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s %s", rd, rs1, s_hex(DUT.d2x_imm_i)); args = $sformatf("%-3s %-3s %s", rd, rs1, s_hex(DUT.d2x_imm));
end end
`OPC_OP: `OPC_OP:
...@@ -346,14 +346,14 @@ module main; ...@@ -346,14 +346,14 @@ module main;
opc = "ld"; opc = "ld";
fun = decode_size(DUT.d2x_fun); fun = decode_size(DUT.d2x_fun);
//decode_op(DUT.d2x_fun); //decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s [0x%-08x + %s]", rd, rs1, DUT.execute.rs1, s_hex($signed(DUT.execute.d_imm_i_i))); args = $sformatf("%-3s %-3s [0x%-08x + %s]", rd, rs1, DUT.execute.rs1, s_hex($signed(DUT.execute.d_imm_i)));
end end
`OPC_STORE: `OPC_STORE:
begin begin
opc = "st"; opc = "st";
fun = decode_size(DUT.d2x_fun); fun = decode_size(DUT.d2x_fun);
//decode_op(DUT.d2x_fun); //decode_op(DUT.d2x_fun);
args = $sformatf("%-3s %-3s [0x%-08x + %s]", rs2, rs1, DUT.execute.rs1, s_hex($signed(DUT.execute.d_imm_s_i))); args = $sformatf("%-3s %-3s [0x%-08x + %s]", rs2, rs1, DUT.execute.rs1, s_hex($signed(DUT.execute.d_imm_i)));
end end
endcase // case (d2x_opcode) endcase // case (d2x_opcode)
......
...@@ -71,9 +71,14 @@ module rv_cpu ...@@ -71,9 +71,14 @@ module rv_cpu
wire [2:0] d2x_fun; wire [2:0] d2x_fun;
wire [4:0] d2x_opcode; wire [4:0] d2x_opcode;
wire d2x_shifter_sign; wire d2x_shifter_sign;
wire [31:0] d2x_imm_i, d2x_imm_s, d2x_imm_u, d2x_imm_b, d2x_imm_j;
wire [31:0] d2x_imm;
wire d2x_is_signed_compare;
wire d2x_is_signed_alu_op;
wire d2x_is_add_o;
wire d2x_is_shift_o;
wire d_load_hazard; wire d2x_load_hazard;
wire d_stall, d_kill; wire d_stall, d_kill;
...@@ -109,10 +114,11 @@ module rv_cpu ...@@ -109,10 +114,11 @@ module rv_cpu
.f_pc_i(f2d_pc), .f_pc_i(f2d_pc),
.f_valid_i(f2d_valid), .f_valid_i(f2d_valid),
.x_load_hazard_o(d_load_hazard),
.rf_rs1_o(rf_rs1), .rf_rs1_o(rf_rs1),
.rf_rs2_o(rf_rs2), .rf_rs2_o(rf_rs2),
.x_load_hazard_o(d2x_load_hazard),
.x_valid_o(d2x_valid), .x_valid_o(d2x_valid),
.x_pc_o(d2x_pc), .x_pc_o(d2x_pc),
...@@ -126,12 +132,12 @@ module rv_cpu ...@@ -126,12 +132,12 @@ module rv_cpu
.x_opcode_o(d2x_opcode), .x_opcode_o(d2x_opcode),
.x_shifter_sign_o(d2x_shifter_sign), .x_shifter_sign_o(d2x_shifter_sign),
.x_imm_i_o(d2x_imm_i), .x_imm_o(d2x_imm),
.x_imm_s_o(d2x_imm_s), .x_is_signed_compare_o(d2x_is_signed_compare),
.x_imm_b_o(d2x_imm_b), .x_is_signed_alu_op_o(d2x_is_signed_alu_op),
.x_imm_u_o(d2x_imm_u), .x_is_add_o(d2x_is_add),
.x_imm_j_o(d2x_imm_j) .x_is_shift_o(d2x_is_shift)
); );
wire [4:0] x2w_rd; wire [4:0] x2w_rd;
...@@ -201,22 +207,22 @@ module rv_cpu ...@@ -201,22 +207,22 @@ module rv_cpu
.d_valid_i(d2x_valid), .d_valid_i(d2x_valid),
.d_load_hazard_i(d_load_hazard), .d_load_hazard_i(d2x_load_hazard),
.d_pc_i(d2x_pc), .d_pc_i(d2x_pc),
.d_rd_i(d2x_rd), .d_rd_i(d2x_rd),
.d_fun_i(d2x_fun), .d_fun_i(d2x_fun),
.d_imm_i(d2x_imm),
.d_is_signed_compare_i(d2x_is_signed_compare),
.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),
.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),
.d_opcode_i(d2x_opcode), .d_opcode_i(d2x_opcode),
.d_shifter_sign_i(d2x_shifter_sign), .d_shifter_sign_i(d2x_shifter_sign),
.d_imm_i_i(d2x_imm_i),
.d_imm_s_i(d2x_imm_s),
.d_imm_b_i(d2x_imm_b),
.d_imm_u_i(d2x_imm_u),
.d_imm_j_i(d2x_imm_j),
.f_branch_target_o (x2f_pc_bra), // fixme: consistent naming .f_branch_target_o (x2f_pc_bra), // fixme: consistent naming
.f_branch_take_o (x2f_bra), .f_branch_take_o (x2f_bra),
......
...@@ -30,7 +30,7 @@ module rv_exec ...@@ -30,7 +30,7 @@ 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 x_stall_req_o,
input w_stall_req_i, w_stall_req_i,
input [31:0] d_pc_i, input [31:0] d_pc_i,
...@@ -47,12 +47,12 @@ module rv_exec ...@@ -47,12 +47,12 @@ module rv_exec
input [4:0] d_opcode_i, input [4:0] d_opcode_i,
input d_shifter_sign_i, input d_shifter_sign_i,
input [31:0] d_imm_i_i, input [31:0] d_imm_i,
input [31:0] d_imm_s_i, input d_is_signed_compare_i,
input [31:0] d_imm_b_i, input d_is_signed_alu_op_i,
input [31:0] d_imm_u_i, input d_is_add_i,
input [31:0] d_imm_j_i, input d_is_shift_i,
output reg [31:0] f_branch_target_o, output reg [31:0] f_branch_target_o,
output reg f_branch_take_o, output reg f_branch_take_o,
...@@ -96,11 +96,8 @@ module rv_exec ...@@ -96,11 +96,8 @@ module rv_exec
reg rd_write; reg rd_write;
wire cmp_sign_ext = ( ( d_opcode_i == `OPC_BRANCH) && ( ( d_fun_i == `BRA_GE )|| (d_fun_i == `BRA_LT ) ) ) wire [32:0] cmp_op1 = { d_is_signed_compare_i ? rs1[31] : 1'b0, rs1 };
|| ( ( (d_opcode_i == `OPC_OP) || (d_opcode_i == `OPC_OP_IMM) ) && (d_fun_i == `FUNC_SLT ) ); wire [32:0] cmp_op2 = { d_is_signed_compare_i ? rs2[31] : 1'b0, rs2 };
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 [32:0] cmp_rs = cmp_op1 - cmp_op2;
...@@ -121,9 +118,9 @@ module rv_exec ...@@ -121,9 +118,9 @@ module rv_exec
always@* always@*
case (d_opcode_i) case (d_opcode_i)
`OPC_JAL: branch_target <= d_pc_i + d_imm_j_i; `OPC_JAL: branch_target <= d_pc_i + d_imm_i;
`OPC_JALR: branch_target <= rs1 + d_imm_i_i; `OPC_JALR: branch_target <= rs1 + d_imm_i;
`OPC_BRANCH: branch_target <= d_pc_i + d_imm_b_i; `OPC_BRANCH: branch_target <= d_pc_i + d_imm_i;
default: branch_target<= 32'hx; default: branch_target<= 32'hx;
endcase // case (d_opcode_i) endcase // case (d_opcode_i)
...@@ -132,8 +129,8 @@ module rv_exec ...@@ -132,8 +129,8 @@ module rv_exec
always@* always@*
begin begin
case (d_opcode_i) case (d_opcode_i)
`OPC_LUI: alu_op1 <= { d_imm_u_i[31:12] , 12'h0 }; `OPC_LUI: alu_op1 <= d_imm_i;
`OPC_AUIPC: alu_op1 <= { d_imm_u_i[31:12] , 12'h0 }; `OPC_AUIPC: alu_op1 <= d_imm_i;
`OPC_JAL: alu_op1 <= 4; `OPC_JAL: alu_op1 <= 4;
`OPC_JALR: alu_op1 <= 4; `OPC_JALR: alu_op1 <= 4;
default: alu_op1 <= rs1; default: alu_op1 <= rs1;
...@@ -145,27 +142,26 @@ module rv_exec ...@@ -145,27 +142,26 @@ module rv_exec
`OPC_AUIPC: alu_op2 <= d_pc_i; `OPC_AUIPC: alu_op2 <= d_pc_i;
`OPC_JAL: alu_op2 <= d_pc_i; `OPC_JAL: alu_op2 <= d_pc_i;
`OPC_JALR: alu_op2 <= d_pc_i; `OPC_JALR: alu_op2 <= d_pc_i;
`OPC_OP_IMM: alu_op2 <= d_imm_i_i; `OPC_OP_IMM: alu_op2 <= d_imm_i;
default: alu_op2 <= rs2; default: alu_op2 <= rs2;
endcase // case (d_opcode_i) endcase // case (d_opcode_i)
end end
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[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_op1 = {d_is_signed_alu_op_i ? alu_op1[31] : 1'b0, alu_op1 };
wire [32:0] alu_addsub_op2 = {alu_op_signext ? 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@*
if(is_add) if(d_is_add_i)
alu_addsub_result <= alu_addsub_op1 + alu_addsub_op2; alu_addsub_result <= alu_addsub_op1 + alu_addsub_op2;
else else
alu_addsub_result <= alu_addsub_op1 - alu_addsub_op2; alu_addsub_result <= alu_addsub_op1 - alu_addsub_op2;
...@@ -191,8 +187,8 @@ module rv_exec ...@@ -191,8 +187,8 @@ module rv_exec
end // always@ * end // always@ *
reg shifter_req_d0; reg shifter_req_d0;
wire shifter_req = !w_stall_req_i && (d_valid_i) && (d_fun_i == `FUNC_SL || d_fun_i == `FUNC_SR) && wire shifter_req = !w_stall_req_i && (d_valid_i) && d_is_shift_i;
(d_opcode_i == `OPC_OP || d_opcode_i == `OPC_OP_IMM );
rv_shifter shifter rv_shifter shifter
( (
...@@ -235,8 +231,8 @@ module rv_exec ...@@ -235,8 +231,8 @@ module rv_exec
always@* always@*
begin begin
case (d_opcode_i) case (d_opcode_i)
`OPC_LOAD: dm_addr <= rs1 + d_imm_i_i; `OPC_LOAD: dm_addr <= rs1 + d_imm_i;
`OPC_STORE: dm_addr <= rs1 + d_imm_s_i; `OPC_STORE: dm_addr <= rs1 + d_imm_i;
default: dm_addr <= 32'hx; default: dm_addr <= 32'hx;
endcase // case (d_opcode_i) endcase // case (d_opcode_i)
......
...@@ -31,7 +31,7 @@ module rv_decode ...@@ -31,7 +31,7 @@ module rv_decode
input d_stall_i, input d_stall_i,
input d_kill_i, input d_kill_i,
output reg x_load_hazard_o, output reg x_load_hazard_o,
input [31:0] f_ir_i, input [31:0] f_ir_i,
input [31:0] f_pc_i, input [31:0] f_pc_i,
...@@ -41,45 +41,45 @@ module rv_decode ...@@ -41,45 +41,45 @@ module rv_decode
output reg [31:0] x_pc_o, output reg [31:0] x_pc_o,
output reg [4:0] rf_rs1_o, output reg [4:0] rf_rs1_o,
output reg [4:0] rf_rs2_o, output reg [4:0] rf_rs2_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 [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 reg [4:0] x_opcode_o,
output x_shifter_sign_o, output reg x_shifter_sign_o,
output [31:0] x_imm_i_o, output reg [31:0] x_imm_o,
output [31:0] x_imm_s_o, output reg x_is_signed_compare_o,
output [31:0] x_imm_b_o, output reg x_is_signed_alu_op_o,
output [31:0] x_imm_u_o, output reg x_is_add_o,
output [31:0] x_imm_j_o output reg x_is_shift_o
); );
reg [31:0] d_ir = 0;
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] d_rs1 = d_ir[19:15]; reg [4:0] x_rs1;
wire [4:0] d_rs2 = d_ir[24:20]; reg [4:0] x_rs2;
reg [4:0] x_rd;
wire [4:0] rd = d_ir [11:7];
reg [31:0] f_ir_d;
assign x_rs1_o = x_rs1;
assign x_rs2_o = x_rs2;
assign x_rd_o = x_rd;
always@* always@*
if(d_stall_i) if(d_stall_i)
begin begin
rf_rs1_o <= d_rs1; rf_rs1_o <= x_rs1;
rf_rs2_o <= d_rs2; rf_rs2_o <= x_rs2;
end else begin end else begin
rf_rs1_o <= f_rs1; rf_rs1_o <= f_rs1;
rf_rs2_o <= f_rs2; rf_rs2_o <= f_rs2;
...@@ -90,57 +90,85 @@ module rv_decode ...@@ -90,57 +90,85 @@ module rv_decode
begin begin
x_pc_o <= 0; x_pc_o <= 0;
x_valid_o <= 0; x_valid_o <= 0;
end else if(!d_stall_i) begin
end else if(!d_stall_i)
begin
d_ir <= f_ir_i;
x_valid_o <= f_valid_i && !d_kill_i; x_valid_o <= f_valid_i && !d_kill_i;
x_pc_o <= f_pc_i; x_pc_o <= f_pc_i;
end end
wire [4:0] opcode = d_ir[6:2]; wire [4:0] d_opcode = f_ir_i[6:2];
always@(posedge clk_i) always@(posedge clk_i)
if(!d_stall_i) if(!d_stall_i)
x_load_hazard_o <= ( (f_rs1 == rd) || (f_rs2 == rd) ) && (!d_kill_i) && (opcode == `OPC_LOAD); x_load_hazard_o <= ( (f_rs1 == x_rd) || (f_rs2 == x_rd) ) && (!d_kill_i) && (d_opcode == `OPC_LOAD);
assign x_rs1_o = d_ir [19:15];
assign x_rs2_o = d_ir [24:20];
assign x_rd_o = d_ir [11:7];
assign x_opcode_o = d_ir[6:2];
assign x_shamt_o = d_ir[24:20];
always@(posedge clk_i)
if(!d_stall_i)
begin
x_rs1 <= f_rs1;
x_rs2 <= f_rs2;
x_rd <= f_ir_i [11:7];
x_opcode_o <= d_opcode;
x_shamt_o <= f_ir_i[24:20];
end
// 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];
always@* always@(posedge clk_i)
case (opcode) if(!d_stall_i)
case (d_opcode)
`OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC: `OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
x_fun_o <= `FUNC_ADD; x_fun_o <= `FUNC_ADD;
default: default:
x_fun_o <= d_ir[14:12]; x_fun_o <= d_fun;
endcase // case (f_opcode) endcase // case (f_opcode)
always@(posedge clk_i)
//assign x_fun_o = f_ir_i[14:12]; if(!d_stall_i)
x_shifter_sign_o <= f_ir_i[30];
assign x_shifter_sign_o = d_ir[30];
wire[31:0] d_imm_i = { {21{ f_ir_i[31] }}, f_ir_i[30:25], f_ir_i[24:21], f_ir_i[20] };
// decoded imm values wire[31:0] d_imm_s = { {21{ f_ir_i[31] }}, f_ir_i[30:25], f_ir_i[11:8], f_ir_i[7] };
assign x_imm_i_o = { {21{ d_ir[31] }}, d_ir[30:25], d_ir[24:21], d_ir[20] }; wire[31:0] d_imm_b = { {20{ f_ir_i[31] }}, f_ir_i[7], f_ir_i[30:25], f_ir_i[11:8], 1'b0 };
assign x_imm_s_o = { {21{ d_ir[31] }}, d_ir[30:25], d_ir[11:8], d_ir[7] }; wire[31:0] d_imm_u = { f_ir_i[31], f_ir_i[30:20], f_ir_i[19:12], 12'h000 };
assign x_imm_b_o = { {20{ d_ir[31] }}, d_ir[7], d_ir[30:25], d_ir[11:8], 1'b0 }; wire[31:0] d_imm_j = { {12{f_ir_i[31]}},
assign x_imm_u_o = { d_ir[31], d_ir[30:20], d_ir[19:12], 12'h000 }; f_ir_i[19:12],
assign x_imm_j_o = { {12{d_ir[31]}}, f_ir_i[20], f_ir_i[30:25], f_ir_i[24:21], 1'b0};
d_ir[19:12],
d_ir[20], d_ir[30:25], d_ir[24:21], 1'b0};
always@(posedge clk_i)
begin
if(!d_stall_i)
case(d_opcode)
`OPC_LUI, `OPC_AUIPC: x_imm_o <= d_imm_u;
`OPC_OP_IMM, `OPC_LOAD: x_imm_o <= d_imm_i;
`OPC_STORE: x_imm_o <= d_imm_s;
`OPC_JAL: x_imm_o <= d_imm_j;
`OPC_JALR: x_imm_o <= d_imm_i;
`OPC_BRANCH: x_imm_o <= d_imm_b;
default: x_imm_o <= 32'hx;
endcase // case (opcode)
end // always@ (posedge clk_i)
// misc decoding
always@(posedge clk_i)
if(!d_stall_i)
begin
x_is_shift_o <= (d_fun == `FUNC_SL || d_fun == `FUNC_SR) &&
(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 ) ) )
|| ( ( (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_signed_alu_op_o <= (d_fun == `FUNC_SLT);
end
......
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