merged script install file

This commit is contained in:
Thomas Kidd 2024-01-04 22:03:08 -05:00
commit ea8f424b78
47 changed files with 754 additions and 407 deletions

2
.gitignore vendored
View File

@ -190,3 +190,5 @@ benchmarks/embench/run*
sim/cfi.log sim/cfi.log
sim/cfi/* sim/cfi/*
sim/branch/* sim/branch/*
sim/obj_dir
examples/verilog/fulladder/obj_dir

@ -1 +1 @@
Subproject commit eb0a3892215ad2384702db02da1551a59701ec67 Subproject commit c955abf757df98cf38809e40a62d2a6b448ea507

View File

@ -167,7 +167,7 @@ sudo ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV32 /usr/bin/riscv_sim_RV32
# riscof # riscof
sudo pip3 install -U testresources riscv_config sudo pip3 install -U testresources riscv_config
pip3 install git+https://github.com/riscv/riscof.git sudo pip3 install git+https://github.com/riscv/riscof.git
# Download OSU Skywater 130 cell library # Download OSU Skywater 130 cell library
sudo mkdir -p $RISCV/cad/lib sudo mkdir -p $RISCV/cad/lib

View File

@ -35,7 +35,7 @@ localparam XLEN = 32'd32;
// IEEE 754 compliance // IEEE 754 compliance
localparam IEEE754 = 0; localparam IEEE754 = 0;
localparam MISA = (32'h00000104 | 1 << 1 | 1 << 20 | 1 << 18 | 1 << 12 | 1 << 0 | 1 <<3 | 1 << 5); localparam MISA = (32'h00000104 | 1 << 20 | 1 << 18 | 1 << 12 | 1 << 0 | 1 <<3 | 1 << 5);
localparam ZICSR_SUPPORTED = 1; localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1; localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;

View File

@ -34,7 +34,7 @@ localparam XLEN = 32'd64;
localparam IEEE754 = 0; localparam IEEE754 = 0;
// MISA RISC-V configuration per specification // MISA RISC-V configuration per specification
localparam MISA = (32'h00000104 | 1 << 1 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0); localparam MISA = (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0);
localparam ZICSR_SUPPORTED = 1; localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1; localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;

View File

@ -3,6 +3,7 @@ module testbench();
logic a, b, c, s, cout, sexpected, coutexpected; logic a, b, c, s, cout, sexpected, coutexpected;
logic [31:0] vectornum, errors; logic [31:0] vectornum, errors;
logic [4:0] testvectors[10000:0]; logic [4:0] testvectors[10000:0];
integer cycle;
// instantiate device under test // instantiate device under test
fulladder dut(a, b, c, s, cout); fulladder dut(a, b, c, s, cout);
@ -11,12 +12,15 @@ module testbench();
always always
begin begin
clk = 1; #5; clk = 0; #5; clk = 1; #5; clk = 0; #5;
cycle = cycle + 1;
$display("cycle: %x vectornum %x testvectors[vectornum]: %b", cycle, vectornum, testvectors[vectornum]);
end end
// at start of test, load vectors and pulse reset // at start of test, load vectors and pulse reset
initial initial
begin begin
$readmemb("fulladder.tv", testvectors); $readmemb("fulladder.tv", testvectors);
cycle = 0;
vectornum = 0; errors = 0; vectornum = 0; errors = 0;
reset = 1; #22; reset = 0; reset = 1; #22; reset = 0;
end end
@ -36,10 +40,11 @@ module testbench();
errors = errors + 1; errors = errors + 1;
end end
vectornum = vectornum + 1; vectornum = vectornum + 1;
if (testvectors[vectornum] === 5'bx) begin //if (testvectors[vectornum] === 5'bx) begin
if (vectornum === 10) begin
$display("%d tests completed with %d errors", $display("%d tests completed with %d errors",
vectornum, errors); vectornum, errors);
$stop; $finish;
end end
end end
endmodule endmodule

View File

@ -0,0 +1,5 @@
#verilator --timescale "1ns/1ns" --timing -cc --exe --build --top-module testbench fulladder.sv
#verilator --timescale "1ns/1ns" --timing -cc --exe --top-module testbench fulladder.sv
#verilator --binary --top-module testbench fulladder.sv
verilator --timescale "1ns/1ns" --timing --binary --top-module testbench fulladder.sv

View File

@ -17,8 +17,7 @@ all: riscoftests memfiles coveragetests
wally-riscv-arch-test: wallyriscoftests memfiles wally-riscv-arch-test: wallyriscoftests memfiles
coverage: coverage: cov/rv64gc_arch64i.ucdb
#make -C ../tests/coverage --jobs
#iter-elf.bash --cover --search ../tests/coverage #iter-elf.bash --cover --search ../tests/coverage
vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb -logfile cov/log
# vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb cov/buildroot_buildroot.ucdb riscv.ucdb -logfile cov/log # vcover merge -out cov/cov.ucdb cov/rv64gc_arch64i.ucdb cov/rv64gc*.ucdb cov/buildroot_buildroot.ucdb riscv.ucdb -logfile cov/log
@ -60,4 +59,4 @@ memfiles:
make -f makefile-memfile wally-sim-files --jobs make -f makefile-memfile wally-sim-files --jobs
coveragetests: coveragetests:
make -C ../tests/coverage/ make -C ../tests/coverage/ --jobs

View File

@ -68,8 +68,9 @@ coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange $sta
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusW"] coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusW"]
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10 coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache SelAdrCauses"] -item e 1 -fecexprrow 4 10
coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12 coverage exclude -scope /dut/core/ifu/bus/icache/icache/cachefsm -linerange [GetLineNum ../src/cache/cachefsm.sv "exclusion-tag: icache CacheBusRCauses"] -item e 1 -fecexprrow 1-2 12
# cache.sv AdrSelMux and CacheBusAdrMux, excluding unhit Flush branch # cache.sv AdrSelMuxData and AdrSelMuxTag and CacheBusAdrMux, excluding unhit Flush branch
coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1 coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxData -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
coverage exclude -scope /dut/core/ifu/bus/icache/icache/AdrSelMuxTag -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1
coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheBusAdrMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1 3 coverage exclude -scope /dut/core/ifu/bus/icache/icache/CacheBusAdrMux -linerange [GetLineNum ../src/generic/mux.sv "exclusion-tag: mux3"] -item b 1 3
# CacheWay Dirty logic. -scope does not accept wildcards. # CacheWay Dirty logic. -scope does not accept wildcards.
set numcacheways 4 set numcacheways 4
@ -106,6 +107,10 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/clintdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/gpiodec coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/gpiodec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uartdec coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uartdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/plicdec coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/plicdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/dtimdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/iromdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec
# PMA Regions 8, 9, and 10 (dtim, irom, ddr4) are never used in the rv64gc configuration, so exclude coverage # PMA Regions 8, 9, and 10 (dtim, irom, ddr4) are never used in the rv64gc configuration, so exclude coverage
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-cachable"] set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-cachable"]
@ -114,19 +119,13 @@ coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$lin
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-idempotent"] set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-idempotent"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4,6 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4,6
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4,6,8 coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4,6,8
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-atomic"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
set line [GetLineNum ../src/mmu/pmachecker.sv "exclusion-tag: unused-tim"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2,4
# Excluding so far un-used instruction sources for the ifu # Excluding so far un-used instruction sources for the ifu
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/bootromdec # coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/bootromdec
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uncoreramdec # coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/uncoreramdec
#Excluding the bootrom, uncoreran, and clint as sources for the lsu #Excluding the bootrom, uncoreran, and clint as sources for the lsu
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/bootromdec
#Excluding signals in lsu: clintdec and uncoreram accept all sizes so 'SizeValid' will never be 0 #Excluding signals in lsu: clintdec and uncoreram accept all sizes so 'SizeValid' will never be 0
set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"] set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"]
@ -134,25 +133,29 @@ coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/clintdec -lin
set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"] set line [GetLineNum ../src/mmu/adrdec.sv "& SizeValid"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uncoreramdec -linerange $line-$line -item e 1 -fecexprrow 5 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uncoreramdec -linerange $line-$line -item e 1 -fecexprrow 5
set line [GetLineNum ../src/mmu/adrdec.sv "& Supported"] # set line [GetLineNum ../src/mmu/adrdec.sv "& Supported"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/gpiodec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/gpiodec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uartdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/uartdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/plicdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/plicdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/dtimdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/iromdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/ddr4dec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3 # coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker/adrdecs/sdcdec -linerange $line-$line -item e 1 -fecexprrow 3
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/dtimdec
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/iromdec
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/ddr4dec
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker/adrdecs/sdcdec
#################### ####################
# Unused access types due to sharing IFU and LSU logic # Unused access types due to sharing IFU and LSU logic
#################### ####################
## The lsu never executes instructions so 'ExecuteAccessF' will never be 1 ## The lsu never executes instructions so 'ExecuteAccessF' will never be 1
set line [GetLineNum ../src/mmu/pmachecker.sv "AccessRWX ="] set line [GetLineNum ../src/mmu/pmachecker.sv "AccessRWXC ="]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 6 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 6
set line [GetLineNum ../src/mmu/pmachecker.sv "ReadAccessM \\| ExecuteAccessF"] set line [GetLineNum ../src/mmu/pmachecker.sv "ReadAccessM \\| ExecuteAccessF"]
coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 4 coverage exclude -scope /dut/core/lsu/dmmu/dmmu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 4
@ -181,9 +184,9 @@ set line [GetLineNum ../src/mmu/pmachecker.sv "ExecuteAccessF & PMAAccessFault"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1 coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 1
set line [GetLineNum ../src/mmu/pmachecker.sv "ReadAccessM & PMAAccessFault"] set line [GetLineNum ../src/mmu/pmachecker.sv "ReadAccessM & PMAAccessFault"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2-4 coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2-4
set line [GetLineNum ../src/mmu/pmachecker.sv "WriteAccessM & PMAAccessFault"] set line [GetLineNum ../src/mmu/pmachecker.sv "PMAStoreAmoAccessFaultM ="]
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 2-4 coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line
set line [GetLineNum ../src/mmu/pmachecker.sv "AccessRWX \\| AtomicAccessM"] set line [GetLineNum ../src/mmu/pmachecker.sv "AccessRWXC \\| AtomicAccessM"]
coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 3 coverage exclude -scope /dut/core/ifu/immu/immu/pmachecker -linerange $line-$line -item e 1 -fecexprrow 3
set line [GetLineNum ../src/mmu/mmu.sv "ExecuteAccessF \\| ReadAccessM"] set line [GetLineNum ../src/mmu/mmu.sv "ExecuteAccessF \\| ReadAccessM"]
coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,3,4 coverage exclude -scope /dut/core/ifu/immu/immu -linerange $line-$line -item e 1 -fecexprrow 1,3,4
@ -231,6 +234,12 @@ coverage exclude -scope /dut/core/ifu -linerange $line-$line -item c 1 -feccondr
set line [GetLineNum ../src/generic/flop/floprc.sv "reset \\| clear"] set line [GetLineNum ../src/generic/flop/floprc.sv "reset \\| clear"]
coverage exclude -scope /dut/core/priv/priv/pmd/wfi/wficountreg -linerange $line-$line -item c 1 -feccondrow 2 coverage exclude -scope /dut/core/priv/priv/pmd/wfi/wficountreg -linerange $line-$line -item c 1 -feccondrow 2
# Exclude system reset case in ebu
set line [GetLineNum ../src/ebu/ebufsmarb.sv "BeatCounter\\("]
coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item e 1 -fecexprrow 1
set line [GetLineNum ../src/ebu/ebufsmarb.sv "FinalBeatReg\\("]
coverage exclude -scope /dut/core/ebu/ebu/ebufsmarb -linerange $line-$line -item e 1 -fecexprrow 1
# TLB not recently used never has all RU bits = 1 because it will then clear all to 0 # TLB not recently used never has all RU bits = 1 because it will then clear all to 0
# This is a blunt instrument; perhaps there is a more graceful exclusion # This is a blunt instrument; perhaps there is a more graceful exclusion
coverage exclude -srcfile priorityonehot.sv coverage exclude -srcfile priorityonehot.sv

View File

@ -51,9 +51,13 @@
--override cpu/unaligned=T # Zicclsm (should be true) --override cpu/unaligned=T # Zicclsm (should be true)
--override cpu/ignore_non_leaf_DAU=1 --override cpu/ignore_non_leaf_DAU=1
--override cpu/wfi_is_nop=T --override cpu/wfi_is_nop=T
--override cpu/misa_Extensions_mask=0x0 --override cpu/misa_Extensions_mask=0x0 # MISA not writable
--override cpu/Sstc=T --override cpu/Sstc=T
# unsuccessfully attempt to add B extension (DH 12/21/23)
#--override cpu/add_Extensions="B"
#--override cpu/misa_Extensions=0x0014112F
# Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1 # Enable SVADU hardware update of A/D bits when menvcfg.ADUE=1
--override cpu/Svadu=T --override cpu/Svadu=T
#--override cpu/updatePTEA=F #--override cpu/updatePTEA=F

View File

@ -78,7 +78,8 @@ for test in tests64i:
configs.append(tc) configs.append(tc)
tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused tests32gcimperas = ["imperas32i", "imperas32f", "imperas32m", "imperas32c"] # unused
tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zi", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "wally32a", "wally32priv", "wally32periph"] tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "wally32a", "wally32priv", "wally32periph"]
#tests32gc = ["arch32f", "arch32d", "arch32f_fma", "arch32d_fma", "arch32i", "arch32priv", "arch32c", "arch32m", "arch32a", "arch32zifencei", "arch32zba", "arch32zbb", "arch32zbc", "arch32zbs", "arch32zicboz", "arch32zcb", "wally32a", "wally32priv", "wally32periph"]
for test in tests32gc: for test in tests32gc:
tc = TestCase( tc = TestCase(
name=test, name=test,
@ -126,15 +127,19 @@ for test in ahbTests:
configs.append(tc) configs.append(tc)
tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs", tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
"arch64priv", "arch64c", "arch64m", "arch64a", "arch64zi", "wally64a", "wally64periph", "wally64priv"] "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv"]
#tests64gc = ["arch64f", "arch64d", "arch64f_fma", "arch64d_fma", "arch64i", "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs",
# "arch64priv", "arch64c", "arch64m", "arch64a", "arch64zifencei", "wally64a", "wally64periph", "wally64priv", "arch64zicboz", "arch64zcb"]
if (coverage): # delete all but 64gc tests when running coverage if (coverage): # delete all but 64gc tests when running coverage
configs = [] configs = []
tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m", tests64gc = ["coverage64gc", "arch64i", "arch64priv", "arch64c", "arch64m",
"arch64zi", "wally64a", "wally64periph", "wally64priv", "arch64zifencei", "wally64a", "wally64periph", "wally64priv",
"arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] "arch64zba", "arch64zbb", "arch64zbc", "arch64zbs"] # add when working: "arch64zicboz", "arch64zcb",
if (fp): if (fp):
tests64gc.append("arch64f") tests64gc.append("arch64f")
tests64gc.append("arch64d") tests64gc.append("arch64d")
tests64gc.append("arch64f_fma")
tests64gc.append("arch64d_fma")
coverStr = '-coverage' coverStr = '-coverage'
else: else:
coverStr = '' coverStr = ''

View File

@ -8,9 +8,11 @@ basepath=$(dirname $0)/..
#for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do #for config in rv32e rv64gc rv32gc rv32imc rv32i rv64i rv64fpquad; do
for config in rv64gc; do for config in rv64gc; do
echo "$config simulating..." echo "$config simulating..."
if !($verilator --timescale "1ns/1ns" --timing --exe --cc "$@" --top-module testbench "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/cvw.sv $basepath/testbench/testbench.sv $basepath/testbench/common/*.sv $basepath/src/*/*.sv $basepath/src/*/*/*.sv --relative-includes ); then # not working: -GTEST="arch64i"
if !($verilator --timescale "1ns/1ns" --timing --binary "$@" --top-module testbench "-I$basepath/config/shared" "-I$basepath/config/$config" $basepath/src/cvw.sv $basepath/testbench/testbench.sv $basepath/testbench/common/*.sv $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"
exit 1 exit 1
fi fi
./obj_dir/Vtestbench
done done
echo "Verilation complete" echo "Verilation complete"

View File

@ -8,11 +8,11 @@ add wave -noupdate /testbench/dut/core/SATP_REGW
add wave -noupdate /testbench/dut/core/InstrValidM add wave -noupdate /testbench/dut/core/InstrValidM
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/RetM add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/RetM
add wave -noupdate -expand -group HDU -group hazards -color Pink /testbench/dut/core/hzu/TrapM add wave -noupdate -expand -group HDU -group hazards -color Pink /testbench/dut/core/hzu/TrapM
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/LoadStallD add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/ieu/c/LoadStallD
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/ifu/IFUStallF add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/ifu/IFUStallF
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/BPWrongE add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/BPWrongE
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/LSUStallM add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/LSUStallM
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/MDUStallD add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/ieu/c/MDUStallD
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/DivBusyE add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/DivBusyE
add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/FDivBusyE add wave -noupdate -expand -group HDU -group hazards /testbench/dut/core/hzu/FDivBusyE
add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM add wave -noupdate -expand -group HDU -group traps /testbench/dut/core/priv/priv/trap/InstrMisalignedFaultM
@ -59,14 +59,13 @@ add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCSrcE
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PC1NextF add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PC1NextF
add wave -noupdate -group {PCNext Generation} -label {NextValidPCE (from bpred)} /testbench/dut/core/ifu/NextValidPCE add wave -noupdate -group {PCNext Generation} -label {NextValidPCE (from bpred)} /testbench/dut/core/ifu/NextValidPCE
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/CSRWriteFenceM add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/CSRWriteFenceM
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/priv/priv/csr/PC2NextF
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/csr/MEPC_REGW add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/csr/MEPC_REGW
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/csr/SEPC_REGW add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/csr/SEPC_REGW
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/csr/mretM add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/csr/mretM
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/csr/EPC add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 -group xepc /testbench/dut/core/priv/priv/EPCM
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/priv/priv/csr/TrapVectorM add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/priv/priv/csr/TrapVectorM
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/priv/priv/csr/TrapM add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/priv/priv/csr/TrapM
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/priv/priv/csr/RetM add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/priv/priv/RetM
add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/ifu/UnalignedPCNextF add wave -noupdate -group {PCNext Generation} -expand -group pcmux3 /testbench/dut/core/ifu/UnalignedPCNextF
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCNextF
add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCF add wave -noupdate -group {PCNext Generation} /testbench/dut/core/ifu/PCF
@ -195,9 +194,9 @@ add wave -noupdate -group {Decode Stage} /testbench/dut/core/ifu/InstrD
add wave -noupdate -group {Decode Stage} /testbench/InstrDName add wave -noupdate -group {Decode Stage} /testbench/InstrDName
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/InstrValidD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/InstrValidD
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/RegWriteD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/RegWriteD
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/dp/RdD add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/RdD
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/dp/Rs1D add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/Rs1D
add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/dp/Rs2D add wave -noupdate -group {Decode Stage} /testbench/dut/core/ieu/c/Rs2D
add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/PCE add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/PCE
add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/InstrE add wave -noupdate -group {Execution Stage} /testbench/dut/core/ifu/InstrE
add wave -noupdate -group {Execution Stage} /testbench/InstrEName add wave -noupdate -group {Execution Stage} /testbench/InstrEName
@ -251,13 +250,12 @@ add wave -noupdate -group lsu /testbench/dut/core/lsu/IEUAdrExtE
add wave -noupdate -group lsu /testbench/dut/core/lsu/IEUAdrExtM add wave -noupdate -group lsu /testbench/dut/core/lsu/IEUAdrExtM
add wave -noupdate -group lsu /testbench/dut/core/lsu/bus/dcache/dcache/NextSet add wave -noupdate -group lsu /testbench/dut/core/lsu/bus/dcache/dcache/NextSet
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheRW add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CacheRW
add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CMOp add wave -noupdate -group lsu -expand -group dcache /testbench/dut/core/lsu/bus/dcache/dcache/CMOpM
add wave -noupdate -group lsu -expand -group dcache -color Gold /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/CurrState add wave -noupdate -group lsu -expand -group dcache -color Gold /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/CurrState
add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetValid add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetValid
add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid
add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty
add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/ClearDirty
add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SelFlush
add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SelWay add wave -noupdate -group lsu -expand -group dcache -group SRAM-update-control /testbench/dut/core/lsu/bus/dcache/dcache/SelWay
add wave -noupdate -group lsu -expand -group dcache -group {requesting address} /testbench/dut/core/lsu/IEUAdrE add wave -noupdate -group lsu -expand -group dcache -group {requesting address} /testbench/dut/core/lsu/IEUAdrE
add wave -noupdate -group lsu -expand -group dcache -group {requesting address} /testbench/dut/core/lsu/bus/dcache/dcache/PAdr add wave -noupdate -group lsu -expand -group dcache -group {requesting address} /testbench/dut/core/lsu/bus/dcache/dcache/PAdr
@ -291,7 +289,6 @@ add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/
add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWayCntEn add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushWayCntEn
add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/FlushAdrCntEn add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/FlushAdrCntEn
add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdrFlag add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/FlushAdrFlag
add wave -noupdate -group lsu -expand -group dcache -group flush /testbench/dut/core/lsu/bus/dcache/dcache/cachefsm/SelFlush
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/SetValid add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/SetValid
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/ClearValid
add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} /testbench/dut/core/lsu/bus/dcache/dcache/SetDirty
@ -626,24 +623,24 @@ add wave -noupdate -group alu /testbench/dut/core/ieu/dp/alu/B
add wave -noupdate -group alu /testbench/dut/core/ieu/dp/alu/ALUResult add wave -noupdate -group alu /testbench/dut/core/ieu/dp/alu/ALUResult
add wave -noupdate -group alu /testbench/dut/core/ieu/dp/alu/BALUControl add wave -noupdate -group alu /testbench/dut/core/ieu/dp/alu/BALUControl
add wave -noupdate -group alu -divider internals add wave -noupdate -group alu -divider internals
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/Rs1D add wave -noupdate -group Forward /testbench/dut/core/ieu/c/Rs1D
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/Rs2D add wave -noupdate -group Forward /testbench/dut/core/ieu/c/Rs2D
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/Rs1E add wave -noupdate -group Forward /testbench/dut/core/ieu/c/Rs1E
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/Rs2E add wave -noupdate -group Forward /testbench/dut/core/ieu/c/Rs2E
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/RdE add wave -noupdate -group Forward /testbench/dut/core/ieu/c/RdE
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/RdM add wave -noupdate -group Forward /testbench/dut/core/ieu/c/RdM
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/RdW add wave -noupdate -group Forward /testbench/dut/core/ieu/c/RdW
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/MemReadE add wave -noupdate -group Forward /testbench/dut/core/ieu/c/MemReadE
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/RegWriteM add wave -noupdate -group Forward /testbench/dut/core/ieu/c/RegWriteM
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/RegWriteW add wave -noupdate -group Forward /testbench/dut/core/ieu/c/RegWriteW
add wave -noupdate -group Forward -color Thistle /testbench/dut/core/ieu/fw/ForwardAE add wave -noupdate -group Forward -color Thistle /testbench/dut/core/ieu/c/ForwardAE
add wave -noupdate -group Forward -color Thistle /testbench/dut/core/ieu/fw/ForwardBE add wave -noupdate -group Forward -color Thistle /testbench/dut/core/ieu/c/ForwardBE
add wave -noupdate -group Forward -color Thistle /testbench/dut/core/ieu/fw/LoadStallD add wave -noupdate -group Forward -color Thistle /testbench/dut/core/ieu/c/LoadStallD
add wave -noupdate -group Forward /testbench/dut/core/ieu/dp/IFResultM add wave -noupdate -group Forward /testbench/dut/core/ieu/dp/IFResultM
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/ForwardAE add wave -noupdate -group Forward /testbench/dut/core/ieu/c/ForwardAE
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/Rs1E add wave -noupdate -group Forward /testbench/dut/core/ieu/c/Rs1E
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/RdM add wave -noupdate -group Forward /testbench/dut/core/ieu/c/RdM
add wave -noupdate -group Forward /testbench/dut/core/ieu/fw/RdW add wave -noupdate -group Forward /testbench/dut/core/ieu/c/RdW
add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/ALUResultE add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/ALUResultE
add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/SrcAE add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/SrcAE
add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/SrcBE add wave -noupdate -group {alu execution stage} /testbench/dut/core/ieu/dp/SrcBE

20
src/cache/cache.sv vendored
View File

@ -34,11 +34,10 @@ module cache import cvw::*; #(parameter cvw_t P,
input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY input logic Stall, // Stall the cache, preventing new accesses. In-flight access finished but does not return to READY
input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations) input logic FlushStage, // Pipeline flush of second stage (prevent writes and bus operations)
// cpu side // cpu side
input logic [1:0] CacheRWNext, // [1] Read, [0] Write
input logic [1:0] CacheRW, // [1] Read, [0] Write input logic [1:0] CacheRW, // [1] Read, [0] Write
input logic FlushCache, // Flush all dirty lines back to memory input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, // Clear all valid bits input logic InvalidateCache, // Clear all valid bits
input logic [3:0] CMOp, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero input logic [3:0] CMOpM, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits. input logic [11:0] NextSet, // Virtual address, but we only use the lower 12 bits.
input logic [PA_BITS-1:0] PAdr, // Physical address input logic [PA_BITS-1:0] PAdr, // Physical address
input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only) input logic [(WORDLEN-1)/8:0] ByteMask, // Which bytes to write (D$ only)
@ -94,7 +93,6 @@ module cache import cvw::*; #(parameter cvw_t P,
logic FlushWayCntEn; logic FlushWayCntEn;
logic SelWriteback; logic SelWriteback;
logic LRUWriteEn; logic LRUWriteEn;
logic SelFlush;
logic ResetOrFlushCntRst; logic ResetOrFlushCntRst;
logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache; logic [LINELEN-1:0] ReadDataLine, ReadDataLineCache;
logic SelFetchBuffer; logic SelFetchBuffer;
@ -112,10 +110,10 @@ module cache import cvw::*; #(parameter cvw_t P,
// and FlushAdr when handling D$ flushes // and FlushAdr when handling D$ flushes
// The icache must update to the newest PCNextF on flush as it is probably a trap. Trap // The icache must update to the newest PCNextF on flush as it is probably a trap. Trap
// sets PCNextF to XTVEC and the icache must start reading the instruction. // sets PCNextF to XTVEC and the icache must start reading the instruction.
assign AdrSelMuxSelData = {SelFlush, ((SelAdrData | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))}; assign AdrSelMuxSelData = {FlushCache, ((SelAdrData | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))};
mux3 #(SETLEN) AdrSelMuxData(NextSet[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr, mux3 #(SETLEN) AdrSelMuxData(NextSet[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr,
AdrSelMuxSelData, CacheSetData); AdrSelMuxSelData, CacheSetData);
assign AdrSelMuxSelTag = {SelFlush, ((SelAdrTag | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))}; assign AdrSelMuxSelTag = {FlushCache, ((SelAdrTag | SelHPTW) & ~((READ_ONLY_CACHE == 1) & FlushStage))};
mux3 #(SETLEN) AdrSelMuxTag(NextSet[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr, mux3 #(SETLEN) AdrSelMuxTag(NextSet[SETTOP-1:OFFSETLEN], PAdr[SETTOP-1:OFFSETLEN], FlushAdr,
AdrSelMuxSelTag, CacheSetTag); AdrSelMuxSelTag, CacheSetTag);
@ -123,7 +121,7 @@ module cache import cvw::*; #(parameter cvw_t P,
cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0]( cacheway #(P, PA_BITS, XLEN, NUMLINES, LINELEN, TAGLEN, OFFSETLEN, SETLEN, READ_ONLY_CACHE) CacheWays[NUMWAYS-1:0](
.clk, .reset, .CacheEn, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelWay, .clk, .reset, .CacheEn, .CacheSetData, .CacheSetTag, .PAdr, .LineWriteData, .LineByteMask, .SelWay,
.SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay, .SetValid, .ClearValid, .SetDirty, .ClearDirty, .VictimWay,
.FlushWay, .SelFlush, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache); .FlushWay, .FlushCache, .ReadDataLineWay, .HitWay, .ValidWay, .DirtyWay, .HitDirtyWay, .TagWay, .FlushStage, .InvalidateCache);
// Select victim way for associative caches // Select victim way for associative caches
if(NUMWAYS > 1) begin:vict if(NUMWAYS > 1) begin:vict
@ -162,7 +160,7 @@ module cache import cvw::*; #(parameter cvw_t P,
mux3 #(PA_BITS) CacheBusAdrMux(.d0({PAdr[PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}), mux3 #(PA_BITS) CacheBusAdrMux(.d0({PAdr[PA_BITS-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
.d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}), .d1({Tag, PAdr[SETTOP-1:OFFSETLEN], {OFFSETLEN{1'b0}}}),
.d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}), .d2({Tag, FlushAdr, {OFFSETLEN{1'b0}}}),
.s({SelFlush, SelWriteback}), .y(CacheBusAdr)); .s({FlushCache, SelWriteback}), .y(CacheBusAdr));
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Write Path // Write Path
@ -186,7 +184,7 @@ module cache import cvw::*; #(parameter cvw_t P,
// Merge write data into fetched cache line for store miss // Merge write data into fetched cache line for store miss
for(index = 0; index < LINELEN/8; index++) begin for(index = 0; index < LINELEN/8; index++) begin
mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]), mux2 #(8) WriteDataMux(.d0(CacheWriteData[(8*index)%WORDLEN+7:(8*index)%WORDLEN]),
.d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOp[3]), .y(LineWriteData[8*index+7:8*index])); .d1(FetchBuffer[8*index+7:8*index]), .s(FetchBufferByteSel[index] & ~CMOpM[3]), .y(LineWriteData[8*index+7:8*index]));
end end
assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0; assign LineByteMask = SetValid ? '1 : SetDirty ? DemuxedByteMask : '0;
end end
@ -225,11 +223,11 @@ module cache import cvw::*; #(parameter cvw_t P,
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck, cachefsm #(P, READ_ONLY_CACHE) cachefsm(.clk, .reset, .CacheBusRW, .CacheBusAck,
.FlushStage, .CacheRW, .CacheRWNext, .Stall, .FlushStage, .CacheRW, .Stall,
.CacheHit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted, .CacheHit, .LineDirty, .HitLineDirty, .CacheStall, .CacheCommitted,
.CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelWay, .CacheMiss, .CacheAccess, .SelAdrData, .SelAdrTag, .SelWay,
.ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback, .SelFlush, .ClearDirty, .SetDirty, .SetValid, .ClearValid, .SelWriteback,
.FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst, .FlushAdrCntEn, .FlushWayCntEn, .FlushCntRst,
.FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer, .FlushAdrFlag, .FlushWayFlag, .FlushCache, .SelFetchBuffer,
.InvalidateCache, .CMOp, .CacheEn, .LRUWriteEn); .InvalidateCache, .CMOpM, .CacheEn, .LRUWriteEn);
endmodule endmodule

46
src/cache/cachefsm.sv vendored
View File

@ -38,10 +38,9 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
output logic CacheStall, // Cache stalls pipeline during multicycle operation output logic CacheStall, // Cache stalls pipeline during multicycle operation
// inputs from IEU // inputs from IEU
input logic [1:0] CacheRW, // [1] Read, [0] Write input logic [1:0] CacheRW, // [1] Read, [0] Write
input logic [1:0] CacheRWNext, // [1] Read, [0] Write
input logic FlushCache, // Flush all dirty lines back to memory input logic FlushCache, // Flush all dirty lines back to memory
input logic InvalidateCache, // Clear all valid bits input logic InvalidateCache, // Clear all valid bits
input logic [3:0] CMOp, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero input logic [3:0] CMOpM, // 0001: cbo.inval; 0010: cbo.flush; 0100: cbo.clean; 1000: cbo.zero
// Bus controls // Bus controls
input logic CacheBusAck, // Bus operation completed input logic CacheBusAck, // Bus operation completed
output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback) output logic [1:0] CacheBusRW, // [1] Read (cache line fetch) or [0] write bus (cache line writeback)
@ -63,7 +62,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
output logic ClearDirty, // Clear the dirty bit in the selected way and set output logic ClearDirty, // Clear the dirty bit in the selected way and set
output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback output logic SelWriteback, // Overrides cached tag check to select a specific way and set for writeback
output logic LRUWriteEn, // Update the LRU state output logic LRUWriteEn, // Update the LRU state
output logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
output logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway output logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway
output logic FlushAdrCntEn, // Enable the counter for Flush Adr output logic FlushAdrCntEn, // Enable the counter for Flush Adr
output logic FlushWayCntEn, // Enable the way counter during a flush output logic FlushWayCntEn, // Enable the way counter during a flush
@ -79,7 +77,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
logic CMOWriteback; logic CMOWriteback;
logic CMOZeroNoEviction; logic CMOZeroNoEviction;
logic StallConditions; logic StallConditions;
logic StoreHazard;
typedef enum logic [3:0]{STATE_READY, // hit states typedef enum logic [3:0]{STATE_READY, // hit states
// miss states // miss states
@ -97,8 +94,8 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss assign AnyMiss = (CacheRW[0] | CacheRW[1]) & ~CacheHit & ~InvalidateCache; // exclusion-tag: cache AnyMiss
assign AnyUpdateHit = (CacheRW[0]) & CacheHit; // exclusion-tag: icache storeAMO1 assign AnyUpdateHit = (CacheRW[0]) & CacheHit; // exclusion-tag: icache storeAMO1
assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit assign AnyHit = AnyUpdateHit | (CacheRW[1] & CacheHit); // exclusion-tag: icache AnyUpdateHit
assign CMOZeroNoEviction = CMOp[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now assign CMOZeroNoEviction = CMOpM[3] & ~LineDirty; // (hit or miss) with no writeback store zeros now
assign CMOWriteback = ((CMOp[1] | CMOp[2]) & CacheHit & HitLineDirty) | CMOp[3] & LineDirty; assign CMOWriteback = ((CMOpM[1] | CMOpM[2]) & CacheHit & HitLineDirty) | CMOpM[3] & LineDirty;
assign FlushFlag = FlushAdrFlag & FlushWayFlag; assign FlushFlag = FlushAdrFlag & FlushWayFlag;
@ -106,8 +103,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW assign CacheAccess = (|CacheRW) & ((CurrState == STATE_READY & ~Stall & ~FlushStage) | (CurrState == STATE_READ_HOLD & ~Stall & ~FlushStage)); // exclusion-tag: icache CacheW
assign CacheMiss = CacheAccess & ~CacheHit; assign CacheMiss = CacheAccess & ~CacheHit;
assign StoreHazard = CacheRWNext[1] & CacheRW[0] & ~CacheRW[1];
// special case on reset. When the fsm first exists reset the // special case on reset. When the fsm first exists reset the
// PCNextF will no longer be pointing to the correct address. // PCNextF will no longer be pointing to the correct address.
// But PCF will be the reset vector. // But PCF will be the reset vector.
@ -124,7 +119,6 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH; else if(FlushCache & ~READ_ONLY_CACHE) NextState = STATE_FLUSH;
else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement else if(AnyMiss & (READ_ONLY_CACHE | ~LineDirty)) NextState = STATE_FETCH; // exclusion-tag: icache FETCHStatement
else if(AnyMiss | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement else if(AnyMiss | CMOWriteback) NextState = STATE_WRITEBACK; // exclusion-tag: icache WRITEBACKStatement
else if(StoreHazard) NextState = STATE_READ_HOLD;
else NextState = STATE_READY; else NextState = STATE_READY;
STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE; STATE_FETCH: if(CacheBusAck) NextState = STATE_WRITE_LINE;
else if(CacheBusAck) NextState = STATE_READY; else if(CacheBusAck) NextState = STATE_READY;
@ -133,7 +127,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD; STATE_READ_HOLD: if(Stall) NextState = STATE_READ_HOLD;
else NextState = STATE_READY; else NextState = STATE_READY;
// exclusion-tag-start: icache case // exclusion-tag-start: icache case
STATE_WRITEBACK: if(CacheBusAck & ~(|CMOp[3:1])) NextState = STATE_FETCH; STATE_WRITEBACK: if(CacheBusAck & ~(|CMOpM[3:1])) NextState = STATE_FETCH;
else if(CacheBusAck) NextState = STATE_READ_HOLD; // Read_hold lowers CacheStall else if(CacheBusAck) NextState = STATE_READ_HOLD; // Read_hold lowers CacheStall
else NextState = STATE_WRITEBACK; else NextState = STATE_WRITEBACK;
// eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack. // eviction needs a delay as the bus fsm does not correctly handle sending the write command at the same time as getting back the bus ack.
@ -150,7 +144,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
// com back to CPU // com back to CPU
assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD)); assign CacheCommitted = (CurrState != STATE_READY) & ~(READ_ONLY_CACHE & (CurrState == STATE_READ_HOLD));
assign StallConditions = FlushCache | AnyMiss | CMOWriteback | (StoreHazard); assign StallConditions = FlushCache | AnyMiss | CMOWriteback;
assign CacheStall = (CurrState == STATE_READY & StallConditions) | // exclusion-tag: icache StallStates assign CacheStall = (CurrState == STATE_READY & StallConditions) | // exclusion-tag: icache StallStates
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
@ -160,32 +154,26 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
// write enables internal to cache // write enables internal to cache
assign SetValid = CurrState == STATE_WRITE_LINE | assign SetValid = CurrState == STATE_WRITE_LINE |
(CurrState == STATE_READY & CMOZeroNoEviction) | (CurrState == STATE_READY & CMOZeroNoEviction) |
(CurrState == STATE_WRITEBACK & CacheBusAck & CMOp[3]); (CurrState == STATE_WRITEBACK & CacheBusAck & CMOpM[3]);
assign ClearValid = (CurrState == STATE_READY & CMOp[0]) | assign ClearValid = (CurrState == STATE_READY & CMOpM[0]) |
(CurrState == STATE_WRITEBACK & CMOp[2] & CacheBusAck); (CurrState == STATE_WRITEBACK & CMOpM[2] & CacheBusAck);
// coverage off -item e 1 -fecexprrow 8 // coverage off -item e 1 -fecexprrow 8
assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) | assign LRUWriteEn = (((CurrState == STATE_READY & (AnyHit | CMOZeroNoEviction)) |
(CurrState == STATE_WRITE_LINE)) & ~FlushStage) | (CurrState == STATE_WRITE_LINE)) & ~FlushStage) |
(CurrState == STATE_WRITEBACK & CMOp[3] & CacheBusAck); (CurrState == STATE_WRITEBACK & CMOpM[3] & CacheBusAck);
// exclusion-tag-start: icache flushdirtycontrols // exclusion-tag-start: icache flushdirtycontrols
assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty assign SetDirty = (CurrState == STATE_READY & (AnyUpdateHit | CMOZeroNoEviction)) | // exclusion-tag: icache SetDirty
(CurrState == STATE_WRITE_LINE & (CacheRW[0])) | (CurrState == STATE_WRITE_LINE & (CacheRW[0])) |
(CurrState == STATE_WRITEBACK & (CMOp[3] & CacheBusAck)); (CurrState == STATE_WRITEBACK & (CMOpM[3] & CacheBusAck));
assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty assign ClearDirty = (CurrState == STATE_WRITE_LINE & ~(CacheRW[0])) | // exclusion-tag: icache ClearDirty
(CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set. (CurrState == STATE_FLUSH & LineDirty) | // This is wrong in a multicore snoop cache protocal. Dirty must be cleared concurrently and atomically with writeback. For single core cannot clear after writeback on bus ack and change flushadr. Clears the wrong set.
// Flush and eviction controls // Flush and eviction controls
CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]) & CacheBusAck; CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & CacheBusAck;
assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOp[1] | CMOp[2])) | (CacheBusAck & CMOp[3]))) | assign SelWay = (CurrState == STATE_WRITEBACK & ((~CacheBusAck & ~(CMOpM[1] | CMOpM[2])) | (CacheBusAck & CMOpM[3]))) |
(CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) | (CurrState == STATE_READY & ((AnyMiss & LineDirty) | (CMOZeroNoEviction & ~CacheHit))) |
(CurrState == STATE_WRITE_LINE); (CurrState == STATE_WRITE_LINE);
assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2] | ~CacheBusAck)) | assign SelWriteback = (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2] | ~CacheBusAck)) |
(CurrState == STATE_READY & AnyMiss & LineDirty); (CurrState == STATE_READY & AnyMiss & LineDirty);
/* -----\/----- EXCLUDED -----\/-----
assign SelFlush = (CurrState == STATE_READY & FlushCache) |
(CurrState == STATE_FLUSH) |
(CurrState == STATE_FLUSH_WRITEBACK);
-----/\----- EXCLUDED -----/\----- */
assign SelFlush = FlushCache;
// coverage off -item e 1 -fecexprrow 1 // coverage off -item e 1 -fecexprrow 1
// (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck) // (state is always FLUSH_WRITEBACK when FlushWayFlag & CacheBusAck)
assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) | assign FlushAdrCntEn = (CurrState == STATE_FLUSH_WRITEBACK & FlushWayFlag & CacheBusAck) |
@ -198,7 +186,7 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
// Bus interface controls // Bus interface controls
assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses assign CacheBusRW[1] = (CurrState == STATE_READY & AnyMiss & ~LineDirty) | // exclusion-tag: icache CacheBusRCauses
(CurrState == STATE_FETCH & ~CacheBusAck) | (CurrState == STATE_FETCH & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOp)); (CurrState == STATE_WRITEBACK & CacheBusAck & ~(|CMOpM));
logic LoadMiss; logic LoadMiss;
@ -208,14 +196,14 @@ module cachefsm import cvw::*; #(parameter cvw_t P,
assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW assign CacheBusRW[0] = (CurrState == STATE_READY & LoadMiss & LineDirty) | // exclusion-tag: icache CacheBusW
(CurrState == STATE_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) | (CurrState == STATE_FLUSH_WRITEBACK & ~CacheBusAck) |
(CurrState == STATE_WRITEBACK & (CMOp[1] | CMOp[2]) & ~CacheBusAck); (CurrState == STATE_WRITEBACK & (CMOpM[1] | CMOpM[2]) & ~CacheBusAck);
assign SelAdrData = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOp))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed assign SelAdrData = (CurrState == STATE_READY & (CacheRW[0] | AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) |
resetDelay; resetDelay;
assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOp))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed assign SelAdrTag = (CurrState == STATE_READY & (AnyMiss | (|CMOpM))) | // exclusion-tag: icache SelAdrCauses // changes if store delay hazard removed
(CurrState == STATE_FETCH) | (CurrState == STATE_FETCH) |
(CurrState == STATE_WRITEBACK) | (CurrState == STATE_WRITEBACK) |
(CurrState == STATE_WRITE_LINE) | (CurrState == STATE_WRITE_LINE) |

