This commit is contained in:
Kip Macsai-Goren 2021-12-30 17:32:03 +00:00
commit 41db2743f5
38 changed files with 1377 additions and 1371 deletions

5
.gitignore vendored
View File

@ -8,6 +8,7 @@ __pycache__/
#External repos
addins
addins/riscv-arch-test/Makefile.include
#vsim work files to ignore
transcript
@ -43,3 +44,7 @@ fpga/generator/WallyFPGA*
fpga/generator/reports/
fpga/generator/*.log
fpga/generator/*.jou
*.objdump*
*.signature.output
examples/asm/sumtest/sumtest

1
.gitmodules vendored
View File

@ -4,6 +4,7 @@
[submodule "addins/riscv-arch-test"]
path = addins/riscv-arch-test
url = https://github.com/riscv-non-isa/riscv-arch-test
ignore = dirty
[submodule "addins/imperas-riscv-tests"]
path = addins/imperas-riscv-tests
url = https://github.com/riscv-ovpsim/imperas-riscv-tests

View File

@ -44,14 +44,14 @@
# test 12.3.1.1.1 write page tables / entries to phyiscal memory
# sv32 Page table (See Figure 12.12***):
# Level 1 page table, situated at 0x8000D000
.4byte 0x8000D000, 0x20004CC1, 0x0 # points to level 0 page table A
.4byte 0x8000D000, 0x20004C01, 0x0 # points to level 0 page table A
.4byte 0x8000D004, 0x200000CB, 0x0 # Vaddr 0x400000 Paddr 0x80000000: aligned megapage, W=0, used for execute tests
.4byte 0x8000D008, 0x200054E1, 0x0 # points to level 0 page table B
.4byte 0x8000D008, 0x20005421, 0x0 # points to level 0 page table B
.4byte 0x8000D00C, 0x000800C7, 0x0 # Vaddr 0xC00000: misaligned megapage
.4byte 0x8000D800, 0x200000CF, 0x0 # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory)
.4byte 0x8000D804, 0x200000DF, 0x0 # Vaddr 0x80400000 Paddr 0x80000000: aligned megapage, U=1 (aliased with program and data memory)
# Level 0 page table A
.4byte 0x80013000, 0x200070D1, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
.4byte 0x80013000, 0x20007011, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
.4byte 0x80013004, 0x202000DF, 0x0 # Vaddr 0x1000 Paddr 0x80800000: aligned kilopage, U=1
.4byte 0x80013008, 0x202010D5, 0x0 # Vaddr 0x2000: pad PTE has W but not R
.4byte 0x8001300C, 0x20200817, 0x0 # Vaddr 0x3000: A=0, should cause read fault

View File

@ -21,18 +21,15 @@
// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
///////////////////////////////////////////
#include "riscv_test_macros.h"
#include "compliance_test.h"
#include "compliance_io.h"
#include "model_test.h"
#include "arch_test.h"
RVTEST_ISA("RV32I")
RV_COMPLIANCE_RV64M
RV_COMPLIANCE_CODE_BEGIN
RVTEST_IO_INIT
RVTEST_IO_ASSERT_GPR_EQ(x31, x0, 0x00000000)
RVTEST_IO_WRITE_STR(x31, "Test Begin\n")
.section .text.init
.globl rvtest_entry_point
rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
# ---------------------------------------------------------------------------------------------
@ -624,18 +621,15 @@ terminate_test:
ecall # writes mcause to the output.
csrw mtvec, x4 # restore original trap handler to halt program
# ---------------------------------------------------------------------------------------------
RVTEST_IO_WRITE_STR(x31, "Test End\n")
RVTEST_CODE_END
RVMODEL_HALT
# ---------------------------------------------------------------------------------------------
RV_COMPLIANCE_HALT
RV_COMPLIANCE_CODE_END
# Input data section.
.data
RVTEST_DATA_BEGIN
.align 4
rvtest_data:
.word 0xbabecafe
RVTEST_DATA_END
.align 2 # align stack to 4 byte boundary
bottom_of_stack:
@ -643,15 +637,29 @@ bottom_of_stack:
top_of_stack:
# Output data section.
RV_COMPLIANCE_DATA_BEGIN
.align 2 # align output to 4 byte boundary
RVMODEL_DATA_BEGIN
// next lines through test cases copied over from old framework
test_1_res:
.fill 1024, 4, -1
RV_COMPLIANCE_DATA_END
RVMODEL_DATA_END
#ifdef rvtest_mtrap_routine
mtrap_sigptr:
.fill 64*(XLEN/32),4,0xdeadbeef
#endif
#ifdef rvtest_gpr_save
gpr_save:
.fill 32*(XLEN/32),4,0xdeadbeef
#endif
.align 2
test_cases:
# These tests follow the testing plan in Chapter 12 of the riscv-wally textbook *** what is it called and how do I refer to it?

View File

@ -31,7 +31,8 @@ rv64i_sc_tests = \
WALLY-MMU-SV39 \
WALLY-MMU-SV48 \
WALLY-PMA \
WALLY-PMP
WALLY-PMP
rv64i_tests = $(addsuffix .elf, $(rv64i_sc_tests))

View File

@ -47,22 +47,22 @@ test_contents:
# test 12.3.1.1.1 write page tables / entries to phyiscal memory
# sv39 page table (See Figure 12.12***):
# Level 2 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004CC1, 0x0 # points to level 1 page table A
.8byte 0x000000008000D008, 0x00000000200050C1, 0x0 # points to level 1 page table B
.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 1 page table A
.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 1 page table B
.8byte 0x000000008000D010, 0x00000000200000CF, 0x0 # Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory)
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0xC000_0000: misaligned gigapage
.8byte 0x000000008000DFF8, 0x00000000200054E1, 0x0 # points to level 1 page table C
.8byte 0x000000008000DFF8, 0x0000000020005421, 0x0 # points to level 1 page table C
# Level 1 page table A
.8byte 0x0000000080013000, 0x00000000200060C1, 0x0 # points to level 0 page table A
.8byte 0x0000000080013000, 0x0000000020006001, 0x0 # points to level 0 page table A
# Level 1 page table B
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x4000_0000, Paddr 0x80000000: aligned megapage, W=0, used for execution tests
.8byte 0x0000000080014008, 0x00000400000080C3, 0x0 # Vaddr 0x4020_0000: misaligned megapage
.8byte 0x0000000080014010, 0x00000000200000DF, 0x0 # Vaddr 0x4040_0000, Paddr 0x80000000: aligned megapage, aliased with program, U=1
.8byte 0x0000000080014018, 0x00000000210800C9, 0x0 # Vaddr 0x4060_0000, Paddr 0x84200000: R=0, reads should fault
# Level 1 page table C
.8byte 0x0000000080015FF8, 0x00000000200058C1, 0x0 # points to level 0 page table B
.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 0 page table B
# Level 0 page table A
.8byte 0x0000000080018000, 0x00000000200070D1, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
.8byte 0x0000000080018000, 0x0000000020007001, 0x0 # Vaddr 0x0000: bad PTE points to level -1 table
.8byte 0x0000000080018008, 0x00000000200800DF, 0x0 # Vaddr 0x1000, Paddr = 0x80200000: aligned kilopage
.8byte 0x0000000080018010, 0x00000000200810D5, 0x0 # Vaddr 0x2000: bad PTE has W but not R
.8byte 0x0000000080018018, 0x0000000020080817, 0x0 # Vaddr 0x3000 Paddr 0x80202000: A=0, should cause read fault

View File

@ -46,28 +46,28 @@
# test 12.3.1.1.1 write page tables / entries to phyiscal memory
# sv48 page table (See Figure 12.12***):
# Level 3 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004CC1, 0x0 # points to level 2 page table A
.8byte 0x000000008000D008, 0x00000000200050C1, 0x0 # points to level 2 page table B
.8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 2 page table A
.8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 2 page table B
.8byte 0x000000008000D010, 0x00000000000000C7, 0x0 # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0x018000000000, misaligned terapage
.8byte 0x000000008000DFF8, 0x00000000200054E1, 0x0 # points to level 2 page table C
.8byte 0x000000008000DFF8, 0x0000000020005421, 0x0 # points to level 2 page table C
# Level 2 page table A
.8byte 0x0000000080013010, 0x00000000200060C1, 0x0 # points to level 1 page table A
.8byte 0x0000000080013010, 0x0000000020006001, 0x0 # points to level 1 page table A
# Level 2 page table B
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x008000000000, Paddr 0x80000000: aligned gigapage used for execution tests
.8byte 0x0000000080014008, 0x00000000200000DF, 0x0 # Vaddr 0x008040000000, Paddr 0x80000000: aligned gigapage (aliased with data and instr memory) U bit set.
.8byte 0x0000000080014010, 0x00000400080000C3, 0x0 # Vaddr 0x008080000000, misaligned gigapage
# Level 2 page table C
.8byte 0x0000000080015FF8, 0x00000000200058C1, 0x0 # points to level 1 page table B
.8byte 0x0000000080015FF8, 0x0000000020005801, 0x0 # points to level 1 page table B
# Level 1 page table A
.8byte 0x0000000080018000, 0x00000000200000CF, 0x0 # Vaddr 0x80000000, Paddr 0x80000000: aligned megapage (data and instr memory)
.8byte 0x0000000080018008, 0x00000000200064C1, 0x0 # points to level 0 page table A
.8byte 0x0000000080018008, 0x0000000020006401, 0x0 # points to level 0 page table A
.8byte 0x0000000080018010, 0x000000C0000400CF, 0x0 # Vaddr 0x80400000, misaligned megapage
.8byte 0x0000000080018018, 0x00000000214800C9, 0x0 # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0
# Level 1 page table B
.8byte 0x0000000080016FF8, 0x00000000200068C1, 0x0 # points to level 0 page table B
.8byte 0x0000000080016FF8, 0x0000000020006801, 0x0 # points to level 0 page table B
# Level 0 page table A
.8byte 0x0000000080019000, 0x00000000200070D1, 0x0 # Vaddr 0x80200000, Paddr 0x8001C000: bad PTE points to level -1 table
.8byte 0x0000000080019000, 0x0000000020007001, 0x0 # Vaddr 0x80200000, Paddr 0x8001C000: bad PTE points to level -1 table
.8byte 0x0000000080019008, 0x00000000200800DF, 0x0 # Vaddr 0x80201000, Paddr 0x80200000: aligned kilopage
.8byte 0x0000000080019010, 0x00000000200810DF, 0x0 # Vaddr 0x80202000, Paddr 0x80204000: bad PTE has W but not R
.8byte 0x0000000080019018, 0x0000000020080817, 0x0 # Vaddr 0x80203000, Paddr 0x80202000: A=0, should cause read fault

View File

@ -629,40 +629,6 @@ terminate_test:
ecall # writes mcause to the output.
csrw mtvec, x4 # restore original trap handler to halt program
/*
# ---------------------------------------------------------------------------------------------
RVTEST_IO_WRITE_STR(x31, "Test End\n")
# ---------------------------------------------------------------------------------------------
RV_COMPLIANCE_HALT
RV_COMPLIANCE_CODE_END
# Input data section.
.data
.align 3 # align stack to 8 byte boundary
bottom_of_stack:
.fill 1024, 4, -1
top_of_stack:
# Output data section.
RV_COMPLIANCE_DATA_BEGIN
.align 3 # align output to 8 byte boundary
test_1_res:
.fill 1024, 4, -1
RV_COMPLIANCE_DATA_END
.align 3
test_cases:
*/
RVTEST_CODE_END
RVMODEL_HALT
@ -678,37 +644,13 @@ bottom_of_stack:
top_of_stack:
RVMODEL_DATA_BEGIN
// next lines through test cases copied over from old framework
test_1_res:
.fill 1024, 4, -1
RVMODEL_DATA_END
/*
signature_x8_0:
.fill 0*(XLEN/32),4,0xdeadbeef
signature_x8_1:
.fill 19*(XLEN/32),4,0xdeadbeef
signature_x1_0:
.fill 256*(XLEN/32),4,0xdeadbeef
signature_x1_1:
.fill 256*(XLEN/32),4,0xdeadbeef
signature_x1_2:
.fill 148*(XLEN/32),4,0xdeadbeef
*/
#ifdef rvtest_mtrap_routine
mtrap_sigptr:

View File

@ -41,9 +41,9 @@
`define MISA (32'h00000104)
`define ZICSR_SUPPORTED 1
`define ZIFENCEI_SUPPORTED 1
`define ZIFENCEI_SUPPORTED 0
`define COUNTERS 32
`define ZICOUNTERS_SUPPORTED 1
`define ZICOUNTERS_SUPPORTED 0
// Microarchitectural Features
`define UARCH_PIPELINED 1
@ -53,12 +53,12 @@
`define MEM_DCACHE 1
`define MEM_IROM 1
`define MEM_ICACHE 1
`define MEM_VIRTMEM 1
`define MEM_VIRTMEM 0
`define VECTORED_INTERRUPTS_SUPPORTED 1
// TLB configuration. Entries should be a power of 2
`define ITLB_ENTRIES 32
`define DTLB_ENTRIES 32
`define ITLB_ENTRIES 0
`define DTLB_ENTRIES 0
// Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 bytes per way, 256 bit or more blocks
@ -75,7 +75,7 @@
`define DIV_BITSPERCYCLE 4
// Legal number of PMP entries are 0, 16, or 64
`define PMP_ENTRIES 16
`define PMP_ENTRIES 0
// Address space
`define RESET_VECTOR 32'h80000000

View File

@ -5,7 +5,7 @@ export PATH=$PATH:/usr/local/bin/
verilator=`which verilator`
basepath=$(dirname $0)/..
for config in rv64gc rv32gc; do
for config in rv64gc rv32gc rv32ic; do
echo "$config linting..."
if !($verilator --lint-only "$@" --top-module wallypipelinedsoc "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes); then
echo "Exiting after $config lint due to errors or warnings"

View File

@ -203,7 +203,7 @@ add wave -noupdate -group AHB -color Gold /testbench/dut/hart/ebu/BusState
add wave -noupdate -group AHB /testbench/dut/hart/ebu/NextBusState
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/AtomicMaskedM
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/InstrReadF
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/MemSizeM
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/LsuBusSize
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HCLK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESETn
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRDATA
@ -220,19 +220,17 @@ add wave -noupdate -group AHB /testbench/dut/hart/ebu/HMASTLOCK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDRD
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/dcache/genblk3/amoalu/funct
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/dcache/genblk3/amoalu/result
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/dcache/genblk3/amoalu/srca
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/dcache/genblk3/amoalu/srcb
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/dcache/genblk3/amoalu/width
add wave -noupdate -expand -group lsu -color Gold /testbench/dut/hart/lsu/CurrState
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/amo/amoalu/funct
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/amo/amoalu/result
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/amo/amoalu/srca
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/amo/amoalu/srcb
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/amo/amoalu/width
add wave -noupdate -expand -group lsu -color Gold /testbench/dut/hart/lsu/MEM_VIRTMEM/InterlockCurrState
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/SelHPTW
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/InterlockStall
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/LSUStall
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/WalkerInstrPageFaultF
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/WalkerInstrPageFaultRaw
add wave -noupdate -expand -group lsu -group dcache -color Gold /testbench/dut/hart/lsu/dcache/dcachefsm/CurrState
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/WriteDataM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/FinalWriteDataM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWriteEnableM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordWriteEnableM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/SRAMWayWriteEnable
@ -240,7 +238,7 @@ add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcac
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWayWriteEnableM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/SelAdrM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/ReadDataBlockM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/SelReplayCPURequest
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/MEM_VIRTMEM/SelReplayCPURequest
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/IEUAdrE
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/IEUAdrM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/MemAdrE_RENAME
@ -249,13 +247,12 @@ add wave -noupdate -expand -group lsu -group dcache -group flush -radix unsigned
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/dcache/FlushWay
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/dcache/VictimDirtyWay
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/dcache/VictimTag
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/dcache/BasePAdrM
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/dcache/FetchCount
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/dcache/DCacheBusAdr
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/WordCount
add wave -noupdate -expand -group lsu -group dcache -group flush /testbench/dut/hart/lsu/dcache/CacheableM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/DCacheMemWriteData
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/WayHit
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/IgnoreRequest
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/ExceptionM
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WriteEnable}
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetValid}
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetDirty}
@ -338,7 +335,6 @@ add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} -ex
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/WayHit
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataBlockWayMaskedM
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordM
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordMuxM
add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimTag
add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimWay
add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirtyWay
@ -346,73 +342,70 @@ add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemRWM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemAdrE
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/IEUAdrM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemPAdrM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/LsuPAdrM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct3M
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct7M
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/AtomicM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/CacheableM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/FlushDCacheM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/WriteDataM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/ReadDataM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/FinalWriteDataM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/ReadDataWordM
add wave -noupdate -expand -group lsu -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/DCacheStall
add wave -noupdate -expand -group lsu -group dcache -group status /testbench/dut/hart/lsu/dcache/WayHit
add wave -noupdate -expand -group lsu -group dcache -group status -color {Medium Orchid} /testbench/dut/hart/lsu/dcache/CacheHit
add wave -noupdate -expand -group lsu -group dcache -group status /testbench/dut/hart/lsu/dcache/FetchCount
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBPAdr
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBRead
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBWrite
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBAck
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/HRDATA
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/HWDATA
add wave -noupdate -expand -group lsu -group dcache -group status /testbench/dut/hart/lsu/WordCount
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCacheBusAdr
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCacheFetchLine
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCacheWriteLine
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCacheBusAck
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/ReadDataBlockSetsM
add wave -noupdate -expand -group lsu -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCacheMemWriteData
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/FlushWay
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/EffectivePrivilegeMode
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/Translate
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/DisableTranslation
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBMiss
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBHit
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/PhysicalAddress
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/TLBPageFault
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/LoadAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/StoreAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBPAdr
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/PTE
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBWrite
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/SelRegions
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Cacheable
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Idempotent
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/AtomicAllowed
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PMAAccessFault
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMALoadAccessFaultM
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/ReadAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/WriteAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/PMPADDR_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/PMPCFG_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPLoadAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/Match
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/FirstMatch
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/R
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/W
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/X
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/L
add wave -noupdate -expand -group lsu -expand -group ptwalker -color Gold /testbench/dut/hart/lsu/hptw/genblk1/WalkerState
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/hptw/PCF
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/hptw/genblk1/TranslationVAdr
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/hptw/HPTWReadPTE
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/hptw/HPTWAdr
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/hptw/PTE
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/ITLBMissF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/DTLBMissM
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/ITLBWriteF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/DTLBWriteM
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerInstrPageFaultF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerLoadPageFaultM
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerStorePageFaultM
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/tlbcontrol/EffectivePrivilegeMode
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/tlbcontrol/Translate
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/tlbcontrol/DisableTranslation
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/TLBMiss
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/TLBHit
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/PhysicalAddress
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/dmmu/TLBPageFault
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/dmmu/LoadAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/dmmu/StoreAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/TLBPAdr
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/PTE
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/TLBWrite
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/pmachecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/pmachecker/SelRegions
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/Cacheable
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/Idempotent
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/AtomicAllowed
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/pmachecker/PMAAccessFault
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/PMAInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/PMALoadAccessFaultM
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/PMAStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/ReadAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/WriteAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/PMPADDR_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/PMPCFG_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/PMPInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/PMPLoadAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/PMPStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/Match
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/FirstMatch
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/R
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/W
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/X
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/L
add wave -noupdate -expand -group lsu -expand -group ptwalker -color Gold /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/genblk1/WalkerState
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/PCF
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/genblk1/TranslationVAdr
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/HPTWReadPTE
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/HPTWAdr
add wave -noupdate -expand -group lsu -expand -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/PTE
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/ITLBMissF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/DTLBMissM
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/ITLBWriteF
add wave -noupdate -expand -group lsu -expand -group ptwalker -expand -group types /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/DTLBWriteM
add wave -noupdate -expand -group itlb /testbench/dut/hart/ifu/immu/TLBWrite
add wave -noupdate -expand -group itlb /testbench/dut/hart/ifu/ITLBMissF
add wave -noupdate -expand -group itlb /testbench/dut/hart/ifu/immu/PhysicalAddress
@ -504,7 +497,7 @@ add wave -noupdate /testbench/dut/hart/ifu/PCSrcE
add wave -noupdate /testbench/dut/hart/ieu/c/BranchTakenE
add wave -noupdate /testbench/dut/hart/ieu/c/BranchE
add wave -noupdate /testbench/dut/hart/ifu/PCLinkE
add wave -noupdate /testbench/dut/hart/lsu/DCtoAHBSizeM
add wave -noupdate /testbench/dut/hart/lsu/LsuBusSize
add wave -noupdate /testbench/dut/hart/ifu/PCF
add wave -noupdate /testbench/dut/uncore/uart/uart/u/LSR
add wave -noupdate /testbench/dut/uncore/uart/uart/u/DLM

View File

