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

1
.gitmodules vendored
View File

@ -4,6 +4,7 @@
[submodule "addins/riscv-arch-test"] [submodule "addins/riscv-arch-test"]
path = addins/riscv-arch-test path = addins/riscv-arch-test
url = https://github.com/riscv-non-isa/riscv-arch-test url = https://github.com/riscv-non-isa/riscv-arch-test
ignore = dirty
[submodule "addins/imperas-riscv-tests"] [submodule "addins/imperas-riscv-tests"]
path = addins/imperas-riscv-tests path = addins/imperas-riscv-tests
url = https://github.com/riscv-ovpsim/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 # test 12.3.1.1.1 write page tables / entries to phyiscal memory
# sv32 Page table (See Figure 12.12***): # sv32 Page table (See Figure 12.12***):
# Level 1 page table, situated at 0x8000D000 # 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 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 0x8000D00C, 0x000800C7, 0x0 # Vaddr 0xC00000: misaligned megapage
.4byte 0x8000D800, 0x200000CF, 0x0 # Vaddr 0x80000000 Paddr 0x80000000: aligned megapage (program and data memory) .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) .4byte 0x8000D804, 0x200000DF, 0x0 # Vaddr 0x80400000 Paddr 0x80000000: aligned megapage, U=1 (aliased with program and data memory)
# Level 0 page table A # 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 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 0x80013008, 0x202010D5, 0x0 # Vaddr 0x2000: pad PTE has W but not R
.4byte 0x8001300C, 0x20200817, 0x0 # Vaddr 0x3000: A=0, should cause read fault .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. // OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
/////////////////////////////////////////// ///////////////////////////////////////////
#include "riscv_test_macros.h" #include "model_test.h"
#include "compliance_test.h" #include "arch_test.h"
#include "compliance_io.h" RVTEST_ISA("RV32I")
RV_COMPLIANCE_RV64M .section .text.init
.globl rvtest_entry_point
RV_COMPLIANCE_CODE_BEGIN rvtest_entry_point:
RVMODEL_BOOT
RVTEST_CODE_BEGIN
RVTEST_IO_INIT
RVTEST_IO_ASSERT_GPR_EQ(x31, x0, 0x00000000)
RVTEST_IO_WRITE_STR(x31, "Test Begin\n")
# --------------------------------------------------------------------------------------------- # ---------------------------------------------------------------------------------------------
@ -624,18 +621,15 @@ terminate_test:
ecall # writes mcause to the output. ecall # writes mcause to the output.
csrw mtvec, x4 # restore original trap handler to halt program csrw mtvec, x4 # restore original trap handler to halt program
# ---------------------------------------------------------------------------------------------
RVTEST_IO_WRITE_STR(x31, "Test End\n") RVTEST_CODE_END
RVMODEL_HALT
# --------------------------------------------------------------------------------------------- RVTEST_DATA_BEGIN
.align 4
RV_COMPLIANCE_HALT rvtest_data:
.word 0xbabecafe
RV_COMPLIANCE_CODE_END RVTEST_DATA_END
# Input data section.
.data
.align 2 # align stack to 4 byte boundary .align 2 # align stack to 4 byte boundary
bottom_of_stack: bottom_of_stack:
@ -643,15 +637,29 @@ bottom_of_stack:
top_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: test_1_res:
.fill 1024, 4, -1 .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 .align 2
test_cases: 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

@ -33,6 +33,7 @@ rv64i_sc_tests = \
WALLY-PMA \ WALLY-PMA \
WALLY-PMP WALLY-PMP
rv64i_tests = $(addsuffix .elf, $(rv64i_sc_tests)) rv64i_tests = $(addsuffix .elf, $(rv64i_sc_tests))
target_tests += $(rv64i_tests) target_tests += $(rv64i_tests)

View File