View File

@ -43,7 +43,7 @@ module cacheway import cvw::*; #(parameter cvw_t P,
input logic SetDirty, // Set the dirty bit in the selected way and set input logic SetDirty, // Set the dirty bit in the selected way and set
input logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway input logic SelWay, // Controls which way to select a way data and tag, 00 = hitway, 10 = victimway, 11 = flushway
input logic ClearDirty, // Clear the dirty bit in the selected way and set input logic ClearDirty, // Clear the dirty bit in the selected way and set
input logic SelFlush, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr input logic FlushCache, // [0] Use SelAdr, [1] SRAM reads/writes from FlushAdr
input logic VictimWay, // LRU selected this way as victim to evict input logic VictimWay, // LRU selected this way as victim to evict
input logic FlushWay, // This way is selected for flush and possible writeback if dirty input logic FlushWay, // This way is selected for flush and possible writeback if dirty
input logic InvalidateCache,// Clear all valid bits input logic InvalidateCache,// Clear all valid bits
@ -80,12 +80,12 @@ module cacheway import cvw::*; #(parameter cvw_t P,
if (!READ_ONLY_CACHE) begin:flushlogic if (!READ_ONLY_CACHE) begin:flushlogic
logic FlushWayEn; logic FlushWayEn;
mux2 #(1) seltagmux(VictimWay, FlushWay, SelFlush, SelDirty); mux2 #(1) seltagmux(VictimWay, FlushWay, FlushCache, SelDirty);
// FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected. // FlushWay is part of a one hot way selection. Must clear it if FlushWay not selected.
// coverage off -item e 1 -fecexprrow 3 // coverage off -item e 1 -fecexprrow 3
// nonzero ways will never see SelFlush=0 while FlushWay=1 since FlushWay only advances on a subset of SelFlush assertion cases. // nonzero ways will never see FlushCache=0 while FlushWay=1 since FlushWay only advances on a subset of FlushCache assertion cases.
assign FlushWayEn = FlushWay & SelFlush; assign FlushWayEn = FlushWay & FlushCache;
assign SelNonHit = FlushWayEn | SelWay; assign SelNonHit = FlushWayEn | SelWay;
end else begin:flushlogic // no flush operation for read-only caches. end else begin:flushlogic // no flush operation for read-only caches.
assign SelDirty = VictimWay; assign SelDirty = VictimWay;