@ -15,7 +15,7 @@ import sys,os
from collections import namedtuple
regressionDir = os.path.dirname(os.path.abspath(__file__))
os.chdir(regressionDir)
TestCase = namedtuple("TestCase", ['name', 'cmd', 'grepstr'])
TestCase = namedtuple("TestCase", ['name', 'variant', 'cmd', 'grepstr'])
# name: the name of this test configuration (used in printing human-readable
# output and picking logfile names)
# cmd: the command to run to test (should include the logfile as '{}', and
@ -28,6 +28,7 @@ TestCase = namedtuple("TestCase", ['name', 'cmd', 'grepstr'])
configs = [
TestCase(
name="lints",
variant="all",
cmd="./lint-wally &> {}",
grepstr="All lints run with no errors or warnings"
)
@ -41,29 +42,40 @@ def getBuildrootTC(short):
else:
BRcmd="vsim > {} -c <<!\ndo wally-buildroot-batch.do 0 1 0\n!"
BRgrepstr=str(MAX_EXPECTED)+" instructions"
return TestCase(name="buildroot",cmd=BRcmd,grepstr=BRgrepstr)
return TestCase(name="buildroot",variant="rv64gc",cmd=BRcmd,grepstr=BRgrepstr)
tc = TestCase(
name="buildroot-checkpoint",
variant="rv6gc",
cmd="vsim > {} -c <<!\ndo wally-buildroot-batch.do 400100000 400000001 400000000\n!",
grepstr="400100000 instructions")
configs.append(tc)
tests64 = ["wally64i", "arch64i", "arch64priv", "arch64c", "arch64m", "arch64d", "imperas64i", "imperas64f", "imperas64d", "imperas64p", "imperas64mmu", "imperas64m", "imperas64a", "imperas64c"] #, "testsBP64"]
for test in tests64:
tests64gc = ["arch64i", "arch64priv", "arch64c", "arch64m", "arch64d", "imperas64i", "imperas64f", "imperas64d", "imperas64p", "imperas64m", "imperas64a", "imperas64c", "wally64priv"] # "wally64i", #, "testsBP64"]
for test in tests64gc:
tc = TestCase(
name=test,
variant="rv64gc",
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv64gc "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32 = ["wally32i", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32p", "imperas32mmu", "imperas32m", "imperas32a", "imperas32c"]
for test in tests32:
tests32gc = ["arch32i", "arch32priv", "arch32c", "arch32m", "arch32f", "imperas32i", "imperas32f", "imperas32p", "imperas32m", "imperas32a", "imperas32c", "wally32priv"] #"wally32i",
for test in tests32gc:
tc = TestCase(
name=test,
variant="rv32gc",
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv32gc "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
tests32ic = ["arch32i", "arch32c"]
for test in tests32ic:
tc = TestCase(
name=test,
variant="rv32ic",
cmd="vsim > {} -c <<!\ndo wally-pipelined-batch.do rv32ic "+test+"\n!",
grepstr="All tests ran without failures")
configs.append(tc)
import os
@ -76,16 +88,16 @@ def search_log_for_text(text, logfile):
def run_test_case(config):
"""Run the given test case, and return 0 if the test suceeds and 1 if it fails"""
logname = "logs/wally_"+config.name+".log"
logname = "logs/"+config.variant+"_"+config.name+".log"
cmd = config.cmd.format(logname)
print(cmd)
os.chdir(regressionDir)
os.system(cmd)
if search_log_for_text(config.grepstr, logname):
print("%s: Success" % config.name)
print("%s_%s: Success" % (config.variant, config.name))
return 0
else:
print("%s: Failures detected in output" % config.name)
print("%s_%s: Failures detected in output" % (config.variant, config.name))
print(" Check %s" % logname)
return 1

View File

@ -1,3 +1,3 @@
vsim -c <<!
do wally-pipelined-batch.do rv64gc imperas64periph
do wally-pipelined-batch.do rv64gc wally64priv
!

View File

@ -175,11 +175,11 @@ add wave -noupdate -group icache -expand -group {fsm out and control} /testbench
add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/PreCntEn
add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntEn
add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/FinalInstrRawF
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/InstrPAdrF
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/IfuBusFetch
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/ICacheBusAdr
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/FetchCount
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheBusAck
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/ICacheMemWriteData
add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/ICacheMemReadData
@ -187,7 +187,7 @@ add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/SpillDataBlock0
add wave -noupdate -group AHB -color Gold /testbench/dut/hart/ebu/BusState
add wave -noupdate -group AHB /testbench/dut/hart/ebu/NextBusState
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/AtomicMaskedM
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/InstrReadF
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/IfuBusFetch
add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/LsuBusSize
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HCLK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESETn
@ -205,179 +205,181 @@ add wave -noupdate -group AHB /testbench/dut/hart/ebu/HMASTLOCK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDRD
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED
add wave -noupdate -expand -group lsu -color Gold /testbench/dut/hart/lsu/MEM_VIRTMEM/InterlockCurrState
add wave -noupdate -expand -group lsu -color Gold /testbench/dut/hart/lsu/MEM_VIRTMEM/interlockfsm/InterlockCurrState
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/SelHPTW
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/InterlockStall
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/LSUStall
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/ReadDataWordMuxM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/ReadDataM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/WriteDataM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/SelUncached
add wave -noupdate -expand -group lsu -expand -group bus -color Gold /testbench/dut/hart/lsu/BusCurrState
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/SelUncachedAdr
add wave -noupdate -expand -group lsu -expand -group bus -color Gold /testbench/dut/hart/lsu/busfsm/BusCurrState
add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/BusStall
add wave -noupdate -expand -group lsu -expand -group dcache -color Gold /testbench/dut/hart/lsu/dcache/dcachefsm/CurrState
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/WayHit
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWriteEnableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordWriteEnableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWayWriteEnable
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordEnable
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWayWriteEnableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SelAdrM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/ReadDataBlockM
add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusRead
add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusWrite
add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusAdr
add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusAck
add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusHWDATA
add wave -noupdate -expand -group lsu -expand -group dcache -color Gold /testbench/dut/hart/lsu/dcache/dcache/dcachefsm/CurrState
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/WayHit
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/SRAMBlockWriteEnableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/SRAMWordWriteEnableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/SRAMWayWriteEnable
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/SRAMWordEnable
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/SRAMBlockWayWriteEnableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/SelAdrM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/ReadDataBlockM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/MEM_VIRTMEM/SelReplayCPURequest
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/IEUAdrE
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/IEUAdrM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/RAdr
add wave -noupdate -expand -group lsu -expand -group dcache -group flush -radix unsigned /testbench/dut/hart/lsu/dcache/FlushAdr
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/FlushWay
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/VictimDirtyWay
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/VictimTag
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/CacheableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/DCacheMemWriteData
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetValid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[0]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[0]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[0]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[0]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[0]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WriteWordEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[1]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[1]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[1]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[1]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/hart/lsu/dcache/MemWay[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/hart/lsu/dcache/MemWay[1]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/SetValid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[2]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetValid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ClearDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/VDWriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[3]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/SetValid
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/ClearValid
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/SetDirty
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/ClearDirty
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/RAdr
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/WayHit
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataBlockWayMaskedM
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordM
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordMuxM
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimTag
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimWay
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirtyWay
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirty
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemRWM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemAdrE
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemPAdrM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct3M
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct7M
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/AtomicM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/CacheableM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/FlushDCacheM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/DCacheStall
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/RAdr
add wave -noupdate -expand -group lsu -expand -group dcache -group flush -radix unsigned /testbench/dut/hart/lsu/dcache/dcache/FlushAdr
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/dcache/FlushWay
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/dcache/VictimDirtyWay
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/dcache/VictimTag
add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/dcache/CacheableM
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/DCacheMemWriteData
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/SetValid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[0]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[0]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[0]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[0]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/WriteWordEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[1]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[1]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[1]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[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/hart/lsu/dcache/dcache/MemWay[1]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/SetValid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -label TAG {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/SetValid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/SetDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/ClearDirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/VDWriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/CacheTagMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/DirtyBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/ValidBits}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[0]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[0]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[1]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[1]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[2]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[2]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[3]/CacheDataMem/WriteEnable}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/word[3]/CacheDataMem/StoredData}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/dcache/SetValid
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/dcache/ClearValid
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/dcache/SetDirty
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/dcache/ClearDirty
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/dcache/RAdr
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[0]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[1]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[2]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/WayHit}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/Valid}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/Dirty}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/dcache/MemWay[3]/ReadTag}
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/dcache/WayHit
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/dcache/ReadDataBlockWayMaskedM
add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/dcache/ReadDataWordM
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/dcache/VictimTag
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/dcache/VictimWay
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/dcache/VictimDirtyWay
add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/dcache/VictimDirty
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/dcache/LsuRWM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/dcache/LsuAdrE
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/dcache/LsuPAdrM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/dcache/LsuAtomicM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/dcache/CacheableM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/dcache/FlushDCacheM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/dcache/DCacheStall
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/ReadDataWordM
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/FinalWriteDataM
add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/WayHit
add wave -noupdate -expand -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/hart/lsu/dcache/CacheHit
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCFetchLine
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCWriteLine
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/DCacheMemWriteData
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/BUSACK
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/FlushWay
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/VAdr
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/EffectivePrivilegeMode
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/PTE
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/HitPageType
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/Translate
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/DisableTranslation
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBMiss
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBHit
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/PhysicalAddress
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/TLBPageFault
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/LoadAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/StoreAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBPAdr
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/PTE
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/PageTypeWriteVal
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBWrite
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/SelRegions
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Cacheable
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Idempotent
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/AtomicAllowed
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PMAAccessFault
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMALoadAccessFaultM
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/ReadAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/WriteAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/PMPADDR_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/PMPCFG_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPLoadAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/Match
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/FirstMatch
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/R
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/W
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/X
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/pmpchecker/L
add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/dcache/WayHit
add wave -noupdate -expand -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/hart/lsu/dcache/dcache/CacheHit
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/dcache/DCacheFetchLine
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/dcache/DCacheWriteLine
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/dcache/DCacheMemWriteData
add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/dcache/DCacheBusAck
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/dcache/FlushWay
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/VAdr
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/tlbcontrol/EffectivePrivilegeMode
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/PTE
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/HitPageType
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/tlbcontrol/Translate
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/tlbcontrol/DisableTranslation
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/TLBMiss
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/TLBHit
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/PhysicalAddress
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/dmmu/TLBPageFault
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/dmmu/LoadAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/dmmu/StoreAccessFaultM
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/TLBPAdr
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/PTE
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/PageTypeWriteVal
add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/dmmu/genblk1/tlb/TLBWrite
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/pmachecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/pmachecker/SelRegions
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/Cacheable
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/Idempotent
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/AtomicAllowed
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/pmachecker/PMAAccessFault
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/PMAInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/PMALoadAccessFaultM
add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/dmmu/PMAStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/PhysicalAddress
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/ReadAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/WriteAccessM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/PMPADDR_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/PMPCFG_ARRAY_REGW
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/PMPInstrAccessFaultF
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/PMPLoadAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/PMPStoreAccessFaultM
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/Match
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/FirstMatch
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/R
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/W
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/X
add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/dmmu/pmpchecker/pmpchecker/L
add wave -noupdate -expand -group lsu -group ptwalker -color Gold /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/genblk1/WalkerState
add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/PCF
add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/genblk1/TranslationVAdr
@ -468,10 +470,11 @@ add wave -noupdate -group {pc selection} /testbench/dut/hart/ifu/PrivilegedNextP
add wave -noupdate -group {pc selection} /testbench/dut/hart/ifu/PrivilegedChangePCM
add wave -noupdate /testbench/dut/hart/priv/priv/csr/MEPC_REGW
add wave -noupdate /testbench/dut/hart/lsu/LocalLsuBusAdr
add wave -noupdate /testbench/dut/hart/lsu/BasePAdrMaskedM
add wave -noupdate /testbench/dut/hart/lsu/match
add wave -noupdate /testbench/dut/hart/lsu/busfsm/BusNextState
add wave -noupdate /testbench/dut/hart/lsu/busfsm/DCacheFetchLine
add wave -noupdate /testbench/dut/hart/lsu/busfsm/DCacheWriteLine
TreeUpdate [SetDefaultTree]
WaveRestoreCursors {{Cursor 7} {36865 ns} 1} {{Cursor 5} {49445 ns} 1} {{Cursor 3} {35021 ns} 0} {{Cursor 4} {49574 ns} 1}
WaveRestoreCursors {{Cursor 7} {36865 ns} 1} {{Cursor 5} {49445 ns} 1} {{Cursor 3} {9745 ns} 0} {{Cursor 4} {49574 ns} 1}
quietly wave cursor active 3
configure wave -namecolwidth 250
configure wave -valuecolwidth 314
@ -487,4 +490,4 @@ configure wave -griddelta 40
configure wave -timeline 0
configure wave -timelineunits ns
update
WaveRestoreZoom {34887 ns} {35269 ns}
WaveRestoreZoom {9530 ns} {9952 ns}

View File

