Merge branch 'main' of github.com:davidharrishmc/riscv-wally into main

This commit is contained in:
Ross Thompson 2022-02-17 17:50:28 -06:00
commit f97caf37db
74 changed files with 5719 additions and 1704 deletions

View File

@ -126,3 +126,4 @@
`define TESTSBP 0 `define TESTSBP 0
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 1

View File

@ -132,3 +132,4 @@
`define TESTSBP 1 `define TESTSBP 1
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 1

View File

@ -130,3 +130,4 @@
`define TESTSBP 0 `define TESTSBP 0
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 0

View File

@ -128,3 +128,4 @@
`define TESTSBP 0 `define TESTSBP 0
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 0

View File

@ -128,3 +128,4 @@
`define TESTSBP 0 `define TESTSBP 0
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 0

View File

@ -131,3 +131,4 @@
`define TESTSBP 1 `define TESTSBP 1
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 0

View File

@ -131,3 +131,4 @@
`define TESTSBP 0 `define TESTSBP 0
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 0

View File

@ -131,3 +131,4 @@
`define TESTSBP 0 `define TESTSBP 0
`define REPLAY 0 `define REPLAY 0
`define HPTW_WRITES_SUPPORTED 0

View File

@ -22,7 +22,7 @@ def main():
break break
checkpoint = checkpointList[0] checkpoint = checkpointList[0]
logFile = logDir+"checkpoint"+str(checkpoint)+".log" logFile = logDir+"checkpoint"+str(checkpoint)+".log"
runCommand="{\nvsim -c <<!\ndo wally-buildroot-batch.do 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile runCommand="{\nvsim -c <<!\ndo wally-pipelined-batch.do buildroot buildroot 0 "+str(checkpoint+1)+" "+str(checkpoint)+"\n!\n} | tee "+logFile
print(runCommand) print(runCommand)
os.system(runCommand) os.system(runCommand)
try: try:

View File

@ -174,7 +174,7 @@ add wave -noupdate -group muldiv /testbench/dut/wallypipelinedsoc/core/mdu/MulDi
add wave -noupdate -group muldiv /testbench/dut/wallypipelinedsoc/core/mdu/DivBusyE add wave -noupdate -group muldiv /testbench/dut/wallypipelinedsoc/core/mdu/DivBusyE
add wave -noupdate -group icache -color Gold /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/CurrState add wave -noupdate -group icache -color Gold /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/CurrState
add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/BasePAdrF add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/BasePAdrF
add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/WayHit add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/HitWay
add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/genblk1/cachereplacementpolicy/BlockReplacementBits add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/genblk1/cachereplacementpolicy/BlockReplacementBits
add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/genblk1/cachereplacementpolicy/EncVicWay add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/genblk1/cachereplacementpolicy/EncVicWay
add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/VictimWay add wave -noupdate -group icache /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/VictimWay
@ -251,7 +251,7 @@ add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipel
add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/InstrReadF add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/InstrReadF
add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/InstrAckF add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/InstrAckF
add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/ICacheMemWriteEnable add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/controller/ICacheMemWriteEnable
add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/ICacheMemWriteData add wave -noupdate -group icache -expand -group memory /testbench/dut/wallypipelinedsoc/core/ifu/bus/icache/ICacheBusWriteData
add wave -noupdate -group AHB -color Gold /testbench/dut/wallypipelinedsoc/core/ebu/BusState add wave -noupdate -group AHB -color Gold /testbench/dut/wallypipelinedsoc/core/ebu/BusState
add wave -noupdate -group AHB /testbench/dut/wallypipelinedsoc/core/ebu/NextBusState add wave -noupdate -group AHB /testbench/dut/wallypipelinedsoc/core/ebu/NextBusState
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/wallypipelinedsoc/core/ebu/AtomicMaskedM add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/wallypipelinedsoc/core/ebu/AtomicMaskedM
@ -285,7 +285,7 @@ add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipeline
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/SRAMBlockWayWriteEnableM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/SRAMBlockWayWriteEnableM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/SelAdrM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/SelAdrM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataBlockM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataBlockM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/DCacheMemWriteData add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/DCacheBusWriteData
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FlushWay add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FlushWay
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/VictimDirty add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/VictimDirty
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/VDWriteEnableWay add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/VDWriteEnableWay
@ -349,23 +349,23 @@ add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ClearValid add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ClearValid
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/SetDirty add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/SetDirty
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ClearDirty add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ClearDirty
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[0]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[1]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[2]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheWays[3]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/WayHit add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/HitWay
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataBlockWayMaskedM add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataBlockWayMaskedM
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataWordM add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataWordM
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataWordMuxM add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataWordMuxM
@ -385,7 +385,7 @@ add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /t
add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataM add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/ReadDataM
add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/DCacheStallM add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/DCacheStallM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FlushAdrFlag add wave -noupdate -group lsu -expand -group dcache /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FlushAdrFlag
add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/WayHit add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/HitWay
add wave -noupdate -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheHit add wave -noupdate -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/CacheHit
add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FetchCount add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FetchCount
add wave -noupdate -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FetchCountFlag add wave -noupdate -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/wallypipelinedsoc/core/lsu.bus.dcache/FetchCountFlag

View File

@ -183,209 +183,214 @@ add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/ITLB
add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/bus/icache/icache/SelAdr add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/bus/icache/icache/SelAdr
add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/PCNextF add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/PCNextF
add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/PCPF add wave -noupdate -group ifu -expand -group icache /testbench/dut/core/ifu/PCPF
add wave -noupdate -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/icache/WayHit add wave -noupdate -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/bus/icache/icache/HitWay
add wave -noupdate -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/ICacheStallF add wave -noupdate -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/ICacheStallF
add wave -noupdate -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/FinalInstrRawF add wave -noupdate -group ifu -expand -group icache -expand -group {fsm out and control} /testbench/dut/core/ifu/FinalInstrRawF
add wave -noupdate -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/CacheBusAdr add wave -noupdate -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/CacheBusAdr
add wave -noupdate -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/cachefsm/CacheBusAck add wave -noupdate -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/cachefsm/CacheBusAck
add wave -noupdate -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/CacheMemWriteData add wave -noupdate -group ifu -expand -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/icache/CacheBusWriteData
add wave -noupdate -group ifu -expand -group itlb /testbench/dut/core/ifu/immu/immu/TLBWrite add wave -noupdate -group ifu -expand -group itlb /testbench/dut/core/ifu/immu/immu/TLBWrite
add wave -noupdate -group ifu -expand -group itlb /testbench/dut/core/ifu/ITLBMissF add wave -noupdate -group ifu -expand -group itlb /testbench/dut/core/ifu/ITLBMissF
add wave -noupdate -group ifu -expand -group itlb /testbench/dut/core/ifu/immu/immu/PhysicalAddress add wave -noupdate -group ifu -expand -group itlb /testbench/dut/core/ifu/immu/immu/PhysicalAddress
add wave -noupdate -group lsu /testbench/dut/core/lsu/IEUAdrM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/IEUAdrM
add wave -noupdate -group lsu /testbench/dut/core/lsu/LSUPAdrM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUPAdrM
add wave -noupdate -group lsu -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/interlockfsm/InterlockCurrState add wave -noupdate -expand -group lsu -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/interlockfsm/InterlockCurrState
add wave -noupdate -group lsu /testbench/dut/core/lsu/SelHPTW add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/SelHPTW
add wave -noupdate -group lsu /testbench/dut/core/lsu/InterlockStall add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/InterlockStall
add wave -noupdate -group lsu /testbench/dut/core/lsu/LSUStallM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/LSUStallM
add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataWordMuxM
add wave -noupdate -group lsu /testbench/dut/core/lsu/ReadDataM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/ReadDataM
add wave -noupdate -group lsu /testbench/dut/core/lsu/WriteDataM add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/WriteDataM
add wave -noupdate -group lsu /testbench/dut/core/lsu/bus/busdp/SelUncachedAdr add wave -noupdate -expand -group lsu /testbench/dut/core/lsu/bus/busdp/SelUncachedAdr
add wave -noupdate -group lsu -group bus -color Gold /testbench/dut/core/lsu/bus/busdp/busfsm/BusCurrState add wave -noupdate -expand -group lsu -group bus -color Gold /testbench/dut/core/lsu/bus/busdp/busfsm/BusCurrState
add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/BusStall add wave -noupdate -expand -group lsu -group bus /testbench/dut/core/lsu/BusStall
add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusRead add wave -noupdate -expand -group lsu -group bus /testbench/dut/core/lsu/LSUBusRead
add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusWrite add wave -noupdate -expand -group lsu -group bus /testbench/dut/core/lsu/LSUBusWrite
add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusAdr add wave -noupdate -expand -group lsu -group bus /testbench/dut/core/lsu/LSUBusAdr
add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusAck add wave -noupdate -expand -group lsu -group bus /testbench/dut/core/lsu/LSUBusAck
add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusHRDATA add wave -noupdate -expand -group lsu -group bus /testbench/dut/core/lsu/LSUBusHRDATA
add wave -noupdate -group lsu -group bus /testbench/dut/core/lsu/LSUBusHWDATA add wave -noupdate -expand -group lsu -group bus /testbench/dut/core/lsu/LSUBusHWDATA
add wave -noupdate -group lsu -group dcache -color Gold /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/CurrState add wave -noupdate -expand -group lsu -expand -group dcache -color Gold /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/CurrState
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/WayHit add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/HitWay
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/FSMLineWriteEn add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SetValid
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/FSMWordWriteEn add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SelAdr add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/SelAdr
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/SelReplayCPURequest add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/SelReplayCPURequest
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/IEUAdrE add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/IEUAdrE
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/IEUAdrM add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/IEUAdrM
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/RAdr add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/RAdr
add wave -noupdate -group lsu -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/RAdrD} add wave -noupdate -expand -group lsu -expand -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/RAdrD}
add wave -noupdate -group lsu -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ClearDirtyWay} add wave -noupdate -expand -group lsu -expand -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ClearDirtyWay}
add wave -noupdate -group lsu -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty} add wave -noupdate -expand -group lsu -expand -group dcache {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty}
add wave -noupdate -group lsu -group dcache -expand -group flush -radix unsigned /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdr add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush -radix unsigned /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdr
add wave -noupdate -group lsu -group dcache -expand -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay
add wave -noupdate -group lsu -group dcache -expand -group flush /testbench/dut/core/lsu/bus/dcache/dcache/VictimDirtyWay add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu/bus/dcache/dcache/VictimDirtyWay
add wave -noupdate -group lsu -group dcache -expand -group flush /testbench/dut/core/lsu/bus/dcache/dcache/VictimTag add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu/bus/dcache/dcache/VictimTag
add wave -noupdate -group lsu -group dcache -expand -group flush /testbench/dut/core/lsu/CacheableM add wave -noupdate -expand -group lsu -expand -group dcache -expand -group flush /testbench/dut/core/lsu/CacheableM
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheMemWriteData add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusWriteData
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SelectedWriteWordEn} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SelectedWriteWordEn}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetValidWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetValidWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetDirtyWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/SetDirtyWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/CacheTagMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/CacheTagMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/DirtyBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/DirtyBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ValidBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ValidBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SelectedWriteWordEn} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SelectedWriteWordEn}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetValidWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetValidWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetDirtyWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/SetDirtyWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/CacheTagMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/CacheTagMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/DirtyBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/DirtyBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ValidBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ValidBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SelectedWriteWordEn} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SelectedWriteWordEn}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetValidWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetValidWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetDirtyWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/SetDirtyWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/CacheTagMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/CacheTagMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/DirtyBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/DirtyBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ValidBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ValidBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/CacheDataMem/StoredData[69]}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SelectedWriteWordEn} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetValidWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SelectedWriteWordEn}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetDirtyWay} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetValidWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/CacheTagMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/SetDirtyWay}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/DirtyBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -label TAG {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/CacheTagMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ValidBits} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/DirtyBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ValidBits}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/WriteEnable} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/StoredData} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/SetValid add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/SetValid
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid
add wave -noupdate -group lsu -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/RAdr add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/WayHit} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/RAdr
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Valid} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/HitWay}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Valid}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ReadTag} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/Dirty}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/WayHit} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[0]/ReadTag}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/Valid} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/HitWay}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/Dirty} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/Valid}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ReadTag} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/Dirty}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/WayHit} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way1 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[1]/ReadTag}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/Valid} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/HitWay}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/Dirty} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/Valid}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ReadTag} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/Dirty}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/WayHit} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[2]/ReadTag}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/Valid} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/HitWay}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/Dirty} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/Valid}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ReadTag} add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/Dirty}
add wave -noupdate -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/WayHit add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -group way3 {/testbench/dut/core/lsu/bus/dcache/dcache/CacheWays[3]/ReadTag}
add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimTag add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu/bus/dcache/dcache/HitWay
add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimWay add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimTag
add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimDirtyWay add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimWay
add wave -noupdate -group lsu -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimDirty add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimDirtyWay
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/RW add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/core/lsu/bus/dcache/dcache/VictimDirty
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/NextAdr add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/RW
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/PAdr add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/NextAdr
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/Atomic add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/PAdr
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/FlushCache add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/Atomic
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheStall add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/FlushCache
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/ReadDataWordM add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheStall
add wave -noupdate -group lsu -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/FinalWriteDataM add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/ReadDataWordM
add wave -noupdate -group lsu -group dcache -group status /testbench/dut/core/lsu/bus/dcache/dcache/WayHit add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/core/lsu/FinalWriteDataM
add wave -noupdate -group lsu -group dcache -group status -color {Medium Orchid} /testbench/dut/core/lsu/bus/dcache/dcache/CacheHit add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/core/lsu/bus/dcache/dcache/HitWay
add wave -noupdate -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheFetchLine add wave -noupdate -expand -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/core/lsu/bus/dcache/dcache/CacheHit
add wave -noupdate -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheWriteLine add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheFetchLine
add wave -noupdate -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheMemWriteData add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheWriteLine
add wave -noupdate -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusAck add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusWriteData
add wave -noupdate -group lsu -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu/bus/dcache/dcache/CacheBusAck
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/VAdr add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/FlushWay
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/EffectivePrivilegeMode add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/VAdr
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/EffectivePrivilegeMode
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/HitPageType add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/Translate add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/HitPageType
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/DisableTranslation add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/Translate
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBMiss add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/DisableTranslation
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBHit add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBMiss
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/PhysicalAddress add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/TLBHit
add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/TLBPageFault add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/PhysicalAddress
add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/LoadAccessFaultM add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_D
add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/core/lsu/dmmu/dmmu/StoreAmoAccessFaultM add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_A
add wave -noupdate -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBPAdr add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_U
add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_X
add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PageTypeWriteVal add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_W
add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBWrite add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_R
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/ImproperPrivilege add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_V
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_D add wave -noupdate -expand -group lsu -group dtlb -expand -group Status -color Maroon /testbench/dut/core/lsu/dmmu/dmmu/DAPageFault
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_A add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/ImproperPrivilege
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_U add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/UpperBitsUnequalPageFault
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_X add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/Misaligned
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_W add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/dtlb/InvalidRead
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_R add wave -noupdate -expand -group lsu -group dtlb -expand -group Status /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/dtlb/InvalidWrite
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/PTE_V add wave -noupdate -expand -group lsu -group dtlb -group faults /testbench/dut/core/lsu/dmmu/dmmu/TLBPageFault
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/UpperBitsUnequalPageFault add wave -noupdate -expand -group lsu -group dtlb -group faults /testbench/dut/core/lsu/dmmu/dmmu/LoadAccessFaultM
add wave -noupdate -group lsu -group dtlb -group {dtlb stats} /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/Misaligned add wave -noupdate -expand -group lsu -group dtlb -group faults /testbench/dut/core/lsu/dmmu/dmmu/StoreAmoAccessFaultM
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PhysicalAddress add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBPAdr
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/SelRegions add wave -noupdate -expand -group lsu -group dtlb -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PTE
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Cacheable add wave -noupdate -expand -group lsu -group dtlb -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/PageTypeWriteVal
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Idempotent add wave -noupdate -expand -group lsu -group dtlb -group write /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/TLBWrite
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/AtomicAllowed add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PhysicalAddress
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PMAAccessFault add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/SelRegions
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAInstrAccessFaultF add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Cacheable
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMALoadAccessFaultM add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/Idempotent
add wave -noupdate -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAStoreAmoAccessFaultM add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/AtomicAllowed
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/PhysicalAddress add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/pmachecker/PMAAccessFault
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/ReadAccessM add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAInstrAccessFaultF
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/WriteAccessM add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMALoadAccessFaultM
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/PMPADDR_ARRAY_REGW add wave -noupdate -expand -group lsu -group pma /testbench/dut/core/lsu/dmmu/dmmu/PMAStoreAmoAccessFaultM
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/PMPCFG_ARRAY_REGW add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/PhysicalAddress
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/ReadAccessM
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/WriteAccessM
add wave -noupdate -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/PMPADDR_ARRAY_REGW
add wave -noupdate -group lsu -group ptwalker -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/WalkerState add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/pmpchecker/PMPCFG_ARRAY_REGW
add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PCF add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPInstrAccessFaultF
add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWReadPTE add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPLoadAccessFaultM
add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWAdr add wave -noupdate -expand -group lsu -group pmp /testbench/dut/core/lsu/dmmu/dmmu/PMPStoreAmoAccessFaultM
add wave -noupdate -group lsu -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PTE add wave -noupdate -expand -group lsu -expand -group ptwalker -color Gold /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/WalkerState
add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBMissF add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PCF
add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBMissM add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWReadPTE
add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBWriteF add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/HPTWAdr
add wave -noupdate -group lsu -group ptwalker -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBWriteM add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/PTE
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissOrDAFaultF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBMissM
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/ITLBWriteF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DTLBWriteM
add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState
add wave -noupdate -group AHB /testbench/dut/core/ebu/NextBusState add wave -noupdate -group AHB /testbench/dut/core/ebu/NextBusState
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/core/ebu/AtomicMaskedM add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/core/ebu/AtomicMaskedM
@ -520,9 +525,15 @@ add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/CurrState
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/TakeSpillF add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/TakeSpillF
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillF add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/SpillF
add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/IFUCacheBusStallF add wave -noupdate /testbench/dut/core/ifu/SpillSupport/spillsupport/IFUCacheBusStallF
add wave -noupdate -color Yellow /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/DAPageFault
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/OtherPageFault
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/ITLBMissF
add wave -noupdate /testbench/dut/core/lsu/VIRTMEM_SUPPORTED/lsuvirtmem/hptw/Accessed
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/WriteAccess
add wave -noupdate /testbench/dut/core/lsu/dmmu/dmmu/tlb/tlb/tlbcontrol/TLBPageFault
TreeUpdate [SetDefaultTree] TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 7} {14114436 ns} 0} {{Cursor 5} {49445 ns} 1} {{Cursor 3} {235459 ns} 1} {{Cursor 4} {217231 ns} 1} WaveRestoreCursors {{Cursor 7} {62997113 ns} 1} {{Cursor 5} {65676608 ns} 1} {{Cursor 3} {65665947 ns} 1} {{Cursor 4} {65431218 ns} 0}
quietly wave cursor active 1 quietly wave cursor active 4
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 314 configure wave -valuecolwidth 314
configure wave -justifyvalue left configure wave -justifyvalue left
@ -537,4 +548,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update update
WaveRestoreZoom {14114376 ns} {14114586 ns} WaveRestoreZoom {65430777 ns} {65431305 ns}

View File

@ -36,7 +36,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation # start and run simulation
vopt work_${1}_${2}.testbench -work work_${1}_${2} -G INSTR_LIMIT=$3 -G INSTR_WAVEON=$4 -G CHECKPOINT=$5 -o testbenchopt vopt work_${1}_${2}.testbench -work work_${1}_${2} -G INSTR_LIMIT=$3 -G INSTR_WAVEON=$4 -G CHECKPOINT=$5 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070 vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084
run -all run -all
run -all run -all

View File

@ -35,7 +35,7 @@ if {$2 eq "buildroot" || $2 eq "buildroot-checkpoint"} {
vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583 vlog -lint -work work_${1}_${2} +incdir+../config/$1 +incdir+../config/shared ../testbench/testbench-linux.sv ../testbench/common/*.sv ../src/*/*.sv ../src/*/*/*.sv -suppress 2583
# start and run simulation # start and run simulation
vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G INSTR_LIMIT=$3 -G INSTR_WAVEON=$4 -G CHECKPOINT=$5 -o testbenchopt vopt +acc work_${1}_${2}.testbench -work work_${1}_${2} -G INSTR_LIMIT=$3 -G INSTR_WAVEON=$4 -G CHECKPOINT=$5 -o testbenchopt
vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070 vsim -lib work_${1}_${2} testbenchopt -suppress 8852,12070,3084
#-- Run the Simulation #-- Run the Simulation
add log -recursive /* add log -recursive /*

View File

@ -176,7 +176,7 @@ add wave -noupdate -group muldiv /testbench/dut/core/mdu/MulDivResultW
add wave -noupdate -group muldiv /testbench/dut/core/mdu/DivBusyE add wave -noupdate -group muldiv /testbench/dut/core/mdu/DivBusyE
add wave -noupdate -group icache -color Gold /testbench/dut/core/ifu/bus/icache/controller/CurrState add wave -noupdate -group icache -color Gold /testbench/dut/core/ifu/bus/icache/controller/CurrState
add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/BasePAdrF add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/BasePAdrF
add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/WayHit add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/HitWay
add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/VictimWay add wave -noupdate -group icache /testbench/dut/core/ifu/bus/icache/VictimWay
add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/bus/icache/CacheWays[0]/WriteEnable} add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/bus/icache/CacheWays[0]/WriteEnable}
add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/bus/icache/CacheWays[0]/SetValid} add wave -noupdate -group icache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/core/ifu/bus/icache/CacheWays[0]/SetValid}
@ -211,7 +211,7 @@ add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/b
add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/InstrReadF add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/InstrReadF
add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/InstrAckF add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/InstrAckF
add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/ICacheMemWriteEnable add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/controller/ICacheMemWriteEnable
add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/ICacheMemWriteData add wave -noupdate -group icache -expand -group memory /testbench/dut/core/ifu/bus/icache/ICacheBusWriteData
add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState add wave -noupdate -group AHB -color Gold /testbench/dut/core/ebu/BusState
add wave -noupdate -group AHB /testbench/dut/core/ebu/NextBusState add wave -noupdate -group AHB /testbench/dut/core/ebu/NextBusState
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/core/ebu/AtomicMaskedM add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/core/ebu/AtomicMaskedM
@ -244,7 +244,7 @@ add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/SRAMBlockWayWriteEnableM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/SRAMBlockWayWriteEnableM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/SelAdrM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/SelAdrM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/ReadDataBlockM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/ReadDataBlockM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/DCacheMemWriteData add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/DCacheBusWriteData
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/WriteEnable} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/WriteEnable}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/SetValid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/SetValid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/SetDirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/SetDirty}
@ -304,23 +304,23 @@ add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/core/lsu.bus.dcache/ClearValid add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/core/lsu.bus.dcache/ClearValid
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/core/lsu.bus.dcache/SetDirty add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/core/lsu.bus.dcache/SetDirty
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/core/lsu.bus.dcache/ClearDirty add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/core/lsu.bus.dcache/ClearDirty
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/core/lsu.bus.dcache/CacheWays[0]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/core/lsu.bus.dcache/CacheWays[1]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/core/lsu.bus.dcache/CacheWays[2]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/WayHit} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/HitWay}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/Valid} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/Valid}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/Dirty} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/Dirty}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/ReadTag} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/core/lsu.bus.dcache/CacheWays[3]/ReadTag}
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/WayHit add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/HitWay
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/ReadDataBlockWayMaskedM add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/ReadDataBlockWayMaskedM
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/ReadDataWordM add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/ReadDataWordM
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/ReadDataWordMuxM add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/core/lsu.bus.dcache/ReadDataWordMuxM
@ -340,7 +340,7 @@ add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench
add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/core/lsu.bus.dcache/ReadDataM add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/core/lsu.bus.dcache/ReadDataM
add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/core/lsu.bus.dcache/DCacheStallM add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/core/lsu.bus.dcache/DCacheStallM
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/FlushAdrFlag add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu.bus.dcache/FlushAdrFlag
add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/core/lsu.bus.dcache/WayHit add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/core/lsu.bus.dcache/HitWay
add wave -noupdate -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/core/lsu.bus.dcache/CacheHit add wave -noupdate -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/core/lsu.bus.dcache/CacheHit
add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/core/lsu.bus.dcache/FetchCount add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/core/lsu.bus.dcache/FetchCount
add wave -noupdate -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu.bus.dcache/FetchCountFlag add wave -noupdate -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/core/lsu.bus.dcache/FetchCountFlag

File diff suppressed because one or more lines are too long

View File

@ -56,7 +56,7 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) (
output logic CacheWriteLine, output logic CacheWriteLine,
input logic CacheBusAck, input logic CacheBusAck,
output logic [`PA_BITS-1:0] CacheBusAdr, output logic [`PA_BITS-1:0] CacheBusAdr,
input logic [LINELEN-1:0] CacheMemWriteData, input logic [LINELEN-1:0] CacheBusWriteData,
output logic [LINELEN-1:0] ReadDataLine); output logic [LINELEN-1:0] ReadDataLine);
// Cache parameters // Cache parameters
@ -68,16 +68,16 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) (
localparam WORDSPERLINE = LINELEN/`XLEN; localparam WORDSPERLINE = LINELEN/`XLEN;
localparam FlushAdrThreshold = NUMLINES - 1; localparam FlushAdrThreshold = NUMLINES - 1;
logic [1:0] SelAdr; logic SelAdr;
logic [SETLEN-1:0] RAdr; logic [SETLEN-1:0] RAdr;
logic [LINELEN-1:0] CacheWriteData; logic [LINELEN-1:0] CacheWriteData;
logic SetValid, ClearValid; logic ClearValid;
logic SetDirty, ClearDirty; logic ClearDirty;
logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0]; logic [LINELEN-1:0] ReadDataLineWay [NUMWAYS-1:0];
logic [NUMWAYS-1:0] WayHit; logic [NUMWAYS-1:0] HitWay, HitWaySaved, HitWayFinal;
logic CacheHit; logic CacheHit;
logic FSMWordWriteEn; logic SetDirty;
logic FSMLineWriteEn; logic SetValid;
logic [NUMWAYS-1:0] VictimWay; logic [NUMWAYS-1:0] VictimWay;
logic [NUMWAYS-1:0] VictimDirtyWay; logic [NUMWAYS-1:0] VictimDirtyWay;
logic VictimDirty; logic VictimDirty;
@ -97,10 +97,8 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) (
logic LRUWriteEn; logic LRUWriteEn;
logic SelFlush; logic SelFlush;
logic ResetOrFlushAdr, ResetOrFlushWay; logic ResetOrFlushAdr, ResetOrFlushWay;
logic [NUMWAYS-1:0] WayHitSaved, WayHitFinal;
logic [NUMWAYS-1:0] SelectedWay; logic [NUMWAYS-1:0] SelectedWay;
logic [NUMWAYS-1:0] SetValidWay, ClearValidWay, SetDirtyWay, ClearDirtyWay; logic [NUMWAYS-1:0] SetValidWay, ClearValidWay, SetDirtyWay, ClearDirtyWay;
logic [NUMWAYS-1:0] WriteWordWayEn, WriteLineWayEn;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Read Path // Read Path
@ -110,19 +108,19 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) (
// and FlushAdr when handling D$ flushes // and FlushAdr when handling D$ flushes
mux3 #(SETLEN) AdrSelMux( mux3 #(SETLEN) AdrSelMux(
.d0(NextAdr[SETTOP-1:OFFSETLEN]), .d1(PAdr[SETTOP-1:OFFSETLEN]), .d2(FlushAdr), .d0(NextAdr[SETTOP-1:OFFSETLEN]), .d1(PAdr[SETTOP-1:OFFSETLEN]), .d2(FlushAdr),
.s(SelAdr), .y(RAdr)); .s({SelFlush, SelAdr}), .y(RAdr));
// Array of cache ways, along with victim, hit, dirty, and read merging logic // Array of cache ways, along with victim, hit, dirty, and read merging logic
cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN) CacheWays[NUMWAYS-1:0]( cacheway #(NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN) CacheWays[NUMWAYS-1:0](
.clk, .reset, .RAdr, .PAdr, .WriteWordWayEn, .WriteLineWayEn, .CacheWriteData, .clk, .reset, .RAdr, .PAdr, .CacheWriteData,
.SetValidWay, .ClearValidWay, .SetDirtyWay, .ClearDirtyWay, .SelEvict, .VictimWay, .SetValidWay, .ClearValidWay, .SetDirtyWay, .ClearDirtyWay, .SelEvict, .VictimWay,
.FlushWay, .SelFlush, .ReadDataLineWay, .WayHit, .VictimDirtyWay, .VictimTagWay, .FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .VictimDirtyWay, .VictimTagWay,
.InvalidateAll(InvalidateCacheM)); .Invalidate(InvalidateCacheM));
if(NUMWAYS > 1) begin:vict if(NUMWAYS > 1) begin:vict
cachereplacementpolicy #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cachereplacementpolicy( cachereplacementpolicy #(NUMWAYS, SETLEN, OFFSETLEN, NUMLINES) cachereplacementpolicy(
.clk, .reset, .WayHit(WayHitFinal), .VictimWay, .PAdr, .RAdr, .LRUWriteEn); .clk, .reset, .HitWay(HitWayFinal), .VictimWay, .RAdr, .LRUWriteEn);
end else assign VictimWay = 1'b1; // one hot. end else assign VictimWay = 1'b1; // one hot.
assign CacheHit = | WayHit; assign CacheHit = | HitWay;
assign VictimDirty = | VictimDirtyWay; assign VictimDirty = | VictimDirtyWay;
// ReadDataLineWay is a 2d array of cache line len by number of ways. // ReadDataLineWay is a 2d array of cache line len by number of ways.
// Need to OR together each way in a bitwise manner. // Need to OR together each way in a bitwise manner.
@ -130,69 +128,59 @@ module cache #(parameter LINELEN, NUMLINES, NUMWAYS, DCACHE = 1) (
or_rows #(NUMWAYS, LINELEN) ReadDataAOMux(.a(ReadDataLineWay), .y(ReadDataLine)); or_rows #(NUMWAYS, LINELEN) ReadDataAOMux(.a(ReadDataLineWay), .y(ReadDataLine));
or_rows #(NUMWAYS, TAGLEN) VictimTagAOMux(.a(VictimTagWay), .y(VictimTag)); or_rows #(NUMWAYS, TAGLEN) VictimTagAOMux(.a(VictimTagWay), .y(VictimTag));
// Because of the sram clocked read when the ieu is stalled the read data maybe lost. // Because of the sram clocked read when the ieu is stalled the read data maybe lost.
// There are two ways to resolve. 1. We can replay the read of the sram or we can save // There are two ways to resolve. 1. We can replay the read of the sram or we can save
// the data. Replay is eaiser but creates a longer critical path. // the data. Replay is eaiser but creates a longer critical path.
// save/restore only wayhit and readdata. // save/restore only wayhit and readdata.
if(!`REPLAY) begin if(!`REPLAY) begin
flopenr #(NUMWAYS) wayhitsavereg(clk, save, reset, WayHit, WayHitSaved); flopenr #(NUMWAYS) wayhitsavereg(clk, save, reset, HitWay, HitWaySaved);
mux2 #(NUMWAYS) saverestoremux(WayHit, WayHitSaved, restore, WayHitFinal); mux2 #(NUMWAYS) saverestoremux(HitWay, HitWaySaved, restore, HitWayFinal);
end else assign WayHitFinal = WayHit; end else assign HitWayFinal = HitWay;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Path: Write data and address. Muxes between writes from bus and writes from CPU. // Write Path: Write data and address. Muxes between writes from bus and writes from CPU.
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
mux2 #(LINELEN) WriteDataMux(.d0({WORDSPERLINE{FinalWriteData}}), mux2 #(LINELEN) WriteDataMux(.d0({WORDSPERLINE{FinalWriteData}}),
.d1(CacheMemWriteData), .s(FSMLineWriteEn), .y(CacheWriteData)); .d1(CacheBusWriteData), .s(SetValid), .y(CacheWriteData));
mux3 #(`PA_BITS) CacheBusAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}), mux3 #(`PA_BITS) CacheBusAdrMux(.d0({PAdr[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d1({VictimTag, PAdr[SETTOP-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}), .d1({VictimTag, PAdr[SETTOP-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}), .d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}),
.s({SelFlush, SelEvict}), .s({SelFlush, SelEvict}), .y(CacheBusAdr));
.y(CacheBusAdr));
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Flush address and way generation during flush // Flush address and way generation during flush
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
assign ResetOrFlushAdr = reset | FlushAdrCntRst; assign ResetOrFlushAdr = reset | FlushAdrCntRst;
flopenr #(SETLEN) FlushAdrReg(.clk, .reset(ResetOrFlushAdr), flopenr #(SETLEN) FlushAdrReg(.clk, .reset(ResetOrFlushAdr), .en(FlushAdrCntEn),
.en(FlushAdrCntEn), .d(FlushAdrP1), .q(FlushAdr)); .d(FlushAdrP1), .q(FlushAdr));
assign FlushAdrP1 = FlushAdr + 1'b1; assign FlushAdrP1 = FlushAdr + 1'b1;
assign FlushAdrFlag = (FlushAdr == FlushAdrThreshold[SETLEN-1:0]); assign FlushAdrFlag = (FlushAdr == FlushAdrThreshold[SETLEN-1:0]);
assign ResetOrFlushWay = reset | FlushWayCntRst; assign ResetOrFlushWay = reset | FlushWayCntRst;
flopenl #(NUMWAYS) FlushWayReg(.clk, .load(ResetOrFlushWay), flopenl #(NUMWAYS) FlushWayReg(.clk, .load(ResetOrFlushWay), .en(FlushWayCntEn),
.en(FlushWayCntEn), .val({{NUMWAYS-1{1'b0}}, 1'b1}), .val({{NUMWAYS-1{1'b0}}, 1'b1}), .d(NextFlushWay), .q(FlushWay));
.d(NextFlushWay), .q(FlushWay));
assign FlushWayFlag = FlushWay[NUMWAYS-1]; assign FlushWayFlag = FlushWay[NUMWAYS-1];
assign NextFlushWay = {FlushWay[NUMWAYS-2:0], FlushWay[NUMWAYS-1]}; assign NextFlushWay = {FlushWay[NUMWAYS-2:0], FlushWay[NUMWAYS-1]};
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Path: Write Enables // Write Path: Write Enables
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
mux3 #(NUMWAYS) selectwaymux(HitWayFinal, VictimWay, FlushWay,
// *** change to structural {SelFlush, SetValid}, SelectedWay);
mux3 #(NUMWAYS) selectwaymux(WayHitFinal, VictimWay, FlushWay, {SelFlush, FSMLineWriteEn}, SelectedWay);
assign SetValidWay = SetValid ? SelectedWay : '0; assign SetValidWay = SetValid ? SelectedWay : '0;
assign ClearValidWay = ClearValid ? SelectedWay : '0; assign ClearValidWay = ClearValid ? SelectedWay : '0;
assign SetDirtyWay = SetDirty ? SelectedWay : '0; assign SetDirtyWay = SetDirty ? SelectedWay : '0;
assign ClearDirtyWay = ClearDirty ? SelectedWay : '0; assign ClearDirtyWay = ClearDirty ? SelectedWay : '0;
assign WriteWordWayEn = FSMWordWriteEn ? SelectedWay : '0;
assign WriteLineWayEn = FSMLineWriteEn ? SelectedWay : '0;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Cache FSM // Cache FSM
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
cachefsm cachefsm(.clk, .reset, .CacheFetchLine, .CacheWriteLine, .CacheBusAck, cachefsm cachefsm(.clk, .reset, .CacheFetchLine, .CacheWriteLine, .CacheBusAck,
.RW, .Atomic, .CPUBusy, .IgnoreRequestTLB, .IgnoreRequestTrapM, .RW, .Atomic, .CPUBusy, .IgnoreRequestTLB, .IgnoreRequestTrapM,
.CacheHit, .VictimDirty, .CacheStall, .CacheCommitted, .CacheHit, .VictimDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdr, .SetValid, .CacheMiss, .CacheAccess, .SelAdr,
.ClearValid, .SetDirty, .ClearDirty, .FSMWordWriteEn, .ClearValid, .ClearDirty, .SetDirty,
.FSMLineWriteEn, .SelEvict, .SelFlush, .SetValid, .SelEvict, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst, .FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst,
.FlushWayCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .FlushWayCntRst, .FlushAdrFlag, .FlushWayFlag, .FlushCache,
.save, .restore, .save, .restore,

View File

@ -32,78 +32,74 @@
module cachefsm module cachefsm
(input logic clk, (input logic clk,
input logic reset, input logic reset,
// inputs from IEU // inputs from IEU
input logic [1:0] RW, input logic [1:0] RW,
input logic [1:0] Atomic, input logic [1:0] Atomic,
input logic FlushCache, input logic FlushCache,
// hazard inputs // hazard inputs
input logic CPUBusy, input logic CPUBusy,
// interlock fsm // interlock fsm
input logic IgnoreRequestTLB, input logic IgnoreRequestTLB,
input logic IgnoreRequestTrapM, input logic IgnoreRequestTrapM,
// Bus inputs // Bus inputs
input logic CacheBusAck, input logic CacheBusAck,
// dcache internals // dcache internals
input logic CacheHit, input logic CacheHit,
input logic VictimDirty, input logic VictimDirty,
input logic FlushAdrFlag, input logic FlushAdrFlag,
input logic FlushWayFlag, input logic FlushWayFlag,
// hazard outputs // hazard outputs
output logic CacheStall, output logic CacheStall,
// counter outputs // counter outputs
output logic CacheMiss, output logic CacheMiss,
output logic CacheAccess, output logic CacheAccess,
// Bus outputs // Bus outputs
output logic CacheCommitted, output logic CacheCommitted,
output logic CacheWriteLine, output logic CacheWriteLine,
output logic CacheFetchLine, output logic CacheFetchLine,
// dcache internals // dcache internals
output logic [1:0] SelAdr, output logic SelAdr,
output logic SetValid, output logic ClearValid,
output logic ClearValid, output logic ClearDirty,
output logic SetDirty, output logic SetDirty,
output logic ClearDirty, output logic SetValid,
output logic FSMWordWriteEn, output logic SelEvict,
output logic FSMLineWriteEn, output logic LRUWriteEn,
output logic SelEvict, output logic SelFlush,
output logic LRUWriteEn, output logic FlushAdrCntEn,
output logic SelFlush, output logic FlushWayCntEn,
output logic FlushAdrCntEn, output logic FlushAdrCntRst,
output logic FlushWayCntEn, output logic FlushWayCntRst,
output logic FlushAdrCntRst, output logic save,
output logic FlushWayCntRst, output logic restore);
output logic save,
output logic restore);
logic [1:0] PreSelAdr;
logic resetDelay; logic resetDelay;
logic Read, Write, AMO; logic AMO;
logic DoAMO, DoRead, DoWrite, DoFlush; logic DoAMO, DoRead, DoWrite, DoFlush;
logic DoAMOHit, DoReadHit, DoWriteHit; logic DoAnyUpdateHit, DoAnyHit;
logic DoAMOMiss, DoReadMiss, DoWriteMiss; logic DoAnyMiss;
logic FlushFlag; logic FlushFlag, FlushWayAndNotAdrFlag;
typedef enum logic [3:0] {STATE_READY, typedef enum logic [3:0] {STATE_READY, // hit states
// miss states
STATE_MISS_FETCH_WDV, STATE_MISS_FETCH_WDV,
STATE_MISS_FETCH_DONE, STATE_MISS_FETCH_DONE,
STATE_MISS_EVICT_DIRTY, STATE_MISS_EVICT_DIRTY,
STATE_MISS_WRITE_CACHE_LINE, STATE_MISS_WRITE_CACHE_LINE,
STATE_MISS_READ_WORD, STATE_MISS_READ_WORD,
STATE_MISS_READ_WORD_DELAY, STATE_MISS_READ_WORD_DELAY,
STATE_MISS_WRITE_WORD, STATE_MISS_WRITE_WORD,
// cpu stalled replay/restore state
STATE_CPU_BUSY, STATE_CPU_BUSY,
STATE_CPU_BUSY_FINISH_AMO, // flush cache
STATE_FLUSH,
STATE_FLUSH, STATE_FLUSH_CHECK,
STATE_FLUSH_CHECK, STATE_FLUSH_INCR,
STATE_FLUSH_INCR, STATE_FLUSH_WRITE_BACK,
STATE_FLUSH_WRITE_BACK, STATE_FLUSH_CLEAR_DIRTY} statetype;
STATE_FLUSH_CLEAR_DIRTY} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState; (* mark_debug = "true" *) statetype CurrState, NextState;
logic IgnoreRequest; logic IgnoreRequest;
@ -112,21 +108,15 @@ module cachefsm
// if the command is used in the READY state then the cache needs to be able to supress // if the command is used in the READY state then the cache needs to be able to supress
// using both IgnoreRequestTLB and IgnoreRequestTrapM. Otherwise we can just use IgnoreRequestTLB. // using both IgnoreRequestTLB and IgnoreRequestTrapM. Otherwise we can just use IgnoreRequestTLB.
// need to re organize all of these. Low priority though.
assign DoFlush = FlushCache & ~IgnoreRequestTrapM; // do NOT suppress flush on DTLBMissM. Does not depend on address translation. assign DoFlush = FlushCache & ~IgnoreRequestTrapM; // do NOT suppress flush on DTLBMissM. Does not depend on address translation.
assign AMO = Atomic[1] & (&RW); assign AMO = Atomic[1] & (&RW);
assign DoAMO = AMO & ~IgnoreRequest; assign DoAMO = AMO & ~IgnoreRequest;
assign DoAMOHit = DoAMO & CacheHit; assign DoRead = RW[1] & ~IgnoreRequest;
assign DoAMOMiss = DoAMO & ~CacheHit; assign DoWrite = RW[0] & ~IgnoreRequest;
assign Read = RW[1];
assign DoRead = Read & ~IgnoreRequest;
assign DoReadHit = DoRead & CacheHit;
assign DoReadMiss = DoRead & ~CacheHit;
assign Write = RW[0];
assign DoWrite = Write & ~IgnoreRequest;
assign DoWriteHit = DoWrite & CacheHit;
assign DoWriteMiss = DoWrite & ~CacheHit;
assign DoAnyMiss = (DoAMO | DoRead | DoWrite) & ~CacheHit;
assign DoAnyUpdateHit = (DoAMO | DoWrite) & CacheHit;
assign DoAnyHit = DoAnyUpdateHit | (DoRead & CacheHit);
assign FlushFlag = FlushAdrFlag & FlushWayFlag; assign FlushFlag = FlushAdrFlag & FlushWayFlag;
// outputs for the performance counters. // outputs for the performance counters.
@ -137,7 +127,6 @@ module cachefsm
// PCNextF will no longer be pointing to the correct address. // PCNextF will no longer be pointing to the correct address.
// But PCF will be the reset vector. // But PCF will be the reset vector.
flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay)); flop #(1) resetDelayReg(.clk, .d(reset), .q(resetDelay));
assign SelAdr = resetDelay ? 2'b01 : PreSelAdr;
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset) CurrState <= #1 STATE_READY; if (reset) CurrState <= #1 STATE_READY;
@ -146,54 +135,49 @@ module cachefsm
always_comb begin always_comb begin
NextState = STATE_READY; NextState = STATE_READY;
case (CurrState) case (CurrState)
STATE_READY: if(IgnoreRequest) NextState = STATE_READY; STATE_READY: if(IgnoreRequest) NextState = STATE_READY;
else if(DoFlush) NextState = STATE_FLUSH; else if(DoFlush) NextState = STATE_FLUSH;
else if(DoAMOHit & CPUBusy) NextState = STATE_CPU_BUSY_FINISH_AMO; // change else if(DoAnyHit & CPUBusy) NextState = STATE_CPU_BUSY;
else if(DoReadHit & CPUBusy) NextState = STATE_CPU_BUSY; else if(DoAnyMiss) NextState = STATE_MISS_FETCH_WDV; // change
else if(DoWriteHit & CPUBusy) NextState = STATE_CPU_BUSY; else NextState = STATE_READY;
else if(DoReadMiss | DoWriteMiss | DoAMOMiss) NextState = STATE_MISS_FETCH_WDV; // change STATE_MISS_FETCH_WDV: if(CacheBusAck) NextState = STATE_MISS_FETCH_DONE;
else NextState = STATE_READY; else NextState = STATE_MISS_FETCH_WDV;
STATE_MISS_FETCH_WDV: if (CacheBusAck) NextState = STATE_MISS_FETCH_DONE; STATE_MISS_FETCH_DONE: if(VictimDirty) NextState = STATE_MISS_EVICT_DIRTY;
else NextState = STATE_MISS_FETCH_WDV; else NextState = STATE_MISS_WRITE_CACHE_LINE;
STATE_MISS_FETCH_DONE: if(VictimDirty) NextState = STATE_MISS_EVICT_DIRTY; STATE_MISS_WRITE_CACHE_LINE: NextState = STATE_MISS_READ_WORD;
else NextState = STATE_MISS_WRITE_CACHE_LINE; STATE_MISS_READ_WORD: if(RW[0] & ~AMO) NextState = STATE_MISS_WRITE_WORD;
STATE_MISS_WRITE_CACHE_LINE: NextState = STATE_MISS_READ_WORD; else NextState = STATE_MISS_READ_WORD_DELAY;
STATE_MISS_READ_WORD: if (Write & ~AMO) NextState = STATE_MISS_WRITE_WORD; STATE_MISS_READ_WORD_DELAY: if(CPUBusy) NextState = STATE_CPU_BUSY;
else NextState = STATE_MISS_READ_WORD_DELAY; else NextState = STATE_READY;
STATE_MISS_READ_WORD_DELAY: if(AMO & CPUBusy) NextState = STATE_CPU_BUSY_FINISH_AMO; STATE_MISS_WRITE_WORD: if(CPUBusy) NextState = STATE_CPU_BUSY;
else if(CPUBusy) NextState = STATE_CPU_BUSY; else NextState = STATE_READY;
else NextState = STATE_READY; STATE_MISS_EVICT_DIRTY: if(CacheBusAck) NextState = STATE_MISS_WRITE_CACHE_LINE;
STATE_MISS_WRITE_WORD: if(CPUBusy) NextState = STATE_CPU_BUSY; else NextState = STATE_MISS_EVICT_DIRTY;
else NextState = STATE_READY; STATE_CPU_BUSY: if(CPUBusy) NextState = STATE_CPU_BUSY;
STATE_MISS_EVICT_DIRTY: if(CacheBusAck) NextState = STATE_MISS_WRITE_CACHE_LINE; else NextState = STATE_READY;
else NextState = STATE_MISS_EVICT_DIRTY; STATE_FLUSH: NextState = STATE_FLUSH_CHECK;
STATE_CPU_BUSY: if(CPUBusy) NextState = STATE_CPU_BUSY; STATE_FLUSH_CHECK: if(VictimDirty) NextState = STATE_FLUSH_WRITE_BACK;
else NextState = STATE_READY; else if(FlushFlag) NextState = STATE_READY;
STATE_CPU_BUSY_FINISH_AMO: if(CPUBusy) NextState = STATE_CPU_BUSY_FINISH_AMO; else if(FlushWayFlag) NextState = STATE_FLUSH_INCR;
else NextState = STATE_READY; else NextState = STATE_FLUSH_CHECK;
STATE_FLUSH: NextState = STATE_FLUSH_CHECK; STATE_FLUSH_INCR: NextState = STATE_FLUSH_CHECK;
STATE_FLUSH_CHECK: if(VictimDirty) NextState = STATE_FLUSH_WRITE_BACK; STATE_FLUSH_WRITE_BACK: if(CacheBusAck) NextState = STATE_FLUSH_CLEAR_DIRTY;
else if (FlushFlag) NextState = STATE_READY; else NextState = STATE_FLUSH_WRITE_BACK;
else if(FlushWayFlag) NextState = STATE_FLUSH_INCR; STATE_FLUSH_CLEAR_DIRTY: if(FlushFlag) NextState = STATE_READY;
else NextState = STATE_FLUSH_CHECK; else if(FlushWayFlag) NextState = STATE_FLUSH_INCR;
STATE_FLUSH_INCR: NextState = STATE_FLUSH_CHECK; else NextState = STATE_FLUSH_CHECK;
STATE_FLUSH_WRITE_BACK: if(CacheBusAck) NextState = STATE_FLUSH_CLEAR_DIRTY; default: NextState = STATE_READY;
else NextState = STATE_FLUSH_WRITE_BACK;
STATE_FLUSH_CLEAR_DIRTY: if(FlushAdrFlag & FlushWayFlag) NextState = STATE_READY;
else if (FlushWayFlag) NextState = STATE_FLUSH_INCR;
else NextState = STATE_FLUSH_CHECK;
default: NextState = STATE_READY;
endcase endcase
end end
// com back to CPU // com back to CPU
assign CacheCommitted = CurrState != STATE_READY; assign CacheCommitted = CurrState != STATE_READY;
assign CacheStall = (CurrState == STATE_READY & (DoFlush | DoAMOMiss | DoReadMiss | DoWriteMiss)) | assign CacheStall = (CurrState == STATE_READY & (DoFlush | DoAnyMiss)) |
(CurrState == STATE_MISS_FETCH_WDV) | (CurrState == STATE_MISS_FETCH_WDV) |
(CurrState == STATE_MISS_FETCH_DONE) | (CurrState == STATE_MISS_FETCH_DONE) |
(CurrState == STATE_MISS_EVICT_DIRTY) |
(CurrState == STATE_MISS_WRITE_CACHE_LINE) | (CurrState == STATE_MISS_WRITE_CACHE_LINE) |
(CurrState == STATE_MISS_READ_WORD) | (CurrState == STATE_MISS_READ_WORD) |
(CurrState == STATE_MISS_EVICT_DIRTY) |
(CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH) |
(CurrState == STATE_FLUSH_CHECK & ~(FlushFlag)) | (CurrState == STATE_FLUSH_CHECK & ~(FlushFlag)) |
(CurrState == STATE_FLUSH_INCR) | (CurrState == STATE_FLUSH_INCR) |
@ -201,18 +185,13 @@ module cachefsm
(CurrState == STATE_FLUSH_CLEAR_DIRTY & ~(FlushFlag)); (CurrState == STATE_FLUSH_CLEAR_DIRTY & ~(FlushFlag));
// write enables internal to cache // write enables internal to cache
assign SetValid = CurrState == STATE_MISS_WRITE_CACHE_LINE; assign SetValid = CurrState == STATE_MISS_WRITE_CACHE_LINE;
assign ClearValid = '0; assign SetDirty = (CurrState == STATE_READY & DoAnyUpdateHit) |
assign SetDirty = (CurrState == STATE_READY & DoAMO) |
(CurrState == STATE_READY & DoWrite) |
(CurrState == STATE_MISS_READ_WORD_DELAY & AMO) |
(CurrState == STATE_MISS_WRITE_WORD);
assign ClearDirty = (CurrState == STATE_MISS_WRITE_CACHE_LINE) |
(CurrState == STATE_FLUSH_CLEAR_DIRTY);
assign FSMWordWriteEn = (CurrState == STATE_READY & (DoAMOHit | DoWriteHit)) |
(CurrState == STATE_MISS_READ_WORD_DELAY & AMO) | (CurrState == STATE_MISS_READ_WORD_DELAY & AMO) |
(CurrState == STATE_MISS_WRITE_WORD); (CurrState == STATE_MISS_WRITE_WORD);
assign FSMLineWriteEn = (CurrState == STATE_MISS_WRITE_CACHE_LINE); assign ClearValid = '0;
assign LRUWriteEn = (CurrState == STATE_READY & (DoAMOHit | DoReadHit | DoWriteHit)) | assign ClearDirty = (CurrState == STATE_MISS_WRITE_CACHE_LINE) |
(CurrState == STATE_FLUSH_CLEAR_DIRTY);
assign LRUWriteEn = (CurrState == STATE_READY & DoAnyHit) |
(CurrState == STATE_MISS_READ_WORD_DELAY) | (CurrState == STATE_MISS_READ_WORD_DELAY) |
(CurrState == STATE_MISS_WRITE_WORD); (CurrState == STATE_MISS_WRITE_WORD);
// Flush and eviction controls // Flush and eviction controls
@ -220,42 +199,38 @@ module cachefsm
assign SelFlush = (CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH_CHECK) | assign SelFlush = (CurrState == STATE_FLUSH) | (CurrState == STATE_FLUSH_CHECK) |
(CurrState == STATE_FLUSH_INCR) | (CurrState == STATE_FLUSH_WRITE_BACK) | (CurrState == STATE_FLUSH_INCR) | (CurrState == STATE_FLUSH_WRITE_BACK) |
(CurrState == STATE_FLUSH_CLEAR_DIRTY); (CurrState == STATE_FLUSH_CLEAR_DIRTY);
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_CHECK & ~VictimDirty & FlushWayFlag & ~FlushAdrFlag) | assign FlushWayAndNotAdrFlag = FlushWayFlag & ~FlushAdrFlag;
(CurrState == STATE_FLUSH_CLEAR_DIRTY & FlushWayFlag & ~FlushAdrFlag); assign FlushAdrCntEn = (CurrState == STATE_FLUSH_CHECK & ~VictimDirty & FlushWayAndNotAdrFlag) |
(CurrState == STATE_FLUSH_CLEAR_DIRTY & FlushWayAndNotAdrFlag);
assign FlushWayCntEn = (CurrState == STATE_FLUSH_CHECK & ~VictimDirty & ~(FlushFlag)) | assign FlushWayCntEn = (CurrState == STATE_FLUSH_CHECK & ~VictimDirty & ~(FlushFlag)) |
(CurrState == STATE_FLUSH_CLEAR_DIRTY & ~(FlushFlag)); (CurrState == STATE_FLUSH_CLEAR_DIRTY & ~FlushFlag);
assign FlushAdrCntRst = (CurrState == STATE_READY); assign FlushAdrCntRst = (CurrState == STATE_READY);
assign FlushWayCntRst = (CurrState == STATE_READY) | (CurrState == STATE_FLUSH_INCR); assign FlushWayCntRst = (CurrState == STATE_READY) | (CurrState == STATE_FLUSH_INCR);
// Bus interface controls // Bus interface controls
assign CacheFetchLine = (CurrState == STATE_READY & (DoAMOMiss | DoWriteMiss | DoReadMiss)); assign CacheFetchLine = (CurrState == STATE_READY & DoAnyMiss);
assign CacheWriteLine = (CurrState == STATE_MISS_FETCH_DONE & VictimDirty) | assign CacheWriteLine = (CurrState == STATE_MISS_FETCH_DONE & VictimDirty) |
(CurrState == STATE_FLUSH_CHECK & VictimDirty); (CurrState == STATE_FLUSH_CHECK & VictimDirty);
// handle cpu stall. // handle cpu stall.
assign restore = ((CurrState == STATE_CPU_BUSY) | (CurrState == STATE_CPU_BUSY_FINISH_AMO)) & ~`REPLAY; assign restore = ((CurrState == STATE_CPU_BUSY)) & ~`REPLAY;
assign save = ((CurrState == STATE_READY & (DoAMOHit | DoReadHit | DoWriteHit) & CPUBusy) | assign save = ((CurrState == STATE_READY & DoAnyHit & CPUBusy) |
(CurrState == STATE_MISS_READ_WORD_DELAY & (AMO | Read) & CPUBusy) | (CurrState == STATE_MISS_READ_WORD_DELAY & (AMO | RW[1]) & CPUBusy) |
(CurrState == STATE_MISS_WRITE_WORD & DoWrite & CPUBusy)) & ~`REPLAY; (CurrState == STATE_MISS_WRITE_WORD & DoWrite & CPUBusy)) & ~`REPLAY;
// **** can this be simplified? // **** can this be simplified?
assign PreSelAdr = ((CurrState == STATE_READY & IgnoreRequestTLB) | // Ignore Request is needed on TLB miss. assign SelAdr = (CurrState == STATE_READY & IgnoreRequestTLB) | // Ignore Request is needed on TLB miss.
(CurrState == STATE_READY & (AMO & CacheHit)) | // use the raw requests as we don't want IgnoreRequestTrapM in the critical path
(CurrState == STATE_READY & (Read & CacheHit) & (CPUBusy & `REPLAY)) | (CurrState == STATE_READY & ((AMO | RW[0]) & CacheHit)) | // changes if store delay hazard removed
(CurrState == STATE_READY & (Write & CacheHit)) | (CurrState == STATE_READY & (RW[1] & CacheHit) & (CPUBusy & `REPLAY)) |
(CurrState == STATE_MISS_FETCH_WDV) |
(CurrState == STATE_MISS_FETCH_DONE) | (CurrState == STATE_MISS_FETCH_WDV) |
(CurrState == STATE_MISS_WRITE_CACHE_LINE) | (CurrState == STATE_MISS_FETCH_DONE) |
(CurrState == STATE_MISS_READ_WORD) | (CurrState == STATE_MISS_EVICT_DIRTY) |
(CurrState == STATE_MISS_READ_WORD_DELAY & (AMO | (CPUBusy & `REPLAY))) | (CurrState == STATE_MISS_WRITE_CACHE_LINE) |
(CurrState == STATE_MISS_WRITE_WORD) | (CurrState == STATE_MISS_READ_WORD) |
(CurrState == STATE_MISS_EVICT_DIRTY) | (CurrState == STATE_MISS_READ_WORD_DELAY & (AMO | (CPUBusy & `REPLAY))) |
(CurrState == STATE_CPU_BUSY & (CPUBusy & `REPLAY)) | (CurrState == STATE_MISS_WRITE_WORD) |
(CurrState == STATE_CPU_BUSY_FINISH_AMO)) ? 2'b01 :
((CurrState == STATE_FLUSH) | (CurrState == STATE_CPU_BUSY & (CPUBusy & `REPLAY)) |
(CurrState == STATE_FLUSH_CHECK & ~(VictimDirty & FlushFlag)) | resetDelay;
(CurrState == STATE_FLUSH_INCR) |
(CurrState == STATE_FLUSH_WRITE_BACK) |
(CurrState == STATE_FLUSH_CLEAR_DIRTY & ~(FlushFlag))) ? 2'b10 :
2'b00;
endmodule // cachefsm endmodule // cachefsm

View File

@ -32,9 +32,8 @@
module cachereplacementpolicy module cachereplacementpolicy
#(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128)( #(parameter NUMWAYS = 4, SETLEN = 9, OFFSETLEN = 5, NUMLINES = 128)(
input logic clk, reset, input logic clk, reset,
input logic [NUMWAYS-1:0] WayHit, input logic [NUMWAYS-1:0] HitWay,
output logic [NUMWAYS-1:0] VictimWay, output logic [NUMWAYS-1:0] VictimWay,
input logic [`PA_BITS-1:0] PAdr,
input logic [SETLEN-1:0] RAdr, input logic [SETLEN-1:0] RAdr,
input logic LRUWriteEn); input logic LRUWriteEn);
@ -53,7 +52,6 @@ module cachereplacementpolicy
// Pipeline Delay Registers // Pipeline Delay Registers
flopr #(SETLEN) RAdrDelayReg(clk, reset, RAdr, RAdrD); flopr #(SETLEN) RAdrDelayReg(clk, reset, RAdr, RAdrD);
flopr #(SETLEN) PAdrDelayReg(clk, reset, PAdr[SETLEN+OFFSETLEN-1:OFFSETLEN], PAdrD);
flopr #(1) LRUWriteEnDelayReg(clk, reset, LRUWriteEn, LRUWriteEnD); flopr #(1) LRUWriteEnDelayReg(clk, reset, LRUWriteEn, LRUWriteEnD);
flopr #(NUMWAYS-1) NewReplacementDelayReg(clk, reset, NewReplacement, NewReplacementD); flopr #(NUMWAYS-1) NewReplacementDelayReg(clk, reset, NewReplacement, NewReplacementD);
@ -61,13 +59,13 @@ module cachereplacementpolicy
// Needs to be resettable for simulation, but could omit reset for synthesis *** // Needs to be resettable for simulation, but could omit reset for synthesis ***
always_ff @(posedge clk) always_ff @(posedge clk)
if (reset) for (int set = 0; set < NUMLINES; set++) ReplacementBits[set] = '0; if (reset) for (int set = 0; set < NUMLINES; set++) ReplacementBits[set] = '0;
else if (LRUWriteEnD) ReplacementBits[PAdrD[SETLEN+OFFSETLEN-1:OFFSETLEN]] = NewReplacementD; else if (LRUWriteEnD) ReplacementBits[RAdrD] = NewReplacementD;
assign LineReplacementBits = ReplacementBits[RAdrD]; assign LineReplacementBits = ReplacementBits[RAdrD];
genvar index; genvar index;
if(NUMWAYS == 2) begin : PseudoLRU if(NUMWAYS == 2) begin : PseudoLRU
assign LRUEn[0] = 1'b0; assign LRUEn[0] = 1'b0;
assign NewReplacement[0] = WayHit[1]; assign NewReplacement[0] = HitWay[1];
assign VictimWay[1] = ~LineReplacementBits[0]; assign VictimWay[1] = ~LineReplacementBits[0];
assign VictimWay[0] = LineReplacementBits[0]; assign VictimWay[0] = LineReplacementBits[0];
end else if (NUMWAYS == 4) begin : PseudoLRU end else if (NUMWAYS == 4) begin : PseudoLRU
@ -84,15 +82,15 @@ module cachereplacementpolicy
assign VictimWay[2] = LineReplacementBits[2] & ~LineReplacementBits[1]; assign VictimWay[2] = LineReplacementBits[2] & ~LineReplacementBits[1];
assign VictimWay[3] = LineReplacementBits[2] & LineReplacementBits[1]; assign VictimWay[3] = LineReplacementBits[2] & LineReplacementBits[1];
// New LRU bits which are updated is function only of the WayHit. // New LRU bits which are updated is function only of the HitWay.
// However the not updated bits come from the old LRU. // However the not updated bits come from the old LRU.
assign LRUEn[2] = |WayHit; assign LRUEn[2] = |HitWay;
assign LRUEn[1] = WayHit[3] | WayHit[2]; assign LRUEn[1] = HitWay[3] | HitWay[2];
assign LRUEn[0] = WayHit[1] | WayHit[0]; assign LRUEn[0] = HitWay[1] | HitWay[0];
assign LRUMask[2] = WayHit[1] | WayHit[0]; assign LRUMask[2] = HitWay[1] | HitWay[0];
assign LRUMask[1] = WayHit[2]; assign LRUMask[1] = HitWay[2];
assign LRUMask[0] = WayHit[0]; assign LRUMask[0] = HitWay[0];
mux2 #(1) LRUMuxes[NUMWAYS-2:0](LineReplacementBits, LRUMask, LRUEn, NewReplacement); mux2 #(1) LRUMuxes[NUMWAYS-2:0](LineReplacementBits, LRUMask, LRUEn, NewReplacement);
end end
@ -101,21 +99,21 @@ module cachereplacementpolicy
// selects // selects
assign LRUEn[6] = 1'b1; assign LRUEn[6] = 1'b1;
assign LRUEn[5] = WayHit[7] | WayHit[6] | WayHit[5] | WayHit[4]; assign LRUEn[5] = HitWay[7] | HitWay[6] | HitWay[5] | HitWay[4];
assign LRUEn[4] = WayHit[7] | WayHit[6]; assign LRUEn[4] = HitWay[7] | HitWay[6];
assign LRUEn[3] = WayHit[5] | WayHit[4]; assign LRUEn[3] = HitWay[5] | HitWay[4];
assign LRUEn[2] = WayHit[3] | WayHit[2] | WayHit[1] | WayHit[0]; assign LRUEn[2] = HitWay[3] | HitWay[2] | HitWay[1] | HitWay[0];
assign LRUEn[1] = WayHit[3] | WayHit[2]; assign LRUEn[1] = HitWay[3] | HitWay[2];
assign LRUEn[0] = WayHit[1] | WayHit[0]; assign LRUEn[0] = HitWay[1] | HitWay[0];
// mask // mask
assign LRUMask[6] = WayHit[7] | WayHit[6] | WayHit[5] | WayHit[4]; assign LRUMask[6] = HitWay[7] | HitWay[6] | HitWay[5] | HitWay[4];
assign LRUMask[5] = WayHit[7] | WayHit[6]; assign LRUMask[5] = HitWay[7] | HitWay[6];
assign LRUMask[4] = WayHit[7]; assign LRUMask[4] = HitWay[7];
assign LRUMask[3] = WayHit[5]; assign LRUMask[3] = HitWay[5];
assign LRUMask[2] = WayHit[3] | WayHit[2]; assign LRUMask[2] = HitWay[3] | HitWay[2];
assign LRUMask[1] = WayHit[2]; assign LRUMask[1] = HitWay[2];
assign LRUMask[0] = WayHit[0]; assign LRUMask[0] = HitWay[0];
for(index = 0; index < NUMWAYS-1; index++) for(index = 0; index < NUMWAYS-1; index++)
assign NewReplacement[index] = LRUEn[index] ? LRUMask[index] : LineReplacementBits[index]; assign NewReplacement[index] = LRUEn[index] ? LRUMask[index] : LineReplacementBits[index];

View File

@ -37,21 +37,20 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
input logic [$clog2(NUMLINES)-1:0] RAdr, input logic [$clog2(NUMLINES)-1:0] RAdr,
input logic [`PA_BITS-1:0] PAdr, input logic [`PA_BITS-1:0] PAdr,
input logic WriteWordWayEn,
input logic WriteLineWayEn,
input logic [LINELEN-1:0] CacheWriteData, input logic [LINELEN-1:0] CacheWriteData,
input logic SetValidWay, input logic SetValidWay,
input logic ClearValidWay, input logic ClearValidWay,
input logic SetDirtyWay, input logic SetDirtyWay,
input logic ClearDirtyWay, input logic ClearDirtyWay,
input logic SelEvict, input logic SelEvict,
input logic VictimWay,
input logic InvalidateAll,
input logic SelFlush, input logic SelFlush,
input logic VictimWay,
input logic FlushWay, input logic FlushWay,
input logic Invalidate,
output logic [LINELEN-1:0] ReadDataLineWay, output logic [LINELEN-1:0] ReadDataLineWay,
output logic WayHit, output logic HitWay,
output logic VictimDirtyWay, output logic VictimDirtyWay,
output logic [TAGLEN-1:0] VictimTagWay); output logic [TAGLEN-1:0] VictimTagWay);
@ -59,28 +58,25 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
localparam LOGWPL = $clog2(WORDSPERLINE); localparam LOGWPL = $clog2(WORDSPERLINE);
localparam LOGXLENBYTES = $clog2(`XLEN/8); localparam LOGXLENBYTES = $clog2(`XLEN/8);
logic [NUMLINES-1:0] ValidBits; logic [NUMLINES-1:0] ValidBits;
logic [NUMLINES-1:0] DirtyBits; logic [NUMLINES-1:0] DirtyBits;
logic [LINELEN-1:0] ReadDataLine; logic [LINELEN-1:0] ReadDataLine;
logic [TAGLEN-1:0] ReadTag; logic [TAGLEN-1:0] ReadTag;
logic Valid; logic Valid;
logic Dirty; logic Dirty;
logic SelData; logic SelData;
logic SelTag; logic SelTag;
logic [$clog2(NUMLINES)-1:0] RAdrD;
logic [$clog2(NUMLINES)-1:0] RAdrD; logic [2**LOGWPL-1:0] MemPAdrDecoded;
logic [LINELEN/`XLEN-1:0] SelectedWriteWordEn;
logic [2**LOGWPL-1:0] MemPAdrDecoded;
logic [LINELEN/`XLEN-1:0] SelectedWriteWordEn;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Enable demux // Write Enable demux
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
onehotdecoder #(LOGWPL) adrdec( onehotdecoder #(LOGWPL) adrdec(
.bin(PAdr[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]), .decoded(MemPAdrDecoded)); .bin(PAdr[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]), .decoded(MemPAdrDecoded));
// If writing the whole line set all write enables to 1, else only set the correct word. // If writing the whole line set all write enables to 1, else only set the correct word.
assign SelectedWriteWordEn = WriteLineWayEn ? '1 : WriteWordWayEn ? MemPAdrDecoded : '0; // OR-AND assign SelectedWriteWordEn = SetValidWay ? '1 : SetDirtyWay ? MemPAdrDecoded : '0; // OR-AND
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Tag Array // Tag Array
@ -88,12 +84,13 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk, sram1p1rw #(.DEPTH(NUMLINES), .WIDTH(TAGLEN)) CacheTagMem(.clk,
.Adr(RAdr), .ReadData(ReadTag), .Adr(RAdr), .ReadData(ReadTag),
.CacheWriteData(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .WriteEnable(WriteLineWayEn)); .CacheWriteData(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]), .WriteEnable(SetValidWay));
// AND portion of distributed tag multiplexer // AND portion of distributed tag multiplexer
assign SelTag = SelFlush ? FlushWay : VictimWay; mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelTag);
assign VictimTagWay = SelTag ? ReadTag : '0; // AND part of AOMux assign VictimTagWay = SelTag ? ReadTag : '0; // AND part of AOMux
assign VictimDirtyWay = SelTag & Dirty & Valid; assign VictimDirtyWay = SelTag & Dirty & Valid;
assign HitWay = Valid & (ReadTag == PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]);
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Data Array // Data Array
@ -109,8 +106,7 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
end end
// AND portion of distributed read multiplexers // AND portion of distributed read multiplexers
assign WayHit = Valid & (ReadTag == PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]); mux3 #(1) selecteddatamux(HitWay, VictimWay, FlushWay, {SelFlush, SelEvict}, SelData);
mux3 #(1) selecteddatamux(WayHit, VictimWay, FlushWay, {SelFlush, SelEvict}, SelData);
assign ReadDataLineWay = SelData ? ReadDataLine : '0; // AND part of AO mux. assign ReadDataLineWay = SelData ? ReadDataLine : '0; // AND part of AO mux.
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -118,9 +114,9 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
always_ff @(posedge clk) begin // Valid bit array, always_ff @(posedge clk) begin // Valid bit array,
if (reset | InvalidateAll) ValidBits <= #1 '0; if (reset | Invalidate) ValidBits <= #1 '0;
else if (SetValidWay) ValidBits[RAdr] <= #1 1'b1; else if (SetValidWay) ValidBits[RAdr] <= #1 1'b1;
else if (ClearValidWay) ValidBits[RAdr] <= #1 1'b0; else if (ClearValidWay) ValidBits[RAdr] <= #1 1'b0;
end end
flop #($clog2(NUMLINES)) RAdrDelayReg(clk, RAdr, RAdrD); flop #($clog2(NUMLINES)) RAdrDelayReg(clk, RAdr, RAdrD);
assign Valid = ValidBits[RAdrD]; assign Valid = ValidBits[RAdrD];
@ -132,8 +128,8 @@ module cacheway #(parameter NUMLINES=512, parameter LINELEN = 256, TAGLEN = 26,
// Dirty bits // Dirty bits
if (DIRTY_BITS) begin:dirty if (DIRTY_BITS) begin:dirty
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset) DirtyBits <= #1 {NUMLINES{1'b0}}; if (reset) DirtyBits <= #1 {NUMLINES{1'b0}};
else if (SetDirtyWay) DirtyBits[RAdr] <= #1 1'b1; else if (SetDirtyWay) DirtyBits[RAdr] <= #1 1'b1;
else if (ClearDirtyWay) DirtyBits[RAdr] <= #1 1'b0; else if (ClearDirtyWay) DirtyBits[RAdr] <= #1 1'b0;
end end
assign Dirty = DirtyBits[RAdrD]; assign Dirty = DirtyBits[RAdrD];

View File

@ -111,7 +111,7 @@ module ahblite (
else if (IFUBusRead) NextBusState = INSTRREAD; else if (IFUBusRead) NextBusState = INSTRREAD;
else NextBusState = IDLE; else NextBusState = IDLE;
INSTRREAD: if (~HREADY) NextBusState = INSTRREAD; INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; // if (IFUBusRead still high) else NextBusState = IDLE; // if (IFUBusRead still high) *** need to wait?
default: NextBusState = IDLE; default: NextBusState = IDLE;
endcase endcase

View File

@ -156,10 +156,13 @@ module controller(
7'b1100011: ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches 7'b1100011: ControlsD = `CTRLW'b0_010_11_00_000_1_0_0_0_0_0_0_0_0_00_0; // branches
7'b1100111: ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr 7'b1100111: ControlsD = `CTRLW'b1_000_01_00_000_0_0_1_1_0_0_0_0_0_00_0; // jalr
7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal 7'b1101111: ControlsD = `CTRLW'b1_011_11_00_000_0_0_1_1_0_0_0_0_0_00_0; // jal
7'b1110011: if (Funct3D == 3'b000) 7'b1110011: if (`ZICSR_SUPPORTED) begin
if (Funct3D == 3'b000)
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules
else else
ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs ControlsD = `CTRLW'b1_000_00_00_010_0_0_0_0_0_1_0_0_0_00_0; // csrs
end else
ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction default: ControlsD = `CTRLW'b0_000_00_00_000_0_0_0_0_0_0_0_0_0_00_1; // non-implemented instruction
endcase endcase

View File

@ -49,6 +49,7 @@ module regfile (
// register 0 hardwired to 0 // register 0 hardwired to 0
// reset is intended for simulation only, not synthesis // reset is intended for simulation only, not synthesis
// can logic be adjusted to not need resettable registers?
always_ff @(negedge clk) // or posedge reset) // *** make this a preload in testbench rather than reset always_ff @(negedge clk) // or posedge reset) // *** make this a preload in testbench rather than reset
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0; if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0;

View File

@ -75,7 +75,7 @@ module ifu (
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic ITLBWriteF, ITLBFlushF, input logic ITLBWriteF, ITLBFlushF,
output logic ITLBMissF, output logic ITLBMissF, InstrDAPageFaultF,
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H // pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW[`PMP_ENTRIES-1:0],
@ -98,6 +98,7 @@ module ifu (
logic [`XLEN-1:0] PCD; logic [`XLEN-1:0] PCD;
localparam [31:0] nop = 32'h00000013; // instruction for NOP localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic [31:0] NextInstrD, NextInstrE;
logic [`XLEN-1:0] PCBPWrongInvalidate; logic [`XLEN-1:0] PCBPWrongInvalidate;
@ -155,6 +156,7 @@ module ifu (
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(), .InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(), .InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(), .LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
.DAPageFault(InstrDAPageFaultF),
.AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0), .AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -184,25 +186,30 @@ module ifu (
localparam integer LINELEN = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS : `XLEN; localparam integer LINELEN = (`IMEM == `MEM_CACHE) ? `ICACHE_LINELENINBITS : `XLEN;
localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1;
logic [LINELEN-1:0] ReadDataLine; logic [LINELEN-1:0] ReadDataLine;
logic [LINELEN-1:0] ICacheMemWriteData; logic [LINELEN-1:0] ICacheBusWriteData;
logic [`PA_BITS-1:0] ICacheBusAdr; logic [`PA_BITS-1:0] ICacheBusAdr;
logic ICacheBusAck; logic ICacheBusAck;
logic save,restore; logic save,restore;
logic [31:0] temp; logic [31:0] temp;
logic SelUncachedAdr;
busdp #(WORDSPERLINE, LINELEN, 32, LOGWPL) busdp #(WORDSPERLINE, LINELEN, LOGWPL)
busdp(.clk, .reset, busdp(.clk, .reset,
.LSUBusHRDATA(IFUBusHRDATA), .LSUBusAck(IFUBusAck), .LSUBusWrite(), .LSUBusWriteCrit(), .LSUBusHRDATA(IFUBusHRDATA), .LSUBusAck(IFUBusAck), .LSUBusWrite(), .LSUBusWriteCrit(),
.LSUBusRead(IFUBusRead), .LSUBusSize(), .LSUBusRead(IFUBusRead), .LSUBusSize(),
.LSUFunct3M(3'b010), .LSUBusAdr(IFUBusAdr), .DCacheBusAdr(ICacheBusAdr), .LSUFunct3M(3'b010), .LSUBusAdr(IFUBusAdr), .DCacheBusAdr(ICacheBusAdr),
.WordCount(), .LSUBusHWDATA(), .WordCount(),
.DCacheFetchLine(ICacheFetchLine), .DCacheFetchLine(ICacheFetchLine),
.DCacheWriteLine(1'b0), .DCacheBusAck(ICacheBusAck), .DCacheWriteLine(1'b0), .DCacheBusAck(ICacheBusAck),
.DCacheMemWriteData(ICacheMemWriteData), .LSUPAdrM(PCPF), .DCacheBusWriteData(ICacheBusWriteData), .LSUPAdrM(PCPF),
.FinalAMOWriteDataM(), .ReadDataWordM(FinalInstrRawF), .ReadDataWordMuxM(AllInstrRawF[31:0]), .FinalWriteDataM(), .SelUncachedAdr,
.IgnoreRequest(ITLBMissF), .LSURWM(2'b10), .CPUBusy, .CacheableM(CacheableF), .IgnoreRequest(ITLBMissF), .LSURWM(2'b10), .CPUBusy, .CacheableM(CacheableF),
.BusStall, .BusCommittedM()); .BusStall, .BusCommittedM());
mux2 #(32) UnCachedDataMux(.d0(FinalInstrRawF), .d1(ICacheBusWriteData[32-1:0]),
.s(SelUncachedAdr), .y(AllInstrRawF[31:0]));
if(`IMEM == `MEM_CACHE) begin : icache if(`IMEM == `MEM_CACHE) begin : icache
logic [1:0] IFURWF; logic [1:0] IFURWF;
assign IFURWF = CacheableF ? 2'b10 : 2'b00; assign IFURWF = CacheableF ? 2'b10 : 2'b00;
@ -211,7 +218,7 @@ module ifu (
.NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS), .NUMLINES(`ICACHE_WAYSIZEINBYTES*8/`ICACHE_LINELENINBITS),
.NUMWAYS(`ICACHE_NUMWAYS), .DCACHE(0)) .NUMWAYS(`ICACHE_NUMWAYS), .DCACHE(0))
icache(.clk, .reset, .CPUBusy, .IgnoreRequestTLB(ITLBMissF), .IgnoreRequestTrapM('0), icache(.clk, .reset, .CPUBusy, .IgnoreRequestTLB(ITLBMissF), .IgnoreRequestTrapM('0),
.CacheMemWriteData(ICacheMemWriteData), .CacheBusAck(ICacheBusAck), .CacheBusWriteData(ICacheBusWriteData), .CacheBusAck(ICacheBusAck),
.CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF), .CacheBusAdr(ICacheBusAdr), .CacheStall(ICacheStallF),
.CacheFetchLine(ICacheFetchLine), .CacheFetchLine(ICacheFetchLine),
.CacheWriteLine(), .ReadDataLine(ReadDataLine), .CacheWriteLine(), .ReadDataLine(ReadDataLine),
@ -308,8 +315,10 @@ module ifu (
flopenr #(`XLEN) InstrMisalignedAdrReg(clk, reset, ~StallM, PCNextF, InstrMisalignedAdrM); flopenr #(`XLEN) InstrMisalignedAdrReg(clk, reset, ~StallM, PCNextF, InstrMisalignedAdrM);
// Instruction and PC/PCLink pipeline registers // Instruction and PC/PCLink pipeline registers
flopenr #(32) InstrEReg(clk, reset, ~StallE, FlushE ? nop : InstrD, InstrE); mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD);
flopenr #(32) InstrMReg(clk, reset, ~StallM, FlushM ? nop : InstrE, InstrM); mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE);
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); flopenr #(`XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE);
flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); flopenr #(`XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD); flopenr #(`XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD);

View File

@ -34,7 +34,7 @@
`include "wally-config.vh" `include "wally-config.vh"
module busdp #(parameter WORDSPERLINE, LINELEN, WORDLEN, LOGWPL, LSU=0) module busdp #(parameter WORDSPERLINE, LINELEN, LOGWPL, LSU=0)
( (
input logic clk, reset, input logic clk, reset,
// bus interface // bus interface
@ -42,7 +42,6 @@ module busdp #(parameter WORDSPERLINE, LINELEN, WORDLEN, LOGWPL, LSU=0)
input logic LSUBusAck, input logic LSUBusAck,
output logic LSUBusWrite, output logic LSUBusWrite,
output logic LSUBusRead, output logic LSUBusRead,
output logic [`XLEN-1:0] LSUBusHWDATA,
output logic [2:0] LSUBusSize, output logic [2:0] LSUBusSize,
input logic [2:0] LSUFunct3M, input logic [2:0] LSUFunct3M,
output logic [`PA_BITS-1:0] LSUBusAdr, output logic [`PA_BITS-1:0] LSUBusAdr,
@ -52,13 +51,12 @@ module busdp #(parameter WORDSPERLINE, LINELEN, WORDLEN, LOGWPL, LSU=0)
input logic DCacheFetchLine, input logic DCacheFetchLine,
input logic DCacheWriteLine, input logic DCacheWriteLine,
output logic DCacheBusAck, output logic DCacheBusAck,
output logic [LINELEN-1:0] DCacheMemWriteData, output logic [LINELEN-1:0] DCacheBusWriteData,
output logic SelUncachedAdr,
// lsu interface // lsu interface
input logic [`PA_BITS-1:0] LSUPAdrM, input logic [`PA_BITS-1:0] LSUPAdrM,
input logic [`XLEN-1:0] FinalAMOWriteDataM, input logic [`XLEN-1:0] FinalWriteDataM,
input logic [WORDLEN-1:0] ReadDataWordM,
output logic [WORDLEN-1:0] ReadDataWordMuxM,
input logic IgnoreRequest, input logic IgnoreRequest,
input logic [1:0] LSURWM, input logic [1:0] LSURWM,
input logic CPUBusy, input logic CPUBusy,
@ -70,26 +68,17 @@ module busdp #(parameter WORDSPERLINE, LINELEN, WORDLEN, LOGWPL, LSU=0)
localparam integer WordCountThreshold = (`DMEM == `MEM_CACHE) ? WORDSPERLINE - 1 : 0; localparam integer WordCountThreshold = (`DMEM == `MEM_CACHE) ? WORDSPERLINE - 1 : 0;
logic [`XLEN-1:0] PreLSUBusHWDATA;
logic [`PA_BITS-1:0] LocalLSUBusAdr; logic [`PA_BITS-1:0] LocalLSUBusAdr;
logic SelUncachedAdr;
genvar index; genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer for (index = 0; index < WORDSPERLINE; index++) begin:fetchbuffer
flopen #(`XLEN) fb(.clk, .en(LSUBusAck & LSUBusRead & (index == WordCount)), flopen #(`XLEN) fb(.clk, .en(LSUBusAck & LSUBusRead & (index == WordCount)),
.d(LSUBusHRDATA), .q(DCacheMemWriteData[(index+1)*`XLEN-1:index*`XLEN])); .d(LSUBusHRDATA), .q(DCacheBusWriteData[(index+1)*`XLEN-1:index*`XLEN]));
end end
mux2 #(`PA_BITS) localadrmux(DCacheBusAdr, LSUPAdrM, SelUncachedAdr, LocalLSUBusAdr); mux2 #(`PA_BITS) localadrmux(DCacheBusAdr, LSUPAdrM, SelUncachedAdr, LocalLSUBusAdr);
assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr; assign LSUBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLSUBusAdr;
if(LSU == 1) mux2 #(`XLEN) lsubushwdatamux( .d0(ReadDataWordM), .d1(FinalAMOWriteDataM),
.s(SelUncachedAdr), .y(LSUBusHWDATA));
else assign LSUBusHWDATA = '0;
mux2 #(3) lsubussizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(LSUFunct3M), mux2 #(3) lsubussizemux(.d0(`XLEN == 32 ? 3'b010 : 3'b011), .d1(LSUFunct3M),
.s(SelUncachedAdr), .y(LSUBusSize)); .s(SelUncachedAdr), .y(LSUBusSize));
mux2 #(WORDLEN) UnCachedDataMux(.d0(ReadDataWordM), .d1(DCacheMemWriteData[WORDLEN-1:0]),
.s(SelUncachedAdr), .y(ReadDataWordMuxM));
busfsm #(WordCountThreshold, LOGWPL, (`DMEM == `MEM_CACHE)) // *** cleanup Icache? must fix. busfsm #(WordCountThreshold, LOGWPL, (`DMEM == `MEM_CACHE)) // *** cleanup Icache? must fix.
busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine, busfsm(.clk, .reset, .IgnoreRequest, .LSURWM, .DCacheFetchLine, .DCacheWriteLine,

View File

@ -35,9 +35,9 @@ module interlockfsm
(input logic clk, (input logic clk,
input logic reset, input logic reset,
input logic AnyCPUReqM, input logic AnyCPUReqM,
input logic ITLBMissF, input logic ITLBMissOrDAFaultF,
input logic ITLBWriteF, input logic ITLBWriteF,
input logic DTLBMissM, input logic DTLBMissOrDAFaultM,
input logic DTLBWriteM, input logic DTLBWriteM,
input logic TrapM, input logic TrapM,
input logic DCacheStallM, input logic DCacheStallM,
@ -66,10 +66,10 @@ module interlockfsm
always_comb begin always_comb begin
case(InterlockCurrState) case(InterlockCurrState)
STATE_T0_READY: if (TrapM) InterlockNextState = STATE_T0_READY; STATE_T0_READY: if (TrapM) InterlockNextState = STATE_T0_READY;
else if(~ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS; else if(~ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS;
else if(ITLBMissF & ~DTLBMissM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS; else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS;
else if(ITLBMissF & ~DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS; else if(ITLBMissOrDAFaultF & ~DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS;
else if(ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS; else if(ITLBMissOrDAFaultF & DTLBMissOrDAFaultM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS;
else InterlockNextState = STATE_T0_READY; else InterlockNextState = STATE_T0_READY;
STATE_T0_REPLAY: if(DCacheStallM) InterlockNextState = STATE_T0_REPLAY; STATE_T0_REPLAY: if(DCacheStallM) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T0_READY; else InterlockNextState = STATE_T0_READY;
@ -90,7 +90,7 @@ module interlockfsm
// this code has a problem with imperas64mmu as it reads in an invalid uninitalized instruction. InterlockStall becomes x and it propagates // this code has a problem with imperas64mmu as it reads in an invalid uninitalized instruction. InterlockStall becomes x and it propagates
// everywhere. The case statement below implements the same logic but any x on the inputs will resolve to 0. // everywhere. The case statement below implements the same logic but any x on the inputs will resolve to 0.
// Note this will cause a problem for post synthesis gate simulation. // Note this will cause a problem for post synthesis gate simulation.
assign InterlockStall = (InterlockCurrState == STATE_T0_READY & (DTLBMissM | ITLBMissF)) | assign InterlockStall = (InterlockCurrState == STATE_T0_READY & (DTLBMissOrDAFaultM | ITLBMissOrDAFaultF)) |
(InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) | (InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS); (InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
@ -99,7 +99,7 @@ module interlockfsm
always_comb begin always_comb begin
InterlockStall = 1'b0; InterlockStall = 1'b0;
case(InterlockCurrState) case(InterlockCurrState)
STATE_T0_READY: if((DTLBMissM | ITLBMissF) & ~TrapM) InterlockStall = 1'b1; STATE_T0_READY: if((DTLBMissOrDAFaultM | ITLBMissOrDAFaultF) & ~TrapM) InterlockStall = 1'b1;
STATE_T3_DTLB_MISS: InterlockStall = 1'b1; STATE_T3_DTLB_MISS: InterlockStall = 1'b1;
STATE_T4_ITLB_MISS: InterlockStall = 1'b1; STATE_T4_ITLB_MISS: InterlockStall = 1'b1;
STATE_T5_ITLB_MISS: InterlockStall = 1'b1; STATE_T5_ITLB_MISS: InterlockStall = 1'b1;
@ -112,7 +112,7 @@ module interlockfsm
assign SelReplayCPURequest = (InterlockNextState == STATE_T0_REPLAY); assign SelReplayCPURequest = (InterlockNextState == STATE_T0_REPLAY);
assign SelHPTW = (InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) | assign SelHPTW = (InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS); (InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
assign IgnoreRequestTLB = (InterlockCurrState == STATE_T0_READY & (ITLBMissF | DTLBMissM)); assign IgnoreRequestTLB = (InterlockCurrState == STATE_T0_READY & (ITLBMissOrDAFaultF | DTLBMissOrDAFaultM));
assign IgnoreRequestTrapM = (InterlockCurrState == STATE_T0_READY & (TrapM)) | assign IgnoreRequestTrapM = (InterlockCurrState == STATE_T0_READY & (TrapM)) |
((InterlockCurrState == STATE_T0_REPLAY) & (TrapM)); ((InterlockCurrState == STATE_T0_REPLAY) & (TrapM));

View File

@ -74,6 +74,7 @@ module lsu (
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic [`XLEN-1:0] PCF, input logic [`XLEN-1:0] PCF,
input logic ITLBMissF, input logic ITLBMissF,
input logic InstrDAPageFaultF,
output logic [`XLEN-1:0] PTE, output logic [`XLEN-1:0] PTE,
output logic [1:0] PageType, output logic [1:0] PageType,
output logic ITLBWriteF, output logic ITLBWriteF,
@ -101,7 +102,8 @@ module lsu (
logic IgnoreRequestTLB, IgnoreRequestTrapM; logic IgnoreRequestTLB, IgnoreRequestTrapM;
logic BusCommittedM, DCacheCommittedM; logic BusCommittedM, DCacheCommittedM;
logic LSUBusWriteCrit; logic LSUBusWriteCrit;
logic DataDAPageFaultM;
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
assign IEUAdrExtM = {2'b00, IEUAdrM}; assign IEUAdrExtM = {2'b00, IEUAdrM};
assign LSUStallM = DCacheStallM | InterlockStall | BusStall; assign LSUStallM = DCacheStallM | InterlockStall | BusStall;
@ -113,7 +115,9 @@ module lsu (
if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED if(`VIRTMEM_SUPPORTED) begin : VIRTMEM_SUPPORTED
lsuvirtmem lsuvirtmem(.clk, .reset, .StallW, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF, lsuvirtmem lsuvirtmem(.clk, .reset, .StallW, .MemRWM, .AtomicM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .TrapM, .DCacheStallM, .SATP_REGW, .PCF, .DTLBMissM, .DTLBWriteM, .InstrDAPageFaultF, .DataDAPageFaultM,
.TrapM, .DCacheStallM, .SATP_REGW, .PCF,
.STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
.ReadDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M, .IEUAdrM, .ReadDataM, .Funct3M, .LSUFunct3M, .Funct7M, .LSUFunct7M, .IEUAdrM,
.IEUAdrExtM, .PTE, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE, .IEUAdrExtM, .PTE, .PageType, .PreLSURWM, .LSUAtomicM, .IEUAdrE,
.LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW, .LSUAdrE, .PreLSUPAdrM, .CPUBusy, .InterlockStall, .SelHPTW,
@ -152,7 +156,8 @@ module lsu (
.Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(), .Cacheable(CacheableM), .Idempotent(), .AtomicAllowed(),
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAmoAccessFaultM, .InstrAccessFaultF(), .LoadAccessFaultM, .StoreAmoAccessFaultM,
.InstrPageFaultF(),.LoadPageFaultM, .StoreAmoPageFaultM, .InstrPageFaultF(),.LoadPageFaultM, .StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.DAPageFault(DataDAPageFaultM),
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), // **** change this to just use PreLSURWM .AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), // **** change this to just use PreLSURWM
.WriteAccessM(PreLSURWM[0]), .ReadAccessM(PreLSURWM[1]), .WriteAccessM(PreLSURWM[0]), .ReadAccessM(PreLSURWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -168,7 +173,7 @@ module lsu (
// Memory System // Memory System
// Either Data Cache or Data Tightly Integrated Memory or just bus interface // Either Data Cache or Data Tightly Integrated Memory or just bus interface
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM; logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM, PostSWWWriteDataM;
logic [`XLEN-1:0] ReadDataWordM; logic [`XLEN-1:0] ReadDataWordM;
logic [`XLEN-1:0] ReadDataWordMuxM; logic [`XLEN-1:0] ReadDataWordMuxM;
logic IgnoreRequest; logic IgnoreRequest;
@ -185,7 +190,7 @@ module lsu (
localparam integer LINELEN = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS : `XLEN; localparam integer LINELEN = (`DMEM == `MEM_CACHE) ? `DCACHE_LINELENINBITS : `XLEN;
localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1; localparam integer LOGWPL = (`DMEM == `MEM_CACHE) ? $clog2(WORDSPERLINE) : 1;
logic [LINELEN-1:0] ReadDataLineM; logic [LINELEN-1:0] ReadDataLineM;
logic [LINELEN-1:0] DCacheMemWriteData; logic [LINELEN-1:0] DCacheBusWriteData;
logic [`PA_BITS-1:0] DCacheBusAdr; logic [`PA_BITS-1:0] DCacheBusAdr;
logic DCacheWriteLine; logic DCacheWriteLine;
logic DCacheFetchLine; logic DCacheFetchLine;
@ -194,16 +199,21 @@ module lsu (
logic [`PA_BITS-1:0] WordOffsetAddr; logic [`PA_BITS-1:0] WordOffsetAddr;
logic SelBus; logic SelBus;
logic [LOGWPL-1:0] WordCount; logic [LOGWPL-1:0] WordCount;
logic SelUncachedAdr;
busdp #(WORDSPERLINE, LINELEN, `XLEN, LOGWPL, 1) busdp( busdp #(WORDSPERLINE, LINELEN, LOGWPL, 1) busdp(
.clk, .reset, .clk, .reset,
.LSUBusHRDATA, .LSUBusHWDATA, .LSUBusAck, .LSUBusWrite, .LSUBusRead, .LSUBusSize, .LSUBusHRDATA, .LSUBusAck, .LSUBusWrite, .LSUBusRead, .LSUBusSize,
.WordCount, .LSUBusWriteCrit, .WordCount, .LSUBusWriteCrit,
.LSUFunct3M, .LSUBusAdr, .DCacheBusAdr, .DCacheFetchLine, .LSUFunct3M, .LSUBusAdr, .DCacheBusAdr, .DCacheFetchLine,
.DCacheWriteLine, .DCacheBusAck, .DCacheMemWriteData, .LSUPAdrM, .FinalAMOWriteDataM, .DCacheWriteLine, .DCacheBusAck, .DCacheBusWriteData, .LSUPAdrM, .FinalWriteDataM,
.ReadDataWordM, .ReadDataWordMuxM, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM, .SelUncachedAdr, .IgnoreRequest, .LSURWM, .CPUBusy, .CacheableM,
.BusStall, .BusCommittedM); .BusStall, .BusCommittedM);
mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM), .d1(DCacheBusWriteData[`XLEN-1:0]),
.s(SelUncachedAdr), .y(ReadDataWordMuxM));
mux2 #(`XLEN) lsubushwdatamux( .d0(ReadDataWordM), .d1(FinalWriteDataM),
.s(SelUncachedAdr), .y(LSUBusHWDATA));
assign WordOffsetAddr = LSUBusWriteCrit ? ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) : LSUPAdrM; assign WordOffsetAddr = LSUBusWriteCrit ? ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) : LSUPAdrM;
if(`DMEM == `MEM_CACHE) begin : dcache if(`DMEM == `MEM_CACHE) begin : dcache
@ -218,7 +228,7 @@ module lsu (
.CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess), .CacheStall(DCacheStallM), .CacheMiss(DCacheMiss), .CacheAccess(DCacheAccess),
.IgnoreRequestTLB, .IgnoreRequestTrapM, .CacheCommitted(DCacheCommittedM), .IgnoreRequestTLB, .IgnoreRequestTrapM, .CacheCommitted(DCacheCommittedM),
.CacheBusAdr(DCacheBusAdr), .ReadDataLine(ReadDataLineM), .CacheBusAdr(DCacheBusAdr), .ReadDataLine(ReadDataLineM),
.CacheMemWriteData(DCacheMemWriteData), .CacheFetchLine(DCacheFetchLine), .CacheBusWriteData(DCacheBusWriteData), .CacheFetchLine(DCacheFetchLine),
.CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0)); .CacheWriteLine(DCacheWriteLine), .CacheBusAck(DCacheBusAck), .InvalidateCacheM(1'b0));
subcachelineread #(LINELEN, `XLEN, `XLEN) subcachelineread( subcachelineread #(LINELEN, `XLEN, `XLEN) subcachelineread(
@ -234,13 +244,16 @@ module lsu (
subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]), subwordread subwordread(.ReadDataWordMuxM, .LSUPAdrM(LSUPAdrM[2:0]),
.Funct3M(LSUFunct3M), .ReadDataM); .Funct3M(LSUFunct3M), .ReadDataM);
// this might only get instantiated if there is a dcache or dtim. if(`DMEM != `MEM_BUS) begin
// There is a copy in the ebu. *** is it needed there, or can data come in from ebu, get logic [`XLEN-1:0] ReadDataWordMaskedM;
// muxed here and sent back out. assign ReadDataWordMaskedM = CacheableM ? ReadDataWordM : '0; // AND-gate
// Explore changing feedback path from output of AMOALU to subword write *** subwordwrite subwordwrite(.HRDATA(ReadDataWordMaskedM), .HADDRD(LSUPAdrM[2:0]),
subwordwrite subwordwrite(.HRDATA(ReadDataWordM), .HADDRD(LSUPAdrM[2:0]), .HSIZED({LSUFunct3M[2], 1'b0, LSUFunct3M[1:0]}),
.HSIZED({LSUFunct3M[2], 1'b0, LSUFunct3M[1:0]}), .HWDATAIN(FinalAMOWriteDataM), .HWDATA(PostSWWWriteDataM));
.HWDATAIN(FinalAMOWriteDataM), .HWDATA(FinalWriteDataM)); end else
assign PostSWWWriteDataM = FinalAMOWriteDataM;
assign FinalWriteDataM = SelHPTW ? PTE : PostSWWWriteDataM;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Atomic operations // Atomic operations

View File

@ -37,9 +37,14 @@ module lsuvirtmem(
output logic ITLBWriteF, output logic ITLBWriteF,
input logic DTLBMissM, input logic DTLBMissM,
output logic DTLBWriteM, output logic DTLBWriteM,
input logic InstrDAPageFaultF,
input logic DataDAPageFaultM,
input logic TrapM, input logic TrapM,
input logic DCacheStallM, input logic DCacheStallM,
input logic [`XLEN-1:0] SATP_REGW, // from csr input logic [`XLEN-1:0] SATP_REGW, // from csr
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW,
input logic [`XLEN-1:0] PCF, input logic [`XLEN-1:0] PCF,
input logic [`XLEN-1:0] ReadDataM, input logic [`XLEN-1:0] ReadDataM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
@ -69,23 +74,26 @@ module lsuvirtmem(
logic [2:0] HPTWSize; logic [2:0] HPTWSize;
logic SelReplayCPURequest; logic SelReplayCPURequest;
logic [11:0] PreLSUAdrE; logic [11:0] PreLSUAdrE;
logic ITLBMissOrDAFaultF;
logic DTLBMissOrDAFaultM;
logic HPTWWrite;
assign AnyCPUReqM = (|MemRWM) | (|AtomicM); assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
assign ITLBMissOrDAFaultF = ITLBMissF | (`HPTW_WRITES_SUPPORTED & InstrDAPageFaultF);
assign DTLBMissOrDAFaultM = DTLBMissM | (`HPTW_WRITES_SUPPORTED & DataDAPageFaultM);
interlockfsm interlockfsm ( interlockfsm interlockfsm (
.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF, .clk, .reset, .AnyCPUReqM, .ITLBMissOrDAFaultF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .TrapM, .DCacheStallM, .DTLBMissOrDAFaultM, .DTLBWriteM, .TrapM, .DCacheStallM,
.InterlockStall, .SelReplayCPURequest, .SelHPTW, .IgnoreRequestTLB, .IgnoreRequestTrapM); .InterlockStall, .SelReplayCPURequest, .SelHPTW, .IgnoreRequestTLB, .IgnoreRequestTrapM);
hptw hptw( // *** remove logic from (), mention this in style guide CH3 hptw hptw( // *** remove logic from (), mention this in style guide CH3
.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM, .clk, .reset, .SATP_REGW, .PCF, .IEUAdrM, .MemRWM, .AtomicM,
.ITLBMissF(ITLBMissF & ~TrapM), .DTLBMissM(DTLBMissM & ~TrapM), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .PrivilegeModeW,
.ITLBMissF(ITLBMissOrDAFaultF & ~TrapM), .DTLBMissM(DTLBMissOrDAFaultM & ~TrapM), // *** Fix me. *** I'm not sure ITLBMiss should be suppressed on TrapM.
.PTE, .PageType, .ITLBWriteF, .DTLBWriteM, .HPTWReadPTE(ReadDataM), .PTE, .PageType, .ITLBWriteF, .DTLBWriteM, .HPTWReadPTE(ReadDataM),
.DCacheStallM, .HPTWAdr, .HPTWRead, .HPTWSize); .DCacheStallM, .HPTWAdr, .HPTWRead, .HPTWWrite, .HPTWSize);
// multiplex the outputs to LSU // multiplex the outputs to LSU
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLSURWM); mux2 #(2) rwmux(MemRWM, {HPTWRead, HPTWWrite}, SelHPTW, PreLSURWM);
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M);
mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M);
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM); mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LSUAtomicM);

View File

@ -32,31 +32,37 @@
module hptw module hptw
( (
input logic clk, reset, input logic clk, reset,
input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table input logic [`XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table
input logic [`XLEN-1:0] PCF, IEUAdrM, // addresses to translate input logic [`XLEN-1:0] PCF, IEUAdrM, // addresses to translate
(* mark_debug = "true" *) input logic ITLBMissF, DTLBMissM, // TLB Miss input logic [1:0] MemRWM, AtomicM,
input logic [`XLEN-1:0] HPTWReadPTE, // page table entry from LSU // system status
input logic DCacheStallM, // stall from LSU input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW,
(* mark_debug = "true" *) input logic ITLBMissF, DTLBMissM, // TLB Miss
input logic [`XLEN-1:0] HPTWReadPTE, // page table entry from LSU
input logic DCacheStallM, // stall from LSU
output logic [`XLEN-1:0] PTE, // page table entry to TLBs output logic [`XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs output logic [1:0] PageType, // page type to TLBs
(* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry (* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic [`PA_BITS-1:0] HPTWAdr, output logic [`PA_BITS-1:0] HPTWAdr,
output logic HPTWRead, // HPTW requesting to read memory output logic HPTWRead, // HPTW requesting to read memory
output logic [2:0] HPTWSize // 32 or 64 bit access. output logic HPTWWrite,
output logic [2:0] HPTWSize // 32 or 64 bit access.
); );
typedef enum logic [3:0] {L0_ADR, L0_RD, typedef enum logic [3:0] {L0_ADR, L0_RD,
L1_ADR, L1_RD, L1_ADR, L1_RD,
L2_ADR, L2_RD, L2_ADR, L2_RD,
L3_ADR, L3_RD, L3_ADR, L3_RD,
LEAF, IDLE} statetype; LEAF, IDLE, UPDATE_PTE} statetype;
logic DTLBWalk; // register TLBs translation miss requests logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN; logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`PPN_BITS-1:0] CurrentPPN; logic [`PPN_BITS-1:0] CurrentPPN;
logic MemWrite; logic MemWrite;
logic Executable, Writable, Readable, Valid; logic Executable, Writable, Readable, Valid, PTE_U;
logic Misaligned, MegapageMisaligned; logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
logic StartWalk; logic StartWalk;
@ -65,7 +71,11 @@ module hptw
logic [1:0] NextPageType; logic [1:0] NextPageType;
logic [`SVMODE_BITS-1:0] SvMode; logic [`SVMODE_BITS-1:0] SvMode;
logic [`XLEN-1:0] TranslationVAdr; logic [`XLEN-1:0] TranslationVAdr;
logic [`XLEN-1:0] NextPTE;
logic UpdatePTE;
logic DAPageFault;
logic [`PA_BITS-1:0] HPTWReadAdr;
(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState; (* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
// Extract bits from CSRs and inputs // Extract bits from CSRs and inputs
@ -80,21 +90,89 @@ module hptw
// State flops // State flops
flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB) flopenr #(1) TLBMissMReg(clk, reset, StartWalk, DTLBMissM, DTLBWalk); // when walk begins, record whether it was for DTLB (or record 0 for ITLB)
assign PRegEn = HPTWRead & ~DCacheStallM; assign PRegEn = HPTWRead & ~DCacheStallM;
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn, HPTWReadPTE, PTE); // Capture page table entry from data cache
flopenr #(`XLEN) PTEReg(clk, reset, PRegEn | UpdatePTE, NextPTE, PTE); // Capture page table entry from data cache
// Assign PTE descriptors common across all XLEN values // Assign PTE descriptors common across all XLEN values
// For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table // For non-leaf PTEs, D, A, U bits are reserved and ignored. They do not cause faults while walking the page table
assign {Executable, Writable, Readable, Valid} = PTE[3:0]; assign {PTE_U, Executable, Writable, Readable, Valid} = PTE[4:0];
assign LeafPTE = Executable | Writable | Readable; assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid & ~(Writable & ~Readable); assign ValidPTE = Valid & ~(Writable & ~Readable);
assign ValidLeafPTE = ValidPTE & LeafPTE; assign ValidLeafPTE = ValidPTE & LeafPTE;
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites
logic SV39Mode;
logic ReadAccess, WriteAccess;
logic InvalidRead, InvalidWrite;
logic UpperBitsUnequalPageFault;
logic OtherPageFault;
logic [1:0] EffectivePrivilegeMode;
logic ImproperPrivilege;
logic SaveHPTWAdr, SelHPTWWriteAdr;
logic [`PA_BITS-1:0] HPTWWriteAdr;
logic SetDirty;
logic Dirty, Accessed;
assign NextPTE = UpdatePTE ? {PTE[`XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]} : HPTWReadPTE; // This will be HPTWReadPTE if not handling DAPageFault.
flopenr #(`PA_BITS) HPTWAdrWriteReg(clk, reset, SaveHPTWAdr, HPTWReadAdr, HPTWWriteAdr);
assign SaveHPTWAdr = WalkerState == L0_ADR;
assign SelHPTWWriteAdr = UpdatePTE | HPTWWrite;
mux2 #(`PA_BITS) HPTWWriteAdrMux(HPTWReadAdr, HPTWWriteAdr, SelHPTWWriteAdr, HPTWAdr); // HPTWAdr = HPTWReadAdr if not handling DAPageFault.
assign {Dirty, Accessed} = PTE[7:6];
assign WriteAccess = (MemRWM[0] | |AtomicM);
assign SetDirty = ~Dirty & & DTLBWalk & WriteAccess;
assign ReadAccess = MemRWM[1];
assign EffectivePrivilegeMode = (DTLBWalk == 0) ? PrivilegeModeW : (STATUS_MPRV ? STATUS_MPP : PrivilegeModeW); // DTLB uses MPP mode when MPRV is 1
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) |
((EffectivePrivilegeMode == `S_MODE) & PTE_U & (~STATUS_SUM & DTLBWalk));
// *** turn into module
if (`XLEN==64) begin:rv64
assign SV39Mode = (SATP_REGW[`XLEN-1:`XLEN-`SVMODE_BITS] == `SV39);
// page fault if upper bits aren't all the same
logic UpperEqual39, UpperEqual48;
assign UpperEqual39 = &(TranslationVAdr[63:38]) | ~|(TranslationVAdr[63:38]);
assign UpperEqual48 = &(TranslationVAdr[63:47]) | ~|(TranslationVAdr[63:47]);
assign UpperBitsUnequalPageFault = SV39Mode ? ~UpperEqual39 : ~UpperEqual48;
end else begin
assign SV39Mode = 0;
assign UpperBitsUnequalPageFault = 0;
end
assign InvalidRead = ReadAccess & ~Readable & (~STATUS_MXR | ~Executable);
assign InvalidWrite = WriteAccess & ~Writable;
assign OtherPageFault = DTLBWalk? ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~Valid :
ImproperPrivilege | ~Executable | UpperBitsUnequalPageFault | Misaligned | ~Valid;
// hptw needs to know if there is a Dirty or Access fault occuring on this
// memory access. If there is the PTE needs to be updated seting Access
// and possibly also Dirty. Dirty is set if the operation is a store/amo.
// However any other fault should not cause the update.
assign DAPageFault = ValidLeafPTE & (~Accessed | SetDirty) & ~OtherPageFault; // set to 0 if not handling DAPageFault.
assign HPTWWrite = (WalkerState == UPDATE_PTE);
assign UpdatePTE = WalkerState == LEAF & DAPageFault;
end else begin // block: hptwwrites
assign NextPTE = HPTWReadPTE;
assign HPTWAdr = HPTWReadAdr;
assign DAPageFault = '0;
assign UpdatePTE = '0;
assign HPTWWrite = '0;
end
// Enable and select signals based on states // Enable and select signals based on states
assign StartWalk = (WalkerState == IDLE) & TLBMiss; assign StartWalk = (WalkerState == IDLE) & TLBMiss;
assign HPTWRead = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD); assign HPTWRead = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
assign DTLBWriteM = (WalkerState == LEAF) & DTLBWalk; assign DTLBWriteM = (WalkerState == LEAF & ~DAPageFault) & DTLBWalk;
assign ITLBWriteF = (WalkerState == LEAF) & ~DTLBWalk; assign ITLBWriteF = (WalkerState == LEAF & ~DAPageFault) & ~DTLBWalk;
// FSM to track PageType based on the levels of the page table traversed // FSM to track PageType based on the levels of the page table traversed
flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType); flopr #(2) PageTypeReg(clk, reset, NextPageType, PageType);
@ -113,7 +191,7 @@ module hptw
logic [`PPN_BITS-1:0] PPN; logic [`PPN_BITS-1:0] PPN;
assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state assign VPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? TranslationVAdr[31:22] : TranslationVAdr[21:12]; // select VPN field based on HPTW state
assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN; assign PPN = ((WalkerState == L1_ADR) | (WalkerState == L1_RD)) ? BasePageTablePPN : CurrentPPN;
assign HPTWAdr = {PPN, VPN, 2'b00}; assign HPTWReadAdr = {PPN, VPN, 2'b00};
assign HPTWSize = 3'b010; assign HPTWSize = 3'b010;
end else begin // RV64 end else begin // RV64
logic [8:0] VPN; logic [8:0] VPN;
@ -127,7 +205,7 @@ module hptw
endcase endcase
assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) | assign PPN = ((WalkerState == L3_ADR) | (WalkerState == L3_RD) |
(SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN; (SvMode != `SV48 & ((WalkerState == L2_ADR) | (WalkerState == L2_RD)))) ? BasePageTablePPN : CurrentPPN;
assign HPTWAdr = {PPN, VPN, 3'b000}; assign HPTWReadAdr = {PPN, VPN, 3'b000};
assign HPTWSize = 3'b011; assign HPTWSize = 3'b011;
end end
@ -151,46 +229,42 @@ module hptw
// to decrease the latency of the HPTW. However, if the D$ is a cycle limiter, it's better to leave the // to decrease the latency of the HPTW. However, if the D$ is a cycle limiter, it's better to leave the
// HPTW as shown below to keep the D$ setup time out of the critical path. // HPTW as shown below to keep the D$ setup time out of the critical path.
// *** Is this really true. Talk with Ross. Seems like it's the next state logic on critical path instead. // *** Is this really true. Talk with Ross. Seems like it's the next state logic on critical path instead.
// *** address TYPE(statetype)
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb always_comb
case (WalkerState) case (WalkerState)
IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState; IDLE: if (TLBMiss) NextWalkerState = InitialWalkerState;
else NextWalkerState = IDLE; else NextWalkerState = IDLE;
L3_ADR: NextWalkerState = L3_RD; // first access in SV48 L3_ADR: NextWalkerState = L3_RD; // first access in SV48
L3_RD: if (DCacheStallM) NextWalkerState = L3_RD; L3_RD: if (DCacheStallM) NextWalkerState = L3_RD;
else NextWalkerState = L2_ADR; else NextWalkerState = L2_ADR;
// LEVEL3: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
// else if (ValidNonLeafPTE) NextWalkerState = L2_ADR;
// else NextWalkerState = FAULT;
L2_ADR: if (InitialWalkerState == L2_ADR) NextWalkerState = L2_RD; // first access in SV39
else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidNonLeafPTE) NextWalkerState = L2_RD; else if (ValidNonLeafPTE) NextWalkerState = L2_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L2_RD: if (DCacheStallM) NextWalkerState = L2_RD; L2_RD: if (DCacheStallM) NextWalkerState = L2_RD;
else NextWalkerState = L1_ADR; else NextWalkerState = L1_ADR;
// LEVEL2: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
// else if (ValidNonLeafPTE) NextWalkerState = L1_ADR;
// else NextWalkerState = FAULT;
L1_ADR: if (InitialWalkerState == L1_ADR) NextWalkerState = L1_RD; // first access in SV32
else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages else if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
else if (ValidNonLeafPTE) NextWalkerState = L1_RD; else if (ValidNonLeafPTE) NextWalkerState = L1_RD;
else NextWalkerState = LEAF; else NextWalkerState = LEAF;
L1_RD: if (DCacheStallM) NextWalkerState = L1_RD; L1_RD: if (DCacheStallM) NextWalkerState = L1_RD;
else NextWalkerState = L0_ADR; else NextWalkerState = L0_ADR;
// LEVEL1: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; L0_ADR: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages
// else if (ValidNonLeafPTE) NextWalkerState = L0_ADR; else if (ValidNonLeafPTE) NextWalkerState = L0_RD;
// else NextWalkerState = FAULT; else NextWalkerState = LEAF;
L0_ADR: if (ValidLeafPTE & ~Misaligned) NextWalkerState = LEAF; // could shortcut this by a cyle for all Lx_ADR superpages L0_RD: if (DCacheStallM) NextWalkerState = L0_RD;
else if (ValidNonLeafPTE) NextWalkerState = L0_RD; else NextWalkerState = LEAF;
else NextWalkerState = LEAF; LEAF: if (DAPageFault) NextWalkerState = UPDATE_PTE;
L0_RD: if (DCacheStallM) NextWalkerState = L0_RD; else NextWalkerState = IDLE;
else NextWalkerState = LEAF; // *** TODO update PTE with dirty/access. write to TLB and update memory.
// LEVEL0: if (ValidLeafPTE) NextWalkerState = LEAF; // probably want to write the PTE in UPDATE_PTE then go to leaf and update TLB.
// else NextWalkerState = FAULT; UPDATE_PTE: if(`HPTW_WRITES_SUPPORTED & DCacheStallM) NextWalkerState = UPDATE_PTE;
LEAF: NextWalkerState = IDLE; // updates TLB else NextWalkerState = LEAF;
default: begin default: begin
// synthesis translate_off // synthesis translate_off
$error("Default state in HPTW should be unreachable"); if (WalkerState !== 'x)
$error("Default state in HPTW should be unreachable; was %d", WalkerState);
// synthesis translate_on // synthesis translate_on
NextWalkerState = IDLE; // should never be reached NextWalkerState = IDLE; // should never be reached
end end

View File

@ -34,20 +34,20 @@
module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
parameter IMMU = 0) ( parameter IMMU = 0) (
input logic clk, reset, input logic clk, reset,
// Current value of satp CSR (from privileged unit) // Current value of satp CSR (from privileged unit)
input logic [`XLEN-1:0] SATP_REGW, input logic [`XLEN-1:0] SATP_REGW,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
// Current privilege level of the processeor // Current privilege level of the processeor
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
// 00 - TLB is not being accessed // 00 - TLB is not being accessed
// 1x - TLB is accessed for a read (or an instruction) // 1x - TLB is accessed for a read (or an instruction)
// x1 - TLB is accessed for a write // x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write // 11 - TLB is accessed for both read and write
input logic DisableTranslation, input logic DisableTranslation,
// VAdr goes to the TLB only. Virtual if the TLB is active. // VAdr goes to the TLB only. Virtual if the TLB is active.
// PAdr goes to address mux bypassing the TLB. PAdr used when there is no translation. // PAdr goes to address mux bypassing the TLB. PAdr used when there is no translation.
@ -57,32 +57,33 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
// performed. // performed.
// PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr) // PhysicalAddress is selected to be PAdr when no translation or the translated VAdr (TLBPAdr)
// when there is translation. // when there is translation.
input logic [`PA_BITS-1:0] PAdr, // *** consider renaming this. input logic [`PA_BITS-1:0] PAdr, // *** consider renaming this.
input logic [`XLEN-1:0] VAdr, input logic [`XLEN-1:0] VAdr,
input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits input logic [1:0] Size, // 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
// Controls for writing a new entry to the TLB // Controls for writing a new entry to the TLB
input logic [`XLEN-1:0] PTE, input logic [`XLEN-1:0] PTE,
input logic [1:0] PageTypeWriteVal, input logic [1:0] PageTypeWriteVal,
input logic TLBWrite, input logic TLBWrite,
// Invalidate all TLB entries // Invalidate all TLB entries
input logic TLBFlush, input logic TLBFlush,
// Physical address outputs // Physical address outputs
output logic [`PA_BITS-1:0] PhysicalAddress, output logic [`PA_BITS-1:0] PhysicalAddress,
output logic TLBMiss, output logic TLBMiss,
output logic Cacheable, Idempotent, AtomicAllowed, output logic Cacheable, Idempotent, AtomicAllowed,
// Faults // Faults
output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM, output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM,
output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM, output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM,
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, output logic DAPageFault,
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
// PMA checker signals // PMA checker signals
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM,
input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0], input var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0] input var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0]
); );
logic [`PA_BITS-1:0] TLBPAdr; logic [`PA_BITS-1:0] TLBPAdr;
@ -109,7 +110,7 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
.PrivilegeModeW, .ReadAccess, .WriteAccess, .PrivilegeModeW, .ReadAccess, .WriteAccess,
.DisableTranslation, .PTE, .PageTypeWriteVal, .DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
.Translate, .TLBPageFault); .Translate, .TLBPageFault, .DAPageFault);
end else begin:tlb// just pass address through as physical end else begin:tlb// just pass address through as physical
assign Translate = 0; assign Translate = 0;
assign TLBMiss = 0; assign TLBMiss = 0;

View File

@ -56,43 +56,44 @@
// The TLB will have 2**ENTRY_BITS total entries // The TLB will have 2**ENTRY_BITS total entries
module tlb #(parameter TLB_ENTRIES = 8, module tlb #(parameter TLB_ENTRIES = 8,
parameter ITLB = 0) ( parameter ITLB = 0) (
input logic clk, reset, input logic clk, reset,
// Current value of satp CSR (from privileged unit) // Current value of satp CSR (from privileged unit)
input logic [`SVMODE_BITS-1:0] SATP_MODE, input logic [`SVMODE_BITS-1:0] SATP_MODE,
input logic [`ASID_BITS-1:0] SATP_ASID, input logic [`ASID_BITS-1:0] SATP_ASID,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
// Current privilege level of the processeor // Current privilege level of the processeor
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
// 00 - TLB is not being accessed // 00 - TLB is not being accessed
// 1x - TLB is accessed for a read (or an instruction) // 1x - TLB is accessed for a read (or an instruction)
// x1 - TLB is accessed for a write // x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write // 11 - TLB is accessed for both read and write
input logic ReadAccess, WriteAccess, input logic ReadAccess, WriteAccess,
input logic DisableTranslation, input logic DisableTranslation,
// address input before translation (could be physical or virtual) // address input before translation (could be physical or virtual)
input logic [`XLEN-1:0] VAdr, input logic [`XLEN-1:0] VAdr,
// Controls for writing a new entry to the TLB // Controls for writing a new entry to the TLB
input logic [`XLEN-1:0] PTE, input logic [`XLEN-1:0] PTE,
input logic [1:0] PageTypeWriteVal, input logic [1:0] PageTypeWriteVal,
input logic TLBWrite, input logic TLBWrite,
// Invalidate all TLB entries // Invalidate all TLB entries
input logic TLBFlush, input logic TLBFlush,
// Physical address outputs // Physical address outputs
output logic [`PA_BITS-1:0] TLBPAdr, output logic [`PA_BITS-1:0] TLBPAdr,
output logic TLBMiss, output logic TLBMiss,
output logic TLBHit, output logic TLBHit,
output logic Translate, output logic Translate,
// Faults // Faults
output logic TLBPageFault output logic TLBPageFault,
output logic DAPageFault
); );
logic [TLB_ENTRIES-1:0] Matches, WriteEnables, PTE_Gs; // used as the one-hot encoding of WriteIndex logic [TLB_ENTRIES-1:0] Matches, WriteEnables, PTE_Gs; // used as the one-hot encoding of WriteIndex
@ -132,7 +133,7 @@ module tlb #(parameter TLB_ENTRIES = 8,
tlbcontrol #(ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, tlbcontrol #(ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .TLBFlush, .PrivilegeModeW, .ReadAccess, .WriteAccess, .DisableTranslation, .TLBFlush,
.PTEAccessBits, .CAMHit, .Misaligned, .TLBMiss, .TLBHit, .TLBPageFault, .PTEAccessBits, .CAMHit, .Misaligned, .TLBMiss, .TLBHit, .TLBPageFault,
.SV39Mode, .Translate); .DAPageFault, .SV39Mode, .Translate);
tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables); tlblru #(TLB_ENTRIES) lru(.clk, .reset, .TLBWrite, .TLBFlush, .Matches, .CAMHit, .WriteEnables);
tlbcam #(TLB_ENTRIES, `VPN_BITS + `ASID_BITS, `VPN_SEGMENT_BITS) tlbcam #(TLB_ENTRIES, `VPN_BITS + `ASID_BITS, `VPN_SEGMENT_BITS)

View File

@ -33,27 +33,28 @@
module tlbcontrol #(parameter ITLB = 0) ( module tlbcontrol #(parameter ITLB = 0) (
// Current value of satp CSR (from privileged unit) // Current value of satp CSR (from privileged unit)
input logic [`SVMODE_BITS-1:0] SATP_MODE, input logic [`SVMODE_BITS-1:0] SATP_MODE,
input logic [`XLEN-1:0] VAdr, input logic [`XLEN-1:0] VAdr,
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
// 00 - TLB is not being accessed // 00 - TLB is not being accessed
// 1x - TLB is accessed for a read (or an instruction) // 1x - TLB is accessed for a read (or an instruction)
// x1 - TLB is accessed for a write // x1 - TLB is accessed for a write
// 11 - TLB is accessed for both read and write // 11 - TLB is accessed for both read and write
input logic ReadAccess, WriteAccess, input logic ReadAccess, WriteAccess,
input logic DisableTranslation, input logic DisableTranslation,
input logic TLBFlush, // Invalidate all TLB entries input logic TLBFlush, // Invalidate all TLB entries
input logic [7:0] PTEAccessBits, input logic [7:0] PTEAccessBits,
input logic CAMHit, input logic CAMHit,
input logic Misaligned, input logic Misaligned,
output logic TLBMiss, output logic TLBMiss,
output logic TLBHit, output logic TLBHit,
output logic TLBPageFault, output logic TLBPageFault,
output logic SV39Mode, output logic DAPageFault,
output logic Translate output logic SV39Mode,
output logic Translate
); );
// Sections of the page table entry // Sections of the page table entry
@ -63,7 +64,6 @@ module tlbcontrol #(parameter ITLB = 0) (
logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits logic PTE_D, PTE_A, PTE_U, PTE_X, PTE_W, PTE_R, PTE_V; // Useful PTE Control Bits
logic UpperBitsUnequalPageFault; logic UpperBitsUnequalPageFault;
logic DAPageFault;
logic TLBAccess; logic TLBAccess;
logic ImproperPrivilege; logic ImproperPrivilege;
@ -97,9 +97,14 @@ module tlbcontrol #(parameter ITLB = 0) (
// only execute non-user mode pages. // only execute non-user mode pages.
assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) | assign ImproperPrivilege = ((EffectivePrivilegeMode == `U_MODE) & ~PTE_U) |
((EffectivePrivilegeMode == `S_MODE) & PTE_U); ((EffectivePrivilegeMode == `S_MODE) & PTE_U);
if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites
assign DAPageFault = Translate & TLBHit & ~PTE_A & ~TLBPageFault;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end else begin
// fault for software handling if access bit is off // fault for software handling if access bit is off
assign DAPageFault = ~PTE_A; assign DAPageFault = ~PTE_A;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V)); assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | ~PTE_X | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end
end else begin:dtlb // Data TLB fault checking end else begin:dtlb // Data TLB fault checking
logic InvalidRead, InvalidWrite; logic InvalidRead, InvalidWrite;
@ -114,9 +119,14 @@ module tlbcontrol #(parameter ITLB = 0) (
// Check for write error. Writes are invalid when the page's write bit is // Check for write error. Writes are invalid when the page's write bit is
// low. // low.
assign InvalidWrite = WriteAccess & ~PTE_W; assign InvalidWrite = WriteAccess & ~PTE_W;
// Fault for software handling if access bit is off or writing a page with dirty bit off if(`HPTW_WRITES_SUPPORTED) begin : hptwwrites
assign DAPageFault = ~PTE_A | WriteAccess & ~PTE_D; assign DAPageFault = Translate & TLBHit & (~PTE_A | WriteAccess & ~PTE_D) & ~TLBPageFault;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V)); assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end else begin
// Fault for software handling if access bit is off or writing a page with dirty bit off
assign DAPageFault = ~PTE_A | WriteAccess & ~PTE_D;
assign TLBPageFault = (Translate & TLBHit & (ImproperPrivilege | InvalidRead | InvalidWrite | DAPageFault | UpperBitsUnequalPageFault | Misaligned | ~PTE_V));
end
end end
assign TLBHit = CAMHit & TLBAccess; assign TLBHit = CAMHit & TLBAccess;

