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.
This commit is contained in:
Ross Thompson 2021-04-22 10:20:36 -05:00
parent 50e893eec9
commit 7c8d2e9b78
3 changed files with 133 additions and 73 deletions

View File

@ -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/dut/hart/ifu/PCE
add wave -noupdate -expand -group {Execution Stage} /testbench/InstrEName 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 {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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 -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 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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -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/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/FlushD
add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE 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/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/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/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/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/AHBOFFETWIDTH
add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/BlockByteLength 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/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/LOGWPL
add wave -noupdate -expand -group icache -group parameters /testbench/dut/hart/ifu/icache/controller/LINESIZE 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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -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 -expand -group memory -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 -expand -group memory -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 -expand -group memory -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 -expand -group memory -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 -expand -group memory -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 -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/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/AlignedInstrRawD
add wave -noupdate -expand -group icache -expand -group {instr to cpu} /testbench/dut/hart/ifu/icache/controller/InstrRawD 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 -expand -group pc /testbench/dut/hart/ifu/icache/controller/PCNextPF
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPreFinalF add wave -noupdate -expand -group pc /testbench/dut/hart/ifu/icache/controller/PCPF
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPFinalF 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/ICacheMemReadData
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPreFinalF add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPreFinalF
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/ReadLine 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 -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/icache/cachemem/OldReadPAdr
add wave -noupdate /testbench/dut/hart/ifu/CompressedF 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] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 2} {44 ns} 0} {{Cursor 2} {9098514 ns} 0} WaveRestoreCursors {{Cursor 2} {9808584 ns} 0} {{Cursor 3} {9808065 ns} 0} {{Cursor 4} {535 ns} 0}
quietly wave cursor active 2 quietly wave cursor active 1
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 513 configure wave -valuecolwidth 513
configure wave -justifyvalue left configure wave -justifyvalue left
@ -231,4 +236,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {9098483 ns} {9098569 ns} WaveRestoreZoom {9808255 ns} {9808913 ns}

View File