View File

@ -65,6 +65,7 @@ module ahbcacheinterface #(
input logic [PA_BITS-1:0] PAdr, // Physical address of uncached memory operation input logic [PA_BITS-1:0] PAdr, // Physical address of uncached memory operation
input logic [LLEN-1:0] WriteDataM, // IEU write data for uncached store input logic [LLEN-1:0] WriteDataM, // IEU write data for uncached store
input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write
input logic BusAtomic, // Uncache atomic memory operation
input logic [2:0] Funct3, // Size of uncached memory operation input logic [2:0] Funct3, // Size of uncached memory operation
input logic BusCMOZero, // Uncached cbo.zero must write zero to full sized cacheline without going through the cache input logic BusCMOZero, // Uncached cbo.zero must write zero to full sized cacheline without going through the cache
@ -121,7 +122,7 @@ module ahbcacheinterface #(
flopen #(AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[AHBW/8-1:0], HWSTRB); flopen #(AHBW/8) HWSTRBReg(HCLK, HREADY, BusByteMaskM[AHBW/8-1:0], HWSTRB);
buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm( buscachefsm #(BeatCountThreshold, AHBWLOGBWPL, READ_ONLY_CACHE) AHBBuscachefsm(
.HCLK, .HRESETn, .Flush, .BusRW, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat, .HCLK, .HRESETn, .Flush, .BusRW, .BusAtomic, .Stall, .BusCommitted, .BusStall, .CaptureEn, .SelBusBeat,
.CacheBusRW, .BusCMOZero, .CacheBusAck, .BeatCount, .BeatCountDelayed, .CacheBusRW, .BusCMOZero, .CacheBusAck, .BeatCount, .BeatCountDelayed,
.HREADY, .HTRANS, .HWRITE, .HBURST); .HREADY, .HTRANS, .HWRITE, .HBURST);
endmodule endmodule

View File

@ -42,6 +42,7 @@ module buscachefsm #(
input logic Stall, // Core pipeline is stalled input logic Stall, // Core pipeline is stalled
input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting input logic Flush, // Pipeline stage flush. Prevents bus transaction from starting
input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write input logic [1:0] BusRW, // Uncached memory operation read/write control: 10: read, 01: write
input logic BusAtomic, // Uncache atomic memory operation
input logic BusCMOZero, // Uncached cbo.zero must write zero to full sized cacheline without going through the cache input logic BusCMOZero, // Uncached cbo.zero must write zero to full sized cacheline without going through the cache
output logic BusStall, // Bus is busy with an in flight memory operation output logic BusStall, // Bus is busy with an in flight memory operation
output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt output logic BusCommitted, // Bus is busy with an in flight memory operation and it is not safe to take an interrupt
@ -65,7 +66,7 @@ module buscachefsm #(
output logic [2:0] HBURST // AHB burst length output logic [2:0] HBURST // AHB burst length
); );
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype; typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, ATOMIC_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype;
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype; typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
busstatetype CurrState, NextState; busstatetype CurrState, NextState;
@ -87,21 +88,25 @@ module buscachefsm #(
always_comb begin always_comb begin
case(CurrState) case(CurrState)
ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE; ADR_PHASE: if (HREADY & |BusRW) NextState = DATA_PHASE;
else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK; else if (HREADY & BusWrite) NextState = CACHE_WRITEBACK;
else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH; else if (HREADY & CacheBusRW[1]) NextState = CACHE_FETCH;
else NextState = ADR_PHASE; else NextState = ADR_PHASE;
DATA_PHASE: if(HREADY) NextState = MEM3; DATA_PHASE: if(HREADY & BusAtomic) NextState = ATOMIC_PHASE;
else NextState = DATA_PHASE; else if(HREADY & ~BusAtomic) NextState = MEM3;
MEM3: if(Stall) NextState = MEM3; else NextState = DATA_PHASE;
else NextState = ADR_PHASE; ATOMIC_PHASE: if(HREADY) NextState = MEM3;
CACHE_FETCH: if(HREADY & FinalBeatCount & BusWrite) NextState = CACHE_WRITEBACK; else NextState = ATOMIC_PHASE;
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; MEM3: if(Stall) NextState = MEM3;
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; else NextState = ADR_PHASE;
else NextState = CACHE_FETCH; CACHE_FETCH: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
CACHE_WRITEBACK: if(HREADY & FinalBeatCount & BusWrite) NextState = CACHE_WRITEBACK; else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH; else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE; else NextState = CACHE_FETCH;
else NextState = CACHE_WRITEBACK; CACHE_WRITEBACK: if(HREADY & FinalBeatCount & CacheBusRW[0]) NextState = CACHE_WRITEBACK;
else if(HREADY & FinalBeatCount & CacheBusRW[1]) NextState = CACHE_FETCH;
else if(HREADY & FinalBeatCount & BusCMOZero) NextState = MEM3;
else if(HREADY & FinalBeatCount & ~|CacheBusRW) NextState = ADR_PHASE;
else NextState = CACHE_WRITEBACK;
default: NextState = ADR_PHASE; default: NextState = ADR_PHASE;
endcase endcase
end end
@ -120,19 +125,23 @@ module buscachefsm #(
assign CaptureEn = (CurrState == DATA_PHASE & BusRW[1] & ~Flush) | (CurrState == CACHE_FETCH & HREADY); assign CaptureEn = (CurrState == DATA_PHASE & BusRW[1] & ~Flush) | (CurrState == CACHE_FETCH & HREADY);
assign CacheAccess = CurrState == CACHE_FETCH | CurrState == CACHE_WRITEBACK; assign CacheAccess = CurrState == CACHE_FETCH | CurrState == CACHE_WRITEBACK;
assign BusStall = (CurrState == ADR_PHASE & ((|BusRW) | (|CacheBusRW))) | assign BusStall = (CurrState == ADR_PHASE & ((|BusRW) | (|CacheBusRW) | BusCMOZero)) |
//(CurrState == DATA_PHASE & ~BusRW[0]) | // *** replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem. //(CurrState == DATA_PHASE & ~BusRW[0]) | // *** replace the next line with this. Fails uart test but i think it's a test problem not a hardware problem.
(CurrState == DATA_PHASE) | (CurrState == DATA_PHASE) |
(CurrState == CACHE_FETCH & ~HREADY) | (CurrState == ATOMIC_PHASE) |
(CurrState == CACHE_WRITEBACK & ~HREADY); (CurrState == CACHE_FETCH & ~FinalBeatCount) |
(CurrState == CACHE_WRITEBACK & ~FinalBeatCount);
assign BusCommitted = (CurrState != ADR_PHASE) & ~(READ_ONLY_CACHE & CurrState == MEM3); assign BusCommitted = (CurrState != ADR_PHASE) & ~(READ_ONLY_CACHE & CurrState == MEM3);
// AHB bus interface // AHB bus interface
assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW)) & ~Flush) | assign HTRANS = (CurrState == ADR_PHASE & HREADY & ((|BusRW) | (|CacheBusRW) | BusCMOZero) & ~Flush) |
(CurrState == DATA_PHASE & BusAtomic) |
(CacheAccess & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request (CacheAccess & FinalBeatCount & |CacheBusRW & HREADY & ~Flush) ? AHB_NONSEQ : // if we have a pipelined request
(CacheAccess & |BeatCount) ? (`BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE; (CacheAccess & |BeatCount) ? (`BURST_EN ? AHB_SEQ : AHB_NONSEQ) : AHB_IDLE;
assign HWRITE = (BusRW[0] | BusWrite & ~Flush) | (CurrState == CACHE_WRITEBACK & |BeatCount); assign HWRITE = ((BusRW[0] & ~BusAtomic) | BusWrite & ~Flush) | (CurrState == DATA_PHASE & BusAtomic) |
(CurrState == CACHE_WRITEBACK & |BeatCount);
assign HBURST = `BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0; assign HBURST = `BURST_EN & ((|CacheBusRW & ~Flush) | (CacheAccess & |BeatCount)) ? LocalBurstType : 3'b0;
always_comb begin always_comb begin
@ -149,6 +158,7 @@ module buscachefsm #(
assign CacheBusAck = (CacheAccess & HREADY & FinalBeatCount & ~BusCMOZero); assign CacheBusAck = (CacheAccess & HREADY & FinalBeatCount & ~BusCMOZero);
assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | BusWrite)) | assign SelBusBeat = (CurrState == ADR_PHASE & (BusRW[0] | BusWrite)) |
(CurrState == DATA_PHASE & BusRW[0]) | (CurrState == DATA_PHASE & BusRW[0]) |
(CurrState == ATOMIC_PHASE & BusRW[0]) |
(CurrState == CACHE_WRITEBACK) | (CurrState == CACHE_WRITEBACK) |
(CurrState == CACHE_FETCH); (CurrState == CACHE_FETCH);

View File

@ -28,9 +28,9 @@
module hazard import cvw::*; #(parameter cvw_t P) ( module hazard import cvw::*; #(parameter cvw_t P) (
input logic BPWrongE, CSRWriteFenceM, RetM, TrapM, input logic BPWrongE, CSRWriteFenceM, RetM, TrapM,
input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD, input logic StructuralStallD,
input logic LSUStallM, IFUStallF, input logic LSUStallM, IFUStallF,
input logic FCvtIntStallD, FPUStallD, input logic FPUStallD,
input logic DivBusyE, FDivBusyE, input logic DivBusyE, FDivBusyE,
input logic wfiM, IntPendingM, input logic wfiM, IntPendingM,
// Stall & flush outputs // Stall & flush outputs
@ -82,7 +82,7 @@ module hazard import cvw::*; #(parameter cvw_t P) (
// The IFU stalls the entire pipeline rather than just Fetch to avoid complications with instructions later in the pipeline causing Exceptions // The IFU stalls the entire pipeline rather than just Fetch to avoid complications with instructions later in the pipeline causing Exceptions
// A trap could be asserted at the start of a IFU/LSU stall, and should flush the memory operation // A trap could be asserted at the start of a IFU/LSU stall, and should flush the memory operation
assign StallFCause = '0; assign StallFCause = '0;
assign StallDCause = (LoadStallD | StoreStallD | MDUStallD | CSRRdStallD | FCvtIntStallD | FPUStallD) & ~FlushDCause; assign StallDCause = (StructuralStallD | FPUStallD) & ~FlushDCause;
assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause; assign StallECause = (DivBusyE | FDivBusyE) & ~FlushECause;
assign StallMCause = WFIStallM & ~FlushMCause; assign StallMCause = WFIStallM & ~FlushMCause;
// Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1. // Need to gate IFUStallF when the equivalent FlushFCause = FlushDCause = 1.

View File

