mirror of
https://github.com/openhwgroup/cvw
synced 2025-02-11 06:05:49 +00:00
Broken icache. Design is done. Time to debug.
This commit is contained in:
parent
59b340dac9
commit
649589ee2c
@ -26,7 +26,6 @@ add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSR
|
|||||||
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/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/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/LoadStallD
|
||||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/InstrStall
|
|
||||||
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/DataStall
|
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 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
|
||||||
@ -39,11 +38,6 @@ add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbe
|
|||||||
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallE
|
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallE
|
||||||
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallM
|
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallM
|
||||||
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallW
|
add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallW
|
||||||
add wave -noupdate /testbench/dut/hart/hzu/StallFCause_Q
|
|
||||||
add wave -noupdate /testbench/dut/hart/hzu/StallDCause_Q
|
|
||||||
add wave -noupdate /testbench/dut/hart/hzu/StallECause_Q
|
|
||||||
add wave -noupdate /testbench/dut/hart/hzu/StallMCause_Q
|
|
||||||
add wave -noupdate /testbench/dut/hart/hzu/StallWCause_Q
|
|
||||||
add wave -noupdate -group Bpred -expand -group direction -divider Update
|
add wave -noupdate -group Bpred -expand -group direction -divider Update
|
||||||
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdatePC
|
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdatePC
|
||||||
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdateEN
|
add wave -noupdate -group Bpred -expand -group direction /testbench/dut/hart/ifu/bpred/Predictor/DirPredictor/UpdateEN
|
||||||
@ -80,36 +74,36 @@ add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/c/RegWriteD
|
|||||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/RdD
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/RdD
|
||||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs1D
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs1D
|
||||||
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs2D
|
add wave -noupdate -group {Decode Stage} /testbench/dut/hart/ieu/dp/Rs2D
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rf
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/rf
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a1
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/a1
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a2
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/a2
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/a3
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/a3
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rd1
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/rd1
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/rd2
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/rd2
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/we3
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/we3
|
||||||
add wave -noupdate -expand -group RegFile /testbench/dut/hart/ieu/dp/regf/wd3
|
add wave -noupdate -group RegFile /testbench/dut/hart/ieu/dp/regf/wd3
|
||||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ALUResultW
|
add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ALUResultW
|
||||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ReadDataW
|
add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ReadDataW
|
||||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/CSRReadValW
|
add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/CSRReadValW
|
||||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultSrcW
|
add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultSrcW
|
||||||
add wave -noupdate -expand -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultW
|
add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultW
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/a
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/a
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/b
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/b
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/alucontrol
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/alucontrol
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/result
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/result
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/flags
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/flags
|
||||||
add wave -noupdate -expand -group alu -divider internals
|
add wave -noupdate -group alu -divider internals
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/overflow
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/overflow
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/carry
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/carry
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/zero
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/zero
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/neg
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/neg
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/lt
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/lt
|
||||||
add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/ltu
|
add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/ltu
|
||||||
add wave -noupdate /testbench/InstrFName
|
add wave -noupdate /testbench/InstrFName
|
||||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemAdrM
|
add wave -noupdate -group dcache /testbench/dut/hart/MemAdrM
|
||||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/MemPAdrM
|
add wave -noupdate -group dcache /testbench/dut/hart/MemPAdrM
|
||||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/WriteDataM
|
add wave -noupdate -group dcache /testbench/dut/hart/WriteDataM
|
||||||
add wave -noupdate -expand -group dcache /testbench/dut/hart/dmem/MemRWM
|
add wave -noupdate -group dcache /testbench/dut/hart/dmem/MemRWM
|
||||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1D
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1D
|
||||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2D
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2D
|
||||||
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1E
|
add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1E
|
||||||
@ -148,32 +142,64 @@ add wave -noupdate -group {function radix debug} /testbench/functionRadix/functi
|
|||||||
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionAddr
|
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionAddr
|
||||||
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrIndex
|
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/ProgramAddrIndex
|
||||||
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionName
|
add wave -noupdate -group {function radix debug} /testbench/functionRadix/function_radix/FunctionName
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/InstrD
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/InstrD
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/SrcAE
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/SrcAE
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/SrcBE
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/SrcBE
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/Funct3E
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/Funct3E
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/MulDivE
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/MulDivE
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/W64E
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/W64E
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/StallM
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/StallM
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/StallW
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/StallW
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/FlushM
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushM
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/FlushW
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/FlushW
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/MulDivResultW
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/MulDivResultW
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/genblk1/div/start
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/genblk1/div/start
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/DivDoneE
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivDoneE
|
||||||
add wave -noupdate -expand -group muldiv /testbench/dut/hart/mdu/DivBusyE
|
add wave -noupdate -group muldiv /testbench/dut/hart/mdu/DivBusyE
|
||||||
add wave -noupdate /testbench/dut/hart/mdu/genblk1/gclk
|
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/fsm1/CURRENT_STATE
|
||||||
add wave -noupdate -expand -group divider /testbench/dut/hart/mdu/genblk1/div/fsm1/CURRENT_STATE
|
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/N
|
||||||
add wave -noupdate -expand -group divider /testbench/dut/hart/mdu/genblk1/div/N
|
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/D
|
||||||
add wave -noupdate -expand -group divider /testbench/dut/hart/mdu/genblk1/div/D
|
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/Q
|
||||||
add wave -noupdate -expand -group divider /testbench/dut/hart/mdu/genblk1/div/Q
|
add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/rem0
|
||||||
add wave -noupdate -expand -group divider /testbench/dut/hart/mdu/genblk1/div/rem0
|
add wave -noupdate -expand -group parameters /testbench/dut/hart/ifu/icache/controller/AHBByteLength
|
||||||
add wave -noupdate /testbench/dut/hart/MulDivResultW
|
add wave -noupdate -expand -group parameters /testbench/dut/hart/ifu/icache/controller/AHBOFFETWIDTH
|
||||||
add wave -noupdate /testbench/dut/hart/mdu/genblk1/PrelimResultE
|
add wave -noupdate -expand -group parameters /testbench/dut/hart/ifu/icache/controller/BlockByteLength
|
||||||
add wave -noupdate /testbench/dut/hart/mdu/Funct3E
|
add wave -noupdate -expand -group parameters /testbench/dut/hart/ifu/icache/controller/OFFSETWIDTH
|
||||||
add wave -noupdate /testbench/dut/hart/mdu/genblk1/QuotE
|
add wave -noupdate -expand -group parameters /testbench/dut/hart/ifu/icache/controller/WORDSPERLINE
|
||||||
|
add wave -noupdate -expand -group parameters /testbench/dut/hart/ifu/icache/controller/LOGWPL
|
||||||
|
add wave -noupdate -expand -group parameters /testbench/dut/hart/ifu/icache/controller/LINESIZE
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/CurrState
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrPAdrF
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCount
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteData
|
||||||
|
add wave -noupdate -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWritePAdr
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPF
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPreFinalF
|
||||||
|
add wave -noupdate -expand -group {instr to cpu} /testbench/dut/hart/ifu/icache/controller/FinalInstrRawF
|
||||||
|
add wave -noupdate -expand -group {instr to cpu} /testbench/dut/hart/ifu/icache/controller/AlignedInstrRawD
|
||||||
|
add wave -noupdate -expand -group {instr to cpu} /testbench/dut/hart/ifu/icache/controller/InstrRawD
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/hit
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/spill
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/spillSave
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/UnalignedSelect
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCMux
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/controller/PCPFinalF
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/DataValidBit
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/DataValid
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/ReadTag
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/DataTag
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/WriteEnable
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/WriteLine
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/WritePAdr
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/WriteSet
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/WriteTag
|
||||||
|
add wave -noupdate /testbench/dut/hart/ifu/icache/cachemem/cachetags/StoredData
|
||||||
TreeUpdate [SetDefaultTree]
|
TreeUpdate [SetDefaultTree]
|
||||||
WaveRestoreCursors {{Cursor 2} {128433 ns} 0}
|
WaveRestoreCursors {{Cursor 2} {237 ns} 0}
|
||||||
quietly wave cursor active 1
|
quietly wave cursor active 1
|
||||||
configure wave -namecolwidth 250
|
configure wave -namecolwidth 250
|
||||||
configure wave -valuecolwidth 229
|
configure wave -valuecolwidth 229
|
||||||
@ -189,4 +215,4 @@ configure wave -griddelta 40
|
|||||||
configure wave -timeline 0
|
configure wave -timeline 0
|
||||||
configure wave -timelineunits ns
|
configure wave -timelineunits ns
|
||||||
update
|
update
|
||||||
WaveRestoreZoom {128007 ns} {128663 ns}
|
WaveRestoreZoom {96 ns} {400 ns}
|
||||||
|
@ -129,57 +129,141 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
output logic InstrReadF
|
output logic InstrReadF
|
||||||
);
|
);
|
||||||
|
|
||||||
|
// FSM states
|
||||||
|
localparam STATE_READY = 0;
|
||||||
|
localparam STATE_HIT_SPILL = 1; // spill, block 0 hit
|
||||||
|
localparam STATE_HIT_SPILL_MISS_FETCH_WDV = 2; // block 1 miss, issue read to AHB and wait data.
|
||||||
|
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
|
||||||
|
|
||||||
|
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_INVALIDATE = 15; // *** not sure if invalidate or evict? invalidate by cache block or address?
|
||||||
|
|
||||||
|
localparam AHBByteLength = `XLEN / 8;
|
||||||
|
localparam AHBOFFETWIDTH = $clog2(AHBByteLength);
|
||||||
|
|
||||||
|
|
||||||
|
localparam BlockByteLength = LINESIZE / 8;
|
||||||
|
localparam OFFSETWIDTH = $clog2(BlockByteLength);
|
||||||
|
|
||||||
|
localparam WORDSPERLINE = LINESIZE/`XLEN;
|
||||||
|
localparam LOGWPL = $clog2(WORDSPERLINE);
|
||||||
|
|
||||||
|
logic [3:0] CurrState, NextState;
|
||||||
|
logic hit, spill;
|
||||||
|
logic SavePC;
|
||||||
|
logic [1:0] PCMux;
|
||||||
|
logic CntReset;
|
||||||
|
logic PreCntEn, CntEn;
|
||||||
|
logic spillSave;
|
||||||
|
logic UnalignedSelect;
|
||||||
|
logic FetchCountFlag;
|
||||||
|
localparam FetchCountThreshold = WORDSPERLINE - 1;
|
||||||
|
|
||||||
|
logic [LOGWPL:0] FetchCount, NextFetchCount;
|
||||||
|
|
||||||
|
logic [`XLEN-1:0] PCPreFinalF, PCPFinalF, PCSpillF;
|
||||||
|
logic [`XLEN-1:OFFSETWIDTH] PCPTrunkF;
|
||||||
|
|
||||||
|
|
||||||
|
logic [31:0] FinalInstrRawF;
|
||||||
|
|
||||||
|
logic [15:0] SpillDataBlock0;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// Happy path signals
|
// Happy path signals
|
||||||
logic [31:0] AlignedInstrRawF, AlignedInstrRawD;
|
logic [31:0] AlignedInstrRawD;
|
||||||
logic FlushDLastCycleN;
|
|
||||||
logic PCPMisalignedF;
|
//logic [31:0] AlignedInstrRawF, AlignedInstrRawD;
|
||||||
|
//logic FlushDLastCycleN;
|
||||||
|
//logic PCPMisalignedF;
|
||||||
const logic [31:0] NOP = 32'h13;
|
const logic [31:0] NOP = 32'h13;
|
||||||
logic [`XLEN-1:0] PCPF;
|
logic [`XLEN-1:0] PCPF;
|
||||||
|
|
||||||
|
logic reset_q;
|
||||||
|
|
||||||
// Misaligned signals
|
// Misaligned signals
|
||||||
logic [`XLEN:0] MisalignedInstrRawF;
|
//logic [`XLEN:0] MisalignedInstrRawF;
|
||||||
logic MisalignedStall;
|
//logic MisalignedStall;
|
||||||
// Cache fault signals
|
// Cache fault signals
|
||||||
logic FaultStall;
|
//logic FaultStall;
|
||||||
|
|
||||||
|
|
||||||
|
flopenr #(`XLEN) PCPFFlop(clk, reset, SavePC, {UpperPCNextPF, LowerPCNextF}, PCPF);
|
||||||
|
// on spill we want to get the first 2 bytes of the next cache block.
|
||||||
|
// the spill only occurs if the PCPF mod BlockByteLength == -2. Therefore we can
|
||||||
|
// simply add 2 to land on the next cache block.
|
||||||
|
assign PCSpillF = PCPF + 2'b10;
|
||||||
|
|
||||||
|
// now we have to select between these three PCs
|
||||||
|
assign PCPreFinalF = PCMux[0] ? PCPF : {UpperPCNextPF, LowerPCNextF};
|
||||||
|
assign PCPFinalF = PCMux[1] ? PCSpillF : PCPreFinalF;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
// truncate the offset from PCPF for memory address generation
|
||||||
|
assign PCPTrunkF = PCPFinalF[`XLEN-1:OFFSETWIDTH];
|
||||||
|
|
||||||
// Detect if the instruction is compressed
|
// Detect if the instruction is compressed
|
||||||
assign CompressedF = AlignedInstrRawF[1:0] != 2'b11;
|
assign CompressedF = FinalInstrRawF[1:0] != 2'b11;
|
||||||
|
|
||||||
|
|
||||||
// Handle happy path (data in cache, reads aligned)
|
// Handle happy path (data in cache, reads aligned)
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
|
|
||||||
generate
|
generate
|
||||||
if (`XLEN == 32) begin
|
if (`XLEN == 32) begin
|
||||||
assign AlignedInstrRawF = PCPF[1] ? MisalignedInstrRawF : ICacheMemReadData;
|
assign AlignedInstrRawF = PCPF[1] ? MisalignedInstrRawF : ICacheMemReadData;
|
||||||
assign PCPMisalignedF = PCPF[1] && ~CompressedF;
|
//assign PCPMisalignedF = PCPF[1] && ~CompressedF;
|
||||||
end else begin
|
end else begin
|
||||||
assign AlignedInstrRawF = PCPF[2]
|
assign AlignedInstrRawF = PCPF[2]
|
||||||
? (PCPF[1] ? MisalignedInstrRawF : ICacheMemReadData[63:32])
|
? (PCPF[1] ? MisalignedInstrRawF : ICacheMemReadData[63:32])
|
||||||
: (PCPF[1] ? ICacheMemReadData[47:16] : ICacheMemReadData[31:0]);
|
: (PCPF[1] ? ICacheMemReadData[47:16] : ICacheMemReadData[31:0]);
|
||||||
assign PCPMisalignedF = PCPF[2] && PCPF[1] && ~CompressedF;
|
//assign PCPMisalignedF = PCPF[2] && PCPF[1] && ~CompressedF;
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
flopenr #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, AlignedInstrRawF, AlignedInstrRawD);
|
//flopenr #(32) AlignedInstrRawDFlop(clk, reset, ~StallD, AlignedInstrRawF, AlignedInstrRawD);
|
||||||
flopr #(1) FlushDLastCycleFlop(clk, reset, ~FlushD & (FlushDLastCycleN | ~StallF), FlushDLastCycleN);
|
//flopr #(1) FlushDLastCycleFlop(clk, reset, ~FlushD & (FlushDLastCycleN | ~StallF), FlushDLastCycleN);
|
||||||
flopenr #(`XLEN) PCPFFlop(clk, reset, ~StallF, {UpperPCNextPF, LowerPCNextF}, PCPF);
|
|
||||||
mux2 #(32) InstrRawDMux(AlignedInstrRawD, NOP, ~FlushDLastCycleN, InstrRawD);
|
//mux2 #(32) InstrRawDMux(AlignedInstrRawD, NOP, ~FlushDLastCycleN, InstrRawD);
|
||||||
|
|
||||||
// Stall for faults or misaligned reads
|
// Stall for faults or misaligned reads
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
always_comb begin
|
always_comb begin
|
||||||
assign ICacheStallF = FaultStall | MisalignedStall;
|
assign ICacheStallF = FaultStall | MisalignedStall;
|
||||||
end
|
end
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
|
|
||||||
// Handle misaligned, noncompressed reads
|
// Handle misaligned, noncompressed reads
|
||||||
|
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
logic MisalignedState, NextMisalignedState;
|
logic MisalignedState, NextMisalignedState;
|
||||||
logic [15:0] MisalignedHalfInstrF;
|
logic [15:0] MisalignedHalfInstrF;
|
||||||
logic [15:0] UpperHalfWord;
|
logic [15:0] UpperHalfWord;
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
flopenr #(16) MisalignedHalfInstrFlop(clk, reset, ~FaultStall & (PCPMisalignedF & MisalignedState), AlignedInstrRawF[15:0], MisalignedHalfInstrF);
|
flopenr #(16) MisalignedHalfInstrFlop(clk, reset, ~FaultStall & (PCPMisalignedF & MisalignedState), AlignedInstrRawF[15:0], MisalignedHalfInstrF);
|
||||||
flopenr #(1) MisalignedStateFlop(clk, reset, ~FaultStall, NextMisalignedState, MisalignedState);
|
flopenr #(1) MisalignedStateFlop(clk, reset, ~FaultStall, NextMisalignedState, MisalignedState);
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
// When doing a misaligned read, swizzle the bits correctly
|
// When doing a misaligned read, swizzle the bits correctly
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
generate
|
generate
|
||||||
if (`XLEN == 32) begin
|
if (`XLEN == 32) begin
|
||||||
assign UpperHalfWord = ICacheMemReadData[31:16];
|
assign UpperHalfWord = ICacheMemReadData[31:16];
|
||||||
@ -194,14 +278,18 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
assign MisalignedInstrRawF = {ICacheMemReadData[15:0], MisalignedHalfInstrF};
|
assign MisalignedInstrRawF = {ICacheMemReadData[15:0], MisalignedHalfInstrF};
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
// Manage internal state and stall when necessary
|
// Manage internal state and stall when necessary
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
always_comb begin
|
always_comb begin
|
||||||
assign MisalignedStall = PCPMisalignedF & MisalignedState;
|
assign MisalignedStall = PCPMisalignedF & MisalignedState;
|
||||||
assign NextMisalignedState = ~PCPMisalignedF | ~MisalignedState;
|
assign NextMisalignedState = ~PCPMisalignedF | ~MisalignedState;
|
||||||
end
|
end
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
// Pick the correct address to read
|
// Pick the correct address to read
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
generate
|
generate
|
||||||
if (`XLEN == 32) begin
|
if (`XLEN == 32) begin
|
||||||
assign ICacheMemReadLowerAdr = {LowerPCNextF[11:2] + (PCPMisalignedF & ~MisalignedState), 2'b00};
|
assign ICacheMemReadLowerAdr = {LowerPCNextF[11:2] + (PCPMisalignedF & ~MisalignedState), 2'b00};
|
||||||
@ -209,16 +297,15 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
assign ICacheMemReadLowerAdr = {LowerPCNextF[11:3] + (PCPMisalignedF & ~MisalignedState), 3'b00};
|
assign ICacheMemReadLowerAdr = {LowerPCNextF[11:3] + (PCPMisalignedF & ~MisalignedState), 3'b00};
|
||||||
end
|
end
|
||||||
endgenerate
|
endgenerate
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
// TODO Handle reading instructions that cross page boundaries
|
// TODO Handle reading instructions that cross page boundaries
|
||||||
assign ICacheMemReadUpperPAdr = UpperPCNextPF;
|
//assign ICacheMemReadUpperPAdr = UpperPCNextPF;
|
||||||
|
|
||||||
|
|
||||||
// Handle cache faults
|
// Handle cache faults
|
||||||
|
|
||||||
localparam integer WORDSPERLINE = LINESIZE/`XLEN;
|
|
||||||
localparam integer LOGWPL = $clog2(WORDSPERLINE);
|
|
||||||
localparam integer OFFSETWIDTH = $clog2(LINESIZE/8);
|
|
||||||
|
|
||||||
|
/* -----\/----- EXCLUDED -----\/-----
|
||||||
logic FetchState, BeginFetchState;
|
logic FetchState, BeginFetchState;
|
||||||
logic [LOGWPL:0] FetchWordNum, NextFetchWordNum;
|
logic [LOGWPL:0] FetchWordNum, NextFetchWordNum;
|
||||||
logic [`XLEN-1:0] LineAlignedPCPF;
|
logic [`XLEN-1:0] LineAlignedPCPF;
|
||||||
@ -226,12 +313,6 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
flopr #(1) FetchStateFlop(clk, reset, BeginFetchState | (FetchState & ~EndFetchState), FetchState);
|
flopr #(1) FetchStateFlop(clk, reset, BeginFetchState | (FetchState & ~EndFetchState), FetchState);
|
||||||
flopr #(LOGWPL+1) FetchWordNumFlop(clk, reset, NextFetchWordNum, FetchWordNum);
|
flopr #(LOGWPL+1) FetchWordNumFlop(clk, reset, NextFetchWordNum, FetchWordNum);
|
||||||
|
|
||||||
genvar i;
|
|
||||||
generate
|
|
||||||
for (i=0; i < WORDSPERLINE; i++) begin
|
|
||||||
flopenr #(`XLEN) flop(clk, reset, FetchState & (i == FetchWordNum), InstrInF, ICacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN]);
|
|
||||||
end
|
|
||||||
endgenerate
|
|
||||||
|
|
||||||
// Enter the fetch state when we hit a cache fault
|
// Enter the fetch state when we hit a cache fault
|
||||||
always_comb begin
|
always_comb begin
|
||||||
@ -242,10 +323,10 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
|
|
||||||
// Machinery to request the correct addresses from main memory
|
// Machinery to request the correct addresses from main memory
|
||||||
always_comb begin
|
always_comb begin
|
||||||
InstrReadF = FetchState & ~EndFetchState & ~ICacheMemWriteEnable;
|
InstrReadF = FetchState & ~EndFetchState & ~ICacheMemWriteEnable; // next stage logic
|
||||||
LineAlignedPCPF = {ICacheMemReadUpperPAdr, ICacheMemReadLowerAdr[11:OFFSETWIDTH], {OFFSETWIDTH{1'b0}}};
|
LineAlignedPCPF = {ICacheMemReadUpperPAdr, ICacheMemReadLowerAdr[11:OFFSETWIDTH], {OFFSETWIDTH{1'b0}}}; // the fetch address for abh?
|
||||||
InstrPAdrF = LineAlignedPCPF + FetchWordNum*(`XLEN/8);
|
InstrPAdrF = LineAlignedPCPF + FetchWordNum*(`XLEN/8); // ?
|
||||||
NextFetchWordNum = FetchState ? FetchWordNum+InstrAckF : {LOGWPL+1{1'b0}};
|
NextFetchWordNum = FetchState ? FetchWordNum+InstrAckF : {LOGWPL+1{1'b0}}; // convert to enable
|
||||||
end
|
end
|
||||||
|
|
||||||
// Write to cache memory when we have the line here
|
// Write to cache memory when we have the line here
|
||||||
@ -258,4 +339,255 @@ module icachecontroller #(parameter LINESIZE = 256) (
|
|||||||
always_comb begin
|
always_comb begin
|
||||||
FaultStall = FetchState | ~ICacheMemReadValid;
|
FaultStall = FetchState | ~ICacheMemReadValid;
|
||||||
end
|
end
|
||||||
|
-----/\----- EXCLUDED -----/\----- */
|
||||||
|
|
||||||
|
// the FSM is always runing, do not stall.
|
||||||
|
flopr #(4) stateReg(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.d(NextState),
|
||||||
|
.q(CurrState));
|
||||||
|
|
||||||
|
assign spill = PCPF[5:1] == 5'b1_1111 ? 1'b1 : 1'b0;
|
||||||
|
assign hit = ICacheMemReadValid; // note ICacheMemReadValid is hit.
|
||||||
|
assign FetchCountFlag = FetchCount == FetchCountThreshold;
|
||||||
|
|
||||||
|
// Next state logic
|
||||||
|
always_comb begin
|
||||||
|
UnalignedSelect = 1'b0;
|
||||||
|
CntReset = 1'b0;
|
||||||
|
PreCntEn = 1'b0;
|
||||||
|
InstrReadF = 1'b0;
|
||||||
|
ICacheMemWriteEnable = 1'b0;
|
||||||
|
spillSave = 1'b0;
|
||||||
|
PCMux = 2'b00;
|
||||||
|
|
||||||
|
case (CurrState)
|
||||||
|
|
||||||
|
STATE_READY: begin
|
||||||
|
PCMux = 2'b00;
|
||||||
|
if (hit & ~spill) begin
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end else if (hit & spill) begin
|
||||||
|
spillSave = 1'b1;
|
||||||
|
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;
|
||||||
|
NextState = STATE_MISS_SPILL_FETCH_WDV;
|
||||||
|
end else begin
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
// branch 1, hit spill and 2, miss spill hit
|
||||||
|
STATE_HIT_SPILL: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
UnalignedSelect = 1'b1;
|
||||||
|
if (hit) begin
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end else
|
||||||
|
CntReset = 1'b1;
|
||||||
|
NextState = STATE_HIT_SPILL_MISS_FETCH_WDV;
|
||||||
|
end
|
||||||
|
STATE_HIT_SPILL_MISS_FETCH_WDV: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
InstrReadF = 1'b1;
|
||||||
|
PreCntEn = 1'b1;
|
||||||
|
if (FetchCountFlag & InstrAckF) begin
|
||||||
|
NextState = STATE_HIT_SPILL_MISS_FETCH_DONE;
|
||||||
|
end else begin
|
||||||
|
NextState = STATE_HIT_SPILL_MISS_FETCH_WDV;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_HIT_SPILL_MISS_FETCH_DONE: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
ICacheMemWriteEnable = 1'b1;
|
||||||
|
NextState = STATE_HIT_SPILL_MERGE;
|
||||||
|
end
|
||||||
|
STATE_HIT_SPILL_MERGE: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
UnalignedSelect = 1'b1;
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end
|
||||||
|
|
||||||
|
// branch 3 miss no spill
|
||||||
|
STATE_MISS_FETCH_WDV: begin
|
||||||
|
PCMux = 2'b01;
|
||||||
|
InstrReadF = 1'b1;
|
||||||
|
PreCntEn = 1'b1;
|
||||||
|
if (FetchCountFlag & InstrAckF) begin
|
||||||
|
NextState = STATE_MISS_FETCH_DONE;
|
||||||
|
end else begin
|
||||||
|
NextState = STATE_MISS_FETCH_WDV;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_MISS_FETCH_DONE: begin
|
||||||
|
PCMux = 2'b01;
|
||||||
|
ICacheMemWriteEnable = 1'b1;
|
||||||
|
NextState = STATE_MISS_READ;
|
||||||
|
end
|
||||||
|
STATE_MISS_READ: begin
|
||||||
|
PCMux = 2'b01;
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end
|
||||||
|
|
||||||
|
// branch 4 miss spill hit, and 5 miss spill miss
|
||||||
|
STATE_MISS_SPILL_FETCH_WDV: begin
|
||||||
|
PCMux = 2'b01;
|
||||||
|
PreCntEn = 1'b1;
|
||||||
|
InstrReadF = 1'b1;
|
||||||
|
if (FetchCountFlag & InstrAckF) begin
|
||||||
|
NextState = STATE_MISS_SPILL_FETCH_DONE;
|
||||||
|
end else begin
|
||||||
|
NextState = STATE_MISS_SPILL_FETCH_WDV;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_MISS_SPILL_FETCH_DONE: begin
|
||||||
|
PCMux = 2'b01;
|
||||||
|
ICacheMemWriteEnable = 1'b1;
|
||||||
|
NextState = STATE_MISS_SPILL_READ1;
|
||||||
|
end
|
||||||
|
STATE_MISS_SPILL_READ1: begin // always be a hit as we just wrote that cache block.
|
||||||
|
PCMux = 2'b10; // there is a 1 cycle delay after setting the address before the date arrives.
|
||||||
|
spillSave = 1'b1; /// *** Could pipeline these to make it clearer in the fsm.
|
||||||
|
NextState = STATE_MISS_SPILL_2;
|
||||||
|
end
|
||||||
|
STATE_MISS_SPILL_2: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
UnalignedSelect = 1'b1;
|
||||||
|
if (~hit) begin
|
||||||
|
CntReset = 1'b1;
|
||||||
|
NextState = STATE_MISS_SPILL_MISS_FETCH_WDV;
|
||||||
|
end else begin
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_MISS_SPILL_MISS_FETCH_WDV: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
PreCntEn = 1'b1;
|
||||||
|
InstrReadF = 1'b1;
|
||||||
|
if (FetchCountFlag & InstrAckF) begin
|
||||||
|
NextState = STATE_MISS_SPILL_MISS_FETCH_DONE;
|
||||||
|
end else begin
|
||||||
|
NextState = STATE_MISS_SPILL_MISS_FETCH_WDV;
|
||||||
|
end
|
||||||
|
end
|
||||||
|
STATE_MISS_SPILL_MISS_FETCH_DONE: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
ICacheMemWriteEnable = 1'b1;
|
||||||
|
NextState = STATE_MISS_SPILL_MERGE;
|
||||||
|
end
|
||||||
|
STATE_MISS_SPILL_MERGE: begin
|
||||||
|
PCMux = 2'b10;
|
||||||
|
UnalignedSelect = 1'b1;
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end
|
||||||
|
default: begin
|
||||||
|
PCMux = 2'b01;
|
||||||
|
NextState = STATE_READY;
|
||||||
|
end
|
||||||
|
// *** add in error handling and invalidate/evict
|
||||||
|
endcase
|
||||||
|
end
|
||||||
|
|
||||||
|
// fsm outputs
|
||||||
|
// 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) | 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 ? 1'b1 : 1'b0;
|
||||||
|
assign CntEn = PreCntEn & InstrAckF;
|
||||||
|
|
||||||
|
// to compute the fetch address we need to add the bit shifted
|
||||||
|
// counter output to the address.
|
||||||
|
|
||||||
|
flopenr #(LOGWPL+1)
|
||||||
|
FetchCountReg(.clk(clk),
|
||||||
|
.reset(reset | CntReset),
|
||||||
|
.en(CntEn),
|
||||||
|
.d(NextFetchCount),
|
||||||
|
.q(FetchCount));
|
||||||
|
|
||||||
|
assign NextFetchCount = FetchCount + 1'b1;
|
||||||
|
|
||||||
|
// This part is confusing.
|
||||||
|
// we need to remove the offset bits (PCPTrunkF). Because the AHB interface is XLEN wide
|
||||||
|
// we need to address on that number of bits so the PC is extended to the right by AHBByteLength with zeros.
|
||||||
|
// fetch count is already aligned to AHBByteLength, but we need to extend back to the full address width with
|
||||||
|
// more zeros after the addition. This will be the number of offset bits less the AHBByteLength.
|
||||||
|
assign InstrPAdrF = {{PCPTrunkF, {{LOGWPL}{1'b0}}} + FetchCount, {{OFFSETWIDTH-LOGWPL}{1'b0}}};
|
||||||
|
|
||||||
|
|
||||||
|
// store read data from memory interface before writing into SRAM.
|
||||||
|
genvar i;
|
||||||
|
generate
|
||||||
|
for (i = 0; i < AHBByteLength; i++) begin
|
||||||
|
flopenr #(`XLEN) flop(.clk(clk),
|
||||||
|
.reset(reset),
|
||||||
|
.en(InstrAckF & (i == FetchCount)),
|
||||||
|
.d(InstrInF),
|
||||||
|
.q(ICacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN]));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// what address is used to write the SRAM?
|
||||||
|
|
||||||
|
|
||||||
|
// spills require storing the first cache block so it can merged
|
||||||
|
// with the second
|
||||||
|
// can optimize size, for now just make it the size of the data
|
||||||
|
// leaving the cache memory.
|
||||||
|
flopenr #(16) SpillInstrReg(.clk(clk),
|
||||||
|
.en(spillSave),
|
||||||
|
.reset(reset),
|
||||||
|
.d(ICacheMemReadData[15:0]),
|
||||||
|
.q(SpillDataBlock0));
|
||||||
|
|
||||||
|
// use the not quite final PC to do the final selection.
|
||||||
|
generate
|
||||||
|
if( `XLEN == 32) begin
|
||||||
|
logic [1:1] PCPreFinalF_q;
|
||||||
|
flop #(1) PCFReg(.clk(clk),
|
||||||
|
.d(PCPreFinalF[1]),
|
||||||
|
.q(PCPreFinalF_q[1]));
|
||||||
|
assign FinalInstrRawF = PCPreFinalF[1] ? {SpillDataBlock0, ICacheMemReadData[31:16]} : ICacheMemReadData;
|
||||||
|
end else begin
|
||||||
|
logic [2:1] PCPreFinalF_q;
|
||||||
|
flop #(2) PCFReg(.clk(clk),
|
||||||
|
.d(PCPreFinalF[2:1]),
|
||||||
|
.q(PCPreFinalF_q[2:1]));
|
||||||
|
mux4 #(32) AlignmentMux(.d0(ICacheMemReadData[31:0]),
|
||||||
|
.d1(ICacheMemReadData[47:16]),
|
||||||
|
.d2(ICacheMemReadData[63:32]),
|
||||||
|
.d3({SpillDataBlock0, ICacheMemReadData[63:48]}),
|
||||||
|
.s(PCPreFinalF[2:1]),
|
||||||
|
.y(FinalInstrRawF));
|
||||||
|
end
|
||||||
|
endgenerate
|
||||||
|
|
||||||
|
// There is a frustrating issue on the first access.
|
||||||
|
// The cache will not contain any valid data but will contain x's on
|
||||||
|
// reset. This makes FinalInstrRawF invalid. On the first cycle out of
|
||||||
|
// reset this register will pickup this x and it will propagate throughout
|
||||||
|
// the cpu causing simulation failure, most likely a trap for invalid instruction.
|
||||||
|
// Reset must be held 1 cycle longer to prevent this issue. additionally the
|
||||||
|
// reset should be to a NOP rather than 0.
|
||||||
|
|
||||||
|
// register reset
|
||||||
|
flop #(1) resetReg (.clk(clk),
|
||||||
|
.d(reset),
|
||||||
|
.q(reset_q));
|
||||||
|
|
||||||
|
flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FinalInstrRawF, NOP, AlignedInstrRawD);
|
||||||
|
mux2 #(32) InstrRawDMux(AlignedInstrRawD, NOP, FlushD, InstrRawD);
|
||||||
|
|
||||||
|
assign {ICacheMemReadUpperPAdr, ICacheMemReadLowerAdr} = PCPFinalF;
|
||||||
|
|
||||||
|
assign ICacheMemWritePAdr = PCPFinalF;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
endmodule
|
endmodule
|
||||||
|
@ -77,6 +77,8 @@ module ifu (
|
|||||||
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
logic [31:0] nop = 32'h00000013; // instruction for NOP
|
||||||
// *** send this to the trap unit
|
// *** send this to the trap unit
|
||||||
logic ITLBPageFaultF;
|
logic ITLBPageFaultF;
|
||||||
|
logic reset_q; // *** look at this later.
|
||||||
|
|
||||||
|
|
||||||
tlb #(3) itlb(.TLBAccess(1'b1), .VirtualAddress(PCF),
|
tlb #(3) itlb(.TLBAccess(1'b1), .VirtualAddress(PCF),
|
||||||
.PageTableEntryWrite(PageTableEntryF), .PageTypeWrite(PageTypeF),
|
.PageTableEntryWrite(PageTableEntryF), .PageTypeWrite(PageTypeF),
|
||||||
@ -87,7 +89,7 @@ module ifu (
|
|||||||
|
|
||||||
// branch predictor signals
|
// branch predictor signals
|
||||||
logic SelBPPredF;
|
logic SelBPPredF;
|
||||||
logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F;
|
logic [`XLEN-1:0] BPPredPCF, PCCorrectE, PCNext0F, PCNext1F, PCNext2F;
|
||||||
logic [3:0] InstrClassD, InstrClassE;
|
logic [3:0] InstrClassD, InstrClassE;
|
||||||
|
|
||||||
|
|
||||||
@ -98,10 +100,10 @@ module ifu (
|
|||||||
|
|
||||||
// jarred 2021-03-14 Add instrution cache block to remove rd2
|
// jarred 2021-03-14 Add instrution cache block to remove rd2
|
||||||
assign PCNextPF = PCNextF; // Temporary workaround until iTLB is live
|
assign PCNextPF = PCNextF; // Temporary workaround until iTLB is live
|
||||||
icache ic(
|
icache icache(
|
||||||
.*,
|
.*,
|
||||||
.UpperPCPF(PCPF[`XLEN-1:12]),
|
.UpperPCNextPF(PCNextPF[`XLEN-1:12]),
|
||||||
.LowerPCF(PCF[11:0])
|
.LowerPCNextF(PCNextPF[11:0])
|
||||||
);
|
);
|
||||||
|
|
||||||
assign PrivilegedChangePCM = RetM | TrapM;
|
assign PrivilegedChangePCM = RetM | TrapM;
|
||||||
@ -120,8 +122,18 @@ module ifu (
|
|||||||
mux2 #(`XLEN) pcmux2(.d0(PCNext1F),
|
mux2 #(`XLEN) pcmux2(.d0(PCNext1F),
|
||||||
.d1(PrivilegedNextPCM),
|
.d1(PrivilegedNextPCM),
|
||||||
.s(PrivilegedChangePCM),
|
.s(PrivilegedChangePCM),
|
||||||
|
.y(PCNext2F));
|
||||||
|
|
||||||
|
mux2 #(`XLEN) pcmux3(.d0(PCNext2F),
|
||||||
|
.d1(`RESET_VECTOR),
|
||||||
|
.s(reset_q),
|
||||||
.y(UnalignedPCNextF));
|
.y(UnalignedPCNextF));
|
||||||
|
|
||||||
|
flop #(1) resetReg (.clk(clk),
|
||||||
|
.d(reset),
|
||||||
|
.q(reset_q));
|
||||||
|
|
||||||
|
|
||||||
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
assign PCNextF = {UnalignedPCNextF[`XLEN-1:1], 1'b0}; // hart-SPEC p. 21 about 16-bit alignment
|
||||||
flopenl #(`XLEN) pcreg(clk, reset, ~StallF & ~ICacheStallF, PCNextF, `RESET_VECTOR, PCF);
|
flopenl #(`XLEN) pcreg(clk, reset, ~StallF & ~ICacheStallF, PCNextF, `RESET_VECTOR, PCF);
|
||||||
|
|
||||||
|
@ -447,7 +447,7 @@ module testbench();
|
|||||||
|
|
||||||
// Track names of instructions
|
// Track names of instructions
|
||||||
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
|
instrTrackerTB it(clk, reset, dut.hart.ieu.dp.FlushE,
|
||||||
dut.hart.ifu.ic.controller.AlignedInstrRawF,
|
dut.hart.ifu.icache.controller.FinalInstrRawF,
|
||||||
dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
|
dut.hart.ifu.InstrD, dut.hart.ifu.InstrE,
|
||||||
dut.hart.ifu.InstrM, dut.hart.ifu.InstrW,
|
dut.hart.ifu.InstrM, dut.hart.ifu.InstrW,
|
||||||
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
InstrFName, InstrDName, InstrEName, InstrMName, InstrWName);
|
||||||
|
Loading…
Reference in New Issue
Block a user