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

attempt to pipeline decoding even more

parent 15333cd6
......@@ -294,7 +294,7 @@ module main;
begin
opc = "auipc";
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
......@@ -302,7 +302,7 @@ module main;
begin
opc = "lui";
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
......@@ -310,7 +310,7 @@ module main;
begin
opc = "op-imm";
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
`OPC_OP:
......@@ -346,14 +346,14 @@ module main;
opc = "ld";
fun = decode_size(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
`OPC_STORE:
begin
opc = "st";
fun = decode_size(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
endcase // case (d2x_opcode)
......
......@@ -71,9 +71,14 @@ module rv_cpu
wire [2:0] d2x_fun;
wire [4:0] d2x_opcode;
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;
......@@ -109,10 +114,11 @@ module rv_cpu
.f_pc_i(f2d_pc),
.f_valid_i(f2d_valid),
.x_load_hazard_o(d_load_hazard),
.rf_rs1_o(rf_rs1),
.rf_rs2_o(rf_rs2),
.x_load_hazard_o(d2x_load_hazard),
.x_valid_o(d2x_valid),
.x_pc_o(d2x_pc),
......@@ -126,12 +132,12 @@ module rv_cpu
.x_opcode_o(d2x_opcode),
.x_shifter_sign_o(d2x_shifter_sign),
.x_imm_i_o(d2x_imm_i),
.x_imm_s_o(d2x_imm_s),
.x_imm_b_o(d2x_imm_b),
.x_imm_u_o(d2x_imm_u),
.x_imm_j_o(d2x_imm_j)
.x_imm_o(d2x_imm),
.x_is_signed_compare_o(d2x_is_signed_compare),
.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)
);
wire [4:0] x2w_rd;
......@@ -201,22 +207,22 @@ module rv_cpu
.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_rd_i(d2x_rd),
.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_rs2_value_i(x_rs2_value),
.d_opcode_i(d2x_opcode),
.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_take_o (x2f_bra),
......
......@@ -30,7 +30,7 @@ module rv_exec
input x_stall_i,
input x_kill_i,
output x_stall_req_o,
input w_stall_req_i,
w_stall_req_i,
input [31:0] d_pc_i,
......@@ -47,12 +47,12 @@ module rv_exec
input [4:0] d_opcode_i,
input d_shifter_sign_i,
input [31:0] d_imm_i_i,
input [31:0] d_imm_s_i,
input [31:0] d_imm_b_i,
input [31:0] d_imm_u_i,
input [31:0] d_imm_j_i,
input [31:0] d_imm_i,
input d_is_signed_compare_i,
input d_is_signed_alu_op_i,
input d_is_add_i,
input d_is_shift_i,
output reg [31:0] f_branch_target_o,
output reg f_branch_take_o,
......@@ -96,11 +96,8 @@ module rv_exec
reg rd_write;
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 ? rs1[31] : 1'b0, rs1 };
wire [32:0] cmp_op2 = { cmp_sign_ext ? rs2[31] : 1'b0, rs2 };
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_rs = cmp_op1 - cmp_op2;
......@@ -121,9 +118,9 @@ module rv_exec
always@*
case (d_opcode_i)
`OPC_JAL: branch_target <= d_pc_i + d_imm_j_i;
`OPC_JALR: branch_target <= rs1 + d_imm_i_i;
`OPC_BRANCH: branch_target <= d_pc_i + d_imm_b_i;
`OPC_JAL: branch_target <= d_pc_i + d_imm_i;
`OPC_JALR: branch_target <= rs1 + d_imm_i;
`OPC_BRANCH: branch_target <= d_pc_i + d_imm_i;
default: branch_target<= 32'hx;
endcase // case (d_opcode_i)
......@@ -132,8 +129,8 @@ module rv_exec
always@*
begin
case (d_opcode_i)
`OPC_LUI: alu_op1 <= { d_imm_u_i[31:12] , 12'h0 };
`OPC_AUIPC: alu_op1 <= { d_imm_u_i[31:12] , 12'h0 };
`OPC_LUI: alu_op1 <= d_imm_i;
`OPC_AUIPC: alu_op1 <= d_imm_i;
`OPC_JAL: alu_op1 <= 4;
`OPC_JALR: alu_op1 <= 4;
default: alu_op1 <= rs1;
......@@ -145,27 +142,26 @@ module rv_exec
`OPC_AUIPC: alu_op2 <= d_pc_i;
`OPC_JAL: 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;
endcase // case (d_opcode_i)
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 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 };
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 };
reg [32:0] alu_addsub_result;
always@*
if(is_add)
if(d_is_add_i)
alu_addsub_result <= alu_addsub_op1 + alu_addsub_op2;
else
alu_addsub_result <= alu_addsub_op1 - alu_addsub_op2;
......@@ -191,8 +187,8 @@ module rv_exec
end // always@ *
reg shifter_req_d0;
wire shifter_req = !w_stall_req_i && (d_valid_i) && (d_fun_i == `FUNC_SL || d_fun_i == `FUNC_SR) &&
(d_opcode_i == `OPC_OP || d_opcode_i == `OPC_OP_IMM );
wire shifter_req = !w_stall_req_i && (d_valid_i) && d_is_shift_i;
rv_shifter shifter
(
......@@ -235,8 +231,8 @@ module rv_exec
always@*
begin
case (d_opcode_i)
`OPC_LOAD: dm_addr <= rs1 + d_imm_i_i;
`OPC_STORE: dm_addr <= rs1 + d_imm_s_i;
`OPC_LOAD: dm_addr <= rs1 + d_imm_i;
`OPC_STORE: dm_addr <= rs1 + d_imm_i;
default: dm_addr <= 32'hx;
endcase // case (d_opcode_i)
......
......@@ -31,7 +31,7 @@ module rv_decode
input d_stall_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_pc_i,
......@@ -41,45 +41,45 @@ module rv_decode
output reg [31:0] x_pc_o,
output reg [4:0] rf_rs1_o,
output reg [4:0] rf_rs2_o,
output reg [4:0] rf_rs1_o,
output reg [4:0] rf_rs2_o,
output [4:0] x_rs1_o,
output [4:0] x_rs2_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 [4:0] x_opcode_o,
output x_shifter_sign_o,
output reg [4:0] x_opcode_o,
output reg x_shifter_sign_o,
output [31:0] x_imm_i_o,
output [31:0] x_imm_s_o,
output [31:0] x_imm_b_o,
output [31:0] x_imm_u_o,
output [31:0] x_imm_j_o
output reg [31:0] x_imm_o,
output reg x_is_signed_compare_o,
output reg x_is_signed_alu_op_o,
output reg x_is_add_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_rs2 = f_ir_i[24:20];
wire [4:0] d_rs1 = d_ir[19:15];
wire [4:0] d_rs2 = d_ir[24:20];
reg [4:0] x_rs1;
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@*
if(d_stall_i)
begin
rf_rs1_o <= d_rs1;
rf_rs2_o <= d_rs2;
rf_rs1_o <= x_rs1;
rf_rs2_o <= x_rs2;
end else begin
rf_rs1_o <= f_rs1;
rf_rs2_o <= f_rs2;
......@@ -90,57 +90,85 @@ module rv_decode
begin
x_pc_o <= 0;
x_valid_o <= 0;
end else if(!d_stall_i)
begin
d_ir <= f_ir_i;
end else if(!d_stall_i) begin
x_valid_o <= f_valid_i && !d_kill_i;
x_pc_o <= f_pc_i;
end
wire [4:0] opcode = d_ir[6:2];
wire [4:0] d_opcode = f_ir_i[6:2];
always@(posedge clk_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
wire [2:0] d_fun = f_ir_i[14:12];
always@*
case (opcode)
always@(posedge clk_i)
if(!d_stall_i)
case (d_opcode)
`OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
x_fun_o <= `FUNC_ADD;
default:
x_fun_o <= d_ir[14:12];
x_fun_o <= d_fun;
endcase // case (f_opcode)
//assign x_fun_o = f_ir_i[14:12];
assign x_shifter_sign_o = d_ir[30];
always@(posedge clk_i)
if(!d_stall_i)
x_shifter_sign_o <= f_ir_i[30];
// decoded imm values
assign x_imm_i_o = { {21{ d_ir[31] }}, d_ir[30:25], d_ir[24:21], d_ir[20] };
assign x_imm_s_o = { {21{ d_ir[31] }}, d_ir[30:25], d_ir[11:8], d_ir[7] };
assign x_imm_b_o = { {20{ d_ir[31] }}, d_ir[7], d_ir[30:25], d_ir[11:8], 1'b0 };
assign x_imm_u_o = { d_ir[31], d_ir[30:20], d_ir[19:12], 12'h000 };
assign x_imm_j_o = { {12{d_ir[31]}},
d_ir[19:12],
d_ir[20], d_ir[30:25], d_ir[24:21], 1'b0};
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] };
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] };
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 };
wire[31:0] d_imm_u = { f_ir_i[31], f_ir_i[30:20], f_ir_i[19:12], 12'h000 };
wire[31:0] d_imm_j = { {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};
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