@ -27,8 +27,8 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) ( module alu import cvw::*; #(parameter cvw_t P) (
input logic [WIDTH-1:0] A, B, // Operands input logic [P.XLEN-1:0] A, B, // Operands
input logic W64, // W64-type instruction input logic W64, // W64-type instruction
input logic SubArith, // Subtraction or arithmetic shift input logic SubArith, // Subtraction or arithmetic shift
input logic [2:0] ALUSelect, // ALU mux select signal input logic [2:0] ALUSelect, // ALU mux select signal
@ -37,14 +37,14 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
input logic [2:0] Funct3, // For BMU decoding input logic [2:0] Funct3, // For BMU decoding
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
input logic BMUActiveE, // Bit manipulation instruction being executed input logic BMUActiveE, // Bit manipulation instruction being executed
output logic [WIDTH-1:0] ALUResult, // ALU result output logic [P.XLEN-1:0] ALUResult, // ALU result
output logic [WIDTH-1:0] Sum); // Sum of operands output logic [P.XLEN-1:0] Sum); // Sum of operands
// CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction. // CondInvB = ~B when subtracting, B otherwise. Shift = shift result. SLT/U = result of a slt/u instruction.
// FullResult = ALU result before adjusting for a RV64 w-suffix instruction. // FullResult = ALU result before adjusting for a RV64 w-suffix instruction.
logic [WIDTH-1:0] CondMaskInvB, Shift, FullResult, PreALUResult; // Intermediate Signals logic [P.XLEN-1:0] CondMaskInvB, Shift, FullResult, PreALUResult; // Intermediate Signals
logic [WIDTH-1:0] CondMaskB; // Result of B mask select mux logic [P.XLEN-1:0] CondMaskB; // Result of B mask select mux
logic [WIDTH-1:0] CondShiftA; // Result of A shifted select mux logic [P.XLEN-1:0] CondShiftA; // Result of A shifted select mux
logic Carry, Neg; // Flags: carry out, negative logic Carry, Neg; // Flags: carry out, negative
logic LT, LTU; // Less than, Less than unsigned logic LT, LTU; // Less than, Less than unsigned
logic Asign, Bsign; // Sign bits of A, B logic Asign, Bsign; // Sign bits of A, B
@ -53,7 +53,7 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
// CondMaskB is B for add/sub, or a masked version of B for certain bit manipulation instructions // CondMaskB is B for add/sub, or a masked version of B for certain bit manipulation instructions
// CondShiftA is A for add/sub or a shifted version of A for shift-and-add BMU instructions // CondShiftA is A for add/sub or a shifted version of A for shift-and-add BMU instructions
assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB; assign CondMaskInvB = SubArith ? ~CondMaskB : CondMaskB;
assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(WIDTH-1){1'b0}}, SubArith}; assign {Carry, Sum} = CondShiftA + CondMaskInvB + {{(P.XLEN-1){1'b0}}, SubArith};
// Shifts (configurable for rotation) // Shifts (configurable for rotation)
shifter #(P) sh(.A, .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2])); shifter #(P) sh(.A, .Amt(B[P.LOG_XLEN-1:0]), .Right(Funct3[2]), .W64, .SubArith, .Y(Shift), .Rotate(BALUControl[2]));
@ -62,9 +62,9 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
// Overflow occurs when the numbers being subtracted have the opposite sign // Overflow occurs when the numbers being subtracted have the opposite sign
// and the result has the opposite sign of A. // and the result has the opposite sign of A.
// LT is simplified from Overflow = Asign & Bsign & Asign & Neg; LT = Neg ^ Overflow // LT is simplified from Overflow = Asign & Bsign & Asign & Neg; LT = Neg ^ Overflow
assign Neg = Sum[WIDTH-1]; assign Neg = Sum[P.XLEN-1];
assign Asign = A[WIDTH-1]; assign Asign = A[P.XLEN-1];
assign Bsign = B[WIDTH-1]; assign Bsign = B[P.XLEN-1];
assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg; assign LT = Asign & ~Bsign | Asign & Neg | ~Bsign & Neg;
assign LTU = ~Carry; assign LTU = ~Carry;
@ -73,21 +73,22 @@ module alu import cvw::*; #(parameter cvw_t P, parameter WIDTH) (
case (ALUSelect) case (ALUSelect)
3'b000: FullResult = Sum; // add or sub (including address generation) 3'b000: FullResult = Sum; // add or sub (including address generation)
3'b001: FullResult = Shift; // sll, sra, or srl 3'b001: FullResult = Shift; // sll, sra, or srl
3'b010: FullResult = {{(WIDTH-1){1'b0}}, LT}; // slt 3'b010: FullResult = {{(P.XLEN-1){1'b0}}, LT}; // slt
3'b011: FullResult = {{(WIDTH-1){1'b0}}, LTU}; // sltu 3'b011: FullResult = {{(P.XLEN-1){1'b0}}, LTU}; // sltu
3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv 3'b100: FullResult = A ^ CondMaskInvB; // xor, xnor, binv
3'b101: FullResult = (P.ZBS_SUPPORTED | P.ZBB_SUPPORTED) ? {{(WIDTH-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported) 3'b101: FullResult = (P.ZBS_SUPPORTED | P.ZBB_SUPPORTED) ? {{(P.XLEN-1){1'b0}},{|(A & CondMaskB)}} : Shift; // bext (or IEU shift when BMU not supported)
3'b110: FullResult = A | CondMaskInvB; // or, orn, bset 3'b110: FullResult = A | CondMaskInvB; // or, orn, bset
3'b111: FullResult = A & CondMaskInvB; // and, bclr 3'b111: FullResult = A & CondMaskInvB; // and, bclr
endcase endcase
// Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits // Support RV64I W-type addw/subw/addiw/shifts that discard upper 32 bits and sign-extend 32-bit result to 64 bits
if (WIDTH == 64) assign PreALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult; if (P.XLEN == 64) assign PreALUResult = W64 ? {{32{FullResult[31]}}, FullResult[31:0]} : FullResult;
else assign PreALUResult = FullResult; else assign PreALUResult = FullResult;
// Final Result B instruction select mux // Final Result B instruction select mux
if (P.ZBC_SUPPORTED | P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED) begin : bitmanipalu if (P.ZBC_SUPPORTED | P.ZBS_SUPPORTED | P.ZBA_SUPPORTED | P.ZBB_SUPPORTED) begin : bitmanipalu
bitmanipalu #(P, WIDTH) balu(.A, .B, .W64, .BSelect, .ZBBSelect, .BMUActiveE, bitmanipalu #(P) balu(
.A, .B, .W64, .BSelect, .ZBBSelect, .BMUActiveE,
.Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult, .Funct3, .LT,.LTU, .BALUControl, .PreALUResult, .FullResult,
.CondMaskB, .CondShiftA, .ALUResult); .CondMaskB, .CondShiftA, .ALUResult);
end else begin end else begin

View File

@ -27,9 +27,8 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module bitmanipalu import cvw::*; #(parameter cvw_t P, module bitmanipalu import cvw::*; #(parameter cvw_t P) (
parameter WIDTH=32) ( input logic [P.XLEN-1:0] A, B, // Operands
input logic [WIDTH-1:0] A, B, // Operands
input logic W64, // W64-type instruction input logic W64, // W64-type instruction
input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction input logic [1:0] BSelect, // Binary encoding of if it's a ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelect, // ZBB mux select signal input logic [2:0] ZBBSelect, // ZBB mux select signal
@ -38,37 +37,37 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P,
input logic LTU, // less than unsigned flag input logic LTU, // less than unsigned flag
input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControl, // ALU Control signals for B instructions in Execute Stage
input logic BMUActiveE, // Bit manipulation instruction being executed input logic BMUActiveE, // Bit manipulation instruction being executed
input logic [WIDTH-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals input logic [P.XLEN-1:0] PreALUResult, FullResult,// PreALUResult, FullResult signals
output logic [WIDTH-1:0] CondMaskB, // B is conditionally masked for ZBS instructions output logic [P.XLEN-1:0] CondMaskB, // B is conditionally masked for ZBS instructions
output logic [WIDTH-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions output logic [P.XLEN-1:0] CondShiftA, // A is conditionally shifted for ShAdd instructions
output logic [WIDTH-1:0] ALUResult); // Result output logic [P.XLEN-1:0] ALUResult); // Result
logic [WIDTH-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result logic [P.XLEN-1:0] ZBBResult, ZBCResult; // ZBB, ZBC Result
logic [WIDTH-1:0] MaskB; // BitMask of B logic [P.XLEN-1:0] MaskB; // BitMask of B
logic [WIDTH-1:0] RevA; // Bit-reversed A logic [P.XLEN-1:0] RevA; // Bit-reversed A
logic Rotate; // Indicates if it is Rotate instruction logic Rotate; // Indicates if it is Rotate instruction
logic Mask; // Indicates if it is ZBS instruction logic Mask; // Indicates if it is ZBS instruction
logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction logic PreShift; // Inidicates if it is sh1add, sh2add, sh3add instruction
logic [1:0] PreShiftAmt; // Amount to Pre-Shift A logic [1:0] PreShiftAmt; // Amount to Pre-Shift A
logic [WIDTH-1:0] CondZextA; // A Conditional Extend Intermediary Signal logic [P.XLEN-1:0] CondZextA; // A Conditional Extend Intermediary Signal
logic [WIDTH-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity logic [P.XLEN-1:0] ABMU, BBMU; // Gated data inputs to reduce BMU activity
// gate data inputs to BMU to only operate when BMU is active // gate data inputs to BMU to only operate when BMU is active
assign ABMU = A & {WIDTH{BMUActiveE}}; assign ABMU = A & {P.XLEN{BMUActiveE}};
assign BBMU = B & {WIDTH{BMUActiveE}}; assign BBMU = B & {P.XLEN{BMUActiveE}};
// Extract control signals from bitmanip ALUControl. // Extract control signals from bitmanip ALUControl.
assign {Mask, PreShift} = BALUControl[1:0]; assign {Mask, PreShift} = BALUControl[1:0];
// Mask Generation Mux // Mask Generation Mux
if (P.ZBS_SUPPORTED) begin: zbsdec if (P.ZBS_SUPPORTED) begin: zbsdec
decoder #($clog2(WIDTH)) maskgen(BBMU[$clog2(WIDTH)-1:0], MaskB); decoder #($clog2(P.XLEN)) maskgen(BBMU[$clog2(P.XLEN)-1:0], MaskB);
mux2 #(WIDTH) maskmux(B, MaskB, Mask, CondMaskB); mux2 #(P.XLEN) maskmux(B, MaskB, Mask, CondMaskB);
end else assign CondMaskB = B; end else assign CondMaskB = B;
// 0-3 bit Pre-Shift Mux // 0-3 bit Pre-Shift Mux
if (P.ZBA_SUPPORTED) begin: zbapreshift if (P.ZBA_SUPPORTED) begin: zbapreshift
if (WIDTH == 64) begin if (P.XLEN == 64) begin
mux2 #(64) zextmux(A, {{32{1'b0}}, A[31:0]}, W64, CondZextA); mux2 #(64) zextmux(A, {{32{1'b0}}, A[31:0]}, W64, CondZextA);
end else assign CondZextA = A; end else assign CondZextA = A;
assign PreShiftAmt = Funct3[2:1] & {2{PreShift}}; assign PreShiftAmt = Funct3[2:1] & {2{PreShift}};
@ -80,17 +79,17 @@ module bitmanipalu import cvw::*; #(parameter cvw_t P,
// Bit reverse needed for some ZBB, ZBC instructions // Bit reverse needed for some ZBB, ZBC instructions
if (P.ZBC_SUPPORTED | P.ZBB_SUPPORTED) begin: bitreverse if (P.ZBC_SUPPORTED | P.ZBB_SUPPORTED) begin: bitreverse
bitreverse #(WIDTH) brA(.A(ABMU), .RevA); bitreverse #(P.XLEN) brA(.A(ABMU), .RevA);
end end
// ZBC Unit // ZBC Unit
if (P.ZBC_SUPPORTED) begin: zbc if (P.ZBC_SUPPORTED) begin: zbc
zbc #(WIDTH) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult); zbc #(P.XLEN) ZBC(.A(ABMU), .RevA, .B(BBMU), .Funct3, .ZBCResult);
end else assign ZBCResult = 0; end else assign ZBCResult = 0;
// ZBB Unit // ZBB Unit
if (P.ZBB_SUPPORTED) begin: zbb if (P.ZBB_SUPPORTED) begin: zbb
zbb #(WIDTH) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult); zbb #(P.XLEN) ZBB(.A(ABMU), .RevA, .B(BBMU), .W64, .LT, .LTU, .BUnsigned(Funct3[0]), .ZBBSelect, .ZBBResult);
end else assign ZBBResult = 0; end else assign ZBBResult = 0;
// Result Select Mux // Result Select Mux

View File

@ -39,10 +39,14 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers output logic IllegalBaseInstrD, // Illegal I-type instruction, or illegal RV32 access to upper 16 registers
output logic JumpD, // Jump instruction output logic JumpD, // Jump instruction
output logic BranchD, // Branch instruction output logic BranchD, // Branch instruction
// Execute stage control signals output logic StructuralStallD, // Structural stalls detected by controller
output logic LoadStallD, // Structural stalls for load, sent to performance counters
output logic [4:0] Rs1D, Rs2D, // Register sources to read in Decode or Execute stage
// Execute stage control signals
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] FlagsE, // Comparison flags ({eq, lt}) input logic [1:0] FlagsE, // Comparison flags ({eq, lt})
input logic FWriteIntE, // Write integer register, coming from FPU controller input logic FWriteIntE, // Write integer register, coming from FPU controller
input logic FCvtIntE, // FPU convert float to int
output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit) output logic PCSrcE, // Select signal to choose next PC (for datapath and Hazard unit)
output logic ALUSrcAE, ALUSrcBE, // ALU operands output logic ALUSrcAE, ALUSrcBE, // ALU operands
output logic ALUResultSrcE, // Selects result to pass on to Memory stage output logic ALUResultSrcE, // Selects result to pass on to Memory stage
@ -65,7 +69,7 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic [3:0] CMOpM, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero output logic [3:0] CMOpM, // 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
output logic IFUPrefetchE, // instruction prefetch output logic IFUPrefetchE, // instruction prefetch
output logic LSUPrefetchM, // data prefetch output logic LSUPrefetchM, // data prefetch
output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers
// Memory stage control signals // Memory stage control signals
input logic StallM, FlushM, // Stall, flush Memory stage input logic StallM, FlushM, // Stall, flush Memory stage
output logic [1:0] MemRWE, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write output logic [1:0] MemRWE, // Mem read/write: MemRWM[1] = 1 for read, MemRWM[0] = 1 for write
@ -83,14 +87,16 @@ module controller import cvw::*; #(parameter cvw_t P) (
output logic [2:0] ResultSrcW, // Select source of result to write back to register file output logic [2:0] ResultSrcW, // Select source of result to write back to register file
// Stall during CSRs // Stall during CSRs
output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions output logic CSRWriteFenceM, // CSR write or fence instruction; needs to flush the following instructions
output logic StoreStallD // Store (memory write) causes stall output logic [4:0] RdE, RdM, // Pipelined destination registers
// Forwarding controls
output logic [4:0] RdW // Register destinations in Execute, Memory, or Writeback stage
); );
logic [4:0] Rs1E, Rs2E; // pipelined register sources
logic [6:0] OpD; // Opcode in Decode stage logic [6:0] OpD; // Opcode in Decode stage
logic [2:0] Funct3D; // Funct3 field in Decode stage logic [2:0] Funct3D; // Funct3 field in Decode stage
logic [6:0] Funct7D; // Funct7 field in Decode stage logic [6:0] Funct7D; // Funct7 field in Decode stage
logic [4:0] Rs1D, Rs2D, RdD; // Rs1/2 source register / dest reg in Decode stage logic [4:0] RdD; // Rs1/2 source register / dest reg in Decode stage
`define CTRLW 24 `define CTRLW 24
@ -146,6 +152,11 @@ module controller import cvw::*; #(parameter cvw_t P) (
logic [3:0] CMOpD, CMOpE; // which CMO instruction 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero logic [3:0] CMOpD, CMOpE; // which CMO instruction 1: cbo.inval; 2: cbo.flush; 4: cbo.clean; 8: cbo.zero
logic IFUPrefetchD; // instruction prefetch logic IFUPrefetchD; // instruction prefetch
logic LSUPrefetchD, LSUPrefetchE; // data prefetch logic LSUPrefetchD, LSUPrefetchE; // data prefetch
logic CMOStallD; // Structural hazards from cache management ops
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
logic FCvtIntStallD, MDUStallD, CSRRdStallD; // Stall due to conversion, load, multiply/divide, CSR read
logic StoreStallD; // load after store hazard
// Extract fields // Extract fields
assign OpD = InstrD[6:0]; assign OpD = InstrD[6:0];
@ -394,6 +405,9 @@ module controller import cvw::*; #(parameter cvw_t P) (
flopenrc #(35) controlregE(clk, reset, FlushE, ~StallE, flopenrc #(35) controlregE(clk, reset, FlushE, ~StallE,
{ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, InstrValidD}, {ALUSelectD, RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUSrcAD, ALUSrcBD, ALUResultSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, SubArithD, MDUD, AtomicD, InvalidateICacheD, FlushDCacheD, FenceD, CMOpD, IFUPrefetchD, LSUPrefetchD, InstrValidD},
{ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, InstrValidE}); {ALUSelectE, IEURegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUSrcAE, ALUSrcBE, ALUResultSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, SubArithE, MDUE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, CMOpE, IFUPrefetchE, LSUPrefetchE, InstrValidE});
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
// Branch Logic // Branch Logic
// The comparator handles both signed and unsigned branches using BranchSignedE // The comparator handles both signed and unsigned branches using BranchSignedE
@ -415,22 +429,37 @@ module controller import cvw::*; #(parameter cvw_t P) (
flopenrc #(25) controlregM(clk, reset, FlushM, ~StallM, flopenrc #(25) controlregM(clk, reset, FlushM, ~StallM,
{RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE, CMOpE, LSUPrefetchE}, {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, FWriteIntE, AtomicE, InvalidateICacheE, FlushDCacheE, FenceE, InstrValidE, IntDivE, CMOpE, LSUPrefetchE},
{RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM, CMOpM, LSUPrefetchM}); {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, FWriteIntM, AtomicM, InvalidateICacheM, FlushDCacheM, FenceM, InstrValidM, IntDivM, CMOpM, LSUPrefetchM});
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
// Writeback stage pipeline control register // Writeback stage pipeline control register
flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW, flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW,
{RegWriteM, ResultSrcM, IntDivM}, {RegWriteM, ResultSrcM, IntDivM},
{RegWriteW, ResultSrcW, IntDivW}); {RegWriteW, ResultSrcW, IntDivW});
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
// Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA // Flush F, D, and E stages on a CSR write or Fence.I or SFence.VMA
assign CSRWriteFenceM = CSRWriteM | FenceM; assign CSRWriteFenceM = CSRWriteM | FenceM;
// the synchronous DTIM cannot read immediately after write // Forwarding logic
// a cache cannot read or write immediately after a write always_comb begin
// atomic operations are also detected as MemRWD[1] ForwardAE = 2'b00;
// *** RT: Remove this after updating the cache. ForwardBE = 2'b00;
// *** RT: Check that atomic after atomic works correctly. if (Rs1E != 5'b0)
//assign StoreStallD = ((|CMOpE)) & ((|CMOpD)); if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
logic AMOHazard; else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01;
assign AMOHazard = &MemRWE & MemRWD[1];
assign StoreStallD = ((|CMOpE) & (|CMOpD)) | AMOHazard; if (Rs2E != 5'b0)
if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time
// Structural hazard causes stall if any of these events occur
assign MatchDE = ((Rs1D == RdE) | (Rs2D == RdE)) & (RdE != 5'b0); // Decode-stage instruction source depends on result from execute stage instruction
assign LoadStallD = (MemReadE|SCE) & MatchDE;
assign StoreStallD = MemRWD[1] & MemRWE[0]; // Store or AMO followed by load or AMO
assign CSRRdStallD = CSRReadE & MatchDE;
assign MDUStallD = MDUE & MatchDE; // Int mult/div is at least two cycle latency, even when coming from the FDIV
assign FCvtIntStallD = FCvtIntE & MatchDE; // FPU to Integer transfers have single-cycle latency except fcvt
assign StructuralStallD = LoadStallD | StoreStallD | CSRRdStallD | MDUStallD | FCvtIntStallD;
endmodule endmodule

View File

@ -32,6 +32,7 @@ module datapath import cvw::*; #(parameter cvw_t P) (
// Decode stage signals // Decode stage signals
input logic [2:0] ImmSrcD, // Selects type of immediate extension input logic [2:0] ImmSrcD, // Selects type of immediate extension
input logic [31:0] InstrD, // Instruction in Decode stage input logic [31:0] InstrD, // Instruction in Decode stage
input logic [4:0] Rs1D, Rs2D, // Source registers
// Execute stage signals // Execute stage signals
input logic [P.XLEN-1:0] PCE, // PC in Execute stage input logic [P.XLEN-1:0] PCE, // PC in Execute stage
input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage) input logic [P.XLEN-1:0] PCLinkE, // PC + 4 (of instruction in Execute stage)
@ -68,9 +69,8 @@ module datapath import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] CSRReadValW, // CSR read result input logic [P.XLEN-1:0] CSRReadValW, // CSR read result
input logic [P.XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result input logic [P.XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result
input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result input logic [P.XLEN-1:0] FIntDivResultW, // FPU's integer divide result
input logic [4:0] RdW // Destination register
// Hazard Unit signals // Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage
output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage
); );
// Fetch stage signals // Fetch stage signals
@ -94,9 +94,6 @@ module datapath import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division) logic [P.XLEN-1:0] MulDivResultW; // Multiply always comes from MDU. Divide could come from MDU or FPU (when using fdivsqrt for integer division)
// Decode stage // Decode stage
assign Rs1D = InstrD[19:15];
assign Rs2D = InstrD[24:20];
assign RdD = InstrD[11:7];
regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D); regfile #(P.XLEN, P.E_SUPPORTED) regf(clk, reset, RegWriteW, Rs1D, Rs2D, RdW, ResultW, R1D, R2D);
extend #(P) ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD); extend #(P) ext(.InstrD(InstrD[31:7]), .ImmSrcD, .ImmExtD);
@ -104,28 +101,23 @@ module datapath import cvw::*; #(parameter cvw_t P) (
flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E); flopenrc #(P.XLEN) RD1EReg(clk, reset, FlushE, ~StallE, R1D, R1E);
flopenrc #(P.XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E); flopenrc #(P.XLEN) RD2EReg(clk, reset, FlushE, ~StallE, R2D, R2E);
flopenrc #(P.XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE); flopenrc #(P.XLEN) ImmExtEReg(clk, reset, FlushE, ~StallE, ImmExtD, ImmExtE);
flopenrc #(5) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE);
mux3 #(P.XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE); mux3 #(P.XLEN) faemux(R1E, ResultW, IFResultM, ForwardAE, ForwardedSrcAE);
mux3 #(P.XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE); mux3 #(P.XLEN) fbemux(R2E, ResultW, IFResultM, ForwardBE, ForwardedSrcBE);
comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE); comparator #(P.XLEN) comp(ForwardedSrcAE, ForwardedSrcBE, BranchSignedE, FlagsE);
mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE); mux2 #(P.XLEN) srcamux(ForwardedSrcAE, PCE, ALUSrcAE, SrcAE);
mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE); mux2 #(P.XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(P, P.XLEN) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, BMUActiveE, ALUResultE, IEUAdrE); alu #(P) alu(SrcAE, SrcBE, W64E, SubArithE, ALUSelectE, BSelectE, ZBBSelectE, Funct3E, BALUControlE, BMUActiveE, ALUResultE, IEUAdrE);
mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE); mux2 #(P.XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE); mux2 #(P.XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);
// Memory stage pipeline register // Memory stage pipeline register
flopenrc #(P.XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM); flopenrc #(P.XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);
flopenrc #(P.XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM); flopenrc #(P.XLEN) IEUResultMReg(clk, reset, FlushM, ~StallM, IEUResultE, IEUResultM);
flopenrc #(5) RdMReg(clk, reset, FlushM, ~StallM, RdE, RdM);
flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM); flopenrc #(P.XLEN) WriteDataMReg(clk, reset, FlushM, ~StallM, ForwardedSrcBE, WriteDataM);
// Writeback stage pipeline register and logic // Writeback stage pipeline register and logic
flopenrc #(P.XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW); flopenrc #(P.XLEN) IFResultWReg(clk, reset, FlushW, ~StallW, IFResultM, IFResultW);
flopenrc #(5) RdWReg(clk, reset, FlushW, ~StallW, RdM, RdW);
// floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt // floating point inputs: FIntResM comes from fclass, fcmp, fmv; FCvtIntResW comes from fcvt
if (P.F_SUPPORTED) begin:fpmux if (P.F_SUPPORTED) begin:fpmux

