diff --git a/.gitignore b/.gitignore index cfde0fa6..9c0f454d 100644 --- a/.gitignore +++ b/.gitignore @@ -39,3 +39,13 @@ wally-pipelined/linux-testgen/buildroot-config-src/linux.config.old wally-pipelined/linux-testgen/buildroot-config-src/busybox.config.old wally-pipelined/regression/slack-notifier/slack-webhook-url.txt +/testsBP/fpga-test-dram/bin/blink-led +/testsBP/fpga-test-dram/bin/blink-led.memfile +/testsBP/fpga-test-dram/bin/blink-led.objdump +/testsBP/fpga-test-dram/bin/blink-led.objdump.addr +/testsBP/fpga-test-dram/bin/blink-led.objdump.lab +/testsBP/fpga-test-sdc/bin/fpga-test-sdc +/testsBP/fpga-test-sdc/bin/fpga-test-sdc.memfile +/testsBP/fpga-test-sdc/bin/fpga-test-sdc.objdump +/testsBP/fpga-test-sdc/bin/fpga-test-sdc.objdump.addr +/testsBP/fpga-test-sdc/bin/fpga-test-sdc.objdump.lab diff --git a/testsBP/fpga-test-dram/Makefile b/testsBP/fpga-test-dram/Makefile new file mode 100644 index 00000000..df754441 --- /dev/null +++ b/testsBP/fpga-test-dram/Makefile @@ -0,0 +1,112 @@ +CEXT := c +CPPEXT := cpp +AEXT := s +SEXT := S +SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\) +OBJEXT := o +DEPEXT := d +SRCDIR := . +BUILDDIR := OBJ + +SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort) +OBJECTS := $(SOURCES:.$(CEXT)=.$(OBJEXT)) +OBJECTS := $(OBJECTS:.$(AEXT)=.$(OBJEXT)) +OBJECTS := $(OBJECTS:.$(SEXT)=.$(OBJEXT)) +OBJECTS := $(OBJECTS:.$(CPPEXT)=.$(OBJEXT)) +OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS)) + +TARGETDIR := bin +TARGET := $(TARGETDIR)/blink-led +ROOT := .. +LIBRARY_DIRS := +LIBRARY_FILES := + +MARCH :=-march=rv64imfdc +MABI :=-mabi=lp64d +LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles +LINKER :=$(ROOT)/linker1000.x + + +AFLAGS =$(MARCH) $(MABI) -W +CFLAGS =$(MARCH) $(MABI) -mcmodel=medany -O2 +AS=riscv64-unknown-elf-as +CC=riscv64-unknown-elf-gcc +AR=riscv64-unknown-elf-ar + + +#Default Make +all: directories $(TARGET).memfile + +#Remake +remake: clean all + +#Make the Directories +directories: + @mkdir -p $(TARGETDIR) + @mkdir -p $(BUILDDIR) + +clean: + rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump + + +#Needed for building additional library projects +ifdef LIBRARY_DIRS +LIBS+=${LIBRARY_DIRS:%=-L%} ${LIBRARY_FILES:%=-l%} +INC+=${LIBRARY_DIRS:%=-I%} + +${LIBRARY_DIRS}: + make -C $@ -j 1 + +.PHONY: $(LIBRARY_DIRS) $(TARGET) +endif + + +#Pull in dependency info for *existing* .o files +-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT)) + +#Link +$(TARGET): $(OBJECTS) $(LIBRARY_DIRS) + $(CC) $(LINK_FLAGS) -g -o $(TARGET) $(OBJECTS) ${LIBS} -T ${LINKER} + + +#Compile +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list + @$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CEXT) > $(BUILDDIR)/$*.$(DEPEXT) + @cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp + @sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT) + @sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT) + @rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp + +# gcc won't output dependencies for assembly files for some reason +# most asm files don't have dependencies so the echo will work for now. +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(AEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -c -o $@ $< > $(BUILDDIR)/$*.list + @echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT) + +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list + @echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT) + +# C++ +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list + @$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CPPEXT) > $(BUILDDIR)/$*.$(DEPEXT) + @cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp + @sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT) + @sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT) + @rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp + +# convert to hex +$(TARGET).memfile: $(TARGET) + @echo 'Making object dump file.' + @riscv64-unknown-elf-objdump -D $< > $<.objdump + @echo 'Making memory file' + exe2memfile0.pl $< + extractFunctionRadix.sh $<.objdump + mkdir -p ../../imperas-riscv-tests/work/rv64BP/ + cp -f $(TARGETDIR)/* ../../imperas-riscv-tests/work/rv64BP/ diff --git a/testsBP/fpga-test-dram/blink-led.s b/testsBP/fpga-test-dram/blink-led.s new file mode 100644 index 00000000..7c44d8e9 --- /dev/null +++ b/testsBP/fpga-test-dram/blink-led.s @@ -0,0 +1,130 @@ +PERIOD = 22000000 +#PERIOD = 100 + +.section .init +.global _start +.type _start, @function + + +_start: + # Initialize global pointer + .option push + .option norelax + 1:auipc gp, %pcrel_hi(__global_pointer$) + addi gp, gp, %pcrel_lo(1b) + .option pop + + li x1, 0 + li x2, 0 + li x4, 0 + li x5, 0 + li x6, 0 + li x7, 0 + li x8, 0 + li x9, 0 + li x10, 0 + li x11, 0 + li x12, 0 + li x13, 0 + li x14, 0 + li x15, 0 + li x16, 0 + li x17, 0 + li x18, 0 + li x19, 0 + li x20, 0 + li x21, 0 + li x22, 0 + li x23, 0 + li x24, 0 + li x25, 0 + li x26, 0 + li x27, 0 + li x28, 0 + li x29, 0 + li x30, 0 + li x31, 0 + + # write to gpio + li x2, 0xFF + la x3, 0x10012000 + + # +8 is output enable + # +C is output value + + addi x4, x3, 8 + addi x5, x3, 0xC + + # write initial value of 0xFF to GPO + sw x2, 0x0(x5) + # enable output + sw x2, 0x0(x4) + + # before jumping to led loop + # lets try writting to dram. + + li x21, 0 + li x23, 4096*16 # 64KB of data + + li x22, 0x80000000 + li x24, 0 + +write_loop: + add x25, x22, x24 + sw x24, 0(x25) + addi x24, x24, 4 + blt x24, x23, write_loop + + li x24, 0 +read_loop: + add x25, x22, x24 + lw x21, 0(x25) + + # check value + bne x21, x24, fail_loop + + addi x24, x24, 4 + + # + blt x24, x23, read_loop + + + +loop: + + # delay + li x20, PERIOD +delay1: + addi x20, x20, -1 + bge x20, x0, delay1 + + # new GPO + addi x2, x2, 1 + sw x2, 0x0(x5) + + j loop + + +fail_loop: + + # delay + li x20, PERIOD/20 +fail_delay1: + addi x20, x20, -1 + bge x20, x0, fail_delay1 + + # clear GPO + sw x0, 0x0(x5) + + # delay + li x20, PERIOD/20 +fail_delay2: + addi x20, x20, -1 + bge x20, x0, fail_delay2 + + # write GPO + sw x2, 0x0(x5) + + j fail_loop + + diff --git a/testsBP/fpga-test-sdc/Makefile b/testsBP/fpga-test-sdc/Makefile new file mode 100644 index 00000000..0c6d3666 --- /dev/null +++ b/testsBP/fpga-test-sdc/Makefile @@ -0,0 +1,112 @@ +CEXT := c +CPPEXT := cpp +AEXT := s +SEXT := S +SRCEXT := \([$(CEXT)$(AEXT)$(SEXT)]\|$(CPPEXT)\) +OBJEXT := o +DEPEXT := d +SRCDIR := . +BUILDDIR := OBJ + +SOURCES ?= $(shell find $(SRCDIR) -type f -regex ".*\.$(SRCEXT)" | sort) +OBJECTS := $(SOURCES:.$(CEXT)=.$(OBJEXT)) +OBJECTS := $(OBJECTS:.$(AEXT)=.$(OBJEXT)) +OBJECTS := $(OBJECTS:.$(SEXT)=.$(OBJEXT)) +OBJECTS := $(OBJECTS:.$(CPPEXT)=.$(OBJEXT)) +OBJECTS := $(patsubst $(SRCDIR)/%,$(BUILDDIR)/%,$(OBJECTS)) + +TARGETDIR := bin +TARGET := $(TARGETDIR)/fpga-test-sdc +ROOT := .. +LIBRARY_DIRS := +LIBRARY_FILES := + +MARCH :=-march=rv64imfdc +MABI :=-mabi=lp64d +LINK_FLAGS :=$(MARCH) $(MABI) -nostartfiles +LINKER :=$(ROOT)/linker1000.x + + +AFLAGS =$(MARCH) $(MABI) -W +CFLAGS =$(MARCH) $(MABI) -mcmodel=medany -O2 +AS=riscv64-unknown-elf-as +CC=riscv64-unknown-elf-gcc +AR=riscv64-unknown-elf-ar + + +#Default Make +all: directories $(TARGET).memfile + +#Remake +remake: clean all + +#Make the Directories +directories: + @mkdir -p $(TARGETDIR) + @mkdir -p $(BUILDDIR) + +clean: + rm -rf $(BUILDDIR) $(TARGETDIR) *.memfile *.objdump + + +#Needed for building additional library projects +ifdef LIBRARY_DIRS +LIBS+=${LIBRARY_DIRS:%=-L%} ${LIBRARY_FILES:%=-l%} +INC+=${LIBRARY_DIRS:%=-I%} + +${LIBRARY_DIRS}: + make -C $@ -j 1 + +.PHONY: $(LIBRARY_DIRS) $(TARGET) +endif + + +#Pull in dependency info for *existing* .o files +-include $(OBJECTS:.$(OBJEXT)=.$(DEPEXT)) + +#Link +$(TARGET): $(OBJECTS) $(LIBRARY_DIRS) + $(CC) $(LINK_FLAGS) -g -o $(TARGET) $(OBJECTS) ${LIBS} -T ${LINKER} + + +#Compile +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list + @$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CEXT) > $(BUILDDIR)/$*.$(DEPEXT) + @cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp + @sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT) + @sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT) + @rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp + +# gcc won't output dependencies for assembly files for some reason +# most asm files don't have dependencies so the echo will work for now. +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(AEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) -c -o $@ $< > $(BUILDDIR)/$*.list + @echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT) + +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(SEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list + @echo $@: $< > $(BUILDDIR)/$*.$(DEPEXT) + +# C++ +$(BUILDDIR)/%.$(OBJEXT): $(SRCDIR)/%.$(CPPEXT) + @mkdir -p $(dir $@) + $(CC) $(CFLAGS) $(INC) -c -o $@ $< > $(BUILDDIR)/$*.list + @$(CC) $(CFLAGS) $(INC) -MM $(SRCDIR)/$*.$(CPPEXT) > $(BUILDDIR)/$*.$(DEPEXT) + @cp -f $(BUILDDIR)/$*.$(DEPEXT) $(BUILDDIR)/$*.$(DEPEXT).tmp + @sed -e 's|.*:|$(BUILDDIR)/$*.$(OBJEXT):|' < $(BUILDDIR)/$*.$(DEPEXT).tmp > $(BUILDDIR)/$*.$(DEPEXT) + @sed -e 's/.*://' -e 's/\\$$//' < $(BUILDDIR)/$*.$(DEPEXT).tmp | fmt -1 | sed -e 's/^ *//' -e 's/$$/:/' >> $(BUILDDIR)/$*.$(DEPEXT) + @rm -f $(BUILDDIR)/$*.$(DEPEXT).tmp + +# convert to hex +$(TARGET).memfile: $(TARGET) + @echo 'Making object dump file.' + @riscv64-unknown-elf-objdump -D $< > $<.objdump + @echo 'Making memory file' + exe2memfile0.pl $< + extractFunctionRadix.sh $<.objdump + mkdir -p ../../imperas-riscv-tests/work/rv64BP/ + cp -f $(TARGETDIR)/* ../../imperas-riscv-tests/work/rv64BP/ diff --git a/testsBP/fpga-test-sdc/copyFlash.c b/testsBP/fpga-test-sdc/copyFlash.c new file mode 100644 index 00000000..d9c6c2e5 --- /dev/null +++ b/testsBP/fpga-test-sdc/copyFlash.c @@ -0,0 +1,40 @@ +/////////////////////////////////////////// +// copyFlash.sv +// +// Written: Ross Thompson September 25, 2021 +// Modified: +// +// Purpose: copies flash card into memory +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +#include "sdcDriver.h" + +void copyFlash(long int blockAddr, long int * Dst, int numBlocks) { + + setSDCCLK(1); + waitInitSDC(); + + int index; + + for(index = 0; index < numBlocks; index++) { + copySDC512(blockAddr+(index*512), Dst+(512/8)); + } + + +} diff --git a/testsBP/fpga-test-sdc/sdcDriver.c b/testsBP/fpga-test-sdc/sdcDriver.c new file mode 100644 index 00000000..3c69b7d4 --- /dev/null +++ b/testsBP/fpga-test-sdc/sdcDriver.c @@ -0,0 +1,68 @@ +/////////////////////////////////////////// +// SDC.sv +// +// Written: Ross Thompson September 25, 2021 +// Modified: +// +// Purpose: driver for sdc reader. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + + +#include "sdcDriver.h" + +#define SDC_MAIL_BOX 0x12100 + +void copySDC512(long int blockAddr, long int * Dst) { + + waitInitSDC(); + + volatile long int * mailBoxAddr; + volatile int * mailBoxCmd; + volatile int * mailBoxStatus; + volatile long int * mailBoxReadData; + mailBoxStatus = (int *) (SDC_MAIL_BOX + 0x4); + mailBoxCmd = (int *) (SDC_MAIL_BOX + 0x8); + mailBoxAddr = (long int *) (SDC_MAIL_BOX + 0x10); + mailBoxReadData = (long int *) (SDC_MAIL_BOX + 0x18); + + // write the SDC address register with the blockAddr + *mailBoxAddr = blockAddr; + *mailBoxCmd = 0x4; + + // wait until the mailbox has valid data + // this occurs when status[1] = 0 + while((*mailBoxStatus & 0x2) == 0x2); + + int index; + for(index = 0; index < 512/8; index++) { + Dst[index] = *mailBoxReadData; + } +} + +volatile void waitInitSDC(){ + volatile int * mailBoxStatus; + mailBoxStatus = (int *) (SDC_MAIL_BOX + 0x4); + while((*mailBoxStatus & 0x1) != 0x1); +} + +void setSDCCLK(int divider){ + volatile int * mailBoxCLK; + mailBoxCLK = (int *) (SDC_MAIL_BOX + 0x0); + *mailBoxCLK = divider; +} diff --git a/testsBP/fpga-test-sdc/sdcDriver.h b/testsBP/fpga-test-sdc/sdcDriver.h new file mode 100644 index 00000000..7876aeda --- /dev/null +++ b/testsBP/fpga-test-sdc/sdcDriver.h @@ -0,0 +1,9 @@ +#ifndef __SDCDRIVER_H +#define __SDCDRIVER_H + + +void copySDC512(long int, long int *); +volatile void waitInitSDC(); +void setSDCCLK(int); + +#endif diff --git a/testsBP/fpga-test-sdc/test-sdc.s b/testsBP/fpga-test-sdc/test-sdc.s new file mode 100644 index 00000000..4bc98a27 --- /dev/null +++ b/testsBP/fpga-test-sdc/test-sdc.s @@ -0,0 +1,97 @@ +#PERIOD = 22000000 +PERIOD = 20 + +.section .init +.global _start +.type _start, @function + + +_start: + # Initialize global pointer + .option push + .option norelax + 1:auipc gp, %pcrel_hi(__global_pointer$) + addi gp, gp, %pcrel_lo(1b) + .option pop + + li x1, 0 + li x2, 0 + li x4, 0 + li x5, 0 + li x6, 0 + li x7, 0 + li x8, 0 + li x9, 0 + li x10, 0 + li x11, 0 + li x12, 0 + li x13, 0 + li x14, 0 + li x15, 0 + li x16, 0 + li x17, 0 + li x18, 0 + li x19, 0 + li x20, 0 + li x21, 0 + li x22, 0 + li x23, 0 + li x24, 0 + li x25, 0 + li x26, 0 + li x27, 0 + li x28, 0 + li x29, 0 + li x30, 0 + li x31, 0 + + + # set the stack pointer to the top of memory - 8 bytes (pointer size) + li sp, 0x87FFFFF8 + + li a0, 0x20000000 + li a1, 0x80000000 + li a2, 2 + jal ra, copyFlash + + + # now toggle led so we know the copy completed. + + # write to gpio + li t2, 0xFF + la t3, 0x1001200C + li t4, 5 + +loop: + + # delay + li t0, PERIOD/2 +delay1: + addi t0, t0, -1 + bge t0, x0, delay1 + sw t2, 0x0(t3) + + li t0, PERIOD/2 +delay2: + addi t0, t0, -1 + bge t0, x0, delay2 + sw x0, 0x0(t3) + + addi t4, t4, -1 + bgt t4, x0, loop + + + + jal ra, _halt + +.section .text +.global _halt +.type _halt, @function +_halt: + li gp, 1 + li a0, 0 + ecall + j _halt + + + diff --git a/wally-pipelined/bin/exe2memfile0.pl b/wally-pipelined/bin/exe2memfile0.pl new file mode 100755 index 00000000..1b0dad53 --- /dev/null +++ b/wally-pipelined/bin/exe2memfile0.pl @@ -0,0 +1,193 @@ +#!/usr/bin/perl -w + +# exe2memfile.pl +# David_Harris@hmc.edu 26 November 2020 +# Converts an executable file to a series of 32-bit hex instructions +# to read into a Verilog simulation with $readmemh + +use File::stat; +use IO::Handle; + +if ($#ARGV == -1) { + die("Usage: $0 executable_file"); +} + +# array to hold contents of memory file +my @memfilebytes = (0)*16384*4; +my $maxaddress = 0; + +STDOUT->autoflush(1); +# *** Ross Thompson I think there is a bug here needs to be +1 +print ("Processing $#ARGV memfiles: \n"); +my $frac = $#ARGV/10; +for(my $i=0; $i<=$#ARGV; $i++) { + if ($i < 10 || $i % $frac == 0) { print ("$i ") }; + my $fname = $ARGV[$i]; +# print "fname = $fname"; + my $ofile = $fname.".objdump"; + my $memfile = $fname.".memfile"; + + my $needsprocessing = 0; + if (!-e $memfile) { $needsprocessing = 1; } # create memfile if it doesn't exist + else { + my $osb = stat($ofile) || die("Can't stat $ofile"); + my $msb = stat($memfile) || die("Can't stat $memfile"); + my $otime = $osb->mtime; + my $mtime = $msb->mtime; + if ($otime > $mtime) { $needsprocessing = 1; } # is memfile out of date? + } + + if ($needsprocessing == 1) { + open(FILE, $ofile) || die("Can't read $ofile"); + my $mode = 0; # parse for code + my $section = ""; + my $data = ""; + my $address; + my $first = 0; + my $firstAddress; + + # initialize to all zeros; + # *** need to fix the zeroing range. Not always 64K + for (my $i=0; $i < 65536*4; $i++) { + $memfilebytes[$i] = "00"; + } + + while() { + # objdump fill is divided into several .sections of which only some we want to actually process. + # In general we want everything except the .comment and .*attributes + if (/Disassembly of section (.*):/) { + $section = $1; + print ("setting section to $section\n"); + } else { + # now check if the section is one we are interested in processing. + #if ($section ne ".comment" && $section ne ".riscv.attributes" && $section =~ /\.debug.*/) { + if ($section =~ "\.init|\.text|\..*data|\..*bss") { + # the structure is: possible space(s) hex number: possible space(s) hex number space(s) junk + # there are also lines we need to skip: possible space(s) hex number : + if (/^\s*([0-9A-Fa-f]{1,16}):\s+([0-9A-Fa-f]+).*$/) { + $address = &fixadr($1); + if ($first == 0) { + $first = 1; + $firstAddress = $address; + } + $data = $2; + &emitData($address, $data); + # my $len = length($data); + # for (my $i=0; $i<$len/2; $i++) { + # $memfilebytes[$address+$i] = substr($data, $len-2-2*$i, 2); + # } +# print ("Addr $address $data\n"); +# } elsif (/^\s*\.\.\./) { +# print ("Got ...\n"); +# } else { +# print ("No match\n"); + } + } + } +# # *** this mode stuff does not work if a section is missing or reordered. +# if ($mode == 0) { # Parse code +# # print("Examining $_\n"); +# if (/^\s*(\S{1,16}):\s+(\S+)\s+/) { +# $address = &fixadr($1); +# my $instr = $2; +# my $len = length($instr); +# for (my $i=0; $i<$len/2; $i++) { +# $memfilebytes[$address+$i] = substr($instr, $len-2-2*$i, 2); +# } +# print ("address $address $instr\n"); +# } +# if (/Disassembly of section .data:/) { $mode = 1;} +# } elsif ($mode == 1) { # Parse data segment +# if (/^\s*(\S{1,16}):\s+(.*)/) { +# $address = &fixadr($1); +# # print "addresss $address maxaddress $maxaddress\n"; +# if ($address > $maxaddress) { $maxaddress = $address; } +# my $line = $2; +# # merge chunks with spaces +# # *** might need to change +# $line =~ s/(\S)\s(\S)/$1$2/g; +# # strip off comments +# $line =~ /^(\S*)/; +# $payload = $1; +# &emitData($address, $payload); +# } +# if (/Disassembly of section .comment:/) { $mode = 2; } +# } elsif ($mode == 2) { # parse the comment section +# if (/Disassembly of section .riscv.attributes:/) { $mode = 3; } +# } + } + close(FILE); + $maxaddress = $address + 32; # pad some zeros at the end + + # print to memory file + # *** this is a problem + if ($fname =~ /rv32/) { + open(MEMFILE, ">$memfile") || die("Can't write $memfile"); + for (my $i=$firstAddress; $i<= $maxaddress; $i = $i + 4) { + for ($j=3; $j>=0; $j--) { + no warnings 'uninitialized'; + my $value = $memfilebytes[$i+$j]; + if ($value eq ""){ + print MEMFILE "00"; + } else { + print MEMFILE "$memfilebytes[$i+$j]"; + } + } + print MEMFILE "\n"; + } + close(MEMFILE); + } else { + open(MEMFILE, ">$memfile") || die("Can't write $memfile"); + for (my $i=$firstAddress; $i<= $maxaddress; $i = $i + 8) { + for ($j=7; $j>=0; $j--) { + no warnings 'uninitialized'; + my $value = $memfilebytes[$i+$j]; + if ($value eq ""){ + print MEMFILE "00"; + } else { + print MEMFILE "$memfilebytes[$i+$j]"; + } + } + print MEMFILE "\n"; + } + close(MEMFILE); + } + } +} +print("\n"); + +sub emitData { + # print the data portion of the ELF into a memroy file, including 0s for empty stuff + # deal with endianness + my $address = shift; + my $payload = shift; + +# print("Emitting data. address = $address payload = $payload\n"); + + my $len = length($payload); + if ($len <= 8) { + # print word or halfword + for(my $i=0; $i<$len/2; $i++) { + my $adr = $address+$i; + my $b = substr($payload, $len-2-2*$i, 2); + $memfilebytes[$adr] = $b; +# print(" $adr $b\n"); + } + } elsif ($len == 12) { + # weird case of three halfwords on line + &emitData($address, substr($payload, 0, 4)); + &emitData($address+2, substr($payload, 4, 4)); + &emitData($address+4, substr($payload, 8, 4)); + } else { + &emitData($address, substr($payload, 0, 8)); + &emitData($address+4, substr($payload, 8, $len-8)); + } +} + +sub fixadr { + # strip off leading 8 from address and convert to decimal + # if the leading 8 is not present don't remove. + my $adr = shift; + #print "addr $adr\n"; + return hex($adr); +} diff --git a/wally-pipelined/config/buildroot/wally-config.vh b/wally-pipelined/config/buildroot/wally-config.vh index f6373e1a..9d182273 100644 --- a/wally-pipelined/config/buildroot/wally-config.vh +++ b/wally-pipelined/config/buildroot/wally-config.vh @@ -37,8 +37,9 @@ `define XLEN 64 `define MISA (32'h0014112D) -`define ZCSR_SUPPORTED 1 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 `define COUNTERS 32 // Microarchitectural Features @@ -92,6 +93,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 56'h0C000000 `define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h00000020 // Bus Interface width `define AHBW 64 diff --git a/wally-pipelined/config/busybear/wally-config.vh b/wally-pipelined/config/busybear/wally-config.vh index 25394589..e431bd36 100644 --- a/wally-pipelined/config/busybear/wally-config.vh +++ b/wally-pipelined/config/busybear/wally-config.vh @@ -37,8 +37,9 @@ `define XLEN 64 `define MISA (32'h0014112D) -`define ZCSR_SUPPORTED 1 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 `define COUNTERS 32 // Microarchitectural Features @@ -95,6 +96,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 56'h0C000000 `define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h00000020 // Bus Interface width `define AHBW 64 diff --git a/wally-pipelined/config/coremark/wally-config.vh b/wally-pipelined/config/coremark/wally-config.vh index 1706d345..c233d5aa 100644 --- a/wally-pipelined/config/coremark/wally-config.vh +++ b/wally-pipelined/config/coremark/wally-config.vh @@ -36,9 +36,10 @@ //`define MISA (32'h00000104) `define MISA (32'h00000104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -92,6 +93,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 34'h0C000000 `define PLIC_RANGE 34'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h00000020 // Test modes diff --git a/wally-pipelined/config/coremark_bare/wally-config.vh b/wally-pipelined/config/coremark_bare/wally-config.vh index e877db39..6645c473 100644 --- a/wally-pipelined/config/coremark_bare/wally-config.vh +++ b/wally-pipelined/config/coremark_bare/wally-config.vh @@ -37,9 +37,10 @@ //`define MISA (32'h00000104) //`define MISA (32'h00001104 | 1<<5 | 1<<18 | 1 << 20 | 1 << 12 | 1 << 0) `define MISA (32'h00000104 | 0 << 5 | 0 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -96,6 +97,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 56'h0C000000 `define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h00000020 // Test modes diff --git a/wally-pipelined/config/rv32ic/wally-config.vh b/wally-pipelined/config/rv32ic/wally-config.vh index 6325a236..6eeebdd6 100644 --- a/wally-pipelined/config/rv32ic/wally-config.vh +++ b/wally-pipelined/config/rv32ic/wally-config.vh @@ -35,9 +35,10 @@ `define XLEN 32 `define MISA (32'h00000104 | 1 << 20 | 1 << 18 | 1 << 12 | 1 << 0) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -92,6 +93,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 34'h0C000000 `define PLIC_RANGE 34'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 34'h00012100 +`define SDC_RANGE 34'h00000020 // Bus Interface width `define AHBW 32 diff --git a/wally-pipelined/config/rv32icfd/wally-config.vh b/wally-pipelined/config/rv32icfd/wally-config.vh index fbfd1255..82f6ca7e 100644 --- a/wally-pipelined/config/rv32icfd/wally-config.vh +++ b/wally-pipelined/config/rv32icfd/wally-config.vh @@ -35,9 +35,10 @@ `define XLEN 32 `define MISA (32'h00000104 | 1 << 5 | 1 << 20 | 1 << 18 | 1 << 12) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -92,6 +93,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 34'h0C000000 `define PLIC_RANGE 34'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 34'h00012100 +`define SDC_RANGE 34'h00000020 // Bus Interface width `define AHBW 32 diff --git a/wally-pipelined/config/rv64BP/wally-config.vh b/wally-pipelined/config/rv64BP/wally-config.vh index 0085c77b..cc99222f 100644 --- a/wally-pipelined/config/rv64BP/wally-config.vh +++ b/wally-pipelined/config/rv64BP/wally-config.vh @@ -37,9 +37,10 @@ //`define MISA (32'h00000105) `define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -58,15 +59,18 @@ // Cache configuration. Sizes should be a power of two // typical configuration 4 ways, 4096 bytes per way, 256 bit or more blocks `define DCACHE_NUMWAYS 4 -`define DCACHE_WAYSIZEINBYTES 2048 +`define DCACHE_WAYSIZEINBYTES 4096 `define DCACHE_BLOCKLENINBITS 256 `define DCACHE_REPLBITS 3 -`define ICACHE_NUMWAYS 1 +`define ICACHE_NUMWAYS 4 `define ICACHE_WAYSIZEINBYTES 4096 `define ICACHE_BLOCKLENINBITS 256 +// Legal number of PMP entries are 0, 16, or 64 +`define PMP_ENTRIES 64 + // Address space -`define RESET_VECTOR 64'h0000000000000000 +`define RESET_VECTOR 64'h0000000000001000 // Bus Interface width `define AHBW 64 @@ -93,6 +97,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 56'h0C000000 `define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h0000001F // Test modes diff --git a/wally-pipelined/config/rv64ic/wally-config.vh b/wally-pipelined/config/rv64ic/wally-config.vh index 5b3eddb6..58bbaa9e 100644 --- a/wally-pipelined/config/rv64ic/wally-config.vh +++ b/wally-pipelined/config/rv64ic/wally-config.vh @@ -36,9 +36,10 @@ // MISA RISC-V configuration per specification `define MISA (32'h00000104 | 0 << 5 | 0 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -96,6 +97,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 56'h0C000000 `define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h00000020 // Test modes diff --git a/wally-pipelined/config/rv64icfd/wally-config.vh b/wally-pipelined/config/rv64icfd/wally-config.vh index 83a1070f..0bc3ac70 100644 --- a/wally-pipelined/config/rv64icfd/wally-config.vh +++ b/wally-pipelined/config/rv64icfd/wally-config.vh @@ -37,9 +37,10 @@ // MISA RISC-V configuration per specification `define MISA (32'h00000104 | 1 << 5 | 1 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -93,6 +94,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 56'h0C000000 `define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h00000020 // Bus Interface width `define AHBW 64 diff --git a/wally-pipelined/config/rv64imc/wally-config.vh b/wally-pipelined/config/rv64imc/wally-config.vh index 1e8b2437..1240dbbb 100644 --- a/wally-pipelined/config/rv64imc/wally-config.vh +++ b/wally-pipelined/config/rv64imc/wally-config.vh @@ -35,9 +35,10 @@ // MISA RISC-V configuration per specification `define MISA (32'h00000104 | 0 << 5 | 0 << 3 | 1 << 18 | 1 << 20 | 1 << 12 | 1 << 0) -`define ZCSR_SUPPORTED 1 +`define ZICSR_SUPPORTED 1 +`define ZIFENCEI_SUPPORTED 1 `define COUNTERS 32 -`define ZCOUNTERS_SUPPORTED 1 +`define ZICOUNTERS_SUPPORTED 1 // Microarchitectural Features `define UARCH_PIPELINED 1 @@ -91,6 +92,9 @@ `define PLIC_SUPPORTED 1'b1 `define PLIC_BASE 56'h0C000000 `define PLIC_RANGE 56'h03FFFFFF +`define SDC_SUPPORTED 1'b1 +`define SDC_BASE 56'h00012100 +`define SDC_RANGE 56'h00000020 // Test modes diff --git a/wally-pipelined/linux-testgen/testvector-generation/analyzeTrace.py b/wally-pipelined/linux-testgen/testvector-generation/analyzeTrace.py new file mode 100755 index 00000000..629ac3be --- /dev/null +++ b/wally-pipelined/linux-testgen/testvector-generation/analyzeTrace.py @@ -0,0 +1,57 @@ +#! /usr/bin/python3 +import sys,os +import matplotlib.pyplot as plt +import matplotlib.animation as animation +import matplotlib.ticker as ticker + +# Argument Parsing +if len(sys.argv) != 4: + sys.exit('Error analyzeTrace.py expects 3 args:\n ') +traceFile = sys.argv[1] +addressFile = sys.argv[2] +labelFile = sys.argv[3] +if not os.path.exists(traceFile): + sys.exit('Error trace file '+traceFile+'not found') +if not os.path.exists(addressFile): + sys.exit('Error address file '+addressFile+'not found') +if not os.path.exists(labelFile): + sys.exit('Error label file '+labelFile+'not found') + +print('Loading labels') +funcList=[] +with open(addressFile, 'r') as addresses, open(labelFile, 'r') as labels: + for address, label in zip(addresses, labels): + funcList.append([int(address.strip('\n'),16),label.strip('\n'),0]) + +def lookupAdr(address): + labelCount = len(funcList) + guessIndex = labelCount + guessAdr = funcList[guessIndex-1][0] + if address < funcList[0][0]: + return 0 + while (address < guessAdr): + guessIndex-=1 + if guessIndex == -1: + return 0 + guessAdr=funcList[guessIndex][0] + funcList[guessIndex][2] += 1 + #print(funcList[guessIndex][1]) + return 1 + +print('Parsing trace') +with open(traceFile, 'r') as trace: + iCount = 0 + for l in trace: + lookupAdr(int(l.split(' ')[0],16)) + iCount += 1 + if (iCount % 1e5==0): + print('Reached '+str(iCount/1e6)+' million instructions') + +print('Sorting by function frequency') +funcListSorted = sorted(funcList, key=lambda labelEntry: -labelEntry[2]) +with open('traceAnalysis.txt','w') as outFile: + outFile.write('Virtual Address \t'+('%-50s'%'Function')+'Occurences\n') + for labelEntry in funcListSorted: + addr = '%x' % labelEntry[0] + outFile.write(addr+'\t'+('%-50s' % labelEntry[1])+str(labelEntry[2])+'\n') +print('Logged results to traceAnalysis.txt') diff --git a/wally-pipelined/linux-testgen/testvector-generation/analyzeTrace.sh b/wally-pipelined/linux-testgen/testvector-generation/analyzeTrace.sh new file mode 100755 index 00000000..c84660cf --- /dev/null +++ b/wally-pipelined/linux-testgen/testvector-generation/analyzeTrace.sh @@ -0,0 +1 @@ + ./analyzeTrace.py ../linux-testvectors/all.txt ../linux-testvectors/vmlinux.objdump.addr ../linux-testvectors/vmlinux.objdump.lab diff --git a/wally-pipelined/proposed-sdc.txt b/wally-pipelined/proposed-sdc.txt new file mode 100644 index 00000000..893143dd --- /dev/null +++ b/wally-pipelined/proposed-sdc.txt @@ -0,0 +1,55 @@ +SD Flash interface + +regsiter map: +1. clock divider +2. address +3. data register +4. command register +5. size register + Number of bytes to read or write. +6. status register + 1. bits 11 to 0: bytes currently in the buffer + 2. bits 12 to 29: reservered + 3. bit 30: fault + 4. bit 31: busy + 5. bits XLEN-1 to 32: reservered + + + +non dma read operation +1. write the address regsiter +2. write the command register to read +3. wait for interrupt or pool on status +4. Check status for fault and number of bytes. +5. read the data register for 512 bytes. (64 ld, or 128 lw) + + +non dma write operation +1. write address register +2. write data register for 512 bytes. (64 sd, or 128 sw) +3. write command register to write data to flash +4. wait for interrupt or pool on status +5. check status for fault and number of bytes written. + +implement dma transfers later + + +interrupts +1. operation done +2. bus error (more of an exception) + Occurs if attempting to do an operation while the flash controller is busy. + ie. if status[31] is set generate an interrupt + This is tricky in a multiprocessor environment. + + + + +tasks +1. [-] Remove all AFRL identifiers +2. [X] get the existing sdc compiled on wally. + 1. [X] use wally primatives over tcore's +3. build abhlite interface with the above registers and necessary fsm. + 1. [ ] The sd card reader uses a 4 bit data interface. We can change this to be something + more pratical. +4. write test programs +5. [X] Convert VHDL to system verilog diff --git a/wally-pipelined/regression/linux-wave.do b/wally-pipelined/regression/linux-wave.do index c6d6ce3c..10d264d8 100644 --- a/wally-pipelined/regression/linux-wave.do +++ b/wally-pipelined/regression/linux-wave.do @@ -14,41 +14,41 @@ add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/InstrM add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/lsu/MemAdrM add wave -noupdate -expand -group {WriteBack stage} /testbench/dut/hart/ieu/InstrValidW add wave -noupdate -expand -group {WriteBack stage} /testbench/PCW -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/EcallFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/StorePageFaultM -add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InterruptM -add wave -noupdate -group HDU -group interrupts /testbench/dut/hart/priv/trap/PendingIntsM -add wave -noupdate -group HDU -group interrupts /testbench/dut/hart/priv/trap/CommittedM -add wave -noupdate -group HDU -group interrupts /testbench/dut/hart/priv/trap/InstrValidM -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/BPPredWrongE -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/RetM -add wave -noupdate -group HDU -expand -group hazards -color Pink /testbench/dut/hart/hzu/TrapM -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/LoadStallD -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/StoreStallD -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/ICacheStallF -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/hzu/LSUStall -add wave -noupdate -group HDU -expand -group hazards /testbench/dut/hart/MulDivStallD -add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF -add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushD -add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushE -add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushM -add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushW -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallE -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallM -add wave -noupdate -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallW +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/EcallFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StorePageFaultM +add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InterruptM +add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/hart/priv/trap/PendingIntsM +add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/hart/priv/trap/CommittedM +add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/hart/priv/trap/InstrValidM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/RetM +add wave -noupdate -expand -group HDU -group hazards -color Pink /testbench/dut/hart/hzu/TrapM +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/StoreStallD +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/ICacheStallF +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LSUStall +add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/MulDivStallD +add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF +add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushD +add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushE +add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushM +add wave -noupdate -expand -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushW +add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/hart/StallF +add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/hart/StallD +add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/hart/StallE +add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/hart/StallM +add wave -noupdate -expand -group HDU -group Stall -color Orange /testbench/dut/hart/StallW add wave -noupdate -group Bpred -color Orange /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/GHR add wave -noupdate -group Bpred -expand -group {branch update selection inputs} /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/BPPredF add wave -noupdate -group Bpred -expand -group {branch update selection inputs} {/testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/InstrClassE[0]} @@ -158,12 +158,12 @@ add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/Write add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/ALUResultE add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcAE add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcBE -add wave -noupdate -expand -group PCS /testbench/dut/hart/ifu/PCNextF -add wave -noupdate -expand -group PCS /testbench/dut/hart/PCF -add wave -noupdate -expand -group PCS /testbench/dut/hart/ifu/PCD -add wave -noupdate -expand -group PCS /testbench/dut/hart/PCE -add wave -noupdate -expand -group PCS /testbench/dut/hart/PCM -add wave -noupdate -expand -group PCS /testbench/PCW +add wave -noupdate -group PCS /testbench/dut/hart/ifu/PCNextF +add wave -noupdate -group PCS /testbench/dut/hart/PCF +add wave -noupdate -group PCS /testbench/dut/hart/ifu/PCD +add wave -noupdate -group PCS /testbench/dut/hart/PCE +add wave -noupdate -group PCS /testbench/dut/hart/PCM +add wave -noupdate -group PCS /testbench/PCW add wave -noupdate -group muldiv /testbench/dut/hart/mdu/InstrD add wave -noupdate -group muldiv /testbench/dut/hart/mdu/SrcAE add wave -noupdate -group muldiv /testbench/dut/hart/mdu/SrcBE @@ -183,32 +183,33 @@ add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/N add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/D add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/Q add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/rem0 -add wave -noupdate -expand -group icache -color Gold /testbench/dut/hart/ifu/icache/controller/CurrState -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/controller/NextState -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/ITLBMissF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/ITLBWriteF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/ReadLineF -add wave -noupdate -expand -group icache {/testbench/dut/hart/ifu/icache/icachemem/word[0]/CacheDataMem/Addr} -add wave -noupdate -expand -group icache {/testbench/dut/hart/ifu/icache/icachemem/word[0]/CacheDataMem/WriteData} -add wave -noupdate -expand -group icache {/testbench/dut/hart/ifu/icache/icachemem/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/PCNextIndexF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/ReadLineF -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/hit -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spill -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/ICacheStallF -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/SavePC -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/UnalignedSelect -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntReset -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/PreCntEn -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntEn -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/FetchCount -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/ICacheMemWriteData +add wave -noupdate -group icache -color Gold /testbench/dut/hart/ifu/icache/controller/CurrState +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/controller/NextState +add wave -noupdate -group icache /testbench/dut/hart/ifu/ITLBMissF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/ITLBWriteF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/ReadLineF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/PCNextIndexF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/ReadLineF +add wave -noupdate -group icache {/testbench/dut/hart/ifu/icache/MemWay[0]/ValidBits} +add wave -noupdate -group icache {/testbench/dut/hart/ifu/icache/MemWay[1]/ValidBits} +add wave -noupdate -group icache {/testbench/dut/hart/ifu/icache/MemWay[2]/ValidBits} +add wave -noupdate -group icache {/testbench/dut/hart/ifu/icache/MemWay[3]/ValidBits} +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/hit +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spill +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/ICacheStallF +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/SavePC +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/UnalignedSelect +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntReset +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/PreCntEn +add wave -noupdate -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntEn +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/FetchCount +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/ICacheMemWriteData add wave -noupdate -group AHB -color Gold /testbench/dut/hart/ebu/BusState add wave -noupdate -group AHB /testbench/dut/hart/ebu/NextBusState add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/AtomicMaskedM @@ -231,156 +232,170 @@ add wave -noupdate -group AHB /testbench/dut/hart/ebu/HADDRD add wave -noupdate -group AHB /testbench/dut/hart/ebu/HSIZED add wave -noupdate -group AHB /testbench/dut/hart/ebu/HWRITED add wave -noupdate -group AHB /testbench/dut/hart/ebu/StallW -add wave -noupdate -group lsu -expand -group {LSU ARB} /testbench/dut/hart/lsu/arbiter/SelPTW -add wave -noupdate -group lsu -expand -group dcache -color Gold /testbench/dut/hart/lsu/dcache/dcachefsm/CurrState -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/WalkerPageFaultM -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/WriteDataM -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWriteEnableM -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordWriteEnableM -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWayWriteEnable -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordEnable -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWayWriteEnableM -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SelAdrM -add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/DCacheMemWriteData -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetValid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetDirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[0]/CacheTagMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/DirtyBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/ValidBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/DirtyBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/SetDirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WriteWordEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[1]/CacheTagMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/SetValid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/SetDirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[2]/CacheTagMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/DirtyBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/ValidBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetValid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetDirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[3]/CacheTagMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/DirtyBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ValidBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/hart/lsu/dcache/SetValid -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/hart/lsu/dcache/ClearValid -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/hart/lsu/dcache/SetDirty -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/hart/lsu/dcache/ClearDirty -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WayHit} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/Valid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/Dirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/ReadTag} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WayHit} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/Valid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/Dirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/ReadTag} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/WayHit} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/Valid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/Dirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/ReadTag} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WayHit} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/Valid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/Dirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ReadTag} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/WayHit -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataBlockWayMaskedM -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordM -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordMuxM -add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimTag -add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimWay -add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirtyWay -add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirty -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/MemRWM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/MemAdrE -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/MemPAdrM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct3M -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct7M -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/AtomicM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/CacheableM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/WriteDataM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/ReadDataM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/DCacheStall -add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/WayHit -add wave -noupdate -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/hart/lsu/dcache/CacheHit -add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/FetchCount -add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBPAdr -add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBRead -add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBWrite -add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBAck -add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/HRDATA -add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/HWDATA -add wave -noupdate -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/EffectivePrivilegeMode -add wave -noupdate -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/Translate -add wave -noupdate -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/DisableTranslation -add wave -noupdate -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBMiss -add wave -noupdate -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBHit -add wave -noupdate -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/PhysicalAddress -add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/TLBPageFault -add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/LoadAccessFaultM -add wave -noupdate -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/StoreAccessFaultM -add wave -noupdate -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBPAdr -add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/PTE -add wave -noupdate -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBWrite -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PhysicalAddress -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/SelRegions -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Cacheable -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Idempotent -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/AtomicAllowed -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PMAAccessFault -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAInstrAccessFaultF -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMALoadAccessFaultM -add wave -noupdate -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAStoreAccessFaultM -add wave -noupdate -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPInstrAccessFaultF -add wave -noupdate -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPLoadAccessFaultM -add wave -noupdate -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPStoreAccessFaultM -add wave -noupdate -group lsu -group ptwalker -color Gold /testbench/dut/hart/lsu/hptw/genblk1/WalkerState -add wave -noupdate -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/PCF -add wave -noupdate -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/genblk1/TranslationVAdr -add wave -noupdate -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/TranslationPAdr -add wave -noupdate -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/HPTWReadPTE -add wave -noupdate -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/PTE -add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/ITLBMissF -add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/DTLBMissM -add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/ITLBWriteF -add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/DTLBWriteM -add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerInstrPageFaultF -add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerLoadPageFaultM -add wave -noupdate -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerStorePageFaultM +add wave -noupdate -expand -group lsu -expand -group {LSU ARB} /testbench/dut/hart/lsu/arbiter/SelPTW +add wave -noupdate -expand -group lsu -expand -group dcache -color Gold /testbench/dut/hart/lsu/dcache/dcachefsm/CurrState +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/WalkerPageFaultM +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/WriteDataM +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWriteEnableM +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordWriteEnableM +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWayWriteEnable +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordEnable +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWayWriteEnableM +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SelAdrM +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/ReadDataBlockM +add wave -noupdate -expand -group lsu -expand -group dcache -group flush -radix unsigned /testbench/dut/hart/lsu/dcache/FlushAdr +add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/FlushWay +add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/VictimDirtyWay +add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/VictimTag +add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/BasePAdrM +add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/FetchCount +add wave -noupdate -expand -group lsu -expand -group dcache -group flush /testbench/dut/hart/lsu/dcache/CacheableM +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/DCacheMemWriteData +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetValid} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetDirty} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[0]/CacheTagMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/DirtyBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/ValidBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word1 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word2 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way0 -expand -group Way0Word3 {/testbench/dut/hart/lsu/dcache/MemWay[0]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/DirtyBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/ValidBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/SetDirty} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WriteWordEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[1]/CacheTagMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word2 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way1 -expand -group Way1Word3 {/testbench/dut/hart/lsu/dcache/MemWay[1]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/SetValid} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/SetDirty} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[2]/CacheTagMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/DirtyBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/ValidBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word1 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetValid} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetDirty} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ClearDirty} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/VDWriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[3]/CacheTagMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/DirtyBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ValidBits} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/SetValid +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/ClearValid +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/SetDirty +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Cache SRAM writes} -group valid/dirty /testbench/dut/hart/lsu/dcache/ClearDirty +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/RAdr +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WayHit} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/Valid} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/Dirty} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/ReadTag} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/WayHit} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/Valid} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/Dirty} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way1 {/testbench/dut/hart/lsu/dcache/MemWay[1]/ReadTag} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/WayHit} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/Valid} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/Dirty} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/ReadTag} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WayHit} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/Valid} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/Dirty} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ReadTag} +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/WayHit +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataBlockWayMaskedM +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordM +add wave -noupdate -expand -group lsu -expand -group dcache -group {Cache SRAM read} /testbench/dut/hart/lsu/dcache/ReadDataWordMuxM +add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimTag +add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimWay +add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirtyWay +add wave -noupdate -expand -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirty +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemRWM +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemAdrE +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemPAdrM +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct3M +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct7M +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/AtomicM +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/CacheableM +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/FlushDCacheM +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/WriteDataM +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/ReadDataM +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/DCacheStall +add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/WayHit +add wave -noupdate -expand -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/hart/lsu/dcache/CacheHit +add wave -noupdate -expand -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/FetchCount +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBPAdr +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBRead +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBWrite +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBAck +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/HRDATA +add wave -noupdate -expand -group lsu -expand -group dcache -expand -group {Memory Side} /testbench/dut/hart/lsu/dcache/HWDATA +add wave -noupdate -expand -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/FlushWay +add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/EffectivePrivilegeMode +add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/Translate +add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/tlbcontrol/DisableTranslation +add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBMiss +add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/TLBHit +add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/PhysicalAddress +add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/TLBPageFault +add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/LoadAccessFaultM +add wave -noupdate -expand -group lsu -group dtlb -expand -group faults /testbench/dut/hart/lsu/dmmu/StoreAccessFaultM +add wave -noupdate -expand -group lsu -group dtlb /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBPAdr +add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/PTE +add wave -noupdate -expand -group lsu -group dtlb -expand -group write /testbench/dut/hart/lsu/dmmu/genblk1/tlb/TLBWrite +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PhysicalAddress +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/SelRegions +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Cacheable +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/Idempotent +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/AtomicAllowed +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/pmachecker/PMAAccessFault +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAInstrAccessFaultF +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMALoadAccessFaultM +add wave -noupdate -expand -group lsu -group pma /testbench/dut/hart/lsu/dmmu/PMAStoreAccessFaultM +add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPInstrAccessFaultF +add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPLoadAccessFaultM +add wave -noupdate -expand -group lsu -group pmp /testbench/dut/hart/lsu/dmmu/PMPStoreAccessFaultM +add wave -noupdate -expand -group lsu -group ptwalker -color Gold /testbench/dut/hart/lsu/hptw/genblk1/WalkerState +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/PCF +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/genblk1/TranslationVAdr +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/TranslationPAdr +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/HPTWReadPTE +add wave -noupdate -expand -group lsu -group ptwalker /testbench/dut/hart/lsu/hptw/PTE +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/ITLBMissF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/DTLBMissM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/ITLBWriteF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/DTLBWriteM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerInstrPageFaultF +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerLoadPageFaultM +add wave -noupdate -expand -group lsu -group ptwalker -expand -group types /testbench/dut/hart/lsu/hptw/WalkerStorePageFaultM add wave -noupdate -group csr -color Gray90 -radix unsigned /testbench/dut/hart/priv/csr/genblk1/counters/genblk1/INSTRET_REGW add wave -noupdate -group csr /testbench/dut/hart/priv/csr/genblk1/counters/genblk1/HPMCOUNTER_REGW add wave -noupdate -group csr -expand -group machine /testbench/dut/hart/priv/csr/genblk1/csrm/MIE_REGW @@ -469,20 +484,20 @@ add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HSELUART add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HADDR add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HWRITE add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HWDATA -add wave -noupdate -expand -group {debug trace} -expand -group mem -color Yellow /testbench/dut/hart/FlushW -add wave -noupdate -expand -group {debug trace} -expand -group mem /testbench/dut/hart/priv/trap/InstrValidM -add wave -noupdate -expand -group {debug trace} -expand -group mem /testbench/checkInstrM -add wave -noupdate -expand -group {debug trace} -expand -group mem /testbench/dut/hart/PCM -add wave -noupdate -expand -group {debug trace} -expand -group mem /testbench/ExpectedPCM -add wave -noupdate -expand -group {debug trace} -expand -group mem /testbench/line -add wave -noupdate -expand -group {debug trace} -expand -group mem /testbench/textM -add wave -noupdate -expand -group {debug trace} -expand -group mem -color Brown /testbench/dut/hart/hzu/TrapM -add wave -noupdate -expand -group {debug trace} -expand -group wb /testbench/dut/hart/ieu/c/InstrValidW -add wave -noupdate -expand -group {debug trace} -expand -group wb /testbench/checkInstrW -add wave -noupdate -expand -group {debug trace} -expand -group wb /testbench/PCW -add wave -noupdate -expand -group {debug trace} -expand -group wb /testbench/ExpectedPCW -add wave -noupdate -expand -group {debug trace} -expand -group wb /testbench/TrapW -add wave -noupdate -expand -group {debug trace} -expand -group wb /testbench/textW +add wave -noupdate -group {debug trace} -expand -group mem -color Yellow /testbench/dut/hart/FlushW +add wave -noupdate -group {debug trace} -expand -group mem /testbench/dut/hart/priv/trap/InstrValidM +add wave -noupdate -group {debug trace} -expand -group mem /testbench/checkInstrM +add wave -noupdate -group {debug trace} -expand -group mem /testbench/dut/hart/PCM +add wave -noupdate -group {debug trace} -expand -group mem /testbench/ExpectedPCM +add wave -noupdate -group {debug trace} -expand -group mem /testbench/line +add wave -noupdate -group {debug trace} -expand -group mem /testbench/textM +add wave -noupdate -group {debug trace} -expand -group mem -color Brown /testbench/dut/hart/hzu/TrapM +add wave -noupdate -group {debug trace} -expand -group wb /testbench/dut/hart/ieu/c/InstrValidW +add wave -noupdate -group {debug trace} -expand -group wb /testbench/checkInstrW +add wave -noupdate -group {debug trace} -expand -group wb /testbench/PCW +add wave -noupdate -group {debug trace} -expand -group wb /testbench/ExpectedPCW +add wave -noupdate -group {debug trace} -expand -group wb /testbench/TrapW +add wave -noupdate -group {debug trace} -expand -group wb /testbench/textW add wave -noupdate -group {pc selection} /testbench/dut/hart/ifu/PCNext2F add wave -noupdate -group {pc selection} /testbench/dut/hart/ifu/PrivilegedNextPCM add wave -noupdate -group {pc selection} /testbench/dut/hart/ifu/PrivilegedChangePCM @@ -495,11 +510,16 @@ add wave -noupdate /testbench/dut/hart/ieu/c/BranchTakenE add wave -noupdate /testbench/dut/hart/ieu/c/BranchE add wave -noupdate /testbench/dut/hart/ifu/PCTargetE add wave -noupdate /testbench/dut/hart/ifu/PCLinkE +add wave -noupdate /testbench/dut/hart/lsu/DCtoAHBSizeM +add wave -noupdate /testbench/dut/uncore/dtim/A +add wave -noupdate /testbench/dut/uncore/dtim/memwrite +add wave -noupdate /testbench/dut/uncore/dtim/HWDATA +add wave -noupdate /testbench/dut/uncore/dtim/risingHREADYTim TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 6} {160470606 ns} 0} {{Cursor 21} {161371350 ns} 0} {{Cursor 22} {72228581 ns} 0} {{Cursor 23} {11297671 ns} 0} +WaveRestoreCursors {{Cursor 23} {209183247 ns} 0} {{Cursor 9} {209026335 ns} 0} quietly wave cursor active 1 configure wave -namecolwidth 250 -configure wave -valuecolwidth 354 +configure wave -valuecolwidth 314 configure wave -justifyvalue left configure wave -signalnamewidth 1 configure wave -snapdistance 10 @@ -512,4 +532,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {160470352 ns} {160470676 ns} +WaveRestoreZoom {209183151 ns} {209183343 ns} diff --git a/wally-pipelined/regression/regression-wally.py b/wally-pipelined/regression/regression-wally.py index 4d7baf8e..5c76548b 100755 --- a/wally-pipelined/regression/regression-wally.py +++ b/wally-pipelined/regression/regression-wally.py @@ -31,13 +31,18 @@ configs = [ TestCase( name="buildroot", cmd="vsim -do wally-buildroot-batch.do -c > {}", - grepstr="loaded 6000 instructions" + grepstr="8900000 instructions" ), TestCase( name="arch64", cmd="vsim > {} -c < {} -c < {} -c <" prompt: +# do wally-pipelined.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-pipelined.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work] { + vdel -all +} +vlib work + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt + +# default to config/rv64ic, but allow this to be overridden at the command line. For example: +# do wally-pipelined.do ../config/rv32ic +switch $argc { + 0 {vlog +incdir+../config/rv64BP +incdir+../config/shared ../testbench/testbench-fpga.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} + 1 {vlog +incdir+$1 +incdir+../config/shared ../testbench/testbench-imperas.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} +} +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +vopt -fsmdebug +acc -gDEBUG=1 work.testbench -o workopt +vsim workopt -fsmdebug + +#profile on + +do wave.do +add log -r /* + +-- Run the Simulation +#run 1000 +run -all +#quit diff --git a/wally-pipelined/regression/wally-pipelined-ross.do b/wally-pipelined/regression/wally-pipelined-ross.do index a8c15c4e..8d616b09 100644 --- a/wally-pipelined/regression/wally-pipelined-ross.do +++ b/wally-pipelined/regression/wally-pipelined-ross.do @@ -1,48 +1,49 @@ -# wally-pipelined.do -# -# Modification by Oklahoma State University & Harvey Mudd College -# Use with Testbench -# James Stine, 2008; David Harris 2021 -# Go Cowboys!!!!!! -# -# Takes 1:10 to run RV64IC tests using gui - -# Use this wally-pipelined.do file to run this example. -# Either bring up ModelSim and type the following at the "ModelSim>" prompt: -# do wally-pipelined.do -# or, to run from a shell, type the following at the shell prompt: -# vsim -do wally-pipelined.do -c -# (omit the "-c" to see the GUI while running from the shell) - -onbreak {resume} - -# create library -if [file exists work] { - vdel -all -} -vlib work - -# compile source files -# suppress spurious warnngs about -# "Extra checking for conflicts with always_comb done at vopt time" -# because vsim will run vopt - -# default to config/rv64ic, but allow this to be overridden at the command line. For example: -# do wally-pipelined.do ../config/rv32ic -switch $argc { - 0 {vlog +incdir+../config/rv64ic +incdir+../config/shared ../testbench/testbench-imperas.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} - 1 {vlog +incdir+$1 +incdir+../config/shared ../testbench/testbench-imperas.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} -} -# start and run simulation -# remove +acc flag for faster sim during regressions if there is no need to access internal signals -vopt -fsmdebug +acc -gDEBUG=1 work.testbench -o workopt -vsim workopt -fsmdebug - - -do wave.do -add log -r /* - --- Run the Simulation -#run 1000 -run -all -#quit +# wally-pipelined.do +# +# Modification by Oklahoma State University & Harvey Mudd College +# Use with Testbench +# James Stine, 2008; David Harris 2021 +# Go Cowboys!!!!!! +# +# Takes 1:10 to run RV64IC tests using gui + +# Use this wally-pipelined.do file to run this example. +# Either bring up ModelSim and type the following at the "ModelSim>" prompt: +# do wally-pipelined.do +# or, to run from a shell, type the following at the shell prompt: +# vsim -do wally-pipelined.do -c +# (omit the "-c" to see the GUI while running from the shell) + +onbreak {resume} + +# create library +if [file exists work] { + vdel -all +} +vlib work + +# compile source files +# suppress spurious warnngs about +# "Extra checking for conflicts with always_comb done at vopt time" +# because vsim will run vopt + +# default to config/rv64ic, but allow this to be overridden at the command line. For example: +# do wally-pipelined.do ../config/rv32ic +switch $argc { + 0 {vlog +incdir+../config/rv64ic +incdir+../config/shared ../testbench/testbench-imperas.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} + 1 {vlog +incdir+$1 +incdir+../config/shared ../testbench/testbench-imperas.sv ../testbench/common/*.sv ../src/*/*.sv -suppress 2583} +} +# start and run simulation +# remove +acc flag for faster sim during regressions if there is no need to access internal signals +vopt -fsmdebug +acc -gDEBUG=1 work.testbench -o workopt +vsim workopt -fsmdebug + +#profile on + +do wave.do +add log -r /* + +-- Run the Simulation +#run 1000 +run -all +#quit diff --git a/wally-pipelined/regression/wave.do b/wally-pipelined/regression/wave.do index 6d38b885..302d1ea5 100644 --- a/wally-pipelined/regression/wave.do +++ b/wally-pipelined/regression/wave.do @@ -16,41 +16,41 @@ add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/InstrM add wave -noupdate -expand -group {Memory Stage} /testbench/dut/hart/lsu/MemAdrM add wave -noupdate /testbench/dut/hart/ieu/dp/ResultM add wave -noupdate /testbench/dut/hart/ieu/dp/ResultW -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/EcallFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/StorePageFaultM -add wave -noupdate -expand -group HDU -group traps /testbench/dut/hart/priv/trap/InterruptM -add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/hart/priv/trap/PendingIntsM -add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/hart/priv/trap/CommittedM -add wave -noupdate -expand -group HDU -group interrupts /testbench/dut/hart/priv/trap/InstrValidM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/RetM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/TrapM -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/StoreStallD -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/ICacheStallF -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/hzu/LSUStall -add wave -noupdate -expand -group HDU -group hazards /testbench/dut/hart/MulDivStallD -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushD -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushE -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushM -add wave -noupdate -expand -group HDU -expand -group Flush -color Yellow /testbench/dut/hart/FlushW -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallF -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallD -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallE -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallM -add wave -noupdate -expand -group HDU -expand -group Stall -color Orange /testbench/dut/hart/StallW +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InstrMisalignedFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InstrAccessFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/IllegalInstrFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/BreakpointFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/LoadMisalignedFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/StoreMisalignedFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/LoadAccessFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/StoreAccessFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/EcallFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InstrPageFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/LoadPageFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/StorePageFaultM +add wave -noupdate -group HDU -group traps /testbench/dut/hart/priv/trap/InterruptM +add wave -noupdate -group HDU -group interrupts /testbench/dut/hart/priv/trap/PendingIntsM +add wave -noupdate -group HDU -group interrupts /testbench/dut/hart/priv/trap/CommittedM +add wave -noupdate -group HDU -group interrupts /testbench/dut/hart/priv/trap/InstrValidM +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/BPPredWrongE +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/CSRWritePendingDEM +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/RetM +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/TrapM +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/LoadStallD +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/StoreStallD +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/ICacheStallF +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/hzu/LSUStall +add wave -noupdate -group HDU -group hazards /testbench/dut/hart/MulDivStallD +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/hzu/FlushF +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushD +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushE +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushM +add wave -noupdate -group HDU -group Flush -color Yellow /testbench/dut/hart/FlushW +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/hart/StallF +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/hart/StallD +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/hart/StallE +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/hart/StallM +add wave -noupdate -group HDU -group Stall -color Orange /testbench/dut/hart/StallW add wave -noupdate -group Bpred -color Orange /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/GHR add wave -noupdate -group Bpred -expand -group {branch update selection inputs} /testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/BPPredF add wave -noupdate -group Bpred -expand -group {branch update selection inputs} {/testbench/dut/hart/ifu/bpred/bpred/Predictor/DirPredictor/InstrClassE[0]} @@ -98,12 +98,12 @@ add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/if add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/BPPredClassNonCFIWrongE add wave -noupdate -group Bpred -expand -group {bp wrong} /testbench/dut/hart/ifu/bpred/bpred/BPPredWrongE add wave -noupdate -group Bpred /testbench/dut/hart/ifu/bpred/bpred/BPPredWrongE -add wave -noupdate -expand -group {instruction pipeline} /testbench/InstrFName -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/icache/FinalInstrRawF -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrD -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrE -add wave -noupdate -expand -group {instruction pipeline} /testbench/dut/hart/ifu/InstrM -add wave -noupdate -expand -group {instruction pipeline} /testbench/InstrW +add wave -noupdate -group {instruction pipeline} /testbench/InstrFName +add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/icache/FinalInstrRawF +add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrD +add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrE +add wave -noupdate -group {instruction pipeline} /testbench/dut/hart/ifu/InstrM +add wave -noupdate -group {instruction pipeline} /testbench/InstrW add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCNextF add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCF add wave -noupdate -group {PCNext Generation} /testbench/dut/hart/ifu/PCPlus2or4F @@ -132,18 +132,18 @@ add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/CSRReadValW add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultSrcW add wave -noupdate -group RegFile -group {write regfile mux} /testbench/dut/hart/ieu/dp/ResultW -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/a -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/b -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/alucontrol -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/result -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/flags -add wave -noupdate -group alu -divider internals -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/overflow -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/carry -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/zero -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/neg -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/lt -add wave -noupdate -group alu /testbench/dut/hart/ieu/dp/alu/ltu +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/a +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/b +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/alucontrol +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/result +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/flags +add wave -noupdate -expand -group alu -divider internals +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/overflow +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/carry +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/zero +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/neg +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/lt +add wave -noupdate -expand -group alu /testbench/dut/hart/ieu/dp/alu/ltu add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1D add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs2D add wave -noupdate -group Forward /testbench/dut/hart/ieu/fw/Rs1E @@ -161,12 +161,12 @@ add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/Write add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/ALUResultE add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcAE add wave -noupdate -group {alu execution stage} /testbench/dut/hart/ieu/dp/SrcBE -add wave -noupdate -expand -group PCS /testbench/dut/hart/ifu/PCNextF -add wave -noupdate -expand -group PCS /testbench/dut/hart/PCF -add wave -noupdate -expand -group PCS /testbench/dut/hart/ifu/PCD -add wave -noupdate -expand -group PCS /testbench/dut/hart/PCE -add wave -noupdate -expand -group PCS /testbench/dut/hart/PCM -add wave -noupdate -expand -group PCS /testbench/PCW +add wave -noupdate -group PCS /testbench/dut/hart/ifu/PCNextF +add wave -noupdate -group PCS /testbench/dut/hart/PCF +add wave -noupdate -group PCS /testbench/dut/hart/ifu/PCD +add wave -noupdate -group PCS /testbench/dut/hart/PCE +add wave -noupdate -group PCS /testbench/dut/hart/PCM +add wave -noupdate -group PCS /testbench/PCW add wave -noupdate -group muldiv /testbench/dut/hart/mdu/InstrD add wave -noupdate -group muldiv /testbench/dut/hart/mdu/SrcAE add wave -noupdate -group muldiv /testbench/dut/hart/mdu/SrcBE @@ -186,85 +186,86 @@ add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/N add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/D add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/Q add wave -noupdate -group divider /testbench/dut/hart/mdu/genblk1/div/rem0 -add wave -noupdate -expand -group icache -color Gold /testbench/dut/hart/ifu/icache/controller/CurrState -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/BasePAdrF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/WayHit -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/genblk1/cachereplacementpolicy/BlockReplacementBits -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/genblk1/cachereplacementpolicy/EncVicWay -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/VictimWay -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/hart/ifu/icache/MemWay[0]/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/hart/ifu/icache/MemWay[0]/SetValid} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[0]/CacheTagMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 {/testbench/dut/hart/ifu/icache/MemWay[0]/ValidBits} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word0 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -expand -group Way0Word0 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -group Way0Word1 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -group Way0Word1 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -group Way0Word2 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -group Way0Word3 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way0 -group Way0Word3 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/hart/ifu/icache/MemWay[1]/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 {/testbench/dut/hart/ifu/icache/MemWay[1]/WriteWordEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[1]/CacheTagMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word0 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -expand -group Way1Word0 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -group Way1Word1 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -group Way1Word1 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -group Way1Word2 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -group Way1Word2 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -group Way1Word3 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way1 -group Way1Word3 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/hart/ifu/icache/MemWay[2]/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/hart/ifu/icache/MemWay[2]/SetValid} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[2]/CacheTagMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 {/testbench/dut/hart/ifu/icache/MemWay[2]/ValidBits} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word0 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -expand -group Way2Word0 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -group Way2Word1 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -group Way2Word1 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -group Way2Word2 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -group Way2Word2 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -group Way2Word3 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way2 -group Way2Word3 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/SetValid} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[3]/CacheTagMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/DirtyBits} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/ValidBits} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -expand -group icache -expand -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/controller/NextState -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/ITLBMissF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/ITLBWriteF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/ReadLineF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/PCNextIndexF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/ReadLineF -add wave -noupdate -expand -group icache /testbench/dut/hart/ifu/icache/BasePAdrF -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/hit -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spill -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/ICacheStallF -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/SavePC -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/UnalignedSelect -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntReset -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/PreCntEn -add wave -noupdate -expand -group icache -expand -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntEn -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/InstrPAdrF -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/InstrInF -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/FetchCount -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable -add wave -noupdate -expand -group icache -expand -group memory /testbench/dut/hart/ifu/icache/ICacheMemWriteData +add wave -noupdate -group icache -color Gold /testbench/dut/hart/ifu/icache/controller/CurrState +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/BasePAdrF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/WayHit +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/genblk1/cachereplacementpolicy/BlockReplacementBits +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/genblk1/cachereplacementpolicy/EncVicWay +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/VictimWay +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/ifu/icache/MemWay[0]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/ifu/icache/MemWay[0]/SetValid} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[0]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/ifu/icache/MemWay[0]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -expand -group Way0Word0 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word1 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word2 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way0 -group Way0Word3 {/testbench/dut/hart/ifu/icache/MemWay[0]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/ifu/icache/MemWay[1]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/ifu/icache/MemWay[1]/WriteWordEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[1]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 {/testbench/dut/hart/ifu/icache/MemWay[1]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -expand -group Way1Word0 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word1 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word1 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word2 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word2 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word3 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way1 -group Way1Word3 {/testbench/dut/hart/ifu/icache/MemWay[1]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/ifu/icache/MemWay[2]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/ifu/icache/MemWay[2]/SetValid} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[2]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 {/testbench/dut/hart/ifu/icache/MemWay[2]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -expand -group Way2Word0 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word1 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word1 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word2 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word2 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word3 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -group way2 -group Way2Word3 {/testbench/dut/hart/ifu/icache/MemWay[2]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/SetValid} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/hart/ifu/icache/MemWay[3]/CacheTagMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/DirtyBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/ifu/icache/MemWay[3]/ValidBits} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word1 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word2 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group icache -group {Cache SRAM writes} -expand -group way3 -group Way3Word3 {/testbench/dut/hart/ifu/icache/MemWay[3]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/controller/NextState +add wave -noupdate -group icache /testbench/dut/hart/ifu/ITLBMissF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/ITLBWriteF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/ReadLineF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/PCNextIndexF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/ReadLineF +add wave -noupdate -group icache /testbench/dut/hart/ifu/icache/BasePAdrF +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/hit +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spill +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/ICacheStallF +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/SavePC +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/UnalignedSelect +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/spillSave +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntReset +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/PreCntEn +add wave -noupdate -group icache -group {fsm out and control} /testbench/dut/hart/ifu/icache/controller/CntEn +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/InstrPAdrF +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/InstrInF +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/FetchCountFlag +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/FetchCount +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrReadF +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/InstrAckF +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/controller/ICacheMemWriteEnable +add wave -noupdate -group icache -expand -group memory /testbench/dut/hart/ifu/icache/ICacheMemWriteData add wave -noupdate -group AHB -color Gold /testbench/dut/hart/ebu/BusState add wave -noupdate -group AHB /testbench/dut/hart/ebu/NextBusState add wave -noupdate -group AHB -expand -group {input requests} /testbench/dut/hart/ebu/AtomicMaskedM @@ -297,6 +298,7 @@ add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcac add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMWordEnable add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SRAMBlockWayWriteEnableM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/SelAdrM +add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/ReadDataBlockM add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/DCacheMemWriteData add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/WriteEnable} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way0 {/testbench/dut/hart/lsu/dcache/MemWay[0]/SetValid} @@ -339,20 +341,20 @@ add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} - add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word2 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[2]/CacheDataMem/StoredData} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/WriteEnable} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way2 -expand -group Way2Word3 {/testbench/dut/hart/lsu/dcache/MemWay[2]/word[3]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetValid} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetDirty} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[3]/CacheTagMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/DirtyBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ValidBits} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/StoredData} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} -add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/StoredData} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/WriteEnable} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetValid} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/SetDirty} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -label TAG {/testbench/dut/hart/lsu/dcache/MemWay[3]/CacheTagMem/StoredData} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/DirtyBits} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/ValidBits} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/StoredData} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word0 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[0]/CacheDataMem/WriteEnable} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/StoredData} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word1 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[1]/CacheDataMem/WriteEnable} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/WriteEnable} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word2 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[2]/CacheDataMem/StoredData} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/WriteEnable} +add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -group way3 -expand -group Way3Word3 {/testbench/dut/hart/lsu/dcache/MemWay[3]/word[3]/CacheDataMem/StoredData} add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/hart/lsu/dcache/SetValid add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/hart/lsu/dcache/ClearValid add wave -noupdate -group lsu -expand -group dcache -group {Cache SRAM writes} -expand -group valid/dirty /testbench/dut/hart/lsu/dcache/SetDirty @@ -381,19 +383,22 @@ add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimWay add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirtyWay add wave -noupdate -group lsu -expand -group dcache -group Victim /testbench/dut/hart/lsu/dcache/VictimDirty -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/MemRWM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/MemAdrE -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/MemPAdrM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct3M -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct7M -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/AtomicM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/CacheableM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/WriteDataM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/ReadDataM -add wave -noupdate -group lsu -expand -group dcache -group {CPU side} /testbench/dut/hart/lsu/dcache/DCacheStall +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemRWM +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemAdrE +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/MemPAdrM +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct3M +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/Funct7M +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/AtomicM +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/FlushDCacheM +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/CacheableM +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/WriteDataM +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/ReadDataM +add wave -noupdate -group lsu -expand -group dcache -expand -group {CPU side} /testbench/dut/hart/lsu/dcache/DCacheStall +add wave -noupdate -group lsu -expand -group dcache /testbench/dut/hart/lsu/dcache/FlushAdrFlag add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/WayHit add wave -noupdate -group lsu -expand -group dcache -group status -color {Medium Orchid} /testbench/dut/hart/lsu/dcache/CacheHit add wave -noupdate -group lsu -expand -group dcache -group status /testbench/dut/hart/lsu/dcache/FetchCount +add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/FetchCountFlag add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBPAdr add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBRead add wave -noupdate -group lsu -expand -group dcache -group {Memory Side} /testbench/dut/hart/lsu/dcache/AHBWrite @@ -511,28 +516,46 @@ add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HSELUART add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HADDR add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HWRITE add wave -noupdate -group UART /testbench/dut/uncore/uart/uart/HWDATA -add wave -noupdate -color Gold /testbench/dut/hart/lsu/dcache/subwordread/offset0 -add wave -noupdate /testbench/dut/hart/lsu/dcache/subwordread/offset1 -add wave -noupdate /testbench/dut/hart/lsu/dcache/subwordread/offset2 -add wave -noupdate /testbench/dut/hart/lsu/dcache/subwordread/offset3 -add wave -noupdate /testbench/dut/hart/ExceptionM -add wave -noupdate /testbench/dut/hart/PendingInterruptM -add wave -noupdate /testbench/dut/hart/TrapM -add wave -noupdate /testbench/dut/hart/ifu/icache/CompressedF -add wave -noupdate /testbench/dut/hart/ifu/icache/PCPF -add wave -noupdate /testbench/dut/hart/ifu/PCPFmmu -add wave -noupdate /testbench/dut/hart/ifu/PCPF -add wave -noupdate /testbench/dut/hart/ifu/PCF -add wave -noupdate /testbench/dut/hart/ifu/immu/Translate -add wave -noupdate /testbench/dut/hart/ifu/icache/FinalInstrRawF -add wave -noupdate /testbench/dut/hart/ifu/icache/StallF -add wave -noupdate /testbench/dut/hart/ifu/icache/ICacheMemReadData -add wave -noupdate /testbench/dut/hart/ifu/icache/PCTagF -add wave -noupdate /testbench/dut/hart/ifu/icache/PCPSpillF -add wave -noupdate /testbench/dut/hart/ifu/icache/ICacheReadEn +add wave -noupdate -expand -group SDC -color Gold -label {AHBLite FSM} /testbench/dut/uncore/sdc/SDC/CurrState +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/HCLK +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/CLKGate +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/SDCCLKIn +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/SDCCLK +add wave -noupdate -expand -group SDC -color Gold -label {cmd fsm} /testbench/dut/uncore/sdc/SDC/sd_top/my_sd_cmd_fsm/r_curr_state +add wave -noupdate -expand -group SDC -color Gold -label {dat fsm} /testbench/dut/uncore/sdc/SDC/sd_top/my_sd_dat_fsm/r_curr_state +add wave -noupdate -expand -group SDC -color Gold -label {clk fsm} /testbench/dut/uncore/sdc/SDC/sd_top/my_clk_fsm/r_curr_state +add wave -noupdate -expand -group SDC -expand -group registers /testbench/dut/uncore/sdc/SDC/CLKDiv +add wave -noupdate -expand -group SDC -expand -group registers /testbench/dut/uncore/sdc/SDC/Command +add wave -noupdate -expand -group SDC -expand -group registers -color {Medium Orchid} /testbench/dut/uncore/sdc/SDC/Status +add wave -noupdate -expand -group SDC -expand -group registers /testbench/dut/uncore/sdc/SDC/Address +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} -color Aquamarine /testbench/dut/uncore/sdc/SDC/HSELSDC +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HADDR +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HADDRDelay +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HWRITE +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HREADY +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HTRANS +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HWDATA +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HREADSDC +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} /testbench/dut/uncore/sdc/SDC/HRESPSDC +add wave -noupdate -expand -group SDC -expand -group {AHBLite interface} -color Goldenrod /testbench/dut/uncore/sdc/SDC/HREADYSDC +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/InitTrans +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/sd_top/o_ERROR_CODE_Q +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/sd_top/o_DATA_VALID +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/sd_top/ReadData +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/WordCount +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/HREADSDC +add wave -noupdate -expand -group SDC /testbench/dut/uncore/sdc/SDC/sd_top/o_READY_FOR_READ +add wave -noupdate -expand -group boottim /testbench/dut/uncore/bootdtim/bootdtim/HADDR +add wave -noupdate -expand -group boottim /testbench/dut/uncore/bootdtim/bootdtim/A +add wave -noupdate -expand -group boottim /testbench/dut/uncore/bootdtim/bootdtim/HWADDR +add wave -noupdate -expand -group boottim /testbench/dut/uncore/bootdtim/bootdtim/HSELTim +add wave -noupdate -expand -group boottim /testbench/dut/uncore/bootdtim/bootdtim/HREADYTim +add wave -noupdate -expand -group boottim /testbench/dut/uncore/bootdtim/bootdtim/HRESPTim +add wave -noupdate -expand -group boottim /testbench/dut/uncore/bootdtim/bootdtim/initTrans +add wave -noupdate /testbench/dut/uncore/sdc/SDC/SDCDataValid TreeUpdate [SetDefaultTree] -WaveRestoreCursors {{Cursor 6} {183 ns} 0} -quietly wave cursor active 1 +WaveRestoreCursors {{Cursor 6} {1853243 ns} 0} {{Cursor 3} {2181 ns} 0} +quietly wave cursor active 2 configure wave -namecolwidth 250 configure wave -valuecolwidth 297 configure wave -justifyvalue left @@ -547,4 +570,4 @@ configure wave -griddelta 40 configure wave -timeline 0 configure wave -timelineunits ns update -WaveRestoreZoom {0 ns} {456 ns} +WaveRestoreZoom {209 ns} {4153 ns} diff --git a/wally-pipelined/src/cache/cacheway.sv b/wally-pipelined/src/cache/cacheway.sv index dc1f4c9b..5a7c3d9e 100644 --- a/wally-pipelined/src/cache/cacheway.sv +++ b/wally-pipelined/src/cache/cacheway.sv @@ -31,8 +31,10 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26, input logic reset, input logic [$clog2(NUMLINES)-1:0] RAdr, + input logic [$clog2(NUMLINES)-1:0] WAdr, input logic [`PA_BITS-1:0] PAdr, input logic WriteEnable, + input logic VDWriteEnable, input logic [BLOCKLEN/`XLEN-1:0] WriteWordEnable, input logic TagWriteEnable, input logic [BLOCKLEN-1:0] WriteData, @@ -41,7 +43,10 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26, input logic SetDirty, input logic ClearDirty, input logic SelEvict, - input logic VictimWay, + input logic VictimWay, + input logic InvalidateAll, + input logic SelFlush, + input logic FlushWay, output logic [BLOCKLEN-1:0] ReadDataBlockWayMasked, output logic WayHit, @@ -55,6 +60,8 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26, logic Valid; logic Dirty; logic SelectedWay; + logic [TAGLEN-1:0] VicDirtyWay; + logic [TAGLEN-1:0] FlushThisWay; genvar words; @@ -79,17 +86,29 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26, .WriteEnable(TagWriteEnable)); assign WayHit = Valid & (ReadTag == PAdr[`PA_BITS-1:OFFSETLEN+INDEXLEN]); - assign SelectedWay = SelEvict ? VictimWay : WayHit; + assign SelectedWay = SelFlush ? FlushWay : + SelEvict ? VictimWay : WayHit; assign ReadDataBlockWayMasked = SelectedWay ? ReadDataBlockWay : '0; // first part of AO mux. - assign VictimDirtyWay = VictimWay & Dirty & Valid; - assign VictimTagWay = VictimWay ? ReadTag : '0; + assign VictimDirtyWay = SelFlush ? FlushWay & Dirty & Valid : + VictimWay & Dirty & Valid; +/* -----\/----- EXCLUDED -----\/----- + assign VictimTagWay = SelFlush & FlushWay ? ReadTag : + VictimWay ? ReadTag : '0; + -----/\----- EXCLUDED -----/\----- */ + + assign VicDirtyWay = VictimWay ? ReadTag : '0; + assign FlushThisWay = FlushWay ? ReadTag : '0; + assign VictimTagWay = SelFlush ? FlushThisWay : VicDirtyWay; + always_ff @(posedge clk, posedge reset) begin if (reset) ValidBits <= {NUMLINES{1'b0}}; - else if (SetValid & WriteEnable) ValidBits[PAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= 1'b1; - else if (ClearValid & WriteEnable) ValidBits[PAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= 1'b0; + else if (InvalidateAll) + ValidBits <= {NUMLINES{1'b0}}; + else if (SetValid & (WriteEnable | VDWriteEnable)) ValidBits[WAdr] <= 1'b1; + else if (ClearValid & (WriteEnable | VDWriteEnable)) ValidBits[WAdr] <= 1'b0; Valid <= ValidBits[RAdr]; end @@ -98,8 +117,8 @@ module cacheway #(parameter NUMLINES=512, parameter BLOCKLEN = 256, TAGLEN = 26, always_ff @(posedge clk, posedge reset) begin if (reset) DirtyBits <= {NUMLINES{1'b0}}; - else if (SetDirty & WriteEnable) DirtyBits[PAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= 1'b1; - else if (ClearDirty & WriteEnable) DirtyBits[PAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]] <= 1'b0; + else if (SetDirty & (WriteEnable | VDWriteEnable)) DirtyBits[WAdr] <= 1'b1; + else if (ClearDirty & (WriteEnable | VDWriteEnable)) DirtyBits[WAdr] <= 1'b0; Dirty <= DirtyBits[RAdr]; end end else begin diff --git a/wally-pipelined/src/cache/dcache.sv b/wally-pipelined/src/cache/dcache.sv index 2af4cfe9..733f469f 100644 --- a/wally-pipelined/src/cache/dcache.sv +++ b/wally-pipelined/src/cache/dcache.sv @@ -38,6 +38,7 @@ module dcache input logic [2:0] Funct3M, input logic [6:0] Funct7M, input logic [1:0] AtomicM, + input logic FlushDCacheM, input logic [11:0] MemAdrE, // virtual address, but we only use the lower 12 bits. input logic [`PA_BITS-1:0] MemPAdrM, // physical address input logic [11:0] VAdr, // when hptw writes dtlb we use this address to index SRAM. @@ -68,7 +69,8 @@ module dcache output logic AHBWrite, input logic AHBAck, // from ahb input logic [`XLEN-1:0] HRDATA, // from ahb - output logic [`XLEN-1:0] HWDATA // to ahb + output logic [`XLEN-1:0] HWDATA, // to ahb + output logic [2:0] DCtoAHBSizeM ); /* localparam integer BLOCKLEN = 256; @@ -88,9 +90,12 @@ module dcache localparam integer LOGWPL = $clog2(WORDSPERLINE); localparam integer LOGXLENBYTES = $clog2(`XLEN/8); + localparam integer FetchCountThreshold = WORDSPERLINE - 1; + localparam integer FlushAdrThreshold = NUMLINES - 1; logic [1:0] SelAdrM; logic [INDEXLEN-1:0] RAdr; + logic [INDEXLEN-1:0] WAdr; logic [BLOCKLEN-1:0] SRAMWriteData; logic [BLOCKLEN-1:0] DCacheMemWriteData; logic SetValid, ClearValid; @@ -125,7 +130,20 @@ module dcache logic [TAGLEN-1:0] VictimTagWay [NUMWAYS-1:0]; logic [TAGLEN-1:0] VictimTag; + logic [INDEXLEN-1:0] FlushAdr; + logic [INDEXLEN-1:0] FlushAdrP1; + logic FlushAdrCntEn; + logic FlushAdrCntRst; + logic FlushAdrFlag; + logic [NUMWAYS-1:0] FlushWay; + logic [NUMWAYS-1:0] NextFlushWay; + logic FlushWayCntEn; + logic FlushWayCntRst; + + logic SelFlush; + logic VDWriteEnable; + logic AnyCPUReqM; logic FetchCountFlag; logic PreCntEn; @@ -137,20 +155,30 @@ module dcache // Read Path CPU (IEU) side - mux3 #(INDEXLEN) + mux4 #(INDEXLEN) AdrSelMux(.d0(MemAdrE[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .d1(VAdr[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), .d2(MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), + .d3(FlushAdr), .s(SelAdrM), .y(RAdr)); + mux2 #(INDEXLEN) + WAdrSelMux(.d0(MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), + .d1(FlushAdr), + .s(&SelAdrM), + .y(WAdr)); + + cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN), .OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN)) MemWay[NUMWAYS-1:0](.clk, .reset, .RAdr, + .WAdr, .PAdr(MemPAdrM[`PA_BITS-1:0]), .WriteEnable(SRAMWayWriteEnable), + .VDWriteEnable, .WriteWordEnable(SRAMWordEnable), .TagWriteEnable(SRAMBlockWayWriteEnableM), .WriteData(SRAMWriteData), @@ -160,10 +188,13 @@ module dcache .ClearDirty, .SelEvict, .VictimWay, + .FlushWay, + .SelFlush, .ReadDataBlockWayMasked(ReadDataBlockWayMaskedM), .WayHit, .VictimDirtyWay, - .VictimTagWay); + .VictimTagWay, + .InvalidateAll(1'b0)); generate if(NUMWAYS > 1) begin @@ -201,6 +232,7 @@ module dcache endgenerate // variable input mux + assign ReadDataWordM = ReadDataBlockSetsM[MemPAdrM[$clog2(WORDSPERLINE+`XLEN/8) : $clog2(`XLEN/8)]]; mux2 #(`XLEN) UnCachedDataMux(.d0(ReadDataWordM), @@ -264,9 +296,10 @@ module dcache end endgenerate - mux2 #(`PA_BITS) BaseAdrMux(.d0(MemPAdrM), + mux3 #(`PA_BITS) BaseAdrMux(.d0(MemPAdrM), .d1({VictimTag, MemPAdrM[INDEXLEN+OFFSETLEN-1:OFFSETLEN], {{OFFSETLEN}{1'b0}}}), - .s(SelEvict), + .d2({VictimTag, FlushAdr, {{OFFSETLEN}{1'b0}}}), + .s({SelFlush, SelEvict}), .y(BasePAdrM)); // if not cacheable the offset bits needs to be sent to the EBU. @@ -276,10 +309,7 @@ module dcache assign AHBPAdr = ({{`PA_BITS-LOGWPL{1'b0}}, FetchCount} << $clog2(`XLEN/8)) + BasePAdrMaskedM; - assign HWDATA = CacheableM ? ReadDataBlockSetsM[FetchCount] : WriteDataM; - - localparam FetchCountThreshold = WORDSPERLINE - 1; - + assign HWDATA = CacheableM | SelFlush ? ReadDataBlockSetsM[FetchCount] : WriteDataM; assign FetchCountFlag = (FetchCount == FetchCountThreshold[LOGWPL-1:0]); @@ -292,6 +322,33 @@ module dcache assign NextFetchCount = FetchCount + 1'b1; + // flush address and way generation. + flopenr #(INDEXLEN) + FlushAdrReg(.clk, + .reset(reset | FlushAdrCntRst), + .en(FlushAdrCntEn & FlushWay[NUMWAYS-1]), + .d(FlushAdrP1), + .q(FlushAdr)); + assign FlushAdrP1 = FlushAdr + 1'b1; + + + flopenl #(NUMWAYS) + FlushWayReg(.clk, + .load(reset | FlushWayCntRst), + .en(FlushWayCntEn), + .val({{NUMWAYS-1{1'b0}}, 1'b1}), + .d(NextFlushWay), + .q(FlushWay)); + + assign NextFlushWay = {FlushWay[NUMWAYS-2:0], FlushWay[NUMWAYS-1]}; + + assign FlushAdrFlag = FlushAdr == FlushAdrThreshold[INDEXLEN-1:0] & FlushWay[NUMWAYS-1]; + + generate + if (`XLEN == 32) assign DCtoAHBSizeM = CacheableM | SelFlush ? 3'b010 : Funct3M; + else assign DCtoAHBSizeM = CacheableM | SelFlush ? 3'b011 : Funct3M; + endgenerate; + assign SRAMWriteEnable = SRAMBlockWriteEnableM | SRAMWordWriteEnableM; // controller @@ -333,6 +390,14 @@ module dcache .CntReset, .SelUncached, .SelEvict, + .SelFlush, + .FlushAdrCntEn, + .FlushWayCntEn, + .FlushAdrCntRst, + .FlushWayCntRst, + .FlushAdrFlag, + .FlushDCacheM, + .VDWriteEnable, .LRUWriteEn); diff --git a/wally-pipelined/src/cache/dcachefsm.sv b/wally-pipelined/src/cache/dcachefsm.sv index afccb786..12e1c9ac 100644 --- a/wally-pipelined/src/cache/dcachefsm.sv +++ b/wally-pipelined/src/cache/dcachefsm.sv @@ -27,57 +27,65 @@ module dcachefsm (input logic clk, - input logic reset, + input logic reset, // inputs from IEU - input logic [1:0] MemRWM, - input logic [1:0] AtomicM, - + input logic [1:0] MemRWM, + input logic [1:0] AtomicM, + input logic FlushDCacheM, // hazard inputs - input logic ExceptionM, - input logic PendingInterruptM, - input logic StallWtoDCache, + input logic ExceptionM, + input logic PendingInterruptM, + input logic StallWtoDCache, // mmu inputs - input logic DTLBMissM, - input logic ITLBMissF, - input logic CacheableM, - input logic DTLBWriteM, - input logic ITLBWriteF, - input logic WalkerInstrPageFaultF, + input logic DTLBMissM, + input logic ITLBMissF, + input logic CacheableM, + input logic DTLBWriteM, + input logic ITLBWriteF, + input logic WalkerInstrPageFaultF, // hptw inputs - input logic SelPTW, - input logic WalkerPageFaultM, + input logic SelPTW, + input logic WalkerPageFaultM, // Bus inputs - input logic AHBAck, // from ahb + input logic AHBAck, // from ahb // dcache internals - input logic CacheHit, - input logic FetchCountFlag, - input logic VictimDirty, + input logic CacheHit, + input logic FetchCountFlag, + input logic VictimDirty, + input logic FlushAdrFlag, // hazard outputs - output logic DCacheStall, - output logic CommittedM, + output logic DCacheStall, + output logic CommittedM, // counter outputs - output logic DCacheMiss, - output logic DCacheAccess, + output logic DCacheMiss, + output logic DCacheAccess, // hptw outputs - output logic MemAfterIWalkDone, + output logic MemAfterIWalkDone, // Bus outputs - output logic AHBRead, - output logic AHBWrite, + output logic AHBRead, + output logic AHBWrite, // dcache internals output logic [1:0] SelAdrM, - output logic CntEn, - output logic SetValid, - output logic ClearValid, - output logic SetDirty, - output logic ClearDirty, - output logic SRAMWordWriteEnableM, - output logic SRAMBlockWriteEnableM, - output logic CntReset, - output logic SelUncached, - output logic SelEvict, - output logic LRUWriteEn + output logic CntEn, + output logic SetValid, + output logic ClearValid, + output logic SetDirty, + output logic ClearDirty, + output logic SRAMWordWriteEnableM, + output logic SRAMBlockWriteEnableM, + output logic CntReset, + output logic SelUncached, + output logic SelEvict, + output logic LRUWriteEn, + output logic SelFlush, + output logic FlushAdrCntEn, + output logic FlushWayCntEn, + output logic FlushAdrCntRst, + output logic FlushWayCntRst, + output logic VDWriteEnable + ); logic PreCntEn; @@ -124,7 +132,11 @@ module dcachefsm STATE_PTW_FAULT_UNCACHED_READ_DONE, STATE_CPU_BUSY, - STATE_CPU_BUSY_FINISH_AMO} statetype; + STATE_CPU_BUSY_FINISH_AMO, + + STATE_FLUSH, + STATE_FLUSH_WRITE_BACK, + STATE_FLUSH_CLEAR_DIRTY} statetype; statetype CurrState, NextState; @@ -168,6 +180,12 @@ module dcachefsm DCacheMiss = 1'b0; LRUWriteEn = 1'b0; MemAfterIWalkDone = 1'b0; + SelFlush = 1'b0; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + FlushAdrCntRst = 1'b0; + FlushWayCntRst = 1'b0; + VDWriteEnable = 1'b0; NextState = STATE_READY; case (CurrState) @@ -184,9 +202,17 @@ module dcachefsm SetDirty = 1'b0; LRUWriteEn = 1'b0; CommittedM = 1'b0; - + + if(FlushDCacheM) begin + NextState = STATE_FLUSH; + DCacheStall = 1'b1; + SelAdrM = 2'b11; + FlushAdrCntRst = 1'b1; + FlushWayCntRst = 1'b1; + end + // TLB Miss - if((AnyCPUReqM & DTLBMissM) | ITLBMissF) begin + else if((AnyCPUReqM & DTLBMissM) | ITLBMissF) begin // the LSU arbiter has not yet selected the PTW. // The CPU needs to be stalled until that happens. // If we set DCacheStall for 1 cycle before going to @@ -313,7 +339,7 @@ module dcachefsm SelAdrM = 2'b10; DCacheStall = 1'b1; CommittedM = 1'b1; - if (MemRWM[0]) begin // handles stores and amo write. + if (MemRWM[0] & ~AtomicM[1]) begin // handles stores and amo write. NextState = STATE_MISS_WRITE_WORD; end else begin NextState = STATE_MISS_READ_WORD_DELAY; @@ -842,6 +868,61 @@ module dcachefsm end end + STATE_FLUSH: begin + DCacheStall = 1'b1; + CommittedM = 1'b1; + SelAdrM = 2'b11; + SelFlush = 1'b1; + FlushAdrCntEn = 1'b1; + FlushWayCntEn = 1'b1; + CntReset = 1'b1; + if(VictimDirty) begin + NextState = STATE_FLUSH_WRITE_BACK; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + end else if (FlushAdrFlag) begin + NextState = STATE_READY; + DCacheStall = 1'b0; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + end else begin + NextState = STATE_FLUSH; + end + end + + STATE_FLUSH_WRITE_BACK: begin + DCacheStall = 1'b1; + AHBWrite = 1'b1; + SelAdrM = 2'b11; + CommittedM = 1'b1; + SelFlush = 1'b1; + PreCntEn = 1'b1; + if(FetchCountFlag & AHBAck) begin + NextState = STATE_FLUSH_CLEAR_DIRTY; + end else begin + NextState = STATE_FLUSH_WRITE_BACK; + end + end + + STATE_FLUSH_CLEAR_DIRTY: begin + DCacheStall = 1'b1; + ClearDirty = 1'b1; + VDWriteEnable = 1'b1; + SelFlush = 1'b1; + SelAdrM = 2'b11; + FlushAdrCntEn = 1'b0; + FlushWayCntEn = 1'b0; + if(FlushAdrFlag) begin + NextState = STATE_READY; + DCacheStall = 1'b0; + SelAdrM = 2'b00; + end else begin + NextState = STATE_FLUSH; + FlushAdrCntEn = 1'b1; + FlushWayCntEn = 1'b1; + end + end + default: begin NextState = STATE_READY; end diff --git a/wally-pipelined/src/cache/icache.sv b/wally-pipelined/src/cache/icache.sv index 4123475a..1e55e0da 100644 --- a/wally-pipelined/src/cache/icache.sv +++ b/wally-pipelined/src/cache/icache.sv @@ -46,6 +46,7 @@ module icache input logic ITLBMissF, input logic ITLBWriteF, input logic WalkerInstrPageFaultF, + input logic InvalidateICacheM, // The raw (not decompressed) instruction that was requested // If this instruction is compressed, upper 16 bits may be the next 16 bits or may be zeros @@ -138,24 +139,29 @@ module icache cacheway #(.NUMLINES(NUMLINES), .BLOCKLEN(BLOCKLEN), .TAGLEN(TAGLEN), .OFFSETLEN(OFFSETLEN), .INDEXLEN(INDEXLEN), .DIRTY_BITS(0)) MemWay[NUMWAYS-1:0](.clk, - .reset, - .RAdr(RAdr), - .PAdr(PCTagF), - .WriteEnable(SRAMWayWriteEnable), - .WriteWordEnable({{(BLOCKLEN/`XLEN){1'b1}}}), - .TagWriteEnable(SRAMWayWriteEnable), - .WriteData(ICacheMemWriteData), - .SetValid(ICacheMemWriteEnable), - .ClearValid(1'b0), - .SetDirty(1'b0), - .ClearDirty(1'b0), - .SelEvict(1'b0), - .VictimWay, - .ReadDataBlockWayMasked, - .WayHit, - .VictimDirtyWay(), - .VictimTagWay() - ); + .reset, + .RAdr(RAdr), + .WAdr(PCTagF[INDEXLEN+OFFSETLEN-1:OFFSETLEN]), + .PAdr(PCTagF), + .WriteEnable(SRAMWayWriteEnable), + .VDWriteEnable(1'b0), + .WriteWordEnable({{(BLOCKLEN/`XLEN){1'b1}}}), + .TagWriteEnable(SRAMWayWriteEnable), + .WriteData(ICacheMemWriteData), + .SetValid(ICacheMemWriteEnable), + .ClearValid(1'b0), + .SetDirty(1'b0), + .ClearDirty(1'b0), + .SelEvict(1'b0), + .VictimWay, + .FlushWay(1'b0), + .SelFlush(1'b0), + .ReadDataBlockWayMasked, + .WayHit, + .VictimDirtyWay(), + .VictimTagWay(), + .InvalidateAll(InvalidateICacheM) + ); generate if(NUMWAYS > 1) begin diff --git a/wally-pipelined/src/hazard/hazard.sv b/wally-pipelined/src/hazard/hazard.sv index 6b81ebbc..0a16a8fd 100644 --- a/wally-pipelined/src/hazard/hazard.sv +++ b/wally-pipelined/src/hazard/hazard.sv @@ -35,6 +35,7 @@ module hazard( input logic FPUStallD, FStallD, input logic DivBusyE,FDivBusyE, input logic EcallFaultM, BreakpointFaultM, + input logic InvalidateICacheM, // Stall & flush outputs output logic StallF, StallD, StallE, StallM, StallW, output logic FlushF, FlushD, FlushE, FlushM, FlushW @@ -68,18 +69,16 @@ module hazard( assign StallM = StallMCause | StallW; assign StallW = StallWCause; - //assign FirstUnstalledD = (~StallD & StallF & ~MulDivStallD); - //assign FirstUnstalledE = (~StallE & StallD & ~MulDivStallD); assign FirstUnstalledD = (~StallD && StallF); assign FirstUnstalledE = (~StallE && StallD); assign FirstUnstalledM = (~StallM && StallE); assign FirstUnstalledW = (~StallW && StallM); // Each stage flushes if the previous stage is the last one stalled (for cause) or the system has reason to flush - assign FlushF = BPPredWrongE; - assign FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE; - assign FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE; - assign FlushM = FirstUnstalledM | TrapM | RetM; + assign FlushF = BPPredWrongE | InvalidateICacheM; + assign FlushD = FirstUnstalledD | TrapM | RetM | BPPredWrongE | InvalidateICacheM; + assign FlushE = FirstUnstalledE | TrapM | RetM | BPPredWrongE | InvalidateICacheM; + assign FlushM = FirstUnstalledM | TrapM | RetM | InvalidateICacheM; // on Trap the memory stage should be flushed going into the W stage, // except if the instruction causing the Trap is an ecall or ebreak. assign FlushW = FirstUnstalledW | (TrapM & ~(BreakpointFaultM | EcallFaultM)); diff --git a/wally-pipelined/src/ieu/controller.sv b/wally-pipelined/src/ieu/controller.sv index ab503483..ed5f0240 100644 --- a/wally-pipelined/src/ieu/controller.sv +++ b/wally-pipelined/src/ieu/controller.sv @@ -56,6 +56,7 @@ module controller( output logic [1:0] AtomicM, output logic [2:0] Funct3M, output logic RegWriteM, // for Hazard Unit + output logic InvalidateICacheM, FlushDCacheM, output logic InstrValidM, InstrValidW, // Writeback stage control signals input logic StallW, FlushW, @@ -71,7 +72,7 @@ module controller( logic [6:0] Funct7D; logic [4:0] Rs1D; - `define CTRLW 23 + `define CTRLW 24 // pipelined control signals logic RegWriteE; @@ -86,9 +87,12 @@ module controller( logic CSRZeroSrcD; logic CSRReadD; logic [1:0] AtomicD; + logic FenceD; + logic InvalidateICacheD, FlushDCacheD; logic CSRWriteD, CSRWriteE; logic InstrValidD, InstrValidE; logic PrivilegedD, PrivilegedE; + logic InvalidateICacheE, FlushDCacheE; logic [`CTRLW-1:0] ControlsD; logic aluc3D; logic subD, sraD, sltD, sltuD; @@ -103,55 +107,53 @@ module controller( assign Rs1D = InstrD[19:15]; // Main Instruction Decoder - // *** perhaps decoding of non-IEU instructions should also go here, and should be gated by MISA bits in a generate so - // they don't get generated if that mode is disabled generate always_comb case(OpD) - // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_MulDiv_Atomic_Illegal - 7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // illegal instruction - 7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_00_0_0_0_0_0_0_00_0; // lw - 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_00_0_0_0_0_0_0_00_0; // flw - 7'b0001111: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_0; // fence = nop - 7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_0_0_0_0_00_0; // I-type ALU - 7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_00_0_0_0_0_0_0_00_0; // auipc + // RegWrite_ImmSrc_ALUSrc_MemRW_ResultSrc_Branch_ALUOp_Jump_TargetSrc_W64_CSRRead_Privileged_Fence_MulDiv_Atomic_Illegal + 7'b0000000: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // illegal instruction + 7'b0000011: ControlsD = `CTRLW'b1_000_01_10_001_0_00_0_0_0_0_0_0_0_00_0; // lw + 7'b0000111: ControlsD = `CTRLW'b0_000_01_10_001_0_00_0_0_0_0_0_0_0_00_0; // flw + 7'b0001111: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_1_0_00_0; // fence + 7'b0010011: ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_0_0_0_0_0_00_0; // I-type ALU + 7'b0010111: ControlsD = `CTRLW'b1_100_11_00_000_0_00_0_0_0_0_0_0_0_00_0; // auipc 7'b0011011: if (`XLEN == 64) - ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_1_0_0_0_00_0; // IW-type ALU for RV64i + ControlsD = `CTRLW'b1_000_01_00_000_0_10_0_0_1_0_0_0_0_00_0; // IW-type ALU for RV64i else - ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction - 7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_00_0; // sw - 7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_00_0; // fsw + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction + 7'b0100011: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_0_00_0; // sw + 7'b0100111: ControlsD = `CTRLW'b0_001_01_01_000_0_00_0_0_0_0_0_0_0_00_0; // fsw 7'b0101111: if (`A_SUPPORTED) begin if (InstrD[31:27] == 5'b00010) - ControlsD = `CTRLW'b1_000_00_10_001_0_00_0_0_0_0_0_0_01_0; // lr + ControlsD = `CTRLW'b1_000_00_10_001_0_00_0_0_0_0_0_0_0_01_0; // lr else if (InstrD[31:27] == 5'b00011) - ControlsD = `CTRLW'b1_101_01_01_100_0_00_0_0_0_0_0_0_01_0; // sc + ControlsD = `CTRLW'b1_101_01_01_100_0_00_0_0_0_0_0_0_0_01_0; // sc else - ControlsD = `CTRLW'b1_101_01_11_001_0_00_0_0_0_0_0_0_10_0;; // amo + ControlsD = `CTRLW'b1_101_01_11_001_0_00_0_0_0_0_0_0_0_10_0;; // amo end else - ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction 7'b0110011: if (Funct7D == 7'b0000000 || Funct7D == 7'b0100000) - ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_0_0_0_0_00_0; // R-type + ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_0_0_0_0_0_00_0; // R-type else if (Funct7D == 7'b0000001 && `M_SUPPORTED) - ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_0_0_0_1_00_0; // Multiply/Divide + ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_0_0_0_0_1_00_0; // Multiply/Divide else - ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction - 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_0_0_0_0_00_0; // lui + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction + 7'b0110111: ControlsD = `CTRLW'b1_100_01_00_000_0_11_0_0_0_0_0_0_0_00_0; // lui 7'b0111011: if ((Funct7D == 7'b0000000 || Funct7D == 7'b0100000) && `XLEN == 64) - ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_1_0_0_0_00_0; // R-type W instructions for RV64i + ControlsD = `CTRLW'b1_000_00_00_000_0_10_0_0_1_0_0_0_0_00_0; // R-type W instructions for RV64i else if (Funct7D == 7'b0000001 && `M_SUPPORTED && `XLEN == 64) - ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_1_0_0_1_00_0; // W-type Multiply/Divide + ControlsD = `CTRLW'b1_000_00_00_011_0_00_0_0_1_0_0_0_1_00_0; // W-type Multiply/Divide else - ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction - //7'b1010011: ControlsD = `CTRLW'b0_000_00_00_101_0_00_0_0_0_0_0_0_00_1; // FP - 7'b1100011: ControlsD = `CTRLW'b0_010_00_00_000_1_01_0_0_0_0_0_0_00_0; // beq - 7'b1100111: ControlsD = `CTRLW'b1_000_00_00_000_0_00_1_1_0_0_0_0_00_0; // jalr - 7'b1101111: ControlsD = `CTRLW'b1_011_00_00_000_0_00_1_0_0_0_0_0_00_0; // jal + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction + //7'b1010011: ControlsD = `CTRLW'b0_000_00_00_101_0_00_0_0_0_0_0_0_0_00_1; // FP + 7'b1100011: ControlsD = `CTRLW'b0_010_00_00_000_1_01_0_0_0_0_0_0_0_00_0; // beq + 7'b1100111: ControlsD = `CTRLW'b1_000_00_00_000_0_00_1_1_0_0_0_0_0_00_0; // jalr + 7'b1101111: ControlsD = `CTRLW'b1_011_00_00_000_0_00_1_0_0_0_0_0_0_00_0; // jal 7'b1110011: if (Funct3D == 3'b000) - ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_1_0_00_0; // privileged; decoded further in priveleged modules + ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_1_0_0_00_0; // privileged; decoded further in priveleged modules else - ControlsD = `CTRLW'b1_000_00_00_010_0_00_0_0_0_1_0_0_00_0; // csrs - default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_00_1; // non-implemented instruction + ControlsD = `CTRLW'b1_000_00_00_010_0_00_0_0_0_1_0_0_0_00_0; // csrs + default: ControlsD = `CTRLW'b0_000_00_00_000_0_00_0_0_0_0_0_0_0_00_1; // non-implemented instruction endcase endgenerate @@ -160,7 +162,7 @@ module controller( assign IllegalBaseInstrFaultD = ControlsD[0]; assign {RegWriteD, ImmSrcD, ALUSrcAD, ALUSrcBD, MemRWD, ResultSrcD, BranchD, ALUOpD, JumpD, TargetSrcD, W64D, CSRReadD, - PrivilegedD, MulDivD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD; + PrivilegedD, FenceD, MulDivD, AtomicD, unused} = IllegalIEUInstrFaultD ? `CTRLW'b0 : ControlsD; // *** move Privileged, CSRwrite?? Or move controller out of IEU into datapath and handle all instructions assign CSRZeroSrcD = InstrD[14] ? (InstrD[19:15] == 0) : (Rs1D == 0); // Is a CSR instruction using zero as the source? @@ -181,14 +183,29 @@ module controller( 2'b11: ALUControlD = 5'b01110; // pass B through for lui default: ALUControlD = {W64D, aluc3D, Funct3D}; // R-type instructions endcase - + + // Fences + // Ordinary fence is presently a nop + // FENCE.I flushes the D$ and invalidates the I$ if Zifencei is supported and I$ is implemented + generate + if (`ZIFENCEI_SUPPORTED & `MEM_ICACHE) begin + logic FenceID; + assign FenceID = FenceD & (Funct3D == 3'b001); // is it a FENCE.I instruction? + assign InvalidateICacheD = FenceID; + assign FlushDCacheD = FenceID; + end else begin + assign InvalidateICacheD = 0; + assign FlushDCacheD = 0; + end + endgenerate + // Decocde stage pipeline control register flopenrc #(1) controlregD(clk, reset, FlushD, ~StallD, 1'b1, InstrValidD); // Execute stage pipeline control register and logic - flopenrc #(27) controlregE(clk, reset, FlushE, ~StallE, - {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InstrValidD}, - {RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InstrValidE}); + flopenrc #(29) controlregE(clk, reset, FlushE, ~StallE, + {RegWriteD, ResultSrcD, MemRWD, JumpD, BranchD, ALUControlD, ALUSrcAD, ALUSrcBD, TargetSrcD, CSRReadD, CSRWriteD, PrivilegedD, Funct3D, W64D, MulDivD, AtomicD, InvalidateICacheD, FlushDCacheD, InstrValidD}, + {RegWriteE, ResultSrcE, MemRWE, JumpE, BranchE, ALUControlE, ALUSrcAE, ALUSrcBE, TargetSrcE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, W64E, MulDivE, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE}); // Branch Logic assign {zeroE, ltE, ltuE} = FlagsE; @@ -210,9 +227,9 @@ module controller( assign SCE = (ResultSrcE == 3'b100); // Memory stage pipeline control register - flopenrc #(15) controlregM(clk, reset, FlushM, ~StallM, - {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, AtomicE, InstrValidE}, - {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, AtomicM, InstrValidM}); + flopenrc #(17) controlregM(clk, reset, FlushM, ~StallM, + {RegWriteE, ResultSrcE, MemRWE, CSRReadE, CSRWriteE, PrivilegedE, Funct3E, AtomicE, InvalidateICacheE, FlushDCacheE, InstrValidE}, + {RegWriteM, ResultSrcM, MemRWM, CSRReadM, CSRWriteM, PrivilegedM, Funct3M, AtomicM, InvalidateICacheM, FlushDCacheM, InstrValidM}); // Writeback stage pipeline control register flopenrc #(5) controlregW(clk, reset, FlushW, ~StallW, diff --git a/wally-pipelined/src/ieu/ieu.sv b/wally-pipelined/src/ieu/ieu.sv index b23f61b6..f2984d7f 100644 --- a/wally-pipelined/src/ieu/ieu.sv +++ b/wally-pipelined/src/ieu/ieu.sv @@ -59,6 +59,7 @@ module ieu ( output logic [4:0] RdM, input logic DataAccessFaultM, input logic [`XLEN-1:0] FIntResM, + output logic InvalidateICacheM, FlushDCacheM, // Writeback stage input logic [`XLEN-1:0] CSRReadValW, ReadDataM, MulDivResultW, diff --git a/wally-pipelined/src/ifu/ifu.sv b/wally-pipelined/src/ifu/ifu.sv index 7215c382..69f61d8e 100644 --- a/wally-pipelined/src/ifu/ifu.sv +++ b/wally-pipelined/src/ifu/ifu.sv @@ -48,6 +48,7 @@ module ifu ( // Mem input logic RetM, TrapM, input logic [`XLEN-1:0] PrivilegedNextPCM, + input logic InvalidateICacheM, output logic [31:0] InstrD, InstrE, InstrM, InstrW, output logic [`XLEN-1:0] PCM, output logic [4:0] InstrClassM, @@ -153,7 +154,8 @@ module ifu ( icache icache(.*, .PCNextF(PCNextFPhys), .PCPF(PCPFmmu), - .WalkerInstrPageFaultF(WalkerInstrPageFaultF)); + .WalkerInstrPageFaultF, + .InvalidateICacheM); flopenl #(32) AlignedInstrRawDFlop(clk, reset | reset_q, ~StallD, FlushD ? nop : FinalInstrRawF, nop, InstrRawD); @@ -171,11 +173,16 @@ module ifu ( .y(PCNext1F)); mux2 #(`XLEN) pcmux2(.d0(PCNext1F), + .d1(PCE), + .s(InvalidateICacheM), + .y(PCNext2F)); + + mux2 #(`XLEN) pcmux3(.d0(PCNext2F), .d1(PrivilegedNextPCM), .s(PrivilegedChangePCM), - .y(PCNext2F)); + .y(PCNext3F)); - mux2 #(`XLEN) pcmux4(.d0(PCNext2F), + mux2 #(`XLEN) pcmux4(.d0(PCNext3F), .d1(`RESET_VECTOR), .s(reset_q), .y(UnalignedPCNextF)); diff --git a/wally-pipelined/src/lsu/lsu.sv b/wally-pipelined/src/lsu/lsu.sv index ed13ebeb..feb212e8 100644 --- a/wally-pipelined/src/lsu/lsu.sv +++ b/wally-pipelined/src/lsu/lsu.sv @@ -42,6 +42,7 @@ module lsu input logic [1:0] AtomicM, input logic ExceptionM, input logic PendingInterruptM, + input logic FlushDCacheM, output logic CommittedM, output logic SquashSCW, output logic DataMisalignedM, @@ -222,11 +223,6 @@ module lsu // *** BUG, this is most likely wrong assign CacheableMtoDCache = SelPTW ? 1'b1 : CacheableM; - generate - if (`XLEN == 32) assign DCtoAHBSizeM = CacheableMtoDCache ? 3'b010 : Funct3MtoDCache; - else assign DCtoAHBSizeM = CacheableMtoDCache ? 3'b011 : Funct3MtoDCache; - endgenerate; - // Specify which type of page fault is occurring assign DTLBLoadPageFaultM = DTLBPageFaultM & MemRWMtoLRSC[1]; @@ -253,7 +249,8 @@ module lsu .FlushW(FlushWtoDCache), .MemRWM(MemRWMtoDCache), .Funct3M(Funct3MtoDCache), - .Funct7M(Funct7M), + .Funct7M(Funct7M), + .FlushDCacheM, .AtomicM(AtomicMtoDCache), .MemAdrE(MemAdrEtoDCache), .MemPAdrM(MemPAdrM), @@ -282,7 +279,8 @@ module lsu .AHBWrite(DCtoAHBWriteM), .AHBAck(DCfromAHBAck), .HWDATA(DCtoAHBWriteData), - .HRDATA(DCfromAHBReadData) + .HRDATA(DCfromAHBReadData), + .DCtoAHBSizeM ); endmodule diff --git a/wally-pipelined/src/mmu/adrdecs.sv b/wally-pipelined/src/mmu/adrdecs.sv index 3084b0ac..7e35f882 100644 --- a/wally-pipelined/src/mmu/adrdecs.sv +++ b/wally-pipelined/src/mmu/adrdecs.sv @@ -30,19 +30,20 @@ module adrdecs ( input logic [`PA_BITS-1:0] PhysicalAddress, input logic AccessRW, AccessRX, AccessRWX, input logic [1:0] Size, - output logic [6:0] SelRegions + output logic [7:0] SelRegions ); // Determine which region of physical memory (if any) is being accessed // *** eventually uncomment Access signals - adrdec boottimdec(PhysicalAddress, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[5]); - adrdec timdec(PhysicalAddress, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[4]); - adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[3]); - adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[2]); - adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[1]); - adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[0]); + adrdec boottimdec(PhysicalAddress, `BOOTTIM_BASE, `BOOTTIM_RANGE, `BOOTTIM_SUPPORTED, /*1'b1*/AccessRX, Size, 4'b1111, SelRegions[6]); + adrdec timdec(PhysicalAddress, `TIM_BASE, `TIM_RANGE, `TIM_SUPPORTED, /*1'b1*/AccessRWX, Size, 4'b1111, SelRegions[5]); + adrdec clintdec(PhysicalAddress, `CLINT_BASE, `CLINT_RANGE, `CLINT_SUPPORTED, AccessRW, Size, 4'b1111, SelRegions[4]); + adrdec gpiodec(PhysicalAddress, `GPIO_BASE, `GPIO_RANGE, `GPIO_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[3]); + adrdec uartdec(PhysicalAddress, `UART_BASE, `UART_RANGE, `UART_SUPPORTED, AccessRW, Size, 4'b0001, SelRegions[2]); + adrdec plicdec(PhysicalAddress, `PLIC_BASE, `PLIC_RANGE, `PLIC_SUPPORTED, AccessRW, Size, 4'b0100, SelRegions[1]); + adrdec sdcdec(PhysicalAddress, `SDC_BASE, `SDC_RANGE, `SDC_SUPPORTED, AccessRW, Size, 4'b1100, SelRegions[0]); - assign SelRegions[6] = ~|(SelRegions[5:0]); + assign SelRegions[7] = ~|(SelRegions[6:0]); endmodule diff --git a/wally-pipelined/src/mmu/pmachecker.sv b/wally-pipelined/src/mmu/pmachecker.sv index a95252f3..5ce62c0d 100644 --- a/wally-pipelined/src/mmu/pmachecker.sv +++ b/wally-pipelined/src/mmu/pmachecker.sv @@ -45,7 +45,7 @@ module pmachecker ( logic PMAAccessFault; logic AccessRW, AccessRWX, AccessRX; - logic [6:0] SelRegions; + logic [7:0] SelRegions; // Determine what type of access is being made assign AccessRW = ReadAccessM | WriteAccessM; @@ -61,7 +61,7 @@ module pmachecker ( assign AtomicAllowed = SelRegions[4]; // Detect access faults - assign PMAAccessFault = SelRegions[6] & AccessRWX; + assign PMAAccessFault = SelRegions[7] & AccessRWX; assign PMAInstrAccessFaultF = ExecuteAccessF && PMAAccessFault; assign PMALoadAccessFaultM = ReadAccessM && PMAAccessFault; assign PMAStoreAccessFaultM = WriteAccessM && PMAAccessFault; diff --git a/wally-pipelined/src/privileged/csr.sv b/wally-pipelined/src/privileged/csr.sv index eb532253..b995a3bb 100644 --- a/wally-pipelined/src/privileged/csr.sv +++ b/wally-pipelined/src/privileged/csr.sv @@ -90,7 +90,7 @@ module csr #(parameter logic IllegalCSRMWriteReadonlyM; generate - if (`ZCSR_SUPPORTED) begin + if (`ZICSR_SUPPORTED) begin // modify CSRs always_comb begin // Choose either rs1 or uimm[4:0] as source diff --git a/wally-pipelined/src/privileged/csrc.sv b/wally-pipelined/src/privileged/csrc.sv index 4149e0cb..3b1e544d 100644 --- a/wally-pipelined/src/privileged/csrc.sv +++ b/wally-pipelined/src/privileged/csrc.sv @@ -91,7 +91,7 @@ module csrc #(parameter ); generate - if (`ZCOUNTERS_SUPPORTED) begin + if (`ZICOUNTERS_SUPPORTED) begin // logic [63:0] TIME_REGW, TIMECMP_REGW; logic [63:0] CYCLE_REGW, INSTRET_REGW; logic [63:0] HPMCOUNTER3_REGW, HPMCOUNTER4_REGW; // add more performance counters here if desired @@ -413,7 +413,7 @@ module csrc #(parameter genvar j; generate - if (`ZCOUNTERS_SUPPORTED) begin + if (`ZICOUNTERS_SUPPORTED) begin logic [`COUNTERS:0][63:0] HPMCOUNTER_REGW; logic [`COUNTERS:0][63:0] HPMCOUNTERPlusM; logic [`COUNTERS:0][`XLEN-1:0] NextHPMCOUNTERM; diff --git a/wally-pipelined/src/privileged/trap.sv b/wally-pipelined/src/privileged/trap.sv index 6bb41597..5814f915 100644 --- a/wally-pipelined/src/privileged/trap.sv +++ b/wally-pipelined/src/privileged/trap.sv @@ -159,6 +159,7 @@ module trap ( if (InstrMisalignedFaultM) NextFaultMtvalM = InstrMisalignedAdrM; else if (LoadMisalignedFaultM) NextFaultMtvalM = MemAdrM; else if (StoreMisalignedFaultM) NextFaultMtvalM = MemAdrM; + else if (BreakpointFaultM) NextFaultMtvalM = PCM; else if (InstrPageFaultM) NextFaultMtvalM = PCM; else if (LoadPageFaultM) NextFaultMtvalM = MemAdrM; else if (StorePageFaultM) NextFaultMtvalM = MemAdrM; diff --git a/wally-pipelined/src/sdc/SDC.sv b/wally-pipelined/src/sdc/SDC.sv new file mode 100644 index 00000000..1f66e770 --- /dev/null +++ b/wally-pipelined/src/sdc/SDC.sv @@ -0,0 +1,339 @@ +/////////////////////////////////////////// +// SDC.sv +// +// Written: Ross Thompson September 22, 2021 +// Modified: +// +// Purpose: SDC interface to AHBLite BUS. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +`define SDCCLKDIV -8'd2 + +module SDC + (input logic HCLK, + input logic HRESETn, + input logic HSELSDC, + input logic [4:0] HADDR, + input logic HWRITE, + input logic HREADY, + input logic [1:0] HTRANS, + input logic [`XLEN-1:0] HWDATA, + output logic [`XLEN-1:0] HREADSDC, + output logic HRESPSDC, + output logic HREADYSDC, + + //sd card interface + // place the tristate drivers at the top. this level + // will use dedicated 1 direction ports. + output logic SDCCmdOut, + input logic SDCCmdIn, + output logic SDCCmdOE, + input logic [3:0] SDCDatIn, + output logic SDCCLK, + + // interrupt to PLIC + output logic SDCIntM); + + logic InitTrans; + logic RegRead; + logic RegWrite; + logic [4:0] HADDRDelay; + + + // Register outputs + logic [7:0] CLKDiv; + logic [2:0] Command; + logic [63:9] Address; + + + logic SDCDone; + + logic [2:0] ErrorCode; + logic InvalidCommand; + logic SDCBusy; + + logic StartCLKDivUpdate; + logic CLKDivUpdateEn; + logic SDCCLKEN; + logic CLKGate; + logic SDCCLKIn; + + + logic SDCDataValid; + logic [`XLEN-1:0] SDCReadData; + logic [`XLEN-1:0] SDCWriteData; + logic FatalError; + + logic [4095:0] ReadData512Byte; + logic [`XLEN-1:0] ReadData512ByteWords [4096/`XLEN-1:0] ; + logic SDCInitialized; + logic SDCRestarting; + logic SDCLast; + + logic [$clog2(4096/`XLEN)-1:0] WordCount; + logic WordCountRst; + logic [5:0] Status; + logic CommandCompleted; + logic ReadDone; + + + + genvar index; + + assign HRESPSDC = 1'b0; + + // registers + //| Offset | Name | Size | Purpose | + //|--------+---------+--------+------------------------------------------------| + //| 0x0 | CLKDiv | 4 | Divide HCLK to produce SDCLK | + //| 0x4 | Status | 4 | Provide status to software | + //| 0x8 | Control | 4 | Send commands to SDC | + //| 0xC | Size | 4 | Size of data command (only 512 byte supported) | + //| 0x10 | address | 8 | address of operation | + //| 0x18 | data | XLEN/8 | Data Bus interface | + + // Status contains + // Status[0] initialized + // Status[1] Busy on read + // Status[2] invalid command + // Status[5:3] error code + + // control contains 3 bit command + // control[2:0] + // 000 nop op + // xx1 initialize + // 010 Write no implemented + // 100 Read + // 110 Atomic read/write not implemented + + // size is fixed to 512. Read only + + + // Currently using a mailbox style interface. Data is passed through the Data register (0x10) + // The card will support 3 operations + // 1. initialize + // 2. read + // 3. write + // all read and write operations will occur on 512 bytes (4096 bits) of data + // starting at the 512 byte aligned address in the address register This register + // is the byte address. + + // currently does not support writes + + assign InitTrans = HREADY & HSELSDC & (HTRANS != 2'b00); + assign RegRead = InitTrans & ~HWRITE; + // AHBLite Spec has write data 1 cycle after write command + flopr #(1) RegWriteReg(HCLK, ~HRESETn, InitTrans & HWRITE, RegWrite); + + flopenr #(5) HADDRReg(HCLK, ~HRESETn, InitTrans, HADDR, HADDRDelay); + + assign StartCLKDivUpdate = HADDRDelay == '0 & RegWrite; + + flopenl #(8) CLKDivReg(HCLK, ~HRESETn, CLKDivUpdateEn, HWDATA[7:0], `SDCCLKDIV, CLKDiv); + + // Control reg + flopenl #(3) CommandReg(HCLK, ~HRESETn, (HADDRDelay == 'h8 & RegWrite) | (CommandCompleted), + CommandCompleted ? '0 : HWDATA[2:0], '0, Command); + + generate + if (`XLEN == 64) begin + flopenr #(64-9) AddressReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite), + HWDATA[`XLEN-1:9], Address); + end else begin + flopenr #(32-9) AddressLowReg(HCLK, ~HRESETn, (HADDRDelay == 'h10 & RegWrite), + HWDATA[`XLEN-1:9], Address[31:9]); + flopenr #(32) AddressHighReg(HCLK, ~HRESETn, (HADDRDelay == 'h14 & RegWrite), + HWDATA, Address[63:32]); + end + endgenerate + + flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite), + HWDATA, SDCWriteData); + + assign InvalidCommand = (Command[2] | Command[1]) & Command[0]; + + assign Status = {ErrorCode, InvalidCommand, SDCBusy, SDCInitialized}; + + generate + if(`XLEN == 64) begin + always_comb + case(HADDRDelay[4:0]) + 'h0: HREADSDC = {24'b0, CLKDiv, 26'b0, Status}; + 'h4: HREADSDC = {26'b0, Status, 29'b0, Command}; + 'h8: HREADSDC = {29'b0, Command, 32'h200}; + 'hC: HREADSDC = {32'h200, Address[31:9], 9'b0}; + 'h10: HREADSDC = {Address, 9'b0}; + 'h18: HREADSDC = SDCReadData; + default: HREADSDC = {24'b0, CLKDiv, 26'b0, Status}; + endcase // case (HADDRDelay[4:0]) + end else begin + always_comb + case(HADDRDelay[4:0]) + 'h0: HREADSDC = {24'b0, CLKDiv}; + 'h4: HREADSDC = {26'b0, Status}; + 'h8: HREADSDC = {29'b0, Command}; + 'hC: HREADSDC = 'h200; + 'h10: HREADSDC = {Address[31:9], 9'b0}; + 'h14: HREADSDC = Address[63:32]; + 'h18: HREADSDC = SDCReadData[31:0]; + default: HREADSDC = {24'b0, CLKDiv}; + endcase + end + endgenerate + + + for(index = 0; index < 4096/`XLEN; index++) begin + assign ReadData512ByteWords[index] = ReadData512Byte[(index+1)*`XLEN-1:index*`XLEN]; + end + + assign SDCReadData = ReadData512ByteWords[WordCount]; + + flopenr #($clog2(4096/`XLEN)) WordCountReg + (.clk(HCLK), + .reset(~HRESETn | WordCountRst), + .en(HADDRDelay[4:0] == 'h18 & ReadDone), + .d(WordCount + 1'b1), + .q(WordCount)); + + + + typedef enum {STATE_READY, + + // clock update states + STATE_CLK_DIV1, + STATE_CLK_DIV2, + STATE_CLK_DIV3, + STATE_CLK_DIV4, + + // restart SDC + STATE_RESTART, + + // SDC operation + STATE_PROCESS_CMD, + + STATE_READ + } statetype; + + + statetype CurrState, NextState; + + always_ff @(posedge HCLK, negedge HRESETn) + if (~HRESETn) CurrState <= STATE_READY; + else CurrState <= NextState; + + always_comb begin + CLKDivUpdateEn = 1'b0; + HREADYSDC = 1'b0; + SDCCLKEN = 1'b1; + WordCountRst = 1'b0; + SDCBusy = 1'b0; + CommandCompleted = 1'b0; + ReadDone = 1'b0; + + case (CurrState) + STATE_READY : begin + if (StartCLKDivUpdate)begin + NextState = STATE_CLK_DIV1; + HREADYSDC = 1'b0; + end else if (Command[2] | Command[1]) begin + NextState = STATE_PROCESS_CMD; + HREADYSDC = 1'b0; + end else if(HADDR[4:0] == 'h18 & RegRead) begin + NextState = STATE_READ; + HREADYSDC = 1'b0; + end else begin + NextState = STATE_READY; + HREADYSDC = 1'b1; + end + end + STATE_CLK_DIV1: begin + NextState = STATE_CLK_DIV2; + SDCCLKEN = 1'b0; + end + STATE_CLK_DIV2: begin + NextState = STATE_CLK_DIV3; + CLKDivUpdateEn = 1'b1; + SDCCLKEN = 1'b0; + end + STATE_CLK_DIV3: begin + NextState = STATE_CLK_DIV4; + SDCCLKEN = 1'b0; + end + STATE_CLK_DIV4: begin + NextState = STATE_READY; + end + STATE_PROCESS_CMD: begin + HREADYSDC = 1'b1; + WordCountRst = 1'b1; + SDCBusy = 1'b1; + if(SDCDataValid) begin + NextState = STATE_READY; + CommandCompleted = 1'b1; + end else begin + NextState = STATE_PROCESS_CMD; + CommandCompleted = 1'b0; + end + end + STATE_READ: begin + NextState = STATE_READY; + HREADYSDC = 1'b1; + ReadDone = 1'b1; + end + endcase + end + + // clock generation divider + + clockgater clockgater(.E(SDCCLKEN), + .SE(1'b0), + .CLK(HCLK), + .ECLK(CLKGate)); + + + clkdivider #(8) clkdivider(.i_COUNT_IN_MAX(CLKDiv), + .i_EN(CLKDiv != 'b1), + .i_CLK(CLKGate), + .i_RST(~HRESETn | CLKDivUpdateEn), + .o_CLK(SDCCLKIn)); + + sd_top sd_top(.CLK(SDCCLKIn), + .a_RST(~HRESETn), + .i_SD_CMD(SDCCmdIn), + .o_SD_CMD(SDCCmdOut), + .o_SD_CMD_OE(SDCCmdOE), + .i_SD_DAT(SDCDatIn), + .o_SD_CLK(SDCCLK), + .i_BLOCK_ADDR(Address[32:9]), + .o_READY_FOR_READ(SDCInitialized), + .o_SD_RESTARTING(SDCRestarting), + .i_READ_REQUEST(Command[2]), + .o_DATA_TO_CORE(), + .ReadData(ReadData512Byte), + .o_DATA_VALID(SDCDataValid), + .o_LAST_NIBBLE(SDCLast), + .o_ERROR_CODE_Q(ErrorCode), + .o_FATAL_ERROR(FatalError), + .i_COUNT_IN_MAX(-8'd62), + .LIMIT_SD_TIMERS(1'b1)); // *** must change this to 0 for real hardware. + + +endmodule + diff --git a/wally-pipelined/src/sdc/clkdivider.sv b/wally-pipelined/src/sdc/clkdivider.sv new file mode 100644 index 00000000..084d020a --- /dev/null +++ b/wally-pipelined/src/sdc/clkdivider.sv @@ -0,0 +1,72 @@ +/////////////////////////////////////////// +// clock divider.sv +// +// Written: Ross Thompson September 18, 2021 +// Modified: +// +// Purpose: clock divider for sd flash +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module clkdivider #(parameter integer g_COUNT_WIDTH) + ( + input logic [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX, //((Divide by value)/2) - 1 + input logic i_EN, //Enable frequency division of i_clk + input logic i_CLK, // 1.2 GHz Base clock + input logic i_RST, // at start: clears flip flop and loads counter, + // i_RST must NOT be a_RST, it needs to be synchronized with the 50 MHz Clock to load the + // counter's initial value + output logic o_CLK // frequency divided clock + ); + + + logic [g_COUNT_WIDTH-1:0] r_count_out; // wider for sign + logic w_counter_overflowed; + + logic r_fd_Q; + logic w_fd_D; + + logic w_load; + + assign w_load = i_RST | w_counter_overflowed; // reload when zero occurs or when set by outside + + counter #(.WIDTH(g_COUNT_WIDTH)) // wider for sign, this way the (MSB /= '1') only for zero + my_counter (.clk(i_CLK), + .Load(w_load), // reload when zero occurs or when set by outside + .CountIn(i_COUNT_IN_MAX), // negative signed integer + .CountOut(r_count_out), + .Enable(1'b1), // ALWAYS COUNT + .reset(1'b0)); // no reset, only load + + + assign w_counter_overflowed = r_count_out[g_COUNT_WIDTH-1] == '0; + + flopenr #(1) toggle_flip_flop + (.d(w_fd_D), + .q(r_fd_Q), + .clk(i_CLK), + .reset(i_RST), // reset when told by outside + .en(w_counter_overflowed)); // only update when counter overflows + + assign w_fd_D = ~ r_fd_Q; + + assign o_CLK = i_EN ? r_fd_Q : i_CLK; + +endmodule diff --git a/wally-pipelined/src/sdc/counter.sv b/wally-pipelined/src/sdc/counter.sv new file mode 100644 index 00000000..2a1f93bc --- /dev/null +++ b/wally-pipelined/src/sdc/counter.sv @@ -0,0 +1,54 @@ +/////////////////////////////////////////// +// counter.sv +// +// Written: Ross Thompson +// Modified: +// +// Purpose: basic up counter +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module counter #(parameter integer WIDTH=32) + ( + input logic [WIDTH-1:0] CountIn, + output logic [WIDTH-1:0] CountOut, + input logic Load, + input logic Enable, + input logic clk, + input logic reset); + + logic [WIDTH-1:0] NextCount; + logic [WIDTH-1:0] count_q; + logic [WIDTH-1:0] CountP1; + + flopenr #(WIDTH) reg1(.clk, + .reset, + .en(Enable | Load), + .d(NextCount), + .q(CountOut)); + + assign CountP1 = CountOut + 1'b1; + + // mux between load and P1 + assign NextCount = Load ? CountIn : CountP1; + +endmodule + + diff --git a/wally-pipelined/src/sdc/crc16_sipo_np_ce.sv b/wally-pipelined/src/sdc/crc16_sipo_np_ce.sv new file mode 100644 index 00000000..444555c7 --- /dev/null +++ b/wally-pipelined/src/sdc/crc16_sipo_np_ce.sv @@ -0,0 +1,62 @@ +/////////////////////////////////////////// +// crc16 sipo np ce +// +// Written: Ross Thompson September 18, 2021 +// Modified: +// +// Purpose: CRC16 generator SIPO using register_ce +// w/o appending any zero-bits to the message +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module crc16_sipo_np_ce + (input logic CLK, // sequential device + input logic RST, // initial calue of CRC register must be "0000_0000_0000_0000" + input logic i_enable, // input is valid + input logic i_message_bit, + output logic [15:0] o_crc16); + + logic [15:0] w_crc16_d; + + flopenr #(16) crc16reg(.clk(CLK), + .reset(RST), + .en(i_enable), + .d(w_crc16_d), + .q(o_crc16)); + + assign w_crc16_d[15] = o_crc16[14]; + assign w_crc16_d[14] = o_crc16[13]; + assign w_crc16_d[13] = o_crc16[12]; + assign w_crc16_d[12] = o_crc16[11] ^ (i_message_bit ^ o_crc16[15]); + assign w_crc16_d[11] = o_crc16[10]; + assign w_crc16_d[10] = o_crc16[9]; + assign w_crc16_d[9] = o_crc16[8]; + assign w_crc16_d[8] = o_crc16[7]; + assign w_crc16_d[7] = o_crc16[6]; + assign w_crc16_d[6] = o_crc16[5]; + assign w_crc16_d[5] = o_crc16[4] ^ (i_message_bit ^ o_crc16[15]); + assign w_crc16_d[4] = o_crc16[3]; + assign w_crc16_d[3] = o_crc16[2]; + assign w_crc16_d[2] = o_crc16[1]; + assign w_crc16_d[1] = o_crc16[0]; + assign w_crc16_d[0] = i_message_bit ^ o_crc16[15]; + + +endmodule diff --git a/wally-pipelined/src/sdc/crc7_pipo.sv b/wally-pipelined/src/sdc/crc7_pipo.sv new file mode 100644 index 00000000..46ba0062 --- /dev/null +++ b/wally-pipelined/src/sdc/crc7_pipo.sv @@ -0,0 +1,66 @@ +/////////////////////////////////////////// +// crc7 sipo np ce +// +// Written: Ross Thompson September 18, 2021 +// Modified: +// +// Purpose: takes 40 bits of input, generates 7 bit CRC after a single +// clock cycle! +// w/o appending any zero-bits to the message +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module crc7_pipo + (input logic [39:0] i_DATA, + input logic i_CRC_ENABLE, + input logic RST, + input logic CLK, + output logic [6:0] o_CRC); + + logic [6:0] r_lfsr_q; + logic [6:0] w_lfsr_d; + + assign o_CRC = r_lfsr_q; + + assign w_lfsr_d[0] = r_lfsr_q[1] ^ r_lfsr_q[2] ^ r_lfsr_q[4] ^ r_lfsr_q[6] ^ i_DATA[0] ^ i_DATA[4] ^ i_DATA[7] ^ i_DATA[8] ^ i_DATA[12] ^ i_DATA[14] ^ i_DATA[15] ^ i_DATA[16] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[21] ^ i_DATA[23] ^ i_DATA[24] ^ i_DATA[30] ^ i_DATA[31] ^ i_DATA[34] ^ i_DATA[35] ^ i_DATA[37] ^ i_DATA[39]; + + assign w_lfsr_d[1] = r_lfsr_q[2] ^ r_lfsr_q[3] ^ r_lfsr_q[5] ^ i_DATA[1] ^ i_DATA[5] ^ i_DATA[8] ^ i_DATA[9] ^ i_DATA[13] ^ i_DATA[15] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[21] ^ i_DATA[22] ^ i_DATA[24] ^ i_DATA[25] ^ i_DATA[31] ^ i_DATA[32] ^ i_DATA[35] ^ i_DATA[36] ^ i_DATA[38]; + + assign w_lfsr_d[2] = r_lfsr_q[0] ^ r_lfsr_q[3] ^ r_lfsr_q[4] ^ r_lfsr_q[6] ^ i_DATA[2] ^ i_DATA[6] ^ i_DATA[9] ^ i_DATA[10] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[22] ^ i_DATA[23] ^ i_DATA[25] ^ i_DATA[26] ^ i_DATA[32] ^ i_DATA[33] ^ i_DATA[36] ^ i_DATA[37] ^ i_DATA[39]; + + assign w_lfsr_d[3] = r_lfsr_q[0] ^ r_lfsr_q[2] ^ r_lfsr_q[5] ^ r_lfsr_q[6] ^ i_DATA[0] ^ i_DATA[3] ^ i_DATA[4] ^ i_DATA[8] ^ i_DATA[10] ^ i_DATA[11] ^ i_DATA[12] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[20] ^ i_DATA[26] ^ i_DATA[27] ^ i_DATA[30] ^ i_DATA[31] ^ i_DATA[33] ^ i_DATA[35] ^ i_DATA[38] ^ i_DATA[39]; + + assign w_lfsr_d[4] = r_lfsr_q[1] ^ r_lfsr_q[3] ^ r_lfsr_q[6] ^ i_DATA[1] ^ i_DATA[4] ^ i_DATA[5] ^ i_DATA[9] ^ i_DATA[11] ^ i_DATA[12] ^ i_DATA[13] ^ i_DATA[15] ^ i_DATA[17] ^ i_DATA[18] ^ i_DATA[20] ^ i_DATA[21] ^ i_DATA[27] ^ i_DATA[28] ^ i_DATA[31] ^ i_DATA[32] ^ i_DATA[34] ^ i_DATA[36] ^ i_DATA[39]; + + assign w_lfsr_d[5] = r_lfsr_q[0] ^ r_lfsr_q[2] ^ r_lfsr_q[4] ^ i_DATA[2] ^ i_DATA[5] ^ i_DATA[6] ^ i_DATA[10] ^ i_DATA[12] ^ i_DATA[13] ^ i_DATA[14] ^ i_DATA[16] ^ i_DATA[18] ^ i_DATA[19] ^ i_DATA[21] ^ i_DATA[22] ^ i_DATA[28] ^ i_DATA[29] ^ i_DATA[32] ^ i_DATA[33] ^ i_DATA[35] ^ i_DATA[37]; + + assign w_lfsr_d[6] = r_lfsr_q[0] ^ r_lfsr_q[1] ^ r_lfsr_q[3] ^ r_lfsr_q[5] ^ i_DATA[3] ^ i_DATA[6] ^ i_DATA[7] ^ i_DATA[11] ^ i_DATA[13] ^ i_DATA[14] ^ i_DATA[15] ^ i_DATA[17] ^ i_DATA[19] ^ i_DATA[20] ^ i_DATA[22] ^ i_DATA[23] ^ i_DATA[29] ^ i_DATA[30] ^ i_DATA[33] ^ i_DATA[34] ^ i_DATA[36] ^ i_DATA[38]; + + + + flopenr #(7) + lfsrReg(.clk(CLK), + .reset(RST), + .en(i_CRC_ENABLE), + .d(w_lfsr_d), + .q(r_lfsr_q)); + + +endmodule diff --git a/wally-pipelined/src/sdc/crc7_sipo_np_ce.sv b/wally-pipelined/src/sdc/crc7_sipo_np_ce.sv new file mode 100644 index 00000000..5721aa95 --- /dev/null +++ b/wally-pipelined/src/sdc/crc7_sipo_np_ce.sv @@ -0,0 +1,61 @@ +/////////////////////////////////////////// +// crc16 sipo np ce +// +// Written: Ross Thompson September 18, 2021 +// Modified: +// +// Purpose: CRC7 generator SIPO using register_ce +// w/o appending any zero-bits othe message +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module crc7_sipo_np_ce + ( + input logic clk, + input logic rst,// initial CRC value must be b"000_0000" + input logic i_enable, + input logic i_message_bit, + output logic [6:0] o_crc7); + + + logic [6:0] w_crc7_d; + logic [6:0] r_crc7_q; + + flopenr #(7) + crc7Reg(.clk(clk), + .reset(rst), + .en(i_enable), + .d(w_crc7_d), + .q(r_crc7_q)); + + assign w_crc7_d[6] = r_crc7_q[5]; + assign w_crc7_d[5] = r_crc7_q[4]; + assign w_crc7_d[4] = r_crc7_q[3]; + assign w_crc7_d[3] = r_crc7_q[2] ^ (i_message_bit ^ r_crc7_q[6]); + assign w_crc7_d[2] = r_crc7_q[1]; + assign w_crc7_d[1] = r_crc7_q[0]; + assign w_crc7_d[0] = i_message_bit ^ r_crc7_q[6]; + + assign o_crc7 = r_crc7_q; + + +endmodule + + diff --git a/wally-pipelined/src/sdc/piso_generic_ce.sv b/wally-pipelined/src/sdc/piso_generic_ce.sv new file mode 100644 index 00000000..ad1d6a17 --- /dev/null +++ b/wally-pipelined/src/sdc/piso_generic_ce.sv @@ -0,0 +1,51 @@ +/////////////////////////////////////////// +// piso generic ce +// +// Written: Ross Thompson September 18, 2021 +// Modified: +// +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module piso_generic_ce #(parameter integer g_BUS_WIDTH) + ( + input logic clk, + input logic i_load, + input logic [g_BUS_WIDTH-1:0] i_data, + input logic i_en, + output o_data); + + + logic [g_BUS_WIDTH-1:0] w_reg_d; + logic [g_BUS_WIDTH-1:0] r_reg_q; + + flopenr #(g_BUS_WIDTH) + shiftReg(.clk(clk), + .reset(1'b0), + .en(1'b1), + .d(w_reg_d), + .q(r_reg_q)); + + assign o_data = i_en ? r_reg_q[g_BUS_WIDTH - 1] : 1'b1; + assign w_reg_d = i_load ? i_data : + i_en ? {r_reg_q[g_BUS_WIDTH - 2 : 0], 1'b1} : + r_reg_q[g_BUS_WIDTH - 1 : 0]; + +endmodule diff --git a/wally-pipelined/src/sdc/regfile_p2r1w1_nibo.sv b/wally-pipelined/src/sdc/regfile_p2r1w1_nibo.sv new file mode 100644 index 00000000..b508ec36 --- /dev/null +++ b/wally-pipelined/src/sdc/regfile_p2r1w1_nibo.sv @@ -0,0 +1,49 @@ +/////////////////////////////////////////// +// regfile_p2r1w1_nibo +// +// Written: Ross Thompson September 18, 2021 +// Modified: 2 port register file with 1 read and 1 write +// +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module regfile_p2r1w1_nibo #(parameter integer DEPTH = 10, parameter integer WIDTH = 4) + (input logic clk, + input logic we1, + input logic [DEPTH-1:0] ra1, + output logic [WIDTH-1:0] rd1, + output logic [(2**DEPTH)*WIDTH-1:0] Rd1All, + input logic [DEPTH-1:0] wa1, + input logic [WIDTH-1:0] wd1); + + logic [WIDTH-1:0] regs [2**DEPTH-1:0]; + genvar index; + + always_ff @(posedge clk) begin + if(we1) begin + regs[wa1] <= wd1; + end + end + + assign rd1 = regs[ra1]; + for(index = 0; index < 2**DEPTH; index++) + assign Rd1All[index*WIDTH+WIDTH-1:index*WIDTH] = regs[index]; + +endmodule diff --git a/wally-pipelined/src/sdc/regfile_p2r1w1bwen.sv b/wally-pipelined/src/sdc/regfile_p2r1w1bwen.sv new file mode 100644 index 00000000..4ace3749 --- /dev/null +++ b/wally-pipelined/src/sdc/regfile_p2r1w1bwen.sv @@ -0,0 +1,51 @@ +/////////////////////////////////////////// +// regfile_p2r1w1bwen +// +// Written: Ross Thompson September 18, 2021 +// Modified: 2 port register file with 1 read and 1 write +// +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module regfile_p2r1w1bwen #(parameter integer DEPTH = 10, parameter integer WIDTH = 4) + (input logic clk, + input logic we1, + input logic [WIDTH-1:0] we1bit, + input logic [DEPTH-1:0] ra1, + output logic [WIDTH-1:0] rd1, + input logic [DEPTH-1:0] wa1, + input logic [WIDTH-1:0] wd1); + + logic [WIDTH-1:0] regs [2**DEPTH-1:0]; + integer i; + + always_ff @(posedge clk) begin + if(we1) begin + for (i=0; i < WIDTH; i++) begin + if(we1bit[i]) begin + regs[wa1][i] <= wd1[i]; + end + end + end + end + + assign rd1 = regs[ra1]; + +endmodule diff --git a/wally-pipelined/src/sdc/sd_clk_fsm.sv b/wally-pipelined/src/sdc/sd_clk_fsm.sv new file mode 100644 index 00000000..337cb8c7 --- /dev/null +++ b/wally-pipelined/src/sdc/sd_clk_fsm.sv @@ -0,0 +1,94 @@ +/////////////////////////////////////////// +// sd_clk_fsm.sv +// +// Written: Ross Thompson September 19, 2021 +// Modified: +// +// Purpose: Controls clock dividers. +// Replaces s_disable_sd_clocks, s_select_hs_clk, s_enable_hs_clk +// in sd_cmd_fsm.vhd. Attempts to correct issues with oversampling and +// under-sampling of control signals (for counter_cmd), that were present in my +// previous design. +// This runs on 50 MHz. +// sd_cmd_fsm will run on SD_CLK_Gated (50 MHz or 400 KHz, selected by this) +// asynchronous reset is used for both sd_cmd_fsm and for this. +// It must be synchronized with 50 MHz and held for a minimum period of a full +// 400 KHz pulse width. +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module sd_clk_fsm + ( + input logic CLK, + input logic i_RST, + output logic o_DONE, + input logic i_START, + input logic i_FATAL_ERROR, + output logic o_HS_TO_INIT_CLK_DIVIDER_RST, // resets clock divider that is going from 50 MHz to 400 KHz + output logic o_SD_CLK_SELECTED, // which clock is selected ('0'=HS or '1'=init) + output logic o_G_CLK_SD_EN); // Turns gated clock (G_CLK_SD) off and on + + + logic [3:0] w_next_state; + logic [3:0] r_curr_state; + + + // clock selection + parameter c_sd_clk_init = 1'b1; + parameter c_sd_clk_hs = 1'b0; + + // States + localparam s_reset = 4'b0000; + localparam s_enable_init_clk = 4'b0001; // enable 400 KHz + localparam s_disable_sd_clocks = 4'b0010; + localparam s_select_hs_clk = 4'b0011; + localparam s_enable_hs_clk = 4'b0100; + localparam s_done = 4'b0101; + localparam s_disable_sd_clocks_2 = 4'b0110; // if error occurs + localparam s_select_init_clk = 4'b0111; // if error occurs + localparam s_safe_state = 4'b1111; //always provide a safe state return if all states are not used + + flopenr #(4) stateReg(.clk(CLK), + .reset(i_RST), + .en(1'b1), + .d(w_next_state), + .q(r_curr_state)); + + assign w_next_state = i_RST ? s_reset : + r_curr_state == s_reset | (r_curr_state == s_enable_init_clk & ~i_START) | (r_curr_state == s_select_init_clk) ? s_enable_init_clk : + r_curr_state == s_enable_init_clk & i_START ? s_disable_sd_clocks : + r_curr_state == s_disable_sd_clocks ? s_select_hs_clk : + r_curr_state == s_select_hs_clk ? s_enable_hs_clk : + r_curr_state == s_enable_hs_clk | (r_curr_state == s_done & ~i_FATAL_ERROR) ? s_done : + r_curr_state == s_done & i_FATAL_ERROR ? s_disable_sd_clocks_2 : + r_curr_state == s_disable_sd_clocks_2 ? s_select_init_clk : + s_safe_state; + + + assign o_HS_TO_INIT_CLK_DIVIDER_RST = r_curr_state == s_reset; + + assign o_SD_CLK_SELECTED = (r_curr_state == s_select_hs_clk) | (r_curr_state == s_enable_hs_clk) | (r_curr_state == s_done) ? c_sd_clk_hs : c_sd_clk_init; + + assign o_G_CLK_SD_EN = (r_curr_state == s_enable_init_clk) | (r_curr_state == s_enable_hs_clk) | (r_curr_state == s_done); + + assign o_DONE = r_curr_state == s_done; + +endmodule + diff --git a/wally-pipelined/src/sdc/sd_cmd_fsm.sv b/wally-pipelined/src/sdc/sd_cmd_fsm.sv new file mode 100644 index 00000000..edf1ff08 --- /dev/null +++ b/wally-pipelined/src/sdc/sd_cmd_fsm.sv @@ -0,0 +1,560 @@ +/////////////////////////////////////////// +// sd_clk_fsm.sv +// +// Written: Ross Thompson September 19, 2021 +// Modified: +// +// Purpose: Finite state machine for the SD CMD bus +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module sd_cmd_fsm + ( + + input logic CLK, // HS + //i_SLOWER_CLK : in std_logic; + input logic i_RST, // reset FSM, + // MUST COME OUT OF RESET + // SYNCHRONIZED TO THE 1.2 GHZ CLOCK! + output logic o_TIMER_LOAD, o_TIMER_EN, // Timer + output logic [18:0] o_TIMER_IN, + input logic [18:0] i_TIMER_OUT, + output logic o_COUNTER_LOAD, o_COUNTER_EN, // Counter + output logic [7:0] o_COUNTER_IN, + input logic [7:0] i_COUNTER_OUT, + output logic o_SD_CLK_EN, // Clock Gaters + input logic i_CLOCK_CHANGE_DONE, // Communication with CLK_FSM + output logic o_START_CLOCK_CHANGE, // Communication with CLK_FSM + output logic o_IC_RST, o_IC_EN, o_IC_UP_DOWN, // Instruction counter + input logic [3:0] i_IC_OUT, // stop when you get to 10 because that is CMD17 + input logic [1:0] i_USES_DAT, + input logic [6:0] i_OPCODE, + input logic [2:0] i_R_TYPE, + // bit masks + input logic [31:0] i_NO_REDO_MASK, + input logic [31:0] i_NO_REDO_ANS, + input logic [31:0] i_NO_ERROR_MASK, + input logic [31:0] i_NO_ERROR_ANS, + output logic o_SD_CMD_OE, // Enable ouptut on tri-state SD_CMD line + // TX Components + output logic o_TX_PISO40_LOAD, o_TX_PISO40_EN, // Shift register for TX command head + output logic o_TX_PISO8_LOAD, o_TX_PISO8_EN, // Shift register for TX command tail + output logic o_TX_CRC7_PIPO_RST, o_TX_CRC7_PIPO_EN, // Parallel-to-Parallel CRC7 Generator + output logic [1:0] o_TX_SOURCE_SELECT, // What gets sent to CMD_TX + // TX Memory + output logic o_CMD_TX_IS_CMD55_RST, + output logic o_CMD_TX_IS_CMD55_EN, // '1' means that the command that was just sent has index + // 55, so the subsequent command is to be + // viewed as ACMD by the SD card. + // RX Components + input logic i_SD_CMD_RX, // serial response input on SD_CMD + output logic o_RX_SIPO48_RST, o_RX_SIPO48_EN, // Shift Register for all 48 bits of Response + + input logic [39:8] i_RESPONSE_CONTENT, // last 32 bits of RX_SIPO_40_OUT + input logic [45:40] i_RESPONSE_INDEX, // 6 bits from RX_SIPO_40_OUT + output logic o_RX_CRC7_SIPO_RST, o_RX_CRC7_SIPO_EN, // Serial-to-parallel CRC7 Generator + input logic [6:0] i_RX_CRC7, + // RX Memory + output logic o_RCA_REGISTER_RST, o_RCA_REGISTER_EN, // Relative Card Address + // Communication to sd_dat_fsm + output logic o_CMD_TX_DONE, // begin waiting for DAT_RX to complete + input logic i_DAT_RX_DONE, // now go to next state since data block rx was completed + input logic i_ERROR_CRC16, // repeat last command + input logic i_ERROR_DAT_TIMES_OUT, + // Commnuication to core + output logic o_READY_FOR_READ, // tell core that I have completed initialization + output logic o_SD_RESTARTING, // inform core the need to restart + input logic i_READ_REQUEST, // core tells me to execute CMD17 + // Communication to Host + output logic o_DAT_ERROR_FD_RST, + output logic [2:0] o_ERROR_CODE_Q, // Indicates what caused the fatal error + output logic o_FATAL_ERROR, // SD Card is damaged beyond recovery, restart entire initialization procedure of card + input logic LIMIT_SD_TIMERS + ); + + + + logic [4:0] w_next_state, r_curr_state; + logic w_resend_last_command, w_rx_crc7_check, w_rx_index_check, w_rx_bad_crc7, w_rx_bad_index, w_rx_bad_reply, w_bad_card; + + logic [31:0] w_redo_result, w_error_result; + logic w_ACMD41_init_done; + logic w_fail_cnt_en, w_fail_count_rst; + logic [10:0] r_fail_count_out; + + logic w_ACMD41_busy_timer_START, w_ACMD41_times_out_FLAG, w_ACMD41_busy_timer_RST; //give up after 1000 ms of ACMD41 + logic [2:0] w_ERROR_CODE_D, r_ERROR_CODE_Q ; // Error Codes for fatal error on SD CMD FSM + logic w_ERROR_CODE_RST, w_ERROR_CODE_EN; + logic [18:0] Timer_In; + + + localparam s_reset_clear_error_reg = 5'b00000; + localparam s_idle_supply_no_clk = 5'b00001; + localparam s_idle_supply_sd_clk = 5'b00010; + localparam s_ld_head = 5'b00011; + localparam s_tx_head = 5'b00100; + localparam s_ld_tail = 5'b00101; + localparam s_tx_tail = 5'b00110; + localparam s_setup_rx = 5'b00111; + localparam s_idle_ncc = 5'b01000; + localparam s_fetch_next_cmd = 5'b01001; + localparam s_rx_48 = 5'b01010; + localparam s_rx_136 = 5'b01011; + localparam s_error_no_response = 5'b01100; + localparam s_idle_for_dat = 5'b01101; + localparam s_error_bad_card = 5'b01110; + localparam s_idle_nrc = 5'b01111; + localparam s_count_attempt = 5'b10000; + localparam s_reset_from_error = 5'b10001; + //localparam s_enable_hs_clk = 5'b10010; + localparam s_idle_for_start_bit = 5'b10011; + localparam s_fetch_prev_cmd = 5'b10100; // use to resend previous cmd55 if acmd is resent + // localparam s_setup_rx_b = 5'b10110; +// localparam s_idle_for_start_bit_b= 5'b10111; +// localparam s_rx_48_b = 5'b11000; +// localparam s_rx_136_b = 5'b11001; + localparam s_error_dat_time_out = 5'b11010; // don't advance states if the dat fsm times out + localparam s_idle_for_clock_change = 5'b11011; // replaces s_disable_sd_clocks, s_select_hs_clk, s_enable_hs_clk + localparam s_study_response = 5'b11100; // Do error checking here + localparam s_idle_for_read_request = 5'b11101; // After power up and initialization sequence is completed + localparam s_Error_TX_Failed = 5'b11110; // when fail_cnt_out exceeds c_max_attempts + + localparam c_MAX_ATTEMPTS = 3; // Give up sending a command after 3 failed attempts + // (except ACMD41) so the processor is not locked up forever + + localparam c_response_type_R0_NONE = 0; + localparam c_response_type_R1_NORMAL = 1; + localparam c_response_type_R2_CID_CSD = 2; + localparam c_response_type_R3_OCR = 3; + localparam c_response_type_R6_RCA = 6; + localparam c_response_type_R7_CIC = 7; + + localparam c_start_bit = 1'b0; + + localparam c_DAT_none = 2'b00; + localparam c_DAT_busy = 2'b01; + localparam c_DAT_wide = 2'b10; + localparam c_DAT_block = 2'b11; + + // Instructions mnemonics based on index (opcode(5 downto 0)) + localparam logic [45:40] c_Go_Idle_State = 6'd0; //CMD0 + localparam logic [45:40] c_All_Send_CID = 6'd02; // CMD2 + localparam logic [45:40] c_SD_Send_RCA = 6'd03; // CMD3 + localparam logic [45:40] c_Switch_Function = 6'd06; // CMD6 + localparam logic [45:40] c_Set_Bus_Width = 6'd06; // ACMD6 + localparam logic [45:40] c_Select_Card = 6'd07; // CMD7 + localparam logic [45:40] c_Send_IF_State = 6'd08; // CMD8 + localparam logic [45:40] c_Read_Single_Block = 6'd17; // CMD17 + localparam logic [45:40] c_SD_Send_OCR = 6'd41; // ACMD41 + localparam logic [45:40] c_App_Command = 6'd55; // CMD55 + +// clock selection + localparam c_sd_clk_init = 1'b1; + localparam c_sd_clk_hs = 1'b0; + + //tx source selection + localparam logic [1:0] c_tx_low = 2'b00; + localparam logic [1:0] c_tx_high = 2'b01; + localparam logic [1:0] c_tx_head = 2'b10; + localparam logic [1:0] c_tx_tail = 2'b11; + + // Error Codes for Error Register + localparam logic [2:0] c_NO_ERRORS = 3'b000; // no fatal errors occurred + // (default value when register is cleared during reset) + localparam [2:0] C_ERROR_NO_CMD_RESPONSE = 3'b100; // card timed out while waiting for a response on CMD, no start bit + // of response packet was ever received + // (possible causes: illegal command, card is disconnected, + // not meeting timing (you can fix timing by inverting the clock + // sent to card)) + localparam logic [2:0] c_ERROR_NO_DAT_RESPONSE = 3'b101; // card timed out while waiting for a data block on DAT, no start bit + // of DAT packet was ever received + // (possible cause: card is disconnected) + localparam logic [2:0] C_ERROR_BAD_CARD_STATUS = 3'b110; // status bits of a response indicate a card is not supported + // or that the card is damaged internally + localparam logic [2:0] C_ERROR_EXCEED_MAX_ATTEMPTS = 3'b111; // if a command fails it may be resent, + // but after so many attempts you should just give up + + //Alias for value of SD_CMD_Output_Enable + localparam c_TX_COMMAND = 1'b1; // Enable output on SD_CMD + localparam c_RX_RESPONSE = 1'b0; // Disable Output on SD_CMD + + // load values in for timers and counters + localparam logic [7:0] c_NID_max = 8'd63; // counter_in: should be "4" + // downto 0 = 5 bits count + // but is not enough time for + // sdModel.v + localparam logic [7:0] c_NCR_max = 8'd63; // counter_in + localparam logic [7:0] c_NCC_min = 8'd7; // counter_in + localparam logic [7:0] c_NRC_min = 8'd8; // counter_in + + //localparam logic [18:0] c_1000ms = 19'd400000; // ACMD41 timeout + //*** BUG this value is too bit to fit into 19 bits. + localparam logic [18:0] c_1000ms = 19'd40000; // ACMD41 timeout + + // command instruction type (opcode(6)) + localparam c_CMD = 1'b0; + localparam c_ACMD = 1'b1; + + // counter direction for up_down + localparam c_increment = 1'b1; // count <= count + 1 + localparam c_decrement = 1'b0; // count <= count - 1 + + assign Timer_In = LIMIT_SD_TIMERS ? 19'b0000000000000000011 : 19'b0011000011010100000; // 250 ms + + //Fail Counter, tracks how many failed attempts at command transmission + counter #(11) fail_counter + (.CountIn(11'b0), + .CountOut(r_fail_count_out), + .Load(1'b0), + .Enable(w_fail_cnt_en), + .clk(CLK), + .reset(w_fail_count_rst)); + + // Simple timer for ACMD41 busy + simple_timer #(19) ACMD41_busy_timer + (.VALUE(c_1000ms), + .START(w_ACMD41_busy_timer_START), + .FLAG(w_ACMD41_times_out_FLAG), + .RST(w_ACMD41_busy_timer_RST), + .CLK(CLK)); + + // State Register, instantiate register_ce. 32 state state machine + flopenr #(5) state_reg + (.d(w_next_state), + .q(r_curr_state), + .en(1'b1), + .reset(i_RST), + .clk(CLK)); + + // Error register : indicates what type of fatal error occured for interrupt + flopenr #(3) error_reg + (.d(w_ERROR_CODE_D), + .q(r_ERROR_CODE_Q), + .en(w_ERROR_CODE_EN), + .reset(w_ERROR_CODE_RST), + .clk(CLK)); + + assign o_ERROR_CODE_Q = r_ERROR_CODE_Q; + + assign w_next_state = i_RST ? s_reset_clear_error_reg : + + ((r_curr_state == s_reset_clear_error_reg) | + (r_curr_state == s_Error_TX_Failed) | + (r_curr_state == s_error_no_response) | + (r_curr_state == s_error_bad_card) | + (r_curr_state == s_error_dat_time_out)) ? s_reset_from_error : + + + ((r_curr_state == s_reset_from_error) | + ((r_curr_state == s_idle_supply_no_clk) & (i_TIMER_OUT > 0))) ? s_idle_supply_no_clk : + + (((r_curr_state == s_idle_supply_no_clk) & (i_TIMER_OUT == 0)) | + ((r_curr_state == s_idle_supply_sd_clk) & (i_COUNTER_OUT > 0))) ? s_idle_supply_sd_clk : + + (r_curr_state == s_ld_head) ? s_count_attempt : + + (((r_curr_state == s_count_attempt) & (r_fail_count_out <= (c_MAX_ATTEMPTS-1))) | + ((r_curr_state == s_count_attempt) & + (((i_IC_OUT == 2) & (i_OPCODE[5:0] == c_App_Command)) | + ((i_IC_OUT == 3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR})))) // to work CMD55, ACMD41 MUST be lines 2, 3 of instruction fetch mux of sd_top.vhd + & (w_ACMD41_times_out_FLAG) + & (r_fail_count_out > (c_MAX_ATTEMPTS-1)))) ? s_tx_head : + + ((r_curr_state == s_count_attempt) & (r_fail_count_out > (c_MAX_ATTEMPTS-1))) ? s_Error_TX_Failed : + + ((r_curr_state == s_tx_head) | ((r_curr_state == s_ld_tail) & (i_COUNTER_OUT > 8))) ? s_ld_tail : + + (((r_curr_state == s_ld_tail) & (i_COUNTER_OUT == 8)) | + ((r_curr_state == s_tx_tail) & (i_COUNTER_OUT > 0))) ? s_tx_tail : + + (r_curr_state == s_tx_tail) & (i_COUNTER_OUT == 0) ? s_setup_rx : + + (((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) | + ((r_curr_state == s_idle_ncc) & (i_COUNTER_OUT > 0))) ? s_idle_ncc : + + (((r_curr_state == s_setup_rx) & (i_R_TYPE != c_response_type_R0_NONE)) | + ((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) & + (i_COUNTER_OUT > 0))) ? s_idle_for_start_bit : + + ((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) & + (i_COUNTER_OUT == 0)) ? s_error_no_response : + + (((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) & + /* verilator lint_off UNSIGNED */ + (i_COUNTER_OUT >= 0) & (i_R_TYPE == c_response_type_R2_CID_CSD)) | + /* verilator lint_on UNSIGNED */ + ((r_curr_state == s_rx_136) & (i_COUNTER_OUT > 0))) ? s_rx_136 : + + (((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) & + /* verilator lint_off UNSIGNED */ + (i_COUNTER_OUT >= 0) & (i_R_TYPE != c_response_type_R2_CID_CSD)) | + /* verilator lint_on UNSIGNED */ + ((r_curr_state == s_rx_48) & (i_COUNTER_OUT > 0))) ? s_rx_48 : + + (((r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0)) | + ((r_curr_state == s_rx_48) & (i_COUNTER_OUT) == 0)) ? s_study_response : + + (r_curr_state == s_study_response) & w_bad_card ? s_error_bad_card : + + (((r_curr_state == s_study_response) & (~w_bad_card) & (i_USES_DAT != c_DAT_none)) | + ((r_curr_state == s_idle_for_dat) & (~i_DAT_RX_DONE))) ? s_idle_for_dat : + + ((r_curr_state == s_idle_for_dat) & (i_DAT_RX_DONE) & (i_ERROR_DAT_TIMES_OUT)) ? s_error_dat_time_out : + + (((r_curr_state == s_idle_for_dat) & (i_DAT_RX_DONE) & + (~i_ERROR_DAT_TIMES_OUT)) | + ((r_curr_state == s_study_response) & (~w_bad_card) & + (i_USES_DAT == c_DAT_none)) | + ((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT > 0))) ? s_idle_nrc : + + ((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) & + (w_resend_last_command) & ((i_OPCODE[6] == c_ACMD) & + ((i_OPCODE[5:0]) != c_App_Command))) ? s_fetch_prev_cmd : + + ((r_curr_state == s_fetch_prev_cmd) | + ((r_curr_state == s_idle_supply_sd_clk) & (i_COUNTER_OUT == 0)) | + ((r_curr_state == s_fetch_next_cmd) & // before CMD17 + (i_IC_OUT < 9)) | // blindly load head of next command + ((r_curr_state == s_idle_for_read_request) & (i_READ_REQUEST)) | // got the request, load head + ((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) & + (w_resend_last_command) & ((i_OPCODE[6] == c_CMD) | + ((i_OPCODE[5:0]) == c_App_Command)))) ? s_ld_head : + + (((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) & + (~w_resend_last_command) & ((i_OPCODE) == ({c_CMD, c_Switch_Function}))) | + ((r_curr_state == s_idle_for_clock_change) & (~i_CLOCK_CHANGE_DONE))) ? s_idle_for_clock_change : + + (((r_curr_state == s_idle_ncc) & (i_COUNTER_OUT == 0)) | + ((r_curr_state == s_idle_nrc) & (i_COUNTER_OUT == 0) & + (~w_resend_last_command) & ((i_OPCODE) != ({c_CMD, c_Switch_Function}))) | + ((r_curr_state == s_idle_for_clock_change) & (i_CLOCK_CHANGE_DONE))) ? s_fetch_next_cmd : + + (((r_curr_state == s_fetch_next_cmd) & + (i_IC_OUT >= 9)) | // During and after CMD17, wait for request to send CMD17 from core + // waiting for request + (r_curr_state == s_idle_for_read_request)) ? s_idle_for_read_request : + + s_reset_clear_error_reg; + + + + + + + // state outputs + assign w_ACMD41_busy_timer_START = ((r_curr_state == s_count_attempt) & (i_OPCODE == {c_ACMD, c_SD_Send_OCR}) & (r_fail_count_out == 1)); + + assign w_ACMD41_busy_timer_RST = ((r_curr_state == s_reset_from_error) | (w_ACMD41_init_done)); + + // Error Register + assign w_ERROR_CODE_RST = (r_curr_state == s_reset_clear_error_reg); + + assign w_ERROR_CODE_EN = (r_curr_state == s_error_bad_card) | (r_curr_state == s_error_no_response) | (r_curr_state == s_Error_TX_Failed) | (r_curr_state == s_error_dat_time_out); + + assign w_ERROR_CODE_D = (r_curr_state == s_Error_TX_Failed) ? C_ERROR_EXCEED_MAX_ATTEMPTS : // give up + (r_curr_state == s_error_bad_card) ? C_ERROR_BAD_CARD_STATUS : // card is damaged or unsupported + (r_curr_state == s_error_no_response) ? C_ERROR_NO_CMD_RESPONSE : // no response was received on CMD line + (r_curr_state == s_error_dat_time_out) ? c_ERROR_NO_DAT_RESPONSE : // no data packet was received on DAT bus + c_NO_ERRORS; // all is well + + // Failure counter + assign w_fail_count_rst = ((r_curr_state == s_reset_from_error) | (r_curr_state == s_fetch_next_cmd & i_OPCODE[5:0] != c_App_Command)); + + + assign w_fail_cnt_en = ((r_curr_state == s_count_attempt) & (i_OPCODE[6] != c_ACMD | i_OPCODE[5:0] == c_App_Command)); + // & (i_OPCODE != ({c_ACMD, c_SD_Send_OCR})) else // NOT ACMD41, it can take up to 1 second + + // Timer module + assign o_TIMER_EN = (r_curr_state == s_idle_supply_no_clk); + + assign o_TIMER_LOAD = (r_curr_state == s_reset_from_error); + + assign o_TIMER_IN = (r_curr_state == s_reset_from_error) ? Timer_In : '0; + + // Clock selection/gater module(s) ... + assign o_SD_CLK_EN = ~((r_curr_state == s_reset_from_error) | (r_curr_state == s_idle_supply_no_clk) | (r_curr_state == s_idle_for_clock_change)); + + assign o_START_CLOCK_CHANGE = (r_curr_state == s_idle_for_clock_change); + + // RCA register module + assign o_RCA_REGISTER_RST = (r_curr_state == s_reset_from_error); + + assign o_RCA_REGISTER_EN = ((r_curr_state == s_idle_nrc) & (i_R_TYPE == c_response_type_R6_RCA)); + + // Instruction counter module + assign o_IC_RST = (r_curr_state == s_reset_from_error); + + //assign o_IC_EN = (r_curr_state == s_fetch_next_cmd) | (r_curr_state == s_fetch_prev_cmd); + + assign o_IC_EN = (((r_curr_state == s_fetch_next_cmd) & (i_IC_OUT < 10)) | (r_curr_state == s_fetch_prev_cmd)); + + assign o_IC_UP_DOWN = (r_curr_state == s_fetch_prev_cmd) ? c_decrement : c_increment; + + // "Previous Command sent was CMD55, so the command I'm now sending is ACMD" module + assign o_CMD_TX_IS_CMD55_RST = (r_curr_state == s_reset_from_error); + + assign o_CMD_TX_IS_CMD55_EN = (r_curr_state == s_ld_head); + + // Output signals to DAT FSM + //o_CMD_TX_DONE = '0' when (r_curr_state == s_reset) else // reset + // '0' when (r_curr_state == s_idle_supply_no_clk) | (r_curr_state == s_idle_supply_sd_clk) else // power up + // '0' when ((r_curr_state == s_ld_head) + // | (r_curr_state == s_tx_head) + // | (r_curr_state == s_ld_tail) + // | (r_curr_state == s_tx_tail)) else // tx + // '1'; + assign o_CMD_TX_DONE = (r_curr_state == s_setup_rx); + + // Counter Module + assign o_COUNTER_LOAD = (r_curr_state == s_idle_supply_no_clk) | + (r_curr_state == s_ld_head) | + (r_curr_state == s_setup_rx) | + (r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) | + (r_curr_state == s_rx_48) & (i_COUNTER_OUT == 0) | + (r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0); + + assign o_COUNTER_IN = (r_curr_state == s_idle_supply_no_clk) ? 8'd73 : + // | is it 73 downto 0 == 74 bits + (r_curr_state == s_ld_head) ? 8'd47 : // or is it 48 + ((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) ? c_NCC_min : + ((r_curr_state == s_setup_rx) + & (i_R_TYPE != c_response_type_R0_NONE) + & (((i_OPCODE) == ({c_CMD, c_All_Send_CID})) | + ((i_OPCODE) == ({c_ACMD, c_SD_Send_OCR})))) ? c_NID_max : + (r_curr_state == s_setup_rx) ? c_NCR_max : + ((r_curr_state == s_idle_for_start_bit) & (i_R_TYPE == c_response_type_R2_CID_CSD)) ? 8'd135 : // | is it 136 + (r_curr_state == s_idle_for_start_bit) ? 8'd46 : // | is it not48 + (r_curr_state == s_rx_48) | (r_curr_state == s_rx_136) ? c_NRC_min : // | is it 8 + 8'd0; + + assign o_COUNTER_EN = (r_curr_state == s_idle_supply_sd_clk) ? 1'b1 : + ((r_curr_state == s_tx_head) | (r_curr_state == s_ld_tail) | (r_curr_state == s_tx_tail)) ? 1'b1 : + (r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) ? 1'b0 : + (r_curr_state == s_idle_for_start_bit) ? 1'b1 : + (r_curr_state == s_rx_48) & (i_COUNTER_OUT == 0) ? 1'b0 : + (r_curr_state == s_rx_48) ? 1'b1 : + (r_curr_state == s_idle_nrc) ? 1'b1 : + (r_curr_state == s_rx_136) & (i_COUNTER_OUT == 0) ? 1'b0 : + (r_curr_state == s_rx_136) ? 1'b1 : + (r_curr_state == s_idle_ncc) ? 1'b1 : + 1'b0; + + // SD_CMD Tri-state Buffer Module + assign o_SD_CMD_OE = (r_curr_state == s_idle_supply_sd_clk) ? c_TX_COMMAND : + ((r_curr_state == s_tx_head) + | (r_curr_state == s_ld_tail) + | (r_curr_state == s_tx_tail)) ? c_TX_COMMAND : + c_RX_RESPONSE; + + // Shift Registers + // TX_PISO40 Transmit Command Head + assign o_TX_PISO40_LOAD = (r_curr_state == s_ld_head); + + assign o_TX_PISO40_EN = (r_curr_state == s_tx_head) | (r_curr_state == s_ld_tail); + + // TX_CRC7_PIPO Generate Tail + assign o_TX_CRC7_PIPO_RST = (r_curr_state == s_ld_head); + + assign o_TX_CRC7_PIPO_EN = (r_curr_state == s_tx_head); + + // TX_PISO8 Transmit Command Tail + assign o_TX_PISO8_LOAD = (r_curr_state == s_ld_tail); + + assign o_TX_PISO8_EN = (r_curr_state == s_tx_tail); + + // RX_CRC7_SIPO Calculate the CRC7 of the first 47-bits of reply (should be zero) + assign o_RX_CRC7_SIPO_RST = (r_curr_state == s_setup_rx); + + assign o_RX_CRC7_SIPO_EN = (r_curr_state == s_rx_48) & (i_COUNTER_OUT > 0); // or (r_curr_state == s_rx_48_b) + + // RX_SIPO40 Content bits of response + assign o_RX_SIPO48_RST = (r_curr_state == s_setup_rx); + + assign o_RX_SIPO48_EN = (r_curr_state == s_rx_48 | r_curr_state == s_rx_48); + + // Fatal Error Signal Wire + assign o_FATAL_ERROR = (r_curr_state == s_error_bad_card) | (r_curr_state == s_error_no_response) | + (r_curr_state == s_Error_TX_Failed) | (r_curr_state == s_error_dat_time_out); + + assign o_DAT_ERROR_FD_RST = (r_curr_state == s_ld_head); + + // I'm debating the merit of creating yet another state for sd_cmd_fsm.vhd to go into when and if sd_dat_fsm.vhd + // times out while waiting for start bit on the DAT bus resulting in Error_Time_Out going high in + // sd_Dat_fsm.vhd while sd_cmd_fsm.vhd is still in s_idle_for_dat + + // TX source selection bits for mux + assign o_TX_SOURCE_SELECT = (r_curr_state == s_idle_supply_sd_clk) ? c_tx_high : + ((r_curr_state == s_ld_head) + | (r_curr_state == s_tx_head) + | (r_curr_state == s_ld_tail)) ? c_tx_head : + (r_curr_state == s_tx_tail) ? c_tx_tail : + c_tx_high; // This occurs when not transmitting anything + + // Study Response + assign w_rx_crc7_check = (r_curr_state == s_idle_nrc) & + ((i_R_TYPE != c_response_type_R0_NONE) & + (i_R_TYPE != c_response_type_R3_OCR) & + (i_R_TYPE != c_response_type_R2_CID_CSD)); + + assign w_rx_index_check = (r_curr_state == s_idle_nrc) & + ((i_R_TYPE != c_response_type_R0_NONE) & + (i_R_TYPE != c_response_type_R3_OCR) & + (i_R_TYPE != c_response_type_R2_CID_CSD)); + + assign w_redo_result = i_RESPONSE_CONTENT & i_NO_REDO_MASK; + + assign w_rx_bad_reply = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & (w_redo_result != i_NO_REDO_ANS)); + + assign w_rx_bad_crc7 = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & ((w_rx_crc7_check) & (i_RX_CRC7 != 7'b0))); + + assign w_rx_bad_index = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) + & ((w_rx_index_check) & (i_RESPONSE_INDEX != i_OPCODE[5:0]))); + + assign w_resend_last_command = ((r_curr_state == s_idle_nrc | r_curr_state == s_study_response) & + ((w_rx_bad_reply) | (w_rx_bad_index) | (w_rx_bad_crc7))) | + ((r_curr_state == s_idle_nrc) & + ((i_ERROR_CRC16) & + ((i_USES_DAT == c_DAT_block) | (i_USES_DAT == c_DAT_wide)))); + + assign w_error_result = i_RESPONSE_CONTENT & i_NO_ERROR_MASK; + + // Make assignment based on what was read from the OCR Register. + // Bit 31, Card power up status bit: '1' == SD Flash Card power up procedure is finished. + // '0' == SD Flash Card power up procedure is not finished. + // Bit 30, Card capacity status bit: '1' == Extended capacity card is in use (64 GB in size or greater). + // '0' == Extended capacity card is not in use. + assign w_ACMD41_init_done = ((i_IC_OUT == 3) & (i_OPCODE == ({c_ACMD, c_SD_Send_OCR}))) & + (~w_rx_bad_reply) & (r_curr_state == s_study_response); + + assign w_bad_card = ((r_curr_state == s_study_response) & (w_error_result != i_NO_ERROR_ANS) & + ((~w_ACMD41_times_out_FLAG) | (w_ACMD41_init_done))); + + // Communication with core + assign o_READY_FOR_READ = (r_curr_state == s_idle_for_read_request); + + assign o_SD_RESTARTING = (r_curr_state == s_Error_TX_Failed) | + (r_curr_state == s_error_dat_time_out) | + (r_curr_state == s_error_bad_card) | + (r_curr_state == s_error_no_response); + + + + +endmodule diff --git a/wally-pipelined/src/sdc/sd_dat_fsm.sv b/wally-pipelined/src/sdc/sd_dat_fsm.sv new file mode 100644 index 00000000..1519a112 --- /dev/null +++ b/wally-pipelined/src/sdc/sd_dat_fsm.sv @@ -0,0 +1,232 @@ +/////////////////////////////////////////// +// sd_dat_fsm.sv +// +// Written: Ross Thompson September 19, 2021 +// Modified: +// +// Purpose: Runs in parallel with sd_cmd_fsm to control activity on the DAT +// bus of the SD card. +// 14 State Mealy FSM + Safe state = 15 State Mealy FSM +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module sd_dat_fsm + ( + input logic CLK, // HS Clock (48 MHz) + input logic i_RST, + // Timer module control + input logic i_SD_CLK_SELECTED, // Which frequency I'm in determines what count in to load for a 100ms timer + output logic o_TIMER_LOAD, o_TIMER_EN, // Timer Control signals + output logic [22:0] o_TIMER_IN, // Need Enough bits for 100 milliseconds at 48MHz + input logic [22:0] i_TIMER_OUT, // (ceiling(log((clk freq)(delay desired)-1)/log(2))-1) downto 0 + // Nibble counter module control + output logic o_COUNTER_RST, o_COUNTER_EN, // nibble counter + input logic [10:0] i_COUNTER_OUT, // max nibbles is 1024 + crc16 bits = 1040 bits + // CRC16 Generation control + output logic o_CRC16_EN, o_CRC16_RST, // shared signals for all 4 CRC16_SIPO (one for each of 4 DAT lines) + input logic i_DATA_CRC16_GOOD, // indicates that no errors in transmission when CRC16 are all zero + // For R1b + output logic o_BUSY_RST, o_BUSY_EN, // busy signal for R1b + input logic i_DAT0_Q, + // Storage Buffers for DAT bits read + output logic o_NIBO_EN, // 512 bytes block data (Nibble In Block Out) + // From LUT + input logic [1:0] i_USES_DAT, // current command needs use of DAT bus + // For communicating with core + output logic o_DATA_VALID, // indicates that DATA being send over o_DATA to core is valid + output logic o_LAST_NIBBLE, // indicates that the last nibble has been sent + // For communication with sd_cmd_fsm + input logic i_CMD_TX_DONE, // command transmission completed, begin waiting for DATA + output logic o_DAT_RX_DONE, // tell SD_CMD_FSM that DAT communication is completed, send next instruction to sd card + output logic o_ERROR_DAT_TIMES_OUT, // error flag for when DAT times out (so don't fetch more instructions) + output logic o_DAT_ERROR_FD_RST, + output logic o_DAT_ERROR_FD_EN, // tell SD_CMD_FSM to resend command due to error in transmission + input logic LIMIT_SD_TIMERS + ); + + logic [3:0] w_next_state, r_curr_state; + + logic w_error_crc16_fd_en, w_error_crc16_fd_rst, w_error_crc16_fd_d; // Save ERROR_CRC16 so CMD FSM sees it in IDLE_NRC (not just in IDLE_DAT) + logic r_error_crc16_fd_Q; + + logic [22:0] Identify_Timer_In; + logic [22:0] Data_TX_Timer_In; + + localparam logic [3:0] s_reset = 4'b0000; + localparam logic [3:0] s_idle = 4'b0001; + localparam logic [3:0] s_idle_for_start_bit = 4'b0010; + localparam logic [3:0] s_read_r1b = 4'b0011; + localparam logic [3:0] s_notify_r1b_completed = 4'b0100; + localparam logic [3:0] s_error_time_out = 4'b0101; + localparam logic [3:0] s_rx_wide_data = 4'b0110; + localparam logic [3:0] s_rx_block_data = 4'b0111; + localparam logic [3:0] s_rx_crc16 = 4'b1000; + localparam logic [3:0] s_error_crc16_fail = 4'b1001; + localparam logic [3:0] s_publish_block_data = 4'b1010; + localparam logic [3:0] s_publish_wide_data = 4'b1011; + localparam logic [3:0] s_reset_wide_data = 4'b1100; + localparam logic [3:0] s_reset_block_data = 4'b1101; + localparam logic [3:0] s_reset_nibble_counter = 4'b1110; // Before publishing CMD17 Block Data + + localparam logic [1:0] c_DAT_none = 2'b00; + localparam logic [1:0] c_DAT_busy = 2'b01; + localparam logic [1:0] c_DAT_wide = 2'b10; + localparam logic [1:0] c_DAT_block = 2'b11; + + localparam logic c_start_bit = 0; + localparam logic c_busy_bit = 0; + + // load values in for timers and counters + localparam logic c_slow_clock = 1'b1; // use during initialization (card identification mode) + localparam logic c_HS_clock = 1'b0; // use after CMD6 switches clock frequency (CMD17) + + + assign Identify_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b00000001001110001000000; // 40,000 unsigned. + assign Data_TX_Timer_In = LIMIT_SD_TIMERS ? 23'b00000000000000001100011 : 23'b11110100001001000000000; // 8,000,000 unsigned. + + flopenr #(4) stateReg(.clk(CLK), + .reset(i_RST), + .en(1'b1), + .d(w_next_state), + .q(r_curr_state)); + + assign w_next_state = ((i_RST) | + (r_curr_state == s_error_time_out) | // noticed this change is needed during emulation + (r_curr_state == s_notify_r1b_completed) | + (r_curr_state == s_error_crc16_fail) | + (r_curr_state == s_publish_wide_data) | + ((r_curr_state == s_publish_block_data) & (i_COUNTER_OUT == 1023))) ? s_reset : + + ((r_curr_state == s_reset) | + ((r_curr_state == s_idle) & ((i_USES_DAT == c_DAT_none) | ((i_USES_DAT != c_DAT_none) & (~i_CMD_TX_DONE))))) ? s_idle : + + ((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_wide) & (i_CMD_TX_DONE)) ? s_reset_wide_data : + + ((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_block) & (i_CMD_TX_DONE)) ? s_reset_block_data : + + ((r_curr_state == s_reset_wide_data) | + ((r_curr_state == s_idle) & (i_USES_DAT == c_DAT_busy) & (i_CMD_TX_DONE)) | + (r_curr_state == s_reset_block_data) | + ((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) & (i_DAT0_Q != c_start_bit))) ? s_idle_for_start_bit : + + ((r_curr_state == s_idle_for_start_bit) & // Apparently R1b's busy signal is optional, + (i_TIMER_OUT == 0) & // Even if it never shows up, + (i_USES_DAT == c_DAT_busy)) ? s_notify_r1b_completed : // pretend it did, & move on + + (((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) & + (i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_busy)) | + ((r_curr_state == s_read_r1b) & (i_TIMER_OUT > 0) & (i_DAT0_Q == c_busy_bit))) ? s_read_r1b : + + (((r_curr_state == s_read_r1b) & (i_TIMER_OUT == 0)) | + ((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT == 0) & + (i_USES_DAT != c_DAT_busy))) ? s_error_time_out : + + ((r_curr_state == s_read_r1b) & (i_DAT0_Q != c_busy_bit)) ? s_notify_r1b_completed : + + (((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) & (i_DAT0_Q == c_start_bit) & + (i_USES_DAT == c_DAT_wide)) | + ((r_curr_state == s_rx_wide_data) & (i_COUNTER_OUT < 128))) ? s_rx_wide_data : + + (((r_curr_state == s_idle_for_start_bit) & (i_TIMER_OUT > 0) & + (i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_block)) | + ((r_curr_state == s_rx_block_data) & (i_COUNTER_OUT < 1023))) ? s_rx_block_data : + + (((r_curr_state == s_rx_wide_data) & (i_COUNTER_OUT == 128)) | + ((r_curr_state == s_rx_block_data) & (i_COUNTER_OUT == 1023)) | + ((r_curr_state == s_rx_crc16) & + (((i_USES_DAT == c_DAT_wide) & (i_COUNTER_OUT < 144)) | + ((i_USES_DAT == c_DAT_block) & (i_COUNTER_OUT < 1040))))) ? s_rx_crc16 : + + ((r_curr_state == s_rx_crc16) & + (((i_USES_DAT == c_DAT_wide) & (i_COUNTER_OUT == 144)) | + ((i_USES_DAT == c_DAT_block) & (i_COUNTER_OUT == 1040))) & + (~i_DATA_CRC16_GOOD)) ? s_error_crc16_fail : + + ((r_curr_state == s_rx_crc16) & (i_USES_DAT == c_DAT_wide) & (i_COUNTER_OUT == 144) & + (i_DATA_CRC16_GOOD)) ? s_publish_wide_data : + + ((r_curr_state == s_rx_crc16) & + (i_USES_DAT == c_DAT_block) & (i_COUNTER_OUT == 1040) & (i_DATA_CRC16_GOOD)) ? s_reset_nibble_counter : + + ((r_curr_state == s_reset_nibble_counter)) ? s_publish_block_data : + + s_reset; + + assign o_TIMER_IN = (r_curr_state == s_reset) & (i_SD_CLK_SELECTED == c_slow_clock) ? Identify_Timer_In : Data_TX_Timer_In; + + assign o_TIMER_LOAD = ((r_curr_state == s_reset) | + (r_curr_state == s_reset_block_data)); + + assign o_TIMER_EN = ((r_curr_state == s_idle_for_start_bit) | + (r_curr_state == s_read_r1b)); + + // Nibble Counter module + assign o_COUNTER_RST = (r_curr_state == s_reset) | (r_curr_state == s_reset_nibble_counter); + + assign o_COUNTER_EN = ((r_curr_state == s_rx_block_data) | + (r_curr_state == s_rx_wide_data) | + (r_curr_state == s_rx_crc16)) | (r_curr_state == s_publish_block_data); + + // CRC16 Generation module + assign o_CRC16_RST = (r_curr_state == s_reset); + + assign o_CRC16_EN = ((r_curr_state == s_rx_block_data) | + (r_curr_state == s_rx_wide_data) | + (r_curr_state == s_rx_crc16)); + + // Flip Flop Module (for R1b) + assign o_BUSY_RST = (r_curr_state == s_reset); + + //o_BUSY_EN = '1' when ((r_curr_state == s_idle_for_start_bit) | + // (r_curr_state == s_read_r1b)) else + // '0'; + assign o_BUSY_EN = 1'b1; // Always sample data + + // DAT Storage Modules + assign o_NIBO_EN = (r_curr_state == s_rx_block_data); + + // To sd_cmd_fsm + assign o_DAT_RX_DONE = ((r_curr_state == s_error_time_out) | + (r_curr_state == s_notify_r1b_completed) | + (r_curr_state == s_error_crc16_fail) | + (r_curr_state == s_publish_wide_data) | + (r_curr_state == s_publish_block_data)); + + assign o_ERROR_DAT_TIMES_OUT = (r_curr_state == s_error_time_out); + + + // o_RESEND_READ_WIDE (Error! This is not defined. Indicates switch command must be re-rent), + // should be a function of block busy logic + + // For Communication with core + assign o_DATA_VALID = (r_curr_state == s_publish_block_data); + + assign o_LAST_NIBBLE = ((r_curr_state == s_publish_block_data) + & (i_COUNTER_OUT == 1023)) | (r_curr_state == s_error_time_out); // notify done if errors occur + + // o_ERROR_CRC16 (note: saved to flip flop because otherwise is only 1 clock cycle, not what I want) + assign o_DAT_ERROR_FD_RST = (r_curr_state == s_reset_block_data) | (r_curr_state == s_reset_wide_data); + assign o_DAT_ERROR_FD_EN = (r_curr_state == s_rx_crc16); + + + + + +endmodule diff --git a/wally-pipelined/src/sdc/sd_top.sv b/wally-pipelined/src/sdc/sd_top.sv new file mode 100644 index 00000000..99191b50 --- /dev/null +++ b/wally-pipelined/src/sdc/sd_top.sv @@ -0,0 +1,667 @@ +/////////////////////////////////////////// +// sd_top.sv +// +// Written: Ross Thompson September 19, 2021 +// Modified: +// +// Purpose: SD card controller +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module sd_top #(parameter g_COUNT_WIDTH = 8) + ( + input logic CLK, // 1.2 GHz (1.0 GHz typical) + input logic a_RST, // Reset signal (Must be held for minimum of 24 clock cycles) + // a_RST MUST COME OUT OF RESET SYNCHRONIZED TO THE 1.2 GHZ CLOCK! + // io_SD_CMD_z : inout std_logic; // SD CMD Bus + input logic i_SD_CMD, // CMD Response from card + output logic o_SD_CMD, // CMD Command from host + output logic o_SD_CMD_OE, // Direction of SD_CMD + input logic [3:0] i_SD_DAT, // SD DAT Bus + output logic o_SD_CLK, // SD CLK Bus + // For communication with core cpu + input logic [32:9] i_BLOCK_ADDR, // see "Addressing" in parts.fods (only 8GB total capacity is used) + output logic o_READY_FOR_READ, // tells core that initialization sequence is completed and + // sd card is ready to read a 512 byte block to the core. + // Held high during idle until i_READ_REQUEST is received + output logic o_SD_RESTARTING, // inform core the need to restart + + input logic i_READ_REQUEST, // After Ready for read is sent to the core, the core will + // pulse this bit high to indicate it wants the block at this address + output logic [3:0] o_DATA_TO_CORE, // nibble being sent to core when DATA block is + output logic [4095:0] ReadData, // full 512 bytes to Bus + // being published + output logic o_DATA_VALID, // held high while data being read to core to indicate that it is valid + output logic o_LAST_NIBBLE, // pulse when last nibble is sent + output logic [2:0] o_ERROR_CODE_Q, // indicates which error occured + output logic o_FATAL_ERROR, // indicates that the FATAL ERROR register has updated + // For tuning + input logic [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX, + input logic LIMIT_SD_TIMERS + ); + + localparam logic c_CMD = 1'b0; + localparam logic c_ACMD = 1'b1; + + // packet bit names + localparam logic c_start_bit = 1'b0; // bit 47 + localparam logic c_stop_bit = 1'b1; // bit 0, AKA "end bit" + // transmitter bit, bit 46 + localparam logic c_tx_host_command = 1'b1; + localparam logic c_tx_card_response = 1'b0; + + // response types + localparam logic [2:0] c_response_type_R0_NONE = 3'd0; + localparam logic [2:0] c_response_type_R1_NORMAL = 3'd1; + localparam logic [2:0] c_response_type_R2_CID_CSD = 3'd2; + localparam logic [2:0] c_response_type_R3_OCR = 3'd3; + localparam logic [2:0] c_response_type_R6_RCA = 3'd6; + localparam logic [2:0] c_response_type_R7_CIC = 3'd7; + + // uses dat + localparam logic [1:0] c_DAT_none = 2'b00; + localparam logic [1:0] c_DAT_busy = 2'b01; + localparam logic [1:0] c_DAT_wide = 2'b10; + localparam logic [1:0] c_DAT_block = 2'b11; + + // tx source selection + localparam logic [1:0] c_tx_low = 2'b00; + localparam logic [1:0] c_tx_high = 2'b01; + localparam logic [1:0] c_tx_head = 2'b10; + localparam logic [1:0] c_tx_tail = 2'b11; + + // command indexes + localparam logic [45:40] c_Go_Idle_State = 6'd00; // CMD0 + localparam logic [45:40] c_All_Send_CID = 6'd02; // CMD2 + localparam logic [45:40] c_SD_Send_RCA = 6'd03; // CMD3 + localparam logic [45:40] c_Switch_Function = 6'd06; // CMD6 + localparam logic [45:40] c_Set_Bus_Width = 6'd06; // ACMD6 + localparam logic [45:40] c_Select_Card = 6'd07; // CMD7 + localparam logic [45:40] c_Send_IF_State = 6'd08; // CMD8 + localparam logic [45:40] c_Read_Single_Block = 6'd17; // CMD17 + localparam logic [45:40] c_SD_Send_OCR = 6'd41; // ACMD41 + localparam logic [45:40] c_App_Command = 6'd55; // CMD55 + + // bitmasks + localparam logic [127:96] c_CMD0_mask_check_redo_bits = 32'h00000000; // Go_Idle_State + localparam logic [127:96] c_CMD0_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD0_mask_check_error_bits = 32'h00000000; + localparam logic [127:96] c_CMD0_ans_error_free = 32'h00000000; + + localparam logic [127:96] c_CMD2_mask_check_redo_bits = 32'h00000000; // All_Send_CID + localparam logic [127:96] c_CMD2_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD2_mask_check_error_bits = 32'h00000000; + localparam logic [127:96] c_CMD2_ans_error_free = 32'h00000000; + + localparam logic [127:96] c_CMD3_mask_check_redo_bits = 32'h00000000; // SD_Send_RCA + localparam logic [127:96] c_CMD3_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD3_mask_check_error_bits = 32'h00002000; + localparam logic [127:96] c_CMD3_ans_error_free = 32'h00000000; + + localparam logic [127:96] c_CMD6_mask_check_redo_bits = 32'h00000000; // Switch_Function + localparam logic [127:96] c_CMD6_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD6_mask_check_error_bits = 32'h82380000; + localparam logic [127:96] c_CMD6_ans_error_free = 32'h00000000; + + localparam logic [127:96] c_ACMD6_mask_check_redo_bits = 32'h00000000; // Set_Bus_Width + localparam logic [127:96] c_ACMD6_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_ACMD6_mask_check_error_bits = 32'h8F398020; + localparam logic [127:96] c_ACMD6_ans_error_free = 32'h00000020; + + localparam logic [127:96] c_CMD7_mask_check_redo_bits = 32'h00000000; // Select_Card + localparam logic [127:96] c_CMD7_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD7_mask_check_error_bits = 32'h0F398000; + localparam logic [127:96] c_CMD7_ans_error_free = 32'h00000000; + + localparam logic [127:96] c_CMD8_mask_check_redo_bits = 32'h00000000; // Send_IF_State + localparam logic [127:96] c_CMD8_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD8_mask_check_error_bits = 32'h00000FFF; + localparam logic [127:96] c_CMD8_ans_error_free = 32'h000001FF; + + localparam logic [127:96] c_CMD17_mask_check_redo_bits = 32'h00000000; // Read_Single_Block + localparam logic [127:96] c_CMD17_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD17_mask_check_error_bits = 32'hCF398000; + localparam logic [127:96] c_CMD17_ans_error_free = 32'h00000000; + + localparam logic [127:96] c_ACMD41_mask_check_redo_bits = 32'h80000000; // SD_Send_OCR + localparam logic [127:96] c_ACMD41_ans_dont_redo = 32'h80000000; + localparam logic [127:96] c_ACMD41_mask_check_error_bits = 32'h41FF8000; + localparam logic [127:96] c_ACMD41_ans_error_free = 32'h40FF8000; + + localparam logic [127:96] c_CMD55_mask_check_redo_bits = 32'h00000000; // App_Command + localparam logic [127:96] c_CMD55_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_CMD55_mask_check_error_bits = 32'h0F398000; + localparam logic [127:96] c_CMD55_ans_error_free = 32'h00000000; + + localparam logic [127:96] c_ACMD55_mask_check_redo_bits = 32'h00000000; // App_Command + localparam logic [127:96] c_ACMD55_ans_dont_redo = 32'h00000000; + localparam logic [127:96] c_ACMD55_mask_check_error_bits = 32'h0F398000; + localparam logic [127:96] c_ACMD55_ans_error_free = 32'h00000000; + + // SD_CMD_FSM Connections + logic w_TIMER_LOAD, w_TIMER_EN; + logic [18:0] w_TIMER_IN; + logic [18:0] r_TIMER_OUT; + logic w_COUNTER_LOAD, w_COUNTER_EN; + logic [7:0] w_COUNTER_IN; + logic [7:0] r_COUNTER_OUT; + logic w_SD_CLK_EN; + logic w_CLOCK_CHANGE_DONE, w_START_CLOCK_CHANGE; // to clk fsm + logic w_HS_TO_INIT_CLK_DIVIDER_RST; + logic w_IC_RST, w_IC_EN, w_IC_UP_DOWN; + //logic w_USES_DAT : std_logic_vector(1 downto 0); + //logic w_OPCODE_Q : std_logic_vector(6 downto 0); + //logic w_R_TYPE : std_logic_vector(2 downto 0); + //logic w_NO_REDO_MASK : std_logic_vector(31 downto 0); + //logic w_NO_REDO_ANS : std_logic_vector(31 downto 0); + //logic w_NO_ERROR_MASK : std_logic_vector(31 downto 0); + //logic w_NO_ERROR_ANS : std_logic_vector(31 downto 0); + logic w_SD_CMD_OE; + //logic w_SD_CMD_IE : std_logic; // tri-state buffer - input enable (for simulation only) + logic w_TX_PISO40_LOAD, w_TX_PISO40_EN; + logic w_TX_PISO8_LOAD, w_TX_PISO8_EN; + logic w_TX_CRC7_PIPO_RST, w_TX_CRC7_PIPO_EN; + logic [1:0] w_TX_SOURCE_SELECT; + logic w_CMD_TX_IS_CMD55_RST; + logic w_CMD_TX_IS_CMD55_EN; + //logic w_CMD_RX; + logic w_RX_SIPO48_RST, w_RX_SIPO48_EN; + logic [39:8] r_RESPONSE_CONTENT; + logic [45:40] r_RESPONSE_INDEX; + logic w_RX_CRC7_SIPO_RST, w_RX_CRC7_SIPO_EN; + logic [6:0] r_RX_CRC7_Q; + logic w_RCA_REGISTER_RST, w_RCA_REGISTER_EN; + logic w_CMD_TX_DONE; + logic w_DAT_RX_DONE; + logic w_DAT_ERROR_FD_RST_DAT, w_DAT_ERROR_FD_RST_CMD, w_DAT_ERROR_FD_RST, w_DAT_ERROR_FD_EN; + logic r_DAT_ERROR_Q; // CRC16 error or time out + logic w_NOT_DAT_ERROR_Q; // '0'=no error, '1'=tx error on DAT bus + logic w_ERROR_DAT_TIMES_OUT; + logic w_FATAL_ERROR; + logic [2:0] r_ERROR_CODE_Q; // indicates which fatal error occured + + // Communication with core + logic w_READY_FOR_READ; + logic w_READ_REQUEST; + logic [3:0] r_DATA_TO_CORE; + logic w_DATA_VALID; + logic w_LAST_NIBBLE; + + //SD_DAT_FSM Connections + logic w_DAT_TIMER_LOAD, w_DAT_TIMER_EN; + logic w_DAT_COUNTER_RST, w_DAT_COUNTER_EN; + logic w_CRC16_EN, w_CRC16_RST; + logic w_BUSY_RST, w_BUSY_EN; + logic w_NIBO_EN; + logic w_DATA_CRC16_GOOD; + logic w_VALID_BLOCK_D, w_VALID_BLOCK_EN, w_VALID_WIDE_D, w_VALID_WIDE_EN; + logic [22:0] w_DAT_TIMER_IN; + logic [22:0] r_DAT_TIMER_OUT; + logic [10:0] r_DAT_COUNTER_OUT; + logic [3:0] r_DAT_Q; + + // RCA Register + logic [15:0] w_RCA_D_Q; + logic [15:0] r_RCA_Q2; + + // Multiplexer Logics + logic [132:0] w_instruction_control_bits; + logic [132:130] w_R_TYPE ; + logic [129:128] w_USES_DAT ; + logic [127:96] w_NO_REDO_MASK ; + logic [95:64] w_NO_REDO_ANS ; + logic [63:32] w_NO_ERROR_MASK ; + logic [31:0] w_NO_ERROR_ANS ; + logic [45:40] w_command_index ; + logic [39:8] w_command_arguments ; + logic [47:8] w_command_head ; + logic [6:0] w_OPCODE_Q ; + + // TOP_LEVEL Connections + logic [40:9] w_BLOCK_ADDR ; + logic [3:0] r_IC_OUT ; + logic [2:0] r_command_index_is_55_history ; // [0] is live index, [1] is currently saved index, [2] is index of previous command + logic r_previous_command_index_was_55_q; // is index of previous command 55, wired to r_command_index_is_55_history[2] + logic r_ACMD_Q; // if the previous command sent to the SD card successfully had index 55, then the SD card thinks the current command is ACMD + logic [4095:0] r_block_data ; // data block from CMD17 + + // TX + logic [45:8] w_command_content; // first 40 bits of command packet + logic w_tx_head_Q; // transmission of first part of command packet + logic w_tx_tail_Q; // transmission of last part of command packet + logic [7:0] r_command_tail; // last 8 bits of command packet + logic [6:0] r_TX_CRC7; + //logic w_TX_Q:= '0'; // actual transmission when tx is enabled + + // RX + logic [47:0] r_RX_RESPONSE; + + // Tri state IO Driver BC18MIMS + logic w_SD_CMD_TX_Q; // Write Data + logic w_SD_CMD_RX; // Read Data + + + // CLOCKS + //logic r_CLK_HS := '0'; // 50 MHz Divided Clock [static] + //logic r_SD_CLK_ungated := '0'; // Selected clock before it is clock gated + + //logic r_SD_CLK := '0'; // GATED CLOCKS + logic r_TO_SD_CLK; // What is actually sent to the SD card + + logic w_G_CLK_SD_EN; + logic r_CLK_SD, r_G_CLK_SD; // clocks + logic r_G_CLK_SD_n; + logic [15:0] r_CLK_FSM_RST ; // a_rst logic delayed by one 1.2 GHz period + logic w_SD_CLK_SELECTED; + + //DAT FSM Connections + logic [15:0] r_DAT3_CRC16, r_DAT2_CRC16, r_DAT1_CRC16; + logic [15:0] r_DAT0_CRC16; + + + assign w_BLOCK_ADDR = {8'h00, i_BLOCK_ADDR}; // (40 downto 36 are zero since card is 64 GB) + // (35 downto 32 are zero since memeory is only 8GB total) + + assign o_READY_FOR_READ = w_READY_FOR_READ; + assign w_READ_REQUEST = i_READ_REQUEST; + assign o_DATA_TO_CORE = r_DATA_TO_CORE; + assign o_DATA_VALID = w_DATA_VALID; + assign o_LAST_NIBBLE = (w_LAST_NIBBLE | w_FATAL_ERROR); // indicate done if (last nibble OR Fatal Error go high) + assign o_FATAL_ERROR = w_FATAL_ERROR; + + sd_cmd_fsm my_sd_cmd_fsm + ( + .CLK(r_G_CLK_SD), + .i_RST(a_RST), + .o_TIMER_LOAD(w_TIMER_LOAD), + .o_TIMER_EN(w_TIMER_EN), + .o_TIMER_IN(w_TIMER_IN), + .i_TIMER_OUT(r_TIMER_OUT), + .o_COUNTER_LOAD(w_COUNTER_LOAD), + .o_COUNTER_EN(w_COUNTER_EN), + .o_COUNTER_IN(w_COUNTER_IN), + .i_COUNTER_OUT(r_COUNTER_OUT), + .o_SD_CLK_EN(w_SD_CLK_EN), + .i_CLOCK_CHANGE_DONE(w_CLOCK_CHANGE_DONE), + .o_START_CLOCK_CHANGE(w_START_CLOCK_CHANGE), + .o_IC_RST(w_IC_RST), + .o_IC_EN(w_IC_EN), + .o_IC_UP_DOWN(w_IC_UP_DOWN), + .i_IC_OUT(r_IC_OUT), + .i_USES_DAT(w_USES_DAT), + .i_OPCODE(w_OPCODE_Q), + .i_R_TYPE(w_R_TYPE), + .i_NO_REDO_MASK(w_NO_REDO_MASK), + .i_NO_REDO_ANS(w_NO_REDO_ANS), + .i_NO_ERROR_MASK(w_NO_ERROR_MASK), + .i_NO_ERROR_ANS(w_NO_ERROR_ANS), + .o_SD_CMD_OE(w_SD_CMD_OE), + .o_TX_PISO40_LOAD(w_TX_PISO40_LOAD), + .o_TX_PISO40_EN(w_TX_PISO40_EN), + .o_TX_PISO8_LOAD(w_TX_PISO8_LOAD), + .o_TX_PISO8_EN(w_TX_PISO8_EN), + .o_TX_CRC7_PIPO_RST(w_TX_CRC7_PIPO_RST), + .o_TX_CRC7_PIPO_EN(w_TX_CRC7_PIPO_EN), + .o_TX_SOURCE_SELECT(w_TX_SOURCE_SELECT), + .o_CMD_TX_IS_CMD55_RST(w_CMD_TX_IS_CMD55_RST), + .o_CMD_TX_IS_CMD55_EN(w_CMD_TX_IS_CMD55_EN), + .i_SD_CMD_RX(w_SD_CMD_RX), + .o_RX_SIPO48_RST(w_RX_SIPO48_RST), + .o_RX_SIPO48_EN(w_RX_SIPO48_EN), + .i_RESPONSE_CONTENT(r_RESPONSE_CONTENT), + .i_RESPONSE_INDEX(r_RESPONSE_INDEX), + .o_RX_CRC7_SIPO_RST(w_RX_CRC7_SIPO_RST), + .o_RX_CRC7_SIPO_EN(w_RX_CRC7_SIPO_EN), + .i_RX_CRC7(r_RX_CRC7_Q), + .o_RCA_REGISTER_RST(w_RCA_REGISTER_RST), + .o_RCA_REGISTER_EN(w_RCA_REGISTER_EN), + .o_CMD_TX_DONE(w_CMD_TX_DONE), + .i_DAT_RX_DONE(w_DAT_RX_DONE), + .i_ERROR_CRC16(w_NOT_DAT_ERROR_Q), + .i_ERROR_DAT_TIMES_OUT(w_ERROR_DAT_TIMES_OUT), + .i_READ_REQUEST(w_READ_REQUEST), + .o_READY_FOR_READ(w_READY_FOR_READ), + .o_SD_RESTARTING(o_SD_RESTARTING), + .o_DAT_ERROR_FD_RST(w_DAT_ERROR_FD_RST_CMD), + .o_ERROR_CODE_Q(r_ERROR_CODE_Q), + .o_FATAL_ERROR(w_FATAL_ERROR), + .LIMIT_SD_TIMERS(LIMIT_SD_TIMERS)); + + assign o_ERROR_CODE_Q = r_ERROR_CODE_Q; + + sd_dat_fsm my_sd_dat_fsm + (.CLK(r_G_CLK_SD), + .i_RST(a_RST), + .o_TIMER_LOAD(w_DAT_TIMER_LOAD), + .o_TIMER_EN(w_DAT_TIMER_EN), + .o_TIMER_IN(w_DAT_TIMER_IN), + .i_TIMER_OUT(r_DAT_TIMER_OUT), + .i_SD_CLK_SELECTED(w_SD_CLK_SELECTED), + .o_COUNTER_RST(w_DAT_COUNTER_RST), + .o_COUNTER_EN(w_DAT_COUNTER_EN), + .i_COUNTER_OUT(r_DAT_COUNTER_OUT), + .o_CRC16_EN(w_CRC16_EN), + .o_CRC16_RST(w_CRC16_RST), + .i_DATA_CRC16_GOOD(w_DATA_CRC16_GOOD), + .o_BUSY_RST(w_BUSY_RST), + .o_BUSY_EN(w_BUSY_EN), + .i_DAT0_Q(r_DAT_Q[0]), + .o_NIBO_EN(w_NIBO_EN), + .i_USES_DAT(w_USES_DAT), + .i_CMD_TX_DONE(w_CMD_TX_DONE), + .o_DAT_RX_DONE(w_DAT_RX_DONE), + .o_ERROR_DAT_TIMES_OUT(w_ERROR_DAT_TIMES_OUT), + .o_DATA_VALID(w_DATA_VALID), + .o_LAST_NIBBLE(w_LAST_NIBBLE), + .o_DAT_ERROR_FD_RST(w_DAT_ERROR_FD_RST_DAT), + .o_DAT_ERROR_FD_EN(w_DAT_ERROR_FD_EN), + .LIMIT_SD_TIMERS(LIMIT_SD_TIMERS)); + + assign w_DAT_ERROR_FD_RST = w_DAT_ERROR_FD_RST_CMD | w_DAT_ERROR_FD_RST_DAT; + + flopenr #(1) dat_error_fd + (.clk(r_G_CLK_SD), + .d(w_DATA_CRC16_GOOD), + .q(r_DAT_ERROR_Q), + .en(w_DAT_ERROR_FD_EN), + .reset((w_DAT_ERROR_FD_RST))); + + assign w_NOT_DAT_ERROR_Q = ~r_DAT_ERROR_Q; + + up_down_counter #(23) dat_fsm_timer + ( + .CountIn(w_DAT_TIMER_IN), + .CountOut(r_DAT_TIMER_OUT), + .Load(w_DAT_TIMER_LOAD), + .Enable(w_DAT_TIMER_EN), + .UpDown(1'b0), // Count DOWN only + .clk(r_G_CLK_SD), + .reset(1'b0)); // No Reset, Just Load + + counter #(11) dat_nibble_counter + ( + .CountIn('0), + .CountOut(r_DAT_COUNTER_OUT), + .Load(1'b0), + .Enable(w_DAT_COUNTER_EN), + .clk(r_G_CLK_SD), + .reset(w_DAT_COUNTER_RST)); + + regfile_p2r1w1_nibo #(.DEPTH(10), .WIDTH(4) ) regfile_cmd17_data_block // Nibble In - Nibble Out (NINO) + (.clk(r_G_CLK_SD), + .we1(w_NIBO_EN), + .ra1(r_DAT_COUNTER_OUT[9:0]), // Nibble Read (to core) Address + .rd1(r_DATA_TO_CORE), // output nibble to core + .Rd1All(ReadData), + .wa1(r_DAT_COUNTER_OUT[9:0]), // Nibble Write (to host) Address + .wd1(r_DAT_Q)); // input nibble from card + + crc16_sipo_np_ce crc16_sipo_np_ce_DAT3 + (.CLK(r_G_CLK_SD), + .RST(w_CRC16_RST), + .i_enable(w_CRC16_EN), + .i_message_bit(r_DAT_Q[3]), + .o_crc16(r_DAT3_CRC16)); + + crc16_sipo_np_ce crc16_sipo_np_ce_DAT2 + (.CLK(r_G_CLK_SD), + .RST(w_CRC16_RST), + .i_enable(w_CRC16_EN), + .i_message_bit(r_DAT_Q[2]), + .o_crc16(r_DAT2_CRC16)); + + crc16_sipo_np_ce crc16_sipo_np_ce_DAT1 + (.CLK(r_G_CLK_SD), + .RST(w_CRC16_RST), + .i_enable(w_CRC16_EN), + .i_message_bit(r_DAT_Q[1]), + .o_crc16(r_DAT1_CRC16)); + + crc16_sipo_np_ce crc16_sipo_np_ce_DAT0 + (.CLK(r_G_CLK_SD), + .RST(w_CRC16_RST), + .i_enable(w_CRC16_EN), + .i_message_bit(r_DAT_Q[0]), + .o_crc16(r_DAT0_CRC16)); + + + assign w_DATA_CRC16_GOOD = ({r_DAT3_CRC16, r_DAT2_CRC16, r_DAT1_CRC16, r_DAT0_CRC16}) == 64'h0000000000000000; + + flopenr #(4) busy_bit_fd + (.en(w_BUSY_EN), + .clk(r_G_CLK_SD), + .d(i_SD_DAT), + .q(r_DAT_Q), + .reset(w_BUSY_RST)); + + sd_clk_fsm my_clk_fsm + (.CLK(CLK), + .i_RST(a_RST), + .o_DONE(w_CLOCK_CHANGE_DONE), + .i_START(w_START_CLOCK_CHANGE), + .o_HS_TO_INIT_CLK_DIVIDER_RST(w_HS_TO_INIT_CLK_DIVIDER_RST), + .o_SD_CLK_SELECTED(w_SD_CLK_SELECTED), + .i_FATAL_ERROR(w_FATAL_ERROR), + .o_G_CLK_SD_EN(w_G_CLK_SD_EN)); + + up_down_counter #(19) cmd_fsm_timer + (.CountIn(w_TIMER_IN), + .CountOut(r_TIMER_OUT), + .Load(w_TIMER_LOAD), + .Enable(w_TIMER_EN), + .UpDown(1'b0), // Count DOWN only + .clk(r_G_CLK_SD), + .reset(1'b0)); // No Reset, Just Load + + up_down_counter #(8) cmd_fsm_counter + (.CountIn(w_COUNTER_IN), + .CountOut(r_COUNTER_OUT), + .Load(w_COUNTER_LOAD), + .Enable(w_COUNTER_EN), + .UpDown(1'b0), // Count DOWN only + .clk(r_G_CLK_SD), + .reset(1'b0)); // No RESET, only LOAD + + up_down_counter #(4) instruction_counter + (.CountIn('0), // No CountIn, only RESET + .CountOut(r_IC_OUT), + .Load(1'b0), // No LOAD, only RESET + .Enable(w_IC_EN), + .UpDown(w_IC_UP_DOWN), + .clk(r_G_CLK_SD), + .reset(w_IC_RST)); + + // Clock selection + clkdivider #(g_COUNT_WIDTH) slow_clk_divider // Divide 50 MHz to <400 KHz (Initial clock) + (.i_COUNT_IN_MAX(i_COUNT_IN_MAX), + .i_EN(w_SD_CLK_SELECTED), + .i_RST(w_HS_TO_INIT_CLK_DIVIDER_RST), + .i_CLK(CLK), + .o_CLK(r_CLK_SD)); + + clockgater sd_clk_gater // Select which clock goes to components + (.CLK(r_CLK_SD), + .E(w_G_CLK_SD_EN), + .SE(1'b0), + .ECLK(r_G_CLK_SD)); + + clockgater to_sd_clk_gater // Enable activity on the SD_CLK line + (.CLK(r_G_CLK_SD), + .E(w_SD_CLK_EN), + .SE(1'b0), + .ECLK(r_TO_SD_CLK)); + + flopenr #(16) RCA_register_CE + (.clk(r_G_CLK_SD), + .en(w_RCA_REGISTER_EN), + .d(w_RCA_D_Q), + .q(r_RCA_Q2), + .reset(w_RCA_REGISTER_RST)); + + // ACMD_Detector + flopenr #(1) index_history_fd_2to1 + (.clk(r_G_CLK_SD), + .reset(w_CMD_TX_IS_CMD55_RST), + .en(w_CMD_TX_IS_CMD55_EN), + .d(r_command_index_is_55_history[2]), + .q(r_command_index_is_55_history[1])); + + flopenr #(1) index_history_fd_1to0 + (.clk(r_G_CLK_SD), + .reset(w_CMD_TX_IS_CMD55_RST), + .en(w_CMD_TX_IS_CMD55_EN), + .d(r_command_index_is_55_history[1]), + .q(r_command_index_is_55_history[0])); + + + + assign r_command_index_is_55_history[2] = (w_command_index == 55); + + + assign r_previous_command_index_was_55_q = r_command_index_is_55_history[0]; + assign r_ACMD_Q = r_previous_command_index_was_55_q; // if the previous command WAS 55, the current command is ACMD + + assign o_SD_CLK = r_TO_SD_CLK; + + + + // Multiplexers + //Fetch index and argument of command + assign w_command_content = (r_IC_OUT == 0) ? ({c_Go_Idle_State, 32'h00000000}) : // CMD0 + (r_IC_OUT == 1) ? ({c_Send_IF_State, 32'h000001FF}) : // CMD8 + (r_IC_OUT == 2) ? ({c_App_Command, 32'h00000000}) : // CMD55 + (r_IC_OUT == 3) ? ({c_SD_Send_OCR, 32'h40FF8000}) : // ACMD41 + (r_IC_OUT == 4) ? ({c_All_Send_CID, 32'h00000000}) : // CMD2 + (r_IC_OUT == 5) ? ({c_SD_Send_RCA, 32'h00000000}) : // CMD3 + (r_IC_OUT == 6) ? ({c_Select_Card, r_RCA_Q2[15:0], 16'h0000}) : // CMD7 + (r_IC_OUT == 7) ? ({c_App_Command, r_RCA_Q2[15:0], 16'h0000}) : // CMD55 + (r_IC_OUT == 8) ? ({c_Set_Bus_Width, 32'h00000002}) : // ACMD6 + (r_IC_OUT == 9) ? ({c_Switch_Function, 32'h80FFFFF1}) : // CMD6 + (r_IC_OUT == 10) ? ({c_Read_Single_Block, w_BLOCK_ADDR}) : // CMD17 + ({c_Read_Single_Block, w_BLOCK_ADDR}); // when in doubt just send CMD17 + + assign w_command_index = w_command_content[45:40]; + assign w_command_arguments = w_command_content[39:8]; + assign w_command_head = {c_start_bit, c_tx_host_command, w_command_content}; + + assign w_OPCODE_Q = {r_ACMD_Q, w_command_index}; + + // TX + + crc7_pipo tx_crc7_pipo + (.CLK(r_G_CLK_SD), + .i_DATA(w_command_head), + .i_CRC_ENABLE(w_TX_CRC7_PIPO_EN), + .RST(w_TX_CRC7_PIPO_RST), + .o_CRC(r_TX_CRC7)); + + assign r_command_tail = {r_TX_CRC7, c_stop_bit}; + + piso_generic_ce #(40) tx_piso40_command_head + (.clk(r_G_CLK_SD), + .i_load(w_TX_PISO40_LOAD), + .i_data(w_command_head), + .i_en(w_TX_PISO40_EN), + .o_data(w_tx_head_Q)); + + piso_generic_ce #(8) tx_piso8_command_tail + (.clk(r_G_CLK_SD), + .i_load(w_TX_PISO8_LOAD), + .i_data(r_command_tail), + .i_en(w_TX_PISO8_EN), + .o_data(w_tx_tail_Q)); + + assign w_SD_CMD_TX_Q = (w_TX_SOURCE_SELECT == c_tx_low) ? 1'b0 : + (w_TX_SOURCE_SELECT == c_tx_high) ? 1'b1 : + (w_TX_SOURCE_SELECT == c_tx_head) ? w_tx_head_Q : + (w_TX_SOURCE_SELECT == c_tx_tail) ? w_tx_tail_Q : + 1'b0; + + assign w_SD_CMD_RX = i_SD_CMD; + assign r_G_CLK_SD_n = ~r_G_CLK_SD; + + flopenr #(1) sd_cmd_out_reg + (.d(w_SD_CMD_TX_Q), + .q(o_SD_CMD), + .en(1'b1), + .clk(r_G_CLK_SD_n), + .reset(a_RST)); + + flopenr #(1) sd_cmd_out_oe_reg + (.d(w_SD_CMD_OE), + .q(o_SD_CMD_OE), + .en(1'b1), + .clk(r_G_CLK_SD_n), + .reset(a_RST)); + + // RX + sipo_generic_ce #(48) rx_sipo48_response_content + (.clk(r_G_CLK_SD), + .rst(w_RX_SIPO48_RST), + .i_enable(w_RX_SIPO48_EN), + .i_message_bit(w_SD_CMD_RX), + .o_data(r_RX_RESPONSE)); + + assign r_RESPONSE_CONTENT = r_RX_RESPONSE[39:8]; + assign r_RESPONSE_INDEX = r_RX_RESPONSE[45:40]; + assign w_RCA_D_Q = r_RESPONSE_CONTENT[39:24]; + + crc7_sipo_np_ce rx_crc7_sipo + (.clk(r_G_CLK_SD), + .rst(w_RX_CRC7_SIPO_RST), + .i_enable(w_RX_CRC7_SIPO_EN), + .i_message_bit(w_SD_CMD_RX), + .o_crc7(r_RX_CRC7_Q)); + + // Fetch control bits using r_opcode + assign w_instruction_control_bits = (w_OPCODE_Q == ({c_CMD, c_Go_Idle_State})) ? ({c_response_type_R0_NONE, c_DAT_none, c_CMD0_mask_check_redo_bits, c_CMD0_ans_dont_redo, c_CMD0_mask_check_error_bits, c_CMD0_ans_error_free}) : // CMD0 + + (w_OPCODE_Q == ({c_CMD, c_All_Send_CID})) ? ({c_response_type_R2_CID_CSD, c_DAT_none, c_CMD2_mask_check_redo_bits, c_CMD2_ans_dont_redo, c_CMD2_mask_check_error_bits, c_CMD2_ans_error_free}): // CMD2 + + (w_OPCODE_Q == ({c_CMD, c_SD_Send_RCA})) ? ({c_response_type_R6_RCA, c_DAT_none, c_CMD3_mask_check_redo_bits, c_CMD3_ans_dont_redo, c_CMD3_mask_check_error_bits, c_CMD3_ans_error_free}) : // CMD3 + + (w_OPCODE_Q == ({c_CMD, c_Switch_Function})) ? ({c_response_type_R1_NORMAL, c_DAT_wide, c_CMD6_mask_check_redo_bits, c_CMD6_ans_dont_redo, c_CMD6_mask_check_error_bits, c_CMD6_ans_error_free}): // CMD6 + + (w_OPCODE_Q == ({c_ACMD, c_Set_Bus_Width})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD6_mask_check_redo_bits, c_ACMD6_ans_dont_redo, c_ACMD6_mask_check_error_bits, c_ACMD6_ans_error_free}): //ACMD6 + + (w_OPCODE_Q == ({c_CMD, c_Select_Card})) ? ({c_response_type_R1_NORMAL, c_DAT_busy, c_CMD7_mask_check_redo_bits, c_CMD7_ans_dont_redo, c_CMD7_mask_check_error_bits, c_CMD7_ans_error_free}): // CMD7 + + (w_OPCODE_Q == ({c_CMD, c_Send_IF_State})) ? ({c_response_type_R7_CIC, c_DAT_none, c_CMD8_mask_check_redo_bits, c_CMD8_ans_dont_redo, c_CMD8_mask_check_error_bits, c_CMD8_ans_error_free}): // CMD8 + + (w_OPCODE_Q == ({c_CMD, c_Read_Single_Block})) ? ({c_response_type_R1_NORMAL, c_DAT_block, c_CMD17_mask_check_redo_bits, c_CMD17_ans_dont_redo, c_CMD17_mask_check_error_bits, c_CMD17_ans_error_free}): // CMD17 + + (w_OPCODE_Q == ({c_ACMD, c_SD_Send_OCR})) ? ({c_response_type_R3_OCR, c_DAT_none, c_ACMD41_mask_check_redo_bits, c_ACMD41_ans_dont_redo, c_ACMD41_mask_check_error_bits, c_ACMD41_ans_error_free}) : //ACMD41 + + (w_OPCODE_Q == ({c_CMD, c_App_Command})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_CMD55_mask_check_redo_bits, c_CMD55_ans_dont_redo, c_CMD55_mask_check_error_bits, c_CMD55_ans_error_free}) : // CMD55 + + (w_OPCODE_Q == ({c_ACMD, c_App_Command})) ? ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD55_mask_check_redo_bits, c_ACMD55_ans_dont_redo, c_ACMD55_mask_check_error_bits, c_ACMD55_ans_error_free}) : //ACMD55 + + ({c_response_type_R1_NORMAL, c_DAT_none, c_ACMD55_mask_check_redo_bits, c_ACMD55_ans_dont_redo, c_ACMD55_mask_check_error_bits, c_ACMD55_ans_error_free}); // when in doubt just send ACMD55 + + assign w_R_TYPE = w_instruction_control_bits[132:130]; + assign w_USES_DAT = w_instruction_control_bits[129:128]; + assign w_NO_REDO_MASK = w_instruction_control_bits[127:96]; + assign w_NO_REDO_ANS = w_instruction_control_bits[95:64]; + assign w_NO_ERROR_MASK = w_instruction_control_bits[63:32]; + assign w_NO_ERROR_ANS = w_instruction_control_bits[31:0]; + + +endmodule + diff --git a/wally-pipelined/src/sdc/simple_timer.sv b/wally-pipelined/src/sdc/simple_timer.sv new file mode 100644 index 00000000..07ff9bdb --- /dev/null +++ b/wally-pipelined/src/sdc/simple_timer.sv @@ -0,0 +1,55 @@ +/////////////////////////////////////////// +// simple_timer.sv +// +// Written: Ross Thompson September 20, 2021 +// Modified: +// +// Purpose: SD card controller +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module simple_timer #(parameter BUS_WIDTH = 4) + ( + input logic [BUS_WIDTH-1:0] VALUE, + input logic START, + output logic FLAG, + input logic RST, + input logic CLK); + + + logic [BUS_WIDTH-1:0] count; + logic timer_en; + + assign timer_en = count != 0; + + always_ff @(posedge CLK, posedge RST) begin + if (RST) begin + count <= '0; + end else if (START) begin + count <= VALUE - 1'b1; + end else if(timer_en) begin + count <= count - 1'b1; + end + end + + assign FLAG = count != 0; + +endmodule + diff --git a/wally-pipelined/src/sdc/sipo_generic_ce.sv b/wally-pipelined/src/sdc/sipo_generic_ce.sv new file mode 100644 index 00000000..210767af --- /dev/null +++ b/wally-pipelined/src/sdc/sipo_generic_ce.sv @@ -0,0 +1,53 @@ +/////////////////////////////////////////// +// sipo_generic_ce +// +// Written: Ross Thompson September 20, 2021 +// Modified: +// +// Purpose: serial to n-bit parallel shift register using register_ce. +// When given a n-bit word as input transmit the message serially MSB (leftmost) +// bit first. + +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module sipo_generic_ce #(g_BUS_WIDTH) + (input logic clk, + input logic rst, + input logic i_enable, // data valid, write to register + input logic i_message_bit, // serial data + output logic [g_BUS_WIDTH-1:0] o_data // message received, parallel data + ); + + logic [g_BUS_WIDTH-1:0] w_reg_d; + logic [g_BUS_WIDTH-1:0] r_reg_q; + + flopenr #(g_BUS_WIDTH) shiftReg + (.d(w_reg_d), + .q(r_reg_q), + .en(i_enable), + .reset(rst), + .clk(clk)); + + assign w_reg_d = {r_reg_q[g_BUS_WIDTH-2:0], i_message_bit}; + + assign o_data = r_reg_q; + +endmodule diff --git a/wally-pipelined/src/sdc/tb/ramdisk2.hex b/wally-pipelined/src/sdc/tb/ramdisk2.hex new file mode 100644 index 00000000..33628869 --- /dev/null +++ b/wally-pipelined/src/sdc/tb/ramdisk2.hex @@ -0,0 +1,513 @@ +@20000000 10 32 54 76 +@20000004 00 01 02 03 +@20000008 04 05 06 07 +@2000000C 08 09 0A 0B +@20000010 0C 0D 0E 0F +@20000014 0F 0E 0D 0C +@20000018 0B 0A 09 08 +@2000001C 07 06 05 04 +@20000020 03 02 01 00 +@20000024 10 32 54 76 +@20000028 10 32 54 76 +@2000002C 10 32 54 76 +@20000030 10 32 54 76 +@20000034 10 32 54 76 +@20000038 10 32 54 76 +@2000003C 10 32 54 76 +@20000040 10 32 54 76 +@20000044 10 32 54 76 +@20000048 10 32 54 76 +@2000004C 10 32 54 76 +@20000050 10 32 54 76 +@20000054 10 32 54 76 +@20000058 10 32 54 76 +@2000005C 10 32 54 76 +@20000060 10 32 54 76 +@20000064 10 32 54 76 +@20000068 10 32 54 76 +@2000006C 10 32 54 76 +@20000070 10 32 54 76 +@20000074 10 32 54 76 +@20000078 10 32 54 76 +@2000007C 10 32 54 76 +@20000080 10 32 54 76 +@20000084 10 32 54 76 +@20000088 10 32 54 76 +@2000008C 10 32 54 76 +@20000090 10 32 54 76 +@20000094 10 32 54 76 +@20000098 10 32 54 76 +@2000009C 10 32 54 76 +@200000A0 10 32 54 76 +@200000A4 10 32 54 76 +@200000A8 10 32 54 76 +@200000AC 10 32 54 76 +@200000B0 10 32 54 76 +@200000B4 10 32 54 76 +@200000B8 10 32 54 76 +@200000BC 10 32 54 76 +@200000C0 10 32 54 76 +@200000C4 10 32 54 76 +@200000C8 10 32 54 76 +@200000CC 10 32 54 76 +@200000D0 10 32 54 76 +@200000D4 10 32 54 76 +@200000D8 10 32 54 76 +@200000DC 10 32 54 76 +@200000E0 10 32 54 76 +@200000E4 10 32 54 76 +@200000E8 10 32 54 76 +@200000EC 10 32 54 76 +@200000F0 10 32 54 76 +@200000F4 10 32 54 76 +@200000F8 10 32 54 76 +@200000FC 10 32 54 76 +@20000100 10 32 54 76 +@20000104 10 32 54 76 +@20000108 10 32 54 76 +@2000010C 10 32 54 76 +@20000110 10 32 54 76 +@20000114 10 32 54 76 +@20000118 10 32 54 76 +@2000011C 10 32 54 76 +@20000120 10 32 54 76 +@20000124 10 32 54 76 +@20000128 10 32 54 76 +@2000012C 10 32 54 76 +@20000130 10 32 54 76 +@20000134 10 32 54 76 +@20000138 10 32 54 76 +@2000013C 10 32 54 76 +@20000140 10 32 54 76 +@20000144 10 32 54 76 +@20000148 10 32 54 76 +@2000014C 10 32 54 76 +@20000150 10 32 54 76 +@20000154 10 32 54 76 +@20000158 10 32 54 76 +@2000015C 10 32 54 76 +@20000160 10 32 54 76 +@20000164 10 32 54 76 +@20000168 10 32 54 76 +@2000016C 10 32 54 76 +@20000170 10 32 54 76 +@20000174 10 32 54 76 +@20000178 10 32 54 76 +@2000017C 10 32 54 76 +@20000180 10 32 54 76 +@20000184 10 32 54 76 +@20000188 10 32 54 76 +@2000018C 10 32 54 76 +@20000190 10 32 54 76 +@20000194 10 32 54 76 +@20000198 10 32 54 76 +@2000019C 10 32 54 76 +@200001A0 10 32 54 76 +@200001A4 10 32 54 76 +@200001A8 10 32 54 76 +@200001AC 10 32 54 76 +@200001B0 10 32 54 76 +@200001B4 10 32 54 76 +@200001B8 10 32 54 76 +@200001BC 10 32 54 76 +@200001C0 10 32 54 76 +@200001C4 10 32 54 76 +@200001C8 10 32 54 76 +@200001CC 10 32 54 76 +@200001D0 10 32 54 76 +@200001D4 10 32 54 76 +@200001D8 10 32 54 76 +@200001DC 10 32 54 76 +@200001E0 10 32 54 76 +@200001E4 10 32 54 76 +@200001E8 10 32 54 76 +@200001EC 10 32 54 76 +@200001F0 10 32 54 76 +@200001F4 10 32 54 76 +@200001F8 10 32 54 76 +@200001FC 10 32 54 76 + +@20000200 20 42 64 86 +@20000204 30 52 74 96 +@20000208 40 62 84 A6 +@2000020C 50 72 94 B6 +@20000210 60 82 A4 C6 +@20000214 70 92 B4 D6 +@20000218 80 A2 C4 E6 +@2000021C 90 B2 D4 F6 +@20000220 A0 C2 E4 06 +@20000224 B0 D2 F4 16 +@20000228 C0 E2 04 26 +@2000022C D0 F2 14 36 +@20000230 E0 02 24 46 +@20000234 F0 12 34 56 +@20000238 00 22 44 66 +@2000023C 10 32 54 76 +@20000240 20 42 64 86 +@20000244 30 52 74 96 +@20000248 40 62 84 A6 +@2000024C 50 72 94 B6 +@20000250 60 82 A4 C6 +@20000254 70 92 B4 D6 +@20000258 80 A2 C4 E6 +@2000025C 90 B2 D4 F6 +@20000260 A0 C2 E4 06 +@20000264 B0 D2 F4 16 +@20000268 C0 E2 04 26 +@2000026C D0 F2 14 36 +@20000270 E0 02 24 46 +@20000274 F0 12 34 56 +@20000278 00 22 44 66 +@2000027C 10 32 54 76 +@20000280 20 42 64 86 +@20000284 30 52 74 96 +@20000288 40 62 84 A6 +@2000028C 50 72 94 B6 +@20000290 60 82 A4 C6 +@20000294 70 92 B4 D6 +@20000298 80 A2 C4 E6 +@2000029C 90 B2 D4 F6 +@200002A0 A0 C2 E4 06 +@200002A4 B0 D2 F4 16 +@200002A8 C0 E2 04 26 +@200002AC D0 F2 14 36 +@200002B0 E0 02 24 46 +@200002B4 F0 12 34 56 +@200002B8 00 22 44 66 +@200002BC 10 32 54 76 +@200002C0 20 42 64 86 +@200002C4 30 52 74 96 +@200002C8 40 62 84 A6 +@200002CC 50 72 94 B6 +@200002D0 60 82 A4 C6 +@200002D4 70 92 B4 D6 +@200002D8 80 A2 C4 E6 +@200002DC 90 B2 D4 F6 +@200002E0 A0 C2 E4 06 +@200002E4 B0 D2 F4 16 +@200002E8 C0 E2 04 26 +@200002EC D0 F2 14 36 +@200002F0 E0 02 24 46 +@200002F4 F0 12 34 56 +@200002F8 00 22 44 66 +@200002FC 10 32 54 76 +@20000300 20 42 64 86 +@20000304 30 52 74 96 +@20000308 40 62 84 A6 +@2000030C 50 72 94 B6 +@20000310 60 82 A4 C6 +@20000314 70 92 B4 D6 +@20000318 80 A2 C4 E6 +@2000031C 90 B2 D4 F6 +@20000320 A0 C2 E4 06 +@20000324 B0 D2 F4 16 +@20000328 C0 E2 04 26 +@2000032C D0 F2 14 36 +@20000330 E0 02 24 46 +@20000334 F0 12 34 56 +@20000338 00 22 44 66 +@2000033C 10 32 54 76 +@20000340 20 42 64 86 +@20000344 30 52 74 96 +@20000348 40 62 84 A6 +@2000034C 50 72 94 B6 +@20000350 60 82 A4 C6 +@20000354 70 92 B4 D6 +@20000358 80 A2 C4 E6 +@2000035C 90 B2 D4 F6 +@20000360 A0 C2 E4 06 +@20000364 B0 D2 F4 16 +@20000368 C0 E2 04 26 +@2000036C D0 F2 14 36 +@20000370 E0 02 24 46 +@20000374 F0 12 34 56 +@20000378 00 22 44 66 +@2000037C 10 32 54 76 +@20000380 20 42 64 86 +@20000384 30 52 74 96 +@20000388 40 62 84 A6 +@2000038C 50 72 94 B6 +@20000390 60 82 A4 C6 +@20000394 70 92 B4 D6 +@20000398 80 A2 C4 E6 +@2000039C 90 B2 D4 F6 +@200003A0 A0 C2 E4 06 +@200003A4 B0 D2 F4 16 +@200003A8 C0 E2 04 26 +@200003AC D0 F2 14 36 +@200003B0 E0 02 24 46 +@200003B4 F0 12 34 56 +@200003B8 00 22 44 66 +@200003BC 10 32 54 76 +@200003C0 20 42 64 86 +@200003C4 30 52 74 96 +@200003C8 40 62 84 A6 +@200003CC 50 72 94 B6 +@200003D0 60 82 A4 C6 +@200003D4 70 92 B4 D6 +@200003D8 80 A2 C4 E6 +@200003DC 90 B2 D4 F6 +@200003E0 A0 C2 E4 06 +@200003E4 B0 D2 F4 16 +@200003E8 C0 E2 04 26 +@200003EC D0 F2 14 36 +@200003F0 E0 02 24 46 +@200003F4 F0 12 34 56 +@200003F8 00 22 44 66 +@200003FC 10 32 54 76 +@1ffff0000 00 00 00 00 +@1ffff0004 00 00 00 00 +@1ffff0008 00 00 00 00 +@1ffff000c 00 00 00 00 +@1ffff0010 00 00 00 00 +@1ffff0014 00 00 00 00 +@1ffff0018 00 00 00 00 +@1ffff001c 00 00 00 00 +@1ffff0020 00 00 00 00 +@1ffff0024 00 00 00 00 +@1ffff0028 00 00 00 00 +@1ffff002c 00 00 00 00 +@1ffff0030 00 00 00 00 +@1ffff0034 00 00 00 00 +@1ffff0038 00 00 00 00 +@1ffff003c 00 00 00 00 +@1ffff0040 00 00 00 00 +@1ffff0044 00 00 00 00 +@1ffff0048 00 00 00 00 +@1ffff004c 00 00 00 00 +@1ffff0050 00 00 00 00 +@1ffff0054 00 00 00 00 +@1ffff0058 00 00 00 00 +@1ffff005c 00 00 00 00 +@1ffff0060 00 00 00 00 +@1ffff0064 00 00 00 00 +@1ffff0068 00 00 00 00 +@1ffff006C 00 00 00 00 +@1ffff0070 00 00 00 00 +@1ffff0074 00 00 00 00 +@1ffff0078 00 00 00 00 +@1ffff007c 00 00 00 00 +@1ffff0080 00 00 00 00 +@1ffff0084 00 00 00 00 +@1ffff0088 00 00 00 00 +@1ffff008c 00 00 00 00 +@1ffff0090 00 00 00 00 +@1ffff0094 00 00 00 00 +@1ffff0098 00 00 00 00 +@1ffff009c 00 00 00 00 +@1ffff00a0 00 00 00 00 +@1ffff00a4 00 00 00 00 +@1ffff00a8 00 00 00 00 +@1ffff00ac 00 00 00 00 +@1ffff00b0 00 00 00 00 +@1ffff00b4 00 00 00 00 +@1ffff00b8 00 00 00 00 +@1ffff00bc 00 00 00 00 +@1ffff00c0 00 00 00 00 +@1ffff00c4 00 00 00 00 +@1ffff00c8 00 00 00 00 +@1ffff00cc 00 00 00 00 +@1ffff00d0 00 00 00 00 +@1ffff00d4 00 00 00 00 +@1ffff00d8 00 00 00 00 +@1ffff00dc 00 00 00 00 +@1ffff00e0 00 00 00 00 +@1ffff00e4 00 00 00 00 +@1ffff00e8 00 00 00 00 +@1ffff00ec 00 00 00 00 +@1ffff00f0 00 00 00 00 +@1ffff00f4 00 00 00 00 +@1ffff00f8 00 00 00 00 +@1ffff00fc 00 00 00 00 +@1ffff0100 00 00 00 00 +@1ffff0104 00 00 00 00 +@1ffff0108 00 00 00 00 +@1ffff010c 00 00 00 00 +@1ffff0110 00 00 00 00 +@1ffff0114 00 00 00 00 +@1ffff0118 00 00 00 00 +@1ffff011c 00 00 00 00 +@1ffff0120 00 00 00 00 +@1ffff0124 00 00 00 00 +@1ffff0128 00 00 00 00 +@1ffff012c 00 00 00 00 +@1ffff0130 00 00 00 00 +@1ffff0134 00 00 00 00 +@1ffff0138 00 00 00 00 +@1ffff013c 00 00 00 00 +@1ffff0140 00 00 00 00 +@1ffff0144 00 00 00 00 +@1ffff0148 00 00 00 00 +@1ffff014c 00 00 00 00 +@1ffff0150 00 00 00 00 +@1ffff0154 00 00 00 00 +@1ffff0158 00 00 00 00 +@1ffff015c 00 00 00 00 +@1ffff0160 00 00 00 00 +@1ffff0164 00 00 00 00 +@1ffff0168 00 00 00 00 +@1ffff016C 00 00 00 00 +@1ffff0170 00 00 00 00 +@1ffff0174 00 00 00 00 +@1ffff0178 00 00 00 00 +@1ffff017c 00 00 00 00 +@1ffff0180 00 00 00 00 +@1ffff0184 00 00 00 00 +@1ffff0188 00 00 00 00 +@1ffff018c 00 00 00 00 +@1ffff0190 00 00 00 00 +@1ffff0194 00 00 00 00 +@1ffff0198 00 00 00 00 +@1ffff019c 00 00 00 00 +@1ffff01a0 00 00 00 00 +@1ffff01a4 00 00 00 00 +@1ffff01a8 00 00 00 00 +@1ffff01ac 00 00 00 00 +@1ffff01b0 00 00 00 00 +@1ffff01b4 00 00 00 00 +@1ffff01b8 00 00 00 00 +@1ffff01bc 00 00 00 00 +@1ffff01c0 00 00 00 00 +@1ffff01c4 00 00 00 00 +@1ffff01c8 00 00 00 00 +@1ffff01cc 00 00 00 00 +@1ffff01d0 00 00 00 00 +@1ffff01d4 00 00 00 00 +@1ffff01d8 00 00 00 00 +@1ffff01dc 00 00 00 00 +@1ffff01e0 00 00 00 00 +@1ffff01e4 00 00 00 00 +@1ffff01e8 00 00 00 00 +@1ffff01ec 00 00 00 00 +@1ffff01f0 00 00 00 00 +@1ffff01f4 00 00 00 00 +@1ffff01f8 00 00 00 00 +@1ffff01fc 00 00 00 00 +@0ffff0000 00 00 00 00 +@0ffff0004 00 00 00 00 +@0ffff0008 00 00 00 00 +@0ffff000c 00 00 00 00 +@0ffff0010 00 00 00 00 +@0ffff0014 00 00 00 00 +@0ffff0018 00 00 00 00 +@0ffff001c 00 00 00 00 +@0ffff0020 00 00 00 00 +@0ffff0024 00 00 00 00 +@0ffff0028 00 00 00 00 +@0ffff002c 00 00 00 00 +@0ffff0030 00 00 00 00 +@0ffff0034 00 00 00 00 +@0ffff0038 00 00 00 00 +@0ffff003c 00 00 00 00 +@0ffff0040 00 00 00 00 +@0ffff0044 00 00 00 00 +@0ffff0048 00 00 00 00 +@0ffff004c 00 00 00 00 +@0ffff0050 00 00 00 00 +@0ffff0054 00 00 00 00 +@0ffff0058 00 00 00 00 +@0ffff005c 00 00 00 00 +@0ffff0060 00 00 00 00 +@0ffff0064 00 00 00 00 +@0ffff0068 00 00 00 00 +@0ffff006C 00 00 00 00 +@0ffff0070 00 00 00 00 +@0ffff0074 00 00 00 00 +@0ffff0078 00 00 00 00 +@0ffff007c 00 00 00 00 +@0ffff0080 00 00 00 00 +@0ffff0084 00 00 00 00 +@0ffff0088 00 00 00 00 +@0ffff008c 00 00 00 00 +@0ffff0090 00 00 00 00 +@0ffff0094 00 00 00 00 +@0ffff0098 00 00 00 00 +@0ffff009c 00 00 00 00 +@0ffff00a0 00 00 00 00 +@0ffff00a4 00 00 00 00 +@0ffff00a8 00 00 00 00 +@0ffff00ac 00 00 00 00 +@0ffff00b0 00 00 00 00 +@0ffff00b4 00 00 00 00 +@0ffff00b8 00 00 00 00 +@0ffff00bc 00 00 00 00 +@0ffff00c0 00 00 00 00 +@0ffff00c4 00 00 00 00 +@0ffff00c8 00 00 00 00 +@0ffff00cc 00 00 00 00 +@0ffff00d0 00 00 00 00 +@0ffff00d4 00 00 00 00 +@0ffff00d8 00 00 00 00 +@0ffff00dc 00 00 00 00 +@0ffff00e0 00 00 00 00 +@0ffff00e4 00 00 00 00 +@0ffff00e8 00 00 00 00 +@0ffff00ec 00 00 00 00 +@0ffff00f0 00 00 00 00 +@0ffff00f4 00 00 00 00 +@0ffff00f8 00 00 00 00 +@0ffff00fc 00 00 00 00 +@0ffff0100 00 00 00 00 +@0ffff0104 00 00 00 00 +@0ffff0108 00 00 00 00 +@0ffff010c 00 00 00 00 +@0ffff0110 00 00 00 00 +@0ffff0114 00 00 00 00 +@0ffff0118 00 00 00 00 +@0ffff011c 00 00 00 00 +@0ffff0120 00 00 00 00 +@0ffff0124 00 00 00 00 +@0ffff0128 00 00 00 00 +@0ffff012c 00 00 00 00 +@0ffff0130 00 00 00 00 +@0ffff0134 00 00 00 00 +@0ffff0138 00 00 00 00 +@0ffff013c 00 00 00 00 +@0ffff0140 00 00 00 00 +@0ffff0144 00 00 00 00 +@0ffff0148 00 00 00 00 +@0ffff014c 00 00 00 00 +@0ffff0150 00 00 00 00 +@0ffff0154 00 00 00 00 +@0ffff0158 00 00 00 00 +@0ffff015c 00 00 00 00 +@0ffff0160 00 00 00 00 +@0ffff0164 00 00 00 00 +@0ffff0168 00 00 00 00 +@0ffff016C 00 00 00 00 +@0ffff0170 00 00 00 00 +@0ffff0174 00 00 00 00 +@0ffff0178 00 00 00 00 +@0ffff017c 00 00 00 00 +@0ffff0180 00 00 00 00 +@0ffff0184 00 00 00 00 +@0ffff0188 00 00 00 00 +@0ffff018c 00 00 00 00 +@0ffff0190 00 00 00 00 +@0ffff0194 00 00 00 00 +@0ffff0198 00 00 00 00 +@0ffff019c 00 00 00 00 +@0ffff01a0 00 00 00 00 +@0ffff01a4 00 00 00 00 +@0ffff01a8 00 00 00 00 +@0ffff01ac 00 00 00 00 +@0ffff01b0 00 00 00 00 +@0ffff01b4 00 00 00 00 +@0ffff01b8 00 00 00 00 +@0ffff01bc 00 00 00 00 +@0ffff01c0 00 00 00 00 +@0ffff01c4 00 00 00 00 +@0ffff01c8 00 00 00 00 +@0ffff01cc 00 00 00 00 +@0ffff01d0 00 00 00 00 +@0ffff01d4 00 00 00 00 +@0ffff01d8 00 00 00 00 +@0ffff01dc 00 00 00 00 +@0ffff01e0 00 00 00 00 +@0ffff01e4 00 00 00 00 +@0ffff01e8 00 00 00 00 +@0ffff01ec 00 00 00 00 +@0ffff01f0 00 00 00 00 +@0ffff01f4 00 00 00 00 +@0ffff01f8 00 00 00 00 +@0ffff01fc 00 00 00 00 diff --git a/wally-pipelined/src/sdc/tb/run_tb.do b/wally-pipelined/src/sdc/tb/run_tb.do new file mode 100644 index 00000000..e16a5b8c --- /dev/null +++ b/wally-pipelined/src/sdc/tb/run_tb.do @@ -0,0 +1,17 @@ +onbreak {resume} + +# create library +if [file exists work] { + vdel -all +} +vlib work + +vlog +incdir+../../../config/rv64ic +incdir+../../../config/shared ../../../testbench/common/*.sv ../../*/*.sv sd_top_tb.sv -suppress 2583 + +vopt -fsmdebug +acc -gDEBUG=1 work.sd_top_tb -o workopt +vsim workopt -fsmdebug + +do wave.do +add log -r /* + +run 3000 us diff --git a/wally-pipelined/src/sdc/tb/sd_top_tb.sv b/wally-pipelined/src/sdc/tb/sd_top_tb.sv new file mode 100644 index 00000000..21ce7fd5 --- /dev/null +++ b/wally-pipelined/src/sdc/tb/sd_top_tb.sv @@ -0,0 +1,119 @@ +/////////////////////////////////////////// +// sd_top_tb.sv +// +// Written: Ross Thompson September 20, 2021 +// Modified: +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + + +module sd_top_tb(); + + + localparam integer g_COUNT_WIDTH = 8; + + logic a_RST; + logic i_SD_CMD; + logic o_SD_CMD; + logic o_SD_CMD_OE; + wire [3:0] i_SD_DAT; + logic o_SD_CLK; + logic [32:9] i_BLOCK_ADDR; + logic [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX; + + logic o_READY_FOR_READ; + logic i_READ_REQUEST; + logic [3:0] o_DATA_TO_CORE; + logic o_DATA_VALID; + logic o_LAST_NIBBLE; + logic [4095:0] ReadData; + + // Driver + wire PAD; + + logic r_CLK; + + + // clock + + sd_top #(g_COUNT_WIDTH) DUT + (.CLK(r_CLK), + .a_RST(a_RST), + .i_SD_CMD(i_SD_CMD), + .o_SD_CMD(o_SD_CMD), + .o_SD_CMD_OE(o_SD_CMD_OE), + .i_SD_DAT(i_SD_DAT), + .o_SD_CLK(o_SD_CLK), + .i_BLOCK_ADDR(i_BLOCK_ADDR), + .o_READY_FOR_READ(o_READY_FOR_READ), + .i_READ_REQUEST(i_READ_REQUEST), + .o_DATA_TO_CORE(o_DATA_TO_CORE), + .ReadData(ReadData), + .o_DATA_VALID(o_DATA_VALID), + .o_LAST_NIBBLE(o_LAST_NIBBLE), + .i_COUNT_IN_MAX(i_COUNT_IN_MAX), + .LIMIT_SD_TIMERS(1'b1)); + + sdModel sdcard + (.sdClk(o_SD_CLK), + .cmd(PAD), + .dat(i_SD_DAT)); + + // tri state pad + // replace with I/O standard cell or FPGA gate. + assign PAD = o_SD_CMD_OE ? o_SD_CMD : 1'bz; + assign i_SD_CMD = PAD; + + + always + begin + r_CLK = 1; # 5; r_CLK = 0; # 5; + end + + + initial $readmemh("ramdisk2.hex", sdcard.FLASHmem); + + initial begin + + a_RST = 1'b0; + i_BLOCK_ADDR = 24'h100000; + i_COUNT_IN_MAX = '0; + i_READ_REQUEST = 1'b0; + + # 5; + i_COUNT_IN_MAX = -62; + + # 10; + a_RST = 1'b1; + + # 4800; + + a_RST = 1'b0; + + # 2000000; + i_READ_REQUEST = 1'b0; + # 10000; + i_READ_REQUEST = 1'b1; + # 10000; + i_READ_REQUEST = 1'b0; + + end + +endmodule diff --git a/wally-pipelined/src/sdc/tb/wave.do b/wally-pipelined/src/sdc/tb/wave.do new file mode 100644 index 00000000..e41e298a --- /dev/null +++ b/wally-pipelined/src/sdc/tb/wave.do @@ -0,0 +1,128 @@ +onerror {resume} +quietly WaveActivateNextPane {} 0 +add wave -noupdate /sd_top_tb/DUT/a_RST +add wave -noupdate /sd_top_tb/DUT/CLK +add wave -noupdate /sd_top_tb/DUT/i_BLOCK_ADDR +add wave -noupdate /sd_top_tb/DUT/i_READ_REQUEST +add wave -noupdate /sd_top_tb/DUT/i_COUNT_IN_MAX +add wave -noupdate /sd_top_tb/DUT/LIMIT_SD_TIMERS +add wave -noupdate /sd_top_tb/DUT/o_READY_FOR_READ +add wave -noupdate /sd_top_tb/DUT/o_SD_RESTARTING +add wave -noupdate /sd_top_tb/DUT/o_DATA_TO_CORE +add wave -noupdate /sd_top_tb/DUT/o_DATA_VALID +add wave -noupdate /sd_top_tb/DUT/o_LAST_NIBBLE +add wave -noupdate /sd_top_tb/DUT/o_ERROR_CODE_Q +add wave -noupdate /sd_top_tb/DUT/o_FATAL_ERROR +add wave -noupdate -expand -group interface /sd_top_tb/DUT/o_SD_CLK +add wave -noupdate -expand -group interface /sd_top_tb/DUT/o_SD_CMD +add wave -noupdate -expand -group interface /sd_top_tb/DUT/o_SD_CMD_OE +add wave -noupdate -expand -group interface /sd_top_tb/DUT/i_SD_CMD +add wave -noupdate -expand -group interface /sd_top_tb/DUT/i_SD_DAT +add wave -noupdate -label {cmd fsm} /sd_top_tb/DUT/my_sd_cmd_fsm/r_curr_state +add wave -noupdate -label {dat fsm} /sd_top_tb/DUT/my_sd_dat_fsm/r_curr_state +add wave -noupdate -label {clk fsm} /sd_top_tb/DUT/my_clk_fsm/r_curr_state +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_RST +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_TIMER_OUT +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_COUNTER_OUT +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_CLOCK_CHANGE_DONE +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_IC_OUT +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_USES_DAT +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_OPCODE +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_R_TYPE +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_NO_REDO_MASK +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_NO_REDO_ANS +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_NO_ERROR_MASK +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_NO_ERROR_ANS +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_SD_CMD_RX +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_RESPONSE_CONTENT +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_RESPONSE_INDEX +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_RX_CRC7 +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_DAT_RX_DONE +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_ERROR_CRC16 +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_ERROR_DAT_TIMES_OUT +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/i_READ_REQUEST +add wave -noupdate -group old /sd_top_tb/DUT/my_sd_cmd_fsm/LIMIT_SD_TIMERS +add wave -noupdate -group old /sd_top_tb/DUT/my_clk_fsm/i_START +add wave -noupdate -group old /sd_top_tb/DUT/my_clk_fsm/i_FATAL_ERROR +add wave -noupdate -group old /sd_top_tb/DUT/my_clk_fsm/i_RST +add wave -noupdate -group old /sd_top_tb/DUT/my_clk_fsm/o_DONE +add wave -noupdate -group old /sd_top_tb/DUT/my_clk_fsm/o_G_CLK_SD_EN +add wave -noupdate -group old /sd_top_tb/DUT/my_clk_fsm/o_HS_TO_INIT_CLK_DIVIDER_RST +add wave -noupdate -group old /sd_top_tb/DUT/my_clk_fsm/o_SD_CLK_SELECTED +add wave -noupdate -group old -expand /sd_top_tb/DUT/w_OPCODE_Q +add wave -noupdate -group old /sd_top_tb/DUT/c_CMD +add wave -noupdate -group old /sd_top_tb/DUT/c_ACMD +add wave -noupdate -group old /sd_top_tb/DUT/c_Go_Idle_State +add wave -noupdate -group old /sd_top_tb/DUT/c_response_type_R0_NONE +add wave -noupdate -group old /sd_top_tb/DUT/c_response_type_R0_NONE +add wave -noupdate -group old /sd_top_tb/DUT/c_response_type_R1_NORMAL +add wave -noupdate -group old /sd_top_tb/DUT/c_response_type_R2_CID_CSD +add wave -noupdate -group old /sd_top_tb/DUT/c_response_type_R3_OCR +add wave -noupdate -group old /sd_top_tb/DUT/c_response_type_R6_RCA +add wave -noupdate -group old /sd_top_tb/DUT/c_response_type_R7_CIC +add wave -noupdate -group old /sd_top_tb/DUT/w_instruction_control_bits +add wave -noupdate -group old /sd_top_tb/DUT/w_command_index +add wave -noupdate -group old /sd_top_tb/DUT/r_IC_OUT +add wave -noupdate -group old /sd_top_tb/DUT/w_BLOCK_ADDR +add wave -noupdate /sd_top_tb/DUT/w_TX_SOURCE_SELECT +add wave -noupdate /sd_top_tb/DUT/w_tx_tail_Q +add wave -noupdate /sd_top_tb/DUT/w_TX_PISO8_LOAD +add wave -noupdate /sd_top_tb/DUT/w_TX_PISO8_EN +add wave -noupdate /sd_top_tb/DUT/r_command_tail +add wave -noupdate /sd_top_tb/DUT/r_TX_CRC7 +add wave -noupdate /sd_top_tb/DUT/w_TX_CRC7_PIPO_RST +add wave -noupdate /sd_top_tb/DUT/w_TX_CRC7_PIPO_EN +add wave -noupdate /sd_top_tb/DUT/w_command_head +add wave -noupdate /sd_top_tb/DUT/my_sd_dat_fsm/i_DAT0_Q +add wave -noupdate /sd_top_tb/sdcard/oeDat +add wave -noupdate /sd_top_tb/sdcard/datOut +add wave -noupdate /sd_top_tb/sdcard/dat +add wave -noupdate /sd_top_tb/DUT/my_sd_cmd_fsm/w_resend_last_command +add wave -noupdate /sd_top_tb/DUT/my_sd_cmd_fsm/i_ERROR_CRC16 +add wave -noupdate /sd_top_tb/DUT/r_DAT3_CRC16 +add wave -noupdate /sd_top_tb/DUT/r_DAT2_CRC16 +add wave -noupdate /sd_top_tb/DUT/r_DAT1_CRC16 +add wave -noupdate /sd_top_tb/DUT/r_DAT0_CRC16 +add wave -noupdate -radix decimal /sd_top_tb/DUT/my_sd_cmd_fsm/i_COUNTER_OUT +add wave -noupdate /sd_top_tb/DUT/CLK +add wave -noupdate /sd_top_tb/DUT/r_CLK_SD +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/i_COUNT_IN_MAX +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/i_EN +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/i_CLK +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/i_RST +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/g_COUNT_WIDTH +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/r_count_out +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/w_counter_overflowed +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/r_fd_Q +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/w_fd_D +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/w_load +add wave -noupdate -expand -group {clock divider} /sd_top_tb/DUT/slow_clk_divider/o_CLK +add wave -noupdate /sd_top_tb/sdcard/ByteAddr +add wave -noupdate /sd_top_tb/sdcard/write_out_index +add wave -noupdate /sd_top_tb/sdcard/inCmd +add wave -noupdate /sd_top_tb/DUT/w_TX_SOURCE_SELECT +add wave -noupdate /sd_top_tb/DUT/w_command_head +add wave -noupdate /sd_top_tb/DUT/r_IC_OUT +add wave -noupdate /sd_top_tb/DUT/w_BLOCK_ADDR +add wave -noupdate /sd_top_tb/DUT/i_BLOCK_ADDR +add wave -noupdate /sd_top_tb/DUT/regfile_cmd17_data_block/regs +add wave -noupdate /sd_top_tb/DUT/regfile_cmd17_data_block/ra1 +add wave -noupdate /sd_top_tb/ReadData +TreeUpdate [SetDefaultTree] +WaveRestoreCursors {{Cursor 1} {2028326 ns} 0} {{Cursor 2} {4831 ns} 0} +quietly wave cursor active 1 +configure wave -namecolwidth 245 +configure wave -valuecolwidth 180 +configure wave -justifyvalue left +configure wave -signalnamewidth 1 +configure wave -snapdistance 10 +configure wave -datasetprefix 0 +configure wave -rowmargin 4 +configure wave -childrowmargin 2 +configure wave -gridoffset 0 +configure wave -gridperiod 1 +configure wave -griddelta 40 +configure wave -timeline 0 +configure wave -timelineunits ns +update +WaveRestoreZoom {1979107 ns} {2077545 ns} diff --git a/wally-pipelined/src/sdc/up_down_counter.sv b/wally-pipelined/src/sdc/up_down_counter.sv new file mode 100644 index 00000000..13c5676c --- /dev/null +++ b/wally-pipelined/src/sdc/up_down_counter.sv @@ -0,0 +1,55 @@ +/////////////////////////////////////////// +// counter.sv +// +// Written: Ross Thompson +// Modified: +// +// Purpose: basic up counter +// +// A component of the Wally configurable RISC-V project. +// +// Copyright (C) 2021 Harvey Mudd College & Oklahoma State University +// +// Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation +// files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, +// modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software +// is furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES +// OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS +// BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT +// OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +/////////////////////////////////////////// + +`include "wally-config.vh" + +module up_down_counter #(parameter integer WIDTH=32) + ( + input logic [WIDTH-1:0] CountIn, + output logic [WIDTH-1:0] CountOut, + input logic Load, + input logic Enable, + input logic UpDown, + input logic clk, + input logic reset); + + logic [WIDTH-1:0] NextCount; + logic [WIDTH-1:0] count_q; + logic [WIDTH-1:0] CountP1; + + flopenr #(WIDTH) reg1(.clk, + .reset, + .en(Enable | Load), + .d(NextCount), + .q(CountOut)); + + assign CountP1 = UpDown ? CountOut + 1'b1 : CountOut - 1'b1; + + // mux between load and P1 + assign NextCount = Load ? CountIn : CountP1; + +endmodule + + diff --git a/wally-pipelined/src/uncore/uncore.sv b/wally-pipelined/src/uncore/uncore.sv index 3df8ee1c..27a48ce8 100644 --- a/wally-pipelined/src/uncore/uncore.sv +++ b/wally-pipelined/src/uncore/uncore.sv @@ -57,30 +57,36 @@ module uncore ( output logic [31:0] GPIOPinsOut, GPIOPinsEn, input logic UARTSin, output logic UARTSout, + output logic SDCCmdOut, + output logic SDCCmdOE, + input logic SDCCmdIn, + input logic [3:0] SDCDatIn, + output logic SDCCLK, output logic [63:0] MTIME_CLINT, MTIMECMP_CLINT ); logic [`XLEN-1:0] HWDATA; - logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART; + logic [`XLEN-1:0] HREADTim, HREADCLINT, HREADPLIC, HREADGPIO, HREADUART, HREADSDC; - logic [6:0] HSELRegions; - logic HSELTim, HSELCLINT, HSELPLIC, HSELGPIO, PreHSELUART, HSELUART; - logic HSELTimD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD; - logic HRESPTim, HRESPCLINT, HRESPPLIC, HRESPGPIO, HRESPUART; - logic HREADYTim, HREADYCLINT, HREADYPLIC, HREADYGPIO, HREADYUART; + logic [7:0] HSELRegions; + logic HSELTim, HSELCLINT, HSELPLIC, HSELGPIO, PreHSELUART, HSELUART, HSELSDC; + logic HSELTimD, HSELCLINTD, HSELPLICD, HSELGPIOD, HSELUARTD, HSELSDCD; + logic HRESPTim, HRESPCLINT, HRESPPLIC, HRESPGPIO, HRESPUART, HRESPSDC; + logic HREADYTim, HREADYCLINT, HREADYPLIC, HREADYGPIO, HREADYUART, HRESPSDCD; logic [`XLEN-1:0] HREADBootTim; - logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim; + logic HSELBootTim, HSELBootTimD, HRESPBootTim, HREADYBootTim, HREADYSDC; logic HSELNoneD; logic [1:0] MemRWboottim; logic UARTIntr,GPIOIntr; - + logic SDCIntM; + // Determine which region of physical memory (if any) is being accessed // Use a trimmed down portion of the PMA checker - only the address decoders // Set access types to all 1 as don't cares because the MMU has already done access checking adrdecs adrdecs({{(`PA_BITS-32){1'b0}}, HADDR}, 1'b1, 1'b1, 1'b1, HSIZE[1:0], HSELRegions); // unswizzle HSEL signals - assign {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC} = HSELRegions[5:0]; + assign {HSELBootTim, HSELTim, HSELCLINT, HSELGPIO, HSELUART, HSELPLIC, HSELSDC} = HSELRegions[6:0]; assign HSELEXT = HSELRegions[4]; @@ -119,6 +125,19 @@ module uncore ( end else begin : uart assign UARTSout = 0; assign UARTIntr = 0; end + if (`SDC_SUPPORTED == 1) begin : sdc + SDC SDC(.HCLK, .HRESETn, .HSELSDC, .HADDR(HADDR[4:0]), .HWRITE, .HREADY, .HTRANS, + .HWDATA, .HREADSDC, .HRESPSDC, .HREADYSDC, + // sdc interface + .SDCCmdOut, .SDCCmdIn, .SDCCmdOE, .SDCDatIn, .SDCCLK, + // interrupt to PLIC + .SDCIntM + ); + end else begin : sdc + assign SDCCLK = 0; + assign SDCCmdOut = 0; + assign SDCCmdOE = 0; + end endgenerate // mux could also include external memory @@ -129,24 +148,27 @@ module uncore ( ({`XLEN{HSELPLICD}} & HREADPLIC) | ({`XLEN{HSELGPIOD}} & HREADGPIO) | ({`XLEN{HSELBootTimD}} & HREADBootTim) | - ({`XLEN{HSELUARTD}} & HREADUART); - //assign HRESP = HSELTimD & HRESPTim | + ({`XLEN{HSELUARTD}} & HREADUART) | + ({`XLEN{HSELSDCD}} & HREADSDC); + assign HRESP = HSELTimD & HRESPEXT | HSELCLINTD & HRESPCLINT | HSELPLICD & HRESPPLIC | HSELGPIOD & HRESPGPIO | HSELBootTimD & HRESPBootTim | - HSELUARTD & HRESPUART; - //assign HREADY = HSELTimD & HREADYTim | + HSELUARTD & HRESPUART | + HSELSDC & HRESPSDC; + assign HREADY = HSELTimD & HREADYEXT | HSELCLINTD & HREADYCLINT | HSELPLICD & HREADYPLIC | HSELGPIOD & HREADYGPIO | HSELBootTimD & HREADYBootTim | HSELUARTD & HREADYUART | + HSELSDCD & HREADYSDC | HSELNoneD; // don't lock up the bus if no region is being accessed // Address Decoder Delay (figure 4-2 in spec) - flopr #(7) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELBootTimD, HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD}); + flopr #(8) hseldelayreg(HCLK, ~HRESETn, HSELRegions, {HSELNoneD, HSELBootTimD, HSELTimD, HSELCLINTD, HSELGPIOD, HSELUARTD, HSELPLICD, HSELSDCD}); endmodule diff --git a/wally-pipelined/src/wally/wallypipelinedhart.sv b/wally-pipelined/src/wally/wallypipelinedhart.sv index f7968f2d..329fd0cd 100644 --- a/wally-pipelined/src/wally/wallypipelinedhart.sv +++ b/wally-pipelined/src/wally/wallypipelinedhart.sv @@ -85,7 +85,7 @@ module wallypipelinedhart logic LoadMisalignedFaultM, LoadAccessFaultM; logic StoreMisalignedFaultM, StoreAccessFaultM; logic [`XLEN-1:0] InstrMisalignedAdrM; - + logic InvalidateICacheM, FlushDCacheM; logic PCSrcE; logic CSRWritePendingDEM; logic DivDoneE; @@ -196,6 +196,7 @@ module wallypipelinedhart .MemAdrM(MemAdrM), .WriteDataM(WriteDataM), .ReadDataM(ReadDataM), + .FlushDCacheM, // connected to ahb (all stay the same) .DCtoAHBPAdrM(DCtoAHBPAdrM), diff --git a/wally-pipelined/src/wally/wallypipelinedsoc.sv b/wally-pipelined/src/wally/wallypipelinedsoc.sv index c1ae3c02..a49d4cd6 100644 --- a/wally-pipelined/src/wally/wallypipelinedsoc.sv +++ b/wally-pipelined/src/wally/wallypipelinedsoc.sv @@ -50,10 +50,13 @@ module wallypipelinedsoc ( output logic HMASTLOCK, output logic HREADY, // I/O Interface - input logic [31:0] GPIOPinsIn, - output logic [31:0] GPIOPinsOut, GPIOPinsEn, - input logic UARTSin, - output logic UARTSout + input logic [31:0] GPIOPinsIn, + output logic [31:0] GPIOPinsOut, GPIOPinsEn, + input logic UARTSin, + output logic UARTSout, + output tri1 SDCCmd, + input logic [3:0] SDCDat, + output logic SDCCLK ); // to instruction memory *** remove later @@ -73,7 +76,15 @@ module wallypipelinedsoc ( logic [15:0] rd2; // bogus, delete when real multicycle fetch works logic [31:0] InstrF; logic HRESP; - + + logic SDCCmdOut; + logic SDCCmdOE; + logic SDCCmdIn; + logic [3:0] SDCDatIn; + + assign SDCCmd = SDCCmdOE ? SDCCmdOut : 1'bz; + assign SDCCmdIn = SDCCmd; + assign SDCDatIn = SDCDat; // when write supported this will be a tristate // instantiate processor and memories wallypipelinedhart hart(.*); diff --git a/wally-pipelined/testbench/common/sdModel.sv b/wally-pipelined/testbench/common/sdModel.sv new file mode 100644 index 00000000..52795dd0 --- /dev/null +++ b/wally-pipelined/testbench/common/sdModel.sv @@ -0,0 +1,1052 @@ +//`include "timescale.v" +//`timescale 1ps / 1ps +`include "sd_defines.h" +`define tTLH 10 //Clock rise time +`define tHL 10 //Clock fall time +`define tISU 6 //Input setup time +`define tIH 0 //Input hold time +`define tODL 14 //Output delay +`define DLY_TO_OUTP 47 //47 + +`define BLOCKSIZE 512 +`define MEMSIZE 24643590 // 2mb block +`define BLOCK_BUFFER_SIZE 1 +`define TIME_BUSY 63 + +`define PRG 7 +`define RCV 6 +`define DATAS 5 +`define TRAN 4 + +module sdModel + ( + input sdClk, + inout tri1 cmd, + inout tri1 [3:0] dat + ); + //parameter SD_FILE = "ramdisk2.hex"; + + reg oeCmd; + reg oeDat; + reg cmdOut; + reg [3:0] datOut; + reg [10:0] transf_cnt; + reg [10:0] BLOCK_WIDTH; + + reg [5:0] lastCMD; + reg cardIdentificationState; + reg CardTransferActive; + reg [2:0] BusWidth; + + assign cmd = oeCmd ? cmdOut : 1'bz; + assign dat = oeDat ? datOut : 4'bz; + + reg InbuffStatus; + reg [32:0] ByteAddr; + reg [7:0] Inbuff [0:511]; + reg [7:0] FLASHmem [logic[32:0]]; + reg [7:0] wide_data [0:63]; + + + + reg [46:0] inCmd; + reg [5:0] cmdRead; + reg [7:0] cmdWrite; + reg crcIn; + reg crcEn; + reg crcRst; + reg [31:0] CardStatus; + reg [15:0] RCA; + reg [31:0] OCR; + reg [120:0] CID; + reg [120:0] CSD; + reg Busy; //0 when busy + wire [6:0] crcOut; + reg [4:0] crc_c; + + reg [3:0] CurrentState; + reg [3:0] DataCurrentState; + +`define RCASTART 16'h2000 +`define OCRSTART 32'h40ff8000 // SDHC +`define STATUSSTART 32'h0 +`define CIDSTART 128'hffffffddddddddaaaaaaaa99999999 //Just some random data not really useful anyway +`define CSDSTART 128'hadaeeeddddddddaaaaaaaa12345678 + +`define outDelay 4 + reg [2:0] outDelayCnt; + reg [9:0] flash_write_cnt; + reg [8:0] flash_blockwrite_cnt; + + parameter SIZE = 10; + parameter CONTENT_SIZE = 40; + parameter + IDLE = 10'b0000_0000_01, + READ_CMD = 10'b0000_0000_10, + ANALYZE_CMD = 10'b0000_0001_00, + SEND_CMD = 10'b0000_0010_00; + reg [SIZE-1:0] state; + reg [SIZE-1:0] next_state; + + parameter + DATA_IDLE =10'b0000_0000_01, + READ_WAITS =10'b0000_0000_10, + READ_DATA =10'b0000_0001_00, + WRITE_FLASH =10'b0000_0010_00, + WRITE_DATA =10'b0000_0100_00; + parameter okcrctoken = 4'b0101; + parameter invalidcrctoken = 4'b1111; + reg [SIZE-1:0] dataState; + reg [SIZE-1:0] next_datastate; + + reg ValidCmd; + reg inValidCmd; + + reg [7:0] response_S; + reg [135:0] response_CMD; + integer responseType; + + reg [9:0] block_cnt; + reg wptr; + reg crc_ok; + reg [3:0] last_din; + + reg crcDat_rst; + reg mult_read; + reg mult_write; + reg crcDat_en; + reg [3:0] crcDat_in; + wire [15:0] crcDat_out [3:0]; + + genvar i; + generate + for(i=0; i<4; i=i+1) begin:CRC_16_gen + sd_crc_16 CRC_16_i (crcDat_in[i],crcDat_en, sdClk, crcDat_rst, crcDat_out[i]); + end + endgenerate + + sd_crc_7 crc_7 + ( + crcIn, + crcEn, + sdClk, + crcRst, + crcOut + ); + + reg stop; + + reg appendCrc; + reg [5:0] startUppCnt; + + reg q_start_bit; + + //Card initialization DAT contents + //initial $readmemh(SD_FILE, FLASHmem); + + initial begin + wide_data[0] <= 00; + wide_data[1] <= 20; + wide_data[2] <= 80; + wide_data[3] <= 01; + wide_data[4] <= 80; + wide_data[5] <= 01; + wide_data[6] <= 80; + wide_data[7] <= 01; + wide_data[8] <= 80; + wide_data[9] <= 01; + wide_data[10] <= 80; + wide_data[11] <= 01; + wide_data[12] <= 80; + wide_data[13] <= 03; + wide_data[14] <= 00; + wide_data[15] <= 00; + wide_data[16] <= 01; + wide_data[17] <= 00; + wide_data[18] <= 00; + wide_data[19] <= 00; + wide_data[20] <= 00; + wide_data[21] <= 00; + wide_data[22] <= 00; + wide_data[23] <= 00; + wide_data[24] <= 00; + wide_data[25] <= 00; + wide_data[26] <= 00; + wide_data[27] <= 00; + wide_data[28] <= 00; + wide_data[29] <= 00; + wide_data[30] <= 00; + wide_data[31] <= 00; + wide_data[32] <= 00; + wide_data[33] <= 00; + wide_data[34] <= 00; + wide_data[35] <= 00; + wide_data[36] <= 00; + wide_data[37] <= 00; + wide_data[38] <= 00; + wide_data[39] <= 00; + wide_data[40] <= 00; + wide_data[41] <= 00; + wide_data[42] <= 00; + wide_data[43] <= 00; + wide_data[44] <= 00; + wide_data[45] <= 00; + wide_data[46] <= 00; + wide_data[47] <= 00; + wide_data[48] <= 00; + wide_data[49] <= 00; + wide_data[50] <= 00; + wide_data[51] <= 00; + wide_data[52] <= 00; + wide_data[53] <= 00; + wide_data[54] <= 00; + wide_data[55] <= 00; + wide_data[56] <= 00; + wide_data[57] <= 00; + wide_data[58] <= 00; + wide_data[59] <= 00; + wide_data[60] <= 00; + wide_data[61] <= 00; + wide_data[62] <= 00; + wide_data[63] <= 00; + end + + + + integer k; + + reg qCmd; + reg [2:0] crcCnt; + + reg add_wrong_cmd_crc; + reg add_wrong_cmd_indx; + reg add_wrong_data_crc; + + initial begin + add_wrong_data_crc<=0; + add_wrong_cmd_indx<=0; + add_wrong_cmd_crc<=0; + stop<=1; + cardIdentificationState<=1; + state<=IDLE; + dataState<=DATA_IDLE; + Busy<=0; + oeCmd<=0; + crcCnt<=0; + CardTransferActive<=0; + qCmd<=1; + oeDat<=0; + cmdOut<=0; + cmdWrite<=0; + InbuffStatus<=0; + datOut<=0; + inCmd<=0; + BusWidth<=1; + responseType=0; + mult_read=0; + mult_write=0; + crcIn<=0; + response_S<=0; + crcEn<=0; + crcRst<=0; + cmdRead<=0; + ValidCmd<=0; + inValidCmd=0; + appendCrc<=0; + RCA<= `RCASTART; + OCR<= `OCRSTART; + CardStatus <= `STATUSSTART; + CID<=`CIDSTART; + CSD<=`CSDSTART; + response_CMD<=0; + outDelayCnt<=0; + crcDat_rst<=1; + crcDat_en<=0; + crcDat_in<=0; + transf_cnt<=0; + ByteAddr<=0; + block_cnt <=0; + wptr<=0; + transf_cnt<=0; + crcDat_rst<=1; + crcDat_en<=0; + crcDat_in<=0; + flash_write_cnt<=0; + startUppCnt<=0; + flash_blockwrite_cnt<=0; + end + + //CARD logic + + always @ (state or cmd or cmdRead or ValidCmd or inValidCmd or cmdWrite or outDelayCnt) + begin : FSM_COMBO + next_state = 0; + case(state) + IDLE: begin + if (!cmd) + next_state = READ_CMD; + else + next_state = IDLE; + end + READ_CMD: begin + if (cmdRead>= 47) + next_state = ANALYZE_CMD; + else + next_state = READ_CMD; + end + ANALYZE_CMD: begin + if ((ValidCmd ) && (outDelayCnt >= `outDelay )) // outDelayCnt >= 4 (NCR) + next_state = SEND_CMD; + else if (inValidCmd) + next_state = IDLE; + else + next_state = ANALYZE_CMD; + end + SEND_CMD: begin + if (cmdWrite>= response_S) + next_state = IDLE; + else + next_state = SEND_CMD; + + end + + + endcase + end + + always @ (dataState or CardStatus or crc_c or flash_write_cnt or dat[0] ) + begin : FSM_COMBODAT + next_datastate = 0; + case(dataState) + DATA_IDLE: begin + if ((CardStatus[12:9]==`RCV) || (mult_write == 1'b1) ) + next_datastate = READ_WAITS; + else if ((CardStatus[12:9]==`DATAS )|| (mult_read == 1'b1) ) + next_datastate = WRITE_DATA; + else + next_datastate = DATA_IDLE; + end + + READ_WAITS: begin + if ( dat[0] == 1'b0 ) + next_datastate = READ_DATA; + else + next_datastate = READ_WAITS; + end + + READ_DATA : begin + if (crc_c==0 ) + next_datastate = WRITE_FLASH; + else begin + if (stop == 1'b0) + next_datastate = READ_DATA; + else + next_datastate = DATA_IDLE; + end + + end + WRITE_FLASH : begin + if (flash_write_cnt>265 ) + next_datastate = DATA_IDLE; + else + next_datastate = WRITE_FLASH; + + end + + WRITE_DATA : begin + if (transf_cnt >= BLOCK_WIDTH) // transf_cnt >= 1044 + next_datastate= DATA_IDLE; + else + begin + if (stop == 1'b0) + next_datastate=WRITE_DATA; + else + next_datastate = DATA_IDLE; + end + end + + endcase + end + + always @ (posedge sdClk ) + begin + + q_start_bit <= dat[0]; + end + + always @ (posedge sdClk ) + begin : FSM_SEQ + state <= next_state; + end + + always @ (posedge sdClk ) + begin : FSM_SEQDAT + dataState <= next_datastate; + end + + always @ (posedge sdClk) begin + if (CardTransferActive) begin + if (InbuffStatus==0) //empty + CardStatus[8]<=1; + else + CardStatus[8]<=0; + end + else + CardStatus[8]<=1; + startUppCnt<=startUppCnt+1; + OCR[31]<=Busy; // THERE IS NO TILDA "OCR[31]<=~BUSY", BUSY is OCR[31] + if (startUppCnt == `TIME_BUSY) // startUppCnt == 63 (counts until ACMD41 valid) + Busy <=1; + end // always @ (posedge sdClk) + + + always @ (posedge sdClk) begin + qCmd<=cmd; + end + + //read data and cmd on rising edge + always @ (posedge sdClk) begin + case(state) + IDLE: begin + mult_write <= 0; + mult_read <=0; + crcIn<=0; + crcEn<=0; + crcRst<=1; + oeCmd<=0; + stop<=0; + cmdRead<=0; + appendCrc<=0; + ValidCmd<=0; + inValidCmd=0; + cmdWrite<=0; + crcCnt<=0; + response_CMD<=0; + response_S<=0; + outDelayCnt<=0; + responseType=0; + end // case: IDLE + + READ_CMD: begin //read cmd + crcEn<=1; + crcRst<=0; + crcIn <= #`tIH qCmd; // tIH 0 + inCmd[47-cmdRead] <= #`tIH qCmd; // tIH 0 + cmdRead <= #1 cmdRead+1; + if (cmdRead >= 40) + crcEn<=0; + + if (cmdRead == 46) begin + oeCmd<=1; + cmdOut<=1; + end + end // case: READ_CMD + + + ANALYZE_CMD: begin//check for valid cmd + //Wrong CRC go idle + if (inCmd[46] == 0) //start + inValidCmd=1; + else if (inCmd[7:1] != crcOut) begin + inValidCmd=1; + $fdisplay(sdModel_file_desc, "**sd_Model Command Packet - CRC Error") ; + $display(sdModel_file_desc, "**sd_Model Command Packet - CRC Error") ; + end + else if (inCmd[0] != 1) begin//stop + inValidCmd=1; + $fdisplay(sdModel_file_desc, "**sd_Model Command Packet - No Stop Bit Error") ; + $display(sdModel_file_desc, "**sd_Model Command Packet - No Stop Bit Error") ; + end + else begin + if(outDelayCnt ==0 ) + CardStatus[3]<=0; // AKE_SEQ_ERROR = no error in sequence of authentication process, until I say otherwise + case(inCmd[45:40]) + 0 : response_S <= 0; // GO_IDLE_STATE + 2 : response_S <= 136; //ALL_SEND_CARD_ID (CID) + 3 : response_S <= 48; //SEND_RELATIVE_CARD_ADDRESS (RCA) + 7 : response_S <= 48; // SELECT_CARD + 8 : response_S <= 48; // SEND_INTERFACE_CONDITION (IC) + 9 : response_S <= 136; // SEND_CARD_SPECIFIC_DATA (CSD) + 14 : response_S <= 0; // reserved (why is this even here?) + 16 : response_S <= 48; // SET_BLOCK_LENGTH (Does nothing for SDHC/SDXC) + 17 : response_S <= 48; // READ_SINGLE_BLOCK of data from card + 18 : response_S <= 48; // READ_MULTIPLE_BLOCKS of data from card + 24 : response_S <= 48; // WRITE_BLOCK of data to card + 25 : response_S <= 48; // WRITE_MULTIPLE_BLOCKS of data to card + 33 : response_S <= 48; // ERASE_WR_BLK_END + 55 : response_S <= 48; // APP_CMD + 41 : response_S <= 48; // CMD41 - SD_SEND_OCR + endcase // case (inCmd[45:40]) + + case(inCmd[45:40]) + 0 : begin // GO_IDLE_STATE + response_CMD <= 0; + cardIdentificationState<=1; + ResetCard; + end + 2 : begin //ALL_SEND_CARD_ID (CID) + if (lastCMD != 41 && outDelayCnt==0) begin + $fdisplay(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 2 in Start-up state") ; + //$display(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 2 in Start-up state") ; + CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process + end + response_CMD[127:8] <= CID; + appendCrc<=0; + CardStatus[12:9] <=2; + end + 3 : begin //SEND_RELATIVE_CARD_ADDRESS (RCA) + if (lastCMD != 2 && outDelayCnt==0 ) begin + $fdisplay(sdModel_file_desc, "**Error in sequence, CMD 2 should precede 3 in Start-up state") ; + //$display(sdModel_file_desc, "**Error in sequence, CMD 2 should precede 3 in Start-up state") ; + CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process + end + response_CMD[127:112] <= RCA[15:0] ; + response_CMD[111:96] <= CardStatus[15:0] ; + appendCrc<=1; + CardStatus[12:9] <=3; + cardIdentificationState<=0; + end + 6 : begin + if (lastCMD == 55 && outDelayCnt==0) begin //ACMD6 - SET_BUS_WIDTH + if (inCmd[9:8] == 2'b10) begin + BusWidth <=4; + $display(sdModel_file_desc, "**BUS WIDTH 4 ") ; + end + else + BusWidth <=1; + + response_S<=48; + response_CMD[127:96] <= CardStatus; + end + else if (outDelayCnt==0) begin //CMD6 - SWITCH_CARD_FUNCTION (Clock speed) + if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state + CardStatus[12:9] <=`DATAS;//Put card in data state + response_CMD[127:96] <= CardStatus ; + response_S<=48; + BLOCK_WIDTH <= 11'd148; + $fdisplay(sdModel_file_desc, "**Error Invalid CMD, %h",inCmd[45:40]); + $display(sdModel_file_desc, "**Error Invalid CMD, %h",inCmd[45:40]); + end + else begin + response_S <= 0; + response_CMD[127:96] <= 0; + $fdisplay(sdModel_file_desc, "**Error Invalid CMD, %h, card not in transfer state",inCmd[45:40]); + $display(sdModel_file_desc, "**Error Invalid CMD, %h, card not in transfer state",inCmd[45:40]); + end // else: !if(CardStatus[12:9] == `TRAN) + end // if (outDelayCnt==0) + end // case: 6 + + 7: begin // SELECT_CARD + if (outDelayCnt==0) begin + if (inCmd[39:24]== RCA[15:0]) begin + CardTransferActive <= 1; + response_CMD[127:96] <= CardStatus ; + CardStatus[12:9] <=`TRAN; + end + else begin + CardTransferActive <= 0; + response_CMD[127:96] <= CardStatus ; + CardStatus[12:9] <=3; + end + end + end // case: 7 + + + 8 : begin // SEND_INTERFACE_CONDITION (IC) + response_CMD[127:96] <= {20'h00000 , inCmd[19:8]}; //not supported by V1.0 card + response_S<=48; + + $fdisplay(sdModel_file_desc, "**Warning Unofficially Supported CMD, %h",inCmd[45:40]); + $display(sdModel_file_desc, "**Warning Unofficially Supported CMD, %h",inCmd[45:40]); + end + + 9 : begin // SEND_CARD_SPECIFIC_DATA (CSD) + if (lastCMD != 41 && outDelayCnt==0) begin + $fdisplay(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 9 in Start-up state") ; + //$display(sdModel_file_desc, "**Error in sequence, ACMD 41 should precede 9 in Start-up state") ; + CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process + end + response_CMD[127:8] <= CSD; + appendCrc<=0; + CardStatus[12:9] <=2; + end + + 12: begin // STOP_TRANSMISSION + response_CMD[127:96] <= CardStatus ; + stop<=1; + mult_write <= 0; + mult_read <=0; + CardStatus[12:9] <= `TRAN; + end + + 16 : begin // SET_BLOCK_LENGTH (Does nothing for SDHC/SDXC) + response_CMD[127:96] <= CardStatus ; + end + + 17 : begin // READ_SINGLE_BLOCK of data from card + if (outDelayCnt==0) begin + if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state + CardStatus[12:9] <=`DATAS;//Put card in data state + response_CMD[127:96] <= CardStatus ; + BLOCK_WIDTH <= 11'd1044; + + ByteAddr = inCmd[39:8] << 9; + if (ByteAddr%512 !=0) + $display("**Block Misalign Error"); + end + else begin + response_S <= 0; + response_CMD[127:96] <= 0; + end + end + end + + 18 : begin // READ_MULTIPLE_BLOCKS of data from card + if (outDelayCnt==0) begin + if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state + CardStatus[12:9] <=`DATAS;//Put card in data state + response_CMD[127:96] <= CardStatus ; + mult_read <= 1; + ByteAddr = inCmd[39:8] << 9; + if (ByteAddr%512 !=0) + $display("**Block Misalign Error"); + end + else begin + response_S <= 0; + response_CMD[127:96] <= 0; + end + end + end + + 24 : begin // WRITE_BLOCK of data to card + if (outDelayCnt==0) begin + if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state + if (CardStatus[8]) begin //If Free write buffer + CardStatus[12:9] <=`RCV;//Put card in Rcv state + response_CMD[127:96] <= CardStatus ; + ByteAddr = inCmd[39:8] << 9; + if (ByteAddr%512 !=0) + $display("**Block Misalign Error"); + end + else begin + response_CMD[127:96] <= CardStatus; + $fdisplay(sdModel_file_desc, "**Error Try to blockwrite when No Free Writebuffer") ; + $display("**Error Try to blockwrite when No Free Writebuffer") ; + end + end + else begin + response_S <= 0; + response_CMD[127:96] <= 0; + end + end + end // case: 24 + + 25 : begin // WRITE_MULTIPLE_BLOCKS of data to card + if (outDelayCnt==0) begin + if (CardStatus[12:9] == `TRAN) begin //If card is in transfer state + if (CardStatus[8]) begin //If Free write buffer + CardStatus[12:9] <=`RCV;//Put card in Rcv state + response_CMD[127:96] <= CardStatus ; + ByteAddr = inCmd[39:8] << 9; + mult_write <= 1; + if (ByteAddr%512 !=0) + $display("**Block Misalign Error"); + end + else begin + response_CMD[127:96] <= CardStatus; + $fdisplay(sdModel_file_desc, "**Error Try to blockwrite when No Free Writebuffer") ; + $display("**Error Try to blockwrite when No Free Writebuffer") ; + end // else: !if(CardStatus[8]) + end // if (CardStatus[12:9] == `TRAN) + else begin + response_S <= 0; + response_CMD[127:96] <= 0; + end // else: !if(CardStatus[12:9] == `TRAN) + end // if (outDelayCnt==0) + end // case: 25 + + 33 : response_CMD[127:96] <= 48; // ERASE_WR_BLK_END + + 55 : + begin // APP_CMD + response_CMD[127:96] <= CardStatus ; + CardStatus[5] <=1; //Next CMD is AP specific CMD + appendCrc<=1; + end + + 41 : // CMD41 - SD_SEND_OCR + begin + if (cardIdentificationState) begin + if (lastCMD != 55 && outDelayCnt==0) begin // CMD41 - Reserved/Invalid + $fdisplay(sdModel_file_desc, "**Error in sequence, CMD 55 should precede 41 in Start-up state") ; + $display( "**Error in sequence, CMD 55 should precede 41 in Start-up state") ; + CardStatus[3]<=1; // AKE_SEQ_ERROR = ERROR in sequence of authentication process + end + else begin // CMD41 - SD_SEND_OCR + responseType=3; + response_CMD[127:96] <= OCR; + appendCrc<=0; + CardStatus[5] <=0; // not expecting next command to be ACMD + if (Busy==1) + CardStatus[12:9] <=1; // READY + end // else: !if(lastCMD != 55 && outDelayCnt==0) + end // if (cardIdentificationState) + end // case: 41 + endcase // case (inCmd[45:40]) + + ValidCmd<=1; + crcIn<=0; + + outDelayCnt<=outDelayCnt+1; + if (outDelayCnt==`outDelay) // if (outDelayCnt == 4) + crcRst<=1; + + oeCmd<=1; + cmdOut<=1; + response_CMD[135:134] <=0; // Start bit = 0, tx bit = 0 (response from card) + + // for those who aren't keeping track, we are still in 'else: !if(inCmd[0] != 1)' + if (responseType != 3) + if (!add_wrong_cmd_indx) + response_CMD[133:128] <=inCmd[45:40]; + else + response_CMD[133:128] <=0; + + if (responseType == 3) + response_CMD[133:128] <=6'b111111; + + lastCMD <=inCmd[45:40]; + end // else: !if(inCmd[0] != 1) + end // case: ANALYZE_CMD + endcase // case (state) + end // always @ (posedge sdClk) + + always @ ( negedge sdClk) begin + case(state) + + SEND_CMD: begin + crcRst<=0; + crcEn<=1; + cmdWrite<=cmdWrite+1; + if (response_S!=0) + cmdOut<=0; + else + cmdOut<=1; + + if ((cmdWrite>0) && (cmdWrite < response_S-8)) begin + cmdOut<=response_CMD[135-cmdWrite]; + crcIn<=response_CMD[134-cmdWrite]; + if (cmdWrite >= response_S-9) + crcEn<=0; + end + else if (cmdWrite!=0) begin + crcEn<=0; + if (add_wrong_cmd_crc) begin + cmdOut<=0; + crcCnt<=crcCnt+1; + end + else begin + cmdOut<=crcOut[6-crcCnt]; + crcCnt<=crcCnt+1; + if (responseType == 3) + cmdOut<=1; + end + end // if (cmdWrite!=0) + if (cmdWrite == response_S-1) + cmdOut<=1; + end // case: SEND_CMD + endcase // case (state) + end // always @ ( negedge sdClk) + + integer outdly_cnt; + + always @ (posedge sdClk) begin // Read DATA from host on positive clock edge + + case (dataState) + DATA_IDLE: begin + + crcDat_rst<=1; + crcDat_en<=0; + crcDat_in<=0; + + end + + READ_WAITS: begin + oeDat<=0; + crcDat_rst<=0; + crcDat_en<=1; + crcDat_in<=0; + crc_c<=15;// + crc_ok<=1; + end + + READ_DATA: begin + + InbuffStatus<=1; + if (transf_cnt<`BIT_BLOCK_REC) begin + if (wptr) + Inbuff[block_cnt][3:0] <= dat; + else + Inbuff[block_cnt][7:4] <= dat; + + if (!add_wrong_data_crc) + crcDat_in<=dat; + else + crcDat_in<=4'b1010; + + crc_ok<=1; + transf_cnt<=transf_cnt+1; + if (wptr) + block_cnt<=block_cnt+1; + wptr<=~wptr; + end // if (transf_cnt<`BIT_BLOCK_REC) + + else if ( transf_cnt <= (`BIT_BLOCK_REC +`BIT_CRC_CYCLE-1)) begin + transf_cnt<=transf_cnt+1; + crcDat_en<=0; + last_din <=dat; + + if (transf_cnt> `BIT_BLOCK_REC) begin + crc_c<=crc_c-1; + + if (crcDat_out[0][crc_c] != last_din[0]) + crc_ok<=0; + if (crcDat_out[1][crc_c] != last_din[1]) + crc_ok<=0; + if (crcDat_out[2][crc_c] != last_din[2]) + crc_ok<=0; + if (crcDat_out[3][crc_c] != last_din[3]) + crc_ok<=0; + end // if (transf_cnt> `BIT_BLOCK_REC) + end // if ( transf_cnt <= (`BIT_BLOCK_REC +`BIT_CRC_CYCLE-1)) + end // case: READ_DATA + + WRITE_FLASH: begin + oeDat<=1; + block_cnt <=0; + wptr<=0; + transf_cnt<=0; + crcDat_rst<=1; + crcDat_en<=0; + crcDat_in<=0; + end + + endcase // case (dataState) + + end // always @ (posedge sdClk) + + reg data_send_index; + integer write_out_index; + always @ (negedge sdClk) begin // Write DATA to Host on negative clock edge + + case (dataState) + DATA_IDLE: begin + write_out_index<=0; + transf_cnt<=0; + data_send_index<=0; + outdly_cnt<=0; + flash_write_cnt<=0; + end + + WRITE_DATA: begin + oeDat<=1; + outdly_cnt<=outdly_cnt+1; + datOut <= 4'b1111; // listen... until I tell you otherwise, DAT bus is all high (thanks Ross) + + + if ( outdly_cnt > `DLY_TO_OUTP) begin // if (outdly_cnt > 47) NAC cycles elapsed + transf_cnt <= transf_cnt+1; // start counting bits transferred + crcDat_en<=1; // Enable CRC16 + crcDat_rst<=0; // Stop reset of CRC16 + oeDat<=1; // Enable output + end + + else begin // NAC cycles have not elapsed + crcDat_en<=0; // Disable CRC16 generation + crcDat_rst<=1; // Reset CRC16 generators + oeDat<=0; // Do NOT enable output (I REALLY DO AGREE WITH THIS!) + crc_c<=16; // point to bit 16 of CRC16 + end // else: !if( outdly_cnt > `DLY_TO_OUTP) + + if (transf_cnt==1) begin // first nibble + if (BLOCK_WIDTH == 11'd1044) begin + last_din <= FLASHmem[ByteAddr+(write_out_index)][7:4]; // LOAD register with upper nibble + crcDat_in<= FLASHmem[ByteAddr+(write_out_index)][7:4]; // LOAD CRC16 with upper nibble + end + else begin + // code for wide width data + last_din <= wide_data[write_out_index][7:4]; + crcDat_in <= wide_data[write_out_index][7:4]; + end + datOut<=0; // Send nothing yet + data_send_index<=1; // Next nibble is lower nibble + end + + else if ( (transf_cnt>=2) && (transf_cnt<=BLOCK_WIDTH -`CRC_OFF )) begin // if (2 <= transf_cnt <= 1025) + data_send_index<=~data_send_index; //toggle + if (!data_send_index) begin //upper nibble + if (BLOCK_WIDTH == 11'd1044) begin + last_din <= FLASHmem[ByteAddr+(write_out_index)][7:4]; // LOAD register with upper nibble + crcDat_in<= FLASHmem[ByteAddr+(write_out_index)][7:4]; // LOAD CRC16 with upper nibble + end + else begin + // code for wide width data + last_din <= wide_data[write_out_index][7:4]; + crcDat_in <= wide_data[write_out_index][7:4]; + end + end // if (!data_send_index) + else begin //lower nibble + if (BLOCK_WIDTH == 11'd1044) begin + last_din<=FLASHmem[ByteAddr+(write_out_index)][3:0]; + end + else begin + last_din <= wide_data[write_out_index][3:0]; + end + if (!add_wrong_data_crc) + if (BLOCK_WIDTH == 11'd1044) begin + crcDat_in<= FLASHmem[ByteAddr+(write_out_index)][3:0]; + end + else begin + crcDat_in <= wide_data[write_out_index][3:0]; + end + else // SNAFU + crcDat_in<=4'b1010; + write_out_index<=write_out_index+1; // Having sent the lower nibble, increment the byte counter + + end // else: !if(!data_send_index) + + datOut<= last_din; // output content of register + + + if ( transf_cnt >=BLOCK_WIDTH-`CRC_OFF ) begin // if (trans_cnt >= 1025) + crcDat_en<=0; // Disable CRC16 Generators + end + end // if ( (transf_cnt>=2) && (transf_cnt<=`BIT_BLOCK-`CRC_OFF )) + + else if (transf_cnt>BLOCK_WIDTH-`CRC_OFF & crc_c!=0) begin // if ((transf_cnt > 1025) and (crc_c /= 0)) + datOut<= last_din; // if sent all data bitsbut not crc16 bits yet + crcDat_en<=0; // Disable CRC16 generators + crc_c<=crc_c-1; // point to next bit of CRC16 to begin transmission of CRC16 + if (crc_c<= 16) begin // begin sending CRC16 (16 downto 1) + datOut[0]<=crcDat_out[0][crc_c-1]; + datOut[1]<=crcDat_out[1][crc_c-1]; + datOut[2]<=crcDat_out[2][crc_c-1]; + datOut[3]<=crcDat_out[3][crc_c-1]; + end + + end // if (transf_cnt>`BIT_BLOCK-`CRC_OFF & crc_c!=0) + else if (transf_cnt==BLOCK_WIDTH-2) begin // if (transf_cnt = 1042) Last CRC16 bit is 1041 + datOut<=4'b1111; // send end bits + end + else if ((transf_cnt !=0) && (crc_c == 0 ))begin // if sent data bits and crc_c points past last bit of CRC + oeDat<=0; // disable output on DAT bus + CardStatus[12:9] <= `TRAN; // put card in transfer state + end + + end // case: WRITE_DATA + + + WRITE_FLASH: begin + flash_write_cnt<=flash_write_cnt+1; + CardStatus[12:9] <= `PRG; + datOut[0]<=0; + datOut[1]<=1; + datOut[2]<=1; + datOut[3]<=1; + if (flash_write_cnt == 0) + datOut<=1; + else if(flash_write_cnt == 1) + datOut[0]<=1; + else if(flash_write_cnt == 2) + datOut[0]<=0; + + else if ((flash_write_cnt > 2) && (flash_write_cnt < 7)) begin + if (crc_ok) + datOut[0] <=okcrctoken[6-flash_write_cnt]; + else + datOut[0] <= invalidcrctoken[6-flash_write_cnt]; + + end + else if ((flash_write_cnt >= 7) && (flash_write_cnt < 264)) begin + datOut[0]<=0; + + flash_blockwrite_cnt<=flash_blockwrite_cnt+2; + FLASHmem[ByteAddr+(flash_blockwrite_cnt)]=Inbuff[flash_blockwrite_cnt]; + FLASHmem[ByteAddr+(flash_blockwrite_cnt+1)]=Inbuff[flash_blockwrite_cnt+1]; + end + + else begin + datOut<=1; + InbuffStatus<=0; + CardStatus[12:9] <= `TRAN; + end // else: !if((flash_write_cnt >= 7) && (flash_write_cnt < 264)) + end // case: WRITE_FLASH + endcase // case (dataState) + end // always @ (negedge sdClk) + + integer sdModel_file_desc; + + initial + begin + sdModel_file_desc = $fopen("sd_model.log"); + if (sdModel_file_desc < 2) + begin + $display("*E Could not open/create testbench log file in /log/ directory!"); + $finish; + end + end + + task ResetCard; // MAC registers + begin + add_wrong_data_crc<=0; + add_wrong_cmd_indx<=0; + add_wrong_cmd_crc<=0; + cardIdentificationState<=1; + state<=IDLE; + dataState<=DATA_IDLE; + Busy<=0; + oeCmd<=0; + crcCnt<=0; + CardTransferActive<=0; + qCmd<=1; + oeDat<=0; + cmdOut<=0; + cmdWrite<=0; + startUppCnt<=0; + InbuffStatus<=0; + datOut<=0; + inCmd<=0; + BusWidth<=1; + responseType=0; + crcIn<=0; + response_S<=0; + crcEn<=0; + crcRst<=0; + cmdRead<=0; + ValidCmd<=0; + inValidCmd=0; + appendCrc<=0; + RCA<= `RCASTART; + OCR<= `OCRSTART; + CardStatus <= `STATUSSTART; + CID<=`CIDSTART; + CSD<=`CSDSTART; + response_CMD<=0; + outDelayCnt<=0; + crcDat_rst<=1; + crcDat_en<=0; + crcDat_in<=0; + transf_cnt<=0; + ByteAddr<=0; + block_cnt <=0; + wptr<=0; + transf_cnt<=0; + crcDat_rst<=1; + crcDat_en<=0; + crcDat_in<=0; + flash_write_cnt<=0; + flash_blockwrite_cnt<=0; + end + endtask + +endmodule // sdModel diff --git a/wally-pipelined/testbench/common/sd_crc_16.sv b/wally-pipelined/testbench/common/sd_crc_16.sv new file mode 100644 index 00000000..c7a02bf3 --- /dev/null +++ b/wally-pipelined/testbench/common/sd_crc_16.sv @@ -0,0 +1,48 @@ +// ========================================================================== +// CRC Generation Unit - Linear Feedback Shift Register implementation +// (c) Kay Gorontzi, GHSi.de, distributed under the terms of LGPL +// https://www.ghsi.de/CRC/index.php? + +// https://www.ghsi.de/CRC/index.php? +// ========================================================================= +module sd_crc_16(BITVAL, Enable, CLK, RST, CRC); + input BITVAL;// Next input bit + input Enable; + input CLK; // Current bit valid (Clock) + input RST; // Init CRC value + output reg [15:0] CRC; // Current output CRC value + + + // We need output registers + wire inv; + + assign inv = BITVAL ^ CRC[15]; // XOR required? + + always @(posedge CLK or posedge RST) begin + if (RST) begin + CRC = 0; + + end + else begin + if (Enable==1) begin + CRC[15] = CRC[14]; + CRC[14] = CRC[13]; + CRC[13] = CRC[12]; + CRC[12] = CRC[11] ^ inv; + CRC[11] = CRC[10]; + CRC[10] = CRC[9]; + CRC[9] = CRC[8]; + CRC[8] = CRC[7]; + CRC[7] = CRC[6]; + CRC[6] = CRC[5]; + CRC[5] = CRC[4] ^ inv; + CRC[4] = CRC[3]; + CRC[3] = CRC[2]; + CRC[2] = CRC[1]; + CRC[1] = CRC[0]; + CRC[0] = inv; + end + end + end + +endmodule diff --git a/wally-pipelined/testbench/common/sd_crc_7.sv b/wally-pipelined/testbench/common/sd_crc_7.sv new file mode 100644 index 00000000..352e6af6 --- /dev/null +++ b/wally-pipelined/testbench/common/sd_crc_7.sv @@ -0,0 +1,34 @@ +module sd_crc_7(BITVAL, Enable, CLK, RST, CRC); + input BITVAL;// Next input bit + input Enable; + input CLK; // Current bit valid (Clock) + input RST; // Init CRC value + output [6:0] CRC; // Current output CRC value + + reg [6:0] CRC; + // We need output registers + wire inv; + + assign inv = BITVAL ^ CRC[6]; // XOR required? + + + always @(posedge CLK or posedge RST) begin + if (RST) begin + CRC = 0; + + end + else begin + if (Enable==1) begin + CRC[6] = CRC[5]; + CRC[5] = CRC[4]; + CRC[4] = CRC[3]; + CRC[3] = CRC[2] ^ inv; + CRC[2] = CRC[1]; + CRC[1] = CRC[0]; + CRC[0] = inv; + end + end + end + +endmodule + diff --git a/wally-pipelined/testbench/common/sd_defines.h b/wally-pipelined/testbench/common/sd_defines.h new file mode 100644 index 00000000..9421fa5c --- /dev/null +++ b/wally-pipelined/testbench/common/sd_defines.h @@ -0,0 +1,89 @@ +//Read the documentation before changing values + +`define BIG_ENDIAN +//`define LITLE_ENDIAN + +`define SIM +//`define SYN + +`define SDC_IRQ_ENABLE + +`define ACTEL + +//`define CUSTOM +//`define ALTERA +//`define XLINX +//`define SIMULATOR + +`define RESEND_MAX_CNT 3 + +//MAX 255 BD +//BD size/4 + +`ifdef ACTEL + `define BD_WIDTH 5 + `define BD_SIZE 32 + `define RAM_MEM_WIDTH_16 + `define RAM_MEM_WIDTH 16 + +`endif + +//`ifdef CUSTOM + // `define NR_O_BD_4 +// `define BD_WIDTH 5 +// `define BD_SIZE 32 +// `define RAM_MEM_WIDTH_32 +// `define RAM_MEM_WIDTH 32 +//`endif + + + +`ifdef SYN + `define RESET_CLK_DIV 0 + `define MEM_OFFSET 4 +`endif + +`ifdef SIM + `define RESET_CLK_DIV 0 + `define MEM_OFFSET 4 +`endif + +//SD-Clock Defines --------- +//Use bus clock or a seperate clock +`define SDC_CLK_BUS_CLK +//`define SDC_CLK_SEP + +// Use of internal clock divider +//`define SDC_CLK_STATIC +`define SDC_CLK_DYNAMIC + + +//SD DATA-transfer defines--- +`define BLOCK_SIZE 512 +`define SD_BUS_WIDTH_4 +`define SD_BUS_W 4 + +//at 512 bytes per block, equal 1024 4 bytes writings with a bus width of 4, add 2 for startbit and Z bit. +//Add 18 for crc, endbit and z. +`define BIT_BLOCK 1044 +`define CRC_OFF 19 +`define BIT_BLOCK_REC 1024 +`define BIT_CRC_CYCLE 16 + + +//FIFO defines--------------- +`define FIFO_RX_MEM_DEPTH 8 +`define FIFO_RX_MEM_ADR_SIZE 4 + +`define FIFO_TX_MEM_DEPTH 8 +`define FIFO_TX_MEM_ADR_SIZE 4 +//--------------------------- + + + + + + + + + diff --git a/wally-pipelined/testbench/testbench-arch.sv b/wally-pipelined/testbench/testbench-arch.sv index 93d98175..b32cc4a4 100644 --- a/wally-pipelined/testbench/testbench-arch.sv +++ b/wally-pipelined/testbench/testbench-arch.sv @@ -288,48 +288,47 @@ string tests32f[] = '{ }; string tests32priv[] = '{ - "rv32i_m/privilege/ebreak", "2090", - "rv32i_m/privilege/ecall", "2090", - "rv32i_m/privilege/misalign-beq-01", "20a0", - "rv32i_m/privilege/misalign-bge-01", "20a0", - "rv32i_m/privilege/misalign-bgeu-01", "20a0", - "rv32i_m/privilege/misalign-blt-01", "20a0", - "rv32i_m/privilege/misalign-bltu-01", "20a0", - "rv32i_m/privilege/misalign-bne-01", "20a0", - "rv32i_m/privilege/misalign-jal-01", "20a0", - "rv32i_m/privilege/misalign-lh-01", "20a0", - "rv32i_m/privilege/misalign-lhu-01", "20a0", - "rv32i_m/privilege/misalign-lw-01", "20a0", - "rv32i_m/privilege/misalign-lwu-01", "20a0", - "rv32i_m/privilege/misalign-sh-01", "20a0", - "rv32i_m/privilege/misalign-sw-01", "20a0", - "rv32i_m/privilege/misalign1-jalr-01", "20a0", - "rv32i_m/privilege/misalign2-jalr-01", "20a0" + "rv32i_m/privilege/ebreak", "2070", + "rv32i_m/privilege/ecall", "2070", + "rv32i_m/privilege/misalign-beq-01", "2080", + "rv32i_m/privilege/misalign-bge-01", "2080", + "rv32i_m/privilege/misalign-bgeu-01", "2080", + "rv32i_m/privilege/misalign-blt-01", "2080", + "rv32i_m/privilege/misalign-bltu-01", "2080", + "rv32i_m/privilege/misalign-bne-01", "2080", + "rv32i_m/privilege/misalign-jal-01", "2080", + "rv32i_m/privilege/misalign-lh-01", "2080", + "rv32i_m/privilege/misalign-lhu-01", "2080", + "rv32i_m/privilege/misalign-lw-01", "2080", + "rv32i_m/privilege/misalign-sh-01", "2080", + "rv32i_m/privilege/misalign-sw-01", "2080", + "rv32i_m/privilege/misalign1-jalr-01", "2080", + "rv32i_m/privilege/misalign2-jalr-01", "2080" }; string tests32m[] = '{ - "rv32i_m/M/div-01", "9010", - "rv32i_m/M/divu-01", "a010", - "rv32i_m/M/mul-01", "9010", - "rv32i_m/M/mulh-01", "9010", - "rv32i_m/M/mulhsu-01", "9010", - "rv32i_m/M/mulhu-01", "a010", - "rv32i_m/M/rem-01", "9010", - "rv32i_m/M/remu-01", "a010", + "rv32i_m/M/div-01", "5010", + "rv32i_m/M/divu-01", "5010", + "rv32i_m/M/mul-01", "5010", + "rv32i_m/M/mulh-01", "5010", + "rv32i_m/M/mulhsu-01", "5010", + "rv32i_m/M/mulhu-01", "5010", + "rv32i_m/M/rem-01", "5010", + "rv32i_m/M/remu-01", "5010" }; string tests32ic[] = '{ - "rv32i_m/C/cadd-01", "8010", - "rv32i_m/C/caddi-01", "4010", + "rv32i_m/C/cadd-01", "4010", + "rv32i_m/C/caddi-01", "3010", "rv32i_m/C/caddi16sp-01", "2010", "rv32i_m/C/caddi4spn-01", "2010", - "rv32i_m/C/cand-01", "8010", - "rv32i_m/C/candi-01", "4010", - "rv32i_m/C/cbeqz-01", "4010", - "rv32i_m/C/cbnez-01", "5010", - "rv32i_m/C/cebreak-01", "2070", + "rv32i_m/C/cand-01", "4010", + "rv32i_m/C/candi-01", "3010", + "rv32i_m/C/cbeqz-01", "3010", + "rv32i_m/C/cbnez-01", "3010", + "rv32i_m/C/cebreak-01", "2050", "rv32i_m/C/cj-01", "3010", - "rv32i_m/C/cjal-01", "", + "rv32i_m/C/cjal-01", "3010", "rv32i_m/C/cjalr-01", "2010", "rv32i_m/C/cjr-01", "2010", "rv32i_m/C/cli-01", "2010", @@ -338,30 +337,30 @@ string tests32f[] = '{ "rv32i_m/C/clwsp-01", "2010", "rv32i_m/C/cmv-01", "2010", "rv32i_m/C/cnop-01", "2010", - "rv32i_m/C/cor-01", "8010", + "rv32i_m/C/cor-01", "4010", "rv32i_m/C/cslli-01", "2010", "rv32i_m/C/csrai-01", "2010", "rv32i_m/C/csrli-01", "2010", - "rv32i_m/C/csub-01", "8010", - "rv32i_m/C/csw-01", "3010", - "rv32i_m/C/cswsp-01", "3010", - "rv32i_m/C/cxor-01", "8010" + "rv32i_m/C/csub-01", "4010", + "rv32i_m/C/csw-01", "2010", + "rv32i_m/C/cswsp-01", "2010", + "rv32i_m/C/cxor-01", "4010" }; string tests32i[] = '{ - "rv32i_m/I/add-01", "9010", - "rv32i_m/I/addi-01", "6010", - "rv32i_m/I/and-01", "9010", - "rv32i_m/I/andi-01", "6010", + "rv32i_m/I/add-01", "5010", + "rv32i_m/I/addi-01", "4010", + "rv32i_m/I/and-01", "5010", + "rv32i_m/I/andi-01", "4010", "rv32i_m/I/auipc-01", "2010", - "rv32i_m/I/beq-01", "47010", - "rv32i_m/I/bge-01", "47010", - "rv32i_m/I/bgeu-01", "56010", - "rv32i_m/I/blt-01", "4d010", - "rv32i_m/I/bltu-01", "57010", - "rv32i_m/I/bne-01", "43010", + "rv32i_m/I/beq-01", "39010", + "rv32i_m/I/bge-01", "3a010", + "rv32i_m/I/bgeu-01", "4a010", + "rv32i_m/I/blt-01", "38010", + "rv32i_m/I/bltu-01", "4b010", + "rv32i_m/I/bne-01", "39010", "rv32i_m/I/fence-01", "2010", - "rv32i_m/I/jal-01", "122010", + "rv32i_m/I/jal-01", "1ad010", "rv32i_m/I/jalr-01", "2010", "rv32i_m/I/lb-align-01", "2010", "rv32i_m/I/lbu-align-01", "2010", @@ -369,24 +368,24 @@ string tests32f[] = '{ "rv32i_m/I/lhu-align-01", "2010", "rv32i_m/I/lui-01", "2010", "rv32i_m/I/lw-align-01", "2010", - "rv32i_m/I/or-01", "9010", - "rv32i_m/I/ori-01", "6010", - "rv32i_m/I/sb-align-01", "3010", - "rv32i_m/I/sh-align-01", "3010", - "rv32i_m/I/sll-01", "3010", + "rv32i_m/I/or-01", "5010", + "rv32i_m/I/ori-01", "4010", + "rv32i_m/I/sb-align-01", "2010", + "rv32i_m/I/sh-align-01", "2010", + "rv32i_m/I/sll-01", "2010", "rv32i_m/I/slli-01", "2010", - "rv32i_m/I/slt-01", "9010", - "rv32i_m/I/slti-01", "6010", - "rv32i_m/I/sltiu-01", "6010", - "rv32i_m/I/sltu-01", "a010", - "rv32i_m/I/sra-01", "3010", + "rv32i_m/I/slt-01", "5010", + "rv32i_m/I/slti-01", "4010", + "rv32i_m/I/sltiu-01", "4010", + "rv32i_m/I/sltu-01", "5010", + "rv32i_m/I/sra-01", "2010", "rv32i_m/I/srai-01", "2010", - "rv32i_m/I/srl-01", "3010", + "rv32i_m/I/srl-01", "2010", "rv32i_m/I/srli-01", "2010", - "rv32i_m/I/sub-01", "9010", - "rv32i_m/I/sw-align-01", "3010", - "rv32i_m/I/xor-01", "9010", - "rv32i_m/I/xori-01", "6010" + "rv32i_m/I/sub-01", "5010", + "rv32i_m/I/sw-align-01", "2010", + "rv32i_m/I/xor-01", "5010", + "rv32i_m/I/xori-01", "4010" }; string tests[]; @@ -417,13 +416,15 @@ string tests32f[] = '{ initial begin if (`XLEN == 64) begin // RV64 if (`TESTSBP) begin - tests = testsBP64; + //tests = testsBP64; // testsbp should not run the other tests. It starts at address 0 rather than // 0x8000_0000, the next if must remain an else if. end else if (TESTSPERIPH) - tests = tests64periph; + //tests = tests64periph; + tests = {}; else if (TESTSPRIV) - tests = tests64p; + //tests = tests64p; + tests = {}; else begin tests = {tests64priv, tests64i}; // tests = {tests64p,tests64i, tests64periph}; @@ -439,17 +440,25 @@ string tests32f[] = '{ end else begin // RV32 // *** add the 32 bit bp tests if (TESTSPERIPH) - tests = tests32periph; + //tests = tests32periph; + tests = {}; else if (TESTSPRIV) - tests = tests32p; + //tests = tests32p; + tests = {}; else begin - tests = {tests32i, tests32p};//,tests32periph}; *** broken at the moment + tests = {tests32priv, tests32i}; + //tests = {tests32i, tests32priv}; + if (`C_SUPPORTED) tests = {tests, tests32ic}; + if (`M_SUPPORTED) tests = {tests, tests32m}; + //if (`C_SUPPORTED) tests = {tests32ic, tests}; + //if (`M_SUPPORTED) tests = {tests32m, tests}; +/* tests = {tests32i, tests32p};//,tests32periph}; *** broken at the moment if (`C_SUPPORTED % 2 == 1) tests = {tests, tests32ic}; else tests = {tests, tests32iNOc}; if (`M_SUPPORTED % 2 == 1) tests = {tests, tests32m}; if (`F_SUPPORTED) tests = {tests32f, tests}; if (`MEM_VIRTMEM) tests = {tests32mmu, tests}; - if (`A_SUPPORTED) tests = {tests32a, tests}; + if (`A_SUPPORTED) tests = {tests32a, tests}; */ end end end @@ -458,6 +467,12 @@ string tests32f[] = '{ logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout; + logic SDCCLK; + tri1 SDCCmd; + tri1 [3:0] SDCDat; + + assign SDCmd = 1'bz; + assign SDCDat = 4'bz; // instantiate device to be tested assign GPIOPinsIn = 0; diff --git a/wally-pipelined/testbench/testbench-coremark.sv b/wally-pipelined/testbench/testbench-coremark.sv index 82a41d83..2feccab5 100644 --- a/wally-pipelined/testbench/testbench-coremark.sv +++ b/wally-pipelined/testbench/testbench-coremark.sv @@ -52,6 +52,12 @@ module testbench(); string signame, memfilename; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout; + logic SDCCLK; + tri1 SDCCmd; + tri1 [3:0] SDCDat; + + assign SDCmd = 1'bz; + assign SDCDat = 4'bz; // instantiate device to be tested assign GPIOPinsIn = 0; assign UARTSin = 1; diff --git a/wally-pipelined/testbench/testbench-coremark_bare.sv b/wally-pipelined/testbench/testbench-coremark_bare.sv index 90003e98..71fb52be 100644 --- a/wally-pipelined/testbench/testbench-coremark_bare.sv +++ b/wally-pipelined/testbench/testbench-coremark_bare.sv @@ -52,6 +52,14 @@ module testbench(); string signame, memfilename; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout; + logic SDCCLK; + tri1 SDCCmd; + tri1 [3:0] SDCDat; + + assign SDCmd = 1'bz; + assign SDCDat = 4'bz; + + // instantiate device to be tested assign GPIOPinsIn = 0; assign UARTSin = 1; diff --git a/wally-pipelined/testbench/testbench-fpga.sv b/wally-pipelined/testbench/testbench-fpga.sv index fbe13cf4..f7c80412 100644 --- a/wally-pipelined/testbench/testbench-fpga.sv +++ b/wally-pipelined/testbench/testbench-fpga.sv @@ -564,11 +564,20 @@ string tests32f[] = '{ end end - string signame, memfilename, romfilename; + string signame, memfilename, romfilename, sdcfilename; logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout; + logic SDCCLK; + tri1 SDCCmd; + tri1 [3:0] SDCDat; + + sdModel sdcard + (.sdClk(SDCCLK), + .cmd(SDCCmd), + .dat(SDCDat)); + // instantiate device to be tested assign GPIOPinsIn = 0; assign UARTSin = 1; @@ -612,11 +621,13 @@ string tests32f[] = '{ -----/\----- EXCLUDED -----/\----- */ // read test vectors into memory memfilename = {"../../imperas-riscv-tests/work/", tests[test], ".elf.memfile"}; - romfilename = {"../../imperas-riscv-tests/work/rv64BP/blink-led.memfile"}; + romfilename = {"../../imperas-riscv-tests/work/rv64BP/fpga-test-sdc.memfile"}; + sdcfilename = {"../src/sdc/tb/ramdisk2.hex"}; $readmemh(memfilename, dut.uncore.dtim.RAM); $readmemh(romfilename, dut.uncore.bootdtim.bootdtim.RAM); - ProgramAddrMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.addr"}; - ProgramLabelMapFile = {"../../imperas-riscv-tests/work/", tests[test], ".elf.objdump.lab"}; + $readmemh(sdcfilename, sdcard.FLASHmem); + ProgramAddrMapFile = {"../../imperas-riscv-tests/work/rv64BP/fpga-test-sdc.objdump.addr"}; + ProgramLabelMapFile = {"../../imperas-riscv-tests/work/rv64BP/fpga-test-sdc.objdump.lab"}; $display("Read memfile %s", memfilename); reset = 1; # 42; reset = 0; end diff --git a/wally-pipelined/testbench/testbench-imperas.sv b/wally-pipelined/testbench/testbench-imperas.sv index 31814076..c312ef0a 100644 --- a/wally-pipelined/testbench/testbench-imperas.sv +++ b/wally-pipelined/testbench/testbench-imperas.sv @@ -566,6 +566,10 @@ string tests32f[] = '{ logic [31:0] GPIOPinsIn, GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout; + logic SDCCLK; + tri1 SDCCmd; + tri1 [3:0] SDCDat; + // instantiate device to be tested assign GPIOPinsIn = 0; assign UARTSin = 1; @@ -582,6 +586,18 @@ string tests32f[] = '{ dut.hart.ifu.InstrM, dut.hart.ifu.InstrW, InstrFName, InstrDName, InstrEName, InstrMName, InstrWName); + // SD card model + + assign SDCmd = 1'bz; + assign SDCDat = 4'bz; +/* -----\/----- EXCLUDED -----\/----- + sdModel sdcard + (.sdClk(SDCCLK), + .cmd(SDCCmd), + .dat(SDCDat)); + -----/\----- EXCLUDED -----/\----- */ + + // initialize tests localparam integer MemStartAddr = `TIM_BASE>>(1+`XLEN/32); localparam integer MemEndAddr = (`TIM_RANGE+`TIM_BASE)>>1+(`XLEN/32); diff --git a/wally-pipelined/testbench/testbench-linux.sv b/wally-pipelined/testbench/testbench-linux.sv index 40e0e75c..c090ad93 100644 --- a/wally-pipelined/testbench/testbench-linux.sv +++ b/wally-pipelined/testbench/testbench-linux.sv @@ -55,6 +55,14 @@ module testbench(); logic [31:0] GPIOPinsIn; logic [31:0] GPIOPinsOut, GPIOPinsEn; logic UARTSin, UARTSout; + + logic SDCCLK; + tri1 SDCCmd; + tri1 [3:0] SDCDat; + + assign SDCmd = 1'bz; + assign SDCDat = 4'bz; + assign GPIOPinsIn = 0; assign UARTSin = 1; @@ -363,38 +371,40 @@ module testbench(); InstrCountW += 1; // turn on waves at certain point if (InstrCountW == waveOnICount) $stop; + // print progress message + if (InstrCountW % 'd100000 == 0) $display("Reached %d instructions", InstrCountW); // check PCW fault = 0; if(PCW != ExpectedPCW) begin - $display("PCW: %016x does not equal ExpectedPCW: %016x", PCW, ExpectedPCW); - fault = 1; + $display("PCW: %016x does not equal ExpectedPCW: %016x", PCW, ExpectedPCW); + fault = 1; end // check instruction value if(dut.hart.ifu.InstrW != ExpectedInstrW) begin - $display("InstrW: %x does not equal ExpectedInstrW: %x", dut.hart.ifu.InstrW, ExpectedInstrW); - fault = 1; + $display("InstrW: %x does not equal ExpectedInstrW: %x", dut.hart.ifu.InstrW, ExpectedInstrW); + fault = 1; end // check the number of instructions if(dut.hart.priv.csr.genblk1.counters.genblk1.INSTRET_REGW != InstrCountW) begin - $display("%t, Number of instruction Retired = %d does not equal number of instructions in trace = %d", $time, dut.hart.priv.csr.genblk1.counters.genblk1.INSTRET_REGW, InstrCountW); - if(!`DontHaltOnCSRMisMatch) fault = 1; + $display("%t, Number of instruction Retired = %d does not equal number of instructions in trace = %d", $time, dut.hart.priv.csr.genblk1.counters.genblk1.INSTRET_REGW, InstrCountW); + if(!`DontHaltOnCSRMisMatch) fault = 1; end #2; // delay 2 ns. if(`DEBUG_TRACE > 2) begin - $display("Reg Write Address: %02d ? expected value: %02d", dut.hart.ieu.dp.regf.a3, ExpectedRegAdrW); - $display("RF[%02d]: %016x ? expected value: %016x", ExpectedRegAdrW, dut.hart.ieu.dp.regf.rf[ExpectedRegAdrW], ExpectedRegValueW); + $display("Reg Write Address: %02d ? expected value: %02d", dut.hart.ieu.dp.regf.a3, ExpectedRegAdrW); + $display("RF[%02d]: %016x ? expected value: %016x", ExpectedRegAdrW, dut.hart.ieu.dp.regf.rf[ExpectedRegAdrW], ExpectedRegValueW); end if (RegWriteW == "GPR") begin - if (dut.hart.ieu.dp.regf.a3 != ExpectedRegAdrW) begin - $display("Reg Write Address: %02d does not equal expected value: %02d", dut.hart.ieu.dp.regf.a3, ExpectedRegAdrW); - fault = 1; - end + if (dut.hart.ieu.dp.regf.a3 != ExpectedRegAdrW) begin + $display("Reg Write Address: %02d does not equal expected value: %02d", dut.hart.ieu.dp.regf.a3, ExpectedRegAdrW); + fault = 1; + end if (dut.hart.ieu.dp.regf.rf[ExpectedRegAdrW] != ExpectedRegValueW) begin $display("RF[%02d]: %016x does not equal expected value: %016x", ExpectedRegAdrW, dut.hart.ieu.dp.regf.rf[ExpectedRegAdrW], ExpectedRegValueW);