From d8ab7a5de2fc20e7bd839ff67135546b0c8fcb03 Mon Sep 17 00:00:00 2001 From: Ross Thompson Date: Thu, 22 Apr 2021 10:20:36 -0500 Subject: [PATCH] Partially working icache. The current issue is a StallF is required to halt the icache from getting an updated PCF. However if the dmemory is the reason for a stall it is possible for the icache stall to hold the d memory request continuously causing d memory to repeatedly read from memory. This keeps StallF high and the icache FSM is never allowed to complete. --- wally-pipelined/regression/wave.do | 101 +++++++++++++++-------------- wally-pipelined/src/ifu/icache.sv | 90 ++++++++++++++++++------- wally-pipelined/src/ifu/ifu.sv | 15 ++++- 3 files changed, 133 insertions(+), 73 deletions(-) diff --git a/wally-pipelined/regression/wave.do b/wally-pipelined/regression/wave.do index bdbb9ec2..280042de 100644 --- a/wally-pipelined/regression/wave.do +++ b/wally-pipelined/regression/wave.do @@ -9,26 +9,26 @@ add wave -noupdate -expand -group {Execution Stage} /testbench/functionRadix/fun add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/PCE add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName add wave -noupdate -expand -group {Execution Stage} /testbench/dut/hart/ifu/InstrE -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/EcallFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/StorePageFaultM -add wave -noupdate -expand -group HDU -expand -group traps /testbench/dut/hart/priv/trap/InterruptM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/RetM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/TrapM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/DataStall -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/MulDivStallD +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/EcallFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StorePageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InterruptM +add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/BPPredWrongE +add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM +add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/RetM +add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/TrapM +add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/LoadStallD +add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/hzu/DataStall +add wave -noupdate -expand -group HDU -expand -group hazards /testbench/dut/hart/MulDivStallD add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushD add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE @@ -172,6 +172,8 @@ add wave -noupdate -expand -group icache -expand -group {fsm out and control} /t add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/UnalignedSelect add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/PCMux +add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave +add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntReset add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/AHBByteLength add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/AHBOFFETWIDTH add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/BlockByteLength @@ -179,34 +181,35 @@ add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/i add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/WORDSPERLINE add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/LOGWPL add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/LINESIZE -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/FetchCount -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/InstrPAdrF -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/InstrInF -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteData -add wave -noupdate -expand -group icache -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWritePAdr -add wave -noupdate -expand -group icache -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/DataValidBit -add wave -noupdate -expand -group icache -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/DataValid -add wave -noupdate -expand -group icache -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/ReadTag -add wave -noupdate -expand -group icache -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/DataTag -add wave -noupdate -expand -group icache -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/cachetags/ReadAddr -add wave -noupdate -expand -group icache -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/cachetags/ReadData -add wave -noupdate -expand -group icache -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/ReadPAdr -add wave -noupdate -expand -group icache -group memory -expand -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteEnable -add wave -noupdate -expand -group icache -group memory -expand -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteLine -add wave -noupdate -expand -group icache -group memory -expand -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WritePAdr -add wave -noupdate -expand -group icache -group memory -expand -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteSet -add wave -noupdate -expand -group icache -group memory -expand -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteTag -add wave -noupdate -expand -group icache -group memory -expand -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/cachetags/StoredData +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCount +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrPAdrF +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrInF +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteData +add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWritePAdr +add wave -noupdate -expand -group icache -expand -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/DataValidBit +add wave -noupdate -expand -group icache -expand -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/DataValid +add wave -noupdate -expand -group icache -expand -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/ReadTag +add wave -noupdate -expand -group icache -expand -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/DataTag +add wave -noupdate -expand -group icache -expand -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/cachetags/ReadAddr +add wave -noupdate -expand -group icache -expand -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/cachetags/ReadData +add wave -noupdate -expand -group icache -expand -group memory -group {tag read} /testbench/dut/hart/ifu/icache/cachemem/ReadPAdr +add wave -noupdate -expand -group icache -expand -group memory -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteEnable +add wave -noupdate -expand -group icache -expand -group memory -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteLine +add wave -noupdate -expand -group icache -expand -group memory -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WritePAdr +add wave -noupdate -expand -group icache -expand -group memory -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteSet +add wave -noupdate -expand -group icache -expand -group memory -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/WriteTag +add wave -noupdate -expand -group icache -expand -group memory -group {tag write} /testbench/dut/hart/ifu/icache/cachemem/cachetags/StoredData add wave -noupdate -expand -group icache -expand -group {instr to cpu} /testbench/dut/hart/ifu/icache/controller/FinalInstrRawF add wave -noupdate -expand -group icache -expand -group {instr to cpu} /testbench/dut/hart/ifu/icache/controller/AlignedInstrRawD add wave -noupdate -expand -group icache -expand -group {instr to cpu} /testbench/dut/hart/ifu/icache/controller/InstrRawD -add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPF -add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPreFinalF -add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPFinalF +add wave -noupdate -expand -group pc /testbench/dut/hart/ifu/icache/controller/PCNextPF +add wave -noupdate -expand -group pc /testbench/dut/hart/ifu/icache/controller/PCPF +add wave -noupdate -expand -group pc /testbench/dut/hart/ifu/icache/controller/PCPreFinalF +add wave -noupdate -expand -group pc /testbench/dut/hart/ifu/icache/controller/PCPFinalF add wave -noupdate /testbench/dut/hart/ifu/icache/controller/ICacheMemReadData add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPreFinalF add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/ReadLine @@ -214,9 +217,11 @@ add wave -noupdate -radix hexadecimal -childformat {{{/testbench/dut/hart/ifu/ic add wave -noupdate -label {read offset} -radix unsigned -childformat {{(4) -radix unsigned} {(3) -radix unsigned} {(2) -radix unsigned} {(1) -radix unsigned} {(0) -radix unsigned}} -subitemconfig {{/testbench/dut/hart/ifu/icache/cachemem/OldReadPAdr[4]} {-radix unsigned} {/testbench/dut/hart/ifu/icache/cachemem/OldReadPAdr[3]} {-radix unsigned} {/testbench/dut/hart/ifu/icache/cachemem/OldReadPAdr[2]} {-radix unsigned} {/testbench/dut/hart/ifu/icache/cachemem/OldReadPAdr[1]} {-radix unsigned} {/testbench/dut/hart/ifu/icache/cachemem/OldReadPAdr[0]} {-radix unsigned}} /testbench/dut/hart/ifu/icache/cachemem/offset add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/OldReadPAdr add wave -noupdate /testbench/dut/hart/ifu/CompressedF +add wave -noupdate /testbench/dut/hart/ifu/icache/controller/SpillDataBlock0 +add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPreFinalF_q TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 2} {44 ns} 0} {{Cursor 2} {9098514 ns} 0} -quietly wave cursor active 2 +WaveRestoreCursors {{Cursor 2} {9808584 ns} 0} {{Cursor 3} {9808065 ns} 0} {{Cursor 4} {535 ns} 0} +quietly wave cursor active 1 configure wave -namecolwidth 250 configure wave -valuecolwidth 513 configure wave -justifyvalue left @@ -231,4 +236,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {9098483 ns} {9098569 ns} +WaveRestoreZoom {9808255 ns} {9808913 ns} diff --git a/wally-pipelined/src/ifu/icache.sv b/wally-pipelined/src/ifu/icache.sv index b14ae516..6f0437e2 100644 --- a/wally-pipelined/src/ifu/icache.sv +++ b/wally-pipelined/src/ifu/icache.sv @@ -140,19 +140,41 @@ module icachecontroller #(parameter LINESIZE = 256) ( localparam STATE_HIT_SPILL_MISS_FETCH_DONE = 3; // write data into SRAM/LUT localparam STATE_HIT_SPILL_MERGE = 4; // Read block 0 of CPU access, should be able to optimize into STATE_HIT_SPILL. - localparam STATE_MISS_FETCH_WDV = 5; // aligned miss, issue read to AHB and wait for data. - localparam STATE_MISS_FETCH_DONE = 6; // write data into SRAM/LUT - localparam STATE_MISS_READ = 7; // read block 1 from SRAM/LUT + // a challenge is the spill signal gets us out of the ready state and moves us to + // 1 of the 2 spill branches. However the original fsm design had us return to + // the ready state when the spill + hits/misses were fully resolved. The problem + // is the spill signal is based on PCPF so when we return to READY to check if the + // cache has a hit it still expresses spill. We can fix in 1 of two ways. + // 1. we can add 1 extra state at the end of each spill branch to returns the instruction + // to the CPU advancing the CPU and icache to the next instruction. + // 2. We can assert a signal which is delayed 1 cycle to suppress the spill when we get + // to the READY state. + // The first first option is more robust and increases the number of states by 2. The + // second option is seams like it should work, but I worry there is a hidden interaction + // between CPU stalling and that register. + // Picking option 1. - localparam STATE_MISS_SPILL_FETCH_WDV = 8; // spill, miss on block 0, issue read to AHB and wait - localparam STATE_MISS_SPILL_FETCH_DONE = 9; // write data into SRAM/LUT - localparam STATE_MISS_SPILL_READ1 = 10; // read block 0 from SRAM/LUT - localparam STATE_MISS_SPILL_2 = 11; // return to ready if hit or do second block update. - localparam STATE_MISS_SPILL_MISS_FETCH_WDV = 12; // miss on block 1, issue read to AHB and wait - localparam STATE_MISS_SPILL_MISS_FETCH_DONE = 13; // write data to SRAM/LUT - localparam STATE_MISS_SPILL_MERGE = 14; // read block 0 of CPU access, + localparam STATE_HIT_SPILL_FINAL = 5; // this state replicates STATE_READY's replay of the + // spill access but does nto consider spill. It also does not do another operation. + - localparam STATE_INVALIDATE = 15; // *** not sure if invalidate or evict? invalidate by cache block or address? + localparam STATE_MISS_FETCH_WDV = 6; // aligned miss, issue read to AHB and wait for data. + localparam STATE_MISS_FETCH_DONE = 7; // write data into SRAM/LUT + localparam STATE_MISS_READ = 8; // read block 1 from SRAM/LUT + + localparam STATE_MISS_SPILL_FETCH_WDV = 9; // spill, miss on block 0, issue read to AHB and wait + localparam STATE_MISS_SPILL_FETCH_DONE = 10; // write data into SRAM/LUT + localparam STATE_MISS_SPILL_READ1 = 11; // read block 0 from SRAM/LUT + localparam STATE_MISS_SPILL_2 = 12; // return to ready if hit or do second block update. + localparam STATE_MISS_SPILL_MISS_FETCH_WDV = 13; // miss on block 1, issue read to AHB and wait + localparam STATE_MISS_SPILL_MISS_FETCH_DONE = 14; // write data to SRAM/LUT + localparam STATE_MISS_SPILL_MERGE = 15; // read block 0 of CPU access, + + localparam STATE_MISS_SPILL_FINAL = 16; // this state replicates STATE_READY's replay of the + // spill access but does nto consider spill. It also does not do another operation. + + + localparam STATE_INVALIDATE = 17; // *** not sure if invalidate or evict? invalidate by cache block or address? localparam AHBByteLength = `XLEN / 8; localparam AHBOFFETWIDTH = $clog2(AHBByteLength); @@ -164,7 +186,7 @@ module icachecontroller #(parameter LINESIZE = 256) ( localparam WORDSPERLINE = LINESIZE/`XLEN; localparam LOGWPL = $clog2(WORDSPERLINE); - logic [3:0] CurrState, NextState; + logic [4:0] CurrState, NextState; logic hit, spill; logic SavePC; logic [1:0] PCMux; @@ -213,7 +235,8 @@ module icachecontroller #(parameter LINESIZE = 256) ( assign PCSpillF = PCPF + 2'b10; // now we have to select between these three PCs - assign PCPreFinalF = PCMux[0] | StallF ? PCPF : PCNextPF; // *** don't like the stallf + assign PCPreFinalF = PCMux[0] | StallF ? PCPF : PCNextPF; // *** don't like the stallf + //assign PCPreFinalF = PCMux[0] ? PCPF : PCNextPF; // *** don't like the stallf assign PCPFinalF = PCMux[1] ? PCSpillF : PCPreFinalF; @@ -347,12 +370,12 @@ module icachecontroller #(parameter LINESIZE = 256) ( -----/\----- EXCLUDED -----/\----- */ // the FSM is always runing, do not stall. - flopr #(4) stateReg(.clk(clk), + flopr #(5) stateReg(.clk(clk), .reset(reset), .d(NextState), .q(CurrState)); - assign spill = PCPF[5:1] == 5'b1_1111 ? 1'b1 : 1'b0; + assign spill = PCPF[4:1] == 4'b1111 ? 1'b1 : 1'b0; assign hit = ICacheMemReadValid; // note ICacheMemReadValid is hit. assign FetchCountFlag = FetchCount == FetchCountThreshold; @@ -366,6 +389,8 @@ module icachecontroller #(parameter LINESIZE = 256) ( spillSave = 1'b0; PCMux = 2'b00; ICacheReadEn = 1'b0; + SavePC = 1'b0; + ICacheStallF = 1'b1; case (CurrState) @@ -373,15 +398,19 @@ module icachecontroller #(parameter LINESIZE = 256) ( PCMux = 2'b00; ICacheReadEn = 1'b1; if (hit & ~spill) begin + SavePC = 1'b1; + ICacheStallF = 1'b0; NextState = STATE_READY; end else if (hit & spill) begin spillSave = 1'b1; + PCMux = 2'b10; NextState = STATE_HIT_SPILL; end else if (~hit & ~spill) begin CntReset = 1'b1; NextState = STATE_MISS_FETCH_WDV; end else if (~hit & spill) begin CntReset = 1'b1; + PCMux = 2'b10; NextState = STATE_MISS_SPILL_FETCH_WDV; end else begin NextState = STATE_READY; @@ -394,7 +423,7 @@ module icachecontroller #(parameter LINESIZE = 256) ( UnalignedSelect = 1'b1; ICacheReadEn = 1'b1; if (hit) begin - NextState = STATE_READY; + NextState = STATE_HIT_SPILL_FINAL; end else CntReset = 1'b1; NextState = STATE_HIT_SPILL_MISS_FETCH_WDV; @@ -418,7 +447,15 @@ module icachecontroller #(parameter LINESIZE = 256) ( PCMux = 2'b10; UnalignedSelect = 1'b1; ICacheReadEn = 1'b1; - NextState = STATE_READY; + NextState = STATE_HIT_SPILL_FINAL; + end + STATE_HIT_SPILL_FINAL: begin + ICacheReadEn = 1'b1; + PCMux = 2'b00; + UnalignedSelect = 1'b1; + SavePC = 1'b1; + NextState = STATE_READY; + ICacheStallF = 1'b0; end // branch 3 miss no spill @@ -472,7 +509,7 @@ module icachecontroller #(parameter LINESIZE = 256) ( CntReset = 1'b1; NextState = STATE_MISS_SPILL_MISS_FETCH_WDV; end else begin - NextState = STATE_READY; + NextState = STATE_MISS_SPILL_FINAL; end end STATE_MISS_SPILL_MISS_FETCH_WDV: begin @@ -494,7 +531,15 @@ module icachecontroller #(parameter LINESIZE = 256) ( PCMux = 2'b10; UnalignedSelect = 1'b1; ICacheReadEn = 1'b1; - NextState = STATE_READY; + NextState = STATE_MISS_SPILL_FINAL; + end + STATE_MISS_SPILL_FINAL: begin + ICacheReadEn = 1'b1; + PCMux = 2'b00; + UnalignedSelect = 1'b1; + SavePC = 1'b1; + ICacheStallF = 1'b0; + NextState = STATE_READY; end default: begin PCMux = 2'b01; @@ -508,9 +553,10 @@ module icachecontroller #(parameter LINESIZE = 256) ( // stall CPU any time we are not in the ready state. any other state means the // cache is either requesting data from the memory interface or handling a // spill over two cycles. - assign ICacheStallF = ((CurrState != STATE_READY) | ~hit) | reset_q ? 1'b1 : 1'b0; + // *** BUG this logic will need to change + //assign ICacheStallF = ((CurrState != STATE_READY) | ~hit | spill) | reset_q ? 1'b1 : 1'b0; // save the PC anytime we are in the ready state. The saved value will be used as the PC may not be stable. - assign SavePC = (CurrState == STATE_READY) & hit ? 1'b1 : 1'b0; + //assign SavePC = ((CurrState == STATE_READY) & hit) & ~spill ? 1'b1 : 1'b0; assign CntEn = PreCntEn & InstrAckF; assign InstrReadF = (CurrState == STATE_HIT_SPILL_MISS_FETCH_WDV) || @@ -571,7 +617,7 @@ module icachecontroller #(parameter LINESIZE = 256) ( .en(~StallF), .d(PCPreFinalF[1]), .q(PCPreFinalF_q[1])); - assign FinalInstrRawF = PCPreFinalF_q[1] ? {ICacheMemReadData[31:16], SpillDataBlock0} : ICacheMemReadData; + assign FinalInstrRawF = spill ? {ICacheMemReadData[15:0], SpillDataBlock0} : ICacheMemReadData; // There is a frustrating issue on the first access. // The cache will not contain any valid data but will contain x's on diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 58b144f5..5d728764 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -89,7 +89,7 @@ module ifu ( // branch predictor signals logic SelBPPredF; - logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F, PCNext2F; + logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F, PCNext2F, PCNext3F; logic [3:0] InstrClassD, InstrClassE; @@ -124,11 +124,20 @@ module ifu ( .s(PrivilegedChangePCM), .y(PCNext2F)); + // *** try to remove this in the future as it can add a long path. + // StallF may arrive late. +/* -----\/----- EXCLUDED -----\/----- mux2 #(`XLEN) pcmux3(.d0(PCNext2F), + .d1(PCF), + .s(StallF), + .y(PCNext3F)); + -----/\----- EXCLUDED -----/\----- */ + + mux2 #(`XLEN) pcmux4(.d0(PCNext2F), .d1(`RESET_VECTOR), .s(reset_q), - .y(UnalignedPCNextF)); - + .y(UnalignedPCNextF)); + flop #(1) resetReg (.clk(clk), .d(reset), .q(reset_q));