View File

@ -1,62 +0,0 @@
///////////////////////////////////////////
// forward.sv
//
// Written: David_Harris@hmc.edu, Sarah.Harris@unlv.edu
// Created: 9 January 2021
// Modified:
//
// Purpose: Determine datapath forwarding
//
// Documentation: RISC-V System on Chip Design Chapter 4 (Section 4.2.2.3)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module forward(
// Detect hazards
input logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, RdE, RdM, RdW, // Source and destination registers
input logic MemReadE, MDUE, CSRReadE, // Execute stage instruction is a load (MemReadE), divide (MDUE), or CSR read (CSRReadE)
input logic RegWriteM, RegWriteW, // Instruction in Memory or Writeback stage writes register file
input logic FCvtIntE, // FPU convert float to int
input logic SCE, // Store Conditional instruction
// Forwarding controls
output logic [1:0] ForwardAE, ForwardBE, // Select signals for forwarding multiplexers
output logic FCvtIntStallD, LoadStallD, MDUStallD, CSRRdStallD // Stall due to conversion, load, multiply/divide, CSR read
);
logic MatchDE; // Match between a source register in Decode stage and destination register in Execute stage
always_comb begin
ForwardAE = 2'b00;
ForwardBE = 2'b00;
if (Rs1E != 5'b0)
if ((Rs1E == RdM) & RegWriteM) ForwardAE = 2'b10;
else if ((Rs1E == RdW) & RegWriteW) ForwardAE = 2'b01;
if (Rs2E != 5'b0)
if ((Rs2E == RdM) & RegWriteM) ForwardBE = 2'b10;
else if ((Rs2E == RdW) & RegWriteW) ForwardBE = 2'b01;
end
// Stall on dependent operations that finish in Mem Stage and can't bypass in time
assign MatchDE = ((Rs1D == RdE) | (Rs2D == RdE)) & (RdE != 5'b0); // Decode-stage instruction source depends on result from execute stage instruction
assign FCvtIntStallD = FCvtIntE & MatchDE; // FPU to Integer transfers have single-cycle latency except fcvt
assign LoadStallD = (MemReadE|SCE) & MatchDE;
assign MDUStallD = MDUE & MatchDE; // Int mult/div is at least two cycle latency, even when coming from the FDIV
assign CSRRdStallD = CSRReadE & MatchDE;
endmodule

View File

@ -73,8 +73,8 @@ module ieu import cvw::*; #(parameter cvw_t P) (
// Hazard unit signals // Hazard unit signals
input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit input logic StallD, StallE, StallM, StallW, // Stall signals from hazard unit
input logic FlushD, FlushE, FlushM, FlushW, // Flush signals input logic FlushD, FlushE, FlushM, FlushW, // Flush signals
output logic FCvtIntStallD, LoadStallD, // Stall causes from IEU to hazard unit output logic StructuralStallD, // IEU detects structural hazard in Decode stage
output logic MDUStallD, CSRRdStallD, StoreStallD, output logic LoadStallD, // Structural stalls for load, sent to performance counters
output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction output logic CSRReadM, CSRWriteM, PrivilegedM,// CSR read, CSR write, is privileged instruction
output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions output logic CSRWriteFenceM // CSR write or fence instruction needs to flush subsequent instructions
); );
@ -94,7 +94,7 @@ module ieu import cvw::*; #(parameter cvw_t P) (
logic SubArithE; // Subtraction or arithmetic shift logic SubArithE; // Subtraction or arithmetic shift
// Forwarding signals // Forwarding signals
logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E; // Source and destination registers logic [4:0] Rs1D, Rs2D; // Source registers
logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers logic [1:0] ForwardAE, ForwardBE; // Select signals for forwarding multiplexers
logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages logic RegWriteM, RegWriteW; // Register will be written in Memory, Writeback stages
logic MemReadE, CSRReadE; // Load, CSRRead instruction logic MemReadE, CSRReadE; // Load, CSRRead instruction
@ -104,25 +104,23 @@ module ieu import cvw::*; #(parameter cvw_t P) (
controller #(P) c( controller #(P) c(
.clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD, .clk, .reset, .StallD, .FlushD, .InstrD, .STATUS_FS, .ENVCFG_CBE, .ImmSrcD,
.IllegalIEUFPUInstrD, .IllegalBaseInstrD, .StallE, .FlushE, .FlagsE, .FWriteIntE, .IllegalIEUFPUInstrD, .IllegalBaseInstrD,
.StructuralStallD, .LoadStallD, .Rs1D, .Rs2D,
.StallE, .FlushE, .FlagsE, .FWriteIntE,
.PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE, .PCSrcE, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .MemReadE, .CSRReadE,
.Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE, .Funct3E, .IntDivE, .MDUE, .W64E, .SubArithE, .BranchD, .BranchE, .JumpD, .JumpE, .SCE,
.BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .MDUActiveE, .CMOpM, .IFUPrefetchE, .LSUPrefetchM, .BranchSignedE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .MDUActiveE,
.FCvtIntE, .ForwardAE, .ForwardBE, .CMOpM, .IFUPrefetchE, .LSUPrefetchM,
.StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M, .StallM, .FlushM, .MemRWE, .MemRWM, .CSRReadM, .CSRWriteM, .PrivilegedM, .AtomicM, .Funct3M,
.RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM, .RegWriteM, .FlushDCacheM, .InstrValidM, .InstrValidE, .InstrValidD, .FWriteIntM,
.StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); .StallW, .FlushW, .RegWriteW, .IntDivW, .ResultSrcW, .CSRWriteFenceM, .InvalidateICacheM,
.RdW, .RdE, .RdM);
datapath #(P) dp( datapath #(P) dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE, .clk, .reset, .ImmSrcD, .InstrD, .Rs1D, .Rs2D, .StallE, .FlushE, .ForwardAE, .ForwardBE, .W64E, .SubArithE,
.Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .ALUSelectE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE, .PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BSelectE, .ZBBSelectE, .BALUControlE, .BMUActiveE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW, .StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW, .StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
.CSRReadValW, .MDUResultW, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW); .CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW);
forward fw(
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,
.MemReadE, .MDUE, .CSRReadE, .RegWriteM, .RegWriteW,
.FCvtIntE, .SCE, .ForwardAE, .ForwardBE,
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD);
endmodule endmodule

View File

@ -185,7 +185,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(), .InstrAccessFaultF, .LoadAccessFaultM(), .StoreAmoAccessFaultM(),
.InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(), .InstrPageFaultF, .LoadPageFaultM(), .StoreAmoPageFaultM(),
.LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(), .LoadMisalignedFaultM(), .StoreAmoMisalignedFaultM(),
.UpdateDA(InstrUpdateDAF), .CMOp(4'b0), .UpdateDA(InstrUpdateDAF), .CMOpM(4'b0),
.AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0), .AtomicAccessM(1'b0),.ExecuteAccessF(1'b1), .WriteAccessM(1'b0), .ReadAccessM(1'b0),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -223,6 +223,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
// **** must fix words per line vs beats per line as in lsu. // **** must fix words per line vs beats per line as in lsu.
localparam WORDSPERLINE = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/P.XLEN : 1; localparam WORDSPERLINE = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/P.XLEN : 1;
localparam LOGBWPL = P.ICACHE_SUPPORTED ? $clog2(WORDSPERLINE) : 1; localparam LOGBWPL = P.ICACHE_SUPPORTED ? $clog2(WORDSPERLINE) : 1;
if(P.ICACHE_SUPPORTED) begin : icache if(P.ICACHE_SUPPORTED) begin : icache
localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN; localparam LINELEN = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS : P.XLEN;
localparam LLENPOVERAHBW = P.LLEN / P.AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation) localparam LLENPOVERAHBW = P.LLEN / P.AHBW; // Number of AHB beats in a LLEN word. AHBW cannot be larger than LLEN. (implementation limitation)
@ -233,7 +234,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0; assign BusRW = ~ITLBMissF & ~CacheableF & ~SelIROM ? IFURWF : '0;
assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0; assign CacheRWF = ~ITLBMissF & CacheableF & ~SelIROM ? IFURWF : '0;
// *** RT: Fix CMOp. Should be CMOpM. Also PAdr and NextSet are replaced with mux between PCPF/IEUAdrM and PCSpillNextF/IEUAdrE. // *** RT: PAdr and NextSet are replaced with mux between PCPF/IEUAdrM and PCSpillNextF/IEUAdrE.
cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS), cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.ICACHE_LINELENINBITS),
.NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS), .NUMLINES(P.ICACHE_WAYSIZEINBYTES*8/P.ICACHE_LINELENINBITS),
.NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1)) .NUMWAYS(P.ICACHE_NUMWAYS), .LOGBWPL(LOGBWPL), .WORDLEN(32), .MUXINTERVAL(16), .READ_ONLY_CACHE(1))
@ -246,24 +247,29 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess), .CacheMiss(ICacheMiss), .CacheAccess(ICacheAccess),
.ByteMask('0), .BeatCount('0), .SelBusBeat('0), .ByteMask('0), .BeatCount('0), .SelBusBeat('0),
.CacheWriteData('0), .CacheWriteData('0),
.CacheRW(CacheRWF), .CacheRWNext('0), // CacheRWNext is only used to detect hazards. Not possible with icache .CacheRW(CacheRWF),
.FlushCache('0), .FlushCache('0),
.NextSet(PCSpillNextF[11:0]), .NextSet(PCSpillNextF[11:0]),
.PAdr(PCPF), .PAdr(PCPF),
.CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM), .CMOp('0)); .CacheCommitted(CacheCommittedF), .InvalidateCache(InvalidateICacheM), .CMOpM('0));
ahbcacheinterface #(P.AHBW, P.LLEN, P.PA_BITS, WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1) ahbcacheinterface #(P.AHBW, P.LLEN, P.PA_BITS, WORDSPERLINE, LOGBWPL, LINELEN, LLENPOVERAHBW, 1)
ahbcacheinterface(.HCLK(clk), .HRESETn(~reset), ahbcacheinterface(.HCLK(clk), .HRESETn(~reset),
.HRDATA, .HRDATA,
.Flush(FlushD), .CacheBusRW, .BusCMOZero(1'b0), .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), .Flush(FlushD), .CacheBusRW, .BusCMOZero(1'b0), .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(),
.Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr), .Funct3(3'b010), .HADDR(IFUHADDR), .HREADY(IFUHREADY), .HWRITE(IFUHWRITE), .CacheBusAdr(ICacheBusAdr),
.BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0), .BeatCount(), .Cacheable(CacheableF), .SelBusBeat(), .WriteDataM('0), .BusAtomic('0),
.CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0), .CacheBusAck(ICacheBusAck), .HWDATA(), .CacheableOrFlushCacheM(1'b0), .CacheReadDataWordM('0),
.FetchBuffer, .PAdr(PCPF), .FetchBuffer, .PAdr(PCPF),
.BusRW, .Stall(GatedStallD), .BusRW, .Stall(GatedStallD),
.BusStall, .BusCommitted(BusCommittedF)); .BusStall, .BusCommitted(BusCommittedF));
mux3 #(32) UnCachedDataMux(.d0(ICacheInstrF), .d1(FetchBuffer[32-1:0]), .d2(IROMInstrF), logic [31:0] ShiftUncachedInstr;
if(P.XLEN == 64) mux4 #(32) UncachedShiftInstrMux(FetchBuffer[32-1:0], FetchBuffer[48-1:16], FetchBuffer[64-1:32], {16'b0, FetchBuffer[64-1:48]},
PCSpillF[2:1], ShiftUncachedInstr);
else mux2 #(32) UncachedShiftInstrMux(FetchBuffer[32-1:0], {16'b0, FetchBuffer[32-1:16]}, PCSpillF[1], ShiftUncachedInstr);
mux3 #(32) UnCachedDataMux(.d0(ICacheInstrF), .d1(ShiftUncachedInstr), .d2(IROMInstrF),
.s({SelIROM, ~CacheableF}), .y(InstrRawF[31:0])); .s({SelIROM, ~CacheableF}), .y(InstrRawF[31:0]));
end else begin : passthrough end else begin : passthrough
assign IFUHADDR = PCPF; assign IFUHADDR = PCPF;
@ -363,11 +369,11 @@ module ifu import cvw::*; #(parameter cvw_t P) (
flopenrc #(P.XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); flopenrc #(P.XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);
// expand 16-bit compressed instructions to 32 bits // expand 16-bit compressed instructions to 32 bits
if (P.COMPRESSED_SUPPORTED) begin if (P.COMPRESSED_SUPPORTED) begin: decomp
logic IllegalCompInstrD; logic IllegalCompInstrD;
decompress #(P) decomp(.InstrRawD, .InstrD, .IllegalCompInstrD); decompress #(P) decomp(.InstrRawD, .InstrD, .IllegalCompInstrD);
assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr assign IllegalIEUInstrD = IllegalBaseInstrD | IllegalCompInstrD; // illegal if bad 32 or 16-bit instr
end else begin end else begin: decomp
assign InstrD = InstrRawD; assign InstrD = InstrRawD;
assign IllegalIEUInstrD = IllegalBaseInstrD; assign IllegalIEUInstrD = IllegalBaseInstrD;
end end

View File

@ -117,9 +117,9 @@ module align import cvw::*; #(parameter cvw_t P) (
always_comb begin always_comb begin
case (CurrState) case (CurrState)
STATE_READY: if (ValidSpillM & ~MemRWM[0]) NextState = STATE_SPILL; STATE_READY: if (ValidSpillM & ~MemRWM[0]) NextState = STATE_SPILL; // load spill
else if(ValidSpillM & MemRWM[0])NextState = STATE_STORE_DELAY; else if(ValidSpillM) NextState = STATE_STORE_DELAY; // store spill
else NextState = STATE_READY; else NextState = STATE_READY; // no spill
STATE_SPILL: if(StallM) NextState = STATE_SPILL; STATE_SPILL: if(StallM) NextState = STATE_SPILL;
else NextState = STATE_READY; else NextState = STATE_READY;
STATE_STORE_DELAY: NextState = STATE_SPILL; STATE_STORE_DELAY: NextState = STATE_SPILL;
@ -131,7 +131,7 @@ module align import cvw::*; #(parameter cvw_t P) (
assign SelSpillE = (CurrState == STATE_READY & ValidSpillM) | (CurrState == STATE_SPILL & CacheBusHPWTStall) | (CurrState == STATE_STORE_DELAY); assign SelSpillE = (CurrState == STATE_READY & ValidSpillM) | (CurrState == STATE_SPILL & CacheBusHPWTStall) | (CurrState == STATE_STORE_DELAY);
assign SpillSaveM = (CurrState == STATE_READY) & ValidSpillM & ~FlushM; assign SpillSaveM = (CurrState == STATE_READY) & ValidSpillM & ~FlushM;
assign SelStoreDelay = (CurrState == STATE_STORE_DELAY); // *** Can this be merged into the PreLSURWM logic? assign SelStoreDelay = (CurrState == STATE_STORE_DELAY); // *** Can this be merged into the PreLSURWM logic?
assign SpillStallM = SelSpillE | CurrState == STATE_STORE_DELAY; assign SpillStallM = SelSpillE;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Merge spilled data // Merge spilled data

