This commit is contained in:
Ross Thompson 2023-06-15 14:57:23 -05:00
commit d2219023c3
98 changed files with 1848 additions and 1762 deletions

View File

@ -4,7 +4,11 @@
all: all:
make install make install
make regression make testfloat
make riscof
make verify
make coverage
make benchmarks
# install copies over the Makefile.include from riscv-isa-sim # install copies over the Makefile.include from riscv-isa-sim
# And corrects the TARGETDIR path and the RISCV_PREFIX # And corrects the TARGETDIR path and the RISCV_PREFIX
@ -18,9 +22,37 @@ install:
##rm tests/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64/riscvOVPsimPlus.exe ##rm tests/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64/riscvOVPsimPlus.exe
##ln -s ${RISCV}/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64/riscvOVPsimPlus.exe tests/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64/riscvOVPsimPlus.exe ##ln -s ${RISCV}/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64/riscvOVPsimPlus.exe tests/imperas-riscv-tests/riscv-ovpsim-plus/bin/Linux64/riscvOVPsimPlus.exe
regression: riscof:
make -C sim make -C sim
testfloat:
cd ${WALLY}/addins/SoftFloat-3e/build/Linux-x86_64-GCC; make
cd ${WALLY}/addins/TestFloat-3e/build/Linux-x86_64-GCC; make
cd ${WALLY}/tests/fp; ./create_all_vectors.sh
verify:
cd ${WALLY}/sim; ./regression-wally
cd ${WALLY}/sim; ./sim-testfloat-batch all
make imperasdv
imperasdv:
iter-elf.bash --search ${WALLY}/tests/riscof/work/wally-riscv-arch-test/rv64i_m
iter-elf.bash --search ${WALLY}/tests/riscof/work/riscv-arch-test/rv64i_m
coverage:
cd ${WALLY}/sim; ./regresssion-wally -coverage -fp
benchmarks:
make coremark
make embench
coremark:
cd ${WALLY}/benchmarks/coremark; make; make run
embench:
cd ${WALLY}/benchmarks/embench; make; make run
clean: clean:
make clean -C sim make clean -C sim

View File

@ -11,7 +11,11 @@ sources=$(cmbase)/core_main.c $(cmbase)/core_list_join.c $(cmbase)/coremark.h \
$(PORT_DIR)/core_portme.h $(PORT_DIR)/core_portme.c $(PORT_DIR)/core_portme.mak \ $(PORT_DIR)/core_portme.h $(PORT_DIR)/core_portme.c $(PORT_DIR)/core_portme.mak \
$(PORT_DIR)/crt.S $(PORT_DIR)/encoding.h $(PORT_DIR)/util.h $(PORT_DIR)/syscalls.c $(PORT_DIR)/crt.S $(PORT_DIR)/encoding.h $(PORT_DIR)/util.h $(PORT_DIR)/syscalls.c
ABI := $(if $(findstring "64","$(XLEN)"),lp64,ilp32) ABI := $(if $(findstring "64","$(XLEN)"),lp64,ilp32)
ARCH := rv$(XLEN)gc #ARCH := rv$(XLEN)gc_zba_zbb_zbc_zbs
#ARCH := rv$(XLEN)gc
ARCH := rv$(XLEN)imc_zicsr
#ARCH := rv$(XLEN)im_zicsr
#ARCH := rv$(XLEN)i_zicsr
PORT_CFLAGS = -g -mabi=$(ABI) -march=$(ARCH) -static -falign-functions=16 \ PORT_CFLAGS = -g -mabi=$(ABI) -march=$(ARCH) -static -falign-functions=16 \
-mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-3-series -O3 -finline-functions -falign-jumps=4 \ -mbranch-cost=1 -DSKIP_DEFAULT_MEMSET -mtune=sifive-3-series -O3 -finline-functions -falign-jumps=4 \
-fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 \ -fno-delete-null-pointer-checks -fno-rename-registers --param=loop-max-datarefs-for-datadeps=0 \

View File

@ -45,7 +45,7 @@ sudo mkdir -p $RISCV
# Update and Upgrade tools (see https://itsfoss.com/apt-update-vs-upgrade/) # Update and Upgrade tools (see https://itsfoss.com/apt-update-vs-upgrade/)
sudo apt update -y sudo apt update -y
sudo apt upgrade -y sudo apt upgrade -y
sudo apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev libglib2.0-dev python3-pip pkg-config opam z3 zlib1g-dev verilator automake autotools-dev libmpc-dev libmpfr-dev gperf libtool patchutils bc sudo apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev libglib2.0-dev python3-pip pkg-config opam z3 zlib1g-dev automake autotools-dev libmpc-dev libmpfr-dev gperf libtool patchutils bc
# Other python libraries used through the book. # Other python libraries used through the book.
sudo pip3 install matplotlib scipy scikit-learn adjustText lief sudo pip3 install matplotlib scipy scikit-learn adjustText lief
@ -113,6 +113,23 @@ cd ../arch_test_target/spike/device
sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include
sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include
# Wally needs Verilator 5.0 or later.
# Verilator needs to be built from scratch to get the latest version
# apt-get install verilator installs version 4.028 as of 6/8/23
sudo apt-get install -y perl g++ ccache help2man libgoogle-perftools-dev numactl perl-doc zlibc zlib1g
sudo apt-get install -y libfl2 libfl-dev # Ubuntu only (ignore if gives error)
cd $RISCV
git clone https://github.com/verilator/verilator # Only first time
unsetenv VERILATOR_ROOT # For csh; ignore error if on bash
unset VERILATOR_ROOT # For bash
cd verilator
git pull # Make sure git repository is up-to-date
git checkout master # Use development branch (e.g. recent bug fixes)
autoconf # Create ./configure script
./configure # Configure and create Makefile
make -j NUM_THREADS # Build Verilator itself (if error, try just 'make')
sudo make install
# Sail (https://github.com/riscv/sail-riscv) # Sail (https://github.com/riscv/sail-riscv)
# Sail is the new golden reference model for RISC-V. Sail is written in OCaml, which # Sail is the new golden reference model for RISC-V. Sail is written in OCaml, which
# is an object-oriented extension of ML, which in turn is a functional programming # is an object-oriented extension of ML, which in turn is a functional programming

View File

@ -40,10 +40,16 @@ localparam IEEE754 = 0;
localparam MISA = (32'h0014112D); localparam MISA = (32'h0014112D);
localparam ZICSR_SUPPORTED = 1; localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1; localparam ZIFENCEI_SUPPORTED = 1;
localparam ZICOUNTERS_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 1; localparam BUS_SUPPORTED = 1;

View File

@ -41,9 +41,14 @@ localparam MISA = (32'h00000010);
localparam ZICSR_SUPPORTED = 0; localparam ZICSR_SUPPORTED = 0;
localparam ZIFENCEI_SUPPORTED = 0; localparam ZIFENCEI_SUPPORTED = 0;
localparam COUNTERS = 12'd0; localparam COUNTERS = 12'd0;
localparam ZICOUNTERS_SUPPORTED = 0; localparam ZICNTR_SUPPORTED = 0;
localparam ZIHPM_SUPPORTED = 0;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 1; localparam BUS_SUPPORTED = 1;

View File

@ -42,9 +42,14 @@ localparam MISA = (32'h00000104 | 1 << 20 | 1 << 18 | 1 << 12 | 1 << 0 | 1 <<3 |
localparam ZICSR_SUPPORTED = 1; localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1; localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZICOUNTERS_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 1; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 1; localparam BUS_SUPPORTED = 1;

View File

@ -40,10 +40,15 @@ localparam IEEE754 = 0;
localparam MISA = (32'h00000104); localparam MISA = (32'h00000104);
localparam ZICSR_SUPPORTED = 0; localparam ZICSR_SUPPORTED = 0;
localparam ZIFENCEI_SUPPORTED = 0; localparam ZIFENCEI_SUPPORTED = 0;
localparam COUNTERS = 12'd32; localparam COUNTERS = 0;
localparam ZICOUNTERS_SUPPORTED = 0; localparam ZICNTR_SUPPORTED = 0;
localparam ZIHPM_SUPPORTED = 0;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 0; localparam BUS_SUPPORTED = 0;

View File

@ -40,9 +40,14 @@ localparam MISA = (32'h00000104 | 1 << 20 | 1 << 18 | 1 << 12);
localparam ZICSR_SUPPORTED = 1; localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1; localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZICOUNTERS_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 1; localparam BUS_SUPPORTED = 1;

View File

@ -41,9 +41,14 @@ localparam MISA = (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 16 | 1 << 18 | 1 << 20
localparam ZICSR_SUPPORTED = 1; localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1; localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZICOUNTERS_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 1; localparam ZFH_SUPPORTED = 1;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 1; localparam BUS_SUPPORTED = 1;

View File

@ -44,9 +44,14 @@ localparam MISA = (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12
localparam ZICSR_SUPPORTED = 1; localparam ZICSR_SUPPORTED = 1;
localparam ZIFENCEI_SUPPORTED = 1; localparam ZIFENCEI_SUPPORTED = 1;
localparam COUNTERS = 12'd32; localparam COUNTERS = 12'd32;
localparam ZICOUNTERS_SUPPORTED = 1; localparam ZICNTR_SUPPORTED = 1;
localparam ZIHPM_SUPPORTED = 1;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 1; localparam SSTC_SUPPORTED = 1;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 1; localparam BUS_SUPPORTED = 1;

View File

@ -40,10 +40,15 @@ localparam IEEE754 = 0;
localparam MISA = (32'h00000104); localparam MISA = (32'h00000104);
localparam ZICSR_SUPPORTED = 0; localparam ZICSR_SUPPORTED = 0;
localparam ZIFENCEI_SUPPORTED = 0; localparam ZIFENCEI_SUPPORTED = 0;
localparam COUNTERS = 12'd32; localparam COUNTERS = 0;
localparam ZICOUNTERS_SUPPORTED = 0; localparam ZICNTR_SUPPORTED = 0;
localparam ZIHPM_SUPPORTED = 0;
localparam ZFH_SUPPORTED = 0; localparam ZFH_SUPPORTED = 0;
localparam SSTC_SUPPORTED = 0; localparam SSTC_SUPPORTED = 0;
localparam ZICBOM_SUPPORTED = 0;
localparam ZICBOZ_SUPPORTED = 0;
localparam ZICBOP_SUPPORTED = 0;
localparam SVPBMT_SUPPORTED = 0;
// LSU microarchitectural Features // LSU microarchitectural Features
localparam BUS_SUPPORTED = 0; localparam BUS_SUPPORTED = 0;

View File

@ -11,20 +11,25 @@ parameter cvw_t P = '{
ZICSR_SUPPORTED : ZICSR_SUPPORTED, ZICSR_SUPPORTED : ZICSR_SUPPORTED,
ZIFENCEI_SUPPORTED : ZIFENCEI_SUPPORTED, ZIFENCEI_SUPPORTED : ZIFENCEI_SUPPORTED,
COUNTERS : COUNTERS, COUNTERS : COUNTERS,
ZICOUNTERS_SUPPORTED : ZICOUNTERS_SUPPORTED, ZICNTR_SUPPORTED : ZICNTR_SUPPORTED,
ZIHPM_SUPPORTED : ZIHPM_SUPPORTED,
ZFH_SUPPORTED : ZFH_SUPPORTED, ZFH_SUPPORTED : ZFH_SUPPORTED,
SSTC_SUPPORTED : SSTC_SUPPORTED, SSTC_SUPPORTED : SSTC_SUPPORTED,
VIRTMEM_SUPPORTED : VIRTMEM_SUPPORTED, VIRTMEM_SUPPORTED : VIRTMEM_SUPPORTED,
VECTORED_INTERRUPTS_SUPPORTED : VECTORED_INTERRUPTS_SUPPORTED, VECTORED_INTERRUPTS_SUPPORTED : VECTORED_INTERRUPTS_SUPPORTED,
BIGENDIAN_SUPPORTED : BIGENDIAN_SUPPORTED, BIGENDIAN_SUPPORTED : BIGENDIAN_SUPPORTED,
SVADU_SUPPORTED : SVADU_SUPPORTED, SVADU_SUPPORTED : SVADU_SUPPORTED,
ZMMUL_SUPPORTED : ZMMUL_SUPPORTED, ZMMUL_SUPPORTED : ZMMUL_SUPPORTED,
ZICBOM_SUPPORTED : ZICBOM_SUPPORTED,
ZICBOZ_SUPPORTED : ZICBOZ_SUPPORTED,
ZICBOP_SUPPORTED : ZICBOP_SUPPORTED,
SVPBMT_SUPPORTED : SVPBMT_SUPPORTED,
BUS_SUPPORTED : BUS_SUPPORTED, BUS_SUPPORTED : BUS_SUPPORTED,
DCACHE_SUPPORTED : DCACHE_SUPPORTED, DCACHE_SUPPORTED : DCACHE_SUPPORTED,
ICACHE_SUPPORTED : ICACHE_SUPPORTED, ICACHE_SUPPORTED : ICACHE_SUPPORTED,
ITLB_ENTRIES : ITLB_ENTRIES, ITLB_ENTRIES : ITLB_ENTRIES,
DTLB_ENTRIES : DTLB_ENTRIES, DTLB_ENTRIES : DTLB_ENTRIES,
DCACHE_NUMWAYS : DCACHE_NUMWAYS, DCACHE_NUMWAYS : DCACHE_NUMWAYS,
DCACHE_WAYSIZEINBYTES : DCACHE_WAYSIZEINBYTES, DCACHE_WAYSIZEINBYTES : DCACHE_WAYSIZEINBYTES,
DCACHE_LINELENINBITS : DCACHE_LINELENINBITS, DCACHE_LINELENINBITS : DCACHE_LINELENINBITS,
ICACHE_NUMWAYS : ICACHE_NUMWAYS, ICACHE_NUMWAYS : ICACHE_NUMWAYS,

60
sim/FPbuild.txt Normal file
View File

@ -0,0 +1,60 @@
Procedure for Runnning SoftFloat/TestFloat with Wally
1.) First, compile SoftFloat and TestFloat by going to the addins
directory and finding the specific build directory (e.g.,
Linux_x86_64-GCC. Currently, we are using v3e of
SoftFloat/TestFloat. I am not sure of the order, but I always compile
SoftFloat first as I believe TestFloat uses the static library
SoftFloat creates.
2.) Once compiled both, go to the tests/fp directory and run the
create_vectors.sh Linux script. In the past, we have automated this,
but I believe this has fallen into more of a manual state lately.
3.) Then, run remove_spaces.sh which will remove spaces from the
output and put underscores between vectors (this helps differentiate
the vectors that are generated). Again, this can be combined with
Step 2.
4.) TestFloat is run from wally/cvw/sim and sim-testfloat-batch with
its respective test. The format is ./sim-testfloat-add add. All of
the tests are listed below. This can be augmented or added to for
other FP tests given by the great SoftFloat/TestFloat output.
cvtint - test integer conversion unit (fcvtint)
cvtfp - test floating-point conversion unit (fcvtfp)
cmp - test comparison unit's LT, LE, EQ opperations (fcmp)
add - test addition
fma - test fma
mul - test mult with fma
sub - test subtraction
div - test division
sqrt - test square root
all - test everything
4a.) Each test will test all its vectors - if you want to test a
subset of the vectors (e.g., only binary16), you should modify the
cvw/testbench/tests-fp.h and comment out the tests you do not want to
test. The best way to do this is to comment out each item out with
the // comment option in SV. For example,
string f128div[] = '{
// "f128_div_rne.tv",
// "f128_div_rz.tv",
// "f128_div_ru.tv",
// "f128_div_rd.tv",
// "f128_div_rnm.tv"
};

3
src/cache/cache.sv vendored
View File

@ -63,7 +63,7 @@ module cache #(parameter PA_BITS, XLEN, LINELEN, NUMLINES, NUMWAYS, LOGBWPL, W
localparam OFFSETLEN = $clog2(LINEBYTELEN); // Number of bits in offset field localparam OFFSETLEN = $clog2(LINEBYTELEN); // Number of bits in offset field
localparam SETLEN = $clog2(NUMLINES); // Number of set bits localparam SETLEN = $clog2(NUMLINES); // Number of set bits
localparam SETTOP = SETLEN+OFFSETLEN; // Number of set plus offset bits localparam SETTOP = SETLEN+OFFSETLEN; // Number of set plus offset bits
localparam TAGLEN = PA_BITS - SETTOP; // Number of tag bits localparam TAGLEN = PA_BITS - SETTOP; // Number of tag bits
localparam CACHEWORDSPERLINE = LINELEN/WORDLEN;// Number of words in cache line localparam CACHEWORDSPERLINE = LINELEN/WORDLEN;// Number of words in cache line
localparam LOGCWPL = $clog2(CACHEWORDSPERLINE);// Log2 of ^ localparam LOGCWPL = $clog2(CACHEWORDSPERLINE);// Log2 of ^
localparam FLUSHADRTHRESHOLD = NUMLINES - 1; // Used to determine when flush is complete localparam FLUSHADRTHRESHOLD = NUMLINES - 1; // Used to determine when flush is complete
@ -182,6 +182,7 @@ module cache #(parameter PA_BITS, XLEN, LINELEN, NUMLINES, NUMWAYS, LOGBWPL, W
assign LineWriteData = FetchBuffer; assign LineWriteData = FetchBuffer;
assign LineByteMask = '1; assign LineByteMask = '1;
end end
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Flush logic // Flush logic
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -104,8 +104,7 @@ module cacheLRU
if (node == NUMWAYS-2) begin if (node == NUMWAYS-2) begin
assign LRUUpdate[lchild] = ~WayEncoded[r]; assign LRUUpdate[lchild] = ~WayEncoded[r];
assign LRUUpdate[rchild] = WayEncoded[r]; assign LRUUpdate[rchild] = WayEncoded[r];
end end else begin
else begin
assign LRUUpdate[lchild] = LRUUpdate[node] & ~WayEncoded[r]; assign LRUUpdate[lchild] = LRUUpdate[node] & ~WayEncoded[r];
assign LRUUpdate[rchild] = LRUUpdate[node] & WayEncoded[r]; assign LRUUpdate[rchild] = LRUUpdate[node] & WayEncoded[r];
end end

14
src/cache/cacheway.sv vendored
View File

@ -84,8 +84,7 @@ module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN =
// 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 SelFlush=0 while FlushWay=1 since FlushWay only advances on a subset of SelFlush assertion cases.
assign FlushWayEn = FlushWay & SelFlush; assign FlushWayEn = FlushWay & SelFlush;
assign SelNonHit = FlushWayEn | SetValid | SelWriteback; assign SelNonHit = FlushWayEn | SetValid | SelWriteback;
end end else begin:flushlogic // no flush operation for read-only caches.
else begin:flushlogic // no flush operation for read-only caches.
assign SelTag = VictimWay; assign SelTag = VictimWay;
assign SelNonHit = SetValid; assign SelNonHit = SetValid;
end end
@ -135,8 +134,7 @@ module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN =
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]), .dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]), .din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
.we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words])); .we(SelectedWriteWordEn), .bwe(FinalByteMask[SRAMLENINBYTES*(words+1)-1:SRAMLENINBYTES*words]));
end end else begin:wordram // no byte-enable needed for i$.
else begin:wordram // no byte-enable needed for i$.
ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet), ram1p1rwe #(.DEPTH(NUMLINES), .WIDTH(SRAMLEN)) CacheDataMem(.clk, .ce(CacheEn), .addr(CacheSet),
.dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]), .dout(ReadDataLine[SRAMLEN*(words+1)-1:SRAMLEN*words]),
.din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]), .din(LineWriteData[SRAMLEN*(words+1)-1:SRAMLEN*words]),
@ -154,8 +152,8 @@ module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN =
always_ff @(posedge clk) begin // Valid bit array, always_ff @(posedge clk) begin // Valid bit array,
if (reset) ValidBits <= #1 '0; if (reset) ValidBits <= #1 '0;
if(CacheEn) begin if(CacheEn) begin
ValidWay <= #1 ValidBits[CacheSet]; ValidWay <= #1 ValidBits[CacheSet];
if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway if(InvalidateCache) ValidBits <= #1 '0; // exclusion-tag: dcache invalidateway
else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay; else if (SetValidEN) ValidBits[CacheSet] <= #1 SetValidWay;
end end
end end
@ -175,8 +173,4 @@ module cacheway #(parameter PA_BITS, XLEN, NUMLINES=512, LINELEN = 256, TAGLEN =
end end
end end
end else assign Dirty = 1'b0; end else assign Dirty = 1'b0;
endmodule endmodule

View File

@ -43,9 +43,8 @@ module subcachelineread #(parameter LINELEN, WORDLEN,
logic [LINELEN+(WORDLEN-MUXINTERVAL)-1:0] ReadDataLinePad; logic [LINELEN+(WORDLEN-MUXINTERVAL)-1:0] ReadDataLinePad;
logic [WORDLEN-1:0] ReadDataLineSets [(LINELEN/MUXINTERVAL)-1:0]; logic [WORDLEN-1:0] ReadDataLineSets [(LINELEN/MUXINTERVAL)-1:0];
if (PADLEN > 0) begin if (PADLEN > 0) assign ReadDataLinePad = {{PADLEN{1'b0}}, ReadDataLine};
assign ReadDataLinePad = {{PADLEN{1'b0}}, ReadDataLine}; else assign ReadDataLinePad = ReadDataLine;
end else assign ReadDataLinePad = ReadDataLine;
genvar index; genvar index;
for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux for (index = 0; index < WORDSPERLINE; index++) begin:readdatalinesetsmux

View File

@ -45,14 +45,14 @@ module ahbcacheinterface #(
output logic [2:0] HSIZE, // AHB transaction width output logic [2:0] HSIZE, // AHB transaction width
output logic [2:0] HBURST, // AHB burst length output logic [2:0] HBURST, // AHB burst length
// bus interface buses // bus interface buses
input logic [AHBW-1:0] HRDATA, // AHB read data input logic [AHBW-1:0] HRDATA, // AHB read data
output logic [PA_BITS-1:0] HADDR, // AHB address output logic [PA_BITS-1:0] HADDR, // AHB address
output logic [AHBW-1:0] HWDATA, // AHB write data output logic [AHBW-1:0] HWDATA, // AHB write data
output logic [AHBW/8-1:0] HWSTRB, // AHB byte mask output logic [AHBW/8-1:0] HWSTRB, // AHB byte mask
// cache interface // cache interface
input logic [PA_BITS-1:0] CacheBusAdr, // Address of cache line input logic [PA_BITS-1:0] CacheBusAdr, // Address of cache line
input logic [LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback input logic [LLEN-1:0] CacheReadDataWordM, // One word of cache line during a writeback
input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$ input logic CacheableOrFlushCacheM, // Memory operation is cacheable or flushing D$
input logic Cacheable, // Memory operation is cachable input logic Cacheable, // Memory operation is cachable
input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch input logic [1:0] CacheBusRW, // Cache bus operation, 01: writeback, 10: fetch
@ -62,8 +62,8 @@ module ahbcacheinterface #(
output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr output logic SelBusBeat, // Tells the cache to select the word from ReadData or WriteData from BeatCount rather than PAdr
// uncached interface // uncached interface
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 [2:0] Funct3, // Size of uncached memory operation input logic [2:0] Funct3, // Size of uncached memory operation
@ -75,11 +75,11 @@ module ahbcacheinterface #(
localparam BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index localparam BeatCountThreshold = BEATSPERLINE - 1; // Largest beat index
logic [PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation logic [PA_BITS-1:0] LocalHADDR; // Address after selecting between cached and uncached operation
logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage logic [AHBWLOGBWPL-1:0] BeatCountDelayed; // Beat within the cache line in the second (Data) cache stage
logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA logic CaptureEn; // Enable updating the Fetch buffer with valid data from HRDATA
logic [AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s logic [AHBW/8-1:0] BusByteMaskM; // Byte enables within a word. For cache request all 1s
logic [AHBW-1:0] PreHWDATA; // AHB Address phase write data logic [AHBW-1:0] PreHWDATA; // AHB Address phase write data
genvar index; genvar index;

View File

@ -36,19 +36,19 @@ module ahbinterface #(
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ output logic [1:0] HTRANS, // AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic HWRITE, // AHB 0: Read operation 1: Write operation output logic HWRITE, // AHB 0: Read operation 1: Write operation
input logic [XLEN-1:0] HRDATA, // AHB read data input logic [XLEN-1:0] HRDATA, // AHB read data
output logic [XLEN-1:0] HWDATA, // AHB write data output logic [XLEN-1:0] HWDATA, // AHB write data
output logic [XLEN/8-1:0] HWSTRB, // AHB byte mask output logic [XLEN/8-1:0] HWSTRB, // AHB byte mask
// lsu/ifu interface // lsu/ifu interface
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, // Memory operation read/write control: 10: read, 01: write input logic [1:0] BusRW, // Memory operation read/write control: 10: read, 01: write
input logic [XLEN/8-1:0] ByteMask, // Bytes enables within a word input logic [XLEN/8-1:0] ByteMask, // Bytes enables within a word
input logic [XLEN-1:0] WriteData, // IEU write data for a store input logic [XLEN-1:0] WriteData, // IEU write data for a store
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
output logic [(LSU ? XLEN : 32)-1:0] FetchBuffer // Register to hold HRDATA after arriving from the bus output logic [(LSU ? XLEN : 32)-1:0] FetchBuffer // Register to hold HRDATA after arriving from the bus
); );
logic CaptureEn; logic CaptureEn;

View File

@ -46,14 +46,14 @@ module controllerinput #(
input logic HWRITEIn, // Manager input. AHB 0: Read operation 1: Write operation input logic HWRITEIn, // Manager input. AHB 0: Read operation 1: Write operation
input logic [2:0] HSIZEIn, // Manager input. AHB transaction width input logic [2:0] HSIZEIn, // Manager input. AHB transaction width
input logic [2:0] HBURSTIn, // Manager input. AHB burst length input logic [2:0] HBURSTIn, // Manager input. AHB burst length
input logic [PA_BITS-1:0] HADDRIn, // Manager input. AHB address input logic [PA_BITS-1:0] HADDRIn, // Manager input. AHB address
output logic HREADYOut, // Indicate to manager the peripheral is not busy and another manager does not have priority output logic HREADYOut, // Indicate to manager the peripheral is not busy and another manager does not have priority
// controller output // controller output
output logic [1:0] HTRANSOut, // Arbitrated manager transaction. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ output logic [1:0] HTRANSOut, // Arbitrated manager transaction. AHB transaction type, 00: IDLE, 10 NON_SEQ, 11 SEQ
output logic HWRITEOut, // Arbitrated manager transaction. AHB 0: Read operation 1: Write operation output logic HWRITEOut, // Arbitrated manager transaction. AHB 0: Read operation 1: Write operation
output logic [2:0] HSIZEOut, // Arbitrated manager transaction. AHB transaction width output logic [2:0] HSIZEOut, // Arbitrated manager transaction. AHB transaction width
output logic [2:0] HBURSTOut, // Arbitrated manager transaction. AHB burst length output logic [2:0] HBURSTOut, // Arbitrated manager transaction. AHB burst length
output logic [PA_BITS-1:0] HADDROut, // Arbitrated manager transaction. AHB address output logic [PA_BITS-1:0] HADDROut, // Arbitrated manager transaction. AHB address
input logic HREADYIn // Peripheral ready input logic HREADYIn // Peripheral ready
); );
@ -61,7 +61,7 @@ module controllerinput #(
logic [2:0] HSIZESave; logic [2:0] HSIZESave;
logic [2:0] HBURSTSave; logic [2:0] HBURSTSave;
logic [1:0] HTRANSSave; logic [1:0] HTRANSSave;
logic [PA_BITS-1:0] HADDRSave; logic [PA_BITS-1:0] HADDRSave;
if (SAVE_ENABLED) begin if (SAVE_ENABLED) begin
flopenr #(1+3+3+2+PA_BITS) SaveReg(HCLK, ~HRESETn, Save, flopenr #(1+3+3+2+PA_BITS) SaveReg(HCLK, ~HRESETn, Save,
@ -83,6 +83,3 @@ module controllerinput #(
assign HREADYOut = HREADYIn & ~Disable; assign HREADYOut = HREADYIn & ~Disable;
endmodule endmodule

View File

@ -37,25 +37,25 @@ module ebu #(parameter XLEN, PA_BITS, AHBW)(
input logic [1:0] IFUHTRANS, // IFU AHB transaction request input logic [1:0] IFUHTRANS, // IFU AHB transaction request
input logic [2:0] IFUHSIZE, // IFU AHB transaction size input logic [2:0] IFUHSIZE, // IFU AHB transaction size
input logic [2:0] IFUHBURST, // IFU AHB burst length input logic [2:0] IFUHBURST, // IFU AHB burst length
input logic [PA_BITS-1:0] IFUHADDR, // IFU AHB address input logic [PA_BITS-1:0] IFUHADDR, // IFU AHB address
output logic IFUHREADY, // AHB peripheral ready gated by possible non-grant output logic IFUHREADY, // AHB peripheral ready gated by possible non-grant
// Signals from LSU // Signals from LSU
input logic [1:0] LSUHTRANS, // LSU AHB transaction request input logic [1:0] LSUHTRANS, // LSU AHB transaction request
input logic LSUHWRITE, // LSU AHB transaction direction. 1: write, 0: read input logic LSUHWRITE, // LSU AHB transaction direction. 1: write, 0: read
input logic [2:0] LSUHSIZE, // LSU AHB size input logic [2:0] LSUHSIZE, // LSU AHB size
input logic [2:0] LSUHBURST, // LSU AHB burst length input logic [2:0] LSUHBURST, // LSU AHB burst length
input logic [PA_BITS-1:0] LSUHADDR, // LSU AHB address input logic [PA_BITS-1:0] LSUHADDR, // LSU AHB address
input logic [XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN input logic [XLEN-1:0] LSUHWDATA, // initially support AHBW = XLEN
input logic [XLEN/8-1:0] LSUHWSTRB, // AHB byte mask input logic [XLEN/8-1:0] LSUHWSTRB, // AHB byte mask
output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority
// AHB-Lite external signals // AHB-Lite external signals
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
input logic HREADY, // AHB peripheral ready input logic HREADY, // AHB peripheral ready
input logic HRESP, // AHB peripheral response. 0: OK 1: Error input logic HRESP, // AHB peripheral response. 0: OK 1: Error
output logic [PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration output logic [PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration
output logic [AHBW-1:0] HWDATA, // AHB Write data after arbitration output logic [AHBW-1:0] HWDATA, // AHB Write data after arbitration
output logic [XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration output logic [XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration
output logic HWRITE, // AHB transaction direction after arbitration output logic HWRITE, // AHB transaction direction after arbitration
output logic [2:0] HSIZE, // AHB transaction size after arbitration output logic [2:0] HSIZE, // AHB transaction size after arbitration
output logic [2:0] HBURST, // AHB burst length after arbitration output logic [2:0] HBURST, // AHB burst length after arbitration
@ -71,13 +71,13 @@ module ebu #(parameter XLEN, PA_BITS, AHBW)(
logic IFUDisable; logic IFUDisable;
logic IFUSelect; logic IFUSelect;
logic [PA_BITS-1:0] IFUHADDROut; logic [PA_BITS-1:0] IFUHADDROut;
logic [1:0] IFUHTRANSOut; logic [1:0] IFUHTRANSOut;
logic [2:0] IFUHBURSTOut; logic [2:0] IFUHBURSTOut;
logic [2:0] IFUHSIZEOut; logic [2:0] IFUHSIZEOut;
logic IFUHWRITEOut; logic IFUHWRITEOut;
logic [PA_BITS-1:0] LSUHADDROut; logic [PA_BITS-1:0] LSUHADDROut;
logic [1:0] LSUHTRANSOut; logic [1:0] LSUHTRANSOut;
logic [2:0] LSUHBURSTOut; logic [2:0] LSUHBURSTOut;
logic [2:0] LSUHSIZEOut; logic [2:0] LSUHSIZEOut;

View File

@ -33,7 +33,7 @@ module fclassify import cvw::*; #(parameter cvw_t P) (
input logic XSubnorm, // is Subnormal input logic XSubnorm, // is Subnormal
input logic XZero, // is zero input logic XZero, // is zero
input logic XInf, // is infinity input logic XInf, // is infinity
output logic [P.XLEN-1:0] ClassRes // classify result output logic [P.XLEN-1:0] ClassRes // classify result
); );
logic PInf, PZero, PNorm, PSubnorm; // is the input a positive infinity/zero/normal/subnormal logic PInf, PZero, PNorm, PSubnorm; // is the input a positive infinity/zero/normal/subnormal

View File

@ -1,4 +1,3 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// fcmp.sv // fcmp.sv
// //
@ -36,23 +35,23 @@
module fcmp import cvw::*; #(parameter cvw_t P) ( module fcmp import cvw::*; #(parameter cvw_t P) (
input logic [P.FMTBITS-1:0] Fmt, // format of fp number input logic [P.FMTBITS-1:0] Fmt, // format of fp number
input logic [2:0] OpCtrl, // see above table input logic [2:0] OpCtrl, // see above table
input logic Xs, Ys, // input signs input logic Xs, Ys, // input signs
input logic [P.NE-1:0] Xe, Ye, // input exponents input logic [P.NE-1:0] Xe, Ye, // input exponents
input logic [P.NF:0] Xm, Ym, // input mantissa input logic [P.NF:0] Xm, Ym, // input mantissa
input logic XZero, YZero, // is zero input logic XZero, YZero, // is zero
input logic XNaN, YNaN, // is NaN input logic XNaN, YNaN, // is NaN
input logic XSNaN, YSNaN, // is signaling NaN input logic XSNaN, YSNaN, // is signaling NaN
input logic [P.FLEN-1:0] X, Y, // original inputs (before unpacker) input logic [P.FLEN-1:0] X, Y, // original inputs (before unpacker)
output logic CmpNV, // invalid flag output logic CmpNV, // invalid flag
output logic [P.FLEN-1:0] CmpFpRes, // compare floating-point result output logic [P.FLEN-1:0] CmpFpRes, // compare floating-point result
output logic [P.XLEN-1:0] CmpIntRes // compare integer result output logic [P.XLEN-1:0] CmpIntRes // compare integer result
); );
logic LTabs, LT, EQ; // is X < or > or = Y logic LTabs, LT, EQ; // is X < or > or = Y
logic [P.FLEN-1:0] NaNRes; // NaN result logic [P.FLEN-1:0] NaNRes; // NaN result
logic BothZero; // are both inputs zero logic BothZero; // are both inputs zero
logic EitherNaN, EitherSNaN; // are either input a (signaling) NaN logic EitherNaN, EitherSNaN; // are either input a (signaling) NaN
assign LTabs= {1'b0, Xe, Xm} < {1'b0, Ye, Ym}; // unsigned comparison, treating FP as integers assign LTabs= {1'b0, Xe, Xm} < {1'b0, Ye, Ym}; // unsigned comparison, treating FP as integers
assign LT = (Xs & ~Ys) | (Xs & Ys & ~LTabs & ~EQ) | (~Xs & ~Ys & LTabs); // signed comparison assign LT = (Xs & ~Ys) | (Xs & Ys & ~LTabs & ~EQ) | (~Xs & ~Ys & LTabs); // signed comparison
@ -62,7 +61,6 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
assign EitherNaN = XNaN|YNaN; assign EitherNaN = XNaN|YNaN;
assign EitherSNaN = XSNaN|YSNaN; assign EitherSNaN = XSNaN|YSNaN;
// flags // flags
// Min/Max - if an input is a signaling NaN set invalid flag // Min/Max - if an input is a signaling NaN set invalid flag
// LT/LE - signaling - sets invalid if NaN input // LT/LE - signaling - sets invalid if NaN input
@ -85,11 +83,11 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
// select the NaN result // select the NaN result
if (P.FPSIZES == 1) if (P.FPSIZES == 1)
if(P.IEEE754) assign NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]}; if(P.IEEE754) assign NaNRes = {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]};
else assign NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}}; else assign NaNRes = {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}};
else if (P.FPSIZES == 2) else if (P.FPSIZES == 2)
if(P.IEEE754) assign NaNRes = Fmt ? {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, Xs, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]}; if(P.IEEE754) assign NaNRes = Fmt ? {Xs, {P.NE{1'b1}}, 1'b1, Xm[P.NF-2:0]} : {{P.FLEN-P.LEN1{1'b1}}, Xs, {P.NE1{1'b1}}, 1'b1, Xm[P.NF-2:P.NF-P.NF1]};
else assign NaNRes = Fmt ? {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)}; else assign NaNRes = Fmt ? {1'b0, {P.NE{1'b1}}, 1'b1, {P.NF-1{1'b0}}} : {{P.FLEN-P.LEN1{1'b1}}, 1'b0, {P.NE1{1'b1}}, 1'b1, (P.NF1-1)'(0)};
else if (P.FPSIZES == 3) else if (P.FPSIZES == 3)
always_comb always_comb
@ -123,7 +121,6 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
else NaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)}; else NaNRes = {{P.FLEN-P.H_LEN{1'b1}}, 1'b0, {P.H_NE{1'b1}}, 1'b1, (P.H_NF-1)'(0)};
endcase endcase
// Min/Max // Min/Max
// - outputs the min/max of X and Y // - outputs the min/max of X and Y
// - -0 < 0 // - -0 < 0
@ -154,5 +151,4 @@ module fcmp import cvw::*; #(parameter cvw_t P) (
// - inf = inf and -inf = -inf // - inf = inf and -inf = -inf
// - return 0 if comparison with NaN (unordered) // - return 0 if comparison with NaN (unordered)
assign CmpIntRes = {(P.XLEN-1)'(0), (((EQ|BothZero)&OpCtrl[1])|(LT&OpCtrl[0]&~BothZero))&~EitherNaN}; assign CmpIntRes = {(P.XLEN-1)'(0), (((EQ|BothZero)&OpCtrl[1])|(LT&OpCtrl[0]&~BothZero))&~EitherNaN};
endmodule endmodule

View File

@ -27,57 +27,57 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fctrl import cvw::*; #(parameter cvw_t P) ( module fctrl import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic reset, input logic reset,
// input control signals // input control signals
input logic StallE, StallM, StallW, // stall signals input logic StallE, StallM, StallW, // stall signals
input logic FlushE, FlushM, FlushW, // flush signals input logic FlushE, FlushM, FlushW, // flush signals
input logic IntDivE, // is inteteger division input logic IntDivE, // is inteteger division
input logic [2:0] FRM_REGW, // rounding mode from CSR input logic [2:0] FRM_REGW, // rounding mode from CSR
input logic [1:0] STATUS_FS, // is FPU enabled? input logic [1:0] STATUS_FS, // is FPU enabled?
input logic FDivBusyE, // is the divider busy input logic FDivBusyE, // is the divider busy
// intruction // intruction
input logic [31:0] InstrD, // the full instruction input logic [31:0] InstrD, // the full instruction
input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision input logic [6:0] Funct7D, // bits 31:25 of instruction - may contain percision
input logic [6:0] OpD, // bits 6:0 of instruction input logic [6:0] OpD, // bits 6:0 of instruction
input logic [4:0] Rs2D, // bits 24:20 of instruction input logic [4:0] Rs2D, // bits 24:20 of instruction
input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode input logic [2:0] Funct3D, Funct3E, // bits 14:12 of instruction - may contain rounding mode
// input mux selections // input mux selections
output logic XEnD, YEnD, ZEnD, // enable inputs output logic XEnD, YEnD, ZEnD, // enable inputs
output logic XEnE, YEnE, ZEnE, // enable inputs output logic XEnE, YEnE, ZEnE, // enable inputs
// opperation mux selections // opperation mux selections
output logic FCvtIntE, FCvtIntW, // convert to integer opperation output logic FCvtIntE, FCvtIntW, // convert to integer opperation
output logic [2:0] FrmM, // FP rounding mode output logic [2:0] FrmM, // FP rounding mode
output logic [P.FMTBITS-1:0] FmtE, FmtM, // FP format output logic [P.FMTBITS-1:0] FmtE, FmtM, // FP format
output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component output logic [2:0] OpCtrlE, OpCtrlM, // Select which opperation to do in each component
output logic FpLoadStoreM, // FP load or store instruction output logic FpLoadStoreM, // FP load or store instruction
output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit output logic [1:0] PostProcSelE, PostProcSelM, // select result in the post processing unit
output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage output logic [1:0] FResSelE, FResSelM, FResSelW, // Select one of the results that finish in the memory stage
// register control signals // register control signals
output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable output logic FRegWriteE, FRegWriteM, FRegWriteW, // FP register write enable
output logic FWriteIntE, FWriteIntM, // Write to integer register output logic FWriteIntE, FWriteIntM, // Write to integer register
output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input output logic [4:0] Adr1D, Adr2D, Adr3D, // adresses of each input
output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input output logic [4:0] Adr1E, Adr2E, Adr3E, // adresses of each input
// other control signals // other control signals
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
output logic FDivStartE, IDivStartE // Start division or squareroot output logic FDivStartE, IDivStartE // Start division or squareroot
); );
`define FCTRLW 12 `define FCTRLW 12
logic [`FCTRLW-1:0] ControlsD; // control signals logic [`FCTRLW-1:0] ControlsD; // control signals
logic FRegWriteD; // FP register write enable logic FRegWriteD; // FP register write enable
logic FDivStartD; // start division/sqrt logic FDivStartD; // start division/sqrt
logic FWriteIntD; // integer register write enable logic FWriteIntD; // integer register write enable
logic [2:0] OpCtrlD; // Select which opperation to do in each component logic [2:0] OpCtrlD; // Select which opperation to do in each component
logic [1:0] PostProcSelD; // select result in the post processing unit logic [1:0] PostProcSelD; // select result in the post processing unit
logic [1:0] FResSelD; // Select one of the results that finish in the memory stage logic [1:0] FResSelD; // Select one of the results that finish in the memory stage
logic [2:0] FrmD, FrmE; // FP rounding mode logic [2:0] FrmD, FrmE; // FP rounding mode
logic [P.FMTBITS-1:0] FmtD; // FP format logic [P.FMTBITS-1:0] FmtD; // FP format
logic [1:0] Fmt, Fmt2; // format - before possible reduction logic [1:0] Fmt, Fmt2; // format - before possible reduction
logic SupportedFmt; // is the format supported logic SupportedFmt; // is the format supported
logic SupportedFmt2; // is the source format supported for fp -> fp logic SupportedFmt2; // is the source format supported for fp -> fp
logic FCvtIntD, FCvtIntM; // convert to integer opperation logic FCvtIntD, FCvtIntM; // convert to integer opperation
// FPU Instruction Decoder // FPU Instruction Decoder
assign Fmt = Funct7D[1:0]; assign Fmt = Funct7D[1:0];
@ -97,7 +97,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0; // for anything other than loads and stores, check for supported format ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0; // for anything other than loads and stores, check for supported format
else begin else begin
ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0; // default: non-implemented instruction ControlsD = `FCTRLW'b0_0_00_00_000_0_1_0; // default: non-implemented instruction
/* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed /* verilator lint_off CASEINCOMPLETE */ // default value above has priority so no other default needed
case(OpD) case(OpD)
7'b0000111: case(Funct3D) 7'b0000111: case(Funct3D)
3'b010: ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flw 3'b010: ControlsD = `FCTRLW'b1_0_10_00_0xx_0_0_0; // flw
@ -232,8 +232,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
logic [1:0] FmtTmp; logic [1:0] FmtTmp;
assign FmtTmp = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : (~OpD[6]&(&OpD[2:0])) ? {~Funct3D[1], ~(Funct3D[1]^Funct3D[0])} : Funct7D[1:0]; assign FmtTmp = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : (~OpD[6]&(&OpD[2:0])) ? {~Funct3D[1], ~(Funct3D[1]^Funct3D[0])} : Funct7D[1:0];
assign FmtD = (P.FMT == FmtTmp); assign FmtD = (P.FMT == FmtTmp);
end end else if (P.FPSIZES == 3|P.FPSIZES == 4)
else if (P.FPSIZES == 3|P.FPSIZES == 4)
assign FmtD = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0]; assign FmtD = ((Funct7D[6:3] == 4'b0100)&OpD[4]) ? Rs2D[1:0] : Funct7D[1:0];
// Enables indicate that a source register is used and may need stalls. Also indicate special cases for infinity or NaN. // Enables indicate that a source register is used and may need stalls. Also indicate special cases for infinity or NaN.
@ -250,12 +249,9 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
((FResSelD==2'b11)&(PostProcSelD==2'b00))| // mv float to int ((FResSelD==2'b11)&(PostProcSelD==2'b00))| // mv float to int
((FResSelD==2'b01)&((PostProcSelD==2'b00)|((PostProcSelD==2'b01)&OpCtrlD[0])))); // cvt both or sqrt ((FResSelD==2'b01)&((PostProcSelD==2'b00)|((PostProcSelD==2'b01)&OpCtrlD[0])))); // cvt both or sqrt
// Z - fma ops only // Z - fma ops only
assign ZEnD = (PostProcSelD==2'b10)&(~OpCtrlD[2]|OpCtrlD[1]); // fma, add, sub assign ZEnD = (PostProcSelD==2'b10)&(~OpCtrlD[2]|OpCtrlD[1]); // fma, add, sub
// Final Res Sel: // Final Res Sel:
// fp int // fp int
// 00 other cmp // 00 other cmp
@ -321,7 +317,7 @@ module fctrl import cvw::*; #(parameter cvw_t P) (
// Integer division on FPU divider // Integer division on FPU divider
if (P.M_SUPPORTED & P.IDIV_ON_FPU) assign IDivStartE = IntDivE; if (P.M_SUPPORTED & P.IDIV_ON_FPU) assign IDivStartE = IntDivE;
else assign IDivStartE = 0; else assign IDivStartE = 0;
// E/M pipleine register // E/M pipleine register
flopenrc #(13+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM, flopenrc #(13+int'(P.FMTBITS)) EMCtrlReg (clk, reset, FlushM, ~StallM,

View File

@ -1,4 +1,3 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// fcvt.sv // fcvt.sv
// //
@ -96,7 +95,7 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
// int -> fp : | positive integer | 00000... (if needed) | // int -> fp : | positive integer | 00000... (if needed) |
// fp -> fp : | fraction | 00000... (if needed) | // fp -> fp : | fraction | 00000... (if needed) |
assign LzcInFull = IntToFp ? {TrimInt, {P.CVTLEN-P.XLEN+1{1'b0}}} : assign LzcInFull = IntToFp ? {TrimInt, {P.CVTLEN-P.XLEN+1{1'b0}}} :
{Xm, {P.CVTLEN-P.NF{1'b0}}}; {Xm, {P.CVTLEN-P.NF{1'b0}}};
// used as shifter input in postprocessor // used as shifter input in postprocessor
assign LzcIn = LzcInFull[P.CVTLEN-1:0]; assign LzcIn = LzcInFull[P.CVTLEN-1:0];
@ -222,5 +221,4 @@ module fcvt import cvw::*; #(parameter cvw_t P) (
if(Int64) Cs = Int[P.XLEN-1]&Signed; if(Int64) Cs = Int[P.XLEN-1]&Signed;
else Cs = Int[31]&Signed; else Cs = Int[31]&Signed;
else Cs = Xs; else Cs = Xs;
endmodule endmodule

View File

@ -50,9 +50,10 @@ module fdivsqrtcycles import cvw::*; #(parameter cvw_t P) (
else if (P.FPSIZES == 3) else if (P.FPSIZES == 3)
always_comb always_comb
case (FmtE) case (FmtE)
P.FMT: Nf = P.NF; P.FMT: Nf = P.NF;
P.FMT1: Nf = P.NF1; P.FMT1: Nf = P.NF1;
P.FMT2: Nf = P.NF2; P.FMT2: Nf = P.NF2;
default: Nf = 'x; // shouldn't happen
endcase endcase
else if (P.FPSIZES == 4) else if (P.FPSIZES == 4)
always_comb always_comb

View File

@ -56,7 +56,6 @@ module fhazard(
// if the needed value is in the writeback stage // if the needed value is in the writeback stage
end else if ((Adr1E == RdW) & FRegWriteW) ForwardXE = 2'b01; // choose FResult64W end else if ((Adr1E == RdW) & FRegWriteW) ForwardXE = 2'b01; // choose FResult64W
// if the needed value is in the memory stage - input 2 // if the needed value is in the memory stage - input 2
if ((Adr2E == RdM) & FRegWriteM) begin if ((Adr2E == RdM) & FRegWriteM) begin
// if the result will be FResM (can be taken from the memory stage) // if the result will be FResM (can be taken from the memory stage)
@ -64,7 +63,6 @@ module fhazard(
// if the needed value is in the writeback stage // if the needed value is in the writeback stage
end else if ((Adr2E == RdW) & FRegWriteW) ForwardYE = 2'b01; // choose FResult64W end else if ((Adr2E == RdW) & FRegWriteW) ForwardYE = 2'b01; // choose FResult64W
// if the needed value is in the memory stage - input 3 // if the needed value is in the memory stage - input 3
if ((Adr3E == RdM) & FRegWriteM) begin if ((Adr3E == RdM) & FRegWriteM) begin
// if the result will be FResM (can be taken from the memory stage) // if the result will be FResM (can be taken from the memory stage)
@ -72,5 +70,4 @@ module fhazard(
// if the needed value is in the writeback stage // if the needed value is in the writeback stage
end else if ((Adr3E == RdW) & FRegWriteW) ForwardZE = 2'b01; // choose FResult64W end else if ((Adr3E == RdW) & FRegWriteW) ForwardZE = 2'b01; // choose FResult64W
end end
endmodule endmodule

View File

@ -27,40 +27,40 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fpu import cvw::*; #(parameter cvw_t P) ( module fpu import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic reset, input logic reset,
// Hazards // Hazards
input logic StallE, StallM, StallW, // stall signals (from HZU) input logic StallE, StallM, StallW, // stall signals (from HZU)
input logic FlushE, FlushM, FlushW, // flush signals (from HZU) input logic FlushE, FlushM, FlushW, // flush signals (from HZU)
output logic FPUStallD, // Stall the decode stage (To HZU) output logic FPUStallD, // Stall the decode stage (To HZU)
output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU) output logic FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) (to HZU)
// CSRs // CSRs
input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit) input logic [1:0] STATUS_FS, // Is floating-point enabled? (From privileged unit)
input logic [2:0] FRM_REGW, // Rounding mode (from CSR) input logic [2:0] FRM_REGW, // Rounding mode (from CSR)
// Decode stage // Decode stage
input logic [31:0] InstrD, // instruction (from IFU) input logic [31:0] InstrD, // instruction (from IFU)
// Execute stage // Execute stage
input logic [2:0] Funct3E, // Funct fields of instruction specify type of operations input logic [2:0] Funct3E, // Funct fields of instruction specify type of operations
input logic IntDivE, W64E, // Integer division on FPU input logic IntDivE, W64E, // Integer division on FPU
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input for convert, move, and int div (from IEU) input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Integer input for convert, move, and int div (from IEU)
input logic [4:0] RdE, // which FP register to write to (from IEU) input logic [4:0] RdE, // which FP register to write to (from IEU)
output logic FWriteIntE, // integer register write enable (to IEU) output logic FWriteIntE, // integer register write enable (to IEU)
output logic FCvtIntE, // Convert to int (to IEU) output logic FCvtIntE, // Convert to int (to IEU)
// Memory stage // Memory stage
input logic [2:0] Funct3M, // Funct fields of instruction specify type of operations input logic [2:0] Funct3M, // Funct fields of instruction specify type of operations
input logic [4:0] RdM, // which FP register to write to (from IEU) input logic [4:0] RdM, // which FP register to write to (from IEU)
output logic FRegWriteM, // FP register write enable (to privileged unit) output logic FRegWriteM, // FP register write enable (to privileged unit)
output logic FpLoadStoreM, // Fp load instruction? (to LSU) output logic FpLoadStoreM, // Fp load instruction? (to LSU)
output logic [P.FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU) output logic [P.FLEN-1:0] FWriteDataM, // Data to be written to memory (to LSU)
output logic [P.XLEN-1:0] FIntResM, // data to be written to integer register (to IEU) output logic [P.XLEN-1:0] FIntResM, // data to be written to integer register (to IEU)
output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to IFU) output logic IllegalFPUInstrD, // Is the instruction an illegal fpu instruction (to IFU)
output logic [4:0] SetFflagsM, // FPU flags (to privileged unit) output logic [4:0] SetFflagsM, // FPU flags (to privileged unit)
// Writeback stage // Writeback stage
input logic [4:0] RdW, // which FP register to write to (from IEU) input logic [4:0] RdW, // which FP register to write to (from IEU)
input logic [P.FLEN-1:0] ReadDataW, // Read data (from LSU) input logic [P.FLEN-1:0] ReadDataW, // Read data (from LSU)
output logic [P.XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU) output logic [P.XLEN-1:0] FCvtIntResW, // convert result to to be written to integer register (to IEU)
output logic FCvtIntW, // select FCvtIntRes (to IEU) output logic FCvtIntW, // select FCvtIntRes (to IEU)
output logic [P.XLEN-1:0] FIntDivResultW // Result from integer division (to IEU) output logic [P.XLEN-1:0] FIntDivResultW // Result from integer division (to IEU)
); );
// RISC-V FPU specifics: // RISC-V FPU specifics:
@ -68,86 +68,86 @@ module fpu import cvw::*; #(parameter cvw_t P) (
// - RISC-V detects underflow after rounding // - RISC-V detects underflow after rounding
// control signals // control signals
logic FRegWriteW; // FP register write enable logic FRegWriteW; // FP register write enable
logic [2:0] FrmM; // FP rounding mode logic [2:0] FrmM; // FP rounding mode
logic [P.FMTBITS-1:0] FmtE, FmtM; // FP precision 0-single 1-double logic [P.FMTBITS-1:0] FmtE, FmtM; // FP precision 0-single 1-double
logic FDivStartE, IDivStartE; // Start division or squareroot logic FDivStartE, IDivStartE; // Start division or squareroot
logic FWriteIntM; // Write to integer register logic FWriteIntM; // Write to integer register
logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals logic [1:0] ForwardXE, ForwardYE, ForwardZE; // forwarding mux control signals
logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component logic [2:0] OpCtrlE, OpCtrlM; // Select which opperation to do in each component
logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage logic [1:0] FResSelE, FResSelM, FResSelW; // Select one of the results that finish in the memory stage
logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit logic [1:0] PostProcSelE, PostProcSelM; // select result in the post processing unit
logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input logic [4:0] Adr1D, Adr2D, Adr3D; // register adresses of each input
logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input logic [4:0] Adr1E, Adr2E, Adr3E; // register adresses of each input
logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation logic XEnD, YEnD, ZEnD; // X, Y, Z inputs used for current operation
logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation logic XEnE, YEnE, ZEnE; // X, Y, Z inputs used for current operation
logic FRegWriteE; // Write floating-point register logic FRegWriteE; // Write floating-point register
// regfile signals // regfile signals
logic [P.FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage logic [P.FLEN-1:0] FRD1D, FRD2D, FRD3D; // Read Data from FP register - decode stage
logic [P.FLEN-1:0] FRD1E, FRD2E, FRD3E; // Read Data from FP register - execute stage logic [P.FLEN-1:0] FRD1E, FRD2E, FRD3E; // Read Data from FP register - execute stage
logic [P.FLEN-1:0] XE; // Input 1 to the various units (after forwarding) logic [P.FLEN-1:0] XE; // Input 1 to the various units (after forwarding)
logic [P.XLEN-1:0] IntSrcXE; // Input 1 to the various units (after forwarding) logic [P.XLEN-1:0] IntSrcXE; // Input 1 to the various units (after forwarding)
logic [P.FLEN-1:0] PreYE, YE; // Input 2 to the various units (after forwarding) logic [P.FLEN-1:0] PreYE, YE; // Input 2 to the various units (after forwarding)
logic [P.FLEN-1:0] PreZE, ZE; // Input 3 to the various units (after forwarding) logic [P.FLEN-1:0] PreZE, ZE; // Input 3 to the various units (after forwarding)
// unpacking signals // unpacking signals
logic XsE, YsE, ZsE; // input's sign - execute stage logic XsE, YsE, ZsE; // input's sign - execute stage
logic XsM, YsM; // input's sign - memory stage logic XsM, YsM; // input's sign - memory stage
logic [P.NE-1:0] XeE, YeE, ZeE; // input's exponent - execute stage logic [P.NE-1:0] XeE, YeE, ZeE; // input's exponent - execute stage
logic [P.NE-1:0] ZeM; // input's exponent - memory stage logic [P.NE-1:0] ZeM; // input's exponent - memory stage
logic [P.NF:0] XmE, YmE, ZmE; // input's significand - execute stage logic [P.NF:0] XmE, YmE, ZmE; // input's significand - execute stage
logic [P.NF:0] XmM, YmM, ZmM; // input's significand - memory stage logic [P.NF:0] XmM, YmM, ZmM; // input's significand - memory stage
logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage logic XNaNE, YNaNE, ZNaNE; // is the input a NaN - execute stage
logic XNaNM, YNaNM, ZNaNM; // is the input a NaN - memory stage logic XNaNM, YNaNM, ZNaNM; // is the input a NaN - memory stage
logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage logic XSNaNE, YSNaNE, ZSNaNE; // is the input a signaling NaN - execute stage
logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage logic XSNaNM, YSNaNM, ZSNaNM; // is the input a signaling NaN - memory stage
logic XSubnormE; // is the input subnormal logic XSubnormE; // is the input subnormal
logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage logic XZeroE, YZeroE, ZZeroE; // is the input zero - execute stage
logic XZeroM, YZeroM; // is the input zero - memory stage logic XZeroM, YZeroM; // is the input zero - memory stage
logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage logic XInfE, YInfE, ZInfE; // is the input infinity - execute stage
logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage logic XInfM, YInfM, ZInfM; // is the input infinity - memory stage
logic XExpMaxE; // is the exponent all ones (max value) logic XExpMaxE; // is the exponent all ones (max value)
logic [P.FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations logic [P.FLEN-1:0] XPostBoxE; // X after fixing bad NaN box. Needed for 1-input operations
// Fma Signals // Fma Signals
logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting logic FmaAddSubE; // Multiply by 1.0 when adding or subtracting
logic [1:0] FmaZSelE; // Select Z = Y when adding or subtracting, 0 when multiplying logic [1:0] FmaZSelE; // Select Z = Y when adding or subtracting, 0 when multiplying
logic [3*P.NF+3:0] SmE, SmM; // Sum significand logic [3*P.NF+3:0] SmE, SmM; // Sum significand
logic FmaAStickyE, FmaAStickyM; // FMA addend sticky bit output logic FmaAStickyE, FmaAStickyM; // FMA addend sticky bit output
logic [P.NE+1:0] SeE,SeM; // Sum exponent logic [P.NE+1:0] SeE,SeM; // Sum exponent
logic InvAE, InvAM; // Invert addend logic InvAE, InvAM; // Invert addend
logic AsE, AsM; // Addend sign logic AsE, AsM; // Addend sign
logic PsE, PsM; // Product sign logic PsE, PsM; // Product sign
logic SsE, SsM; // Sum sign logic SsE, SsM; // Sum sign
logic [$clog2(3*P.NF+5)-1:0] SCntE, SCntM; // LZA sum leading zero count logic [$clog2(3*P.NF+5)-1:0] SCntE, SCntM; // LZA sum leading zero count
// Cvt Signals // Cvt Signals
logic [P.NE:0] CeE, CeM; // convert intermediate expoent logic [P.NE:0] CeE, CeM; // convert intermediate expoent
logic [P.LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by logic [P.LOGCVTLEN-1:0] CvtShiftAmtE, CvtShiftAmtM; // how much to shift by
logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal logic CvtResSubnormUfE, CvtResSubnormUfM; // does the result underflow or is subnormal
logic CsE, CsM; // convert result sign logic CsE, CsM; // convert result sign
logic IntZeroE, IntZeroM; // is the integer zero? logic IntZeroE, IntZeroM; // is the integer zero?
logic [P.CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder) logic [P.CVTLEN-1:0] CvtLzcInE, CvtLzcInM; // input to the Leading Zero Counter (priority encoder)
logic [P.XLEN-1:0] FCvtIntResM; // fcvt integer result (for IEU) logic [P.XLEN-1:0] FCvtIntResM; // fcvt integer result (for IEU)
// divide signals // divide signals
logic [P.DIVb:0] QmM; // fdivsqrt signifcand logic [P.DIVb:0] QmM; // fdivsqrt signifcand
logic [P.NE+1:0] QeM; // fdivsqrt exponent logic [P.NE+1:0] QeM; // fdivsqrt exponent
logic DivStickyM; // fdivsqrt sticky bit logic DivStickyM; // fdivsqrt sticky bit
logic FDivDoneE, IFDivStartE; // fdivsqrt control signals logic FDivDoneE, IFDivStartE; // fdivsqrt control signals
logic [P.XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU) logic [P.XLEN-1:0] FIntDivResultM; // fdivsqrt integer division result (for IEU)
// result and flag signals // result and flag signals
logic [P.XLEN-1:0] ClassResE; // classify result logic [P.XLEN-1:0] ClassResE; // classify result
logic [P.FLEN-1:0] CmpFpResE; // compare result to FPU (min/max) logic [P.FLEN-1:0] CmpFpResE; // compare result to FPU (min/max)
logic [P.XLEN-1:0] CmpIntResE; // compare result to IEU (eq/lt/le) logic [P.XLEN-1:0] CmpIntResE; // compare result to IEU (eq/lt/le)
logic CmpNVE; // compare invalid flag (Not Valid) logic CmpNVE; // compare invalid flag (Not Valid)
logic [P.FLEN-1:0] SgnResE; // sign injection result logic [P.FLEN-1:0] SgnResE; // sign injection result
logic [P.XLEN-1:0] FIntResE; // FPU to IEU E-stage result (classify, compare, move) logic [P.XLEN-1:0] FIntResE; // FPU to IEU E-stage result (classify, compare, move)
logic [P.FLEN-1:0] PostProcResM; // Postprocessor output logic [P.FLEN-1:0] PostProcResM; // Postprocessor output
logic [4:0] PostProcFlgM; // Postprocessor flags logic [4:0] PostProcFlgM; // Postprocessor flags
logic PreNVE, PreNVM; // selected flag that is ready in the memory stage logic PreNVE, PreNVM; // selected flag that is ready in the memory stage
logic [P.FLEN-1:0] FpResM, FpResW; // FPU preliminary result logic [P.FLEN-1:0] FpResM, FpResW; // FPU preliminary result
logic [P.FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage logic [P.FLEN-1:0] PreFpResE, PreFpResM; // selected result that is ready in the memory stage
logic [P.FLEN-1:0] FResultW; // final FP result being written to the FP register logic [P.FLEN-1:0] FResultW; // final FP result being written to the FP register
@ -156,9 +156,9 @@ module fpu import cvw::*; #(parameter cvw_t P) (
logic [P.FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv logic [P.FLEN-1:0] AlignedSrcAE; // align SrcA from IEU to the floating point format for fmv
logic [P.FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed logic [P.FLEN-1:0] BoxedZeroE; // Zero value for Z for multiplication, with NaN boxing if needed
logic [P.FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed logic [P.FLEN-1:0] BoxedOneE; // One value for Z for multiplication, with NaN boxing if needed
logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt logic StallUnpackedM; // Stall unpacker outputs during multicycle fdivsqrt
logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer logic [P.FLEN-1:0] SgnExtXE; // Sign-extended X input for move to integer
logic mvsgn; // sign bit for extending move logic mvsgn; // sign bit for extending move
////////////////////////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////////////////////////
// Decode Stage: fctrl decoder, read register file // Decode Stage: fctrl decoder, read register file
@ -205,15 +205,15 @@ module fpu import cvw::*; #(parameter cvw_t P) (
mux2 #(P.FLEN) fonemux ({{P.FLEN-P.LEN1{1'b1}}, 2'b0, {P.NE1-1{1'b1}}, (P.NF1)'(0)}, {2'b0, {P.NE-1{1'b1}}, (P.NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes mux2 #(P.FLEN) fonemux ({{P.FLEN-P.LEN1{1'b1}}, 2'b0, {P.NE1-1{1'b1}}, (P.NF1)'(0)}, {2'b0, {P.NE-1{1'b1}}, (P.NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
else if(P.FPSIZES == 3 | P.FPSIZES == 4) else if(P.FPSIZES == 3 | P.FPSIZES == 4)
mux4 #(P.FLEN) fonemux ({{P.FLEN-P.S_LEN{1'b1}}, 2'b0, {P.S_NE-1{1'b1}}, (P.S_NF)'(0)}, mux4 #(P.FLEN) fonemux ({{P.FLEN-P.S_LEN{1'b1}}, 2'b0, {P.S_NE-1{1'b1}}, (P.S_NF)'(0)},
{{P.FLEN-P.D_LEN{1'b1}}, 2'b0, {P.D_NE-1{1'b1}}, (P.D_NF)'(0)}, {{P.FLEN-P.D_LEN{1'b1}}, 2'b0, {P.D_NE-1{1'b1}}, (P.D_NF)'(0)},
{{P.FLEN-P.H_LEN{1'b1}}, 2'b0, {P.H_NE-1{1'b1}}, (P.H_NF)'(0)}, {{P.FLEN-P.H_LEN{1'b1}}, 2'b0, {P.H_NE-1{1'b1}}, (P.H_NF)'(0)},
{2'b0, {P.NE-1{1'b1}}, (P.NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes {2'b0, {P.NE-1{1'b1}}, (P.NF)'(0)}, FmtE, BoxedOneE); // NaN boxing zeroes
assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10); assign FmaAddSubE = OpCtrlE[2]&OpCtrlE[1]&(FResSelE==2'b01)&(PostProcSelE==2'b10);
mux2 #(P.FLEN) fyaddmux (PreYE, BoxedOneE, FmaAddSubE, YE); // Force Y to be 1 for add/subtract mux2 #(P.FLEN) fyaddmux (PreYE, BoxedOneE, FmaAddSubE, YE); // Force Y to be 1 for add/subtract
// Select NAN-boxed value of Z = 0.0 in proper format for FMA for multiply X*Y+Z // Select NAN-boxed value of Z = 0.0 in proper format for FMA for multiply X*Y+Z
// For add and subtract, Z comes from second source operand // For add and subtract, Z comes from second source operand
if(P.FPSIZES == 1) assign BoxedZeroE = 0; if(P.FPSIZES == 1) assign BoxedZeroE = 0;
else if(P.FPSIZES == 2) else if(P.FPSIZES == 2)
mux2 #(P.FLEN) fmulzeromux ({{P.FLEN-P.LEN1{1'b1}}, {P.LEN1{1'b0}}}, (P.FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes mux2 #(P.FLEN) fmulzeromux ({{P.FLEN-P.LEN1{1'b1}}, {P.LEN1{1'b0}}}, (P.FLEN)'(0), FmtE, BoxedZeroE); // NaN boxing zeroes
else if(P.FPSIZES == 3 | P.FPSIZES == 4) else if(P.FPSIZES == 3 | P.FPSIZES == 4)
@ -262,7 +262,6 @@ module fpu import cvw::*; #(parameter cvw_t P) (
.ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE), .ToInt(FWriteIntE), .XZero(XZeroE), .Fmt(FmtE), .Ce(CeE), .ShiftAmt(CvtShiftAmtE),
.ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE)); .ResSubnormUf(CvtResSubnormUfE), .Cs(CsE), .IntZero(IntZeroE), .LzcIn(CvtLzcInE));
// NaN Box SrcA to convert integer to requested FP size // NaN Box SrcA to convert integer to requested FP size
if(P.FPSIZES == 1) assign AlignedSrcAE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE}; if(P.FPSIZES == 1) assign AlignedSrcAE = {{P.FLEN-P.XLEN{1'b1}}, ForwardedSrcAE};
else if(P.FPSIZES == 2) else if(P.FPSIZES == 2)
@ -334,7 +333,7 @@ module fpu import cvw::*; #(parameter cvw_t P) (
.PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM)); .PostProcSel(PostProcSelM), .PostProcRes(PostProcResM), .PostProcFlg(PostProcFlgM), .FCvtIntRes(FCvtIntResM));
// FPU flag selection - to privileged // FPU flag selection - to privileged
mux2 #(5) FPUFlgMux({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM); mux2 #(5) FPUFlgMux({PreNVM&~FResSelM[1], 4'b0}, PostProcFlgM, ~FResSelM[1]&FResSelM[0], SetFflagsM);
mux2 #(P.FLEN) FPUResMux(PreFpResM, PostProcResM, FResSelM[0], FpResM); mux2 #(P.FLEN) FPUResMux(PreFpResM, PostProcResM, FResSelM[0], FpResM);
// M/W pipe registers // M/W pipe registers

View File

@ -30,8 +30,8 @@ module fregfile #(parameter FLEN) (
input logic clk, reset, input logic clk, reset,
input logic we4, // write enable input logic we4, // write enable
input logic [4:0] a1, a2, a3, a4, // adresses input logic [4:0] a1, a2, a3, a4, // adresses
input logic [FLEN-1:0] wd4, // write data input logic [FLEN-1:0] wd4, // write data
output logic [FLEN-1:0] rd1, rd2, rd3 // read data output logic [FLEN-1:0] rd1, rd2, rd3 // read data
); );
logic [FLEN-1:0] rf[31:0]; logic [FLEN-1:0] rf[31:0];
@ -51,4 +51,3 @@ module fregfile #(parameter FLEN) (
assign #2 rd3 = rf[a3]; assign #2 rd3 = rf[a3];
endmodule // regfile endmodule // regfile

View File

@ -27,10 +27,10 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module fsgninj import cvw::*; #(parameter cvw_t P) ( module fsgninj import cvw::*; #(parameter cvw_t P) (
input logic Xs, Ys, // X and Y sign bits input logic Xs, Ys, // X and Y sign bits
input logic [P.FLEN-1:0] X, // X input logic [P.FLEN-1:0] X, // X
input logic [P.FMTBITS-1:0] Fmt, // format input logic [P.FMTBITS-1:0] Fmt, // format
input logic [1:0] OpCtrl, // operation control input logic [1:0] OpCtrl, // operation control
output logic [P.FLEN-1:0] SgnRes // result output logic [P.FLEN-1:0] SgnRes // result
); );
@ -73,5 +73,4 @@ module fsgninj import cvw::*; #(parameter cvw_t P) (
endcase endcase
assign SgnRes = {SgnBits[3], X[P.Q_LEN-2:P.D_LEN], SgnBits[2], X[P.D_LEN-2:P.S_LEN], SgnBits[1], X[P.S_LEN-2:P.H_LEN], SgnBits[0], X[P.H_LEN-2:0]}; assign SgnRes = {SgnBits[3], X[P.Q_LEN-2:P.D_LEN], SgnBits[2], X[P.D_LEN-2:P.S_LEN], SgnBits[1], X[P.S_LEN-2:P.H_LEN], SgnBits[0], X[P.H_LEN-2:0]};
end end
endmodule endmodule

View File

@ -82,7 +82,7 @@ module cvtshiftcalc import cvw::*; #(parameter cvw_t P) (
P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF); P.FMT: ResNegNF = -($clog2(P.NF)+1)'(P.NF);
P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1); P.FMT1: ResNegNF = -($clog2(P.NF)+1)'(P.NF1);
P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2); P.FMT2: ResNegNF = -($clog2(P.NF)+1)'(P.NF2);
default: ResNegNF = 1'bx; default: ResNegNF = 'x;
endcase endcase
end else if (P.FPSIZES == 4) begin end else if (P.FPSIZES == 4) begin

View File

@ -28,24 +28,24 @@
module unpackinput import cvw::*; #(parameter cvw_t P) ( module unpackinput import cvw::*; #(parameter cvw_t P) (
input logic [P.FLEN-1:0] In, // inputs from register file input logic [P.FLEN-1:0] In, // inputs from register file
input logic En, // enable the input input logic En, // enable the input
input logic [P.FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half input logic [P.FMTBITS-1:0] Fmt, // format signal 00 - single 01 - double 11 - quad 10 - half
output logic Sgn, // sign bits of the number output logic Sgn, // sign bits of the number
output logic [P.NE-1:0] Exp, // exponent of the number (converted to largest supported precision) output logic [P.NE-1:0] Exp, // exponent of the number (converted to largest supported precision)
output logic [P.NF:0] Man, // mantissa of the number (converted to largest supported precision) output logic [P.NF:0] Man, // mantissa of the number (converted to largest supported precision)
output logic NaN, // is the number a NaN output logic NaN, // is the number a NaN
output logic SNaN, // is the number a signaling NaN output logic SNaN, // is the number a signaling NaN
output logic Zero, // is the number zero output logic Zero, // is the number zero
output logic Inf, // is the number infinity output logic Inf, // is the number infinity
output logic ExpNonZero, // is the exponent not zero output logic ExpNonZero, // is the exponent not zero
output logic FracZero, // is the fraction zero output logic FracZero, // is the fraction zero
output logic ExpMax, // does In have the maximum exponent (NaN or Inf) output logic ExpMax, // does In have the maximum exponent (NaN or Inf)
output logic Subnorm, // is the number subnormal output logic Subnorm, // is the number subnormal
output logic [P.FLEN-1:0] PostBox // Number reboxed correctly as a NaN output logic [P.FLEN-1:0] PostBox // Number reboxed correctly as a NaN
); );
logic [P.NF-1:0] Frac; // Fraction of XYZ logic [P.NF-1:0] Frac; // Fraction of XYZ
logic BadNaNBox; // incorrectly NaN Boxed logic BadNaNBox; // incorrectly NaN Boxed
if (P.FPSIZES == 1) begin // if there is only one floating point format supported if (P.FPSIZES == 1) begin // if there is only one floating point format supported
assign BadNaNBox = 0; assign BadNaNBox = 0;
@ -107,7 +107,6 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
// is the exponent all 1's // is the exponent all 1's
assign ExpMax = Fmt ? &In[P.FLEN-2:P.NF] : &In[P.LEN1-2:P.NF1]; assign ExpMax = Fmt ? &In[P.FLEN-2:P.NF] : &In[P.LEN1-2:P.NF1];
end else if (P.FPSIZES == 3) begin // three floating point precsions supported end else if (P.FPSIZES == 3) begin // three floating point precsions supported
// largest format | larger format | smallest format // largest format | larger format | smallest format
@ -246,7 +245,6 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
2'b00: Sgn = In[P.S_LEN-1]; 2'b00: Sgn = In[P.S_LEN-1];
2'b10: Sgn = In[P.H_LEN-1]; 2'b10: Sgn = In[P.H_LEN-1];
endcase endcase
// extract the fraction // extract the fraction
always_comb always_comb
@ -266,7 +264,6 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
2'b10: ExpNonZero = |In[P.H_LEN-2:P.H_NF]; 2'b10: ExpNonZero = |In[P.H_LEN-2:P.H_NF];
endcase endcase
// example double to single conversion: // example double to single conversion:
// 1023 = 0011 1111 1111 // 1023 = 0011 1111 1111
// 127 = 0000 0111 1111 (subtract this) // 127 = 0000 0111 1111 (subtract this)
@ -284,8 +281,7 @@ module unpackinput import cvw::*; #(parameter cvw_t P) (
2'b00: Exp = {In[P.S_LEN-2], {P.Q_NE-P.S_NE{~In[P.S_LEN-2]}}, In[P.S_LEN-3:P.S_NF+1], In[P.S_NF]|~ExpNonZero}; 2'b00: Exp = {In[P.S_LEN-2], {P.Q_NE-P.S_NE{~In[P.S_LEN-2]}}, In[P.S_LEN-3:P.S_NF+1], In[P.S_NF]|~ExpNonZero};
2'b10: Exp = {In[P.H_LEN-2], {P.Q_NE-P.H_NE{~In[P.H_LEN-2]}}, In[P.H_LEN-3:P.H_NF+1], In[P.H_NF]|~ExpNonZero}; 2'b10: Exp = {In[P.H_LEN-2], {P.Q_NE-P.H_NE{~In[P.H_LEN-2]}}, In[P.H_LEN-3:P.H_NF+1], In[P.H_NF]|~ExpNonZero};
endcase endcase
// is the exponent all 1's // is the exponent all 1's
always_comb always_comb
case (Fmt) case (Fmt)

View File

@ -33,5 +33,3 @@ module adder #(parameter WIDTH=8) (
assign y = a + b; assign y = a + b;
endmodule endmodule

View File

@ -36,5 +36,3 @@ module counter #(parameter WIDTH=8) (
assign qnext = q + 1; assign qnext = q + 1;
flopenr #(WIDTH) cntrflop(clk, reset, en, qnext, q); flopenr #(WIDTH) cntrflop(clk, reset, en, qnext, q);
endmodule endmodule

View File

@ -32,4 +32,3 @@ module neg #(parameter WIDTH = 8) (
assign y = ~a + 1; assign y = ~a + 1;
endmodule endmodule

View File

@ -48,5 +48,3 @@ module or_rows #(parameter ROWS = 8, COLS=2) (
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
end end
endmodule endmodule

View File

@ -48,6 +48,3 @@ module prioritythermometer #(parameter N = 8) (
end end
/* verilator lint_on UNOPTFLAT */ /* verilator lint_on UNOPTFLAT */
endmodule endmodule

View File

@ -28,55 +28,55 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module datapath import cvw::*; #(parameter cvw_t P) ( module datapath import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
// 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
// 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)
input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage input logic [2:0] Funct3E, // Funct3 field of instruction in Execute stage
input logic StallE, FlushE, // Stall, flush Execute stage input logic StallE, FlushE, // Stall, flush Execute stage
input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages input logic [1:0] ForwardAE, ForwardBE, // Forward ALU operands from later stages
input logic W64E, // W64-type instruction input logic W64E, // W64-type instruction
input logic SubArithE, // Subtraction or arithmetic shift input logic SubArithE, // Subtraction or arithmetic shift
input logic ALUSrcAE, ALUSrcBE, // ALU operands input logic ALUSrcAE, ALUSrcBE, // ALU operands
input logic ALUResultSrcE, // Selects result to pass on to Memory stage input logic ALUResultSrcE, // Selects result to pass on to Memory stage
input logic [2:0] ALUSelectE, // ALU mux select signal input logic [2:0] ALUSelectE, // ALU mux select signal
input logic JumpE, // Is a jump (j) instruction input logic JumpE, // Is a jump (j) instruction
input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch) input logic BranchSignedE, // Branch comparison operands are signed (if it's a branch)
input logic [1:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction input logic [1:0] BSelectE, // One hot encoding of ZBA_ZBB_ZBC_ZBS instruction
input logic [2:0] ZBBSelectE, // ZBB mux select signal input logic [2:0] ZBBSelectE, // ZBB mux select signal
input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage input logic [2:0] BALUControlE, // ALU Control signals for B instructions in Execute Stage
output logic [1:0] FlagsE, // Comparison flags ({eq, lt}) output logic [1:0] FlagsE, // Comparison flags ({eq, lt})
output logic [P.XLEN-1:0] IEUAdrE, // Address computed by ALU output logic [P.XLEN-1:0] IEUAdrE, // Address computed by ALU
output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B
// Memory stage signals // Memory stage signals
input logic StallM, FlushM, // Stall, flush Memory stage input logic StallM, FlushM, // Stall, flush Memory stage
input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int
input logic [P.XLEN-1:0] FIntResM, // FPU integer result input logic [P.XLEN-1:0] FIntResM, // FPU integer result
output logic [P.XLEN-1:0] SrcAM, // ALU's Source A in Memory stage to privilege unit for CSR writes output logic [P.XLEN-1:0] SrcAM, // ALU's Source A in Memory stage to privilege unit for CSR writes
output logic [P.XLEN-1:0] WriteDataM, // Write data in Memory stage output logic [P.XLEN-1:0] WriteDataM, // Write data in Memory stage
// Writeback stage signals // Writeback stage signals
input logic StallW, FlushW, // Stall, flush Writeback stage input logic StallW, FlushW, // Stall, flush Writeback stage
input logic RegWriteW, IntDivW, // Write register file, integer divide instruction input logic RegWriteW, IntDivW, // Write register file, integer divide instruction
input logic SquashSCW, // Squash a store conditional when a conflict arose input logic SquashSCW, // Squash a store conditional when a conflict arose
input logic [2:0] ResultSrcW, // Select source of result to write back to register file input logic [2:0] ResultSrcW, // Select source of result to write back to register file
input logic [P.XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result input logic [P.XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result
input logic [P.XLEN-1:0] ReadDataW, // Read data from LSU input logic [P.XLEN-1:0] ReadDataW, // Read data from LSU
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
// 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] 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 output logic [4:0] RdE, RdM, RdW // Register destinations in Execute, Memory, or Writeback stage
); );
// Fetch stage signals // Fetch stage signals
// Decode stage signals // Decode stage signals
logic [P.XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2) logic [P.XLEN-1:0] R1D, R2D; // Read data from Rs1 (RD1), Rs2 (RD2)
logic [P.XLEN-1:0] ImmExtD; // Extended immediate in Decode stage logic [P.XLEN-1:0] ImmExtD; // Extended immediate in Decode stage
logic [4:0] RdD; // Destination register in Decode stage logic [4:0] RdD; // Destination register in Decode stage
// Execute stage signals // Execute stage signals
logic [P.XLEN-1:0] R1E, R2E; // Source operands read from register file logic [P.XLEN-1:0] R1E, R2E; // Source operands read from register file
logic [P.XLEN-1:0] ImmExtE; // Extended immediate in Execute stage logic [P.XLEN-1:0] ImmExtE; // Extended immediate in Execute stage
@ -103,9 +103,9 @@ 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) Rs1EReg(clk, reset, FlushE, ~StallE, Rs1D, Rs1E);
flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E); flopenrc #(5) Rs2EReg(clk, reset, FlushE, ~StallE, Rs2D, Rs2E);
flopenrc #(5) RdEReg(clk, reset, FlushE, ~StallE, RdD, RdE); 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);
@ -144,5 +144,5 @@ module datapath import cvw::*; #(parameter cvw_t P) (
// handle Store Conditional result if atomic extension supported // handle Store Conditional result if atomic extension supported
if (P.A_SUPPORTED) assign SCResultW = {{(P.XLEN-1){1'b0}}, SquashSCW}; if (P.A_SUPPORTED) assign SCResultW = {{(P.XLEN-1){1'b0}}, SquashSCW};
else assign SCResultW = 0; else assign SCResultW = 0;
endmodule endmodule

View File

@ -30,7 +30,7 @@
module extend #(parameter XLEN, A_SUPPORTED) ( module extend #(parameter XLEN, A_SUPPORTED) (
input logic [31:7] InstrD, // All instruction bits except opcode (lower 7 bits) input logic [31:7] InstrD, // All instruction bits except opcode (lower 7 bits)
input logic [2:0] ImmSrcD, // Select what kind of extension to perform input logic [2:0] ImmSrcD, // Select what kind of extension to perform
output logic [XLEN-1:0 ] ImmExtD); // Extended immediate output logic [XLEN-1:0] ImmExtD); // Extended immediate
localparam [XLEN-1:0] undefined = {(XLEN){1'bx}}; // could change to 0 after debug localparam [XLEN-1:0] undefined = {(XLEN){1'bx}}; // could change to 0 after debug
@ -45,10 +45,10 @@ module extend #(parameter XLEN, A_SUPPORTED) (
// J-type (jal) // J-type (jal)
3'b011: ImmExtD = {{(XLEN-20){InstrD[31]}}, InstrD[19:12], InstrD[20], InstrD[30:21], 1'b0}; 3'b011: ImmExtD = {{(XLEN-20){InstrD[31]}}, InstrD[19:12], InstrD[20], InstrD[30:21], 1'b0};
// U-type (lui, auipc) // U-type (lui, auipc)
3'b100: ImmExtD = {{(XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0}; 3'b100: ImmExtD = {{(XLEN-31){InstrD[31]}}, InstrD[30:12], 12'b0};
// Store Conditional: zero offset // Store Conditional: zero offset
3'b101: if (A_SUPPORTED) ImmExtD = 0; 3'b101: if (A_SUPPORTED) ImmExtD = 0;
else ImmExtD = undefined; else ImmExtD = undefined;
default: ImmExtD = undefined; // undefined default: ImmExtD = undefined; // undefined
endcase endcase
endmodule endmodule

View File

@ -26,7 +26,6 @@
// and limitations under the License. // and limitations under the License.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module ieu import cvw::*; #(parameter cvw_t P) ( module ieu import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
// Decode stage signals // Decode stage signals
@ -34,36 +33,36 @@ module ieu import cvw::*; #(parameter cvw_t P) (
input logic IllegalIEUFPUInstrD, // Illegal instruction input logic IllegalIEUFPUInstrD, // Illegal instruction
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
// Execute stage signals // Execute stage signals
input logic [P.XLEN-1:0] PCE, // PC input logic [P.XLEN-1:0] PCE, // PC
input logic [P.XLEN-1:0] PCLinkE, // PC + 4 input logic [P.XLEN-1:0] PCLinkE, // PC + 4
output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE) output logic PCSrcE, // Select next PC (between PC+4 and IEUAdrE)
input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int input logic FWriteIntE, FCvtIntE, // FPU writes to integer register file, FPU converts float to int
output logic [P.XLEN-1:0] IEUAdrE, // Memory address output logic [P.XLEN-1:0] IEUAdrE, // Memory address
output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
output logic [2:0] Funct3E, // Funct3 instruction field output logic [2:0] Funct3E, // Funct3 instruction field
output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B output logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B
output logic [4:0] RdE, // Destination register output logic [4:0] RdE, // Destination register
// Memory stage signals // Memory stage signals
input logic SquashSCW, // Squash store conditional, from LSU input logic SquashSCW, // Squash store conditional, from LSU
output logic [1:0] MemRWM, // Read/write control goes to LSU output logic [1:0] MemRWM, // Read/write control goes to LSU
output logic [1:0] AtomicM, // Atomic control goes to LSU output logic [1:0] AtomicM, // Atomic control goes to LSU
output logic [P.XLEN-1:0] WriteDataM, // Write data to LSU output logic [P.XLEN-1:0] WriteDataM, // Write data to LSU
output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU output logic [2:0] Funct3M, // Funct3 (size and signedness) to LSU
output logic [P.XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU output logic [P.XLEN-1:0] SrcAM, // ALU SrcA to Privileged unit and FPU
output logic [4:0] RdM, // Destination register output logic [4:0] RdM, // Destination register
input logic [P.XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp) input logic [P.XLEN-1:0] FIntResM, // Integer result from FPU (fmv, fclass, fcmp)
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$ output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidD, InstrValidE, InstrValidM,// Instruction is valid output logic InstrValidD, InstrValidE, InstrValidM, // Instruction is valid
output logic BranchD, BranchE, output logic BranchD, BranchE,
output logic JumpD, JumpE, output logic JumpD, JumpE,
// Writeback stage signals // Writeback stage signals
input logic [P.XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt) input logic [P.XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt)
input logic [P.XLEN-1:0] CSRReadValW, // CSR read value, input logic [P.XLEN-1:0] CSRReadValW, // CSR read value,
input logic [P.XLEN-1:0] MDUResultW, // multiply/divide unit result input logic [P.XLEN-1:0] MDUResultW, // multiply/divide unit result
input logic [P.XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result input logic [P.XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result
input logic FCvtIntW, // FPU converts float to int input logic FCvtIntW, // FPU converts float to int
output logic [4:0] RdW, // Destination register output logic [4:0] RdW, // Destination register
input logic [P.XLEN-1:0] ReadDataW, // LSU's read data input logic [P.XLEN-1:0] ReadDataW, // LSU's read data
// 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
@ -118,4 +117,3 @@ module ieu import cvw::*; #(parameter cvw_t P) (
.FCvtIntE, .SCE, .ForwardAE, .ForwardBE, .FCvtIntE, .SCE, .ForwardAE, .ForwardBE,
.FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD); .FCvtIntStallD, .LoadStallD, .MDUStallD, .CSRRdStallD);
endmodule endmodule

View File

@ -31,10 +31,10 @@ module regfile #(parameter XLEN, E_SUPPORTED) (
input logic clk, reset, input logic clk, reset,
input logic we3, // Write enable input logic we3, // Write enable
input logic [4:0] a1, a2, a3, // Source registers to read (a1, a2), destination register to write (a3) input logic [4:0] a1, a2, a3, // Source registers to read (a1, a2), destination register to write (a3)
input logic [XLEN-1:0] wd3, // Write data for port 3 input logic [XLEN-1:0] wd3, // Write data for port 3
output logic [XLEN-1:0] rd1, rd2); // Read data for ports 1, 2 output logic [XLEN-1:0] rd1, rd2); // Read data for ports 1, 2
localparam NUMREGS = E_SUPPORTED ? 16 : 32; // only 16 registers in E mode localparam NUMREGS = E_SUPPORTED ? 16 : 32; // only 16 registers in E mode
logic [XLEN-1:0] rf[NUMREGS-1:1]; logic [XLEN-1:0] rf[NUMREGS-1:1];
integer i; integer i;
@ -50,7 +50,7 @@ module regfile #(parameter XLEN, E_SUPPORTED) (
always_ff @(negedge clk) always_ff @(negedge clk)
if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0; if (reset) for(i=1; i<NUMREGS; i++) rf[i] <= 0;
else if (we3) rf[a3] <= wd3; else if (we3) rf[a3] <= wd3;
assign #2 rd1 = (a1 != 0) ? rf[a1] : 0; assign #2 rd1 = (a1 != 0) ? rf[a1] : 0;
assign #2 rd2 = (a2 != 0) ? rf[a2] : 0; assign #2 rd2 = (a2 != 0) ? rf[a2] : 0;

View File

@ -41,7 +41,7 @@ module shifter (
assign Sign = A[`XLEN-1] & SubArith; // sign bit for sign extension assign Sign = A[`XLEN-1] & SubArith; // sign bit for sign extension
if (`XLEN==32) begin // rv32 if (`XLEN==32) begin // rv32
if (`ZBB_SUPPORTED) begin: rotfunnel32 //rv32 shifter with rotates if (`ZBB_SUPPORTED) begin: rotfunnel32 // rv32 shifter with rotates
always_comb // funnel mux always_comb // funnel mux
case({Right, Rotate}) case({Right, Rotate})
2'b00: Z = {A[31:0], 31'b0}; 2'b00: Z = {A[31:0], 31'b0};
@ -84,5 +84,3 @@ module shifter (
assign ZShift = Z >> Offset; assign ZShift = Z >> Offset;
assign Y = ZShift[`XLEN-1:0]; assign Y = ZShift[`XLEN-1:0];
endmodule endmodule

View File

@ -1,112 +0,0 @@
import os
# Kevin Wan kewan@hmc.edu 10/27/2021
def read_input(filename): #1
"""Takes in a string filename and outputs the parsed verilog code by line into a list
such that each element of the list is one line of verilog code as a string."""
lineOfCode = []
input_file = open(filename, 'r')
for line in input_file:
lineOfCode.append(line)
return lineOfCode
###################################################################################
def ID_start(GiantString):#2
"""takes in the list of sv file lines, outputs the location that variable names should start"""
VarLoc = 0
VarLineNum = None
for lines in GiantString:
if ' logic ' in lines and (lines.find("//") == -1 or lines.find("//") > lines.find(' logic ')): # // logic does not proceed. logic proceeds. logic // proceeds.
if "[" in lines and "]" in lines:# need to account for these space
NowLoc = lines.find(']') + 3# column number in sv code when 1st char of the var name should appear.
if NowLoc>VarLoc:
VarLoc = NowLoc
VarLineNum = GiantString.index(lines) # Update this number if new record is made.
else:
NowLoc = lines.find('logic') + 7 # same as before.
if NowLoc>VarLoc:
VarLoc = NowLoc
VarLineNum = GiantString.index(lines)
#print("Furthest variable appears on line", VarLineNum + 1,VarLoc) # Disable this line after debugging.
return VarLoc
##################################################################################
def modified_logNew(GS,SOV): #3
Ind = SOV - 1 # SOV is for human readability, Ind is the character's index in computer, since computers count from 0's we need to correct it.
Out = []
for l in GS:
lines = l.replace('\t',' ')
if ' logic ' in lines and (lines.find("//") == -1 or lines.find("//") > lines.find(' logic ')): # // logic does not proceed. logic proceeds. logic // proceeds.
if "[" in lines and "]" in lines: # the line is an extended declaration.
EditLoc = lines.find("]") # Re-finds the string index number of ].
VarLoc = FindCharRel(lines[EditLoc+1::]) + EditLoc + 1 # Checks where variable declaration currently is at.
#print(VarLoc,lines[VarLoc])# VERIFIED
NewLine = Mod_Space_at(lines,VarLoc,VarLoc-Ind)
Out.append(NewLine)# Verified0957 10272021
else:
EditLoc1 = lines.find('c') # Hopefully sees the c in 'logic'
VarLoc1 = FindCharRel(lines[EditLoc1+1::]) + EditLoc1 + 1
NewLine1 = Mod_Space_at(lines,VarLoc1,VarLoc1-Ind)
Out.append(NewLine1)# Verified 1005 10272021
else:
Out.append(lines)
return Out
################################################################################
def write_to_output(filename,GiantString,OW=True,Lines_editted=None): #4
"""Filename is preferrably passed from the early function calls"""
"""GiantString has all the corrected features in the code, each line is a good verilog code line"""
newname = filename
if not OW or OW =='f': #which means no overwrite (create a new file)
Decomposed=filename.split('.')
newname = Decomposed[0] + "_AL." + Decomposed[1] # AL for aligned.
OutFile = open(newname,'w') # This step should create a new file.
OutFile.writelines(GiantString)
OutFile.close()
print("Success! " + newname + " Now contains an aligned file!")
return newname
#################################################################################
def FindCharRel(Ln):
#returns the computer location of a character's first occurence
for num in range(len(Ln)):
if Ln[num] != " ":
return num
def Mod_Space_at(Ln,loc,diff):
#loc is the varLoc from mln, diff is varLoc - Ind
if diff > 0: # to delete
NewString = Ln[:(loc-diff)] + Ln[loc:]
if diff < 0: # to add
NewString = Ln[:loc] + (-diff)*" " + Ln[loc:]
if diff == 0:
NewString = Ln
return NewString
'''def main_filehandler(overwrite=False):
for filename in os.listdir():
if ".sv" in filename:
GiantString = read_input(filename)
SOV = ID_start(GiantString)
ModifiedGS = modified_logNew(GiantString,SOV)
Newname = write_to_output(filename,ModifiedGS,overwrite)'''
def root_filehandler(path,overwrite=False):
for f in os.listdir(path):
if os.path.isdir(f):
root_filehandler(path+"/"+f)
else:
if ".sv" in f:
GiantString = read_input(f)
SOV = ID_start(GiantString)
ModifiedGS = modified_logNew(GiantString,SOV)
Newname = write_to_output(f,ModifiedGS,overwrite)
def driver(overwrite=False):
root_filehandler(os.getcwd())
driver(True)

View File

@ -191,7 +191,7 @@ module bpred import cvw::*; #(parameter cvw_t P) (
if(`INSTR_CLASS_PRED) mux2 #(P.XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE); if(`INSTR_CLASS_PRED) mux2 #(P.XLEN) pcmuxBPWrongInvalidateFlush(PCE, PCF, BPWrongM, NextValidPCE);
else assign NextValidPCE = PCE; else assign NextValidPCE = PCE;
if(P.ZICOUNTERS_SUPPORTED) begin if(P.ZIHPM_SUPPORTED) begin
logic [P.XLEN-1:0] RASPCD, RASPCE; logic [P.XLEN-1:0] RASPCD, RASPCE;
logic BTAWrongE, RASPredPCWrongE; logic BTAWrongE, RASPredPCWrongE;
// performance counters // performance counters

View File

@ -181,4 +181,3 @@ module decompress #(parameter XLEN)(
endcase endcase
end end
endmodule endmodule

View File

@ -26,116 +26,115 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module ifu import cvw::*; #(parameter cvw_t P) ( module ifu import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW, input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation
// Command from CPU // Command from CPU
input logic InvalidateICacheM, // Clears all instruction cache valid bits input logic InvalidateICacheM, // Clears all instruction cache valid bits
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE) input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
input logic InstrValidD, InstrValidE, InstrValidM, input logic InstrValidD, InstrValidE, InstrValidM,
input logic BranchD, BranchE, input logic BranchD, BranchE,
input logic JumpD, JumpE, input logic JumpD, JumpE,
// Bus interface // Bus interface
output logic [P.PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU output logic [P.PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
input logic [P.XLEN-1:0] HRDATA, // Bus read data from IFU to EBU input logic [P.XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
input logic IFUHREADY, // Bus ready from IFU to EBU input logic IFUHREADY, // Bus ready from IFU to EBU
output logic IFUHWRITE, // Bus write operation from IFU to EBU output logic IFUHWRITE, // Bus write operation from IFU to EBU
output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
output logic [P.XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW output logic [P.XLEN-1:0] PCSpillF, // PCF with possible + 2 to handle spill to HPTW
// Execute // Execute
output logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address) output logic [P.XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
input logic PCSrcE, // Executation stage branch is taken input logic PCSrcE, // Executation stage branch is taken
input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address input logic [P.XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address input logic [P.XLEN-1:0] IEUAdrM, // The branch/jump target address
output logic [P.XLEN-1:0] PCE, // Execution stage instruction address output logic [P.XLEN-1:0] PCE, // Execution stage instruction address
output logic BPWrongE, // Prediction is wrong output logic BPWrongE, // Prediction is wrong
output logic BPWrongM, // Prediction is wrong output logic BPWrongM, // Prediction is wrong
// Mem // Mem
output logic CommittedF, // I$ or bus memory operation started, delay interrupts output logic CommittedF, // I$ or bus memory operation started, delay interrupts
input logic [P.XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes. input logic [P.XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
output logic [P.XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence output logic [P.XLEN-1:0] PC2NextF, // Selected PC between branch prediction and next valid PC if CSRWriteFence
output logic [31:0] InstrD, // The decoded instruction in Decode stage output logic [31:0] InstrD, // The decoded instruction in Decode stage
output logic [31:0] InstrM, // The decoded instruction in Memory stage output logic [31:0] InstrM, // The decoded instruction in Memory stage
output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL output logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
output logic [P.XLEN-1:0] PCM, // Memory stage instruction address output logic [P.XLEN-1:0] PCM, // Memory stage instruction address
// branch predictor // branch predictor
output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br output logic [3:0] InstrClassM, // The valid instruction class. 1-hot encoded as jalr, ret, jr (not ret), j, br
output logic BPDirPredWrongM, // Prediction direction is wrong output logic BPDirPredWrongM, // Prediction direction is wrong
output logic BTAWrongM, // Prediction target wrong output logic BTAWrongM, // Prediction target wrong
output logic RASPredPCWrongM, // RAS prediction is wrong output logic RASPredPCWrongM, // RAS prediction is wrong
output logic IClassWrongM, // Class prediction is wrong output logic IClassWrongM, // Class prediction is wrong
output logic ICacheStallF, // I$ busy with multicycle operation output logic ICacheStallF, // I$ busy with multicycle operation
// Faults // Faults
input logic IllegalBaseInstrD, // Illegal non-compressed instruction input logic IllegalBaseInstrD, // Illegal non-compressed instruction
input logic IllegalFPUInstrD, // Illegal FP instruction input logic IllegalFPUInstrD, // Illegal FP instruction
output logic InstrPageFaultF, // Instruction page fault output logic InstrPageFaultF, // Instruction page fault
output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP output logic IllegalIEUFPUInstrD, // Illegal instruction including compressed & FP
output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) output logic InstrMisalignedFaultM, // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
// mmu management // mmu management
input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage input logic [1:0] PrivilegeModeW, // Priviledge mode in Writeback stage
input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB input logic [P.XLEN-1:0] PTE, // Hardware page table walker (HPTW) writes Page table entry (PTE) to ITLB
input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB input logic [1:0] PageType, // Hardware page table walker (HPTW) writes PageType to ITLB
input logic ITLBWriteF, // Writes PTE and PageType to ITLB input logic ITLBWriteF, // Writes PTE and PageType to ITLB
input logic [P.XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration input logic [P.XLEN-1:0] SATP_REGW, // Location of the root page table and page table configuration
input logic STATUS_MXR, // Status CSR: make executable page readable input logic STATUS_MXR, // Status CSR: make executable page readable
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
input logic STATUS_MPRV, // Status CSR: modify machine privilege input logic STATUS_MPRV, // Status CSR: modify machine privilege
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk output logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits output logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP address from privileged unit input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],// PMP address from privileged unit
output logic InstrAccessFaultF, // Instruction access fault output logic InstrAccessFaultF, // Instruction access fault
output logic ICacheAccess, // Report I$ read to performance counters output logic ICacheAccess, // Report I$ read to performance counters
output logic ICacheMiss // Report I$ miss to performance counters output logic ICacheMiss // Report I$ miss to performance counters
); );
localparam [31:0] nop = 32'h00000013; // instruction for NOP localparam [31:0] nop = 32'h00000013; // instruction for NOP
logic [P.XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4 logic [P.XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed) logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
logic [P.XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed) logic [P.XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed)
logic [P.XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill logic [P.XLEN-1:0] PCSpillNextF; // Next PCF after possible + 2 to handle spill
logic [P.XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j) logic [P.XLEN-1:0] PCLinkD; // PCF2or4F delayed 1 cycle. This is next PC after a control flow instruction (br or j)
logic [P.XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F logic [P.XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F
logic [P.XLEN-1:0] PCD; // Decode stage instruction address logic [P.XLEN-1:0] PCD; // Decode stage instruction address
logic [P.XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence logic [P.XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence
logic [P.XLEN-1:0] PCF; // Fetch stage instruction address logic [P.XLEN-1:0] PCF; // Fetch stage instruction address
logic [P.PA_BITS-1:0] PCPF; // Physical address after address translation logic [P.PA_BITS-1:0] PCPF; // Physical address after address translation
logic [P.XLEN+1:0] PCFExt; // logic [P.XLEN+1:0] PCFExt;
logic [31:0] IROMInstrF; // Instruction from the IROM logic [31:0] IROMInstrF; // Instruction from the IROM
logic [31:0] ICacheInstrF; // Instruction from the I$ logic [31:0] ICacheInstrF; // Instruction from the I$
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
logic CompressedF; // The fetched instruction is compressed logic CompressedF; // The fetched instruction is compressed
logic CompressedD; // The decoded instruction is compressed logic CompressedD; // The decoded instruction is compressed
logic CompressedE; // The execution instruction is compressed logic CompressedE; // The execution instruction is compressed
logic CompressedM; // The execution instruction is compressed logic CompressedM; // The execution instruction is compressed
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good logic IllegalIEUInstrD; // IEU Instruction (regular or compressed) is not good
logic [1:0] IFURWF; // IFU alreays read IFURWF = 10 logic [1:0] IFURWF; // IFU alreays read IFURWF = 10
logic [31:0] InstrE; // Instruction in the Execution stage logic [31:0] InstrE; // Instruction in the Execution stage
logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush logic [31:0] NextInstrD, NextInstrE; // Instruction into the next stage after possible stage flush
logic CacheableF; // PMA indicates instruction address is cacheable
logic CacheableF; // PMA indicates instruction address is cacheable logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF
logic SelSpillNextF; // In a spill, stall pipeline and gate local stallF logic BusStall; // Bus interface busy with multicycle operation
logic BusStall; // Bus interface busy with multicycle operation logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation
logic IFUCacheBusStallF; // EIther I$ or bus busy with multicycle operation logic GatedStallD; // StallD gated by selected next spill
logic GatedStallD; // StallD gated by selected next spill
// branch predictor signal // branch predictor signal
logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF logic [P.XLEN-1:0] PC1NextF; // Branch predictor next PCF
logic BusCommittedF; // Bus memory operation in flight, delay interrupts logic BusCommittedF; // Bus memory operation in flight, delay interrupts
logic CacheCommittedF; // I$ memory operation started, delay interrupts logic CacheCommittedF; // I$ memory operation started, delay interrupts
logic SelIROM; // PMA indicates instruction address is in the IROM logic SelIROM; // PMA indicates instruction address is in the IROM
logic [15:0] InstrRawE, InstrRawM; logic [15:0] InstrRawE, InstrRawM;
assign PCFExt = {2'b00, PCSpillF}; assign PCFExt = {2'b00, PCSpillF};
@ -199,6 +198,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// Memory // Memory
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// CommittedM tells the CPU's privileged unit the current instruction // CommittedM tells the CPU's privileged unit the current instruction
// in the memory stage is a memory operaton and that memory operation is either completed // in the memory stage is a memory operaton and that memory operation is either completed
// or is partially executed. Partially completed memory operations need to prevent an interrupts. // or is partially executed. Partially completed memory operations need to prevent an interrupts.
@ -206,7 +206,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
// delay the interrupt until the LSU is in a clean state. // delay the interrupt until the LSU is in a clean state.
assign CommittedF = CacheCommittedF | BusCommittedF; assign CommittedF = CacheCommittedF | BusCommittedF;
logic IgnoreRequest; logic IgnoreRequest;
assign IgnoreRequest = ITLBMissF | FlushD; assign IgnoreRequest = ITLBMissF | FlushD;
// The IROM uses untranslated addresses, so it is not compatible with virtual memory. // The IROM uses untranslated addresses, so it is not compatible with virtual memory.
@ -223,12 +223,12 @@ module ifu import cvw::*; #(parameter cvw_t P) (
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)
logic [LINELEN-1:0] FetchBuffer; logic [LINELEN-1:0] FetchBuffer;
logic [P.PA_BITS-1:0] ICacheBusAdr; logic [P.PA_BITS-1:0] ICacheBusAdr;
logic ICacheBusAck; logic ICacheBusAck;
logic [1:0] CacheBusRW, BusRW, CacheRWF; logic [1:0] CacheBusRW, BusRW, CacheRWF;
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;
@ -255,7 +255,7 @@ module ifu import cvw::*; #(parameter cvw_t P) (
.Flush(FlushD), .CacheBusRW, .HSIZE(IFUHSIZE), .HBURST(IFUHBURST), .HTRANS(IFUHTRANS), .HWSTRB(), .Flush(FlushD), .CacheBusRW, .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),
.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));
@ -321,7 +321,6 @@ module ifu import cvw::*; #(parameter cvw_t P) (
else PCPlus2or4F = {PCF[P.XLEN-1:2], 2'b10}; else PCPlus2or4F = {PCF[P.XLEN-1:2], 2'b10};
else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4 else PCPlus2or4F = {PCPlus4F, PCF[1:0]}; // add 4
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// Branch and Jump Predictor // Branch and Jump Predictor
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
@ -341,10 +340,10 @@ module ifu import cvw::*; #(parameter cvw_t P) (
assign NextValidPCE = PCE; assign NextValidPCE = PCE;
end end
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// Decode stage pipeline register and compressed instruction decoding. // Decode stage pipeline register and compressed instruction decoding.
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
// Decode stage pipeline register and logic // Decode stage pipeline register and logic
flopenrc #(P.XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD); flopenrc #(P.XLEN) PCDReg(clk, reset, FlushD, ~StallD, PCF, PCD);
@ -374,10 +373,10 @@ module ifu import cvw::*; #(parameter cvw_t P) (
// Instruction and PC/PCLink pipeline registers // Instruction and PC/PCLink pipeline registers
// Cannot use flopenrc for Instr(E/M) as it resets to NOP not 0. // Cannot use flopenrc for Instr(E/M) as it resets to NOP not 0.
mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD); mux2 #(32) FlushInstrEMux(InstrD, nop, FlushE, NextInstrD);
mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE); mux2 #(32) FlushInstrMMux(InstrE, nop, FlushM, NextInstrE);
flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE); flopenr #(32) InstrEReg(clk, reset, ~StallE, NextInstrD, InstrE);
flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM); flopenr #(32) InstrMReg(clk, reset, ~StallM, NextInstrE, InstrM);
flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE); flopenr #(P.XLEN) PCEReg(clk, reset, ~StallE, PCD, PCE);
flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM); flopenr #(P.XLEN) PCMReg(clk, reset, ~StallM, PCE, PCM);
//flopenr #(P.XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD); //flopenr #(P.XLEN) PCPDReg(clk, reset, ~StallD, PCPlus2or4F, PCLinkD);

View File

@ -25,10 +25,10 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module irom import cvw::*; #(parameter cvw_t P) ( module irom import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic ce, // Chip Enable. 0: Holds IROMInstrF constant input logic ce, // Chip Enable. 0: Holds IROMInstrF constant
input logic [P.XLEN-1:0] Adr, // PCNextFSpill input logic [P.XLEN-1:0] Adr, // PCNextFSpill
output logic [31:0] IROMInstrF // Instruction read data output logic [31:0] IROMInstrF // Instruction read data
); );
localparam XLENBYTES = {{P.PA_BITS-32{1'b0}}, P.XLEN/8}; // XLEN/8, adjusted for width localparam XLENBYTES = {{P.PA_BITS-32{1'b0}}, P.XLEN/8}; // XLEN/8, adjusted for width
@ -36,14 +36,13 @@ module irom import cvw::*; #(parameter cvw_t P) (
localparam OFFSET = $clog2(XLENBYTES); localparam OFFSET = $clog2(XLENBYTES);
logic [P.XLEN-1:0] IROMInstrFFull; logic [P.XLEN-1:0] IROMInstrFFull;
logic [31:0] RawIROMInstrF; logic [31:0] RawIROMInstrF;
logic [1:0] AdrD;
logic [1:0] AdrD;
flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD); flopen #(2) AdrReg(clk, ce, Adr[2:1], AdrD);
rom1p1r #(ADDR_WDITH, P.XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull)); rom1p1r #(ADDR_WDITH, P.XLEN) rom(.clk, .ce, .addr(Adr[ADDR_WDITH+OFFSET-1:OFFSET]), .dout(IROMInstrFFull));
if (P.XLEN == 32) assign RawIROMInstrF = IROMInstrFFull; if (P.XLEN == 32) assign RawIROMInstrF = IROMInstrFFull;
else begin else begin
// IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two // IROM is aligned to XLEN words, but instructions are 32 bits. Select between the two
// haves. Adr is the Next PCF not PCF so we delay 1 cycle. // haves. Adr is the Next PCF not PCF so we delay 1 cycle.
assign RawIROMInstrF = AdrD[1] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0]; assign RawIROMInstrF = AdrD[1] ? IROMInstrFFull[63:32] : IROMInstrFFull[31:0];
@ -52,4 +51,3 @@ module irom import cvw::*; #(parameter cvw_t P) (
// The spill logic will handle merging the two together. // The spill logic will handle merging the two together.
assign IROMInstrF = AdrD[0] ? {16'b0, RawIROMInstrF[31:16]} : RawIROMInstrF; assign IROMInstrF = AdrD[0] ? {16'b0, RawIROMInstrF[31:16]} : RawIROMInstrF;
endmodule endmodule

View File

@ -32,33 +32,33 @@
`include "wally-config.vh" `include "wally-config.vh"
module spill import cvw::*; #(parameter cvw_t P) ( module spill import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallD, FlushD, input logic StallD, FlushD,
input logic [P.XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage input logic [P.XLEN-1:0] PCF, // 2 byte aligned PC in Fetch stage
input logic [P.XLEN-1:2] PCPlus4F, // PCF + 4 input logic [P.XLEN-1:2] PCPlus4F, // PCF + 4
input logic [P.XLEN-1:0] PCNextF, // The next PCF input logic [P.XLEN-1:0] PCNextF, // The next PCF
input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed input logic [31:0] InstrRawF, // Instruction from the IROM, I$, or bus. Used to check if the instruction if compressed
input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched input logic IFUCacheBusStallF, // I$ or bus are stalled. Transition to second fetch of spill after the first is fetched
input logic ITLBMissF, // ITLB miss, ignore memory request input logic ITLBMissF, // ITLB miss, ignore memory request
input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active) input logic InstrUpdateDAF, // Ignore memory request if the hptw support write and a DA page fault occurs (hptw is still active)
output logic [P.XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill output logic [P.XLEN-1:0] PCSpillNextF, // The next PCF for one of the two memory addresses of the spill
output logic [P.XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill output logic [P.XLEN-1:0] PCSpillF, // PCF for one of the two memory addresses of the spill
output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline output logic SelSpillNextF, // During the transition between the two spill operations, the IFU should stall the pipeline
output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction output logic [31:0] PostSpillInstrRawF,// The final 32 bit instruction after merging the two spilled fetches into 1 instruction
output logic CompressedF); // The fetched instruction is compressed output logic CompressedF); // The fetched instruction is compressed
// Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1] // Spill threshold occurs when all the cache offset PC bits are 1 (except [0]). Without a cache this is just PCF[1]
typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype; typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype;
localparam SPILLTHRESHOLD = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/32 : 1; localparam SPILLTHRESHOLD = P.ICACHE_SUPPORTED ? P.ICACHE_LINELENINBITS/32 : 1;
statetype CurrState, NextState; statetype CurrState, NextState;
logic [P.XLEN-1:0] PCPlus2F; logic [P.XLEN-1:0] PCPlus2F;
logic TakeSpillF; logic TakeSpillF;
logic SpillF; logic SpillF;
logic SelSpillF; logic SelSpillF;
logic SpillSaveF; logic SpillSaveF;
logic [15:0] InstrFirstHalfF; logic [15:0] InstrFirstHalfF;
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// PC logic // PC logic
@ -71,7 +71,6 @@ module spill import cvw::*; #(parameter cvw_t P) (
// select between PCF and PCF+2 // select between PCF and PCF+2
mux2 #(P.XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCSpillF)); mux2 #(P.XLEN) pcspillmux(.d0(PCF), .d1(PCPlus2F), .s(SelSpillF), .y(PCSpillF));
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////
// Detect spill // Detect spill
//////////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////////

View File

@ -30,8 +30,8 @@
module amoalu import cvw::*; #(parameter cvw_t P) ( module amoalu import cvw::*; #(parameter cvw_t P) (
input logic [P.XLEN-1:0] ReadDataM, // LSU's ReadData input logic [P.XLEN-1:0] ReadDataM, // LSU's ReadData
input logic [P.XLEN-1:0] IHWriteDataM, // LSU's WriteData input logic [P.XLEN-1:0] IHWriteDataM, // LSU's WriteData
input logic [6:0] LSUFunct7M, // ALU Operation input logic [6:0] LSUFunct7M, // ALU Operation
input logic [2:0] LSUFunct3M, // Memoy access width input logic [2:0] LSUFunct3M, // Memoy access width
output logic [P.XLEN-1:0] AMOResultM // ALU output output logic [P.XLEN-1:0] AMOResultM // ALU output
); );
@ -72,4 +72,3 @@ module amoalu import cvw::*; #(parameter cvw_t P) (
end end
end end
endmodule endmodule

View File

@ -28,24 +28,24 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module atomic import cvw::*; #(parameter cvw_t P) ( module atomic import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallW, input logic StallW,
input logic [P.XLEN-1:0] ReadDataM, // LSU ReadData XLEN because FPU does not issue atomic memory operation from FPU registers input logic [P.XLEN-1:0] ReadDataM, // LSU ReadData XLEN because FPU does not issue atomic memory operation from FPU registers
input logic [P.XLEN-1:0] IHWriteDataM, // LSU WriteData XLEN because FPU does not issue atomic memory operation from FPU registers input logic [P.XLEN-1:0] IHWriteDataM, // LSU WriteData XLEN because FPU does not issue atomic memory operation from FPU registers
input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address
input logic [6:0] LSUFunct7M, // AMO alu operation gated by HPTW input logic [6:0] LSUFunct7M, // AMO alu operation gated by HPTW
input logic [2:0] LSUFunct3M, // IEU or HPTW memory operation size input logic [2:0] LSUFunct3M, // IEU or HPTW memory operation size
input logic [1:0] LSUAtomicM, // 10: AMO operation, select AMOResultM as the writedata output, 01: LR/SC operation input logic [1:0] LSUAtomicM, // 10: AMO operation, select AMOResultM as the writedata output, 01: LR/SC operation
input logic [1:0] PreLSURWM, // IEU or HPTW Read/Write signal input logic [1:0] PreLSURWM, // IEU or HPTW Read/Write signal
input logic IgnoreRequest, // On FlushM or TLB miss ignore memory operation input logic IgnoreRequest, // On FlushM or TLB miss ignore memory operation
output logic [P.XLEN-1:0] IMAWriteDataM, // IEU, HPTW, or AMO write data output logic [P.XLEN-1:0] IMAWriteDataM, // IEU, HPTW, or AMO write data
output logic SquashSCW, // Store conditional failed disable write to GPR output logic SquashSCW, // Store conditional failed disable write to GPR
output logic [1:0] LSURWM // IEU or HPTW Read/Write signal gated by LR/SC output logic [1:0] LSURWM // IEU or HPTW Read/Write signal gated by LR/SC
); );
logic [P.XLEN-1:0] AMOResultM; logic [P.XLEN-1:0] AMOResultM;
logic MemReadM; logic MemReadM;
amoalu #(P) amoalu(.ReadDataM, .IHWriteDataM, .LSUFunct7M, .LSUFunct3M, .AMOResultM); amoalu #(P) amoalu(.ReadDataM, .IHWriteDataM, .LSUFunct7M, .LSUFunct3M, .AMOResultM);

View File

@ -28,17 +28,17 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module dtim import cvw::*; #(parameter cvw_t P) ( module dtim import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
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 [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
); );
logic we; logic we;
localparam LLENBYTES = P.LLEN/8; localparam LLENBYTES = P.LLEN/8;
// verilator lint_off WIDTH // verilator lint_off WIDTH
@ -52,4 +52,3 @@ module dtim import cvw::*; #(parameter cvw_t P) (
ram1p1rwbe #(.DEPTH(DEPTH), .WIDTH(P.LLEN)) ram1p1rwbe #(.DEPTH(DEPTH), .WIDTH(P.LLEN))
ram(.clk, .ce, .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

@ -29,23 +29,23 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module lrsc import cvw::*; #(parameter cvw_t P) ( module lrsc import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallW, input logic StallW,
input logic MemReadM, // Memory read input logic MemReadM, // Memory read
input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write input logic [1:0] PreLSURWM, // Memory operation from the HPTW or IEU [1]: read, [0]: write
output logic [1:0] LSURWM, // Memory operation after potential squash of SC output logic [1:0] LSURWM, // Memory operation after potential squash of SC
input logic [1:0] LSUAtomicM, // Atomic memory operaiton input logic [1:0] LSUAtomicM, // Atomic memory operaiton
input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address input logic [P.PA_BITS-1:0] PAdrM, // Physical memory address
output logic SquashSCW // Squash the store conditional by not allowing rf write output logic SquashSCW // Squash the store conditional by not allowing rf write
); );
// possible bug: *** double check if PreLSURWM needs to be flushed by ignorerequest. // possible bug: *** double check if PreLSURWM needs to be flushed by ignorerequest.
// Handle atomic load reserved / store conditional // Handle atomic load reserved / store conditional
logic [P.PA_BITS-1:2] ReservationPAdrW; logic [P.PA_BITS-1:2] ReservationPAdrW;
logic ReservationValidM, ReservationValidW; logic ReservationValidM, ReservationValidW;
logic lrM, scM, WriteAdrMatchM; logic lrM, scM, WriteAdrMatchM;
logic SquashSCM; logic SquashSCM;
assign lrM = MemReadM & LSUAtomicM[0]; assign lrM = MemReadM & LSUAtomicM[0];
assign scM = PreLSURWM[0] & LSUAtomicM[0]; assign scM = PreLSURWM[0] & LSUAtomicM[0];

View File

@ -30,63 +30,63 @@
///////////////////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////////////////
module lsu import cvw::*; #(parameter cvw_t P) ( module lsu import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic StallM, FlushM, StallW, FlushW, input logic StallM, FlushM, StallW, FlushW,
output logic LSUStallM, // LSU stalls pipeline during a multicycle operation output logic LSUStallM, // LSU stalls pipeline during a multicycle operation
// connected to cpu (controls) // connected to cpu (controls)
input logic [1:0] MemRWM, // Read/Write control input logic [1:0] MemRWM, // Read/Write control
input logic [2:0] Funct3M, // Size of memory operation input logic [2:0] Funct3M, // Size of memory operation
input logic [6:0] Funct7M, // Atomic memory operation function input logic [6:0] Funct7M, // Atomic memory operation function
input logic [1:0] AtomicM, // Atomic memory operation input logic [1:0] AtomicM, // Atomic memory operation
input logic FlushDCacheM, // Flush D cache to next level of memory input logic FlushDCacheM, // Flush D cache to next level of memory
output logic CommittedM, // Delay interrupts while memory operation in flight output logic CommittedM, // Delay interrupts while memory operation in flight
output logic SquashSCW, // Store conditional failed disable write to GPR output logic SquashSCW, // Store conditional failed disable write to GPR
output logic DCacheMiss, // D cache miss for performance counters output logic DCacheMiss, // D cache miss for performance counters
output logic DCacheAccess, // D cache memory access for performance counters output logic DCacheAccess, // D cache memory access for performance counters
// address and write data // address and write data
input logic [P.XLEN-1:0] IEUAdrE, // Execution stage memory address input logic [P.XLEN-1:0] IEUAdrE, // Execution stage memory address
output logic [P.XLEN-1:0] IEUAdrM, // Memory stage memory address output logic [P.XLEN-1:0] IEUAdrM, // Memory stage memory address
input logic [P.XLEN-1:0] WriteDataM, // Write data from IEU input logic [P.XLEN-1:0] WriteDataM, // Write data from IEU
output logic [P.LLEN-1:0] ReadDataW, // Read data to IEU or FPU output logic [P.LLEN-1:0] ReadDataW, // Read data to IEU or FPU
// cpu privilege // cpu privilege
input logic [1:0] PrivilegeModeW, // Current privilege mode input logic [1:0] PrivilegeModeW, // Current privilege mode
input logic BigEndianM, // Swap byte order to big endian input logic BigEndianM, // Swap byte order to big endian
input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries input logic sfencevmaM, // Virtual memory address fence, invalidate TLB entries
output logic DCacheStallM, // D$ busy with multicycle operation output logic DCacheStallM, // D$ busy with multicycle operation
// fpu // fpu
input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU input logic [P.FLEN-1:0] FWriteDataM, // Write data from FPU
input logic FpLoadStoreM, // Selects FPU as store for write data input logic FpLoadStoreM, // Selects FPU as store for write data
// faults // faults
output logic LoadPageFaultM, StoreAmoPageFaultM, // Page fault exceptions output logic LoadPageFaultM, StoreAmoPageFaultM, // Page fault exceptions
output logic LoadMisalignedFaultM, // Load address misaligned fault output logic LoadMisalignedFaultM, // Load address misaligned fault
output logic LoadAccessFaultM, // Load access fault (PMA) output logic LoadAccessFaultM, // Load access fault (PMA)
output logic HPTWInstrAccessFaultF, // HPTW generated access fault during instruction fetch output logic HPTWInstrAccessFaultF, // HPTW generated access fault during instruction fetch
// cpu hazard unit (trap) // cpu hazard unit (trap)
output logic StoreAmoMisalignedFaultM, // Store or AMO address misaligned fault output logic StoreAmoMisalignedFaultM, // Store or AMO address misaligned fault
output logic StoreAmoAccessFaultM, // Store or AMO access fault output logic StoreAmoAccessFaultM, // Store or AMO access fault
// connect to ahb // connect to ahb
output logic [P.PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU output logic [P.PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU
input logic [P.XLEN-1:0] HRDATA, // Bus read data from LSU to EBU input logic [P.XLEN-1:0] HRDATA, // Bus read data from LSU to EBU
output logic [P.XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU output logic [P.XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU
input logic LSUHREADY, // Bus ready from LSU to EBU input logic LSUHREADY, // Bus ready from LSU to EBU
output logic LSUHWRITE, // Bus write operation from LSU to EBU output logic LSUHWRITE, // Bus write operation from LSU to EBU
output logic [2:0] LSUHSIZE, // Bus operation size from LSU to EBU output logic [2:0] LSUHSIZE, // Bus operation size from LSU to EBU
output logic [2:0] LSUHBURST, // Bus burst from LSU to EBU output logic [2:0] LSUHBURST, // Bus burst from LSU to EBU
output logic [1:0] LSUHTRANS, // Bus transaction type from LSU to EBU output logic [1:0] LSUHTRANS, // Bus transaction type from LSU to EBU
output logic [P.XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU output logic [P.XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU
// page table walker // page table walker
input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR input logic [P.XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
input logic [1:0] STATUS_MPP, // Machine previous privilege mode input logic [1:0] STATUS_MPP, // Machine previous privilege mode
input logic [P.XLEN-1:0] PCSpillF, // Fetch PC input logic [P.XLEN-1:0] PCSpillF, // Fetch PC
input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk input logic ITLBMissF, // ITLB miss causes HPTW (hardware pagetable walker) walk
input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits input logic InstrUpdateDAF, // ITLB hit needs to update dirty or access bits
output logic [P.XLEN-1:0] PTE, // Page table entry write to ITLB output logic [P.XLEN-1:0] PTE, // Page table entry write to ITLB
output logic [1:0] PageType, // Type of page table entry to write to ITLB output logic [1:0] PageType, // Type of page table entry to write to ITLB
output logic ITLBWriteF, // Write PTE to ITLB output logic ITLBWriteF, // Write PTE to ITLB
output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE output logic SelHPTW, // During a HPTW walk the effective privilege mode becomes S_MODE
input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit input var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration from privileged unit
input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP address from privileged unit input var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0] // PMP address from privileged unit
); );
logic [P.XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer logic [P.XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer
@ -94,20 +94,20 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic [P.PA_BITS-1:0] PAdrM; // Physical memory address logic [P.PA_BITS-1:0] PAdrM; // Physical memory address
logic [P.XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address logic [P.XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address
logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal
logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC
logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size logic [2:0] LSUFunct3M; // IEU or HPTW memory operation size
logic [6:0] LSUFunct7M; // AMO function gated by HPTW logic [6:0] LSUFunct7M; // AMO function gated by HPTW
logic [1:0] LSUAtomicM; // AMO signal gated by HPTW logic [1:0] LSUAtomicM; // AMO signal gated by HPTW
logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1 logic GatedStallW; // Hazard unit StallW gated when SelHPTW = 1
logic BusStall; // Bus interface busy with multicycle operation logic BusStall; // Bus interface busy with multicycle operation
logic HPTWStall; // HPTW busy with multicycle operation logic HPTWStall; // HPTW busy with multicycle operation
logic CacheableM; // PMA indicates memory address is cacheable logic CacheableM; // PMA indicates memory address is cacheable
logic BusCommittedM; // Bus memory operation in flight, delay interrupts logic BusCommittedM; // Bus memory operation in flight, delay interrupts
logic DCacheCommittedM; // D$ memory operation started, delay interrupts logic DCacheCommittedM; // D$ memory operation started, delay interrupts
logic [P.LLEN-1:0] DTIMReadDataWordM; // DTIM read data logic [P.LLEN-1:0] DTIMReadDataWordM; // DTIM read data
logic [P.LLEN-1:0] DCacheReadDataWordM; // D$ read data logic [P.LLEN-1:0] DCacheReadDataWordM; // D$ read data
@ -123,16 +123,15 @@ module lsu import cvw::*; #(parameter cvw_t P) (
logic [P.LLEN-1:0] LSUWriteDataM; // Final write data logic [P.LLEN-1:0] LSUWriteDataM; // Final write data
logic [(P.LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write logic [(P.LLEN-1)/8:0] ByteMaskM; // Selects which bytes within a word to write
logic DTLBMissM; // DTLB miss causes HPTW walk logic DTLBMissM; // DTLB miss causes HPTW walk
logic DTLBWriteM; // Writes PTE and PageType to DTLB logic DTLBWriteM; // Writes PTE and PageType to DTLB
logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits logic DataUpdateDAM; // DTLB hit needs to update dirty or access bits
logic LSULoadAccessFaultM; // Load acces fault logic LSULoadAccessFaultM; // Load acces fault
logic LSUStoreAmoAccessFaultM; // Store access fault logic LSUStoreAmoAccessFaultM; // Store access fault
logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle logic IgnoreRequestTLB; // On either ITLB or DTLB miss, ignore miss so HPTW can handle
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$
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Pipeline for IEUAdr E to M // Pipeline for IEUAdr E to M
// Zero-extend address to 34 bits for XLEN=32 // Zero-extend address to 34 bits for XLEN=32
@ -222,7 +221,7 @@ 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;
// 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], MemRWM[0], DTIMAdr); mux2 #(P.PA_BITS) DTIMAdrMux(IEUAdrExtE[P.PA_BITS-1:0], IEUAdrExtM[P.PA_BITS-1:0], MemRWM[0], DTIMAdr);
@ -237,23 +236,23 @@ module lsu import cvw::*; #(parameter cvw_t P) (
if (P.BUS_SUPPORTED) begin : bus if (P.BUS_SUPPORTED) begin : bus
if(P.DCACHE_SUPPORTED) begin : dcache if(P.DCACHE_SUPPORTED) begin : dcache
localparam LLENWORDSPERLINE = P.DCACHE_LINELENINBITS/P.LLEN; // Number of LLEN words in cacheline localparam LLENWORDSPERLINE = P.DCACHE_LINELENINBITS/P.LLEN; // Number of LLEN words in cacheline
localparam LLENLOGBWPL = $clog2(LLENWORDSPERLINE); // Log2 of ^ localparam LLENLOGBWPL = $clog2(LLENWORDSPERLINE); // Log2 of ^
localparam BEATSPERLINE = P.DCACHE_LINELENINBITS/P.AHBW; // Number of AHBW words (beats) in cacheline localparam BEATSPERLINE = P.DCACHE_LINELENINBITS/P.AHBW; // Number of AHBW words (beats) in cacheline
localparam AHBWLOGBWPL = $clog2(BEATSPERLINE); // Log2 of ^ localparam AHBWLOGBWPL = $clog2(BEATSPERLINE); // Log2 of ^
localparam LINELEN = P.DCACHE_LINELENINBITS; // Number of bits in cacheline localparam LINELEN = P.DCACHE_LINELENINBITS; // Number of bits in cacheline
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)
logic [LINELEN-1:0] FetchBuffer; // Temporary buffer to hold partially fetched cacheline logic [LINELEN-1:0] FetchBuffer; // Temporary buffer to hold partially fetched cacheline
logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback. logic [P.PA_BITS-1:0] DCacheBusAdr; // Cacheline address to fetch or writeback.
logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache logic [AHBWLOGBWPL-1:0] BeatCount; // Position within a cacheline. ahbcacheinterface to cache
logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback logic DCacheBusAck; // ahbcacheinterface completed fetch or writeback
logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount logic SelBusBeat; // ahbcacheinterface selects postion in cacheline with BeatCount
logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface logic [1:0] CacheBusRW; // Cache sends request to ahbcacheinterface
logic [1:0] BusRW; // Uncached bus memory access logic [1:0] BusRW; // Uncached bus memory access
logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush logic CacheableOrFlushCacheM; // Memory address is cacheable or operation is a cache flush
logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11) logic [1:0] CacheRWM; // Cache read (10), write (01), AMO (11)
logic [1:0] CacheAtomicM; // Cache AMO logic [1:0] CacheAtomicM; // Cache AMO
logic FlushDCache; // Suppress d cache flush if there is an ITLB miss. logic FlushDCache; // Suppress d cache flush if there is an ITLB miss.
assign BusRW = ~CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0; assign BusRW = ~CacheableM & ~IgnoreRequestTLB & ~SelDTIM ? LSURWM : '0;
assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM; assign CacheableOrFlushCacheM = CacheableM | FlushDCacheM;
@ -320,6 +319,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Atomic operations // Atomic operations
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
if (P.A_SUPPORTED) begin:atomic if (P.A_SUPPORTED) begin:atomic
atomic #(P) atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[P.XLEN-1:0]), .IHWriteDataM, .PAdrM, atomic #(P) atomic(.clk, .reset, .StallW, .ReadDataM(ReadDataM[P.XLEN-1:0]), .IHWriteDataM, .PAdrM,
.LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest, .LSUFunct7M, .LSUFunct3M, .LSUAtomicM, .PreLSURWM, .IgnoreRequest,
@ -335,6 +335,7 @@ module lsu import cvw::*; #(parameter cvw_t P) (
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
// Subword Accesses // Subword Accesses
///////////////////////////////////////////////////////////////////////////////////////////// /////////////////////////////////////////////////////////////////////////////////////////////
subwordread #(P.LLEN) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM, subwordread #(P.LLEN) subwordread(.ReadDataWordMuxM(LittleEndianReadDataWordM), .PAdrM(PAdrM[2:0]), .BigEndianM,
.FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM); .FpLoadStoreM, .Funct3M(LSUFunct3M), .ReadDataM);
subwordwrite #(P.LLEN) subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM); subwordwrite #(P.LLEN) subwordwrite(.LSUFunct3M, .IMAFWriteDataM, .LittleEndianWriteDataM);
@ -361,5 +362,4 @@ module lsu import cvw::*; #(parameter cvw_t P) (
assign LSUWriteDataM = LittleEndianWriteDataM; assign LSUWriteDataM = LittleEndianWriteDataM;
assign LittleEndianReadDataWordM = ReadDataWordMuxM; assign LittleEndianReadDataWordM = ReadDataWordMuxM;
end end
endmodule endmodule

View File

@ -29,12 +29,12 @@
module subwordread #(parameter LLEN) module subwordread #(parameter LLEN)
( (
input logic [LLEN-1:0] ReadDataWordMuxM, input logic [LLEN-1:0] ReadDataWordMuxM,
input logic [2:0] PAdrM, input logic [2:0] PAdrM,
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic FpLoadStoreM, input logic FpLoadStoreM,
input logic BigEndianM, input logic BigEndianM,
output logic [LLEN-1:0] ReadDataM output logic [LLEN-1:0] ReadDataM
); );
logic [7:0] ByteM; logic [7:0] ByteM;
@ -89,7 +89,7 @@ module subwordread #(parameter LLEN)
//3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128 //3'b100: ReadDataM = FpLoadStoreM ? ReadDataWordMuxM : {{LLEN-8{1'b0}}, ByteM[7:0]}; // lbu/flq - only needed when LLEN=128
3'b101: ReadDataM = {{LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu 3'b101: ReadDataM = {{LLEN-16{1'b0}}, HalfwordM[15:0]}; // lhu
3'b110: ReadDataM = {{LLEN-32{1'b0}}, WordM[31:0]}; // lwu 3'b110: ReadDataM = {{LLEN-32{1'b0}}, WordM[31:0]}; // lwu
default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen default: ReadDataM = ReadDataWordMuxM; // Shouldn't happen
endcase endcase
end else begin:swrmux // 32-bit end else begin:swrmux // 32-bit

View File

@ -28,8 +28,8 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module subwordwrite #(parameter LLEN) ( module subwordwrite #(parameter LLEN) (
input logic [2:0] LSUFunct3M, input logic [2:0] LSUFunct3M,
input logic [LLEN-1:0] IMAFWriteDataM, input logic [LLEN-1:0] IMAFWriteDataM,
output logic [LLEN-1:0] LittleEndianWriteDataM output logic [LLEN-1:0] LittleEndianWriteDataM
); );
@ -46,18 +46,18 @@ module subwordwrite #(parameter LLEN) (
end else if (LLEN == 64) begin:sww end else if (LLEN == 64) begin:sww
always_comb always_comb
case(LSUFunct3M[1:0]) case(LSUFunct3M[1:0])
2'b00: LittleEndianWriteDataM = {8{IMAFWriteDataM[7:0]}}; // sb 2'b00: LittleEndianWriteDataM = {8{IMAFWriteDataM[7:0]}}; // sb
2'b01: LittleEndianWriteDataM = {4{IMAFWriteDataM[15:0]}}; // sh 2'b01: LittleEndianWriteDataM = {4{IMAFWriteDataM[15:0]}}; // sh
2'b10: LittleEndianWriteDataM = {2{IMAFWriteDataM[31:0]}}; // sw 2'b10: LittleEndianWriteDataM = {2{IMAFWriteDataM[31:0]}}; // sw
2'b11: LittleEndianWriteDataM = IMAFWriteDataM; // sd 2'b11: LittleEndianWriteDataM = IMAFWriteDataM; // sd
endcase endcase
end else begin:sww // 32-bit end else begin:sww // 32-bit
always_comb always_comb
case(LSUFunct3M[1:0]) case(LSUFunct3M[1:0])
2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb 2'b00: LittleEndianWriteDataM = {4{IMAFWriteDataM[7:0]}}; // sb
2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh 2'b01: LittleEndianWriteDataM = {2{IMAFWriteDataM[15:0]}}; // sh
2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw 2'b10: LittleEndianWriteDataM = IMAFWriteDataM; // sw
default: LittleEndianWriteDataM = IMAFWriteDataM; // shouldn't happen default: LittleEndianWriteDataM = IMAFWriteDataM; // shouldn't happen
endcase endcase
end end
endmodule endmodule

View File

@ -28,9 +28,9 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module swbytemask #(parameter WORDLEN)( module swbytemask #(parameter WORDLEN)(
input logic [2:0] Size, input logic [2:0] Size,
input logic [$clog2(WORDLEN/8)-1:0] Adr, input logic [$clog2(WORDLEN/8)-1:0] Adr,
output logic [WORDLEN/8-1:0] ByteMask output logic [WORDLEN/8-1:0] ByteMask
); );
assign ByteMask = ((2**(2**Size))-1) << Adr; assign ByteMask = ((2**(2**Size))-1) << Adr;

View File

@ -27,38 +27,38 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module div import cvw::*; #(parameter cvw_t P) ( module div import cvw::*; #(parameter cvw_t P) (
input logic clk, input logic clk,
input logic reset, input logic reset,
input logic StallM, input logic StallM,
input logic FlushE, input logic FlushE,
input logic IntDivE, // integer division/remainder instruction of any type input logic IntDivE, // integer division/remainder instruction of any type
input logic DivSignedE, // signed division input logic DivSignedE, // signed division
input logic W64E, // W-type instructions (divw, divuw, remw, remuw) input logic W64E, // W-type instructions (divw, divuw, remw, remuw)
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE,// Forwarding mux outputs for Source A and B input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // Forwarding mux outputs for Source A and B
output logic DivBusyE, // Divide is busy - stall pipeline output logic DivBusyE, // Divide is busy - stall pipeline
output logic [P.XLEN-1:0] QuotM, RemM // Quotient and remainder outputs output logic [P.XLEN-1:0] QuotM, RemM // Quotient and remainder outputs
); );
localparam STEPBITS = $clog2(P.XLEN/P.IDIV_BITSPERCYCLE); // Number of steps localparam STEPBITS = $clog2(P.XLEN/P.IDIV_BITSPERCYCLE); // Number of steps
typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype; // division FSM state typedef enum logic [1:0] {IDLE, BUSY, DONE} statetype; // division FSM state
statetype state; statetype state;
logic [P.XLEN-1:0] W[P.IDIV_BITSPERCYCLE:0]; // Residual for each of k steps logic [P.XLEN-1:0] W[P.IDIV_BITSPERCYCLE:0]; // Residual for each of k steps
logic [P.XLEN-1:0] XQ[P.IDIV_BITSPERCYCLE:0]; // dividend/quotient for each of k steps logic [P.XLEN-1:0] XQ[P.IDIV_BITSPERCYCLE:0]; // dividend/quotient for each of k steps
logic [P.XLEN-1:0] WNext, XQNext; // initialized W and XQ going into registers logic [P.XLEN-1:0] WNext, XQNext; // initialized W and XQ going into registers
logic [P.XLEN-1:0] DinE, XinE; // divisor & dividend, possibly truncated to 32 bits logic [P.XLEN-1:0] DinE, XinE; // divisor & dividend, possibly truncated to 32 bits
logic [P.XLEN-1:0] DnE; // DnE = ~DinE logic [P.XLEN-1:0] DnE; // DnE = ~DinE
logic [P.XLEN-1:0] DAbsBE; // absolute value of D logic [P.XLEN-1:0] DAbsBE; // absolute value of D
logic [P.XLEN-1:0] DAbsB; // registered absolute value of D, constant during division logic [P.XLEN-1:0] DAbsB; // registered absolute value of D, constant during division
logic [P.XLEN-1:0] XnE; // DXnE = ~XinE logic [P.XLEN-1:0] XnE; // DXnE = ~XinE
logic [P.XLEN-1:0] XInitE; // |X|, or original X for divide by 0 logic [P.XLEN-1:0] XInitE; // |X|, or original X for divide by 0
logic [P.XLEN-1:0] WnM, XQnM; // negated residual W and quotient XQ for postprocessing sign correction logic [P.XLEN-1:0] WnM, XQnM; // negated residual W and quotient XQ for postprocessing sign correction
logic [STEPBITS:0] step; // division step logic [STEPBITS:0] step; // division step
logic Div0E, Div0M; // divide by 0 logic Div0E, Div0M; // divide by 0
logic DivStartE; // start integer division logic DivStartE; // start integer division
logic SignXE, SignDE; // sign of dividend and divisor logic SignXE, SignDE; // sign of dividend and divisor
logic NegQE, NegWM, NegQM; // negate quotient or residual during postprocessing logic NegQE, NegWM, NegQM; // negate quotient or residual during postprocessing
////////////////////////////// //////////////////////////////
// Execute Stage: prepare for division calculation with control logic, W logic and absolute values, initialize W and XQ // Execute Stage: prepare for division calculation with control logic, W logic and absolute values, initialize W and XQ
@ -131,7 +131,7 @@ module div import cvw::*; #(parameter cvw_t P) (
step <= 1; step <= 1;
if (Div0E) state <= DONE; if (Div0E) state <= DONE;
else state <= BUSY; else state <= BUSY;
end else if (state == BUSY) begin // pause one cycle at beginning of signed operations for absolute value end else if (state == BUSY) begin // pause one cycle at beginning of signed operations for absolute value
if (step[STEPBITS] | (P.XLEN==64) & W64E & step[STEPBITS-1]) begin // complete in half the time for W-type instructions if (step[STEPBITS] | (P.XLEN==64) & W64E & step[STEPBITS-1]) begin // complete in half the time for W-type instructions
state <= DONE; state <= DONE;
end end

View File

@ -27,21 +27,21 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module mdu import cvw::*; #(parameter cvw_t P) ( module mdu import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic StallM, StallW, input logic StallM, StallW,
input logic FlushE, FlushM, FlushW, input logic FlushE, FlushM, FlushW,
input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output input logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
input logic [2:0] Funct3E, Funct3M, // type of MDU operation input logic [2:0] Funct3E, Funct3M, // type of MDU operation
input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions input logic IntDivE, W64E, // Integer division/remainder, and W-type instrutions
output logic [P.XLEN-1:0] MDUResultW, // multiply/divide result output logic [P.XLEN-1:0] MDUResultW, // multiply/divide result
output logic DivBusyE // busy signal to stall pipeline in Execute stage output logic DivBusyE // busy signal to stall pipeline in Execute stage
); );
logic [P.XLEN*2-1:0] ProdM; // double-width product from mul logic [P.XLEN*2-1:0] ProdM; // double-width product from mul
logic [P.XLEN-1:0] QuotM, RemM; // quotient and remainder from intdivrestoring logic [P.XLEN-1:0] QuotM, RemM; // quotient and remainder from intdivrestoring
logic [P.XLEN-1:0] PrelimResultM; // selected result before W truncation logic [P.XLEN-1:0] PrelimResultM; // selected result before W truncation
logic [P.XLEN-1:0] MDUResultM; // result after W truncation logic [P.XLEN-1:0] MDUResultM; // result after W truncation
logic W64M; // W-type instruction logic W64M; // W-type instruction
// Multiplier // Multiplier
mul #(P.XLEN) mul(.clk, .reset, .StallM, .FlushM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ProdM); mul #(P.XLEN) mul(.clk, .reset, .StallM, .FlushM, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ProdM);
@ -64,13 +64,13 @@ module mdu import cvw::*; #(parameter cvw_t P) (
always_comb always_comb
case (Funct3M) case (Funct3M)
3'b000: PrelimResultM = ProdM[P.XLEN-1:0]; // mul 3'b000: PrelimResultM = ProdM[P.XLEN-1:0]; // mul
3'b001: PrelimResultM = ProdM[P.XLEN*2-1:P.XLEN]; // mulh 3'b001: PrelimResultM = ProdM[P.XLEN*2-1:P.XLEN]; // mulh
3'b010: PrelimResultM = ProdM[P.XLEN*2-1:P.XLEN]; // mulhsu 3'b010: PrelimResultM = ProdM[P.XLEN*2-1:P.XLEN]; // mulhsu
3'b011: PrelimResultM = ProdM[P.XLEN*2-1:P.XLEN]; // mulhu 3'b011: PrelimResultM = ProdM[P.XLEN*2-1:P.XLEN]; // mulhu
3'b100: PrelimResultM = QuotM; // div 3'b100: PrelimResultM = QuotM; // div
3'b101: PrelimResultM = QuotM; // divu 3'b101: PrelimResultM = QuotM; // divu
3'b110: PrelimResultM = RemM; // rem 3'b110: PrelimResultM = RemM; // rem
3'b111: PrelimResultM = RemM; // remu 3'b111: PrelimResultM = RemM; // remu
endcase endcase
// Handle sign extension for W-type instructions // Handle sign extension for W-type instructions
@ -84,5 +84,3 @@ module mdu import cvw::*; #(parameter cvw_t P) (
// Writeback stage pipeline register // Writeback stage pipeline register
flopenrc #(P.XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW); flopenrc #(P.XLEN) MDUResultWReg(clk, reset, FlushW, ~StallW, MDUResultM, MDUResultW);
endmodule // mdu endmodule // mdu

View File

@ -29,9 +29,9 @@
module mul #(parameter XLEN) ( module mul #(parameter XLEN) (
input logic clk, reset, input logic clk, reset,
input logic StallM, FlushM, input logic StallM, FlushM,
input logic [XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // source A and B from after Forwarding mux input logic [XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // source A and B from after Forwarding mux
input logic [2:0] Funct3E, // type of multiply input logic [2:0] Funct3E, // type of multiply
output logic [XLEN*2-1:0] ProdM // double-widthproduct output logic [XLEN*2-1:0] ProdM // double-widthproduct
); );
// Number systems // Number systems
@ -48,12 +48,12 @@ module mul #(parameter XLEN) (
// Signed * Unsigned = P' + ( PA - PB)*2^(XLEN-1) - PP*2^(2XLEN-2) // Signed * Unsigned = P' + ( PA - PB)*2^(XLEN-1) - PP*2^(2XLEN-2)
// Unsigned * Unsigned = P' + ( PA + PB)*2^(XLEN-1) + PP*2^(2XLEN-2) // Unsigned * Unsigned = P' + ( PA + PB)*2^(XLEN-1) + PP*2^(2XLEN-2)
logic [XLEN-1:0] Aprime, Bprime; // lower bits of source A and B logic [XLEN-1:0] Aprime, Bprime; // lower bits of source A and B
logic MULH, MULHSU; // type of multiply logic MULH, MULHSU; // type of multiply
logic [XLEN-2:0] PA, PB; // product of msb and lsbs logic [XLEN-2:0] PA, PB; // product of msb and lsbs
logic PP; // product of msbs logic PP; // product of msbs
logic [XLEN*2-1:0] PP1E, PP2E, PP3E, PP4E; // partial products logic [XLEN*2-1:0] PP1E, PP2E, PP3E, PP4E; // partial products
logic [XLEN*2-1:0] PP1M, PP2M, PP3M, PP4M; // registered partial proudcts logic [XLEN*2-1:0] PP1M, PP2M, PP3M, PP4M; // registered partial proudcts
////////////////////////////// //////////////////////////////
// Execute Stage: Compute partial products // Execute Stage: Compute partial products
@ -90,4 +90,3 @@ module mul #(parameter XLEN) (
// add up partial products; this multi-input add implies CSAs and a final CPA // add up partial products; this multi-input add implies CSAs and a final CPA
assign ProdM = PP1M + PP2M + PP3M + PP4M; //ForwardedSrcAE * ForwardedSrcBE; assign ProdM = PP1M + PP2M + PP3M + PP4M; //ForwardedSrcAE * ForwardedSrcBE;
endmodule endmodule

View File

@ -27,8 +27,8 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module adrdec #(parameter PA_BITS) ( module adrdec #(parameter PA_BITS) (
input logic [PA_BITS-1:0] PhysicalAddress, // Physical address to decode input logic [PA_BITS-1:0] PhysicalAddress, // Physical address to decode
input logic [PA_BITS-1:0] Base, Range, // Base and range of peripheral addresses input logic [PA_BITS-1:0] Base, Range, // Base and range of peripheral addresses
input logic Supported, // Is this peripheral supported? input logic Supported, // Is this peripheral supported?
input logic AccessValid, // Is the access type valid? input logic AccessValid, // Is the access type valid?
input logic [1:0] Size, // Size of access input logic [1:0] Size, // Size of access
@ -50,4 +50,3 @@ module adrdec #(parameter PA_BITS) (
// Select this peripheral if the address matches, the peripheral is supported, and the type and size of access is ok // Select this peripheral if the address matches, the peripheral is supported, and the type and size of access is ok
assign Sel = Match & Supported & AccessValid & SizeValid; assign Sel = Match & Supported & AccessValid & SizeValid;
endmodule endmodule

View File

@ -30,12 +30,12 @@
module adrdecs import cvw::*; #(parameter cvw_t P) ( module adrdecs import cvw::*; #(parameter cvw_t P) (
input logic [P.PA_BITS-1:0] PhysicalAddress, input logic [P.PA_BITS-1:0] PhysicalAddress,
input logic AccessRW, AccessRX, AccessRWX, input logic AccessRW, AccessRX, AccessRWX,
input logic [1:0] Size, input logic [1:0] Size,
output logic [10:0] SelRegions output logic [10:0] SelRegions
); );
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[10]); 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[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[9]); 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[9]);

View File

@ -30,39 +30,39 @@
/////////////////////////////////////////// ///////////////////////////////////////////
module hptw import cvw::*; #(parameter cvw_t P) ( module hptw import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic [P.XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table input logic [P.XLEN-1:0] SATP_REGW, // includes SATP.MODE to determine number of levels in page table
input logic [P.XLEN-1:0] PCSpillF, // addresses to translate input logic [P.XLEN-1:0] PCSpillF, // addresses to translate
input logic [P.XLEN+1:0] IEUAdrExtM, // addresses to translate input logic [P.XLEN+1:0] IEUAdrExtM, // addresses to translate
input logic [1:0] MemRWM, AtomicM, input logic [1:0] MemRWM, AtomicM,
// system status // system status
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV,
input logic [1:0] STATUS_MPP, input logic [1:0] STATUS_MPP,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [P.XLEN-1:0] ReadDataM, // page table entry from LSU input logic [P.XLEN-1:0] ReadDataM, // page table entry from LSU
input logic [P.XLEN-1:0] WriteDataM, input logic [P.XLEN-1:0] WriteDataM,
input logic DCacheStallM, // stall from LSU input logic DCacheStallM, // stall from LSU
input logic [2:0] Funct3M, input logic [2:0] Funct3M,
input logic [6:0] Funct7M, input logic [6:0] Funct7M,
input logic ITLBMissF, input logic ITLBMissF,
input logic DTLBMissM, input logic DTLBMissM,
input logic FlushW, input logic FlushW,
input logic InstrUpdateDAF, input logic InstrUpdateDAF,
input logic DataUpdateDAM, input logic DataUpdateDAM,
output logic [P.XLEN-1:0] PTE, // page table entry to TLBs output logic [P.XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs output logic [1:0] PageType, // page type to TLBs
output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic [1:0] PreLSURWM, output logic [1:0] PreLSURWM,
output logic [P.XLEN+1:0] IHAdrM, output logic [P.XLEN+1:0] IHAdrM,
output logic [P.XLEN-1:0] IHWriteDataM, output logic [P.XLEN-1:0] IHWriteDataM,
output logic [1:0] LSUAtomicM, output logic [1:0] LSUAtomicM,
output logic [2:0] LSUFunct3M, output logic [2:0] LSUFunct3M,
output logic [6:0] LSUFunct7M, output logic [6:0] LSUFunct7M,
output logic IgnoreRequestTLB, output logic IgnoreRequestTLB,
output logic SelHPTW, output logic SelHPTW,
output logic HPTWStall, output logic HPTWStall,
input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM, input logic LSULoadAccessFaultM, LSUStoreAmoAccessFaultM,
output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultF output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultF
); );
typedef enum logic [3:0] {L0_ADR, L0_RD, typedef enum logic [3:0] {L0_ADR, L0_RD,
@ -72,39 +72,39 @@ module hptw import cvw::*; #(parameter cvw_t P) (
LEAF, IDLE, UPDATE_PTE, LEAF, IDLE, UPDATE_PTE,
FAULT} statetype; FAULT} statetype;
logic DTLBWalk; // register TLBs translation miss requests logic DTLBWalk; // register TLBs translation miss requests
logic [P.PPN_BITS-1:0] BasePageTablePPN; logic [P.PPN_BITS-1:0] BasePageTablePPN;
logic [P.PPN_BITS-1:0] CurrentPPN; logic [P.PPN_BITS-1:0] CurrentPPN;
logic Executable, Writable, Readable, Valid, PTE_U; logic Executable, Writable, Readable, Valid, PTE_U;
logic Misaligned, MegapageMisaligned; logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE; logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
logic StartWalk; logic StartWalk;
logic TLBMiss; logic TLBMiss;
logic PRegEn; logic PRegEn;
logic [1:0] NextPageType; logic [1:0] NextPageType;
logic [P.SVMODE_BITS-1:0] SvMode; logic [P.SVMODE_BITS-1:0] SvMode;
logic [P.XLEN-1:0] TranslationVAdr; logic [P.XLEN-1:0] TranslationVAdr;
logic [P.XLEN-1:0] NextPTE; logic [P.XLEN-1:0] NextPTE;
logic UpdatePTE; logic UpdatePTE;
logic HPTWUpdateDA; logic HPTWUpdateDA;
logic [P.PA_BITS-1:0] HPTWReadAdr; logic [P.PA_BITS-1:0] HPTWReadAdr;
logic SelHPTWAdr; logic SelHPTWAdr;
logic [P.XLEN+1:0] HPTWAdrExt; logic [P.XLEN+1:0] HPTWAdrExt;
logic ITLBMissOrUpdateDAF; logic ITLBMissOrUpdateDAF;
logic DTLBMissOrUpdateDAM; logic DTLBMissOrUpdateDAM;
logic LSUAccessFaultM; logic LSUAccessFaultM;
logic [P.PA_BITS-1:0] HPTWAdr; logic [P.PA_BITS-1:0] HPTWAdr;
logic [1:0] HPTWRW; logic [1:0] HPTWRW;
logic [2:0] HPTWSize; // 32 or 64 bit access logic [2:0] HPTWSize; // 32 or 64 bit access
statetype WalkerState, NextWalkerState, InitialWalkerState; statetype WalkerState, NextWalkerState, InitialWalkerState;
logic HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault; logic HPTWLoadAccessFault, HPTWStoreAmoAccessFault, HPTWInstrAccessFault;
logic HPTWLoadAccessFaultDelay, HPTWStoreAmoAccessFaultDelay, HPTWInstrAccessFaultDelay; logic HPTWLoadAccessFaultDelay, HPTWStoreAmoAccessFaultDelay, HPTWInstrAccessFaultDelay;
logic HPTWAccessFaultDelay; logic HPTWAccessFaultDelay;
logic TakeHPTWFault, TakeHPTWFaultDelay; logic TakeHPTWFault, TakeHPTWFaultDelay;
// map hptw access faults onto either the original LSU load/store fault or instruction access fault // map hptw access faults onto either the original LSU load/store fault or instruction access fault
assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM; assign LSUAccessFaultM = LSULoadAccessFaultM | LSUStoreAmoAccessFaultM;
assign HPTWLoadAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0]; assign HPTWLoadAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[1] & ~MemRWM[0];
assign HPTWStoreAmoAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[0]; assign HPTWStoreAmoAccessFault = LSUAccessFaultM & DTLBWalk & MemRWM[0];
assign HPTWInstrAccessFault = LSUAccessFaultM & ~DTLBWalk; assign HPTWInstrAccessFault = LSUAccessFaultM & ~DTLBWalk;
@ -140,16 +140,16 @@ module hptw import cvw::*; #(parameter cvw_t P) (
assign ValidNonLeafPTE = ValidPTE & ~LeafPTE; assign ValidNonLeafPTE = ValidPTE & ~LeafPTE;
if(P.SVADU_SUPPORTED) begin : hptwwrites if(P.SVADU_SUPPORTED) begin : hptwwrites
logic ReadAccess, WriteAccess; logic ReadAccess, WriteAccess;
logic InvalidRead, InvalidWrite, InvalidOp; logic InvalidRead, InvalidWrite, InvalidOp;
logic UpperBitsUnequal; logic UpperBitsUnequal;
logic OtherPageFault; logic OtherPageFault;
logic [1:0] EffectivePrivilegeMode; logic [1:0] EffectivePrivilegeMode;
logic ImproperPrivilege; logic ImproperPrivilege;
logic SaveHPTWAdr, SelHPTWWriteAdr; logic SaveHPTWAdr, SelHPTWWriteAdr;
logic [P.PA_BITS-1:0] HPTWWriteAdr; logic [P.PA_BITS-1:0] HPTWWriteAdr;
logic SetDirty; logic SetDirty;
logic Dirty, Accessed; logic Dirty, Accessed;
logic [P.XLEN-1:0] AccessedPTE; logic [P.XLEN-1:0] AccessedPTE;
assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit assign AccessedPTE = {PTE[P.XLEN-1:8], (SetDirty | PTE[7]), 1'b1, PTE[5:0]}; // set accessed bit, conditionally set dirty bit
@ -194,8 +194,8 @@ module hptw import cvw::*; #(parameter cvw_t P) (
end end
// Enable and select signals based on states // Enable and select signals based on states
assign StartWalk = (WalkerState == IDLE) & TLBMiss; assign StartWalk = (WalkerState == IDLE) & TLBMiss;
assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD); assign HPTWRW[1] = (WalkerState == L3_RD) | (WalkerState == L2_RD) | (WalkerState == L1_RD) | (WalkerState == L0_RD);
assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk; assign DTLBWriteM = (WalkerState == LEAF & ~HPTWUpdateDA) & DTLBWalk;
assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk; assign ITLBWriteF = (WalkerState == LEAF & ~HPTWUpdateDA) & ~DTLBWalk;
@ -310,7 +310,7 @@ module hptw import cvw::*; #(parameter cvw_t P) (
// multiplex the outputs to LSU // multiplex the outputs to LSU
if(P.XLEN == 64) assign HPTWAdrExt = {{(P.XLEN+2-P.PA_BITS){1'b0}}, HPTWAdr}; // extend to 66 bits if(P.XLEN == 64) assign HPTWAdrExt = {{(P.XLEN+2-P.PA_BITS){1'b0}}, HPTWAdr}; // extend to 66 bits
else assign HPTWAdrExt = HPTWAdr; else assign HPTWAdrExt = HPTWAdr;
mux2 #(2) rwmux(MemRWM, HPTWRW, SelHPTW, PreLSURWM); mux2 #(2) rwmux(MemRWM, HPTWRW, SelHPTW, PreLSURWM);
mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M); mux2 #(3) sizemux(Funct3M, HPTWSize, SelHPTW, LSUFunct3M);
mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M); mux2 #(7) funct7mux(Funct7M, 7'b0, SelHPTW, LSUFunct7M);

View File

@ -28,48 +28,48 @@
module mmu import cvw::*; #(parameter cvw_t P, module mmu import cvw::*; #(parameter cvw_t P,
parameter TLB_ENTRIES = 8, IMMU = 0) ( parameter TLB_ENTRIES = 8, IMMU = 0) (
input logic clk, reset, input logic clk, reset,
input logic [P.XLEN-1:0] SATP_REGW, // Current value of satp CSR (from privileged unit) input logic [P.XLEN-1:0] SATP_REGW, // Current value of satp CSR (from privileged unit)
input logic STATUS_MXR, // Status CSR: make executable page readable input logic STATUS_MXR, // Status CSR: make executable page readable
input logic STATUS_SUM, // Status CSR: Supervisor access to user memory input logic STATUS_SUM, // Status CSR: Supervisor access to user memory
input logic STATUS_MPRV, // Status CSR: modify machine privilege input logic STATUS_MPRV, // Status CSR: modify machine privilege
input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level input logic [1:0] STATUS_MPP, // Status CSR: previous machine privilege level
input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor input logic [1:0] PrivilegeModeW, // Current privilege level of the processeor
input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses input logic DisableTranslation, // virtual address translation disabled during D$ flush and HPTW walk that use physical addresses
input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW input logic [P.XLEN+1:0] VAdr, // virtual/physical address from IEU or physical address from HPTW
input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits input logic [1:0] Size, // access size: 00 = 8 bits, 01 = 16 bits, 10 = 32 bits , 11 = 64 bits
input logic [P.XLEN-1:0] PTE, // page table entry input logic [P.XLEN-1:0] PTE, // page table entry
input logic [1:0] PageTypeWriteVal, // page type input logic [1:0] PageTypeWriteVal, // page type
input logic TLBWrite, // write TLB entry input logic TLBWrite, // write TLB entry
input logic TLBFlush, // Invalidate all TLB entries input logic TLBFlush, // Invalidate all TLB entries
output logic [P.PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation output logic [P.PA_BITS-1:0] PhysicalAddress, // PAdr when no translation, or translated VAdr (TLBPAdr) when there is translation
output logic TLBMiss, // Miss TLB output logic TLBMiss, // Miss TLB
output logic Cacheable, // PMA indicates memory address is cachable output logic Cacheable, // PMA indicates memory address is cachable
output logic Idempotent, // PMA indicates memory address is idempotent output logic Idempotent, // PMA indicates memory address is idempotent
output logic SelTIM, // Select a tightly integrated memory output logic SelTIM, // Select a tightly integrated memory
// Faults // Faults
output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM, // access fault sources output logic InstrAccessFaultF, LoadAccessFaultM, StoreAmoAccessFaultM, // access fault sources
output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM, // page fault sources output logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM, // page fault sources
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 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
); );
logic [P.PA_BITS-1:0] TLBPAdr; // physical address for TLB logic [P.PA_BITS-1:0] TLBPAdr; // physical address for TLB
logic PMAInstrAccessFaultF; // Instruction access fault from PMA logic PMAInstrAccessFaultF; // Instruction access fault from PMA
logic PMPInstrAccessFaultF; // Instruction access fault from PMP logic PMPInstrAccessFaultF; // Instruction access fault from PMP
logic PMALoadAccessFaultM; // Load access fault from PMA logic PMALoadAccessFaultM; // Load access fault from PMA
logic PMPLoadAccessFaultM; // Load access fault from PMP logic PMPLoadAccessFaultM; // Load access fault from PMP
logic PMAStoreAmoAccessFaultM; // Store or AMO access fault from PMA logic PMAStoreAmoAccessFaultM; // Store or AMO access fault from PMA
logic PMPStoreAmoAccessFaultM; // Store or AMO access fault from PMP logic PMPStoreAmoAccessFaultM; // Store or AMO access fault from PMP
logic DataMisalignedM; // load or store misaligned logic DataMisalignedM; // load or store misaligned
logic Translate; // Translation occurs when virtual memory is active and DisableTranslation is off logic Translate; // Translation occurs when virtual memory is active and DisableTranslation is off
logic TLBHit; // Hit in TLB logic TLBHit; // Hit in TLB
logic TLBPageFault; // Page fault from TLB logic TLBPageFault; // Page fault from TLB
logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults logic ReadNoAmoAccessM; // Read that is not part of atomic operation causes Load faults. Otherwise StoreAmo faults
// only instantiate TLB if Virtual Memory is supported // only instantiate TLB if Virtual Memory is supported
if (P.VIRTMEM_SUPPORTED) begin:tlb if (P.VIRTMEM_SUPPORTED) begin:tlb
@ -86,9 +86,9 @@ module mmu import cvw::*; #(parameter cvw_t P,
.TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit, .TLBWrite, .TLBFlush, .TLBPAdr, .TLBMiss, .TLBHit,
.Translate, .TLBPageFault, .UpdateDA); .Translate, .TLBPageFault, .UpdateDA);
end else begin:tlb // just pass address through as physical end else begin:tlb // just pass address through as physical
assign Translate = 0; assign Translate = 0;
assign TLBMiss = 0; assign TLBMiss = 0;
assign TLBHit = 1; // *** is this necessary assign TLBHit = 1; // *** is this necessary
assign TLBPageFault = 0; assign TLBPageFault = 0;
end end

View File

@ -30,26 +30,26 @@
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 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
input logic ReadAccessM, // Read access input logic ReadAccessM, // Read access
output logic Cacheable, Idempotent, SelTIM, output logic Cacheable, Idempotent, SelTIM,
output logic PMAInstrAccessFaultF, output logic PMAInstrAccessFaultF,
output logic PMALoadAccessFaultM, output logic PMALoadAccessFaultM,
output logic PMAStoreAmoAccessFaultM output logic PMAStoreAmoAccessFaultM
); );
logic PMAAccessFault; logic PMAAccessFault;
logic AccessRW, AccessRWX, AccessRX; logic AccessRW, AccessRWX, AccessRX;
logic [10:0] SelRegions; logic [10:0] SelRegions;
logic AtomicAllowed; logic AtomicAllowed;
// 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 AccessRWX = ReadAccessM | WriteAccessM | ExecuteAccessF; assign AccessRWX = ReadAccessM | WriteAccessM | ExecuteAccessF;
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, AccessRWX, Size, SelRegions); adrdecs #(P) adrdecs(PhysicalAddress, AccessRW, AccessRX, AccessRWX, Size, SelRegions);
@ -65,9 +65,8 @@ module pmachecker import cvw::*; #(parameter cvw_t P) (
assign SelTIM = SelRegions[10] | SelRegions[9]; // exclusion-tag: unused-tim assign SelTIM = SelRegions[10] | SelRegions[9]; // exclusion-tag: unused-tim
// Detect access faults // Detect access faults
assign PMAAccessFault = (SelRegions[0]) & AccessRWX | AtomicAccessM & ~AtomicAllowed; assign PMAAccessFault = (SelRegions[0]) & AccessRWX | AtomicAccessM & ~AtomicAllowed;
assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault; assign PMAInstrAccessFaultF = ExecuteAccessF & PMAAccessFault;
assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM & PMAAccessFault;
assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault; assign PMAStoreAmoAccessFaultM = WriteAccessM & PMAAccessFault;
endmodule endmodule

View File

@ -87,4 +87,3 @@ module pmpadrdec import cvw::*; #(parameter cvw_t P) (
// attempts an 8-byte access to 0x8, the access should fail (see page 60 of privileged specification 20211203). This // attempts an 8-byte access to 0x8, the access should fail (see page 60 of privileged specification 20211203). This
// implementation will not detect the failure. // implementation will not detect the failure.
endmodule endmodule

View File

@ -40,7 +40,7 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
// keyword, the compiler warns us that it's interpreting the signal as a var, // keyword, the compiler warns us that it's interpreting the signal as a var,
// which we might not intend. // which we might not intend.
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,
output logic PMPInstrAccessFaultF, output logic PMPInstrAccessFaultF,
output logic PMPLoadAccessFaultM, output logic PMPLoadAccessFaultM,
@ -48,11 +48,11 @@ module pmpchecker import cvw::*; #(parameter cvw_t P) (
); );
// Bit i is high when the address falls in PMP region i // Bit i is high when the address falls in PMP region i
logic EnforcePMP; // should PMP be checked in this privilege level logic EnforcePMP; // should PMP be checked in this privilege level
logic [P.PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges logic [P.PMP_ENTRIES-1:0] Match; // physical address matches one of the pmp ranges
logic [P.PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address. logic [P.PMP_ENTRIES-1:0] FirstMatch; // onehot encoding for the first pmpaddr to match the current address.
logic [P.PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set logic [P.PMP_ENTRIES-1:0] L, X, W, R; // PMP matches and has flag set
logic [P.PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i] logic [P.PMP_ENTRIES-1:0] PAgePMPAdr; // for TOR PMP matching, PhysicalAddress > PMPAdr[i]
if (P.PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0 if (P.PMP_ENTRIES > 0) begin: pmp // prevent complaints about array of no elements when PMP_ENTRIES = 0
pmpadrdec #(P) pmpadrdecs[P.PMP_ENTRIES-1:0]( pmpadrdec #(P) pmpadrdecs[P.PMP_ENTRIES-1:0](

View File

@ -29,100 +29,101 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module csr import cvw::*; #(parameter cvw_t P) ( module csr import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic FlushM, FlushW, input logic FlushM, FlushW,
input logic StallE, StallM, StallW, input logic StallE, StallM, StallW,
input logic [31:0] InstrM, // current instruction input logic [31:0] InstrM, // current instruction
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return logic input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return logic
input logic [P.XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU input logic [P.XLEN-1:0] SrcAM, IEUAdrM, // SrcA and memory address from IEU
input logic CSRReadM, CSRWriteM, // read or write CSR input logic CSRReadM, CSRWriteM, // read or write CSR
input logic TrapM, // trap is occurring input logic TrapM, // trap is occurring
input logic mretM, sretM, wfiM, // return or WFI instruction input logic mretM, sretM, wfiM, // return or WFI instruction
input logic IntPendingM, // at least one interrupt is pending and could occur if enabled input logic IntPendingM, // at least one interrupt is pending and could occur if enabled
input logic InterruptM, // interrupt is occurring input logic InterruptM, // interrupt is occurring
input logic ExceptionM, // interrupt is occurring input logic ExceptionM, // interrupt is occurring
input logic MTimerInt, // timer interrupt input logic MTimerInt, // timer interrupt
input logic MExtInt, SExtInt, // external interrupt (from PLIC) input logic MExtInt, SExtInt, // external interrupt (from PLIC)
input logic MSwInt, // software interrupt input logic MSwInt, // software interrupt
input logic [63:0] MTIME_CLINT, // TIME value from CLINT input logic [63:0] MTIME_CLINT, // TIME value from CLINT
input logic InstrValidM, // current instruction is valid input logic InstrValidM, // current instruction is valid
input logic FRegWriteM, // writes to floating point registers change STATUS.FS input logic FRegWriteM, // writes to floating point registers change STATUS.FS
input logic [4:0] SetFflagsM, // Set floating point flag bits in FCSR input logic [4:0] SetFflagsM, // Set floating point flag bits in FCSR
input logic [1:0] NextPrivilegeModeM, // STATUS bits updated based on next privilege mode input logic [1:0] NextPrivilegeModeM, // STATUS bits updated based on next privilege mode
input logic [1:0] PrivilegeModeW, // current privilege mode input logic [1:0] PrivilegeModeW, // current privilege mode
input logic [3:0] CauseM, // Trap cause input logic [3:0] CauseM, // Trap cause
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 StoreStallD,
input logic ICacheStallF, input logic ICacheStallF,
input logic DCacheStallM, input logic DCacheStallM,
input logic BPDirPredWrongM, input logic BPDirPredWrongM,
input logic BTAWrongM, input logic BTAWrongM,
input logic RASPredPCWrongM, input logic RASPredPCWrongM,
input logic IClassWrongM, input logic IClassWrongM,
input logic BPWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, input logic [3:0] InstrClassM,
input logic DCacheMiss, input logic DCacheMiss,
input logic DCacheAccess, input logic DCacheAccess,
input logic ICacheMiss, input logic ICacheMiss,
input logic ICacheAccess, input logic ICacheAccess,
input logic sfencevmaM, input logic sfencevmaM,
input logic InvalidateICacheM, input logic InvalidateICacheM,
input logic DivBusyE, // integer divide busy input logic DivBusyE, // integer divide busy
input logic FDivBusyE, // floating point divide busy input logic FDivBusyE, // floating point divide busy
// outputs from CSRs // outputs from CSRs
output logic [1:0] STATUS_MPP, output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TVM, output logic STATUS_SPP, STATUS_TSR, STATUS_TVM,
output logic [15:0] MEDELEG_REGW, output logic [15:0] MEDELEG_REGW,
output logic [P.XLEN-1:0] SATP_REGW, output logic [P.XLEN-1:0] SATP_REGW,
output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, output logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MIE, STATUS_SIE,
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW, output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TW,
output logic [1:0] STATUS_FS, output logic [1:0] STATUS_FS,
output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0],
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0], output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0],
output logic [2:0] FRM_REGW, output logic [2:0] FRM_REGW,
// //
output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR output logic [P.XLEN-1:0] CSRReadValW, // value read from CSR
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC, accounting for traps and returns
output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level output logic IllegalCSRAccessM, // Illegal CSR access: CSR doesn't exist or is inaccessible at this privilege level
output logic BigEndianM // memory access is big-endian based on privilege mode and STATUS register endian fields output logic BigEndianM // memory access is big-endian based on privilege mode and STATUS register endian fields
); );
localparam MIP = 12'h344; localparam MIP = 12'h344;
localparam SIP = 12'h144; localparam SIP = 12'h144;
logic [P.XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM; logic [P.XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM;
logic [P.XLEN-1:0] CSRReadValM; logic [P.XLEN-1:0] CSRReadValM;
logic [P.XLEN-1:0] CSRSrcM; logic [P.XLEN-1:0] CSRSrcM;
logic [P.XLEN-1:0] CSRRWM, CSRRSM, CSRRCM; logic [P.XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
logic [P.XLEN-1:0] CSRWriteValM; logic [P.XLEN-1:0] CSRWriteValM;
logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW; logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
logic [P.XLEN-1:0] STVEC_REGW, MTVEC_REGW; logic [P.XLEN-1:0] STVEC_REGW, MTVEC_REGW;
logic [P.XLEN-1:0] MEPC_REGW, SEPC_REGW; logic [P.XLEN-1:0] MEPC_REGW, SEPC_REGW;
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW; logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;
logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM; logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM;
logic CSRMWriteM, CSRSWriteM, CSRUWriteM; logic CSRMWriteM, CSRSWriteM, CSRUWriteM;
logic UngatedCSRMWriteM; logic UngatedCSRMWriteM;
logic WriteFRMM, WriteFFLAGSM; logic WriteFRMM, WriteFFLAGSM;
logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM; logic [P.XLEN-1:0] UnalignedNextEPCM, NextEPCM, NextMtvalM;
logic [4:0] NextCauseM; logic [4:0] NextCauseM;
logic [11:0] CSRAdrM; logic [11:0] CSRAdrM;
logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM; logic IllegalCSRCAccessM, IllegalCSRMAccessM, IllegalCSRSAccessM, IllegalCSRUAccessM;
logic InsufficientCSRPrivilegeM; logic InsufficientCSRPrivilegeM;
logic IllegalCSRMWriteReadonlyM; logic IllegalCSRMWriteReadonlyM;
logic [P.XLEN-1:0] CSRReadVal2M; logic [P.XLEN-1:0] CSRReadVal2M;
logic [11:0] MIP_REGW_writeable; logic [11:0] MIP_REGW_writeable;
logic [P.XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM; logic [P.XLEN-1:0] TVecM, TrapVectorM, NextFaultMtvalM;
logic MTrapM, STrapM; logic MTrapM, STrapM;
logic [P.XLEN-1:0] EPC; logic [P.XLEN-1:0] EPC;
logic RetM; logic RetM;
logic SelMtvecM; logic SelMtvecM;
logic [P.XLEN-1:0] TVecAlignedM; logic [P.XLEN-1:0] TVecAlignedM;
logic InstrValidNotFlushedM; logic InstrValidNotFlushedM;
logic STimerInt; logic STimerInt;
logic MENVCFG_STCE;
// only valid unflushed instructions can access CSRs // only valid unflushed instructions can access CSRs
assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW; assign InstrValidNotFlushedM = InstrValidM & ~StallW & ~FlushW;
@ -179,13 +180,13 @@ module csr import cvw::*; #(parameter cvw_t P) (
else CSRReadVal2M = CSRReadValM; else CSRReadVal2M = CSRReadValM;
// Compute AND/OR modification // Compute AND/OR modification
CSRRWM = CSRSrcM; CSRRWM = CSRSrcM;
CSRRSM = CSRReadVal2M | CSRSrcM; CSRRSM = CSRReadVal2M | CSRSrcM;
CSRRCM = CSRReadVal2M & ~CSRSrcM; CSRRCM = CSRReadVal2M & ~CSRSrcM;
case (InstrM[13:12]) case (InstrM[13:12])
2'b01: CSRWriteValM = CSRRWM; 2'b01: CSRWriteValM = CSRRWM;
2'b10: CSRWriteValM = CSRRSM; 2'b10: CSRWriteValM = CSRRSM;
2'b11: CSRWriteValM = CSRRCM; 2'b11: CSRWriteValM = CSRRCM;
default: CSRWriteValM = CSRReadValM; default: CSRWriteValM = CSRReadValM;
endcase endcase
end end
@ -213,7 +214,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
csri #(P) csri(.clk, .reset, csri #(P) csri(.clk, .reset,
.CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM, .CSRMWriteM, .CSRSWriteM, .CSRWriteValM, .CSRAdrM,
.MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt, .MExtInt, .SExtInt, .MTimerInt, .STimerInt, .MSwInt,
.MIDELEG_REGW, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable); .MIDELEG_REGW, .MENVCFG_STCE, .MIP_REGW, .MIE_REGW, .MIP_REGW_writeable);
csrsr #(P) csrsr(.clk, .reset, .StallW, csrsr #(P) csrsr(.clk, .reset, .StallW,
.WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM, .WriteMSTATUSM, .WriteMSTATUSHM, .WriteSSTATUSM,
@ -231,7 +232,8 @@ module csr import cvw::*; #(parameter cvw_t P) (
.MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW, .MEPC_REGW, .MCOUNTEREN_REGW, .MCOUNTINHIBIT_REGW,
.MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .MEDELEG_REGW, .MIDELEG_REGW,.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM, .MIP_REGW, .MIE_REGW, .WriteMSTATUSM, .WriteMSTATUSHM,
.IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM); .IllegalCSRMAccessM, .IllegalCSRMWriteReadonlyM,
.MENVCFG_STCE);
if (P.S_SUPPORTED) begin:csrs if (P.S_SUPPORTED) begin:csrs
@ -242,7 +244,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
.CSRWriteValM, .PrivilegeModeW, .CSRWriteValM, .PrivilegeModeW,
.CSRSReadValM, .STVEC_REGW, .SEPC_REGW, .CSRSReadValM, .STVEC_REGW, .SEPC_REGW,
.SCOUNTEREN_REGW, .SCOUNTEREN_REGW,
.SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, .SATP_REGW, .MIP_REGW, .MIE_REGW, .MIDELEG_REGW, .MTIME_CLINT, .MENVCFG_STCE,
.WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt); .WriteSSTATUSM, .IllegalCSRSAccessM, .STimerInt);
end else begin end else begin
assign WriteSSTATUSM = 0; assign WriteSSTATUSM = 0;
@ -266,7 +268,7 @@ module csr import cvw::*; #(parameter cvw_t P) (
assign IllegalCSRUAccessM = 1; assign IllegalCSRUAccessM = 1;
end end
if (P.ZICOUNTERS_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, .StoreStallD, .CSRWriteM, .CSRMWriteM,
.BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM, .BPDirPredWrongM, .BTAWrongM, .RASPredPCWrongM, .IClassWrongM, .BPWrongM,

View File

@ -1,5 +1,3 @@
/////////////////////////////////////////// ///////////////////////////////////////////
// csrc.sv // csrc.sv
// //
@ -31,57 +29,57 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module csrc import cvw::*; #(parameter cvw_t P) ( 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, StoreStallD,
input logic CSRMWriteM, CSRWriteM, input logic CSRMWriteM, CSRWriteM,
input logic BPDirPredWrongM, input logic BPDirPredWrongM,
input logic BTAWrongM, input logic BTAWrongM,
input logic RASPredPCWrongM, input logic RASPredPCWrongM,
input logic IClassWrongM, input logic IClassWrongM,
input logic BPWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, input logic [3:0] InstrClassM,
input logic DCacheMiss, input logic DCacheMiss,
input logic DCacheAccess, input logic DCacheAccess,
input logic ICacheMiss, input logic ICacheMiss,
input logic ICacheAccess, input logic ICacheAccess,
input logic ICacheStallF, input logic ICacheStallF,
input logic DCacheStallM, input logic DCacheStallM,
input logic sfencevmaM, input logic sfencevmaM,
input logic InterruptM, input logic InterruptM,
input logic ExceptionM, input logic ExceptionM,
input logic InvalidateICacheM, input logic InvalidateICacheM,
input logic DivBusyE, // integer divide busy input logic DivBusyE, // integer divide busy
input logic FDivBusyE, // floating point divide busy input logic FDivBusyE, // floating point divide busy
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
input logic [P.XLEN-1:0] CSRWriteValM, input logic [P.XLEN-1:0] CSRWriteValM,
input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW, input logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
output logic [P.XLEN-1:0] CSRCReadValM, output logic [P.XLEN-1:0] CSRCReadValM,
output logic IllegalCSRCAccessM output logic IllegalCSRCAccessM
); );
localparam MHPMCOUNTERBASE = 12'hB00; localparam MHPMCOUNTERBASE = 12'hB00;
localparam MTIME = 12'hB01; // this is a memory-mapped register; no such CSR exists, and access should faul; localparam MTIME = 12'hB01; // this is a memory-mapped register; no such CSR exists, and access should faul;
localparam MHPMCOUNTERHBASE = 12'hB80; localparam MHPMCOUNTERHBASE = 12'hB80;
localparam MTIMEH = 12'hB81; // this is a memory-mapped register; no such CSR exists, and access should fault localparam MTIMEH = 12'hB81; // this is a memory-mapped register; no such CSR exists, and access should fault
localparam MHPMEVENTBASE = 12'h320; localparam MHPMEVENTBASE = 12'h320;
localparam HPMCOUNTERBASE = 12'hC00; localparam HPMCOUNTERBASE = 12'hC00;
localparam HPMCOUNTERHBASE = 12'hC80; localparam HPMCOUNTERHBASE = 12'hC80;
localparam TIME = 12'hC01; localparam TIME = 12'hC01;
localparam TIMEH = 12'hC81; localparam TIMEH = 12'hC81;
logic [4:0] CounterNumM; logic [4:0] CounterNumM;
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 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];
logic [P.XLEN-1:0] NextHPMCOUNTERM[P.COUNTERS-1:0]; logic [P.XLEN-1:0] NextHPMCOUNTERM[P.COUNTERS-1:0];
genvar i; genvar i;
// Interface signals // Interface signals
@ -89,38 +87,38 @@ module csrc import cvw::*; #(parameter cvw_t P) (
flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, LoadStallM})); flopenrc #(2) LoadStallMReg(.clk, .reset, .clear(FlushM), .en(~StallM), .d({StoreStallE, LoadStallE}), .q({StoreStallM, 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
assign CounterEvent[1] = 1'b0; // Counter 1 doesn't exist assign CounterEvent[1] = 1'b0; // Counter 1 doesn't exist
assign CounterEvent[2] = InstrValidNotFlushedM; // MINSTRET instructions retired assign CounterEvent[2] = InstrValidNotFlushedM; // MINSTRET instructions retired
if(P.QEMU) begin: cevent // No other performance counters in QEMU if (P.ZIHPM_SUPPORTED) begin: cevent // User-defined counters
assign CounterEvent[P.COUNTERS-1:3] = 0; assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction
end else begin: cevent // User-defined counters assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions
assign CounterEvent[3] = InstrClassM[0] & InstrValidNotFlushedM; // branch instruction assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions
assign CounterEvent[4] = InstrClassM[1] & ~InstrClassM[2] & InstrValidNotFlushedM; // jump and not return instructions assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong
assign CounterEvent[5] = InstrClassM[2] & InstrValidNotFlushedM; // return instructions assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction
assign CounterEvent[6] = BPWrongM & InstrValidNotFlushedM; // branch predictor wrong assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target
assign CounterEvent[7] = BPDirPredWrongM & InstrValidNotFlushedM; // Branch predictor wrong direction assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address
assign CounterEvent[8] = BTAWrongM & InstrValidNotFlushedM; // branch predictor wrong target assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong
assign CounterEvent[9] = RASPredPCWrongM & InstrValidNotFlushedM; // return address stack wrong address assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed.
assign CounterEvent[10] = IClassWrongM & InstrValidNotFlushedM; // instruction class predictor wrong assign CounterEvent[12] = StoreStallM; // Store Stall
assign CounterEvent[11] = LoadStallM; // Load Stalls. don't want to suppress on flush as this only happens if flushed. assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access
assign CounterEvent[12] = StoreStallM; // Store Stall assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[13] = DCacheAccess & InstrValidNotFlushedM; // data cache access assign CounterEvent[15] = DCacheStallM; // d cache miss cycles
assign CounterEvent[14] = DCacheMiss; // data cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[16] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access
assign CounterEvent[15] = DCacheStallM; // d cache miss cycles assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss
assign CounterEvent[16] = ICacheAccess & InstrValidNotFlushedM; // instruction cache access assign CounterEvent[18] = ICacheStallF; // i cache miss cycles
assign CounterEvent[17] = ICacheMiss; // instruction cache miss. Miss asserted 1 cycle at start of cache miss assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes
assign CounterEvent[18] = ICacheStallF; // i cache miss cycles assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i
assign CounterEvent[19] = CSRWriteM & InstrValidNotFlushedM; // CSR writes assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma
assign CounterEvent[20] = InvalidateICacheM & InstrValidNotFlushedM; // fence.i assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low
assign CounterEvent[21] = sfencevmaM & InstrValidNotFlushedM; // sfence.vma assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low
assign CounterEvent[22] = InterruptM; // interrupt, InstrValidNotFlushedM will be low
assign CounterEvent[23] = ExceptionM; // exceptions, InstrValidNotFlushedM will be low
// coverage off // coverage off
// DivBusyE will never be assert high since this configuration uses the FPU to do integer division // DivBusyE will never be assert high since this configuration uses the FPU to do integer division
assign CounterEvent[24] = DivBusyE | FDivBusyE; // division cycles *** RT: might need to be delay until the next cycle assign CounterEvent[24] = DivBusyE | FDivBusyE; // division cycles *** RT: might need to be delay until the next cycle
// coverage on // coverage on
assign CounterEvent[P.COUNTERS-1:25] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions assign CounterEvent[P.COUNTERS-1:25] = 0; // eventually give these sources, including FP instructions, I$/D$ misses, branches and mispredictions
end else begin: cevent
assign CounterEvent[P.COUNTERS-1:3] = 0;
end end
// Counter update and write logic // Counter update and write logic
@ -158,14 +156,14 @@ module csrc import cvw::*; #(parameter cvw_t P) (
/* verilator lint_on WIDTH */ /* verilator lint_on WIDTH */
else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+P.COUNTERS & CSRAdrM != MTIME) else if (CSRAdrM >= MHPMCOUNTERBASE & CSRAdrM < MHPMCOUNTERBASE+P.COUNTERS & CSRAdrM != MTIME)
CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; CSRCReadValM = HPMCOUNTER_REGW[CounterNumM];
else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+P.COUNTERS) else if (CSRAdrM >= HPMCOUNTERBASE & CSRAdrM < HPMCOUNTERBASE+P.COUNTERS)
CSRCReadValM = HPMCOUNTER_REGW[CounterNumM]; CSRCReadValM = HPMCOUNTER_REGW[CounterNumM];
else begin else begin
CSRCReadValM = 0; CSRCReadValM = 0;
IllegalCSRCAccessM = 1; // requested CSR doesn't exist IllegalCSRCAccessM = 1; // requested CSR doesn't exist
end end
end else begin // 32-bit counter reads end else begin // 32-bit counter reads
// Veri lator doesn't realize this only occurs for XLEN=32 // Veril ator doesn't realize this only occurs for XLEN=32
/* verilator lint_off WIDTH */ /* verilator lint_off WIDTH */
if (CSRAdrM == TIME) CSRCReadValM = MTIME_CLINT[31:0];// TIME register is a shadow of the memory-mapped MTIME from the CLINT if (CSRAdrM == TIME) CSRCReadValM = MTIME_CLINT[31:0];// TIME register is a shadow of the memory-mapped MTIME from the CLINT
else if (CSRAdrM == TIMEH) CSRCReadValM = MTIME_CLINT[63:32]; else if (CSRAdrM == TIMEH) CSRCReadValM = MTIME_CLINT[63:32];
@ -189,4 +187,4 @@ module csrc import cvw::*; #(parameter cvw_t P) (
end end
endmodule endmodule
// mounteren should only exist if u-mode exists // mounteren should only exist if u-mode exists

View File

@ -30,10 +30,11 @@
module csri import cvw::*; #(parameter cvw_t P) ( module csri import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic CSRMWriteM, CSRSWriteM, input logic CSRMWriteM, CSRSWriteM,
input logic [P.XLEN-1:0] CSRWriteValM, input logic [P.XLEN-1:0] CSRWriteValM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt, input logic MExtInt, SExtInt, MTimerInt, STimerInt, MSwInt,
input logic [11:0] MIDELEG_REGW, input logic [11:0] MIDELEG_REGW,
input logic MENVCFG_STCE,
output logic [11:0] MIP_REGW, MIE_REGW, output logic [11:0] MIP_REGW, MIE_REGW,
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0 output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
); );
@ -60,7 +61,7 @@ module csri import cvw::*; #(parameter cvw_t P) (
if (P.S_SUPPORTED) begin:mask if (P.S_SUPPORTED) begin:mask
if (P.SSTC_SUPPORTED) begin if (P.SSTC_SUPPORTED) begin
assign MIP_WRITE_MASK = 12'h202; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec) assign MIP_WRITE_MASK = 12'h202; // SEIP and SSIP are writable, but STIP is not writable when STIMECMP is implemented (see SSTC spec)
assign STIP = STimerInt; assign STIP = MENVCFG_STCE ? STimerInt : MIP_REGW_writeable[5];
end else begin end else begin
assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9) assign MIP_WRITE_MASK = 12'h222; // SEIP, STIP, SSIP are writeable in MIP (20210108-draft 3.1.9)
assign STIP = MIP_REGW_writeable[5]; assign STIP = MIP_REGW_writeable[5];
@ -81,7 +82,6 @@ module csri import cvw::*; #(parameter cvw_t P) (
else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields else if (WriteMIEM) MIE_REGW <= (CSRWriteValM[11:0] & MIE_WRITE_MASK); // MIE controls M and S fields
else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222 & MIDELEG_REGW) | (MIE_REGW & 12'h888); // only S fields else if (WriteSIEM) MIE_REGW <= (CSRWriteValM[11:0] & 12'h222 & MIDELEG_REGW) | (MIE_REGW & 12'h888); // only S fields
assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0, assign MIP_REGW = {MExtInt, 1'b0, SExtInt|MIP_REGW_writeable[9], 1'b0,
MTimerInt, 1'b0, STIP, 1'b0, MTimerInt, 1'b0, STIP, 1'b0,
MSwInt, 1'b0, MIP_REGW_writeable[1], 1'b0}; MSwInt, 1'b0, MIP_REGW_writeable[1], 1'b0};

View File

@ -32,67 +32,74 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module csrm import cvw::*; #(parameter cvw_t P) ( module csrm import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic UngatedCSRMWriteM, CSRMWriteM, MTrapM, input logic UngatedCSRMWriteM, CSRMWriteM, MTrapM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [P.XLEN-1:0] NextEPCM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW, input logic [P.XLEN-1:0] NextEPCM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
input logic [4:0] NextCauseM, input logic [4:0] NextCauseM,
input logic [P.XLEN-1:0] CSRWriteValM, input logic [P.XLEN-1:0] CSRWriteValM,
input logic [11:0] MIP_REGW, MIE_REGW, input logic [11:0] MIP_REGW, MIE_REGW,
output logic [P.XLEN-1:0] CSRMReadValM, MTVEC_REGW, output logic [P.XLEN-1:0] CSRMReadValM, MTVEC_REGW,
output logic [P.XLEN-1:0] MEPC_REGW, output logic [P.XLEN-1:0] MEPC_REGW,
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW, output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
output logic [15:0] MEDELEG_REGW, output logic [15:0] MEDELEG_REGW,
output logic [11:0] MIDELEG_REGW, output logic [11:0] MIDELEG_REGW,
output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0],
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0],
output logic WriteMSTATUSM, WriteMSTATUSHM, output logic WriteMSTATUSM, WriteMSTATUSHM,
output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM output logic IllegalCSRMAccessM, IllegalCSRMWriteReadonlyM,
output logic MENVCFG_STCE
); );
logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW; logic [P.XLEN-1:0] MISA_REGW, MHARTID_REGW;
logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW; logic [P.XLEN-1:0] MSCRATCH_REGW, MTVAL_REGW, MCAUSE_REGW;
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM; logic [63:0] MENVCFG_REGW;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM; logic [P.XLEN-1:0] MENVCFGH_REGW;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM; logic [63:0] MENVCFG_PreWriteValM, MENVCFG_WriteValM;
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;
logic WriteMENVCFGM;
// Machine CSRs // Machine CSRs
localparam MVENDORID = 12'hF11; localparam MVENDORID = 12'hF11;
localparam MARCHID = 12'hF12; localparam MARCHID = 12'hF12;
localparam MIMPID = 12'hF13; localparam MIMPID = 12'hF13;
localparam MHARTID = 12'hF14; localparam MHARTID = 12'hF14;
localparam MCONFIGPTR = 12'hF15; localparam MCONFIGPTR = 12'hF15;
localparam MSTATUS = 12'h300; localparam MSTATUS = 12'h300;
localparam MISA_ADR = 12'h301; localparam MISA_ADR = 12'h301;
localparam MEDELEG = 12'h302; localparam MEDELEG = 12'h302;
localparam MIDELEG = 12'h303; localparam MIDELEG = 12'h303;
localparam MIE = 12'h304; localparam MIE = 12'h304;
localparam MTVEC = 12'h305; localparam MTVEC = 12'h305;
localparam MCOUNTEREN = 12'h306; localparam MCOUNTEREN = 12'h306;
localparam MSTATUSH = 12'h310; localparam MENVCFG = 12'h30A;
localparam MSTATUSH = 12'h310;
localparam MENVCFGH = 12'h31A;
localparam MCOUNTINHIBIT = 12'h320; localparam MCOUNTINHIBIT = 12'h320;
localparam MSCRATCH = 12'h340; localparam MSCRATCH = 12'h340;
localparam MEPC = 12'h341; localparam MEPC = 12'h341;
localparam MCAUSE = 12'h342; localparam MCAUSE = 12'h342;
localparam MTVAL = 12'h343; localparam MTVAL = 12'h343;
localparam MIP = 12'h344; localparam MIP = 12'h344;
localparam MTINST = 12'h34A; localparam MTINST = 12'h34A;
localparam PMPCFG0 = 12'h3A0; localparam PMPCFG0 = 12'h3A0;
// .. up to 15 more at consecutive addresses // .. up to 15 more at consecutive addresses
localparam PMPADDR0 = 12'h3B0; localparam PMPADDR0 = 12'h3B0;
// ... up to 63 more at consecutive addresses // ... up to 63 more at consecutive addresses
localparam TSELECT = 12'h7A0; localparam TSELECT = 12'h7A0;
localparam TDATA1 = 12'h7A1; localparam TDATA1 = 12'h7A1;
localparam TDATA2 = 12'h7A2; localparam TDATA2 = 12'h7A2;
localparam TDATA3 = 12'h7A3; localparam TDATA3 = 12'h7A3;
localparam DCSR = 12'h7B0; localparam DCSR = 12'h7B0;
localparam DPC = 12'h7B1; localparam DPC = 12'h7B1;
localparam DSCRATCH0 = 12'h7B2; localparam DSCRATCH0 = 12'h7B2;
localparam DSCRATCH1 = 12'h7B3; localparam DSCRATCH1 = 12'h7B3;
// Constants // Constants
localparam ZERO = {(P.XLEN){1'b0}}; localparam ZERO = {(P.XLEN){1'b0}};
localparam MEDELEG_MASK = 16'hB3FF; localparam MEDELEG_MASK = 16'hB3FF;
localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable localparam MIDELEG_MASK = 12'h222; // we choose to not make machine interrupts delegable
// There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop // There are PMP_ENTRIES = 0, 16, or 64 PMPADDR registers, each of which has its own flop
genvar i; genvar i;
@ -130,16 +137,17 @@ module csrm import cvw::*; #(parameter cvw_t P) (
assign MHARTID_REGW = 0; assign MHARTID_REGW = 0;
// Write machine Mode CSRs // Write machine Mode CSRs
assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS); assign WriteMSTATUSM = CSRMWriteM & (CSRAdrM == MSTATUS);
assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH)& (P.XLEN==32); assign WriteMSTATUSHM = CSRMWriteM & (CSRAdrM == MSTATUSH) & (P.XLEN==32);
assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC); assign WriteMTVECM = CSRMWriteM & (CSRAdrM == MTVEC);
assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG); assign WriteMEDELEGM = CSRMWriteM & (CSRAdrM == MEDELEG);
assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG); assign WriteMIDELEGM = CSRMWriteM & (CSRAdrM == MIDELEG);
assign WriteMSCRATCHM = CSRMWriteM & (CSRAdrM == MSCRATCH); assign WriteMSCRATCHM = CSRMWriteM & (CSRAdrM == MSCRATCH);
assign WriteMEPCM = MTrapM | (CSRMWriteM & (CSRAdrM == MEPC)); assign WriteMEPCM = MTrapM | (CSRMWriteM & (CSRAdrM == MEPC));
assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE)); assign WriteMCAUSEM = MTrapM | (CSRMWriteM & (CSRAdrM == MCAUSE));
assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL)); assign WriteMTVALM = MTrapM | (CSRMWriteM & (CSRAdrM == MTVAL));
assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN); assign WriteMCOUNTERENM = CSRMWriteM & (CSRAdrM == MCOUNTEREN);
assign WriteMENVCFGM = CSRMWriteM & (CSRAdrM == MENVCFG);
assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT); assign WriteMCOUNTINHIBITM = CSRMWriteM & (CSRAdrM == MCOUNTINHIBIT);
assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID); assign IllegalCSRMWriteReadonlyM = UngatedCSRMWriteM & (CSRAdrM == MVENDORID | CSRAdrM == MARCHID | CSRAdrM == MIMPID | CSRAdrM == MHARTID);
@ -161,6 +169,39 @@ module csrm import cvw::*; #(parameter cvw_t P) (
flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW); flopenr #(32) MCOUNTERENreg(clk, reset, WriteMCOUNTERENM, CSRWriteValM[31:0], MCOUNTEREN_REGW);
end else assign MCOUNTEREN_REGW = '0; end else assign MCOUNTEREN_REGW = '0;
// MENVCFG is always 64 bits even for RV32
assign MENVCFG_WriteValM = {
MENVCFG_PreWriteValM[63] & P.SSTC_SUPPORTED,
MENVCFG_PreWriteValM[62] & P.SVPBMT_SUPPORTED,
54'b0,
MENVCFG_PreWriteValM[7] & P.ZICBOZ_SUPPORTED,
MENVCFG_PreWriteValM[6:4] & {3{P.ZICBOM_SUPPORTED}},
3'b0,
MENVCFG_PreWriteValM[0] & P.S_SUPPORTED & P.VIRTMEM_SUPPORTED
};
if (P.XLEN == 64) begin
assign MENVCFG_PreWriteValM = CSRWriteValM;
flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM, MENVCFG_REGW);
assign MENVCFGH_REGW = 0;
end else begin
logic WriteMENVCFGHM;
assign MENVCFG_PreWriteValM = {CSRWriteValM, CSRWriteValM};
assign WriteMENVCFGHM = CSRMWriteM & (CSRAdrM == MENVCFGH) & (P.XLEN==32);
flopenr #(P.XLEN) MENVCFGreg(clk, reset, WriteMENVCFGM, MENVCFG_WriteValM[31:0], MENVCFG_REGW[31:0]);
flopenr #(P.XLEN) MENVCFGHreg(clk, reset, WriteMENVCFGHM, MENVCFG_WriteValM[63:32], MENVCFG_REGW[63:32]);
assign MENVCFGH_REGW = MENVCFG_REGW[63:32];
end
// Extract bit fields
assign MENVCFG_STCE = MENVCFG_REGW[63];
// Uncomment these other fields when they are defined
// assign MENVCFG_PBMTE = MENVCFG_REGW[62];
// assign MENVCFG_CBZE = MENVCFG_REGW[7];
// assign MENVCFG_CBCFE = MENVCFG_REGW[6];
// assign MENVCFG_CBIE = MENVCFG_REGW[5:4];
// assign MENVCFG_FIOM = MENVCFG_REGW[0];
// Read machine mode CSRs // Read machine mode CSRs
// verilator lint_off WIDTH // verilator lint_off WIDTH
logic [5:0] entry; logic [5:0] entry;
@ -181,26 +222,28 @@ module csrm import cvw::*; #(parameter cvw_t P) (
end end
end end
else case (CSRAdrM) else case (CSRAdrM)
MISA_ADR: CSRMReadValM = MISA_REGW; MISA_ADR: CSRMReadValM = MISA_REGW;
MVENDORID: CSRMReadValM = 0; MVENDORID: CSRMReadValM = 0;
MARCHID: CSRMReadValM = 0; MARCHID: CSRMReadValM = 0;
MIMPID: CSRMReadValM = {{P.XLEN-12{1'b0}}, 12'h100}; // pipelined implementation MIMPID: CSRMReadValM = {{P.XLEN-12{1'b0}}, 12'h100}; // pipelined implementation
MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0 MHARTID: CSRMReadValM = MHARTID_REGW; // hardwired to 0
MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0 MCONFIGPTR: CSRMReadValM = 0; // hardwired to 0
MSTATUS: CSRMReadValM = MSTATUS_REGW; MSTATUS: CSRMReadValM = MSTATUS_REGW;
MSTATUSH: CSRMReadValM = MSTATUSH_REGW; MSTATUSH: CSRMReadValM = MSTATUSH_REGW;
MTVEC: CSRMReadValM = MTVEC_REGW; MTVEC: CSRMReadValM = MTVEC_REGW;
MEDELEG: CSRMReadValM = {{(P.XLEN-16){1'b0}}, MEDELEG_REGW}; MEDELEG: CSRMReadValM = {{(P.XLEN-16){1'b0}}, MEDELEG_REGW};
MIDELEG: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIDELEG_REGW}; MIDELEG: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIDELEG_REGW};
MIP: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIP_REGW}; MIP: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIP_REGW};
MIE: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIE_REGW}; MIE: CSRMReadValM = {{(P.XLEN-12){1'b0}}, MIE_REGW};
MSCRATCH: CSRMReadValM = MSCRATCH_REGW; MSCRATCH: CSRMReadValM = MSCRATCH_REGW;
MEPC: CSRMReadValM = MEPC_REGW; MEPC: CSRMReadValM = MEPC_REGW;
MCAUSE: CSRMReadValM = MCAUSE_REGW; MCAUSE: CSRMReadValM = MCAUSE_REGW;
MTVAL: CSRMReadValM = MTVAL_REGW; MTVAL: CSRMReadValM = MTVAL_REGW;
MTINST: CSRMReadValM = 0; // implemented as trivial zero MTINST: CSRMReadValM = 0; // implemented as trivial zero
MCOUNTEREN:CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW}; MCOUNTEREN: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTEREN_REGW};
MCOUNTINHIBIT:CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW}; MENVCFG: CSRMReadValM = MENVCFG_REGW[P.XLEN-1:0];
MENVCFGH: CSRMReadValM = MENVCFGH_REGW;
MCOUNTINHIBIT: CSRMReadValM = {{(P.XLEN-32){1'b0}}, MCOUNTINHIBIT_REGW};
default: begin default: begin
CSRMReadValM = 0; CSRMReadValM = 0;
@ -209,4 +252,4 @@ module csrm import cvw::*; #(parameter cvw_t P) (
endcase endcase
end end
// verilator lint_on WIDTH // verilator lint_on WIDTH
endmodule endmodule

View File

@ -29,61 +29,69 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module csrs import cvw::*; #(parameter cvw_t P) ( module csrs import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic CSRSWriteM, STrapM, input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [P.XLEN-1:0] NextEPCM, NextMtvalM, SSTATUS_REGW, input logic [P.XLEN-1:0] NextEPCM, NextMtvalM, SSTATUS_REGW,
input logic [4:0] NextCauseM, input logic [4:0] NextCauseM,
input logic STATUS_TVM, input logic STATUS_TVM,
input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear input logic MCOUNTEREN_TM, // TM bit (1) of MCOUNTEREN; cause illegal instruction when trying to access STIMECMP if clear
input logic [P.XLEN-1:0] CSRWriteValM, input logic [P.XLEN-1:0] CSRWriteValM,
input logic [1:0] PrivilegeModeW, input logic [1:0] PrivilegeModeW,
output logic [P.XLEN-1:0] CSRSReadValM, STVEC_REGW, output logic [P.XLEN-1:0] CSRSReadValM, STVEC_REGW,
output logic [P.XLEN-1:0] SEPC_REGW, output logic [P.XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW, output logic [31:0] SCOUNTEREN_REGW,
output logic [P.XLEN-1:0] SATP_REGW, output logic [P.XLEN-1:0] SATP_REGW,
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
output logic WriteSSTATUSM, input logic MENVCFG_STCE,
output logic IllegalCSRSAccessM, output logic WriteSSTATUSM,
output logic STimerInt output logic IllegalCSRSAccessM,
output logic STimerInt
); );
// Supervisor CSRs // Supervisor CSRs
localparam SSTATUS = 12'h100; localparam SSTATUS = 12'h100;
localparam SIE = 12'h104; localparam SIE = 12'h104;
localparam STVEC = 12'h105; localparam STVEC = 12'h105;
localparam SCOUNTEREN = 12'h106; localparam SCOUNTEREN = 12'h106;
localparam SSCRATCH = 12'h140; localparam SENVCFG = 12'h10A;
localparam SEPC = 12'h141; localparam SSCRATCH = 12'h140;
localparam SCAUSE = 12'h142; localparam SEPC = 12'h141;
localparam STVAL = 12'h143; localparam SCAUSE = 12'h142;
localparam SIP= 12'h144; localparam STVAL = 12'h143;
localparam STIMECMP = 12'h14D; localparam SIP = 12'h144;
localparam STIMECMPH = 12'h15D; localparam STIMECMP = 12'h14D;
localparam SATP = 12'h180; localparam STIMECMPH = 12'h15D;
localparam SATP = 12'h180;
// Constants // Constants
localparam ZERO = {(P.XLEN){1'b0}}; localparam ZERO = {(P.XLEN){1'b0}};
localparam SEDELEG_MASK = ~(ZERO | {{P.XLEN-3{1'b0}}, 3'b111} << 9); localparam SEDELEG_MASK = ~(ZERO | {{P.XLEN-3{1'b0}}, 3'b111} << 9);
logic WriteSTVECM; logic WriteSTVECM;
logic WriteSSCRATCHM, WriteSEPCM; logic WriteSSCRATCHM, WriteSEPCM;
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM; logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
logic WriteSTIMECMPM, WriteSTIMECMPHM; logic WriteSTIMECMPM, WriteSTIMECMPHM;
logic [P.XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW; logic WriteSENVCFGM;
logic [P.XLEN-1:0] SSCRATCH_REGW, STVAL_REGW, SCAUSE_REGW;
logic [P.XLEN-1:0] SENVCFG_REGW;
logic [P.XLEN-1:0] SENVCFG_WriteValM;
logic [63:0] STIMECMP_REGW; logic [63:0] STIMECMP_REGW;
// write enables // write enables
assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS); assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS);
assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC); assign WriteSTVECM = CSRSWriteM & (CSRAdrM == STVEC);
assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH); assign WriteSSCRATCHM = CSRSWriteM & (CSRAdrM == SSCRATCH);
assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC)); assign WriteSEPCM = STrapM | (CSRSWriteM & (CSRAdrM == SEPC));
assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE)); assign WriteSCAUSEM = STrapM | (CSRSWriteM & (CSRAdrM == SCAUSE));
assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL)); assign WriteSTVALM = STrapM | (CSRSWriteM & (CSRAdrM == STVAL));
assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM); assign WriteSATPM = CSRSWriteM & (CSRAdrM == SATP) & (PrivilegeModeW == P.M_MODE | ~STATUS_TVM);
assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN); assign WriteSCOUNTERENM = CSRSWriteM & (CSRAdrM == SCOUNTEREN);
assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == P.M_MODE | MCOUNTEREN_TM); assign WriteSENVCFGM = CSRSWriteM & (CSRAdrM == SENVCFG);
assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == P.M_MODE | MCOUNTEREN_TM) & (P.XLEN == 32); assign WriteSTIMECMPM = CSRSWriteM & (CSRAdrM == STIMECMP) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE));
assign WriteSTIMECMPHM = CSRSWriteM & (CSRAdrM == STIMECMPH) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM & MENVCFG_STCE)) & (P.XLEN == 32);
// CSRs // CSRs
flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW); flopenr #(P.XLEN) STVECreg(clk, reset, WriteSTVECM, {CSRWriteValM[P.XLEN-1:2], 1'b0, CSRWriteValM[0]}, STVEC_REGW);
@ -108,9 +116,27 @@ module csrs import cvw::*; #(parameter cvw_t P) (
// Supervisor timer interrupt logic // Supervisor timer interrupt logic
// Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs // Spec is a bit peculiar - Machine timer interrupts are produced in CLINT, while Supervisor timer interrupts are in CSRs
if (P.SSTC_SUPPORTED) if (P.SSTC_SUPPORTED)
assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison assign STimerInt = ({1'b0, MTIME_CLINT} >= {1'b0, STIMECMP_REGW}); // unsigned comparison
else else
assign STimerInt = 0; assign STimerInt = 0;
assign SENVCFG_WriteValM = {
{(P.XLEN-8){1'b0}},
CSRWriteValM[7] & P.ZICBOZ_SUPPORTED,
CSRWriteValM[6:4] & {3{P.ZICBOM_SUPPORTED}},
3'b0,
CSRWriteValM[0] & P.S_SUPPORTED & P.VIRTMEM_SUPPORTED
};
flopenr #(P.XLEN) SENVCFGreg(clk, reset, WriteSENVCFGM, SENVCFG_WriteValM, SENVCFG_REGW);
// Extract bit fields
// Uncomment these other fields when they are defined
// assign SENVCFG_PBMTE = SENVCFG_REGW[62];
// assign SENVCFG_CBZE = SENVCFG_REGW[7];
// assign SENVCFG_CBCFE = SENVCFG_REGW[6];
// assign SENVCFG_CBIE = SENVCFG_REGW[5:4];
// assign SENVCFG_FIOM = SENVCFG_REGW[0];
// CSR Reads // CSR Reads
always_comb begin:csrr always_comb begin:csrr
@ -130,12 +156,15 @@ module csrs import cvw::*; #(parameter cvw_t P) (
IllegalCSRSAccessM = 1; IllegalCSRSAccessM = 1;
end end
SCOUNTEREN:CSRSReadValM = {{(P.XLEN-32){1'b0}}, SCOUNTEREN_REGW}; SCOUNTEREN:CSRSReadValM = {{(P.XLEN-32){1'b0}}, SCOUNTEREN_REGW};
STIMECMP: if (P.SSTC_SUPPORTED & (PrivilegeModeW == P.M_MODE | MCOUNTEREN_TM)) CSRSReadValM = STIMECMP_REGW[P.XLEN-1:0]; SENVCFG: CSRSReadValM = SENVCFG_REGW;
STIMECMP: if (P.SSTC_SUPPORTED & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM && MENVCFG_STCE)))
CSRSReadValM = STIMECMP_REGW[P.XLEN-1:0];
else begin else begin
CSRSReadValM = 0; CSRSReadValM = 0;
IllegalCSRSAccessM = 1; IllegalCSRSAccessM = 1;
end end
STIMECMPH: if (P.SSTC_SUPPORTED & (P.XLEN == 32) & (PrivilegeModeW == P.M_MODE | MCOUNTEREN_TM)) CSRSReadValM[31:0] = STIMECMP_REGW[63:32]; STIMECMPH: if (P.SSTC_SUPPORTED & (P.XLEN == 32) & (PrivilegeModeW == P.M_MODE | (MCOUNTEREN_TM && MENVCFG_STCE)))
CSRSReadValM[31:0] = STIMECMP_REGW[63:32];
else begin // not supported for RV64 else begin // not supported for RV64
CSRSReadValM = 0; CSRSReadValM = 0;
IllegalCSRSAccessM = 1; IllegalCSRSAccessM = 1;
@ -146,4 +175,4 @@ module csrs import cvw::*; #(parameter cvw_t P) (
end end
endcase endcase
end end
endmodule endmodule

View File

@ -4,7 +4,7 @@
// Written: David_Harris@hmc.edu 9 January 2021 // Written: David_Harris@hmc.edu 9 January 2021
// Modified: // Modified:
// //
// Purpose: Status register // Purpose: Status register (and environment configuration register and others shared across modes)
// See RISC-V Privileged Mode Specification 20190608 // See RISC-V Privileged Mode Specification 20190608
// //
// Documentation: RISC-V System on Chip Design Chapter 5 // Documentation: RISC-V System on Chip Design Chapter 5
@ -28,22 +28,22 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module csrsr import cvw::*; #(parameter cvw_t P) ( module csrsr import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, StallW, input logic clk, reset, StallW,
input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM, input logic WriteMSTATUSM, WriteMSTATUSHM, WriteSSTATUSM,
input logic TrapM, FRegWriteM, input logic TrapM, FRegWriteM,
input logic [1:0] NextPrivilegeModeM, PrivilegeModeW, input logic [1:0] NextPrivilegeModeM, PrivilegeModeW,
input logic mretM, sretM, input logic mretM, sretM,
input logic WriteFRMM, WriteFFLAGSM, input logic WriteFRMM, WriteFFLAGSM,
input logic [P.XLEN-1:0] CSRWriteValM, input logic [P.XLEN-1:0] CSRWriteValM,
input logic SelHPTW, input logic SelHPTW,
output logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW, output logic [P.XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW,
output logic [1:0] STATUS_MPP, output logic [1:0] STATUS_MPP,
output logic STATUS_SPP, STATUS_TSR, STATUS_TW, output logic STATUS_SPP, STATUS_TSR, STATUS_TW,
output logic STATUS_MIE, STATUS_SIE, output logic STATUS_MIE, STATUS_SIE,
output logic STATUS_MXR, STATUS_SUM, output logic STATUS_MXR, STATUS_SUM,
output logic STATUS_MPRV, STATUS_TVM, output logic STATUS_MPRV, STATUS_TVM,
output logic [1:0] STATUS_FS, output logic [1:0] STATUS_FS,
output logic BigEndianM output logic BigEndianM
); );
logic STATUS_SD, STATUS_TW_INT, STATUS_TSR_INT, STATUS_TVM_INT, STATUS_MXR_INT, STATUS_SUM_INT, STATUS_MPRV_INT; logic STATUS_SD, STATUS_TW_INT, STATUS_TSR_INT, STATUS_TVM_INT, STATUS_MXR_INT, STATUS_SUM_INT, STATUS_MPRV_INT;
@ -56,27 +56,27 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
// Lower privilege status registers are a subset of the full status register // Lower privilege status registers are a subset of the full status register
// *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable // *** consider adding MBE, SBE, UBE fields, parameterized to be fixed or adjustable
if (P.XLEN==64) begin: csrsr64 // RV64 if (P.XLEN==64) begin: csrsr64 // RV64
assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'b0, assign MSTATUS_REGW = {STATUS_SD, 25'b0, STATUS_MBE, STATUS_SBE, STATUS_SXL, STATUS_UXL, 9'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0,
STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; STATUS_MIE, 1'b0, STATUS_SIE, 1'b0};
assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ {P.QEMU ? 2'b0 : STATUS_UXL}, /*9'b0, */ 12'b0, assign SSTATUS_REGW = {STATUS_SD, /*27'b0, */ 29'b0, /*STATUS_SXL, */ {P.QEMU ? 2'b0 : STATUS_UXL}, /*9'b0, */ 12'b0,
/*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0, /*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0,
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be. assign MSTATUSH_REGW = '0; // *** does not exist when XLEN=64, but don't want it to have an undefined value. Spec is not clear what it should be.
end else begin: csrsr32 // RV32 end else begin: csrsr32 // RV32
assign MSTATUS_REGW = {STATUS_SD, 8'b0, assign MSTATUS_REGW = {STATUS_SD, 8'b0,
STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV, STATUS_TSR, STATUS_TW, STATUS_TVM, STATUS_MXR, STATUS_SUM, STATUS_MPRV,
STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0, STATUS_XS, STATUS_FS, STATUS_MPP, 2'b0,
STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_MIE, 1'b0, STATUS_SIE, 1'b0}; STATUS_SPP, STATUS_MPIE, STATUS_UBE, STATUS_SPIE, 1'b0, STATUS_MIE, 1'b0, STATUS_SIE, 1'b0};
assign MSTATUSH_REGW = {26'b0, STATUS_MBE, STATUS_SBE, 4'b0}; assign MSTATUSH_REGW = {26'b0, STATUS_MBE, STATUS_SBE, 4'b0};
assign SSTATUS_REGW = {STATUS_SD, 11'b0, assign SSTATUS_REGW = {STATUS_SD, 11'b0,
/*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0, /*STATUS_TSR, STATUS_TW, STATUS_TVM, */STATUS_MXR, STATUS_SUM, /* STATUS_MPRV, */ 1'b0,
STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0, STATUS_XS, STATUS_FS, /*STATUS_MPP, 2'b0*/ 4'b0,
STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE, STATUS_SPP, /*STATUS_MPIE*/ 1'b0, STATUS_UBE, STATUS_SPIE,
/*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0}; /*1'b0, STATUS_MIE, 1'b0*/ 3'b0, STATUS_SIE, 1'b0};
end end
@ -90,21 +90,21 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
end end
// harwired STATUS bits // harwired STATUS bits
assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_TSR = P.S_SUPPORTED & STATUS_TSR_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported assign STATUS_TW = (P.S_SUPPORTED | P.U_SUPPORTED) & STATUS_TW_INT; // override register with 0 if only machine mode supported
assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_TVM = P.S_SUPPORTED & STATUS_TVM_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_MXR = P.S_SUPPORTED & STATUS_MXR_INT; // override reigster with 0 if supervisor mode not supported
/* assign STATUS_UBE = 0; // little-endian /* assign STATUS_UBE = 0; // little-endian
assign STATUS_SBE = 0; // little-endian assign STATUS_SBE = 0; // little-endian
assign STATUS_MBE = 0; // little-endian */ assign STATUS_MBE = 0; // little-endian */
// SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not // SXL and UXL bits only matter for RV64. Set to 10 for RV64 if mode is supported, or 0 if not
assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported assign STATUS_SXL = P.S_SUPPORTED ? 2'b10 : 2'b00; // 10 if supervisor mode supported
assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported assign STATUS_UXL = P.U_SUPPORTED ? 2'b10 : 2'b00; // 10 if user mode supported
assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported assign STATUS_SUM = P.S_SUPPORTED & P.VIRTMEM_SUPPORTED & STATUS_SUM_INT; // override reigster with 0 if supervisor mode not supported
assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported assign STATUS_MPRV = P.U_SUPPORTED & STATUS_MPRV_INT; // override with 0 if user mode not supported
assign STATUS_FS = (P.S_SUPPORTED & (P.F_SUPPORTED | P.D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP assign STATUS_FS = (P.S_SUPPORTED & (P.F_SUPPORTED | P.D_SUPPORTED)) ? STATUS_FS_INT : 2'b00; // off if no FP
assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic assign STATUS_SD = (STATUS_FS == 2'b11) | (STATUS_XS == 2'b11); // dirty state logic
assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty assign STATUS_XS = 2'b00; // No additional user-mode state to be dirty
always_comb always_comb
if (CSRWriteValM[12:11] == P.U_MODE & P.U_SUPPORTED) STATUS_MPP_NEXT = P.U_MODE; if (CSRWriteValM[12:11] == P.U_MODE & P.U_SUPPORTED) STATUS_MPP_NEXT = P.U_MODE;
@ -122,14 +122,14 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
if (SelHPTW) EndiannessPrivMode = P.S_MODE; if (SelHPTW) EndiannessPrivMode = P.S_MODE;
//coverage off -item c 1 -feccondrow 1 //coverage off -item c 1 -feccondrow 1
// status.MPRV always gets reset upon leaving machine mode, so MPRV will never be high when out of machine mode // status.MPRV always gets reset upon leaving machine mode, so MPRV will never be high when out of machine mode
else if (PrivilegeModeW == P.M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP; else if (PrivilegeModeW == P.M_MODE & STATUS_MPRV) EndiannessPrivMode = STATUS_MPP;
//coverage on //coverage on
else EndiannessPrivMode = PrivilegeModeW; else EndiannessPrivMode = PrivilegeModeW;
case (EndiannessPrivMode) case (EndiannessPrivMode)
P.M_MODE: BigEndianM = STATUS_MBE; P.M_MODE: BigEndianM = STATUS_MBE;
P.S_MODE: BigEndianM = STATUS_SBE; P.S_MODE: BigEndianM = STATUS_SBE;
default: BigEndianM = STATUS_UBE; default: BigEndianM = STATUS_UBE;
endcase endcase
end end
end else begin: endianmux end else begin: endianmux
@ -140,22 +140,22 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
// complex register with reset, write enable, and the ability to update other bits in certain cases // complex register with reset, write enable, and the ability to update other bits in certain cases
always_ff @(posedge clk) //, posedge reset) always_ff @(posedge clk) //, posedge reset)
if (reset) begin if (reset) begin
STATUS_TSR_INT <= #1 0; STATUS_TSR_INT <= #1 0;
STATUS_TW_INT <= #1 0; STATUS_TW_INT <= #1 0;
STATUS_TVM_INT <= #1 0; STATUS_TVM_INT <= #1 0;
STATUS_MXR_INT <= #1 0; STATUS_MXR_INT <= #1 0;
STATUS_SUM_INT <= #1 0; STATUS_SUM_INT <= #1 0;
STATUS_MPRV_INT <= #1 0; // Per Priv 3.3 STATUS_MPRV_INT <= #1 0; // Per Priv 3.3
STATUS_FS_INT <= #1 P.F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED STATUS_FS_INT <= #1 P.F_SUPPORTED ? 2'b00 : 2'b00; // leave floating-point off until activated, even if F_SUPPORTED
STATUS_MPP <= #1 0; STATUS_MPP <= #1 0;
STATUS_SPP <= #1 0; STATUS_SPP <= #1 0;
STATUS_MPIE <= #1 0; STATUS_MPIE <= #1 0;
STATUS_SPIE <= #1 0; STATUS_SPIE <= #1 0;
STATUS_MIE <= #1 0; STATUS_MIE <= #1 0;
STATUS_SIE <= #1 0; STATUS_SIE <= #1 0;
STATUS_MBE <= #1 0; STATUS_MBE <= #1 0;
STATUS_SBE <= #1 0; STATUS_SBE <= #1 0;
STATUS_UBE <= #1 0; STATUS_UBE <= #1 0;
end else if (~StallW) begin end else if (~StallW) begin
if (TrapM) begin if (TrapM) begin
// Update interrupt enables per Privileged Spec p. 21 // Update interrupt enables per Privileged Spec p. 21
@ -164,54 +164,54 @@ module csrsr import cvw::*; #(parameter cvw_t P) (
// Modes: 11 = Machine, 01 = Supervisor, 00 = User // Modes: 11 = Machine, 01 = Supervisor, 00 = User
if (NextPrivilegeModeM == P.M_MODE) begin if (NextPrivilegeModeM == P.M_MODE) begin
STATUS_MPIE <= #1 STATUS_MIE; STATUS_MPIE <= #1 STATUS_MIE;
STATUS_MIE <= #1 0; STATUS_MIE <= #1 0;
STATUS_MPP <= #1 PrivilegeModeW; STATUS_MPP <= #1 PrivilegeModeW;
end else begin // supervisor mode end else begin // supervisor mode
STATUS_SPIE <= #1 STATUS_SIE; STATUS_SPIE <= #1 STATUS_SIE;
STATUS_SIE <= #1 0; STATUS_SIE <= #1 0;
STATUS_SPP <= #1 PrivilegeModeW[0]; STATUS_SPP <= #1 PrivilegeModeW[0];
end end
end else if (mretM) begin // Privileged 3.1.6.1 end else if (mretM) begin // Privileged 3.1.6.1
STATUS_MIE <= #1 STATUS_MPIE; // restore global interrupt enable STATUS_MIE <= #1 STATUS_MPIE; // restore global interrupt enable
STATUS_MPIE <= #1 1; // STATUS_MPIE <= #1 1; //
STATUS_MPP <= #1 P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level STATUS_MPP <= #1 P.U_SUPPORTED ? P.U_MODE : P.M_MODE; // set MPP to lowest supported privilege level
STATUS_MPRV_INT <= #1 STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec. STATUS_MPRV_INT <= #1 STATUS_MPRV_INT & (STATUS_MPP == P.M_MODE); // page 21 of privileged spec.
end else if (sretM) begin end else if (sretM) begin
STATUS_SIE <= #1 STATUS_SPIE; // restore global interrupt enable STATUS_SIE <= #1 STATUS_SPIE; // restore global interrupt enable
STATUS_SPIE <= #1 P.S_SUPPORTED; STATUS_SPIE <= #1 P.S_SUPPORTED;
STATUS_SPP <= #1 0; // set SPP to lowest supported privilege level to catch bugs STATUS_SPP <= #1 0; // set SPP to lowest supported privilege level to catch bugs
STATUS_MPRV_INT <= #1 0; // always clear MPRV STATUS_MPRV_INT <= #1 0; // always clear MPRV
end else if (WriteMSTATUSM) begin end else if (WriteMSTATUSM) begin
STATUS_TSR_INT <= #1 CSRWriteValM[22]; STATUS_TSR_INT <= #1 CSRWriteValM[22];
STATUS_TW_INT <= #1 CSRWriteValM[21]; STATUS_TW_INT <= #1 CSRWriteValM[21];
STATUS_TVM_INT <= #1 CSRWriteValM[20]; STATUS_TVM_INT <= #1 CSRWriteValM[20];
STATUS_MXR_INT <= #1 CSRWriteValM[19]; STATUS_MXR_INT <= #1 CSRWriteValM[19];
STATUS_SUM_INT <= #1 CSRWriteValM[18]; STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_MPRV_INT <= #1 CSRWriteValM[17]; STATUS_MPRV_INT <= #1 CSRWriteValM[17];
STATUS_FS_INT <= #1 CSRWriteValM[14:13]; STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_MPP <= #1 STATUS_MPP_NEXT; STATUS_MPP <= #1 STATUS_MPP_NEXT;
STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8]; STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8];
STATUS_MPIE <= #1 CSRWriteValM[7]; STATUS_MPIE <= #1 CSRWriteValM[7];
STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5]; STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5];
STATUS_MIE <= #1 CSRWriteValM[3]; STATUS_MIE <= #1 CSRWriteValM[3];
STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1]; STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED; STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
STATUS_MBE <= #1 nextMBE; STATUS_MBE <= #1 nextMBE;
STATUS_SBE <= #1 nextSBE; STATUS_SBE <= #1 nextSBE;
// coverage off // coverage off
// MSTATUSH only exists in 32-bit configurations, will not be hit on rv64gc // MSTATUSH only exists in 32-bit configurations, will not be hit on rv64gc
end else if (WriteMSTATUSHM) begin end else if (WriteMSTATUSHM) begin
STATUS_MBE <= #1 CSRWriteValM[5] & P.BIGENDIAN_SUPPORTED; STATUS_MBE <= #1 CSRWriteValM[5] & P.BIGENDIAN_SUPPORTED;
STATUS_SBE <= #1 CSRWriteValM[4] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED; STATUS_SBE <= #1 CSRWriteValM[4] & P.S_SUPPORTED & P.BIGENDIAN_SUPPORTED;
// coverage on // coverage on
end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits end else if (WriteSSTATUSM) begin // write a subset of the STATUS bits
STATUS_MXR_INT <= #1 CSRWriteValM[19]; STATUS_MXR_INT <= #1 CSRWriteValM[19];
STATUS_SUM_INT <= #1 CSRWriteValM[18]; STATUS_SUM_INT <= #1 CSRWriteValM[18];
STATUS_FS_INT <= #1 CSRWriteValM[14:13]; STATUS_FS_INT <= #1 CSRWriteValM[14:13];
STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8]; STATUS_SPP <= #1 P.S_SUPPORTED & CSRWriteValM[8];
STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5]; STATUS_SPIE <= #1 P.S_SUPPORTED & CSRWriteValM[5];
STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1]; STATUS_SIE <= #1 P.S_SUPPORTED & CSRWriteValM[1];
STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED; STATUS_UBE <= #1 CSRWriteValM[6] & P.U_SUPPORTED & P.BIGENDIAN_SUPPORTED;
end else if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #1 2'b11; end else if (FRegWriteM | WriteFRMM | WriteFFLAGSM) STATUS_FS_INT <= #1 2'b11;
end end
endmodule endmodule

View File

@ -27,40 +27,40 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module csru import cvw::*; #(parameter cvw_t P) ( module csru import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic InstrValidNotFlushedM, input logic InstrValidNotFlushedM,
input logic CSRUWriteM, input logic CSRUWriteM,
input logic [11:0] CSRAdrM, input logic [11:0] CSRAdrM,
input logic [P.XLEN-1:0] CSRWriteValM, input logic [P.XLEN-1:0] CSRWriteValM,
input logic [1:0] STATUS_FS, input logic [1:0] STATUS_FS,
output logic [P.XLEN-1:0] CSRUReadValM, output logic [P.XLEN-1:0] CSRUReadValM,
input logic [4:0] SetFflagsM, input logic [4:0] SetFflagsM,
output logic [2:0] FRM_REGW, output logic [2:0] FRM_REGW,
output logic WriteFRMM, WriteFFLAGSM, output logic WriteFRMM, WriteFFLAGSM,
output logic IllegalCSRUAccessM output logic IllegalCSRUAccessM
); );
localparam FFLAGS = 12'h001; localparam FFLAGS = 12'h001;
localparam FRM = 12'h002; localparam FRM = 12'h002;
localparam FCSR = 12'h003; localparam FCSR = 12'h003;
logic [4:0] FFLAGS_REGW; logic [4:0] FFLAGS_REGW;
logic [2:0] NextFRMM; logic [2:0] NextFRMM;
logic [4:0] NextFFLAGSM; logic [4:0] NextFFLAGSM;
logic SetOrWriteFFLAGSM; logic SetOrWriteFFLAGSM;
// Write enables // Write enables
assign WriteFRMM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FRM | CSRAdrM == FCSR); assign WriteFRMM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FRM | CSRAdrM == FCSR);
assign WriteFFLAGSM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FFLAGS | CSRAdrM == FCSR); assign WriteFFLAGSM = CSRUWriteM & (STATUS_FS != 2'b00) & (CSRAdrM == FFLAGS | CSRAdrM == FCSR);
// Write Values // Write Values
assign NextFRMM = (CSRAdrM == FCSR) ? CSRWriteValM[7:5] : CSRWriteValM[2:0]; assign NextFRMM = (CSRAdrM == FCSR) ? CSRWriteValM[7:5] : CSRWriteValM[2:0];
assign NextFFLAGSM = WriteFFLAGSM ? CSRWriteValM[4:0] : FFLAGS_REGW | SetFflagsM; assign NextFFLAGSM = WriteFFLAGSM ? CSRWriteValM[4:0] : FFLAGS_REGW | SetFflagsM;
assign SetOrWriteFFLAGSM = WriteFFLAGSM | (|SetFflagsM & InstrValidNotFlushedM); assign SetOrWriteFFLAGSM = WriteFFLAGSM | (|SetFflagsM & InstrValidNotFlushedM);
// CSRs // CSRs
flopenr #(3) FRMreg(clk, reset, WriteFRMM, NextFRMM, FRM_REGW); flopenr #(3) FRMreg(clk, reset, WriteFRMM, NextFRMM, FRM_REGW);
flopenr #(5) FFLAGSreg(clk, reset, SetOrWriteFFLAGSM, NextFFLAGSM, FFLAGS_REGW); flopenr #(5) FFLAGSreg(clk, reset, SetOrWriteFFLAGSM, NextFFLAGSM, FFLAGS_REGW);
// CSR Reads // CSR Reads
always_comb begin always_comb begin

View File

@ -28,91 +28,90 @@
/////////////////////////////////////////// ///////////////////////////////////////////
module privileged import cvw::*; #(parameter cvw_t P) ( module privileged import cvw::*; #(parameter cvw_t P) (
input logic clk, reset, input logic clk, reset,
input logic StallD, StallE, StallM, StallW, input logic StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW, input logic FlushD, FlushE, FlushM, FlushW,
// CSR Reads and Writes, and values needed for traps // CSR Reads and Writes, and values needed for traps
input logic CSRReadM, CSRWriteM, // Read or write CSRs input logic CSRReadM, CSRWriteM, // Read or write CSRs
input logic [P.XLEN-1:0] SrcAM, // GPR register to write input logic [P.XLEN-1:0] SrcAM, // GPR register to write
input logic [31:0] InstrM, // Instruction input logic [31:0] InstrM, // Instruction
input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL input logic [31:0] InstrOrigM, // Original compressed or uncompressed instruction in Memory stage for Illegal Instruction MTVAL
input logic [P.XLEN-1:0] IEUAdrM, // address from IEU input logic [P.XLEN-1:0] IEUAdrM, // address from IEU
input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic input logic [P.XLEN-1:0] PCM, PC2NextF, // program counter, next PC going to trap/return PC logic
// control signals // control signals
input logic InstrValidM, // Current instruction is valid (not flushed) input logic InstrValidM, // Current instruction is valid (not flushed)
input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt input logic CommittedM, CommittedF, // current instruction is using bus; don't interrupt
input logic PrivilegedM, // privileged instruction input logic PrivilegedM, // privileged instruction
// 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 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
input logic BTAWrongM, // branch predictor guessed wrong target input logic BTAWrongM, // branch predictor guessed wrong target
input logic RASPredPCWrongM, // return adddress stack guessed wrong target input logic RASPredPCWrongM, // return adddress stack guessed wrong target
input logic IClassWrongM, // branch predictor guessed wrong instruction class input logic IClassWrongM, // branch predictor guessed wrong instruction class
input logic BPWrongM, // branch predictor is wrong input logic BPWrongM, // branch predictor is wrong
input logic [3:0] InstrClassM, // actual instruction class input logic [3:0] InstrClassM, // actual instruction class
input logic DCacheMiss, // data cache miss input logic DCacheMiss, // data cache miss
input logic DCacheAccess, // data cache accessed (hit or miss) input logic DCacheAccess, // data cache accessed (hit or miss)
input logic ICacheMiss, // instruction cache miss input logic ICacheMiss, // instruction cache miss
input logic ICacheAccess, // instruction cache access input logic ICacheAccess, // instruction cache access
input logic DivBusyE, // integer divide busy input logic DivBusyE, // integer divide busy
input logic FDivBusyE, // floating point divide busy input logic FDivBusyE, // floating point divide busy
// fault sources // fault sources
input logic InstrAccessFaultF, // instruction access fault input logic InstrAccessFaultF, // instruction access fault
input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault input logic LoadAccessFaultM, StoreAmoAccessFaultM, // load or store access fault
input logic HPTWInstrAccessFaultF, // hardware page table access fault while fetching instruction PTE input logic HPTWInstrAccessFaultF, // hardware page table access fault while fetching instruction PTE
input logic InstrPageFaultF, // page faults input logic InstrPageFaultF, // page faults
input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults input logic LoadPageFaultM, StoreAmoPageFaultM, // page faults
input logic InstrMisalignedFaultM, // misaligned instruction fault input logic InstrMisalignedFaultM, // misaligned instruction fault
input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault input logic LoadMisalignedFaultM, StoreAmoMisalignedFaultM, // misaligned data fault
input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU input logic IllegalIEUFPUInstrD, // illegal instruction from IEU or FPU
input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources input logic MTimerInt, MExtInt, SExtInt, MSwInt, // interrupt sources
input logic [63:0] MTIME_CLINT, // timer value from CLINT input logic [63:0] MTIME_CLINT, // timer value from CLINT
input logic [4:0] SetFflagsM, // set FCSR flags from FPU input logic [4:0] SetFflagsM, // set FCSR flags from FPU
input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses input logic SelHPTW, // HPTW in use. Causes system to use S-mode endianness for accesses
// CSR outputs // CSR outputs
output logic [P.XLEN-1:0] CSRReadValW, // Value read from CSR output logic [P.XLEN-1:0] CSRReadValW, // Value read from CSR
output logic [1:0] PrivilegeModeW, // current privilege mode output logic [1:0] PrivilegeModeW, // current privilege mode
output logic [P.XLEN-1:0] SATP_REGW, // supervisor address translation register output logic [P.XLEN-1:0] SATP_REGW, // supervisor address translation register
output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits output logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // status register bits
output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits output logic [1:0] STATUS_MPP, STATUS_FS, // status register bits
output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration entries to MMU output var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0], // PMP configuration entries to MMU
output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU output var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW [P.PMP_ENTRIES-1:0], // PMP address entries to MMU
output logic [2:0] FRM_REGW, // FPU rounding mode output logic [2:0] FRM_REGW, // FPU rounding mode
// PC logic output in privileged unit // PC logic output in privileged unit
output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic output logic [P.XLEN-1:0] UnalignedPCNextF, // Next PC from trap/return PC logic
// control outputs // control outputs
output logic RetM, TrapM, // return instruction, or trap output logic RetM, TrapM, // return instruction, or trap
output logic sfencevmaM, // sfence.vma instruction output logic sfencevmaM, // sfence.vma instruction
input logic InvalidateICacheM, // fence instruction input logic InvalidateICacheM, // fence instruction
output logic BigEndianM, // Use big endian in current privilege mode output logic BigEndianM, // Use big endian in current privilege mode
// Fault outputs // Fault outputs
output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire output logic BreakpointFaultM, EcallFaultM, // breakpoint and Ecall traps should retire
output logic wfiM, IntPendingM // Stall in Memory stage for WFI until interrupt pending or timeout output logic wfiM, IntPendingM // Stall in Memory stage for WFI until interrupt pending or timeout
); );
logic [3:0] CauseM; // trap cause logic [3:0] CauseM; // trap cause
logic [15:0] MEDELEG_REGW; // exception delegation CSR logic [15:0] MEDELEG_REGW; // exception delegation CSR
logic [11:0] MIDELEG_REGW; // interrupt delegation CSR logic [11:0] MIDELEG_REGW; // interrupt delegation CSR
logic sretM, mretM; // supervisor / machine return instruction logic sretM, mretM; // supervisor / machine return instruction
logic IllegalCSRAccessM; // Illegal access to CSR logic IllegalCSRAccessM; // Illegal access to CSR
logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage logic IllegalIEUFPUInstrM; // Illegal IEU or FPU instruction, delayed to Mem stage
logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage logic InstrPageFaultM; // Instruction page fault, delayed to Mem stage
logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages logic InstrAccessFaultM; // Instruction access fault, delayed to Mem stages
logic IllegalInstrFaultM; // Illegal instruction fault logic IllegalInstrFaultM; // Illegal instruction fault
logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit logic STATUS_SPP, STATUS_TSR, STATUS_TW, STATUS_TVM; // Status bits needed within privileged unit
logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables logic STATUS_MIE, STATUS_SIE; // status bits: interrupt enables
logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits logic [11:0] MIP_REGW, MIE_REGW; // interrupt pending and enable bits
logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return logic [1:0] NextPrivilegeModeM; // next privilege mode based on trap or return
logic DelegateM; // trap should be delegated logic DelegateM; // trap should be delegated
logic InterruptM; // interrupt occuring logic InterruptM; // interrupt occuring
logic ExceptionM; // Memory stage instruction caused a fault logic ExceptionM; // Memory stage instruction caused a fault
logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE logic HPTWInstrAccessFaultM; // Hardware page table access fault while fetching instruction PTE
// track the current privilege level // track the current privilege level
privmode #(P) privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM, privmode #(P) privmode(.clk, .reset, .StallW, .TrapM, .mretM, .sretM, .DelegateM,
.STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW); .STATUS_MPP, .STATUS_SPP, .NextPrivilegeModeM, .PrivilegeModeW);
@ -156,8 +155,3 @@ module privileged import cvw::*; #(parameter cvw_t P) (
.InstrValidM, .CommittedM, .CommittedF, .InstrValidM, .CommittedM, .CommittedF,
.TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM); .TrapM, .RetM, .wfiM, .InterruptM, .ExceptionM, .IntPendingM, .DelegateM, .CauseM);
endmodule endmodule

View File

@ -43,10 +43,10 @@ module privmode import cvw::*; #(parameter cvw_t P) (
always_comb begin always_comb begin
if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8) if (TrapM) begin // Change privilege based on DELEG registers (see 3.1.8)
if (P.S_SUPPORTED & DelegateM) NextPrivilegeModeM = P.S_MODE; if (P.S_SUPPORTED & DelegateM) NextPrivilegeModeM = P.S_MODE;
else NextPrivilegeModeM = P.M_MODE; else NextPrivilegeModeM = P.M_MODE;
end else if (mretM) NextPrivilegeModeM = STATUS_MPP; end else if (mretM) NextPrivilegeModeM = STATUS_MPP;
else if (sretM) NextPrivilegeModeM = {1'b0, STATUS_SPP}; else if (sretM) NextPrivilegeModeM = {1'b0, STATUS_SPP};
else NextPrivilegeModeM = PrivilegeModeW; else NextPrivilegeModeM = PrivilegeModeW;
end end
flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, P.M_MODE, PrivilegeModeW); flopenl #(2) privmodereg(clk, reset, ~StallW, NextPrivilegeModeM, P.M_MODE, PrivilegeModeW);

View File

@ -63,13 +63,13 @@ module trap import cvw::*; #(parameter cvw_t P) (
assign MIntGlobalEnM = (PrivilegeModeW != P.M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9 assign MIntGlobalEnM = (PrivilegeModeW != P.M_MODE) | STATUS_MIE; // if M ints enabled or lower priv 3.1.9
assign SIntGlobalEnM = (PrivilegeModeW == P.U_MODE) | ((PrivilegeModeW == P.S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9 assign SIntGlobalEnM = (PrivilegeModeW == P.U_MODE) | ((PrivilegeModeW == P.S_MODE) & STATUS_SIE); // if in lower priv mode, or if S ints enabled and not in higher priv mode 3.1.9
assign PendingIntsM = MIP_REGW & MIE_REGW; assign PendingIntsM = MIP_REGW & MIE_REGW;
assign IntPendingM = |PendingIntsM; assign IntPendingM = |PendingIntsM;
assign Committed = CommittedM | CommittedF; assign Committed = CommittedM | CommittedF;
assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW); assign EnabledIntsM = ({12{MIntGlobalEnM}} & PendingIntsM & ~MIDELEG_REGW | {12{SIntGlobalEnM}} & PendingIntsM & MIDELEG_REGW);
assign ValidIntsM = {12{~Committed}} & EnabledIntsM; assign ValidIntsM = {12{~Committed}} & EnabledIntsM;
assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request. assign InterruptM = (|ValidIntsM) & InstrValidM; // suppress interrupt if the memory system has partially processed a request.
assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) & assign DelegateM = P.S_SUPPORTED & (InterruptM ? MIDELEG_REGW[CauseM] : MEDELEG_REGW[CauseM]) &
(PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE); (PrivilegeModeW == P.U_MODE | PrivilegeModeW == P.S_MODE);
/////////////////////////////////////////// ///////////////////////////////////////////
@ -88,7 +88,7 @@ module trap import cvw::*; #(parameter cvw_t P) (
LoadAccessFaultM | StoreAmoAccessFaultM; LoadAccessFaultM | StoreAmoAccessFaultM;
// coverage on // coverage on
assign TrapM = ExceptionM | InterruptM; assign TrapM = ExceptionM | InterruptM;
assign RetM = mretM | sretM; assign RetM = mretM | sretM;
/////////////////////////////////////////// ///////////////////////////////////////////
// Cause priority defined in table 3.7 of 20190608 privileged spec // Cause priority defined in table 3.7 of 20190608 privileged spec

View File

@ -27,27 +27,27 @@
module ahbapbbridge import cvw::*; #(parameter cvw_t P, module ahbapbbridge import cvw::*; #(parameter cvw_t P,
parameter PERIPHS = 2) ( parameter PERIPHS = 2) (
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic [PERIPHS-1:0] HSEL, input logic [PERIPHS-1:0] HSEL,
input logic [P.PA_BITS-1:0] HADDR, input logic [P.PA_BITS-1:0] HADDR,
input logic [P.XLEN-1:0] HWDATA, input logic [P.XLEN-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB, input logic [P.XLEN/8-1:0] HWSTRB,
input logic HWRITE, input logic HWRITE,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic HREADY, input logic HREADY,
// input logic [3:0] HPROT, // not used // input logic [3:0] HPROT, // not used
output logic [P.XLEN-1:0] HRDATA, output logic [P.XLEN-1:0] HRDATA,
output logic HRESP, HREADYOUT, output logic HRESP, HREADYOUT,
output logic PCLK, PRESETn, output logic PCLK, PRESETn,
output logic [PERIPHS-1:0] PSEL, output logic [PERIPHS-1:0] PSEL,
output logic PWRITE, output logic PWRITE,
output logic PENABLE, output logic PENABLE,
output logic [31:0] PADDR, output logic [31:0] PADDR,
output logic [P.XLEN-1:0] PWDATA, output logic [P.XLEN-1:0] PWDATA,
// output logic [2:0] PPROT, // not used // output logic [2:0] PPROT, // not used
output logic [P.XLEN/8-1:0] PSTRB, output logic [P.XLEN/8-1:0] PSTRB,
// output logic PWAKEUP // not used // output logic PWAKEUP // not used
input logic [PERIPHS-1:0] PREADY, input logic [PERIPHS-1:0] PREADY,
input var [PERIPHS-1:0][P.XLEN-1:0] PRDATA input var [PERIPHS-1:0][P.XLEN-1:0] PRDATA
); );
@ -56,15 +56,15 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P,
logic PREADYOUT; logic PREADYOUT;
// convert AHB to APB signals // convert AHB to APB signals
assign PCLK = HCLK; assign PCLK = HCLK;
assign PRESETn = HRESETn; assign PRESETn = HRESETn;
// identify start of a transaction // identify start of a transaction
assign initTrans = HTRANS[1] & HREADY; // start a transaction when the bus is ready and an active transaction is requested assign initTrans = HTRANS[1] & HREADY; // start a transaction when the bus is ready and an active transaction is requested
assign initTransSel = initTrans & |HSEL; // capture data and address if any of the peripherals are selected assign initTransSel = initTrans & |HSEL; // capture data and address if any of the peripherals are selected
// delay AHB Address phase signals to align with AHB Data phase because APB expects them at the same time // delay AHB Address phase signals to align with AHB Data phase because APB expects them at the same time
flopen #(32) addrreg(HCLK, HREADY, HADDR[31:0], PADDR); flopen #(32) addrreg(HCLK, HREADY, HADDR[31:0], PADDR);
flopenr #(1) writereg(HCLK, ~HRESETn, HREADY, HWRITE, PWRITE); flopenr #(1) writereg(HCLK, ~HRESETn, HREADY, HWRITE, PWRITE);
flopenr #(PERIPHS) selreg(HCLK, ~HRESETn, HREADY, HSEL & {PERIPHS{initTrans}}, PSEL); flopenr #(PERIPHS) selreg(HCLK, ~HRESETn, HREADY, HSEL & {PERIPHS{initTrans}}, PSEL);
// PPROT[2:0] = {Data/InstrB, Secure, Privileged}; // PPROT[2:0] = {Data/InstrB, Secure, Privileged};
@ -73,7 +73,7 @@ module ahbapbbridge import cvw::*; #(parameter cvw_t P,
// AHB Data phase signal doesn't need delay. Note that they are guaranteed to remain stable until READY is asserted // AHB Data phase signal doesn't need delay. Note that they are guaranteed to remain stable until READY is asserted
assign PWDATA = HWDATA; assign PWDATA = HWDATA;
assign PSTRB = HWSTRB; assign PSTRB = HWSTRB;
// enable logic: goes high a cycle after initTrans, then back low on cycle after desired PREADY is asserted // enable logic: goes high a cycle after initTrans, then back low on cycle after desired PREADY is asserted
// cycle1: AHB puts HADDR, HWRITE, HSEL on bus. initTrans is 1, and these are captured // cycle1: AHB puts HADDR, HWRITE, HSEL on bus. initTrans is 1, and these are captured
@ -103,4 +103,3 @@ assign HREADYOUT = PREADYOUT & ~initTransSelD; // don't raise HREADYOUT before a
// resp logic // resp logic
assign HRESP = 0; // bridge never indicates errors assign HRESP = 0; // bridge never indicates errors
endmodule endmodule

View File

@ -31,11 +31,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [15:0] PADDR, input logic [15:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
output logic [63:0] MTIME, output logic [63:0] MTIME,
output logic MTimerInt, MSwInt output logic MTimerInt, MSwInt
@ -48,11 +48,11 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
integer i, j; integer i, j;
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
// word aligned reads // word aligned reads
if (P.XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000}; if (P.XLEN==64) assign #2 entry = {PADDR[15:3], 3'b000};
else assign #2 entry = {PADDR[15:2], 2'b00}; else assign #2 entry = {PADDR[15:2], 2'b00};
// DH 2/20/21: Eventually allow MTIME to run off a separate clock // DH 2/20/21: Eventually allow MTIME to run off a separate clock
// This will require synchronizing MTIME to the system clock // This will require synchronizing MTIME to the system clock
@ -150,36 +150,36 @@ module clint_apb import cvw::*; #(parameter cvw_t P) (
endmodule endmodule
module timeregsync import cvw::*; #(parameter cvw_t P) ( module timeregsync import cvw::*; #(parameter cvw_t P) (
input logic clk, resetn, input logic clk, resetn,
input logic we0, we1, input logic we0, we1,
input logic [P.XLEN-1:0] wd, input logic [P.XLEN-1:0] wd,
output logic [63:0] q); output logic [63:0] q);
if (P.XLEN==64) if (P.XLEN==64)
always_ff @(posedge clk or negedge resetn) always_ff @(posedge clk or negedge resetn)
if (~resetn) q <= 0; if (~resetn) q <= 0;
else if (we0) q <= wd; else if (we0) q <= wd;
else q <= q + 1; else q <= q + 1;
else else
always_ff @(posedge clk or negedge resetn) always_ff @(posedge clk or negedge resetn)
if (~resetn) q <= 0; if (~resetn) q <= 0;
else if (we0) q[31:0] <= wd; else if (we0) q[31:0] <= wd;
else if (we1) q[63:32] <= wd; else if (we1) q[63:32] <= wd;
else q <= q + 1; else q <= q + 1;
endmodule endmodule
module timereg import cvw::*; #(parameter cvw_t P) ( module timereg import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, TIMECLK, input logic PCLK, PRESETn, TIMECLK,
input logic we0, we1, input logic we0, we1,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
output logic [63:0] MTIME, output logic [63:0] MTIME,
output logic done); output logic done);
// if (P.TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME // if (P.TIMEBASE_SYNC) begin:timereg // use PCLK for MTIME
if (1) begin:timereg // use PCLK for MTIME if (1) begin:timereg // use PCLK for MTIME
timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME)); timregsync timeregsync(.clk(PCLK), .resetn(PRESETn), .we0, .we1, .wd(PWDATA), .q(MTIME));
assign done = 1; // immediately completes assign done = 1; // immediately completes
end else begin // use asynchronous TIMECLK end else begin // use asynchronous TIMECLK
// TIME counter runs on TIMECLK but bus interface runs on PCLK // TIME counter runs on TIMECLK but bus interface runs on PCLK
// Need to synchronize reads and writes // Need to synchronize reads and writes
// This is subtle because synchronizing a binary counter on a per-bit basis could give a mix of old and new bits // This is subtle because synchronizing a binary counter on a per-bit basis could give a mix of old and new bits

View File

@ -29,78 +29,78 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module gpio_apb import cvw::*; #(parameter cvw_t P) ( module gpio_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [7:0] PADDR, input logic [7:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic [31:0] iof0, iof1, input logic [31:0] iof0, iof1,
input logic [31:0] GPIOIN, input logic [31:0] GPIOIN,
output logic [31:0] GPIOOUT, GPIOEN, output logic [31:0] GPIOOUT, GPIOEN,
output logic GPIOIntr output logic GPIOIntr
); );
logic [31:0] input0d, input1d, input2d, input3d; logic [31:0] input0d, input1d, input2d, input3d;
logic [31:0] input_val, input_en, output_en, output_val; logic [31:0] input_val, input_en, output_en, output_val;
logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip; logic [31:0] rise_ie, rise_ip, fall_ie, fall_ip, high_ie, high_ip, low_ie, low_ip;
logic [31:0] out_xor, iof_en, iof_sel, iof_out, gpio_out; logic [31:0] out_xor, iof_en, iof_sel, iof_out, gpio_out;
logic [7:0] entry; logic [7:0] entry;
logic [31:0] Din, Dout; logic [31:0] Din, Dout;
logic memwrite; logic memwrite;
// APB I/O // APB I/O
assign entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses assign entry = {PADDR[7:2],2'b00}; // 32-bit word-aligned accesses
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond assign PREADY = 1'b1; // GPIO never takes >1 cycle to respond
// account for subword read/write circuitry // account for subword read/write circuitry
// -- Note GPIO registers are 32 bits no matter what; access them with LW SW. // -- Note GPIO registers are 32 bits no matter what; access them with LW SW.
// (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported") // (At least that's what I think when FE310 spec says "only naturally aligned 32-bit accesses are supported")
if (P.XLEN == 64) begin if (P.XLEN == 64) begin
assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0]; assign Din = entry[2] ? PWDATA[63:32] : PWDATA[31:0];
assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout}; assign PRDATA = entry[2] ? {Dout,32'b0} : {32'b0,Dout};
end else begin // 32-bit end else begin // 32-bit
assign Din = PWDATA[31:0]; assign Din = PWDATA[31:0];
assign PRDATA = Dout; assign PRDATA = Dout;
end end
// register access // register access
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin // asynch reset if (~PRESETn) begin // asynch reset
input_en <= 0; input_en <= 0;
output_en <= 0; output_en <= 0;
// *** synch reset not yet implemented [DH: can we delete this comment? Check if a sync reset is required] // *** synch reset not yet implemented [DH: can we delete this comment? Check if a sync reset is required]
output_val <= #1 0; output_val <= #1 0;
rise_ie <= #1 0; rise_ie <= #1 0;
rise_ip <= #1 0; rise_ip <= #1 0;
fall_ie <= #1 0; fall_ie <= #1 0;
fall_ip <= #1 0; fall_ip <= #1 0;
high_ie <= #1 0; high_ie <= #1 0;
high_ip <= #1 0; high_ip <= #1 0;
low_ie <= #1 0; low_ie <= #1 0;
low_ip <= #1 0; low_ip <= #1 0;
iof_en <= #1 0; iof_en <= #1 0;
iof_sel <= #1 0; iof_sel <= #1 0;
out_xor <= #1 0; out_xor <= #1 0;
end else begin // writes end else begin // writes
// According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit. // According to FE310 spec: Once the interrupt is pending, it will remain set until a 1 is written to the *_ip register at that bit.
/* verilator lint_off CASEINCOMPLETE */ /* verilator lint_off CASEINCOMPLETE */
if (memwrite) if (memwrite)
case(entry) case(entry)
8'h04: input_en <= #1 Din; 8'h04: input_en <= #1 Din;
8'h08: output_en <= #1 Din; 8'h08: output_en <= #1 Din;
8'h0C: output_val <= #1 Din; 8'h0C: output_val <= #1 Din;
8'h18: rise_ie <= #1 Din; 8'h18: rise_ie <= #1 Din;
8'h20: fall_ie <= #1 Din; 8'h20: fall_ie <= #1 Din;
8'h28: high_ie <= #1 Din; 8'h28: high_ie <= #1 Din;
8'h30: low_ie <= #1 Din; 8'h30: low_ie <= #1 Din;
8'h38: iof_en <= #1 Din; 8'h38: iof_en <= #1 Din;
8'h3C: iof_sel <= #1 Din; 8'h3C: iof_sel <= #1 Din;
8'h40: out_xor <= #1 Din; 8'h40: out_xor <= #1 Din;
endcase endcase
/* verilator lint_on CASEINCOMPLETE */ /* verilator lint_on CASEINCOMPLETE */
@ -115,21 +115,21 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
else low_ip <= low_ip | ~input3d; else low_ip <= low_ip | ~input3d;
case(entry) // flop to sample inputs case(entry) // flop to sample inputs
8'h00: Dout <= #1 input_val; 8'h00: Dout <= #1 input_val;
8'h04: Dout <= #1 input_en; 8'h04: Dout <= #1 input_en;
8'h08: Dout <= #1 output_en; 8'h08: Dout <= #1 output_en;
8'h0C: Dout <= #1 output_val; 8'h0C: Dout <= #1 output_val;
8'h18: Dout <= #1 rise_ie; 8'h18: Dout <= #1 rise_ie;
8'h1C: Dout <= #1 rise_ip; 8'h1C: Dout <= #1 rise_ip;
8'h20: Dout <= #1 fall_ie; 8'h20: Dout <= #1 fall_ie;
8'h24: Dout <= #1 fall_ip; 8'h24: Dout <= #1 fall_ip;
8'h28: Dout <= #1 high_ie; 8'h28: Dout <= #1 high_ie;
8'h2C: Dout <= #1 high_ip; 8'h2C: Dout <= #1 high_ip;
8'h30: Dout <= #1 low_ie; 8'h30: Dout <= #1 low_ie;
8'h34: Dout <= #1 low_ip; 8'h34: Dout <= #1 low_ip;
8'h38: Dout <= #1 iof_en; 8'h38: Dout <= #1 iof_en;
8'h3C: Dout <= #1 iof_sel; 8'h3C: Dout <= #1 iof_sel;
8'h40: Dout <= #1 out_xor; 8'h40: Dout <= #1 out_xor;
default: Dout <= #1 0; default: Dout <= #1 0;
endcase endcase
end end
@ -137,18 +137,17 @@ module gpio_apb import cvw::*; #(parameter cvw_t P) (
// chip i/o // chip i/o
// connect OUT to IN for loopback testing // connect OUT to IN for loopback testing
if (P.GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en; if (P.GPIO_LOOPBACK_TEST) assign input0d = ((output_en & GPIOOUT) | (~output_en & GPIOIN)) & input_en;
else assign input0d = GPIOIN & input_en; else assign input0d = GPIOIN & input_en;
// synchroninzer for inputs // synchroninzer for inputs
flop #(32) sync1(PCLK,input0d,input1d); flop #(32) sync1(PCLK,input0d,input1d);
flop #(32) sync2(PCLK,input1d,input2d); flop #(32) sync2(PCLK,input1d,input2d);
flop #(32) sync3(PCLK,input2d,input3d); flop #(32) sync3(PCLK,input2d,input3d);
assign input_val = input3d; assign input_val = input3d;
assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0 assign iof_out = iof_sel & iof1 | ~iof_sel & iof0; // per-bit mux between iof1 and iof0
assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val assign gpio_out = iof_en & iof_out | ~iof_en & output_val; // per-bit mux between IOF and output_val
assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity assign GPIOOUT = gpio_out ^ out_xor; // per-bit flip output polarity
assign GPIOEN = output_en; assign GPIOEN = output_en;
assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)}; assign GPIOIntr = |{(rise_ip & rise_ie),(fall_ip & fall_ie),(high_ip & high_ie),(low_ip & low_ie)};
endmodule endmodule

View File

@ -41,22 +41,22 @@
// hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts // hardcoded to 2 contexts for now; later upgrade to arbitrary (up to 15872) contexts
module plic_apb import cvw::*; #(parameter cvw_t P) ( module plic_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [27:0] PADDR, input logic [27:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic UARTIntr,GPIOIntr, input logic UARTIntr,GPIOIntr,
output logic MExtInt, SExtInt output logic MExtInt, SExtInt
); );
logic memwrite, memread; logic memwrite, memread;
logic [23:0] entry; logic [23:0] entry;
logic [31:0] Din, Dout; logic [31:0] Din, Dout;
// context-independent signals // context-independent signals
logic [`N:1] requests; logic [`N:1] requests;
@ -78,9 +78,9 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
// ======= // =======
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this assign memread = ~PWRITE & PSEL; // read at start of access phase. PENABLE hasn't set up before this
assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond assign PREADY = 1'b1; // PLIC never takes >1 cycle to respond
assign entry = {PADDR[23:2],2'b0}; assign entry = {PADDR[23:2],2'b0};
// account for subword read/write circuitry // account for subword read/write circuitry
// -- Note PLIC registers are 32 bits no matter what; access them with LW SW. // -- Note PLIC registers are 32 bits no matter what; access them with LW SW.
@ -97,6 +97,7 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
// ================== // ==================
// Register Interface // Register Interface
// ================== // ==================
always @(posedge PCLK) begin always @(posedge PCLK) begin
// resetting // resetting
if (~PRESETn) begin if (~PRESETn) begin
@ -110,19 +111,19 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
casez(entry) casez(entry)
24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0]; 24'h0000??: intPriority[entry[7:2]] <= #1 Din[2:0];
`ifdef PLIC_NUM_SRC_LT_32 // eventually switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources `ifdef PLIC_NUM_SRC_LT_32 // eventually switch to a generate for loop so as to deprecate PLIC_NUM_SRC_LT_32 and allow up to 1023 sources
24'h002000: intEn[0][`N:1] <= #1 Din[`N:1]; 24'h002000: intEn[0][`N:1] <= #1 Din[`N:1];
24'h002080: intEn[1][`N:1] <= #1 Din[`N:1]; 24'h002080: intEn[1][`N:1] <= #1 Din[`N:1];
`endif `endif
`ifndef PLIC_NUM_SRC_LT_32 `ifndef PLIC_NUM_SRC_LT_32
24'h002000: intEn[0][31:1] <= #1 Din[31:1]; 24'h002000: intEn[0][31:1] <= #1 Din[31:1];
24'h002004: intEn[0][`N:32] <= #1 Din[31:0]; 24'h002004: intEn[0][`N:32] <= #1 Din[31:0];
24'h002080: intEn[1][31:1] <= #1 Din[31:1]; 24'h002080: intEn[1][31:1] <= #1 Din[31:1];
24'h002084: intEn[1][`N:32] <= #1 Din[31:0]; 24'h002084: intEn[1][`N:32] <= #1 Din[31:0];
`endif `endif
24'h200000: intThreshold[0] <= #1 Din[2:0]; 24'h200000: intThreshold[0] <= #1 Din[2:0];
24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion 24'h200004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion
24'h201000: intThreshold[1] <= #1 Din[2:0]; 24'h201000: intThreshold[1] <= #1 Din[2:0];
24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion 24'h201004: intInProgress <= #1 intInProgress & ~({{`N-1{1'b0}}, 1'b1} << (Din[5:0]-1)); // lower "InProgress" to signify completion
endcase endcase
// Read synchronously because a read can have side effect of changing intInProgress // Read synchronously because a read can have side effect of changing intInProgress
if (memread) begin if (memread) begin
@ -245,4 +246,3 @@ module plic_apb import cvw::*; #(parameter cvw_t P) (
assign MExtInt = |(threshMask[0] & priorities_with_irqs[0]); assign MExtInt = |(threshMask[0] & priorities_with_irqs[0]);
assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]); assign SExtInt = |(threshMask[1] & priorities_with_irqs[1]);
endmodule endmodule

View File

@ -30,33 +30,33 @@
module ram_ahb import cvw::*; #(parameter cvw_t P, module ram_ahb import cvw::*; #(parameter cvw_t P,
parameter BASE=0, RANGE = 65535) ( parameter BASE=0, RANGE = 65535) (
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic HSELRam, input logic HSELRam,
input logic [P.PA_BITS-1:0] HADDR, input logic [P.PA_BITS-1:0] HADDR,
input logic HWRITE, input logic HWRITE,
input logic HREADY, input logic HREADY,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic [P.XLEN-1:0] HWDATA, input logic [P.XLEN-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB, input logic [P.XLEN/8-1:0] HWSTRB,
output logic [P.XLEN-1:0] HREADRam, output logic [P.XLEN-1:0] HREADRam,
output logic HRESPRam, HREADYRam output logic HRESPRam, HREADYRam
); );
localparam ADDR_WIDTH = $clog2(RANGE/8); localparam ADDR_WIDTH = $clog2(RANGE/8);
localparam OFFSET = $clog2(P.XLEN/8); localparam OFFSET = $clog2(P.XLEN/8);
logic [P.XLEN/8-1:0] ByteMask; logic [P.XLEN/8-1:0] ByteMask;
logic [P.PA_BITS-1:0] HADDRD, RamAddr; logic [P.PA_BITS-1:0] HADDRD, RamAddr;
logic initTrans; logic initTrans;
logic memwrite, memwriteD, memread; logic memwrite, memwriteD, memread;
logic nextHREADYRam; logic nextHREADYRam;
logic DelayReady; logic DelayReady;
// a new AHB transactions starts when HTRANS requests a transaction, // a new AHB transactions starts when HTRANS requests a transaction,
// the peripheral is selected, and the previous transaction is completing // the peripheral is selected, and the previous transaction is completing
assign initTrans = HREADY & HSELRam & HTRANS[1] ; assign initTrans = HREADY & HSELRam & HTRANS[1] ;
assign memwrite = initTrans & HWRITE; assign memwrite = initTrans & HWRITE;
assign memread = initTrans & ~HWRITE; assign memread = initTrans & ~HWRITE;
flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD); flopenr #(1) memwritereg(HCLK, ~HRESETn, HREADY, memwrite, memwriteD);
flopenr #(P.PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD); flopenr #(P.PA_BITS) haddrreg(HCLK, ~HRESETn, HREADY, HADDR, HADDRD);
@ -74,7 +74,6 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
ram1p1rwbe #(.DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1), ram1p1rwbe #(.DEPTH(RANGE/8), .WIDTH(P.XLEN)) memory(.clk(HCLK), .ce(1'b1),
.addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam)); .addr(RamAddr[ADDR_WIDTH+OFFSET-1:OFFSET]), .we(memwriteD), .din(HWDATA), .bwe(HWSTRB), .dout(HREADRam));
// use this to add arbitrary latency to ram. Helps test AHB controller correctness // use this to add arbitrary latency to ram. Helps test AHB controller correctness
if(`RAM_LATENCY > 0) begin if(`RAM_LATENCY > 0) begin
logic [7:0] NextCycle, Cycle; logic [7:0] NextCycle, Cycle;
@ -89,15 +88,15 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
always_ff @(posedge HCLK) always_ff @(posedge HCLK)
if (~HRESETn) CurrState <= #1 READY; if (~HRESETn) CurrState <= #1 READY;
else CurrState <= #1 NextState; else CurrState <= #1 NextState;
always_comb begin always_comb begin
case(CurrState) case(CurrState)
READY: if(initTrans & ~CycleFlag) NextState = DELAY; READY: if(initTrans & ~CycleFlag) NextState = DELAY;
else NextState = READY; else NextState = READY;
DELAY: if(CycleFlag) NextState = READY; DELAY: if(CycleFlag) NextState = READY;
else NextState = DELAY; else NextState = DELAY;
default: NextState = READY; default: NextState = READY;
endcase endcase
end end
@ -110,4 +109,3 @@ module ram_ahb import cvw::*; #(parameter cvw_t P,
end end
endmodule endmodule

View File

@ -28,24 +28,23 @@
module rom_ahb import cvw::*; #(parameter cvw_t P, module rom_ahb import cvw::*; #(parameter cvw_t P,
parameter BASE=0, RANGE = 65535) ( parameter BASE=0, RANGE = 65535) (
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic HSELRom, input logic HSELRom,
input logic [P.PA_BITS-1:0] HADDR, input logic [P.PA_BITS-1:0] HADDR,
input logic HREADY, input logic HREADY,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
output logic [P.XLEN-1:0] HREADRom, output logic [P.XLEN-1:0] HREADRom,
output logic HRESPRom, HREADYRom output logic HRESPRom, HREADYRom
); );
localparam ADDR_WIDTH = $clog2(RANGE/8); localparam ADDR_WIDTH = $clog2(RANGE/8);
localparam OFFSET = $clog2(P.XLEN/8); localparam OFFSET = $clog2(P.XLEN/8);
// Never stalls // Never stalls
assign HREADYRom = 1'b1; assign HREADYRom = 1'b1;
assign HRESPRom = 0; // OK assign HRESPRom = 0; // OK
// single-ported ROM // single-ported ROM
rom1p1r #(ADDR_WIDTH, P.XLEN, P.FPGA) rom1p1r #(ADDR_WIDTH, P.XLEN, P.FPGA)
memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom)); memory(.clk(HCLK), .ce(1'b1), .addr(HADDR[ADDR_WIDTH+OFFSET-1:OFFSET]), .dout(HREADRom));
endmodule endmodule

View File

@ -45,7 +45,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines output logic INTR, TXRDYb, RXRDYb, // interrupt and ready lines
// Clocks // Clocks
output logic BAUDOUTb, // active low baud clock output logic BAUDOUTb, // active low baud clock
input logic RCLK, // usually BAUDOUTb tied to RCLK externally input logic RCLK, // usually BAUDOUTb tied to RCLK externally
// E1A Driver // E1A Driver
input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs input logic SIN, DSRb, DCDb, CTSb, RIb, // UART external serial and flow-control inputs
output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs output logic SOUT, RTSb, DTRb, OUT1b, OUT2b // UART external serial and flow-control outputs
@ -71,9 +71,9 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
logic DLAB; // Divisor Latch Access Bit (LCR bit 7) logic DLAB; // Divisor Latch Access Bit (LCR bit 7)
// Baud and rx/tx timing // Baud and rx/tx timing
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
logic [16+UART_PRESCALE-1:0] baudcount; logic [16+UART_PRESCALE-1:0] baudcount;
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16 logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
logic [3:0] rxbitsreceived, txbitssent; logic [3:0] rxbitsreceived, txbitssent;
statetype rxstate, txstate; statetype rxstate, txstate;
@ -122,6 +122,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// Input synchronization: 2-stage synchronizer // Input synchronization: 2-stage synchronizer
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK) begin always_ff @(posedge PCLK) begin
{SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb}; {SINd, DSRbd, DCDbd, CTSbd, RIbd} <= #1 {SIN, DSRb, DCDb, CTSb, RIb};
{SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} : {SINsync, DSRbsync, DCDbsync, CTSbsync, RIbsync} <= #1 loop ? {SOUTbit, ~MCR[0], ~MCR[3], ~MCR[1], ~MCR[2]} :
@ -132,6 +133,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// Register interface (Table 1, note some are read only and some write only) // Register interface (Table 1, note some are read only and some write only)
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin // Table 3 Reset Configuration if (~PRESETn) begin // Table 3 Reset Configuration
IER <= #1 4'b0; IER <= #1 4'b0;
@ -162,13 +164,13 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (~MEMWb & (A == 3'b101)) if (~MEMWb & (A == 3'b101))
LSR[6:1] <= #1 Din[6:1]; // recommended only for test, see 8.6.3 LSR[6:1] <= #1 Din[6:1]; // recommended only for test, see 8.6.3
else begin else begin
LSR[0] <= #1 rxdataready; // Data ready LSR[0] <= #1 rxdataready; // Data ready
LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error LSR[1] <= #1 (LSR[1] | RXBR[10]) & ~squashRXerrIP;; // overrun error
LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error LSR[2] <= #1 (LSR[2] | RXBR[9]) & ~squashRXerrIP; // parity error
LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error LSR[3] <= #1 (LSR[3] | RXBR[8]) & ~squashRXerrIP; // framing error
LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator LSR[4] <= #1 (LSR[4] | rxbreak) & ~squashRXerrIP; // break indicator
LSR[5] <= #1 THRE; // THRE LSR[5] <= #1 THRE; // THRE
LSR[6] <= #1 ~txsrfull & THRE; // TEMT LSR[6] <= #1 ~txsrfull & THRE; // TEMT
if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error if (rxfifohaserr) LSR[7] <= #1 1; // any bits in FIFO have error
end end
@ -208,6 +210,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// Ross Thompson: Found a bug. If the baud rate dividers DLM, and DLL are reloaded // Ross Thompson: Found a bug. If the baud rate dividers DLM, and DLL are reloaded
// the baudcount is not reset to {DLM, DLL, UART_PRESCALE} // the baudcount is not reset to {DLM, DLL, UART_PRESCALE}
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin if (~PRESETn) begin
baudcount <= #1 1; baudcount <= #1 1;
@ -233,17 +236,18 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
/////////////////////////////////////////// ///////////////////////////////////////////
// receive timing and control // receive timing and control
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin if (~PRESETn) begin
rxoversampledcnt <= #1 0; rxoversampledcnt <= #1 0;
rxstate <= #1 UART_IDLE; rxstate <= #1 UART_IDLE;
rxbitsreceived <= #1 0; rxbitsreceived <= #1 0;
rxtimeoutcnt <= #1 0; rxtimeoutcnt <= #1 0;
end else begin end else begin
if (rxstate == UART_IDLE & ~SINsync) begin // got start bit if (rxstate == UART_IDLE & ~SINsync) begin // got start bit
rxstate <= #1 UART_ACTIVE; rxstate <= #1 UART_ACTIVE;
rxoversampledcnt <= #1 0; rxoversampledcnt <= #1 0;
rxbitsreceived <= #1 0; rxbitsreceived <= #1 0;
if (~rxfifotimeout) rxtimeoutcnt <= #1 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf if (~rxfifotimeout) rxtimeoutcnt <= #1 0; // reset timeout when new character is arriving. Jacob Pease: Only if the timeout was not already reached. p.16 PC16550D.pdf
end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin end else if (rxbaudpulse & (rxstate == UART_ACTIVE)) begin
rxoversampledcnt <= #1 rxoversampledcnt + 1; // 16x oversampled counter rxoversampledcnt <= #1 rxoversampledcnt + 1; // 16x oversampled counter
@ -260,13 +264,14 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
// ***explain why // ***explain why
if(QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE if(QEMU) assign rxcentered = rxbaudpulse & (rxoversampledcnt[1:0] == 2'b10); // implies rxstate = UART_ACTIVE
else assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE else assign rxcentered = rxbaudpulse & (rxoversampledcnt == 4'b1000); // implies rxstate = UART_ACTIVE
assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit assign rxbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1; // start bit + data bits + (parity bit) + stop bit
/////////////////////////////////////////// ///////////////////////////////////////////
// receive shift register, buffer register, FIFO // receive shift register, buffer register, FIFO
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) rxshiftreg <= #1 10'b0000000001; // initialize so that there is a valid stop bit if (~PRESETn) rxshiftreg <= #1 10'b0000000001; // initialize so that there is a valid stop bit
else if (rxcentered) rxshiftreg <= #1 {rxshiftreg[8:0], SINsync}; // capture bit else if (rxcentered) rxshiftreg <= #1 {rxshiftreg[8:0], SINsync}; // capture bit
@ -282,11 +287,11 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
assign rxdata = LCR[3] ? rxdata9[7:0] : rxdata9[8:1]; // discard parity bit assign rxdata = LCR[3] ? rxdata9[7:0] : rxdata9[8:1]; // discard parity bit
// ERROR CONDITIONS // ERROR CONDITIONS
assign rxparity = ^rxdata; assign rxparity = ^rxdata;
assign rxparityerr = (rxparity ^ rxparitybit ^ ~evenparitysel) & LCR[3]; // Check even/odd parity (*** check if LCR needs to be inverted) assign rxparityerr = (rxparity ^ rxparitybit ^ ~evenparitysel) & LCR[3]; // Check even/odd parity (*** check if LCR needs to be inverted)
assign rxoverrunerr = fifoenabled ? (rxfifoentries == 15) : rxdataready; // overrun if FIFO or receive buffer register full assign rxoverrunerr = fifoenabled ? (rxfifoentries == 15) : rxdataready; // overrun if FIFO or receive buffer register full
assign rxframingerr = ~rxstopbit; // framing error if no stop bit assign rxframingerr = ~rxstopbit; // framing error if no stop bit
assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time assign rxbreak = rxframingerr & (rxdata9 == 9'b0); // break when 0 for start + data + parity + stop time
// receive FIFO and register // receive FIFO and register
always_ff @(posedge PCLK) always_ff @(posedge PCLK)
@ -298,7 +303,7 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
end else if (rxstate == UART_DONE) begin end else if (rxstate == UART_DONE) begin
RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register RXBR <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; // load recevive buffer register
if (rxoverrunerr) $warning("UART RX Overrun Err\n"); if (rxoverrunerr) $warning("UART RX Overrun Err\n");
if (rxparityerr) $warning("UART RX Parity Err\n"); if (rxparityerr) $warning("UART RX Parity Err\n");
if (rxframingerr) $warning("UART RX Framing Err\n"); if (rxframingerr) $warning("UART RX Framing Err\n");
if (fifoenabled) begin if (fifoenabled) begin
rxfifo[rxfifohead] <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata}; rxfifo[rxfifohead] <= #1 {rxoverrunerr, rxparityerr, rxframingerr, rxdata};
@ -339,14 +344,14 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
else assign rxfullbitunwrapped[i] = ({1'b0,rxfifohead}==i | rxfullbitunwrapped[i-1]) & (rxfifotailunwrapped != i); else assign rxfullbitunwrapped[i] = ({1'b0,rxfifohead}==i | rxfullbitunwrapped[i-1]) & (rxfifotailunwrapped != i);
end end
for (i=0; i<16; i++) begin:rx for (i=0; i<16; i++) begin:rx
assign RXerrbit[i] = |rxfifo[i][10:8]; // are any of the error conditions set? assign RXerrbit[i] = |rxfifo[i][10:8]; // are any of the error conditions set?
assign rxfullbit[i] = rxfullbitunwrapped[i] | rxfullbitunwrapped[i+16]; assign rxfullbit[i] = rxfullbitunwrapped[i] | rxfullbitunwrapped[i+16];
/* if (i > 0) /* if (i > 0)
assign rxfullbit[i] = ((rxfifohead==i) | rxfullbit[i-1]) & (rxfifotail != i); assign rxfullbit[i] = ((rxfifohead==i) | rxfullbit[i-1]) & (rxfifotail != i);
else else
assign rxfullbit[0] = ((rxfifohead==i) | rxfullbit[15]) & (rxfifotail != i);*/ assign rxfullbit[0] = ((rxfifohead==i) | rxfullbit[15]) & (rxfifotail != i);*/
end end
assign rxfifohaserr = |(RXerrbit & rxfullbit); assign rxfifohaserr = |(RXerrbit & rxfullbit);
// receive buffer register and ready bit // receive buffer register and ready bit
always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1) always_ff @(posedge PCLK, negedge PRESETn) // track rxrdy for DMA mode (FCR3 = FCR0 = 1)
@ -361,22 +366,23 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (fifodmamodesel) RXRDYb = ~rxfifodmaready; if (fifodmamodesel) RXRDYb = ~rxfifodmaready;
else RXRDYb = rxfifoempty; else RXRDYb = rxfifoempty;
end else begin end else begin
RBR = RXBR; RBR = RXBR;
RXRDYb = ~rxdataready; RXRDYb = ~rxdataready;
end end
/////////////////////////////////////////// ///////////////////////////////////////////
// transmit timing and control // transmit timing and control
/////////////////////////////////////////// ///////////////////////////////////////////
always_ff @(posedge PCLK, negedge PRESETn) always_ff @(posedge PCLK, negedge PRESETn)
if (~PRESETn) begin if (~PRESETn) begin
txoversampledcnt <= #1 0; txoversampledcnt <= #1 0;
txstate <= #1 UART_IDLE; txstate <= #1 UART_IDLE;
txbitssent <= #1 0; txbitssent <= #1 0;
end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting end else if ((txstate == UART_IDLE) & txsrfull) begin // start transmitting
txstate <= #1 UART_ACTIVE; txstate <= #1 UART_ACTIVE;
txoversampledcnt <= #1 1; txoversampledcnt <= #1 1;
txbitssent <= #1 0; txbitssent <= #1 0;
end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin end else if (txbaudpulse & (txstate == UART_ACTIVE)) begin
txoversampledcnt <= #1 txoversampledcnt + 1; txoversampledcnt <= #1 txoversampledcnt + 1;
if (txnextbit) begin // transmit at end of phase if (txnextbit) begin // transmit at end of phase
@ -390,11 +396,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) - 1 assign txbitsexpected = 4'd1 + (4'd5 + {2'b00, LCR[1:0]}) + {3'b000, LCR[3]} + 4'd1 + {3'b000, LCR[2]} - 4'd1; // start bit + data bits + (parity bit) + stop bit(s) - 1
// *** explain; is this necessary? // *** explain; is this necessary?
if (QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE if (QEMU) assign txnextbit = txbaudpulse & (txoversampledcnt[1:0] == 2'b00); // implies txstate = UART_ACTIVE
else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE else assign txnextbit = txbaudpulse & (txoversampledcnt == 4'b0000); // implies txstate = UART_ACTIVE
/////////////////////////////////////////// ///////////////////////////////////////////
// transmit holding register, shift register, FIFO // transmit holding register, shift register, FIFO
/////////////////////////////////////////// ///////////////////////////////////////////
always_comb begin // compute value for parity and tx holding register always_comb begin // compute value for parity and tx holding register
nexttxdata = fifoenabled ? txfifo[txfifotail] : TXHR; // pick from FIFO or holding register nexttxdata = fifoenabled ? txfifo[txfifotail] : TXHR; // pick from FIFO or holding register
case (LCR[1:0]) // compute parity from appropriate number of bits case (LCR[1:0]) // compute parity from appropriate number of bits
@ -426,9 +433,9 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo if (~MEMWb & A == 3'b000 & ~DLAB) begin // writing transmit holding register or fifo
if (fifoenabled) begin if (fifoenabled) begin
txfifo[txfifohead] <= #1 Din; txfifo[txfifohead] <= #1 Din;
txfifohead <= #1 txfifohead + 1; txfifohead <= #1 txfifohead + 1;
end else begin end else begin
TXHR <= #1 Din; TXHR <= #1 Din;
txhrfull <= #1 1; txhrfull <= #1 1;
end end
$write("%c",Din); // for testbench $write("%c",Din); // for testbench
@ -436,12 +443,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
if (txstate == UART_IDLE) begin // move data into tx shift register if available if (txstate == UART_IDLE) begin // move data into tx shift register if available
if (fifoenabled) begin if (fifoenabled) begin
if (~txfifoempty & ~txsrfull) begin if (~txfifoempty & ~txsrfull) begin
txsr <= #1 txdata; txsr <= #1 txdata;
txfifotail <= #1 txfifotail+1; txfifotail <= #1 txfifotail+1;
txsrfull <= #1 1; txsrfull <= #1 1;
end end
end else if (txhrfull) begin end else if (txhrfull) begin
txsr <= #1 txdata; txsr <= #1 txdata;
txhrfull <= #1 0; txhrfull <= #1 0;
txsrfull <= #1 1; txsrfull <= #1 1;
end end
@ -470,13 +477,13 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
HeadPointerLastMove <= 1'b0; HeadPointerLastMove <= 1'b0;
end end
assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove; assign txfifoempty = (txfifohead == txfifotail) & ~HeadPointerLastMove;
// verilator lint_off WIDTH // verilator lint_off WIDTH
assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) : assign txfifoentries = (txfifohead >= txfifotail) ? (txfifohead-txfifotail) :
(txfifohead + 16 - txfifotail); (txfifohead + 16 - txfifotail);
// verilator lint_on WIDTH // verilator lint_on WIDTH
//assign txfifofull = (txfifoentries == 4'b1111); //assign txfifofull = (txfifoentries == 4'b1111);
assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove; assign txfifofull = (txfifohead == txfifotail) & HeadPointerLastMove;
// transmit buffer ready bit // transmit buffer ready bit
always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1) always_ff @(posedge PCLK, negedge PRESETn) // track txrdy for DMA mode (FCR3 = FCR0 = 1)
@ -490,11 +497,12 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
// Transmitter pin // Transmitter pin
assign SOUTbit = txsr[11]; // transmit most significant bit assign SOUTbit = txsr[11]; // transmit most significant bit
assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break assign SOUT = loop ? 1 : (LCR[6] ? 0 : SOUTbit); // tied to 1 during loopback or 0 during break
/////////////////////////////////////////// ///////////////////////////////////////////
// interrupts // interrupts
/////////////////////////////////////////// ///////////////////////////////////////////
assign RXerr = |LSR[4:1]; // LS interrupt if any of the flags are true assign RXerr = |LSR[4:1]; // LS interrupt if any of the flags are true
assign RXerrIP = RXerr & ~squashRXerrIP; // intr squashed upon reading LSR assign RXerrIP = RXerr & ~squashRXerrIP; // intr squashed upon reading LSR
assign rxdataavailintr = fifoenabled ? rxfifotriggered : rxdataready; assign rxdataavailintr = fifoenabled ? rxfifotriggered : rxdataready;
@ -533,15 +541,15 @@ module uartPC16550D #(parameter UART_PRESCALE, QEMU) (
// modem control logic // modem control logic
/////////////////////////////////////////// ///////////////////////////////////////////
assign loop = MCR[4]; assign loop = MCR[4];
assign DTRb = ~MCR[0] | loop; // disable modem signals in loopback mode assign DTRb = ~MCR[0] | loop; // disable modem signals in loopback mode
assign RTSb = ~MCR[1] | loop; assign RTSb = ~MCR[1] | loop;
assign OUT1b = ~MCR[2] | loop; assign OUT1b = ~MCR[2] | loop;
assign OUT2b = ~MCR[3] | loop; assign OUT2b = ~MCR[3] | loop;
assign DLAB = LCR[7]; assign DLAB = LCR[7];
assign evenparitysel = LCR[4]; assign evenparitysel = LCR[4];
assign fifoenabled = FCR[0]; assign fifoenabled = FCR[0];
assign fifodmamodesel = FCR[3]; assign fifodmamodesel = FCR[3];
always_comb always_comb
case (FCR[7:6]) case (FCR[7:6])

View File

@ -29,18 +29,18 @@
//////////////////////////////////////////////////////////////////////////////////////////////// ////////////////////////////////////////////////////////////////////////////////////////////////
module uart_apb import cvw::*; #(parameter cvw_t P) ( module uart_apb import cvw::*; #(parameter cvw_t P) (
input logic PCLK, PRESETn, input logic PCLK, PRESETn,
input logic PSEL, input logic PSEL,
input logic [2:0] PADDR, input logic [2:0] PADDR,
input logic [P.XLEN-1:0] PWDATA, input logic [P.XLEN-1:0] PWDATA,
input logic [P.XLEN/8-1:0] PSTRB, input logic [P.XLEN/8-1:0] PSTRB,
input logic PWRITE, input logic PWRITE,
input logic PENABLE, input logic PENABLE,
output logic [P.XLEN-1:0] PRDATA, output logic [P.XLEN-1:0] PRDATA,
output logic PREADY, output logic PREADY,
input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface
output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface
output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
// UART interface signals // UART interface signals
logic [2:0] entry; logic [2:0] entry;
@ -49,10 +49,10 @@ module uart_apb import cvw::*; #(parameter cvw_t P) (
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase
assign memread = ~PWRITE & PENABLE & PSEL; assign memread = ~PWRITE & PENABLE & PSEL;
assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond assign PREADY = 1'b1; // CLINT never takes >1 cycle to respond
assign entry = PADDR[2:0]; assign entry = PADDR[2:0];
assign MEMRb = ~memread; assign MEMRb = ~memread;
assign MEMWb = ~memwrite; assign MEMWb = ~memwrite;
if (P.XLEN == 64) begin:uart if (P.XLEN == 64) begin:uart
always_comb begin always_comb begin
@ -97,4 +97,3 @@ module uart_apb import cvw::*; #(parameter cvw_t P) (
); );
endmodule endmodule

View File

@ -29,58 +29,58 @@
module uncore import cvw::*; #(parameter cvw_t P)( module uncore import cvw::*; #(parameter cvw_t P)(
// AHB Bus Interface // AHB Bus Interface
input logic HCLK, HRESETn, input logic HCLK, HRESETn,
input logic TIMECLK, input logic TIMECLK,
input logic [P.PA_BITS-1:0] HADDR, input logic [P.PA_BITS-1:0] HADDR,
input logic [P.AHBW-1:0] HWDATA, input logic [P.AHBW-1:0] HWDATA,
input logic [P.XLEN/8-1:0] HWSTRB, input logic [P.XLEN/8-1:0] HWSTRB,
input logic HWRITE, input logic HWRITE,
input logic [2:0] HSIZE, input logic [2:0] HSIZE,
input logic [2:0] HBURST, input logic [2:0] HBURST,
input logic [3:0] HPROT, input logic [3:0] HPROT,
input logic [1:0] HTRANS, input logic [1:0] HTRANS,
input logic HMASTLOCK, input logic HMASTLOCK,
input logic [P.AHBW-1:0] HRDATAEXT, input logic [P.AHBW-1:0] HRDATAEXT,
input logic HREADYEXT, HRESPEXT, input logic HREADYEXT, HRESPEXT,
output logic [P.AHBW-1:0] HRDATA, output logic [P.AHBW-1:0] HRDATA,
output logic HREADY, HRESP, output logic HREADY, HRESP,
output logic HSELEXT, output logic HSELEXT,
// peripheral pins // peripheral pins
output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT output logic MTimerInt, MSwInt, // Timer and software interrupts from CLINT
output logic MExtInt, SExtInt, // External interrupts from PLIC output logic MExtInt, SExtInt, // External interrupts from PLIC
output logic [63:0] MTIME_CLINT, // MTIME, from CLINT output logic [63:0] MTIME_CLINT, // MTIME, from CLINT
input logic [31:0] GPIOIN, // GPIO pin input value input logic [31:0] GPIOIN, // GPIO pin input value
output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable output logic [31:0] GPIOOUT, GPIOEN, // GPIO pin output value and enable
input logic UARTSin, // UART serial input input logic UARTSin, // UART serial input
output logic UARTSout, // UART serial output output logic UARTSout, // UART serial output
output logic SDCCmdOut, // SD Card command output output logic SDCCmdOut, // SD Card command output
output logic SDCCmdOE, // SD Card command output enable output logic SDCCmdOE, // SD Card command output enable
input logic SDCCmdIn, // SD Card command input input logic SDCCmdIn, // SD Card command input
input logic [3:0] SDCDatIn, // SD Card data input input logic [3:0] SDCDatIn, // SD Card data input
output logic SDCCLK // SD Card clock output logic SDCCLK // SD Card clock
); );
logic [P.XLEN-1:0] HREADRam, HREADSDC; logic [P.XLEN-1:0] HREADRam, HREADSDC;
logic [10:0] HSELRegions; logic [10:0] HSELRegions;
logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC; logic HSELDTIM, HSELIROM, HSELRam, HSELCLINT, HSELPLIC, HSELGPIO, HSELUART, HSELSDC;
logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD; logic HSELDTIMD, HSELIROMD, HSELEXTD, HSELRamD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD;
logic HRESPRam, HRESPSDC; logic HRESPRam, HRESPSDC;
logic HREADYRam, HRESPSDCD; logic HREADYRam, HRESPSDCD;
logic [P.XLEN-1:0] HREADBootRom; logic [P.XLEN-1:0] HREADBootRom;
logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC; logic HSELBootRom, HSELBootRomD, HRESPBootRom, HREADYBootRom, HREADYSDC;
logic HSELNoneD; logic HSELNoneD;
logic UARTIntr,GPIOIntr; logic UARTIntr,GPIOIntr;
logic SDCIntM; logic SDCIntM;
logic PCLK, PRESETn, PWRITE, PENABLE; logic PCLK, PRESETn, PWRITE, PENABLE;
logic [3:0] PSEL, PREADY; logic [3:0] PSEL, PREADY;
logic [31:0] PADDR; logic [31:0] PADDR;
logic [P.XLEN-1:0] PWDATA; logic [P.XLEN-1:0] PWDATA;
logic [P.XLEN/8-1:0] PSTRB; logic [P.XLEN/8-1:0] PSTRB;
logic [3:0][P.XLEN-1:0] PRDATA; logic [3:0][P.XLEN-1:0] PRDATA;
logic [P.XLEN-1:0] HREADBRIDGE; logic [P.XLEN-1:0] HREADBRIDGE;
logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED; logic HRESPBRIDGE, HREADYBRIDGE, HSELBRIDGE, HSELBRIDGED;
// Determine which region of physical memory (if any) is being accessed // Determine which region of physical memory (if any) is being accessed
// Use a trimmed down portion of the PMA checker - only the address decoders // Use a trimmed down portion of the PMA checker - only the address decoders
@ -154,9 +154,9 @@ module uncore import cvw::*; #(parameter cvw_t P)(
.SDCIntM .SDCIntM
); );
end else begin : sdc end else begin : sdc
assign SDCCLK = 0; assign SDCCLK = 0;
assign SDCCmdOut = 0; assign SDCCmdOut = 0;
assign SDCCmdOE = 0; assign SDCCmdOE = 0;
end end
// AHB Read Multiplexer // AHB Read Multiplexer
@ -189,4 +189,3 @@ module uncore import cvw::*; #(parameter cvw_t P)(
HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD}); HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD, HSELNoneD});
flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED); flopenr #(1) hselbridgedelayreg(HCLK, ~HRESETn, HREADY, HSELBRIDGE, HSELBRIDGED);
endmodule endmodule

View File

@ -47,8 +47,9 @@ typedef struct packed {
// RISC-V Features // RISC-V Features
logic ZICSR_SUPPORTED; logic ZICSR_SUPPORTED;
logic ZIFENCEI_SUPPORTED; logic ZIFENCEI_SUPPORTED;
logic [11:0] COUNTERS; logic [11:0] COUNTERS;
logic ZICOUNTERS_SUPPORTED; logic ZICNTR_SUPPORTED;
logic ZIHPM_SUPPORTED;
logic ZFH_SUPPORTED; logic ZFH_SUPPORTED;
logic SSTC_SUPPORTED; logic SSTC_SUPPORTED;
logic VIRTMEM_SUPPORTED; logic VIRTMEM_SUPPORTED;
@ -56,6 +57,10 @@ typedef struct packed {
logic BIGENDIAN_SUPPORTED; logic BIGENDIAN_SUPPORTED;
logic SVADU_SUPPORTED; logic SVADU_SUPPORTED;
logic ZMMUL_SUPPORTED; logic ZMMUL_SUPPORTED;
logic ZICBOM_SUPPORTED;
logic ZICBOZ_SUPPORTED;
logic ZICBOP_SUPPORTED;
logic SVPBMT_SUPPORTED;
// Microarchitectural Features // Microarchitectural Features
logic BUS_SUPPORTED; logic BUS_SUPPORTED;
@ -63,31 +68,31 @@ typedef struct packed {
logic ICACHE_SUPPORTED; logic ICACHE_SUPPORTED;
// TLB configuration. Entries should be a power of 2 // TLB configuration. Entries should be a power of 2
int ITLB_ENTRIES; int ITLB_ENTRIES;
int DTLB_ENTRIES; int DTLB_ENTRIES;
// Cache configuration. Sizes should be a power of two // Cache configuration. Sizes should be a power of two
// typical configuration 4 ways, 4096 ints per way, 256 bit or more lines // typical configuration 4 ways, 4096 ints per way, 256 bit or more lines
int DCACHE_NUMWAYS; int DCACHE_NUMWAYS;
int DCACHE_WAYSIZEINBYTES; int DCACHE_WAYSIZEINBYTES;
int DCACHE_LINELENINBITS; int DCACHE_LINELENINBITS;
int ICACHE_NUMWAYS; int ICACHE_NUMWAYS;
int ICACHE_WAYSIZEINBYTES; int ICACHE_WAYSIZEINBYTES;
int ICACHE_LINELENINBITS; int ICACHE_LINELENINBITS;
// Integer Divider Configuration // Integer Divider Configuration
// IDIV_BITSPERCYCLE must be 1, 2, or 4 // IDIV_BITSPERCYCLE must be 1, 2, or 4
int IDIV_BITSPERCYCLE; int IDIV_BITSPERCYCLE;
logic IDIV_ON_FPU; logic IDIV_ON_FPU;
// Legal number of PMP entries are 0, 16, or 64 // Legal number of PMP entries are 0, 16, or 64
int PMP_ENTRIES; int PMP_ENTRIES;
// Address space // Address space
logic [63:0] RESET_VECTOR; logic [63:0] RESET_VECTOR;
// WFI Timeout Wait // WFI Timeout Wait
int WFI_TIMEOUT_BIT; int WFI_TIMEOUT_BIT;
// Peripheral Addresses // Peripheral Addresses
// Peripheral memory space extends from BASE to BASE+RANGE // Peripheral memory space extends from BASE to BASE+RANGE
@ -129,24 +134,23 @@ typedef struct packed {
logic GPIO_LOOPBACK_TEST; logic GPIO_LOOPBACK_TEST;
// Hardware configuration // Hardware configuration
int UART_PRESCALE ; int UART_PRESCALE ;
// Interrupt configuration // Interrupt configuration
int PLIC_NUM_SRC; int PLIC_NUM_SRC;
logic PLIC_NUM_SRC_LT_32; logic PLIC_NUM_SRC_LT_32;
int PLIC_GPIO_ID; int PLIC_GPIO_ID;
int PLIC_UART_ID; int PLIC_UART_ID;
logic BPRED_SUPPORTED;
BranchPredictorType BPRED_TYPE;
int BPRED_NUM_LHR;
int BPRED_SIZE;
int BTB_SIZE;
logic BPRED_SUPPORTED;
BranchPredictorType BPRED_TYPE;
int BPRED_NUM_LHR;
int BPRED_SIZE;
int BTB_SIZE;
// FPU division architecture // FPU division architecture
int RADIX; int RADIX;
int DIVCOPIES; int DIVCOPIES;
// bit manipulation // bit manipulation
logic ZBA_SUPPORTED; logic ZBA_SUPPORTED;
@ -199,47 +203,47 @@ typedef struct packed {
int PMPCFG_ENTRIES; int PMPCFG_ENTRIES;
// Floating point constants for Quad, Double, Single, and Half precisions // Floating point constants for Quad, Double, Single, and Half precisions
int Q_LEN; int Q_LEN;
int Q_NE; int Q_NE;
int Q_NF; int Q_NF;
int Q_BIAS; int Q_BIAS;
logic [1:0] Q_FMT; logic [1:0] Q_FMT;
int D_LEN; int D_LEN;
int D_NE; int D_NE;
int D_NF; int D_NF;
int D_BIAS; int D_BIAS;
logic [1:0] D_FMT; logic [1:0] D_FMT;
int S_LEN; int S_LEN;
int S_NE; int S_NE;
int S_NF; int S_NF;
int S_BIAS; int S_BIAS;
logic [1:0] S_FMT; logic [1:0] S_FMT;
int H_LEN; int H_LEN;
int H_NE; int H_NE;
int H_NF; int H_NF;
int H_BIAS; int H_BIAS;
logic [1:0] H_FMT; logic [1:0] H_FMT;
// Floating point length FLEN and number of exponent (NE) and fraction (NF) bits // Floating point length FLEN and number of exponent (NE) and fraction (NF) bits
int FLEN; int FLEN;
int NE ; int NE ;
int NF ; int NF ;
logic [1:0] FMT ; logic [1:0] FMT ;
int BIAS; int BIAS;
// Floating point constants needed for FPU paramerterization // Floating point constants needed for FPU paramerterization
int FPSIZES; int FPSIZES;
int FMTBITS; int FMTBITS;
int LEN1 ; int LEN1 ;
int NE1 ; int NE1 ;
int NF1 ; int NF1 ;
logic [1:0] FMT1 ; logic [1:0] FMT1 ;
int BIAS1; int BIAS1;
int LEN2 ; int LEN2 ;
int NE2 ; int NE2 ;
int NF2 ; int NF2 ;
logic [1:0] FMT2 ; logic [1:0] FMT2 ;
int BIAS2; int BIAS2;
// largest length in IEU/FPU // largest length in IEU/FPU
int CVTLEN; int CVTLEN;
@ -251,7 +255,7 @@ typedef struct packed {
// division constants // division constants
int DIVN ; int DIVN ;
int LOGR; int LOGR ;
int RK ; int RK ;
int LOGRK ; int LOGRK ;
int FPDUR ; int FPDUR ;

View File

@ -32,12 +32,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
input logic MTimerInt, MExtInt, SExtInt, MSwInt, input logic MTimerInt, MExtInt, SExtInt, MSwInt,
input logic [63:0] MTIME_CLINT, input logic [63:0] MTIME_CLINT,
// Bus Interface // Bus Interface
input logic [P.AHBW-1:0] HRDATA, input logic [P.AHBW-1:0] HRDATA,
input logic HREADY, HRESP, input logic HREADY, HRESP,
output logic HCLK, HRESETn, output logic HCLK, HRESETn,
output logic [P.PA_BITS-1:0] HADDR, output logic [P.PA_BITS-1:0] HADDR,
output logic [P.AHBW-1:0] HWDATA, output logic [P.AHBW-1:0] HWDATA,
output logic [P.XLEN/8-1:0] HWSTRB, output logic [P.XLEN/8-1:0] HWSTRB,
output logic HWRITE, output logic HWRITE,
output logic [2:0] HSIZE, output logic [2:0] HSIZE,
output logic [2:0] HBURST, output logic [2:0] HBURST,
@ -55,15 +55,15 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic IntDivE, W64E; logic IntDivE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM; logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicM; logic [1:0] AtomicM;
logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE; logic [P.XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
logic [P.XLEN-1:0] SrcAM; logic [P.XLEN-1:0] SrcAM;
logic [2:0] Funct3E; logic [2:0] Funct3E;
logic [31:0] InstrD; logic [31:0] InstrD;
logic [31:0] InstrM, InstrOrigM; logic [31:0] InstrM, InstrOrigM;
logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE; logic [P.XLEN-1:0] PCSpillF, PCE, PCLinkE;
logic [P.XLEN-1:0] PCM; logic [P.XLEN-1:0] PCM;
logic [P.XLEN-1:0] CSRReadValW, MDUResultW; logic [P.XLEN-1:0] CSRReadValW, MDUResultW;
logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF; logic [P.XLEN-1:0] UnalignedPCNextF, PC2NextF;
logic [1:0] MemRWM; logic [1:0] MemRWM;
logic InstrValidD, InstrValidE, InstrValidM; logic InstrValidD, InstrValidE, InstrValidM;
logic InstrMisalignedFaultM; logic InstrMisalignedFaultM;
@ -83,31 +83,31 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic [4:0] RdE, RdM, RdW; logic [4:0] RdE, RdM, RdW;
logic FPUStallD; logic FPUStallD;
logic FWriteIntE; logic FWriteIntE;
logic [P.FLEN-1:0] FWriteDataM; logic [P.FLEN-1:0] FWriteDataM;
logic [P.XLEN-1:0] FIntResM; logic [P.XLEN-1:0] FIntResM;
logic [P.XLEN-1:0] FCvtIntResW; logic [P.XLEN-1:0] FCvtIntResW;
logic FCvtIntW; logic FCvtIntW;
logic FDivBusyE; logic FDivBusyE;
logic FRegWriteM; logic FRegWriteM;
logic FCvtIntStallD; 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;
// memory management unit signals // memory management unit signals
logic ITLBWriteF; logic ITLBWriteF;
logic ITLBMissF; logic ITLBMissF;
logic [P.XLEN-1:0] SATP_REGW; logic [P.XLEN-1:0] SATP_REGW;
logic STATUS_MXR, STATUS_SUM, STATUS_MPRV; logic STATUS_MXR, STATUS_SUM, STATUS_MPRV;
logic [1:0] STATUS_MPP, STATUS_FS; logic [1:0] STATUS_MPP, STATUS_FS;
logic [1:0] PrivilegeModeW; logic [1:0] PrivilegeModeW;
logic [P.XLEN-1:0] PTE; logic [P.XLEN-1:0] PTE;
logic [1:0] PageType; logic [1:0] PageType;
logic sfencevmaM; logic sfencevmaM;
logic SelHPTW; logic SelHPTW;
// PMA checker signals // PMA checker signals
var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0]; var logic [P.PA_BITS-3:0] PMPADDR_ARRAY_REGW[P.PMP_ENTRIES-1:0];
var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0]; var logic [7:0] PMPCFG_ARRAY_REGW[P.PMP_ENTRIES-1:0];
// IMem stalls // IMem stalls
@ -116,14 +116,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
// cpu lsu interface // cpu lsu interface
logic [2:0] Funct3M; logic [2:0] Funct3M;
logic [P.XLEN-1:0] IEUAdrE; logic [P.XLEN-1:0] IEUAdrE;
logic [P.XLEN-1:0] WriteDataM; logic [P.XLEN-1:0] WriteDataM;
logic [P.XLEN-1:0] IEUAdrM; logic [P.XLEN-1:0] IEUAdrM;
logic [P.LLEN-1:0] ReadDataW; logic [P.LLEN-1:0] ReadDataW;
logic CommittedM; logic CommittedM;
// AHB ifu interface // AHB ifu interface
logic [P.PA_BITS-1:0] IFUHADDR; logic [P.PA_BITS-1:0] IFUHADDR;
logic [2:0] IFUHBURST; logic [2:0] IFUHBURST;
logic [1:0] IFUHTRANS; logic [1:0] IFUHTRANS;
logic [2:0] IFUHSIZE; logic [2:0] IFUHSIZE;
@ -131,9 +131,9 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
logic IFUHREADY; logic IFUHREADY;
// AHB LSU interface // AHB LSU interface
logic [P.PA_BITS-1:0] LSUHADDR; logic [P.PA_BITS-1:0] LSUHADDR;
logic [P.XLEN-1:0] LSUHWDATA; logic [P.XLEN-1:0] LSUHWDATA;
logic [P.XLEN/8-1:0] LSUHWSTRB; logic [P.XLEN/8-1:0] LSUHWSTRB;
logic LSUHWRITE; logic LSUHWRITE;
logic LSUHREADY; logic LSUHREADY;
@ -192,12 +192,12 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E, .PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, .Funct3E, .ForwardedSrcAE, .ForwardedSrcBE,
// Memory stage interface // Memory stage interface
.SquashSCW, // from LSU .SquashSCW, // from LSU
.MemRWM, // read/write control goes to LSU .MemRWM, // read/write control goes to LSU
.AtomicM, // atomic control goes to LSU .AtomicM, // atomic control goes to LSU
.WriteDataM, // Write data to LSU .WriteDataM, // Write data to LSU
.Funct3M, // size and signedness to LSU .Funct3M, // size and signedness to LSU
.SrcAM, // to privilege and fpu .SrcAM, // to privilege and fpu
.RdE, .RdM, .FIntResM, .FlushDCacheM, .RdE, .RdM, .FIntResM, .FlushDCacheM,
.BranchD, .BranchE, .JumpD, .JumpE, .BranchD, .BranchE, .JumpD, .JumpE,
// Writeback stage // Writeback stage
@ -219,24 +219,24 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.LSUHADDR, .HRDATA, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE, .LSUHADDR, .HRDATA, .LSUHWDATA, .LSUHWSTRB, .LSUHSIZE,
.LSUHBURST, .LSUHTRANS, .LSUHWRITE, .LSUHREADY, .LSUHBURST, .LSUHTRANS, .LSUHWRITE, .LSUHREADY,
// connect to csr or privilege and stay the same. // connect to csr or privilege and stay the same.
.PrivilegeModeW, .BigEndianM, // connects to csr .PrivilegeModeW, .BigEndianM, // connects to csr
.PMPCFG_ARRAY_REGW, // connects to csr .PMPCFG_ARRAY_REGW, // connects to csr
.PMPADDR_ARRAY_REGW, // connects to csr .PMPADDR_ARRAY_REGW, // connects to csr
// hptw keep i/o // hptw keep i/o
.SATP_REGW, // from csr .SATP_REGW, // from csr
.STATUS_MXR, // from csr .STATUS_MXR, // from csr
.STATUS_SUM, // from csr .STATUS_SUM, // from csr
.STATUS_MPRV, // from csr .STATUS_MPRV, // from csr
.STATUS_MPP, // from csr .STATUS_MPP, // from csr
.sfencevmaM, // connects to privilege .sfencevmaM, // connects to privilege
.DCacheStallM, // connects to privilege .DCacheStallM, // connects to privilege
.LoadPageFaultM, // connects to privilege .LoadPageFaultM, // connects to privilege
.StoreAmoPageFaultM, // connects to privilege .StoreAmoPageFaultM, // connects to privilege
.LoadMisalignedFaultM, // connects to privilege .LoadMisalignedFaultM, // connects to privilege
.LoadAccessFaultM, // connects to privilege .LoadAccessFaultM, // connects to privilege
.HPTWInstrAccessFaultF, // connects to privilege .HPTWInstrAccessFaultF, // connects to privilege
.StoreAmoMisalignedFaultM, // connects to privilege .StoreAmoMisalignedFaultM, // connects to privilege
.StoreAmoAccessFaultM, // connects to privilege .StoreAmoAccessFaultM, // connects to privilege
.InstrUpdateDAF, .InstrUpdateDAF,
.PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW, .PCSpillF, .ITLBMissF, .PTE, .PageType, .ITLBWriteF, .SelHPTW,
.LSUStallM); .LSUStallM);
@ -292,14 +292,14 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW, .PMPCFG_ARRAY_REGW, .PMPADDR_ARRAY_REGW,
.FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM); .FRM_REGW,.BreakpointFaultM, .EcallFaultM, .wfiM, .IntPendingM, .BigEndianM);
end else begin end else begin
assign CSRReadValW = 0; assign CSRReadValW = 0;
assign UnalignedPCNextF = PC2NextF; assign UnalignedPCNextF = PC2NextF;
assign RetM = 0; assign RetM = 0;
assign TrapM = 0; assign TrapM = 0;
assign wfiM = 0; assign wfiM = 0;
assign IntPendingM = 0; assign IntPendingM = 0;
assign sfencevmaM = 0; assign sfencevmaM = 0;
assign BigEndianM = 0; assign BigEndianM = 0;
end end
// multiply/divide unit // multiply/divide unit
@ -310,45 +310,45 @@ module wallypipelinedcore import cvw::*; #(parameter cvw_t P) (
.MDUResultW, .DivBusyE); .MDUResultW, .DivBusyE);
end else begin // no M instructions supported end else begin // no M instructions supported
assign MDUResultW = 0; assign MDUResultW = 0;
assign DivBusyE = 0; assign DivBusyE = 0;
end end
// floating point unit // floating point unit
if (P.F_SUPPORTED) begin:fpu if (P.F_SUPPORTED) begin:fpu
fpu #(P) fpu( fpu #(P) fpu(
.clk, .reset, .clk, .reset,
.FRM_REGW, // Rounding mode from CSR .FRM_REGW, // Rounding mode from CSR
.InstrD, // instruction from IFU .InstrD, // instruction from IFU
.ReadDataW(ReadDataW[P.FLEN-1:0]),// Read data from memory .ReadDataW(ReadDataW[P.FLEN-1:0]), // Read data from memory
.ForwardedSrcAE, // Integer input being processed (from IEU) .ForwardedSrcAE, // Integer input being processed (from IEU)
.StallE, .StallM, .StallW, // stall signals from HZU .StallE, .StallM, .StallW, // stall signals from HZU
.FlushE, .FlushM, .FlushW, // flush signals from HZU .FlushE, .FlushM, .FlushW, // flush signals from HZU
.RdE, .RdM, .RdW, // which FP register to write to (from IEU) .RdE, .RdM, .RdW, // which FP register to write to (from IEU)
.STATUS_FS, // is floating-point enabled? .STATUS_FS, // is floating-point enabled?
.FRegWriteM, // FP register write enable .FRegWriteM, // FP register write enable
.FpLoadStoreM, .FpLoadStoreM,
.ForwardedSrcBE, // Integer input for intdiv .ForwardedSrcBE, // Integer input for intdiv
.Funct3E, .Funct3M, .IntDivE, .W64E, // Integer flags and functions .Funct3E, .Funct3M, .IntDivE, .W64E, // Integer flags and functions
.FPUStallD, // Stall the decode stage .FPUStallD, // Stall the decode stage
.FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation .FWriteIntE, .FCvtIntE, // integer register write enable, conversion operation
.FWriteDataM, // Data to be written to memory .FWriteDataM, // Data to be written to memory
.FIntResM, // data to be written to integer register .FIntResM, // data to be written to integer register
.FCvtIntResW, // fp -> int conversion result to be stored in int register .FCvtIntResW, // fp -> int conversion result to be stored in int register
.FCvtIntW, // fpu result selection .FCvtIntW, // fpu result selection
.FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage) .FDivBusyE, // Is the divide/sqrt unit busy (stall execute stage)
.IllegalFPUInstrD, // Is the instruction an illegal fpu instruction .IllegalFPUInstrD, // Is the instruction an illegal fpu instruction
.SetFflagsM, // FPU flags (to privileged unit) .SetFflagsM, // FPU flags (to privileged unit)
.FIntDivResultW); .FIntDivResultW);
end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low end else begin // no F_SUPPORTED or D_SUPPORTED; tie outputs low
assign FPUStallD = 0; assign FPUStallD = 0;
assign FWriteIntE = 0; assign FWriteIntE = 0;
assign FCvtIntE = 0; assign FCvtIntE = 0;
assign FIntResM = 0; assign FIntResM = 0;
assign FCvtIntW = 0; assign FCvtIntW = 0;
assign FDivBusyE = 0; assign FDivBusyE = 0;
assign IllegalFPUInstrD = 1; assign IllegalFPUInstrD = 1;
assign SetFflagsM = 0; assign SetFflagsM = 0;
assign FpLoadStoreM = 0; assign FpLoadStoreM = 0;
end end
endmodule endmodule

View File

@ -48,9 +48,9 @@ module wallypipelinedsoc import cvw::*; #(parameter cvw_t P) (
output logic HREADY, output logic HREADY,
// I/O Interface // I/O Interface
input logic TIMECLK, // optional for CLINT MTIME counter input logic TIMECLK, // optional for CLINT MTIME counter
input logic [31:0] GPIOIN, // inputs from GPIO input logic [31:0] GPIOIN, // inputs from GPIO
output logic [31:0] GPIOOUT, // output values for GPIO output logic [31:0] GPIOOUT, // output values for GPIO
output logic [31:0] GPIOEN, // output enables for GPIO output logic [31:0] GPIOEN, // output enables for GPIO
input logic UARTSin, // UART serial data input input logic UARTSin, // UART serial data input
output logic UARTSout, // UART serial data output output logic UARTSout, // UART serial data output
input logic SDCCmdIn, // SDC Command input input logic SDCCmdIn, // SDC Command input

View File

@ -139,6 +139,7 @@ module wallyTracer(rvviTrace rvvi);
CSRArray[12'h344] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW; CSRArray[12'h344] = testbench.dut.core.priv.priv.csr.csrm.MIP_REGW;
CSRArray[12'h304] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW; CSRArray[12'h304] = testbench.dut.core.priv.priv.csr.csrm.MIE_REGW;
CSRArray[12'h301] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW; CSRArray[12'h301] = testbench.dut.core.priv.priv.csr.csrm.MISA_REGW;
CSRArray[12'h30A] = testbench.dut.core.priv.priv.csr.csrm.MENVCFG_REGW;
CSRArray[12'hF14] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW; CSRArray[12'hF14] = testbench.dut.core.priv.priv.csr.csrm.MHARTID_REGW;
CSRArray[12'h340] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW; CSRArray[12'h340] = testbench.dut.core.priv.priv.csr.csrm.MSCRATCH_REGW;
CSRArray[12'h342] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW; CSRArray[12'h342] = testbench.dut.core.priv.priv.csr.csrm.MCAUSE_REGW;
@ -157,6 +158,7 @@ module wallyTracer(rvviTrace rvvi);
CSRArray[12'h105] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW; CSRArray[12'h105] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVEC_REGW;
CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW; CSRArray[12'h141] = testbench.dut.core.priv.priv.csr.csrs.csrs.SEPC_REGW;
CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW; CSRArray[12'h106] = testbench.dut.core.priv.priv.csr.csrs.csrs.SCOUNTEREN_REGW;
CSRArray[12'h10A] = testbench.dut.core.priv.priv.csr.csrs.csrs.SENVCFG_REGW;
CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.csrs.SATP_REGW; CSRArray[12'h180] = testbench.dut.core.priv.priv.csr.csrs.csrs.SATP_REGW;
CSRArray[12'h140] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW; CSRArray[12'h140] = testbench.dut.core.priv.priv.csr.csrs.csrs.SSCRATCH_REGW;
CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW; CSRArray[12'h143] = testbench.dut.core.priv.priv.csr.csrs.csrs.STVAL_REGW;
@ -189,6 +191,7 @@ module wallyTracer(rvviTrace rvvi);
CSRArray[12'h344] = CSRArrayOld[12'h344]; CSRArray[12'h344] = CSRArrayOld[12'h344];
CSRArray[12'h304] = CSRArrayOld[12'h304]; CSRArray[12'h304] = CSRArrayOld[12'h304];
CSRArray[12'h301] = CSRArrayOld[12'h301]; CSRArray[12'h301] = CSRArrayOld[12'h301];
CSRArray[12'h30A] = CSRArrayOld[12'h30A];
CSRArray[12'hF14] = CSRArrayOld[12'hF14]; CSRArray[12'hF14] = CSRArrayOld[12'hF14];
CSRArray[12'h340] = CSRArrayOld[12'h340]; CSRArray[12'h340] = CSRArrayOld[12'h340];
CSRArray[12'h342] = CSRArrayOld[12'h342]; CSRArray[12'h342] = CSRArrayOld[12'h342];
@ -207,6 +210,7 @@ module wallyTracer(rvviTrace rvvi);
CSRArray[12'h105] = CSRArrayOld[12'h105]; CSRArray[12'h105] = CSRArrayOld[12'h105];
CSRArray[12'h141] = CSRArrayOld[12'h141]; CSRArray[12'h141] = CSRArrayOld[12'h141];
CSRArray[12'h106] = CSRArrayOld[12'h106]; CSRArray[12'h106] = CSRArrayOld[12'h106];
CSRArray[12'h10A] = CSRArrayOld[12'h10A];
CSRArray[12'h180] = CSRArrayOld[12'h180]; CSRArray[12'h180] = CSRArrayOld[12'h180];
CSRArray[12'h140] = CSRArrayOld[12'h140]; CSRArray[12'h140] = CSRArrayOld[12'h140];
CSRArray[12'h143] = CSRArrayOld[12'h143]; CSRArray[12'h143] = CSRArrayOld[12'h143];
@ -308,6 +312,7 @@ module wallyTracer(rvviTrace rvvi);
CSRArrayOld[12'h344] = CSRArray[12'h344]; CSRArrayOld[12'h344] = CSRArray[12'h344];
CSRArrayOld[12'h304] = CSRArray[12'h304]; CSRArrayOld[12'h304] = CSRArray[12'h304];
CSRArrayOld[12'h301] = CSRArray[12'h301]; CSRArrayOld[12'h301] = CSRArray[12'h301];
CSRArrayOld[12'h30A] = CSRArray[12'h30A];
CSRArrayOld[12'hF14] = CSRArray[12'hF14]; CSRArrayOld[12'hF14] = CSRArray[12'hF14];
CSRArrayOld[12'h340] = CSRArray[12'h340]; CSRArrayOld[12'h340] = CSRArray[12'h340];
CSRArrayOld[12'h342] = CSRArray[12'h342]; CSRArrayOld[12'h342] = CSRArray[12'h342];
@ -326,6 +331,7 @@ module wallyTracer(rvviTrace rvvi);
CSRArrayOld[12'h105] = CSRArray[12'h105]; CSRArrayOld[12'h105] = CSRArray[12'h105];
CSRArrayOld[12'h141] = CSRArray[12'h141]; CSRArrayOld[12'h141] = CSRArray[12'h141];
CSRArrayOld[12'h106] = CSRArray[12'h106]; CSRArrayOld[12'h106] = CSRArray[12'h106];
CSRArrayOld[12'h10A] = CSRArray[12'h10A];
CSRArrayOld[12'h180] = CSRArray[12'h180]; CSRArrayOld[12'h180] = CSRArray[12'h180];
CSRArrayOld[12'h140] = CSRArray[12'h140]; CSRArrayOld[12'h140] = CSRArray[12'h140];
CSRArrayOld[12'h143] = CSRArray[12'h143]; CSRArrayOld[12'h143] = CSRArray[12'h143];
@ -352,6 +358,7 @@ module wallyTracer(rvviTrace rvvi);
assign #2 CSR_W[12'h305] = (CSRArrayOld[12'h305] != CSRArray[12'h305]) ? 1 : 0; assign #2 CSR_W[12'h305] = (CSRArrayOld[12'h305] != CSRArray[12'h305]) ? 1 : 0;
assign #2 CSR_W[12'h341] = (CSRArrayOld[12'h341] != CSRArray[12'h341]) ? 1 : 0; assign #2 CSR_W[12'h341] = (CSRArrayOld[12'h341] != CSRArray[12'h341]) ? 1 : 0;
assign #2 CSR_W[12'h306] = (CSRArrayOld[12'h306] != CSRArray[12'h306]) ? 1 : 0; assign #2 CSR_W[12'h306] = (CSRArrayOld[12'h306] != CSRArray[12'h306]) ? 1 : 0;
assign #2 CSR_W[12'h30A] = (CSRArrayOld[12'h30A] != CSRArray[12'h30A]) ? 1 : 0;
assign #2 CSR_W[12'h320] = (CSRArrayOld[12'h320] != CSRArray[12'h320]) ? 1 : 0; assign #2 CSR_W[12'h320] = (CSRArrayOld[12'h320] != CSRArray[12'h320]) ? 1 : 0;
assign #2 CSR_W[12'h302] = (CSRArrayOld[12'h302] != CSRArray[12'h302]) ? 1 : 0; assign #2 CSR_W[12'h302] = (CSRArrayOld[12'h302] != CSRArray[12'h302]) ? 1 : 0;
assign #2 CSR_W[12'h303] = (CSRArrayOld[12'h303] != CSRArray[12'h303]) ? 1 : 0; assign #2 CSR_W[12'h303] = (CSRArrayOld[12'h303] != CSRArray[12'h303]) ? 1 : 0;
@ -374,6 +381,7 @@ module wallyTracer(rvviTrace rvvi);
assign #2 CSR_W[12'h105] = (CSRArrayOld[12'h105] != CSRArray[12'h105]) ? 1 : 0; assign #2 CSR_W[12'h105] = (CSRArrayOld[12'h105] != CSRArray[12'h105]) ? 1 : 0;
assign #2 CSR_W[12'h141] = (CSRArrayOld[12'h141] != CSRArray[12'h141]) ? 1 : 0; assign #2 CSR_W[12'h141] = (CSRArrayOld[12'h141] != CSRArray[12'h141]) ? 1 : 0;
assign #2 CSR_W[12'h106] = (CSRArrayOld[12'h106] != CSRArray[12'h106]) ? 1 : 0; assign #2 CSR_W[12'h106] = (CSRArrayOld[12'h106] != CSRArray[12'h106]) ? 1 : 0;
assign #2 CSR_W[12'h10A] = (CSRArrayOld[12'h10A] != CSRArray[12'h10A]) ? 1 : 0;
assign #2 CSR_W[12'h180] = (CSRArrayOld[12'h180] != CSRArray[12'h180]) ? 1 : 0; assign #2 CSR_W[12'h180] = (CSRArrayOld[12'h180] != CSRArray[12'h180]) ? 1 : 0;
assign #2 CSR_W[12'h140] = (CSRArrayOld[12'h140] != CSRArray[12'h140]) ? 1 : 0; assign #2 CSR_W[12'h140] = (CSRArrayOld[12'h140] != CSRArray[12'h140]) ? 1 : 0;
assign #2 CSR_W[12'h143] = (CSRArrayOld[12'h143] != CSRArray[12'h143]) ? 1 : 0; assign #2 CSR_W[12'h143] = (CSRArrayOld[12'h143] != CSRArray[12'h143]) ? 1 : 0;
@ -394,6 +402,7 @@ module wallyTracer(rvviTrace rvvi);
assign rvvi.csr_wb[0][0][12'h303] = CSR_W[12'h303]; assign rvvi.csr_wb[0][0][12'h303] = CSR_W[12'h303];
assign rvvi.csr_wb[0][0][12'h344] = CSR_W[12'h344]; assign rvvi.csr_wb[0][0][12'h344] = CSR_W[12'h344];
assign rvvi.csr_wb[0][0][12'h304] = CSR_W[12'h304]; assign rvvi.csr_wb[0][0][12'h304] = CSR_W[12'h304];
assign rvvi.csr_wb[0][0][12'h30A] = CSR_W[12'h30A];
assign rvvi.csr_wb[0][0][12'h301] = CSR_W[12'h301]; assign rvvi.csr_wb[0][0][12'h301] = CSR_W[12'h301];
assign rvvi.csr_wb[0][0][12'hF14] = CSR_W[12'hF14]; assign rvvi.csr_wb[0][0][12'hF14] = CSR_W[12'hF14];
assign rvvi.csr_wb[0][0][12'h340] = CSR_W[12'h340]; assign rvvi.csr_wb[0][0][12'h340] = CSR_W[12'h340];
@ -411,6 +420,7 @@ module wallyTracer(rvviTrace rvvi);
assign rvvi.csr_wb[0][0][12'h105] = CSR_W[12'h105]; assign rvvi.csr_wb[0][0][12'h105] = CSR_W[12'h105];
assign rvvi.csr_wb[0][0][12'h141] = CSR_W[12'h141]; assign rvvi.csr_wb[0][0][12'h141] = CSR_W[12'h141];
assign rvvi.csr_wb[0][0][12'h106] = CSR_W[12'h106]; assign rvvi.csr_wb[0][0][12'h106] = CSR_W[12'h106];
assign rvvi.csr_wb[0][0][12'h10A] = CSR_W[12'h10A];
assign rvvi.csr_wb[0][0][12'h180] = CSR_W[12'h180]; assign rvvi.csr_wb[0][0][12'h180] = CSR_W[12'h180];
assign rvvi.csr_wb[0][0][12'h140] = CSR_W[12'h140]; assign rvvi.csr_wb[0][0][12'h140] = CSR_W[12'h140];
assign rvvi.csr_wb[0][0][12'h143] = CSR_W[12'h143]; assign rvvi.csr_wb[0][0][12'h143] = CSR_W[12'h143];
@ -431,6 +441,7 @@ module wallyTracer(rvviTrace rvvi);
assign rvvi.csr[0][0][12'h303] = CSRArray[12'h303]; assign rvvi.csr[0][0][12'h303] = CSRArray[12'h303];
assign rvvi.csr[0][0][12'h344] = CSRArray[12'h344]; assign rvvi.csr[0][0][12'h344] = CSRArray[12'h344];
assign rvvi.csr[0][0][12'h304] = CSRArray[12'h304]; assign rvvi.csr[0][0][12'h304] = CSRArray[12'h304];
assign rvvi.csr[0][0][12'h30A] = CSRArray[12'h30A];
assign rvvi.csr[0][0][12'h301] = CSRArray[12'h301]; assign rvvi.csr[0][0][12'h301] = CSRArray[12'h301];
assign rvvi.csr[0][0][12'hF14] = CSRArray[12'hF14]; assign rvvi.csr[0][0][12'hF14] = CSRArray[12'hF14];
assign rvvi.csr[0][0][12'h340] = CSRArray[12'h340]; assign rvvi.csr[0][0][12'h340] = CSRArray[12'h340];
@ -448,6 +459,7 @@ module wallyTracer(rvviTrace rvvi);
assign rvvi.csr[0][0][12'h105] = CSRArray[12'h105]; assign rvvi.csr[0][0][12'h105] = CSRArray[12'h105];
assign rvvi.csr[0][0][12'h141] = CSRArray[12'h141]; assign rvvi.csr[0][0][12'h141] = CSRArray[12'h141];
assign rvvi.csr[0][0][12'h106] = CSRArray[12'h106]; assign rvvi.csr[0][0][12'h106] = CSRArray[12'h106];
assign rvvi.csr[0][0][12'h10A] = CSRArray[12'h10A];
assign rvvi.csr[0][0][12'h180] = CSRArray[12'h180]; assign rvvi.csr[0][0][12'h180] = CSRArray[12'h180];
assign rvvi.csr[0][0][12'h140] = CSRArray[12'h140]; assign rvvi.csr[0][0][12'h140] = CSRArray[12'h140];
assign rvvi.csr[0][0][12'h143] = CSRArray[12'h143]; assign rvvi.csr[0][0][12'h143] = CSRArray[12'h143];

View File

@ -113,8 +113,6 @@ module testbenchfp;
`include "parameter-defs.vh" `include "parameter-defs.vh"
/////////////////////////////////////////////////////////////////////////////////////////////// ///////////////////////////////////////////////////////////////////////////////////////////////
// ||||||||| |||||||| ||||||| ||||||||| ||||||| |||||||| ||| // ||||||||| |||||||| ||||||| ||||||||| ||||||| |||||||| |||
@ -680,11 +678,11 @@ module testbenchfp;
// instantiate devices under test // instantiate devices under test
if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "sub" | TEST === "all") begin : fma if (TEST === "fma"| TEST === "mul" | TEST === "add" | TEST === "sub" | TEST === "all") begin : fma
fma #(P) fma(.Xs(Xs), .Ys(Ys), .Zs(Zs), fma #(P) fma(.Xs(Xs), .Ys(Ys), .Zs(Zs),
.Xe(Xe), .Ye(Ye), .Ze(Ze), .Xe(Xe), .Ye(Ye), .Ze(Ze),
.Xm(Xm), .Ym(Ym), .Zm(Zm), .Xm(Xm), .Ym(Ym), .Zm(Zm),
.XZero, .YZero, .ZZero, .Ss, .Se, .XZero, .YZero, .ZZero, .Ss, .Se,
.OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps, .OpCtrl(OpCtrlVal), .Sm, .InvA, .SCnt, .As, .Ps,
.ASticky); .ASticky);
end end
postprocess #(P) postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]), postprocess #(P) postprocess(.Xs(Xs), .Ys(Ys), .PostProcSel(UnitVal[1:0]),
@ -699,13 +697,13 @@ module testbenchfp;
.PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes)); .PostProcFlg(Flg), .PostProcRes(FpRes), .FCvtIntRes(IntRes));
if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt if (TEST === "cvtfp" | TEST === "cvtint" | TEST === "all") begin : fcvt
fcvt #(P) fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal), fcvt fcvt (.Xs(Xs), .Xe(Xe), .Xm(Xm), .Int(SrcA), .ToInt(WriteIntVal),
.XZero(XZero), .OpCtrl(OpCtrlVal), .IntZero, .XZero(XZero), .OpCtrl(OpCtrlVal), .IntZero,
.Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE)); .Fmt(ModFmt), .Ce(CvtCalcExpE), .ShiftAmt(CvtShiftAmtE), .ResSubnormUf(CvtResSubnormUfE), .Cs(CvtResSgnE), .LzcIn(CvtLzcInE));
end end
if (TEST === "cmp" | TEST === "all") begin: fcmp if (TEST === "cmp" | TEST === "all") begin: fcmp
fcmp #(P) fcmp (.Fmt(ModFmt), .OpCtrl(OpCtrlVal), .Xs, .Ys, .Xe, .Ye, fcmp fcmp (.Fmt(ModFmt), .OpCtrl(OpCtrlVal), .Xs, .Ys, .Xe, .Ye,
.Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes), .Xm, .Ym, .XZero, .YZero, .CmpIntRes(CmpRes),
.XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes)); .XNaN, .YNaN, .XSNaN, .YSNaN, .X, .Y, .CmpNV(CmpFlg[4]), .CmpFpRes(FpCmpRes));
end end
@ -892,13 +890,13 @@ always @(negedge clk) begin
// check if result is correct // check if result is correct
// - wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage) // - wait till the division result is done or one extra cylcle for early termination (to simulate the EM pipline stage)
// if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&~((FDivBusyE===1'b1)|DivStart)&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin // if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&~((FDivBusyE===1'b1)|DivStart)&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin
ResMatch = (Res === Ans | NaNGood | NaNGood === 1'bx); assign ResMatch = (Res === Ans | NaNGood | NaNGood === 1'bx);
FlagMatch = (ResFlg === AnsFlg | AnsFlg === 5'bx); assign FlagMatch = (ResFlg === AnsFlg | AnsFlg === 5'bx);
divsqrtop = OpCtrlVal == `SQRT_OPCTRL | OpCtrlVal == `DIV_OPCTRL; assign divsqrtop = OpCtrlVal == `SQRT_OPCTRL | OpCtrlVal == `DIV_OPCTRL;
assign DivDone = OldFDivBusyE & ~FDivBusyE; assign DivDone = OldFDivBusyE & ~FDivBusyE;
//assign divsqrtop = OpCtrl[TestNum] == `SQRT_OPCTRL | OpCtrl[TestNum] == `DIV_OPCTRL; //assign divsqrtop = OpCtrl[TestNum] == `SQRT_OPCTRL | OpCtrl[TestNum] == `DIV_OPCTRL;
CheckNow = (DivDone | ~divsqrtop) & (UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT); assign CheckNow = (DivDone | ~divsqrtop) & (UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT);
if(~(ResMatch & FlagMatch) & CheckNow) begin if(~(ResMatch & FlagMatch) & CheckNow) begin
// if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&(DivDone | (TEST != "sqrt" & TEST != "div"))&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin // if(~((Res === Ans | NaNGood | NaNGood === 1'bx) & (ResFlg === AnsFlg | AnsFlg === 5'bx))&(DivDone | (TEST != "sqrt" & TEST != "div"))&(UnitVal !== `CVTINTUNIT)&(UnitVal !== `CMPUNIT)) begin
errors += 1; errors += 1;
@ -974,10 +972,10 @@ module readvectors (
output logic [`FLEN-1:0] Ans, output logic [`FLEN-1:0] Ans,
output logic [`XLEN-1:0] SrcA, output logic [`XLEN-1:0] SrcA,
output logic [4:0] AnsFlg, output logic [4:0] AnsFlg,
output logic Xs, Ys, Zs, // sign bits of XYZ output logic Xs, Ys, Zs, // sign bits of XYZ
output logic [`NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision) output logic [`NE-1:0] Xe, Ye, Ze, // exponents of XYZ (converted to largest supported precision)
output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision) output logic [`NF:0] Xm, Ym, Zm, // mantissas of XYZ (converted to largest supported precision)
output logic XNaN, YNaN, ZNaN, // is XYZ a NaN output logic XNaN, YNaN, ZNaN, // is XYZ a NaN
output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN output logic XSNaN, YSNaN, ZSNaN, // is XYZ a signaling NaN
output logic XSubnorm, ZSubnorm, // is XYZ denormalized output logic XSubnorm, ZSubnorm, // is XYZ denormalized
output logic XZero, YZero, ZZero, // is XYZ zero output logic XZero, YZero, ZZero, // is XYZ zero
@ -986,6 +984,7 @@ module readvectors (
output logic DivStart, output logic DivStart,
output logic [`FLEN-1:0] X, Y, Z, XPostBox output logic [`FLEN-1:0] X, Y, Z, XPostBox
); );
logic XEn, YEn, ZEn; logic XEn, YEn, ZEn;
`include "parameter-defs.vh" `include "parameter-defs.vh"
@ -1346,7 +1345,6 @@ module readvectors (
assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT)|((Unit == `DIVUNIT)&OpCtrl[0])); assign YEn = ~((Unit == `CVTINTUNIT)|(Unit == `CVTFPUNIT)|((Unit == `DIVUNIT)&OpCtrl[0]));
assign ZEn = (Unit == `FMAUNIT); assign ZEn = (Unit == `FMAUNIT);
unpack #(P) unpack(.X, .Y, .Z, .Fmt(ModFmt), .Xs, .Ys, .Zs, .Xe, .Ye, .Ze, unpack #(P) unpack(.X, .Y, .Z, .Fmt(ModFmt), .Xs, .Ys, .Zs, .Xe, .Ye, .Ze,
.Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN, .Xm, .Ym, .Zm, .XNaN, .YNaN, .ZNaN, .XSNaN, .YSNaN, .ZSNaN,
.XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf, .XSubnorm, .XZero, .YZero, .ZZero, .XInf, .YInf, .ZInf,

View File

@ -866,10 +866,12 @@ module testbench;
"medeleg": `checkCSR(`CSR_BASE.csrm.MEDELEG_REGW) "medeleg": `checkCSR(`CSR_BASE.csrm.MEDELEG_REGW)
"mepc": `checkCSR(`CSR_BASE.csrm.MEPC_REGW) "mepc": `checkCSR(`CSR_BASE.csrm.MEPC_REGW)
"mtval": `checkCSR(`CSR_BASE.csrm.MTVAL_REGW) "mtval": `checkCSR(`CSR_BASE.csrm.MTVAL_REGW)
"menvcfg": `checkCSR(`CSR_BASE.csrm.MENVCFG_REGW)
"sepc": `checkCSR(`CSR_BASE.csrs.csrs.SEPC_REGW) "sepc": `checkCSR(`CSR_BASE.csrs.csrs.SEPC_REGW)
"scause": `checkCSR(`CSR_BASE.csrs.csrs.SCAUSE_REGW) "scause": `checkCSR(`CSR_BASE.csrs.csrs.SCAUSE_REGW)
"stvec": `checkCSR(`CSR_BASE.csrs.csrs.STVEC_REGW) "stvec": `checkCSR(`CSR_BASE.csrs.csrs.STVEC_REGW)
"stval": `checkCSR(`CSR_BASE.csrs.csrs.STVAL_REGW) "stval": `checkCSR(`CSR_BASE.csrs.csrs.STVAL_REGW)
"senvcfg": `checkCSR(`CSR_BASE.csrs.SENVCFG_REGW)
"mip": begin "mip": begin
`checkCSR(`CSR_BASE.csrm.MIP_REGW) `checkCSR(`CSR_BASE.csrm.MIP_REGW)
if(!NO_SPOOFING) begin if(!NO_SPOOFING) begin

View File

@ -33,5 +33,8 @@ main:
csrrw t0, satp, zero csrrw t0, satp, zero
csrrw t0, stvec, zero csrrw t0, stvec, zero
csrrw t0, sscratch, zero csrrw t0, sscratch, zero
li t0, -2
csrrw t1, menvcfg, t0
csrrw t2, senvcfg, t0
j done j done

View File

@ -1,3 +1,5 @@
FFFFFFFF # stimecmp readback
80000000 # menvcfg readback
00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts # skipping instruction address fault since they're impossible with compressed instrs enabled 00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts # skipping instruction address fault since they're impossible with compressed instrs enabled
00000001 # mcause from an instruction access fault 00000001 # mcause from an instruction access fault
00000000 # mtval of faulting instruction address (0x0) 00000000 # mtval of faulting instruction address (0x0)

View File

@ -280,7 +280,7 @@ end_trap_triggers:
la t4, 0x02004000 // MTIMECMP register in CLINT la t4, 0x02004000 // MTIMECMP register in CLINT
li t5, 0xFFFFFFFF li t5, 0xFFFFFFFF
sw t5, 0(t4) // set mtimecmp to 0xFFFFFFFF to really make sure time interrupts don't go off immediately after being enabled sw t5, 0(t4) // set mtimecmp to 0xFFFFFFFF to really make sure time interrupts don't go off immediately after being enabled
j trap_handler_end_\MODE\() // skip the trap handler when it is being defined. j trap_handler_end_\MODE\() // skip the trap handler when it is being defined.
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------

View File

@ -23,7 +23,7 @@
#include "WALLY-TEST-LIB-32.h" #include "WALLY-TEST-LIB-32.h"
RVTEST_ISA("RV32I_Zicsr") RVTEST_ISA("RV32I_Sstc_Zicsr")
RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*); def Drvtest_mtrap_routine=True;def TEST_CASE_1=True;def NO_SAIL=True;",trap) RVTEST_CASE(0,"//check ISA:=regex(.*32.*);check ISA:=regex(.*I.*); def Drvtest_mtrap_routine=True;def TEST_CASE_1=True;def NO_SAIL=True;",trap)
INIT_TESTS INIT_TESTS
@ -34,8 +34,9 @@ TRAP_HANDLER m, EXT_SIGNATURE=1 // turn on recording mtval and status bits on tr
li x28, 0x8 li x28, 0x8
csrs mstatus, x28 // set mstatus.MIE bit to 1 csrs mstatus, x28 // set mstatus.MIE bit to 1
WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources // *** commented out until I can get the trap handler (and spike for time interrupts) to work correctly with interrupts WRITE_READ_CSR stimecmp, 0xFFFFFFFF // set timer to high value so it doesn't go off immediately
WRITE_READ_CSR menvcfgh, 0x80000000 // Enable menvcfg.STCE
WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources
// test 5.3.1.4 Basic trap tests // test 5.3.1.4 Basic trap tests
// instr address misaligned instructions are excluded from this test since they are impossible to cause when compressed instructions are enabled. // instr address misaligned instructions are excluded from this test since they are impossible to cause when compressed instructions are enabled.

View File

@ -1,3 +1,7 @@
FFFFFFFF # stimecmp low bits
00000000 # stimecmp high bits
00000000 # menvcfg low bits
80000000 # menvcfg high bits
00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts 00000aaa # Test 5.3.1.4: readback value from writing mie to enable interrupts
00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled 00000000 # skipping instruction address fault since they're impossible with compressed instrs enabled
00000001 # mcause from an instruction access fault 00000001 # mcause from an instruction access fault

View File

@ -274,7 +274,7 @@ end_trap_triggers:
la t4, 0x02004000 // MTIMECMP register in CLINT la t4, 0x02004000 // MTIMECMP register in CLINT
li t5, 0xFFFFFFFF li t5, 0xFFFFFFFF
sd t5, 0(t4) // set mtimecmp to 0xFFFFFFFF to really make sure time interrupts don't go off immediately after being enabled sd t5, 0(t4) // set mtimecmp to 0xFFFFFFFF to really make sure time interrupts don't go off immediately after being enabled
j trap_handler_end_\MODE\() // skip the trap handler when it is being defined. j trap_handler_end_\MODE\() // skip the trap handler when it is being defined.
// --------------------------------------------------------------------------------------------- // ---------------------------------------------------------------------------------------------

View File

@ -22,7 +22,7 @@
/////////////////////////////////////////// ///////////////////////////////////////////
#include "WALLY-TEST-LIB-64.h" #include "WALLY-TEST-LIB-64.h"
RVTEST_ISA("RV64I_Zicsr") RVTEST_ISA("RV64I_Sstc_Zicsr")
RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True;",trap) RVTEST_CASE(0,"//check ISA:=regex(.*64.*);check ISA:=regex(.*I.*);def TEST_CASE_1=True;def NO_SAIL=True;",trap)
INIT_TESTS INIT_TESTS
@ -33,7 +33,9 @@ TRAP_HANDLER m, EXT_SIGNATURE=1 // turn on recording mtval and status bits on tr
li x28, 0x8 li x28, 0x8
csrs mstatus, x28 // set mstatus.MIE bit to 1 csrs mstatus, x28 // set mstatus.MIE bit to 1
WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources WRITE_READ_CSR stimecmp, 0xFFFFFFFF // set timer to high value so it doesn't go off immediately
WRITE_READ_CSR menvcfg, 0x8000000000000000 // Enable menvcfg.STCE
WRITE_READ_CSR mie, 0xFFF // Enable interrupts from all sources
// test 5.3.1.4 Basic trap tests // test 5.3.1.4 Basic trap tests