Merge branch 'main' of github.com:openhwgroup/cvw into boot

This commit is contained in:
Jacob Pease 2023-01-23 12:41:02 -06:00
commit 9b612fbf6c
70 changed files with 1057 additions and 3049 deletions

3
.gitignore vendored
View file

@ -126,3 +126,6 @@ tests/custom/*/*/*.map
tests/custom/*/*/*.memfile
tests/custom/crt0/*.a
/pipelined/regression/sd_model.log
fpga/src/sdc/*
fpga/src/sdc.tar.gz
fpga/src/CopiedFiles_do_not_add_to_repo/*

141
Install
View file

@ -14,148 +14,14 @@ installed at base diretory $RISCV.
** TL;DR Open Source Tool-chain Installation
The installing details are involved. The following script assumes installation occurs in RISCV=/opt/riscv
The installing details are involved, but can be skipped using the following script. wally-tool-chain-install.sh installs the open source tools to RISCV=/opt/riscv by default. Change by supplying an alternate path as an argument, (ie. wally-tool-chain-install.sh /mnt/disk1/riscv).
This install script does NOT install buildroot or commercial EDA tools; Questa, Design Compiler, or Innovus.
It must be run as root or with sudo.
This script only works for Ubuntu.
This script is tested for Ubuntu, 20.04 and 22.04
wally-tool-chain-install.sh
** TL;DR install summery
*** Environement setup
1. export RISCV=/opt/riscv
2. sudo mkdir $RISCV
3. sudo chown cad $RISCV
4. sudo su cad (or root, if you dont have a cad account)
5. export RISCV=/opt/riscv
6. chmod 755 $RISCV
7. mask 0002
8. cd $RISCV
*** Install dependencies
**** Ubuntu
1. sudo apt update
2. sudo apt upgrade
3. sudo apt install git gawk make texinfo bison flex build-essential python libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libglib2.56-dev libpixman-1-dev build-essential ncurses-base ncurses-bin libncurses5-dev dialog
**** Red Hat / Fedora *** TODO
*** Install RISC-V GCC Cross-Compiler
1. git clone https://github.com/riscv/riscv-gnu-toolchain
2. cd riscv-gnu-toolchain
3. git checkout 2022.09.21
4. ./configure --prefix=$RISCV --enable-multilib --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
5. make --jobs
*** Install elf2hex
1. cd $RISCV
2. export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH
3. git clone https://github.com/sifive/elf2hex.git
4. cd elf2hex
5. autoreconf -i
6. ./configure --target=riscv64-unknown-elf --prefix=$RISCV
7. make
8. make install
*** Install RISC-V Spike Simulator
1. cd $RISCV
2. git clone https://github.com/riscv-software-src/riscv-isa-sim
3. mkdir riscv-isa-sim/build
4. cd riscv-isa-sim/build
5. ../configure --prefix=$RISCV --enable-commitlog
6. make --jobs
7. make install
8. cd ../arch_test_target/spike/device
9. sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include
10. sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include
*** Install Sail Simulator
**** Ubuntu
1. sudo apt install opam build-essential libgmp-dev z3 pkg-config zlib1g-dev
**** Red Hat / Fedora
# Parallel make (--jobs) will massively speed up installation; however it requires significant system RAM. Recomemded to have 64GB
1. sudo bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
When prompted, put it in /usr/bin
2. sudo yum groupinstall 'Development Tools'
3. sudo yum -y install gmp-devel
4. sudo yum -y install zlib-devel
5. git clone https://github.com/Z3Prover/z3.git
6. cd z3
7. python scripts/mk_make.py
8. cd build
9. make
10. sudo make install
11. cd ../..
12. sudo pip3 install chardet==3.0.4
13. sudo pip3 install urllib3==1.22
**** Complete Sail Install with OCaml
# Parallel make (--jobs) will massively speed up installation; however it requires significant system RAM. Recomemded to have 64GB
1. sudo su cad
2. opam init -y --disable-sandboxing
3. opam switch create ocaml-base-compiler.4.06.1
4. opam install sail -y
5. eval $(opam config env)
6. cd $RISCV
7. git clone https://github.com/riscv/sail-riscv.git
8. cd sail-riscv
9. make
10. ARCH=RV32 make
11. ARCH=RV64 make
12. exit
13. sudo su
14. export RISCV=/opt/riscv
15. ln -s $RISCV/sail-riscv/c_emulator/riscv_sim_RV64 /usr/bin/riscv_sim_RV64
16. ln -s $RISCV/sail-riscv/c_emulator/riscv_sim_RV32 /usr/bin/riscv_sim_RV32
17. exit
*** Install riscof
1. sudo pip3 install testresources
2. sudo pip3 install riscof --ignore-installed PyYAML
*** Install Verilator
**** Ubuntu
sudo apt install verilator
**** Red Hat / Fedora *** TODO
*** Install QEMU Simulator (Only required for linux simulation)
1. cd $RISCV
2. git clone --recurse-submodules https://github.com/qemu/qemu
3. cd qemu
4. git checkout v6.2.0 # last version tested; newer versions might be ok
5. ./configure --target-list=riscv64-softmmu --prefix=$RISCV
6. make --jobs
7. make install
*** Cross-Compile Buildroot Linux (Only required for linux simulation)
#May wish to install in another location
1. cd $RISCV
2. export WALLY=~/riscv-wally # make sure you havent sourced ~/riscv-wally/setup.sh by now
3. git clone https://github.com/buildroot/buildroot.git
4. cd buildroot
5. git checkout 2021.05 # last tested working version
6. cp -r $WALLY/linux/buildroot-config-src/wally ./board
7. cp ./board/wally/main.config .config
8. make --jobs
**** Generate disassembly files
1. source ~/riscv-wally/setup.sh
2. cd $WALLY/linux/buildroot-scripts
3. make all
*** Download Synthesis Libraries
1. cd $RISCV
2. mkdir cad
3. mkdir cad/lib
4. cd cad/lib
5. git clone https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12
The step by step instructions include Red Hat 8 / Fedora.
** Detailed Tool-chain Instal Guide
Section 2.1 described Wally platform requirements and Section 2.2 describes how a user gets started using Wally on a Linux server. This appendix describes how the system administrator installs RISC-V tools. Superuser privileges are necessary for many of the tools. Setting up all of the tools can be time-consuming and fussy, so this appendix also describes a fallback flow with Docker and Podman.
@ -405,7 +271,6 @@ If you want to implement your own version of the chip, your tool and license com
Startups can expect to spend more than $1 million on CAD tools to get a chip to market. Commercial CAD tools are not realistically available to individuals without a university or company connection.
* Core-v-wally Repo Installation
** TL;DR Repo Install
cd

284
README.md
View file

@ -3,7 +3,9 @@ Configurable RISC-V Processor
Wally is a 5-stage pipelined processor configurable to support all the standard RISC-V options, incluidng RV32/64, A, C, F, D, and M extensions, FENCE.I, and the various privileged modes and CSRs. It is written in SystemVerilog. It passes the RISC-V Arch Tests and boots Linux on an FPGA.
Wally is described in a textbook, RISC-V System-on-Chip Design, by Harris, Stine, Thompson, and Harris. See Appendix D for directions installing the RISC-V tool chain needed to use Wally.
![Wally block diagram](wallyriscvTopAll.png)
Wally is described in a textbook, RISC-V System-on-Chip Design, by Harris, Stine, Thompson, and Harris. Users should follow the setup instructions below. A system administrator must install CAD tools using the directions further down.
New users may wish to do the following setup to access the server via a GUI and use a text editor.
@ -16,9 +18,17 @@ New users may wish to do the following setup to access the server via a GUI and
Then follow Section 2.2 to clone the repo, source setup, make the tests and run regression
If you don't already have a Github account, create one
In a web browser, visit https://github.com/openhwgroup/cvw
In the upper right part of the screen, click on Fork
Create a fork, choosing the owner as your github account and the repository as cvw.
On the Linux computer where you will be working, log in, clone your fork of the repo,
run the setup script, and build the tests:
$ cd
$ git clone --recurse-submodules https://github.com/davidharrishmc/riscv-wally
$ cd riscv-wally
$ git clone --recurse-submodules https://github.com/<yourgithubid>/cvw
$ cd cvw
$ source ./setup.sh
$ make
$ cd pipelined/regression
@ -26,6 +36,270 @@ Then follow Section 2.2 to clone the repo, source setup, make the tests and run
Add the following lines to your .bashrc or .bash_profile
if [ -f ~/riscv-wally/setup.sh ]; then
source ~/riscv-wally/setup.sh
if [ -f ~/cvw/setup.sh ]; then
source ~/cvw/setup.sh
fi
# Tool-chain Installation (Sys Admin)
This section describes the open source toolchain installation. These steps should only be done once by the system admin.
## TL;DR Open Source Tool-chain Installation
The full instalation details are involved can be be skipped using the following script, wally-tool-chain-install.sh.
The script installs the open source tools to /opt/riscv by default. This can be changed by supply the path as the first argument. This script does not install buildroot (see the Detailed Tool-chain Install Guide in the following section) and does not install commercial EDA tools; Siemens Questa, Synopsys Design Compiler, or Cadence Innovus (see section Installing IDA Tools). It must be run as root or with sudo. This script is tested for Ubuntu, 20.04 and 22.04. Fedora and Red Hat can be installed in the Detailed Tool-chain Install Guide.
$ wally-tool-chain-install.sh <optional, install directory, defaults to /opt/riscv>
## Detailed Tool-chain Install Guide
Section 2.1 described Wally platform requirements and Section 2.2 describes how a user gets started using Wally on a Linux server. This appendix describes how the system administrator installs RISC-V tools. Superuser privileges are necessary for many of the tools. Setting up all of the tools can be time-consuming and fussy, so this appendix also describes a fallback flow with Docker and Podman.
### Open Source Software Installation
Compiling, assembling, and simulating RISC-V programs requires downloading and installing the following free tools:
1. The GCC cross-compiler
2. A RISC-V simulator such as Spike, Sail, and/or QEMU
3. Spike is easy to use but doesnt support peripherals to boot Linux
4. QEMU is faster and can boot Linux
5. Sail is presently the official golden reference for RISC-V and is used by the riscof verification suite, but runs slowly and is painful to instal
This setup needs to be done once by the administrator
Note: The following directions assume you have an account called cad to install shared software and files. You can substitute a different user for cad if you prefer.
Note: Installing software in Linux is unreasonably touchy and varies with the flavor and version of your Linux distribution. Dont be surprised if the installation directions have changed since the book was written or dont work on your machine; you may need some ingenuity to adjust them. Browse the openhwgroup/core-v-wally repo and look at the README.md for the latest build instructions.
### Create the $RISCV Directory
First, set up a directory for riscv software in some place such as /opt/riscv. We will call this shared directory $RISCV.
$ export RISCV=/opt/riscv
$ sudo mkdir $RISCV
$ sudo chown cad $RISCV
$ sudo su cad (or root, if you dont have a cad account)
$ export RISCV=/opt/riscv
$ chmod 755 $RISCV
$ umask 0002
$ cd $RISCV
### Update Tools
Ubuntu users may need to install and update various tools.
$ sudo apt update
$ sudo apt upgrade
$ sudo apt install git gawk make texinfo bison flex build-essential python libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libglib2.56-dev libpixman-1-dev build-essential ncurses-base ncurses-bin libncurses5-dev dialog
### Install RISC-V GCC Cross-Compiler
To install GCC from source can take hours to compile. This configuration enables multilib to target many flavors of RISC-V. This book is tested with GCC 12.2 (tagged 2022.09.21), but will likely work with newer versions as well.
$ git clone https://github.com/riscv/riscv-gnu-toolchain
$ cd riscv-gnu-toolchain
$ git checkout 2022.09.21
$ ./configure --prefix=$RISCV --enable-multilib --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
$ make --jobs
Note: make --jobs will reduce compile time by compiling in parallel. However, adding this option could dramatically increase the memory utilization of your local machine.
### Install elf2hex
We also need the elf2hex utility to convert executable files into hexadecimal files for Verilog simulation. Install with:
$ cd $RISCV
$ export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH
$ git clone https://github.com/sifive/elf2hex.git
$ cd elf2hex
$ autoreconf -i
$ ./configure --target=riscv64-unknown-elf --prefix=$RISCV
$ make
$ make install
Note: The exe2hex utility that comes with Spike doesnt work for our purposes because it doesnt handle programs that start at 0x80000000. The SiFive version above is touchy to install. For example, if Python version 2.x is in your path, it wont install correctly. Also, be sure riscv64-unknown-elf-objcopy shows up in your path in $RISCV/riscv-gnu-toolchain/bin at the time of compilation, or elf2hex wont work properly.
### Install RISC-V Spike Simulator
Spike also takes a while to install and compile, but this can be done concurrently with the GCC installation. After the build, we need to change two Makefiles to support atomic instructions .
$ cd $RISCV
$ git clone https://github.com/riscv-software-src/riscv-isa-sim
$ mkdir riscv-isa-sim/build
$ cd riscv-isa-sim/build
$ ../configure --prefix=$RISCV --enable-commitlog
$ make --jobs
$ make install
$ cd ../arch_test_target/spike/device
$ sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include
$ sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include
### Install Sail Simulator
Sail is the new golden reference model for RISC-V. Sail is written in OCaml, which is an object-oriented extension of ML, which in turn is a functional programming language suited to formal verification. OCaml is installed with the opam OCcaml package manager. Sail has so many dependencies that it can be difficult to install.
On Ubuntu, apt-get makes opam installation fairly simple.
$ sudo apt-get install opam build-essential libgmp-dev z3 pkg-config zlib1g-dev
If you are on RedHat/Rocky Linux 8, installation is much more difficult because packages are not available in the default package manager and some need to be built from source.
$ sudo bash -c "sh <(curl -fsSL https://raw.githubusercontent.com/ocaml/opam/master/shell/install.sh)"
When prompted, put it in /usr/bin
$ sudo yum groupinstall 'Development Tools'
$ sudo yum -y install gmp-devel
$ sudo yum -y install zlib-devel
$ git clone https://github.com/Z3Prover/z3.git
$ cd z3
$ python scripts/mk_make.py
$ cd build
$ make
$ sudo make install
$ cd ../..
$ sudo pip3 install chardet==3.0.4
$ sudo pip3 install urllib3==1.22
Once you have installed the packages on either Ubuntu or RedHat, use opam to install the OCaml compiler and Sail. Run as the cad user because you will be installing Sail in $RISCV.
$ sudo su cad
$ opam init -y --disable-sandboxing
$ opam switch create ocaml-base-compiler.4.06.1
$ opam install sail -y
Now you can clone and compile Sail-RISCV. This will take a while.
$ eval $(opam config env)
$ cd $RISCV
$ git clone https://github.com/riscv/sail-riscv.git
$ cd sail-riscv
$ make
$ ARCH=RV32 make
$ ARCH=RV64 make
$ exit
$ sudo su
$ export RISCV=/opt/riscv
$ ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV64 /usr/bin/riscv_sim_RV64
$ ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV32 /usr/bin/riscv_sim_RV32
$ exit
### Install riscof
riscof is a Python library used as the RISC-V compatibility framework test an implementation such as Wally or Spike against the Sail golden reference. It will be used to compile the riscv-arch-test suite.
It is most convenient if the sysadmin installs riscof into the servers Python libraries:
$ sudo pip3 install testresources
$ sudo pip3 install riscof --ignore-installed PyYAML
However, riscof can also be installed and run locally by individual users.
### Install Verilator
Verilator is a free Verilog simulator with a good Lint tool used to catch errors in the SystemVerilog code. It is needed to run regression.
$ sudo apt install verilator
### Install QEMU Simulator
QEMU is another simulator used when booting Linux in Chapter 17. You can optionally install it using the following commands.
<SIDEBAR>
The QEMU patch changes the VirtIO driver to match the Wally peripherals, and also adds print statements to log the state of the CSRs (see Section 2.5XREF).
</END>
$ cd $RISCV
$ git clone --recurse-submodules https://github.com/qemu/qemu
$ cd qemu
$ git checkout v6.2.0 # last version tested; newer versions might be ok
$ ./configure --target-list=riscv64-softmmu --prefix=$RISCV
$ make --jobs
$ make install
### Cross-Compile Buildroot Linux
Building Linux is only necessary for exploring the boot process in Chapter 17. Building and generating a trace is a time-consuming operation that could be skipped for now; you can return to this section later if you are interested in the Linux details.
Buildroot depends on configuration files in riscv-wally, so the cad user must install Wally first according to the instructions in Section 2.2.2. However, dont source ~/wally-riscv/setup.sh because it will set LD_LIBRARY_PATH in a way to cause make to fail on buildroot.
To configure and build Buildroot:
$ cd $RISCV
$ export WALLY=~/riscv-wally # make sure you havent sourced ~/riscv-wally/setup.sh by now
$ git clone https://github.com/buildroot/buildroot.git
$ cd buildroot
$ git checkout 2021.05 # last tested working version
$ cp -r $WALLY/linux/buildroot-config-src/wally ./board
$ cp ./board/wally/main.config .config
$ make --jobs
To generate disassembly files and the device tree, run another make script. Note that you can expect some warnings about phandle references while running dtc on wally-virt.dtb.
$ source ~/riscv-wally/setup.sh
$ cd $WALLY/linux/buildroot-scripts
$ make all
Note: When the make tasks complete, youll find source code in $RISCV/buildroot/output/build and the executables in $RISCV/buildroot/output/images.
### Download Synthesis Libraries
For logic synthesis, we need a synthesis tool (see Section 3.XREF) and a cell library. Clone the OSU 12-track cell library for the Skywater 130 nm process:
$ cd $RISCV
$ mkdir cad
$ mkdir cad/lib
$ cd cad/lib
$ git clone https://foss-eda-tools.googlesource.com/skywater-pdk/libs/sky130_osu_sc_t12
## Installing EDA Tools
Electronic Design Automation (EDA) tools are vital to implementations of System on Chip architectures as well as validating different designs. Open-source and commercial tools exist for multiple strategies and although the one can spend a lifetime using combinations of different tools, only a small subset of tools is utilized for this text. The tools are chosen because of their ease in access as well as their repeatability for accomplishing many of the tasks utilized to design Wally. It is anticipated that additional tools may be documented later after this is text is published to improve use and access.
Siemens Quest is the primary tool utilized for simulating and validating Wally. For logic synthesis, you will need Synopsys Design Compiler. Questa and Design Compiler are commercial tools that require an educational or commercial license.
Note: Some EDA tools utilize LM_LICENSE_FILE for their environmental variable to point to their license server. Some operating systems may also utilize MGLS_LICENSE_FILE instead, therefore, it is important to read the user manual on the preferred environmental variable required to point to a users license file. Although there are different mechanisms to allow licenses to work, many companies commonly utilize the FlexLM (i.e., Flex-enabled) license server manager that runs off a node locked license.
Although most EDA tools are Linux-friendly, they tend to have issues when not installed on recommended OS flavors. Both Red Hat Enterprise Linux and SUSE Linux products typically tend to be recommended for installing commercial-based EDA tools and are recommended for utilizing complex simulation and architecture exploration. Questa can also be installed on Microsoft Windows as well as Mac OS with a Virtual Machine such as Parallels.
Siemens Questa
Siemens Questa simulates behavioral, RTL and gate-level HDL. To install Siemens Questa first go to a web browser and navigate to
https://eda.sw.siemens.com/en-US/ic/questa/simulation/advanced-simulator/. Click Sign In and log in with your credentials and the product can easily be downloaded and installed. Some Windows-based installations also require gcc libraries that are typically provided as a compressed zip download through Siemens.
Synopsys Design Compiler (DC)
Many commercial synthesis and place and route tools require a common installer. These installers are provided by the EDA vendor and Synopsys has one called Synopsys Installer. To use Synopsys Installer, you will need to acquire a license through Synopsys that is typically Called Synopsys Common Licensing (SCL). Both the Synopsys Installer, license key file, and Design Compiler can all be downloaded through Synopsys Solvnet. First open a web browser, log into Synsopsy Solvnet, and download the installer and Design Compiler installation files. Then, install the Installer
$ firefox &
Navigate to https://solvnet.synopsys.com
Log in with your institutions username and password
Click on Downloads, then scroll down to Synopsys Installer
Select the latest version (currently 5.4). Click Download Here, agree,
Click on SynopsysInstaller_v5.4.run
Return to downloads and also get Design Compiler (synthesis) latest version, and any others you want.
Click on all parts and the .spf file, then click Download Files near the top
move the SynopsysIntaller into /cad/synopsys/Installer_5.4 with 755 permission for cad,
move other files into /cad/synopsys/downloads and work as user cad from here on
$ cd /cad/synopsys/installer_5.4
$ ./SynopsysInstaller_v5.4.run
Accept default installation directory
$ ./installer
Enter source path as /cad/synopsys/downloads, and installation path as /cad/synopsys
When prompted, enter your site ID
Follow prompts
Installer can be utilized in graphical or text-based modes. It is far easier to use the text-based installation tool. To install DC, navigate to the location where your downloaded DC files are and type installer. You should be prompted with questions related to where you wish to have your files installed.
The Synopsys Installer automatically installs all downloaded product files into a single top-level target directory. You do not need to specify the installation directory for each product. For example, if you specify /import/programs/synopsys as the target directory, your installation directory structure might look like this after installation:
/import/programs/synopsys/syn/S-2021.06-SP1
Note: Although most parts of Wally, including the software used in this chapter and Questa simulation, will work on most modern Linux platforms, as of 2022, the Synopsys CAD tools for SoC design are only supported on RedHat Enterprise Linux 7.4 or 8 or SUSE Linux Enterprise Server (SLES) 12 or 15. Moreover, the RISC-V formal specification (sail-riscv) does not build gracefully on RHEL7.
The Verilog simulation has been tested with Siemens Questa/ModelSim. This package is available to universities worldwide as part of the Design Verification Bundle through the Siemens Academic Partner Program members for $990/year.
If you want to implement your own version of the chip, your tool and license complexity rises significantly. Logic synthesis uses Synopsys Design Compiler. Placement and routing uses Cadence Innovus. Both Synopsys and Cadence offer their tools at a steep discount to their university program members, but the cost is still several thousand dollars per year. Most research universities with integrated circuit design programs have Siemens, Synopsys, and Cadence licenses. You also need a process design kit (PDK) for a specific integrated circuit technology and its libraries. The open-source Google Skywater 130 nm PDK is sufficient to synthesize the core but lacks memories. Google presently funds some fabrication runs for universities. IMEC and Muse Semiconductor offers full access to multiproject wafer fabrication on the TSMC 28 nm process including logic, I/O, and memory libraries; this involves three non-disclosure agreements. Fabrication costs on the order of $10,000 for a batch of 1 mm2 chips.
Startups can expect to spend more than $1 million on CAD tools to get a chip to market. Commercial CAD tools are not realistically available to individuals without a university or company connection.

View file

@ -1,8 +1,30 @@
#!/bin/bash
# james.stine@okstate.edu 4 Jan 2022
# Script to run elf2hex for memfile for
# Imperas and riscv-arch-test benchmarks
###########################################
## Written: james.stine@okstate.edu
## Created: 4 Jan 2022
## Modified:
##
## Purpose: Script to run elf2hex for memfile for
## Imperas and riscv-arch-test benchmarks
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
for file in work/rv64i_m/*/*.elf ; do
memfile=${file%.elf}.elf.memfile