View File

@ -28,17 +28,15 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module dtim import cvw::*; #(parameter cvw_t P) ( module dtim import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic FlushW, input logic FlushW,
input logic ce, // Chip Enable. 0: Holds ReadDataWordM input logic ce, // Chip Enable. 0: Holds ReadDataWordM
input logic [1:0] MemRWM, // Read/Write control input logic [1:0] MemRWM, // Read/Write control
input logic [1:0] MemRWE, // Read/Write control input logic [1:0] MemRWE, // Read/Write control
input logic [P.PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address input logic [P.PA_BITS-1:0] DTIMAdr, // No stall: Execution stage memory address. Stall: Memory stage memory address
input logic [P.LLEN-1:0] WriteDataM, // Write data from IEU input logic [P.LLEN-1:0] WriteDataM, // Write data from IEU
input logic [P.LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write input logic [P.LLEN/8-1:0] ByteMaskM, // Selects which bytes within a word to write
output logic [P.LLEN-1:0] ReadDataWordM, // Read data before subword selection output logic [P.LLEN-1:0] ReadDataWordM // Read data before subword selection
output logic DTIMStall,
output logic DTIMSelWrite
); );
logic we; logic we;
@ -50,16 +48,8 @@ module dtim import cvw::*; #(parameter cvw_t P) (
localparam ADDR_WDITH = $clog2(DEPTH); localparam ADDR_WDITH = $clog2(DEPTH);
localparam OFFSET = $clog2(LLENBYTES); localparam OFFSET = $clog2(LLENBYTES);
logic DTIMStallHazard, DTIMStallHazardD; assign we = MemRWM[0] & ~FlushW; // have to ignore write if Trap.
assign DTIMStallHazard = MemRWM[0] & MemRWE[1];
flopr #(1) DTIMStallReg(clk, reset, DTIMStallHazard, DTIMStallHazardD);
assign DTIMStall = DTIMStallHazard & ~DTIMStallHazardD;
assign DTIMSelWrite = MemRWM[0] & ~(DTIMStallHazard & ~DTIMStall);
assign we = DTIMSelWrite & ~FlushW; // have to ignore write if Trap.
ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(DEPTH), .WIDTH(P.LLEN)) ram1p1rwbe #(.USE_SRAM(P.USE_SRAM), .DEPTH(DEPTH), .WIDTH(P.LLEN))
ram(.clk, .ce(ce | DTIMSelWrite), .we, .bwe(ByteMaskM), .addr(DTIMAdr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM)); ram(.clk, .ce, .we, .bwe(ByteMaskM), .addr(DTIMAdr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(ReadDataWordM), .din(WriteDataM));
endmodule endmodule

View File

@ -150,7 +150,6 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation logic IgnoreRequest; // On FlushM or TLB miss ignore memory operation
logic SelDTIM; // Select DTIM rather than bus or D$ logic SelDTIM; // Select DTIM rather than bus or D$
logic [P.XLEN-1:0] WriteDataZM; logic [P.XLEN-1:0] WriteDataZM;
logic DTIMStall;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Pipeline for IEUAdr E to M // Pipeline for IEUAdr E to M
@ -220,7 +219,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
// the trap module. // the trap module.
assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM; assign CommittedM = SelHPTW | DCacheCommittedM | BusCommittedM;
assign GatedStallW = StallW & ~SelHPTW; assign GatedStallW = StallW & ~SelHPTW;
assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall | DTIMStall; assign CacheBusHPWTStall = DCacheStallM | HPTWStall | BusStall;
assign LSUStallM = CacheBusHPWTStall | SpillStallM; assign LSUStallM = CacheBusHPWTStall | SpillStallM;
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
@ -240,7 +239,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM, .StoreAmoAccessFaultM(LSUStoreAmoAccessFaultM), .InstrPageFaultF(), .LoadPageFaultM,
.StoreAmoPageFaultM, .StoreAmoPageFaultM,
.LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw. .LoadMisalignedFaultM, .StoreAmoMisalignedFaultM, // *** these faults need to be supressed during hptw.
.UpdateDA(DataUpdateDAM), .CMOp(CMOpM), .UpdateDA(DataUpdateDAM), .CMOpM(CMOpM),
.AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0), .AtomicAccessM(|LSUAtomicM), .ExecuteAccessF(1'b0),
.WriteAccessM, .ReadAccessM(PreLSURWM[1]), .WriteAccessM, .ReadAccessM(PreLSURWM[1]),
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW); .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW);
@ -269,10 +268,9 @@ module lsu import cvw::*; #(parameter cvw_t P) (
if (P.DTIM_SUPPORTED) begin : dtim if (P.DTIM_SUPPORTED) begin : dtim
logic [P.PA_BITS-1:0] DTIMAdr; logic [P.PA_BITS-1:0] DTIMAdr;
logic [1:0] DTIMMemRWM; logic [1:0] DTIMMemRWM;
logic DTIMSelWrite;
// The DTIM uses untranslated addresses, so it is not compatible with virtual memory. // The DTIM uses untranslated addresses, so it is not compatible with virtual memory.
mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], DTIMSelWrite, DTIMAdr); mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], MemRWM[0], DTIMAdr);
assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0; assign DTIMMemRWM = SelDTIM & ~IgnoreRequestTLB ? LSURWM : '0;
// **** fix ReadDataWordM to be LLEN. ByteMask is wrong length. // **** fix ReadDataWordM to be LLEN. ByteMask is wrong length.
// **** create config to support DTIM with floating point. // **** create config to support DTIM with floating point.
@ -280,9 +278,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
dtim #(P) dtim(.clk, .reset, .ce(~GatedStallW), .MemRWE(MemRWE), // *** update when you update the cache RWE dtim #(P) dtim(.clk, .reset, .ce(~GatedStallW), .MemRWE(MemRWE), // *** update when you update the cache RWE
.MemRWM(DTIMMemRWM), .MemRWM(DTIMMemRWM),
.DTIMAdr, .FlushW, .WriteDataM(LSUWriteDataM), .DTIMAdr, .FlushW, .WriteDataM(LSUWriteDataM),
.ReadDataWordM(DTIMReadDataWordM[P.LLEN-1:0]), .ByteMaskM(ByteMaskM), .DTIMStall, .DTIMSelWrite); .ReadDataWordM(DTIMReadDataWordM[P.LLEN-1:0]), .ByteMaskM(ByteMaskM));
end else begin
assign DTIMStall = '0;
end end
if (P.BUS_SUPPORTED) begin : bus if (P.BUS_SUPPORTED) begin : bus
if(P.DCACHE_SUPPORTED) begin : dcache if(P.DCACHE_SUPPORTED) begin : dcache
@ -307,11 +303,17 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic CacheStall; logic CacheStall;
logic [1:0] CacheBusRWTemp; logic [1:0] CacheBusRWTemp;
logic BusCMOZero; logic BusCMOZero;
logic [3:0] CacheCMOpM;
logic BusAtomic;
if(P.ZICBOZ_SUPPORTED) begin if(P.ZICBOZ_SUPPORTED) begin
assign BusCMOZero = CMOpM[3] & ~CacheableM; assign BusCMOZero = CMOpM[3] & ~CacheableM;
assign CacheCMOpM = (CacheableM & ~SelHPTW) ? CMOpM : '0;
assign BusAtomic = AtomicM[1] & ~CacheableM;
end else begin end else begin
assign BusCMOZero = '0; assign BusCMOZero = '0;
assign CacheCMOpM = '0;
assign BusAtomic = '0;
end end
assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0; assign BusRW = ~CacheableM & ~SelDTIM ? LSURWM : '0;
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM; assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM;
@ -320,7 +322,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN), cache #(.P(P), .PA_BITS(P.PA_BITS), .XLEN(P.XLEN), .LINELEN(P.DCACHE_LINELENINBITS), .NUMLINES(P.DCACHE_WAYSIZEINBYTES*8/LINELEN),
.NUMWAYS(P.DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(CACHEWORDLEN), .MUXINTERVAL(P.LLEN), .READ_ONLY_CACHE(0)) dcache( .NUMWAYS(P.DCACHE_NUMWAYS), .LOGBWPL(LLENLOGBWPL), .WORDLEN(CACHEWORDLEN), .MUXINTERVAL(P.LLEN), .READ_ONLY_CACHE(0)) dcache(
.clk, .reset, .Stall(GatedStallW & ~SelSpillE), .SelBusBeat, .FlushStage(FlushW | IgnoreRequestTLB), .CacheRWNext(MemRWE), // *** change to LSURWE after updating hptw and atomic .clk, .reset, .Stall(GatedStallW & ~SelSpillE), .SelBusBeat, .FlushStage(FlushW | IgnoreRequestTLB),
.CacheRW(SelStoreDelay ? 2'b00 : CacheRWM), .CacheRW(SelStoreDelay ? 2'b00 : CacheRWM),
.FlushCache(FlushDCache), .NextSet(IEUAdrExtE[11:0]), .PAdr(PAdrM), .FlushCache(FlushDCache), .NextSet(IEUAdrExtE[11:0]), .PAdr(PAdrM),
.ByteMask(ByteMaskSpillM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]), .ByteMask(ByteMaskSpillM), .BeatCount(BeatCount[AHBWLOGBWPL-1:AHBWLOGBWPL-LLENLOGBWPL]),
@ -329,8 +331,8 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.CacheCommitted(DCacheCommittedM), .CacheCommitted(DCacheCommittedM),
.CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM), .CacheBusAdr(DCacheBusAdr), .ReadDataWord(DCacheReadDataWordM),
.FetchBuffer, .CacheBusRW(CacheBusRWTemp), .FetchBuffer, .CacheBusRW(CacheBusRWTemp),
.CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0), .CMOp(CMOpM)); .CacheBusAck(DCacheBusAck), .InvalidateCache(1'b0), .CMOpM(CacheCMOpM));
assign DCacheStallM = CacheStall & ~IgnoreRequestTLB; assign DCacheStallM = CacheStall & ~IgnoreRequestTLB;
assign CacheBusRW = CacheBusRWTemp; assign CacheBusRW = CacheBusRWTemp;
@ -340,7 +342,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
.HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB), .HRDATA, .HWDATA(LSUHWDATA), .HWSTRB(LSUHWSTRB),
.HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY), .HSIZE(LSUHSIZE), .HBURST(LSUHBURST), .HTRANS(LSUHTRANS), .HWRITE(LSUHWRITE), .HREADY(LSUHREADY),
.BeatCount, .SelBusBeat, .CacheReadDataWordM(DCacheReadDataWordM[P.LLEN-1:0]), .WriteDataM(LSUWriteDataM), .BeatCount, .SelBusBeat, .CacheReadDataWordM(DCacheReadDataWordM[P.LLEN-1:0]), .WriteDataM(LSUWriteDataM),
.Funct3(LSUFunct3M), .HADDR(LSUHADDR), .CacheBusAdr(DCacheBusAdr), .CacheBusRW, .BusCMOZero, .CacheableOrFlushCacheM, .Funct3(LSUFunct3M), .HADDR(LSUHADDR), .CacheBusAdr(DCacheBusAdr), .CacheBusRW, .BusAtomic, .BusCMOZero, .CacheableOrFlushCacheM,
.CacheBusAck(DCacheBusAck), .FetchBuffer, .PAdr(PAdrM), .CacheBusAck(DCacheBusAck), .FetchBuffer, .PAdr(PAdrM),
.Cacheable(CacheableOrFlushCacheM), .BusRW, .Stall(GatedStallW), .Cacheable(CacheableOrFlushCacheM), .BusRW, .Stall(GatedStallW),
.BusStall, .BusCommitted(BusCommittedM)); .BusStall, .BusCommitted(BusCommittedM));

View File

@ -37,17 +37,17 @@ module adrdecs import cvw::*; #(parameter cvw_t P) (
localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111); localparam logic [3:0] SUPPORTED_SIZE = (P.LLEN == 32 ? 4'b0111 : 4'b1111);
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
adrdec #(P.PA_BITS) dtimdec(PhysicalAddress, P.DTIM_BASE[P.PA_BITS-1:0], P.DTIM_RANGE[P.PA_BITS-1:0], P.DTIM_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[11]); adrdec #(P.PA_BITS) dtimdec(PhysicalAddress, P.DTIM_BASE[P.PA_BITS-1:0], P.DTIM_RANGE[P.PA_BITS-1:0], P.DTIM_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[1]);
adrdec #(P.PA_BITS) iromdec(PhysicalAddress, P.IROM_BASE[P.PA_BITS-1:0], P.IROM_RANGE[P.PA_BITS-1:0], P.IROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[10]); adrdec #(P.PA_BITS) iromdec(PhysicalAddress, P.IROM_BASE[P.PA_BITS-1:0], P.IROM_RANGE[P.PA_BITS-1:0], P.IROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[2]);
adrdec #(P.PA_BITS) ddr4dec(PhysicalAddress, P.EXT_MEM_BASE[P.PA_BITS-1:0], P.EXT_MEM_RANGE[P.PA_BITS-1:0], P.EXT_MEM_SUPPORTED, AccessRWXC, Size, SUPPORTED_SIZE, SelRegions[9]); adrdec #(P.PA_BITS) ddr4dec(PhysicalAddress, P.EXT_MEM_BASE[P.PA_BITS-1:0], P.EXT_MEM_RANGE[P.PA_BITS-1:0], P.EXT_MEM_SUPPORTED, AccessRWXC, Size, SUPPORTED_SIZE, SelRegions[3]);
adrdec #(P.PA_BITS) bootromdec(PhysicalAddress, P.BOOTROM_BASE[P.PA_BITS-1:0], P.BOOTROM_RANGE[P.PA_BITS-1:0], P.BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[8]); adrdec #(P.PA_BITS) bootromdec(PhysicalAddress, P.BOOTROM_BASE[P.PA_BITS-1:0], P.BOOTROM_RANGE[P.PA_BITS-1:0], P.BOOTROM_SUPPORTED, AccessRX, Size, SUPPORTED_SIZE, SelRegions[4]);
adrdec #(P.PA_BITS) uncoreramdec(PhysicalAddress, P.UNCORE_RAM_BASE[P.PA_BITS-1:0], P.UNCORE_RAM_RANGE[P.PA_BITS-1:0], P.UNCORE_RAM_SUPPORTED, AccessRWXC, Size, SUPPORTED_SIZE, SelRegions[7]); adrdec #(P.PA_BITS) uncoreramdec(PhysicalAddress, P.UNCORE_RAM_BASE[P.PA_BITS-1:0], P.UNCORE_RAM_RANGE[P.PA_BITS-1:0], P.UNCORE_RAM_SUPPORTED, AccessRWXC, Size, SUPPORTED_SIZE, SelRegions[5]);
adrdec #(P.PA_BITS) clintdec(PhysicalAddress, P.CLINT_BASE[P.PA_BITS-1:0], P.CLINT_RANGE[P.PA_BITS-1:0], P.CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[6]); adrdec #(P.PA_BITS) clintdec(PhysicalAddress, P.CLINT_BASE[P.PA_BITS-1:0], P.CLINT_RANGE[P.PA_BITS-1:0], P.CLINT_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE, SelRegions[6]);
adrdec #(P.PA_BITS) gpiodec(PhysicalAddress, P.GPIO_BASE[P.PA_BITS-1:0], P.GPIO_RANGE[P.PA_BITS-1:0], P.GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[5]); adrdec #(P.PA_BITS) gpiodec(PhysicalAddress, P.GPIO_BASE[P.PA_BITS-1:0], P.GPIO_RANGE[P.PA_BITS-1:0], P.GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[7]);
adrdec #(P.PA_BITS) uartdec(PhysicalAddress, P.UART_BASE[P.PA_BITS-1:0], P.UART_RANGE[P.PA_BITS-1:0], P.UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[4]); adrdec #(P.PA_BITS) uartdec(PhysicalAddress, P.UART_BASE[P.PA_BITS-1:0], P.UART_RANGE[P.PA_BITS-1:0], P.UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[8]);
adrdec #(P.PA_BITS) plicdec(PhysicalAddress, P.PLIC_BASE[P.PA_BITS-1:0], P.PLIC_RANGE[P.PA_BITS-1:0], P.PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]); adrdec #(P.PA_BITS) plicdec(PhysicalAddress, P.PLIC_BASE[P.PA_BITS-1:0], P.PLIC_RANGE[P.PA_BITS-1:0], P.PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[9]);
adrdec #(P.PA_BITS) sdcdec(PhysicalAddress, P.SDC_BASE[P.PA_BITS-1:0], P.SDC_RANGE[P.PA_BITS-1:0], P.SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[2]); adrdec #(P.PA_BITS) sdcdec(PhysicalAddress, P.SDC_BASE[P.PA_BITS-1:0], P.SDC_RANGE[P.PA_BITS-1:0], P.SDC_SUPPORTED, AccessRW, Size, SUPPORTED_SIZE & 4'b1100, SelRegions[10]);
adrdec #(P.PA_BITS) spidec(PhysicalAddress, P.SPI_BASE[P.PA_BITS-1:0], P.SPI_RANGE[P.PA_BITS-1:0], P.SPI_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]); adrdec #(P.PA_BITS) spidec(PhysicalAddress, P.SPI_BASE[P.PA_BITS-1:0], P.SPI_RANGE[P.PA_BITS-1:0], P.SPI_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[11]);
assign SelRegions[0] = ~|(SelRegions[11:1]); // none of the regions are selected assign SelRegions[0] = ~|(SelRegions[11:1]); // none of the regions are selected
endmodule endmodule

View File

@ -139,7 +139,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
assign LeafPTE = Executable | Writable | Readable; assign LeafPTE = Executable | Writable | Readable;
assign ValidPTE = Valid & ~(Writable & ~Readable); assign ValidPTE = Valid & ~(Writable & ~Readable);
assign ValidLeafPTE = ValidPTE & LeafPTE; assign ValidLeafPTE = ValidPTE & LeafPTE;
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; assign ValidNonLeafPTE = Valid & ~LeafPTE;
if(P.SVADU_SUPPORTED) begin : hptwwrites if(P.SVADU_SUPPORTED) begin : hptwwrites
logic ReadAccess, WriteAccess; logic ReadAccess, WriteAccess;
@ -255,13 +255,14 @@ module hptw import cvw::*; #(parameter cvw_t P) (
end end
// Page Table Walker FSM // Page Table Walker FSM
// there is a bug here. Each memory access needs to be potentially flushed if the PMA/P checkers // *** there is a bug here (RT). Each memory access needs to be potentially flushed if the PMA/P checkers
// generate an access fault. Specially the store on UDPATE_PTE needs to check for access violation. // generate an access fault. Specially the store on UDPATE_PTE needs to check for access violation.
// I think the solution is to do 1 of the following // I think the solution is to do 1 of the following
// 1. Allow the HPTW to generate exceptions and stop walking immediately. // 1. Allow the HPTW to generate exceptions and stop walking immediately.
// 2. If the store would generate an exception don't store to dcache but still write the TLB. When we go back // 2. If the store would generate an exception don't store to dcache but still write the TLB. When we go back
// to LEAF then the PMA/P. Wait this does not work. The PMA/P won't be looking a the address in the table, but // to LEAF then the PMA/P. Wait this does not work. The PMA/P won't be looking a the address in the table, but
// rather than physical address of the translated instruction/data. So we must generate the exception. // rather than physical address of the translated instruction/data. So we must generate the exception.
// *** DH 1/1/24 another bug: when the NAPOT bits (PTE[62:61]) are nonzero on a nonleaf PTE, the walker should make a page fault (Issue 546)
flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState); flopenl #(.TYPE(statetype)) WalkerStateReg(clk, reset | FlushW, 1'b1, NextWalkerState, IDLE, WalkerState);
always_comb always_comb
case (WalkerState) case (WalkerState)

