Only stall the pipeline if rs1/rs2 are read

This commit is contained in:
Graham Edgecombe 2017-12-29 20:37:02 +00:00
parent 3f19fc4226
commit eac6a20040
4 changed files with 81 additions and 1 deletions

View file

@ -47,7 +47,9 @@ module rv32 (
/* decode -> hazard control */
logic [4:0] decode_rs1_unreg;
logic decode_rs1_read_unreg;
logic [4:0] decode_rs2_unreg;
logic decode_rs2_read_unreg;
logic decode_mem_fence_unreg;
/* decode -> execute control */
@ -114,7 +116,9 @@ module rv32 (
rv32_hazard_unit hazard_unit (
/* control in */
.decode_rs1_unreg_in(decode_rs1_unreg),
.decode_rs1_read_unreg_in(decode_rs1_read_unreg),
.decode_rs2_unreg_in(decode_rs2_unreg),
.decode_rs2_read_unreg_in(decode_rs2_read_unreg),
.decode_mem_fence_unreg_in(decode_mem_fence_unreg),
.decode_mem_read_in(decode_mem_read),
@ -195,7 +199,9 @@ module rv32 (
/* control out (to hazard) */
.rs1_unreg_out(decode_rs1_unreg),
.rs1_read_unreg_out(decode_rs1_read_unreg),
.rs2_unreg_out(decode_rs2_unreg),
.rs2_read_unreg_out(decode_rs2_read_unreg),
.mem_fence_unreg_out(decode_mem_fence_unreg),
/* control out */

View file

@ -18,6 +18,8 @@ module rv32_control_unit (
/* control out */
output logic valid_out,
output logic rs1_read_out,
output logic rs2_read_out,
output logic [2:0] imm_out,
output logic [2:0] alu_op_out,
output logic alu_sub_sra_out,
@ -37,6 +39,8 @@ module rv32_control_unit (
);
always_comb begin
valid_out = 0;
rs1_read_out = 0;
rs2_read_out = 0;
imm_out = 3'bx;
alu_op_out = 3'bx;
alu_sub_sra_out = 1'bx;
@ -86,6 +90,7 @@ module rv32_control_unit (
end
`RV32_INSTR_JALR: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -97,6 +102,8 @@ module rv32_control_unit (
end
`RV32_INSTR_BEQ: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_B;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 1;
@ -107,6 +114,8 @@ module rv32_control_unit (
end
`RV32_INSTR_BNE: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_B;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 1;
@ -117,6 +126,8 @@ module rv32_control_unit (
end
`RV32_INSTR_BLT: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_B;
alu_op_out = `RV32_ALU_OP_SLT;
alu_sub_sra_out = 1;
@ -127,6 +138,8 @@ module rv32_control_unit (
end
`RV32_INSTR_BGE: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_B;
alu_op_out = `RV32_ALU_OP_SLT;
alu_sub_sra_out = 1;
@ -137,6 +150,8 @@ module rv32_control_unit (
end
`RV32_INSTR_BLTU: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_B;
alu_op_out = `RV32_ALU_OP_SLTU;
alu_sub_sra_out = 1;
@ -147,6 +162,8 @@ module rv32_control_unit (
end
`RV32_INSTR_BGEU: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_B;
alu_op_out = `RV32_ALU_OP_SLTU;
alu_sub_sra_out = 1;
@ -157,6 +174,7 @@ module rv32_control_unit (
end
`RV32_INSTR_LB: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -169,6 +187,7 @@ module rv32_control_unit (
end
`RV32_INSTR_LH: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -181,6 +200,7 @@ module rv32_control_unit (
end
`RV32_INSTR_LW: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -192,6 +212,7 @@ module rv32_control_unit (
end
`RV32_INSTR_LBU: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -204,6 +225,7 @@ module rv32_control_unit (
end
`RV32_INSTR_LHU: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -216,6 +238,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SB: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_S;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -226,6 +250,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SH: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_S;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -236,6 +262,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SW: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 1;
imm_out = `RV32_IMM_S;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -246,6 +274,7 @@ module rv32_control_unit (
end
`RV32_INSTR_ADDI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
@ -255,6 +284,7 @@ module rv32_control_unit (
end
`RV32_INSTR_SLTI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_SLT;
alu_sub_sra_out = 1;
@ -264,6 +294,7 @@ module rv32_control_unit (
end
`RV32_INSTR_SLTIU: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_SLTU;
alu_sub_sra_out = 1;
@ -273,6 +304,7 @@ module rv32_control_unit (
end
`RV32_INSTR_XORI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_XOR;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -281,6 +313,7 @@ module rv32_control_unit (
end
`RV32_INSTR_ORI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_OR;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -289,6 +322,7 @@ module rv32_control_unit (
end
`RV32_INSTR_ANDI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_I;
alu_op_out = `RV32_ALU_OP_AND;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -297,6 +331,7 @@ module rv32_control_unit (
end
`RV32_INSTR_SLLI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_SHAMT;
alu_op_out = `RV32_ALU_OP_SLL;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -305,6 +340,7 @@ module rv32_control_unit (
end
`RV32_INSTR_SRLI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_SHAMT;
alu_op_out = `RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out = 0;
@ -314,6 +350,7 @@ module rv32_control_unit (
end
`RV32_INSTR_SRAI: begin
valid_out = 1;
rs1_read_out = 1;
imm_out = `RV32_IMM_SHAMT;
alu_op_out = `RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out = 1;
@ -323,6 +360,8 @@ module rv32_control_unit (
end
`RV32_INSTR_ADD: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -331,6 +370,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SUB: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 1;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -339,6 +380,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SLL: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_SLL;
alu_src1_out = `RV32_ALU_SRC1_REG;
alu_src2_out = `RV32_ALU_SRC2_REG;
@ -346,6 +389,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SLT: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_SLT;
alu_sub_sra_out = 1;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -354,6 +399,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SLTU: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_SLTU;
alu_sub_sra_out = 1;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -362,6 +409,8 @@ module rv32_control_unit (
end
`RV32_INSTR_XOR: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_XOR;
alu_src1_out = `RV32_ALU_SRC1_REG;
alu_src2_out = `RV32_ALU_SRC2_REG;
@ -369,6 +418,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SRL: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out = 0;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -377,6 +428,8 @@ module rv32_control_unit (
end
`RV32_INSTR_SRA: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_SRL_SRA;
alu_sub_sra_out = 1;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -385,6 +438,8 @@ module rv32_control_unit (
end
`RV32_INSTR_OR: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_OR;
alu_src1_out = `RV32_ALU_SRC1_REG;
alu_src2_out = `RV32_ALU_SRC2_REG;
@ -392,6 +447,8 @@ module rv32_control_unit (
end
`RV32_INSTR_AND: begin
valid_out = 1;
rs1_read_out = 1;
rs2_read_out = 2;
alu_op_out = `RV32_ALU_OP_AND;
alu_src1_out = `RV32_ALU_SRC1_REG;
alu_src2_out = `RV32_ALU_SRC2_REG;
@ -421,6 +478,7 @@ module rv32_control_unit (
end
`RV32_INSTR_CSRRW: begin
valid_out = 1;
rs1_read_out = 1;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -432,6 +490,7 @@ module rv32_control_unit (
end
`RV32_INSTR_CSRRS: begin
valid_out = 1;
rs1_read_out = 1;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
alu_src1_out = `RV32_ALU_SRC1_REG;
@ -443,6 +502,7 @@ module rv32_control_unit (
end
`RV32_INSTR_CSRRC: begin
valid_out = 1;
rs1_read_out = 1;
alu_op_out = `RV32_ALU_OP_ADD_SUB;
alu_sub_sra_out = 0;
alu_src1_out = `RV32_ALU_SRC1_REG;

View file

@ -24,7 +24,9 @@ module rv32_decode (
/* control out (to hazard) */
output logic [4:0] rs1_unreg_out,
output logic rs1_read_unreg_out,
output logic [4:0] rs2_unreg_out,
output logic rs2_read_unreg_out,
output logic mem_fence_unreg_out,
/* control out */
@ -85,6 +87,8 @@ module rv32_decode (
);
logic valid;
logic rs1_read;
logic rs2_read;
logic [2:0] imm;
logic [2:0] alu_op;
logic alu_sub_sra;
@ -102,6 +106,8 @@ module rv32_decode (
logic branch_pc_src;
logic rd_write;
assign rs1_read_unreg_out = rs1_read;
assign rs2_read_unreg_out = rs2_read;
assign mem_fence_unreg_out = mem_fence;
rv32_control_unit control_unit (
@ -114,6 +120,8 @@ module rv32_decode (
/* control out */
.valid_out(valid),
.rs1_read_out(rs1_read),
.rs2_read_out(rs2_read),
.imm_out(imm),
.alu_op_out(alu_op),
.alu_sub_sra_out(alu_sub_sra),

View file

@ -4,7 +4,9 @@
module rv32_hazard_unit (
/* control in */
input [4:0] decode_rs1_unreg_in,
input decode_rs1_read_unreg_in,
input [4:0] decode_rs2_unreg_in,
input decode_rs2_read_unreg_in,
input decode_mem_fence_unreg_in,
input decode_mem_read_in,
@ -37,13 +39,17 @@ module rv32_hazard_unit (
output logic mem_stall_out,
output logic mem_flush_out
);
logic rs1_matches;
logic rs2_matches;
logic fetch_wait_for_bus;
logic fetch_wait_for_mem_read;
logic fetch_wait_for_mem_fence;
logic mem_wait_for_bus;
assign rs1_matches = decode_rs1_unreg_in == decode_rd_in && decode_rs1_read_unreg_in;
assign rs2_matches = decode_rs2_unreg_in == decode_rd_in && decode_rs2_read_unreg_in;
assign fetch_wait_for_bus = instr_read_in && !instr_ready_in;
assign fetch_wait_for_mem_read = (decode_rs1_unreg_in == decode_rd_in || decode_rs2_unreg_in == decode_rd_in) && |decode_rd_in && (decode_mem_read_in || decode_csr_read_in) && decode_rd_write_in;
assign fetch_wait_for_mem_read = (rs1_matches || rs2_matches) && |decode_rd_in && (decode_mem_read_in || decode_csr_read_in) && decode_rd_write_in;
assign fetch_wait_for_mem_fence = decode_mem_fence_unreg_in || decode_mem_fence_in || execute_mem_fence_in;
assign mem_wait_for_bus = (data_read_in || data_write_in) && !data_ready_in;