@ -29,7 +29,7 @@ module cachereplacementpolicy
(input logic clk, reset,
input logic [NUMWAYS-1:0] WayHit,
output logic [NUMWAYS-1:0] VictimWay,
input logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] MemPAdrM,
input logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] LsuPAdrM,
input logic [INDEXLEN-1:0] RAdr,
input logic LRUWriteEn
);
@ -44,7 +44,7 @@ module cachereplacementpolicy
logic [NUMWAYS-2:0] NewReplacement;
logic [NUMWAYS-2:0] NewReplacementD;
logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] MemPAdrMD;
logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] LsuPAdrMD;
logic [INDEXLEN-1:0] RAdrD;
logic LRUWriteEnD;
@ -52,18 +52,18 @@ module cachereplacementpolicy
always_ff @(posedge clk) begin
if (reset) begin
RAdrD <= '0;
MemPAdrMD <= '0;
LsuPAdrMD <= '0;
LRUWriteEnD <= 0;
NewReplacementD <= '0;
for(int index = 0; index < NUMLINES; index++)
ReplacementBits[index] <= '0;
end else begin
RAdrD <= RAdr;
MemPAdrMD <= MemPAdrM;
LsuPAdrMD <= LsuPAdrM;
LRUWriteEnD <= LRUWriteEn;
NewReplacementD <= NewReplacement;
if (LRUWriteEnD) begin
ReplacementBits[MemPAdrMD[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacementD;
ReplacementBits[LsuPAdrMD[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacementD;
end
end
end

View File

@ -26,124 +26,115 @@
`include "wally-config.vh"
module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26,
parameter OFFSETLEN = 5, parameter INDEXLEN = 9, parameter DIRTY_BITS = 1)
parameter OFFSETLEN = 5, parameter INDEXLEN = 9, parameter DIRTY_BITS = 1)
(input logic clk,
input logic reset,
input logic reset,
input logic [$clog2(NUMLINES)-1:0] RAdr,
input logic [$clog2(NUMLINES)-1:0] WAdr,
input logic [`PA_BITS-1:0] PAdr,
input logic WriteEnable,
input logic VDWriteEnable,
input logic [`PA_BITS-1:0] PAdr,
input logic WriteEnable,
input logic VDWriteEnable,
input logic [BLOCKLEN/`XLEN-1:0] WriteWordEnable,
input logic TagWriteEnable,
input logic [BLOCKLEN-1:0] WriteData,
input logic SetValid,
input logic ClearValid,
input logic SetDirty,
input logic ClearDirty,
input logic SelEvict,
input logic VictimWay,
input logic InvalidateAll,
input logic SelFlush,
input logic FlushWay,
input logic TagWriteEnable,
input logic [BLOCKLEN-1:0] WriteData,
input logic SetValid,
input logic ClearValid,
input logic SetDirty,
input logic ClearDirty,
input logic SelEvict,
input logic VictimWay,
input logic InvalidateAll,
input logic SelFlush,
input logic FlushWay,
output logic [BLOCKLEN-1:0] ReadDataBlockWayMasked,
output logic WayHit,
output logic VictimDirtyWay,
output logic [TAGLEN-1:0] VictimTagWay
output logic [BLOCKLEN-1:0] ReadDataLineWayMasked,
output logic WayHit,
output logic VictimDirtyWay,
output logic [TAGLEN-1:0] VictimTagWay
);
logic [NUMLINES-1:0] ValidBits;
logic [NUMLINES-1:0] DirtyBits;
logic [BLOCKLEN-1:0] ReadDataBlockWay;
logic [TAGLEN-1:0] ReadTag;
logic Valid;
logic Dirty;
logic SelectedWay;
logic [TAGLEN-1:0] VicDirtyWay;
logic [TAGLEN-1:0] FlushThisWay;
logic [NUMLINES-1:0] ValidBits;
logic [NUMLINES-1:0] DirtyBits;
logic [BLOCKLEN-1:0] ReadDataBlockWay;
logic [TAGLEN-1:0] ReadTag;
logic Valid;
logic Dirty;
logic SelectedWay;
logic [TAGLEN-1:0] VicDirtyWay;
logic [TAGLEN-1:0] FlushThisWay;
logic [$clog2(NUMLINES)-1:0] RAdrD, WAdrD;
logic SetValidD, ClearValidD;
logic SetDirtyD, ClearDirtyD;
logic WriteEnableD, VDWriteEnableD;
logic [$clog2(NUMLINES)-1:0] RAdrD;
logic SetValidD, ClearValidD;
logic SetDirtyD, ClearDirtyD;
logic WriteEnableD, VDWriteEnableD;
genvar words;
genvar words;
generate
for(words = 0; words < BLOCKLEN/`XLEN; words++) begin : word
sram1rw #(.DEPTH(`XLEN),
.WIDTH(NUMLINES))
CacheDataMem(.clk(clk),
.Addr(RAdr),
.ReadData(ReadDataBlockWay[(words+1)*`XLEN-1:words*`XLEN] ),
.WriteData(WriteData[(words+1)*`XLEN-1:words*`XLEN]),
.WriteEnable(WriteEnable & WriteWordEnable[words]));
sram1rw #(.DEPTH(`XLEN), .WIDTH(NUMLINES))
CacheDataMem(.clk(clk), .Addr(RAdr),
.ReadData(ReadDataBlockWay[(words+1)*`XLEN-1:words*`XLEN] ),
.WriteData(WriteData[(words+1)*`XLEN-1:words*`XLEN]),
.WriteEnable(WriteEnable & WriteWordEnable[words]));
end
endgenerate
sram1rw #(.DEPTH(TAGLEN),
.WIDTH(NUMLINES))
sram1rw #(.DEPTH(TAGLEN), .WIDTH(NUMLINES))
CacheTagMem(.clk(clk),
.Addr(RAdr),
.ReadData(ReadTag),
.WriteData(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]),
.WriteEnable(TagWriteEnable));
.Addr(RAdr),
.ReadData(ReadTag),
.WriteData(PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]),
.WriteEnable(TagWriteEnable));
assign WayHit = Valid & (ReadTag == PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]);
assign SelectedWay = SelFlush ? FlushWay :
SelEvict ? VictimWay : WayHit;
assign ReadDataBlockWayMasked = SelectedWay ? ReadDataBlockWay : '0; // first part of AO mux.
SelEvict ? VictimWay : WayHit;
assign ReadDataLineWayMasked = SelectedWay ? ReadDataBlockWay : '0; // first part of AO mux.
assign VictimDirtyWay = SelFlush ? FlushWay & Dirty & Valid :
VictimWay & Dirty & Valid;
/* -----\/----- EXCLUDED -----\/-----
assign VictimTagWay = SelFlush & FlushWay ? ReadTag :
VictimWay ? ReadTag : '0;
-----/\----- EXCLUDED -----/\----- */
VictimWay & Dirty & Valid;
assign VicDirtyWay = VictimWay ? ReadTag : '0;
assign FlushThisWay = FlushWay ? ReadTag : '0;
assign VictimTagWay = SelFlush ? FlushThisWay : VicDirtyWay;
always_ff @(posedge clk) begin
if (reset)
ValidBits <= {NUMLINES{1'b0}};
ValidBits <= {NUMLINES{1'b0}};
else if (InvalidateAll)
ValidBits <= {NUMLINES{1'b0}};
else if (SetValidD & (WriteEnableD | VDWriteEnableD)) ValidBits[WAdrD] <= 1'b1;
else if (ClearValidD & (WriteEnableD | VDWriteEnableD)) ValidBits[WAdrD] <= 1'b0;
end
ValidBits <= {NUMLINES{1'b0}};
else if (SetValidD & (WriteEnableD | VDWriteEnableD)) ValidBits[RAdrD] <= 1'b1;
else if (ClearValidD & (WriteEnableD | VDWriteEnableD)) ValidBits[RAdrD] <= 1'b0;
end
always_ff @(posedge clk) begin
RAdrD <= RAdr;
WAdrD <= WAdr;
SetValidD <= SetValid;
ClearValidD <= ClearValid;
WriteEnableD <= WriteEnable;
VDWriteEnableD <= VDWriteEnable;
end
assign Valid = ValidBits[RAdrD];
generate
if(DIRTY_BITS) begin
always_ff @(posedge clk) begin
if (reset)
DirtyBits <= {NUMLINES{1'b0}};
else if (SetDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[WAdrD] <= 1'b1;
else if (ClearDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[WAdrD] <= 1'b0;
if (reset)
DirtyBits <= {NUMLINES{1'b0}};
else if (SetDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[RAdrD] <= 1'b1;
else if (ClearDirtyD & (WriteEnableD | VDWriteEnableD)) DirtyBits[RAdrD] <= 1'b0;
end
always_ff @(posedge clk) begin
SetDirtyD <= SetDirty;
ClearDirtyD <= ClearDirty;
SetDirtyD <= SetDirty;
ClearDirtyD <= ClearDirty;
end
assign Dirty = DirtyBits[RAdrD];

View File

@ -31,30 +31,26 @@ module dcache
input logic CPUBusy,
// cpu side
input logic [1:0] MemRWM,
input logic [2:0] Funct3M,
input logic [6:0] Funct7M,
input logic [1:0] AtomicM,
input logic [1:0] LsuRWM,
input logic [1:0] LsuAtomicM,
input logic FlushDCacheM,
input logic [11:0] MemAdrE, // virtual address, but we only use the lower 12 bits.
input logic [`PA_BITS-1:0] MemPAdrM, // physical address
input logic [11:0] LsuAdrE, // virtual address, but we only use the lower 12 bits.
input logic [`PA_BITS-1:0] LsuPAdrM, // physical address
input logic [`XLEN-1:0] FinalWriteDataM,
output logic [`XLEN-1:0] ReadDataWordM,
output logic DCacheStall,
output logic DCacheMiss,
output logic DCacheAccess,
output logic DCCommittedM,
output logic DCWriteLine,
output logic DCFetchLine,
input logic BUSACK,
output logic DCacheCommittedM,
output logic DCacheWriteLine,
output logic DCacheFetchLine,
input logic DCacheBusAck,
output logic [`PA_BITS-1:0] DCacheBusAdr,
output logic [`XLEN-1:0] ReadDataBlockSetsM [(`DCACHE_BLOCKLENINBITS/`XLEN)-1:0],
output logic SelFlush,
input logic [`DCACHE_BLOCKLENINBITS-1:0] DCacheMemWriteData,
@ -64,120 +60,96 @@ module dcache
input logic IgnoreRequest
);
localparam integer BLOCKLEN = `DCACHE_BLOCKLENINBITS;
localparam integer NUMLINES = `DCACHE_WAYSIZEINBYTES*8/BLOCKLEN;
localparam integer NUMWAYS = `DCACHE_NUMWAYS;
localparam integer BLOCKLEN = `DCACHE_BLOCKLENINBITS;
localparam integer NUMLINES = `DCACHE_WAYSIZEINBYTES*8/BLOCKLEN;
localparam integer NUMWAYS = `DCACHE_NUMWAYS;
localparam integer BLOCKBYTELEN = BLOCKLEN/8;
localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN);
localparam integer INDEXLEN = $clog2(NUMLINES);
localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
localparam integer WORDSPERLINE = BLOCKLEN/`XLEN;
localparam integer LOGWPL = $clog2(WORDSPERLINE);
localparam integer LOGXLENBYTES = $clog2(`XLEN/8);
localparam integer BLOCKBYTELEN = BLOCKLEN/8;
localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN);
localparam integer INDEXLEN = $clog2(NUMLINES);
localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
localparam integer WORDSPERLINE = BLOCKLEN/`XLEN;
localparam integer LOGWPL = $clog2(WORDSPERLINE);
localparam integer LOGXLENBYTES = $clog2(`XLEN/8);
localparam integer FlushAdrThreshold = NUMLINES - 1;
localparam integer FlushAdrThreshold = NUMLINES - 1;
logic [1:0] SelAdrM;
logic [INDEXLEN-1:0] RAdr;
logic [INDEXLEN-1:0] WAdr;
logic [BLOCKLEN-1:0] SRAMWriteData;
logic SetValid, ClearValid;
logic SetDirty, ClearDirty;
logic [BLOCKLEN-1:0] ReadDataBlockWayMaskedM [NUMWAYS-1:0];
logic [NUMWAYS-1:0] WayHit;
logic CacheHit;
logic [BLOCKLEN-1:0] ReadDataBlockM;
logic [`XLEN-1:0] ReadDataWordMuxM;
logic [WORDSPERLINE-1:0] SRAMWordEnable;
logic [1:0] SelAdrM;
logic [INDEXLEN-1:0] RAdr;
logic [BLOCKLEN-1:0] SRAMWriteData;
logic SetValid, ClearValid;
logic SetDirty, ClearDirty;
logic [BLOCKLEN-1:0] ReadDataLineWayMasked [NUMWAYS-1:0];
logic [NUMWAYS-1:0] WayHit;
logic CacheHit;
logic [BLOCKLEN-1:0] ReadDataLineM;
logic [WORDSPERLINE-1:0] SRAMWordEnable;
logic SRAMWordWriteEnableM;
logic SRAMBlockWriteEnableM;
logic [NUMWAYS-1:0] SRAMBlockWayWriteEnableM;
//logic SRAMWriteEnable;
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
logic SRAMWordWriteEnableM;
logic SRAMBlockWriteEnableM;
logic [NUMWAYS-1:0] SRAMBlockWayWriteEnableM;
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
logic [NUMWAYS-1:0] VictimWay;
logic [NUMWAYS-1:0] VictimDirtyWay;
logic VictimDirty;
logic [NUMWAYS-1:0] VictimWay;
logic [NUMWAYS-1:0] VictimDirtyWay;
logic VictimDirty;
logic [2**LOGWPL-1:0] MemPAdrDecodedW;
logic [2**LOGWPL-1:0] MemPAdrDecodedW;
logic [TAGLEN-1:0] VictimTagWay [NUMWAYS-1:0];
logic [TAGLEN-1:0] VictimTag;
logic [TAGLEN-1:0] VictimTagWay [NUMWAYS-1:0];
logic [TAGLEN-1:0] VictimTag;
logic [INDEXLEN-1:0] FlushAdr;
logic [INDEXLEN-1:0] FlushAdrP1;
logic FlushAdrCntEn;
logic FlushAdrCntRst;
logic FlushAdrFlag;
logic [INDEXLEN-1:0] FlushAdr;
logic [INDEXLEN-1:0] FlushAdrP1;
logic FlushAdrCntEn;
logic FlushAdrCntRst;
logic FlushAdrFlag;
logic [NUMWAYS-1:0] FlushWay;
logic [NUMWAYS-1:0] NextFlushWay;
logic FlushWayCntEn;
logic FlushWayCntRst;
logic VDWriteEnable;
logic SelEvict;
logic [NUMWAYS-1:0] FlushWay;
logic [NUMWAYS-1:0] NextFlushWay;
logic FlushWayCntEn;
logic FlushWayCntRst;
logic LRUWriteEn;
logic [NUMWAYS-1:0] VDWriteEnableWay;
logic VDWriteEnable;
logic SelEvict;
logic LRUWriteEn;
logic [NUMWAYS-1:0] VDWriteEnableWay;
logic SelFlush;
// Read Path CPU (IEU) side
mux4 #(INDEXLEN)
AdrSelMux(.d0(MemAdrE[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d1(7'b0), // *** REMOVE
.d2(MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d3(FlushAdr),
.s(SelAdrM),
.y(RAdr));
mux3 #(INDEXLEN)
AdrSelMux(.d0(LsuAdrE[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d1(LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d2(FlushAdr),
.s(SelAdrM),
.y(RAdr));
mux2 #(INDEXLEN)
WAdrSelMux(.d0(MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d1(FlushAdr),
.s(&SelAdrM),
.y(WAdr));
cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN), .OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN))
MemWay[NUMWAYS-1:0](.clk,
.reset,
.RAdr,
.WAdr,
.PAdr(MemPAdrM),
.WriteEnable(SRAMWayWriteEnable),
.VDWriteEnable(VDWriteEnableWay),
.WriteWordEnable(SRAMWordEnable),
.TagWriteEnable(SRAMBlockWayWriteEnableM),
.WriteData(SRAMWriteData),
.SetValid,
.ClearValid,
.SetDirty,
.ClearDirty,
.SelEvict,
.VictimWay,
.FlushWay,
.SelFlush,
.ReadDataBlockWayMasked(ReadDataBlockWayMaskedM),
.WayHit,
.VictimDirtyWay,
.VictimTagWay,
.InvalidateAll(1'b0));
cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN),
.OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN))
MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr,
.PAdr(LsuPAdrM),
.WriteEnable(SRAMWayWriteEnable),
.VDWriteEnable(VDWriteEnableWay),
.WriteWordEnable(SRAMWordEnable),
.TagWriteEnable(SRAMBlockWayWriteEnableM),
.WriteData(SRAMWriteData),
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .SelEvict,
.VictimWay, .FlushWay, .SelFlush,
.ReadDataLineWayMasked,
.WayHit, .VictimDirtyWay, .VictimTagWay,
.InvalidateAll(1'b0));
generate
if(NUMWAYS > 1) begin
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
cachereplacementpolicy(.clk, .reset,
.WayHit,
.VictimWay,
.MemPAdrM(MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.RAdr,
.LRUWriteEn);
.WayHit,
.VictimWay,
.LsuPAdrM(LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.RAdr,
.LRUWriteEn);
end else begin
assign VictimWay = 1'b1; // one hot.
end
@ -187,10 +159,10 @@ module dcache
assign VictimDirty = | VictimDirtyWay;
// ReadDataBlockWayMaskedM is a 2d array of cache block len by number of ways.
// ReadDataLineWayMaskedM is a 2d array of cache block len by number of ways.
// Need to OR together each way in a bitwise manner.
// Final part of the AO Mux. First is the AND in the cacheway.
or_rows #(NUMWAYS, BLOCKLEN) ReadDataAOMux(.a(ReadDataBlockWayMaskedM), .y(ReadDataBlockM));
or_rows #(NUMWAYS, BLOCKLEN) ReadDataAOMux(.a(ReadDataLineWayMasked), .y(ReadDataLineM));
or_rows #(NUMWAYS, TAGLEN) VictimTagAOMux(.a(VictimTagWay), .y(VictimTag));
@ -200,62 +172,61 @@ module dcache
genvar index;
generate
for (index = 0; index < WORDSPERLINE; index++) begin
assign ReadDataBlockSetsM[index] = ReadDataBlockM[((index+1)*`XLEN)-1: (index*`XLEN)];
assign ReadDataBlockSetsM[index] = ReadDataLineM[((index+1)*`XLEN)-1: (index*`XLEN)];
end
endgenerate
// variable input mux
assign ReadDataWordM = ReadDataBlockSetsM[MemPAdrM[$clog2(WORDSPERLINE+`XLEN/8) : $clog2(`XLEN/8)]];
assign ReadDataWordM = ReadDataBlockSetsM[LsuPAdrM[LOGWPL + LOGXLENBYTES - 1 : LOGXLENBYTES]];
// Write Path CPU (IEU) side
onehotdecoder #(LOGWPL)
adrdec(.bin(MemPAdrM[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]),
.decoded(MemPAdrDecodedW));
adrdec(.bin(LsuPAdrM[LOGWPL+LOGXLENBYTES-1:LOGXLENBYTES]),
.decoded(MemPAdrDecodedW));
assign SRAMWordEnable = SRAMBlockWriteEnableM ? '1 : MemPAdrDecodedW;
assign SRAMBlockWayWriteEnableM = SRAMBlockWriteEnableM ? VictimWay : '0;
mux2 #(NUMWAYS) WriteEnableMux(.d0(SRAMWordWriteEnableM ? WayHit : '0),
.d1(SRAMBlockWayWriteEnableM),
.s(SRAMBlockWriteEnableM),
.y(SRAMWayWriteEnable));
.d1(SRAMBlockWayWriteEnableM),
.s(SRAMBlockWriteEnableM),
.y(SRAMWayWriteEnable));
mux2 #(BLOCKLEN) WriteDataMux(.d0({WORDSPERLINE{FinalWriteDataM}}),
.d1(DCacheMemWriteData),
.s(SRAMBlockWriteEnableM),
.y(SRAMWriteData));
.d1(DCacheMemWriteData),
.s(SRAMBlockWriteEnableM),
.y(SRAMWriteData));
mux3 #(`PA_BITS) BaseAdrMux(.d0({MemPAdrM[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d1({VictimTag, MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}),
.s({SelFlush, SelEvict}),
.y(DCacheBusAdr));
mux3 #(`PA_BITS) BaseAdrMux(.d0({LsuPAdrM[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d1({VictimTag, LsuPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}),
.s({SelFlush, SelEvict}),
.y(DCacheBusAdr));
// flush address and way generation.
flopenr #(INDEXLEN)
FlushAdrReg(.clk,
.reset(reset | FlushAdrCntRst),
.en(FlushAdrCntEn & FlushWay[NUMWAYS-1]),
.d(FlushAdrP1),
.q(FlushAdr));
.reset(reset | FlushAdrCntRst),
.en(FlushAdrCntEn & FlushWay[NUMWAYS-1]),
.d(FlushAdrP1),
.q(FlushAdr));
assign FlushAdrP1 = FlushAdr + 1'b1;
flopenl #(NUMWAYS)
FlushWayReg(.clk,
.load(reset | FlushWayCntRst),
.en(FlushWayCntEn),
.val({{NUMWAYS-1{1'b0}}, 1'b1}),
.d(NextFlushWay),
.q(FlushWay));
.load(reset | FlushWayCntRst),
.en(FlushWayCntEn),
.val({{NUMWAYS-1{1'b0}}, 1'b1}),
.d(NextFlushWay),
.q(FlushWay));
assign VDWriteEnableWay = FlushWay & {NUMWAYS{VDWriteEnable}};
@ -263,44 +234,17 @@ module dcache
assign FlushAdrFlag = FlushAdr == FlushAdrThreshold[INDEXLEN-1:0] & FlushWay[NUMWAYS-1];
//assign SRAMWriteEnable = SRAMBlockWriteEnableM | SRAMWordWriteEnableM;
// controller
dcachefsm dcachefsm(.clk,
.reset,
.DCFetchLine,
.DCWriteLine,
.BUSACK,
.MemRWM,
.AtomicM,
.CPUBusy,
.CacheableM,
.IgnoreRequest,
.CacheHit,
.VictimDirty,
.DCacheStall,
.DCCommittedM,
.DCacheMiss,
.DCacheAccess,
.SelAdrM,
.SetValid,
.ClearValid,
.SetDirty,
.ClearDirty,
.SRAMWordWriteEnableM,
.SRAMBlockWriteEnableM,
.SelEvict,
.SelFlush,
.FlushAdrCntEn,
.FlushWayCntEn,
.FlushAdrCntRst,
.FlushWayCntRst,
.FlushAdrFlag,
.FlushDCacheM,
.VDWriteEnable,
.LRUWriteEn);
dcachefsm dcachefsm(.clk, .reset, .DCacheFetchLine, .DCacheWriteLine, .DCacheBusAck,
.LsuRWM, .LsuAtomicM, .CPUBusy, .CacheableM, .IgnoreRequest,
.CacheHit, .VictimDirty, .DCacheStall, .DCacheCommittedM,
.DCacheMiss, .DCacheAccess, .SelAdrM, .SetValid,
.ClearValid, .SetDirty, .ClearDirty, .SRAMWordWriteEnableM,
.SRAMBlockWriteEnableM, .SelEvict, .SelFlush,
.FlushAdrCntEn, .FlushWayCntEn, .FlushAdrCntRst,
.FlushWayCntRst, .FlushAdrFlag, .FlushDCacheM,
.VDWriteEnable, .LRUWriteEn);
endmodule // dcache

View File

@ -29,8 +29,8 @@ module dcachefsm
(input logic clk,
input logic reset,
// inputs from IEU
input logic [1:0] MemRWM,
input logic [1:0] AtomicM,
input logic [1:0] LsuRWM,
input logic [1:0] LsuAtomicM,
input logic FlushDCacheM,
// hazard inputs
input logic CPUBusy,
@ -38,7 +38,7 @@ module dcachefsm
// hptw inputs
input logic IgnoreRequest,
// Bus inputs
input logic BUSACK,
input logic DCacheBusAck,
// dcache internals
input logic CacheHit,
input logic VictimDirty,
@ -50,9 +50,9 @@ module dcachefsm
output logic DCacheMiss,
output logic DCacheAccess,
// Bus outputs
output logic DCCommittedM,
output logic DCWriteLine,
output logic DCFetchLine,
output logic DCacheCommittedM,
output logic DCacheWriteLine,
output logic DCacheFetchLine,
// dcache internals
output logic [1:0] SelAdrM,
@ -94,7 +94,7 @@ module dcachefsm
(* mark_debug = "true" *) statetype CurrState, NextState;
assign AnyCPUReqM = |MemRWM | (|AtomicM);
assign AnyCPUReqM = |LsuRWM | (|LsuAtomicM);
// outputs for the performance counters.
assign DCacheAccess = AnyCPUReqM & CacheableM & CurrState == STATE_READY;
@ -123,8 +123,8 @@ module dcachefsm
FlushWayCntRst = 1'b0;
VDWriteEnable = 1'b0;
NextState = STATE_READY;
DCFetchLine = 1'b0;
DCWriteLine = 1'b0;
DCacheFetchLine = 1'b0;
DCacheWriteLine = 1'b0;
case (CurrState)
STATE_READY: begin
@ -150,19 +150,19 @@ module dcachefsm
else if(FlushDCacheM) begin
NextState = STATE_FLUSH;
DCacheStall = 1'b1;
SelAdrM = 2'b11;
SelAdrM = 2'b10;
FlushAdrCntRst = 1'b1;
FlushWayCntRst = 1'b1;
end
// amo hit
else if(AtomicM[1] & (&MemRWM) & CacheableM & CacheHit) begin
SelAdrM = 2'b10;
else if(LsuAtomicM[1] & (&LsuRWM) & CacheableM & CacheHit) begin
SelAdrM = 2'b01;
DCacheStall = 1'b0;
if(CPUBusy) begin
NextState = STATE_CPU_BUSY_FINISH_AMO;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
end
else begin
SRAMWordWriteEnableM = 1'b1;
@ -172,21 +172,21 @@ module dcachefsm
end
end
// read hit valid cached
else if(MemRWM[1] & CacheableM & CacheHit) begin
else if(LsuRWM[1] & CacheableM & CacheHit) begin
DCacheStall = 1'b0;
LRUWriteEn = 1'b1;
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
end
else begin
NextState = STATE_READY;
end
end
// write hit valid cached
else if (MemRWM[0] & CacheableM & CacheHit) begin
SelAdrM = 2'b10;
else if (LsuRWM[0] & CacheableM & CacheHit) begin
SelAdrM = 2'b01;
DCacheStall = 1'b0;
SRAMWordWriteEnableM = 1'b1;
SetDirty = 1'b1;
@ -194,26 +194,26 @@ module dcachefsm
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
end
else begin
NextState = STATE_READY;
end
end
// read or write miss valid cached
else if((|MemRWM) & CacheableM & ~CacheHit) begin
else if((|LsuRWM) & CacheableM & ~CacheHit) begin
NextState = STATE_MISS_FETCH_WDV;
DCacheStall = 1'b1;
DCFetchLine = 1'b1;
DCacheFetchLine = 1'b1;
end
else NextState = STATE_READY;
end
STATE_MISS_FETCH_WDV: begin
DCacheStall = 1'b1;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
if (BUSACK) begin
if (DCacheBusAck) begin
NextState = STATE_MISS_FETCH_DONE;
end else begin
NextState = STATE_MISS_FETCH_WDV;
@ -222,10 +222,10 @@ module dcachefsm
STATE_MISS_FETCH_DONE: begin
DCacheStall = 1'b1;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
if(VictimDirty) begin
NextState = STATE_MISS_EVICT_DIRTY;
DCWriteLine = 1'b1;
DCacheWriteLine = 1'b1;
end else begin
NextState = STATE_MISS_WRITE_CACHE_BLOCK;
end
@ -235,31 +235,31 @@ module dcachefsm
SRAMBlockWriteEnableM = 1'b1;
DCacheStall = 1'b1;
NextState = STATE_MISS_READ_WORD;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
SetValid = 1'b1;
ClearDirty = 1'b1;
//LRUWriteEn = 1'b1; // DO not update LRU on SRAM fetch update. Wait for subsequent read/write
end
STATE_MISS_READ_WORD: begin
SelAdrM = 2'b10;
SelAdrM = 2'b01;
DCacheStall = 1'b1;
if (MemRWM[0] & ~AtomicM[1]) begin // handles stores and amo write.
if (LsuRWM[0] & ~LsuAtomicM[1]) begin // handles stores and amo write.
NextState = STATE_MISS_WRITE_WORD;
end else begin
NextState = STATE_MISS_READ_WORD_DELAY;
// delay state is required as the read signal MemRWM[1] is still high when we
// delay state is required as the read signal LsuRWM[1] is still high when we
// return to the ready state because the cache is stalling the cpu.
end
end
STATE_MISS_READ_WORD_DELAY: begin
//SelAdrM = 2'b10;
//SelAdrM = 2'b01;
SRAMWordWriteEnableM = 1'b0;
SetDirty = 1'b0;
LRUWriteEn = 1'b0;
if(&MemRWM & AtomicM[1]) begin // amo write
SelAdrM = 2'b10;
if(&LsuRWM & LsuAtomicM[1]) begin // amo write
SelAdrM = 2'b01;
if(CPUBusy) begin
NextState = STATE_CPU_BUSY_FINISH_AMO;
end
@ -273,7 +273,7 @@ module dcachefsm
LRUWriteEn = 1'b1;
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
end
else begin
NextState = STATE_READY;
@ -284,11 +284,11 @@ module dcachefsm
STATE_MISS_WRITE_WORD: begin
SRAMWordWriteEnableM = 1'b1;
SetDirty = 1'b1;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
LRUWriteEn = 1'b1;
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
end
else begin
NextState = STATE_READY;
@ -297,9 +297,9 @@ module dcachefsm
STATE_MISS_EVICT_DIRTY: begin
DCacheStall = 1'b1;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
SelEvict = 1'b1;
if(BUSACK) begin
if(DCacheBusAck) begin
NextState = STATE_MISS_WRITE_CACHE_BLOCK;
end else begin
NextState = STATE_MISS_EVICT_DIRTY;
@ -311,7 +311,7 @@ module dcachefsm
SelAdrM = 2'b00;
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdrM = 2'b10;
SelAdrM = 2'b01;
end
else begin
NextState = STATE_READY;
@ -319,7 +319,7 @@ module dcachefsm
end
STATE_CPU_BUSY_FINISH_AMO: begin
SelAdrM = 2'b10;
SelAdrM = 2'b01;
SRAMWordWriteEnableM = 1'b0;
SetDirty = 1'b0;
LRUWriteEn = 1'b0;
@ -336,7 +336,7 @@ module dcachefsm
STATE_FLUSH: begin
DCacheStall = 1'b1;
SelAdrM = 2'b11;
SelAdrM = 2'b10;
SelFlush = 1'b1;
FlushAdrCntEn = 1'b1;
FlushWayCntEn = 1'b1;
@ -344,7 +344,7 @@ module dcachefsm
NextState = STATE_FLUSH_WRITE_BACK;
FlushAdrCntEn = 1'b0;
FlushWayCntEn = 1'b0;
DCWriteLine = 1'b1;
DCacheWriteLine = 1'b1;
end else if (FlushAdrFlag) begin
NextState = STATE_READY;
DCacheStall = 1'b0;
@ -357,9 +357,9 @@ module dcachefsm
STATE_FLUSH_WRITE_BACK: begin
DCacheStall = 1'b1;
SelAdrM = 2'b11;
SelAdrM = 2'b10;
SelFlush = 1'b1;
if(BUSACK) begin
if(DCacheBusAck) begin
NextState = STATE_FLUSH_CLEAR_DIRTY;
end else begin
NextState = STATE_FLUSH_WRITE_BACK;
@ -371,7 +371,7 @@ module dcachefsm
ClearDirty = 1'b1;
VDWriteEnable = 1'b1;
SelFlush = 1'b1;
SelAdrM = 2'b11;
SelAdrM = 2'b10;
FlushAdrCntEn = 1'b0;
FlushWayCntEn = 1'b0;
if(FlushAdrFlag) begin
@ -391,7 +391,7 @@ module dcachefsm
endcase
end
assign DCCommittedM = CurrState != STATE_READY;
assign DCacheCommittedM = CurrState != STATE_READY;
endmodule // dcachefsm

View File

@ -28,146 +28,135 @@
module icache
(
// Basic pipeline stuff
input logic clk, reset,
input logic StallF,
input logic [`PA_BITS-1:0] PCNextF,
input logic [`PA_BITS-1:0] PCPF,
input logic [`XLEN-1:0] PCF,
input logic clk, reset,
input logic CPUBusy,
input logic [`PA_BITS-1:0] PCNextF,
input logic [`PA_BITS-1:0] PCPF,
input logic [`XLEN-1:0] PCF,
input logic ExceptionM, PendingInterruptM,
input logic ExceptionM, PendingInterruptM,
// Data read in from the ebu unit
(* mark_debug = "true" *) input logic [`XLEN-1:0] InstrInF,
(* mark_debug = "true" *) input logic InstrAckF,
(* mark_debug = "true" *) input logic [`XLEN-1:0] IfuBusHRDATA,
(* mark_debug = "true" *) input logic ICacheBusAck,
// Read requested from the ebu unit
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] InstrPAdrF,
(* mark_debug = "true" *) output logic InstrReadF,
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] ICacheBusAdr,
(* mark_debug = "true" *) output logic IfuBusFetch,
// High if the instruction currently in the fetch stage is compressed
output logic CompressedF,
output logic CompressedF,
// High if the icache is requesting a stall
output logic ICacheStallF,
input logic ITLBMissF,
input logic ITLBWriteF,
input logic InvalidateICacheM,
output logic ICacheStallF,
input logic CacheableF,
input logic ITLBMissF,
input logic ITLBWriteF,
input logic InvalidateICacheM,
// The raw (not decompressed) instruction that was requested
// If this instruction is compressed, upper 16 bits may be the next 16 bits or may be zeros
(* mark_debug = "true" *) output logic [31:0] FinalInstrRawF
(* mark_debug = "true" *) output logic [31:0] FinalInstrRawF
);
// Configuration parameters
localparam integer BLOCKLEN = `ICACHE_BLOCKLENINBITS;
localparam integer NUMLINES = `ICACHE_WAYSIZEINBYTES*8/`ICACHE_BLOCKLENINBITS;
localparam integer BLOCKBYTELEN = BLOCKLEN/8;
localparam integer BLOCKLEN = `ICACHE_BLOCKLENINBITS;
localparam integer NUMLINES = `ICACHE_WAYSIZEINBYTES*8/`ICACHE_BLOCKLENINBITS;
localparam integer BLOCKBYTELEN = BLOCKLEN/8;
localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN);
localparam integer INDEXLEN = $clog2(NUMLINES);
localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN);
localparam integer INDEXLEN = $clog2(NUMLINES);
localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
localparam WORDSPERLINE = BLOCKLEN/`XLEN;
localparam LOGWPL = $clog2(WORDSPERLINE);
localparam FetchCountThreshold = WORDSPERLINE - 1;
localparam integer PA_WIDTH = `PA_BITS - 2;
localparam integer NUMWAYS = `ICACHE_NUMWAYS;
localparam integer PA_WIDTH = `PA_BITS - 2;
localparam integer NUMWAYS = `ICACHE_NUMWAYS;
// Input signals to cache memory
logic ICacheMemWriteEnable;
logic [BLOCKLEN-1:0] ICacheMemWriteData;
logic [`PA_BITS-1:0] PCTagF;
logic ICacheMemWriteEnable;
logic [BLOCKLEN-1:0] ICacheMemWriteData;
logic [`PA_BITS-1:0] FinalPCPF;
// Output signals from cache memory
logic [31:0] ICacheMemReadData;
logic ICacheReadEn;
logic [BLOCKLEN-1:0] ReadLineF;
logic [31:0] ICacheMemReadData;
logic ICacheReadEn;
logic [BLOCKLEN-1:0] ReadLineF;
logic [15:0] SpillDataBlock0;
logic spill;
logic spillSave;
logic [15:0] SpillDataBlock0;
logic spill;
logic spillSave;
logic FetchCountFlag;
logic CntEn;
logic FetchCountFlag;
logic CntEn;
logic [1:1] SelAdr_q;
logic [1:1] SelAdr_q;
logic [LOGWPL-1:0] FetchCount, NextFetchCount;
logic [`PA_BITS-1:0] PCPSpillF;
logic [LOGWPL-1:0] FetchCount, NextFetchCount;
logic [`PA_BITS-1:0] PCPSpillF;
logic CntReset;
logic [1:0] SelAdr;
logic [INDEXLEN-1:0] RAdr;
logic [NUMWAYS-1:0] VictimWay;
logic LRUWriteEn;
logic [NUMWAYS-1:0] WayHit;
logic hit;
logic CntReset;
logic [1:0] SelAdr;
logic [INDEXLEN-1:0] RAdr;
logic [NUMWAYS-1:0] VictimWay;
logic LRUWriteEn;
logic [NUMWAYS-1:0] WayHit;
logic hit;
logic [BLOCKLEN-1:0] ReadDataBlockWayMasked [NUMWAYS-1:0];
logic [BLOCKLEN-1:0] ReadDataLineWayMasked [NUMWAYS-1:0];
logic CacheableF;
logic [31:0] ReadLineSetsF [`ICACHE_BLOCKLENINBITS/16-1:0];
logic [`PA_BITS-1:0] BasePAdrF, BasePAdrMaskedF;
logic [OFFSETLEN-1:0] BasePAdrOffsetF;
logic [`PA_BITS-1:0] BasePAdrMaskedF;
logic [OFFSETLEN-1:0] BasePAdrOffsetF;
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
// on spill we want to get the first 2 bytes of the next cache block.
// the spill only occurs if the PCPF mod BlockByteLength == -2. Therefore we can
// simply add 2 to land on the next cache block.
assign PCPSpillF = PCPF + {{{PA_WIDTH}{1'b0}}, 2'b10}; // *** modelsim does not allow the use of PA_BITS for literal width.
assign PCPSpillF = PCPF + {{{PA_WIDTH}{1'b0}}, 2'b10};
mux3 #(INDEXLEN)
AdrSelMux(.d0(PCNextF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d1(PCF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d2(PCPSpillF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.s(SelAdr),
.y(RAdr));
.d1(PCF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d2(PCPSpillF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.s(SelAdr),
.y(RAdr));
cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN), .OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN),
.DIRTY_BITS(0))
MemWay[NUMWAYS-1:0](.clk,
.reset,
.RAdr(RAdr),
.WAdr(PCTagF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.PAdr(PCTagF),
.WriteEnable(SRAMWayWriteEnable),
.VDWriteEnable(1'b0),
.WriteWordEnable({{(BLOCKLEN/`XLEN){1'b1}}}),
.TagWriteEnable(SRAMWayWriteEnable),
.WriteData(ICacheMemWriteData),
.SetValid(ICacheMemWriteEnable),
.ClearValid(1'b0),
.SetDirty(1'b0),
.ClearDirty(1'b0),
.SelEvict(1'b0),
.VictimWay,
.FlushWay(1'b0),
.SelFlush(1'b0),
.ReadDataBlockWayMasked,
.WayHit,
.VictimDirtyWay(),
.VictimTagWay(),
.InvalidateAll(InvalidateICacheM)
);
cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN),
.OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN), .DIRTY_BITS(0))
MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr,
.PAdr(FinalPCPF),
.WriteEnable(SRAMWayWriteEnable),
.VDWriteEnable(1'b0),
.WriteWordEnable({{(BLOCKLEN/`XLEN){1'b1}}}),
.TagWriteEnable(SRAMWayWriteEnable),
.WriteData(ICacheMemWriteData),
.SetValid(ICacheMemWriteEnable),
.ClearValid(1'b0), .SetDirty(1'b0), .ClearDirty(1'b0), .SelEvict(1'b0),
.VictimWay,
.FlushWay(1'b0), .SelFlush(1'b0),
.ReadDataLineWayMasked, .WayHit,
.VictimDirtyWay(), .VictimTagWay(),
.InvalidateAll(InvalidateICacheM));
generate
if(NUMWAYS > 1) begin
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
cachereplacementpolicy(.clk, .reset,
.WayHit,
.VictimWay,
.MemPAdrM(PCTagF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.RAdr,
.LRUWriteEn); // *** connect
.WayHit,
.VictimWay,
.LsuPAdrM(FinalPCPF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.RAdr,
.LRUWriteEn);
end else begin
assign VictimWay = 1'b1; // one hot.
end
@ -175,51 +164,36 @@ module icache
assign hit = | WayHit;
// ReadDataBlockWayMasked is a 2d array of cache block len by number of ways.
// ReadDataLineWayMasked is a 2d array of cache block len by number of ways.
// Need to OR together each way in a bitwise manner.
// Final part of the AO Mux. First is the AND in the cacheway.
or_rows #(NUMWAYS, BLOCKLEN) ReadDataAOMux(.a(ReadDataBlockWayMasked), .y(ReadLineF));
or_rows #(NUMWAYS, BLOCKLEN) ReadDataAOMux(.a(ReadDataLineWayMasked), .y(ReadLineF));
genvar index;
generate
for(index = 0; index < BLOCKLEN / 16 - 1; index++) begin
assign ReadLineSetsF[index] = ReadLineF[((index+1)*16)+16-1 : (index*16)];
end
assign ReadLineSetsF[BLOCKLEN/16-1] = {16'b0, ReadLineF[BLOCKLEN-1:BLOCKLEN-16]};
endgenerate
assign ICacheMemReadData = ReadLineSetsF[FinalPCPF[$clog2(BLOCKLEN / 32) + 1 : 1]];
always_comb begin
case (PCTagF[4:1])
0: ICacheMemReadData = ReadLineF[31:0];
1: ICacheMemReadData = ReadLineF[47:16];
2: ICacheMemReadData = ReadLineF[63:32];
3: ICacheMemReadData = ReadLineF[79:48];
4: ICacheMemReadData = ReadLineF[95:64];
5: ICacheMemReadData = ReadLineF[111:80];
6: ICacheMemReadData = ReadLineF[127:96];
7: ICacheMemReadData = ReadLineF[143:112];
8: ICacheMemReadData = ReadLineF[159:128];
9: ICacheMemReadData = ReadLineF[175:144];
10: ICacheMemReadData = ReadLineF[191:160];
11: ICacheMemReadData = ReadLineF[207:176];
12: ICacheMemReadData = ReadLineF[223:192];
13: ICacheMemReadData = ReadLineF[239:208];
14: ICacheMemReadData = ReadLineF[255:224];
15: ICacheMemReadData = {16'b0, ReadLineF[255:240]};
endcase
end
// spills require storing the first cache block so it can merged
// with the second
// can optimize size, for now just make it the size of the data
// leaving the cache memory.
flopenr #(16) SpillInstrReg(.clk(clk),
.en(spillSave),
.reset(reset),
.d(ICacheMemReadData[15:0]),
.q(SpillDataBlock0));
.en(spillSave),
.reset(reset),
.d(ICacheMemReadData[15:0]),
.q(SpillDataBlock0));
assign FinalInstrRawF = spill ? {ICacheMemReadData[15:0], SpillDataBlock0} : ICacheMemReadData;
// Detect if the instruction is compressed
assign CompressedF = FinalInstrRawF[1:0] != 2'b11;
assign spill = PCF[4:1] == 4'b1111 ? 1'b1 : 1'b0;
assign spill = &PCF[$clog2(BLOCKLEN/32)+1:1];
// to compute the fetch address we need to add the bit shifted
@ -228,10 +202,10 @@ module icache
flopenr #(LOGWPL)
FetchCountReg(.clk(clk),
.reset(reset | CntReset),
.en(CntEn),
.d(NextFetchCount),
.q(FetchCount));
.reset(reset | CntReset),
.en(CntEn),
.d(NextFetchCount),
.q(FetchCount));
assign NextFetchCount = FetchCount + 1'b1;
@ -241,10 +215,10 @@ module icache
generate
for (i = 0; i < WORDSPERLINE; i++) begin:storebuffer
flopenr #(`XLEN) sb(.clk(clk),
.reset(reset),
.en(InstrAckF & (i == FetchCount)),
.d(InstrInF),
.q(ICacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN]));
.reset(reset),
.en(ICacheBusAck & (i == FetchCount)),
.d(IfuBusHRDATA),
.q(ICacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN]));
end
endgenerate
@ -252,54 +226,44 @@ module icache
// this mux needs to be delayed 1 cycle as it occurs 1 pipeline stage later.
// *** read enable may not be necessary.
flopenr #(1) SelAdrReg(.clk(clk),
.reset(reset),
.en(ICacheReadEn),
.d(SelAdr[1]),
.q(SelAdr_q[1]));
.reset(reset),
.en(ICacheReadEn),
.d(SelAdr[1]),
.q(SelAdr_q[1]));
assign PCTagF = SelAdr_q[1] ? PCPSpillF : PCPF;
// unlike the dcache the victim is never dirty so no eviction is necessary.
/* -----\/----- EXCLUDED -----\/-----
mux2 #(`PA_BITS) BaseAdrMux(.d0(PCTagF),
.d1({VictimTag, PCTagF[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}),
.s(SelEvict),
.y(BasePAdrF));
-----/\----- EXCLUDED -----/\----- */
assign BasePAdrF = PCTagF;
assign FinalPCPF = SelAdr_q[1] ? PCPSpillF : PCPF;
// if not cacheable the offset bits needs to be sent to the EBU.
// if cacheable the offset bits are discarded. $ FSM will fetch the whole block.
assign CacheableF = 1'b1; // *** BUG needs to be an input from MMU.
assign BasePAdrOffsetF = CacheableF ? {{OFFSETLEN}{1'b0}} : BasePAdrF[OFFSETLEN-1:0];
assign BasePAdrMaskedF = {BasePAdrF[`PA_BITS-1:OFFSETLEN], BasePAdrOffsetF};
assign BasePAdrOffsetF = CacheableF ? {{OFFSETLEN}{1'b0}} : FinalPCPF[OFFSETLEN-1:0];
assign BasePAdrMaskedF = {FinalPCPF[`PA_BITS-1:OFFSETLEN], BasePAdrOffsetF};
assign InstrPAdrF = ({{`PA_BITS-LOGWPL{1'b0}}, FetchCount} << $clog2(`XLEN/8)) + BasePAdrMaskedF;
assign ICacheBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, FetchCount} << $clog2(`XLEN/8)) + BasePAdrMaskedF;
// truncate the offset from PCPF for memory address generation
assign SRAMWayWriteEnable = ICacheMemWriteEnable ? VictimWay : '0;
icachefsm controller(.clk,
.reset,
.StallF,
.ICacheReadEn,
.ICacheMemWriteEnable,
.ICacheStallF,
.ITLBMissF,
.ITLBWriteF,
.ExceptionM,
.PendingInterruptM,
.InstrAckF,
.InstrReadF,
.hit,
.FetchCountFlag,
.spill,
.spillSave,
.CntEn,
.CntReset,
.SelAdr,
.LRUWriteEn);
.reset,
.CPUBusy,
.ICacheReadEn,
.ICacheMemWriteEnable,
.ICacheStallF,
.ITLBMissF,
.ITLBWriteF,
.ExceptionM,
.PendingInterruptM,
.ICacheBusAck,
.IfuBusFetch,
.hit,
.FetchCountFlag,
.spill,
.spillSave,
.CntEn,
.CntReset,
.SelAdr,
.LRUWriteEn);
endmodule

View File

@ -29,7 +29,7 @@ module icachefsm
(// Inputs from pipeline
input logic clk, reset,
input logic StallF,
input logic CPUBusy,
// inputs from mmu
input logic ITLBMissF,
@ -38,7 +38,7 @@ module icachefsm
input logic ExceptionM, PendingInterruptM,
// BUS interface
input logic InstrAckF,
input logic ICacheBusAck,
// icache internal inputs
input logic hit,
@ -54,7 +54,7 @@ module icachefsm
output logic ICacheStallF,
// Bus interface outputs
output logic InstrReadF,
output logic IfuBusFetch,
// icache internal outputs
output logic spillSave,
@ -105,10 +105,6 @@ module icachefsm
STATE_MISS_SPILL_FINAL, // this state replicates STATE_READY's replay of the
// spill access but does nto consider spill. It also does not do another operation.
STATE_INVALIDATE, // *** not sure if invalidate or evict? invalidate by cache block or address?
STATE_TLB_MISS,
STATE_TLB_MISS_DONE,
STATE_CPU_BUSY,
STATE_CPU_BUSY_SPILL
} statetype;
@ -125,7 +121,7 @@ module icachefsm
always_comb begin
CntReset = 1'b0;
PreCntEn = 1'b0;
//InstrReadF = 1'b0;
//IfuBusFetch = 1'b0;
ICacheMemWriteEnable = 1'b0;
spillSave = 1'b0;
SelAdr = 2'b00;
@ -149,7 +145,7 @@ module icachefsm
else if (hit & ~spill) begin
ICacheStallF = 1'b0;
LRUWriteEn = 1'b1;
if(StallF) begin
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdr = 2'b01;
end else begin
@ -169,7 +165,7 @@ module icachefsm
SelAdr = 2'b01;
NextState = STATE_MISS_SPILL_FETCH_WDV;
end else begin
if(StallF) begin
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdr = 2'b01;
end else begin
@ -190,9 +186,9 @@ module icachefsm
end
STATE_HIT_SPILL_MISS_FETCH_WDV: begin
SelAdr = 2'b10;
//InstrReadF = 1'b1;
//IfuBusFetch = 1'b1;
PreCntEn = 1'b1;
if (FetchCountFlag & InstrAckF) begin
if (FetchCountFlag & ICacheBusAck) begin
NextState = STATE_HIT_SPILL_MISS_FETCH_DONE;
end else begin
NextState = STATE_HIT_SPILL_MISS_FETCH_WDV;
@ -214,7 +210,7 @@ module icachefsm
ICacheStallF = 1'b0;
LRUWriteEn = 1'b1;
if(StallF) begin
if(CPUBusy) begin
NextState = STATE_CPU_BUSY_SPILL;
SelAdr = 2'b10;
end else begin
@ -225,9 +221,9 @@ module icachefsm
// branch 3 miss no spill
STATE_MISS_FETCH_WDV: begin
SelAdr = 2'b01;
//InstrReadF = 1'b1;
//IfuBusFetch = 1'b1;
PreCntEn = 1'b1;
if (FetchCountFlag & InstrAckF) begin
if (FetchCountFlag & ICacheBusAck) begin
NextState = STATE_MISS_FETCH_DONE;
end else begin
NextState = STATE_MISS_FETCH_WDV;
@ -248,7 +244,7 @@ module icachefsm
ICacheReadEn = 1'b1;
ICacheStallF = 1'b0;
LRUWriteEn = 1'b1;
if(StallF) begin
if(CPUBusy) begin
SelAdr = 2'b01;
NextState = STATE_CPU_BUSY;
SelAdr = 2'b01;
@ -260,8 +256,8 @@ module icachefsm
STATE_MISS_SPILL_FETCH_WDV: begin
SelAdr = 2'b01;
PreCntEn = 1'b1;
//InstrReadF = 1'b1;
if (FetchCountFlag & InstrAckF) begin
//IfuBusFetch = 1'b1;
if (FetchCountFlag & ICacheBusAck) begin
NextState = STATE_MISS_SPILL_FETCH_DONE;
end else begin
NextState = STATE_MISS_SPILL_FETCH_WDV;
@ -293,7 +289,7 @@ module icachefsm
SelAdr = 2'b00;
ICacheStallF = 1'b0;
LRUWriteEn = 1'b1;
if(StallF) begin
if(CPUBusy) begin
NextState = STATE_CPU_BUSY_SPILL;
SelAdr = 2'b10;
end else begin
@ -304,8 +300,8 @@ module icachefsm
STATE_MISS_SPILL_MISS_FETCH_WDV: begin
SelAdr = 2'b10;
PreCntEn = 1'b1;
//InstrReadF = 1'b1;
if (FetchCountFlag & InstrAckF) begin
//IfuBusFetch = 1'b1;
if (FetchCountFlag & ICacheBusAck) begin
NextState = STATE_MISS_SPILL_MISS_FETCH_DONE;
end else begin
NextState = STATE_MISS_SPILL_MISS_FETCH_WDV;
@ -326,7 +322,7 @@ module icachefsm
SelAdr = 2'b00;
ICacheStallF = 1'b0;
LRUWriteEn = 1'b1;
if(StallF) begin
if(CPUBusy) begin
NextState = STATE_CPU_BUSY_SPILL;
SelAdr = 2'b10;
end else begin
@ -335,7 +331,7 @@ module icachefsm
end
STATE_CPU_BUSY: begin
ICacheStallF = 1'b0;
if(StallF) begin
if(CPUBusy) begin
NextState = STATE_CPU_BUSY;
SelAdr = 2'b01;
end
@ -346,7 +342,7 @@ module icachefsm
STATE_CPU_BUSY_SPILL: begin
ICacheStallF = 1'b0;
ICacheReadEn = 1'b1;
if(StallF) begin
if(CPUBusy) begin
NextState = STATE_CPU_BUSY_SPILL;
SelAdr = 2'b10;
end
@ -362,8 +358,8 @@ module icachefsm
endcase
end
assign CntEn = PreCntEn & InstrAckF;
assign InstrReadF = (CurrState == STATE_HIT_SPILL_MISS_FETCH_WDV) ||
assign CntEn = PreCntEn & ICacheBusAck;
assign IfuBusFetch = (CurrState == STATE_HIT_SPILL_MISS_FETCH_WDV) ||
(CurrState == STATE_MISS_FETCH_WDV) ||
(CurrState == STATE_MISS_SPILL_FETCH_WDV) ||
(CurrState == STATE_MISS_SPILL_MISS_FETCH_WDV);

View File

@ -40,10 +40,10 @@ module ahblite (
input logic UnsignedLoadM,
input logic [1:0] AtomicMaskedM,
// Signals from Instruction Cache
input logic [`PA_BITS-1:0] InstrPAdrF, // *** rename these to match block diagram
input logic InstrReadF,
output logic [`XLEN-1:0] InstrRData,
output logic InstrAckF,
input logic [`PA_BITS-1:0] ICacheBusAdr, // *** rename these to match block diagram
input logic IfuBusFetch,
output logic [`XLEN-1:0] IfuBusHRDATA,
output logic ICacheBusAck,
// Signals from Data Cache
input logic [`PA_BITS-1:0] LsuBusAdr,
input logic LsuBusRead,
@ -100,23 +100,23 @@ module ahblite (
case (BusState)
IDLE: if (LsuBusRead) NextBusState = MEMREAD; // Memory has priority over instructions
else if (LsuBusWrite)NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
else if (IfuBusFetch) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (InstrReadF) NextBusState = INSTRREAD;
else if (IfuBusFetch) NextBusState = INSTRREAD;
else NextBusState = IDLE;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD;
else if (IfuBusFetch) NextBusState = INSTRREAD;
else NextBusState = IDLE;
INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; // if (InstrReadF still high)
else NextBusState = IDLE; // if (IfuBusFetch still high)
default: NextBusState = IDLE;
endcase
// bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE);
assign #1 AccessAddress = (GrantData) ? LsuBusAdr[31:0] : InstrPAdrF[31:0];
assign #1 AccessAddress = (GrantData) ? LsuBusAdr[31:0] : ICacheBusAdr[31:0];
assign #1 HADDR = AccessAddress;
assign ISize = 3'b010; // 32 bit instructions for now; later improve for filling cache with full width; ignored on reads anyway
assign HSIZE = (GrantData) ? {1'b0, LsuBusSize[1:0]} : ISize;
@ -136,9 +136,9 @@ module ahblite (
// *** assumes AHBW = XLEN
assign InstrRData = HRDATA;
assign IfuBusHRDATA = HRDATA;
assign LsuBusHRDATA = HRDATA;
assign InstrAckF = (BusState == INSTRREAD) && (NextBusState != INSTRREAD);
assign ICacheBusAck = (BusState == INSTRREAD) && (NextBusState != INSTRREAD);
assign LsuBusAck = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE);
endmodule

View File

@ -1,6 +1,7 @@
`include "wally-config.vh"
// `include "../../config/rv64icfd/wally-config.vh"
// `define XLEN 64
module fcvt (
input logic XSgnE, // X's sign
input logic [10:0] XExpE, // X's exponent
@ -59,7 +60,7 @@ module fcvt (
// fcvt.lu.d = 111
// fcvt.d.l = 100
// fcvt.d.lu = 110
// {long, unsigned, to int, from int}
// {long, unsigned, to int}
// calculate signals based off the input and output's size
assign Res64 = (FOpCtrlE[0]&FOpCtrlE[2]) | (FmtE&~FOpCtrlE[0]);
@ -158,19 +159,24 @@ module fcvt (
// select the integer result
assign CvtIntRes = Of ? FOpCtrlE[1] ? {64{1'b1}} : SgnRes ? {33'b0, {31{1'b1}}}: {1'b0, {63{1'b1}}} :
Uf ? FOpCtrlE[1] ? 64'b0 : SgnRes ? {32'b0, 1'b1, 31'b0} : {1'b1, 63'b0} :
Uf ? FOpCtrlE[1] ? {63'b0, Plus1&~XSgnE} : SgnRes ? {32'b0, 1'b1, 31'b0} : {1'b1, 63'b0} :
Rounded[64-1:0];
// select the floating point result
assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {{32{1'b1}}, ResSgn, ResExp[7:0], ResFrac[51:29]};
// select the result
assign CvtResE = ~FOpCtrlE[0] ? CvtFPRes : CvtIntRes;
assign CvtResE = FOpCtrlE[0] ? CvtIntRes : CvtFPRes;
// calculate the flags
// - to int only sets the invalid flag
// - from int only sets the inexact flag
assign CvtFlgE = {(Of | Uf)&FOpCtrlE[0], 3'b0, (Guard|Round|Sticky)&~FOpCtrlE[0]};
// - only set invalid flag for out-of-range vales if it isn't be indicated by the inexact
// - don't set inexact flag if converting a really large number (closest __ bit integer value is the max value)
// - don't set inexact flag if converting negitive or tiny number to unsigned (closest integer value is 0 or 1)
logic Invalid, Inexact;
assign Invalid = (Of | Uf)&FOpCtrlE[0];
assign Inexact = (Guard|Round|Sticky)&~((&FOpCtrlE[1:0]&Uf&~(Plus1&~XSgnE))|(FOpCtrlE[0]&Of));
assign CvtFlgE = {Invalid&~Inexact, 3'b0, Inexact};
// assign CvtFlgE = {(Of | Uf)&FOpCtrlE[0], 3'b0, (Guard|Round|Sticky)&~FOpCtrlE[0]};

View File

@ -28,7 +28,6 @@
// `define NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
// `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
// `define XLEN 64
`define NANPAYLOAD 1
module fma(
input logic clk,
input logic reset,
@ -117,7 +116,6 @@ module fma1(
logic [3*`NF+5:0] AlignedAddendE; // Z aligned for addition in U(NF+5.2NF+1)
logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted
logic [2*`NF+1:0] ProdManKilled; // the product's mantissa possibly killed
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
logic [3*`NF+6:0] PreSum, NegPreSum; // positive and negitve versions of the sum
logic [`NE-1:0] XExpVal, YExpVal; // exponent value after taking into accound denormals
///////////////////////////////////////////////////////////////////////////////
@ -321,7 +319,6 @@ module add(
output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum
);
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
///////////////////////////////////////////////////////////////////////////////
// Addition
///////////////////////////////////////////////////////////////////////////////
@ -335,15 +332,13 @@ module add(
assign AlignedAddendInv = InvZE ? {1'b1, ~AlignedAddendE} : {1'b0, AlignedAddendE};
// Kill the product if the product is too small to effect the addition (determined in fma1.sv)
assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}};
// Negate ProdMan for LZA and the negitive sum calculation
assign NegProdManKilled = {{`NF+3{~(XZeroE|YZeroE|KillProdE)}}, ~ProdManKilled&{2*`NF+2{~(XZeroE|YZeroE|KillProdE)}}};
// Do the addition
// - calculate a positive and negitive sum in parallel
assign PreSum = AlignedAddendInv + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE};
assign NegPreSum = AlignedAddendE + {NegProdManKilled, 2'b0} + {{(3*`NF+3){1'b0}},~(XZeroE|YZeroE|KillProdE),2'b0};
assign NegPreSum = XZeroE|YZeroE|KillProdE ? {1'b0, AlignedAddendE} : {1'b0, AlignedAddendE} + {{`NF+3{1'b1}}, ~ProdManKilled, 2'b0} + {(3*`NF+7)'(4)};
// Is the sum negitive
assign NegSumE = PreSum[3*`NF+6];
@ -360,6 +355,8 @@ module loa( //https://ieeexplore.ieee.org/abstract/document/930098
logic [3*`NF+6:0] T;
logic [3*`NF+6:0] G;
logic [3*`NF+6:0] Z;
logic [3*`NF+6:0] f;
assign T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4];
assign G[3*`NF+6:2*`NF+4] = 0;
assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4];
@ -375,7 +372,6 @@ module loa( //https://ieeexplore.ieee.org/abstract/document/930098
// - note: the paper linked above uses the numbering system where 0 is the most significant bit
//f[n] = ~T[n]&T[n-1] note: n is the MSB
//f[i] = (T[i+1]&(G[i]&~Z[i-1] | Z[i]&~G[i-1])) | (~T[i+1]&(Z[i]&~Z[i-1] | G[i]&~G[i-1]))
logic [3*`NF+6:0] f;
assign f[3*`NF+6] = ~T[3*`NF+6]&T[3*`NF+5];
assign f[3*`NF+5:0] = (T[3*`NF+6:1]&(G[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | Z[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1})) | (~T[3*`NF+6:1]&(Z[3*`NF+5:0]&{~Z[3*`NF+4:0], 1'b0} | G[3*`NF+5:0]&{~G[3*`NF+4:0], 1'b1}));
@ -440,11 +436,12 @@ module fma2(
logic SumZero; // is the sum zero
logic ResultDenorm; // is the result denormalized
logic Sticky, UfSticky; // Sticky bit
logic Plus1, Minus1, CalcPlus1; // do you add or subtract one for rounding
logic CalcPlus1; // do you add or subtract one for rounding
logic UfPlus1; // do you add one (for determining underflow flag)
logic Invalid,Underflow,Overflow; // flags
logic Guard, Round; // bits needed to determine rounding
logic UfLSBNormSum; // bits needed to determine rounding for underflow flag
logic [`FLEN:0] RoundAdd; // how much to add to the result
@ -471,7 +468,7 @@ module fma2(
// round to nearest max magnitude
fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgnTmp, .SumExp,
.CalcPlus1, .Plus1, .UfPlus1, .Minus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .UfLSBNormSum);
.CalcPlus1, .UfPlus1, .FullResultExp, .ResultFrac, .ResultExp, .Round, .Guard, .RoundAdd, .UfLSBNormSum);
@ -503,8 +500,8 @@ module fma2(
///////////////////////////////////////////////////////////////////////////////
resultselect resultselect(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,
.FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM,
.ZSgnEffM, .PSgnM, .ResultSgn, .Minus1, .Plus1, .CalcPlus1, .Invalid, .Overflow, .Underflow,
.FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd,
.ZSgnEffM, .PSgnM, .ResultSgn, .CalcPlus1, .Invalid, .Overflow, .Underflow,
.ResultDenorm, .ResultExp, .ResultFrac, .FMAResM);
// *** use NF where needed
@ -539,61 +536,6 @@ module resultsign(
endmodule
module resultselect(
input logic XSgnM, YSgnM, // input signs
input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic FmtM, // precision 1 = double 0 = single
input logic AddendStickyM, // sticky bit that is calculated during alignment
input logic KillProdM, // set the product to zero before addition if the product is too small to matter
input logic XInfM, YInfM, ZInfM, // inputs are infinity
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
input logic ZSgnEffM, // the modified Z sign - depends on instruction
input logic PSgnM, // the product's sign
input logic ResultSgn, // the result's sign
input logic Minus1, Plus1, CalcPlus1, // rounding bits
input logic Invalid, Overflow, Underflow, // flags
input logic ResultDenorm, // is the result denormalized
input logic [`NE-1:0] ResultExp, // Result exponent
input logic [`NF-1:0] ResultFrac, // Result fraction
output logic [`FLEN-1:0] FMAResM // FMA final result
);
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
generate if(`NANPAYLOAD) begin
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
end else begin
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, 22'b0};
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, 22'b0};
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, 22'b0};
end
endgenerate
assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} :
{ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} :
{{32{1'b1}}, ResultSgn, 8'hff, 23'b0};
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} - {62'b0, (Minus1&AddendStickyM)} + {62'b0, (Plus1&AddendStickyM)}} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} - {30'b0, (Minus1&AddendStickyM)} + {30'b0, (Plus1&AddendStickyM)}};
assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}};
assign FMAResM = XNaNM ? XNaNResult :
YNaNM ? YNaNResult :
ZNaNM ? ZNaNResult :
Invalid ? InvalidResult :
XInfM ? FmtM ? {PSgnM, XExpM, XManM[`NF-1:0]} : {{32{1'b1}}, PSgnM, XExpM[7:0], XManM[51:29]} :
YInfM ? FmtM ? {PSgnM, YExpM, YManM[`NF-1:0]} : {{32{1'b1}}, PSgnM, YExpM[7:0], YManM[51:29]} :
ZInfM ? FmtM ? {ZSgnEffM, ZExpM, ZManM[`NF-1:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], ZManM[51:29]} :
KillProdM ? KillProdResult :
Overflow ? OverflowResult :
Underflow & ~ResultDenorm & (ResultExp!=1) ? UnderflowResult :
FmtM ? {ResultSgn, ResultExp, ResultFrac} :
{{32{1'b1}}, ResultSgn, ResultExp[7:0], ResultFrac[51:29]};
endmodule
module normalize(
input logic [3*`NF+5:0] SumM, // the positive sum
@ -624,19 +566,6 @@ module normalize(
// Normalization
///////////////////////////////////////////////////////////////////////////////
// logic [8:0] supposedNormCnt;
// logic [8:0] i;
// always_comb begin
// i = 0;
// while (~SumM[3*`NF+5-i] && $unsigned(i) <= $unsigned(3*`NF+5)) i = i+1; // search for leading one
// supposedNormCnt = i; // compute shift count
// end
// always_comb begin
// assert (NormCntM == supposedNormCnt | NormCntM == supposedNormCnt+1 | NormCntM == supposedNormCnt+2) else $fatal ("normcnt not expected");
// end
// Determine if the sum is zero
assign SumZero = ~(|SumM);
@ -644,18 +573,15 @@ module normalize(
assign FracLen = FmtM ? `NF+1 : 13'd24;
// calculate the sum's exponent
assign SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4)); // ****try moving this into previous stage
assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}}; // ***move this ^ the subtraction by a constant isn't simplified
assign SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4));
assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}};
logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL;
assign SumDLTEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp;
assign SumDGEFL = ($signed(SumExpTmpTmp)>=$signed(-(13'd`NF+13'd1)));
assign SumDGEFL = ($signed(SumExpTmpTmp)>=$signed(-(13'd`NF+13'd2)));
assign SumSLTEZ = $signed(SumExpTmpTmp) <= $signed(13'd1023-13'd127);
assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd24+13'd1023-13'd127)) | ~|SumExpTmpTmp;
assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero; //***make sure math good
// always_comb begin
// assert (PreResultDenorm == PreResultDenorm2) else $fatal ("PreResultDenorms not equal");
// end
assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd25+13'd1023-13'd127)) | ~|SumExpTmpTmp;
assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero;
// 010. when should be 001.
// - shift left one
@ -667,9 +593,9 @@ module normalize(
// Determine the shift needed for denormal results
// - if not denorm add 1 to shift out the leading 1
assign DenormShift = PreResultDenorm2 ? SumExpTmp[8:0] : 1; //*** change this when changing the size of DenormShift also change to an and opperation
assign DenormShift = PreResultDenorm2 ? SumExpTmp[8:0] : 1;
// Normalize the sum
assign SumShifted = {3'b0, SumM} << NormCntM+DenormShift; //*** fix mux's with constants in them //***NormCnt can be simplified
assign SumShifted = {3'b0, SumM} << NormCntM+DenormShift;
// LZA correction
assign LZAPlus1 = SumShifted[3*`NF+7];
assign LZAPlus2 = SumShifted[3*`NF+8];
@ -699,18 +625,18 @@ module fmaround(
input logic InvZM, // invert Z
input logic [`NE+1:0] SumExp, // exponent of the normalized sum
input logic ResultSgnTmp, // the result's sign
output logic CalcPlus1, Plus1, UfPlus1, Minus1, // do you add or subtract on from the result
output logic CalcPlus1, UfPlus1, // do you add or subtract on from the result
output logic [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow
output logic [`NF-1:0] ResultFrac, // Result fraction
output logic [`NE-1:0] ResultExp, // Result exponent
output logic Sticky, // sticky bit
output logic [`FLEN:0] RoundAdd, // how much to add to the result
output logic Round, Guard, UfLSBNormSum // bits needed to calculate rounding
);
logic LSBNormSum; // bit used for rounding - least significant bit of the normalized sum
logic SubBySmallNum, UfSubBySmallNum; // was there supposed to be a subtraction by a small number
logic UfGuard; // gaurd bit used to caluculate underflow
logic UfCalcPlus1, CalcMinus1; // do you add or subtract on from the result
logic [`FLEN:0] RoundAdd; // how much to add to the result
logic UfGuard; // guard bit used to caluculate underflow
logic UfCalcPlus1, CalcMinus1, Plus1, Minus1; // do you add or subtract on from the result
logic [`NF-1:0] NormSumTruncated; // the normalized sum trimed to fit the mantissa
logic UfRound;
@ -857,4 +783,62 @@ module fmaflags(
// - Don't set the underflow flag if the result was rounded up to a normal number
assign FMAFlgM = {Invalid, 1'b0, Overflow, UnderflowFlag, Inexact};
endmodule
module resultselect(
input logic XSgnM, YSgnM, // input signs
input logic [`NE-1:0] XExpM, YExpM, ZExpM, // input exponents
input logic [`NF:0] XManM, YManM, ZManM, // input mantissas
input logic [2:0] FrmM, // rounding mode 000 = rount to nearest, ties to even 001 = round twords zero 010 = round down 011 = round up 100 = round to nearest, ties to max magnitude
input logic FmtM, // precision 1 = double 0 = single
input logic AddendStickyM, // sticky bit that is calculated during alignment
input logic KillProdM, // set the product to zero before addition if the product is too small to matter
input logic XInfM, YInfM, ZInfM, // inputs are infinity
input logic XNaNM, YNaNM, ZNaNM, // inputs are NaN
input logic ZSgnEffM, // the modified Z sign - depends on instruction
input logic PSgnM, // the product's sign
input logic ResultSgn, // the result's sign
input logic CalcPlus1, // rounding bits
input logic [`FLEN:0] RoundAdd, // how much to add to the result
input logic Invalid, Overflow, Underflow, // flags
input logic ResultDenorm, // is the result denormalized
input logic [`NE-1:0] ResultExp, // Result exponent
input logic [`NF-1:0] ResultFrac, // Result fraction
output logic [`FLEN-1:0] FMAResM // FMA final result
);
logic [`FLEN-1:0] XNaNResult, YNaNResult, ZNaNResult, InvalidResult, OverflowResult, KillProdResult, UnderflowResult; // possible results
generate if(`IEEE754) begin
assign XNaNResult = FmtM ? {XSgnM, XExpM, 1'b1, XManM[`NF-2:0]} : {{32{1'b1}}, XSgnM, XExpM[7:0], 1'b1, XManM[50:29]};
assign YNaNResult = FmtM ? {YSgnM, YExpM, 1'b1, YManM[`NF-2:0]} : {{32{1'b1}}, YSgnM, YExpM[7:0], 1'b1, YManM[50:29]};
assign ZNaNResult = FmtM ? {ZSgnEffM, ZExpM, 1'b1, ZManM[`NF-2:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], 1'b1, ZManM[50:29]};
end else begin
assign XNaNResult = FmtM ? {1'b0, XExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, XExpM[7:0], 1'b1, 22'b0};
assign YNaNResult = FmtM ? {1'b0, YExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, YExpM[7:0], 1'b1, 22'b0};
assign ZNaNResult = FmtM ? {1'b0, ZExpM, 1'b1, 51'b0} : {{32{1'b1}}, 1'b0, ZExpM[7:0], 1'b1, 22'b0};
end
endgenerate
assign OverflowResult = FmtM ? ((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {ResultSgn, {`NE-1{1'b1}}, 1'b0, {`NF{1'b1}}} :
{ResultSgn, {`NE{1'b1}}, {`NF{1'b0}}} :
((FrmM[1:0]==2'b01) | (FrmM[1:0]==2'b10&~ResultSgn) | (FrmM[1:0]==2'b11&ResultSgn)) ? {{32{1'b1}}, ResultSgn, 8'hfe, {23{1'b1}}} :
{{32{1'b1}}, ResultSgn, 8'hff, 23'b0};
assign InvalidResult = FmtM ? {ResultSgn, {`NE{1'b1}}, 1'b1, {`NF-1{1'b0}}} : {{32{1'b1}}, ResultSgn, 8'hff, 1'b1, 22'b0};
assign KillProdResult = FmtM ? {ResultSgn, {ZExpM, ZManM[`NF-1:0]} + (RoundAdd[`FLEN-2:0]&{`FLEN-1{AddendStickyM}})} : {{32{1'b1}}, ResultSgn, {ZExpM[`NE-1],ZExpM[6:0], ZManM[51:29]} + (RoundAdd[59:29]&{31{AddendStickyM}})};
assign UnderflowResult = FmtM ? {ResultSgn, {`FLEN-1{1'b0}}} + {63'b0,(CalcPlus1&(AddendStickyM|FrmM[1]))} : {{32{1'b1}}, {ResultSgn, 31'b0} + {31'b0, (CalcPlus1&(AddendStickyM|FrmM[1]))}};
assign FMAResM = XNaNM ? XNaNResult :
YNaNM ? YNaNResult :
ZNaNM ? ZNaNResult :
Invalid ? InvalidResult :
XInfM ? FmtM ? {PSgnM, XExpM, XManM[`NF-1:0]} : {{32{1'b1}}, PSgnM, XExpM[7:0], XManM[51:29]} :
YInfM ? FmtM ? {PSgnM, YExpM, YManM[`NF-1:0]} : {{32{1'b1}}, PSgnM, YExpM[7:0], YManM[51:29]} :
ZInfM ? FmtM ? {ZSgnEffM, ZExpM, ZManM[`NF-1:0]} : {{32{1'b1}}, ZSgnEffM, ZExpM[7:0], ZManM[51:29]} :
KillProdM ? KillProdResult :
Overflow ? OverflowResult :
Underflow & ~ResultDenorm & (ResultExp!=1) ? UnderflowResult :
FmtM ? {ResultSgn, ResultExp, ResultFrac} :
{{32{1'b1}}, ResultSgn, ResultExp[7:0], ResultFrac[51:29]};
endmodule

View File

@ -31,11 +31,11 @@ module ifu (
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushF, FlushD, FlushE, FlushM, FlushW,
// Fetch
input logic [`XLEN-1:0] InstrInF,
input logic InstrAckF,
input logic [`XLEN-1:0] IfuBusHRDATA,
input logic ICacheBusAck,
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
output logic [`PA_BITS-1:0] InstrPAdrF,
output logic InstrReadF,
output logic [`PA_BITS-1:0] ICacheBusAdr,
output logic IfuBusFetch,
output logic ICacheStallF,
// Execute
output logic [`XLEN-1:0] PCLinkE,
@ -104,6 +104,8 @@ module ifu (
logic [`XLEN+1:0] PCFExt;
logic [`XLEN-1:0] PCBPWrongInvalidate;
logic BPPredWrongM;
logic CacheableF;
generate
@ -136,7 +138,7 @@ module ifu (
.LoadAccessFaultM(),
.StoreAccessFaultM(),
.DisableTranslation(1'b0),
.Cacheable(), .Idempotent(), .AtomicAllowed(),
.Cacheable(CacheableF), .Idempotent(), .AtomicAllowed(),
.clk, .reset,
.SATP_REGW,
@ -157,17 +159,17 @@ module ifu (
// *** put memory interface on here, InstrF becomes output
//assign InstrPAdrF = PCF; // *** no MMU
//assign InstrReadF = ~StallD; // *** & ICacheMissF; add later
// assign InstrReadF = 1; // *** & ICacheMissF; add later
//assign ICacheBusAdr = PCF; // *** no MMU
//assign IfuBusFetch = ~StallD; // *** & ICacheMissF; add later
// assign IfuBusFetch = 1; // *** & ICacheMissF; add later
// conditional
// 1. ram // controlled by `MEM_IROM
// 2. cache // `MEM_ICACHE
// 3. wire pass-through
icache icache(.clk, .reset, .StallF, .ExceptionM, .PendingInterruptM, .InstrInF, .InstrAckF,
.InstrPAdrF, .InstrReadF, .CompressedF, .ICacheStallF, .ITLBMissF, .ITLBWriteF, .FinalInstrRawF,
icache icache(.clk, .reset, .CPUBusy(StallF), .ExceptionM, .PendingInterruptM, .IfuBusHRDATA, .ICacheBusAck,
.ICacheBusAdr, .IfuBusFetch, .CompressedF, .ICacheStallF, .ITLBMissF, .ITLBWriteF, .FinalInstrRawF,
.CacheableF,
.PCNextF(PCNextFPhys),
.PCPF(PCPFmmu),
.PCF,

View File

@ -0,0 +1,139 @@
///////////////////////////////////////////
// busfsm.sv
//
// Written: Ross Thompson ross1728@gmail.com December 29, 2021
// Modified:
//
// Purpose: Load/Store Unit's interface to BUS
//
// A component of the Wally configurable RISC-V project.
//
// 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-config.vh"
module busfsm #(parameter integer WordCountThreshold,
parameter integer LOGWPL)
(input logic clk,
input logic reset,
input logic IgnoreRequest,
input logic [1:0] LsuRWM,
input logic DCacheFetchLine,
input logic DCacheWriteLine,
input logic LsuBusAck,
input logic CPUBusy,
input logic CacheableM,
output logic BusStall,
output logic LsuBusWrite,
output logic LsuBusRead,
output logic DCacheBusAck,
output logic BusCommittedM,
output logic SelUncachedAdr,
output logic [LOGWPL-1:0] WordCount);
logic UnCachedLsuBusRead;
logic UnCachedLsuBusWrite;
logic CntEn, PreCntEn;
logic CntReset;
logic WordCountFlag;
logic [LOGWPL-1:0] NextWordCount;
typedef enum {STATE_BUS_READY,
STATE_BUS_FETCH,
STATE_BUS_WRITE,
STATE_BUS_UNCACHED_WRITE,
STATE_BUS_UNCACHED_WRITE_DONE,
STATE_BUS_UNCACHED_READ,
STATE_BUS_UNCACHED_READ_DONE,
STATE_BUS_CPU_BUSY} busstatetype;
(* mark_debug = "true" *) busstatetype BusCurrState, BusNextState;
flopenr #(LOGWPL)
WordCountReg(.clk(clk),
.reset(reset | CntReset),
.en(CntEn),
.d(NextWordCount),
.q(WordCount));
assign NextWordCount = WordCount + 1'b1;
assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]);
assign CntEn = PreCntEn & LsuBusAck;
always_ff @(posedge clk)
if (reset) BusCurrState <= #1 STATE_BUS_READY;
else BusCurrState <= #1 BusNextState;
always_comb begin
case(BusCurrState)
STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY;
else if(LsuRWM[0] & (~CacheableM | ~`MEM_DCACHE)) BusNextState = STATE_BUS_UNCACHED_WRITE;
else if(LsuRWM[1] & (~CacheableM | ~`MEM_DCACHE)) BusNextState = STATE_BUS_UNCACHED_READ;
else if(DCacheFetchLine) BusNextState = STATE_BUS_FETCH;
else if(DCacheWriteLine) BusNextState = STATE_BUS_WRITE;
else BusNextState = STATE_BUS_READY;
STATE_BUS_UNCACHED_WRITE: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE;
else BusNextState = STATE_BUS_UNCACHED_WRITE;
STATE_BUS_UNCACHED_READ: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE;
else BusNextState = STATE_BUS_UNCACHED_READ;
STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY;
STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY;
STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY;
STATE_BUS_FETCH: if (WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY;
else BusNextState = STATE_BUS_FETCH;
STATE_BUS_WRITE: if(WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY;
else BusNextState = STATE_BUS_WRITE;
default: BusNextState = STATE_BUS_READY;
endcase
end
assign CntReset = BusCurrState == STATE_BUS_READY;
assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((~CacheableM & (|LsuRWM)) | DCacheFetchLine | DCacheWriteLine)) |
(BusCurrState == STATE_BUS_UNCACHED_WRITE) |
(BusCurrState == STATE_BUS_UNCACHED_READ) |
(BusCurrState == STATE_BUS_FETCH) |
(BusCurrState == STATE_BUS_WRITE);
assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE;
assign UnCachedLsuBusWrite = (BusCurrState == STATE_BUS_READY & ~CacheableM & (LsuRWM[0])) |
(BusCurrState == STATE_BUS_UNCACHED_WRITE);
assign LsuBusWrite = UnCachedLsuBusWrite | (BusCurrState == STATE_BUS_WRITE);
assign UnCachedLsuBusRead = (BusCurrState == STATE_BUS_READY & ~CacheableM & (|LsuRWM[1])) |
(BusCurrState == STATE_BUS_UNCACHED_READ);
assign LsuBusRead = UnCachedLsuBusRead | (BusCurrState == STATE_BUS_FETCH);
assign DCacheBusAck = (BusCurrState == STATE_BUS_FETCH & WordCountFlag & LsuBusAck) |
(BusCurrState == STATE_BUS_WRITE & WordCountFlag & LsuBusAck);
assign BusCommittedM = BusCurrState != STATE_BUS_READY;
assign SelUncachedAdr = (BusCurrState == STATE_BUS_READY & (|LsuRWM & ~CacheableM)) |
(BusCurrState == STATE_BUS_UNCACHED_READ |
BusCurrState == STATE_BUS_UNCACHED_READ_DONE |
BusCurrState == STATE_BUS_UNCACHED_WRITE |
BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE) |
~`MEM_DCACHE; // if no dcache always select uncachedadr.
endmodule

View File

@ -0,0 +1,113 @@
///////////////////////////////////////////
// interlockfsm.sv
//
// Written: Ross Thompson ross1728@gmail.com December 29, 2021
// Modified:
//
// Purpose: Allows the HPTW to take control of the dcache to walk page table and then replay the memory operation if
// there was on.
//
// A component of the Wally configurable RISC-V project.
//
// 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-config.vh"
module interlockfsm
(input logic clk,
input logic reset,
input logic AnyCPUReqM,
input logic ITLBMissF,
input logic ITLBWriteF,
input logic DTLBMissM,
input logic DTLBWriteM,
input logic ExceptionM,
input logic PendingInterruptM,
input logic DCacheStall,
output logic InterlockStall,
output logic SelReplayCPURequest,
output logic SelHPTW,
output logic IgnoreRequest);
typedef enum {STATE_T0_READY,
STATE_T0_REPLAY,
STATE_T3_DTLB_MISS,
STATE_T4_ITLB_MISS,
STATE_T5_ITLB_MISS,
STATE_T7_DITLB_MISS} statetype;
statetype InterlockCurrState, InterlockNextState;
always_ff @(posedge clk)
if (reset) InterlockCurrState <= #1 STATE_T0_READY;
else InterlockCurrState <= #1 InterlockNextState;
always_comb begin
case(InterlockCurrState)
STATE_T0_READY: if(~ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS;
else if(ITLBMissF & ~DTLBMissM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS;
else if(ITLBMissF & ~DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS;
else if(ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS;
else InterlockNextState = STATE_T0_READY;
STATE_T0_REPLAY: if(DCacheStall) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T0_READY;
STATE_T3_DTLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T3_DTLB_MISS;
STATE_T4_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_READY;
else InterlockNextState = STATE_T4_ITLB_MISS;
STATE_T5_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T5_ITLB_MISS;
STATE_T7_DITLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T5_ITLB_MISS;
else InterlockNextState = STATE_T7_DITLB_MISS;
default: InterlockNextState = STATE_T0_READY;
endcase
end // always_comb
// signal to CPU it needs to wait on HPTW.
/* -----\/----- EXCLUDED -----\/-----
// 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.
// Note this will cause a problem for post synthesis gate simulation.
assign InterlockStall = (InterlockCurrState == STATE_T0_READY & (DTLBMissM | ITLBMissF)) |
(InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
-----/\----- EXCLUDED -----/\----- */
always_comb begin
InterlockStall = 1'b0;
case(InterlockCurrState)
STATE_T0_READY: if(DTLBMissM | ITLBMissF) InterlockStall = 1'b1;
STATE_T3_DTLB_MISS: InterlockStall = 1'b1;
STATE_T4_ITLB_MISS: InterlockStall = 1'b1;
STATE_T5_ITLB_MISS: InterlockStall = 1'b1;
STATE_T7_DITLB_MISS: InterlockStall = 1'b1;
default: InterlockStall = 1'b0;
endcase
end
assign SelReplayCPURequest = (InterlockNextState == STATE_T0_REPLAY);
assign SelHPTW = (InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
assign IgnoreRequest = (InterlockCurrState == STATE_T0_READY & (ITLBMissF | DTLBMissM | ExceptionM | PendingInterruptM)) |
((InterlockCurrState == STATE_T0_REPLAY)
& (ExceptionM | PendingInterruptM));
endmodule

View File

@ -31,10 +31,10 @@ module lrsc
input logic clk, reset,
input logic FlushW, CPUBusy,
input logic MemReadM,
input logic [1:0] LsuRWM,
output logic [1:0] DCRWM,
input logic [1:0] PreLsuRWM,
output logic [1:0] LsuRWM,
input logic [1:0] LsuAtomicM,
input logic [`PA_BITS-1:0] MemPAdrM, // from mmu to dcache
input logic [`PA_BITS-1:0] LsuPAdrM, // from mmu to dcache
output logic SquashSCW
);
// Handle atomic load reserved / store conditional
@ -44,16 +44,16 @@ module lrsc
logic SquashSCM;
assign lrM = MemReadM && LsuAtomicM[0];
assign scM = LsuRWM[0] && LsuAtomicM[0];
assign WriteAdrMatchM = LsuRWM[0] && (MemPAdrM[`PA_BITS-1:2] == ReservationPAdrW) && ReservationValidW;
assign scM = PreLsuRWM[0] && LsuAtomicM[0];
assign WriteAdrMatchM = PreLsuRWM[0] && (LsuPAdrM[`PA_BITS-1:2] == ReservationPAdrW) && ReservationValidW;
assign SquashSCM = scM && ~WriteAdrMatchM;
assign DCRWM = SquashSCM ? 2'b00 : LsuRWM;
assign LsuRWM = SquashSCM ? 2'b00 : PreLsuRWM;
always_comb begin // ReservationValidM (next value of valid reservation)
if (lrM) ReservationValidM = 1; // set valid on load reserve
else if (scM || WriteAdrMatchM) ReservationValidM = 0; // clear valid on store to same address or any sc
else ReservationValidM = ReservationValidW; // otherwise don't change valid
end
flopenrc #(`PA_BITS-2) resadrreg(clk, reset, FlushW, lrM, MemPAdrM[`PA_BITS-1:2], ReservationPAdrW); // could drop clear on this one but not valid
flopenrc #(`PA_BITS-2) resadrreg(clk, reset, FlushW, lrM, LsuPAdrM[`PA_BITS-1:2], ReservationPAdrW); // could drop clear on this one but not valid
flopenrc #(1) resvldreg(clk, reset, FlushW, lrM, ReservationValidM, ReservationValidW);
flopenrc #(1) squashreg(clk, reset, FlushW, ~CPUBusy, SquashSCM, SquashSCW);
endmodule

View File

@ -90,20 +90,19 @@ module lsu
logic DTLBPageFaultM;
logic [`PA_BITS-1:0] MemPAdrM; // from mmu to dcache
logic [`PA_BITS-1:0] LsuPAdrM; // from mmu to dcache
logic [`XLEN+1:0] IEUAdrExtM;
logic DTLBMissM;
logic DTLBWriteM;
logic [1:0] DCRWM;
logic [1:0] LsuRWM;
logic [1:0] PreLsuRWM;
logic [2:0] LsuFunct3M;
logic [1:0] LsuAtomicM;
logic [`PA_BITS-1:0] LsuPAdrM, LocalLsuBusAdr;
logic [11:0] LsuAdrE, DCAdrE;
logic [`PA_BITS-1:0] PreLsuPAdrM, LocalLsuBusAdr;
logic [11:0] PreLsuAdrE, LsuAdrE;
logic CPUBusy;
logic MemReadM;
logic DataMisalignedM;
logic DCacheStall;
logic CacheableM;
@ -115,7 +114,7 @@ module lsu
logic InterlockStall;
logic IgnoreRequest;
logic BusCommittedM, DCCommittedM;
logic BusCommittedM, DCacheCommittedM;
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
@ -129,78 +128,13 @@ module lsu
logic [2:0] HPTWSize;
logic SelReplayCPURequest;
typedef enum {STATE_T0_READY,
STATE_T0_REPLAY,
STATE_T3_DTLB_MISS,
STATE_T4_ITLB_MISS,
STATE_T5_ITLB_MISS,
STATE_T7_DITLB_MISS} statetype;
assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
statetype InterlockCurrState, InterlockNextState;
assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
always_ff @(posedge clk)
if (reset) InterlockCurrState <= #1 STATE_T0_READY;
else InterlockCurrState <= #1 InterlockNextState;
always_comb begin
case(InterlockCurrState)
STATE_T0_READY: if(~ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T3_DTLB_MISS;
else if(ITLBMissF & ~DTLBMissM & ~AnyCPUReqM) InterlockNextState = STATE_T4_ITLB_MISS;
else if(ITLBMissF & ~DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T5_ITLB_MISS;
else if(ITLBMissF & DTLBMissM & AnyCPUReqM) InterlockNextState = STATE_T7_DITLB_MISS;
else InterlockNextState = STATE_T0_READY;
STATE_T0_REPLAY: if(DCacheStall) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T0_READY;
STATE_T3_DTLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T3_DTLB_MISS;
STATE_T4_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_READY;
else InterlockNextState = STATE_T4_ITLB_MISS;
STATE_T5_ITLB_MISS: if(ITLBWriteF) InterlockNextState = STATE_T0_REPLAY;
else InterlockNextState = STATE_T5_ITLB_MISS;
STATE_T7_DITLB_MISS: if(DTLBWriteM) InterlockNextState = STATE_T5_ITLB_MISS;
else InterlockNextState = STATE_T7_DITLB_MISS;
default: InterlockNextState = STATE_T0_READY;
endcase
end // always_comb
interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .ExceptionM, .PendingInterruptM, .DCacheStall,
.InterlockStall, .SelReplayCPURequest, .SelHPTW,
.IgnoreRequest);
// signal to CPU it needs to wait on HPTW.
/* -----\/----- EXCLUDED -----\/-----
// 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.
assign InterlockStall = (InterlockCurrState == STATE_T0_READY & (DTLBMissM | ITLBMissF)) |
(InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
-----/\----- EXCLUDED -----/\----- */
always_comb begin
InterlockStall = 1'b0;
case(InterlockCurrState)
STATE_T0_READY: if(DTLBMissM | ITLBMissF) InterlockStall = 1'b1;
STATE_T3_DTLB_MISS: InterlockStall = 1'b1;
STATE_T4_ITLB_MISS: InterlockStall = 1'b1;
STATE_T5_ITLB_MISS: InterlockStall = 1'b1;
STATE_T7_DITLB_MISS: InterlockStall = 1'b1;
default: InterlockStall = 1'b0;
endcase
end
// When replaying CPU memory request after PTW select the IEUAdrM for correct address.
assign SelReplayCPURequest = (InterlockNextState == STATE_T0_REPLAY);
assign SelHPTW = (InterlockCurrState == STATE_T3_DTLB_MISS) | (InterlockCurrState == STATE_T4_ITLB_MISS) |
(InterlockCurrState == STATE_T5_ITLB_MISS) | (InterlockCurrState == STATE_T7_DITLB_MISS);
assign IgnoreRequest = (InterlockCurrState == STATE_T0_READY & (ITLBMissF | DTLBMissM | ExceptionM | PendingInterruptM)) |
((InterlockCurrState == STATE_T0_REPLAY)
& (ExceptionM | PendingInterruptM));
// *** add generate to conditionally create hptw, lsuArb, and mmu
// based on `MEM_VIRTMEM
hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM,
.ITLBMissF(ITLBMissF & ~PendingInterruptM),
.DTLBMissM(DTLBMissM & ~PendingInterruptM),
@ -211,38 +145,31 @@ module lsu
// arbiter between IEU and hptw
// multiplex the outputs to LSU
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, LsuRWM);
mux2 #(2) rwmux(MemRWM, {HPTWRead, 1'b0}, SelHPTW, PreLsuRWM);
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M);
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM);
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, LsuAdrE);
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, LsuPAdrM);
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE);
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM);
// always block interrupts when using the hardware page table walker.
assign CPUBusy = StallW & ~SelHPTW;
// always block interrupts when using the hardware page table walker.
// this is for the d cache SRAM.
// turns out because we cannot pipeline hptw requests we don't need this register
// It is not possible to pipeline hptw as the following load will depend on the previous load's
// data. Therefore we don't need a pipeline register
//flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM); // delay HPTWAdrM by a cycle
//assign LsuRWM = SelHPTW ? {HPTWRead, 1'b0} : MemRWM;
//assign LsuAdrE = SelHPTW ? HPTWAdr[11:0] : IEUAdrE[11:0];
//assign LsuAtomicM = SelHPTW ? 2'b00 : AtomicM;
//assign LsuPAdrM = SelHPTW ? HPTWAdr : IEUAdrExtM[`PA_BITS-1:0];
// Specify which type of page fault is occurring
// *** `MEM_VIRTMEM
assign DTLBLoadPageFaultM = DTLBPageFaultM & LsuRWM[1];
assign DTLBStorePageFaultM = DTLBPageFaultM & LsuRWM[0];
assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1];
assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0];
assign DCAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : LsuAdrE;
// When replaying CPU memory request after PTW select the IEUAdrM for correct address.
assign LsuAdrE = SelReplayCPURequest ? IEUAdrM[11:0] : PreLsuAdrE;
end // if (`MEM_VIRTMEM)
else begin
assign InterlockStall = 1'b0;
assign DCAdrE = LsuAdrE;
assign LsuAdrE = PreLsuAdrE;
assign SelHPTW = 1'b0;
assign IgnoreRequest = 1'b0;
@ -251,11 +178,11 @@ module lsu
assign DTLBWriteM = 1'b0;
assign ITLBWriteF = 1'b0;
assign LsuRWM = MemRWM;
assign PreLsuRWM = MemRWM;
assign LsuFunct3M = Funct3M;
assign LsuAtomicM = AtomicM;
assign LsuAdrE = IEUAdrE[11:0];
assign LsuPAdrM = IEUAdrExtM;
assign PreLsuAdrE = IEUAdrE[11:0];
assign PreLsuPAdrM = IEUAdrExtM;
assign CPUBusy = StallW;
assign DTLBLoadPageFaultM = 1'b0;
@ -263,141 +190,159 @@ module lsu
end
endgenerate
assign CommittedM = SelHPTW | DCCommittedM | BusCommittedM;
// **** look into this confusing signal.
// This signal is confusing. CommittedM tells the CPU's trap unit the current instruction
// in the memory stage is a memory operaton and that memory operation is either completed
// or is partially executed. This signal is only low for the first cycle of a memory
// operation.
// **** I think there is also a bug here. Data cache misses and TLB misses both
// set this bit in the first cycle. It is not strickly wrong, but it may be better
// to flush the memory operation at that time.
assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .DisableTranslation(SelHPTW),
.PAdr(LsuPAdrM),
.VAdr(IEUAdrM),
.Size(LsuFunct3M[1:0]),
.PTE,
.PageTypeWriteVal(PageType),
.TLBWrite(DTLBWriteM),
.TLBFlush(DTLBFlushM),
.PhysicalAddress(MemPAdrM),
.TLBMiss(DTLBMissM),
.Cacheable(CacheableM),
.Idempotent(), .AtomicAllowed(),
.TLBPageFault(DTLBPageFaultM),
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
.AtomicAccessM(1'b0), .ExecuteAccessF(1'b0),
.WriteAccessM(LsuRWM[0]), .ReadAccessM(LsuRWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW
); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist?
generate
if(`ZICSR_SUPPORTED == 1) begin : dmmu
logic DataMisalignedM;
mmu #(.TLB_ENTRIES(`DTLB_ENTRIES), .IMMU(0))
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP,
.PrivilegeModeW, .DisableTranslation(SelHPTW),
.PAdr(PreLsuPAdrM),
.VAdr(IEUAdrM),
.Size(LsuFunct3M[1:0]),
.PTE,
.PageTypeWriteVal(PageType),
.TLBWrite(DTLBWriteM),
.TLBFlush(DTLBFlushM),
.PhysicalAddress(LsuPAdrM),
.TLBMiss(DTLBMissM),
.Cacheable(CacheableM),
.Idempotent(), .AtomicAllowed(),
.TLBPageFault(DTLBPageFaultM),
.InstrAccessFaultF(), .LoadAccessFaultM, .StoreAccessFaultM,
.AtomicAccessM(1'b0), .ExecuteAccessF(1'b0), /// atomicaccessm is probably a bug
.WriteAccessM(PreLsuRWM[0]), .ReadAccessM(PreLsuRWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW
); // *** the pma/pmp instruction access faults don't really matter here. is it possible to parameterize which outputs exist?
// Determine if an Unaligned access is taking place
// hptw guarantees alignment, only check inputs from IEU.
always_comb
case(Funct3M[1:0])
2'b00: DataMisalignedM = 0; // lb, sb, lbu
2'b01: DataMisalignedM = IEUAdrM[0]; // lh, sh, lhu
2'b10: DataMisalignedM = IEUAdrM[1] | IEUAdrM[0]; // lw, sw, flw, fsw, lwu
2'b11: DataMisalignedM = |IEUAdrM[2:0]; // ld, sd, fld, fsd
endcase
// If the CPU's (not HPTW's) request is a page fault.
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
end else begin
assign LsuPAdrM = PreLsuPAdrM;
assign DTLBMissM = 0;
assign CacheableM = 1;
assign DTLBPageFaultM = 0;
assign LoadAccessFaultM = 0;
assign StoreAccessFaultM = 0;
assign LoadMisalignedFaultM = 0;
assign StoreMisalignedFaultM = 0;
end
endgenerate
assign LSUStall = DCacheStall | InterlockStall | BusStall;
// If the CPU's (not HPTW's) request is a page fault.
assign LoadMisalignedFaultM = DataMisalignedM & MemRWM[1];
assign StoreMisalignedFaultM = DataMisalignedM & MemRWM[0];
// Move generate from lrsc to outside this module.
// use PreLsu as prefix for lrsc
generate
if (`A_SUPPORTED) begin
assign MemReadM = LsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .LsuRWM, .LsuAtomicM, .MemPAdrM,
.SquashSCW, .DCRWM);
assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
.SquashSCW, .LsuRWM);
end else begin
assign SquashSCW = 0;
assign DCRWM = LsuRWM;
assign LsuRWM = PreLsuRWM;
end
endgenerate
// Determine if an Unaligned access is taking place
// hptw guarantees alignment, only check inputs from IEU.
always_comb
case(Funct3M[1:0])
2'b00: DataMisalignedM = 0; // lb, sb, lbu
2'b01: DataMisalignedM = IEUAdrM[0]; // lh, sh, lhu
2'b10: DataMisalignedM = IEUAdrM[1] | IEUAdrM[0]; // lw, sw, flw, fsw, lwu
2'b11: DataMisalignedM = |IEUAdrM[2:0]; // ld, sd, fld, fsd
endcase
// conditional
// 1. ram // controlled by `MEM_DTIM
// 2. cache `MEM_DCACHE
// 3. wire pass-through
localparam integer WORDSPERLINE = `DCACHE_BLOCKLENINBITS/`XLEN;
localparam integer WORDSPERLINE = `MEM_DCACHE ? `DCACHE_BLOCKLENINBITS/`XLEN : `XLEN/8;
localparam integer LOGWPL = $clog2(WORDSPERLINE);
localparam integer BLOCKLEN = `DCACHE_BLOCKLENINBITS;
localparam integer WordCountThreshold = WORDSPERLINE - 1;
localparam integer BLOCKLEN = `MEM_DCACHE ? `DCACHE_BLOCKLENINBITS : `XLEN;
localparam integer WordCountThreshold = `MEM_DCACHE ? WORDSPERLINE - 1 : 0;
localparam integer BLOCKBYTELEN = BLOCKLEN/8;
localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN);
// temp
logic WordCountFlag;
logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM;
(* mark_debug = "true" *) logic [`XLEN-1:0] DC_HWDATA_FIXNAME;
logic SelFlush;
(* mark_debug = "true" *) logic [`XLEN-1:0] PreLsuBusHWDATA;
logic [`XLEN-1:0] ReadDataWordM;
logic [`DCACHE_BLOCKLENINBITS-1:0] DCacheMemWriteData;
logic [BLOCKLEN-1:0] DCacheMemWriteData;
// keep
logic [`XLEN-1:0] ReadDataWordMuxM;
logic [LOGWPL-1:0] WordCount, NextWordCount;
logic [`PA_BITS-1:0] BasePAdrMaskedM;
logic [OFFSETLEN-1:0] BasePAdrOffsetM;
logic CntEn, PreCntEn;
logic CntReset;
logic [`PA_BITS-1:0] DCacheBusAdr;
logic [`XLEN-1:0] ReadDataBlockSetsM [(`DCACHE_BLOCKLENINBITS/`XLEN)-1:0];
logic [`XLEN-1:0] ReadDataBlockSetsM [WORDSPERLINE-1:0];
logic DCWriteLine;
logic DCFetchLine;
logic BUSACK;
logic DCacheWriteLine;
logic DCacheFetchLine;
logic DCacheBusAck;
logic UnCachedLsuBusRead;
logic UnCachedLsuBusWrite;
logic SelUncachedAdr;
dcache dcache(.clk, .reset, .CPUBusy,
.MemRWM(DCRWM),
.Funct3M(LsuFunct3M),
.Funct7M, .FlushDCacheM,
.AtomicM(LsuAtomicM),
.MemAdrE(DCAdrE),
.MemPAdrM,
.FinalWriteDataM, .ReadDataWordM, .DCacheStall,
.DCacheMiss, .DCacheAccess, .IgnoreRequest,
.CacheableM(CacheableM),
.DCCommittedM,
.DCacheBusAdr,
.ReadDataBlockSetsM,
.SelFlush,
.DCacheMemWriteData,
.DCFetchLine,
.DCWriteLine,
.BUSACK
);
generate
if(`MEM_DCACHE) begin : dcache
dcache dcache(.clk, .reset, .CPUBusy,
.LsuRWM, .FlushDCacheM, .LsuAtomicM, .LsuAdrE, .LsuPAdrM,
.FinalWriteDataM, .ReadDataWordM, .DCacheStall,
.DCacheMiss, .DCacheAccess,
.IgnoreRequest, .CacheableM, .DCacheCommittedM,
.DCacheBusAdr, .ReadDataBlockSetsM, .DCacheMemWriteData,
.DCacheFetchLine, .DCacheWriteLine,.DCacheBusAck);
end else begin : passthrough
assign ReadDataWordM = 0;
assign DCacheStall = 0;
assign DCacheMiss = 1;
assign DCacheAccess = CacheableM;
assign DCacheCommittedM = 0;
assign DCacheWriteLine = 0;
assign DCacheFetchLine = 0;
assign DCacheBusAdr = 0;
assign ReadDataBlockSetsM[0] = 0;
end
endgenerate
// select between dcache and direct from the BUS. Always selected if no dcache.
mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM),
.d1(DCacheMemWriteData[`XLEN-1:0]),
.s(SelUncachedAdr),
.y(ReadDataWordMuxM));
// sub word selection for read and writes and optional amo alu.
// finally swr
subwordread subwordread(.ReadDataWordMuxM,
.MemPAdrM(MemPAdrM[2:0]),
.LsuPAdrM(LsuPAdrM[2:0]),
.Funct3M(LsuFunct3M),
.ReadDataM);
generate
if (`A_SUPPORTED) begin
if (`A_SUPPORTED) begin : amo
logic [`XLEN-1:0] AMOResult;
amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LsuFunct3M[1:0]),
.result(AMOResult));
@ -405,24 +350,20 @@ module lsu
end else
assign FinalAMOWriteDataM = WriteDataM;
endgenerate
// this might only get instantiated if there is a dcache or dtim.
// There is a copy in the ebu.
subwordwrite subwordwrite(.HRDATA(ReadDataWordM),
.HADDRD(MemPAdrM[2:0]),
.HADDRD(LsuPAdrM[2:0]),
.HSIZED({LsuFunct3M[2], 1'b0, LsuFunct3M[1:0]}),
.HWDATAIN(FinalAMOWriteDataM),
.HWDATA(FinalWriteDataM));
assign LsuBusHWDATA = CacheableM | SelFlush ? DC_HWDATA_FIXNAME : WriteDataM;
generate
if (`XLEN == 32) assign LsuBusSize = UnCachedLsuBusWrite | UnCachedLsuBusRead ? LsuFunct3M : 3'b010;
else assign LsuBusSize = UnCachedLsuBusWrite | UnCachedLsuBusRead ? LsuFunct3M : 3'b011;
endgenerate;
// Bus Side logic
// register the fetch data from the next level of memory.
// This register should be necessary for timing. There is no register in the uncore or
// ahblite controller between the memories and this cache.
logic [LOGWPL-1:0] WordCount;
genvar index;
generate
@ -434,92 +375,20 @@ module lsu
end
endgenerate
//assign LocalLsuBusAdr = SelUncachedAdr ? MemPAdrM : {DCacheBusAdr[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}} ;
assign LocalLsuBusAdr = SelUncachedAdr ? MemPAdrM : DCacheBusAdr ;
assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ;
assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr;
assign DC_HWDATA_FIXNAME = ReadDataBlockSetsM[WordCount];
assign PreLsuBusHWDATA = ReadDataBlockSetsM[WordCount];
assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]);
assign CntEn = PreCntEn & LsuBusAck;
generate
if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010;
else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011;
endgenerate;
flopenr #(LOGWPL)
WordCountReg(.clk(clk),
.reset(reset | CntReset),
.en(CntEn),
.d(NextWordCount),
.q(WordCount));
assign NextWordCount = WordCount + 1'b1;
typedef enum {STATE_BUS_READY,
STATE_BUS_FETCH,
STATE_BUS_WRITE,
STATE_BUS_UNCACHED_WRITE,
STATE_BUS_UNCACHED_WRITE_DONE,
STATE_BUS_UNCACHED_READ,
STATE_BUS_UNCACHED_READ_DONE,
STATE_BUS_CPU_BUSY} busstatetype;
(* mark_debug = "true" *) busstatetype BusCurrState, BusNextState;
always_ff @(posedge clk)
if (reset) BusCurrState <= #1 STATE_BUS_READY;
else BusCurrState <= #1 BusNextState;
always_comb begin
BusNextState = STATE_BUS_READY;
case(BusCurrState)
STATE_BUS_READY: if(IgnoreRequest) BusNextState = STATE_BUS_READY;
else if(DCRWM[0] & ~CacheableM) BusNextState = STATE_BUS_UNCACHED_WRITE;
else if(DCRWM[1] & ~CacheableM) BusNextState = STATE_BUS_UNCACHED_READ;
else if(DCFetchLine) BusNextState = STATE_BUS_FETCH;
else if(DCWriteLine) BusNextState = STATE_BUS_WRITE;
STATE_BUS_UNCACHED_WRITE: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_WRITE_DONE;
else BusNextState = STATE_BUS_UNCACHED_WRITE;
STATE_BUS_UNCACHED_READ: if(LsuBusAck) BusNextState = STATE_BUS_UNCACHED_READ_DONE;
else BusNextState = STATE_BUS_UNCACHED_READ;
STATE_BUS_UNCACHED_WRITE_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY;
STATE_BUS_UNCACHED_READ_DONE: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY;
STATE_BUS_CPU_BUSY: if(CPUBusy) BusNextState = STATE_BUS_CPU_BUSY;
else BusNextState = STATE_BUS_READY;
STATE_BUS_FETCH: if (WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY;
else BusNextState = STATE_BUS_FETCH;
STATE_BUS_WRITE: if(WordCountFlag & LsuBusAck) BusNextState = STATE_BUS_READY;
else BusNextState = STATE_BUS_WRITE;
endcase
end
assign CntReset = BusCurrState == STATE_BUS_READY;
assign BusStall = (BusCurrState == STATE_BUS_READY & ~IgnoreRequest & ((~CacheableM & (|DCRWM)) | DCFetchLine | DCWriteLine)) |
(BusCurrState == STATE_BUS_UNCACHED_WRITE) |
(BusCurrState == STATE_BUS_UNCACHED_READ) |
(BusCurrState == STATE_BUS_FETCH) |
(BusCurrState == STATE_BUS_WRITE);
assign PreCntEn = BusCurrState == STATE_BUS_FETCH | BusCurrState == STATE_BUS_WRITE;
assign UnCachedLsuBusWrite = (BusCurrState == STATE_BUS_READY & ~CacheableM & (DCRWM[0])) |
(BusCurrState == STATE_BUS_UNCACHED_WRITE);
assign LsuBusWrite = UnCachedLsuBusWrite | (BusCurrState == STATE_BUS_WRITE);
assign UnCachedLsuBusRead = (BusCurrState == STATE_BUS_READY & ~CacheableM & (|DCRWM[1])) |
(BusCurrState == STATE_BUS_UNCACHED_READ);
assign LsuBusRead = UnCachedLsuBusRead | (BusCurrState == STATE_BUS_FETCH);
assign BUSACK = (BusCurrState == STATE_BUS_FETCH & WordCountFlag & LsuBusAck) |
(BusCurrState == STATE_BUS_WRITE & WordCountFlag & LsuBusAck);
assign BusCommittedM = BusCurrState != STATE_BUS_READY;
assign SelUncachedAdr = (BusCurrState == STATE_BUS_READY & (|DCRWM & ~CacheableM)) |
(BusCurrState == STATE_BUS_UNCACHED_READ |
BusCurrState == STATE_BUS_UNCACHED_READ_DONE |
BusCurrState == STATE_BUS_UNCACHED_WRITE |
BusCurrState == STATE_BUS_UNCACHED_WRITE_DONE);
busfsm #(WordCountThreshold, LOGWPL)
busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine,
.LsuBusAck, .CPUBusy, .CacheableM, .BusStall, .LsuBusWrite, .LsuBusRead,
.DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);
endmodule

View File

@ -28,7 +28,7 @@
module subwordread
(
input logic [`XLEN-1:0] ReadDataWordMuxM,
input logic [2:0] MemPAdrM,
input logic [2:0] LsuPAdrM,
input logic [2:0] Funct3M,
output logic [`XLEN-1:0] ReadDataM
);
@ -42,7 +42,7 @@ module subwordread
if (`XLEN == 64) begin
// ByteMe mux
always_comb
case(MemPAdrM[2:0])
case(LsuPAdrM[2:0])
3'b000: ByteM = ReadDataWordMuxM[7:0];
3'b001: ByteM = ReadDataWordMuxM[15:8];
3'b010: ByteM = ReadDataWordMuxM[23:16];
@ -55,7 +55,7 @@ module subwordread
// halfword mux
always_comb
case(MemPAdrM[2:1])
case(LsuPAdrM[2:1])
2'b00: HalfwordM = ReadDataWordMuxM[15:0];
2'b01: HalfwordM = ReadDataWordMuxM[31:16];
2'b10: HalfwordM = ReadDataWordMuxM[47:32];
@ -65,7 +65,7 @@ module subwordread
logic [31:0] WordM;
always_comb
case(MemPAdrM[2])
case(LsuPAdrM[2])
1'b0: WordM = ReadDataWordMuxM[31:0];
1'b1: WordM = ReadDataWordMuxM[63:32];
endcase
@ -85,7 +85,7 @@ module subwordread
end else begin // 32-bit
// byte mux
always_comb
case(MemPAdrM[1:0])
case(LsuPAdrM[1:0])
2'b00: ByteM = ReadDataWordMuxM[7:0];
2'b01: ByteM = ReadDataWordMuxM[15:8];
2'b10: ByteM = ReadDataWordMuxM[23:16];
@ -94,7 +94,7 @@ module subwordread
// halfword mux
always_comb
case(MemPAdrM[1])
case(LsuPAdrM[1])
1'b0: HalfwordM = ReadDataWordMuxM[15:0];
1'b1: HalfwordM = ReadDataWordMuxM[31:16];
endcase

View File

@ -119,7 +119,6 @@ module mmu #(parameter TLB_ENTRIES = 8, // number of TLB Entries
pmachecker pmachecker(.*);
pmpchecker pmpchecker(.*);
// If TLB miss and translating we want to not have faults from the PMA and PMP checkers.
// assign SquashBusAccess = PMASquashBusAccess | PMPSquashBusAccess;
assign InstrAccessFaultF = (PMAInstrAccessFaultF | PMPInstrAccessFaultF) & ~(Translate & ~TLBHit);

View File

@ -47,34 +47,37 @@ module pmpchecker (
output logic PMPStoreAccessFaultM
);
generate
if (`PMP_ENTRIES > 0) begin: pmpchecker
// Bit i is high when the address falls in PMP region i
logic EnforcePMP;
logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges
logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address.
logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null
logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
.PhysicalAddress,
.PMPCfg(PMPCFG_ARRAY_REGW),
.PMPAdr(PMPADDR_ARRAY_REGW),
.PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
.PAgePMPAdrOut(PAgePMPAdr),
.FirstMatch, .Match, .Active, .L, .X, .W, .R);
// Bit i is high when the address falls in PMP region i
logic EnforcePMP;
// logic [7:0] PMPCfg[`PMP_ENTRIES-1:0];
logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges
logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address.
logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null
logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
genvar i,j;
priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
.PhysicalAddress,
.PMPCfg(PMPCFG_ARRAY_REGW),
.PMPAdr(PMPADDR_ARRAY_REGW),
.PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
.PAgePMPAdrOut(PAgePMPAdr),
.FirstMatch, .Match, .Active, .L, .X, .W, .R);
priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
// Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active;
assign PMPInstrAccessFaultF = EnforcePMP && ExecuteAccessF && ~|X;
assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM && ~|W;
assign PMPLoadAccessFaultM = EnforcePMP && ReadAccessM && ~|R;
// Only enforce PMP checking for S and U modes when at least one PMP is active or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW == `M_MODE) ? |L : |Active;
assign PMPInstrAccessFaultF = EnforcePMP && ExecuteAccessF && ~|X;
assign PMPStoreAccessFaultM = EnforcePMP && WriteAccessM && ~|W;
assign PMPLoadAccessFaultM = EnforcePMP && ReadAccessM && ~|R;
end else begin: pmpchecker // no checker
assign PMPInstrAccessFaultF = 0;
assign PMPLoadAccessFaultM = 0;
assign PMPStoreAccessFaultM = 0;
end
endgenerate
//assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
endmodule

View File

@ -89,9 +89,35 @@ module csrm #(parameter
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
logic [`PMP_ENTRIES-1:0] WritePMPCFGM;
logic [`PMP_ENTRIES-1:0] WritePMPADDRM ;
logic [`PMP_ENTRIES-1:0] ADDRLocked, CFGLocked;
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
genvar i;
generate
if (`PMP_ENTRIES > 0) begin:pmp
logic [`PMP_ENTRIES-1:0] WritePMPCFGM;
logic [`PMP_ENTRIES-1:0] WritePMPADDRM ;
logic [`PMP_ENTRIES-1:0] ADDRLocked, CFGLocked;
for(i=0; i<`PMP_ENTRIES; i++) begin
// when the lock bit is set, don't allow writes to the PMPCFG or PMPADDR
// also, when the lock bit of the next entry is set and the next entry is TOR, don't allow writes to this entry PMPADDR
assign CFGLocked[i] = PMPCFG_ARRAY_REGW[i][7];
if (i == `PMP_ENTRIES-1)
assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7];
else
assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7] | (PMPCFG_ARRAY_REGW[i+1][7] & PMPCFG_ARRAY_REGW[i+1][4:3] == 2'b01);
assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & ~StallW & ~ADDRLocked[i];
flopenr #(`XLEN) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM, PMPADDR_ARRAY_REGW[i]);
if (`XLEN==64) begin
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & ~StallW & ~CFGLocked[i];
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%8)*8+7:(i%8)*8], PMPCFG_ARRAY_REGW[i]);
end else begin
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & ~StallW & ~CFGLocked[i];
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%4)*8+7:(i%4)*8], PMPCFG_ARRAY_REGW[i]);
end
end
end
endgenerate
localparam MISA_26 = (`MISA) & 32'h03ffffff;
@ -118,7 +144,7 @@ module csrm #(parameter
// CSRs
flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); //busybear: changed reset value to 0
generate
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin // DELEG registers should exist
if (`S_SUPPORTED | (`U_SUPPORTED & `N_SUPPORTED)) begin:deleg // DELEG registers should exist
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);
end else begin
@ -132,43 +158,15 @@ module csrm #(parameter
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
if(`QEMU) assign MTVAL_REGW = `XLEN'b0;
else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
generate
if (`BUSYBEAR == 1)
generate // *** needs comment about bit 1
if (`BUSYBEAR == 1) begin:counters
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, MCOUNTEREN_REGW);
else if (`BUILDROOT == 1)
end else begin:counters
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
else
flopens #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
end
endgenerate
flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW);
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
// *** need to add support for locked PMPCFG and PMPADR
genvar i;
generate
for(i=0; i<`PMP_ENTRIES; i++) begin
// when the lock bit is set, don't allow writes to the PMPCFG or PMPADDR
// also, when the lock bit of the next entry is set and the next entry is TOR, don't allow writes to this entry PMPADDR
assign CFGLocked[i] = PMPCFG_ARRAY_REGW[i][7];
if (i == `PMP_ENTRIES-1)
assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7];
else
assign ADDRLocked[i] = PMPCFG_ARRAY_REGW[i][7] | (PMPCFG_ARRAY_REGW[i+1][7] & PMPCFG_ARRAY_REGW[i+1][4:3] == 2'b01);
assign WritePMPADDRM[i] = (CSRMWriteM & (CSRAdrM == (PMPADDR0+i))) & ~StallW & ~ADDRLocked[i];
flopenr #(`XLEN) PMPADDRreg(clk, reset, WritePMPADDRM[i], CSRWriteValM, PMPADDR_ARRAY_REGW[i]);
if (`XLEN==64) begin
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+2*(i/8)))) & ~StallW & ~CFGLocked[i];
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%8)*8+7:(i%8)*8], PMPCFG_ARRAY_REGW[i]);
end else begin
assign WritePMPCFGM[i] = (CSRMWriteM & (CSRAdrM == (PMPCFG0+i/4))) & ~StallW & ~CFGLocked[i];
// assign WritePMPCFGHM[i] = (CSRMWriteM && (CSRAdrM == PMPCFG0+2*i+1)) && ~StallW;
flopenr #(8) PMPCFGreg(clk, reset, WritePMPCFGM[i], CSRWriteValM[(i%4)*8+7:(i%4)*8], PMPCFG_ARRAY_REGW[i]);
// flopenr #(`XLEN) PMPCFGHreg(clk, reset, WritePMPCFGHM[i], CSRWriteValM, PMPCFG_ARRAY_REGW[i][63:32]);
end
end
endgenerate
// Read machine mode CSRs
// verilator lint_off WIDTH
@ -188,10 +186,6 @@ module csrm #(parameter
entry = (CSRAdrM - PMPCFG0)*4;
CSRMReadValM = {PMPCFG_ARRAY_REGW[entry+3],PMPCFG_ARRAY_REGW[entry+2],PMPCFG_ARRAY_REGW[entry+1],PMPCFG_ARRAY_REGW[entry]};
end
/*
if (~CSRAdrM[0]) CSRMReadValM = {PMPCFG_ARRAY_REGW[]};
else CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG_ARRAY_REGW[(CSRAdrM - PMPCFG0-1)/2][63:32]};*/
end
else case (CSRAdrM)
MISA_ADR: CSRMReadValM = MISA_REGW;
@ -202,8 +196,6 @@ module csrm #(parameter
MSTATUS: CSRMReadValM = MSTATUS_REGW;
MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported
MTVEC: CSRMReadValM = MTVEC_REGW;
//MEDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MEDELEG_REGW};
//MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW};
MEDELEG: CSRMReadValM = MEDELEG_REGW;
MIDELEG: CSRMReadValM = MIDELEG_REGW;
MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW};

View File

@ -79,7 +79,7 @@ module SDC
logic SDCDataValid;
logic [`XLEN-1:0] SDCReadData;
logic [`XLEN-1:0] SDCReadDataPreNibbleSwap;
logic [`XLEN-1:0] SDCReadDataPreNibbleSwap;
logic [`XLEN-1:0] SDCWriteData;
logic FatalError;
@ -208,15 +208,23 @@ module SDC
end
assign SDCReadDataPreNibbleSwap = ReadData512ByteWords[WordCount];
assign SDCReadData = {SDCReadDataPreNibbleSwap[59:56], SDCReadDataPreNibbleSwap[63:60],
SDCReadDataPreNibbleSwap[51:48], SDCReadDataPreNibbleSwap[55:52],
SDCReadDataPreNibbleSwap[43:40], SDCReadDataPreNibbleSwap[47:44],
SDCReadDataPreNibbleSwap[35:32], SDCReadDataPreNibbleSwap[39:36],
SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
generate
if(`XLEN == 64) begin
assign SDCReadData = {SDCReadDataPreNibbleSwap[59:56], SDCReadDataPreNibbleSwap[63:60],
SDCReadDataPreNibbleSwap[51:48], SDCReadDataPreNibbleSwap[55:52],
SDCReadDataPreNibbleSwap[43:40], SDCReadDataPreNibbleSwap[47:44],
SDCReadDataPreNibbleSwap[35:32], SDCReadDataPreNibbleSwap[39:36],
SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
end else begin
assign SDCReadData = {SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
end
endgenerate
flopenr #($clog2(4096/`XLEN)) WordCountReg
(.clk(HCLK),

View File

@ -271,7 +271,7 @@ module sd_cmd_fsm
assign o_ERROR_CODE_Q = r_ERROR_CODE_Q;
assign COUNTER_OUT_GT_ZERO = i_COUNTER_OUT > 0;
assign COUNTER_OUT_GE_ZERO = i_COUNTER_OUT >= 0;
assign COUNTER_OUT_GE_ZERO = $signed(i_COUNTER_OUT) >= $signed(8'b0);
assign COUNTER_OUT_GT_8 = i_COUNTER_OUT > 8;
assign COUNTER_OUT_EQ_8 = i_COUNTER_OUT == 8;
assign COUNTER_OUT_EQ_ZERO = i_COUNTER_OUT == 0;

View File

@ -128,10 +128,10 @@ module wallypipelinedhart (
logic CommittedM;
// AHB ifu interface
logic [`PA_BITS-1:0] InstrPAdrF;
logic [`XLEN-1:0] InstrRData;
logic InstrReadF;
logic InstrAckF;
logic [`PA_BITS-1:0] ICacheBusAdr;
logic [`XLEN-1:0] IfuBusHRDATA;
logic IfuBusFetch;
logic ICacheBusAck;
// AHB LSU interface
logic [`PA_BITS-1:0] LsuBusAdr;
@ -164,8 +164,8 @@ module wallypipelinedhart (
.ExceptionM, .PendingInterruptM,
// Fetch
.InstrInF(InstrRData), .InstrAckF, .PCF, .InstrPAdrF,
.InstrReadF, .ICacheStallF,
.IfuBusHRDATA, .ICacheBusAck, .PCF, .ICacheBusAdr,
.IfuBusFetch, .ICacheStallF,
// Execute
.PCLinkE, .PCSrcE, .IEUAdrE, .PCE,
@ -277,8 +277,8 @@ module wallypipelinedhart (
ahblite ebu(// IFU connections
.clk, .reset,
.UnsignedLoadM(1'b0), .AtomicMaskedM(2'b00),
.InstrPAdrF, // *** rename these to match block diagram
.InstrReadF, .InstrRData, .InstrAckF,
.ICacheBusAdr, // *** rename these to match block diagram
.IfuBusFetch, .IfuBusHRDATA, .ICacheBusAck,
// Signals from Data Cache
.LsuBusAdr, .LsuBusRead, .LsuBusWrite, .LsuBusHWDATA,
.LsuBusHRDATA,

View File

@ -49,6 +49,7 @@ module testbench();
////////////////////////////////// HARDWARE ///////////////////////////////////
///////////////////////////////////////////////////////////////////////////////
logic clk, reset_ext;
logic reset;
initial begin reset_ext <= 1; # 22; reset_ext <= 0; end
always begin clk <= 1; # 5; clk <= 0; # 5; end
@ -77,7 +78,7 @@ module testbench();
assign GPIOPinsIn = 0;
assign UARTSin = 1;
wallypipelinedsoc dut(.clk, .reset_ext,
wallypipelinedsoc dut(.clk, .reset, .reset_ext,
.HRDATAEXT, .HREADYEXT, .HREADY, .HSELEXT, .HRESPEXT, .HCLK,
.HRESETn, .HADDR, .HWDATA, .HWRITE, .HSIZE, .HBURST, .HPROT,
.HTRANS, .HMASTLOCK,
@ -85,8 +86,6 @@ module testbench();
.UARTSin, .UARTSout,
.SDCCLK, .SDCCmdIn, .SDCCmdOut, .SDCCmdOE, .SDCDatIn);
logic reset;
assign reset = dut.reset;
// Write Back stage signals not needed by Wally itself
parameter nop = 'h13;
@ -176,18 +175,18 @@ module testbench();
`define PC dut.hart.ifu.pcreg.q
`define CSR_BASE dut.hart.priv.priv.csr
`define HPMCOUNTER `CSR_BASE.counters.genblk1.HPMCOUNTER_REGW
`define PMP_BASE `CSR_BASE.csrm.genblk4
`define PMP_BASE `CSR_BASE.csrm.pmp
`define PMPCFG genblk2.PMPCFGreg.q
`define PMPADDR PMPADDRreg.q
`define MEDELEG `CSR_BASE.csrm.genblk1.MEDELEGreg.q
`define MIDELEG `CSR_BASE.csrm.genblk1.MIDELEGreg.q
`define MEDELEG `CSR_BASE.csrm.deleg.MEDELEGreg.q
`define MIDELEG `CSR_BASE.csrm.deleg.MIDELEGreg.q
`define MIE `CSR_BASE.csri.MIE_REGW
`define MIP `CSR_BASE.csri.MIP_REGW
`define MCAUSE `CSR_BASE.csrm.MCAUSEreg.q
`define SCAUSE `CSR_BASE.csrs.genblk1.SCAUSEreg.q
`define MEPC `CSR_BASE.csrm.MEPCreg.q
`define SEPC `CSR_BASE.csrs.genblk1.SEPCreg.q
`define MCOUNTEREN `CSR_BASE.csrm.genblk3.MCOUNTERENreg.q
`define MCOUNTEREN `CSR_BASE.csrm.counters.MCOUNTERENreg.q
`define SCOUNTEREN `CSR_BASE.csrs.genblk1.genblk2.SCOUNTERENreg.q
`define MSCRATCH `CSR_BASE.csrm.MSCRATCHreg.q
`define SSCRATCH `CSR_BASE.csrs.genblk1.SSCRATCHreg.q
@ -446,7 +445,7 @@ module testbench();
end \
if(`"STAGE`"=="M") begin \
// override on special conditions \
if (dut.hart.lsu.MemPAdrM == 'h10000005) \
if (dut.hart.lsu.LsuPAdrM == 'h10000005) \
//$display("%tns, %d instrs: Overwrite UART's LSR in memory stage.", $time, InstrCountW-1); \
force dut.hart.ieu.dp.ReadDataM = ExpectedMemReadDataM; \
else \

View File

@ -76,12 +76,14 @@ logic [3:0] dummy;
// pick tests based on modes supported
initial begin
$display("TEST is %s", TEST);
tests = '{};
//tests = '{};
if (`XLEN == 64) begin // RV64
case (TEST)
"arch64i": tests = arch64i;
"arch64priv": tests = arch64priv;
"arch64c": if (`C_SUPPORTED) tests = arch64c;
"arch64c": if (`C_SUPPORTED)
if (`ZICSR_SUPPORTED) tests = {arch64c, arch64cpriv};
else tests = {arch64c};
"arch64m": if (`M_SUPPORTED) tests = arch64m;
"arch64d": if (`D_SUPPORTED) tests = arch64d;
"imperas64i": tests = imperas64i;
@ -102,7 +104,9 @@ logic [3:0] dummy;
case (TEST)
"arch32i": tests = arch32i;
"arch32priv": tests = arch32priv;
"arch32c": if (`C_SUPPORTED) tests = arch32c;
"arch32c": if (`C_SUPPORTED)
if (`ZICSR_SUPPORTED) tests = {arch32c, arch32cpriv};
else tests = {arch32c};
"arch32m": if (`M_SUPPORTED) tests = arch32m;
"arch32f": if (`F_SUPPORTED) tests = arch32f;
"imperas32i": tests = imperas32i;
@ -239,6 +243,7 @@ logic [3:0] dummy;
/* verilator lint_off INFINITELOOP */
while (signature[i] !== 'bx) begin
//$display("signature[%h] = %h", i, signature[i]);
// *** have to figure out how to exclude shadowram when not using a dcache.
if (signature[i] !== dut.uncore.ram.ram.RAM[testadr+i] &&
(signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin
if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) begin
@ -291,17 +296,26 @@ logic [3:0] dummy;
// or sw gp,-56(t0) for new Imperas tests
// or sw gp, -56(t0)
// or on a jump to self infinite loop (6f) for RISC-V Arch tests
assign DCacheFlushStart = dut.hart.priv.priv.EcallFaultM &&
logic ecf; // remove this once we don't rely on old Imperas tests with Ecalls
generate
if (`ZICSR_SUPPORTED) begin
assign ecf = dut.hart.priv.priv.EcallFaultM;
end else begin
assign ecf = 0;
end
endgenerate
assign DCacheFlushStart = ecf &&
(dut.hart.ieu.dp.regf.rf[3] == 1 ||
(dut.hart.ieu.dp.regf.we3 &&
dut.hart.ieu.dp.regf.a3 == 3 &&
dut.hart.ieu.dp.regf.wd3 == 1)) ||
(dut.hart.ifu.InstrM == 32'h6f || dut.hart.ifu.InstrM == 32'hfc32a423 || dut.hart.ifu.InstrM == 32'hfc32a823) && dut.hart.ieu.c.InstrValidM;
// **** Fix when the check in the shadow ram is fixed.
DCacheFlushFSM DCacheFlushFSM(.clk(clk),
.reset(reset),
.start(DCacheFlushStart),
.done(DCacheFlushDone));
.reset(reset),
.start(DCacheFlushStart),
.done(DCacheFlushDone));
generate
@ -330,13 +344,14 @@ module riscvassertions;
assert (`ICACHE_WAYSIZEINBYTES <= 4096 || `MEM_ICACHE == 0 || `MEM_VIRTMEM == 0) else $error("ICACHE_WAYSIZEINBYTES cannot exceed 4 KiB when caches and vitual memory is enabled (to prevent aliasing)");
assert (`ICACHE_BLOCKLENINBITS >= 32 || `MEM_ICACHE == 0) else $error("ICACHE_BLOCKLENINBITS must be at least 32 when caches are enabled");
assert (`ICACHE_BLOCKLENINBITS < `ICACHE_WAYSIZEINBYTES*8) else $error("ICACHE_BLOCKLENINBITS must be smaller than way size");
assert (2**$clog2(`DCACHE_BLOCKLENINBITS) == `DCACHE_BLOCKLENINBITS) else $error("DCACHE_BLOCKLENINBITS must be a power of 2");
assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2");
assert (2**$clog2(`ICACHE_BLOCKLENINBITS) == `ICACHE_BLOCKLENINBITS) else $error("ICACHE_BLOCKLENINBITS must be a power of 2");
assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2");
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES) else $error("ITLB_ENTRIES must be a power of 2");
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES) else $error("DTLB_ENTRIES must be a power of 2");
assert (2**$clog2(`DCACHE_BLOCKLENINBITS) == `DCACHE_BLOCKLENINBITS || `MEM_DCACHE==0) else $error("DCACHE_BLOCKLENINBITS must be a power of 2");
assert (2**$clog2(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES || `MEM_DCACHE==0) else $error("DCACHE_WAYSIZEINBYTES must be a power of 2");
assert (2**$clog2(`ICACHE_BLOCKLENINBITS) == `ICACHE_BLOCKLENINBITS || `MEM_ICACHE==0) else $error("ICACHE_BLOCKLENINBITS must be a power of 2");
assert (2**$clog2(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES || `MEM_ICACHE==0) else $error("ICACHE_WAYSIZEINBYTES must be a power of 2");
assert (2**$clog2(`ITLB_ENTRIES) == `ITLB_ENTRIES || `MEM_VIRTMEM==0) else $error("ITLB_ENTRIES must be a power of 2");
assert (2**$clog2(`DTLB_ENTRIES) == `DTLB_ENTRIES || `MEM_VIRTMEM==0) else $error("DTLB_ENTRIES must be a power of 2");
assert (`RAM_RANGE >= 56'h07FFFFFF) else $warning("Some regression tests will fail if RAM_RANGE is less than 56'h07FFFFFF");
assert (`ZICSR_SUPPORTED == 1 || (`PMP_ENTRIES == 0 && `MEM_VIRTMEM == 0)) else $error("PMP_ENTRIES and MEM_VIRTMEM must be zero if ZICSR not supported.");
end
endmodule
@ -350,10 +365,10 @@ module DCacheFlushFSM
input logic start,
output logic done);
localparam integer numlines = testbench.dut.hart.lsu.dcache.NUMLINES;
localparam integer numways = testbench.dut.hart.lsu.dcache.NUMWAYS;
localparam integer blockbytelen = testbench.dut.hart.lsu.dcache.BLOCKBYTELEN;
localparam integer numwords = testbench.dut.hart.lsu.dcache.BLOCKLEN/`XLEN;
localparam integer numlines = testbench.dut.hart.lsu.dcache.dcache.NUMLINES;
localparam integer numways = testbench.dut.hart.lsu.dcache.dcache.NUMWAYS;
localparam integer blockbytelen = testbench.dut.hart.lsu.dcache.dcache.BLOCKBYTELEN;
localparam integer numwords = testbench.dut.hart.lsu.dcache.dcache.BLOCKLEN/`XLEN;
localparam integer lognumlines = $clog2(numlines);
localparam integer logblockbytelen = $clog2(blockbytelen);
localparam integer lognumways = $clog2(numways);
@ -379,10 +394,10 @@ module DCacheFlushFSM
.logblockbytelen(logblockbytelen))
copyShadow(.clk,
.start,
.tag(testbench.dut.hart.lsu.dcache.MemWay[way].CacheTagMem.StoredData[index]),
.valid(testbench.dut.hart.lsu.dcache.MemWay[way].ValidBits[index]),
.dirty(testbench.dut.hart.lsu.dcache.MemWay[way].DirtyBits[index]),
.data(testbench.dut.hart.lsu.dcache.MemWay[way].word[cacheWord].CacheDataMem.StoredData[index]),
.tag(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].CacheTagMem.StoredData[index]),
.valid(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].ValidBits[index]),
.dirty(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].DirtyBits[index]),
.data(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].word[cacheWord].CacheDataMem.StoredData[index]),
.index(index),
.cacheWord(cacheWord),
.CacheData(CacheData[way][index][cacheWord]),

View File

@ -26,7 +26,8 @@
`define IMPERASTEST "0"
`define RISCVARCHTEST "1"
`define WALLYTEST "2"
`define MYIMPERASTEST "3"
`define MYIMPERASTEST "3"
// *** remove MYIMPERASTEST cases when ported
string tvpaths[] = '{
"../../addins/imperas-riscv-tests/work/",
@ -958,7 +959,6 @@ string imperas32f[] = '{
"rv64i_m/C/candi-01", "4010",
"rv64i_m/C/cbeqz-01", "4010",
"rv64i_m/C/cbnez-01", "5010",
"rv64i_m/C/cebreak-01", "2070",
"rv64i_m/C/cj-01", "3010",
"rv64i_m/C/cjalr-01", "2010",
"rv64i_m/C/cjr-01", "2010",
@ -983,6 +983,11 @@ string imperas32f[] = '{
"rv64i_m/C/cxor-01", "8010"
};
string arch64cpriv[] = '{
// `RISCVARCHTEST,
"rv64i_m/C/cebreak-01", "2070"
};
string arch64i[] = '{
`RISCVARCHTEST,
"rv64i_m/I/add-01", "9010",
@ -1405,7 +1410,6 @@ string imperas32f[] = '{
"rv32i_m/C/candi-01", "3010",
"rv32i_m/C/cbeqz-01", "3010",
"rv32i_m/C/cbnez-01", "3010",
"rv32i_m/C/cebreak-01", "2050",
"rv32i_m/C/cj-01", "3010",
"rv32i_m/C/cjal-01", "3010",
"rv32i_m/C/cjalr-01", "2010",
@ -1426,6 +1430,12 @@ string imperas32f[] = '{
"rv32i_m/C/cxor-01", "4010"
};
string arch32cpriv[] = '{
// `RISCVARCHTEST,
"rv32i_m/C/cebreak-01", "2050"
};
string arch32i[] = '{
`RISCVARCHTEST,
"rv32i_m/I/add-01", "5010",
@ -1475,7 +1485,11 @@ string imperas32f[] = '{
};
string wally64priv[] = '{
`WALLYTEST
`WALLYTEST,
"rv64i_m/privilege/WALLY-MMU-SV39", "30A0",
"rv64i_m/privilege/WALLY-MMU-SV48", "30A0",
"rv64i_m/privilege/WALLY-PMA", "30A0",
"rv64i_m/privilege/WALLY-PMP", "30A0"
};
string wally64periph[] = '{
@ -1488,7 +1502,10 @@ string wally32i[] = '{
};
string wally32priv[] = '{
`WALLYTEST
`WALLYTEST,
"rv32i_m/privilege/WALLY-MMU-SV32", "3080",
"rv32i_m/privilege/WALLY-PMA", "3080",
"rv32i_m/privilege/WALLY-PMP", "3080"
};
string wally32periph[] = '{