View File

@ -55,7 +55,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
output logic UpdateDA, // page fault due to setting dirty or access bit output logic UpdateDA, // page fault due to setting dirty or access bit
output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources output logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned fault sources
// PMA checker signals // PMA checker signals
input logic [3:0] CMOp, // Cache management instructions input logic [3:0] CMOpM, // Cache management instructions
input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type input logic AtomicAccessM, ExecuteAccessF, WriteAccessM, ReadAccessM, // access type
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP addresses
@ -85,7 +85,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
.SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]), .SATP_MODE(SATP_REGW[P.XLEN-1:P.XLEN-P.SVMODE_BITS]),
.SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]), .SATP_ASID(SATP_REGW[P.ASID_BASE+P.ASID_BITS-1:P.ASID_BASE]),
.VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, .VAdr(VAdr[P.XLEN-1:0]), .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOp, .PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM,
.DisableTranslation, .PTE, .PageTypeWriteVal, .DisableTranslation, .PTE, .PageTypeWriteVal,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
.Translate, .TLBPageFault, .UpdateDA, .PBMemoryType); .Translate, .TLBPageFault, .UpdateDA, .PBMemoryType);
@ -107,7 +107,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
// Check physical memory accesses // Check physical memory accesses
/////////////////////////////////////////// ///////////////////////////////////////////
pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOp, pmachecker #(P) pmachecker(.PhysicalAddress, .Size, .CMOpM,
.AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType, .AtomicAccessM, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .PBMemoryType,
.Cacheable, .Idempotent, .SelTIM, .Cacheable, .Idempotent, .SelTIM,
.PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM); .PMAInstrAccessFaultF, .PMALoadAccessFaultM, .PMAStoreAmoAccessFaultM);
@ -115,7 +115,7 @@ module mmu import cvw::*; #(parameter cvw_t P,
if (P.PMP_ENTRIES > 0) begin : pmp if (P.PMP_ENTRIES > 0) begin : pmp
pmpchecker #(P) pmpchecker(.PhysicalAddress, .PrivilegeModeW, pmpchecker #(P) pmpchecker(.PhysicalAddress, .PrivilegeModeW,
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.ExecuteAccessF, .WriteAccessM, .ReadAccessM, .CMOp, .ExecuteAccessF, .WriteAccessM, .ReadAccessM, .CMOpM,
.PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM); .PMPInstrAccessFaultF, .PMPLoadAccessFaultM, .PMPStoreAmoAccessFaultM);
end else begin end else begin
assign PMPInstrAccessFaultF = 0; assign PMPInstrAccessFaultF = 0;

View File

@ -31,7 +31,7 @@
module pmachecker import cvw::*; #(parameter cvw_t P) ( module pmachecker import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic [1:0] Size, input logic [1:0] Size,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
input logic AtomicAccessM, // Atomic access input logic AtomicAccessM, // Atomic access
input logic ExecuteAccessF, // Execute access input logic ExecuteAccessF, // Execute access
input logic WriteAccessM, // Write access input logic WriteAccessM, // Write access
@ -51,29 +51,29 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
// Determine what type of access is being made // Determine what type of access is being made
assign AccessRW = ReadAccessM | WriteAccessM; assign AccessRW = ReadAccessM | WriteAccessM;
assign AccessRWXC = ReadAccessM | WriteAccessM | ExecuteAccessF | (|CMOp); assign AccessRWXC = ReadAccessM | WriteAccessM | ExecuteAccessF | (|CMOpM);
assign AccessRX = ReadAccessM | ExecuteAccessF; assign AccessRX = ReadAccessM | ExecuteAccessF;
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWXC, Size, SelRegions); adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWXC, Size, SelRegions);
// Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable // Only non-core RAM/ROM memory regions are cacheable. PBMT can override cachable; NC and IO are uncachable
assign CacheableRegion = SelRegions[9] | SelRegions[8] | SelRegions[7]; // exclusion-tag: unused-cachable assign CacheableRegion = SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-cachable
assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0; assign Cacheable = (PBMemoryType == 2'b00) ? CacheableRegion : 0;
// Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly // Nonidemdempotent means access could have side effect and must not be done speculatively or redundantly
// I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent // I/O is nonidempotent. PBMT can override PMA; NC is idempotent and IO is non-idempotent
assign IdempotentRegion = SelRegions[11] | SelRegions[10] | SelRegions[9] | SelRegions[8] | SelRegions[7]; // exclusion-tag: unused-idempotent assign IdempotentRegion = SelRegions[1] | SelRegions[2] | SelRegions[3] | SelRegions[4] | SelRegions[5]; // exclusion-tag: unused-idempotent
assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01); assign Idempotent = (PBMemoryType == 2'b00) ? IdempotentRegion : (PBMemoryType == 2'b01);
// Atomic operations are only allowed on RAM // Atomic operations are only allowed on RAM
assign AtomicAllowed = SelRegions[11] | SelRegions[9] | SelRegions[7]; // exclusion-tag: unused-idempotent assign AtomicAllowed = SelRegions[1] | SelRegions[3] | SelRegions[5]; // exclusion-tag: unused-atomic
// Check if tightly integrated memories are selected // Check if tightly integrated memories are selected
assign SelTIM = SelRegions[11] | SelRegions[10]; // exclusion-tag: unused-idempotent assign SelTIM = SelRegions[1] | SelRegions[2]; // exclusion-tag: unused-tim
// Detect access faults // Detect access faults
assign PMAAccessFault = (SelRegions[0]) & AccessRWXC | AtomicAccessM & ~AtomicAllowed; assign PMAAccessFault = SelRegions[0] & AccessRWXC | AtomicAccessM & ~AtomicAllowed;
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault; assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
assign PMAStoreAmoAccessFaultM = (WriteAccessM | (|CMOp)) & PMAAccessFault; assign PMAStoreAmoAccessFaultM = (WriteAccessM | (|CMOpM)) & PMAAccessFault;
endmodule endmodule

View File

@ -42,7 +42,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0],
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0],
input logic ExecuteAccessF, WriteAccessM, ReadAccessM, input logic ExecuteAccessF, WriteAccessM, ReadAccessM,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
output logic PMPInstrAccessFaultF, output logic PMPInstrAccessFaultF,
output logic PMPLoadAccessFaultM, output logic PMPLoadAccessFaultM,
output logic PMPStoreAmoAccessFaultM output logic PMPStoreAmoAccessFaultM
@ -72,8 +72,8 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
// Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region // Only enforce PMP checking for S and U modes or in Machine mode when L bit is set in selected region
assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | (|(L & FirstMatch)); // *** switch to this logic when PMP is initialized for non-machine mode assign EnforcePMP = (PrivilegeModeW != P.M_MODE) | (|(L & FirstMatch)); // *** switch to this logic when PMP is initialized for non-machine mode
assign PMPCBOMAccessFault = EnforcePMP & (|CMOp[2:0]) & ~|((R|W) & FirstMatch) ; assign PMPCBOMAccessFault = EnforcePMP & (|CMOpM[2:0]) & ~|((R|W) & FirstMatch) ;
assign PMPCBOZAccessFault = EnforcePMP & CMOp[3] & ~|(W & FirstMatch) ; assign PMPCBOZAccessFault = EnforcePMP & CMOpM[3] & ~|(W & FirstMatch) ;
assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault; assign PMPCMOAccessFault = PMPCBOZAccessFault | PMPCBOMAccessFault;
assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ; assign PMPInstrAccessFaultF = EnforcePMP & ExecuteAccessF & ~|(X & FirstMatch) ;

View File

@ -62,7 +62,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic ReadAccess, input logic ReadAccess,
input logic WriteAccess, input logic WriteAccess,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
input logic DisableTranslation, input logic DisableTranslation,
input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual) input logic [P.XLEN-1:0] VAdr, // address input before translation (could be physical or virtual)
input logic [P.XLEN-1:0] PTE, // page table entry to write input logic [P.XLEN-1:0] PTE, // page table entry to write
@ -109,7 +109,7 @@ module tlb import cvw::*; #(parameter cvw_t P,
assign NAPOT4 = (PPN[3:0] == 4'b1000); // 64 KiB contiguous region with pte.napot_bits = 4 assign NAPOT4 = (PPN[3:0] == 4'b1000); // 64 KiB contiguous region with pte.napot_bits = 4
tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE, tlbcontrol #(P, ITLB) tlbcontrol(.SATP_MODE, .VAdr, .STATUS_MXR, .STATUS_SUM, .STATUS_MPRV, .STATUS_MPP, .ENVCFG_PBMTE, .ENVCFG_ADUE,
.PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOp, .DisableTranslation, .TLBFlush, .PrivilegeModeW, .ReadAccess, .WriteAccess, .CMOpM, .DisableTranslation, .TLBFlush,
.PTEAccessBits, .CAMHit, .Misaligned, .NAPOT4, .PTEAccessBits, .CAMHit, .Misaligned, .NAPOT4,
.TLBMiss, .TLBHit, .TLBPageFault, .TLBMiss, .TLBHit, .TLBPageFault,
.UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType); .UpdateDA, .SV39Mode, .Translate, .PTE_N, .PBMemoryType);

View File

@ -35,7 +35,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
input logic ENVCFG_ADUE, // HPTW A/D Update enable input logic ENVCFG_ADUE, // HPTW A/D Update enable
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic ReadAccess, WriteAccess, input logic ReadAccess, WriteAccess,
input logic [3:0] CMOp, input logic [3:0] CMOpM,
input logic DisableTranslation, input logic DisableTranslation,
input logic TLBFlush, // Invalidate all TLB entries input logic TLBFlush, // Invalidate all TLB entries
input logic [11:0] PTEAccessBits, input logic [11:0] PTEAccessBits,
@ -69,7 +69,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
assign Translate = (SATP_MODE != P.NO_TRANSLATE[P.SVMODE_BITS-1:0]) & (EffectivePrivilegeMode != P.M_MODE) & ~DisableTranslation; assign Translate = (SATP_MODE != P.NO_TRANSLATE[P.SVMODE_BITS-1:0]) & (EffectivePrivilegeMode != P.M_MODE) & ~DisableTranslation;
// Determine whether TLB is being used // Determine whether TLB is being used
assign TLBAccess = ReadAccess | WriteAccess | (|CMOp); assign TLBAccess = ReadAccess | WriteAccess | (|CMOpM);
// Check that upper bits are legal (all 0s or all 1s) // Check that upper bits are legal (all 0s or all 1s)
vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal); vm64check #(P) vm64check(.SATP_MODE, .VAdr, .SV39Mode, .UpperBitsUnequal);
@ -85,8 +85,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
assign PBMemoryType = PTE_PBMT & {2{Translate & TLBHit & P.SVPBMT_SUPPORTED}}; assign PBMemoryType = PTE_PBMT & {2{Translate & TLBHit & P.SVPBMT_SUPPORTED}};
// check if reserved, N, or PBMT bits are malformed w in RV64 // check if reserved, N, or PBMT bits are malformed w in RV64
assign BadPBMT = PTE_PBMT != 0 & (~(P.SVPBMT_SUPPORTED & ENVCFG_PBMTE) | assign BadPBMT = ((PTE_PBMT != 0) & ~(P.SVPBMT_SUPPORTED & ENVCFG_PBMTE)) | PTE_PBMT == 3; // PBMT must be zero if not supported; value of 3 is reserved
{PTE_X, PTE_W, PTE_R} == 3'b000) | PTE_PBMT == 3; // PBMT must be zero if not supported or for non-leaf PTEs;
assign BadNAPOT = PTE_N & (~P.SVNAPOT_SUPPORTED | ~NAPOT4); // N must be be 0 if CVNAPOT is not supported or not 64 KiB contiguous region assign BadNAPOT = PTE_N & (~P.SVNAPOT_SUPPORTED | ~NAPOT4); // N must be be 0 if CVNAPOT is not supported or not 64 KiB contiguous region
assign BadReserved = PTE_RESERVED; // Reserved bits must be zero assign BadReserved = PTE_RESERVED; // Reserved bits must be zero
@ -94,8 +93,7 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
if (ITLB == 1) begin:itlb // Instruction TLB fault checking if (ITLB == 1) begin:itlb // Instruction TLB fault checking
// User mode may only execute user mode pages, and supervisor mode may // User mode may only execute user mode pages, and supervisor mode may
// only execute non-user mode pages. // only execute non-user mode pages.
assign ImproperPrivilege = ((EffectivePrivilegeMode == P.U_MODE) & ~PTE_U) | assign ImproperPrivilege = ((PrivilegeModeW == P.U_MODE) & ~PTE_U) | ((PrivilegeModeW == P.S_MODE) & PTE_U);
((EffectivePrivilegeMode == P.S_MODE) & PTE_U);
assign PreUpdateDA = ~PTE_A; assign PreUpdateDA = ~PTE_A;
assign InvalidAccess = ~PTE_X; assign InvalidAccess = ~PTE_X;
end else begin:dtlb // Data TLB fault checking end else begin:dtlb // Data TLB fault checking
@ -113,8 +111,8 @@ module tlbcontrol import cvw::*; #(parameter cvw_t P, ITLB = 0) (
// Check for write error. Writes are invalid when the page's write bit is // Check for write error. Writes are invalid when the page's write bit is
// low. // low.
assign InvalidWrite = WriteAccess & ~PTE_W; assign InvalidWrite = WriteAccess & ~PTE_W;
assign InvalidCBOM = (|CMOp[2:0]) & (~PTE_W | (~PTE_R & (~STATUS_MXR | ~PTE_X))); assign InvalidCBOM = (|CMOpM[2:0]) & (~PTE_W | (~PTE_R & (~STATUS_MXR | ~PTE_X)));
assign InvalidCBOZ = CMOp[3] & ~PTE_W; assign InvalidCBOZ = CMOpM[3] & ~PTE_W;
assign InvalidAccess = InvalidRead | InvalidWrite | InvalidCBOM | InvalidCBOZ; assign InvalidAccess = InvalidRead | InvalidWrite | InvalidCBOM | InvalidCBOZ;
assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D; assign PreUpdateDA = ~PTE_A | WriteAccess & ~PTE_D;
end end

View File

@ -54,7 +54,6 @@ module csr import cvw::*; #(parameter cvw_t P) (
input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode input logic SelHPTW, // hardware page table walker active, so base endianness on supervisor mode
// inputs for performance counters // inputs for performance counters
input logic LoadStallD, input logic LoadStallD,
input logic StoreStallD,
input logic ICacheStallF, input logic ICacheStallF,
input logic DCacheStallM, input logic DCacheStallM,
input logic BPDirPredWrongM, input logic BPDirPredWrongM,
@ -275,7 +274,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
if (P.ZICNTR_SUPPORTED) begin:counters if (P.ZICNTR_SUPPORTED) begin:counters
csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM, csrc #(P) counters(.clk, .reset, .StallE, .StallM, .FlushM,
.InstrValidNotFlushedM, .LoadStallD, .StoreStallD, .CSRWriteM, .CSRMWriteM, .InstrValidNotFlushedM, .LoadStallD, .CSRWriteM, .CSRMWriteM,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .sfencevmaM,
.InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .InterruptM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,

View File

@ -32,7 +32,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic StallE, StallM, input logic StallE, StallM,
input logic FlushM, input logic FlushM,
input logic InstrValidNotFlushedM, LoadStallD, StoreStallD, input logic InstrValidNotFlushedM, LoadStallD,
input logic CSRMWriteM, CSRWriteM, input logic CSRMWriteM, CSRWriteM,
input logic BPDirPredWrongM, input logic BPDirPredWrongM,
input logic BTAWrongM, input logic BTAWrongM,
@ -75,7 +75,6 @@ module csrc import cvw::*; #(parameter cvw_t P) (
logic [P.XLEN-1:0] HPMCOUNTER_REGW[P.COUNTERS-1:0]; logic [P.XLEN-1:0] HPMCOUNTER_REGW[P.COUNTERS-1:0];
logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0]; logic [P.XLEN-1:0] HPMCOUNTERH_REGW[P.COUNTERS-1:0];
logic LoadStallE, LoadStallM; logic LoadStallE, LoadStallM;
logic StoreStallE, StoreStallM;
logic [P.COUNTERS-1:0] WriteHPMCOUNTERM; logic [P.COUNTERS-1:0] WriteHPMCOUNTERM;
logic [P.COUNTERS-1:0] CounterEvent; logic [P.COUNTERS-1:0] CounterEvent;
logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0]; logic [63:0] HPMCOUNTERPlusM[P.COUNTERS-1:0];
@ -83,8 +82,8 @@ module csrc import cvw::*; #(parameter cvw_t P) (
genvar i; genvar i;
// Interface signals // Interface signals
flopenrc #(2) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d({StoreStallD, LoadStallD}), .q({StoreStallE, LoadStallE})); // don't flush the load stall during a load stall. flopenrc #(1) LoadStallEReg(.clk, .reset, .clear(1'b0), .en(~StallE), .d(LoadStallD), .q(LoadStallE)); // don't flush the load stall during a load stall.
flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, LoadStallM})); flopenrc #(1) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d(LoadStallE), .q(LoadStallM));
// Determine when to increment each counter // Determine when to increment each counter
assign CounterEvent[0] = 1'b1; // MCYCLE always increments assign CounterEvent[0] = 1'b1; // MCYCLE always increments
@ -100,7 +99,7 @@ module csrc import cvw::*; #(parameter cvw_t P) (
assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
assign CounterEvent[12] = StoreStallM; // Store Stall assign CounterEvent[12] = 0; // depricated Store Stall
assign CounterEvent[13] = DCacheAccess; // data cache access assign CounterEvent[13] = DCacheAccess; // data cache access
assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[15] = DCacheStallM; // d cache miss cycles assign CounterEvent[15] = DCacheStallM; // d cache miss cycles

View File

