Commit 8d0fb7a5 authored by Tomasz Wlostowski's avatar Tomasz Wlostowski

runs sorting test, added barrel shifter and optimized a bit

parent fb33d0f1
...@@ -7,9 +7,10 @@ target = "xilinx" ...@@ -7,9 +7,10 @@ target = "xilinx"
include_dirs=["."] include_dirs=["."]
files = [ "main.sv", files = [ "main.sv",
"rv_cpu.v", "rv_cpu.v",
"rv_exec.v", "rv_exec.v",
"rv_fetch.v", "rv_fetch.v",
"rv_predecode.v", "rv_predecode.v",
"rv_regfile.v", "rv_regfile.v",
"rv_writeback.v"]; "rv_writeback.v",
"rv_shifter.v"];
...@@ -24,12 +24,16 @@ ...@@ -24,12 +24,16 @@
module main; module main;
const int dump_insns = 1;
const int dump_mem_accesses = 1;
reg clk = 0; reg clk = 0;
reg rst = 1; reg rst = 1;
wire [31:0] im_addr; wire [31:0] im_addr;
reg [31:0] im_data; reg [31:0] im_data;
wire im_valid = 1'b1; reg im_valid;
wire [31:0] dm_addr; wire [31:0] dm_addr;
...@@ -37,6 +41,8 @@ module main; ...@@ -37,6 +41,8 @@ module main;
reg [31:0] dm_data_l; reg [31:0] dm_data_l;
wire [3:0] dm_data_select; wire [3:0] dm_data_select;
wire dm_write; wire dm_write;
reg dm_valid_l = 0;
localparam int mem_size = 16384; localparam int mem_size = 16384;
...@@ -60,9 +66,19 @@ module main; ...@@ -60,9 +66,19 @@ module main;
endtask // load_ram endtask // load_ram
int seed;
always@(posedge clk) always@(posedge clk)
begin begin
im_data <= mem[(im_addr / 4) % mem_size]; if( $dist_uniform(seed, 0, 100 ) <= 100) begin
im_data <= mem[(im_addr / 4) % mem_size];
im_valid <= 1;
end else
im_valid <= 0;
if(dm_write && dm_data_select[0]) if(dm_write && dm_data_select[0])
mem [(dm_addr / 4) % mem_size][7:0] <= dm_data_s[7:0]; mem [(dm_addr / 4) % mem_size][7:0] <= dm_data_s[7:0];
...@@ -73,7 +89,16 @@ module main; ...@@ -73,7 +89,16 @@ module main;
if(dm_write && dm_data_select[3]) if(dm_write && dm_data_select[3])
mem [(dm_addr / 4) % mem_size][31:24] <= dm_data_s[31:24]; mem [(dm_addr / 4) % mem_size][31:24] <= dm_data_s[31:24];
dm_data_l <= mem[(dm_addr/4) % mem_size]; if( $dist_uniform(seed, 0, 100 ) <= 50) begin
dm_data_l <= mem[(dm_addr/4) % mem_size];
dm_valid_l <= 1;
end else begin
dm_data_l <= 32'hx;
dm_valid_l <= 0;
end
// dm_data_l <= mem[(dm_addr/4) % mem_size];
end end
...@@ -94,7 +119,8 @@ module main; ...@@ -94,7 +119,8 @@ module main;
.dm_data_s_o(dm_data_s), .dm_data_s_o(dm_data_s),
.dm_data_l_i(dm_data_l), .dm_data_l_i(dm_data_l),
.dm_data_select_o(dm_data_select), .dm_data_select_o(dm_data_select),
.dm_write_o(dm_write) .dm_write_o(dm_write),
.dm_valid_l_i(dm_valid_l)
); );
always #5ns clk <= ~clk; always #5ns clk <= ~clk;
...@@ -191,11 +217,13 @@ module main; ...@@ -191,11 +217,13 @@ module main;
always@(posedge clk) always@(posedge clk)
begin begin
if(dump_mem_accesses)
begin
dm_addr_d0 <= dm_addr; dm_addr_d0 <= dm_addr;
if(dm_write) if(dm_write)
$display("DM Write addr %x data %x", dm_addr, dm_data_s); $display("DM Write addr %x data %x", dm_addr, dm_data_s);
if (DUT.writeback.x_load_i) if (DUT.writeback.x_load_i && !DUT.writeback.w_stall_i)
begin begin
if ($isunkown(dm_data_l)) if ($isunkown(dm_data_l))
begin begin
...@@ -206,7 +234,7 @@ module main; ...@@ -206,7 +234,7 @@ module main;
$display("DM Load addr %x data %x -> %s", dm_addr_d0, dm_data_l, decode_regname(DUT.writeback.x_rd_i)); $display("DM Load addr %x data %x -> %s", dm_addr_d0, dm_data_l, decode_regname(DUT.writeback.x_rd_i));
end end
end
end end
integer f_console; integer f_console;
...@@ -236,7 +264,7 @@ module main; ...@@ -236,7 +264,7 @@ module main;
always@(posedge clk) always@(posedge clk)
if(!DUT.execute.x_stall_i && !DUT.execute.x_kill_i) if(dump_insns && DUT.execute.d_valid_i && !DUT.execute.x_stall_i && !DUT.execute.x_kill_i)
begin begin
automatic string opc="<unk>", fun="", args=""; automatic string opc="<unk>", fun="", args="";
......
...@@ -37,7 +37,9 @@ module rv_cpu ...@@ -37,7 +37,9 @@ module rv_cpu
output [31:0] dm_data_s_o, output [31:0] dm_data_s_o,
input [31:0] dm_data_l_i, input [31:0] dm_data_l_i,
output [3:0] dm_data_select_o, output [3:0] dm_data_select_o,
output dm_write_o output dm_write_o,
input dm_busy_s_i,
input dm_valid_l_i
); );
wire f_stall; wire f_stall;
...@@ -46,11 +48,14 @@ module rv_cpu ...@@ -46,11 +48,14 @@ module rv_cpu
wire x_kill; wire x_kill;
wire f_kill; wire f_kill;
wire [31:0] f2d_pc, f2d_ir; wire [31:0] f2d_pc, f2d_pc_plus_4, f2d_ir;
wire f2d_ir_valid; wire f2d_ir_valid;
wire [31:0] x2f_pc_bra; wire [31:0] x2f_pc_bra;
wire x2f_bra; wire x2f_bra;
wire f2d_valid;
wire f_stall_req;
...@@ -64,10 +69,12 @@ module rv_cpu ...@@ -64,10 +69,12 @@ module rv_cpu
.f_stall_i(f_stall), .f_stall_i(f_stall),
.f_kill_i(f_kill), .f_kill_i(f_kill),
.f_valid_o(f2d_valid),
.f_ir_o(f2d_ir), .f_ir_o(f2d_ir),
.f_pc_o(f2d_pc), .f_pc_o(f2d_pc),
.f_ir_valid_o(f2d_ir_valid),
// .f_ir_valid_o(f2d_ir_valid),
.x_pc_bra_i(x2f_pc_bra), .x_pc_bra_i(x2f_pc_bra),
.x_bra_i(x2f_bra) .x_bra_i(x2f_bra)
); );
...@@ -159,6 +166,7 @@ module rv_cpu ...@@ -159,6 +166,7 @@ module rv_cpu
.x_stall_i(x_stall), .x_stall_i(x_stall),
.x_kill_i(x_kill), .x_kill_i(x_kill),
.x_stall_req_o(x_stall_req), .x_stall_req_o(x_stall_req),
.d_valid_i(f2d_valid),
.d_pc_i(d2x_pc), .d_pc_i(d2x_pc),
.d_rd_i(d2x_rd), .d_rd_i(d2x_rd),
...@@ -194,13 +202,17 @@ module rv_cpu ...@@ -194,13 +202,17 @@ module rv_cpu
.dm_write_o(dm_write_o) .dm_write_o(dm_write_o)
); );
wire w_stall_req;
rv_writeback writeback rv_writeback writeback
( (
.clk_i(clk_i), .clk_i(clk_i),
.rst_i(rst_i), .rst_i(rst_i),
.w_stall_i(w_stall), .w_stall_i(w_stall),
.w_stall_req_o(w_stall_req),
.x_fun_i(x2w_fun), .x_fun_i(x2w_fun),
.x_load_i(x2w_load), .x_load_i(x2w_load),
...@@ -210,28 +222,32 @@ module rv_cpu ...@@ -210,28 +222,32 @@ module rv_cpu
.x_dm_addr_i(x2w_dm_addr), .x_dm_addr_i(x2w_dm_addr),
.dm_data_l_i(dm_data_l_i), .dm_data_l_i(dm_data_l_i),
.dm_valid_l_i(dm_valid_l_i),
.rf_rd_value_o(rf_rd_value), .rf_rd_value_o(rf_rd_value),
.rf_rd_o(rf_rd), .rf_rd_o(rf_rd),
.rf_rd_write_o(rf_rd_write) .rf_rd_write_o(rf_rd_write)
); );
reg x_bra_d0; reg x2f_bra_d0;
always@(posedge clk_i) always@(posedge clk_i)
if(rst_i) if(rst_i)
x_bra_d0 <= 0; x2f_bra_d0 <= 0;
else if (!x_stall) else if (!x_stall)
x_bra_d0 <= x2f_bra; x2f_bra_d0 <= x2f_bra;
assign f_stall = 0; assign f_stall = x_stall_req || w_stall_req;
assign x_stall = x_stall_req || w_stall_req;
assign x_stall = f_stall || (!f2d_ir_valid); // || (!f2d_ir_valid);
assign w_stall = x_stall; assign w_stall = 0;
//x_stall_req;
assign x_kill = x2f_bra ; assign x_kill = x2f_bra || x2f_bra_d0;
assign f_kill = x2f_bra ; assign f_kill = x2f_bra ;
//&& ~x_bra_d0; //&& ~x_bra_d0;
......
...@@ -29,7 +29,7 @@ module rv_exec ...@@ -29,7 +29,7 @@ module rv_exec
input x_stall_i, input x_stall_i,
input x_kill_i, input x_kill_i,
output reg x_stall_req_o, output x_stall_req_o,
input [31:0] d_pc_i, input [31:0] d_pc_i,
input [4:0] d_rd_i, input [4:0] d_rd_i,
...@@ -37,6 +37,8 @@ module rv_exec ...@@ -37,6 +37,8 @@ module rv_exec
input [31:0] rf_rs1_value_i, input [31:0] rf_rs1_value_i,
input [31:0] rf_rs2_value_i, input [31:0] rf_rs2_value_i,
input d_valid_i,
input [4:0] d_opcode_i, input [4:0] d_opcode_i,
input d_shifter_sign_i, input d_shifter_sign_i,
...@@ -86,7 +88,30 @@ module rv_exec ...@@ -86,7 +88,30 @@ 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 ) ) )
|| ( ( (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));
// branch condition decoding
always@*
case (d_fun_i)
`BRA_EQ: branch_condition_met <= cmp_equal;
`BRA_NEQ: branch_condition_met <= ~cmp_equal;
`BRA_GE: branch_condition_met <= ~cmp_lt | cmp_equal;
`BRA_LT: branch_condition_met <= cmp_lt;
`BRA_GEU: branch_condition_met <= ~cmp_lt | cmp_equal;
`BRA_LTU: branch_condition_met <= cmp_lt;
default: branch_condition_met <= 0;
endcase // case (d_fun_i)
/* -----\/----- EXCLUDED -----\/-----
// branch condition decoding // branch condition decoding
always@* always@*
case (d_fun_i) case (d_fun_i)
...@@ -98,6 +123,7 @@ module rv_exec ...@@ -98,6 +123,7 @@ module rv_exec
`BRA_LTU: branch_condition_met <= (rs1 < rs2); `BRA_LTU: branch_condition_met <= (rs1 < rs2);
default: branch_condition_met <= 0; default: branch_condition_met <= 0;
endcase // case (d_fun_i) endcase // case (d_fun_i)
-----/\----- EXCLUDED -----/\----- */
always@* always@*
case (d_opcode_i) case (d_opcode_i)
...@@ -108,15 +134,57 @@ module rv_exec ...@@ -108,15 +134,57 @@ module rv_exec
default: branch_target<= 32'hx; default: branch_target<= 32'hx;
endcase // case (d_opcode_i) 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 // decode ALU operands
always@* always@*
begin begin
alu_op1 <= rs1; case (d_opcode_i)
alu_op2 <= (d_opcode_i == `OPC_OP_IMM) ? d_imm_i_i : rs2; `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_JAL: alu_op1 <= 4;
`OPC_JALR: alu_op1 <= 4;
default: alu_op1 <= rs1;
endcase // case (d_opcode_i)
//alu_op1 <= rs1;
case (d_opcode_i)
`OPC_LUI: alu_op2 <= 0;
`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;
default: alu_op2 <= rs2;
endcase // case (d_opcode_i)
//alu_op2 <= (d_opcode_i == `OPC_OP_IMM) ? d_imm_i_i : rs2;
//endcase
end end
wire is_subtract = (d_opcode_i == `OPC_OP && d_shifter_sign_i); wire is_subtract = (d_opcode_i == `OPC_OP && d_shifter_sign_i);
wire[31:0] shifter_result;
// the ALU itself // the ALU itself
always@* always@*
begin begin
...@@ -130,32 +198,69 @@ module rv_exec ...@@ -130,32 +198,69 @@ module rv_exec
`FUNC_XOR: alu_result <= alu_op1 ^ alu_op2; `FUNC_XOR: alu_result <= alu_op1 ^ alu_op2;
`FUNC_OR: alu_result <= alu_op1 | alu_op2; `FUNC_OR: alu_result <= alu_op1 | alu_op2;
`FUNC_AND: alu_result <= alu_op1 & alu_op2; `FUNC_AND: alu_result <= alu_op1 & alu_op2;
`FUNC_SLT: alu_result <= ($signed(alu_op1) < $signed(alu_op2)) ? 1 : 0; `FUNC_SLT: alu_result <= cmp_lt ? 1 : 0;
`FUNC_SLTU: alu_result <= ((alu_op1) < (alu_op2)) ? 1 : 0; `FUNC_SLTU: alu_result <= cmp_lt ? 1 : 0;
`FUNC_SL: alu_result <= alu_op1 << alu_op2[4:0]; `FUNC_SL, `FUNC_SR: alu_result <= shifter_result;
/* `FUNC_SL: alu_result <= alu_op1 << alu_op2[4:0];
`FUNC_SR: `FUNC_SR:
begin begin
if(d_shifter_sign_i) if(d_shifter_sign_i)
alu_result <= $signed(alu_op1) >>> alu_op2[4:0]; alu_result <= $signed(alu_op1) >>> alu_op2[4:0];
else else
alu_result <= alu_op1 >> alu_op2[4:0]; alu_result <= alu_op1 >> alu_op2[4:0];
end end*/
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 shifter_req = (d_valid_i) && (d_fun_i == `FUNC_SL || d_fun_i == `FUNC_SR) &&
(d_opcode_i == `OPC_OP || d_opcode_i == `OPC_OP_IMM );
rv_shifter shifter
(
.clk_i(clk_i),
.rst_i(rst_i),
.d_i(alu_op1),
.q_o(shifter_result),
.shift_i(alu_op2[4:0]),
.func_i(d_fun_i),
.arith_i(d_shifter_sign_i)
);
always@(posedge clk_i)
shifter_req_d0 <= shifter_req;
wire shifter_stall_req = shifter_req && !shifter_req_d0;
// && !shifter_req_d0;
/* always@(posedge clk_i)
if(shifter_req)
$display("%08x: shifter op %x fun %x %x op1 %x op2 %x", d_pc_i, d_opcode_i, d_fun_i, d_shifter_sign_i, alu_op1, alu_op2);
always@(posedge clk_i)
if(shifter_req_d0)
$display("%08x: shifter result %x", d_pc_i, shifter_result);
*/
// rdest write value // rdest write value
always@* always@*
begin begin
case (d_opcode_i) case (d_opcode_i)
`OPC_OP_IMM, `OPC_OP: `OPC_OP_IMM, `OPC_OP, `OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
begin begin
rd_value <= alu_result; rd_value <= alu_result;
rd_write <= 1; rd_write <= 1;
end end
`OPC_JAL, `OPC_JALR: /* `OPC_JAL, `OPC_JALR:
begin begin
rd_value <= d_pc_i + 4; rd_value <= d_pc_i + 4;
rd_write <= 1; rd_write <= 1;
...@@ -166,13 +271,13 @@ module rv_exec ...@@ -166,13 +271,13 @@ module rv_exec
rd_value <= { d_imm_u_i[31:12] , 12'h0 }; rd_value <= { d_imm_u_i[31:12] , 12'h0 };
rd_write <= 1; rd_write <= 1;
end end
`OPC_AUIPC: `OPC_AUIPC:
begin begin
rd_value <= d_pc_i + { d_imm_u_i[31:12], 12'h0 }; rd_value <= d_pc_i + { d_imm_u_i[31:12], 12'h0 };
rd_write <= 1; rd_write <= 1;
end end
*/
default: default:
begin begin
...@@ -199,7 +304,7 @@ module rv_exec ...@@ -199,7 +304,7 @@ module rv_exec
// generate store value/select // generate store value/select
always@* always@*
begin begin
case (d_fun_i) case (d_fun_i)
`LDST_B: `LDST_B:
begin begin
dm_data_s <= { rs2[7:0], rs2[7:0], rs2[7:0], rs2[7:0] }; dm_data_s <= { rs2[7:0], rs2[7:0], rs2[7:0], rs2[7:0] };
...@@ -213,7 +318,9 @@ module rv_exec ...@@ -213,7 +318,9 @@ module rv_exec
begin begin
dm_data_s <= { rs2[15:0], rs2[15:0] }; dm_data_s <= { rs2[15:0], rs2[15:0] };
dm_select_s[0] <= (dm_addr [1] == 1'b0); dm_select_s[0] <= (dm_addr [1] == 1'b0);
dm_select_s[1] <= (dm_addr [1] == 1'b1); dm_select_s[1] <= (dm_addr [1] == 1'b0);
dm_select_s[2] <= (dm_addr [1] == 1'b1);
dm_select_s[3] <= (dm_addr [1] == 1'b1);
end end
`LDST_L: `LDST_L:
...@@ -248,7 +355,7 @@ module rv_exec ...@@ -248,7 +355,7 @@ module rv_exec
always@* always@*
begin begin
dm_write_s <= ( (d_opcode_i == `OPC_STORE) && !x_stall_i ); dm_write_s <= ( (d_opcode_i == `OPC_STORE) && !x_stall_i && d_valid_i);
end end
assign dm_addr_o = dm_addr; assign dm_addr_o = dm_addr;
...@@ -261,7 +368,6 @@ module rv_exec ...@@ -261,7 +368,6 @@ module rv_exec
if (rst_i) begin if (rst_i) begin
f_branch_target_o <= 0; f_branch_target_o <= 0;
f_branch_take_o <= 0; f_branch_take_o <= 0;
x_stall_req_o <= 0;
w_rd_write_o <= 0; w_rd_write_o <= 0;
w_rd_o <= 0; w_rd_o <= 0;
w_fun_o <= 0; w_fun_o <= 0;
...@@ -270,20 +376,26 @@ module rv_exec ...@@ -270,20 +376,26 @@ module rv_exec
end else if (!x_stall_i) begin end else if (!x_stall_i) begin
f_branch_target_o <= branch_target; f_branch_target_o <= branch_target;
f_branch_take_o <= branch_take && !x_kill_i; f_branch_take_o <= branch_take && !x_kill_i && d_valid_i;
x_stall_req_o <= 0;
w_rd_o <= d_rd_i; w_rd_o <= d_rd_i;
// 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;
w_rd_write_o <= rd_write && !x_kill_i && d_valid_i;
w_fun_o <= d_fun_i; w_fun_o <= d_fun_i;
w_load_o <= (d_opcode_i == `OPC_LOAD ? 1: 0) && !x_kill_i; w_load_o <= (d_opcode_i == `OPC_LOAD ? 1: 0) && d_valid_i && !x_kill_i;
w_dm_addr_o <= dm_addr; w_dm_addr_o <= dm_addr;
end // if (!x_stall_i) end else begin // if (!x_stall_i)
f_branch_take_o <= 0;
w_rd_write_o <= 0;
w_load_o <= 0;
end
assign x_stall_req_o = shifter_stall_req;
endmodule endmodule
......
...@@ -35,8 +35,10 @@ module rv_fetch ...@@ -35,8 +35,10 @@ module rv_fetch
output [31:0] f_ir_o, output [31:0] f_ir_o,
output reg [31:0] f_pc_o, output reg [31:0] f_pc_o,
output reg f_ir_valid_o, output reg [31:0] f_pc_plus_4_o,
output reg f_valid_o,
input [31:0] x_pc_bra_i, input [31:0] x_pc_bra_i,
input x_bra_i input x_bra_i
); );
...@@ -46,38 +48,47 @@ module rv_fetch ...@@ -46,38 +48,47 @@ module rv_fetch
reg rst_d; reg rst_d;
wire [31:0] pc_next = (x_bra_i ? x_pc_bra_i : pc + 4); 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));
assign f_ir_o = ir; assign f_ir_o = ir;
assign im_addr_o = pc_next; assign im_addr_o = pc_next;
always@(posedge clk_i) always@(posedge clk_i)
if (rst_i) begin if (rst_i) begin
pc <= -4; pc <= -4;
ir <= 0; ir <= 0;
f_ir_valid_o <= 0; f_valid_o <= 0;
rst_d <= 0; rst_d <= 0;
end else begin end else begin
rst_d <= 1; rst_d <= 1;
if (!f_stall_i) begin if (!f_stall_i) begin
pc <= pc_next;
if(im_valid_i) begin f_pc_o <= pc;
ir <= im_data_i;
f_ir_valid_o <= rst_d && !f_kill_i;
f_pc_o <= pc;
pc <= pc_next;
end // if (i_valid_i) if(im_valid_i) begin
ir <= im_data_i; // emit nop
f_valid_o <= (rst_d && !f_kill_i);
end else begin// if (i_valid_i)
f_valid_o <= 0;
end
end else begin // if (!f_stall_i) end else begin // if (!f_stall_i)
f_ir_valid_o <= 0; // f_stall_req_o <= 0;
end // else: !if(!f_stall_i) end // else: !if(!f_stall_i)
end // else: !if(rst_i) end // else: !if(rst_i)
endmodule endmodule
......
...@@ -44,7 +44,7 @@ module rv_predecode ...@@ -44,7 +44,7 @@ module rv_predecode
output [4:0] x_rd_o, output [4:0] x_rd_o,
output [4:0] x_shamt_o, output [4:0] x_shamt_o,
output [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 x_shifter_sign_o, output x_shifter_sign_o,
...@@ -56,9 +56,12 @@ module rv_predecode ...@@ -56,9 +56,12 @@ module rv_predecode
output [31:0] x_imm_j_o output [31:0] x_imm_j_o
); );
wire [4:0] f_opcode = f_ir_i[6:2];
assign rf_rs1_o = im_data_i [19:15]; assign rf_rs1_o = im_data_i [19:15];
assign rf_rs2_o = im_data_i [24:20]; assign rf_rs2_o = im_data_i [24:20];
assign x_rs1_o = f_ir_i [19:15]; assign x_rs1_o = f_ir_i [19:15];
assign x_rs2_o = f_ir_i [24:20]; assign x_rs2_o = f_ir_i [24:20];
...@@ -66,7 +69,21 @@ module rv_predecode ...@@ -66,7 +69,21 @@ module rv_predecode
assign x_rd_o = f_ir_i [11:7]; assign x_rd_o = f_ir_i [11:7];
assign x_opcode_o = f_ir_i[6:2]; assign x_opcode_o = f_ir_i[6:2];
assign x_shamt_o = f_ir_i[24:20]; assign x_shamt_o = f_ir_i[24:20];
assign x_fun_o = f_ir_i[14:12];
// attempt to reuse ALU for jump address generation
always@*
case (f_opcode)
`OPC_JAL, `OPC_JALR, `OPC_LUI, `OPC_AUIPC:
x_fun_o <= `FUNC_ADD;
default:
x_fun_o <= f_ir_i[14:12];
endcase // case (f_opcode)
//assign x_fun_o = f_ir_i[14:12];
assign x_shifter_sign_o = f_ir_i[30]; assign x_shifter_sign_o = f_ir_i[30];
...@@ -81,7 +98,8 @@ f_ir_i[20], f_ir_i[30:25], f_ir_i[24:21], 1'b0}; ...@@ -81,7 +98,8 @@ f_ir_i[20], f_ir_i[30:25], f_ir_i[24:21], 1'b0};
assign x_pc_o = f_pc_i; assign x_pc_o = f_pc_i;
......
...@@ -29,16 +29,20 @@ module rv_writeback ...@@ -29,16 +29,20 @@ module rv_writeback
input w_stall_i, input w_stall_i,
output w_stall_req_o,
input [2:0] x_fun_i, input [2:0] x_fun_i,
input x_load_i, input x_load_i,
input [31:0] x_dm_addr_i, input [31:0] x_dm_addr_i,
input [4:0] x_rd_i, input [4:0] x_rd_i,
input [31:0] x_rd_value_i, input [31:0] x_rd_value_i,
input x_rd_write_i, input x_rd_write_i,
input [31:0] dm_data_l_i, input [31:0] dm_data_l_i,
input dm_valid_l_i,
output [31:0] rf_rd_value_o, output [31:0] rf_rd_value_o,
output [4:0] rf_rd_o, output [4:0] rf_rd_o,
output rf_rd_write_o output rf_rd_write_o
...@@ -92,7 +96,8 @@ module rv_writeback ...@@ -92,7 +96,8 @@ module rv_writeback
assign rf_rd_value_o = (x_load_i ? load_value : x_rd_value_i ); assign rf_rd_value_o = (x_load_i ? load_value : x_rd_value_i );
assign rf_rd_o = (x_rd_i); assign rf_rd_o = (x_rd_i);
assign rf_rd_write_o = (w_stall_i ? 1'b0 : (x_load_i ? 1'b1 : x_rd_write_i )); assign rf_rd_write_o = (w_stall_i ? 1'b0 : (x_load_i && dm_valid_l_i ? 1'b1 : x_rd_write_i ));
assign w_stall_req_o = (x_load_i && !dm_valid_l_i);
endmodule // rv_writeback endmodule // rv_writeback
...@@ -36,15 +36,18 @@ add wave -noupdate -expand -group fetch /main/DUT/fetch/rst_i ...@@ -36,15 +36,18 @@ add wave -noupdate -expand -group fetch /main/DUT/fetch/rst_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_addr_o add wave -noupdate -expand -group fetch /main/DUT/fetch/im_addr_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_data_i add wave -noupdate -expand -group fetch /main/DUT/fetch/im_data_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_valid_i add wave -noupdate -expand -group fetch /main/DUT/fetch/im_valid_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/im_valid_d0
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_stall_i add wave -noupdate -expand -group fetch /main/DUT/fetch/f_stall_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_kill_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_ir_o add wave -noupdate -expand -group fetch /main/DUT/fetch/f_ir_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_pc_o add wave -noupdate -expand -group fetch /main/DUT/fetch/f_pc_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/f_ir_valid_o add wave -noupdate -expand -group fetch /main/DUT/fetch/f_valid_o
add wave -noupdate -expand -group fetch /main/DUT/fetch/x_pc_bra_i add wave -noupdate -expand -group fetch /main/DUT/fetch/x_pc_bra_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/x_bra_i add wave -noupdate -expand -group fetch /main/DUT/fetch/x_bra_i
add wave -noupdate -expand -group fetch /main/DUT/fetch/pc add wave -noupdate -expand -group fetch /main/DUT/fetch/pc
add wave -noupdate -expand -group fetch /main/DUT/fetch/pc_next
add wave -noupdate -expand -group fetch /main/DUT/fetch/ir add wave -noupdate -expand -group fetch /main/DUT/fetch/ir
add wave -noupdate -expand -group fetch /main/DUT/fetch/rst_d
add wave -noupdate -expand -group fetch /main/DUT/fetch/pc_next
add wave -noupdate -group decode /main/DUT/decode/clk_i add wave -noupdate -group decode /main/DUT/decode/clk_i
add wave -noupdate -group decode /main/DUT/decode/rst_i add wave -noupdate -group decode /main/DUT/decode/rst_i
add wave -noupdate -group decode /main/DUT/decode/f_ir_i add wave -noupdate -group decode /main/DUT/decode/f_ir_i
...@@ -80,11 +83,34 @@ add wave -noupdate -expand -group regfile /main/DUT/regfile/rs2_regfile ...@@ -80,11 +83,34 @@ add wave -noupdate -expand -group regfile /main/DUT/regfile/rs2_regfile
add wave -noupdate -expand -group regfile /main/DUT/regfile/rs1_bypass 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 -expand -group regfile /main/DUT/regfile/rs2_bypass
add wave -noupdate /main/DUT/regfile/bank0/ram add wave -noupdate /main/DUT/regfile/bank0/ram
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/clk_i
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/rst_i
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/d_i
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/q_o
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_i
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/func_i
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/arith_i
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/extend_sign
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_pre
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_16
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_8
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/s1_out
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/s2_extend_sign
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/s2_shift
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/s2_func
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_4
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_2
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_1
add wave -noupdate -expand -group shifter /main/DUT/execute/shifter/shift_post
add wave -noupdate -expand -group execute /main/DUT/execute/clk_i add wave -noupdate -expand -group execute /main/DUT/execute/clk_i
add wave -noupdate -expand -group execute /main/DUT/execute/rst_i add wave -noupdate -expand -group execute /main/DUT/execute/rst_i
add wave -noupdate -expand -group execute /main/DUT/execute/x_kill_i add wave -noupdate -expand -group execute /main/DUT/execute/x_kill_i
add wave -noupdate -expand -group execute /main/DUT/execute/x_stall_i add wave -noupdate -expand -group execute /main/DUT/execute/x_stall_i
add wave -noupdate -expand -group execute /main/DUT/execute/x_stall_req_o add wave -noupdate -expand -group execute /main/DUT/execute/x_stall_req_o
add wave -noupdate -expand -group execute /main/DUT/execute/d_valid_i
add wave -noupdate -expand -group execute /main/DUT/execute/shifter_req
add wave -noupdate -expand -group execute /main/DUT/execute/shifter_req_d0
add wave -noupdate -expand -group execute /main/DUT/execute/shifter_stall_req
add wave -noupdate -expand -group execute /main/DUT/execute/d_pc_i add wave -noupdate -expand -group execute /main/DUT/execute/d_pc_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_rd_i add wave -noupdate -expand -group execute /main/DUT/execute/d_rd_i
add wave -noupdate -expand -group execute /main/DUT/execute/d_fun_i add wave -noupdate -expand -group execute /main/DUT/execute/d_fun_i
...@@ -124,19 +150,21 @@ add wave -noupdate -expand -group execute /main/DUT/execute/rd_write ...@@ -124,19 +150,21 @@ add wave -noupdate -expand -group execute /main/DUT/execute/rd_write
add wave -noupdate -expand -group writeback /main/DUT/writeback/clk_i add wave -noupdate -expand -group writeback /main/DUT/writeback/clk_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/rst_i add wave -noupdate -expand -group writeback /main/DUT/writeback/rst_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/w_stall_i add wave -noupdate -expand -group writeback /main/DUT/writeback/w_stall_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/w_stall_req_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_fun_i add wave -noupdate -expand -group writeback /main/DUT/writeback/x_fun_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_load_i add wave -noupdate -expand -group writeback /main/DUT/writeback/x_load_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_i add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_value_i add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_value_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_write_i add wave -noupdate -expand -group writeback /main/DUT/writeback/x_rd_write_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/dm_data_l_i add wave -noupdate -expand -group writeback /main/DUT/writeback/dm_data_l_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/dm_valid_l_i
add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_value_o add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_value_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/rf_rd_o 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/rf_rd_write_o
add wave -noupdate -expand -group writeback /main/DUT/writeback/load_value add wave -noupdate -expand -group writeback /main/DUT/writeback/load_value
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 1} {969304 ps} 0} WaveRestoreCursors {{Cursor 1} {14655000 ps} 0}
configure wave -namecolwidth 150 configure wave -namecolwidth 250
configure wave -valuecolwidth 100 configure wave -valuecolwidth 100
configure wave -justifyvalue left configure wave -justifyvalue left
configure wave -signalnamewidth 1 configure wave -signalnamewidth 1
...@@ -150,4 +178,4 @@ configure wave -griddelta 40 ...@@ -150,4 +178,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ps configure wave -timelineunits ps
update update
WaveRestoreZoom {911 ns} {1039 ns} WaveRestoreZoom {11530808 ps} {16159192 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