View File

@ -42,7 +42,7 @@ module csr #(parameter
input logic StallE, StallM, StallW, input logic StallE, StallM, StallW,
input logic [31:0] InstrM, input logic [31:0] InstrM,
input logic [`XLEN-1:0] PCM, SrcAM, input logic [`XLEN-1:0] PCM, SrcAM,
input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM, uretM, input logic CSRReadM, CSRWriteM, TrapM, MTrapM, STrapM, UTrapM, mretM, sretM,
input logic TimerIntM, ExtIntM, SwIntM, input logic TimerIntM, ExtIntM, SwIntM,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
input logic InstrValidM, FRegWriteM, LoadStallD, input logic InstrValidM, FRegWriteM, LoadStallD,
@ -59,8 +59,8 @@ module csr #(parameter
input logic [`XLEN-1:0] CauseM, NextFaultMtvalM, input logic [`XLEN-1:0] CauseM, NextFaultMtvalM,
output logic [1:0] STATUS_MPP, output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, output logic STATUS_SPP, STATUS_TSR,
output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW, output logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW, output logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, output logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MIE, STATUS_SIE,
@ -76,12 +76,12 @@ module csr #(parameter
); );
localparam NOP = 32'h13; localparam NOP = 32'h13;
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRNReadValM, CSRCReadValM, CSRReadValM; logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM, CSRReadValM;
logic [`XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM; logic [`XLEN-1:0] CSRSrcM, CSRRWM, CSRRSM, CSRRCM, CSRWriteValM;
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW; (* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW;
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM; logic WriteMSTATUSM, WriteSSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic STATUS_TVM; logic STATUS_TVM;
logic WriteFRMM, WriteFFLAGSM; logic WriteFRMM, WriteFFLAGSM;
@ -90,7 +90,7 @@ module csr #(parameter
logic [11:0] CSRAdrM; logic [11:0] CSRAdrM;
//logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported //logic [11:0] UIP_REGW, UIE_REGW = 0; // N user-mode exceptions not supported
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, IllegalCSRNAccessM, InsufficientCSRPrivilegeM; logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM, InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM; logic IllegalCSRMWriteReadonlyM;
logic InstrValidNotFlushedM; logic InstrValidNotFlushedM;
@ -126,10 +126,10 @@ module csr #(parameter
.CSRAdrM, .ExtIntM, .TimerIntM, .SwIntM, .CSRAdrM, .ExtIntM, .TimerIntM, .SwIntM,
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM); .MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .CSRWriteValM);
csrsr csrsr(.clk, .reset, .StallW, csrsr csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteSSTATUSM, .WriteUSTATUSM, .WriteMSTATUSM, .WriteSSTATUSM,
.TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW, .TrapM, .FRegWriteM, .NextPrivilegeModeM, .PrivilegeModeW,
.mretM, .sretM, .uretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM, .mretM, .sretM, .WriteFRMM, .WriteFFLAGSM, .CSRWriteValM,
.MSTATUS_REGW, .SSTATUS_REGW, .USTATUS_REGW, .MSTATUS_REGW, .SSTATUS_REGW,
.STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TW, .STATUS_MPP, .STATUS_SPP, .STATUS_TSR, .STATUS_TW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM); .STATUS_MIE, .STATUS_SIE, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_TVM);
csrc counters(.clk, .reset, csrc counters(.clk, .reset,
@ -153,27 +153,22 @@ module csr #(parameter
.NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW, .NextEPCM, .NextCauseM, .NextMtvalM, .SSTATUS_REGW,
.STATUS_TVM, .CSRWriteValM, .PrivilegeModeW, .STATUS_TVM, .CSRWriteValM, .PrivilegeModeW,
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW, .CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
.SCOUNTEREN_REGW, .SEDELEG_REGW, .SIDELEG_REGW, .SCOUNTEREN_REGW,
.SATP_REGW, .SIP_REGW, .SIE_REGW, .SATP_REGW, .SIP_REGW, .SIE_REGW,
.WriteSSTATUSM, .IllegalCSRSAccessM); .WriteSSTATUSM, .IllegalCSRSAccessM);
csrn csrn(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRNWriteM(CSRUWriteM), .UTrapM, .CSRAdrM,
.NextEPCM, .NextCauseM, .NextMtvalM, .USTATUS_REGW,
.CSRWriteValM, .CSRNReadValM, .UEPC_REGW, .UTVEC_REGW,
.UIP_REGW, .UIE_REGW, .WriteUSTATUSM, .IllegalCSRNAccessM);
csru csru(.clk, .reset, .InstrValidNotFlushedM, .StallW, csru csru(.clk, .reset, .InstrValidNotFlushedM, .StallW,
.CSRUWriteM, .CSRAdrM, .CSRWriteValM, .CSRUReadValM, .CSRUWriteM, .CSRAdrM, .CSRWriteValM, .CSRUReadValM,
.SetFflagsM, .FRM_REGW, .WriteFRMM, .WriteFFLAGSM, .SetFflagsM, .FRM_REGW, .WriteFRMM, .WriteFFLAGSM,
.IllegalCSRUAccessM); .IllegalCSRUAccessM);
// merge CSR Reads // merge CSR Reads
assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM | CSRNReadValM; assign CSRReadValM = CSRUReadValM | CSRSReadValM | CSRMReadValM | CSRCReadValM;
flopenrc #(`XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW); flopenrc #(`XLEN) CSRValWReg(clk, reset, FlushW, ~StallW, CSRReadValM, CSRReadValW);
// merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient // merge illegal accesses: illegal if none of the CSR addresses is legal or privilege is insufficient
assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) | assign InsufficientCSRPrivilegeM = (CSRAdrM[9:8] == 2'b11 & PrivilegeModeW != `M_MODE) |
(CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE); (CSRAdrM[9:8] == 2'b01 & PrivilegeModeW == `U_MODE);
assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM & assign IllegalCSRAccessM = ((IllegalCSRCAccessM & IllegalCSRMAccessM &
IllegalCSRSAccessM & IllegalCSRUAccessM & IllegalCSRNAccessM | IllegalCSRSAccessM & IllegalCSRUAccessM |
InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM; InsufficientCSRPrivilegeM) & CSRReadM) | IllegalCSRMWriteReadonlyM;
endmodule endmodule

View File

@ -111,14 +111,5 @@ module csri #(parameter
SIP_REGW = 12'b0; SIP_REGW = 12'b0;
SIE_REGW = 12'b0; SIE_REGW = 12'b0;
end end
// User Modes iterrupts depricated
/*if (`U_SUPPORTED & `N_SUPPORTED) begin
UIP_REGW = IP_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible
UIE_REGW = IE_REGW & MIDELEG_REGW & SIDELEG_REGW & 'h111; // only delegated interrupts visible
end else begin
UIP_REGW = 12'b0;
UIE_REGW = 12'b0;
end */
end end
endmodule endmodule

View File

@ -146,7 +146,7 @@ module csrm #(parameter
// CSRs // CSRs
flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW);
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin:deleg // DELEG registers should exist if (`S_SUPPORTED) begin:deleg // DELEG registers should exist
flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW); flopenr #(`XLEN) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW);
flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW);
end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0; end else assign {MEDELEG_REGW, MIDELEG_REGW} = 0;
@ -165,8 +165,7 @@ module csrm #(parameter
logic [5:0] entry; logic [5:0] entry;
always_comb begin always_comb begin
entry = '0; entry = '0;
IllegalCSRMAccessM = !(`S_SUPPORTED | `U_SUPPORTED & `N_SUPPORTED) & IllegalCSRMAccessM = !(`S_SUPPORTED) & (CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
(CSRAdrM == MEDELEG | CSRAdrM == MIDELEG); // trap on DELEG register access when no S or N-mode
if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + `PMP_ENTRIES) // reading a PMP entry if (CSRAdrM >= PMPADDR0 & CSRAdrM < PMPADDR0 + `PMP_ENTRIES) // reading a PMP entry
CSRMReadValM = PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0]; CSRMReadValM = PMPADDR_ARRAY_REGW[CSRAdrM - PMPADDR0];
else if (CSRAdrM >= PMPCFG0 & CSRAdrM < PMPCFG0 + `PMP_ENTRIES/4) begin else if (CSRAdrM >= PMPCFG0 & CSRAdrM < PMPCFG0 + `PMP_ENTRIES/4) begin