@ -45,7 +45,6 @@ module privileged import cvw::*; #(parameter cvw_t P) (
// processor events for performance counter logging // processor events for performance counter logging
input logic FRegWriteM, // instruction will write floating-point registers input logic FRegWriteM, // instruction will write floating-point registers
input logic LoadStallD, // load instruction is stalling input logic LoadStallD, // load instruction is stalling
input logic StoreStallD, // store instruction is stalling
input logic ICacheStallF, // I cache stalled input logic ICacheStallF, // I cache stalled
input logic DCacheStallM, // D cache stalled input logic DCacheStallM, // D cache stalled
input logic BPDirPredWrongM, // branch predictor guessed wrong direction input logic BPDirPredWrongM, // branch predictor guessed wrong direction
@ -133,7 +132,7 @@ module privileged import cvw::*; #(parameter cvw_t P) (
.InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM, .InstrM, .InstrOrigM, .PCM, .SrcAM, .IEUAdrM,
.CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM, .CSRReadM, .CSRWriteM, .TrapM, .mretM, .sretM, .InterruptM,
.MTimerInt, .MExtInt, .SExtInt, .MSwInt, .MTimerInt, .MExtInt, .SExtInt, .MSwInt,
.MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD, .StoreStallD, .MTIME_CLINT, .InstrValidM, .FRegWriteM, .LoadStallD,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .BPWrongM,
.sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE, .sfencevmaM, .ExceptionM, .InvalidateICacheM, .ICacheStallF, .DCacheStallM, .DivBusyE, .FDivBusyE,
.IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .IClassWrongM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess,

View File

@ -91,7 +91,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions); adrdecs #(P) adrdecs(HADDR, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions);
// unswizzle HSEL signals // unswizzle HSEL signals
assign {HSELDTIM, HSELIROM, HSELEXT, HSELBootRom, HSELRam, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELEXTSDC, HSELSPI} = HSELRegions[11:1]; assign {HSELSPI, HSELEXTSDC, HSELPLIC, HSELUART, HSELGPIO, HSELCLINT, HSELRam, HSELBootRom, HSELEXT, HSELIROM, HSELDTIM} = HSELRegions[11:1];
// AHB -> APB bridge // AHB -> APB bridge
ahbapbbridge #(P, 5) ahbapbbridge ( ahbapbbridge #(P, 5) ahbapbbridge (
@ -180,7 +180,7 @@ module uncore import cvw::*; #(parameter cvw_t P)(
// device is ready. Hense this register must be selectively enabled by HREADY. // device is ready. Hense this register must be selectively enabled by HREADY.
// However on reset None must be seleted. // However on reset None must be seleted.
flopenl #(12) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions, 12'b1, flopenl #(12) hseldelayreg(HCLK, ~HRESETn, HREADY, HSELRegions, 12'b1,
{HSELDTIMD, HSELIROMD, HSELEXTD, HSELBootRomD, HSELRamD, {HSELSPID, HSELEXTSDCD, HSELPLICD, HSELUARTD, HSELGPIOD, HSELCLINTD,
HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELEXTSDCD, HSELSPID, HSELNoneD}); HSELRamD, HSELBootRomD, HSELEXTD, HSELIROMD, HSELDTIMD, HSELNoneD});
flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED); flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED);
endmodule endmodule

View File

@ -75,7 +75,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic PCSrcE; logic PCSrcE;
logic CSRWriteFenceM; logic CSRWriteFenceM;
logic DivBusyE; logic DivBusyE;
logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD; logic StructuralStallD;
logic LoadStallD;
logic SquashSCW; logic SquashSCW;
logic MDUActiveE; // Mul/Div instruction being executed logic MDUActiveE; // Mul/Div instruction being executed
logic ENVCFG_ADUE; // HPTW A/D Update enable logic ENVCFG_ADUE; // HPTW A/D Update enable
@ -95,7 +96,6 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic FCvtIntW; logic FCvtIntW;
logic FDivBusyE; logic FDivBusyE;
logic FRegWriteM; logic FRegWriteM;
logic FCvtIntStallD;
logic FpLoadStoreM; logic FpLoadStoreM;
logic [4:0] SetFflagsM; logic [4:0] SetFflagsM;
logic [P.XLEN-1:0] FIntDivResultW; logic [P.XLEN-1:0] FIntDivResultW;
@ -211,8 +211,8 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW, .InstrValidM, .InstrValidE, .InstrValidD, .FCvtIntResW, .FCvtIntW,
// hazards // hazards
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD, .PCSrcE, .StructuralStallD, .LoadStallD, .PCSrcE,
.CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM, .StoreStallD); .CSRReadM, .CSRWriteM, .PrivilegedM, .CSRWriteFenceM, .InvalidateICacheM);
lsu #(P) lsu( lsu #(P) lsu(
.clk, .reset, .StallM, .FlushM, .StallW, .FlushW, .clk, .reset, .StallM, .FlushM, .StallW, .FlushW,
@ -266,9 +266,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
// global stall and flush control // global stall and flush control
hazard #(P) hzu( hazard #(P) hzu(
.BPWrongE, .CSRWriteFenceM, .RetM, .TrapM, .BPWrongE, .CSRWriteFenceM, .RetM, .TrapM,
.LoadStallD, .StoreStallD, .MDUStallD, .CSRRdStallD, .StructuralStallD,
.LSUStallM, .IFUStallF, .LSUStallM, .IFUStallF,
.FCvtIntStallD, .FPUStallD, .FPUStallD,
.DivBusyE, .FDivBusyE, .DivBusyE, .FDivBusyE,
.wfiM, .IntPendingM, .wfiM, .IntPendingM,
// Stall & flush outputs // Stall & flush outputs
@ -284,7 +284,7 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM, .InstrM, .InstrOrigM, .CSRReadValW, .EPCM, .TrapVectorM,
.RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF, .RetM, .TrapM, .sfencevmaM, .InvalidateICacheM, .DCacheStallM, .ICacheStallF,
.InstrValidM, .CommittedM, .CommittedF, .InstrValidM, .CommittedM, .CommittedF,
.FRegWriteM, .LoadStallD, .StoreStallD, .FRegWriteM, .LoadStallD,
.BPDirPredWrongM, .BTAWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .BPWrongM,
.RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE, .RASPredPCWrongM, .IClassWrongM, .DivBusyE, .FDivBusyE,
.InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM, .InstrClassM, .DCacheMiss, .DCacheAccess, .ICacheMiss, .ICacheAccess, .PrivilegedM,

View File

@ -205,12 +205,12 @@ module testbench;
end end
always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7]));
always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11]));
always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9]));
always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3]));
always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5]));
final begin final begin
void'(rvviRefShutdown()); void'(rvviRefShutdown());

View File

@ -432,11 +432,12 @@ module testbench;
end end
end end
always @(dut.core.MTimerInt) void'(rvvi.net_push("MTimerInterrupt", dut.core.MTimerInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[7]) void'(rvvi.net_push("MTimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[7]));
always @(dut.core.MExtInt) void'(rvvi.net_push("MExternalInterrupt", dut.core.MExtInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[11]) void'(rvvi.net_push("MExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[11]));
always @(dut.core.SExtInt) void'(rvvi.net_push("SExternalInterrupt", dut.core.SExtInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[9]) void'(rvvi.net_push("SExternalInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[9]));
always @(dut.core.MSwInt) void'(rvvi.net_push("MSWInterrupt", dut.core.MSwInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[3]) void'(rvvi.net_push("MSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[3]));
always @(dut.core.priv.priv.csr.csrs.csrs.STimerInt) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csrs.csrs.STimerInt)); always @(dut.core.priv.priv.csr.csri.MIP_REGW[1]) void'(rvvi.net_push("SSWInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[1]));
always @(dut.core.priv.priv.csr.csri.MIP_REGW[5]) void'(rvvi.net_push("STimerInterrupt", dut.core.priv.priv.csr.csri.MIP_REGW[5]));
final begin final begin
void'(rvviRefShutdown()); void'(rvviRefShutdown());

View File

@ -44,8 +44,9 @@ string tvpaths[] = '{
string coverage64gc[] = '{ string coverage64gc[] = '{
`COVERAGE, `COVERAGE,
"tlbmisc",
"tlbNAPOT",
"ieu", "ieu",
// "tlbNAPOT",
"priv", "priv",
"ebu", "ebu",
"csrwrites", "csrwrites",
@ -2114,7 +2115,7 @@ string arch64zbs[] = '{
`WALLYTEST, `WALLYTEST,
"rv32i_m/privilege/src/WALLY-csr-permission-s-01.S", "rv32i_m/privilege/src/WALLY-csr-permission-s-01.S",
"rv32i_m/privilege/src/WALLY-csr-permission-u-01.S", "rv32i_m/privilege/src/WALLY-csr-permission-u-01.S",
"rv32i_m/privilege/src/WALLY-cbom-01.S", // "rv32i_m/privilege/src/WALLY-cbom-01.S",
"rv32i_m/privilege/src/WALLY-cboz-01.S", "rv32i_m/privilege/src/WALLY-cboz-01.S",
"rv32i_m/privilege/src/WALLY-mie-01.S", "rv32i_m/privilege/src/WALLY-mie-01.S",
"rv32i_m/privilege/src/WALLY-minfo-01.S", "rv32i_m/privilege/src/WALLY-minfo-01.S",

View File

@ -51,9 +51,11 @@ main:
jal a1, looptest jal a1, looptest
li a2, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT li a2, 0x40215240 # Test properly formed pages with 1 in PPN[3] that are not NAPOT
jal a1, looptest jal a1, looptest
# li t4, 0x1000 # address step size li t4, 0x1000 # address step size
# li a2, 0x80216000 # Test NAPOT pages li a2, 0x80216000 # Test NAPOT pages
# jal a1, looptest jal a1, looptest
li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
ecall
j done j done
looptest: looptest:
@ -62,30 +64,64 @@ looptest:
li t3, 35 # Max amount of Loops = 34 li t3, 35 # Max amount of Loops = 34
li t5, 0x8082 # return instruction opcode li t5, 0x8082 # return instruction opcode
loop: bge t2, t3, looptesti # exit loop if i >= loops loop: bge t2, t3, finished # exit loop if i >= loops
sw t5, 0(t0) # store a return at this address to exercise DTLB sw t5, 0(t0) # store a return at this address to exercise DTLB
lw t1, 0(t0) # read it back lw t1, 0(t0) # read it back
fence.i # synchronize with I$ fence.i # synchronize with I$
jal changetoipfhandler # set up trap handler to return from instruction page fault if necessary
jalr ra, t0 # jump to the return statement to exercise the ITLB jalr ra, t0 # jump to the return statement to exercise the ITLB
jal changetodefaulthandler
add t0, t0, t4 add t0, t0, t4
addi t2, t2, 1 addi t2, t2, 1
j loop j loop
looptesti:
mv t0, a2 # base address
li t2, 0 # i = 0
fence.i # synchronize with I$
# Exercise itlb by jumping to each of the return statements
loopi: bge t2, t3, finished # exit loop if i >= loops
jalr ra, t0 # jump to the return statement to exercise the ITLB
add t0, t0, t4
addi t2, t2, 1
j loopi
finished: finished:
jr a1 jr a1
changetoipfhandler:
li a0, 3
ecall # switch to machine mode
la a0, ipf_handler
csrw mtvec, a0 # point to new handler
li a0, 1
ecall # switch back to supervisor mode
ret
changetodefaulthandler:
li a0, 3
ecall # switch to machine mode
la a0, trap_handler
csrw mtvec, a0 # point to new handler
li a0, 1
ecall # switch back to supervisor mode
ret
instructionpagefaulthandler:
csrw mepc, ra # go back to calling function
mret
.align 4 # trap handlers must be aligned to multiple of 4
ipf_handler:
# Load trap handler stack pointer tp
csrrw tp, mscratch, tp # swap MSCRATCH and tp
sd t0, 0(tp) # Save t0 and t1 on the stack
sd t1, -8(tp)
csrr t0, mcause # Check the cause
li t1, 8 # is it an ecall trap?
andi t0, t0, 0xFC # if CAUSE = 8, 9, or 11
beq t0, t1, ecall # yes, take ecall
csrr t0, mcause
li t1, 12 # is it an instruction page fault
beq t0, t1, ipf # yes, return to calling function
j trap_return
ipf:
csrw mepc, ra # return to calling function
ld t1, -8(tp) # restore t1 and t0
ld t0, 0(tp)
csrrw tp, mscratch, tp # restore tp
mret # return from trap
.data .data
.align 16 .align 16

333
tests/coverage/tlbmisc.S Normal file
View File

@ -0,0 +1,333 @@
///////////////////////////////////////////
// tlbmisc.S
//
// Written David_Harris@hmc.edu 1/1/24
//
// Purpose: Test coverage for other TLB issues
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the License); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
// load code to initalize stack, handle interrupts, terminate
#include "WALLY-init-lib.h"
# run-elf.bash find this in project description
main:
li t5, 0x1
slli t5, t5, 62
ori t5, t5, 0xF0
csrs menvcfg, t5 # menvcfg.PBMTE = 1, CBZE, CBCFE, CBIE all 1
# store ret instruction in case we jump to an address mapping to 80000000
li t0, 0x80000000
li t5, 0x8082 # return instruction opcode
sw t5, 0(t0)
fence.i
# Page table root address at 0x80010000; SV48
li t5, 0x9000000000080010
csrw satp, t5
# sfence.vma x0, x0
# switch to supervisor mode
li a0, 1
ecall
# Instruction fetch from misaligned pages
jal changetoipfhandler # set up trap handler to return from instruction page fault if necessary
li t0, 0x8000000000
jalr ra, t0 # jump misaligned terapage
li t0, 0x00000000
jalr ra, t0 # jump to misaligned gigapage
li t0, 0x80200000
jalr ra, t0 # jump to misaligned megapage
# exercise ebufsmarb
li t0, 0x80000000
lw t1, 0(t0) # fetch from an address to warm up tlb entries
li t0, 0x80A00000
lw t1, 0(t0) # trigger TLB miss on a non-first entry
jal backandforth
# exercise malformed PBMT pages
# page has PBMT = 3 (reserved)
li t0, 0x80400000
lw t1, 0(t0) # read from page
sw t1, 0(t0) # write to page
jalr ra, t0 # jump to page
# Nonleaf PTE has PBMT != 0 # this should cause a page fault during page walking. However, as of issue 546 1/1/24, both ImperasDV and Wally don't detect this
li t0, 0x80600000
lw t1, 0(t0) # read from page
sw t1, 0(t0) # write to page
jalr ra, t0 # jump to page
# change back to default trap handler after checking everything that might cause an instruction page fault
jal changetodefaulthandler
# exercise CBOM instructions with various permissions
li t0, 0x80800000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80801000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80802000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80803000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80804000
cbo.zero (t0)
cbo.clean (t0)
# set mstatus.MXR
li a0, 3
ecall
li t0, 1
slli t0, t0, 19
csrs mstatus, t0 # mstatus.mxr = 1
li a0, 1
ecall
# exercise CBOM again now that MXR is set
li t0, 0x80800000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80801000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80802000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80803000
cbo.zero (t0)
cbo.clean (t0)
li t0, 0x80804000
cbo.zero (t0)
cbo.clean (t0)
# clear mstatus.MXR
li a0, 3
ecall
li t0, 1
slli t0, t0, 19
csrc mstatus, t0 # mstatus.mxr = 1
li a0, 1
ecall
# wrap up
li a0, 3 # switch back to machine mode because code at 0x80000000 may not have clean page table entry
ecall
j done
backandforth:
ret
changetoipfhandler:
li a0, 3
ecall # switch to machine mode
la a0, ipf_handler
csrw mtvec, a0 # point to new handler
li a0, 1
ecall # switch back to supervisor mode
ret
changetodefaulthandler:
li a0, 3
ecall # switch to machine mode
la a0, trap_handler
csrw mtvec, a0 # point to new handler
li a0, 1
ecall # switch back to supervisor mode
ret
instructionpagefaulthandler:
csrw mepc, ra # go back to calling function
mret
.align 4 # trap handlers must be aligned to multiple of 4
ipf_handler:
# Load trap handler stack pointer tp
csrrw tp, mscratch, tp # swap MSCRATCH and tp
sd t0, 0(tp) # Save t0 and t1 on the stack
sd t1, -8(tp)
csrr t0, mcause # Check the cause
li t1, 8 # is it an ecall trap?
andi t0, t0, 0xFC # if CAUSE = 8, 9, or 11
beq t0, t1, ecall # yes, take ecall
csrr t0, mcause
li t1, 12 # is it an instruction page fault
beq t0, t1, ipf # yes, return to calling function
j trap_return
ipf:
csrw mepc, ra # return to calling function
ld t1, -8(tp) # restore t1 and t0
ld t0, 0(tp)
csrrw tp, mscratch, tp # restore tp
mret # return from trap
.data
.align 16
# root Page table situated at 0x80010000
pagetable:
.8byte 0x200044C1 # 0x00000000-0x80_00000000: PTE at 0x80011000 C1 dirty, accessed, valid
.8byte 0x00000000000010CF # misaligned terapage at 0x80_00000000
# next page table at 0x80011000
.align 12
.8byte 0x00000000000010CF # misaligned gigapage at 0x00000000
.8byte 0x00000000200058C1 # PTE for pages at 0x40000000
.8byte 0x00000000200048C1 # gigapage at 0x80000000 pointing to 0x80120000
# Next page table at 0x80012000 for gigapage at 0x80000000
.align 12
.8byte 0x0000000020004CC1 # for VA starting at 80000000 (pointer to NAPOT 64 KiB pages)
.8byte 0x0000000020014CCF # for VA starting at 80200000 (misaligned megapage)
.8byte 0x00000000200050C1 # for VA starting at 80400000 (bad PBMT pages)
.8byte 0x4000000020004CC1 # for VA starting at 80600000 (bad entry: nonleaf PTE can't have PBMT != 0)
.8byte 0x00000000200054C1 # for VA starting at 80800000 (testing rwx permissiosn with cbom/cboz)
.8byte 0x0000000020004CC1 # for VA starting at 80A00000 (pointer to NAPOT 64 KiB pages like at 80000000)
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
.8byte 0x0000000020004CC1
# Leaf page table at 0x80013000 with NAPOT pages
.align 12
#80000000
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0xA0000000200020CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x80000000200060CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000A0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
.8byte 0x800000002000E0CF
# Leaf page table at 0x80014000 with PBMT pages
.align 12
#80400000
.8byte 0x60000000200020CF # reserved entry
# Leaf page table at 0x80015000 with various permissions for testing CBOM and CBOZ
.align 12
#80800000
.8byte 0x00000000200000CF # valid rwx for VA 80800000
.8byte 0x00000000200000CB # valid r x for VA 80801000
.8byte 0x00000000200000C3 # valid r for VA 80802000
.8byte 0x00000000200000C5 # valid x for VA 80803000
.8byte 0x00000000200000CD # valid wx for VA 80804000 (illegal combination, but used to test tlbcontrol)

View File

@ -1,7 +1,7 @@
hart_ids: [0] hart_ids: [0]
hart0: hart0:
# ISA: RV64IMAFDCSUZicsr_Zicboz_Zifencei_Zca_Zba_Zbb_Zbc_Zbs # Zkbs_Zcb # ISA: RV64IMAFDCSUZicsr_Zicboz_Zifencei_Zbb_Zbc_Zbs # Zkbs_Zcb
ISA: RV64IMAFDCSUZicsr_Zifencei_Zbb_Zbc_Zbs # Zkbs_Zcb ISA: RV64IMAFDCSUZicsr_Zifencei_Zca_Zcb_Zbb_Zbc_Zbs # Zkbs_Zcb
physical_addr_sz: 56 physical_addr_sz: 56
User_Spec_Version: '2.3' User_Spec_Version: '2.3'
supported_xlen: [64] supported_xlen: [64]