@ -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_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_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. // a challenge is the spill signal gets us out of the ready state and moves us to
localparam STATE_MISS_FETCH_DONE = 6; // write data into SRAM/LUT // 1 of the 2 spill branches. However the original fsm design had us return to
localparam STATE_MISS_READ = 7; // read block 1 from SRAM/LUT // 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_HIT_SPILL_FINAL = 5; // this state replicates STATE_READY's replay of the
localparam STATE_MISS_SPILL_FETCH_DONE = 9; // write data into SRAM/LUT // spill access but does nto consider spill. It also does not do another operation.
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_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 AHBByteLength = `XLEN / 8;
localparam AHBOFFETWIDTH = $clog2(AHBByteLength); localparam AHBOFFETWIDTH = $clog2(AHBByteLength);
@ -164,7 +186,7 @@ module icachecontroller #(parameter LINESIZE = 256) (
localparam WORDSPERLINE = LINESIZE/`XLEN; localparam WORDSPERLINE = LINESIZE/`XLEN;
localparam LOGWPL = $clog2(WORDSPERLINE); localparam LOGWPL = $clog2(WORDSPERLINE);
logic [3:0] CurrState, NextState; logic [4:0] CurrState, NextState;
logic hit, spill; logic hit, spill;
logic SavePC; logic SavePC;
logic [1:0] PCMux; logic [1:0] PCMux;
@ -213,7 +235,8 @@ module icachecontroller #(parameter LINESIZE = 256) (
assign PCSpillF = PCPF + 2'b10; assign PCSpillF = PCPF + 2'b10;
// now we have to select between these three PCs // 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; assign PCPFinalF = PCMux[1] ? PCSpillF : PCPreFinalF;
@ -347,12 +370,12 @@ module icachecontroller #(parameter LINESIZE = 256) (
-----/\----- EXCLUDED -----/\----- */ -----/\----- EXCLUDED -----/\----- */
// the FSM is always runing, do not stall. // the FSM is always runing, do not stall.
flopr #(4) stateReg(.clk(clk), flopr #(5) stateReg(.clk(clk),
.reset(reset), .reset(reset),
.d(NextState), .d(NextState),
.q(CurrState)); .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 hit = ICacheMemReadValid; // note ICacheMemReadValid is hit.
assign FetchCountFlag = FetchCount == FetchCountThreshold; assign FetchCountFlag = FetchCount == FetchCountThreshold;
@ -366,6 +389,8 @@ module icachecontroller #(parameter LINESIZE = 256) (
spillSave = 1'b0; spillSave = 1'b0;
PCMux = 2'b00; PCMux = 2'b00;
ICacheReadEn = 1'b0; ICacheReadEn = 1'b0;
SavePC = 1'b0;
ICacheStallF = 1'b1;
case (CurrState) case (CurrState)
@ -373,15 +398,19 @@ module icachecontroller #(parameter LINESIZE = 256) (
PCMux = 2'b00; PCMux = 2'b00;
ICacheReadEn = 1'b1; ICacheReadEn = 1'b1;
if (hit & ~spill) begin if (hit & ~spill) begin
SavePC = 1'b1;
ICacheStallF = 1'b0;
NextState = STATE_READY; NextState = STATE_READY;
end else if (hit & spill) begin end else if (hit & spill) begin
spillSave = 1'b1; spillSave = 1'b1;
PCMux = 2'b10;
NextState = STATE_HIT_SPILL; NextState = STATE_HIT_SPILL;
end else if (~hit & ~spill) begin end else if (~hit & ~spill) begin
CntReset = 1'b1; CntReset = 1'b1;
NextState = STATE_MISS_FETCH_WDV; NextState = STATE_MISS_FETCH_WDV;
end else if (~hit & spill) begin end else if (~hit & spill) begin
CntReset = 1'b1; CntReset = 1'b1;
PCMux = 2'b10;
NextState = STATE_MISS_SPILL_FETCH_WDV; NextState = STATE_MISS_SPILL_FETCH_WDV;
end else begin end else begin
NextState = STATE_READY; NextState = STATE_READY;
@ -394,7 +423,7 @@ module icachecontroller #(parameter LINESIZE = 256) (
UnalignedSelect = 1'b1; UnalignedSelect = 1'b1;
ICacheReadEn = 1'b1; ICacheReadEn = 1'b1;
if (hit) begin if (hit) begin
NextState = STATE_READY; NextState = STATE_HIT_SPILL_FINAL;
end else end else
CntReset = 1'b1; CntReset = 1'b1;
NextState = STATE_HIT_SPILL_MISS_FETCH_WDV; NextState = STATE_HIT_SPILL_MISS_FETCH_WDV;
@ -418,7 +447,15 @@ module icachecontroller #(parameter LINESIZE = 256) (
PCMux = 2'b10; PCMux = 2'b10;
UnalignedSelect = 1'b1; UnalignedSelect = 1'b1;
ICacheReadEn = 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 end
// branch 3 miss no spill // branch 3 miss no spill
@ -472,7 +509,7 @@ module icachecontroller #(parameter LINESIZE = 256) (
CntReset = 1'b1; CntReset = 1'b1;
NextState = STATE_MISS_SPILL_MISS_FETCH_WDV; NextState = STATE_MISS_SPILL_MISS_FETCH_WDV;
end else begin end else begin
NextState = STATE_READY; NextState = STATE_MISS_SPILL_FINAL;
end end
end end
STATE_MISS_SPILL_MISS_FETCH_WDV: begin STATE_MISS_SPILL_MISS_FETCH_WDV: begin
@ -494,7 +531,15 @@ module icachecontroller #(parameter LINESIZE = 256) (
PCMux = 2'b10; PCMux = 2'b10;
UnalignedSelect = 1'b1; UnalignedSelect = 1'b1;
ICacheReadEn = 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 end
default: begin default: begin
PCMux = 2'b01; 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 // 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 // cache is either requesting data from the memory interface or handling a
// spill over two cycles. // 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. // 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 CntEn = PreCntEn & InstrAckF;
assign InstrReadF = (CurrState == STATE_HIT_SPILL_MISS_FETCH_WDV) || assign InstrReadF = (CurrState == STATE_HIT_SPILL_MISS_FETCH_WDV) ||
@ -571,7 +617,7 @@ module icachecontroller #(parameter LINESIZE = 256) (
.en(~StallF), .en(~StallF),
.d(PCPreFinalF[1]), .d(PCPreFinalF[1]),
.q(PCPreFinalF_q[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. // There is a frustrating issue on the first access.
// The cache will not contain any valid data but will contain x's on // The cache will not contain any valid data but will contain x's on

View File

@ -89,7 +89,7 @@ module ifu (
// branch predictor signals // branch predictor signals
logic SelBPPredF; 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; logic [3:0] InstrClassD, InstrClassE;
@ -124,11 +124,20 @@ module ifu (
.s(PrivilegedChangePCM), .s(PrivilegedChangePCM),
.y(PCNext2F)); .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), mux2 #(`XLEN) pcmux3(.d0(PCNext2F),
.d1(PCF),
.s(StallF),
.y(PCNext3F));
-----/\----- EXCLUDED -----/\----- */
mux2 #(`XLEN) pcmux4(.d0(PCNext2F),
.d1(`RESET_VECTOR), .d1(`RESET_VECTOR),
.s(reset_q), .s(reset_q),
.y(UnalignedPCNextF)); .y(UnalignedPCNextF));
flop #(1) resetReg (.clk(clk), flop #(1) resetReg (.clk(clk),
.d(reset), .d(reset),
.q(reset_q)); .q(reset_q));