@ -47,22 +47,22 @@ test_contents:
# test 12.3.1.1.1 write page tables / entries to phyiscal memory # test 12.3.1.1.1 write page tables / entries to phyiscal memory
# sv39 page table (See Figure 12.12***): # sv39 page table (See Figure 12.12***):
# Level 2 page table, situated at 0x8000D000 # Level 2 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004CC1, 0x0 # points to level 1 page table A .8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 1 page table A
.8byte 0x000000008000D008, 0x00000000200050C1, 0x0 # points to level 1 page table B .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 0x000000008000D010, 0x00000000200000CF, 0x0 # Vaddr 0x8000_0000, Paddr 0x80000000: aligned gigapage (program and data memory)
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0xC000_0000: misaligned gigapage .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 # 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 # Level 1 page table B
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x4000_0000, Paddr 0x80000000: aligned megapage, W=0, used for execution tests .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 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 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 .8byte 0x0000000080014018, 0x00000000210800C9, 0x0 # Vaddr 0x4060_0000, Paddr 0x84200000: R=0, reads should fault
# Level 1 page table C # 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 # 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 0x0000000080018008, 0x00000000200800DF, 0x0 # Vaddr 0x1000, Paddr = 0x80200000: aligned kilopage
.8byte 0x0000000080018010, 0x00000000200810D5, 0x0 # Vaddr 0x2000: bad PTE has W but not R .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 .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 # test 12.3.1.1.1 write page tables / entries to phyiscal memory
# sv48 page table (See Figure 12.12***): # sv48 page table (See Figure 12.12***):
# Level 3 page table, situated at 0x8000D000 # Level 3 page table, situated at 0x8000D000
.8byte 0x000000008000D000, 0x0000000020004CC1, 0x0 # points to level 2 page table A .8byte 0x000000008000D000, 0x0000000020004C01, 0x0 # points to level 2 page table A
.8byte 0x000000008000D008, 0x00000000200050C1, 0x0 # points to level 2 page table B .8byte 0x000000008000D008, 0x0000000020005001, 0x0 # points to level 2 page table B
.8byte 0x000000008000D010, 0x00000000000000C7, 0x0 # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage .8byte 0x000000008000D010, 0x00000000000000C7, 0x0 # Vaddr 0x010000000000, Paddr 0x00000000: aligned terapage
.8byte 0x000000008000D018, 0x00004000004000C7, 0x0 # Vaddr 0x018000000000, misaligned 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 # 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 # Level 2 page table B
.8byte 0x0000000080014000, 0x00000000200000CB, 0x0 # Vaddr 0x008000000000, Paddr 0x80000000: aligned gigapage used for execution tests .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 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 .8byte 0x0000000080014010, 0x00000400080000C3, 0x0 # Vaddr 0x008080000000, misaligned gigapage
# Level 2 page table C # 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 # Level 1 page table A
.8byte 0x0000000080018000, 0x00000000200000CF, 0x0 # Vaddr 0x80000000, Paddr 0x80000000: aligned megapage (data and instr memory) .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 0x0000000080018010, 0x000000C0000400CF, 0x0 # Vaddr 0x80400000, misaligned megapage
.8byte 0x0000000080018018, 0x00000000214800C9, 0x0 # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0 .8byte 0x0000000080018018, 0x00000000214800C9, 0x0 # Vaddr 0x80600000, Paddr 0x85200000: aligned megapage, R=0
# Level 1 page table B # 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 # 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 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 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 .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. ecall # writes mcause to the output.
csrw mtvec, x4 # restore original trap handler to halt program csrw mtvec, x4 # restore original trap handler to halt program
/*
# ---------------------------------------------------------------------------------------------
RVTEST_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 RVTEST_CODE_END
RVMODEL_HALT RVMODEL_HALT
@ -678,37 +644,13 @@ bottom_of_stack:
top_of_stack: top_of_stack:
RVMODEL_DATA_BEGIN RVMODEL_DATA_BEGIN
// next lines through test cases copied over from old framework
test_1_res: test_1_res:
.fill 1024, 4, -1 .fill 1024, 4, -1
RVMODEL_DATA_END 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 #ifdef rvtest_mtrap_routine
mtrap_sigptr: mtrap_sigptr:

View File

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

View File

@ -5,7 +5,7 @@ export PATH=$PATH:/usr/local/bin/
verilator=`which verilator` verilator=`which verilator`
basepath=$(dirname $0)/.. basepath=$(dirname $0)/..
for config in rv64gc rv32gc; do for config in rv64gc rv32gc rv32ic; do
echo "$config linting..." 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 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" 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 /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/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/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/HCLK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESETn add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESETn
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRDATA 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/HADDRD
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED 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/amo/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/amo/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/amo/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/amo/amoalu/srcb
add wave -noupdate -group AMO_ALU /testbench/dut/hart/lsu/dcache/genblk3/amoalu/width 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/CurrState 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/SelHPTW
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/InterlockStall 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/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 -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/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/SRAMWordWriteEnableM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/dcache/SRAMWayWriteEnable 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/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/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/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/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/IEUAdrM
add wave -noupdate -expand -group lsu -group dcache /testbench/dut/hart/lsu/MemAdrE_RENAME 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/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/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/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/DCacheBusAdr
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/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 -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/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/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/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]/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]/SetValid}
add wave -noupdate -expand -group lsu -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetDirty} 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/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/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/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/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/VictimWay
add wave -noupdate -expand -group lsu -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirtyWay 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/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/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/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/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/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/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/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/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/FinalWriteDataM
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/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 -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 /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 -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 -group status /testbench/dut/hart/lsu/WordCount
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/DCacheBusAdr
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/DCacheFetchLine
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/DCacheWriteLine
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/DCacheBusAck
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/ReadDataBlockSetsM
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 -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 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/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/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/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/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/dmmu/TLBHit
add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/PhysicalAddress 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/TLBPageFault 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/LoadAccessFaultM 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/StoreAccessFaultM 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/genblk1/tlb/TLBPAdr 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/genblk1/tlb/PTE 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/genblk1/tlb/TLBWrite 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/pmachecker/PhysicalAddress 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/pmachecker/SelRegions 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/Cacheable 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/Idempotent 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/AtomicAllowed 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/pmachecker/PMAAccessFault 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/PMAInstrAccessFaultF 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/PMALoadAccessFaultM 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/PMAStoreAccessFaultM 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/pmpchecker/PhysicalAddress 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/pmpchecker/ReadAccessM 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/pmpchecker/WriteAccessM 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/pmpchecker/PMPADDR_ARRAY_REGW 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/pmpchecker/PMPCFG_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/PMPInstrAccessFaultF 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/PMPLoadAccessFaultM 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/PMPStoreAccessFaultM 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/pmpchecker/Match 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/pmpchecker/FirstMatch 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/pmpchecker/R 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/pmpchecker/W 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/pmpchecker/X 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/pmpchecker/L 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/hptw/genblk1/WalkerState 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/hptw/PCF 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/hptw/genblk1/TranslationVAdr 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/hptw/HPTWReadPTE 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/hptw/HPTWAdr 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/hptw/PTE 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/hptw/ITLBMissF 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/hptw/DTLBMissM 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/hptw/ITLBWriteF 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/hptw/DTLBWriteM 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 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 itlb /testbench/dut/hart/ifu/immu/TLBWrite 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/ITLBMissF
add wave -noupdate -expand -group itlb /testbench/dut/hart/ifu/immu/PhysicalAddress 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/BranchTakenE
add wave -noupdate /testbench/dut/hart/ieu/c/BranchE add wave -noupdate /testbench/dut/hart/ieu/c/BranchE
add wave -noupdate /testbench/dut/hart/ifu/PCLinkE 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/hart/ifu/PCF
add wave -noupdate /testbench/dut/uncore/uart/uart/u/LSR add wave -noupdate /testbench/dut/uncore/uart/uart/u/LSR
add wave -noupdate /testbench/dut/uncore/uart/uart/u/DLM add wave -noupdate /testbench/dut/uncore/uart/uart/u/DLM

View File

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

View File

@ -1,3 +1,3 @@
vsim -c <<! 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/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/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 {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/controller/IfuBusFetch
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/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/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/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/controller/ICacheMemWriteEnable
add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/ICacheMemWriteData 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 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 -color Gold /testbench/dut/hart/ebu/BusState
add wave -noupdate -group AHB /testbench/dut/hart/ebu/NextBusState 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/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 -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/HCLK
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HRESETn 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/HADDRD
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED
add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED 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/SelHPTW
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/InterlockStall 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/LSUStall
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/ReadDataWordMuxM 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/ReadDataM
add wave -noupdate -expand -group lsu /testbench/dut/hart/lsu/WriteDataM 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 /testbench/dut/hart/lsu/SelUncachedAdr
add wave -noupdate -expand -group lsu -expand -group bus -color Gold /testbench/dut/hart/lsu/BusCurrState 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 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 bus /testbench/dut/hart/lsu/LsuBusRead
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/WayHit add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusWrite
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWriteEnableM add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusAdr
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordWriteEnableM add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusAck
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWayWriteEnable add wave -noupdate -expand -group lsu -expand -group bus /testbench/dut/hart/lsu/LsuBusHWDATA
add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordEnable 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/SRAMBlockWayWriteEnableM 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/SelAdrM 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/ReadDataBlockM 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/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/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/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 /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/FlushAdr 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/FlushWay 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/VictimDirtyWay 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/VictimTag 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/CacheableM 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/DCacheMemWriteData 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/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]/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/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 {/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/MemWay[0]/CacheTagMem/StoredData} 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/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]/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 {/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/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/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 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/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/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 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/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/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 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/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/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 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/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]/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/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/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/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 {/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/MemWay[1]/CacheTagMem/StoredData} 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/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/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 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/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/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 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/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/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 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/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/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 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/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]/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/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 {/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/MemWay[2]/CacheTagMem/StoredData} 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/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]/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 {/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/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/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 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/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/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 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/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/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 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/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/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} -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/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]/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/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/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/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 {/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/MemWay[3]/CacheTagMem/StoredData} 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/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]/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 {/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/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/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 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/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/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 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/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/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 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/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/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} -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/SetValid 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/ClearValid 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/SetDirty 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/ClearDirty 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/RAdr 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/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]/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/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/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 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/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]/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/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/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 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/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]/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/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/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 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/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]/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/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/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} -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/WayHit 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/ReadDataBlockWayMaskedM 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/ReadDataWordM 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 {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/dcache/VictimTag
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/dcache/VictimWay
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/dcache/VictimDirtyWay
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/dcache/VictimDirty
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/dcache/LsuRWM
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/dcache/LsuAdrE
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/dcache/LsuPAdrM
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/dcache/LsuAtomicM
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/dcache/CacheableM
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/dcache/FlushDCacheM
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/dcache/DCacheStall
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 -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/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 -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 /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/CacheHit 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/DCFetchLine 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/DCWriteLine 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/DCacheMemWriteData 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/BUSACK 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/FlushWay 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/genblk1/tlb/VAdr 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/genblk1/tlb/tlbcontrol/EffectivePrivilegeMode 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/genblk1/tlb/PTE 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/genblk1/tlb/HitPageType 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/genblk1/tlb/tlbcontrol/Translate 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/genblk1/tlb/tlbcontrol/DisableTranslation 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/TLBMiss 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/TLBHit 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/PhysicalAddress 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/TLBPageFault 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/LoadAccessFaultM 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/StoreAccessFaultM 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/genblk1/tlb/TLBPAdr 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/genblk1/tlb/PTE 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/genblk1/tlb/PageTypeWriteVal 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/genblk1/tlb/TLBWrite 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/pmachecker/PhysicalAddress 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/pmachecker/SelRegions 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/Cacheable 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/Idempotent 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/AtomicAllowed 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/pmachecker/PMAAccessFault 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/PMAInstrAccessFaultF 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/PMALoadAccessFaultM 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/PMAStoreAccessFaultM 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/pmpchecker/PhysicalAddress 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/pmpchecker/ReadAccessM 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/pmpchecker/WriteAccessM 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/pmpchecker/PMPADDR_ARRAY_REGW 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/pmpchecker/PMPCFG_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/PMPInstrAccessFaultF 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/PMPLoadAccessFaultM 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/PMPStoreAccessFaultM 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/pmpchecker/Match 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/pmpchecker/FirstMatch 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/pmpchecker/R 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/pmpchecker/W 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/pmpchecker/X 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/pmpchecker/L 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 -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/PCF
add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/MEM_VIRTMEM/hptw/genblk1/TranslationVAdr 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 -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/priv/priv/csr/MEPC_REGW
add wave -noupdate /testbench/dut/hart/lsu/LocalLsuBusAdr add wave -noupdate /testbench/dut/hart/lsu/LocalLsuBusAdr
add wave -noupdate /testbench/dut/hart/lsu/BasePAdrMaskedM add wave -noupdate /testbench/dut/hart/lsu/busfsm/BusNextState
add wave -noupdate /testbench/dut/hart/lsu/match add wave -noupdate /testbench/dut/hart/lsu/busfsm/DCacheFetchLine
add wave -noupdate /testbench/dut/hart/lsu/busfsm/DCacheWriteLine
TreeUpdate [SetDefaultTree] 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 quietly wave cursor active 3
configure wave -namecolwidth 250 configure wave -namecolwidth 250
configure wave -valuecolwidth 314 configure wave -valuecolwidth 314
@ -487,4 +490,4 @@ configure wave -griddelta 40
configure wave -timeline 0 configure wave -timeline 0
configure wave -timelineunits ns configure wave -timelineunits ns
update 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 clk, reset,
input logic [NUMWAYS-1:0] WayHit, input logic [NUMWAYS-1:0] WayHit,
output logic [NUMWAYS-1:0] VictimWay, 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 [INDEXLEN-1:0] RAdr,
input logic LRUWriteEn input logic LRUWriteEn
); );
@ -44,7 +44,7 @@ module cachereplacementpolicy
logic [NUMWAYS-2:0] NewReplacement; logic [NUMWAYS-2:0] NewReplacement;
logic [NUMWAYS-2:0] NewReplacementD; logic [NUMWAYS-2:0] NewReplacementD;
logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] MemPAdrMD; logic [INDEXLEN+OFFSETLEN-1:OFFSETLEN] LsuPAdrMD;
logic [INDEXLEN-1:0] RAdrD; logic [INDEXLEN-1:0] RAdrD;
logic LRUWriteEnD; logic LRUWriteEnD;
@ -52,18 +52,18 @@ module cachereplacementpolicy
always_ff @(posedge clk) begin always_ff @(posedge clk) begin
if (reset) begin if (reset) begin
RAdrD <= '0; RAdrD <= '0;
MemPAdrMD <= '0; LsuPAdrMD <= '0;
LRUWriteEnD <= 0; LRUWriteEnD <= 0;
NewReplacementD <= '0; NewReplacementD <= '0;
for(int index = 0; index < NUMLINES; index++) for(int index = 0; index < NUMLINES; index++)
ReplacementBits[index] <= '0; ReplacementBits[index] <= '0;
end else begin end else begin
RAdrD <= RAdr; RAdrD <= RAdr;
MemPAdrMD <= MemPAdrM; LsuPAdrMD <= LsuPAdrM;
LRUWriteEnD <= LRUWriteEn; LRUWriteEnD <= LRUWriteEn;
NewReplacementD <= NewReplacement; NewReplacementD <= NewReplacement;
if (LRUWriteEnD) begin if (LRUWriteEnD) begin
ReplacementBits[MemPAdrMD[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacementD; ReplacementBits[LsuPAdrMD[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= NewReplacementD;
end end
end end
end end

View File

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

View File

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

View File

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

View File

@ -28,146 +28,135 @@
module icache module icache
( (
// Basic pipeline stuff // Basic pipeline stuff
input logic clk, reset, input logic clk, reset,
input logic StallF, input logic CPUBusy,
input logic [`PA_BITS-1:0] PCNextF, input logic [`PA_BITS-1:0] PCNextF,
input logic [`PA_BITS-1:0] PCPF, input logic [`PA_BITS-1:0] PCPF,
input logic [`XLEN-1:0] PCF, input logic [`XLEN-1:0] PCF,
input logic ExceptionM, PendingInterruptM, input logic ExceptionM, PendingInterruptM,
// Data read in from the ebu unit // Data read in from the ebu unit
(* mark_debug = "true" *) input logic [`XLEN-1:0] InstrInF, (* mark_debug = "true" *) input logic [`XLEN-1:0] IfuBusHRDATA,
(* mark_debug = "true" *) input logic InstrAckF, (* mark_debug = "true" *) input logic ICacheBusAck,
// Read requested from the ebu unit // Read requested from the ebu unit
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] InstrPAdrF, (* mark_debug = "true" *) output logic [`PA_BITS-1:0] ICacheBusAdr,
(* mark_debug = "true" *) output logic InstrReadF, (* mark_debug = "true" *) output logic IfuBusFetch,
// High if the instruction currently in the fetch stage is compressed // 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 // High if the icache is requesting a stall
output logic ICacheStallF, output logic ICacheStallF,
input logic ITLBMissF, input logic CacheableF,
input logic ITLBWriteF, input logic ITLBMissF,
input logic InvalidateICacheM, input logic ITLBWriteF,
input logic InvalidateICacheM,
// The raw (not decompressed) instruction that was requested // 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 // 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 // Configuration parameters
localparam integer BLOCKLEN = `ICACHE_BLOCKLENINBITS; localparam integer BLOCKLEN = `ICACHE_BLOCKLENINBITS;
localparam integer NUMLINES = `ICACHE_WAYSIZEINBYTES*8/`ICACHE_BLOCKLENINBITS; localparam integer NUMLINES = `ICACHE_WAYSIZEINBYTES*8/`ICACHE_BLOCKLENINBITS;
localparam integer BLOCKBYTELEN = BLOCKLEN/8; localparam integer BLOCKBYTELEN = BLOCKLEN/8;
localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN); localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN);
localparam integer INDEXLEN = $clog2(NUMLINES); localparam integer INDEXLEN = $clog2(NUMLINES);
localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN; localparam integer TAGLEN = `PA_BITS - OFFSETLEN - INDEXLEN;
localparam WORDSPERLINE = BLOCKLEN/`XLEN; localparam WORDSPERLINE = BLOCKLEN/`XLEN;
localparam LOGWPL = $clog2(WORDSPERLINE); localparam LOGWPL = $clog2(WORDSPERLINE);
localparam FetchCountThreshold = WORDSPERLINE - 1; localparam FetchCountThreshold = WORDSPERLINE - 1;
localparam integer PA_WIDTH = `PA_BITS - 2; localparam integer PA_WIDTH = `PA_BITS - 2;
localparam integer NUMWAYS = `ICACHE_NUMWAYS; localparam integer NUMWAYS = `ICACHE_NUMWAYS;
// Input signals to cache memory // Input signals to cache memory
logic ICacheMemWriteEnable; logic ICacheMemWriteEnable;
logic [BLOCKLEN-1:0] ICacheMemWriteData; logic [BLOCKLEN-1:0] ICacheMemWriteData;
logic [`PA_BITS-1:0] PCTagF; logic [`PA_BITS-1:0] FinalPCPF;
// Output signals from cache memory // Output signals from cache memory
logic [31:0] ICacheMemReadData; logic [31:0] ICacheMemReadData;
logic ICacheReadEn; logic ICacheReadEn;
logic [BLOCKLEN-1:0] ReadLineF; logic [BLOCKLEN-1:0] ReadLineF;
logic [15:0] SpillDataBlock0; logic [15:0] SpillDataBlock0;
logic spill; logic spill;
logic spillSave; logic spillSave;
logic FetchCountFlag; logic FetchCountFlag;
logic CntEn; logic CntEn;
logic [1:1] SelAdr_q; logic [1:1] SelAdr_q;
logic [LOGWPL-1:0] FetchCount, NextFetchCount; logic [LOGWPL-1:0] FetchCount, NextFetchCount;
logic [`PA_BITS-1:0] PCPSpillF; logic [`PA_BITS-1:0] PCPSpillF;
logic CntReset; logic CntReset;
logic [1:0] SelAdr; logic [1:0] SelAdr;
logic [INDEXLEN-1:0] RAdr; logic [INDEXLEN-1:0] RAdr;
logic [NUMWAYS-1:0] VictimWay; logic [NUMWAYS-1:0] VictimWay;
logic LRUWriteEn; logic LRUWriteEn;
logic [NUMWAYS-1:0] WayHit; logic [NUMWAYS-1:0] WayHit;
logic hit; logic hit;
logic [BLOCKLEN-1:0] ReadDataBlockWayMasked [NUMWAYS-1:0]; logic [BLOCKLEN-1:0] ReadDataLineWayMasked [NUMWAYS-1:0];
logic [31:0] ReadLineSetsF [`ICACHE_BLOCKLENINBITS/16-1:0];
logic [`PA_BITS-1:0] BasePAdrMaskedF;
logic [OFFSETLEN-1:0] BasePAdrOffsetF;
logic CacheableF; logic [NUMWAYS-1:0] SRAMWayWriteEnable;
logic [`PA_BITS-1:0] BasePAdrF, BasePAdrMaskedF;
logic [OFFSETLEN-1:0] BasePAdrOffsetF;
logic [NUMWAYS-1:0] SRAMWayWriteEnable;
// on spill we want to get the first 2 bytes of the next cache block. // 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 // the spill only occurs if the PCPF mod BlockByteLength == -2. Therefore we can
// simply add 2 to land on the next cache block. // 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) mux3 #(INDEXLEN)
AdrSelMux(.d0(PCNextF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), AdrSelMux(.d0(PCNextF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d1(PCF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .d1(PCF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.d2(PCPSpillF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .d2(PCPSpillF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.s(SelAdr), .s(SelAdr),
.y(RAdr)); .y(RAdr));
cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN),
cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN), .OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN), .OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN), .DIRTY_BITS(0))
.DIRTY_BITS(0)) MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr,
MemWay[NUMWAYS-1:0](.clk, .PAdr(FinalPCPF),
.reset, .WriteEnable(SRAMWayWriteEnable),
.RAdr(RAdr), .VDWriteEnable(1'b0),
.WAdr(PCTagF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .WriteWordEnable({{(BLOCKLEN/`XLEN){1'b1}}}),
.PAdr(PCTagF), .TagWriteEnable(SRAMWayWriteEnable),
.WriteEnable(SRAMWayWriteEnable), .WriteData(ICacheMemWriteData),
.VDWriteEnable(1'b0), .SetValid(ICacheMemWriteEnable),
.WriteWordEnable({{(BLOCKLEN/`XLEN){1'b1}}}), .ClearValid(1'b0), .SetDirty(1'b0), .ClearDirty(1'b0), .SelEvict(1'b0),
.TagWriteEnable(SRAMWayWriteEnable), .VictimWay,
.WriteData(ICacheMemWriteData), .FlushWay(1'b0), .SelFlush(1'b0),
.SetValid(ICacheMemWriteEnable), .ReadDataLineWayMasked, .WayHit,
.ClearValid(1'b0), .VictimDirtyWay(), .VictimTagWay(),
.SetDirty(1'b0), .InvalidateAll(InvalidateICacheM));
.ClearDirty(1'b0),
.SelEvict(1'b0),
.VictimWay,
.FlushWay(1'b0),
.SelFlush(1'b0),
.ReadDataBlockWayMasked,
.WayHit,
.VictimDirtyWay(),
.VictimTagWay(),
.InvalidateAll(InvalidateICacheM)
);
generate generate
if(NUMWAYS > 1) begin if(NUMWAYS > 1) begin
cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES) cachereplacementpolicy #(NUMWAYS, INDEXLEN, OFFSETLEN, NUMLINES)
cachereplacementpolicy(.clk, .reset, cachereplacementpolicy(.clk, .reset,
.WayHit, .WayHit,
.VictimWay, .VictimWay,
.MemPAdrM(PCTagF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .LsuPAdrM(FinalPCPF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]),
.RAdr, .RAdr,
.LRUWriteEn); // *** connect .LRUWriteEn);
end else begin end else begin
assign VictimWay = 1'b1; // one hot. assign VictimWay = 1'b1; // one hot.
end end
@ -175,51 +164,36 @@ module icache
assign hit = | WayHit; 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. // Need to OR together each way in a bitwise manner.
// Final part of the AO Mux. First is the AND in the cacheway. // 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
always_comb begin assign ICacheMemReadData = ReadLineSetsF[FinalPCPF[$clog2(BLOCKLEN / 32) + 1 : 1]];
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 // spills require storing the first cache block so it can merged
// with the second // with the second
// can optimize size, for now just make it the size of the data // can optimize size, for now just make it the size of the data
// leaving the cache memory. // leaving the cache memory.
flopenr #(16) SpillInstrReg(.clk(clk), flopenr #(16) SpillInstrReg(.clk(clk),
.en(spillSave), .en(spillSave),
.reset(reset), .reset(reset),
.d(ICacheMemReadData[15:0]), .d(ICacheMemReadData[15:0]),
.q(SpillDataBlock0)); .q(SpillDataBlock0));
assign FinalInstrRawF = spill ? {ICacheMemReadData[15:0], SpillDataBlock0} : ICacheMemReadData; assign FinalInstrRawF = spill ? {ICacheMemReadData[15:0], SpillDataBlock0} : ICacheMemReadData;
// Detect if the instruction is compressed // Detect if the instruction is compressed
assign CompressedF = FinalInstrRawF[1:0] != 2'b11; 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 // to compute the fetch address we need to add the bit shifted
@ -228,10 +202,10 @@ module icache
flopenr #(LOGWPL) flopenr #(LOGWPL)
FetchCountReg(.clk(clk), FetchCountReg(.clk(clk),
.reset(reset | CntReset), .reset(reset | CntReset),
.en(CntEn), .en(CntEn),
.d(NextFetchCount), .d(NextFetchCount),
.q(FetchCount)); .q(FetchCount));
assign NextFetchCount = FetchCount + 1'b1; assign NextFetchCount = FetchCount + 1'b1;
@ -241,10 +215,10 @@ module icache
generate generate
for (i = 0; i < WORDSPERLINE; i++) begin:storebuffer for (i = 0; i < WORDSPERLINE; i++) begin:storebuffer
flopenr #(`XLEN) sb(.clk(clk), flopenr #(`XLEN) sb(.clk(clk),
.reset(reset), .reset(reset),
.en(InstrAckF & (i == FetchCount)), .en(ICacheBusAck & (i == FetchCount)),
.d(InstrInF), .d(IfuBusHRDATA),
.q(ICacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN])); .q(ICacheMemWriteData[(i+1)*`XLEN-1:i*`XLEN]));
end end
endgenerate endgenerate
@ -252,54 +226,44 @@ module icache
// this mux needs to be delayed 1 cycle as it occurs 1 pipeline stage later. // this mux needs to be delayed 1 cycle as it occurs 1 pipeline stage later.
// *** read enable may not be necessary. // *** read enable may not be necessary.
flopenr #(1) SelAdrReg(.clk(clk), flopenr #(1) SelAdrReg(.clk(clk),
.reset(reset), .reset(reset),
.en(ICacheReadEn), .en(ICacheReadEn),
.d(SelAdr[1]), .d(SelAdr[1]),
.q(SelAdr_q[1])); .q(SelAdr_q[1]));
assign PCTagF = SelAdr_q[1] ? PCPSpillF : PCPF; assign FinalPCPF = 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;
// if not cacheable the offset bits needs to be sent to the EBU. // 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. // 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}} : FinalPCPF[OFFSETLEN-1:0];
assign BasePAdrOffsetF = CacheableF ? {{OFFSETLEN}{1'b0}} : BasePAdrF[OFFSETLEN-1:0]; assign BasePAdrMaskedF = {FinalPCPF[`PA_BITS-1:OFFSETLEN], BasePAdrOffsetF};
assign BasePAdrMaskedF = {BasePAdrF[`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 // truncate the offset from PCPF for memory address generation
assign SRAMWayWriteEnable = ICacheMemWriteEnable ? VictimWay : '0; assign SRAMWayWriteEnable = ICacheMemWriteEnable ? VictimWay : '0;
icachefsm controller(.clk, icachefsm controller(.clk,
.reset, .reset,
.StallF, .CPUBusy,
.ICacheReadEn, .ICacheReadEn,
.ICacheMemWriteEnable, .ICacheMemWriteEnable,
.ICacheStallF, .ICacheStallF,
.ITLBMissF, .ITLBMissF,
.ITLBWriteF, .ITLBWriteF,
.ExceptionM, .ExceptionM,
.PendingInterruptM, .PendingInterruptM,
.InstrAckF, .ICacheBusAck,
.InstrReadF, .IfuBusFetch,
.hit, .hit,
.FetchCountFlag, .FetchCountFlag,
.spill, .spill,
.spillSave, .spillSave,
.CntEn, .CntEn,
.CntReset, .CntReset,
.SelAdr, .SelAdr,
.LRUWriteEn); .LRUWriteEn);
endmodule endmodule

View File

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

View File

@ -40,10 +40,10 @@ module ahblite (
input logic UnsignedLoadM, input logic UnsignedLoadM,
input logic [1:0] AtomicMaskedM, input logic [1:0] AtomicMaskedM,
// Signals from Instruction Cache // Signals from Instruction Cache
input logic [`PA_BITS-1:0] InstrPAdrF, // *** rename these to match block diagram input logic [`PA_BITS-1:0] ICacheBusAdr, // *** rename these to match block diagram
input logic InstrReadF, input logic IfuBusFetch,
output logic [`XLEN-1:0] InstrRData, output logic [`XLEN-1:0] IfuBusHRDATA,
output logic InstrAckF, output logic ICacheBusAck,
// Signals from Data Cache // Signals from Data Cache
input logic [`PA_BITS-1:0] LsuBusAdr, input logic [`PA_BITS-1:0] LsuBusAdr,
input logic LsuBusRead, input logic LsuBusRead,
@ -100,23 +100,23 @@ module ahblite (
case (BusState) case (BusState)
IDLE: if (LsuBusRead) NextBusState = MEMREAD; // Memory has priority over instructions IDLE: if (LsuBusRead) NextBusState = MEMREAD; // Memory has priority over instructions
else if (LsuBusWrite)NextBusState = MEMWRITE; else if (LsuBusWrite)NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD; else if (IfuBusFetch) NextBusState = INSTRREAD;
else NextBusState = IDLE; else NextBusState = IDLE;
MEMREAD: if (~HREADY) NextBusState = MEMREAD; MEMREAD: if (~HREADY) NextBusState = MEMREAD;
else if (InstrReadF) NextBusState = INSTRREAD; else if (IfuBusFetch) NextBusState = INSTRREAD;
else NextBusState = IDLE; else NextBusState = IDLE;
MEMWRITE: if (~HREADY) NextBusState = MEMWRITE; MEMWRITE: if (~HREADY) NextBusState = MEMWRITE;
else if (InstrReadF) NextBusState = INSTRREAD; else if (IfuBusFetch) NextBusState = INSTRREAD;
else NextBusState = IDLE; else NextBusState = IDLE;
INSTRREAD: if (~HREADY) NextBusState = INSTRREAD; INSTRREAD: if (~HREADY) NextBusState = INSTRREAD;
else NextBusState = IDLE; // if (InstrReadF still high) else NextBusState = IDLE; // if (IfuBusFetch still high)
default: NextBusState = IDLE; default: NextBusState = IDLE;
endcase endcase
// bus outputs // bus outputs
assign #1 GrantData = (NextBusState == MEMREAD) || (NextBusState == MEMWRITE); 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 #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 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; assign HSIZE = (GrantData) ? {1'b0, LsuBusSize[1:0]} : ISize;
@ -136,9 +136,9 @@ module ahblite (
// *** assumes AHBW = XLEN // *** assumes AHBW = XLEN
assign InstrRData = HRDATA; assign IfuBusHRDATA = HRDATA;
assign LsuBusHRDATA = 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); assign LsuBusAck = (BusState == MEMREAD) && (NextBusState != MEMREAD) || (BusState == MEMWRITE) && (NextBusState != MEMWRITE);
endmodule endmodule

View File

@ -1,6 +1,7 @@
`include "wally-config.vh" `include "wally-config.vh"
// `include "../../config/rv64icfd/wally-config.vh" // `include "../../config/rv64icfd/wally-config.vh"
// `define XLEN 64
module fcvt ( module fcvt (
input logic XSgnE, // X's sign input logic XSgnE, // X's sign
input logic [10:0] XExpE, // X's exponent input logic [10:0] XExpE, // X's exponent
@ -59,7 +60,7 @@ module fcvt (
// fcvt.lu.d = 111 // fcvt.lu.d = 111
// fcvt.d.l = 100 // fcvt.d.l = 100
// fcvt.d.lu = 110 // fcvt.d.lu = 110
// {long, unsigned, to int, from int} // {long, unsigned, to int}
// calculate signals based off the input and output's size // calculate signals based off the input and output's size
assign Res64 = (FOpCtrlE[0]&FOpCtrlE[2]) | (FmtE&~FOpCtrlE[0]); assign Res64 = (FOpCtrlE[0]&FOpCtrlE[2]) | (FmtE&~FOpCtrlE[0]);
@ -158,19 +159,24 @@ module fcvt (
// select the integer result // select the integer result
assign CvtIntRes = Of ? FOpCtrlE[1] ? {64{1'b1}} : SgnRes ? {33'b0, {31{1'b1}}}: {1'b0, {63{1'b1}}} : 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]; Rounded[64-1:0];
// select the floating point result // select the floating point result
assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {{32{1'b1}}, ResSgn, ResExp[7:0], ResFrac[51:29]}; assign CvtFPRes = FmtE ? {ResSgn, ResExp, ResFrac} : {{32{1'b1}}, ResSgn, ResExp[7:0], ResFrac[51:29]};
// select the result // select the result
assign CvtResE = ~FOpCtrlE[0] ? CvtFPRes : CvtIntRes; assign CvtResE = FOpCtrlE[0] ? CvtIntRes : CvtFPRes;
// calculate the flags // calculate the flags
// - to int only sets the invalid flag // - only set invalid flag for out-of-range vales if it isn't be indicated by the inexact
// - from int only sets the inexact flag // - don't set inexact flag if converting a really large number (closest __ bit integer value is the max value)
assign CvtFlgE = {(Of | Uf)&FOpCtrlE[0], 3'b0, (Guard|Round|Sticky)&~FOpCtrlE[0]}; // - 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 NE 11//(`Q_SUPPORTED ? 15 : `D_SUPPORTED ? 11 : 8)
// `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23) // `define NF 52//(`Q_SUPPORTED ? 112 : `D_SUPPORTED ? 52 : 23)
// `define XLEN 64 // `define XLEN 64
`define NANPAYLOAD 1
module fma( module fma(
input logic clk, input logic clk,
input logic reset, 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+5:0] AlignedAddendE; // Z aligned for addition in U(NF+5.2NF+1)
logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted logic [3*`NF+6:0] AlignedAddendInv; // aligned addend possibly inverted
logic [2*`NF+1:0] ProdManKilled; // the product's mantissa possibly killed 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 [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 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 output logic [3*`NF+6:0] PreSum, NegPreSum// possibly negitive sum
); );
logic [3*`NF+4:0] NegProdManKilled; // a negated ProdManKilled
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
// Addition // Addition
/////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////
@ -335,15 +332,13 @@ module add(
assign AlignedAddendInv = InvZE ? {1'b1, ~AlignedAddendE} : {1'b0, AlignedAddendE}; 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) // Kill the product if the product is too small to effect the addition (determined in fma1.sv)
assign ProdManKilled = ProdManE&{2*`NF+2{~KillProdE}}; 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 // Do the addition
// - calculate a positive and negitive sum in parallel // - calculate a positive and negitive sum in parallel
assign PreSum = AlignedAddendInv + {55'b0, ProdManKilled, 2'b0} + {{3*`NF+6{1'b0}}, InvZE}; 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 // Is the sum negitive
assign NegSumE = PreSum[3*`NF+6]; 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] T;
logic [3*`NF+6:0] G; logic [3*`NF+6:0] G;
logic [3*`NF+6:0] Z; 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 T[3*`NF+6:2*`NF+4] = A[3*`NF+6:2*`NF+4];
assign G[3*`NF+6:2*`NF+4] = 0; assign G[3*`NF+6:2*`NF+4] = 0;
assign Z[3*`NF+6:2*`NF+4] = ~A[3*`NF+6:2*`NF+4]; 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 // - 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[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])) //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+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})); 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 SumZero; // is the sum zero
logic ResultDenorm; // is the result denormalized logic ResultDenorm; // is the result denormalized
logic Sticky, UfSticky; // Sticky bit 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 UfPlus1; // do you add one (for determining underflow flag)
logic Invalid,Underflow,Overflow; // flags logic Invalid,Underflow,Overflow; // flags
logic Guard, Round; // bits needed to determine rounding logic Guard, Round; // bits needed to determine rounding
logic UfLSBNormSum; // bits needed to determine rounding for underflow flag 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 // round to nearest max magnitude
fmaround fmaround(.FmtM, .FrmM, .Sticky, .UfSticky, .NormSum, .AddendStickyM, .NormSumSticky, .ZZeroM, .InvZM, .ResultSgnTmp, .SumExp, 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, resultselect resultselect(.XSgnM, .YSgnM, .XExpM, .YExpM, .ZExpM, .XManM, .YManM, .ZManM,
.FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .FrmM, .FmtM, .AddendStickyM, .KillProdM, .XInfM, .YInfM, .ZInfM, .XNaNM, .YNaNM, .ZNaNM, .RoundAdd,
.ZSgnEffM, .PSgnM, .ResultSgn, .Minus1, .Plus1, .CalcPlus1, .Invalid, .Overflow, .Underflow, .ZSgnEffM, .PSgnM, .ResultSgn, .CalcPlus1, .Invalid, .Overflow, .Underflow,
.ResultDenorm, .ResultExp, .ResultFrac, .FMAResM); .ResultDenorm, .ResultExp, .ResultFrac, .FMAResM);
// *** use NF where needed // *** use NF where needed
@ -539,61 +536,6 @@ module resultsign(
endmodule 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( module normalize(
input logic [3*`NF+5:0] SumM, // the positive sum input logic [3*`NF+5:0] SumM, // the positive sum
@ -624,19 +566,6 @@ module normalize(
// Normalization // 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 // Determine if the sum is zero
assign SumZero = ~(|SumM); assign SumZero = ~(|SumM);
@ -644,18 +573,15 @@ module normalize(
assign FracLen = FmtM ? `NF+1 : 13'd24; assign FracLen = FmtM ? `NF+1 : 13'd24;
// calculate the sum's exponent // 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 SumExpTmpTmp = KillProdM ? {2'b0, ZExpM} : ProdExpM + -({4'b0, NormCntM} + 1 - (`NF+4));
assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}}; // ***move this ^ the subtraction by a constant isn't simplified assign SumExpTmp = FmtM ? SumExpTmpTmp : (SumExpTmpTmp-1023+127)&{`NE+2{|SumExpTmpTmp}};
logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL; logic SumDLTEZ, SumDGEFL, SumSLTEZ, SumSGEFL;
assign SumDLTEZ = SumExpTmpTmp[`NE+1] | ~|SumExpTmpTmp; 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 SumSLTEZ = $signed(SumExpTmpTmp) <= $signed(13'd1023-13'd127);
assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd24+13'd1023-13'd127)) | ~|SumExpTmpTmp; assign SumSGEFL = ($signed(SumExpTmpTmp)>=$signed(-13'd25+13'd1023-13'd127)) | ~|SumExpTmpTmp;
assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero; //***make sure math good assign PreResultDenorm2 = (FmtM ? SumDLTEZ : SumSLTEZ) & (FmtM ? SumDGEFL : SumSGEFL) & ~SumZero;
// always_comb begin
// assert (PreResultDenorm == PreResultDenorm2) else $fatal ("PreResultDenorms not equal");
// end
// 010. when should be 001. // 010. when should be 001.
// - shift left one // - shift left one
@ -667,9 +593,9 @@ module normalize(
// Determine the shift needed for denormal results // Determine the shift needed for denormal results
// - if not denorm add 1 to shift out the leading 1 // - 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 // 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 // LZA correction
assign LZAPlus1 = SumShifted[3*`NF+7]; assign LZAPlus1 = SumShifted[3*`NF+7];
assign LZAPlus2 = SumShifted[3*`NF+8]; assign LZAPlus2 = SumShifted[3*`NF+8];
@ -699,18 +625,18 @@ module fmaround(
input logic InvZM, // invert Z input logic InvZM, // invert Z
input logic [`NE+1:0] SumExp, // exponent of the normalized sum input logic [`NE+1:0] SumExp, // exponent of the normalized sum
input logic ResultSgnTmp, // the result's sign 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 [`NE+1:0] FullResultExp, // ResultExp with bits to determine sign and overflow
output logic [`NF-1:0] ResultFrac, // Result fraction output logic [`NF-1:0] ResultFrac, // Result fraction
output logic [`NE-1:0] ResultExp, // Result exponent output logic [`NE-1:0] ResultExp, // Result exponent
output logic Sticky, // sticky bit 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 output logic Round, Guard, UfLSBNormSum // bits needed to calculate rounding
); );
logic LSBNormSum; // bit used for rounding - least significant bit of the normalized sum 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 SubBySmallNum, UfSubBySmallNum; // was there supposed to be a subtraction by a small number
logic UfGuard; // gaurd bit used to caluculate underflow logic UfGuard; // guard bit used to caluculate underflow
logic UfCalcPlus1, CalcMinus1; // do you add or subtract on from the result logic UfCalcPlus1, CalcMinus1, Plus1, Minus1; // do you add or subtract on from the result
logic [`FLEN:0] RoundAdd; // how much to add to the result
logic [`NF-1:0] NormSumTruncated; // the normalized sum trimed to fit the mantissa logic [`NF-1:0] NormSumTruncated; // the normalized sum trimed to fit the mantissa
logic UfRound; logic UfRound;
@ -858,3 +784,61 @@ module fmaflags(
assign FMAFlgM = {Invalid, 1'b0, Overflow, UnderflowFlag, Inexact}; assign FMAFlgM = {Invalid, 1'b0, Overflow, UnderflowFlag, Inexact};
endmodule 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 StallF, StallD, StallE, StallM, StallW,
input logic FlushF, FlushD, FlushE, FlushM, FlushW, input logic FlushF, FlushD, FlushE, FlushM, FlushW,
// Fetch // Fetch
input logic [`XLEN-1:0] InstrInF, input logic [`XLEN-1:0] IfuBusHRDATA,
input logic InstrAckF, input logic ICacheBusAck,
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF, (* mark_debug = "true" *) output logic [`XLEN-1:0] PCF,
output logic [`PA_BITS-1:0] InstrPAdrF, output logic [`PA_BITS-1:0] ICacheBusAdr,
output logic InstrReadF, output logic IfuBusFetch,
output logic ICacheStallF, output logic ICacheStallF,
// Execute // Execute
output logic [`XLEN-1:0] PCLinkE, output logic [`XLEN-1:0] PCLinkE,
@ -104,6 +104,8 @@ module ifu (
logic [`XLEN+1:0] PCFExt; logic [`XLEN+1:0] PCFExt;
logic [`XLEN-1:0] PCBPWrongInvalidate; logic [`XLEN-1:0] PCBPWrongInvalidate;
logic BPPredWrongM; logic BPPredWrongM;
logic CacheableF;
generate generate
@ -136,7 +138,7 @@ module ifu (
.LoadAccessFaultM(), .LoadAccessFaultM(),
.StoreAccessFaultM(), .StoreAccessFaultM(),
.DisableTranslation(1'b0), .DisableTranslation(1'b0),
.Cacheable(), .Idempotent(), .AtomicAllowed(), .Cacheable(CacheableF), .Idempotent(), .AtomicAllowed(),
.clk, .reset, .clk, .reset,
.SATP_REGW, .SATP_REGW,
@ -157,17 +159,17 @@ module ifu (
// *** put memory interface on here, InstrF becomes output // *** put memory interface on here, InstrF becomes output
//assign InstrPAdrF = PCF; // *** no MMU //assign ICacheBusAdr = PCF; // *** no MMU
//assign InstrReadF = ~StallD; // *** & ICacheMissF; add later //assign IfuBusFetch = ~StallD; // *** & ICacheMissF; add later
// assign InstrReadF = 1; // *** & ICacheMissF; add later // assign IfuBusFetch = 1; // *** & ICacheMissF; add later
// conditional // conditional
// 1. ram // controlled by `MEM_IROM // 1. ram // controlled by `MEM_IROM
// 2. cache // `MEM_ICACHE // 2. cache // `MEM_ICACHE
// 3. wire pass-through // 3. wire pass-through
icache icache(.clk, .reset, .StallF, .ExceptionM, .PendingInterruptM, .InstrInF, .InstrAckF, icache icache(.clk, .reset, .CPUBusy(StallF), .ExceptionM, .PendingInterruptM, .IfuBusHRDATA, .ICacheBusAck,
.InstrPAdrF, .InstrReadF, .CompressedF, .ICacheStallF, .ITLBMissF, .ITLBWriteF, .FinalInstrRawF, .ICacheBusAdr, .IfuBusFetch, .CompressedF, .ICacheStallF, .ITLBMissF, .ITLBWriteF, .FinalInstrRawF,
.CacheableF,
.PCNextF(PCNextFPhys), .PCNextF(PCNextFPhys),
.PCPF(PCPFmmu), .PCPF(PCPFmmu),
.PCF, .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 clk, reset,
input logic FlushW, CPUBusy, input logic FlushW, CPUBusy,
input logic MemReadM, input logic MemReadM,
input logic [1:0] LsuRWM, input logic [1:0] PreLsuRWM,
output logic [1:0] DCRWM, output logic [1:0] LsuRWM,
input logic [1:0] LsuAtomicM, 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 output logic SquashSCW
); );
// Handle atomic load reserved / store conditional // Handle atomic load reserved / store conditional
@ -44,16 +44,16 @@ module lrsc
logic SquashSCM; logic SquashSCM;
assign lrM = MemReadM && LsuAtomicM[0]; assign lrM = MemReadM && LsuAtomicM[0];
assign scM = LsuRWM[0] && LsuAtomicM[0]; assign scM = PreLsuRWM[0] && LsuAtomicM[0];
assign WriteAdrMatchM = LsuRWM[0] && (MemPAdrM[`PA_BITS-1:2] == ReservationPAdrW) && ReservationValidW; assign WriteAdrMatchM = PreLsuRWM[0] && (LsuPAdrM[`PA_BITS-1:2] == ReservationPAdrW) && ReservationValidW;
assign SquashSCM = scM && ~WriteAdrMatchM; 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) always_comb begin // ReservationValidM (next value of valid reservation)
if (lrM) ReservationValidM = 1; // set valid on load reserve 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 if (scM || WriteAdrMatchM) ReservationValidM = 0; // clear valid on store to same address or any sc
else ReservationValidM = ReservationValidW; // otherwise don't change valid else ReservationValidM = ReservationValidW; // otherwise don't change valid
end 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) resvldreg(clk, reset, FlushW, lrM, ReservationValidM, ReservationValidW);
flopenrc #(1) squashreg(clk, reset, FlushW, ~CPUBusy, SquashSCM, SquashSCW); flopenrc #(1) squashreg(clk, reset, FlushW, ~CPUBusy, SquashSCM, SquashSCW);
endmodule endmodule

View File

@ -90,20 +90,19 @@ module lsu
logic DTLBPageFaultM; 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 [`XLEN+1:0] IEUAdrExtM;
logic DTLBMissM; logic DTLBMissM;
logic DTLBWriteM; logic DTLBWriteM;
logic [1:0] DCRWM;
logic [1:0] LsuRWM; logic [1:0] LsuRWM;
logic [1:0] PreLsuRWM;
logic [2:0] LsuFunct3M; logic [2:0] LsuFunct3M;
logic [1:0] LsuAtomicM; logic [1:0] LsuAtomicM;
logic [`PA_BITS-1:0] LsuPAdrM, LocalLsuBusAdr; logic [`PA_BITS-1:0] PreLsuPAdrM, LocalLsuBusAdr;
logic [11:0] LsuAdrE, DCAdrE; logic [11:0] PreLsuAdrE, LsuAdrE;
logic CPUBusy; logic CPUBusy;
logic MemReadM; logic MemReadM;
logic DataMisalignedM;
logic DCacheStall; logic DCacheStall;
logic CacheableM; logic CacheableM;
@ -115,7 +114,7 @@ module lsu
logic InterlockStall; logic InterlockStall;
logic IgnoreRequest; logic IgnoreRequest;
logic BusCommittedM, DCCommittedM; logic BusCommittedM, DCacheCommittedM;
flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM); flopenrc #(`XLEN) AddressMReg(clk, reset, FlushM, ~StallM, IEUAdrE, IEUAdrM);
@ -129,78 +128,13 @@ module lsu
logic [2:0] HPTWSize; logic [2:0] HPTWSize;
logic SelReplayCPURequest; logic SelReplayCPURequest;
typedef enum {STATE_T0_READY, assign AnyCPUReqM = (|MemRWM) | (|AtomicM);
STATE_T0_REPLAY,
STATE_T3_DTLB_MISS,
STATE_T4_ITLB_MISS,
STATE_T5_ITLB_MISS,
STATE_T7_DITLB_MISS} statetype;
statetype InterlockCurrState, InterlockNextState; interlockfsm interlockfsm (.clk, .reset, .AnyCPUReqM, .ITLBMissF, .ITLBWriteF,
.DTLBMissM, .DTLBWriteM, .ExceptionM, .PendingInterruptM, .DCacheStall,
.InterlockStall, .SelReplayCPURequest, .SelHPTW,
.IgnoreRequest);
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
// 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, hptw hptw(.clk, .reset, .SATP_REGW, .PCF, .IEUAdrM,
.ITLBMissF(ITLBMissF & ~PendingInterruptM), .ITLBMissF(ITLBMissF & ~PendingInterruptM),
.DTLBMissM(DTLBMissM & ~PendingInterruptM), .DTLBMissM(DTLBMissM & ~PendingInterruptM),
@ -211,38 +145,31 @@ module lsu
// arbiter between IEU and hptw // arbiter between IEU and hptw
// multiplex the outputs to LSU // 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 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LsuFunct3M);
mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM); mux2 #(2) atomicmux(AtomicM, 2'b00, SelHPTW, LsuAtomicM);
mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, LsuAdrE); mux2 #(12) adremux(IEUAdrE[11:0], HPTWAdr[11:0], SelHPTW, PreLsuAdrE);
mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, LsuPAdrM); mux2 #(`PA_BITS) lsupadrmux(IEUAdrExtM[`PA_BITS-1:0], HPTWAdr, SelHPTW, PreLsuPAdrM);
assign CPUBusy = StallW & ~SelHPTW;
// always block interrupts when using the hardware page table walker. // always block interrupts when using the hardware page table walker.
assign CPUBusy = StallW & ~SelHPTW;
// this is for the d cache SRAM. // It is not possible to pipeline hptw as the following load will depend on the previous load's
// turns out because we cannot pipeline hptw requests we don't need this register // data. Therefore we don't need a pipeline register
//flop #(`PA_BITS) HPTWAdrMReg(clk, HPTWAdr, HPTWAdrM); // delay HPTWAdrM by a cycle //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 // Specify which type of page fault is occurring
// *** `MEM_VIRTMEM assign DTLBLoadPageFaultM = DTLBPageFaultM & PreLsuRWM[1];
assign DTLBLoadPageFaultM = DTLBPageFaultM & LsuRWM[1]; assign DTLBStorePageFaultM = DTLBPageFaultM & PreLsuRWM[0];
assign DTLBStorePageFaultM = DTLBPageFaultM & LsuRWM[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) end // if (`MEM_VIRTMEM)
else begin else begin
assign InterlockStall = 1'b0; assign InterlockStall = 1'b0;
assign DCAdrE = LsuAdrE; assign LsuAdrE = PreLsuAdrE;
assign SelHPTW = 1'b0; assign SelHPTW = 1'b0;
assign IgnoreRequest = 1'b0; assign IgnoreRequest = 1'b0;
@ -251,11 +178,11 @@ module lsu
assign DTLBWriteM = 1'b0; assign DTLBWriteM = 1'b0;
assign ITLBWriteF = 1'b0; assign ITLBWriteF = 1'b0;
assign LsuRWM = MemRWM; assign PreLsuRWM = MemRWM;
assign LsuFunct3M = Funct3M; assign LsuFunct3M = Funct3M;
assign LsuAtomicM = AtomicM; assign LsuAtomicM = AtomicM;
assign LsuAdrE = IEUAdrE[11:0]; assign PreLsuAdrE = IEUAdrE[11:0];
assign LsuPAdrM = IEUAdrExtM; assign PreLsuPAdrM = IEUAdrExtM;
assign CPUBusy = StallW; assign CPUBusy = StallW;
assign DTLBLoadPageFaultM = 1'b0; assign DTLBLoadPageFaultM = 1'b0;
@ -263,141 +190,159 @@ module lsu
end end
endgenerate 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)) generate
dmmu(.clk, .reset, .SATP_REGW, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, if(`ZICSR_SUPPORTED == 1) begin : dmmu
.PrivilegeModeW, .DisableTranslation(SelHPTW), logic DataMisalignedM;
.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?
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; 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. // Move generate from lrsc to outside this module.
// use PreLsu as prefix for lrsc
generate generate
if (`A_SUPPORTED) begin if (`A_SUPPORTED) begin
assign MemReadM = LsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM; assign MemReadM = PreLsuRWM[1] & ~(IgnoreRequest) & ~DTLBMissM;
lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .LsuRWM, .LsuAtomicM, .MemPAdrM, lrsc lrsc(.clk, .reset, .FlushW, .CPUBusy, .MemReadM, .PreLsuRWM, .LsuAtomicM, .LsuPAdrM,
.SquashSCW, .DCRWM); .SquashSCW, .LsuRWM);
end else begin end else begin
assign SquashSCW = 0; assign SquashSCW = 0;
assign DCRWM = LsuRWM; assign LsuRWM = PreLsuRWM;
end end
endgenerate 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 // conditional
// 1. ram // controlled by `MEM_DTIM // 1. ram // controlled by `MEM_DTIM
// 2. cache `MEM_DCACHE // 2. cache `MEM_DCACHE
// 3. wire pass-through // 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 LOGWPL = $clog2(WORDSPERLINE);
localparam integer BLOCKLEN = `DCACHE_BLOCKLENINBITS; localparam integer BLOCKLEN = `MEM_DCACHE ? `DCACHE_BLOCKLENINBITS : `XLEN;
localparam integer WordCountThreshold = `MEM_DCACHE ? WORDSPERLINE - 1 : 0;
localparam integer WordCountThreshold = WORDSPERLINE - 1;
localparam integer BLOCKBYTELEN = BLOCKLEN/8; localparam integer BLOCKBYTELEN = BLOCKLEN/8;
localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN); localparam integer OFFSETLEN = $clog2(BLOCKBYTELEN);
// temp // temp
logic WordCountFlag;
logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM; logic [`XLEN-1:0] FinalAMOWriteDataM, FinalWriteDataM;
(* mark_debug = "true" *) logic [`XLEN-1:0] DC_HWDATA_FIXNAME; (* mark_debug = "true" *) logic [`XLEN-1:0] PreLsuBusHWDATA;
logic SelFlush;
logic [`XLEN-1:0] ReadDataWordM; logic [`XLEN-1:0] ReadDataWordM;
logic [`DCACHE_BLOCKLENINBITS-1:0] DCacheMemWriteData; logic [BLOCKLEN-1:0] DCacheMemWriteData;
// keep // keep
logic [`XLEN-1:0] ReadDataWordMuxM; 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 [`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 DCacheWriteLine;
logic DCFetchLine; logic DCacheFetchLine;
logic BUSACK; logic DCacheBusAck;
logic UnCachedLsuBusRead;
logic UnCachedLsuBusWrite;
logic SelUncachedAdr; logic SelUncachedAdr;
generate
dcache dcache(.clk, .reset, .CPUBusy, if(`MEM_DCACHE) begin : dcache
.MemRWM(DCRWM), dcache dcache(.clk, .reset, .CPUBusy,
.Funct3M(LsuFunct3M), .LsuRWM, .FlushDCacheM, .LsuAtomicM, .LsuAdrE, .LsuPAdrM,
.Funct7M, .FlushDCacheM, .FinalWriteDataM, .ReadDataWordM, .DCacheStall,
.AtomicM(LsuAtomicM), .DCacheMiss, .DCacheAccess,
.MemAdrE(DCAdrE), .IgnoreRequest, .CacheableM, .DCacheCommittedM,
.MemPAdrM, .DCacheBusAdr, .ReadDataBlockSetsM, .DCacheMemWriteData,
.FinalWriteDataM, .ReadDataWordM, .DCacheStall, .DCacheFetchLine, .DCacheWriteLine,.DCacheBusAck);
.DCacheMiss, .DCacheAccess, .IgnoreRequest, end else begin : passthrough
.CacheableM(CacheableM), assign ReadDataWordM = 0;
.DCCommittedM, assign DCacheStall = 0;
.DCacheBusAdr, assign DCacheMiss = 1;
.ReadDataBlockSetsM, assign DCacheAccess = CacheableM;
.SelFlush, assign DCacheCommittedM = 0;
.DCacheMemWriteData, assign DCacheWriteLine = 0;
.DCFetchLine, assign DCacheFetchLine = 0;
.DCWriteLine, assign DCacheBusAdr = 0;
.BUSACK assign ReadDataBlockSetsM[0] = 0;
); end
endgenerate
// select between dcache and direct from the BUS. Always selected if no dcache.
mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM), mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM),
.d1(DCacheMemWriteData[`XLEN-1:0]), .d1(DCacheMemWriteData[`XLEN-1:0]),
.s(SelUncachedAdr), .s(SelUncachedAdr),
.y(ReadDataWordMuxM)); .y(ReadDataWordMuxM));
// sub word selection for read and writes and optional amo alu.
// finally swr // finally swr
subwordread subwordread(.ReadDataWordMuxM, subwordread subwordread(.ReadDataWordMuxM,
.MemPAdrM(MemPAdrM[2:0]), .LsuPAdrM(LsuPAdrM[2:0]),
.Funct3M(LsuFunct3M), .Funct3M(LsuFunct3M),
.ReadDataM); .ReadDataM);
generate generate
if (`A_SUPPORTED) begin if (`A_SUPPORTED) begin : amo
logic [`XLEN-1:0] AMOResult; logic [`XLEN-1:0] AMOResult;
amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LsuFunct3M[1:0]), amoalu amoalu(.srca(ReadDataM), .srcb(WriteDataM), .funct(Funct7M), .width(LsuFunct3M[1:0]),
.result(AMOResult)); .result(AMOResult));
@ -406,23 +351,19 @@ module lsu
assign FinalAMOWriteDataM = WriteDataM; assign FinalAMOWriteDataM = WriteDataM;
endgenerate endgenerate
// this might only get instantiated if there is a dcache or dtim.
// There is a copy in the ebu.
subwordwrite subwordwrite(.HRDATA(ReadDataWordM), subwordwrite subwordwrite(.HRDATA(ReadDataWordM),
.HADDRD(MemPAdrM[2:0]), .HADDRD(LsuPAdrM[2:0]),
.HSIZED({LsuFunct3M[2], 1'b0, LsuFunct3M[1:0]}), .HSIZED({LsuFunct3M[2], 1'b0, LsuFunct3M[1:0]}),
.HWDATAIN(FinalAMOWriteDataM), .HWDATAIN(FinalAMOWriteDataM),
.HWDATA(FinalWriteDataM)); .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 // Bus Side logic
// register the fetch data from the next level of memory. // 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 // This register should be necessary for timing. There is no register in the uncore or
// ahblite controller between the memories and this cache. // ahblite controller between the memories and this cache.
logic [LOGWPL-1:0] WordCount;
genvar index; genvar index;
generate generate
@ -434,92 +375,20 @@ module lsu
end end
endgenerate endgenerate
assign LocalLsuBusAdr = SelUncachedAdr ? LsuPAdrM : DCacheBusAdr ;
//assign LocalLsuBusAdr = SelUncachedAdr ? MemPAdrM : {DCacheBusAdr[`PA_BITS-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}} ;
assign LocalLsuBusAdr = SelUncachedAdr ? MemPAdrM : DCacheBusAdr ;
assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr; assign LsuBusAdr = ({{`PA_BITS-LOGWPL{1'b0}}, WordCount} << $clog2(`XLEN/8)) + LocalLsuBusAdr;
assign PreLsuBusHWDATA = ReadDataBlockSetsM[WordCount];
assign LsuBusHWDATA = SelUncachedAdr ? WriteDataM : PreLsuBusHWDATA; // *** why is this not FinalWriteDataM? which does not work.
assign DC_HWDATA_FIXNAME = ReadDataBlockSetsM[WordCount]; generate
if (`XLEN == 32) assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b010;
else assign LsuBusSize = SelUncachedAdr ? LsuFunct3M : 3'b011;
endgenerate;
assign WordCountFlag = (WordCount == WordCountThreshold[LOGWPL-1:0]); busfsm #(WordCountThreshold, LOGWPL)
assign CntEn = PreCntEn & LsuBusAck; busfsm(.clk, .reset, .IgnoreRequest, .LsuRWM, .DCacheFetchLine, .DCacheWriteLine,
.LsuBusAck, .CPUBusy, .CacheableM, .BusStall, .LsuBusWrite, .LsuBusRead,
flopenr #(LOGWPL) .DCacheBusAck, .BusCommittedM, .SelUncachedAdr, .WordCount);
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);
endmodule endmodule

View File

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

View File

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

View File

@ -47,34 +47,37 @@ module pmpchecker (
output logic PMPStoreAccessFaultM 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]
// Bit i is high when the address falls in PMP region i pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0](
logic EnforcePMP; .PhysicalAddress,
// logic [7:0] PMPCfg[`PMP_ENTRIES-1:0]; .PMPCfg(PMPCFG_ARRAY_REGW),
logic [`PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges .PMPAdr(PMPADDR_ARRAY_REGW),
logic [`PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. .PAgePMPAdrIn({PAgePMPAdr[`PMP_ENTRIES-2:0], 1'b1}),
logic [`PMP_ENTRIES-1:0] Active; // PMP register i is non-null .PAgePMPAdrOut(PAgePMPAdr),
logic [`PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set .FirstMatch, .Match, .Active, .L, .X, .W, .R);
logic [`PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
genvar i,j;
pmpadrdec pmpadrdecs[`PMP_ENTRIES-1:0]( priorityonehot #(`PMP_ENTRIES) pmppriority(.a(Match), .y(FirstMatch)); // combine the match signal from all the adress decoders to find the first one that matches.
.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;
// 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;
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; //assign PMPSquashBusAccess = PMPInstrAccessFaultF | PMPLoadAccessFaultM | PMPStoreAccessFaultM;
endmodule endmodule

View File

@ -89,9 +89,35 @@ module csrm #(parameter
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
logic [`PMP_ENTRIES-1:0] WritePMPCFGM;
logic [`PMP_ENTRIES-1:0] WritePMPADDRM ; // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
logic [`PMP_ENTRIES-1:0] ADDRLocked, CFGLocked; 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; localparam MISA_26 = (`MISA) & 32'h03ffffff;
@ -118,7 +144,7 @@ module csrm #(parameter
// CSRs // CSRs
flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); //busybear: changed reset value to 0 flopenr #(`XLEN) MTVECreg(clk, reset, WriteMTVECM, {CSRWriteValM[`XLEN-1:2], 1'b0, CSRWriteValM[0]}, MTVEC_REGW); //busybear: changed reset value to 0
generate 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) MEDELEGreg(clk, reset, WriteMEDELEGM, CSRWriteValM & MEDELEG_MASK /*12'h7FF*/, MEDELEG_REGW);
flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW); flopenr #(`XLEN) MIDELEGreg(clk, reset, WriteMIDELEGM, CSRWriteValM & MIDELEG_MASK /*12'h222*/, MIDELEG_REGW);
end else begin end else begin
@ -132,43 +158,15 @@ module csrm #(parameter
flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW); flopenr #(`XLEN) MCAUSEreg(clk, reset, WriteMCAUSEM, NextCauseM, MCAUSE_REGW);
if(`QEMU) assign MTVAL_REGW = `XLEN'b0; if(`QEMU) assign MTVAL_REGW = `XLEN'b0;
else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW); else flopenr #(`XLEN) MTVALreg(clk, reset, WriteMTVALM, NextMtvalM, MTVAL_REGW);
generate generate // *** needs comment about bit 1
if (`BUSYBEAR == 1) if (`BUSYBEAR == 1) begin:counters
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, {CSRWriteValM[31:2],1'b0,CSRWriteValM[0]}, MCOUNTEREN_REGW); 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); flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
else end
flopens #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
endgenerate endgenerate
flopenr #(32) MCOUNTINHIBITreg(clk, reset, WriteMCOUNTINHIBITM, CSRWriteValM[31:0], MCOUNTINHIBIT_REGW); 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 // Read machine mode CSRs
// verilator lint_off WIDTH // verilator lint_off WIDTH
@ -188,10 +186,6 @@ module csrm #(parameter
entry = (CSRAdrM - PMPCFG0)*4; entry = (CSRAdrM - PMPCFG0)*4;
CSRMReadValM = {PMPCFG_ARRAY_REGW[entry+3],PMPCFG_ARRAY_REGW[entry+2],PMPCFG_ARRAY_REGW[entry+1],PMPCFG_ARRAY_REGW[entry]}; CSRMReadValM = {PMPCFG_ARRAY_REGW[entry+3],PMPCFG_ARRAY_REGW[entry+2],PMPCFG_ARRAY_REGW[entry+1],PMPCFG_ARRAY_REGW[entry]};
end end
/*
if (~CSRAdrM[0]) CSRMReadValM = {PMPCFG_ARRAY_REGW[]};
else CSRMReadValM = {{(`XLEN-32){1'b0}}, PMPCFG_ARRAY_REGW[(CSRAdrM - PMPCFG0-1)/2][63:32]};*/
end end
else case (CSRAdrM) else case (CSRAdrM)
MISA_ADR: CSRMReadValM = MISA_REGW; MISA_ADR: CSRMReadValM = MISA_REGW;
@ -202,8 +196,6 @@ module csrm #(parameter
MSTATUS: CSRMReadValM = MSTATUS_REGW; MSTATUS: CSRMReadValM = MSTATUS_REGW;
MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported MSTATUSH: CSRMReadValM = 0; // flush this out later if MBE and SBE fields are supported
MTVEC: CSRMReadValM = MTVEC_REGW; MTVEC: CSRMReadValM = MTVEC_REGW;
//MEDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MEDELEG_REGW};
//MIDELEG: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIDELEG_REGW};
MEDELEG: CSRMReadValM = MEDELEG_REGW; MEDELEG: CSRMReadValM = MEDELEG_REGW;
MIDELEG: CSRMReadValM = MIDELEG_REGW; MIDELEG: CSRMReadValM = MIDELEG_REGW;
MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW}; MIP: CSRMReadValM = {{(`XLEN-12){1'b0}}, MIP_REGW};

View File

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

View File

@ -271,7 +271,7 @@ module sd_cmd_fsm
assign o_ERROR_CODE_Q = r_ERROR_CODE_Q; assign o_ERROR_CODE_Q = r_ERROR_CODE_Q;
assign COUNTER_OUT_GT_ZERO = i_COUNTER_OUT > 0; 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_GT_8 = i_COUNTER_OUT > 8;
assign COUNTER_OUT_EQ_8 = i_COUNTER_OUT == 8; assign COUNTER_OUT_EQ_8 = i_COUNTER_OUT == 8;
assign COUNTER_OUT_EQ_ZERO = i_COUNTER_OUT == 0; assign COUNTER_OUT_EQ_ZERO = i_COUNTER_OUT == 0;

View File

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

View File

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

View File

@ -76,12 +76,14 @@ logic [3:0] dummy;
// pick tests based on modes supported // pick tests based on modes supported
initial begin initial begin
$display("TEST is %s", TEST); $display("TEST is %s", TEST);
tests = '{}; //tests = '{};
if (`XLEN == 64) begin // RV64 if (`XLEN == 64) begin // RV64
case (TEST) case (TEST)
"arch64i": tests = arch64i; "arch64i": tests = arch64i;
"arch64priv": tests = arch64priv; "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; "arch64m": if (`M_SUPPORTED) tests = arch64m;
"arch64d": if (`D_SUPPORTED) tests = arch64d; "arch64d": if (`D_SUPPORTED) tests = arch64d;
"imperas64i": tests = imperas64i; "imperas64i": tests = imperas64i;
@ -102,7 +104,9 @@ logic [3:0] dummy;
case (TEST) case (TEST)
"arch32i": tests = arch32i; "arch32i": tests = arch32i;
"arch32priv": tests = arch32priv; "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; "arch32m": if (`M_SUPPORTED) tests = arch32m;
"arch32f": if (`F_SUPPORTED) tests = arch32f; "arch32f": if (`F_SUPPORTED) tests = arch32f;
"imperas32i": tests = imperas32i; "imperas32i": tests = imperas32i;
@ -239,6 +243,7 @@ logic [3:0] dummy;
/* verilator lint_off INFINITELOOP */ /* verilator lint_off INFINITELOOP */
while (signature[i] !== 'bx) begin while (signature[i] !== 'bx) begin
//$display("signature[%h] = %h", i, signature[i]); //$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] && if (signature[i] !== dut.uncore.ram.ram.RAM[testadr+i] &&
(signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin (signature[i] !== DCacheFlushFSM.ShadowRAM[testadr+i])) begin
if (signature[i+4] !== 'bx || signature[i] !== 32'hFFFFFFFF) 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) for new Imperas tests
// or sw gp, -56(t0) // or sw gp, -56(t0)
// or on a jump to self infinite loop (6f) for RISC-V Arch tests // 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.rf[3] == 1 ||
(dut.hart.ieu.dp.regf.we3 && (dut.hart.ieu.dp.regf.we3 &&
dut.hart.ieu.dp.regf.a3 == 3 && dut.hart.ieu.dp.regf.a3 == 3 &&
dut.hart.ieu.dp.regf.wd3 == 1)) || 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; (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), DCacheFlushFSM DCacheFlushFSM(.clk(clk),
.reset(reset), .reset(reset),
.start(DCacheFlushStart), .start(DCacheFlushStart),
.done(DCacheFlushDone)); .done(DCacheFlushDone));
generate 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_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 >= 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 (`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_BLOCKLENINBITS) == `DCACHE_BLOCKLENINBITS || `MEM_DCACHE==0) 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(`DCACHE_WAYSIZEINBYTES) == `DCACHE_WAYSIZEINBYTES || `MEM_DCACHE==0) 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_BLOCKLENINBITS) == `ICACHE_BLOCKLENINBITS || `MEM_ICACHE==0) 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(`ICACHE_WAYSIZEINBYTES) == `ICACHE_WAYSIZEINBYTES || `MEM_ICACHE==0) 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(`ITLB_ENTRIES) == `ITLB_ENTRIES || `MEM_VIRTMEM==0) 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(`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 (`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 end
endmodule endmodule
@ -350,10 +365,10 @@ module DCacheFlushFSM
input logic start, input logic start,
output logic done); output logic done);
localparam integer numlines = testbench.dut.hart.lsu.dcache.NUMLINES; localparam integer numlines = testbench.dut.hart.lsu.dcache.dcache.NUMLINES;
localparam integer numways = testbench.dut.hart.lsu.dcache.NUMWAYS; localparam integer numways = testbench.dut.hart.lsu.dcache.dcache.NUMWAYS;
localparam integer blockbytelen = testbench.dut.hart.lsu.dcache.BLOCKBYTELEN; localparam integer blockbytelen = testbench.dut.hart.lsu.dcache.dcache.BLOCKBYTELEN;
localparam integer numwords = testbench.dut.hart.lsu.dcache.BLOCKLEN/`XLEN; localparam integer numwords = testbench.dut.hart.lsu.dcache.dcache.BLOCKLEN/`XLEN;
localparam integer lognumlines = $clog2(numlines); localparam integer lognumlines = $clog2(numlines);
localparam integer logblockbytelen = $clog2(blockbytelen); localparam integer logblockbytelen = $clog2(blockbytelen);
localparam integer lognumways = $clog2(numways); localparam integer lognumways = $clog2(numways);
@ -379,10 +394,10 @@ module DCacheFlushFSM
.logblockbytelen(logblockbytelen)) .logblockbytelen(logblockbytelen))
copyShadow(.clk, copyShadow(.clk,
.start, .start,
.tag(testbench.dut.hart.lsu.dcache.MemWay[way].CacheTagMem.StoredData[index]), .tag(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].CacheTagMem.StoredData[index]),
.valid(testbench.dut.hart.lsu.dcache.MemWay[way].ValidBits[index]), .valid(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].ValidBits[index]),
.dirty(testbench.dut.hart.lsu.dcache.MemWay[way].DirtyBits[index]), .dirty(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].DirtyBits[index]),
.data(testbench.dut.hart.lsu.dcache.MemWay[way].word[cacheWord].CacheDataMem.StoredData[index]), .data(testbench.dut.hart.lsu.dcache.dcache.MemWay[way].word[cacheWord].CacheDataMem.StoredData[index]),
.index(index), .index(index),
.cacheWord(cacheWord), .cacheWord(cacheWord),
.CacheData(CacheData[way][index][cacheWord]), .CacheData(CacheData[way][index][cacheWord]),

