From 67be950d3a8e858d29bb1f363930af2517e2e0ee Mon Sep 17 00:00:00 2001 From: James Clarke Date: Sun, 3 Nov 2019 04:12:34 +0000 Subject: [PATCH] FetchStage: Use EHRs to remove conflicts between doDecode and doFetch3 This conflict was introduced by 53aacff7c when compressed support was added. Previously, doDecode could be scheduled in the same cycle as doFetch3 (and only in that order), but the Reg reads added to doDecode prevented this. Instead, use EHRs to allow a bypass path from doDecode to doFetch3. This means we can issue every cycle again, rather than only every other cycle. --- .../RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv index 7424031..e91e389 100644 --- a/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv +++ b/src_Core/RISCY_OOO/procs/RV64G_OOO/FetchStage.bsv @@ -321,13 +321,13 @@ module mkFetchStage(FetchStage); Integer pc_redirect_port = 2; // Epochs - Reg#(Bool) decode_epoch <- mkReg(False); + Ehr#(2, Bool) decode_epoch <- mkEhr(False); Reg#(Epoch) f_main_epoch <- mkReg(0); // fetch estimate of main epoch - // Regs to hold the first half of an instruction that straddles a cache line boundary - Reg #(Bool) rg_pending_straddle <- mkReg (False); - Reg #(Addr) rg_half_inst_pc <- mkRegU; // The PC of the straddling instruction - Reg #(Bit #(16)) rg_half_inst_lsbs <- mkRegU; // The 16 lsbs of the straddling instruction + // Regs/wires to hold the first half of an instruction that straddles a cache line boundary + Ehr #(2, Bool) ehr_pending_straddle <- mkEhr (False); + Ehr #(2, Addr) ehr_half_inst_pc <- mkEhr (?); // The PC of the straddling instruction + Ehr #(2, Bit #(16)) ehr_half_inst_lsbs <- mkEhr (?); // The 16 lsbs of the straddling instruction // Pipeline Stage FIFOs Fifo#(2, Tuple2#(Bit#(TLog#(SupSize)),Fetch1ToFetch2)) f12f2 <- mkCFFifo; @@ -456,7 +456,7 @@ module mkFetchStage(FetchStage); let out = Fetch1ToFetch2 { pc: pc, pred_next_pc: pred_next_pc, - decode_epoch: decode_epoch, + decode_epoch: decode_epoch[0], main_epoch: f_main_epoch}; f12f2.enq(tuple2(fromInteger(posLastSup),out)); if (verbose) $display("Fetch1: ", fshow(out)); @@ -539,11 +539,11 @@ module mkFetchStage(FetchStage); end end - if (fetch3In.decode_epoch != decode_epoch) begin + if (fetch3In.decode_epoch != decode_epoch[1]) begin // Just drop it. if (verbosity > 0) begin $display ("----------------"); - $display ("Fetch3: Drop: decode epoch: %d", decode_epoch); + $display ("Fetch3: Drop: decode epoch: %d", decode_epoch[1]); $display ("Fetch3: f22f3.first: ", fshow (f22f3.first)); $display ("Fetch3: inst_d: ", fshow (inst_d)); end @@ -554,8 +554,8 @@ module mkFetchStage(FetchStage); Addr start_PC = fetch3In.pc; // Handle cache-line boundary straddling instruction, if one is pending - if (rg_pending_straddle) begin - if (fetch3In.pc != rg_half_inst_pc + 4) begin + if (ehr_pending_straddle[1]) begin + if (fetch3In.pc != ehr_half_inst_pc[1] + 4) begin $display ("----------------"); $display ("Fetch3: straddle: pc mismatch"); $display ("Fetch3: f22f3.first: ", fshow (f22f3.first)); @@ -564,17 +564,17 @@ module mkFetchStage(FetchStage); end else begin // Prepend onto the sequence: { first-half of the instruction , 0 } - v_x16 = shiftInAt0 (shiftInAt0 (v_x16, rg_half_inst_lsbs), 0); + v_x16 = shiftInAt0 (shiftInAt0 (v_x16, ehr_half_inst_lsbs[1]), 0); let bound = valueOf (SupSizeX2) - 1; if (n_x16s < (fromInteger (bound) - 1)) n_x16s = n_x16s + 2; else if (n_x16s < fromInteger (bound)) n_x16s = n_x16s + 1; - start_PC = rg_half_inst_pc; - rg_pending_straddle <= False; + start_PC = ehr_half_inst_pc[1]; + ehr_pending_straddle[1] <= False; if (verbosity > 0) begin $display ("----------------"); - $display ("Fetch3: straddle: prepend x16 %0h", rg_half_inst_lsbs); + $display ("Fetch3: straddle: prepend x16 %0h", ehr_half_inst_lsbs[1]); $display ("Fetch3: f22f3.first: ", fshow (f22f3.first)); $display ("Fetch3: inst_d: ", fshow (inst_d)); $display ("Fetch3: v_x16: ", fshow (v_x16)); @@ -606,7 +606,7 @@ module mkFetchStage(FetchStage); // The main_epoch check is required to make sure this stage doesn't // redirect the PC if a later stage already redirected the PC. if (fetch3In.main_epoch == f_main_epoch) begin - Bool decode_epoch_local = decode_epoch; // next value for decode epoch + Bool decode_epoch_local = decode_epoch[0]; // next value for decode epoch Maybe#(Addr) redirectPc = Invalid; // next pc redirect by branch predictor Maybe#(TrainNAP) trainNAP = Invalid; // training data sent to next addr pred `ifdef PERF_COUNT @@ -619,9 +619,9 @@ module mkFetchStage(FetchStage); if ((inst_data[i].inst_kind == Inst_32b_Lsbs) && (fromInteger(i) <= nbSup)) begin if (fetch3In.decode_epoch == decode_epoch_local) begin // Save the half-instruction and redirect doFetch1 to get the next cache line - rg_pending_straddle <= True; - rg_half_inst_pc <= inst_data[i].pc; - rg_half_inst_lsbs <= inst_data[i].orig_inst [15:0]; + ehr_pending_straddle[0] <= True; + ehr_half_inst_pc[0] <= inst_data[i].pc; + ehr_half_inst_lsbs[0] <= inst_data[i].orig_inst [15:0]; decode_epoch_local = ! decode_epoch_local; let next_PC = inst_data[i].pc + 4; redirectPc = tagged Valid (next_PC); @@ -782,7 +782,7 @@ module mkFetchStage(FetchStage); if(redirectPc matches tagged Valid .nextPc) begin pc_reg[pc_decode_port] <= nextPc; end - decode_epoch <= decode_epoch_local; + decode_epoch[0] <= decode_epoch_local; // send training data for next addr pred if (trainNAP matches tagged Valid .x) begin napTrainByDecQ.enq(x);