View File

@ -1,103 +0,0 @@
///////////////////////////////////////////
// csrn.sv
//
// Written: David_Harris@hmc.edu 9 January 2021
// Modified:
// dottolia@hmc.edu 3 May 2021 - fix bug with utvec getting wrong value
//
// Purpose: User-Mode Control and Status Registers for User Mode Exceptions
// See RISC-V Privileged Mode Specification 20190608 Table 2.2
//
// A component of the Wally configurable RISC-V project.
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// MIT LICENSE
// Permission is hereby granted, free of charge, to any person obtaining a copy of this
// software and associated documentation files (the "Software"), to deal in the Software
// without restriction, including without limitation the rights to use, copy, modify, merge,
// publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons
// to whom the Software is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or
// substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
// INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
// PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
// TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE
// OR OTHER DEALINGS IN THE SOFTWARE.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module csrn #(parameter
USTATUS =12'h000,
UIE = 12'h004,
UTVEC = 12'h005,
USCRATCH = 12'h040,
UEPC = 12'h041,
UCAUSE = 12'h042,
UTVAL = 12'h043,
UIP = 12'h044) (
input logic clk, reset,
input logic InstrValidNotFlushedM, StallW,
input logic CSRNWriteM, UTrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, USTATUS_REGW,
input logic [`XLEN-1:0] CSRWriteValM,
output logic [`XLEN-1:0] CSRNReadValM, UEPC_REGW, UTVEC_REGW,
input logic [11:0] UIP_REGW, UIE_REGW,
output logic WriteUSTATUSM,
output logic IllegalCSRNAccessM
);
// User mode CSRs below only needed when user mode traps are supported
if (`N_SUPPORTED) begin:nmode // depricated; consider removing***
logic WriteUTVECM;
logic WriteUSCRATCHM, WriteUEPCM;
logic WriteUCAUSEM, WriteUTVALM;
logic [`XLEN-1:0] UEDELEG_REGW, UIDELEG_REGW;
logic [`XLEN-1:0] USCRATCH_REGW, UCAUSE_REGW, UTVAL_REGW;
// Write enables
assign WriteUSTATUSM = CSRNWriteM & (CSRAdrM == USTATUS) & InstrValidNotFlushedM;
assign WriteUTVECM = CSRNWriteM & (CSRAdrM == UTVEC) & InstrValidNotFlushedM;
assign WriteUEPCM = UTrapM | (CSRNWriteM & (CSRAdrM == UEPC)) & InstrValidNotFlushedM;
assign WriteUCAUSEM = UTrapM | (CSRNWriteM & (CSRAdrM == UCAUSE)) & InstrValidNotFlushedM;
assign WriteUTVALM = UTrapM | (CSRNWriteM & (CSRAdrM == UTVAL)) & InstrValidNotFlushedM;
// CSRs
flopenl #(`XLEN) UTVECreg(clk, reset, WriteUTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, `RESET_VECTOR, UTVEC_REGW);
flopenr #(`XLEN) USCRATCHreg(clk, reset, WriteUSCRATCHM, CSRWriteValM, USCRATCH_REGW);
flopenr #(`XLEN) UEPCreg(clk, reset, WriteUEPCM, NextEPCM, UEPC_REGW);
flopenr #(`XLEN) UCAUSEreg(clk, reset, WriteUCAUSEM, NextCauseM, UCAUSE_REGW);
flopenr #(`XLEN) UTVALreg(clk, reset, WriteUTVALM, NextMtvalM, UTVAL_REGW);
// CSR Reads
always_comb begin
IllegalCSRNAccessM = 0;
case (CSRAdrM)
USTATUS: CSRNReadValM = USTATUS_REGW;
UTVEC: CSRNReadValM = UTVEC_REGW;
UIP: CSRNReadValM = {{(`XLEN-12){1'b0}}, UIP_REGW};
UIE: CSRNReadValM = {{(`XLEN-12){1'b0}}, UIE_REGW};
USCRATCH: CSRNReadValM = USCRATCH_REGW;
UEPC: CSRNReadValM = UEPC_REGW;
UCAUSE: CSRNReadValM = UCAUSE_REGW;
UTVAL: CSRNReadValM = UTVAL_REGW;
default: begin
CSRNReadValM = 0;
IllegalCSRNAccessM = 1;
end
endcase
end
end else begin // if not supported
assign WriteUSTATUSM = 0;
assign CSRNReadValM = 0;
assign UEPC_REGW = 0;
assign UTVEC_REGW = 0;
assign IllegalCSRNAccessM = 1;
end
endmodule

View File

@ -35,8 +35,6 @@
module csrs #(parameter module csrs #(parameter
// Supervisor CSRs // Supervisor CSRs
SSTATUS = 12'h100, SSTATUS = 12'h100,
SEDELEG = 12'h102,
SIDELEG = 12'h103,
SIE = 12'h104, SIE = 12'h104,
STVEC = 12'h105, STVEC = 12'h105,
SCOUNTEREN = 12'h106, SCOUNTEREN = 12'h106,
@ -62,7 +60,6 @@ module csrs #(parameter
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW, output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] SEPC_REGW, (* mark_debug = "true" *) output logic [`XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW, output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SEDELEG_REGW, SIDELEG_REGW,
output logic [`XLEN-1:0] SATP_REGW, output logic [`XLEN-1:0] SATP_REGW,
(* mark_debug = "true" *) input logic [11:0] SIP_REGW, SIE_REGW, (* mark_debug = "true" *) input logic [11:0] SIP_REGW, SIE_REGW,
output logic WriteSSTATUSM, output logic WriteSSTATUSM,
@ -102,27 +99,12 @@ module csrs #(parameter
assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported assign SATP_REGW = 0; // hardwire to zero if virtual memory not supported
flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW); flopens #(32) SCOUNTERENreg(clk, reset, WriteSCOUNTERENM, CSRWriteValM[31:0], SCOUNTEREN_REGW);
if (`N_SUPPORTED) begin:nregs
logic WriteSEDELEGM, WriteSIDELEGM;
assign WriteSEDELEGM = CSRSWriteM & (CSRAdrM == SEDELEG);
assign WriteSIDELEGM = CSRSWriteM & (CSRAdrM == SIDELEG);
flopenr #(`XLEN) SEDELEGreg(clk, reset, WriteSEDELEGM, CSRWriteValM & SEDELEG_MASK, SEDELEG_REGW);
flopenr #(`XLEN) SIDELEGreg(clk, reset, WriteSIDELEGM, CSRWriteValM, SIDELEG_REGW);
end else begin
assign SEDELEG_REGW = 0;
assign SIDELEG_REGW = 0;
end
// CSR Reads // CSR Reads
always_comb begin:csrr always_comb begin:csrr
IllegalCSRSAccessM = !(`N_SUPPORTED) & (CSRAdrM == SEDELEG | CSRAdrM == SIDELEG); // trap on DELEG register access when no N-mode IllegalCSRSAccessM = 0;
case (CSRAdrM) case (CSRAdrM)
SSTATUS: CSRSReadValM = SSTATUS_REGW; SSTATUS: CSRSReadValM = SSTATUS_REGW;
STVEC: CSRSReadValM = STVEC_REGW; STVEC: CSRSReadValM = STVEC_REGW;
// SIDELEG: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIDELEG_REGW};
// SEDELEG: CSRSReadValM = {{(`XLEN-12){1'b0}}, SEDELEG_REGW};
SIDELEG: CSRSReadValM = SIDELEG_REGW;
SEDELEG: CSRSReadValM = SEDELEG_REGW;
SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIP_REGW}; SIP: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIP_REGW};
SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIE_REGW}; SIE: CSRSReadValM = {{(`XLEN-12){1'b0}}, SIE_REGW};
SSCRATCH: CSRSReadValM = SSCRATCH_REGW; SSCRATCH: CSRSReadValM = SSCRATCH_REGW;
@ -146,8 +128,6 @@ module csrs #(parameter
assign CSRSReadValM = 0; assign CSRSReadValM = 0;
assign SEPC_REGW = 0; assign SEPC_REGW = 0;
assign STVEC_REGW = 0; assign STVEC_REGW = 0;
assign SEDELEG_REGW = 0;
assign SIDELEG_REGW = 0;
assign SCOUNTEREN_REGW = 0; assign SCOUNTEREN_REGW = 0;
assign SATP_REGW = 0; assign SATP_REGW = 0;
assign IllegalCSRSAccessM = 1; assign IllegalCSRSAccessM = 1;

View File

@ -33,13 +33,13 @@
module csrsr ( module csrsr (
input logic clk, reset, StallW, input logic clk, reset, StallW,
input logic WriteMSTATUSM, WriteSSTATUSM, WriteUSTATUSM, input logic WriteMSTATUSM, WriteSSTATUSM,
input logic TrapM, FRegWriteM, input logic TrapM, FRegWriteM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic mretM, sretM, uretM, input logic mretM, sretM,
input logic WriteFRMM, WriteFFLAGSM, input logic WriteFRMM, WriteFFLAGSM,
input logic [`XLEN-1:0] CSRWriteValM, input logic [`XLEN-1:0] CSRWriteValM,
output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, USTATUS_REGW, output logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW,
output logic [1:0] STATUS_MPP, output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TW, output logic STATUS_SPP, STATUS_TSR, STATUS_TW,
output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MIE, STATUS_SIE,
@ -66,11 +66,6 @@ module csrsr (
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE, STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE}; /*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
assign USTATUS_REGW = {/*STATUS_SD, */ 59'b0, /*STATUS_SXL, STATUS_UXL, 9'b0, */
/*STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, , 1'b0,*/
/* STATUS_XS, STATUS_FS, /*STATUS_MPP, 8'b0, */
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
end else begin: csrsr32 // RV32 end else begin: csrsr32 // RV32
assign MSTATUS_REGW = {STATUS_SD, 8'b0, assign MSTATUS_REGW = {STATUS_SD, 8'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
@ -81,11 +76,6 @@ module csrsr (
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE, STATUS_SPP, /*STATUS_MPIE, 1'b0*/ 2'b0, STATUS_SPIE, STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE}; /*STATUS_MIE, 1'b0*/ 2'b0, STATUS_SIE, STATUS_UIE};
assign USTATUS_REGW = {/*STATUS_SD, */ 27'b0, /*STATUS_SXL, STATUS_UXL, 9'b0, */
/*STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, , 1'b0,*/
/*STATUS_XS, STATUS_FS, STATUS_MPP, 8'b0, */
/*STATUS_SPP, STATUS_MPIE, 1'b0 2'b0, STATUS_SPIE,*/ STATUS_UPIE,
/*STATUS_MIE, 1'b0*/ 3'b0, /*STATUS_SIE, */STATUS_UIE};
end end
// harwired STATUS bits // harwired STATUS bits
@ -156,9 +146,6 @@ module csrsr (
STATUS_SPIE <= #1 `S_SUPPORTED; STATUS_SPIE <= #1 `S_SUPPORTED;
STATUS_SPP <= #1 0; // Privileged 4.1.1 STATUS_SPP <= #1 0; // Privileged 4.1.1
STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec STATUS_MPRV_INT <= #1 0; // per 20210108 draft spec
end else if (uretM) begin
STATUS_UIE <= #1 STATUS_UPIE;
STATUS_UPIE <= #1 `U_SUPPORTED;
end else if (WriteMSTATUSM) begin end else if (WriteMSTATUSM) begin
STATUS_TSR_INT <= #1 CSRWriteValM[22]; STATUS_TSR_INT <= #1 CSRWriteValM[22];
STATUS_TW_INT <= #1 CSRWriteValM[21]; STATUS_TW_INT <= #1 CSRWriteValM[21];
@ -184,10 +171,6 @@ module csrsr (
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4]; STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1]; STATUS_SIE <= #1 `S_SUPPORTED & CSRWriteValM[1];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0]; STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end else if (WriteUSTATUSM) begin // write a subset of the STATUS bits end
STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_UPIE <= #1 `U_SUPPORTED & CSRWriteValM[4];
STATUS_UIE <= #1 `U_SUPPORTED & CSRWriteValM[0];
end
end end
endmodule endmodule

View File

@ -37,12 +37,11 @@ module privdec (
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic STATUS_TSR, input logic STATUS_TSR,
output logic IllegalInstrFaultM, output logic IllegalInstrFaultM,
output logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM); output logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM);
logic IllegalPrivilegedInstrM; logic IllegalPrivilegedInstrM;
// xRET defined in Privileged Spect 3.2.2 // xRET defined in Privileged Spect 3.2.2
assign uretM = PrivilegedM & (InstrM[31:20] == 12'b000000000010) & `N_SUPPORTED;
assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & `S_SUPPORTED & assign sretM = PrivilegedM & (InstrM[31:20] == 12'b000100000010) & `S_SUPPORTED &
PrivilegeModeW[0] & ~STATUS_TSR; PrivilegeModeW[0] & ~STATUS_TSR;
assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) & (PrivilegeModeW == `M_MODE); assign mretM = PrivilegedM & (InstrM[31:20] == 12'b001100000010) & (PrivilegeModeW == `M_MODE);
@ -50,8 +49,8 @@ module privdec (
assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000); assign ecallM = PrivilegedM & (InstrM[31:20] == 12'b000000000000);
assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001); assign ebreakM = PrivilegedM & (InstrM[31:20] == 12'b000000000001);
assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101); assign wfiM = PrivilegedM & (InstrM[31:20] == 12'b000100000101);
assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001); assign sfencevmaM = PrivilegedM & (InstrM[31:25] == 7'b0001001); // *** & (PrivilegedModeW == `M_MODE | ~STATUS_TVM); // *** does this work in U mode?
assign IllegalPrivilegedInstrM = PrivilegedM & ~(uretM|sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM); assign IllegalPrivilegedInstrM = PrivilegedM & ~(sretM|mretM|ecallM|ebreakM|wfiM|sfencevmaM);
assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM | TrappedSRETM; // *** generalize this for other instructions assign IllegalInstrFaultM = (IllegalIEUInstrFaultM & IllegalFPUInstrM) | IllegalPrivilegedInstrM | IllegalCSRAccessM | TrappedSRETM; // *** generalize this for other instructions
// *** initially, wfi is nop // *** initially, wfi is nop

View File

@ -85,11 +85,10 @@ module privileged (
logic [1:0] NextPrivilegeModeM; logic [1:0] NextPrivilegeModeM;
logic [`XLEN-1:0] CauseM, NextFaultMtvalM; logic [`XLEN-1:0] CauseM, NextFaultMtvalM;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW; logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW;
// logic [11:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW; logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW;
logic [`XLEN-1:0] MEDELEG_REGW, MIDELEG_REGW, SEDELEG_REGW, SIDELEG_REGW;
logic uretM, sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM; logic sretM, mretM, ecallM, ebreakM, wfiM, sfencevmaM;
logic IllegalCSRAccessM; logic IllegalCSRAccessM;
logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM; logic IllegalIEUInstrFaultE, IllegalIEUInstrFaultM;
logic IllegalFPUInstrM; logic IllegalFPUInstrM;
@ -103,7 +102,7 @@ module privileged (
logic STATUS_SPP, STATUS_TSR, STATUS_TW; logic STATUS_SPP, STATUS_TSR, STATUS_TW;
logic STATUS_MIE, STATUS_SIE; logic STATUS_MIE, STATUS_SIE;
logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW; logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW;
logic md, sd; logic md;
logic StallMQ; logic StallMQ;
@ -112,36 +111,28 @@ module privileged (
/////////////////////////////////////////// ///////////////////////////////////////////
// get bits of DELEG registers based on CAUSE // get bits of DELEG registers based on CAUSE
// assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[3:0]] : MEDELEG_REGW[CauseM[3:0]];
// assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[3:0]] : SEDELEG_REGW[CauseM[3:0]]; // depricated
assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; assign md = CauseM[`XLEN-1] ? MIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : MEDELEG_REGW[CauseM[`LOG_XLEN-1:0]];
assign sd = CauseM[`XLEN-1] ? SIDELEG_REGW[CauseM[`LOG_XLEN-1:0]] : SEDELEG_REGW[CauseM[`LOG_XLEN-1:0]]; // depricated
// PrivilegeMode FSM // PrivilegeMode FSM
always_comb begin always_comb begin
TrappedSRETM = 0; TrappedSRETM = 0;
if (mretM) NextPrivilegeModeM = STATUS_MPP; if (mretM) NextPrivilegeModeM = STATUS_MPP;
else if (sretM) else if (sretM)
if (STATUS_TSR & PrivilegeModeW == `S_MODE) begin if (STATUS_TSR & PrivilegeModeW == `S_MODE) begin
TrappedSRETM = 1; TrappedSRETM = 1;
NextPrivilegeModeM = PrivilegeModeW; NextPrivilegeModeM = PrivilegeModeW;
end else NextPrivilegeModeM = {1'b0, STATUS_SPP}; end else NextPrivilegeModeM = {1'b0, STATUS_SPP};
else if (uretM) NextPrivilegeModeM = `U_MODE;
else if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8) else if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
if (PrivilegeModeW == `U_MODE) if (`S_SUPPORTED & md & (PrivilegeModeW == `U_MODE | PrivilegeModeW == `S_MODE))
if (`N_SUPPORTED & `U_SUPPORTED & md & sd) NextPrivilegeModeM = `U_MODE; NextPrivilegeModeM = `S_MODE;
else if (`S_SUPPORTED & md) NextPrivilegeModeM = `S_MODE; else NextPrivilegeModeM = `M_MODE;
else NextPrivilegeModeM = `M_MODE; end else NextPrivilegeModeM = PrivilegeModeW;
else if (PrivilegeModeW == `S_MODE)
if (`S_SUPPORTED & md) NextPrivilegeModeM = `S_MODE;
else NextPrivilegeModeM = `M_MODE;
else NextPrivilegeModeM = `M_MODE;
end else NextPrivilegeModeM = PrivilegeModeW;
end end
// *** WFI could be implemented here and depends on TW
flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW); flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, `M_MODE, PrivilegeModeW);
// *** WFI could be implemented here and depends on TW
/////////////////////////////////////////// ///////////////////////////////////////////
// decode privileged instructions // decode privileged instructions
/////////////////////////////////////////// ///////////////////////////////////////////
@ -149,7 +140,7 @@ module privileged (
privdec pmd(.InstrM(InstrM[31:20]), privdec pmd(.InstrM(InstrM[31:20]),
.PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM, .PrivilegedM, .IllegalIEUInstrFaultM, .IllegalCSRAccessM, .IllegalFPUInstrM, .TrappedSRETM,
.PrivilegeModeW, .STATUS_TSR, .IllegalInstrFaultM, .PrivilegeModeW, .STATUS_TSR, .IllegalInstrFaultM,
.uretM, .sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM); .sretM, .mretM, .ecallM, .ebreakM, .wfiM, .sfencevmaM);
/////////////////////////////////////////// ///////////////////////////////////////////
// Control and Status Registers // Control and Status Registers
@ -158,7 +149,7 @@ module privileged (
.FlushE, .FlushM, .FlushW, .FlushE, .FlushM, .FlushW,
.StallE, .StallM, .StallW, .StallE, .StallM, .StallW,
.InstrM, .PCM, .SrcAM, .InstrM, .PCM, .SrcAM,
.CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM, .uretM, .CSRReadM, .CSRWriteM, .TrapM, .MTrapM, .STrapM, .UTrapM, .mretM, .sretM,
.TimerIntM, .ExtIntM, .SwIntM, .TimerIntM, .ExtIntM, .SwIntM,
.MTIME_CLINT, .MTIME_CLINT,
.InstrValidM, .FRegWriteM, .LoadStallD, .InstrValidM, .FRegWriteM, .LoadStallD,
@ -167,8 +158,8 @@ module privileged (
.NextPrivilegeModeM, .PrivilegeModeW, .NextPrivilegeModeM, .PrivilegeModeW,
.CauseM, .NextFaultMtvalM, .STATUS_MPP, .CauseM, .NextFaultMtvalM, .STATUS_MPP,
.STATUS_SPP, .STATUS_TSR, .STATUS_SPP, .STATUS_TSR,
.MEPC_REGW, .SEPC_REGW, .UEPC_REGW, .UTVEC_REGW, .STVEC_REGW, .MTVEC_REGW, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MEDELEG_REGW, .MIDELEG_REGW, .SEDELEG_REGW, .SIDELEG_REGW, .MEDELEG_REGW, .MIDELEG_REGW,
.SATP_REGW, .SATP_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MIE, .STATUS_SIE,
@ -216,9 +207,9 @@ module privileged (
.BreakpointFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, .BreakpointFaultM, .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM,
.LoadAccessFaultM, .StoreAmoAccessFaultM, .EcallFaultM, .InstrPageFaultM, .LoadAccessFaultM, .StoreAmoAccessFaultM, .EcallFaultM, .InstrPageFaultM,
.LoadPageFaultM, .StoreAmoPageFaultM, .LoadPageFaultM, .StoreAmoPageFaultM,
.mretM, .sretM, .uretM, .mretM, .sretM,
.PrivilegeModeW, .NextPrivilegeModeM, .PrivilegeModeW, .NextPrivilegeModeM,
.MEPC_REGW, .SEPC_REGW, .UEPC_REGW, .UTVEC_REGW, .STVEC_REGW, .MTVEC_REGW, .MEPC_REGW, .SEPC_REGW, .STVEC_REGW, .MTVEC_REGW,
.MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW, .MIP_REGW, .MIE_REGW, .SIP_REGW, .SIE_REGW,
.STATUS_MIE, .STATUS_SIE, .STATUS_MIE, .STATUS_SIE,
.PCM, .PCM,

View File

@ -38,9 +38,9 @@ module trap (
(* mark_debug = "true" *) input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM, (* mark_debug = "true" *) input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
(* mark_debug = "true" *) input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM, (* mark_debug = "true" *) input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
(* mark_debug = "true" *) input logic LoadPageFaultM, StoreAmoPageFaultM, (* mark_debug = "true" *) input logic LoadPageFaultM, StoreAmoPageFaultM,
(* mark_debug = "true" *) input logic mretM, sretM, uretM, (* mark_debug = "true" *) input logic mretM, sretM,
input logic [1:0] PrivilegeModeW, NextPrivilegeModeM, input logic [1:0] PrivilegeModeW, NextPrivilegeModeM,
(* mark_debug = "true" *) input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, UEPC_REGW, UTVEC_REGW, STVEC_REGW, MTVEC_REGW, (* mark_debug = "true" *) input logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW, STVEC_REGW, MTVEC_REGW,
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW, (* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, SIP_REGW, SIE_REGW,
input logic STATUS_MIE, STATUS_SIE, input logic STATUS_MIE, STATUS_SIE,
input logic [`XLEN-1:0] PCM, input logic [`XLEN-1:0] PCM,
@ -84,15 +84,13 @@ module trap (
assign TrapM = ExceptionM | InterruptM; // *** clean this up later DH assign TrapM = ExceptionM | InterruptM; // *** clean this up later DH
assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE); assign MTrapM = TrapM & (NextPrivilegeModeM == `M_MODE);
assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED; assign STrapM = TrapM & (NextPrivilegeModeM == `S_MODE) & `S_SUPPORTED;
assign UTrapM = TrapM & (NextPrivilegeModeM == `U_MODE) & `N_SUPPORTED; assign RetM = mretM | sretM;
assign RetM = mretM | sretM | uretM;
always_comb always_comb
if (NextPrivilegeModeM == `U_MODE) PrivilegedTrapVector = UTVEC_REGW; if (NextPrivilegeModeM == `S_MODE) PrivilegedTrapVector = STVEC_REGW;
else if (NextPrivilegeModeM == `S_MODE) PrivilegedTrapVector = STVEC_REGW; else PrivilegedTrapVector = MTVEC_REGW;
else PrivilegedTrapVector = MTVEC_REGW;
// Handle vectored traps (when mtvec/stvec/utvec csr value has bits [1:0] == 01) // Handle vectored traps (when mtvec/stvec csr value has bits [1:0] == 01)
// For vectored traps, set program counter to _tvec value + 4 times the cause code // For vectored traps, set program counter to _tvec value + 4 times the cause code
// //
// POSSIBLE OPTIMIZATION: // POSSIBLE OPTIMIZATION:
@ -115,7 +113,6 @@ module trap (
always_comb always_comb
if (mretM) PrivilegedNextPCM = MEPC_REGW; if (mretM) PrivilegedNextPCM = MEPC_REGW;
else if (sretM) PrivilegedNextPCM = SEPC_REGW; else if (sretM) PrivilegedNextPCM = SEPC_REGW;
else if (uretM) PrivilegedNextPCM = UEPC_REGW;
else PrivilegedNextPCM = PrivilegedVectoredTrapVector; else PrivilegedNextPCM = PrivilegedVectoredTrapVector;
// Cause priority defined in table 3.7 of 20190608 privileged spec // Cause priority defined in table 3.7 of 20190608 privileged spec

View File

@ -90,12 +90,14 @@ module uncore (
// unswizzle HSEL signals // unswizzle HSEL signals
assign {HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[7:0]; assign {HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[7:0];
// subword accesses: converts HWDATAIN to HWDATA // subword accesses: converts HWDATAIN to HWDATA only if no dtim or cache.
// *** can this be merged into LSU instead of replicated? if(`DMEM == `MEM_BUS)
subwordwrite sww( subwordwrite sww(
.HRDATA, .HRDATA,
.HADDRD, .HSIZED, .HADDRD, .HSIZED,
.HWDATAIN, .HWDATA); .HWDATAIN, .HWDATA);
else assign HWDATA = HWDATAIN;
// generate // generate
// on-chip RAM // on-chip RAM

View File

@ -163,7 +163,7 @@ module wallypipelinedcore (
logic ICacheMiss; logic ICacheMiss;
logic ICacheAccess; logic ICacheAccess;
logic BreakpointFaultM, EcallFaultM; logic BreakpointFaultM, EcallFaultM;
logic InstrDAPageFaultF;
ifu ifu( ifu ifu(
.clk, .reset, .clk, .reset,
@ -201,8 +201,8 @@ module wallypipelinedcore (
// pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H // pmp/pma (inside mmu) signals. *** temporarily from AHB bus but eventually replace with internal versions pre H
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.InstrAccessFaultF .InstrAccessFaultF,
.InstrDAPageFaultF
); // instruction fetch unit: PC, branch prediction, instruction cache ); // instruction fetch unit: PC, branch prediction, instruction cache
@ -276,6 +276,7 @@ module wallypipelinedcore (
.LoadAccessFaultM, // connects to privilege .LoadAccessFaultM, // connects to privilege
.StoreAmoMisalignedFaultM, // connects to privilege .StoreAmoMisalignedFaultM, // connects to privilege
.StoreAmoAccessFaultM, // connects to privilege .StoreAmoAccessFaultM, // connects to privilege
.InstrDAPageFaultF,
.PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .PCF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF,
.LSUStallM); // change to LSUStallM .LSUStallM); // change to LSUStallM

1
pipelined/srt/lint-srt Executable file
View File

@ -0,0 +1 @@
verilator --lint-only --top-module srt srt.sv -I../config/rv64gc -I../config/shared ../src/generic/*.sv ../src/generic/flop/*.sv

View File

@ -1 +1 @@
vsim -c -do srt.do vsim -c -do "do srt.do"

View File

@ -17,7 +17,7 @@ if [file exists work] {
} }
vlib work vlib work
vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv vlog +incdir+../config/rv64gc +incdir+../config/shared srt.sv testbench.sv ../src/generic/flop/flop*.sv ../src/generic/mux.sv ../src/fpu/unpacking.sv
vopt +acc work.testbench -o workopt vopt +acc work.testbench -o workopt
vsim workopt vsim workopt

View File

@ -273,135 +273,3 @@ module finaladd(
assign #1 r = diff[54] ? diff[53:2] : diff[52:1]; assign #1 r = diff[54] ? diff[53:2] : diff[52:1];
endmodule endmodule
/////////////
// counter //
/////////////
module counter(input logic clk,
input logic req,
output logic done);
logic [5:0] count;
// This block of control logic sequences the divider
// through its iterations. You may modify it if you
// build a divider which completes in fewer iterations.
// You are not responsible for the (trivial) circuit
// design of the block.
always @(posedge clk)
begin
if (count == 54) done <= #1 1;
else if (done | req) done <= #1 0;
if (req) count <= #1 0;
else count <= #1 count+1;
end
endmodule
///////////
// clock //
///////////
module clock(clk);
output clk;
// Internal clk signal
logic clk;
endmodule
//////////
// testbench //
//////////
module testbench;
logic clk;
logic req;
logic done;
logic [51:0] a;
logic [51:0] b;
logic [51:0] r;
logic [54:0] rp, rm; // positive quotient digits
// Test parameters
parameter MEM_SIZE = 40000;
parameter MEM_WIDTH = 52+52+52;
`define memr 51:0
`define memb 103:52
`define mema 155:104
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
logic [MEM_WIDTH-1:0] Vec; // Verilog doesn't allow direct access to a
// bit field of an array
logic [51:0] correctr, nextr, diffn, diffp;
integer testnum, errors;
// Divider
srt #(52) srt(.clk, .Start(req),
.Stall(1'b0), .Flush(1'b0),
.SrcXFrac(a), .SrcYFrac(b),
.SrcA('0), .SrcB('0), .Fmt(2'b00),
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0),
.Quot(r), .Rem(), .Flags());
// Counter
counter counter(clk, req, done);
initial
forever
begin
clk = 1; #17;
clk = 0; #16;
end
// Read test vectors from disk
initial
begin
testnum = 0;
errors = 0;
$readmemh ("testvectors", Tests);
Vec = Tests[testnum];
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
req <= #5 1;
end
// Apply directed test vectors read from file.
always @(posedge clk)
begin
if (done)
begin
req <= #5 1;
diffp = correctr - r;
diffn = r - correctr;
if (($signed(diffn) > 1) | ($signed(diffp) > 1)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("result was %h, should be %h %h %h\n", r, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (a === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
end
end
if (req)
begin
req <= #5 0;
correctr = nextr;
testnum = testnum+1;
Vec = Tests[testnum];
$display("a = %h b = %h",a,b);
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
end
end
endmodule

View File

@ -11,7 +11,52 @@
// This Verilog file models a radix 2 SRT divider which // This Verilog file models a radix 2 SRT divider which
// produces one quotient digit per cycle. The divider // produces one quotient digit per cycle. The divider
// keeps the partial remainder in carry-save form. // keeps the partial remainder in carry-save form.
`include "wally-config.vh"
// will also be used for integer division so keep in mind when naming modules/signals
/////////////////
// srt_divide //
////////////////
module srt_divide(input logic clk,
input logic req,
input logic sqrt, // 1 to compute sqrt(a), 0 to compute a/b
input logic [63:0] a, b, // input numbers
output logic [54:0] rp, rm,
output logic [10:0] expE);
// output logic from Unpackers
logic XSgnE, YSgnE, ZSgnE;
logic [10:0] XExpE, YExpE, ZExpE; // exponent
logic [52:0] XManE, YManE, ZManE;
logic XNormE;
logic XNaNE, YNaNE, ZNaNE;
logic XSNaNE, YSNaNE, ZSNaNE;
logic XDenormE, YDenormE, ZDenormE; // denormals
logic XZeroE, YZeroE, ZZeroE;
logic [10:0] BiasE; // currrently hardcoded, will probs be removed
logic XInfE, YInfE, ZInfE;
logic XExpMaxE; // says exponent is all ones, can ignore
// have Unpackers
// have mantissa divider
// exponent divider
// hopefully having the .* here works for unpacker --- nope it doesn't
unpack unpacking(a, b, 0, 1'b1, 0, XSgnE, YSgnE, ZSgnE, XExpE, YExpE, ZExpE, XManE, YManE, ZManE, XNormE,XNaNE, YNaNE, ZNaNE,XSNaNE, YSNaNE, ZSNaNE,XDenormE, YDenormE, ZDenormE,XZeroE, YZeroE, ZZeroE,BiasE,XInfE, YInfE, ZInfE,XExpMaxE);
srt srt(clk, req, XManE[51:0], YManE[51:0], rp, rm);
exp exp(XexpE, YExpE, expE);
endmodule
// exponent module
// first iteration
module exp(input [10:0] e1, e2,
output [10:0] e); // for a 64 bit number, exponent section is 11 bits
assign e = (e1 - e2) + 11'd1023; // bias is hardcoded
endmodule
///////// /////////
// srt // // srt //
///////// /////////
@ -39,12 +84,12 @@ module srt(input logic clk,
// When start is asserted, the inputs are loaded into the divider. // When start is asserted, the inputs are loaded into the divider.
// Otherwise, the divisor is retained and the partial remainder // Otherwise, the divisor is retained and the partial remainder
// is fed back for the next iteration. // is fed back for the next iteration.
mux2 psmux({psa[54:0], 1'b0}, {4'b0001, a}, req, psn); mux2_special psmux({psa[54:0], 1'b0}, {4'b0001, a}, req, psn);
flop psflop(clk, psn, ps); flop_special psflop(clk, psn, ps);
mux2 pcmux({pca[54:0], 1'b0}, 56'b0, req, pcn); mux2_special pcmux({pca[54:0], 1'b0}, 56'b0, req, pcn);
flop pcflop(clk, pcn, pc); flop_special pcflop(clk, pcn, pc);
mux2 dmux(d, {4'b0001, b}, req, dn); mux2_special dmux(d, {4'b0001, b}, req, dn);
flop dflop(clk, dn, d); flop_special dflop(clk, dn, d);
// Quotient Selection logic // Quotient Selection logic
// Given partial remainder, select quotient of +1, 0, or -1 (qp, qz, pm) // Given partial remainder, select quotient of +1, 0, or -1 (qp, qz, pm)
@ -54,7 +99,7 @@ module srt(input logic clk,
// Divisor Selection logic // Divisor Selection logic
inv dinv(d, d_b); inv dinv(d, d_b);
mux3 divisorsel(d_b, 56'b0, d, qp, qz, qm, dsel); mux3_special divisorsel(d_b, 56'b0, d, qp, qz, qm, dsel);
// Partial Product Generation // Partial Product Generation
csa csa(ps, pc, dsel, qp, psa, pca); csa csa(ps, pc, dsel, qp, psa, pca);
@ -63,7 +108,7 @@ endmodule
////////// //////////
// mux2 // // mux2 //
////////// //////////
module mux2(input logic [55:0] in0, in1, module mux2_special(input logic [55:0] in0, in1,
input logic sel, input logic sel,
output logic [55:0] out); output logic [55:0] out);
@ -73,7 +118,7 @@ endmodule
////////// //////////
// flop // // flop //
////////// //////////
module flop(clk, in, out); module flop_special(clk, in, out);
input clk; input clk;
input [55:0] in; input [55:0] in;
output [55:0] out; output [55:0] out;
@ -159,9 +204,9 @@ module inv(input logic [55:0] in,
endmodule endmodule
////////// //////////
// mux3 // // mux3_special //
////////// //////////
module mux3(in0, in1, in2, sel0, sel1, sel2, out); module mux3_special(in0, in1, in2, sel0, sel1, sel2, out);
input [55:0] in0; input [55:0] in0;
input [55:0] in1; input [55:0] in1;
input [55:0] in2; input [55:0] in2;
@ -271,6 +316,24 @@ module testbench;
logic [51:0] b; logic [51:0] b;
logic [51:0] r; logic [51:0] r;
logic [54:0] rp, rm; // positive quotient digits logic [54:0] rp, rm; // positive quotient digits
//input logic [63:0] X, Y, Z, - numbers
//input logic FmtE, ---- format, 1 is for double precision, 0 is single
//input logic [2:0] FOpCtrlE, ---- controling operations for FPU, 1 is sqrt, 0 is divide
// all variables are commented in fpu.sv
// output logic from Unpackers
logic XSgnE, YSgnE, ZSgnE;
logic [10:0] XExpE, YExpE, ZExpE; // exponent
logic [52:0] XManE, YManE, ZManE;
logic XNormE;
logic XNaNE, YNaNE, ZNaNE;
logic XSNaNE, YSNaNE, ZSNaNE;
logic XDenormE, YDenormE, ZDenormE; // denormals
logic XZeroE, YZeroE, ZZeroE;
logic [10:0] BiasE; // currrently hardcoded, will probs be removed
logic XInfE, YInfE, ZInfE;
logic XExpMaxE; // says exponent is all ones, can ignore
// Test parameters // Test parameters
parameter MEM_SIZE = 40000; parameter MEM_SIZE = 40000;
@ -287,8 +350,15 @@ module testbench;
logic [51:0] correctr, nextr; logic [51:0] correctr, nextr;
integer testnum, errors; integer testnum, errors;
// Unpackers
unpacking unpack(.X({12'b100010000010,a}), .Y({12'b100010000001,b}), .Z(0), .FmtE(1'b1), .FOpCtrlE(0), .*);
// Divider // Divider
srt srt(clk, req, a, b, rp, rm); srt srt(.clk(clk), .req(req), .sqrt(1'b0), .a(XManE[51:0]), .b(YManE[51:0]), .rp(rp),.rm(rm));
//srt srt(.clk(clk), .req(req), .sqrt(1'b0), .a(a), .b(b), .rp(rp),.rm(rm));
// Divider + unpacker
// Final adder converts quotient digits to 2's complement & normalizes // Final adder converts quotient digits to 2's complement & normalizes
finaladd finaladd(rp, rm, r); finaladd finaladd(rp, rm, r);
@ -326,7 +396,9 @@ module testbench;
begin begin
req <= #5 1; req <= #5 1;
$display("result was %h, should be %h\n", r, correctr); $display("result was %h, should be %h\n", r, correctr);
if ((correctr - r) > 1) // check if accurate to 1 ulp //if (abs(correctr - r) > 1) // check if accurate to 1 ulp
// giving error "srt_stanford.sv(395): (vopt-7063) Failed to find 'abs' in hierarchical name 'abs'."
if (correctr - r > 1) // check if accurate to 1 ulp
begin begin
errors = errors+1; errors = errors+1;
$display("failed\n"); $display("failed\n");

132
pipelined/srt/testbench.sv Normal file
View File

@ -0,0 +1,132 @@
/////////////
// counter //
/////////////
module counter(input logic clk,
input logic req,
output logic done);
logic [5:0] count;
// This block of control logic sequences the divider
// through its iterations. You may modify it if you
// build a divider which completes in fewer iterations.
// You are not responsible for the (trivial) circuit
// design of the block.
always @(posedge clk)
begin
if (count == 54) done <= #1 1;
else if (done | req) done <= #1 0;
if (req) count <= #1 0;
else count <= #1 count+1;
end
endmodule
///////////
// clock //
///////////
module clock(clk);
output clk;
// Internal clk signal
logic clk;
endmodule
//////////
// testbench //
//////////
module testbench;
logic clk;
logic req;
logic done;
logic [51:0] a;
logic [51:0] b;
logic [51:0] r;
logic [54:0] rp, rm; // positive quotient digits
// Test parameters
parameter MEM_SIZE = 40000;
parameter MEM_WIDTH = 52+52+52;
`define memr 51:0
`define memb 103:52
`define mema 155:104
// Test logicisters
logic [MEM_WIDTH-1:0] Tests [0:MEM_SIZE]; // Space for input file
logic [MEM_WIDTH-1:0] Vec; // Verilog doesn't allow direct access to a
// bit field of an array
logic [51:0] correctr, nextr, diffn, diffp;
integer testnum, errors;
// Divider
srt #(52) srt(.clk, .Start(req),
.Stall(1'b0), .Flush(1'b0),
.SrcXFrac(a), .SrcYFrac(b),
.SrcA('0), .SrcB('0), .Fmt(2'b00),
.W64(1'b0), .Signed(1'b0), .Int(1'b0), .Sqrt(1'b0),
.Quot(r), .Rem(), .Flags());
// Counter
counter counter(clk, req, done);
initial
forever
begin
clk = 1; #17;
clk = 0; #16;
end
// Read test vectors from disk
initial
begin
testnum = 0;
errors = 0;
$readmemh ("testvectors", Tests);
Vec = Tests[testnum];
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
req <= #5 1;
end
// Apply directed test vectors read from file.
always @(posedge clk)
begin
if (done)
begin
req <= #5 1;
diffp = correctr - r;
diffn = r - correctr;
if (($signed(diffn) > 1) | ($signed(diffp) > 1)) // check if accurate to 1 ulp
begin
errors = errors+1;
$display("result was %h, should be %h %h %h\n", r, correctr, diffn, diffp);
$display("failed\n");
$stop;
end
if (a === 52'hxxxxxxxxxxxxx)
begin
$display("%d Tests completed successfully", testnum);
$stop;
end
end
if (req)
begin
req <= #5 0;
correctr = nextr;
testnum = testnum+1;
Vec = Tests[testnum];
$display("a = %h b = %h",a,b);
a = Vec[`mema];
b = Vec[`memb];
nextr = Vec[`memr];
end
end
endmodule

View File

@ -28,7 +28,7 @@ double random_input(void);
void main(void) void main(void)
{ {
FILE *fptr; FILE *fptr;
double a, b, r; double x1, x2, a, b, r;
double list[ENTRIES] = {1, 1.5, 1.25, 1.125, 1.0625, double list[ENTRIES] = {1, 1.5, 1.25, 1.125, 1.0625,
1.75, 1.875, 1.99999, 1.75, 1.875, 1.99999,
1.1, 1.2, 1.01, 1.001, 1.0001, 1.1, 1.2, 1.01, 1.001, 1.0001,
@ -63,6 +63,7 @@ void main(void)
void output(FILE *fptr, double a, double b, double r) void output(FILE *fptr, double a, double b, double r)
{ {
printhex(fptr, a); printhex(fptr, a);
fprintf(fptr, "_"); fprintf(fptr, "_");
printhex(fptr, b); printhex(fptr, b);

View File

@ -102,7 +102,6 @@ module instrNameDecTB(
10'b1101111_???: name = "JAL"; 10'b1101111_???: name = "JAL";
10'b1110011_000: if (imm == 0) name = "ECALL"; 10'b1110011_000: if (imm == 0) name = "ECALL";
else if (imm == 1) name = "EBREAK"; else if (imm == 1) name = "EBREAK";
else if (imm == 2) name = "URET";
else if (imm == 258) name = "SRET"; else if (imm == 258) name = "SRET";
else if (imm == 770) name = "MRET"; else if (imm == 770) name = "MRET";
else if (funct7 == 9) name = "SFENCE.VMA"; else if (funct7 == 9) name = "SFENCE.VMA";

View File

@ -1483,13 +1483,13 @@ string imperas32f[] = '{
string wally64priv[] = '{ string wally64priv[] = '{
`WALLYTEST, `WALLYTEST,
"rv64i_m/privilege/WALLY-MMU-SV39", "30A0", "rv64i_m/privilege/WALLY-MMU-SV39", "40A0",
"rv64i_m/privilege/WALLY-MMU-SV48", "30A0", "rv64i_m/privilege/WALLY-MMU-SV48", "40A0",
"rv64i_m/privilege/WALLY-PMP", "30A0", "rv64i_m/privilege/WALLY-PMP", "40A0",
"rv64i_m/privilege/WALLY-PMA", "30A0", "rv64i_m/privilege/WALLY-PMA", "40A0",
"rv64i_m/privilege/WALLY-minfo-01", "30A0", "rv64i_m/privilege/WALLY-minfo-01", "40A0",
"rv64i_m/privilege/WALLY-CSR-permission-s-01", "40A0", "rv64i_m/privilege/WALLY-CSR-permission-s-01", "50A0",
"rv64i_m/privilege/WALLY-CSR-permission-u-01", "40A0" "rv64i_m/privilege/WALLY-CSR-permission-u-01", "50A0"
}; };
string wally64periph[] = '{ string wally64periph[] = '{
@ -1548,9 +1548,11 @@ string wally32i[] = '{
string wally32priv[] = '{ string wally32priv[] = '{
`WALLYTEST, `WALLYTEST,
"rv32i_m/privilege/WALLY-MMU-SV32", "3080", "rv32i_m/privilege/WALLY-MMU-SV32", "4080",
"rv32i_m/privilege/WALLY-PMP", "3080", "rv32i_m/privilege/WALLY-PMP", "4080",
"rv32i_m/privilege/WALLY-PMA", "3080" "rv32i_m/privilege/WALLY-CSR-permission-s-01", "5080",
"rv32i_m/privilege/WALLY-CSR-permission-u-01", "5080",
"rv32i_m/privilege/WALLY-minfo-01", "4080"
}; };
string wally32periph[] = '{ string wally32periph[] = '{

View File

@ -7,17 +7,53 @@ NAME := synth
export DESIGN ?= wallypipelinedcore export DESIGN ?= wallypipelinedcore
export FREQ ?= 500 export FREQ ?= 500
export CONFIG ?= rv32e export CONFIG ?= rv32e
export TECH ?= 130 # sky130 and sky90 presently supported
export TECH ?= sky130
# MAXCORES allows parallel compilation, which is faster but less CPU-efficient
# Avoid when doing sweeps of many optimization points in parallel
export MAXCORES ?= 4
# MAXOPT turns on flattening, boundary optimization, and retiming
# The output netlist is hard to interpret, but significantly better PPA
export MAXOPT ?= 0
time := $(shell date +%F-%H-%M) time := $(shell date +%F-%H-%M)
hash := $(shell git rev-parse --short HEAD) hash := $(shell git rev-parse --short HEAD)
export OUTPUTDIR := runs/$(DESIGN)_$(CONFIG)_$(TECH)nm_$(FREQ)_MHz_$(time)_$(hash) export OUTPUTDIR := runs/$(DESIGN)_$(CONFIG)_$(TECH)nm_$(FREQ)_MHz_$(time)_$(hash)
export SAIFPOWER ?= 0 export SAIFPOWER ?= 0
CONFIGDIR ?= ~/riscv-wally/pipelined/config
#CONFIGS ?= $(shell find $(CONFIGDIR) -name "rv*")
CONFIGS ?= ("rv32e", "rv32ic")
print:
echo "files in $(CONFIGDIR) are $(CONFIGS)."
default: default:
@echo "Basic synthesis procedure for OSU/HMC/UNLV:" @echo "Basic synthesis procedure for Wally:"
@echo " adapt Makefile to your liking..." @echo " Invoke with make synth"
@echo
test: rv%
echo "Running test on $<"
rv%.log: rv%
echo $<
flavors:
rm -rf $(CONFIGDIR)/rv32em
cp -r $(CONFIGDIR)/rv32e $(CONFIGDIR)/rv32em
sed -i 's/h00000010/h00001010/' $(CONFIGDIR)/rv32em/wally-config.vh
# rv32e, 32ic, 32gc 64ic, 64gc
# 64gc - FPU
# PMP16
# PMP0
# No virtual memory
# Muldiv
allsynth:
make flavors
make synth DESIGN=wallypipelinedcore CONFIG=rv32e TECH=sky90 FREQ=500 MAXCORES=1
make synth DESIGN=wallypipelinedcore CONFIG=rv32em TECH=sky90 FREQ=500 MAXCORES=1
synth: synth:
@echo "DC Synthesis" @echo "DC Synthesis"

View File

@ -10,6 +10,9 @@ suppress_message {VER-130}
suppress_message {VER-281} suppress_message {VER-281}
suppress_message {VER-173} suppress_message {VER-173}
# Enable Multicore
set_host_options -max_cores $::env(MAXCORES)
# get outputDir from environment (Makefile) # get outputDir from environment (Makefile)
set outputDir $::env(OUTPUTDIR) set outputDir $::env(OUTPUTDIR)
set cfgName $::env(CONFIG) set cfgName $::env(CONFIG)
@ -17,6 +20,7 @@ set cfgName $::env(CONFIG)
set hdl_src "../pipelined/src" set hdl_src "../pipelined/src"
set cfg "${hdl_src}/../config/${cfgName}/wally-config.vh" set cfg "${hdl_src}/../config/${cfgName}/wally-config.vh"
set saifpower $::env(SAIFPOWER) set saifpower $::env(SAIFPOWER)
set maxopt $::env(MAXOPT)
eval file copy -force ${cfg} {hdl/} eval file copy -force ${cfg} {hdl/}
eval file copy -force ${cfg} $outputDir eval file copy -force ${cfg} $outputDir
@ -65,7 +69,7 @@ if { $saifpower == 1 } {
# Set reset false path # Set reset false path
set_false_path -from [get_ports reset] set_false_path -from [get_ports reset]
# Set Frequency in [MHz] or [ps] # Set Frequency in [MHz] or period in [ns]
set my_clock_pin clk set my_clock_pin clk
set my_uncertainty 0.0 set my_uncertainty 0.0
set my_clk_freq_MHz $::env(FREQ) set my_clk_freq_MHz $::env(FREQ)
@ -84,13 +88,20 @@ if { $find_clock != [list] } {
create_clock -period $my_period -name $my_clk create_clock -period $my_period -name $my_clk
} }
# Optimize paths that are close to critical
set_critical_range [expr $my_period*0.05] $current_design
# Partitioning - flatten or hierarchically synthesize # Partitioning - flatten or hierarchically synthesize
# ungroup -all -flatten -simple_names if { $maxopt == 1 } {
ungroup -all -flatten -simple_names
}
# Set input pins except clock # Set input pins except clock
set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]] set all_in_ex_clk [remove_from_collection [all_inputs] [get_ports $my_clk]]
# Specifies delays be propagated through the clock network # Specifies delays be propagated through the clock network
# This is getting optimized poorly in the current flow, causing a lot of clock skew
# and unrealistic bad timing results.
# set_propagated_clock [get_clocks $my_clk] # set_propagated_clock [get_clocks $my_clk]
# Setting constraints on input ports # Setting constraints on input ports
@ -101,8 +112,8 @@ if {$tech == "sky130"} {
} }
# Set input/output delay # Set input/output delay
set_input_delay 0.0 -max -clock $my_clk $all_in_ex_clk set_input_delay 0.1 -max -clock $my_clk $all_in_ex_clk
set_output_delay 0.0 -max -clock $my_clk [all_outputs] set_output_delay 0.1 -max -clock $my_clk [all_outputs]
# Setting load constraint on output ports # Setting load constraint on output ports
if {$tech == "sky130"} { if {$tech == "sky130"} {
@ -120,7 +131,7 @@ set_wire_load_mode "top"
# Set fanout # Set fanout
set_max_fanout 6 $all_in_ex_clk set_max_fanout 6 $all_in_ex_clk
# Fix hold time violations # Fix hold time violations (DH: this doesn't seem to be working right now)
#set_fix_hold [all_clocks] #set_fix_hold [all_clocks]
# Deal with constants and buffers to isolate ports # Deal with constants and buffers to isolate ports
@ -132,11 +143,16 @@ set_fix_multiple_port_nets -all -buffer_constants
# group_path -name COMBO -from [all_inputs] -to [all_outputs] # group_path -name COMBO -from [all_inputs] -to [all_outputs]
# Save Unmapped Design # Save Unmapped Design
set filename [format "%s%s%s%s" $outputDir "/unmapped/" $my_toplevel ".ddc"] #set filename [format "%s%s%s%s" $outputDir "/unmapped/" $my_toplevel ".ddc"]
write_file -format ddc -hierarchy -o $filename #write_file -format ddc -hierarchy -o $filename
# Compile statements # Compile statements
compile_ultra -no_seq_output_inversion -no_boundary_optimization if { $maxopt == 1 } {
compile_ultra -retime
optimize_registers
} else {
compile_ultra -no_seq_output_inversion -no_boundary_optimization
}
# Eliminate need for assign statements (yuck!) # Eliminate need for assign statements (yuck!)
set verilogout_no_tri true set verilogout_no_tri true
@ -160,7 +176,7 @@ redirect $filename {report_constraint -all_violators}
redirect $outputDir/reports/check_design.rpt { check_design } redirect $outputDir/reports/check_design.rpt { check_design }
# Report Final Netlist (Hierarchical) # Report Final Netlist (Hierarchical)
set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".vh"] set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sv"]
write_file -f verilog -hierarchy -output $filename write_file -f verilog -hierarchy -output $filename
set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdc"] set filename [format "%s%s%s%s" $outputDir "/mapped/" $my_toplevel ".sdc"]
@ -178,14 +194,17 @@ redirect $filename { report_qor }
# Report Timing # Report Timing
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_reportpath.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_reportpath.rep"]
redirect $filename { report_path_group } #redirect $filename { report_path_group }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_report_clock.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_report_clock.rep"]
redirect $filename { report_clock } # redirect $filename { report_clock }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_timing.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_timing.rep"]
redirect $filename { report_timing -capacitance -transition_time -nets -nworst 1 } redirect $filename { report_timing -capacitance -transition_time -nets -nworst 1 }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_mindelay.rep"]
redirect $filename { report_timing -capacitance -transition_time -nets -delay_type min -nworst 1 }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_per_module_timing.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_per_module_timing.rep"]
redirect -append $filename { echo "\n\n\n//// Critical paths through ifu ////\n\n\n" } redirect -append $filename { echo "\n\n\n//// Critical paths through ifu ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/*} -nworst 1 } redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ifu/*} -nworst 1 }
@ -265,20 +284,14 @@ redirect -append $filename { echo "\n\n\n//// Critical path through FlushW ////\
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushW} -nworst 1 } redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/FlushW} -nworst 1 }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_ieu_timing.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_ieu_timing.rep"]
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/RD1D ////\n\n\n" } redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R1D ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/RD1D} -nworst 1 } redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R1D} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/RD2D ////\n\n\n" } redirect -append $filename { echo "\n\n\n//// Critical path through datapath/R2D ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/RD2D} -nworst 1 } redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/R2D} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/PreSrcAE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/PreSrcAE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/SrcAE ////\n\n\n" } redirect -append $filename { echo "\n\n\n//// Critical path through datapath/SrcAE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/SrcAE} -nworst 1 } redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/SrcAE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ALUResultE ////\n\n\n" } redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ALUResultE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ALUResultE} -nworst 1 } redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ALUResultE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/WriteDataE ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/WriteDataE} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through dataphath/ResultM ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/ResultM} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/WriteDataW ////\n\n\n" } redirect -append $filename { echo "\n\n\n//// Critical path through datapath/WriteDataW ////\n\n\n" }
redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/WriteDataW} -nworst 1 } redirect -append $filename { report_timing -capacitance -transition_time -nets -through {ieu/dp/WriteDataW} -nworst 1 }
redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ReadDataM ////\n\n\n" } redirect -append $filename { echo "\n\n\n//// Critical path through datapath/ReadDataM ////\n\n\n" }
@ -323,7 +336,7 @@ set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_area.rep"
redirect $filename { report_area -hierarchy -nosplit -physical -designware} redirect $filename { report_area -hierarchy -nosplit -physical -designware}
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_cell.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_cell.rep"]
redirect $filename { report_cell [get_cells -hier *] } # redirect $filename { report_cell [get_cells -hier *] }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_power.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_power.rep"]
redirect $filename { report_power -hierarchy -levels 1 } redirect $filename { report_power -hierarchy -levels 1 }
@ -332,6 +345,6 @@ set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_constrain
redirect $filename { report_constraint } redirect $filename { report_constraint }
set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_hier.rep"] set filename [format "%s%s%s%s" $outputDir "/reports/" $my_toplevel "_hier.rep"]
redirect $filename { report_hierarchy } # redirect $filename { report_hierarchy }
quit quit

View File

@ -28,15 +28,15 @@ do
echo -e "Check $(printf %-24s ${stub}) \e[33m ... IGNORE \e[39m" echo -e "Check $(printf %-24s ${stub}) \e[33m ... IGNORE \e[39m"
continue continue
fi fi
# KMG: changed diff snippet to a grep that will strip comments with '//' and '#' out of the reference file # KMG: changed diff snippet to a grep that will strip comments with '#' out of the reference file
diff --ignore-case --ignore-trailing-space --strip-trailing-cr <(grep -o '^[^//#]*' ${ref}) ${sig} &> /dev/null diff --ignore-case --ignore-trailing-space --strip-trailing-cr <(grep -o '^[^#]*' ${ref}) ${sig} &> /dev/null
if [ $? == 0 ] if [ $? == 0 ]
then then
echo -e "\e[32m ... OK \e[39m" echo -e "\e[32m ... OK \e[39m"
else else
echo -e "\e[31m ... FAIL \e[39m" echo -e "\e[31m ... FAIL \e[39m"
FAIL=$((${FAIL} + 1)) FAIL=$((${FAIL} + 1))
sdiff ${ref} ${sig} > ${dif} sdiff <(grep -o '^[^#]*' ${ref}) ${sig} > ${dif}
fi fi
done done

View File

@ -63,9 +63,8 @@ copy:
$(info !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) $(info !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
$(info <<<<<<<<<<<<<<<<<<<<<<<<<<<< COPYING REFERENCES WITHOUT SIMULATING >>>>>>>>>>>>>>>>>>>>>>>>>>>>) $(info <<<<<<<<<<<<<<<<<<<<<<<<<<<< COPYING REFERENCES WITHOUT SIMULATING >>>>>>>>>>>>>>>>>>>>>>>>>>>>)
$(info !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!) $(info !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!)
$(V) echo "Copying References without simulating for the following tests:" $(V) echo "Copying References without simulating for the following tests: $(target_tests_nosim)"
$(V) echo $(target_tests_nosim) $(V) for test in $(target_tests_nosim); do grep -o '^[^#]*' $(ref_dir)/$$test.reference_output > $(work_dir_isa)/$$test.signature.output; done
$(V) for test in $(target_tests_nosim); do grep -o '^[^//#]*' $(ref_dir)/$$test.reference_output > $(work_dir_isa)/$$test.signature.output; done
compile: $(combined_elf) compile: $(combined_elf)
run: $(target_log) run: $(target_log)

View File

@ -29,7 +29,10 @@
rv32i_sc_tests = \ rv32i_sc_tests = \
WALLY-MMU-SV32 \ WALLY-MMU-SV32 \
WALLY-PMP WALLY-PMP \
WALLY-CSR-permission-s-01 \
WALLY-CSR-permission-u-01 \
WALLY-minfo-01
target_tests_nosim = WALLY-PMA \ target_tests_nosim = WALLY-PMA \

View File

@ -0,0 +1,195 @@
///////////////////////////////////////////
//
// WALLY-CSR-permissions
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-02-05
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in S mode.
# *** several of these appear not to be implemented in the assembler?
# I get "assembler messages: error: unkown CSR" with many of them.
GOTO_S_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively
# High-bit versions storing the upper 32 bits of some CSRs for RV32
# WRITE_READ_CSR mstatush 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR menvcfgh 0xbad
# WRITE_READ_CSR mseccfgh 0xbad
WRITE_READ_CSR pmpcfg1 0xbad
WRITE_READ_CSR pmpcfg3 0xbad
WRITE_READ_CSR mcycleh 0xbad
WRITE_READ_CSR minstreth 0xbad
WRITE_READ_CSR mhpmcounter3h 0xbad
WRITE_READ_CSR mhpmcounter4h 0xbad
WRITE_READ_CSR mhpmcounter5h 0xbad
WRITE_READ_CSR mhpmcounter6h 0xbad
WRITE_READ_CSR mhpmcounter7h 0xbad
WRITE_READ_CSR mhpmcounter8h 0xbad
WRITE_READ_CSR mhpmcounter9h 0xbad
WRITE_READ_CSR mhpmcounter10h 0xbad
WRITE_READ_CSR mhpmcounter11h 0xbad
WRITE_READ_CSR mhpmcounter12h 0xbad
WRITE_READ_CSR mhpmcounter13h 0xbad
WRITE_READ_CSR mhpmcounter14h 0xbad
WRITE_READ_CSR mhpmcounter15h 0xbad
WRITE_READ_CSR mhpmcounter16h 0xbad
WRITE_READ_CSR mhpmcounter17h 0xbad
WRITE_READ_CSR mhpmcounter18h 0xbad
WRITE_READ_CSR mhpmcounter19h 0xbad
WRITE_READ_CSR mhpmcounter20h 0xbad
WRITE_READ_CSR mhpmcounter21h 0xbad
WRITE_READ_CSR mhpmcounter22h 0xbad
WRITE_READ_CSR mhpmcounter23h 0xbad
WRITE_READ_CSR mhpmcounter24h 0xbad
WRITE_READ_CSR mhpmcounter25h 0xbad
WRITE_READ_CSR mhpmcounter26h 0xbad
WRITE_READ_CSR mhpmcounter27h 0xbad
WRITE_READ_CSR mhpmcounter28h 0xbad
WRITE_READ_CSR mhpmcounter29h 0xbad
WRITE_READ_CSR mhpmcounter30h 0xbad
WRITE_READ_CSR mhpmcounter31h 0xbad
# Machine information Registers
WRITE_READ_CSR mvendorid, 0xbad
WRITE_READ_CSR marchid, 0xbad
WRITE_READ_CSR mimpid, 0xbad
WRITE_READ_CSR mhartid, 0xbad
# WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup
WRITE_READ_CSR mstatus, 0xbad
WRITE_READ_CSR misa, 0xbad
WRITE_READ_CSR medeleg, 0xbad
WRITE_READ_CSR mideleg, 0xbad
WRITE_READ_CSR mie, 0xbad
WRITE_READ_CSR mtvec, 0xbad
WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling
WRITE_READ_CSR mscratch, 0xbad
WRITE_READ_CSR mepc, 0xbad
WRITE_READ_CSR mcause, 0xbad
WRITE_READ_CSR mtval, 0xbad
WRITE_READ_CSR mip, 0xbad
# WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration
# WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection
WRITE_READ_CSR pmpcfg0, 0xbad
WRITE_READ_CSR pmpcfg2, 0xbad # there's 1 pmpcfg reg per 8 pmpaddr regs
WRITE_READ_CSR pmpaddr0, 0xbad
WRITE_READ_CSR pmpaddr1, 0xbad
WRITE_READ_CSR pmpaddr2, 0xbad
WRITE_READ_CSR pmpaddr3, 0xbad
WRITE_READ_CSR pmpaddr4, 0xbad
WRITE_READ_CSR pmpaddr5, 0xbad
WRITE_READ_CSR pmpaddr6, 0xbad
WRITE_READ_CSR pmpaddr7, 0xbad
WRITE_READ_CSR pmpaddr8, 0xbad
WRITE_READ_CSR pmpaddr9, 0xbad
WRITE_READ_CSR pmpaddr10, 0xbad
WRITE_READ_CSR pmpaddr11, 0xbad
WRITE_READ_CSR pmpaddr12, 0xbad
WRITE_READ_CSR pmpaddr13, 0xbad
WRITE_READ_CSR pmpaddr14, 0xbad
WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers
WRITE_READ_CSR mcycle, 0xbad
WRITE_READ_CSR minstret, 0xbad
WRITE_READ_CSR mhpmcounter3, 0xbad
WRITE_READ_CSR mhpmcounter4, 0xbad
WRITE_READ_CSR mhpmcounter5, 0xbad
WRITE_READ_CSR mhpmcounter6, 0xbad
WRITE_READ_CSR mhpmcounter7, 0xbad
WRITE_READ_CSR mhpmcounter8, 0xbad
WRITE_READ_CSR mhpmcounter9, 0xbad
WRITE_READ_CSR mhpmcounter10, 0xbad
WRITE_READ_CSR mhpmcounter11, 0xbad
WRITE_READ_CSR mhpmcounter12, 0xbad
WRITE_READ_CSR mhpmcounter13, 0xbad
WRITE_READ_CSR mhpmcounter14, 0xbad
WRITE_READ_CSR mhpmcounter15, 0xbad
WRITE_READ_CSR mhpmcounter16, 0xbad
WRITE_READ_CSR mhpmcounter17, 0xbad
WRITE_READ_CSR mhpmcounter18, 0xbad
WRITE_READ_CSR mhpmcounter19, 0xbad
WRITE_READ_CSR mhpmcounter20, 0xbad
WRITE_READ_CSR mhpmcounter21, 0xbad
WRITE_READ_CSR mhpmcounter22, 0xbad
WRITE_READ_CSR mhpmcounter23, 0xbad
WRITE_READ_CSR mhpmcounter24, 0xbad
WRITE_READ_CSR mhpmcounter25, 0xbad
WRITE_READ_CSR mhpmcounter26, 0xbad
WRITE_READ_CSR mhpmcounter27, 0xbad
WRITE_READ_CSR mhpmcounter28, 0xbad
WRITE_READ_CSR mhpmcounter29, 0xbad
WRITE_READ_CSR mhpmcounter30, 0xbad
WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup
WRITE_READ_CSR mcountinhibit, 0xbad
WRITE_READ_CSR mhpmevent3, 0xbad
WRITE_READ_CSR mhpmevent4, 0xbad
WRITE_READ_CSR mhpmevent5, 0xbad
WRITE_READ_CSR mhpmevent6, 0xbad
WRITE_READ_CSR mhpmevent7, 0xbad
WRITE_READ_CSR mhpmevent8, 0xbad
WRITE_READ_CSR mhpmevent9, 0xbad
WRITE_READ_CSR mhpmevent10, 0xbad
WRITE_READ_CSR mhpmevent11, 0xbad
WRITE_READ_CSR mhpmevent12, 0xbad
WRITE_READ_CSR mhpmevent13, 0xbad
WRITE_READ_CSR mhpmevent14, 0xbad
WRITE_READ_CSR mhpmevent15, 0xbad
WRITE_READ_CSR mhpmevent16, 0xbad
WRITE_READ_CSR mhpmevent17, 0xbad
WRITE_READ_CSR mhpmevent18, 0xbad
WRITE_READ_CSR mhpmevent19, 0xbad
WRITE_READ_CSR mhpmevent20, 0xbad
WRITE_READ_CSR mhpmevent21, 0xbad
WRITE_READ_CSR mhpmevent22, 0xbad
WRITE_READ_CSR mhpmevent23, 0xbad
WRITE_READ_CSR mhpmevent24, 0xbad
WRITE_READ_CSR mhpmevent25, 0xbad
WRITE_READ_CSR mhpmevent26, 0xbad
WRITE_READ_CSR mhpmevent27, 0xbad
WRITE_READ_CSR mhpmevent28, 0xbad
WRITE_READ_CSR mhpmevent29, 0xbad
WRITE_READ_CSR mhpmevent30, 0xbad
WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS
TEST_STACK_AND_DATA

View File

@ -0,0 +1,173 @@
///////////////////////////////////////////
//
// WALLY-CSR-permissions
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-02-05
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in R mode.
GOTO_U_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively
# Supervisor Trap Setup
WRITE_READ_CSR sstatus, 0xbad
WRITE_READ_CSR sie, 0xbad
WRITE_READ_CSR stvec, 0xbad
WRITE_READ_CSR scounteren, 0xbad
# Supervisor Configuration
# WRITE_READ_CSR senvcfg, 0xbad # *** these appear not to be implemented in the compile step of make???
# Supervisor Trap Handling
WRITE_READ_CSR sscratch, 0xbad
WRITE_READ_CSR sepc, 0xbad
WRITE_READ_CSR scause, 0xbad
WRITE_READ_CSR stval, 0xbad
WRITE_READ_CSR sip, 0xbad
# Supervisor Protection and Translation
WRITE_READ_CSR satp, 0xbad
# Machine information Registers
WRITE_READ_CSR mvendorid, 0xbad
WRITE_READ_CSR marchid, 0xbad
WRITE_READ_CSR mimpid, 0xbad
WRITE_READ_CSR mhartid, 0xbad
# WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup
WRITE_READ_CSR mstatus, 0xbad
WRITE_READ_CSR misa, 0xbad
WRITE_READ_CSR medeleg, 0xbad
WRITE_READ_CSR mideleg, 0xbad
WRITE_READ_CSR mie, 0xbad
WRITE_READ_CSR mtvec, 0xbad
WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling
WRITE_READ_CSR mscratch, 0xbad
WRITE_READ_CSR mepc, 0xbad
WRITE_READ_CSR mcause, 0xbad
WRITE_READ_CSR mtval, 0xbad
WRITE_READ_CSR mip, 0xbad
# WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration
# WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection
WRITE_READ_CSR pmpcfg0, 0xbad
WRITE_READ_CSR pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
WRITE_READ_CSR pmpaddr0, 0xbad
WRITE_READ_CSR pmpaddr1, 0xbad
WRITE_READ_CSR pmpaddr2, 0xbad
WRITE_READ_CSR pmpaddr3, 0xbad
WRITE_READ_CSR pmpaddr4, 0xbad
WRITE_READ_CSR pmpaddr5, 0xbad
WRITE_READ_CSR pmpaddr6, 0xbad
WRITE_READ_CSR pmpaddr7, 0xbad
WRITE_READ_CSR pmpaddr8, 0xbad
WRITE_READ_CSR pmpaddr9, 0xbad
WRITE_READ_CSR pmpaddr10, 0xbad
WRITE_READ_CSR pmpaddr11, 0xbad
WRITE_READ_CSR pmpaddr12, 0xbad
WRITE_READ_CSR pmpaddr13, 0xbad
WRITE_READ_CSR pmpaddr14, 0xbad
WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers
WRITE_READ_CSR mcycle, 0xbad
WRITE_READ_CSR minstret, 0xbad
WRITE_READ_CSR mhpmcounter3, 0xbad
WRITE_READ_CSR mhpmcounter4, 0xbad
WRITE_READ_CSR mhpmcounter5, 0xbad
WRITE_READ_CSR mhpmcounter6, 0xbad
WRITE_READ_CSR mhpmcounter7, 0xbad
WRITE_READ_CSR mhpmcounter8, 0xbad
WRITE_READ_CSR mhpmcounter9, 0xbad
WRITE_READ_CSR mhpmcounter10, 0xbad
WRITE_READ_CSR mhpmcounter11, 0xbad
WRITE_READ_CSR mhpmcounter12, 0xbad
WRITE_READ_CSR mhpmcounter13, 0xbad
WRITE_READ_CSR mhpmcounter14, 0xbad
WRITE_READ_CSR mhpmcounter15, 0xbad
WRITE_READ_CSR mhpmcounter16, 0xbad
WRITE_READ_CSR mhpmcounter17, 0xbad
WRITE_READ_CSR mhpmcounter18, 0xbad
WRITE_READ_CSR mhpmcounter19, 0xbad
WRITE_READ_CSR mhpmcounter20, 0xbad
WRITE_READ_CSR mhpmcounter21, 0xbad
WRITE_READ_CSR mhpmcounter22, 0xbad
WRITE_READ_CSR mhpmcounter23, 0xbad
WRITE_READ_CSR mhpmcounter24, 0xbad
WRITE_READ_CSR mhpmcounter25, 0xbad
WRITE_READ_CSR mhpmcounter26, 0xbad
WRITE_READ_CSR mhpmcounter27, 0xbad
WRITE_READ_CSR mhpmcounter28, 0xbad
WRITE_READ_CSR mhpmcounter29, 0xbad
WRITE_READ_CSR mhpmcounter30, 0xbad
WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup
WRITE_READ_CSR mcountinhibit, 0xbad
WRITE_READ_CSR mhpmevent3, 0xbad
WRITE_READ_CSR mhpmevent4, 0xbad
WRITE_READ_CSR mhpmevent5, 0xbad
WRITE_READ_CSR mhpmevent6, 0xbad
WRITE_READ_CSR mhpmevent7, 0xbad
WRITE_READ_CSR mhpmevent8, 0xbad
WRITE_READ_CSR mhpmevent9, 0xbad
WRITE_READ_CSR mhpmevent10, 0xbad
WRITE_READ_CSR mhpmevent11, 0xbad
WRITE_READ_CSR mhpmevent12, 0xbad
WRITE_READ_CSR mhpmevent13, 0xbad
WRITE_READ_CSR mhpmevent14, 0xbad
WRITE_READ_CSR mhpmevent15, 0xbad
WRITE_READ_CSR mhpmevent16, 0xbad
WRITE_READ_CSR mhpmevent17, 0xbad
WRITE_READ_CSR mhpmevent18, 0xbad
WRITE_READ_CSR mhpmevent19, 0xbad
WRITE_READ_CSR mhpmevent20, 0xbad
WRITE_READ_CSR mhpmevent21, 0xbad
WRITE_READ_CSR mhpmevent22, 0xbad
WRITE_READ_CSR mhpmevent23, 0xbad
WRITE_READ_CSR mhpmevent24, 0xbad
WRITE_READ_CSR mhpmevent25, 0xbad
WRITE_READ_CSR mhpmevent26, 0xbad
WRITE_READ_CSR mhpmevent27, 0xbad
WRITE_READ_CSR mhpmevent28, 0xbad
WRITE_READ_CSR mhpmevent29, 0xbad
WRITE_READ_CSR mhpmevent30, 0xbad
WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS
TEST_STACK_AND_DATA

View File

@ -22,9 +22,18 @@
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h" #include "WALLY-TEST-LIB-32.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 2
test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# Test Contents # Test Contents
# #

View File

@ -35,9 +35,18 @@
#define PLIC_RANGE 0x03FFFFFF #define PLIC_RANGE 0x03FFFFFF
#include "WALLY-TEST-LIB-32.h" #include "WALLY-TEST-LIB-32.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .4byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 2
test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# Test Contents # Test Contents
# #

View File

@ -22,9 +22,18 @@
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h" #include "WALLY-TEST-LIB-32.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .4byte statements as below.
INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 2
test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# Test Contents # Test Contents
# #
@ -45,22 +54,22 @@
# Test 12.3.2.2.1 Config: Write known values and set PMP config according to table 12.4 in the *** riscv book, copied below # Test 12.3.2.2.1 Config: Write known values and set PMP config according to table 12.4 in the *** riscv book, copied below
# write pmpaddr regs # write pmpaddr regs
# | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments | # | Reg | pmpaddr | pmpcfg | L | A | X | W | R | Comments |
.4byte 0x0, 0x0FFFFFFF, write_pmpaddr_0 # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW | .4byte 0x0, 0x0FFFFFFF, write_pmpaddr_0 # | 0 | 0x0FFFFFFF | 1F | 0 | NAPOT | 0 | 1 | 1 | I/O 00000000-7FFFFFFF RW |
.4byte 0x1, 0x20040000, write_pmpaddr_0 # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | | .4byte 0x1, 0x20040000, write_pmpaddr_1 # | 1 | 0x20040000 | 00 | 0 | OFF | 0 | 0 | 0 | |
.4byte 0x2, 0x2004003F, write_pmpaddr_0 # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R | .4byte 0x2, 0x2004003F, write_pmpaddr_2 # | 2 | 0x2004003F | 09 | 0 | TOR | 0 | 0 | 1 | 80100000-801000FF R |
.4byte 0x3, 0x20040080, write_pmpaddr_0 # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | | .4byte 0x3, 0x20040080, write_pmpaddr_3 # | 3 | 0x20040080 | 00 | 0 | OFF | 0 | 0 | 0 | |
.4byte 0x4, 0x20040084, write_pmpaddr_0 # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X | .4byte 0x4, 0x20040084, write_pmpaddr_4 # | 4 | 0x20040084 | 0C | 0 | TOR | 1 | 0 | 0 | 80100200-80100210 X |
.4byte 0x5, 0x200400C0, write_pmpaddr_0 # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out | .4byte 0x5, 0x200400C0, write_pmpaddr_5 # | 5 | 0x200400C0 | 90 | 1 | NA4 | 0 | 0 | 0 | 80100300-80100303 locked out |
.4byte 0x6, 0x2004013F, write_pmpaddr_0 # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access | .4byte 0x6, 0x2004013F, write_pmpaddr_6 # | 6 | 0x2004013F | 18 | 0 | NAPOT | 0 | 0 | 0 | 80100400-801004FF no access |
# Pmpaddr 7-14 are all zeroed out in this test, so they don't need writes. # Pmpaddr 7-14 are all zeroed out in this test, so they don't need writes.
.4byte 0xF, 0x2FFFFFFF, write_pmpaddr_0 # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX| .4byte 0xF, 0x2FFFFFFF, write_pmpaddr_15 # | 15 | 0x2FFFFFFF | 1F | 0 | NAPOT | 1 | 1 | 1 | Main mem 80000000-FFFFFFFF RWX|
# write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output. # write pmpcfg regs with the information in the table above. this should also write the value of these registers to the output.
.4byte 0x0, 0x0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0009001F .4byte 0x0, 0x0009001F, write_pmpcfg_0 # write pmpcfg0, output 0x0009001F
.4byte 0x1, 0x0018900C, write_pmpcfg_0 # write pmpcfg1, output 0x0018900C .4byte 0x1, 0x0018900C, write_pmpcfg_1 # write pmpcfg1, output 0x0018900C
# pmpcfg2 is zeroed out, so it doesn't need a write # pmpcfg2 is zeroed out, so it doesn't need a write
.4byte 0x3, 0x1F000000, write_pmpcfg_0 # write pmpcfg3, output 0x1F000000 .4byte 0x3, 0x1F000000, write_pmpcfg_3 # write pmpcfg3, output 0x1F000000
# write known values to memory where W=0. This should be possible since we're in machine mode. # write known values to memory where W=0. This should be possible since we're in machine mode.
.4byte 0x80100010, 0x600DAA, write32_test # write to pmpaddr 1-2 range .4byte 0x80100010, 0x600DAA, write32_test # write to pmpaddr 1-2 range
@ -74,9 +83,9 @@
# attempt to write to pmpaddr5 and pmp5cfg after lockout # attempt to write to pmpaddr5 and pmp5cfg after lockout
.4byte 0x1, 0x0018FF0C, write_pmpcfg_0 # attempt to edit only pmp5cfg (pmpcfg1[8:15]) after lockout. .4byte 0x1, 0x0018FF0C, write_pmpcfg_1 # attempt to edit only pmp5cfg (pmpcfg1[8:15]) after lockout.
# instruction ignored, output is 0x0018900C, NOT 0x0018FF0C # instruction ignored, output is 0x0018900C, NOT 0x0018FF0C
.4byte 0x5, 0xFFFFFFFF, write_pmpaddr_0 # attempt to edit pmpaddr5 after lockout. .4byte 0x5, 0xFFFFFFFF, write_pmpaddr_5 # attempt to edit pmpaddr5 after lockout.
# instruction ignored, output is 0x200400C0, NOT 0xFFFFFFFF # instruction ignored, output is 0x200400C0, NOT 0xFFFFFFFF
# Test 12.3.2.2.2 Machine mode access # Test 12.3.2.2.2 Machine mode access

View File

@ -4,7 +4,7 @@
// //
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu> // Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
// //
// Created 2021-07-20 // Created 2021-07-19
// //
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University // Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
// //
@ -23,6 +23,9 @@
#include "model_test.h" #include "model_test.h"
#include "arch_test.h" #include "arch_test.h"
.macro INIT_TESTS
RVTEST_ISA("RV32I") RVTEST_ISA("RV32I")
.section .text.init .section .text.init
@ -31,7 +34,7 @@ rvtest_entry_point:
RVMODEL_BOOT RVMODEL_BOOT
RVTEST_CODE_BEGIN RVTEST_CODE_BEGIN
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
// Initialization Overview: // Initialization Overview:
// //
// Initialize x6 as a virtual pointer to the test results // Initialize x6 as a virtual pointer to the test results
@ -56,9 +59,9 @@ RVTEST_CODE_BEGIN
li a1, 0 li a1, 0
li a2, 0 // reset trap handler inputs to zero li a2, 0 // reset trap handler inputs to zero
// go to first test! // go to beginning of S file where we can decide between using the test data loop
j test_setup // or using the macro inline code insertion
j s_file_begin
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
// General traps Handler // General traps Handler
@ -225,12 +228,16 @@ ecallhandler_changetousermode:
j trapreturn j trapreturn
instrfault: instrfault:
lw x1, -4(sp) // load return address int x1 (the address after the jal into faulting page) lw x1, -4(sp) // load return address int x1 (the address AFTER the jal into faulting page)
j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page) j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page)
illegalinstr:
j trapreturn // return to the code after recording the mcause
accessfault: accessfault:
// *** What do I have to do here? // *** What do I have to do here?
j trapreturn j trapreturn
// Table of trap behavior // Table of trap behavior
// lists what to do on each exception (not interrupts) // lists what to do on each exception (not interrupts)
// unexpected exceptions should cause segfaults for easy detection // unexpected exceptions should cause segfaults for easy detection
@ -239,13 +246,13 @@ accessfault:
.align 2 // aligns this data table to an 4 byte boundary .align 2 // aligns this data table to an 4 byte boundary
trap_handler_vector_table: trap_handler_vector_table:
.4byte segfault // 0: instruction address misaligned .4byte segfault // 0: instruction address misaligned
.4byte instrfault // 1: instruction access fault .4byte instrfault // 1: instruction access fault
.4byte segfault // 2: illegal instruction .4byte illegalinstr // 2: illegal instruction
.4byte segfault // 3: breakpoint .4byte segfault // 3: breakpoint
.4byte segfault // 4: load address misaligned .4byte segfault // 4: load address misaligned
.4byte accessfault // 5: load access fault .4byte accessfault // 5: load access fault
.4byte segfault // 6: store address misaligned .4byte segfault // 6: store address misaligned
.4byte accessfault // 7: store access fault .4byte accessfault // 7: store access fault
.4byte ecallhandler // 8: ecall from U-mode .4byte ecallhandler // 8: ecall from U-mode
.4byte ecallhandler // 9: ecall from S-mode .4byte ecallhandler // 9: ecall from S-mode
.4byte segfault // 10: reserved .4byte segfault // 10: reserved
@ -260,6 +267,220 @@ trap_return_pagetype_table:
.4byte 0xC // 0: kilopage has 12 offset bits .4byte 0xC // 0: kilopage has 12 offset bits
.4byte 0x16 // 1: megapage has 22 offset bits .4byte 0x16 // 1: megapage has 22 offset bits
.endm
// Test Summary table!
// Test Name : Description : Fault output value : Normal output values
// ---------------------:-------------------------------------------:-------------------------------------------:------------------------------------------------------
// write64_test : Write 64 bits to address : 0x6, 0x7, or 0xf : None
// write32_test : Write 32 bits to address : 0x6, 0x7, or 0xf : None
// write16_test : Write 16 bits to address : 0x6, 0x7, or 0xf : None
// write08_test : Write 8 bits to address : 0x6, 0x7, or 0xf : None
// read64_test : Read 64 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read32_test : Read 32 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read16_test : Read 16 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read08_test : Read 8 bitsfrom address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// executable_test : test executable on virtual page : 0x0, 0x1, or 0xc, then 0xbad : value of x7 modified by exectuion code (usually 0x111)
// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_baremetal : satp.MODE = bare metal : None : None
// goto_sv32 : satp.MODE = sv32 : None : None
// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_read_csr : write to specified CSR : old CSR value, 0x2, depending on perms : value written to CSR
// csr_r_access : test read-only permissions on CSR : 0xbad : 0x2, then 0x11
// *** TESTS TO ADD: execute inline, read unknown value out, read CSR unknown value, just read CSR value
.macro WRITE32 ADDR VAL
// attempt to write VAL to ADDR
// Success outputs:
// None
// Fault outputs:
// 0x6: misaligned address
// 0x7: access fault
// 0xf: page fault
li x29, \VAL
li x30, \ADDR
sw x29, 0(x30)
.endm
.macro WRITE16 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sh x29, 0(x30)
.endm
.macro WRITE08 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sb x29, 0(x30)
.endm
.macro READ32 ADDR
// Attempt read at ADDR. Write the value read out to the output *** Consider adding specific test for reading a non known value
// Success outputs:
// value read out from ADDR
// Fault outputs:
// One of the following followed by 0xBAD
// 0x4: misaligned address
// 0x5: access fault
// 0xD: page fault
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lw x7, 0(x29)
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro READ16 ADDR
// All reads have the same description/outputs as read32.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lh x7, 0(x29)
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro READ08 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lb x7, 0(x29)
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
// These goto_x_mode tests all involve invoking the trap handler,
// So their outputs are inevitably:
// 0x8: test called from U mode
// 0x9: test called from S mode
// 0xB: test called from M mode
// they generally do not fault or cause issues as long as these modes are enabled
// *** add functionality to check if modes are enabled before jumping? maybe cause a fault if not?
.macro GOTO_M_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 2 // determine trap handler behavior (go to machine mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_S_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 3 // determine trap handler behavior (go to supervisor mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_U_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 4 // determine trap handler behavior (go to user mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
// These tests change virtual memory settings, turning it on/off and changing between types.
// They don't have outputs as any error with turning on virtual memory should reveal itself in the tests *** Consider changing this policy?
.macro GOTO_BAREMETAL
// Turn translation off
li x7, 0 // satp.MODE value for bare metal (0)
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro GOTO_SV32
// Turn on sv39 virtual memory
li x7, 1 // satp.MODE value for Sv32 (1)
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro WRITE_READ_CSR CSR VAL
// attempt to write CSR with VAL. Note: this also tests read access to CSR
// Success outputs:
// value read back out from CSR after writing
// Fault outputs:
// The previous CSR value before write attempt
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
li x30, 0xbad // load bad value to be overwritten by csrr
li x29, \VAL
csrw \CSR\(), x29
csrr x30, \CSR
sw x30, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro CSR_R_ACCESS CSR
// verify that a csr is accessible to read but not to write
// Success outputs:
// 0x2, then
// 0x11 *** consider changing to something more meaningful
// Fault outputs:
// 0xBAD *** consider changing this one as well. in general, do we need the branching if it hould cause an illegal instruction fault?
csrr x29, \CSR
csrwi \CSR\(), 0xA // Attempt to write a 'random' value to the CSR
csrr x30, \CSR
bne x30, x29, 1f // 1f represents write_access
li x30, 0x11 // Write failed, confirming read only permissions.
j 2f // j r_access_end
1: // w_access (write succeeded, violating read-only)
li x30, 0xBAD
2: // r_access end
sw x30, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro EXECUTE_AT_ADDRESS ADDR
// Execute the code already written to ADDR, returning the value in x7.
// *** Note: this test itself doesn't write the code to ADDR because it might be callled at a point where we dont have write access to ADDR
// Assumes the code modifies x7, usually to become 0x111.
// Sample code: 0x11100393 (li x7, 0x111), 0x00008067 (ret)
// Success outputs:
// modified value of x7. (0x111 if you use the sample code)
// Fault outputs:
// One of the following followed by 0xBAD
// 0x0: misaligned address
// 0x1: access fault
// 0xC: page fault
fence.i // forces caches and main memory to sync so execution code written to ADDR can run.
li x7, 0xBAD
li x28, \ADDR
jalr x28 // jump to executable test code
sw x7, 0(x6)
addi x6, x6, 4
addi x16, x16, 4
.endm
.macro END_TESTS
// invokes one final ecall to return to machine mode then terminates this program, so the output is
// 0x8: termination called from U mode
// 0x9: termination called from S mode
// 0xB: termination called from M mode
j terminate_test
.endm
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
// Test Handler // Test Handler
// //
@ -269,17 +490,18 @@ trap_return_pagetype_table:
// Input parameters: // Input parameters:
// //
// x28: // x28:
// Address input for the test taking place (think address to read/write, new address to return to, etc...) // Address input for the test taking place (think: address to read/write, new address to return to, etc...)
// //
// x29: // x29:
// Value input for the test taking place (think value to write, any other extra info needed) // Value input for the test taking place (think: value to write, any other extra info needed)
// //
// x30: // x30:
// Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below // Label for the location of the test that's about to take place
//
// ------------------------------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------------------------------
test_setup: .macro INIT_TEST_TABLE // *** Consider renaming this test. to what???
test_loop_setup:
la x5, test_cases la x5, test_cases
test_loop: test_loop:
@ -298,25 +520,25 @@ test_loop:
jr x30 jr x30
// Test Name : Description : Fault output value : Normal output values // Test Name : Description : Fault output value : Normal output values
// ----------------------:---------------------------------------:------------------------:------------------------------------------------------ // ----------------------:-------------------------------------------:------------------------:------------------------------------------------------
// write32_test : Write 32 bits to address : 0xf : None // write32_test : Write 32 bits to address : 0xf : None
// write16_test : Write 16 bits to address : 0xf : None // write16_test : Write 16 bits to address : 0xf : None
// write08_test : Write 8 bits to address : 0xf : None // write08_test : Write 8 bits to address : 0xf : None
// read32_test : Read 32 bits from address : 0xd, 0xbad : readvalue in hex // read32_test : Read 32 bits from address : 0xd, 0xbad : readvalue in hex
// read16_test : Read 16 bits from address : 0xd, 0xbad : readvalue in hex // read16_test : Read 16 bits from address : 0xd, 0xbad : readvalue in hex
// read08_test : Read 8 bits from address : 0xd, 0xbad : readvalue in hex // read08_test : Read 8 bits from address : 0xd, 0xbad : readvalue in hex
// executable_test : test executable at address : 0xc, 0xbad : leading 12 bits of the li instr written to address. In general this is 0x111. (be sure to also write a return instruction) // executable_test : test executable on virtual page : 0xc, 0xbad : value of x7 modified by exectuion code (usually 0x111)
// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 // terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_baremetal : satp.MODE = bare metal : None : None // goto_baremetal : satp.MODE = bare metal : None : None
// goto_sv32 : satp.MODE = sv32 : None : None // goto_sv39 : satp.MODE = sv39 : None : None
// write_mxr_sum : write sstatus.[19:18] = MXR, SUM bits : None : None // goto_sv48 : satp.MODE = sv48 : None : None
// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 // write_mxr_sum : write sstatus.[19:18] = MXR, SUM bits : None : None
// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 // goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8 // goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_pmpcfg_x : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value // goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_pmpaddr_x : Write one of the pmpaddr csr's : None : readback of pmpaddr value // write_pmpcfg_x : Write one of the pmpcfg csr's : mstatuses?, 0xD : readback of pmpcfg value
// write_pmpaddr_x : Write one of the pmpaddr csr's : None : readback of pmpaddr value
write32_test: write32_test:
// address to write in x28, word value in x29 // address to write in x28, word value in x29
@ -360,9 +582,9 @@ read08_test:
addi x16, x16, 4 addi x16, x16, 4
j test_loop // go to next test case j test_loop // go to next test case
goto_s_mode: goto_s_mode:
li a0, 3 // Trap handler behavior (go to machine mode) // return to address in x28,
li a0, 3 // Trap handler behavior (go to supervisor mode)
mv a1, x28 // return VPN mv a1, x28 // return VPN
mv a2, x29 // return page types mv a2, x29 // return page types
ecall // writes mcause to the output. ecall // writes mcause to the output.
@ -385,21 +607,11 @@ goto_u_mode:
goto_baremetal: goto_baremetal:
// Turn translation off // Turn translation off
li x7, 0 // satp.MODE value for bare metal (0) GOTO_BAREMETAL
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well. Be careful
j test_loop // go to next test case j test_loop // go to next test case
goto_sv32: goto_sv32:
li x7, 1 // satp.MODE value for Sv39 (1) GOTO_SV32
slli x7, x7, 31
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well. Be careful
j test_loop // go to next test case j test_loop // go to next test case
write_mxr_sum: write_mxr_sum:
@ -415,25 +627,26 @@ write_mxr_sum:
write_pmpcfg_0: write_pmpcfg_0:
// writes the value in x29 to the pmpcfg register specified in x28. // writes the value in x29 to the pmpcfg register specified in x28.
li x7, 0x0 // then writes the final value of pmpcfgX to the output.
bne x7, x28, write_pmpcfg_1
csrw pmpcfg0, x29 csrw pmpcfg0, x29
csrr x30, pmpcfg0 csrr x30, pmpcfg0
j write_pmpcfg_end
write_pmpcfg_1: write_pmpcfg_1:
li x7, 0x1
bne x7, x28, write_pmpcfg_2
csrw pmpcfg1, x29 csrw pmpcfg1, x29
csrr x30, pmpcfg1 csrr x30, pmpcfg1
j write_pmpcfg_end
write_pmpcfg_2: write_pmpcfg_2:
li x7, 0x2
bne x7, x28, write_pmpcfg_3
csrw pmpcfg2, x29 csrw pmpcfg2, x29
csrr x30, pmpcfg2 csrr x30, pmpcfg2
j write_pmpcfg_end
write_pmpcfg_3: write_pmpcfg_3:
li x7, 0x3
bne x7, x28, write_pmpcfg_end
csrw pmpcfg3, x29 csrw pmpcfg3, x29
csrr x30, pmpcfg3 csrr x30, pmpcfg3
j write_pmpcfg_end
write_pmpcfg_end: write_pmpcfg_end:
sw x30, 0(x6) sw x30, 0(x6)
addi x6, x6, 4 addi x6, x6, 4
@ -441,103 +654,88 @@ write_pmpcfg_end:
j test_loop j test_loop
write_pmpaddr_0: write_pmpaddr_0:
// write_read_csr pmpaddr0, x29
// writes the value in x29 to the pmpaddr register specified in x28. // writes the value in x29 to the pmpaddr register specified in x28.
// then writes the final value of pmpaddrX to the output. // then writes the final value of pmpaddrX to the output.
li x7, 0x0
bne x7, x28, write_pmpaddr_1
csrw pmpaddr0, x29 csrw pmpaddr0, x29
csrr x30, pmpaddr0 csrr x30, pmpaddr0
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_1: write_pmpaddr_1:
li x7, 0x1
bne x7, x28, write_pmpaddr_2
csrw pmpaddr1, x29 csrw pmpaddr1, x29
csrr x30, pmpaddr1 csrr x30, pmpaddr1
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_2: write_pmpaddr_2:
li x7, 0x2
bne x7, x28, write_pmpaddr_3
csrw pmpaddr2, x29 csrw pmpaddr2, x29
csrr x30, pmpaddr2 csrr x30, pmpaddr2
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_3: write_pmpaddr_3:
li x7, 0x3
bne x7, x28, write_pmpaddr_4
csrw pmpaddr3, x29 csrw pmpaddr3, x29
csrr x30, pmpaddr3 csrr x30, pmpaddr3
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_4: write_pmpaddr_4:
li x7, 0x4
bne x7, x28, write_pmpaddr_5
csrw pmpaddr4, x29 csrw pmpaddr4, x29
csrr x30, pmpaddr4 csrr x30, pmpaddr4
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_5: write_pmpaddr_5:
li x7, 0x5
bne x7, x28, write_pmpaddr_6
csrw pmpaddr5, x29 csrw pmpaddr5, x29
csrr x30, pmpaddr5 csrr x30, pmpaddr5
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_6: write_pmpaddr_6:
li x7, 0x6
bne x7, x28, write_pmpaddr_7
csrw pmpaddr6, x29 csrw pmpaddr6, x29
csrr x30, pmpaddr6 csrr x30, pmpaddr6
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_7: write_pmpaddr_7:
li x7, 0x7
bne x7, x28, write_pmpaddr_8
csrw pmpaddr7, x29 csrw pmpaddr7, x29
csrr x30, pmpaddr7 csrr x30, pmpaddr7
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_8: write_pmpaddr_8:
li x7, 0x8
bne x7, x28, write_pmpaddr_9
csrw pmpaddr8, x29 csrw pmpaddr8, x29
csrr x30, pmpaddr8 csrr x30, pmpaddr8
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_9: write_pmpaddr_9:
li x7, 0x9
bne x7, x28, write_pmpaddr_10
csrw pmpaddr9, x29 csrw pmpaddr9, x29
csrr x30, pmpaddr9 csrr x30, pmpaddr9
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_10: write_pmpaddr_10:
li x7, 0xA
bne x7, x28, write_pmpaddr_11
csrw pmpaddr10, x29 csrw pmpaddr10, x29
csrr x30, pmpaddr10 csrr x30, pmpaddr10
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_11: write_pmpaddr_11:
li x7, 0xB
bne x7, x28, write_pmpaddr_12
csrw pmpaddr11, x29 csrw pmpaddr11, x29
csrr x30, pmpaddr11 csrr x30, pmpaddr11
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_12: write_pmpaddr_12:
li x7, 0xC
bne x7, x28, write_pmpaddr_13
csrw pmpaddr12, x29 csrw pmpaddr12, x29
csrr x30, pmpaddr12 csrr x30, pmpaddr12
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_13: write_pmpaddr_13:
li x7, 0xD
bne x7, x28, write_pmpaddr_14
csrw pmpaddr13, x29 csrw pmpaddr13, x29
csrr x30, pmpaddr13 csrr x30, pmpaddr13
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_14: write_pmpaddr_14:
li x7, 0xE
bne x7, x28, write_pmpaddr_15
csrw pmpaddr14, x29 csrw pmpaddr14, x29
csrr x30, pmpaddr14 csrr x30, pmpaddr14
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_15: write_pmpaddr_15:
li x7, 0xF
bne x7, x28, write_pmpaddr_end
csrw pmpaddr15, x29 csrw pmpaddr15, x29
csrr x30, pmpaddr15 csrr x30, pmpaddr15
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_end: write_pmpaddr_end:
sw x30, 0(x6) sw x30, 0(x6)
addi x6, x6, 4 addi x6, x6, 4
@ -555,18 +753,21 @@ executable_test:
addi x16, x16, 4 addi x16, x16, 4
j test_loop j test_loop
.endm
// notably, terminate_test is not a part of the test table macro because it needs to be defined
// in any type of test, macro or test table, for the trap handler to work
terminate_test: terminate_test:
li a0, 2 // Trap handler behavior (go to machine mode) li a0, 2 // Trap handler behavior (go to machine mode)
ecall // writes mcause to the output. ecall // writes mcause to the output.
csrw mtvec, x4 // restore original trap handler to halt program csrw mtvec, x4 // restore original trap handler to halt program
RVTEST_CODE_END RVTEST_CODE_END
RVMODEL_HALT RVMODEL_HALT
.macro TEST_STACK_AND_DATA
RVTEST_DATA_BEGIN RVTEST_DATA_BEGIN
.align 4 .align 4
rvtest_data: rvtest_data:
@ -575,14 +776,12 @@ RVTEST_DATA_END
.align 2 // align stack to 4 byte boundary .align 2 // align stack to 4 byte boundary
bottom_of_stack: bottom_of_stack:
.fill 1024, 4, 0xdeadbeef .fill 1024, 4, 0xdeadbeef
top_of_stack: top_of_stack:
RVMODEL_DATA_BEGIN RVMODEL_DATA_BEGIN
// next lines through test cases copied over from old framework
test_1_res: test_1_res:
.fill 1024, 4, 0xdeadbeef .fill 1024, 4, 0xdeadbeef
@ -602,6 +801,4 @@ gpr_save:
#endif #endif
.align 2 .endm
test_cases:

View File

@ -0,0 +1,39 @@
///////////////////////////////////////////
//
// WALLY-MMU
//
// Author: Kip Macsai-Goren <kmacsaigoren@g.hmc.edu>
//
// Created 2022-01-25
//
// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University
//
// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation
// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy,
// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
// is furnished to do so, subject to the following conditions:
//
// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
//
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "WALLY-TEST-LIB-32.h"
INIT_TESTS
s_file_begin:
// Test 5.2.3.1: testing Read-only access to Machine info CSRs
CSR_R_ACCESS mvendorid
CSR_R_ACCESS marchid
CSR_R_ACCESS mimpid
CSR_R_ACCESS mhartid
# CSR_R_ACCESS mconfigptr # Unimplemented in spike as of 31 Jan 22
END_TESTS
TEST_STACK_AND_DATA

View File

@ -21,133 +21,137 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-MACROS-64.h" #include "WALLY-TEST-LIB-64.h"
INIT_TESTS INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in S mode. # Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in S mode.
# *** several of these appear not to be implemented in the assembler? # *** several of these appear not to be implemented in the assembler?
# I get "assembler messages: error: unkown CSR" with many of them. # I get "assembler messages: error: unkown CSR" with many of them.
goto_s_mode 0x0, 0x0 GOTO_S_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back # Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively # should result in an illegal instruction for the write and read, respectively
# Machine information Registers # Machine information Registers
write_read_csr mvendorid, 0xbad WRITE_READ_CSR mvendorid, 0xbad
write_read_csr marchid, 0xbad WRITE_READ_CSR marchid, 0xbad
write_read_csr mimpid, 0xbad WRITE_READ_CSR mimpid, 0xbad
write_read_csr mhartid, 0xbad WRITE_READ_CSR mhartid, 0xbad
# write_read_csr mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22 # WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup # Machine Trap Setup
write_read_csr mstatus, 0xbad WRITE_READ_CSR mstatus, 0xbad
write_read_csr misa, 0xbad WRITE_READ_CSR misa, 0xbad
write_read_csr medeleg, 0xbad WRITE_READ_CSR medeleg, 0xbad
write_read_csr mideleg, 0xbad WRITE_READ_CSR mideleg, 0xbad
write_read_csr mie, 0xbad WRITE_READ_CSR mie, 0xbad
write_read_csr mtvec, 0xbad WRITE_READ_CSR mtvec, 0xbad
write_read_csr mcounteren, 0xbad WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling # Machine Trap Handling
write_read_csr mscratch, 0xbad WRITE_READ_CSR mscratch, 0xbad
write_read_csr mepc, 0xbad WRITE_READ_CSR mepc, 0xbad
write_read_csr mcause, 0xbad WRITE_READ_CSR mcause, 0xbad
write_read_csr mtval, 0xbad WRITE_READ_CSR mtval, 0xbad
write_read_csr mip, 0xbad WRITE_READ_CSR mip, 0xbad
# write_read_csr mtinst, 0xbad # *** these appear not to be implemented in the compile step of make??? # WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# write_read_csr mtval2, 0xbad # WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration # Machine Configuration
# write_read_csr menvcfg, 0xbad # *** these appear not to be implemented in the compile step of make??? # WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# write_read_csr mseccgf, 0xbad # WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection # Machine Memory Protection
write_read_csr pmpcfg0, 0xbad WRITE_READ_CSR pmpcfg0, 0xbad
write_read_csr pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs WRITE_READ_CSR pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
write_read_csr pmpaddr0, 0xbad WRITE_READ_CSR pmpaddr0, 0xbad
write_read_csr pmpaddr1, 0xbad WRITE_READ_CSR pmpaddr1, 0xbad
write_read_csr pmpaddr2, 0xbad WRITE_READ_CSR pmpaddr2, 0xbad
write_read_csr pmpaddr3, 0xbad WRITE_READ_CSR pmpaddr3, 0xbad
write_read_csr pmpaddr4, 0xbad WRITE_READ_CSR pmpaddr4, 0xbad
write_read_csr pmpaddr5, 0xbad WRITE_READ_CSR pmpaddr5, 0xbad
write_read_csr pmpaddr6, 0xbad WRITE_READ_CSR pmpaddr6, 0xbad
write_read_csr pmpaddr7, 0xbad WRITE_READ_CSR pmpaddr7, 0xbad
write_read_csr pmpaddr8, 0xbad WRITE_READ_CSR pmpaddr8, 0xbad
write_read_csr pmpaddr9, 0xbad WRITE_READ_CSR pmpaddr9, 0xbad
write_read_csr pmpaddr10, 0xbad WRITE_READ_CSR pmpaddr10, 0xbad
write_read_csr pmpaddr11, 0xbad WRITE_READ_CSR pmpaddr11, 0xbad
write_read_csr pmpaddr12, 0xbad WRITE_READ_CSR pmpaddr12, 0xbad
write_read_csr pmpaddr13, 0xbad WRITE_READ_CSR pmpaddr13, 0xbad
write_read_csr pmpaddr14, 0xbad WRITE_READ_CSR pmpaddr14, 0xbad
write_read_csr pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers # Machine Counter/Timers
write_read_csr mcycle, 0xbad WRITE_READ_CSR mcycle, 0xbad
write_read_csr minstret, 0xbad WRITE_READ_CSR minstret, 0xbad
write_read_csr mhpmcounter3, 0xbad WRITE_READ_CSR mhpmcounter3, 0xbad
write_read_csr mhpmcounter4, 0xbad WRITE_READ_CSR mhpmcounter4, 0xbad
write_read_csr mhpmcounter5, 0xbad WRITE_READ_CSR mhpmcounter5, 0xbad
write_read_csr mhpmcounter6, 0xbad WRITE_READ_CSR mhpmcounter6, 0xbad
write_read_csr mhpmcounter7, 0xbad WRITE_READ_CSR mhpmcounter7, 0xbad
write_read_csr mhpmcounter8, 0xbad WRITE_READ_CSR mhpmcounter8, 0xbad
write_read_csr mhpmcounter9, 0xbad WRITE_READ_CSR mhpmcounter9, 0xbad
write_read_csr mhpmcounter10, 0xbad WRITE_READ_CSR mhpmcounter10, 0xbad
write_read_csr mhpmcounter11, 0xbad WRITE_READ_CSR mhpmcounter11, 0xbad
write_read_csr mhpmcounter12, 0xbad WRITE_READ_CSR mhpmcounter12, 0xbad
write_read_csr mhpmcounter13, 0xbad WRITE_READ_CSR mhpmcounter13, 0xbad
write_read_csr mhpmcounter14, 0xbad WRITE_READ_CSR mhpmcounter14, 0xbad
write_read_csr mhpmcounter15, 0xbad WRITE_READ_CSR mhpmcounter15, 0xbad
write_read_csr mhpmcounter16, 0xbad WRITE_READ_CSR mhpmcounter16, 0xbad
write_read_csr mhpmcounter17, 0xbad WRITE_READ_CSR mhpmcounter17, 0xbad
write_read_csr mhpmcounter18, 0xbad WRITE_READ_CSR mhpmcounter18, 0xbad
write_read_csr mhpmcounter19, 0xbad WRITE_READ_CSR mhpmcounter19, 0xbad
write_read_csr mhpmcounter20, 0xbad WRITE_READ_CSR mhpmcounter20, 0xbad
write_read_csr mhpmcounter21, 0xbad WRITE_READ_CSR mhpmcounter21, 0xbad
write_read_csr mhpmcounter22, 0xbad WRITE_READ_CSR mhpmcounter22, 0xbad
write_read_csr mhpmcounter23, 0xbad WRITE_READ_CSR mhpmcounter23, 0xbad
write_read_csr mhpmcounter24, 0xbad WRITE_READ_CSR mhpmcounter24, 0xbad
write_read_csr mhpmcounter25, 0xbad WRITE_READ_CSR mhpmcounter25, 0xbad
write_read_csr mhpmcounter26, 0xbad WRITE_READ_CSR mhpmcounter26, 0xbad
write_read_csr mhpmcounter27, 0xbad WRITE_READ_CSR mhpmcounter27, 0xbad
write_read_csr mhpmcounter28, 0xbad WRITE_READ_CSR mhpmcounter28, 0xbad
write_read_csr mhpmcounter29, 0xbad WRITE_READ_CSR mhpmcounter29, 0xbad
write_read_csr mhpmcounter30, 0xbad WRITE_READ_CSR mhpmcounter30, 0xbad
write_read_csr mhpmcounter31, 0xbad WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup # Machine Counter Setup
write_read_csr mcountinhibit, 0xbad WRITE_READ_CSR mcountinhibit, 0xbad
write_read_csr mhpmevent3, 0xbad WRITE_READ_CSR mhpmevent3, 0xbad
write_read_csr mhpmevent4, 0xbad WRITE_READ_CSR mhpmevent4, 0xbad
write_read_csr mhpmevent5, 0xbad WRITE_READ_CSR mhpmevent5, 0xbad
write_read_csr mhpmevent6, 0xbad WRITE_READ_CSR mhpmevent6, 0xbad
write_read_csr mhpmevent7, 0xbad WRITE_READ_CSR mhpmevent7, 0xbad
write_read_csr mhpmevent8, 0xbad WRITE_READ_CSR mhpmevent8, 0xbad
write_read_csr mhpmevent9, 0xbad WRITE_READ_CSR mhpmevent9, 0xbad
write_read_csr mhpmevent10, 0xbad WRITE_READ_CSR mhpmevent10, 0xbad
write_read_csr mhpmevent11, 0xbad WRITE_READ_CSR mhpmevent11, 0xbad
write_read_csr mhpmevent12, 0xbad WRITE_READ_CSR mhpmevent12, 0xbad
write_read_csr mhpmevent13, 0xbad WRITE_READ_CSR mhpmevent13, 0xbad
write_read_csr mhpmevent14, 0xbad WRITE_READ_CSR mhpmevent14, 0xbad
write_read_csr mhpmevent15, 0xbad WRITE_READ_CSR mhpmevent15, 0xbad
write_read_csr mhpmevent16, 0xbad WRITE_READ_CSR mhpmevent16, 0xbad
write_read_csr mhpmevent17, 0xbad WRITE_READ_CSR mhpmevent17, 0xbad
write_read_csr mhpmevent18, 0xbad WRITE_READ_CSR mhpmevent18, 0xbad
write_read_csr mhpmevent19, 0xbad WRITE_READ_CSR mhpmevent19, 0xbad
write_read_csr mhpmevent20, 0xbad WRITE_READ_CSR mhpmevent20, 0xbad
write_read_csr mhpmevent21, 0xbad WRITE_READ_CSR mhpmevent21, 0xbad
write_read_csr mhpmevent22, 0xbad WRITE_READ_CSR mhpmevent22, 0xbad
write_read_csr mhpmevent23, 0xbad WRITE_READ_CSR mhpmevent23, 0xbad
write_read_csr mhpmevent24, 0xbad WRITE_READ_CSR mhpmevent24, 0xbad
write_read_csr mhpmevent25, 0xbad WRITE_READ_CSR mhpmevent25, 0xbad
write_read_csr mhpmevent26, 0xbad WRITE_READ_CSR mhpmevent26, 0xbad
write_read_csr mhpmevent27, 0xbad WRITE_READ_CSR mhpmevent27, 0xbad
write_read_csr mhpmevent28, 0xbad WRITE_READ_CSR mhpmevent28, 0xbad
write_read_csr mhpmevent29, 0xbad WRITE_READ_CSR mhpmevent29, 0xbad
write_read_csr mhpmevent30, 0xbad WRITE_READ_CSR mhpmevent30, 0xbad
write_read_csr mhpmevent31, 0xbad WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS END_TESTS
TEST_STACK_AND_DATA

View File

@ -21,149 +21,153 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-MACROS-64.h" #include "WALLY-TEST-LIB-64.h"
INIT_TESTS INIT_TESTS
s_file_begin:
# Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in R mode. # Test 5.2.3.6: Test that all the machine mode CSR's are innaccessible for reads and writes in R mode.
goto_u_mode 0x0, 0x0 GOTO_U_MODE 0x0, 0x0
# Attempt to write 0xbad to each of these CSRs and read the value back # Attempt to write 0xbad to each of these CSRs and read the value back
# should result in an illegal instruction for the write and read, respectively # should result in an illegal instruction for the write and read, respectively
# Supervisor Trap Setup # Supervisor Trap Setup
write_read_csr sstatus, 0xbad WRITE_READ_CSR sstatus, 0xbad
write_read_csr sie, 0xbad WRITE_READ_CSR sie, 0xbad
write_read_csr stvec, 0xbad WRITE_READ_CSR stvec, 0xbad
write_read_csr scounteren, 0xbad WRITE_READ_CSR scounteren, 0xbad
# Supervisor Configuration # Supervisor Configuration
# write_read_csr senvcfg, 0xbad # *** these appear not to be implemented in the compile step of make??? # WRITE_READ_CSR senvcfg, 0xbad # *** these appear not to be implemented in GCC
# Supervisor Trap Handling # Supervisor Trap Handling
write_read_csr sscratch, 0xbad WRITE_READ_CSR sscratch, 0xbad
write_read_csr sepc, 0xbad WRITE_READ_CSR sepc, 0xbad
write_read_csr scause, 0xbad WRITE_READ_CSR scause, 0xbad
write_read_csr stval, 0xbad WRITE_READ_CSR stval, 0xbad
write_read_csr sip, 0xbad WRITE_READ_CSR sip, 0xbad
# Supervisor Protection and Translation # Supervisor Protection and Translation
write_read_csr satp, 0xbad WRITE_READ_CSR satp, 0xbad
# Machine information Registers # Machine information Registers
write_read_csr mvendorid, 0xbad WRITE_READ_CSR mvendorid, 0xbad
write_read_csr marchid, 0xbad WRITE_READ_CSR marchid, 0xbad
write_read_csr mimpid, 0xbad WRITE_READ_CSR mimpid, 0xbad
write_read_csr mhartid, 0xbad WRITE_READ_CSR mhartid, 0xbad
# write_read_csr mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22 # WRITE_READ_CSR mconfigptr, 0xbad # mconfigptr unimplemented in spike as of 31 Jan 22
# Machine Trap Setup # Machine Trap Setup
write_read_csr mstatus, 0xbad WRITE_READ_CSR mstatus, 0xbad
write_read_csr misa, 0xbad WRITE_READ_CSR misa, 0xbad
write_read_csr medeleg, 0xbad WRITE_READ_CSR medeleg, 0xbad
write_read_csr mideleg, 0xbad WRITE_READ_CSR mideleg, 0xbad
write_read_csr mie, 0xbad WRITE_READ_CSR mie, 0xbad
write_read_csr mtvec, 0xbad WRITE_READ_CSR mtvec, 0xbad
write_read_csr mcounteren, 0xbad WRITE_READ_CSR mcounteren, 0xbad
# Machine Trap Handling # Machine Trap Handling
write_read_csr mscratch, 0xbad WRITE_READ_CSR mscratch, 0xbad
write_read_csr mepc, 0xbad WRITE_READ_CSR mepc, 0xbad
write_read_csr mcause, 0xbad WRITE_READ_CSR mcause, 0xbad
write_read_csr mtval, 0xbad WRITE_READ_CSR mtval, 0xbad
write_read_csr mip, 0xbad WRITE_READ_CSR mip, 0xbad
# write_read_csr mtinst, 0xbad # *** these appear not to be implemented in the compile step of make??? # WRITE_READ_CSR mtinst, 0xbad # *** these appear not to be implemented in GCC
# write_read_csr mtval2, 0xbad # WRITE_READ_CSR mtval2, 0xbad
# Machine Configuration # Machine Configuration
# write_read_csr menvcfg, 0xbad # *** these appear not to be implemented in the compile step of make??? # WRITE_READ_CSR menvcfg, 0xbad # *** these appear not to be implemented in GCC
# write_read_csr mseccgf, 0xbad # WRITE_READ_CSR mseccgf, 0xbad
# Machine Memory Protection # Machine Memory Protection
write_read_csr pmpcfg0, 0xbad WRITE_READ_CSR pmpcfg0, 0xbad
write_read_csr pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs WRITE_READ_CSR pmpcfg2, 0xbad # pmpcfg 1 and 3 dont exist in rv64. there's 1 pmpcfg reg per 8 pmpaddr regs
write_read_csr pmpaddr0, 0xbad WRITE_READ_CSR pmpaddr0, 0xbad
write_read_csr pmpaddr1, 0xbad WRITE_READ_CSR pmpaddr1, 0xbad
write_read_csr pmpaddr2, 0xbad WRITE_READ_CSR pmpaddr2, 0xbad
write_read_csr pmpaddr3, 0xbad WRITE_READ_CSR pmpaddr3, 0xbad
write_read_csr pmpaddr4, 0xbad WRITE_READ_CSR pmpaddr4, 0xbad
write_read_csr pmpaddr5, 0xbad WRITE_READ_CSR pmpaddr5, 0xbad
write_read_csr pmpaddr6, 0xbad WRITE_READ_CSR pmpaddr6, 0xbad
write_read_csr pmpaddr7, 0xbad WRITE_READ_CSR pmpaddr7, 0xbad
write_read_csr pmpaddr8, 0xbad WRITE_READ_CSR pmpaddr8, 0xbad
write_read_csr pmpaddr9, 0xbad WRITE_READ_CSR pmpaddr9, 0xbad
write_read_csr pmpaddr10, 0xbad WRITE_READ_CSR pmpaddr10, 0xbad
write_read_csr pmpaddr11, 0xbad WRITE_READ_CSR pmpaddr11, 0xbad
write_read_csr pmpaddr12, 0xbad WRITE_READ_CSR pmpaddr12, 0xbad
write_read_csr pmpaddr13, 0xbad WRITE_READ_CSR pmpaddr13, 0xbad
write_read_csr pmpaddr14, 0xbad WRITE_READ_CSR pmpaddr14, 0xbad
write_read_csr pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config WRITE_READ_CSR pmpaddr15, 0xbad # only pmpcfg0...15 are enabled in our config
# Machine Counter/Timers # Machine Counter/Timers
write_read_csr mcycle, 0xbad WRITE_READ_CSR mcycle, 0xbad
write_read_csr minstret, 0xbad WRITE_READ_CSR minstret, 0xbad
write_read_csr mhpmcounter3, 0xbad WRITE_READ_CSR mhpmcounter3, 0xbad
write_read_csr mhpmcounter4, 0xbad WRITE_READ_CSR mhpmcounter4, 0xbad
write_read_csr mhpmcounter5, 0xbad WRITE_READ_CSR mhpmcounter5, 0xbad
write_read_csr mhpmcounter6, 0xbad WRITE_READ_CSR mhpmcounter6, 0xbad
write_read_csr mhpmcounter7, 0xbad WRITE_READ_CSR mhpmcounter7, 0xbad
write_read_csr mhpmcounter8, 0xbad WRITE_READ_CSR mhpmcounter8, 0xbad
write_read_csr mhpmcounter9, 0xbad WRITE_READ_CSR mhpmcounter9, 0xbad
write_read_csr mhpmcounter10, 0xbad WRITE_READ_CSR mhpmcounter10, 0xbad
write_read_csr mhpmcounter11, 0xbad WRITE_READ_CSR mhpmcounter11, 0xbad
write_read_csr mhpmcounter12, 0xbad WRITE_READ_CSR mhpmcounter12, 0xbad
write_read_csr mhpmcounter13, 0xbad WRITE_READ_CSR mhpmcounter13, 0xbad
write_read_csr mhpmcounter14, 0xbad WRITE_READ_CSR mhpmcounter14, 0xbad
write_read_csr mhpmcounter15, 0xbad WRITE_READ_CSR mhpmcounter15, 0xbad
write_read_csr mhpmcounter16, 0xbad WRITE_READ_CSR mhpmcounter16, 0xbad
write_read_csr mhpmcounter17, 0xbad WRITE_READ_CSR mhpmcounter17, 0xbad
write_read_csr mhpmcounter18, 0xbad WRITE_READ_CSR mhpmcounter18, 0xbad
write_read_csr mhpmcounter19, 0xbad WRITE_READ_CSR mhpmcounter19, 0xbad
write_read_csr mhpmcounter20, 0xbad WRITE_READ_CSR mhpmcounter20, 0xbad
write_read_csr mhpmcounter21, 0xbad WRITE_READ_CSR mhpmcounter21, 0xbad
write_read_csr mhpmcounter22, 0xbad WRITE_READ_CSR mhpmcounter22, 0xbad
write_read_csr mhpmcounter23, 0xbad WRITE_READ_CSR mhpmcounter23, 0xbad
write_read_csr mhpmcounter24, 0xbad WRITE_READ_CSR mhpmcounter24, 0xbad
write_read_csr mhpmcounter25, 0xbad WRITE_READ_CSR mhpmcounter25, 0xbad
write_read_csr mhpmcounter26, 0xbad WRITE_READ_CSR mhpmcounter26, 0xbad
write_read_csr mhpmcounter27, 0xbad WRITE_READ_CSR mhpmcounter27, 0xbad
write_read_csr mhpmcounter28, 0xbad WRITE_READ_CSR mhpmcounter28, 0xbad
write_read_csr mhpmcounter29, 0xbad WRITE_READ_CSR mhpmcounter29, 0xbad
write_read_csr mhpmcounter30, 0xbad WRITE_READ_CSR mhpmcounter30, 0xbad
write_read_csr mhpmcounter31, 0xbad WRITE_READ_CSR mhpmcounter31, 0xbad
# Machine Counter Setup # Machine Counter Setup
write_read_csr mcountinhibit, 0xbad WRITE_READ_CSR mcountinhibit, 0xbad
write_read_csr mhpmevent3, 0xbad WRITE_READ_CSR mhpmevent3, 0xbad
write_read_csr mhpmevent4, 0xbad WRITE_READ_CSR mhpmevent4, 0xbad
write_read_csr mhpmevent5, 0xbad WRITE_READ_CSR mhpmevent5, 0xbad
write_read_csr mhpmevent6, 0xbad WRITE_READ_CSR mhpmevent6, 0xbad
write_read_csr mhpmevent7, 0xbad WRITE_READ_CSR mhpmevent7, 0xbad
write_read_csr mhpmevent8, 0xbad WRITE_READ_CSR mhpmevent8, 0xbad
write_read_csr mhpmevent9, 0xbad WRITE_READ_CSR mhpmevent9, 0xbad
write_read_csr mhpmevent10, 0xbad WRITE_READ_CSR mhpmevent10, 0xbad
write_read_csr mhpmevent11, 0xbad WRITE_READ_CSR mhpmevent11, 0xbad
write_read_csr mhpmevent12, 0xbad WRITE_READ_CSR mhpmevent12, 0xbad
write_read_csr mhpmevent13, 0xbad WRITE_READ_CSR mhpmevent13, 0xbad
write_read_csr mhpmevent14, 0xbad WRITE_READ_CSR mhpmevent14, 0xbad
write_read_csr mhpmevent15, 0xbad WRITE_READ_CSR mhpmevent15, 0xbad
write_read_csr mhpmevent16, 0xbad WRITE_READ_CSR mhpmevent16, 0xbad
write_read_csr mhpmevent17, 0xbad WRITE_READ_CSR mhpmevent17, 0xbad
write_read_csr mhpmevent18, 0xbad WRITE_READ_CSR mhpmevent18, 0xbad
write_read_csr mhpmevent19, 0xbad WRITE_READ_CSR mhpmevent19, 0xbad
write_read_csr mhpmevent20, 0xbad WRITE_READ_CSR mhpmevent20, 0xbad
write_read_csr mhpmevent21, 0xbad WRITE_READ_CSR mhpmevent21, 0xbad
write_read_csr mhpmevent22, 0xbad WRITE_READ_CSR mhpmevent22, 0xbad
write_read_csr mhpmevent23, 0xbad WRITE_READ_CSR mhpmevent23, 0xbad
write_read_csr mhpmevent24, 0xbad WRITE_READ_CSR mhpmevent24, 0xbad
write_read_csr mhpmevent25, 0xbad WRITE_READ_CSR mhpmevent25, 0xbad
write_read_csr mhpmevent26, 0xbad WRITE_READ_CSR mhpmevent26, 0xbad
write_read_csr mhpmevent27, 0xbad WRITE_READ_CSR mhpmevent27, 0xbad
write_read_csr mhpmevent28, 0xbad WRITE_READ_CSR mhpmevent28, 0xbad
write_read_csr mhpmevent29, 0xbad WRITE_READ_CSR mhpmevent29, 0xbad
write_read_csr mhpmevent30, 0xbad WRITE_READ_CSR mhpmevent30, 0xbad
write_read_csr mhpmevent31, 0xbad WRITE_READ_CSR mhpmevent31, 0xbad
END_TESTS END_TESTS
TEST_STACK_AND_DATA

View File

@ -22,8 +22,18 @@
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h" #include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below. INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
.align 3
test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# Test Contents # Test Contents

View File

@ -22,8 +22,19 @@
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h" #include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below. INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
.align 3
test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# Test Contents # Test Contents
@ -39,7 +50,6 @@
# #
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
# =========== test 12.3.1.1 Page Table Translation =========== # =========== test 12.3.1.1 Page Table Translation ===========

View File

@ -35,8 +35,19 @@
#define PLIC_RANGE 0x03FFFFFF #define PLIC_RANGE 0x03FFFFFF
#include "WALLY-TEST-LIB-64.h" #include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below. INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
.align 3
test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# Test Contents # Test Contents

View File

@ -22,8 +22,19 @@
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h" #include "WALLY-TEST-LIB-64.h"
// Test library includes and handler for each type of test, a trap handler, imperas compliance instructions
// Ideally this should mean that a test can be written by simply adding .8byte statements as below. INIT_TESTS
s_file_begin:
j test_loop_setup // begin test loop/table tests instead of executing inline code.
INIT_TEST_TABLE
TEST_STACK_AND_DATA
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook
.align 3
test_cases:
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
# Test Contents # Test Contents

View File

@ -23,6 +23,9 @@
#include "model_test.h" #include "model_test.h"
#include "arch_test.h" #include "arch_test.h"
.macro INIT_TESTS
RVTEST_ISA("RV64I") RVTEST_ISA("RV64I")
.section .text.init .section .text.init
@ -56,9 +59,9 @@ RVTEST_CODE_BEGIN
li a1, 0 li a1, 0
li a2, 0 // reset trap handler inputs to zero li a2, 0 // reset trap handler inputs to zero
// go to first test! // go to beginning of S file where we can decide between using the test data loop
j test_setup // or using the macro inline code insertion
j s_file_begin
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
// General traps Handler // General traps Handler
@ -230,6 +233,9 @@ instrfault:
ld x1, -8(sp) // load return address int x1 (the address AFTER the jal into faulting page) ld x1, -8(sp) // load return address int x1 (the address AFTER the jal into faulting page)
j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page) j trapreturn_finished // puts x1 into mepc, restores stack and returns to program (outside of faulting page)
illegalinstr:
j trapreturn // return to the code after recording the mcause
accessfault: accessfault:
// *** What do I have to do here? // *** What do I have to do here?
j trapreturn j trapreturn
@ -243,7 +249,7 @@ accessfault:
trap_handler_vector_table: trap_handler_vector_table:
.8byte segfault // 0: instruction address misaligned .8byte segfault // 0: instruction address misaligned
.8byte instrfault // 1: instruction access fault .8byte instrfault // 1: instruction access fault
.8byte segfault // 2: illegal instruction .8byte illegalinstr // 2: illegal instruction
.8byte segfault // 3: breakpoint .8byte segfault // 3: breakpoint
.8byte segfault // 4: load address misaligned .8byte segfault // 4: load address misaligned
.8byte accessfault // 5: load access fault .8byte accessfault // 5: load access fault
@ -265,6 +271,249 @@ trap_return_pagetype_table:
.8byte 0x1E // 2: gigapage has 30 offset bits .8byte 0x1E // 2: gigapage has 30 offset bits
.8byte 0x27 // 3: terapage has 39 offset bits .8byte 0x27 // 3: terapage has 39 offset bits
.endm
// Test Summary table!
// Test Name : Description : Fault output value : Normal output values
// ---------------------:-------------------------------------------:-------------------------------------------:------------------------------------------------------
// write64_test : Write 64 bits to address : 0x6, 0x7, or 0xf : None
// write32_test : Write 32 bits to address : 0x6, 0x7, or 0xf : None
// write16_test : Write 16 bits to address : 0x6, 0x7, or 0xf : None
// write08_test : Write 8 bits to address : 0x6, 0x7, or 0xf : None
// read64_test : Read 64 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read32_test : Read 32 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read16_test : Read 16 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// read08_test : Read 8 bits from address : 0x4, 0x5, or 0xd, then 0xbad : readvalue in hex
// executable_test : test executable on virtual page : 0x0, 0x1, or 0xc, then 0xbad : value of x7 modified by exectuion code (usually 0x111)
// terminate_test : terminate tests : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_baremetal : satp.MODE = bare metal : None : None
// goto_sv39 : satp.MODE = sv39 : None : None
// goto_sv48 : satp.MODE = sv48 : None : None
// goto_m_mode : go to mahcine mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_s_mode : go to supervisor mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// goto_u_mode : go to user mode : mcause value for fault : from M 0xb, from S 0x9, from U 0x8
// write_read_csr : write to specified CSR : old CSR value, 0x2, depending on perms : value written to CSR
// csr_r_access : test read-only permissions on CSR : 0xbad : 0x2, then 0x11
// *** TESTS TO ADD: execute inline, read unknown value out, read CSR unknown value, just read CSR value
.macro WRITE64 ADDR VAL
// attempt to write VAL to ADDR
// Success outputs:
// None
// Fault outputs:
// 0x6: misaligned address
// 0x7: access fault
// 0xf: page fault
li x29, \VAL
li x30, \ADDR
sd x29, 0(x30)
.endm
.macro WRITE32 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sw x29, 0(x30)
.endm
.macro WRITE16 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sh x29, 0(x30)
.endm
.macro WRITE08 ADDR VAL
// all write tests have the same description/outputs as write64
li x29, \VAL
li x30, \ADDR
sb x29, 0(x30)
.endm
.macro READ64 ADDR
// Attempt read at ADDR. Write the value read out to the output *** Consider adding specific test for reading a non known value
// Success outputs:
// value read out from ADDR
// Fault outputs:
// One of the following followed by 0xBAD
// 0x4: misaligned address
// 0x5: access fault
// 0xD: page fault
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
ld x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro READ32 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lw x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro READ16 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lh x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro READ08 ADDR
// All reads have the same description/outputs as read64.
// They will store the sign extended value of what was read out at ADDR
li x7, 0xBAD // bad value that will be overwritten on good reads.
li x29, \ADDR
lb x7, 0(x29)
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
// These goto_x_mode tests all involve invoking the trap handler,
// So their outputs are inevitably:
// 0x8: test called from U mode
// 0x9: test called from S mode
// 0xB: test called from M mode
// they generally do not fault or cause issues as long as these modes are enabled
// *** add functionality to check if modes are enabled before jumping? maybe cause a fault if not?
.macro GOTO_M_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 2 // determine trap handler behavior (go to machine mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_S_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 3 // determine trap handler behavior (go to supervisor mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
.macro GOTO_U_MODE RETURN_VPN RETURN_PAGETYPE
li a0, 4 // determine trap handler behavior (go to user mode)
li a1, \RETURN_VPN // return VPN
li a2, \RETURN_PAGETYPE // return page types
ecall // writes mcause to the output.
// now in S mode
.endm
// These tests change virtual memory settings, turning it on/off and changing between types.
// They don't have outputs as any error with turning on virtual memory should reveal itself in the tests *** Consider changing this policy?
.macro GOTO_BAREMETAL
// Turn translation off
li x7, 0 // satp.MODE value for bare metal (0)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro GOTO_SV39
// Turn on sv39 virtual memory
li x7, 8 // satp.MODE value for Sv39 (8)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro GOTO_SV48
// Turn on sv48 virtual memory
li x7, 9 // satp.MODE value for Sv39 (8)
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field. *** add option for different pagetable location
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
.endm
.macro WRITE_READ_CSR CSR VAL
// attempt to write CSR with VAL. Note: this also tests read access to CSR
// Success outputs:
// value read back out from CSR after writing
// Fault outputs:
// The previous CSR value before write attempt
// *** Most likely 0x2, the mcause for illegal instruction if we don't have write or read access
li x30, 0xbad // load bad value to be overwritten by csrr
li x29, \VAL
csrw \CSR\(), x29
csrr x30, \CSR
sd x30, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro CSR_R_ACCESS CSR
// verify that a csr is accessible to read but not to write
// Success outputs:
// 0x2, then
// 0x11 *** consider changing to something more meaningful
// Fault outputs:
// 0xBAD *** consider changing this one as well. in general, do we need the branching if it hould cause an illegal instruction fault?
csrr x29, \CSR
csrwi \CSR\(), 0xA // Attempt to write a 'random' value to the CSR
csrr x30, \CSR
bne x30, x29, 1f // 1f represents write_access
li x30, 0x11 // Write failed, confirming read only permissions.
j 2f // j r_access_end
1: // w_access (write succeeded, violating read-only)
li x30, 0xBAD
2: // r_access end
sd x30, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro EXECUTE_AT_ADDRESS ADDR
// Execute the code already written to ADDR, returning the value in x7.
// *** Note: this test itself doesn't write the code to ADDR because it might be callled at a point where we dont have write access to ADDR
// Assumes the code modifies x7, usually to become 0x111.
// Sample code: 0x11100393 (li x7, 0x111), 0x00008067 (ret)
// Success outputs:
// modified value of x7. (0x111 if you use the sample code)
// Fault outputs:
// One of the following followed by 0xBAD
// 0x0: misaligned address
// 0x1: access fault
// 0xC: page fault
fence.i // forces caches and main memory to sync so execution code written to ADDR can run.
li x7, 0xBAD
li x28, \ADDR
jalr x28 // jump to executable test code
sd x7, 0(x6)
addi x6, x6, 8
addi x16, x16, 8
.endm
.macro END_TESTS
// invokes one final ecall to return to machine mode then terminates this program, so the output is
// 0x8: termination called from U mode
// 0x9: termination called from S mode
// 0xB: termination called from M mode
j terminate_test
.endm
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------
// Test Handler // Test Handler
// //
@ -274,17 +523,18 @@ trap_return_pagetype_table:
// Input parameters: // Input parameters:
// //
// x28: // x28:
// Address input for the test taking place (think address to read/write, new address to return to, etc...) // Address input for the test taking place (think: address to read/write, new address to return to, etc...)
// //
// x29: // x29:
// Value input for the test taking place (think value to write, any other extra info needed) // Value input for the test taking place (think: value to write, any other extra info needed)
// //
// x30: // x30:
// Test type input that determines which kind of test will take place. Encoding for this input is in the table/case statements below // Label for the location of the test that's about to take place
//
// ------------------------------------------------------------------------------------------------------------------------------------ // ------------------------------------------------------------------------------------------------------------------------------------
test_setup: .macro INIT_TEST_TABLE // *** Consider renaming this test. to what???
test_loop_setup:
la x5, test_cases la x5, test_cases
test_loop: test_loop:
@ -407,30 +657,15 @@ goto_u_mode:
goto_baremetal: goto_baremetal:
// Turn translation off // Turn translation off
li x7, 0 // satp.MODE value for bare metal (0) GOTO_BAREMETAL
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
j test_loop // go to next test case j test_loop // go to next test case
goto_sv39: goto_sv39:
li x7, 8 // satp.MODE value for Sv39 (8) GOTO_SV39
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
j test_loop // go to next test case j test_loop // go to next test case
goto_sv48: goto_sv48:
li x7, 9 // satp.MODE value for Sv48 GOTO_SV48
slli x7, x7, 60
li x28, 0x8000D // Base Pagetable physical page number, satp.PPN field.
add x7, x7, x28
csrw satp, x7
sfence.vma x0, x0 // *** flushes global pte's as well
j test_loop // go to next test case j test_loop // go to next test case
write_mxr_sum: write_mxr_sum:
@ -447,15 +682,15 @@ write_mxr_sum:
write_pmpcfg_0: write_pmpcfg_0:
// writes the value in x29 to the pmpcfg register specified in x28. // writes the value in x29 to the pmpcfg register specified in x28.
// then writes the final value of pmpcfgX to the output. // then writes the final value of pmpcfgX to the output.
li x7, 0x0
bne x7, x28, write_pmpcfg_2
csrw pmpcfg0, x29 csrw pmpcfg0, x29
csrr x30, pmpcfg0 csrr x30, pmpcfg0
j write_pmpcfg_end
write_pmpcfg_2: write_pmpcfg_2:
li x7, 0x2
bne x7, x28, write_pmpcfg_end
csrw pmpcfg2, x29 csrw pmpcfg2, x29
csrr x30, pmpcfg2 // I would use csrrw but we need the value AFTER the csr has been written csrr x30, pmpcfg2 // I would use csrrw but we need the value AFTER the csr has been written
j write_pmpcfg_end
write_pmpcfg_end: write_pmpcfg_end:
sd x30, 0(x6) sd x30, 0(x6)
addi x6, x6, 8 addi x6, x6, 8
@ -463,103 +698,88 @@ write_pmpcfg_end:
j test_loop j test_loop
write_pmpaddr_0: write_pmpaddr_0:
// write_read_csr pmpaddr0, x29
// writes the value in x29 to the pmpaddr register specified in x28. // writes the value in x29 to the pmpaddr register specified in x28.
// then writes the final value of pmpaddrX to the output. // then writes the final value of pmpaddrX to the output.
li x7, 0x0
bne x7, x28, write_pmpaddr_1
csrw pmpaddr0, x29 csrw pmpaddr0, x29
csrr x30, pmpaddr0 csrr x30, pmpaddr0
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_1: write_pmpaddr_1:
li x7, 0x1
bne x7, x28, write_pmpaddr_2
csrw pmpaddr1, x29 csrw pmpaddr1, x29
csrr x30, pmpaddr1 csrr x30, pmpaddr1
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_2: write_pmpaddr_2:
li x7, 0x2
bne x7, x28, write_pmpaddr_3
csrw pmpaddr2, x29 csrw pmpaddr2, x29
csrr x30, pmpaddr2 csrr x30, pmpaddr2
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_3: write_pmpaddr_3:
li x7, 0x3
bne x7, x28, write_pmpaddr_4
csrw pmpaddr3, x29 csrw pmpaddr3, x29
csrr x30, pmpaddr3 csrr x30, pmpaddr3
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_4: write_pmpaddr_4:
li x7, 0x4
bne x7, x28, write_pmpaddr_5
csrw pmpaddr4, x29 csrw pmpaddr4, x29
csrr x30, pmpaddr4 csrr x30, pmpaddr4
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_5: write_pmpaddr_5:
li x7, 0x5
bne x7, x28, write_pmpaddr_6
csrw pmpaddr5, x29 csrw pmpaddr5, x29
csrr x30, pmpaddr5 csrr x30, pmpaddr5
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_6: write_pmpaddr_6:
li x7, 0x6
bne x7, x28, write_pmpaddr_7
csrw pmpaddr6, x29 csrw pmpaddr6, x29
csrr x30, pmpaddr6 csrr x30, pmpaddr6
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_7: write_pmpaddr_7:
li x7, 0x7
bne x7, x28, write_pmpaddr_8
csrw pmpaddr7, x29 csrw pmpaddr7, x29
csrr x30, pmpaddr7 csrr x30, pmpaddr7
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_8: write_pmpaddr_8:
li x7, 0x8
bne x7, x28, write_pmpaddr_9
csrw pmpaddr8, x29 csrw pmpaddr8, x29
csrr x30, pmpaddr8 csrr x30, pmpaddr8
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_9: write_pmpaddr_9:
li x7, 0x9
bne x7, x28, write_pmpaddr_10
csrw pmpaddr9, x29 csrw pmpaddr9, x29
csrr x30, pmpaddr9 csrr x30, pmpaddr9
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_10: write_pmpaddr_10:
li x7, 0xA
bne x7, x28, write_pmpaddr_11
csrw pmpaddr10, x29 csrw pmpaddr10, x29
csrr x30, pmpaddr10 csrr x30, pmpaddr10
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_11: write_pmpaddr_11:
li x7, 0xB
bne x7, x28, write_pmpaddr_12
csrw pmpaddr11, x29 csrw pmpaddr11, x29
csrr x30, pmpaddr11 csrr x30, pmpaddr11
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_12: write_pmpaddr_12:
li x7, 0xC
bne x7, x28, write_pmpaddr_13
csrw pmpaddr12, x29 csrw pmpaddr12, x29
csrr x30, pmpaddr12 csrr x30, pmpaddr12
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_13: write_pmpaddr_13:
li x7, 0xD
bne x7, x28, write_pmpaddr_14
csrw pmpaddr13, x29 csrw pmpaddr13, x29
csrr x30, pmpaddr13 csrr x30, pmpaddr13
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_14: write_pmpaddr_14:
li x7, 0xE
bne x7, x28, write_pmpaddr_15
csrw pmpaddr14, x29 csrw pmpaddr14, x29
csrr x30, pmpaddr14 csrr x30, pmpaddr14
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_15: write_pmpaddr_15:
li x7, 0xF
bne x7, x28, write_pmpaddr_end
csrw pmpaddr15, x29 csrw pmpaddr15, x29
csrr x30, pmpaddr15 csrr x30, pmpaddr15
j write_pmpaddr_end j write_pmpaddr_end
write_pmpaddr_end: write_pmpaddr_end:
sd x30, 0(x6) sd x30, 0(x6)
addi x6, x6, 8 addi x6, x6, 8
@ -577,6 +797,10 @@ executable_test:
addi x16, x16, 8 addi x16, x16, 8
j test_loop j test_loop
.endm
// notably, terminate_test is not a part of the test table macro because it needs to be defined
// in any type of test, macro or test table, for the trap handler to work
terminate_test: terminate_test:
li a0, 2 // Trap handler behavior (go to machine mode) li a0, 2 // Trap handler behavior (go to machine mode)
@ -586,6 +810,8 @@ terminate_test:
RVTEST_CODE_END RVTEST_CODE_END
RVMODEL_HALT RVMODEL_HALT
.macro TEST_STACK_AND_DATA
RVTEST_DATA_BEGIN RVTEST_DATA_BEGIN
.align 4 .align 4
rvtest_data: rvtest_data:
@ -619,6 +845,4 @@ gpr_save:
#endif #endif
.align 3 .endm
test_cases:

View File

@ -21,17 +21,19 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-MACROS-64.h" #include "WALLY-TEST-LIB-64.h"
INIT_TESTS INIT_TESTS
s_file_begin:
// Test 5.2.3.1: testing Read-only access to Machine info CSRs // Test 5.2.3.1: testing Read-only access to Machine info CSRs
CSR_R_ACCESS mvendorid
CSR_R_ACCESS marchid
CSR_R_ACCESS mimpid
CSR_R_ACCESS mhartid
# CSR_R_ACCESS mconfigptr # Unimplemented in spike as of 31 Jan 22
csr_r_access mvendorid END_TESTS
csr_r_access marchid
csr_r_access mimpid
csr_r_access mhartid
# csr_r_access mconfigptr # Unimplemented in spike as of 31 Jan 22
TEST_STACK_AND_DATA
END_TESTS