View File

@ -27,6 +27,7 @@
`define RISCVARCHTEST "1" `define RISCVARCHTEST "1"
`define WALLYTEST "2" `define WALLYTEST "2"
`define MYIMPERASTEST "3" `define MYIMPERASTEST "3"
// *** remove MYIMPERASTEST cases when ported
string tvpaths[] = '{ string tvpaths[] = '{
"../../addins/imperas-riscv-tests/work/", "../../addins/imperas-riscv-tests/work/",
@ -958,7 +959,6 @@ string imperas32f[] = '{
"rv64i_m/C/candi-01", "4010", "rv64i_m/C/candi-01", "4010",
"rv64i_m/C/cbeqz-01", "4010", "rv64i_m/C/cbeqz-01", "4010",
"rv64i_m/C/cbnez-01", "5010", "rv64i_m/C/cbnez-01", "5010",
"rv64i_m/C/cebreak-01", "2070",
"rv64i_m/C/cj-01", "3010", "rv64i_m/C/cj-01", "3010",
"rv64i_m/C/cjalr-01", "2010", "rv64i_m/C/cjalr-01", "2010",
"rv64i_m/C/cjr-01", "2010", "rv64i_m/C/cjr-01", "2010",
@ -983,6 +983,11 @@ string imperas32f[] = '{
"rv64i_m/C/cxor-01", "8010" "rv64i_m/C/cxor-01", "8010"
}; };
string arch64cpriv[] = '{
// `RISCVARCHTEST,
"rv64i_m/C/cebreak-01", "2070"
};
string arch64i[] = '{ string arch64i[] = '{
`RISCVARCHTEST, `RISCVARCHTEST,
"rv64i_m/I/add-01", "9010", "rv64i_m/I/add-01", "9010",
@ -1405,7 +1410,6 @@ string imperas32f[] = '{
"rv32i_m/C/candi-01", "3010", "rv32i_m/C/candi-01", "3010",
"rv32i_m/C/cbeqz-01", "3010", "rv32i_m/C/cbeqz-01", "3010",
"rv32i_m/C/cbnez-01", "3010", "rv32i_m/C/cbnez-01", "3010",
"rv32i_m/C/cebreak-01", "2050",
"rv32i_m/C/cj-01", "3010", "rv32i_m/C/cj-01", "3010",
"rv32i_m/C/cjal-01", "3010", "rv32i_m/C/cjal-01", "3010",
"rv32i_m/C/cjalr-01", "2010", "rv32i_m/C/cjalr-01", "2010",
@ -1426,6 +1430,12 @@ string imperas32f[] = '{
"rv32i_m/C/cxor-01", "4010" "rv32i_m/C/cxor-01", "4010"
}; };
string arch32cpriv[] = '{
// `RISCVARCHTEST,
"rv32i_m/C/cebreak-01", "2050"
};
string arch32i[] = '{ string arch32i[] = '{
`RISCVARCHTEST, `RISCVARCHTEST,
"rv32i_m/I/add-01", "5010", "rv32i_m/I/add-01", "5010",
@ -1475,7 +1485,11 @@ string imperas32f[] = '{
}; };
string wally64priv[] = '{ 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[] = '{ string wally64periph[] = '{
@ -1488,7 +1502,10 @@ string wally32i[] = '{
}; };
string wally32priv[] = '{ 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[] = '{ string wally32periph[] = '{