From eac6a20040889713440fd027f46a72fbe691bfaf Mon Sep 17 00:00:00 2001 From: Graham Edgecombe Date: Fri, 29 Dec 2017 20:37:02 +0000 Subject: [PATCH] Only stall the pipeline if rs1/rs2 are read --- rv32.sv | 6 +++++ rv32_control.sv | 60 +++++++++++++++++++++++++++++++++++++++++++++++++ rv32_decode.sv | 8 +++++++ rv32_hazard.sv | 8 ++++++- 4 files changed, 81 insertions(+), 1 deletion(-) diff --git a/rv32.sv b/rv32.sv index f5ea86c..e895e5d 100644 --- a/rv32.sv +++ b/rv32.sv @@ -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 */ diff --git a/rv32_control.sv b/rv32_control.sv index ac3eb7f..07a2a57 100644 --- a/rv32_control.sv +++ b/rv32_control.sv @@ -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; diff --git a/rv32_decode.sv b/rv32_decode.sv index 0aa2049..c222bb6 100644 --- a/rv32_decode.sv +++ b/rv32_decode.sv @@ -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), diff --git a/rv32_hazard.sv b/rv32_hazard.sv index 079b887..a854455 100644 --- a/rv32_hazard.sv +++ b/rv32_hazard.sv @@ -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;