View file

@ -1,9 +1,35 @@
#!/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
###########################################
## exe2memfile.pl
##
## Written: David_Harris@hmc.edu
## Created: 26 November 2020
## Modified:
##
## Purpose: Converts an executable file to a series of 32-bit hex instructions
## to read into a Verilog simulation with $readmemh
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
#
#
use File::stat;
use IO::Handle;
@ -167,4 +193,4 @@ sub fixadr {
my $adr = shift;
if ($adr =~ s/^8/0/) { return hex($adr); }
else { die("address $adr lacks leading 8\n"); }
}
}

View file

@ -1,34 +1,33 @@
#!/bin/bash
######################
# extractFunctionRadix.sh
#
# Written: Ross Thompson
# email: ross1728@gmail.com
# Created: March 1, 2021
# Modified: March 10, 2021
#
# Purpose: Processes all compiled object files into 2 types of files which assist in debuging applications.
# File 1: .addr: A sorted list of function starting addresses.
# When a the PCE is greater than or equal to the function's starting address, the label will be associated with this address.
# File 2: .lab: A sorted list of funciton labels. The names of functions. Modelsim will display these names rather than the function address.
#
# 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.
######################
## extractFunctionRadix.sh
##
## Written: Ross Thompson
## email: ross1728@gmail.com
## Created: March 1, 2021
## Modified: March 10, 2021
##
## Purpose: Processes all compiled object files into 2 types of files which assist in debuging applications.
## File 1: .addr: A sorted list of function starting addresses.
## When a the PCE is greater than or equal to the function's starting address, the label will be associated with this address.
## File 2: .lab: A sorted list of funciton labels. The names of functions. Modelsim will display these names rather than the function address.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
function processProgram {

View file

@ -1,5 +1,30 @@
#!/usr/bin/python3
###########################################
## Written: Ross Thompson ross1728@gmail.com
## Created: 4 Jan 2022
## Modified:
##
## Purpose: Parses the performance counters from a modelsim trace.
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
import os
import sys
import matplotlib.pyplot as plt

View file

@ -1,8 +1,33 @@
#!/bin/bash
# testcount.pl
# David_Harris@hmc.edu 25 December 2022
# Read the riscv-test-suite directories from riscv-arch-test
# and count how many tests are in each
###########################################
## testcount.pl
##
## Written: David_Harris@hmc.edu
## Created: 25 December 2022
## Modified: Read the riscv-test-suite directories from riscv-arch-test
## and count how many tests are in each
##
## Purpose: Read the riscv-test-suite directories from riscv-arch-test
## and count how many tests are in each
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
for dir in `ls ${WALLY}/addins/riscv-arch-test/riscv-test-suite/rv*/*`
do

View file

@ -1,8 +1,33 @@
#!/bin/perl -W
# testlist.pl
# David_Harris@hmc.edu 25 December 2021
# Read the work directories from riscv-arch-test or imperas-riscv-tests
# and generate a list of tests and signature addresses for tests.vh
###########################################
## testlist.pl
##
## Written: David_Harris@hmc.edu
## Created: 25 December 2021
## Modified:
##
## Purpose: Read the work directories from riscv-arch-test or imperas-riscv-tests
## and generate a list of tests and signature addresses for tests.vh
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
use strict;
use warnings;

View file

@ -1,9 +1,32 @@
#!/usr/bin/perl -w
# vclean.pl
# David_Harris@hmc.edu 7 December 2023
# Identifies unused signals in Verilog files
# verilator should do this, but it also reports partially used signals
###########################################
## vclean.pl
##
## Written: David_Harris@hmc.edu
## Created: 7 December 2023
## Modified:
##
## Purpose: Identifies unused signals in Verilog files
## verilator should do this, but it also reports partially used signals
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
use strict;
@ -43,4 +66,4 @@ sub clean {
printf("$sig not used in $fname\n");
}
}
}
}

127
bin/wally-tool-chain-install.sh Executable file
View file

@ -0,0 +1,127 @@
#!/bin/bash
###########################################
## Tool chain install script.
##
## Written: Ross Thompson ross1728@gmail.com
## Created: 18 January 2023
## Modified: 22 January 2023
##
## Purpose: Open source tool chain installation script
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org/licenses/SHL-2.1/
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
export RISCV="${1:-/opt/riscv}"
export PATH=$PATH:$RISCV/bin
set -e # break on error
NUM_THREADS=1 # for low memory machines > 16GiB
#NUM_THREADS=8 # for >= 32GiB
#NUM_THREADS=16 # for >= 64GiB
sudo mkdir -p $RISCV
# UPDATE / UPGRADE
apt update
# INSTALL
apt install -y git gawk make texinfo bison flex build-essential python3 libz-dev libexpat-dev autoconf device-tree-compiler ninja-build libpixman-1-dev build-essential ncurses-base ncurses-bin libncurses5-dev dialog curl wget ftp libgmp-dev
# needed for Ubuntu 22.04, gcc cross compiler expects python not python2 or python3.
if ! command -v python &> /dev/null
then
echo "WARNING: python3 was installed as python3 rather than python. Creating symlink."
ln -sf /usr/bin/python3 /usr/bin/python
fi
# gcc cross-compiler
cd $RISCV
git clone https://github.com/riscv/riscv-gnu-toolchain
cd riscv-gnu-toolchain
./configure --prefix=${RISCV} --enable-multilib --with-multilib-generator="rv32e-ilp32e--;rv32i-ilp32--;rv32im-ilp32--;rv32iac-ilp32--;rv32imac-ilp32--;rv32imafc-ilp32f--;rv32imafdc-ilp32d--;rv64i-lp64--;rv64ic-lp64--;rv64iac-lp64--;rv64imac-lp64--;rv64imafdc-lp64d--;rv64im-lp64--;"
make -j ${NUM_THREADS}
make install
# elf2hex
cd $RISCV
export PATH=$RISCV/riscv-gnu-toolchain/bin:$PATH
git clone https://github.com/sifive/elf2hex.git
cd elf2hex
autoreconf -i
./configure --target=riscv64-unknown-elf --prefix=$RISCV
make
make install
# Update Python3.6 for QEMU
apt-get -y update
apt-get -y install python3-pip
apt-get -y install pkg-config
apt-get -y install libglib2.0-dev
# QEMU
cd $RISCV
git clone --recurse-submodules https://github.com/qemu/qemu
cd qemu
./configure --target-list=riscv64-softmmu --prefix=$RISCV
make -j ${NUM_THREADS}
make install
# Spike
cd $RISCV
git clone https://github.com/riscv-software-src/riscv-isa-sim
mkdir -p riscv-isa-sim/build
cd riscv-isa-sim/build
../configure --prefix=$RISCV --enable-commitlog
make -j ${NUM_THREADS}
make install
cd ../arch_test_target/spike/device
sed -i 's/--isa=rv32ic/--isa=rv32iac/' rv32i_m/privilege/Makefile.include
sed -i 's/--isa=rv64ic/--isa=rv64iac/' rv64i_m/privilege/Makefile.include
# SAIL
cd $RISCV
apt-get install -y opam build-essential libgmp-dev z3 pkg-config zlib1g-dev
git clone https://github.com/Z3Prover/z3.git
cd z3
python scripts/mk_make.py
cd build
make -j ${NUM_THREADS}
make install
cd ../..
pip3 install chardet==3.0.4
pip3 install urllib3==1.22
opam init -y --disable-sandboxing
opam switch create ocaml-base-compiler.4.06.1
opam install sail -y
eval $(opam config env)
git clone https://github.com/riscv/sail-riscv.git
cd sail-riscv
make -j ${NUM_THREADS}
ARCH=RV32 make
ARCH=RV64 make
ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV64 /usr/bin/riscv_sim_RV64
ln -sf $RISCV/sail-riscv/c_emulator/riscv_sim_RV32 /usr/bin/riscv_sim_RV32
pip3 install testresources
pip3 install riscof --ignore-installed PyYAML
# Verilator
apt install -y verilator

View file

@ -356,7 +356,7 @@ connect_debug_port u_ila_0/probe68 [get_nets [list wallypipelinedsoc/core/hzu/St
create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe69]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe69]
connect_debug_port u_ila_0/probe69 [get_nets [list wallypipelinedsoc/core/hzu/StallDCause08_in]]
connect_debug_port u_ila_0/probe69 [get_nets [list wallypipelinedsoc/core/hzu/StallDCause]]
create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe70]
@ -434,9 +434,10 @@ set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe83]
connect_debug_port u_ila_0/probe83 [get_nets [list {wallypipelinedsoc/core/ebu.ebu/HTRANS[0]} {wallypipelinedsoc/core/ebu.ebu/HTRANS[1]}]]
create_debug_port u_ila_0 probe
set_property port_width 64 [get_debug_ports u_ila_0/probe84]
set_property port_width 53 [get_debug_ports u_ila_0/probe84]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe84]
connect_debug_port u_ila_0/probe84 [get_nets [list {wallypipelinedsoc/core/ebu.ebu/HWDATA[0]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[1]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[2]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[3]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[4]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[5]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[6]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[7]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[8]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[9]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[10]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[11]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[12]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[13]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[14]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[15]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[16]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[17]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[18]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[19]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[20]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[21]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[22]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[23]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[24]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[25]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[26]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[27]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[28]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[29]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[30]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[31]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[32]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[33]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[34]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[35]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[36]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[37]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[38]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[39]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[40]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[41]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[42]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[43]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[44]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[45]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[46]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[47]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[48]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[49]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[50]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[51]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[52]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[53]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[54]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[55]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[56]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[57]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[58]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[59]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[60]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[61]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[62]} {wallypipelinedsoc/core/ebu.ebu/HWDATA[63]}]]
connect_debug_port u_ila_0/probe84 [get_nets [list {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][1]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][2]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][3]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][4]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][5]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][6]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][7]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][8]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][9]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][10]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][11]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][12]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][13]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][14]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][15]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][16]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][17]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][18]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][19]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][20]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][21]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][22]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][23]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][24]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][25]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][26]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][27]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][28]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][29]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][30]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][31]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][32]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][33]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][34]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][35]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][36]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][37]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][38]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][39]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][40]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][41]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][42]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][43]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][44]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][45]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][46]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][47]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][48]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][49]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][50]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][51]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][52]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][53]} ]]
create_debug_port u_ila_0 probe
@ -531,7 +532,7 @@ connect_debug_port u_ila_0/probe101 [get_nets [list {wallypipelinedsoc/core/ifu/
create_debug_port u_ila_0 probe
set_property port_width 1 [get_debug_ports u_ila_0/probe102]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe102]
connect_debug_port u_ila_0/probe102 [get_nets [list wallypipelinedsoc/core/ifu/SpillSupport.spillsupport/CurrState[0] ]]
connect_debug_port u_ila_0/probe102 [get_nets [list wallypipelinedsoc/core/ifu/Spill.spill/CurrState[0] ]]
create_debug_port u_ila_0 probe
@ -1143,8 +1144,3 @@ set_property port_width 53 [get_debug_ports u_ila_0/probe223]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe223]
connect_debug_port u_ila_0/probe223 [get_nets [list {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][1]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][2]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][3]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][4]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][5]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][6]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][7]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][8]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][9]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][10]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][11]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][12]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][13]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][14]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][15]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][16]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][17]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][18]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][19]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][20]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][21]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][22]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][23]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][24]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][25]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][26]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][27]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][28]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][29]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][30]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][31]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][32]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][33]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][34]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][35]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][36]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][37]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][38]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][39]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][40]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][41]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][42]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][43]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][44]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][45]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][46]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][47]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][48]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][49]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][50]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][51]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][52]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[1][53]} ]]
create_debug_port u_ila_0 probe
set_property port_width 53 [get_debug_ports u_ila_0/probe224]
set_property PROBE_TYPE DATA_AND_TRIGGER [get_debug_ports u_ila_0/probe224]
connect_debug_port u_ila_0/probe224 [get_nets [list {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][1]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][2]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][3]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][4]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][5]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][6]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][7]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][8]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][9]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][10]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][11]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][12]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][13]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][14]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][15]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][16]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][17]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][18]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][19]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][20]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][21]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][22]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][23]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][24]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][25]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][26]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][27]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][28]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][29]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][30]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][31]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][32]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][33]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][34]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][35]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][36]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][37]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][38]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][39]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][40]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][41]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][42]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][43]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][44]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][45]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][46]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][47]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][48]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][49]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][50]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][51]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][52]} {wallypipelinedsoc/uncore.uncore/plic.plic/irqs_at_max_priority[0][53]} ]]

View file

@ -0,0 +1,132 @@
lsu/lsu.sv: logic IEUAdrM
lsu/lsu.sv: logic WriteDataM
lsu/lsu.sv: logic LSUHADDR
lsu/lsu.sv: logic HRDATA
lsu/lsu.sv: logic LSUHWDATA
lsu/lsu.sv: logic LSUHREADY
lsu/lsu.sv: logic LSUHWRITE
lsu/lsu.sv: logic LSUHSIZE
lsu/lsu.sv: logic LSUHBURST
lsu/lsu.sv: logic LSUHTRANS
lsu/lsu.sv: logic LSUHWSTRB
lsu/lsu.sv: logic IHAdrM
ieu/regfile.sv: logic rf
ieu/datapath.sv: logic RegWriteW
hazard/hazard.sv: logic BPPredWrongE
hazard/hazard.sv: logic LoadStallD
hazard/hazard.sv: logic LSUStallM
hazard/hazard.sv: logic FCvtIntStallD
hazard/hazard.sv: logic DivBusyE
hazard/hazard.sv: logic EcallFaultM
hazard/hazard.sv: logic WFIStallM
hazard/hazard.sv: logic StallF
hazard/hazard.sv: logic FlushD
cache/cachefsm.sv: statetype CurrState
wally/wallypipelinedcore.sv: logic TrapM
wally/wallypipelinedcore.sv: logic SrcAM
wally/wallypipelinedcore.sv: logic InstrM
wally/wallypipelinedcore.sv: logic PCM
wally/wallypipelinedcore.sv: logic MemRWM
wally/wallypipelinedcore.sv: logic InstrValidM
wally/wallypipelinedcore.sv: logic WriteDataM
wally/wallypipelinedcore.sv: logic IEUAdrM
ifu/spill.sv: statetype CurrState
ifu/ifu.sv: logic IFUStallF
ifu/ifu.sv: logic IFUHADDR
ifu/ifu.sv: logic HRDATA
ifu/ifu.sv: logic IFUHREADY
ifu/ifu.sv: logic IFUHWRITE
ifu/ifu.sv: logic IFUHSIZE
ifu/ifu.sv: logic IFUHBURST
ifu/ifu.sv: logic IFUHTRANS
ifu/ifu.sv: logic PCF
ifu/ifu.sv: logic PCNextF
ifu/ifu.sv: logic PCPF
ifu/ifu.sv: logic PostSpillInstrRawF
mmu/hptw.sv: logic ITLBWriteF
mmu/hptw.sv: statetype WalkerState
privileged/csrs.sv: logic CSRSReadValM
privileged/csrs.sv: logic SEPC_REGW
privileged/csrs.sv: logic MIP_REGW
privileged/csrs.sv: logic SSCRATCH_REGW
privileged/csrs.sv: logic SCAUSE_REGW
privileged/csr.sv: logic CSRReadValM
privileged/csr.sv: logic CSRSrcM
privileged/csr.sv: logic CSRWriteValM
privileged/csr.sv: logic MSTATUS_REGW
privileged/trap.sv: logic InstrMisalignedFaultM
privileged/trap.sv: logic BreakpointFaultM
privileged/trap.sv: logic LoadAccessFaultM
privileged/trap.sv: logic LoadPageFaultM
privileged/trap.sv: logic mretM
privileged/trap.sv: logic MIP_REGW
privileged/trap.sv: logic PendingIntsM
privileged/privileged.sv: logic CSRReadM
privileged/privileged.sv: logic InterruptM
privileged/csrc.sv: logic HPMCOUNTER_REGW
privileged/csri.sv: logic MExtInt
privileged/csri.sv: logic MIP_REGW_writeabl
privileged/csrm.sv: logic MIP_REGW
privileged/csrm.sv: logic MEPC_REGW
privileged/csrm.sv: logic MEDELEG_REGW
privileged/csrm.sv: logic MIDELEG_REGW
privileged/csrm.sv: logic MSCRATCH_REGW
privileged/csrm.sv: logic MCAUSE_REGW
uncore/uart_apb.sv: logic SIN
uncore/uart_apb.sv: logic SOUT
uncore/uart_apb.sv: logic OUT1b
uncore/uartPC16550D.sv: logic RBR
uncore/uartPC16550D.sv: logic FCR
uncore/uartPC16550D.sv: logic IER
uncore/uartPC16550D.sv: logic MCR
uncore/uartPC16550D.sv: logic baudpulse
uncore/uartPC16550D.sv: statetype rxstate
uncore/uartPC16550D.sv: logic rxfifo
uncore/uartPC16550D.sv: logic txfifo
uncore/uartPC16550D.sv: logic rxfifohead
uncore/uartPC16550D.sv: logic rxfifoentries
uncore/uartPC16550D.sv: logic RXBR
uncore/uartPC16550D.sv: logic rxtimeoutcnt
uncore/uartPC16550D.sv: logic rxparityerr
uncore/uartPC16550D.sv: logic rxdataready
uncore/uartPC16550D.sv: logic rxfifoempty
uncore/uartPC16550D.sv: logic rxdata
uncore/uartPC16550D.sv: logic RXerrbit
uncore/uartPC16550D.sv: logic rxfullbitunwrapped
uncore/uartPC16550D.sv: logic txdata
uncore/uartPC16550D.sv: logic txnextbit
uncore/uartPC16550D.sv: logic txfifoempty
uncore/uartPC16550D.sv: logic fifoenabled
uncore/uartPC16550D.sv: logic RXerr
uncore/uartPC16550D.sv: logic THRE
uncore/uartPC16550D.sv: logic rxdataavailintr
uncore/uartPC16550D.sv: logic intrID
uncore/plic_apb.sv: logic MExtInt
uncore/plic_apb.sv: logic Din
uncore/plic_apb.sv: logic requests
uncore/plic_apb.sv: logic intPriority
uncore/plic_apb.sv: logic intInProgress
uncore/plic_apb.sv: logic intThreshold
uncore/plic_apb.sv: logic intEn
uncore/plic_apb.sv: logic intClaim
uncore/plic_apb.sv: logic irqMatrix
uncore/plic_apb.sv: logic priorities_with_irqs
uncore/plic_apb.sv: logic max_priority_with_irqs
uncore/plic_apb.sv: logic irqs_at_max_priority
uncore/plic_apb.sv: logic threshMask
uncore/clint_apb.sv: logic MTIME
uncore/clint_apb.sv: logic MTIMECMP
ebu/ebu.sv: logic HCLK
ebu/ebu.sv: logic HREADY
ebu/ebu.sv: logic HRESP
ebu/ebu.sv: logic HADDR
ebu/ebu.sv: logic HWDATA
ebu/ebu.sv: logic HWSTRB
ebu/ebu.sv: logic HWRITE
ebu/ebu.sv: logic HSIZE
ebu/ebu.sv: logic HBURST
ebu/ebu.sv: logic HPROT
ebu/ebu.sv: logic HTRANS
ebu/ebu.sv: logic HMASTLOC
ebu/buscachefsm.sv: busstatetype CurrState
ebu/busfsm.sv: busstatetype CurrState

View file

@ -0,0 +1 @@
test to make sure i can still merge my code into the new open hardware group.

View file

@ -1,8 +1,9 @@
dst := IP
sdc_src := ~/repos/sdc.tar.gz
# vcu118
# export XILINX_PART := xcvu9p-flga2104-2L-e
# export XILINX_BOARD := xilinx.com:vcu118:part0:2.4
# export board := vcu118
#export XILINX_PART := xcvu9p-flga2104-2L-e
#export XILINX_BOARD := xilinx.com:vcu118:part0:2.4
#export board := vcu118
# vcu108
export XILINX_PART := xcvu095-ffva2104-2-e
@ -12,7 +13,7 @@ export board := vcu108
all: FPGA
FPGA: IP
FPGA: PreProcessFiles IP SDC
vivado -mode tcl -source wally.tcl 2>&1 | tee wally.log
IP: $(dst)/xlnx_proc_sys_reset.log \
@ -23,6 +24,15 @@ IP: $(dst)/xlnx_proc_sys_reset.log \
$(dst)/xlnx_axi_dwidth_conv_32to64.log \
$(dst)/xlnx_axi_dwidth_conv_64to32.log
SDC:
cp $(sdc_src) ../src/
tar xzf ../src/sdc.tar.gz -C ../src
PreProcessFiles:
rm -rf ../src/CopiedFiles_do_not_add_to_repo/
cp -r ../../pipelined/src/ ../src/CopiedFiles_do_not_add_to_repo/
./insert_debug_comment.sh
$(dst)/%.log: %.tcl
mkdir -p IP
cd IP;\

View file

@ -0,0 +1,38 @@
#!/bin/bash
###########################################
## insert_debug_comment.sh
##
## Written: Ross Thompson ross1728@gmail.com
## Created: 20 January 2023
## Modified: 20 January 2023
##
## A component of the CORE-V-WALLY configurable RISC-V project.
##
## Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
##
## SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
##
## Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
## except in compliance with the License, or, at your option, the Apache License version 2.0. You
## may obtain a copy of the License at
##
## https:##solderpad.org#licenses#SHL-2.1#
##
## Unless required by applicable law or agreed to in writing, any work distributed under the
## License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
## either express or implied. See the License for the specific language governing permissions
## and limitations under the License.
################################################################################################
# This script copies wally's pipelined#src to fpga#src#CopiedFiles_do_not_add_to_repo
# Then it processes them to add mark_debug on signals needed by the FPGA's ILA.
copiedDir="../src/CopiedFiles_do_not_add_to_repo"
while read line; do
readarray -d ":" -t StrArray <<< "$line"
file="${copiedDir}/${StrArray[0]}"
signal=`echo "${StrArray[1]}" | awk '{$1=$1};1'`
readarray -d " " -t SigArray <<< $signal
sigType=`echo "${SigArray[0]}" | awk '{$1=$1};1'`
sigName=`echo "${SigArray[1]}" | awk '{$1=$1};1'`
find $copiedDir -wholename $file | xargs sed -i "s/\(.*${sigType}.*${sigName}\)/(\* mark_debug = \"true\" \*)\1/g"
done < ../constraints/marked_debug.txt

View file

@ -20,8 +20,10 @@ read_ip IP/xlnx_axi_dwidth_conv_32to64.srcs/sources_1/ip/xlnx_axi_dwidth_conv_32
read_ip IP/xlnx_axi_dwidth_conv_64to32.srcs/sources_1/ip/xlnx_axi_dwidth_conv_64to32/xlnx_axi_dwidth_conv_64to32.xci
read_verilog -sv [glob -type f ../../pipelined/src/*/*.sv ../../pipelined/src/*/*/*.sv]
read_verilog [glob -type f ../../pipelined/src/uncore/newsdc/*.v]
read_verilog -sv [glob -type f ../src/CopiedFiles_do_not_add_to_repo/*/*.sv ../src/CopiedFiles_do_not_add_to_repo/*/*/*.sv]
read_verilog [glob -type f ../../pipelined/src/uncore/newsdc/*.v]
read_verilog {../src/fpgaTop.v}
read_verilog -sv [glob -type f ../src/sdc/*.sv]
set_property include_dirs {../../pipelined/config/fpga ../../pipelined/config/shared} [current_fileset]

View file

@ -52,6 +52,7 @@
// macros to define supported modes
`define A_SUPPORTED ((`MISA >> 0) % 2 == 1)
`define B_SUPPORTED ((`ZBA_SUPPORTED | `ZBB_SUPPORTED | `ZBC_SUPPORTED | `ZBS_SUPPORTED)) // not based on MISA
`define C_SUPPORTED ((`MISA >> 2) % 2 == 1)
`define D_SUPPORTED ((`MISA >> 3) % 2 == 1)
`define E_SUPPORTED ((`MISA >> 4) % 2 == 1)

View file

@ -26,6 +26,12 @@
`define RADIX 32'h4
`define DIVCOPIES 32'h4
// eventually move to each config
`define ZBA_SUPPORTED 0
`define ZBB_SUPPORTED 0
`define ZBC_SUPPORTED 0
`define ZBS_SUPPORTED 0
// Memory synthesis configuration
`define USE_SRAM 0

View file

@ -0,0 +1 @@
test

View file

@ -1,13 +1,20 @@
///////////////////////////////////////////
// simple_timer.sv
// bmu.sv
//
// Written: Ross Thompson September 20, 2021
// Written: kekim@g.hmc.edu, David_Harris@hmc.edu 20 January 2023
// Modified:
//
// Purpose: SD card controller
// Purpose: Bit manipulation extensions Zba, Zbb, Zbc, Zbs
// Single-cycle operation in Execute stage
//
// Documentation: n/a
// See RISC-V Bit-Manipulation ISA-extensions
// Version 1.0.0-38-g865e7a7, 2021-06-28: Release candidate
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// Copyright (C) 2021-23 Harvey Mudd College & Oklahoma State University
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
@ -24,31 +31,15 @@
`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
module bmu(
input logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // inputs A and B from IEU forwarding mux output
input logic [31:0] InstrD, // instruction
output logic BMUE, // bit manipulation instruction
output logic [`XLEN-1:0] BMUResultE // bit manipulation result
);
logic [BUS_WIDTH-1:0] count;
logic timer_en;
assign timer_en = count != 0;
endmodule // mdu
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

View file

@ -7,7 +7,7 @@
//
// Purpose: Implements the I$ and D$. Interfaces with requests from IEU and HPTW and ahbcacheinterface
//
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.9, 7.11, and 7.20)
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.9, 7.10, and 7.19)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//

View file

@ -7,7 +7,7 @@
//
// Purpose: Implements Pseudo LRU. Tested for Powers of 2.
//
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.8 and 7.16 to 7.19)
// Documentation: RISC-V System on Chip Design Chapter 7 (Figures 7.8 and 7.15 to 7.18)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//

View file

@ -7,7 +7,7 @@
//
// Purpose: Controller for the dcache fsm
//
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.15 and Table 7.1)
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.14 and Table 7.1)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
@ -85,7 +85,7 @@ module cachefsm (
STATE_FLUSH,
STATE_FLUSH_WRITEBACK} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState;
statetype CurrState, NextState;
assign AMO = CacheAtomic[1] & (&CacheRW);
assign StoreAMO = AMO | CacheRW[0];

View file

@ -7,7 +7,7 @@
//
// Purpose: Storage and read/write access to data cache data, tag valid, dirty, and replacement.
//
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.12)
// Documentation: RISC-V System on Chip Design Chapter 7 (Figure 7.11)
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//

View file

@ -67,7 +67,7 @@ module buscachefsm #(
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3, CACHE_FETCH, CACHE_WRITEBACK} busstatetype;
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
(* mark_debug = "true" *) busstatetype CurrState, NextState;
busstatetype CurrState, NextState;
logic [AHBWLOGBWPL-1:0] NextBeatCount;
logic FinalBeatCount;

View file

@ -50,7 +50,7 @@ module busfsm (
typedef enum logic [2:0] {ADR_PHASE, DATA_PHASE, MEM3} busstatetype;
typedef enum logic [1:0] {AHB_IDLE = 2'b00, AHB_BUSY = 2'b01, AHB_NONSEQ = 2'b10, AHB_SEQ = 2'b11} ahbtranstype;
(* mark_debug = "true" *) busstatetype CurrState, NextState;
busstatetype CurrState, NextState;
always_ff @(posedge HCLK)
if (~HRESETn | Flush) CurrState <= #1 ADR_PHASE;

View file

@ -52,18 +52,18 @@ module ebu (
output logic LSUHREADY, // AHB peripheral. Never gated as LSU always has priority
// AHB-Lite external signals
(* mark_debug = "true" *) output logic HCLK, HRESETn,
(* mark_debug = "true" *) input logic HREADY, // AHB peripheral ready
(* mark_debug = "true" *) input logic HRESP, // AHB peripheral response. 0: OK 1: Error
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration
(* mark_debug = "true" *) output logic [`AHBW-1:0] HWDATA, // AHB Write data after arbitration
(* mark_debug = "true" *) output logic [`XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration
(* mark_debug = "true" *) output logic HWRITE, // AHB transaction direction after arbitration
(* mark_debug = "true" *) output logic [2:0] HSIZE, // AHB transaction size after arbitration
(* mark_debug = "true" *) output logic [2:0] HBURST, // AHB burst length after arbitration
(* mark_debug = "true" *) output logic [3:0] HPROT, // AHB protection. Wally does not use
(* mark_debug = "true" *) output logic [1:0] HTRANS, // AHB transaction request after arbitration
(* mark_debug = "true" *) output logic HMASTLOCK // AHB master lock. Wally does not use
output logic HCLK, HRESETn,
input logic HREADY, // AHB peripheral ready
input logic HRESP, // AHB peripheral response. 0: OK 1: Error
output logic [`PA_BITS-1:0] HADDR, // AHB address to peripheral after arbitration
output logic [`AHBW-1:0] HWDATA, // AHB Write data after arbitration
output logic [`XLEN/8-1:0] HWSTRB, // AHB byte write enables after arbitration
output logic HWRITE, // AHB transaction direction after arbitration
output logic [2:0] HSIZE, // AHB transaction size after arbitration
output logic [2:0] HBURST, // AHB burst length after arbitration
output logic [3:0] HPROT, // AHB protection. Wally does not use
output logic [1:0] HTRANS, // AHB transaction request after arbitration
output logic HMASTLOCK // AHB master lock. Wally does not use
);
typedef enum logic [1:0] {IDLE, ARBITRATE} statetype;

View file

@ -28,18 +28,18 @@
`include "wally-config.vh"
module hazard(
module hazard (
// Detect hazards
(* mark_debug = "true" *) input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM,
(* mark_debug = "true" *) input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
(* mark_debug = "true" *) input logic LSUStallM, IFUStallF,
(* mark_debug = "true" *) input logic FCvtIntStallD, FPUStallD,
(* mark_debug = "true" *) input logic DivBusyE, FDivBusyE,
(* mark_debug = "true" *) input logic EcallFaultM, BreakpointFaultM,
(* mark_debug = "true" *) input logic WFIStallM,
input logic BPPredWrongE, CSRWriteFenceM, RetM, TrapM,
input logic LoadStallD, StoreStallD, MDUStallD, CSRRdStallD,
input logic LSUStallM, IFUStallF,
input logic FCvtIntStallD, FPUStallD,
input logic DivBusyE, FDivBusyE,
input logic EcallFaultM, BreakpointFaultM,
input logic WFIStallM,
// Stall & flush outputs
(* mark_debug = "true" *) output logic StallF, StallD, StallE, StallM, StallW,
(* mark_debug = "true" *) output logic FlushD, FlushE, FlushM, FlushW
output logic StallF, StallD, StallE, StallM, StallW,
output logic FlushD, FlushE, FlushM, FlushW
);
logic StallFCause, StallDCause, StallECause, StallMCause, StallWCause;

View file

@ -48,6 +48,7 @@ module datapath (
output logic [1:0] FlagsE, // Comparison flags ({eq, lt})
output logic [`XLEN-1:0] IEUAdrE, // Address computed by ALU
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU sources before the mux chooses between them and PCE to put in srcA/B
input logic BMUE, // Bit manipulation instruction
// Memory stage signals
input logic StallM, FlushM, // Stall, flush Memory stage
input logic FWriteIntM, FCvtIntW, // FPU writes integer register file, FPU converts float to int
@ -56,12 +57,14 @@ module datapath (
output logic [`XLEN-1:0] WriteDataM, // Write data in Memory stage
// Writeback stage signals
input logic StallW, FlushW, // Stall, flush Writeback stage
(* mark_debug = "true" *) input logic RegWriteW, IntDivW, // Write register file, integer divide instruction
input logic RegWriteW, IntDivW, // Write register file, integer divide instruction
input logic SquashSCW, // Squash a store conditional when a conflict arose
input logic [2:0] ResultSrcW, // Select source of result to write back to register file
input logic [`XLEN-1:0] FCvtIntResW, // FPU convert fp to integer result
input logic [`XLEN-1:0] ReadDataW, // Read data from LSU
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, // CSR read result, MDU (Multiply/divide unit) result
input logic [`XLEN-1:0] CSRReadValW, // CSR read result
input logic [`XLEN-1:0] MDUResultW, // MDU (Multiply/divide unit) result
input logic [`XLEN-1:0] BMUResultE, // bit manipulation unit result
input logic [`XLEN-1:0] FIntDivResultW, // FPU's integer divide result
// Hazard Unit signals
output logic [4:0] Rs1D, Rs2D, Rs1E, Rs2E, // Register sources to read in Decode or Execute stage
@ -78,6 +81,7 @@ module datapath (
logic [`XLEN-1:0] ImmExtE; // Extended immediate in Execute stage
logic [`XLEN-1:0] SrcAE, SrcBE; // ALU operands
logic [`XLEN-1:0] ALUResultE, AltResultE, IEUResultE; // ALU result, Alternative result (ImmExtE or PC+4), result of execution stage
logic [`XLEN-1:0] IEUBResultE; // IEUResultE before optional bit manipulation mux
// Memory stage signals
logic [`XLEN-1:0] IEUResultM; // Result from execution stage
logic [`XLEN-1:0] IFResultM; // Result from either IEU or single-cycle FPU op writing an integer register
@ -110,7 +114,10 @@ module datapath (
mux2 #(`XLEN) srcbmux(ForwardedSrcBE, ImmExtE, ALUSrcBE, SrcBE);
alu #(`XLEN) alu(SrcAE, SrcBE, ALUControlE, Funct3E, ALUResultE, IEUAdrE);
mux2 #(`XLEN) altresultmux(ImmExtE, PCLinkE, JumpE, AltResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUResultE);
mux2 #(`XLEN) ieuresultmux(ALUResultE, AltResultE, ALUResultSrcE, IEUBResultE);
if (`B_SUPPORTED)
mux2 #(`XLEN) bmuresultmux(IEUResultE, BMUResultE, BMUE, IEUResultE);
else assign IEUResultE = IEUBResultE;
// Memory stage pipeline register
flopenrc #(`XLEN) SrcAMReg(clk, reset, FlushM, ~StallM, SrcAE, SrcAM);

View file

@ -43,6 +43,7 @@ module ieu (
output logic IntDivE, W64E, // Integer divide, RV64 W-type instruction
output logic [2:0] Funct3E, // Funct3 instruction field
output logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE, // ALU src inputs before the mux choosing between them and PCE to put in srcA/B
input logic BMUE, // This is a bit manipulation instruction
output logic [4:0] RdE, // Destination register
// Memory stage signals
input logic SquashSCW, // Squash store conditional, from LSU
@ -56,8 +57,10 @@ module ieu (
output logic InvalidateICacheM, FlushDCacheM, // Invalidate I$, flush D$
output logic InstrValidM, // Instruction is valid
// Writeback stage signals
input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt
input logic [`XLEN-1:0] CSRReadValW, MDUResultW, // CSR read value, MDU (multiply/divide unit) result
input logic [`XLEN-1:0] FIntDivResultW, // Integer divide result from FPU fdivsqrt)
input logic [`XLEN-1:0] CSRReadValW, // CSR read value,
input logic [`XLEN-1:0] MDUResultW, // multiply/divide unit result
input logic [`XLEN-1:0] BMUResultE, // bit manipulation unit result
input logic [`XLEN-1:0] FCvtIntResW, // FPU's float to int conversion result
input logic FCvtIntW, // FPU converts float to int
output logic [4:0] RdW, // Destination register
@ -102,10 +105,10 @@ module ieu (
datapath dp(
.clk, .reset, .ImmSrcD, .InstrD, .StallE, .FlushE, .ForwardAE, .ForwardBE,
.ALUControlE, .Funct3E, .ALUSrcAE, .ALUSrcBE, .ALUResultSrcE, .JumpE, .BranchSignedE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE,
.PCE, .PCLinkE, .FlagsE, .IEUAdrE, .ForwardedSrcAE, .ForwardedSrcBE, .BMUE,
.StallM, .FlushM, .FWriteIntM, .FIntResM, .SrcAM, .WriteDataM, .FCvtIntW,
.StallW, .FlushW, .RegWriteW, .IntDivW, .SquashSCW, .ResultSrcW, .ReadDataW, .FCvtIntResW,
.CSRReadValW, .MDUResultW, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
.CSRReadValW, .MDUResultW, .BMUResultE, .FIntDivResultW, .Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW);
forward fw(
.Rs1D, .Rs2D, .Rs1E, .Rs2E, .RdE, .RdM, .RdW,

View file

@ -38,7 +38,7 @@ module regfile (
localparam NUMREGS = `E_SUPPORTED ? 16 : 32; // only 16 registers in E mode
(* mark_debug = "true" *) logic [`XLEN-1:0] rf[NUMREGS-1:1];
logic [`XLEN-1:0] rf[NUMREGS-1:1];
integer i;
// Three ported register file

View file

@ -28,32 +28,32 @@
`include "wally-config.vh"
module ifu (
input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW,
(* mark_debug = "true" *) output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation
input logic clk, reset,
input logic StallF, StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW,
output logic IFUStallF, // IFU stalsl pipeline during a multicycle operation
// Command from CPU
input logic InvalidateICacheM, // Clears all instruction cache valid bits
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
input logic InvalidateICacheM, // Clears all instruction cache valid bits
input logic CSRWriteFenceM, // CSR write or fence instruction, PCNextF = the next valid PC (typically PCE)
// Bus interface
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
(* mark_debug = "true" *) input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
(* mark_debug = "true" *) input logic IFUHREADY, // Bus ready from IFU to EBU
(* mark_debug = "true" *) output logic IFUHWRITE, // Bus write operation from IFU to EBU
(* mark_debug = "true" *) output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
(* mark_debug = "true" *) output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
(* mark_debug = "true" *) output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
output logic [`PA_BITS-1:0] IFUHADDR, // Bus address from IFU to EBU
input logic [`XLEN-1:0] HRDATA, // Bus read data from IFU to EBU
input logic IFUHREADY, // Bus ready from IFU to EBU
output logic IFUHWRITE, // Bus write operation from IFU to EBU
output logic [2:0] IFUHSIZE, // Bus operation size from IFU to EBU
output logic [2:0] IFUHBURST, // Bus burst from IFU to EBU
output logic [1:0] IFUHTRANS, // Bus transaction type from IFU to EBU
(* mark_debug = "true" *) output logic [`XLEN-1:0] PCF, // Fetch stage instruction address
// Execute
output logic [`XLEN-1:0] PCF, // Fetch stage instruction address
// Execute
output logic [`XLEN-1:0] PCLinkE, // The address following the branch instruction. (AKA Fall through address)
input logic PCSrcE, // Executation stage branch is taken
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
input logic PCSrcE, // Executation stage branch is taken
input logic [`XLEN-1:0] IEUAdrE, // The branch/jump target address
output logic [`XLEN-1:0] PCE, // Execution stage instruction address
output logic BPPredWrongE, // Prediction is wrong
// Mem
// Mem
output logic CommittedF, // I$ or bus memory operation started, delay interrupts
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
input logic [`XLEN-1:0] UnalignedPCNextF, // The next PCF, but not aligned to 2 bytes.
output logic [`XLEN-1:0] PCNext2F, // Selected PC between branch prediction and next valid PC if CSRWriteFence
output logic [31:0] InstrD, // The decoded instruction in Decode stage
output logic [31:0] InstrM, // The decoded instruction in Memory stage
@ -91,7 +91,7 @@ module ifu (
localparam [31:0] nop = 32'h00000013; // instruction for NOP
(* mark_debug = "true" *) logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
logic [`XLEN-1:0] PCNextF; // Next PCF, selected from Branch predictor, Privilege, or PC+2/4
logic BranchMisalignedFaultE; // Branch target not aligned to 4 bytes if no compressed allowed (2 bytes if allowed)
logic [`XLEN-1:0] PCPlus2or4F; // PCF + 2 (CompressedF) or PCF + 4 (Non-compressed)
logic [`XLEN-1:0] PCNextFSpill; // Next PCF after possible + 2 to handle spill
@ -100,14 +100,14 @@ module ifu (
logic [`XLEN-1:2] PCPlus4F; // PCPlus4F is always PCF + 4. Fancy way to compute PCPlus2or4F
logic [`XLEN-1:0] PCD; // Decode stage instruction address
logic [`XLEN-1:0] NextValidPCE; // The PC of the next valid instruction in the pipeline after csr write or fence
(* mark_debug = "true" *) logic [`PA_BITS-1:0] PCPF; // Physical address after address translation
logic [`PA_BITS-1:0] PCPF; // Physical address after address translation
logic [`XLEN+1:0] PCFExt; //
logic [31:0] IROMInstrF; // Instruction from the IROM
logic [31:0] ICacheInstrF; // Instruction from the I$
logic [31:0] InstrRawF; // Instruction from the IROM, I$, or bus
logic CompressedF; // The fetched instruction is compressed
(* mark_debug = "true" *) logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
logic [31:0] PostSpillInstrRawF; // Fetch instruction after merge two halves of spill
logic [31:0] InstrRawD; // Non-decompressed instruction in the Decode stage
logic [1:0] IFURWF; // IFU alreays read IFURWF = 10

View file

@ -58,7 +58,7 @@ module spill #(
logic SpillSaveF;
logic [15:0] InstrFirstHalf;
typedef enum logic [1:0] {STATE_READY, STATE_SPILL} statetype;
(* mark_debug = "true" *) statetype CurrState, NextState;
statetype CurrState, NextState;
////////////////////////////////////////////////////////////////////////////////////////////////////
// PC logic

View file

@ -47,8 +47,8 @@ module lsu (
output logic DCacheAccess, // D cache memory access for performance counters
// address and write data
input logic [`XLEN-1:0] IEUAdrE, // Execution stage memory address
(* mark_debug = "true" *) output logic [`XLEN-1:0] IEUAdrM, // Memory stage memory address
(* mark_debug = "true" *) input logic [`XLEN-1:0] WriteDataM, // Write data from IEU
output logic [`XLEN-1:0] IEUAdrM, // Memory stage memory address
input logic [`XLEN-1:0] WriteDataM, // Write data from IEU
output logic [`LLEN-1:0] ReadDataW, // Read data to IEU or FPU
// cpu privilege
input logic [1:0] PrivilegeModeW, // Current privilege mode
@ -66,15 +66,15 @@ module lsu (
output logic StoreAmoMisalignedFaultM, // Store or AMO address misaligned fault
output logic StoreAmoAccessFaultM, // Store or AMO access fault
// connect to ahb
(* mark_debug = "true" *) output logic [`PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU
(* mark_debug = "true" *) input logic [`XLEN-1:0] HRDATA, // Bus read data from LSU to EBU
(* mark_debug = "true" *) output logic [`XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU
(* mark_debug = "true" *) input logic LSUHREADY, // Bus ready from LSU to EBU
(* mark_debug = "true" *) output logic LSUHWRITE, // Bus write operation from LSU to EBU
(* mark_debug = "true" *) output logic [2:0] LSUHSIZE, // Bus operation size from LSU to EBU
(* mark_debug = "true" *) output logic [2:0] LSUHBURST, // Bus burst from LSU to EBU
(* mark_debug = "true" *) output logic [1:0] LSUHTRANS, // Bus transaction type from LSU to EBU
(* mark_debug = "true" *) output logic [`XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU
output logic [`PA_BITS-1:0] LSUHADDR, // Bus address from LSU to EBU
input logic [`XLEN-1:0] HRDATA, // Bus read data from LSU to EBU
output logic [`XLEN-1:0] LSUHWDATA, // Bus write data from LSU to EBU
input logic LSUHREADY, // Bus ready from LSU to EBU
output logic LSUHWRITE, // Bus write operation from LSU to EBU
output logic [2:0] LSUHSIZE, // Bus operation size from LSU to EBU
output logic [2:0] LSUHBURST, // Bus burst from LSU to EBU
output logic [1:0] LSUHTRANS, // Bus transaction type from LSU to EBU
output logic [`XLEN/8-1:0] LSUHWSTRB, // Bus byte write enables from LSU to EBU
// page table walker
input logic [`XLEN-1:0] SATP_REGW, // SATP (supervisor address translation and protection) CSR
input logic STATUS_MXR, STATUS_SUM, STATUS_MPRV, // STATUS CSR bits: make executable readable, supervisor user memory, machine privilege
@ -93,7 +93,7 @@ module lsu (
logic [`XLEN+1:0] IEUAdrExtM; // Memory stage address zero-extended to PA_BITS or XLEN whichever is longer
logic [`XLEN+1:0] IEUAdrExtE; // Execution stage address zero-extended to PA_BITS or XLEN whichever is longer
logic [`PA_BITS-1:0] PAdrM; // Physical memory address
(* mark_debug = "true" *) logic [`XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address
logic [`XLEN+1:0] IHAdrM; // Either IEU or HPTW memory address
logic [1:0] PreLSURWM; // IEU or HPTW Read/Write signal
logic [1:0] LSURWM; // IEU or HPTW Read/Write signal gated by LR/SC

View file

@ -53,7 +53,7 @@ module hptw (
input logic DataDAPageFaultM,
output logic [`XLEN-1:0] PTE, // page table entry to TLBs
output logic [1:0] PageType, // page type to TLBs
(* mark_debug = "true" *) output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic ITLBWriteF, DTLBWriteM, // write TLB with new entry
output logic [1:0] PreLSURWM,
output logic [`XLEN+1:0] IHAdrM,
output logic [`XLEN-1:0] IHWriteDataM,
@ -67,36 +67,36 @@ module hptw (
output logic LoadAccessFaultM, StoreAmoAccessFaultM, HPTWInstrAccessFaultM
);
typedef enum logic [3:0] {L0_ADR, L0_RD,
typedef enum logic [3:0] {L0_ADR, L0_RD,
L1_ADR, L1_RD,
L2_ADR, L2_RD,
L3_ADR, L3_RD,
LEAF, IDLE, UPDATE_PTE} statetype;
logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`PPN_BITS-1:0] CurrentPPN;
logic Executable, Writable, Readable, Valid, PTE_U;
logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
logic StartWalk;
logic TLBMiss;
logic PRegEn;
logic [1:0] NextPageType;
logic [`SVMODE_BITS-1:0] SvMode;
logic [`XLEN-1:0] TranslationVAdr;
logic [`XLEN-1:0] NextPTE;
logic UpdatePTE;
logic DAPageFault;
logic [`PA_BITS-1:0] HPTWReadAdr;
logic SelHPTWAdr;
logic [`XLEN+1:0] HPTWAdrExt;
logic ITLBMissOrDAFaultF;
logic DTLBMissOrDAFaultM;
logic [`PA_BITS-1:0] HPTWAdr;
logic [1:0] HPTWRW;
logic [2:0] HPTWSize; // 32 or 64 bit access
(* mark_debug = "true" *) statetype WalkerState, NextWalkerState, InitialWalkerState;
logic DTLBWalk; // register TLBs translation miss requests
logic [`PPN_BITS-1:0] BasePageTablePPN;
logic [`PPN_BITS-1:0] CurrentPPN;
logic Executable, Writable, Readable, Valid, PTE_U;
logic Misaligned, MegapageMisaligned;
logic ValidPTE, LeafPTE, ValidLeafPTE, ValidNonLeafPTE;
logic StartWalk;
logic TLBMiss;
logic PRegEn;
logic [1:0] NextPageType;
logic [`SVMODE_BITS-1:0] SvMode;
logic [`XLEN-1:0] TranslationVAdr;
logic [`XLEN-1:0] NextPTE;
logic UpdatePTE;
logic DAPageFault;
logic [`PA_BITS-1:0] HPTWReadAdr;
logic SelHPTWAdr;
logic [`XLEN+1:0] HPTWAdrExt;
logic ITLBMissOrDAFaultF;
logic DTLBMissOrDAFaultM;
logic [`PA_BITS-1:0] HPTWAdr;
logic [1:0] HPTWRW;
logic [2:0] HPTWSize; // 32 or 64 bit access
statetype WalkerState, NextWalkerState, InitialWalkerState;
// map hptw access faults onto either the original LSU load/store fault or instruction access fault
assign LoadAccessFaultM = WalkerState == IDLE ? LSULoadAccessFaultM : (LSULoadAccessFaultM | LSUStoreAmoAccessFaultM) & DTLBWalk & MemRWM[1] & ~MemRWM[0];

View file

@ -86,11 +86,11 @@ module csr #(parameter
);
logic [`XLEN-1:0] CSRMReadValM, CSRSReadValM, CSRUReadValM, CSRCReadValM;
(* mark_debug = "true" *) logic [`XLEN-1:0] CSRReadValM;
(* mark_debug = "true" *) logic [`XLEN-1:0] CSRSrcM;
logic [`XLEN-1:0] CSRReadValM;
logic [`XLEN-1:0] CSRSrcM;
logic [`XLEN-1:0] CSRRWM, CSRRSM, CSRRCM;
(* mark_debug = "true" *) logic [`XLEN-1:0] CSRWriteValM;
(* mark_debug = "true" *) logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
logic [`XLEN-1:0] CSRWriteValM;
logic [`XLEN-1:0] MSTATUS_REGW, SSTATUS_REGW, MSTATUSH_REGW;
logic [`XLEN-1:0] STVEC_REGW, MTVEC_REGW;
logic [`XLEN-1:0] MEPC_REGW, SEPC_REGW;
logic [31:0] MCOUNTINHIBIT_REGW, MCOUNTEREN_REGW, SCOUNTEREN_REGW;

View file

@ -63,7 +63,7 @@ module csrc #(parameter
);
logic [4:0] CounterNumM;
(* mark_debug = "true" *) logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0];
logic [`XLEN-1:0] HPMCOUNTER_REGW[`COUNTERS-1:0];
logic [`XLEN-1:0] HPMCOUNTERH_REGW[`COUNTERS-1:0];
logic LoadStallE, LoadStallM;
logic [`COUNTERS-1:0] WriteHPMCOUNTERM;

View file

@ -39,9 +39,9 @@ module csri #(parameter
input logic CSRMWriteM, CSRSWriteM,
input logic [`XLEN-1:0] CSRWriteValM,
input logic [11:0] CSRAdrM,
(* mark_debug = "true" *) input logic MExtInt, SExtInt, MTimerInt, MSwInt,
input logic MExtInt, SExtInt, MTimerInt, MSwInt,
output logic [11:0] MIP_REGW, MIE_REGW,
(* mark_debug = "true" *) output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
output logic [11:0] MIP_REGW_writeable // only SEIP, STIP, SSIP are actually writeable; the rest are hardwired to 0
);
logic [11:0] MIP_WRITE_MASK, SIP_WRITE_MASK, MIE_WRITE_MASK;

View file

@ -78,12 +78,12 @@ module csrm #(parameter
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, MSTATUS_REGW, MSTATUSH_REGW,
input logic [`XLEN-1:0] CSRWriteValM,
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW,
input logic [11:0] MIP_REGW, MIE_REGW,
output logic [`XLEN-1:0] CSRMReadValM, MTVEC_REGW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] MEPC_REGW,
output logic [`XLEN-1:0] MEPC_REGW,
output logic [31:0] MCOUNTEREN_REGW, MCOUNTINHIBIT_REGW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] MEDELEG_REGW,
(* mark_debug = "true" *) output logic [11:0] MIDELEG_REGW,
output logic [`XLEN-1:0] MEDELEG_REGW,
output logic [11:0] MIDELEG_REGW,
output var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0],
output var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0],
output logic WriteMSTATUSM, WriteMSTATUSHM,
@ -91,8 +91,8 @@ module csrm #(parameter
);
logic [`XLEN-1:0] MISA_REGW, MHARTID_REGW;
(* mark_debug = "true" *) logic [`XLEN-1:0] MSCRATCH_REGW;
(* mark_debug = "true" *) logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW;
logic [`XLEN-1:0] MSCRATCH_REGW;
logic [`XLEN-1:0] MCAUSE_REGW, MTVAL_REGW;
logic WriteMTVECM, WriteMEDELEGM, WriteMIDELEGM;
logic WriteMSCRATCHM, WriteMEPCM, WriteMCAUSEM, WriteMTVALM;
logic WriteMCOUNTERENM, WriteMCOUNTINHIBITM;

View file

@ -42,21 +42,21 @@ module csrs #(parameter
STVAL = 12'h143,
SIP= 12'h144,
SATP = 12'h180) (
input logic clk, reset,
input logic InstrValidNotFlushedM,
input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
input logic STATUS_TVM,
input logic [`XLEN-1:0] CSRWriteValM,
input logic [1:0] PrivilegeModeW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
(* mark_debug = "true" *) output logic [`XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SATP_REGW,
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
output logic WriteSSTATUSM,
output logic IllegalCSRSAccessM
input logic clk, reset,
input logic InstrValidNotFlushedM,
input logic CSRSWriteM, STrapM,
input logic [11:0] CSRAdrM,
input logic [`XLEN-1:0] NextEPCM, NextCauseM, NextMtvalM, SSTATUS_REGW,
input logic STATUS_TVM,
input logic [`XLEN-1:0] CSRWriteValM,
input logic [1:0] PrivilegeModeW,
output logic [`XLEN-1:0] CSRSReadValM, STVEC_REGW,
output logic [`XLEN-1:0] SEPC_REGW,
output logic [31:0] SCOUNTEREN_REGW,
output logic [`XLEN-1:0] SATP_REGW,
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW,
output logic WriteSSTATUSM,
output logic IllegalCSRSAccessM
);
// Constants
@ -66,8 +66,8 @@ module csrs #(parameter
logic WriteSTVECM;
logic WriteSSCRATCHM, WriteSEPCM;
logic WriteSCAUSEM, WriteSTVALM, WriteSATPM, WriteSCOUNTERENM;
(* mark_debug = "true" *) logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
(* mark_debug = "true" *) logic [`XLEN-1:0] SCAUSE_REGW;
logic [`XLEN-1:0] SSCRATCH_REGW, STVAL_REGW;
logic [`XLEN-1:0] SCAUSE_REGW;
// write enables
assign WriteSSTATUSM = CSRSWriteM & (CSRAdrM == SSTATUS) & InstrValidNotFlushedM;

View file

@ -34,7 +34,7 @@ module privileged (
input logic StallD, StallE, StallM, StallW,
input logic FlushD, FlushE, FlushM, FlushW,
// CSR Reads and Writes, and values needed for traps
(* mark_debug = "true" *) input logic CSRReadM, CSRWriteM, // Read or write CSRs
input logic CSRReadM, CSRWriteM, // Read or write CSRs
input logic [`XLEN-1:0] SrcAM, // GPR register to write
input logic [31:0] InstrM, // Instruction
input logic [`XLEN-1:0] IEUAdrM, // address from IEU
@ -104,7 +104,7 @@ module privileged (
logic DelegateM; // trap should be delegated
logic wfiM; // wait for interrupt instruction
logic IntPendingM; // interrupt is pending, even if not enabled. ends wfi
(* mark_debug = "true" *) logic InterruptM; // interrupt occuring
logic InterruptM; // interrupt occuring
// track the current privilege level

View file

@ -30,14 +30,14 @@
module trap (
input logic reset,
(* mark_debug = "true" *) input logic InstrMisalignedFaultM, InstrAccessFaultM, HPTWInstrAccessFaultM, IllegalInstrFaultM,
(* mark_debug = "true" *) input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
(* mark_debug = "true" *) input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
(* mark_debug = "true" *) input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources
(* mark_debug = "true" *) input logic mretM, sretM, // return instructions
input logic InstrMisalignedFaultM, InstrAccessFaultM, HPTWInstrAccessFaultM, IllegalInstrFaultM,
input logic BreakpointFaultM, LoadMisalignedFaultM, StoreAmoMisalignedFaultM,
input logic LoadAccessFaultM, StoreAmoAccessFaultM, EcallFaultM, InstrPageFaultM,
input logic LoadPageFaultM, StoreAmoPageFaultM, // various trap sources
input logic mretM, sretM, // return instructions
input logic wfiM, // wait for interrupt instruction
input logic [1:0] PrivilegeModeW, // current privilege mode
(* mark_debug = "true" *) input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs
input logic [11:0] MIP_REGW, MIE_REGW, MIDELEG_REGW, // interrupt pending, enabled, and delegate CSRs
input logic [`XLEN-1:0] MEDELEG_REGW, // exception delegation SR
input logic STATUS_MIE, STATUS_SIE, // machine/supervisor interrupt enables
input logic InstrValidM, // current instruction is valid, not flushed
@ -55,7 +55,7 @@ module trap (
logic ExceptionM; // exception is occurring
logic Committed; // LSU or IFU has committed to a bus operation that can't be interrupted
logic BothInstrAccessFaultM; // instruction or HPTW ITLB fill caused an Instruction Access Fault
(* mark_debug = "true" *) logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
logic [11:0] PendingIntsM, ValidIntsM, EnabledIntsM; // interrupts are pending, valid, or enabled
///////////////////////////////////////////
// Determine pending enabled interrupts

View file

@ -39,14 +39,14 @@ module clint_apb (
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic PREADY,
(* mark_debug = "true" *) output logic [63:0] MTIME,
output logic [63:0] MTIME,
output logic MTimerInt, MSwInt
);
logic MSIP;
logic [15:0] entry;
logic memwrite;
(* mark_debug = "true" *) logic [63:0] MTIMECMP;
logic [63:0] MTIMECMP;
integer i, j;
assign memwrite = PWRITE & PENABLE & PSEL; // only write in access phase

View file

@ -53,27 +53,27 @@ module plic_apb (
output logic [`XLEN-1:0] PRDATA,
output logic PREADY,
input logic UARTIntr,GPIOIntr,
(* mark_debug = "true" *) output logic MExtInt, SExtInt
output logic MExtInt, SExtInt
);
logic memwrite, memread;
logic [23:0] entry;
(* mark_debug = "true" *) logic [31:0] Din, Dout;
logic [31:0] Din, Dout;
// context-independent signals
(* mark_debug = "true" *) logic [`N:1] requests;
(* mark_debug = "true" *) logic [`N:1][2:0] intPriority;
(* mark_debug = "true" *) logic [`N:1] intInProgress, intPending, nextIntPending;
logic [`N:1] requests;
logic [`N:1][2:0] intPriority;
logic [`N:1] intInProgress, intPending, nextIntPending;
// context-dependent signals
(* mark_debug = "true" *) logic [`C-1:0][2:0] intThreshold;
(* mark_debug = "true" *) logic [`C-1:0][`N:1] intEn;
(* mark_debug = "true" *) logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
(* mark_debug = "true" *) logic [`C-1:0][7:1][`N:1] irqMatrix;
(* mark_debug = "true" *) logic [`C-1:0][7:1] priorities_with_irqs;
(* mark_debug = "true" *) logic [`C-1:0][7:1] max_priority_with_irqs;
(* mark_debug = "true" *) logic [`C-1:0][`N:1] irqs_at_max_priority;
(* mark_debug = "true" *) logic [`C-1:0][7:1] threshMask;
logic [`C-1:0][2:0] intThreshold;
logic [`C-1:0][`N:1] intEn;
logic [`C-1:0][5:0] intClaim; // ID's are 6 bits if we stay within 63 sources
logic [`C-1:0][7:1][`N:1] irqMatrix;
logic [`C-1:0][7:1] priorities_with_irqs;
logic [`C-1:0][7:1] max_priority_with_irqs;
logic [`C-1:0][`N:1] irqs_at_max_priority;
logic [`C-1:0][7:1] threshMask;
// =======
// AHB I/O

View file

@ -1,362 +0,0 @@
///////////////////////////////////////////
// SDC.sv
//
// Written: Ross Thompson September 22, 2021
// Modified:
//
// Purpose: SDC interface to AHBLite BUS.
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
`define SDCCLKDIV -8'd3
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 signed [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] SDCReadDataPreNibbleSwap;
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[1];
//assign RegRead = InitTrans & ~HWRITE;
// register resolve combo loop
flopr #(1) RegReadReg(HCLK, ~HRESETn, InitTrans & ~HWRITE, RegRead);
// 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);
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
flopen #(`XLEN) DataReg(HCLK, (HADDRDelay == 'h18 & RegWrite),
HWDATA, SDCWriteData);
assign InvalidCommand = (Command[2] | Command[1]) & Command[0];
assign Status = {ErrorCode, InvalidCommand, SDCBusy, SDCInitialized};
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
for(index = 0; index < 4096/`XLEN; index++) begin
assign ReadData512ByteWords[index] = ReadData512Byte[(index+1)*`XLEN-1:index*`XLEN];
end
assign SDCReadDataPreNibbleSwap = ReadData512ByteWords[WordCount];
if(`XLEN == 64) begin
assign SDCReadData = {SDCReadDataPreNibbleSwap[59:56], SDCReadDataPreNibbleSwap[63:60],
SDCReadDataPreNibbleSwap[51:48], SDCReadDataPreNibbleSwap[55:52],
SDCReadDataPreNibbleSwap[43:40], SDCReadDataPreNibbleSwap[47:44],
SDCReadDataPreNibbleSwap[35:32], SDCReadDataPreNibbleSwap[39:36],
SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
end else begin
assign SDCReadData = {SDCReadDataPreNibbleSwap[27:24], SDCReadDataPreNibbleSwap[31:28],
SDCReadDataPreNibbleSwap[19:16], SDCReadDataPreNibbleSwap[23:20],
SDCReadDataPreNibbleSwap[11:8], SDCReadDataPreNibbleSwap[15:12],
SDCReadDataPreNibbleSwap[3:0], SDCReadDataPreNibbleSwap[7:4]};
end
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(HADDRDelay[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
default: begin
NextState = STATE_READY;
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 <= 0), // enable if < 0 (msb is 1)
.i_CLK(CLKGate),
.i_RST(~HRESETn | CLKDivUpdateEn),
.o_CLK(SDCCLKIn));
// assign SDCCLKIn = CLKGate;
// should always be 0 for real implementation, but for simulation set to 1.
logic LimitTimers;
assign LimitTimers = '0;
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(LimitTimers)); // *** must change this to 0 for real hardware.
endmodule

View file

@ -1,43 +0,0 @@
///////////////////////////////////////////
// counter.sv
//
// Written: Richard Davis
// Modified: Ross Thompson
// Converted to SystemVerilog.
//
// Purpose: basic up counter
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module SDCcounter #(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;
assign NextCount = Load ? CountIn : (CountOut + 1'b1);
flopenr #(WIDTH) reg1(clk, reset, Enable | Load, NextCount, CountOut);
endmodule

View file

@ -1,105 +0,0 @@
///////////////////////////////////////////
// clock divider.sv
//
// Written: Richard Davis
// Modified: Ross Thompson September 18, 2021
// Converted to system verilog.
//
// Purpose: clock divider for sd flash
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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;
logic resetD, resetDD, resetPulse;
logic rstdd2, rstddn;
assign w_load = resetPulse | w_counter_overflowed; // reload when zero occurs or when set by outside
SDCcounter #(.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;
// to ensure the clock keeps running we need to make the reset last 1 cycle
// rather than until the reset is released. Alternatively we could do
// two resets. The first which resets this and the clk_fsm and the second
// which resets the rest of the design.
// Or we can make this clock divider not depend on reset.
flop #(1) pulseReset
(.d(i_RST),
.q(resetD),
.clk(i_CLK));
flop #(1) pulseReset2
(.d(resetD),
.q(resetDD),
.clk(i_CLK));
//assign resetPulse = i_RST & ~resetDD;
assign resetPulse = ~i_RST & resetDD;
assign rstdd2 = i_RST | resetDD;
flop #(1) fallingEdge
(.d(rstdd2),
.q(rstddn),
.clk(~i_CLK));
flopenr #(1) toggle_flip_flop
(.d(w_fd_D),
.q(r_fd_Q),
.clk(i_CLK),
.reset(resetPulse),
.en(w_counter_overflowed)); // only update when counter overflows
assign w_fd_D = ~ r_fd_Q;
/* -----\/----- EXCLUDED -----\/-----
if(`FPGA) BUFGMUX clkMux(.I1(r_fd_Q), .I0(i_CLK), .S(i_EN), .O(o_CLK));
else assign o_CLK = i_EN ? r_fd_Q : i_CLK;
-----/\----- EXCLUDED -----/\----- */
if(`FPGA) BUFGMUX clkMux(.I1(r_fd_Q), .I0(i_CLK), .S(i_EN & ~rstddn), .O(o_CLK));
else assign o_CLK = i_EN & ~rstddn ? r_fd_Q : i_CLK;
endmodule

View file

@ -1,63 +0,0 @@
///////////////////////////////////////////
// crc16 sipo np ce
//
// Written: Richard Davis
// Modified: Ross Thompson September 18, 2021
// Converted to system verilog.
//
// Purpose: CRC16 generator SIPO using register_ce
// w/o appending any zero-bits to the message
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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

View file

@ -1,67 +0,0 @@
///////////////////////////////////////////
// crc7 sipo np ce
//
// Written: Richard Davis
// Modified: Ross Thompson September 18, 2021
// Converted to system verilog.
//
// 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 CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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

View file

@ -1,60 +0,0 @@
///////////////////////////////////////////
// crc16 sipo np ce
//
// Written: Richard Davis
// Modified: Ross Thompson September 18, 2021
//
// Purpose: CRC7 generator SIPO using register_ce
// w/o appending any zero-bits othe message
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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

View file

@ -1,49 +0,0 @@
///////////////////////////////////////////
// piso generic ce
//
// Written: Richard Davis
// Modified: Ross Thompson September 18, 2021
//
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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

View file

@ -1,49 +0,0 @@
///////////////////////////////////////////
// regfile_p2r1w1_nibo
//
// Written: Ross Thompson September 18, 2021
// Modified: 2 port register file with 1 read and 1 write
//
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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

View file

@ -1,44 +0,0 @@
///////////////////////////////////////////
// regfile_p2r1w1bwen
//
// Written: Ross Thompson September 18, 2021
// Modified: 2 port register file with 1 read and 1 write
//
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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)
if (we1) // global write enable
regs[wa1] = wd1 & we1bit | regs[wa1] & ~we1bit; // bit write enable
assign rd1 = regs[ra1];
endmodule

View file

@ -1,93 +0,0 @@
///////////////////////////////////////////
// sd_clk_fsm.sv
//
// Written: Richard Davis
// Modified: Ross Thompson September 19, 2021
//
// 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 CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`include "wally-config.vh"
module sd_clk_fsm (
input logic CLK,
input logic i_RST,
(* mark_debug = "true" *)output logic o_DONE,
(* mark_debug = "true" *)input logic i_START,
(* mark_debug = "true" *)input logic i_FATAL_ERROR,
(* mark_debug = "true" *)output logic o_HS_TO_INIT_CLK_DIVIDER_RST, // resets clock divider that is going from 50 MHz to 400 KHz
(* mark_debug = "true" *)output logic o_SD_CLK_SELECTED, // which clock is selected ('0'=HS or '1'=init)
(* mark_debug = "true" *)output logic o_G_CLK_SD_EN // Turns gated clock (G_CLK_SD) off and on
);
logic [3:0] w_next_state;
(* mark_debug = "true" *) 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

View file

@ -1,586 +0,0 @@
///////////////////////////////////////////
// sd_clk_fsm.sv
//
// Written: Richard Davis
// Modified: Ross Thompson September 19, 2021
//
// Purpose: Finite state machine for the SD CMD bus
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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,
(* mark_debug = "true" *) 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
(* mark_debug = "true" *) input logic i_ERROR_CRC16, // repeat last command
(* mark_debug = "true" *) 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;
(* mark_debug = "true" *) logic [4:0] 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 = 1500; // 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
logic COUNTER_OUT_GT_ZERO;
logic COUNTER_OUT_GE_ZERO;
logic COUNTER_OUT_GT_8;
logic COUNTER_OUT_EQ_8;
logic COUNTER_OUT_EQ_ZERO;
logic TIMER_OUT_GT_ZERO;
logic TIMER_OUT_EQ_ZERO;
logic fail_count_out_le_max_attempts;
logic fail_count_out_lt_max_attempts;
logic fail_count_out_gt_max_attempts;
logic IC_OUT_EQ_2;
logic IC_OUT_EQ_3;
logic IC_OUT_LT_9;
logic IC_OUT_GE_9;
assign Timer_In = LIMIT_SD_TIMERS ? 19'b0000000000000000011 : 19'b0011000011010100000; // 250 ms
//Fail Counter, tracks how many failed attempts at command transmission
SDCcounter #(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 COUNTER_OUT_GT_ZERO = i_COUNTER_OUT > 0;
assign COUNTER_OUT_GE_ZERO = $signed(i_COUNTER_OUT) >= $signed(8'b0);
assign COUNTER_OUT_GT_8 = i_COUNTER_OUT > 8;
assign COUNTER_OUT_EQ_8 = i_COUNTER_OUT == 8;
assign COUNTER_OUT_EQ_ZERO = i_COUNTER_OUT == 0;
assign TIMER_OUT_GT_ZERO = i_TIMER_OUT > 0;
assign TIMER_OUT_EQ_ZERO = i_TIMER_OUT == 0;
assign fail_count_out_le_max_attempts = r_fail_count_out <= (c_MAX_ATTEMPTS-1);
assign fail_count_out_lt_max_attempts = r_fail_count_out < (c_MAX_ATTEMPTS-1);
assign fail_count_out_gt_max_attempts = r_fail_count_out > (c_MAX_ATTEMPTS-1);
assign IC_OUT_EQ_2 = i_IC_OUT == 2;
assign IC_OUT_EQ_3 = i_IC_OUT == 3;
assign IC_OUT_LT_9 = i_IC_OUT < 9;
assign IC_OUT_GE_9 = i_IC_OUT >= 9;
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) & (TIMER_OUT_GT_ZERO))) ? s_idle_supply_no_clk :
(((r_curr_state == s_idle_supply_no_clk) & (TIMER_OUT_EQ_ZERO)) |
((r_curr_state == s_idle_supply_sd_clk) & (COUNTER_OUT_GT_ZERO))) ? s_idle_supply_sd_clk :
(r_curr_state == s_ld_head) ? s_count_attempt :
(((r_curr_state == s_count_attempt) & (fail_count_out_le_max_attempts)) |
((r_curr_state == s_count_attempt) &
(((IC_OUT_EQ_2) & (i_OPCODE[5:0] == c_App_Command)) |
((IC_OUT_EQ_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)
& (fail_count_out_gt_max_attempts))) ? s_tx_head :
((r_curr_state == s_count_attempt) & (fail_count_out_gt_max_attempts)) ? s_Error_TX_Failed :
((r_curr_state == s_tx_head) | ((r_curr_state == s_ld_tail) & (COUNTER_OUT_GT_8))) ? s_ld_tail :
(((r_curr_state == s_ld_tail) & (COUNTER_OUT_EQ_8)) |
((r_curr_state == s_tx_tail) & (COUNTER_OUT_GT_ZERO))) ? s_tx_tail :
(r_curr_state == s_tx_tail) & (COUNTER_OUT_EQ_ZERO) ? s_setup_rx :
(((r_curr_state == s_setup_rx) & (i_R_TYPE == c_response_type_R0_NONE)) |
((r_curr_state == s_idle_ncc) & (COUNTER_OUT_GT_ZERO))) ? 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) &
(COUNTER_OUT_GT_ZERO))) ? s_idle_for_start_bit :
((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX != c_start_bit) &
(COUNTER_OUT_EQ_ZERO)) ? s_error_no_response :
(((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) &
/* verilator lint_off UNSIGNED */
(COUNTER_OUT_GE_ZERO) & (i_R_TYPE == c_response_type_R2_CID_CSD)) |
/* verilator lint_on UNSIGNED */
((r_curr_state == s_rx_136) & (COUNTER_OUT_GT_ZERO))) ? s_rx_136 :
(((r_curr_state == s_idle_for_start_bit) & (i_SD_CMD_RX == c_start_bit) &
/* verilator lint_off UNSIGNED */
(COUNTER_OUT_GE_ZERO) & (i_R_TYPE != c_response_type_R2_CID_CSD)) |
/* verilator lint_on UNSIGNED */
((r_curr_state == s_rx_48) & (COUNTER_OUT_GT_ZERO))) ? s_rx_48 :
(((r_curr_state == s_rx_136) & (COUNTER_OUT_EQ_ZERO)) |
((r_curr_state == s_rx_48) & COUNTER_OUT_EQ_ZERO)) ? 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) & (COUNTER_OUT_GT_ZERO))) ? s_idle_nrc :
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
(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) & (COUNTER_OUT_EQ_ZERO)) |
((r_curr_state == s_fetch_next_cmd) & // before CMD17
(IC_OUT_LT_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) & (COUNTER_OUT_EQ_ZERO) &
(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) & (COUNTER_OUT_EQ_ZERO) &
(~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) & (COUNTER_OUT_EQ_ZERO)) |
((r_curr_state == s_idle_nrc) & (COUNTER_OUT_EQ_ZERO) &
(~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) &
(IC_OUT_GE_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

View file

@ -1,253 +0,0 @@
///////////////////////////////////////////
// sd_dat_fsm.sv
//
// Written: Richard Davis
// Modified: Ross Thompson September 19, 2021
//
// 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 CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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
(* mark_debug = "true" *)output logic o_CRC16_EN, o_CRC16_RST, // shared signals for all 4 CRC16_SIPO (one for each of 4 DAT lines)
(* mark_debug = "true" *)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
(* mark_debug = "true" *)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
(* mark_debug = "true" *)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
(* mark_debug = "true" *)input logic i_CMD_TX_DONE, // command transmission completed, begin waiting for DATA
(* mark_debug = "true" *)output logic o_DAT_RX_DONE, // tell SD_CMD_FSM that DAT communication is completed, send next instruction to sd card
(* mark_debug = "true" *)output logic o_ERROR_DAT_TIMES_OUT, // error flag for when DAT times out (so don't fetch more instructions)
(* mark_debug = "true" *)output logic o_DAT_ERROR_FD_RST,
(* mark_debug = "true" *)output logic o_DAT_ERROR_FD_EN, // tell SD_CMD_FSM to resend command due to error in transmission
input logic LIMIT_SD_TIMERS
);
(* mark_debug = "true" *) logic [3:0] r_curr_state;
logic [3:0] w_next_state;
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)
logic TIMER_OUT_GT_0;
logic TIMER_OUT_EQ_0;
logic COUNTER_OUT_EQ_1023;
logic COUNTER_OUT_LT_1023;
logic COUNTER_OUT_LT_128;
logic COUNTER_OUT_EQ_128;
logic COUNTER_OUT_LT_144;
logic COUNTER_OUT_EQ_144;
logic COUNTER_OUT_LT_1040;
logic COUNTER_OUT_EQ_1040;
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 TIMER_OUT_GT_0 = i_TIMER_OUT > 0;
assign TIMER_OUT_EQ_0 = i_TIMER_OUT == 0;
assign COUNTER_OUT_EQ_1023 = i_COUNTER_OUT == 1023;
assign COUNTER_OUT_LT_1023 = i_COUNTER_OUT < 1023;
assign COUNTER_OUT_LT_128 = i_COUNTER_OUT < 128;
assign COUNTER_OUT_EQ_128 = i_COUNTER_OUT == 128;
assign COUNTER_OUT_LT_144 = i_COUNTER_OUT < 144;
assign COUNTER_OUT_EQ_144 = i_COUNTER_OUT == 144;
assign COUNTER_OUT_LT_1040 = i_COUNTER_OUT < 1040;
assign COUNTER_OUT_EQ_1040 = i_COUNTER_OUT == 1040;
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) & (COUNTER_OUT_EQ_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) & (TIMER_OUT_GT_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,
(TIMER_OUT_EQ_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) & (TIMER_OUT_GT_0) &
(i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_busy)) |
((r_curr_state == s_read_r1b) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_busy_bit))) ? s_read_r1b :
(((r_curr_state == s_read_r1b) & (TIMER_OUT_EQ_0)) |
((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_EQ_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) & (TIMER_OUT_GT_0) & (i_DAT0_Q == c_start_bit) &
(i_USES_DAT == c_DAT_wide)) |
((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_LT_128))) ? s_rx_wide_data :
(((r_curr_state == s_idle_for_start_bit) & (TIMER_OUT_GT_0) &
(i_DAT0_Q == c_start_bit) & (i_USES_DAT == c_DAT_block)) |
((r_curr_state == s_rx_block_data) & (COUNTER_OUT_LT_1023))) ? s_rx_block_data :
(((r_curr_state == s_rx_wide_data) & (COUNTER_OUT_EQ_128)) |
((r_curr_state == s_rx_block_data) & (COUNTER_OUT_EQ_1023)) |
((r_curr_state == s_rx_crc16) &
(((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_LT_144)) |
((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_LT_1040))))) ? s_rx_crc16 :
((r_curr_state == s_rx_crc16) &
(((i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144)) |
((i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_1040))) &
(~i_DATA_CRC16_GOOD)) ? s_error_crc16_fail :
((r_curr_state == s_rx_crc16) & (i_USES_DAT == c_DAT_wide) & (COUNTER_OUT_EQ_144) &
(i_DATA_CRC16_GOOD)) ? s_publish_wide_data :
((r_curr_state == s_rx_crc16) &
(i_USES_DAT == c_DAT_block) & (COUNTER_OUT_EQ_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)
& (COUNTER_OUT_EQ_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

View file

@ -1,652 +0,0 @@
///////////////////////////////////////////
// sd_top.sv
//
// Written: Richard Davis
// Modified: Ross Thompson September 19, 2021
//
// Purpose: SD card controller
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
/// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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
(* mark_debug = "true" *)input logic i_SD_CMD, // CMD Response from card
(* mark_debug = "true" *)output logic o_SD_CMD, // CMD Command from host
(* mark_debug = "true" *)output logic o_SD_CMD_OE, // Direction of SD_CMD
(* mark_debug = "true" *)input logic [3:0] i_SD_DAT, // SD DAT Bus
(* mark_debug = "true" *)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; //32'h80000000; // SD_Send_OCR
localparam logic [127:96] c_ACMD41_ans_dont_redo = 32'h80000000; //32'h80000000;
localparam logic [127:96] c_ACMD41_mask_check_error_bits = 32'h41FF8000; // 32'h41FF8000;
localparam logic [127:96] c_ACMD41_ans_error_free = 32'h40FF8000; // 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;
(* mark_debug = "true" *)logic w_IC_RST, w_IC_EN, w_IC_UP_DOWN;
(* mark_debug = "true" *)logic w_SD_CMD_OE;
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_RX_SIPO48_RST, w_RX_SIPO48_EN;
(* mark_debug = "true" *)logic [39:8] r_RESPONSE_CONTENT;
(* mark_debug = "true" *)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;
(* mark_debug = "true" *)logic r_DAT_ERROR_Q; // CRC16 error or time out
(* mark_debug = "true" *)logic w_NOT_DAT_ERROR_Q; // '0'=no error, '1'=tx error on DAT bus
(* mark_debug = "true" *)logic w_ERROR_DAT_TIMES_OUT;
(* mark_debug = "true" *)logic w_FATAL_ERROR;
(* mark_debug = "true" *)logic [2:0] r_ERROR_CODE_Q; // indicates which fatal error occured
// Communication with core
(* mark_debug = "true" *)logic w_READY_FOR_READ;
(* mark_debug = "true" *)logic w_READ_REQUEST;
(* mark_debug = "true" *)logic [3:0] r_DATA_TO_CORE;
(* mark_debug = "true" *)logic w_DATA_VALID;
(* mark_debug = "true" *)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 [22:0] w_DAT_TIMER_IN;
logic [22:0] r_DAT_TIMER_OUT;
logic [10:0] r_DAT_COUNTER_OUT;
(* mark_debug = "true" *)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 ;
(* mark_debug = "true" *)logic [6:0] w_OPCODE_Q ;
// TOP_LEVEL Connections
logic [40:9] w_BLOCK_ADDR ;
(* mark_debug = "true" *)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
// 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;
// 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 [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
SDCcounter #(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 | a_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_EN(1'b1),
//.i_RST(w_HS_TO_INIT_CLK_DIVIDER_RST),
.i_RST(a_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 | a_RST),
.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;
flopenr #(1) sd_cmd_out_reg
(.d(w_SD_CMD_TX_Q),
.q(o_SD_CMD),
.en(1'b1),
.clk(~r_G_CLK_SD),
.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),
.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

View file

@ -1,98 +0,0 @@
///////////////////////////////////////////
// sd_top_wrapper.sv
//
// Written: Richard Davis
// Modified: Ross Thompson September 19, 2021
//
// Purpose: SD card controller wrapper
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
/// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the License); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an AS IS BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
module sd_top_wrapper #(parameter g_COUNT_WIDTH = 8) (
input logic clk_in1_p,
input logic clk_in1_n,
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
inout SD_CMD, // CMD Response from card
input logic [3:0] i_SD_DAT, // SD DAT Bus
output logic o_SD_CLK, // SD CLK Bus
// For communication with core cpu
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 being published
output logic o_DATA_VALID // held high while data being read to core to indicate that it is valid
);
wire CLK;
wire LIMIT_SD_TIMERS;
wire [g_COUNT_WIDTH-1:0] i_COUNT_IN_MAX;
wire [4095:0] ReadData; // full 512 bytes to Bus
wire [32:9] i_BLOCK_ADDR; // see "Addressing" in parts.fods (only 8GB total capacity is used)
wire o_SD_CMD; // CMD Command from host
wire i_SD_CMD; // CMD Command from host
wire o_SD_CMD_OE; // Direction of SD_CMD
wire [2:0] o_ERROR_CODE_Q; // indicates which error occured
wire o_FATAL_ERROR; // indicates that the FATAL ERROR register has updated
wire o_LAST_NIBBLE; // pulse when last nibble is sent
assign LIMIT_SD_TIMERS = 1'b0;
assign i_COUNT_IN_MAX = -8'd62;
assign i_BLOCK_ADDR = 23'h0;
clk_wiz_0 clk_wiz_0(.clk_in1_p(clk_in1_p),
.clk_in1_n(clk_in1_n),
.reset(1'b0),
.clk_out1(CLK),
.locked(locked));
IOBUF SDCMDIODriver(.T(~o_SD_CMD_OE),
.I(o_SD_CMD),
.O(i_SD_CMD),
.IO(SD_CMD));
sd_top #(g_COUNT_WIDTH)
sd_top(.CLK(CLK),
.a_RST(a_RST),
.i_SD_CMD(i_SD_CMD), // CMD Response from card
.o_SD_CMD(o_SD_CMD), // CMD Command from host
.o_SD_CMD_OE(o_SD_CMD_OE), // Direction of SD_CMD
.i_SD_DAT(i_SD_DAT), // SD DAT Bus
.o_SD_CLK(o_SD_CLK), // SD CLK Bus
.i_BLOCK_ADDR(i_BLOCK_ADDR), // see "Addressing" in parts.fods (only 8GB total capacity is used)
.o_READY_FOR_READ(o_READY_FOR_READ), // tells core that initialization sequence is completed and
.o_SD_RESTARTING(o_SD_RESTARTING), // inform core the need to restart
.i_READ_REQUEST(i_READ_REQUEST), // After Ready for read is sent to the core, the core will
.o_DATA_TO_CORE(o_DATA_TO_CORE), // nibble being sent to core when DATA block is
.ReadData(ReadData), // full 512 bytes to Bus
.o_DATA_VALID(o_DATA_VALID), // held high while data being read to core to indicate that it is valid
.o_LAST_NIBBLE(o_LAST_NIBBLE), // pulse when last nibble is sent
.o_ERROR_CODE_Q(o_ERROR_CODE_Q), // indicates which error occured
.o_FATAL_ERROR(o_FATAL_ERROR), // indicates that the FATAL ERROR register has updated
.i_COUNT_IN_MAX(i_COUNT_IN_MAX),
.LIMIT_SD_TIMERS(LIMIT_SD_TIMERS)
);
endmodule

View file

@ -1,51 +0,0 @@
///////////////////////////////////////////
// sipo_generic_ce
//
// Written: Richard Davis
// Modified: Ross Thompson September 20, 2021
//
// 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 CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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

View file

@ -1,45 +0,0 @@
///////////////////////////////////////////
// counter.sv
//
// Written: Ross Thompson
// Modified:
//
// Purpose: basic up counter
//
// A component of the CORE-V-WALLY configurable RISC-V project.
//
// SPDX-License-Identifier: Apache-2.0 WITH SHL-2.1
//
// Licensed under the Solderpad Hardware License v 2.1 (the “License”); you may not use this file
// except in compliance with the License, or, at your option, the Apache License version 2.0. You
// may obtain a copy of the License at
//
// https://solderpad.org/licenses/SHL-2.1/
//
// Unless required by applicable law or agreed to in writing, any work distributed under the
// License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
// either express or implied. See the License for the specific language governing permissions
// and limitations under the License.
////////////////////////////////////////////////////////////////////////////////////////////////
`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] CountP1;
assign CountP1 = UpDown ? CountOut + 1'b1 : CountOut - 1'b1;
assign NextCount = Load ? CountIn : CountP1;
flopenr #(WIDTH) reg1(clk, reset, Enable | Load, NextCount, CountOut);
endmodule

View file

@ -56,10 +56,10 @@ module uartPC16550D(
typedef enum logic [1:0] {UART_IDLE, UART_ACTIVE, UART_DONE, UART_BREAK} statetype;
// Registers
(* mark_debug = "true" *) logic [10:0] RBR;
(* mark_debug = "true" *) logic [7:0] FCR, LCR, LSR, SCR, DLL, DLM;
(* mark_debug = "true" *) logic [3:0] IER, MSR;
(* mark_debug = "true" *) logic [4:0] MCR;
logic [10:0] RBR;
logic [7:0] FCR, LCR, LSR, SCR, DLL, DLM;
logic [3:0] IER, MSR;
logic [4:0] MCR;
// Syncrhonized and delayed UART signals
logic SINd, DSRbd, DCDbd, CTSbd, RIbd;
@ -72,50 +72,50 @@ module uartPC16550D(
logic DLAB; // Divisor Latch Access Bit (LCR bit 7)
// Baud and rx/tx timing
(* mark_debug = "true" *) logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
logic baudpulse, txbaudpulse, rxbaudpulse; // high one system clk cycle each baud/16 period
logic [16+`UART_PRESCALE-1:0] baudcount;
logic [3:0] rxoversampledcnt, txoversampledcnt; // count oversampled-by-16
logic [3:0] rxbitsreceived, txbitssent;
(* mark_debug = "true" *) statetype rxstate, txstate;
statetype rxstate, txstate;
// shift registrs and FIFOs
logic [9:0] rxshiftreg;
(* mark_debug = "true" *) logic [10:0] rxfifo[15:0];
(* mark_debug = "true" *) logic [7:0] txfifo[15:0];
logic [10:0] rxfifo[15:0];
logic [7:0] txfifo[15:0];
logic [4:0] rxfifotailunwrapped;
(* mark_debug = "true" *) logic [3:0] rxfifohead, rxfifotail, txfifohead, txfifotail, rxfifotriggerlevel;
(* mark_debug = "true" *) logic [3:0] rxfifoentries, txfifoentries;
logic [3:0] rxfifohead, rxfifotail, txfifohead, txfifotail, rxfifotriggerlevel;
logic [3:0] rxfifoentries, txfifoentries;
logic [3:0] rxbitsexpected, txbitsexpected;
// receive data
(* mark_debug = "true" *) logic [10:0] RXBR;
(* mark_debug = "true" *) logic [9:0] rxtimeoutcnt;
logic [10:0] RXBR;
logic [9:0] rxtimeoutcnt;
logic rxcentered;
logic rxparity, rxparitybit, rxstopbit;
(* mark_debug = "true" *) logic rxparityerr, rxoverrunerr, rxframingerr, rxbreak, rxfifohaserr;
(* mark_debug = "true" *) logic rxdataready;
(* mark_debug = "true" *) logic rxfifoempty, rxfifotriggered, rxfifotimeout;
logic rxparityerr, rxoverrunerr, rxframingerr, rxbreak, rxfifohaserr;
logic rxdataready;
logic rxfifoempty, rxfifotriggered, rxfifotimeout;
logic rxfifodmaready;
logic [8:0] rxdata9;
(* mark_debug = "true" *) logic [7:0] rxdata;
(* mark_debug = "true" *) logic [15:0] RXerrbit, rxfullbit;
(* mark_debug = "true" *) logic [31:0] rxfullbitunwrapped;
logic [7:0] rxdata;
logic [15:0] RXerrbit, rxfullbit;
logic [31:0] rxfullbitunwrapped;
// transmit data
logic [7:0] TXHR, nexttxdata;
(* mark_debug = "true" *) logic [11:0] txdata, txsr;
(* mark_debug = "true" *) logic txnextbit, txhrfull, txsrfull;
logic [11:0] txdata, txsr;
logic txnextbit, txhrfull, txsrfull;
logic txparity;
(* mark_debug = "true" *) logic txfifoempty, txfifofull, txfifodmaready;
logic txfifoempty, txfifofull, txfifodmaready;
// control signals
(* mark_debug = "true" *) logic fifoenabled, fifodmamodesel, evenparitysel;
logic fifoenabled, fifodmamodesel, evenparitysel;
// interrupts
(* mark_debug = "true" *) logic RXerr, RXerrIP, squashRXerrIP, prevSquashRXerrIP, setSquashRXerrIP, resetSquashRXerrIP;
(* mark_debug = "true" *) logic THRE, THRE_IP, squashTHRE_IP, prevSquashTHRE_IP, setSquashTHRE_IP, resetSquashTHRE_IP;
(* mark_debug = "true" *) logic rxdataavailintr, modemstatusintr, intrpending;
(* mark_debug = "true" *) logic [2:0] intrID;
logic RXerr, RXerrIP, squashRXerrIP, prevSquashRXerrIP, setSquashRXerrIP, resetSquashRXerrIP;
logic THRE, THRE_IP, squashTHRE_IP, prevSquashTHRE_IP, setSquashTHRE_IP, resetSquashTHRE_IP;
logic rxdataavailintr, modemstatusintr, intrpending;
logic [2:0] intrID;
logic baudpulseComb;
logic HeadPointerLastMove;

View file

@ -40,9 +40,9 @@ module uart_apb (
input logic PENABLE,
output logic [`XLEN-1:0] PRDATA,
output logic PREADY,
(* mark_debug = "true" *) input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface
(* mark_debug = "true" *) output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface
(* mark_debug = "true" *) output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
input logic SIN, DSRb, DCDb, CTSb, RIb, // from E1A driver from RS232 interface
output logic SOUT, RTSb, DTRb, // to E1A driver to RS232 interface
output logic OUT1b, OUT2b, INTR, TXRDYb, RXRDYb); // to CPU
// UART interface signals
logic [2:0] entry;

View file

@ -52,23 +52,23 @@ module wallypipelinedcore (
logic StallF, StallD, StallE, StallM, StallW;
logic FlushD, FlushE, FlushM, FlushW;
logic RetM;
(* mark_debug = "true" *) logic TrapM;
logic TrapM;
// signals that must connect through DP
logic IntDivE, W64E;
logic CSRReadM, CSRWriteM, PrivilegedM;
logic [1:0] AtomicM;
logic [`XLEN-1:0] ForwardedSrcAE, ForwardedSrcBE;
(* mark_debug = "true" *) logic [`XLEN-1:0] SrcAM;
logic [`XLEN-1:0] SrcAM;
logic [2:0] Funct3E;
logic [31:0] InstrD;
(* mark_debug = "true" *) logic [31:0] InstrM;
logic [31:0] InstrM;
logic [`XLEN-1:0] PCF, PCE, PCLinkE;
(* mark_debug = "true" *) logic [`XLEN-1:0] PCM;
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] UnalignedPCNextF, PCNext2F;
(* mark_debug = "true" *) logic [1:0] MemRWM;
(* mark_debug = "true" *) logic InstrValidM;
logic [`XLEN-1:0] PCM;
logic [`XLEN-1:0] CSRReadValW, MDUResultW;
logic [`XLEN-1:0] UnalignedPCNextF, PCNext2F;
logic [1:0] MemRWM;
logic InstrValidM;
logic InstrMisalignedFaultM;
logic IllegalBaseInstrFaultD, IllegalIEUInstrFaultD;
logic InstrPageFaultF, LoadPageFaultM, StoreAmoPageFaultM;
@ -110,7 +110,6 @@ module wallypipelinedcore (
logic sfencevmaM, WFIStallM;
logic SelHPTW;
// PMA checker signals
var logic [`XLEN-1:0] PMPADDR_ARRAY_REGW [`PMP_ENTRIES-1:0];
var logic [7:0] PMPCFG_ARRAY_REGW[`PMP_ENTRIES-1:0];
@ -122,8 +121,8 @@ module wallypipelinedcore (
// cpu lsu interface
logic [2:0] Funct3M;
logic [`XLEN-1:0] IEUAdrE;
(* mark_debug = "true" *) logic [`XLEN-1:0] WriteDataM;
(* mark_debug = "true" *) logic [`XLEN-1:0] IEUAdrM;
logic [`XLEN-1:0] WriteDataM;
logic [`XLEN-1:0] IEUAdrM;
logic [`LLEN-1:0] ReadDataW;
logic CommittedM;
@ -163,6 +162,10 @@ module wallypipelinedcore (
logic FCvtIntE;
logic CommittedF;
// Bit manipulation unit
logic [`XLEN-1:0] BMUResultE; // Bit manipuation result BMU -> IEU
logic BMUE; // is this a BMU instruction
// instruction fetch unit: PC, branch prediction, instruction cache
ifu ifu(.clk, .reset,
.StallF, .StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
@ -190,7 +193,7 @@ module wallypipelinedcore (
.InstrD, .IllegalIEUInstrFaultD, .IllegalBaseInstrFaultD,
// Execute Stage interface
.PCE, .PCLinkE, .FWriteIntE, .FCvtIntE, .IEUAdrE, .IntDivE, .W64E,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE,
.Funct3E, .ForwardedSrcAE, .ForwardedSrcBE, .BMUE,
// Memory stage interface
.SquashSCW, // from LSU
.MemRWM, // read/write control goes to LSU
@ -200,7 +203,7 @@ module wallypipelinedcore (
.SrcAM, // to privilege and fpu
.RdE, .RdM, .FIntResM, .InvalidateICacheM, .FlushDCacheM,
// Writeback stage
.CSRReadValW, .MDUResultW, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
.CSRReadValW, .MDUResultW, .BMUResultE, .FIntDivResultW, .RdW, .ReadDataW(ReadDataW[`XLEN-1:0]),
.InstrValidM, .FCvtIntResW, .FCvtIntW,
// hazards
.StallD, .StallE, .StallM, .StallW, .FlushD, .FlushE, .FlushM, .FlushW,
@ -357,4 +360,15 @@ module wallypipelinedcore (
assign SetFflagsM = 0;
assign FpLoadStoreM = 0;
end
// bit manipulation unit
if (`B_SUPPORTED) begin:bmu
bmu bmu(.ForwardedSrcAE, .ForwardedSrcBE, .InstrD, .BMUE, .BMUResultE);
end else begin // no B instructions supported
assign BMUResultE = 0;
assign BMUE = 0;
end
endmodule

View file

@ -133,6 +133,7 @@ logic [3:0] dummy;
"wally32periph": tests = wally32periph;
"embench": tests = embench;
"coremark": tests = coremark;
"arch32ba": if (`ZBA_SUPPORTED) tests = arch32ba;
endcase
end
if (tests.size() == 0) begin

View file

@ -944,6 +944,14 @@ string imperas32f[] = '{
"rv32i_m/Zifencei/src/Fencei.S"
};
string arch32ba[] = '{
`RISCVARCHTEST,
// *** unclear why add.uw isn't in the list
"rv64i_m/B/src/sh1add-01.S",
"rv64i_m/B/src/sh1add-02.S",
"rv64i_m/B/src/sh1add-013.S"
};
string arch64m[] = '{
`RISCVARCHTEST,
"rv64i_m/M/src/div-01.S",

View file

@ -2,7 +2,7 @@
# setup.sh
# David_Harris@hmc.edu and kekim@hmc.edu 1 December 2021
# Set up tools for riscv-wally
# Set up tools for rvw
echo "Executing Wally setup.sh"
@ -15,14 +15,15 @@ echo \$WALLY set to ${WALLY}
# Must edit these based on your local environment. Ask your sysadmin.
export MGLS_LICENSE_FILE=1717@solidworks.eng.hmc.edu # Change this to your Siemens license server
export SNPSLMD_LICENSE_FILE=27020@zircon.eng.hmc.edu # Change this to your Synopsys license server
export PATH=/cad/mentor/questa_sim-2021.2_1/questasim/bin:$PATH # Change this for your path to Questa
export PATH=/cad/synopsys/SYN/bin:$PATH # Change this for your path to Design Compiler
export QUESTAPATH=/cad/mentor/questa_sim-2021.2_1/questasim/bin # Change this for your path to Questa
export SNPSPATH=/cad/synopsys/SYN/bin # Change this for your path to Design Compiler
# Path to RISC-V Tools
export RISCV=/opt/riscv # change this if you installed the tools in a different location
# Tools
# Questa and Synopsys
export PATH=$QUESTAPATH:$SNPSPATH:$PATH
# GCC
export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$RISCV/riscv-gnu-toolchain/lib:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/lib
export PATH=$PATH:$RISCV/riscv-gnu-toolchain/bin:$RISCV/riscv-gnu-toolchain/riscv64-unknown-elf/bin # GCC tools

View file

@ -1,6 +1,7 @@
hart_ids: [0]
hart0:
ISA: RV32IMAFDCZicsr_Zifencei
# ISA: RV32IMAFDCZicsr_Zifencei_Zba_Zbb_Zbc_Zbs
physical_addr_sz: 32
User_Spec_Version: '2.3'
supported_xlen: [32]

View file

@ -1,6 +1,7 @@
hart_ids: [0]
hart0:
ISA: RV64IMAFDCSUZicsr_Zifencei
# ISA: RV64IMAFDCSUZicsr_Zifencei_Zba_Zbb_Zbc_Zbs
physical_addr_sz: 56
User_Spec_Version: '2.3'
supported_xlen: [64]

BIN
wallyriscvTopAll.png Normal file

Binary file not shown.

After

Width:  |  Height:  |  Size: 38 KiB