Initial commit
This commit is contained in:
@@ -0,0 +1,276 @@
|
||||
# [RISC-V Desgin in an Open_Source Design Flow](https://microtec-academy.de/produkt/risc-v-design-in-an-open-source-design-flow/)
|
||||
|
||||
A RISC-V design course, where you learn about the the RISC-V theory and then use it to build your own RISC-V processor.
|
||||
|
||||
This project has the full solution for the course exercises. It is able to simulate the Decoder or CPU as DUTs (device under tests). The simulation executes a SW test from a designated Hex file on the DUT.
|
||||
|
||||
In this README you will learn about ...
|
||||
|
||||
* what **prerequisites** you need to get this project running
|
||||
* how the project is **organised**
|
||||
* how to **run simulations**
|
||||
|
||||
## Background
|
||||
|
||||
This course is a part of the initiative [*Bavarian Chip Design Center (BCDC)*](https://www.iis.fraunhofer.de/en/ff/sse/bavarian-chip-design-center.html), which aims to develop and improve the IC-Design workforce in Bavaria.
|
||||
|
||||
This course is an adaptation of the code-base developed at [Lund University](https://www.lth.se/) by Per Andersson as part of the effort to develop and improve education in Digital System Design. You can find the original source-code under [this repository](https://github.com/PalePrime/single_cycle).
|
||||
|
||||
## Prerequisites
|
||||
|
||||
Bash Shell Terminal
|
||||
|
||||
* Windows: you need to install gitbash or use something similar
|
||||
* MacOS/Linux: bash is preinstalled
|
||||
|
||||
GCC Compiler
|
||||
|
||||
* Installation details [here](https://gcc.gnu.org/install/)
|
||||
|
||||
Verilator
|
||||
|
||||
* If not installed, you can find the installation [here](https://verilator.org/guide/latest/install.html). It is highly recommended to install through a package manager for all operating systems.
|
||||
* For Linux use apt package manager. Info under [verilator install guide](https://verilator.org/guide/latest/install.html#package-manager-quick-install).
|
||||
* For MacOS the package manager is [homebrew](https://brew.sh/).
|
||||
* For Windows an package manager option is [pacman](https://gist.github.com/AndreSteenveld/cb6662c93c8323795c5fd347defb8976) (untested).
|
||||
* Export the *VERILATOR* environment variable. Make sure to use your Verilator install directory -> `export VERILATOR=</path/to/verilator>/bin/verilator`
|
||||
|
||||
Surfer Waveform Viewer
|
||||
|
||||
* If not installed, you can find the installation [here](https://surfer-project.org/)
|
||||
* Export the *WAVE_VIEWER* environment variables. Make sure to use your Surfer install directory -> `export WAVE_VIEWER=</path/to/surfer>/surfer`
|
||||
|
||||
IDE (optional)
|
||||
|
||||
* Any IDE of your choosing will make it easy to view and manage the files
|
||||
|
||||
## Project Organisation
|
||||
|
||||
### Resources
|
||||
|
||||
Path: `doc`
|
||||
|
||||
* Module diagrams
|
||||
* RISC-V Cards
|
||||
* RISC-V ISM
|
||||
* RISC-V ASM
|
||||
|
||||
### RTL source code
|
||||
|
||||
Path: `hw/rtl`
|
||||
|
||||
### File lists of SV code
|
||||
|
||||
Path: `hw/file_lists`
|
||||
|
||||
* RTL file list
|
||||
* Testbench file list
|
||||
|
||||
### Verification source code
|
||||
|
||||
#### SV testbenches used in EDA playground
|
||||
|
||||
Path: `hw/dv/rtl`
|
||||
|
||||
#### Verilator environment
|
||||
|
||||
Path: `hw/dv/verilator/`
|
||||
|
||||
* SV Toplevel harnesses
|
||||
* Decoder
|
||||
* CPU
|
||||
* C++ testbenches
|
||||
* Decoder
|
||||
* CPU
|
||||
* Makefile
|
||||
|
||||
### Software and Hex programs used for testing
|
||||
|
||||
Path: `sw/risc-v`
|
||||
|
||||
* Main Memory: Hex code
|
||||
* Decoder:
|
||||
* Assembly code
|
||||
* Hex code from assembeled assembly code
|
||||
* Fibonacci Series/Hello World/Prime Factors:
|
||||
* C Code
|
||||
* Assembly code from compiled C code
|
||||
* Simplified assembly code from assembly code (not available for Fibonacci Series)
|
||||
* Hex code from assembeled assembly or simplified assembly code
|
||||
|
||||
## Running Simulations
|
||||
|
||||
### Quick start
|
||||
|
||||
Run the two commands below
|
||||
|
||||
```
|
||||
cd hw/dv/verilator
|
||||
```
|
||||
|
||||
```
|
||||
make clean all run wave
|
||||
```
|
||||
|
||||
This will convert the RTL into C++, compile the model, create the simulation binary, run the simulation, and start the waveform viewer. The output of the simulation should be the following:
|
||||
|
||||
```
|
||||
*** Running simulation...
|
||||
|
||||
Creating model...
|
||||
Registered DPI-C functions:
|
||||
scopesDump:
|
||||
SCOPE 0x55616d28b940: TOP.cpu_harness
|
||||
DPI-EXPORT 0x556136cc8f77: enable
|
||||
DPI-EXPORT 0x556136cc8f89: getLed
|
||||
DPI-EXPORT 0x556136cc8fda: getMem
|
||||
DPI-EXPORT 0x556136cc9006: getReg
|
||||
DPI-EXPORT 0x556136cc9242: loadRAM
|
||||
DPI-EXPORT 0x556136cdcc19: printMem
|
||||
DPI-EXPORT 0x556136cdcd88: printReg
|
||||
DPI-EXPORT 0x556136cc8fab: setBtn
|
||||
DPI-EXPORT 0x556136cc8f68: setClk
|
||||
DPI-EXPORT 0x556136cc8f78: setInitial
|
||||
DPI-EXPORT 0x556136cc8fea: setMem
|
||||
DPI-EXPORT 0x556136cc8fc9: setReset
|
||||
|
||||
Initializing SRAM memory from ../../../sw/risc-v/hello_world/helloWorld.hex
|
||||
program set to helloWorld
|
||||
|
||||
Starting model...
|
||||
|
||||
Resetting...
|
||||
Starting CPU...
|
||||
Running for 500 clock cycles...
|
||||
|
||||
Printing evaluation for helloWorld program!
|
||||
|
||||
T=3960: Hex ASCII
|
||||
Value at RAM[1024]: 0x68000000 : h
|
||||
Value at RAM[1025]: 0x00000000 :
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=6840: Hex ASCII
|
||||
Value at RAM[1024]: 0x68650000 : he
|
||||
Value at RAM[1025]: 0x00000000 :
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=9720: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c00 : hel
|
||||
Value at RAM[1025]: 0x00000000 :
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=12600: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x00000000 :
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=15480: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f000000 : o
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=18360: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f200000 : o
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=21240: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f207700 : o w
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=24120: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f20776f : o wo
|
||||
Value at RAM[1026]: 0x00000000 :
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=27000: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f20776f : o wo
|
||||
Value at RAM[1026]: 0x72000000 : r
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=29880: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f20776f : o wo
|
||||
Value at RAM[1026]: 0x726c0000 : rl
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=32760: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f20776f : o wo
|
||||
Value at RAM[1026]: 0x726c6400 : rld
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
T=35640: Hex ASCII
|
||||
Value at RAM[1024]: 0x68656c6c : hell
|
||||
Value at RAM[1025]: 0x6f20776f : o wo
|
||||
Value at RAM[1026]: 0x726c6421 : rld!
|
||||
Value at RAM[1027]: 0x00000000 :
|
||||
|
||||
|
||||
Done, closing simulation.
|
||||
```
|
||||
|
||||
**Important:** The makefile reads the file lists `hw/file_lists/rtl_flist.f` and `hw/file_lists/tb_flist.f`. The make process does not recognize RTL or TB file changes, so it is required to run `make clean` after RTL or TB changes, otherwise the changed files will not be compiled.
|
||||
|
||||
### Makefile details
|
||||
|
||||
By default, the hex-file `sw/risc-v/hello_world.hex` is loaded into the Main Memory before starting the simulation, and the simulation is run for 500 clock cycles. This behavior can by overriden by specifying *PROG* and *NCYCLES* environment variables, which will load the specified hex file and run for the specified number of clock cycles.
|
||||
|
||||
```
|
||||
make run PROG=/path/to/myprog.hex NCYCLES=2000
|
||||
```
|
||||
|
||||
You can also combine the different make targets.
|
||||
|
||||
```
|
||||
make clean all run wave PROG=/path/to/myprog.hex NCYCLES=2000
|
||||
```
|
||||
|
||||
**Important:** If the simulation is not showing the full expected result, make sure that the number of cycles are sufficient for the CPU to finish executing the program (check if the last instruction executed is the *jump to halt* instruction)
|
||||
|
||||
Available Make targets (commands)
|
||||
|
||||
* **make clean** - remove old files
|
||||
* **make** - build and compile the RTL simulator using Verilator and GCC (alias for `make all`)
|
||||
* **make run** - run the simulation (requires built and compiled RTL)
|
||||
* **make wave** - show the waveform in Surfer
|
||||
* **make clean all run wave** - runs all the make targets (order is important)
|
||||
|
||||
It is not necessary to close the Surfer viewer if the simulation is run again. Just reload the Surfer window after the new run.
|
||||
|
||||
### Things you need/can change
|
||||
|
||||
* In the *Makefile*
|
||||
* **PROG** - variable holding the hex file path of the program to be loaded
|
||||
* **NCYCLES** - Variable for the number of cycles the CPU is going to run for
|
||||
* **TOPMODULE** - Variable with the module name of the harness
|
||||
* Int the *tb_flist.f*
|
||||
* Add new harnesses you have created
|
||||
|
||||
### Things you can do
|
||||
|
||||
* You can run the exact same tests you ran on EDA Playground and you should get the same results. However, the test here will be using verilator.
|
||||
* You can create your own harness and C++ testbenches for modules other than Decoder and CPU to get familiar with verilator testbenches
|
||||
* Compare Icarus and Verilator output (uninitialised memory locations are set to 'x' when using Icarus and '0' when using verilator)
|
||||
@@ -0,0 +1,131 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram name="Page-1" id="6TD31-tx4YeMT5SjUeEL">
|
||||
<mxGraphModel dx="796" dy="265" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="827" pageHeight="1169" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-1" value="" style="group" parent="1" vertex="1" connectable="0">
|
||||
<mxGeometry x="370" y="345.16" width="152.95000000000005" height="118.00999999999999" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-2" value="" style="group" parent="fx5yl9cXGPLrq4qI7ClV-1" vertex="1" connectable="0">
|
||||
<mxGeometry y="4.839999999999975" width="152.95000000000005" height="113.17000000000002" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-3" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.75;exitDx=0;exitDy=0;startArrow=none;startFill=0;endArrow=none;endFill=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="150" y="75.66836734693868" as="targetPoint"/>
|
||||
<mxPoint x="118.95000000000005" y="75.50000000000011" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-4" value="eqFlag" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-3" vertex="1" connectable="0">
|
||||
<mxGeometry x="-0.8665" relative="1" as="geometry">
|
||||
<mxPoint x="21" y="7" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-5" value="" style="shape=image;verticalLabelPosition=bottom;labelBackgroundColor=default;verticalAlign=top;aspect=fixed;imageAspect=0;image=data:image/png,iVBORw0KGgoAAAANSUhEUgAAAE8AAACjCAYAAADLskN/AAAAAXNSR0IArs4c6QAAAIRlWElmTU0AKgAAAAgABQESAAMAAAABAAEAAAEaAAUAAAABAAAASgEbAAUAAAABAAAAUgEoAAMAAAABAAIAAIdpAAQAAAABAAAAWgAAAAAAAABIAAAAAQAAAEgAAAABAAOgAQADAAAAAQABAACgAgAEAAAAAQAAAE+gAwAEAAAAAQAAAKMAAAAAHJ2haQAAAAlwSFlzAAALEwAACxMBAJqcGAAAB9pJREFUeAHt3clS3EYYB/BhGFPeFxhsfEI8gMFgs93mJYwHigOVSvIIPpixy0tSyUPY46pszp5H4BovcZaqnOGWeDdgBrzgyfdX1K5Bo0atae39qcoItdQt9W96rEb61CoUCgWL/vHUoUBz375931Beq8P8RmdrLi4ubh07duzFgQMHbjNisLbQxLS8vNys1WqvgHjw4MFvqYhKsGLM3NrGEz+AeOPGja3e3t7Vw4cPf8eIuzcK4bZjDsSbN2++AuKRI0e+Z0RvxB1o7gUH8XVfX98aI7YDur08lx3EN0Ck1vgjt8T/IT2xZIlArNfrb8vl8jpB/mQ6osxp13QHcRuI/f39P5uKuCuS30qBSIAvjx8//otpiH4+SuuBeOvWrXenTp16SF2ce6YgKuGobiQQh4eHH9HZ+X7eEVVdAm0nEEdGRh4fPXr0t7wiBkIJurGD2Dx9+vQT+tPvQd4Qg3p0tH0L4tO9e/f+kxfEjjB0MtGJpTk6OvqMLoX9m3VEHQetvEA8c+bMiywjagGEkRmIZ8+eXd2/f//DrLXEMOofShlAHB8fX3MQFwgy9VMoFQ+zkKWlpcwghlnvUMsC4sTExDrdHnhETXAhjc0w1ApHUZiD+JJuDzwmwCtpQoyivpGUib7i5OTkBhCLxeLVNCBGUtEoCwXi1NRU49ChQ09KpdK1JBGjrGekZQNxenp6M0nESCsYR+ECkS6FPe3u7v4izpYYR/1i2QcQq9XqBhD37NnzZRyIsVQszp0AcXZ2thEHYpz1inVfApEuyj7r6en5KoqWGGuFktgZEOfm5rboouxzuhz2NSFaYUEmUZ9E9gnEixcvNsJETKQiSe4UiBQZtomgJt3wuiTrkei+HUSt8LpEK5CGnQNRRIYFDa9Lw/Gn4hiAKCLDqJujFF6XigNP00EIRAQ1+UWGpem4U3UsDqIdGUZn6B+oe1Nxd3FSdcBpPBiBiKCm1vC6LpLE8bpBedlDYGVlpUAXZrcvXLiw2Wg0/mY8DyS/JCAODQ0VGM9PSrK+q6urUJSs42QFAcZTQJJtwngyGYV0xlNAkm3CeDIZhXTGU0CSbcJ4MhmFdMZTQJJtwngyGYV0xlNAkm3CeDIZhXTGU0CSbcJ4MhmFdMZTQJJtwngyGYV0xlNAkm3CeDIZhXTGU0CSbcJ4MhmFdMZTQJJtwngyGYV0Gw+30ngKLlCkMPyPx8bGVi9fvrwdPDvngIBFiHcHBgY28agST/4CZNYWZrGAR5MQSY74DJ7kAl54diuksKrPEV5Fz7++k2c3e40MD4CYLAzpgUc2+avc3lDIp+1ra6u1/qAnaT7AwyDz8/Ov24swN0UJz4G0ECFJY0Vt4FF2nuyYPP+W19oK6fcKAf41MzOzZvoJJUjLazVEt+YjPMNw6dKlt6a2wk7xBKRFz/7fMbVvqIsnEI3sG4aFB0R8lT8zqW8YJh4AMRnTN6S6Bj7b2kJ+P0zoG0aG5+BaeAQJY4nmsW8YNZ5ooBUC/BNDeeSpbxgXHhAtGlzrwzz1DYGH5zDinCq0s6XBwcFC1q9ex/ocBloe4Oivku2sw8Xa2jAeHv+fF5BcnG3zeD2QKKLr56HwPF8DjAKvIq4+56lb4nXlKFQ8/G2LAk257xEWXgUF4Y6b1yeU1zRdPPt6HgaLzuMJwe9D7xiPxmP6BJn5SjIpBJgqeeyz+bUyr/Vkpt5VEXfPTPyKdoyHa3NQznOfzQvHL82v5RnTZ/OD8lovxUOsClaa0mfzwvFL88KrING0PpsflNf6Vjw7Po+CHJ/zCcGLqj3NxuM+WzuMSgrw7BF96I/4gmVZtMyTqgCuJPNwSKparu1ivQzv2ncuFvk5DI2PkfEYT0NAIyu3PMbTENDIyi2P8TQENLJyy2M8DQGNrNzyGE9DQCMrtzzG0xDQyMotj/E0BDSycstjPA0Bjazc8hhPQ0AjK7c8xtMQ0MjKLS8gHuJ3cNuR4hTvIKvKDXLjt0EULKwI7VeaW/TPnoyH2Q1AoDnvPbMcs/ez3fIau47Q3pBQExGxNLfea7l+MRbIq+K1Wu01+TSddz1K0YShVxlGpeFpJUJ7BTTnLaO+aMbjAY1eErwFNBoj5rYACTI3qpWhsg7aJtCcNysH8dqxrTF4QMM7vcNAE4K5xwMa3iYPNOdt8qLu2vPc4gENwelAo87tp9pSHgXkDq8VzYm59qh2OEm5wQNatVrdIBZ8PfFwYeRT5vHw+MP58+fXMTxnT0/P9cjFWnaQWTygYRRJesr8SalUutZSp9h+zRyeg7aaJJr4dDKDB7Rz5869wEDYxWLxqqhAkvPU4wGNxmt+CTSCupIklnvfqcVz0Nbp785HdNAL7gNPw3Lq8LKAJj641OABbXx8fA3jGNDBLYgDTPM8cTygnTx5cgsDWGcFTXygieEJNIzsmDW0xPCAhsGpy+XyH1lFix2P7nk2T5w40ejt7f0962ix4Qk0GjP0QV7QIsfD3XW0NAwLRzuriB3maR76CQNoeHcG3fO8n1c00QBCwxNodGnoXt7RQsOr1+t4Z1qTrnLcpbklCjZh3nHLE2h4L4ZpaKJhBMYjNM+IIVGgSXNlPBEx5A6zMgnLXVdfPIEmC7NyF2jSshRPNczKJCx3XdvwgoZZuQs0adnGwz3PTsOsTMJy11U7zMpdoEnL2mFWJmFxXUMS+A+AHlfjWfSaUAAAAABJRU5ErkJggg==;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="70" y="10" width="48.95" height="101" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-6" value="<span style="color: rgb(0, 0, 0); font-family: Helvetica; font-size: 12px; font-style: normal; font-variant-ligatures: normal; font-variant-caps: normal; font-weight: 400; letter-spacing: normal; orphans: 2; text-align: center; text-indent: 0px; text-transform: none; widows: 2; word-spacing: 0px; -webkit-text-stroke-width: 0px; white-space: normal; background-color: rgb(251, 251, 251); text-decoration-thickness: initial; text-decoration-style: initial; text-decoration-color: initial; float: none; display: inline !important;">ALU</span>" style="text;whiteSpace=wrap;html=1;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="88.94999999999999" y="45.5" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-7" style="rounded=0;orthogonalLoop=1;jettySize=auto;html=1;verticalAlign=middle;endArrow=none;endFill=0;entryX=0.5;entryY=1;entryDx=0;entryDy=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="108.36999999999988" y="8" as="targetPoint"/>
|
||||
<mxPoint x="108.36999999999999" y="29" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-8" value="aluOp" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-7" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.1579" relative="1" as="geometry">
|
||||
<mxPoint y="-17" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-9" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="104.52000000000002" y="23" as="sourcePoint"/>
|
||||
<mxPoint x="112.52000000000002" y="13" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-10" value="<span style="font-size: 9px;">3</span>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="99.99999999999999" y="5" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-11" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;endArrow=none;endFill=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="148.95000000000016" y="50.70270270270271" as="targetPoint"/>
|
||||
<mxPoint x="118.94999999999999" y="50.625" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-12" value="result" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-11" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.1333" relative="1" as="geometry">
|
||||
<mxPoint x="2" y="-14" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-13" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="128.95" y="56" as="sourcePoint"/>
|
||||
<mxPoint x="136.95" y="46" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-14" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;endArrow=none;endFill=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="70.00000000000011" y="29.702702702702766" as="targetPoint"/>
|
||||
<mxPoint x="40" y="30.000000000000057" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-15" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="35.00000000000006" as="sourcePoint"/>
|
||||
<mxPoint x="58" y="25.000000000000057" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-16" value="<span style="font-size: 9px;">32</span>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="44" y="23.000000000000057" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-17" value="op1" style="text;strokeColor=none;align=center;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="5" y="19.500000000000057" width="40" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-18" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;exitX=1;exitY=0.25;exitDx=0;exitDy=0;endArrow=none;endFill=0;strokeWidth=2;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="70.00000000000011" y="89.87270270270272" as="targetPoint"/>
|
||||
<mxPoint x="40" y="90.17000000000002" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-19" value="" style="endArrow=none;html=1;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="50" y="95.17000000000002" as="sourcePoint"/>
|
||||
<mxPoint x="58" y="85.17000000000002" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-20" value="<span style="font-size: 9px;">32</span>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="44" y="83.17000000000002" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-21" value="op2" style="text;strokeColor=none;align=center;fillColor=none;html=1;verticalAlign=middle;whiteSpace=wrap;rounded=0;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="5" y="79.67000000000002" width="40" height="20" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-22" value="<font style="font-size: 9px;">32</font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="fx5yl9cXGPLrq4qI7ClV-2" vertex="1">
|
||||
<mxGeometry x="122.95000000000005" y="41.58000000000004" width="30" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="80" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;" edge="1" parent="fx5yl9cXGPLrq4qI7ClV-2">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="99.94999999999999" y="94.67000000000002" as="targetPoint"/>
|
||||
<mxPoint x="100" y="110" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="81" value="aluNegAr" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" vertex="1" connectable="0" parent="80">
|
||||
<mxGeometry x="0.0744" relative="1" as="geometry">
|
||||
<mxPoint y="18" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-23" style="edgeStyle=none;rounded=0;orthogonalLoop=1;jettySize=auto;html=1;endArrow=none;endFill=0;" parent="fx5yl9cXGPLrq4qI7ClV-1" edge="1">
|
||||
<mxGeometry relative="1" as="geometry">
|
||||
<mxPoint x="85" as="targetPoint"/>
|
||||
<mxPoint x="85" y="22.840000000000032" as="sourcePoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="fx5yl9cXGPLrq4qI7ClV-24" value="aluBypass" style="edgeLabel;html=1;align=center;verticalAlign=middle;resizable=0;points=[];" parent="fx5yl9cXGPLrq4qI7ClV-23" vertex="1" connectable="0">
|
||||
<mxGeometry x="0.0744" relative="1" as="geometry">
|
||||
<mxPoint y="-21" as="offset"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,77 @@
|
||||
<svg host="65bd71144e" xmlns="http://www.w3.org/2000/svg" style="background: transparent; background-color: transparent;" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" width="573px" height="359px" viewBox="-0.5 -0.5 573 359" content="<mxfile scale="2" border="0"><diagram name="Page-1" id="Dras1X57W6EPz2KZu20U">5Vdtb9sgEP41lrYPqWyIU+djm75sXSdVi9R1nyoaU5vOBg+TxN6v32FwbJKsydp1mzopUriH4+DuHh5kD0/y6lySIv0oYpp5yI8rD594CB0i5OmfH9cGwGhogESy2EBBB0zZd2pB36JzFtPScVRCZIoVLjgTnNOZcjAipVi6bvcic3ctSEI3gOmMZJvoZxar1KAROuzwd5QlabtzMBqbmZy0zjaTMiWxWPYgfOrhiRRCmVFeTWima9fWxaw7+8ns6mCScrXPghPCBqT208uL24vkw4M/u59OBigyYRYkm9uM7WlV3ZZASUZ4oq3jZcoUnRZkpqeW0HDAUpVnYAUwlEIRxQQHczD2AbhnWTYRmZCAcMF1iFJJ8ZW2oIdwhO7waAQz0EJFGKca14s3E7Q5L6hUtOpBNuFzKnKqZA0udhZFoVmyYp9txrLrZcu0tN9GixHLnmQVuSswDGyNf6HeGG+p9yiDbY9jtoBhoprMDVQWhDu9GH2ba7pAqZryHcGkTO7ewGnhOH7797YJAVznalA2N0o7BqioTGwbpN3t03s42DV4TISk7daQndndPRHAzjnXqCLFnMc0tg3cwRZ9Pnvhg2Fr21jBdvK8BEVC36FIEG1SJNpGkfClONJqyyu9k8PAvZNoS8H/6J0cjjbKS2N4BKwppEpFIjjJTjv02GV653MpRGEr/0CVqi3ByVwJty+0YuqmN/6iQx2E1jqpbOTGqFuDQ743faO3Spvdssaqd3WtFHM5o4/plS26IjKhag9h05V7lAWSZsDHhfu8butps/RISlL3HArBuCp7ka800CPX2L3N7e0+29Mf7/BfveZP9EdhuMZXk2HH3lWpnvHI+BsCksMlvs1p/hoUG0drNQ32U+zoxQQk/KsCcuD7rohgPHySjKBdOqKjXFHJoGy7G7pbW/C+2uL/bm15XruDf6vd4Xj8pHYf/jft3q7NGK/pyDh0Q5iU7Ko10jwq02B233XGvfs4xqc/AA==</diagram></mxfile>">
|
||||
<defs/>
|
||||
<g>
|
||||
<g>
|
||||
<path d="M 144 280 L 164 290 L 144 300 Z" fill="none" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" transform="rotate(-90,154,290)" pointer-events="all" style="stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="74" y="0" width="160" height="300" fill="none" stroke="#000000" stroke-width="2" pointer-events="all" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="translate(-0.5 -0.5)scale(2)">
|
||||
<switch>
|
||||
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 75px; margin-left: 38px;">
|
||||
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
|
||||
<div style="display: inline-block; font-size: 14px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">
|
||||
<div>
|
||||
<span style="color: light-dark(rgb(0, 0, 0), rgb(237, 237, 237)); font-size: 12px;">
|
||||
RISC-V Core
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="77" y="79" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="14px" text-anchor="middle" font-weight="bold">
|
||||
RISC-V Core
|
||||
</text>
|
||||
</switch>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M 404 200 L 424 210 L 404 220 Z" fill="none" stroke="#82b366" stroke-width="2" stroke-miterlimit="10" transform="rotate(-90,414,210)" pointer-events="all" style="stroke: light-dark(rgb(130, 179, 102), rgb(68, 110, 44));"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M 494 140 L 554 140 L 554 340 L 14 340 L 14 150.03 L 61.26 150.01" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
<path d="M 71.76 150 L 57.77 157.01 L 61.26 150.01 L 57.76 143.01 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
</g>
|
||||
<g>
|
||||
<rect x="334" y="60" width="160" height="160" fill="none" stroke="#000000" stroke-width="2" pointer-events="all" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
</g>
|
||||
<g>
|
||||
<g transform="translate(-0.5 -0.5)scale(2)">
|
||||
<switch>
|
||||
<foreignObject style="overflow: visible; text-align: left;" pointer-events="none" width="100%" height="100%" requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility">
|
||||
<div xmlns="http://www.w3.org/1999/xhtml" style="display: flex; align-items: unsafe center; justify-content: unsafe center; width: 78px; height: 1px; padding-top: 70px; margin-left: 168px;">
|
||||
<div style="box-sizing: border-box; font-size: 0; text-align: center; color: #000000; ">
|
||||
<div style="display: inline-block; font-size: 14px; font-family: "Helvetica"; color: light-dark(#000000, #ffffff); line-height: 1.2; pointer-events: all; font-weight: bold; white-space: normal; word-wrap: normal; ">
|
||||
main_mem
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</foreignObject>
|
||||
<text x="207" y="74" fill="light-dark(#000000, #ffffff)" font-family=""Helvetica"" font-size="14px" text-anchor="middle" font-weight="bold">
|
||||
main_mem
|
||||
</text>
|
||||
</switch>
|
||||
</g>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M 234.16 100.2 L 284.03 100.23 L 321.26 100.06" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
<path d="M 331.76 100.01 L 317.8 107.07 L 321.26 100.06 L 317.73 93.07 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
</g>
|
||||
<g>
|
||||
<path d="M 234.16 179.7 L 284.03 179.61 L 321.26 179.9" fill="none" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="stroke" style="stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
<path d="M 331.76 179.98 L 317.71 186.87 L 321.26 179.9 L 317.82 172.87 Z" fill="#000000" stroke="#000000" stroke-width="2" stroke-miterlimit="10" pointer-events="all" style="fill: light-dark(rgb(0, 0, 0), rgb(255, 255, 255)); stroke: light-dark(rgb(0, 0, 0), rgb(255, 255, 255));"/>
|
||||
</g>
|
||||
</g>
|
||||
<switch>
|
||||
<g requiredFeatures="http://www.w3.org/TR/SVG11/feature#Extensibility"/>
|
||||
<a transform="translate(0,-5)" xlink:href="https://www.drawio.com/doc/faq/svg-export-text-problems" target="_blank">
|
||||
<text text-anchor="middle" font-size="10px" x="50%" y="100%">
|
||||
Text is not SVG - cannot display
|
||||
</text>
|
||||
</a>
|
||||
</switch>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 7.3 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 136 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 18 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 89 KiB |
File diff suppressed because one or more lines are too long
|
After Width: | Height: | Size: 144 KiB |
@@ -0,0 +1,163 @@
|
||||
<mxfile host="Electron" agent="Mozilla/5.0 (X11; Linux x86_64) AppleWebKit/537.36 (KHTML, like Gecko) draw.io/26.2.2 Chrome/134.0.6998.178 Electron/35.1.2 Safari/537.36" version="26.2.2">
|
||||
<diagram name="Page-1" id="vqPtpfTpDl2-zyb6y6Gk">
|
||||
<mxGraphModel dx="2152" dy="1262" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0" />
|
||||
<mxCell id="1" parent="0" />
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="270" width="680" height="340" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="480" width="540" height="80" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-3" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;entryX=0.47;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.683;exitY=0.008;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" edge="1" source="QNMoGRvylN2gnaf27AE2-24">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="650.4" y="435" as="sourcePoint" />
|
||||
<mxPoint x="649.9999999999999" y="355" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-4" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;exitX=0.588;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.489;entryY=0.019;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" edge="1" target="QNMoGRvylN2gnaf27AE2-23">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="579.7999999999997" y="354.99999999999994" as="sourcePoint" />
|
||||
<mxPoint x="579.96" y="435.16" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-5" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" edge="1" source="QNMoGRvylN2gnaf27AE2-7">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="299.7999999999998" y="400" as="sourcePoint" />
|
||||
<mxPoint x="299.7999999999998" y="480.0799999999999" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" edge="1" source="QNMoGRvylN2gnaf27AE2-8">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="370" y="360" as="sourcePoint" />
|
||||
<mxPoint x="369.8" y="480" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-7" value="setClk()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="270" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-8" value="setReset()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-9" value="enable()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="410" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-10" value="setInitial()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="480" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-11" value="setBtn()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-12" value="getLed()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="620" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-13" value="loadRAM" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="690" y="325" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-14" value="dumpRAM()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="760" y="325" width="70" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-15" value="cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="790" y="580" width="90" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-20" value="cpu (device under test)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="650" y="530" width="140" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-21" value="clk" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="280" y="480" width="40" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-22" value="rst" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="345" y="480" width="40" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-23" value="btn[6:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="480" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-24" value="led[7:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="480" width="60" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-25" value="DPI-C tasks and functions" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="500" y="295" width="160" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-26" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="80" width="680" height="160" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-27" value="tb_cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="780" y="210" width="110" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-28" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="100" width="130" height="110" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-29" value="<b>class cpu</b><div>cpu::tick()</div><div>cpu::setReset()</div><div>cpu::waitClocks()</div><div>cpu::loadRAM()</div><div>...</div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="630" y="110" width="110" height="100" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-30" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.052;exitY=0.966;exitDx=0;exitDy=0;exitPerimeter=0;flowAnimation=0;shadow=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-7" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="940" y="260" as="sourcePoint" />
|
||||
<mxPoint x="500" y="400" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-31" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.138;exitY=1.004;exitDx=0;exitDy=0;exitPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-8" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="557" y="216" as="sourcePoint" />
|
||||
<mxPoint x="310" y="335" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-32" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.834;exitY=1.006;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.603;entryY=0.068;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-29" target="QNMoGRvylN2gnaf27AE2-14" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="-20" y="450" as="sourcePoint" />
|
||||
<mxPoint x="30" y="400" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-33" value="<b><font style="font-size: 19px;">...</font></b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="650" y="200" width="40" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-34" value="<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><b>main()</b><div>create cpu instance</div><div>cpu.loadRam("hexfile");</div><div>cpu.reset(10);</div><div>cpu.start();</div><div>...</div><div>cpu.stop();</div><div>cpu.delete();</div></blockquote>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;align=left;" parent="1" vertex="1">
|
||||
<mxGeometry x="260" y="95" width="210" height="130" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-35" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.002;entryY=0.547;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#bac8d3;strokeColor=default;" parent="1" source="QNMoGRvylN2gnaf27AE2-34" target="QNMoGRvylN2gnaf27AE2-28" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="440" y="250" as="sourcePoint" />
|
||||
<mxPoint x="530" y="160" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-36" value="<font style="font-size: 20px;"><b>C++</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||
<mxGeometry x="930" y="140" width="60" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-37" value="<font style="font-size: 20px;"><b>SystemVerilog</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||
<mxGeometry x="880" y="394" width="160" height="40" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-39" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="960" y="120" as="sourcePoint" />
|
||||
<mxPoint x="960" y="80" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-40" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="959.66" y="240" as="sourcePoint" />
|
||||
<mxPoint x="959.66" y="200" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-41" value="" style="endArrow=none;html=1;rounded=0;exitX=0.996;exitY=0.511;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="959.66" y="325" as="sourcePoint" />
|
||||
<mxPoint x="959.66" y="285" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-42" value="" style="endArrow=none;html=1;rounded=0;" parent="1" target="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="959.66" y="560" as="sourcePoint" />
|
||||
<mxPoint x="959.66" y="520" as="targetPoint" />
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="CcVjRRQ9gQZcIWVMXx_5-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="40" width="890" height="620" as="geometry" />
|
||||
</mxCell>
|
||||
<mxCell id="CcVjRRQ9gQZcIWVMXx_5-2" value="Text" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="1105" y="548" width="50" height="30" as="geometry" />
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
@@ -0,0 +1,160 @@
|
||||
<mxfile host="65bd71144e">
|
||||
<diagram name="Page-1" id="vqPtpfTpDl2-zyb6y6Gk">
|
||||
<mxGraphModel dx="1708" dy="882" grid="1" gridSize="10" guides="1" tooltips="1" connect="1" arrows="1" fold="1" page="1" pageScale="1" pageWidth="1169" pageHeight="827" math="0" shadow="0">
|
||||
<root>
|
||||
<mxCell id="0"/>
|
||||
<mxCell id="1" parent="0"/>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f5f5f5;fontColor=#333333;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="270" width="680" height="340" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-1" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#f8cecc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="250" y="480" width="540" height="80" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-3" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;entryX=0.47;entryY=1;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.683;exitY=0.008;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-24" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="650.4" y="435" as="sourcePoint"/>
|
||||
<mxPoint x="649.9999999999999" y="355" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-4" value="" style="shape=flexArrow;endArrow=classic;html=1;rounded=0;exitX=0.588;exitY=0.999;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.489;entryY=0.019;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" target="QNMoGRvylN2gnaf27AE2-23" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="579.7999999999997" y="354.99999999999994" as="sourcePoint"/>
|
||||
<mxPoint x="579.96" y="435.16" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-5" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-7" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="299.7999999999998" y="400" as="sourcePoint"/>
|
||||
<mxPoint x="299.7999999999998" y="480.0799999999999" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-6" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.118;entryY=0.001;entryDx=0;entryDy=0;entryPerimeter=0;exitX=0.5;exitY=1;exitDx=0;exitDy=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-8" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="370" y="360" as="sourcePoint"/>
|
||||
<mxPoint x="369.8" y="480" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-7" value="setClk()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="270" y="325" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-8" value="setReset()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="340" y="325" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-9" value="enable()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="410" y="325" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-10" value="setInitial()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="480" y="325" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-11" value="setBtn()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="325" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-12" value="getLed()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="620" y="325" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-13" value="loadRAM" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="690" y="325" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-14" value="dumpRAM()" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="760" y="325" width="70" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-15" value="cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="790" y="580" width="90" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-20" value="cpu (device under test)" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="645" y="530" width="150" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-21" value="clk" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="280" y="480" width="40" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-22" value="rst" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="345" y="480" width="40" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-23" value="btn[6:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="550" y="480" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-24" value="led[7:0]" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="480" width="60" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-25" value="DPI-C tasks and functions" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="500" y="295" width="160" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-26" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=#d5e8d4;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="200" y="80" width="680" height="160" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-27" value="tb_cpu_harness" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="780" y="210" width="110" height="30" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-28" value="" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;" parent="1" vertex="1">
|
||||
<mxGeometry x="610" y="100" width="130" height="110" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-29" value="<b>class cpu</b><div>cpu::tick()</div><div>cpu::setReset()</div><div>cpu::waitClocks()</div><div>cpu::loadRAM()</div><div>...</div>" style="text;html=1;align=left;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="630" y="110" width="110" height="100" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-30" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.052;exitY=0.966;exitDx=0;exitDy=0;exitPerimeter=0;flowAnimation=0;shadow=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-7" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="940" y="260" as="sourcePoint"/>
|
||||
<mxPoint x="500" y="400" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-31" value="" style="endArrow=classic;html=1;rounded=0;entryX=0.5;entryY=0;entryDx=0;entryDy=0;exitX=0.138;exitY=1.004;exitDx=0;exitDy=0;exitPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-28" target="QNMoGRvylN2gnaf27AE2-8" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="557" y="216" as="sourcePoint"/>
|
||||
<mxPoint x="310" y="335" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-32" value="" style="endArrow=classic;html=1;rounded=0;exitX=0.834;exitY=1.006;exitDx=0;exitDy=0;exitPerimeter=0;entryX=0.603;entryY=0.068;entryDx=0;entryDy=0;entryPerimeter=0;dashed=1;" parent="1" source="QNMoGRvylN2gnaf27AE2-29" target="QNMoGRvylN2gnaf27AE2-14" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="-20" y="450" as="sourcePoint"/>
|
||||
<mxPoint x="30" y="400" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-33" value="<b><font style="font-size: 19px;">...</font></b>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;" parent="1" vertex="1">
|
||||
<mxGeometry x="650" y="200" width="40" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-34" value="<blockquote style="margin: 0 0 0 40px; border: none; padding: 0px;"><b>main()</b><div>create cpu instance</div><div>cpu.loadRam("hexfile");</div><div>cpu.reset(10);</div><div>cpu.start();</div><div>...</div><div>cpu.stop();</div><div>cpu.delete();</div></blockquote>" style="rounded=1;whiteSpace=wrap;html=1;fillColor=#fff2cc;strokeColor=default;align=left;" parent="1" vertex="1">
|
||||
<mxGeometry x="260" y="95" width="210" height="130" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-35" value="" style="shape=flexArrow;endArrow=classic;startArrow=classic;html=1;rounded=0;exitX=1;exitY=0.5;exitDx=0;exitDy=0;entryX=-0.002;entryY=0.547;entryDx=0;entryDy=0;entryPerimeter=0;fillColor=#bac8d3;strokeColor=default;" parent="1" source="QNMoGRvylN2gnaf27AE2-34" target="QNMoGRvylN2gnaf27AE2-28" edge="1">
|
||||
<mxGeometry width="100" height="100" relative="1" as="geometry">
|
||||
<mxPoint x="440" y="250" as="sourcePoint"/>
|
||||
<mxPoint x="530" y="160" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-36" value="<font style="font-size: 20px;"><b>C++</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||
<mxGeometry x="930" y="140" width="60" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-37" value="<font style="font-size: 20px;"><b>SystemVerilog</b></font>" style="text;html=1;align=center;verticalAlign=middle;resizable=0;points=[];autosize=1;strokeColor=none;fillColor=none;rotation=-90;" parent="1" vertex="1">
|
||||
<mxGeometry x="880" y="394" width="160" height="40" as="geometry"/>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-39" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="960" y="120" as="sourcePoint"/>
|
||||
<mxPoint x="960" y="80" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-40" value="" style="endArrow=none;html=1;rounded=0;" parent="1" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="959.66" y="240" as="sourcePoint"/>
|
||||
<mxPoint x="959.66" y="200" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-41" value="" style="endArrow=none;html=1;rounded=0;exitX=0.996;exitY=0.511;exitDx=0;exitDy=0;exitPerimeter=0;" parent="1" source="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="959.66" y="325" as="sourcePoint"/>
|
||||
<mxPoint x="959.66" y="285" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="QNMoGRvylN2gnaf27AE2-42" value="" style="endArrow=none;html=1;rounded=0;" parent="1" target="QNMoGRvylN2gnaf27AE2-37" edge="1">
|
||||
<mxGeometry width="50" height="50" relative="1" as="geometry">
|
||||
<mxPoint x="959.66" y="560" as="sourcePoint"/>
|
||||
<mxPoint x="959.66" y="520" as="targetPoint"/>
|
||||
</mxGeometry>
|
||||
</mxCell>
|
||||
<mxCell id="2" value="" style="rounded=0;whiteSpace=wrap;html=1;fillColor=none;" vertex="1" parent="1">
|
||||
<mxGeometry x="160" y="40" width="890" height="620" as="geometry"/>
|
||||
</mxCell>
|
||||
</root>
|
||||
</mxGraphModel>
|
||||
</diagram>
|
||||
</mxfile>
|
||||
Binary file not shown.
|
After Width: | Height: | Size: 89 KiB |
BIN
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,25 @@
|
||||
// MemGen_16_10_stub.sv
|
||||
// Behavioral stub - ports matched from MemGen_32_11.sv instantiation
|
||||
module MemGen_16_10 #(
|
||||
parameter ADDR_WIDTH = 10,
|
||||
parameter DATA_WIDTH = 16
|
||||
)(
|
||||
input logic chip_en,
|
||||
input logic clock,
|
||||
input logic [ADDR_WIDTH-1:0] addr,
|
||||
input logic rd_en,
|
||||
output logic [DATA_WIDTH-1:0] rd_data,
|
||||
input logic wr_en,
|
||||
input logic [DATA_WIDTH-1:0] wr_data
|
||||
);
|
||||
logic [DATA_WIDTH-1:0] mem [0:(2**ADDR_WIDTH)-1];
|
||||
|
||||
always_ff @(posedge clock) begin
|
||||
if (chip_en) begin
|
||||
if (wr_en)
|
||||
mem[addr] <= wr_data;
|
||||
else if (rd_en)
|
||||
rd_data <= mem[addr];
|
||||
end
|
||||
end
|
||||
endmodule
|
||||
@@ -0,0 +1,112 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Bomin Kim
|
||||
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
`timescale 1ns/1ns
|
||||
|
||||
module alu_tb();
|
||||
|
||||
// Local Signals
|
||||
logic[2:0] aluOp;
|
||||
logic aluNegAr;
|
||||
logic aluBypass;
|
||||
logic[31:0] op1;
|
||||
logic[31:0] op2;
|
||||
logic[31:0] result;
|
||||
logic eqFlag;
|
||||
|
||||
// Toplevel instance (DUT)
|
||||
alu u_alu (
|
||||
.aluOp(aluOp),
|
||||
.aluNegAr(aluNegAr),
|
||||
.aluBypass(aluBypass),
|
||||
.op1(op1),
|
||||
.op2(op2),
|
||||
.result(result),
|
||||
.eqFlag(eqFlag)
|
||||
);
|
||||
|
||||
// list of aluOp
|
||||
localparam logic[2:0] f3add = 3'b000;
|
||||
localparam logic[2:0] f3sl = 3'b001;
|
||||
localparam logic[2:0] f3slt = 3'b010;
|
||||
localparam logic[2:0] f3sltU = 3'b011;
|
||||
localparam logic[2:0] f3xor = 3'b100;
|
||||
localparam logic[2:0] f3sr = 3'b101;
|
||||
localparam logic[2:0] f3or = 3'b110;
|
||||
localparam logic[2:0] f3and = 3'b111;
|
||||
|
||||
// Initialize and run simulation
|
||||
initial begin
|
||||
dumpWave("wave.vcd");
|
||||
|
||||
// Initialize inputs
|
||||
aluOp = 0;
|
||||
aluNegAr = 0;
|
||||
aluBypass = 0;
|
||||
op1 = 0;
|
||||
op2 = 0;
|
||||
#10
|
||||
|
||||
// Set op1 and op2
|
||||
op1 = 32'hDEAD_BEEF; op2 = 32'h0000_0001; #70
|
||||
$display("\nTime = %0dns \t : op1 = %h, op2 = %h", $time, op1, op2);
|
||||
|
||||
$display("\nTime = %0dns \t : Is op1 and op2 equal?; eqFlag = %d", $time, eqFlag);
|
||||
|
||||
aluBypass = 1; #70
|
||||
$display("\nTime = %0dns \t : AluBypass is set; result = %h", $time, result);
|
||||
|
||||
aluBypass = 0; aluOp = f3add; #70
|
||||
$display("\nTime = %0dns \t : Alu operates addition; result = %h", $time, result);
|
||||
|
||||
aluNegAr = 1; #70
|
||||
$display("\nTime = %0dns \t : Alu operates subtraction; result = %h", $time, result);
|
||||
|
||||
aluNegAr = 0; aluOp = f3sl; #70
|
||||
$display("\nTime = %0dns \t : Alu operates shift left; result = %h", $time, result);
|
||||
|
||||
aluOp = f3slt; #70
|
||||
$display("\nTime = %0dns \t : Alu operates set less than; result = %h", $time, result);
|
||||
|
||||
aluOp = f3sltU; #70
|
||||
$display("\nTime = %0dns \t : Alu operates set less than (unsigned); result = %h", $time, result);
|
||||
|
||||
aluOp = f3xor; #70
|
||||
$display("\nTime = %0dns \t : Alu operates bit-wise XOR; result = %h", $time, result);
|
||||
|
||||
aluOp = f3sr; aluNegAr = 1; #70
|
||||
$display("\nTime = %0dns \t : Alu operates arithmetic right shift; result = %h", $time, result);
|
||||
|
||||
aluNegAr = 0; #70
|
||||
$display("\nTime = %0dns \t : Alu operates logical right shift; result = %h", $time, result);
|
||||
|
||||
aluOp = f3or; #70
|
||||
$display("\nTime = %0dns \t : Alu operates bit-wise OR; result = %h", $time, result);
|
||||
|
||||
aluOp = f3and; #70
|
||||
$display("\nTime = %0dns \t : Alu operates bit-wise AND; result = %h", $time, result);
|
||||
$finish;
|
||||
|
||||
end
|
||||
|
||||
// Wave Dump Helper Task
|
||||
task dumpWave(string fileName);
|
||||
// Open wave file and dump all signals (2D arrays not included)
|
||||
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||
$dumpfile(fileName);
|
||||
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "alu_tb");
|
||||
$dumpvars(0, alu_tb);
|
||||
endtask: dumpWave
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,164 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 H.Elzomor Renamed file and module from soc_tb to cpu_tb
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
// `define fibonacci
|
||||
// `define helloWorld
|
||||
// `define primeFactors
|
||||
|
||||
`timescale 1ns/1ns
|
||||
|
||||
module cpu_tb ();
|
||||
|
||||
// local signals
|
||||
logic[7:0] led;
|
||||
logic[6:0] btn;
|
||||
logic reset;
|
||||
logic clk;
|
||||
|
||||
// Toplevel instance (DUT)
|
||||
cpu u_cpu (
|
||||
.led(led),
|
||||
.btn(btn),
|
||||
.clk_25mhz(clk)
|
||||
);
|
||||
|
||||
// Tie reset signal to the reset button
|
||||
assign btn[0] = reset;
|
||||
|
||||
// Clock generation
|
||||
always #20 clk = ~clk;
|
||||
|
||||
// Initialize and run simulation
|
||||
initial begin
|
||||
dumpWave("wave.vcd");
|
||||
`ifdef fibonacci
|
||||
loadMem("fibonacci.hex");
|
||||
`elsif helloWorld
|
||||
loadMem("helloWorld.hex");
|
||||
`elsif primeFactors
|
||||
loadMem("primeFactors.hex");
|
||||
`endif
|
||||
|
||||
clk = 0;
|
||||
$display("\nTime = %0dns \t : Resetting the CPU", $time);
|
||||
reset = 0; #100;
|
||||
$display("\nTime = %0dns \t : Reset released", $time);
|
||||
reset = 1; #500000;
|
||||
$finish;
|
||||
end
|
||||
|
||||
// Fibonacci Program Monitor
|
||||
`ifdef fibonacci
|
||||
localparam int fibonacciStartLoc = 2027;
|
||||
localparam int fibonacciLengthInWords = 10;
|
||||
always_comb begin: Monitor_Fibonacci_Series_Calculation
|
||||
$display("\nTime =%5dns\t\t\t Hex \t Dec", $time);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+0, u_cpu.theMem.RAM[fibonacciStartLoc+0], u_cpu.theMem.RAM[fibonacciStartLoc+0]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+1, u_cpu.theMem.RAM[fibonacciStartLoc+1], u_cpu.theMem.RAM[fibonacciStartLoc+1]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+2, u_cpu.theMem.RAM[fibonacciStartLoc+2], u_cpu.theMem.RAM[fibonacciStartLoc+2]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+3, u_cpu.theMem.RAM[fibonacciStartLoc+3], u_cpu.theMem.RAM[fibonacciStartLoc+3]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+4, u_cpu.theMem.RAM[fibonacciStartLoc+4], u_cpu.theMem.RAM[fibonacciStartLoc+4]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+5, u_cpu.theMem.RAM[fibonacciStartLoc+5], u_cpu.theMem.RAM[fibonacciStartLoc+5]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+6, u_cpu.theMem.RAM[fibonacciStartLoc+6], u_cpu.theMem.RAM[fibonacciStartLoc+6]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+7, u_cpu.theMem.RAM[fibonacciStartLoc+7], u_cpu.theMem.RAM[fibonacciStartLoc+7]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+8, u_cpu.theMem.RAM[fibonacciStartLoc+8], u_cpu.theMem.RAM[fibonacciStartLoc+8]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0d",fibonacciStartLoc+9, u_cpu.theMem.RAM[fibonacciStartLoc+9], u_cpu.theMem.RAM[fibonacciStartLoc+9]);
|
||||
$display("");
|
||||
end
|
||||
|
||||
// Hello World Program Monitor
|
||||
`elsif helloWorld
|
||||
localparam int helloWorldStartLoc = 1024;
|
||||
localparam int helloWorldLengthInWords = 4;
|
||||
always_comb begin: Monitor_Hello_World_Printing
|
||||
$display("\nTime =%5dns\t\t Hex \t\t ASCII", $time);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+0, u_cpu.theMem.RAM[helloWorldStartLoc+0], u_cpu.theMem.RAM[helloWorldStartLoc+0]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+1, u_cpu.theMem.RAM[helloWorldStartLoc+1], u_cpu.theMem.RAM[helloWorldStartLoc+1]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+2, u_cpu.theMem.RAM[helloWorldStartLoc+2], u_cpu.theMem.RAM[helloWorldStartLoc+2]);
|
||||
$display("Value at RAM[%0d]: 0x%h : %0s", helloWorldStartLoc+3, u_cpu.theMem.RAM[helloWorldStartLoc+3], u_cpu.theMem.RAM[helloWorldStartLoc+3]);
|
||||
$display("");
|
||||
end
|
||||
|
||||
// Prime Factors Program Monitor
|
||||
`elsif primeFactors
|
||||
localparam int primeNumberReg = 16;
|
||||
always_comb begin: Monitor_Factorization_Number
|
||||
if(u_cpu.theRegisters.registers[primeNumberReg] > 1)
|
||||
$display("\nTime =%5dns \t : Register [%0d] updated - Finding the prime factors of %0d", $time,primeNumberReg, u_cpu.theRegisters.registers[primeNumberReg]);
|
||||
end
|
||||
localparam int primeFactorsReg = 17;
|
||||
always_comb begin: Monitor_Prime_Number
|
||||
if(u_cpu.theRegisters.registers[primeFactorsReg] > 1)
|
||||
$display("Time =%5dns \t : Register [%0d] updated - %0d is a prime factor", $time,primeFactorsReg, u_cpu.theRegisters.registers[primeFactorsReg]);
|
||||
end
|
||||
`endif
|
||||
|
||||
// Wave Dump Helper Task
|
||||
int i;
|
||||
task dumpWave(string fileName);
|
||||
// Open wave file and dump all signals (2D arrays not included)
|
||||
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||
$dumpfile(fileName);
|
||||
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "cpu_tb");
|
||||
$dumpvars(0, cpu_tb);
|
||||
|
||||
// Dump Memory in wave file
|
||||
$display("\nTime = %0dns \t : Dumping Memory in wave file", $time);
|
||||
for (i = 0; i < 100; i++) begin $dumpvars(0, cpu_tb.u_cpu.theMem.RAM[i]); end // A part of the Instruction Memory
|
||||
for (i = 1024; i < 1124; i++) begin $dumpvars(0, cpu_tb.u_cpu.theMem.RAM[i]); end // A part of the Data Memory
|
||||
for (i = 1968; i < 2048; i++) begin $dumpvars(0, cpu_tb.u_cpu.theMem.RAM[i]); end // A part of the Stack
|
||||
|
||||
// Dump registers in wave file
|
||||
$display("\nTime = %0dns \t : Dumping Registers in wave file", $time);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[1]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[2]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[3]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[4]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[5]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[6]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[7]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[8]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[9]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[10]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[11]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[12]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[13]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[14]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[15]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[16]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[17]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[18]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[19]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[20]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[21]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[22]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[23]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[24]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[25]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[26]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[27]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[28]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[29]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[30]);
|
||||
$dumpvars(0, cpu_tb.u_cpu.theRegisters.registers[31]);
|
||||
endtask: dumpWave
|
||||
|
||||
// Load hex file into memory
|
||||
task loadMem (string fileName);
|
||||
$display("\nTime = %0dns \t : Loading '%s' into Memory", $time, fileName);
|
||||
$readmemh(fileName, cpu_tb.u_cpu.theMem.RAM);
|
||||
endtask: loadMem
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,150 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
`timescale 1ns/1ns
|
||||
|
||||
module decoder_tb ();
|
||||
|
||||
// local Parameters
|
||||
localparam MEM_SIZE = 37;
|
||||
localparam REG_FILE_SIZE = 32;
|
||||
|
||||
// local signals
|
||||
logic clk;
|
||||
int counter;
|
||||
logic[31:0] mem [MEM_SIZE-1:0];
|
||||
logic[31:0] regFile [REG_FILE_SIZE-1:0];
|
||||
// PC
|
||||
logic[31:0] CurrentPC;
|
||||
logic[31:0] JumpOrBranchPC;
|
||||
logic JumpOrBranch;
|
||||
logic[31:0] NextPC;
|
||||
// Memory
|
||||
logic[31:0] DAddr;
|
||||
logic[31:0] WData;
|
||||
logic[31:0] RData;
|
||||
logic[31:0] Instruction;
|
||||
logic WrMem;
|
||||
logic[1:0] DWidth;
|
||||
// Register File;
|
||||
logic[4:0] Rs1;
|
||||
logic[4:0] Rs2;
|
||||
logic[4:0] Rd;
|
||||
logic[31:0] RRs1;
|
||||
logic[31:0] RRs2;
|
||||
logic[31:0] WRd;
|
||||
logic WrReg;
|
||||
// Protection
|
||||
logic Illegal;
|
||||
|
||||
// Toplevel instance (DUT)
|
||||
decoder u_decoder (
|
||||
// PC
|
||||
.CurrentPC(CurrentPC),
|
||||
.JumpOrBranchPC(JumpOrBranchPC),
|
||||
.JumpOrBranch(JumpOrBranch),
|
||||
// Memory
|
||||
.DAddr(DAddr),
|
||||
.WData(WData),
|
||||
.RData(RData),
|
||||
.Instruction(Instruction),
|
||||
.WrMem(WrMem),
|
||||
.DWidth(DWidth),
|
||||
// Register File
|
||||
.Rs1(Rs1),
|
||||
.Rs2(Rs2),
|
||||
.Rd(Rd),
|
||||
.RRs1(RRs1),
|
||||
.RRs2(RRs2),
|
||||
.WRd(WRd),
|
||||
.WrReg(WrReg),
|
||||
// Protection
|
||||
.Illegal(Illegal)
|
||||
);
|
||||
|
||||
// Clock generation
|
||||
always begin
|
||||
clk = ~clk; #1;
|
||||
end
|
||||
|
||||
// Load a new instruction every cycle
|
||||
always_ff @(posedge clk) begin: increment_instruction_and_print_info
|
||||
if (counter < MEM_SIZE) begin
|
||||
if (counter > 0) printInfo();
|
||||
Instruction = mem[counter++];
|
||||
end
|
||||
end
|
||||
|
||||
// Return the value of the RegFile
|
||||
always_comb begin: reg_file_assignment
|
||||
RRs1 = regFile[Rs1];
|
||||
RRs2 = regFile[Rs2];
|
||||
end
|
||||
|
||||
// Initialize and run simulation
|
||||
initial begin
|
||||
dumpWave("wave.vcd");
|
||||
loadMem("decoder.hex");
|
||||
clk = 1;
|
||||
counter = 0;
|
||||
CurrentPC = 32'hdeadbeef;
|
||||
RData = 32'hbeefdead;
|
||||
for(int i=0; i<REG_FILE_SIZE; i++) begin
|
||||
regFile[i] = i;
|
||||
end
|
||||
while (counter < MEM_SIZE) #1;
|
||||
printInfo();
|
||||
#1 $finish;
|
||||
end
|
||||
|
||||
// Functions
|
||||
// Wave Dump Helper Task
|
||||
task dumpWave(string fileName);
|
||||
// Open wave file and dump all signals (2D arrays not included)
|
||||
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||
$dumpfile(fileName);
|
||||
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "decoder_tb");
|
||||
$dumpvars(0, decoder_tb);
|
||||
endtask: dumpWave
|
||||
|
||||
// Load hex file into memory
|
||||
task loadMem (string fileName);
|
||||
$display("\nTime = %0dns \t : Loading '%s' into Memory", $time, fileName);
|
||||
$readmemh(fileName, mem);
|
||||
endtask: loadMem
|
||||
|
||||
// Print decoder signals
|
||||
task printInfo();
|
||||
$displayh("\n(cycle %0d) Decoder (I/O) \tDecoder (Internal Signals) \tALU" , counter );
|
||||
$displayh(" -------------------------- \t--------------------------------------------- \t---------------------" );
|
||||
$displayh(" CurrentPC : 0x%h OpCode : 0b%b aluOp : 0b%b" , CurrentPC , u_decoder.theOp , u_decoder.aluOp );
|
||||
$displayh(" JumpOrBranchPC: 0x%h theFunct3: 0b%b aluNegAr : 0b%b" , JumpOrBranchPC, u_decoder.theFunct3, u_decoder.aluNegAr );
|
||||
$displayh(" JumpOrBranch : 0b%b \ttheFunct7: 0b%b aluBypass: 0b%b", JumpOrBranch , u_decoder.theFunct7, u_decoder.aluBypass);
|
||||
$displayh(" DAddr : 0x%h i_imm : 0b%b op1 : 0x%h" , DAddr , u_decoder.i_imm , u_decoder.op1 );
|
||||
$displayh(" WData : 0x%h s_imm : 0b%b op2 : 0x%h" , WData , u_decoder.s_imm , u_decoder.op2 );
|
||||
$displayh(" RData : 0x%h b_imm : 0b%b result : 0x%h" , RData , u_decoder.b_imm , u_decoder.result );
|
||||
$displayh(" Instruction : 0x%h u_imm : 0b%b eqFlag : 0b%b" , Instruction , u_decoder.u_imm , u_decoder.eqFlag );
|
||||
$displayh(" WrMem : 0b%b \tj_imm : 0b%b" , WrMem , u_decoder.j_imm );
|
||||
$displayh(" DWidth : 0b%b" , DWidth );
|
||||
$displayh(" Rs1 : %0d " , Rs1 );
|
||||
$displayh(" Rs2 : %0d " , Rs2 );
|
||||
$displayh(" Rd : 0x%h" , Rd );
|
||||
$displayh(" RRs1 : %0d " , RRs1 );
|
||||
$displayh(" RRs2 : %0d " , RRs2 );
|
||||
$displayh(" WRd : 0x%h" , WRd );
|
||||
$displayh(" WrReg : 0b%b" , WrReg );
|
||||
$displayh(" Illegal : 0b%b" , Illegal );
|
||||
endtask: printInfo
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,238 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 20.Oct.2025 by Aliakbar Merchant
|
||||
// Last Modified : 24.Oct.2025 by Aliakbar Merchant [commit 89a5087]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
`timescale 1ns/1ns
|
||||
|
||||
module main_mem_tb ();
|
||||
|
||||
// local Parameters
|
||||
localparam string MEM_INIT_FILE = "main_mem.hex";
|
||||
// Helpers for addressing width
|
||||
localparam logic[1:0] _byte = 2'b00; // byte: 8 bits
|
||||
localparam logic[1:0] _half = 2'b01; // half: 16 bits
|
||||
localparam logic[1:0] _word = 2'b10; // word: 32 bits
|
||||
|
||||
// Local Signals
|
||||
// clk and reset
|
||||
logic clk;
|
||||
logic reset;
|
||||
// Memory
|
||||
logic[31:0] DAddr;
|
||||
logic[31:0] IAddr;
|
||||
logic[31:0] DWData;
|
||||
logic[31:0] DRData;
|
||||
logic[31:0] IRData;
|
||||
logic DWE;
|
||||
logic[1:0] DWidth;
|
||||
// Helpers for display results purpose
|
||||
logic[31:0] value_at_0;
|
||||
logic[31:0] value_at_1;
|
||||
logic[31:0] value_at_2;
|
||||
logic[31:0] value_at_3;
|
||||
logic[31:0] value_at_1024;
|
||||
logic[31:0] value_at_1025;
|
||||
logic[31:0] value_at_1026;
|
||||
logic[31:0] value_at_1027;
|
||||
|
||||
// Toplevel instance (DUT)
|
||||
main_mem u_main_mem (
|
||||
.clk (clk ),
|
||||
.reset (reset ),
|
||||
.DAddr (DAddr ),
|
||||
.IAddr (IAddr ),
|
||||
.DWData (DWData ),
|
||||
.DRData (DRData ),
|
||||
.IRData (IRData ),
|
||||
.DWE (DWE ),
|
||||
.DWidth (DWidth )
|
||||
);
|
||||
|
||||
// Clock generation
|
||||
always #1 clk = ~clk;
|
||||
|
||||
// Initialize and run simulation
|
||||
initial begin
|
||||
loadMem(MEM_INIT_FILE);
|
||||
value_at_0 = main_mem_tb.u_main_mem.RAM[0];
|
||||
value_at_1 = main_mem_tb.u_main_mem.RAM[1];
|
||||
value_at_2 = main_mem_tb.u_main_mem.RAM[2];
|
||||
value_at_3 = main_mem_tb.u_main_mem.RAM[3];
|
||||
value_at_1024 = main_mem_tb.u_main_mem.RAM[1024];
|
||||
value_at_1025 = main_mem_tb.u_main_mem.RAM[1025];
|
||||
value_at_1026 = main_mem_tb.u_main_mem.RAM[1026];
|
||||
value_at_1027 = main_mem_tb.u_main_mem.RAM[1027];
|
||||
clk = 0;
|
||||
DAddr = 32'd4096;
|
||||
IAddr = 0;
|
||||
DWData = 0;
|
||||
DWidth = 0;
|
||||
reset = 1; DWE=1; #7;
|
||||
DWE = 0;
|
||||
reset = 0; #2;
|
||||
test_scenario1(); #30;
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
// Test scenario 1
|
||||
task test_scenario1();
|
||||
fork
|
||||
read_inst_mem(15);
|
||||
display_inst_read_results();
|
||||
write_data_mem(4096);
|
||||
join
|
||||
display_write_results();
|
||||
fork
|
||||
display_read_results();
|
||||
read_data_mem(4096);
|
||||
join
|
||||
endtask: test_scenario1
|
||||
|
||||
// Intruction memory read transactions and results display
|
||||
task read_inst_mem(int unsigned n = 1);
|
||||
repeat(n) begin
|
||||
cycles_pe(1);
|
||||
IAddr = IAddr+4;
|
||||
end
|
||||
endtask:read_inst_mem
|
||||
|
||||
task display_inst_read_results();
|
||||
$display("\n----------------------------------------------------------------------------------" );
|
||||
$display("Instruction MEMORY READ RESULTS" );
|
||||
$display("15 instruction are read by testbench starting at adrress 0x0000 i.e at (RAM[0]) but only 4 displyed for simplicity" );
|
||||
$display("----------------------------------------------------------------------------------" );
|
||||
|
||||
cycles_pe(2);
|
||||
$display("Time = %0dns \t : IAddr = 0x0000(RAM[0]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_0, IRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : IAddr = 0x0004(RAM[1]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_1, IRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : IAddr = 0x0008(RAM[2]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_2, IRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : IAddr = 0x000c(RAM[3]): Expected value = 0x%h Actual Value at IRData: 0x%h" , $time, value_at_3, IRData );
|
||||
endtask:display_inst_read_results
|
||||
|
||||
// Data memory write transaction and results display
|
||||
task write_data_mem(logic [31:0] daddr_init=32'd4096);
|
||||
cycles_pe(1);
|
||||
DWE = 1;
|
||||
DWidth = 0;
|
||||
DAddr = daddr_init+0;
|
||||
DWData = 32'hDEADBEEF;
|
||||
cycles_pe(1);
|
||||
DWE = 1;
|
||||
DWidth = 1;
|
||||
DAddr = daddr_init+4;
|
||||
DWData = 32'hDEADBEEF;
|
||||
cycles_pe(1);
|
||||
DWE = 1;
|
||||
DWidth = 2;
|
||||
DAddr = daddr_init+8;
|
||||
DWData = 32'hDEADBEEF;
|
||||
cycles_pe(1);
|
||||
DWE = 1;
|
||||
DWidth = 3;
|
||||
DAddr = daddr_init+12;
|
||||
DWData = 32'hDEADBEEF;
|
||||
cycles_pe(1);
|
||||
DWE = 0;
|
||||
endtask:write_data_mem
|
||||
|
||||
task display_write_results();
|
||||
$display("\n----------------------------------------------------------------------------------" );
|
||||
$display("DATA MEMORY WRITE RESULTS" );
|
||||
$display("4 Write transaction are being done by testbench starting at adrress 0x1000 i.e at (RAM[1024]) with all 4 combination of DWidth" );
|
||||
$display("Data written is always 0xDEADBEEF i.e DWData = DEADBEEF" );
|
||||
$display("----------------------------------------------------------------------------------" );
|
||||
|
||||
$display("Time = %0dns \t : DWidth = 0 DAddr = 0x1000(RAM[1024]): Start value at RAM[1024] = 0x%h Expected value at RAM[1024]= 0xef%h Actual Value at RAM[1024]: 0x%h" , $time, value_at_1024,value_at_1024[23:0], getMem(1024) );
|
||||
$display("Time = %0dns \t : DWidth = 1 DAddr = 0x1004(RAM[1025]): Start value at RAM[1025] = 0x%h Expected value at RAM[1025]= 0xbeef%h Actual Value at RAM[1025]: 0x%h" , $time, value_at_1025,value_at_1025[15:0], getMem(1025) );
|
||||
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1008(RAM[1026]): Start value at RAM[1026] = 0x%h Expected value at RAM[1026]= 0xdeadbeef Actual Value at RAM[1026]: 0x%h" , $time, value_at_1026, getMem(1026) );
|
||||
$display("Time = %0dns \t : DWidth = 3 DAddr = 0x100c(RAM[1027]): Start value at RAM[1027] = 0x%h Expected value at RAM[1027]= 0x%h Actual Value at RAM[1027]: 0x%h" , $time, value_at_1027,value_at_1027, getMem(1027) );
|
||||
endtask:display_write_results
|
||||
|
||||
// Data Memory read transaction and results display
|
||||
task read_data_mem(logic [31:0] daddr_init=32'd4096);
|
||||
cycles_pe(1);
|
||||
DWidth = 0;
|
||||
DAddr = daddr_init+0;
|
||||
cycles_pe(1);
|
||||
DWidth = 1;
|
||||
DAddr = daddr_init+4;
|
||||
cycles_pe(1);
|
||||
DWidth = 2;
|
||||
DAddr = daddr_init+8;
|
||||
cycles_pe(1);
|
||||
DWidth = 3;
|
||||
DAddr = daddr_init+12;
|
||||
cycles_pe(1);
|
||||
DWidth = 2;
|
||||
DAddr = daddr_init+0;
|
||||
cycles_pe(1);
|
||||
DWidth = 2;
|
||||
DAddr = daddr_init+4;
|
||||
cycles_pe(1);
|
||||
DWidth = 2;
|
||||
DAddr = daddr_init+8;
|
||||
cycles_pe(1);
|
||||
DWidth = 2;
|
||||
DAddr = daddr_init+12;
|
||||
endtask:read_data_mem
|
||||
|
||||
task display_read_results();
|
||||
$display("\n----------------------------------------------------------------------------------" );
|
||||
$display("DATA MEMORY READ RESULTS" );
|
||||
$display("8 Read transaction are being done by testbench starting at adrress 0x1000 i.e at (RAM[1024])" );
|
||||
$display("----------------------------------------------------------------------------------" );
|
||||
|
||||
cycles_pe(2);
|
||||
$display("Time = %0dns \t : DWidth = 0 DAddr = 0x1000(RAM[1024]): Expected value = 0x000000ef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : DWidth = 1 DAddr = 0x1004(RAM[1025]): Expected value = 0x0000beef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1008(RAM[1026]): Expected value = 0xdeadbeef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : DWidth = 3 DAddr = 0x100c(RAM[1027]): Expected value = 0xdeadbeef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1000(RAM[1024]): Expected value = 0xef%h Actual Value at DRData: 0x%h" , $time, value_at_1024[23:0], DRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1004(RAM[1025]): Expected value = 0xbeef%h Actual Value at DRData: 0x%h" , $time, value_at_1025[15:0], DRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x1008(RAM[1026]): Expected value = 0xdeadbeef Actual Value at DRData: 0x%h" , $time, DRData );
|
||||
cycles_pe(1);
|
||||
$display("Time = %0dns \t : DWidth = 2 DAddr = 0x100c(RAM[1027]): Expected value = 0x%h Actual Value at DRData: 0x%h" , $time, value_at_1027, DRData );
|
||||
endtask:display_read_results
|
||||
|
||||
|
||||
// Helper tasks
|
||||
// Memory
|
||||
function int getMem(int location);
|
||||
getMem = u_main_mem.RAM[location];
|
||||
endfunction: getMem
|
||||
|
||||
task cycles_pe(int unsigned N = 1);
|
||||
repeat(N) @(posedge clk);
|
||||
endtask: cycles_pe
|
||||
|
||||
task cycles_ne(int unsigned N = 1);
|
||||
repeat(N) @(negedge clk);
|
||||
endtask: cycles_ne
|
||||
|
||||
// Load hex file into memory
|
||||
task loadMem (string fileName);
|
||||
$display("\nTime = %0dns \t : Loading '%s' into Memory", $time, fileName);
|
||||
$readmemh(fileName, main_mem_tb.u_main_mem.RAM);
|
||||
endtask: loadMem
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,68 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Bomin Kim
|
||||
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
`timescale 1ns/1ns
|
||||
|
||||
module pc_tb ();
|
||||
|
||||
// Local Signals
|
||||
logic[31:0] CurrentPC;
|
||||
logic[31:0] JumpOrBranchPC;
|
||||
logic JumpOrBranch;
|
||||
logic[31:0] NextPC;
|
||||
logic reset;
|
||||
logic clk;
|
||||
|
||||
// Toplevel instance (DUT)
|
||||
pc u_pc (
|
||||
.CurrentPC(CurrentPC),
|
||||
.JumpOrBranchPC(JumpOrBranchPC),
|
||||
.JumpOrBranch(JumpOrBranch),
|
||||
.NextPC(NextPC),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
// Clock generation
|
||||
always #20 clk = ~clk;
|
||||
|
||||
// Initialization and run simulation
|
||||
initial begin
|
||||
dumpWave("wave.vcd");
|
||||
clk = 0;
|
||||
JumpOrBranchPC = 32'h8;
|
||||
JumpOrBranch = 0;
|
||||
reset = 0; #100;
|
||||
reset = 1; #100;
|
||||
reset = 0; #490;
|
||||
JumpOrBranch = 1; #60;
|
||||
JumpOrBranch = 0; #500;
|
||||
$finish;
|
||||
end
|
||||
|
||||
// NextPC Monitor
|
||||
initial begin
|
||||
$monitor("time=%0t clk=%b reset=%b JumpOrBranch=%0h CurrentPC=%0h NextPC=%0h", $time, clk, reset, JumpOrBranch, CurrentPC, NextPC);
|
||||
end
|
||||
|
||||
// Wave Dump Helper Task
|
||||
task dumpWave(string fileName);
|
||||
// Open wave file and dump all signals (2D arrays not included)
|
||||
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||
$dumpfile(fileName);
|
||||
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "pc_tb");
|
||||
$dumpvars(0, pc_tb);
|
||||
endtask: dumpWave
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,137 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Bomin Kim
|
||||
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
`timescale 1ns/1ns
|
||||
|
||||
module reg_file_tb ();
|
||||
|
||||
// Local Signals
|
||||
logic[4:0] Rs1;
|
||||
logic[4:0] Rs2;
|
||||
logic[4:0] Rd;
|
||||
logic[31:0] RRs1;
|
||||
logic[31:0] RRs2;
|
||||
logic[31:0] WRd;
|
||||
logic WrReg;
|
||||
logic reset;
|
||||
logic clk;
|
||||
|
||||
// Toplevel instance (DUT)
|
||||
reg_file u_reg_file (
|
||||
.Rs1(Rs1),
|
||||
.Rs2(Rs2),
|
||||
.Rd(Rd),
|
||||
.RRs1(RRs1),
|
||||
.RRs2(RRs2),
|
||||
.WRd(WRd),
|
||||
.WrReg(WrReg),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
// Clock generation
|
||||
always #20 clk = ~clk;
|
||||
|
||||
// Initialization and run simulation
|
||||
initial begin
|
||||
dumpWave("wave.vcd");
|
||||
|
||||
// Initialize inputs
|
||||
clk = 0;
|
||||
Rs1 = 0; Rs2 = 0; Rd = 0;
|
||||
WRd = 0; WrReg = 0; // Read
|
||||
reset = 1;
|
||||
|
||||
#50
|
||||
reset = 0;
|
||||
|
||||
#50 // Write 0xDEADBEEF to reg21
|
||||
Rd = 5'd21;
|
||||
WrReg = 1; // Write
|
||||
WRd = 32'hDEADBEEF;
|
||||
#50; WrReg = 0;
|
||||
|
||||
#50
|
||||
Rs1 = 5'd21; // read reg21 into RRs1
|
||||
Rs2 = 5'd0;
|
||||
|
||||
#50 // Write 0x12345678 to reg5
|
||||
Rd = 5'd5;
|
||||
WrReg = 1; // Write
|
||||
WRd = 32'h12345678;
|
||||
#50; WrReg = 0;
|
||||
|
||||
#50
|
||||
Rs1 = 5'd5; // read reg10 into RRs1
|
||||
|
||||
#50
|
||||
Rs1 = 5'd0; // read zero register
|
||||
|
||||
#50
|
||||
Rd = 5'd0; // attempt to write 0xCAFEBABE to zero register
|
||||
WRd = 32'hCAFEBABE;
|
||||
WrReg = 1; // Write
|
||||
#50; WrReg = 0;
|
||||
|
||||
#50
|
||||
Rs1 = 5'd5; // Read from reg5
|
||||
#200
|
||||
|
||||
$finish;
|
||||
end
|
||||
|
||||
// Wave Dump Helper Task
|
||||
task dumpWave(string fileName);
|
||||
// Open wave file and dump all signals (2D arrays not included)
|
||||
$display("\nTime = %0dns \t : Opening wave file '%s'", $time, fileName);
|
||||
$dumpfile(fileName);
|
||||
$display("Time = %0dns \t : Dumping all %s signals in wave file (2D arrays not included)", $time, "reg_file_tb");
|
||||
$dumpvars(0, reg_file_tb);
|
||||
|
||||
// Dump registers in wave file
|
||||
$display("\nTime = %0dns \t : Dumping Registers in wave file", $time);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[1]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[2]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[3]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[4]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[5]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[6]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[7]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[8]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[9]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[10]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[11]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[12]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[13]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[14]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[15]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[16]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[17]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[18]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[19]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[20]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[21]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[22]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[23]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[24]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[25]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[26]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[27]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[28]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[29]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[30]);
|
||||
$dumpvars(0, reg_file_tb.u_reg_file.registers[31]);
|
||||
endtask: dumpWave
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,79 @@
|
||||
# OpenFile ./cpu_tb.sv
|
||||
ls
|
||||
# alu_tb.sv decoder_tb.sv pc_tb.sv transcript
|
||||
# cpu_tb.sv main_mem_tb.sv reg_file_tb.sv work
|
||||
vsim compile.tcl
|
||||
# vsim compile.tcl
|
||||
# Start time: 11:01:25 on Nov 28,2025
|
||||
# ** Error (suppressible): (vsim-19) Failed to access library 'compile' at "compile".
|
||||
# No such file or directory. (errno = ENOENT)
|
||||
# Error loading design
|
||||
# End time: 11:01:25 on Nov 28,2025, Elapsed time: 0:00:00
|
||||
# Errors: 1, Warnings: 0
|
||||
ls
|
||||
# alu_tb.sv decoder_tb.sv pc_tb.sv transcript
|
||||
# cpu_tb.sv main_mem_tb.sv reg_file_tb.sv work
|
||||
cd ..
|
||||
ls
|
||||
# rtl verilator wave_configs
|
||||
cd ..
|
||||
pwd
|
||||
# C:/PhD/RISC-V Design Course Material/RISC-V Desgin Course - Complete Source Code/riscv_in3days-public/hw
|
||||
cd ..
|
||||
ls
|
||||
# README.md doc hw sw
|
||||
cd ..
|
||||
ls
|
||||
# riscv_in3days-public
|
||||
cd ..
|
||||
ls
|
||||
# Course Introduction & Closing - Public.pdf
|
||||
# Day 1
|
||||
# Day 2
|
||||
# Day 3
|
||||
# Day 4
|
||||
# RISC-V Desgin Course - Complete Source Code
|
||||
# References
|
||||
cd ..
|
||||
cd ..
|
||||
la
|
||||
# ambiguous command name "la": label labelframe langOf lappend lassign lattice_edition layout
|
||||
ls
|
||||
# Drivers Program Files (x86) inetpub
|
||||
# DumpStack.log Steam_Community_Markt intelFPGA
|
||||
# Lukas Users intelFPGA_lite
|
||||
# PhD Windows vfcompat.dll
|
||||
# ProcLogs appverifUI.dll
|
||||
# Program Files flexlm
|
||||
pwd
|
||||
# C:/
|
||||
ls
|
||||
# Drivers Program Files (x86) inetpub
|
||||
# DumpStack.log Steam_Community_Markt intelFPGA
|
||||
# Lukas Users intelFPGA_lite
|
||||
# PhD Windows vfcompat.dll
|
||||
# ProcLogs appverifUI.dll
|
||||
# Program Files flexlm
|
||||
cd PhD
|
||||
ls
|
||||
# Code compile.tcl
|
||||
# RISC-V Design Course Material
|
||||
cd RISC-V Design Course Material
|
||||
# wrong # args: should be "cd ?dirName?"
|
||||
ls
|
||||
# Code compile.tcl
|
||||
# RISC-V Design Course Material
|
||||
ls
|
||||
# Code compile.tcl
|
||||
# RISC-V Design Course Material
|
||||
cd RISC-V Design Course Material
|
||||
# wrong # args: should be "cd ?dirName?"
|
||||
ls
|
||||
# Code compile.tcl
|
||||
# RISC-V Design Course Material
|
||||
run compile.tcl
|
||||
# No Design Loaded!
|
||||
compile.tcl
|
||||
# couldn't execute ".\compile.tcl": no such file or directory
|
||||
run compile.tcl
|
||||
# No Design Loaded!
|
||||
@@ -0,0 +1,10 @@
|
||||
m255
|
||||
K4
|
||||
z2
|
||||
13
|
||||
!s112 1.1
|
||||
!i10d 8192
|
||||
!i10e 25
|
||||
!i10f 100
|
||||
cModel Technology
|
||||
dC:/PhD/RISC-V Design Course Material/RISC-V Desgin Course - Complete Source Code/riscv_in3days-public/hw/dv/rtl
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -0,0 +1,78 @@
|
||||
export PRJ_ROOT = ../../..
|
||||
|
||||
|
||||
# directroy containig syrinx application programs
|
||||
SWDIR = $(PRJ_ROOT)/sw/risc-v
|
||||
DVDIR = $(PRJ_ROOT)/hw/dv
|
||||
|
||||
# toplevel syrinx file list
|
||||
RTL_FLIST = $(PRJ_ROOT)/hw/file_lists/rtl_flist.f
|
||||
TB_FLIST = $(PRJ_ROOT)/hw/file_lists/tb_flist.f
|
||||
|
||||
|
||||
# if we have multiple file list, we combine them here
|
||||
FLIST = -f $(RTL_FLIST) -f $(TB_FLIST)
|
||||
|
||||
# Default number of simulation cycles
|
||||
NCYCLES ?= 500
|
||||
|
||||
# Standard boot loader and dummy application to be used if nothing else is specified
|
||||
|
||||
PROG ?= $(SWDIR)/hello_world/helloWorld.hex
|
||||
|
||||
# top module name
|
||||
TOPMODULE = cpu_harness
|
||||
|
||||
# NUmber of GCC parallel threads
|
||||
COMPILE_THREADS = 32
|
||||
|
||||
# Verilator CPU usage, should be adapated to simulation host
|
||||
SIM_THREADS = 4
|
||||
TRACE_THREADS = 1
|
||||
|
||||
|
||||
EXTRA_ARGS += --trace-fst --trace-structs --trace-max-array 2048 --trace-threads $(TRACE_THREADS) --threads $(SIM_THREADS)
|
||||
EXTRA_ARGS += --clk clk --no-timing
|
||||
# EXTRA_ARGS += -O2
|
||||
|
||||
# Used by some code constructs
|
||||
VDEFS = +define+SIMULATION
|
||||
|
||||
|
||||
|
||||
all: ./obj_dir/V$(TOPMODULE)
|
||||
|
||||
wave: wavedump.fst
|
||||
@echo
|
||||
@echo "*** Starting waveform viewer..."
|
||||
$(WAVE_VIEWER) wavedump.fst -s $(DVDIR)/wave_configs/verilator_wave.surf.ron
|
||||
|
||||
run:
|
||||
@echo
|
||||
@echo "*** Running simulation..."
|
||||
@./obj_dir/V$(TOPMODULE) $(NCYCLES) $(PROG)
|
||||
|
||||
./obj_dir/V$(TOPMODULE): .stamp.verilate
|
||||
@echo
|
||||
@echo "*** Building simulator..."
|
||||
make -C obj_dir -f V$(TOPMODULE).mk V$(TOPMODULE) -j $(COMPILE_THREADS)
|
||||
|
||||
.stamp.verilate: src/tb_$(TOPMODULE).cpp
|
||||
@echo "*** Generating C++ model..."
|
||||
$(VERILATOR) --trace $(EXTRA_ARGS) $(VDEFS) -cc $(FLIST) --top-module $(TOPMODULE) --exe src/tb_$(TOPMODULE).cpp
|
||||
@touch .stamp.verilate
|
||||
|
||||
lint:$(VERILOG_SOURCES)
|
||||
$(VERILATOR) --lint-only $(INCLUDES) $(VERILOG_SOURCES) --top-module $(TOPMODULE)
|
||||
|
||||
|
||||
paths:
|
||||
@echo $(PRJ_ROOT)/$(APB)
|
||||
|
||||
|
||||
|
||||
clean:
|
||||
rm -rf .stamp.*;
|
||||
rm -rf ./obj_dir
|
||||
rm -rf wavedump.fst*
|
||||
rm -rf *.dasm
|
||||
@@ -0,0 +1,148 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Verilator simulation harness
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Aug.2025 by Marcus Bednara
|
||||
// Last Modified : 15.Oct.2025 by Hussein Elzomor [commit d0452cd]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 H.Elzomor Renamed file and module from soc_harness to cpu_harness
|
||||
// 15.Oct.2025 H.Elzomor Added getMem function, setMem task and printMem task
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
timeunit 1ps;
|
||||
timeprecision 1ps;
|
||||
|
||||
module cpu_harness;
|
||||
|
||||
// local signals
|
||||
logic clk,
|
||||
rst;
|
||||
|
||||
logic [7:0] led;
|
||||
|
||||
logic [6:0] btn;
|
||||
|
||||
|
||||
// toplevel instance (DUT)
|
||||
|
||||
cpu u_cpu (
|
||||
.led (led),
|
||||
.btn ({btn[6:1], rst}),
|
||||
.clk_25mhz (clk)
|
||||
); // u_cpu
|
||||
|
||||
|
||||
`ifdef VERILATOR
|
||||
|
||||
// Declare all functions with DPI-C interface to make them accessible from the C++ testbench
|
||||
|
||||
export "DPI-C" task setClk;
|
||||
export "DPI-C" task enable;
|
||||
export "DPI-C" task loadRAM;
|
||||
// export "DPI-C" task dumpSRAM;
|
||||
export "DPI-C" task setInitial;
|
||||
export "DPI-C" function getLed;
|
||||
export "DPI-C" task setBtn;
|
||||
export "DPI-C" task setReset;
|
||||
export "DPI-C" function getMem;
|
||||
export "DPI-C" task setMem;
|
||||
export "DPI-C" task printMem;
|
||||
export "DPI-C" function getReg;
|
||||
export "DPI-C" task printReg;
|
||||
|
||||
|
||||
// Clocking is controlled from C++ testbench
|
||||
task setClk (input logic val);
|
||||
clk = val;
|
||||
endtask: setClk
|
||||
|
||||
`else
|
||||
|
||||
// If not using verilator, generate clock here
|
||||
|
||||
const realtime clk_PERIOD = 1.0ns;
|
||||
|
||||
|
||||
initial begin: clock_driver
|
||||
clk = '1;
|
||||
forever begin
|
||||
#(clk_PERIOD/2.0);
|
||||
clk <= ~clk;
|
||||
end
|
||||
end: clock_driver
|
||||
|
||||
task wait_clk_cycles(int unsigned n);
|
||||
repeat(n) @(posedge clk);
|
||||
endtask
|
||||
|
||||
`endif
|
||||
|
||||
|
||||
// Remaining tasks are identical for Verilator and other simulators
|
||||
|
||||
|
||||
|
||||
task loadRAM (input string fileName);
|
||||
$display ("Initializing SRAM memory from %s", fileName);
|
||||
$readmemh(fileName, u_cpu.theMem.RAM);
|
||||
endtask: loadRAM
|
||||
|
||||
|
||||
/* Some helper stuff */
|
||||
|
||||
task enable(int val);
|
||||
// nothing to do, we have no fetch enable in this design
|
||||
endtask: enable
|
||||
|
||||
task setInitial();
|
||||
btn = 7'b0;
|
||||
rst = 'b0;
|
||||
endtask: setInitial
|
||||
|
||||
function int getLed;
|
||||
getLed = {24'b0, led};
|
||||
endfunction: getLed
|
||||
|
||||
task setBtn(int val);
|
||||
btn[6:1] = val[5:0];
|
||||
endtask: setBtn
|
||||
|
||||
task setReset (input int val);
|
||||
rst = (val==1);
|
||||
endtask: setReset
|
||||
|
||||
function int getMem(int location);
|
||||
getMem = u_cpu.theMem.RAM[location];
|
||||
endfunction: getMem
|
||||
|
||||
task setMem(int location, int value);
|
||||
u_cpu.theMem.RAM[location] = value;
|
||||
endtask: setMem
|
||||
|
||||
task printMem (int location, string prog);
|
||||
case (prog)
|
||||
"fibonacci" :$display("Value at RAM[%0d]: 0x%h : %0d", location, getMem(location), getMem(location));
|
||||
"helloWorld" :$display("Value at RAM[%0d]: 0x%h : %s" , location, getMem(location), getMem(location));
|
||||
default :$display("Value at RAM[%0d]: 0x%h : %0d", location, getMem(location), getMem(location));
|
||||
endcase
|
||||
endtask: printMem
|
||||
|
||||
function int getReg(int location);
|
||||
getReg = u_cpu.theRegisters.registers[location];
|
||||
endfunction: getReg
|
||||
|
||||
task printReg (int location, string prog);
|
||||
case (prog)
|
||||
"primeNumber" :$display("Time =%5dns \t : Register [%0d] updated - Finding the prime factors of %0d", $time, location, getReg(location));
|
||||
"primeFactors":$display("Time =%5dns \t : Register [%0d] updated - %0d is a prime factor", $time, location, getReg(location));
|
||||
default :$display("Time =%5dns \t : Value at Reg[%0d]: 0x%h", $time, location, getReg(location));
|
||||
endcase
|
||||
endtask: printReg
|
||||
|
||||
endmodule: cpu_harness
|
||||
@@ -0,0 +1,173 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Verilator simulation harness
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
timeunit 1ps;
|
||||
timeprecision 1ps;
|
||||
|
||||
module decoder_harness;
|
||||
// local Parameters
|
||||
localparam MEM_SIZE = 37;
|
||||
localparam REG_FILE_SIZE = 32;
|
||||
|
||||
// local signals
|
||||
logic clk;
|
||||
int counter;
|
||||
logic[31:0] mem [MEM_SIZE-1:0];
|
||||
logic[31:0] regFile [REG_FILE_SIZE-1:0];
|
||||
// PC
|
||||
logic[31:0] CurrentPC;
|
||||
logic[31:0] JumpOrBranchPC;
|
||||
logic JumpOrBranch;
|
||||
logic[31:0] NextPC;
|
||||
// Memory
|
||||
logic[31:0] DAddr;
|
||||
logic[31:0] WData;
|
||||
logic[31:0] RData;
|
||||
logic[31:0] Instruction;
|
||||
logic WrMem;
|
||||
logic[1:0] DWidth;
|
||||
// Register File;
|
||||
logic[4:0] Rs1;
|
||||
logic[4:0] Rs2;
|
||||
logic[4:0] Rd;
|
||||
logic[31:0] RRs1;
|
||||
logic[31:0] RRs2;
|
||||
logic[31:0] WRd;
|
||||
logic WrReg;
|
||||
// Protection
|
||||
logic Illegal;
|
||||
|
||||
// toplevel instance (DUT)
|
||||
decoder u_decoder (
|
||||
// PC
|
||||
.CurrentPC(CurrentPC),
|
||||
.JumpOrBranchPC(JumpOrBranchPC),
|
||||
.JumpOrBranch(JumpOrBranch),
|
||||
// Memory
|
||||
.DAddr(DAddr),
|
||||
.WData(WData),
|
||||
.RData(RData),
|
||||
.Instruction(Instruction),
|
||||
.WrMem(WrMem),
|
||||
.DWidth(DWidth),
|
||||
// Register File
|
||||
.Rs1(Rs1),
|
||||
.Rs2(Rs2),
|
||||
.Rd(Rd),
|
||||
.RRs1(RRs1),
|
||||
.RRs2(RRs2),
|
||||
.WRd(WRd),
|
||||
.WrReg(WrReg),
|
||||
// Protection
|
||||
.Illegal(Illegal)
|
||||
); // u_decoder
|
||||
|
||||
|
||||
// Special Verilator specific tasks
|
||||
`ifdef VERILATOR
|
||||
|
||||
// Declare all functions with DPI-C interface to make them accessible from the C++ testbench
|
||||
// Setters
|
||||
export "DPI-C" task setClk;
|
||||
export "DPI-C" task enable;
|
||||
export "DPI-C" task loadRAM;
|
||||
export "DPI-C" task setInitial;
|
||||
export "DPI-C" task printInfo;
|
||||
|
||||
// Clocking is controlled from C++ testbench
|
||||
task setClk (input logic val);
|
||||
clk = val;
|
||||
endtask: setClk
|
||||
|
||||
`else
|
||||
|
||||
// If not using verilator, generate clock here
|
||||
const realtime clk_PERIOD = 1.0ns;
|
||||
|
||||
initial begin: clock_driver
|
||||
clk = '1;
|
||||
forever begin
|
||||
#(clk_PERIOD/2.0);
|
||||
clk <= ~clk;
|
||||
end
|
||||
end: clock_driver
|
||||
|
||||
task wait_clk_cycles(int unsigned n);
|
||||
repeat(n) @(posedge clk);
|
||||
endtask
|
||||
|
||||
`endif
|
||||
|
||||
// Load a new instruction every cycle
|
||||
always_ff @(posedge clk) begin: increment_instruction_and_print_info
|
||||
if (counter < MEM_SIZE) begin
|
||||
if (counter > 0) printInfo();
|
||||
Instruction = mem[counter++];
|
||||
end
|
||||
end
|
||||
|
||||
// Return the value of the RegFile
|
||||
always_comb begin: reg_file_assignment
|
||||
RRs1 = regFile[Rs1];
|
||||
RRs2 = regFile[Rs2];
|
||||
end
|
||||
|
||||
// Remaining tasks are identical for Verilator and other simulators
|
||||
task enable(int val);
|
||||
// nothing to do, we have no fetch enable in this design
|
||||
endtask: enable
|
||||
|
||||
// Load data into memory
|
||||
task loadRAM (input string fileName);
|
||||
$display ("Initializing SRAM memory from %s", fileName);
|
||||
$readmemh(fileName, mem);
|
||||
endtask: loadRAM
|
||||
|
||||
// Set initial values
|
||||
task setInitial();
|
||||
Instruction = mem[0];
|
||||
counter = 0;
|
||||
CurrentPC = 32'hdeadbeef;
|
||||
RData = 32'hbeefdead;
|
||||
for(int i=0; i<REG_FILE_SIZE; i++) begin
|
||||
regFile[i] = i;
|
||||
end
|
||||
endtask: setInitial
|
||||
|
||||
// Print decoder signals
|
||||
task printInfo();
|
||||
$displayh("(cycle %0d) Decoder (I/O) \tDecoder (Internal Signals) \tALU" , counter );
|
||||
$displayh(" -------------------------- \t--------------------------------------------- \t---------------------" , );
|
||||
$displayh(" CurrentPC : 0x%h OpCode : 0b%b aluOp : 0b%b" , CurrentPC , u_decoder.theOp , u_decoder.aluOp );
|
||||
$displayh(" JumpOrBranchPC: 0x%h theFunct3: 0b%b aluNegAr : 0b%b", JumpOrBranchPC, u_decoder.theFunct3, u_decoder.aluNegAr );
|
||||
$displayh(" JumpOrBranch : 0b%b \ttheFunct7: 0b%b aluBypass: 0b%b", JumpOrBranch , u_decoder.theFunct7, u_decoder.aluBypass);
|
||||
$displayh(" DAddr : 0x%h i_imm : 0b%b op1 : 0x%h" , DAddr , u_decoder.i_imm , u_decoder.op1 );
|
||||
$displayh(" WData : 0x%h s_imm : 0b%b op2 : 0x%h" , WData , u_decoder.s_imm , u_decoder.op2 );
|
||||
$displayh(" RData : 0x%h b_imm : 0b%b result : 0x%h" , RData , u_decoder.b_imm , u_decoder.result );
|
||||
$displayh(" Instruction : 0x%h u_imm : 0b%b eqFlag : 0b%b" , Instruction , u_decoder.u_imm , u_decoder.eqFlag );
|
||||
$displayh(" WrMem : 0b%b \tj_imm : 0b%b" , WrMem , u_decoder.j_imm );
|
||||
$displayh(" DWidth : 0b%b" , DWidth );
|
||||
$displayh(" Rs1 : %0d " , Rs1 );
|
||||
$displayh(" Rs2 : %0d " , Rs2 );
|
||||
$displayh(" Rd : 0x%h" , Rd );
|
||||
$displayh(" RRs1 : %0d " , RRs1 );
|
||||
$displayh(" RRs2 : %0d " , RRs2 );
|
||||
$displayh(" WRd : 0x%h" , WRd );
|
||||
$displayh(" WrReg : 0b%b" , WrReg );
|
||||
$displayh(" Illegal : 0b%b" , Illegal );
|
||||
$displayh("");
|
||||
endtask: printInfo
|
||||
|
||||
endmodule: decoder_harness
|
||||
@@ -0,0 +1,328 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Verilator tb
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Aug.2025 by Marcus Bednara
|
||||
// Last Modified : 15.Oct.2025 by Hussein Elzomor [commit d0452cd]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 H.Elzomor Renamed modules from *soc* to *cpu*
|
||||
// 15.Oct.2025 H.Elzomor Added evalText function
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <verilated.h>
|
||||
#include <verilated_fst_c.h>
|
||||
#include "Vcpu_harness.h"
|
||||
#include "Vcpu_harness__Dpi.h"
|
||||
|
||||
// only required for accessing model internal memory ressources via the rootp pointer.
|
||||
// Bad style, better use systemverilog harness with tasks and functions to do that.
|
||||
// #include "Vcpu_harness___024root.h"
|
||||
// #include "svdpi.h"
|
||||
|
||||
|
||||
#define SOC_CLK_PERIOD 40
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Simulation environment class for the cpu model.
|
||||
/// Contains a set of high level methods for controlling the model from test environment.
|
||||
class cpu
|
||||
{
|
||||
private:
|
||||
|
||||
Vcpu_harness *dut;
|
||||
VerilatedFstC *mTrace;
|
||||
vluint64_t T;
|
||||
|
||||
uint32_t cpuClkState;
|
||||
|
||||
bool running;
|
||||
|
||||
string program;
|
||||
|
||||
public:
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Constructor
|
||||
cpu (int argc, char** argv)
|
||||
{
|
||||
// setup verilator stuff
|
||||
T = 0;
|
||||
dut = new Vcpu_harness();
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Verilated::traceEverOn(true);
|
||||
mTrace = new VerilatedFstC;
|
||||
dut->trace(mTrace, 5);
|
||||
mTrace->open("wavedump.fst");
|
||||
|
||||
cout << "Registered DPI-C functions:\n";
|
||||
Verilated::scopesDump();
|
||||
const svScope scope = svGetScopeFromName("TOP.cpu_harness");
|
||||
assert(scope); // Check for nullptr if scope not found
|
||||
svSetScope(scope);
|
||||
|
||||
running = false;
|
||||
|
||||
// initialize all input signals
|
||||
initSignals();
|
||||
|
||||
} // swirl()
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief simulation tick, advances the simulation time and calls the eval() function of the model on every active clock edge
|
||||
void tick ()
|
||||
{
|
||||
int do_eval;
|
||||
|
||||
if (T%SOC_CLK_PERIOD==0) {
|
||||
dut->setClk(cpuClkState);
|
||||
cpuClkState = 1-cpuClkState;
|
||||
do_eval = 1;
|
||||
}
|
||||
|
||||
|
||||
// Other clock domains must be generated the same way
|
||||
|
||||
// if (T%OTHER_CLK_PERIOD==0) {
|
||||
// dut->setOtherClk(otherClkState);
|
||||
// otherClkState = 1-otherClkState;
|
||||
// do_eval = 1;
|
||||
// }
|
||||
|
||||
if (do_eval) {
|
||||
dut->eval();
|
||||
// evaluate the LED status in each clock cycle if the CPU is running (i.e., after reset)
|
||||
if (running && program == "unknown") evalLed();
|
||||
// evaluate the Fibonacci Series location in stack (starting at 2027) and print value if it has changed
|
||||
if (running && program == "fibonacci") evalFibonacci();
|
||||
// evaluate the 'hello world!' location in the DataMem in each clock cycle if the CPU is running (i.e., after reset)
|
||||
if (running && program == "helloWorld") evalHelloWorld();
|
||||
// evaluate the Prime Factors location in RegFile (x17) and print value if it has changed
|
||||
if (running && program == "primeFactors") evalPrimeFactors();
|
||||
mTrace->dump(T);
|
||||
do_eval = 0;
|
||||
}
|
||||
|
||||
T++;
|
||||
|
||||
} // tick()
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Initialize all input signals of the hardware model to a defined value
|
||||
void initSignals()
|
||||
{
|
||||
dut->setInitial();
|
||||
} // initSignals()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Wait for a number of active edges of clk signal
|
||||
/// @param numEdges number of rising edges
|
||||
/// @param active active 1=rising 0=falling edge
|
||||
void waitClocks (int numEdges=1, int activeEdge=1)
|
||||
{
|
||||
int clk_d;
|
||||
|
||||
for (int j=0; j<numEdges; ++j) {
|
||||
while (1) {
|
||||
clk_d = cpuClkState;
|
||||
tick();
|
||||
if (clk_d==1-activeEdge && cpuClkState==activeEdge) break;
|
||||
}
|
||||
} // for
|
||||
} // waitClocks()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Toggle the reset signal active (low)
|
||||
/// @param numEdges number of clock cyles keeping the reset active
|
||||
void reset (int numEdges=1)
|
||||
{
|
||||
dut->setReset(0); // reset is active low
|
||||
waitClocks (numEdges);
|
||||
dut->setReset(1);
|
||||
} // reset();
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief load the cpu memory from vmem formatted file
|
||||
void loadRAM (char* vmemFile)
|
||||
{
|
||||
dut->loadRAM(vmemFile);
|
||||
} // loadRAM()
|
||||
|
||||
/// @brief check the LED status and print value if it has change
|
||||
void evalLed ()
|
||||
{
|
||||
static uint8_t oldLedStatus=0xff;
|
||||
uint8_t currentLedStatus;
|
||||
currentLedStatus=dut->getLed();
|
||||
if (currentLedStatus!=oldLedStatus) {
|
||||
cout << "T=" << T << ": LED=" << std::bitset<8>(currentLedStatus) << endl;
|
||||
oldLedStatus = currentLedStatus;
|
||||
}
|
||||
} // evalLed()
|
||||
|
||||
/// @brief check Fibonacci Series location in stack (starting at 2027) and print value if it has changed
|
||||
void evalFibonacci()
|
||||
{
|
||||
int memStartLoc = 2027;
|
||||
const int memLengthInBytes = 40;
|
||||
const int memLengthInWords = ceil(memLengthInBytes / 4.0);
|
||||
static uint32_t oldValue[memLengthInWords];
|
||||
uint32_t vlaue[memLengthInWords];
|
||||
bool update = 0;
|
||||
for (int i = 0; i < memLengthInWords; i++)
|
||||
{
|
||||
vlaue[i] = dut->getMem(memStartLoc + i);
|
||||
if (oldValue[i] != vlaue[i])
|
||||
update = 1;
|
||||
}
|
||||
if (update)
|
||||
{
|
||||
cout << endl
|
||||
<< "T=" << T << ": \t Hex \t Dec" << endl;
|
||||
for (int i = 0; i < memLengthInWords; i++)
|
||||
{
|
||||
dut->printMem(memStartLoc + i, "fibonacci");
|
||||
oldValue[i] = vlaue[i];
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
} // evalFibonacci()
|
||||
|
||||
/// @brief check 'hello world' location in DataMem (starting at 1024) and print value if it has changed
|
||||
void evalHelloWorld()
|
||||
{
|
||||
int memStartLoc = 1024;
|
||||
const int memLengthInBytes = 13;
|
||||
const int memLengthInWords = ceil(memLengthInBytes / 4.0);
|
||||
static uint32_t oldValue[memLengthInWords];
|
||||
uint32_t vlaue[memLengthInWords];
|
||||
bool update = 0;
|
||||
for (int i = 0; i < memLengthInWords; i++)
|
||||
{
|
||||
vlaue[i] = dut->getMem(memStartLoc + i);
|
||||
if (oldValue[i] != vlaue[i])
|
||||
update = 1;
|
||||
}
|
||||
if (update)
|
||||
{
|
||||
cout << endl
|
||||
<< "T=" << T << ": \t Hex \t ASCII" << endl;
|
||||
for (int i = 0; i < memLengthInWords; i++)
|
||||
{
|
||||
dut->printMem(memStartLoc + i, "helloWorld");
|
||||
oldValue[i] = vlaue[i];
|
||||
}
|
||||
cout << endl;
|
||||
}
|
||||
} // evalHelloWorld()
|
||||
|
||||
/// @brief check Prime Factors location in RegFile (x17) and print value if it has changed
|
||||
void evalPrimeFactors()
|
||||
{
|
||||
// Number to be factorised
|
||||
int regLoc_Number = 16;
|
||||
static uint32_t oldValue_Number;
|
||||
uint32_t value_Number;
|
||||
value_Number = dut->getReg(regLoc_Number);
|
||||
if (oldValue_Number != value_Number & value_Number > 1) dut->printReg(regLoc_Number, "primeNumber");
|
||||
oldValue_Number = value_Number;
|
||||
|
||||
// Prime Factors
|
||||
int regLoc_PrimeFactor = 17;
|
||||
static uint32_t oldValue_PrimeFactor;
|
||||
uint32_t value_PrimeFactor;
|
||||
value_PrimeFactor = dut->getReg(regLoc_PrimeFactor);
|
||||
if (oldValue_PrimeFactor != value_PrimeFactor & value_PrimeFactor > 1) dut->printReg(regLoc_PrimeFactor, "primeFactors");
|
||||
oldValue_PrimeFactor = value_PrimeFactor;
|
||||
|
||||
} // evalPrimeFactors()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief start the DUT
|
||||
void start()
|
||||
{
|
||||
running = true;
|
||||
dut->enable(1);
|
||||
} // start()
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief close the trace file and delete the Verilator object
|
||||
void stop()
|
||||
{
|
||||
dut->enable(0);
|
||||
mTrace->close();
|
||||
delete dut;
|
||||
} // stop()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Set the program name
|
||||
void setProgram(string prog)
|
||||
{
|
||||
if (prog.find("fibonacci") != string::npos) program = "fibonacci";
|
||||
else if (prog.find("helloWorld") != string::npos) program = "helloWorld";
|
||||
else if (prog.find("primeFactors") != string::npos) program = "primeFactors";
|
||||
else program = "unknown";
|
||||
|
||||
cout << "program set to " << program << endl;
|
||||
} // setProgram()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Get the program name
|
||||
string getProgram()
|
||||
{
|
||||
return program;
|
||||
} // getProgram()
|
||||
|
||||
}; // class cpu
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
uint32_t nCycles;
|
||||
char* program_path = new char[strlen(argv[2])]();
|
||||
|
||||
// Get number of simulation cycles
|
||||
nCycles = atoi(argv[1]);
|
||||
|
||||
// Get the program
|
||||
program_path = argv[2];
|
||||
string program_path_str = program_path;
|
||||
|
||||
cout << "\nCreating model...\n";
|
||||
cpu *m = new cpu(argc, argv);
|
||||
m->loadRAM(program_path);
|
||||
m->setProgram(program_path_str);
|
||||
|
||||
cout << "\nStarting model...\n";
|
||||
|
||||
cout << "\nResetting...\n";
|
||||
m->reset(10);
|
||||
|
||||
cout << "Starting CPU...\n" << std::flush;
|
||||
m->start();
|
||||
|
||||
cout << "Running for " << nCycles << " clock cycles...\n\n" << std::flush;
|
||||
cout << "Printing evaluation for " << m->getProgram() << " program!\n" << std::flush;
|
||||
m->waitClocks(nCycles);
|
||||
|
||||
cout << "\nDone, closing simulation.\n\n\n" << std::flush;
|
||||
m->stop();
|
||||
delete m;
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
@@ -0,0 +1,185 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Verilator tb
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
using namespace std;
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
#include <verilated.h>
|
||||
#include <verilated_fst_c.h>
|
||||
#include "Vdecoder_harness.h"
|
||||
#include "Vdecoder_harness__Dpi.h"
|
||||
|
||||
// only required for accessing model internal memory ressources via the rootp pointer.
|
||||
// Bad style, better use systemverilog harness with tasks and functions to do that.
|
||||
// #include "Vdecoder_harness___024root.h"
|
||||
// #include "svdpi.h"
|
||||
|
||||
|
||||
#define DECODER_CLK_PERIOD 40
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Simulation environment class for the decoder model.
|
||||
/// Contains a set of high level methods for controlling the model from test environment.
|
||||
class decoder
|
||||
{
|
||||
private:
|
||||
|
||||
Vdecoder_harness *dut;
|
||||
VerilatedFstC *mTrace;
|
||||
vluint64_t T;
|
||||
|
||||
uint32_t decoderClkState;
|
||||
bool running;
|
||||
|
||||
public:
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Constructor
|
||||
decoder (int argc, char** argv)
|
||||
{
|
||||
// setup verilator stuff
|
||||
T = 0;
|
||||
dut = new Vdecoder_harness();
|
||||
Verilated::commandArgs(argc, argv);
|
||||
Verilated::traceEverOn(true);
|
||||
mTrace = new VerilatedFstC;
|
||||
dut->trace(mTrace, 5);
|
||||
mTrace->open("wavedump.fst");
|
||||
|
||||
cout << "Registered DPI-C functions:\n";
|
||||
Verilated::scopesDump();
|
||||
const svScope scope = svGetScopeFromName("TOP.decoder_harness");
|
||||
assert(scope); // Check for nullptr if scope not found
|
||||
svSetScope(scope);
|
||||
|
||||
running = false;
|
||||
|
||||
// initialize all input signals
|
||||
initSignals();
|
||||
|
||||
} // swirl()
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief simulation tick, advances the simulation time and calls the eval() function of the model on every active clock edge
|
||||
void tick ()
|
||||
{
|
||||
int do_eval;
|
||||
|
||||
if (T%DECODER_CLK_PERIOD==0) {
|
||||
dut->setClk(decoderClkState);
|
||||
decoderClkState = 1-decoderClkState;
|
||||
do_eval = 1;
|
||||
}
|
||||
|
||||
if (do_eval) {
|
||||
dut->eval();
|
||||
mTrace->dump(T);
|
||||
do_eval = 0;
|
||||
}
|
||||
|
||||
T++;
|
||||
|
||||
} // tick()
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Initialize all input signals of the hardware model to a defined value
|
||||
void initSignals()
|
||||
{
|
||||
dut->setInitial();
|
||||
} // initSignals()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief Wait for a number of active edges of clk signal
|
||||
/// @param numEdges number of rising edges
|
||||
/// @param active active 1=rising 0=falling edge
|
||||
void waitClocks (int numEdges=1, int activeEdge=1)
|
||||
{
|
||||
int clk_d;
|
||||
|
||||
for (int j=0; j<numEdges; ++j) {
|
||||
while (1) {
|
||||
clk_d = decoderClkState;
|
||||
tick();
|
||||
if (clk_d==1-activeEdge && decoderClkState==activeEdge) break;
|
||||
}
|
||||
} // for
|
||||
} // waitClocks()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief load the decoder memory from vmem formatted file
|
||||
void loadRAM(char *vmemFile)
|
||||
{
|
||||
dut->loadRAM(vmemFile);
|
||||
} // loadRAM()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief start the DUT
|
||||
void start()
|
||||
{
|
||||
running = true;
|
||||
dut->enable(1);
|
||||
} // start()
|
||||
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief close the trace file and delete the Verilator object
|
||||
void stop()
|
||||
{
|
||||
dut->enable(0);
|
||||
mTrace->close();
|
||||
delete dut;
|
||||
} // stop()
|
||||
|
||||
//--------------------------------------------------------------
|
||||
/// @brief print signal info
|
||||
void printInfo()
|
||||
{
|
||||
dut->printInfo();
|
||||
}
|
||||
}; // class decoder
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
int main (int argc, char** argv)
|
||||
{
|
||||
uint32_t nCycles;
|
||||
int r;
|
||||
|
||||
// Get number of simulation cycles
|
||||
nCycles = atoi(argv[1]);
|
||||
|
||||
cout << "\nCreating model...\n";
|
||||
decoder *m = new decoder(argc, argv);
|
||||
m->loadRAM(argv[2]);
|
||||
|
||||
cout << "Starting DECODER simulation...\n" << std::flush;
|
||||
m->start();
|
||||
|
||||
cout << "Running for " << nCycles << " clock cycles...\n" << std::flush;
|
||||
m->waitClocks(nCycles);
|
||||
|
||||
m->printInfo();
|
||||
|
||||
cout << "\nDone, closing simulation.\n\n\n" << std::flush;
|
||||
m->stop();
|
||||
delete m;
|
||||
|
||||
exit(EXIT_SUCCESS);
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,19 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Aug.2025 by Marcus Bednara
|
||||
// Last Modified : 01.Nov.2025 by Hussein Elzomor
|
||||
// ------
|
||||
// Notes : All ${}-variables must be provided by shell or Makefile {using export}
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
${PRJ_ROOT}/hw/rtl/pc.sv
|
||||
${PRJ_ROOT}/hw/rtl/reg_file.sv
|
||||
${PRJ_ROOT}/hw/rtl/alu.sv
|
||||
${PRJ_ROOT}/hw/rtl/main_mem.sv
|
||||
${PRJ_ROOT}/hw/rtl/decoder.sv
|
||||
${PRJ_ROOT}/hw/rtl/cpu.sv
|
||||
@@ -0,0 +1,24 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Aug.2025 by Marcus Bednara
|
||||
// Last Modified : 01.Nov.2025 by Hussein Elzomor
|
||||
// ------
|
||||
// Notes : All ${}-variables must be provided by shell or Makefile {using export}
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
// Used with verilator
|
||||
${PRJ_ROOT}/hw/dv/verilator/rtl/decoder_harness.sv
|
||||
${PRJ_ROOT}/hw/dv/verilator/rtl/cpu_harness.sv
|
||||
|
||||
// Used with other compilers and simulators (eg. Icarus)
|
||||
// ${PRJ_ROOT}/hw/dv/rtl/pc_tb.sv
|
||||
// ${PRJ_ROOT}/hw/dv/rtl/reg_file_tb.sv
|
||||
// ${PRJ_ROOT}/hw/dv/rtl/alu_tb.sv
|
||||
// ${PRJ_ROOT}/hw/dv/rtl/main_mem_tb.sv
|
||||
// ${PRJ_ROOT}/hw/dv/rtl/decoder_tb.sv
|
||||
// ${PRJ_ROOT}/hw/dv/rtl/cpu_tb.sv
|
||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Executable
+60
@@ -0,0 +1,60 @@
|
||||
module MemGen_32_11 #(
|
||||
parameter data_width = 32,
|
||||
parameter addr_width = 11,
|
||||
parameter mem_depth = 2048
|
||||
)(
|
||||
input chip_en,
|
||||
input clock,
|
||||
input [addr_width-1:0]addr,
|
||||
output reg [data_width-1:0]rd_data,
|
||||
input rd_en,
|
||||
|
||||
input wr_en,
|
||||
input [data_width-1:0]wr_data
|
||||
);
|
||||
// Bank selection: 1 bit selects one of 2 banks
|
||||
reg [1:0] mem_sel ;
|
||||
wire [31:0] mem_data_out [1:0];
|
||||
|
||||
// Address decoder and output multiplexer
|
||||
always @(*)
|
||||
begin
|
||||
if ( chip_en == 1'b1 )
|
||||
case (addr[10])
|
||||
1'b0 : begin mem_sel = 2'b01; rd_data = mem_data_out[0]; end
|
||||
1'b1 : begin mem_sel = 2'b10; rd_data = mem_data_out[1]; end
|
||||
endcase
|
||||
else
|
||||
begin
|
||||
mem_sel = 2'b00;
|
||||
rd_data = 32'h00000000;
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
genvar i;
|
||||
// Instantiate 2 banks, each with 2 halves (low + high 16 bits)
|
||||
generate
|
||||
for (i = 0; i < 2; i = i + 1) begin
|
||||
MemGen_16_10 U_lo (
|
||||
.chip_en(mem_sel[i]),
|
||||
.clock(clock),
|
||||
.addr(addr[9:0]),
|
||||
.rd_en(rd_en),
|
||||
.rd_data(mem_data_out[i][15:0]),
|
||||
.wr_en(wr_en),
|
||||
.wr_data(wr_data[15:0])
|
||||
);
|
||||
MemGen_16_10 U_hi (
|
||||
.chip_en(mem_sel[i]),
|
||||
.clock(clock),
|
||||
.addr(addr[9:0]),
|
||||
.rd_en(rd_en),
|
||||
.rd_data(mem_data_out[i][31:16]),
|
||||
.wr_en(wr_en),
|
||||
.wr_data(wr_data[31:16])
|
||||
);
|
||||
end
|
||||
endgenerate
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,52 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 Bomin Kim Refactored ALU logic from decoder into this file
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
module alu (
|
||||
input logic[2:0] aluOp,
|
||||
input logic aluNegAr,
|
||||
input logic aluBypass,
|
||||
input logic[31:0] op1,
|
||||
input logic[31:0] op2,
|
||||
output logic[31:0] result,
|
||||
output logic eqFlag
|
||||
);
|
||||
|
||||
// Local parameters; list of aluOp
|
||||
localparam logic[2:0] f3add = 3'b000;
|
||||
localparam logic[2:0] f3sl = 3'b001;
|
||||
localparam logic[2:0] f3slt = 3'b010;
|
||||
localparam logic[2:0] f3sltU = 3'b011;
|
||||
localparam logic[2:0] f3xor = 3'b100;
|
||||
localparam logic[2:0] f3sr = 3'b101;
|
||||
localparam logic[2:0] f3or = 3'b110;
|
||||
localparam logic[2:0] f3and = 3'b111;
|
||||
|
||||
// ALU logic
|
||||
always_comb begin : ALU
|
||||
eqFlag = op1 == op2;
|
||||
if (aluBypass) result = op1;
|
||||
else case(aluOp)
|
||||
f3add: result = aluNegAr ? op1 - op2 : op1 + op2;
|
||||
f3sl: result = op1 << op2[4:0];
|
||||
f3slt: result = {31'b0, $signed(op1) < $signed(op2)};
|
||||
f3sltU: result = {31'b0, $unsigned(op1) < $unsigned(op2)};
|
||||
f3xor: result = op1 ^ op2;
|
||||
f3sr: result = aluNegAr ? $signed(op1) >>> op2[4:0] : $signed(op1) >> op2[4:0];
|
||||
f3or: result = op1 | op2;
|
||||
f3and: result = op1 & op2;
|
||||
endcase
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,135 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 H.Elzomor Renamed file and module from soc to cpu
|
||||
// 15.Oct.2025 H.Elzomor Added an initial condition for clk_12p5
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
module cpu (
|
||||
output logic[7:0] led,
|
||||
input logic[6:0] btn,
|
||||
input logic clk_25mhz
|
||||
//input logic scan_en
|
||||
);
|
||||
|
||||
// Local Signals
|
||||
// Clock & Reset
|
||||
logic clk;
|
||||
// logic clk12p5;
|
||||
logic reset;
|
||||
// PC
|
||||
logic[31:0] CurrentPC;
|
||||
logic[31:0] JumpOrBranchPC;
|
||||
logic JumpOrBranch;
|
||||
logic[31:0] NextPC;
|
||||
// Memory
|
||||
logic[31:0] DAddr;
|
||||
logic[31:0] WData;
|
||||
logic[31:0] RData;
|
||||
logic[31:0] Instruction;
|
||||
logic WrMem;
|
||||
logic[1:0] DWidth;
|
||||
// Register File;
|
||||
logic[4:0] Rs1;
|
||||
logic[4:0] Rs2;
|
||||
logic[4:0] Rd;
|
||||
logic[31:0] RRs1;
|
||||
logic[31:0] RRs2;
|
||||
logic[31:0] WRd;
|
||||
logic WrReg;
|
||||
// Protection
|
||||
logic Illegal;
|
||||
|
||||
// Logic
|
||||
assign clk = clk_25mhz;
|
||||
// Clock (12.5MHz)
|
||||
//assign clk = scan_en ? clk_25mhz : clk12p5;
|
||||
//assign clk = clk12p5;
|
||||
|
||||
// always_ff @(posedge clk_25mhz) begin
|
||||
// if (reset)
|
||||
// clk12p5 <= 1'b0;
|
||||
// else if (!scan_en)
|
||||
// clk12p5 <= ~clk12p5;
|
||||
// end
|
||||
// Reset
|
||||
assign reset = ~btn[0];
|
||||
|
||||
// LED
|
||||
assign led[0] = Illegal;
|
||||
assign led[1] = WrMem;
|
||||
assign led[7:2] = NextPC[7:2];
|
||||
|
||||
// Module Instantiation
|
||||
// Decoder
|
||||
decoder theDecoder (
|
||||
// PC
|
||||
.CurrentPC(CurrentPC),
|
||||
.JumpOrBranchPC(JumpOrBranchPC),
|
||||
.JumpOrBranch(JumpOrBranch),
|
||||
// Memory
|
||||
.DAddr(DAddr),
|
||||
.WData(WData),
|
||||
.RData(RData),
|
||||
.Instruction(Instruction),
|
||||
.WrMem(WrMem),
|
||||
.DWidth(DWidth),
|
||||
// Register File
|
||||
.Rs1(Rs1),
|
||||
.Rs2(Rs2),
|
||||
.Rd(Rd),
|
||||
.RRs1(RRs1),
|
||||
.RRs2(RRs2),
|
||||
.WRd(WRd),
|
||||
.WrReg(WrReg),
|
||||
// Protection
|
||||
.Illegal(Illegal)
|
||||
);
|
||||
|
||||
// Register File
|
||||
reg_file theRegisters (
|
||||
.Rs1(Rs1),
|
||||
.Rs2(Rs2),
|
||||
.Rd(Rd),
|
||||
.RRs1(RRs1),
|
||||
.RRs2(RRs2),
|
||||
.WRd(WRd),
|
||||
.WrReg(WrReg),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
// PC
|
||||
pc thePC (
|
||||
.CurrentPC(CurrentPC),
|
||||
.JumpOrBranchPC(JumpOrBranchPC),
|
||||
.JumpOrBranch(JumpOrBranch),
|
||||
.NextPC(NextPC),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
// Main Memory
|
||||
main_mem #(
|
||||
) theMem (
|
||||
.DAddr(DAddr),
|
||||
.IAddr(NextPC),
|
||||
.DWData(WData),
|
||||
.DRData(RData),
|
||||
.IRData(Instruction),
|
||||
.DWE(WrMem),
|
||||
.DWidth(DWidth),
|
||||
.reset(reset),
|
||||
.clk(clk)
|
||||
);
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,231 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||
// Last Modified : 23.Oct.2025 by Hussein Elzomor [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 H.Elzomor Moved PC and ALU logic to their respective files
|
||||
// 15.Oct.2025 H.Elzomor Absorbed the branching logic into the decoder logic
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
module decoder (
|
||||
// PC
|
||||
input logic[31:0] CurrentPC,
|
||||
output logic[31:0] JumpOrBranchPC,
|
||||
output logic JumpOrBranch,
|
||||
// Memory
|
||||
output logic[31:0] DAddr,
|
||||
output logic[31:0] WData,
|
||||
input logic[31:0] RData,
|
||||
input logic[31:0] Instruction,
|
||||
output logic WrMem,
|
||||
output logic[1:0] DWidth,
|
||||
// Register File
|
||||
output logic[4:0] Rs1,
|
||||
output logic[4:0] Rs2,
|
||||
output logic[4:0] Rd,
|
||||
input logic[31:0] RRs1,
|
||||
input logic[31:0] RRs2,
|
||||
output logic[31:0] WRd,
|
||||
output logic WrReg,
|
||||
// Protection
|
||||
output logic Illegal
|
||||
);
|
||||
|
||||
// Local Parameters
|
||||
// OpCode: set a local parameter for each operation
|
||||
localparam logic[6:0] opLd = 7'b0000011;
|
||||
localparam logic[6:0] opAluImm = 7'b0010011;
|
||||
localparam logic[6:0] opUpPC = 7'b0010111;
|
||||
localparam logic[6:0] opSt = 7'b0100011;
|
||||
localparam logic[6:0] opAlu = 7'b0110011;
|
||||
localparam logic[6:0] opUpImm = 7'b0110111;
|
||||
localparam logic[6:0] opBranch = 7'b1100011;
|
||||
localparam logic[6:0] opJALR = 7'b1100111;
|
||||
localparam logic[6:0] opJAL = 7'b1101111;
|
||||
|
||||
// Func7: set a local parameter for each function 7
|
||||
localparam logic[6:0] f7neg = 7'b0100000;
|
||||
|
||||
// Func3: set a local parameter for each function 3
|
||||
// Load/Store
|
||||
localparam logic[2:0] f3byte = 3'b000;
|
||||
localparam logic[2:0] f3half = 3'b001;
|
||||
localparam logic[2:0] f3word = 3'b010;
|
||||
localparam logic[2:0] f3byteU = 3'b100;
|
||||
localparam logic[2:0] f3halfU = 3'b101;
|
||||
// ALU
|
||||
localparam logic[2:0] f3add = 3'b000;
|
||||
localparam logic[2:0] f3sl = 3'b001;
|
||||
localparam logic[2:0] f3slt = 3'b010;
|
||||
localparam logic[2:0] f3sltU = 3'b011;
|
||||
localparam logic[2:0] f3xor = 3'b100;
|
||||
localparam logic[2:0] f3sr = 3'b101;
|
||||
localparam logic[2:0] f3or = 3'b110;
|
||||
localparam logic[2:0] f3and = 3'b111;
|
||||
// Branch
|
||||
localparam logic[2:0] f3beq = 3'b000;
|
||||
localparam logic[2:0] f3bne = 3'b001;
|
||||
localparam logic[2:0] f3blt = 3'b100;
|
||||
localparam logic[2:0] f3bge = 3'b101;
|
||||
localparam logic[2:0] f3bltU = 3'b110;
|
||||
localparam logic[2:0] f3bgeU = 3'b111;
|
||||
|
||||
// Local Signals
|
||||
// Instruction breakdown (excluding I/O)
|
||||
logic[6:0] theOp;
|
||||
logic[2:0] theFunct3;
|
||||
logic[6:0] theFunct7;
|
||||
logic[31:0] i_imm;
|
||||
logic[31:0] s_imm;
|
||||
logic[31:0] b_imm;
|
||||
logic[31:0] u_imm;
|
||||
logic[31:0] j_imm;
|
||||
// ALU
|
||||
logic[2:0] aluOp;
|
||||
logic aluNegAr;
|
||||
logic aluBypass;
|
||||
logic[31:0] op1;
|
||||
logic[31:0] op2;
|
||||
logic[31:0] result;
|
||||
logic eqFlag;
|
||||
|
||||
// Instruction breakdown: assign values
|
||||
// OpCode and functions 3/7
|
||||
assign theOp = Instruction[6:0];
|
||||
assign theFunct3 = Instruction[14:12];
|
||||
assign theFunct7 = Instruction[31:25];
|
||||
// Registers
|
||||
assign Rs1 = Instruction[19:15];
|
||||
assign Rs2 = Instruction[24:20];
|
||||
assign Rd = Instruction[11:7];
|
||||
// Immediates
|
||||
always_comb begin : Immediate_Generator
|
||||
i_imm = {{21{Instruction[31]}}, Instruction[30:20]};
|
||||
s_imm = {{21{Instruction[31]}}, Instruction[30:25], Instruction[11:7]};
|
||||
b_imm = {{20{Instruction[31]}}, Instruction[7], Instruction[30:25], Instruction[11:8], 1'b0};
|
||||
u_imm = {Instruction[31:12], 12'b0};
|
||||
j_imm = {{12{Instruction[31]}}, Instruction[19:12], Instruction[20], Instruction[30:21], 1'b0};
|
||||
end
|
||||
|
||||
// Decoder Logic
|
||||
always_comb begin : Main_Decoder
|
||||
// Factored port/signal values
|
||||
JumpOrBranch = '0;
|
||||
JumpOrBranchPC = '0;
|
||||
DAddr = '0;
|
||||
WData = RRs2;
|
||||
WrMem = '0;
|
||||
DWidth = f3word[1:0];
|
||||
WrReg = '1;
|
||||
Illegal = '0;
|
||||
aluOp = theFunct3;
|
||||
aluNegAr = '0;
|
||||
aluBypass = '0;
|
||||
op1 = RRs1;
|
||||
op2 = RRs2;
|
||||
// OpCode Cases
|
||||
case(theOp)
|
||||
opLd: begin
|
||||
DAddr = RRs1 + i_imm;
|
||||
DWidth = theFunct3[1:0];
|
||||
aluBypass = '1;
|
||||
op1 = RData;
|
||||
case(theFunct3)
|
||||
f3byte: op1[31:8] = {24{RData[7]}};
|
||||
f3byteU: op1[31:8] = {24{1'b0}};
|
||||
f3half: op1[31:16] = {16{RData[15]}};
|
||||
f3halfU: op1[31:16] = {16{1'b0}};
|
||||
f3word: ;
|
||||
default: begin
|
||||
Illegal = '1;
|
||||
WrReg = '0;
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
opAluImm: begin
|
||||
op2 = i_imm;
|
||||
aluOp = theFunct3;
|
||||
aluNegAr = (theFunct7 == f7neg) & (theFunct3 == f3sr);
|
||||
end
|
||||
opUpPC: begin
|
||||
op1 = u_imm;
|
||||
op2 = CurrentPC;
|
||||
aluOp = f3add;
|
||||
end
|
||||
opSt: begin
|
||||
WrReg = '0;
|
||||
WrMem = '1;
|
||||
DAddr = RRs1 + s_imm;
|
||||
DWidth = theFunct3[1:0];
|
||||
end
|
||||
opAlu: begin
|
||||
aluOp = theFunct3;
|
||||
aluNegAr = (theFunct7 == f7neg) & ((theFunct3 == f3add) | (theFunct3 == f3sr));
|
||||
end
|
||||
opUpImm: begin
|
||||
op1 = u_imm;
|
||||
aluBypass = '1;
|
||||
end
|
||||
opBranch: begin
|
||||
WrReg = '0;
|
||||
JumpOrBranchPC = CurrentPC + b_imm;
|
||||
aluOp = f3slt;
|
||||
case(theFunct3)
|
||||
f3beq : begin JumpOrBranch = ( eqFlag)? '1 : '0; end
|
||||
f3bne : begin JumpOrBranch = (~eqFlag)? '1 : '0; end
|
||||
f3blt : begin JumpOrBranch = ( result[0])? '1 : '0; end
|
||||
f3bge : begin JumpOrBranch = (~result[0])? '1 : '0; end
|
||||
f3bltU: begin aluOp = f3sltU; JumpOrBranch = ( result[0])? '1 : '0; end
|
||||
f3bgeU: begin aluOp = f3sltU; JumpOrBranch = (~result[0])? '1 : '0; end
|
||||
default: begin
|
||||
Illegal = '1;
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
opJALR: begin
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = (RRs1 + i_imm) & 32'hFFFFFFFE;
|
||||
op1 = CurrentPC;
|
||||
op2 = 4;
|
||||
aluOp = f3add;
|
||||
end
|
||||
opJAL: begin
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC + j_imm;
|
||||
op1 = CurrentPC;
|
||||
op2 = 4;
|
||||
aluOp = f3add;
|
||||
end
|
||||
default: begin
|
||||
Illegal = '1;
|
||||
WrReg = '0;
|
||||
JumpOrBranch = '1;
|
||||
JumpOrBranchPC = CurrentPC;
|
||||
end
|
||||
endcase
|
||||
end
|
||||
|
||||
// ALU module instantiation
|
||||
alu theALU (
|
||||
.aluOp(aluOp),
|
||||
.aluNegAr(aluNegAr),
|
||||
.aluBypass(aluBypass),
|
||||
.op1(op1),
|
||||
.op2(op2),
|
||||
.result(result),
|
||||
.eqFlag(eqFlag)
|
||||
);
|
||||
assign WRd = result;
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,120 @@
|
||||
// *********************************************************************************************
|
||||
// main_mem.sv - Macro-based implementation using MemGen_32_11
|
||||
// *********************************************************************************************
|
||||
// Replaces the behavioral flip-flop RAM with an SRAM macro wrapper.
|
||||
//
|
||||
// Key differences from the original:
|
||||
// - Uses MemGen_32_11 (2048 words x 32 bits, single-port SRAM macro)
|
||||
// - Time-multiplexed using the 25 MHz clock for two accesses per CPU cycle:
|
||||
// clk12p5=0 -> instruction fetch (IAddr)
|
||||
// clk12p5=1 -> data access (DAddr read/write)
|
||||
// - Word-only writes; SB/SH instructions will be dropped (TODO: add RMW later)
|
||||
// - MEM_INIT_FILE parameter kept for interface compatibility (not functional)
|
||||
// *********************************************************************************************
|
||||
|
||||
module main_mem #(
|
||||
parameter int ABits = 13
|
||||
//parameter string MEM_INIT_FILE = ""
|
||||
)(
|
||||
input logic clk, // 12.5 MHz CPU clock (= clk12p5)
|
||||
// input logic clk_25mhz, // NEW: 25 MHz memory clock
|
||||
input logic reset,
|
||||
input logic[31:0] DAddr,
|
||||
input logic[31:0] IAddr,
|
||||
input logic[31:0] DWData,
|
||||
output logic[31:0] DRData,
|
||||
output logic[31:0] IRData,
|
||||
input logic DWE,
|
||||
input logic[1:0] DWidth
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Localparam
|
||||
//---------------------------------------------------------------------------
|
||||
localparam logic[1:0] _byte = 2'b00;
|
||||
localparam logic[1:0] _half = 2'b01;
|
||||
localparam logic[1:0] _word = 2'b10;
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Time-multiplexing logic
|
||||
//
|
||||
// The CPU runs on clk12p5 (half of clk_25mhz).
|
||||
// We use clk_25mhz to drive the memory; within one CPU cycle:
|
||||
// - During clk12p5 LOW: present instruction address
|
||||
// - During clk12p5 HIGH: present data address
|
||||
//
|
||||
// The macro latches the address on the rising edge of its own clock (clk_25mhz),
|
||||
// so we select which address to send based on the current phase.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
logic [10:0] mem_addr; // 11-bit word address for MemGen_32_11
|
||||
logic [31:0] mem_wr_data;
|
||||
logic mem_wr_en;
|
||||
logic mem_rd_en;
|
||||
logic [31:0] mem_rd_data;
|
||||
|
||||
// Phase: 0 = instruction fetch, 1 = data access
|
||||
// Since clk12p5 rises on clk_25mhz rising edge, clk12p5 itself tells us the phase
|
||||
wire phase_is_data = clk; // clk = clk12p5
|
||||
|
||||
always_comb begin
|
||||
if (phase_is_data) begin
|
||||
// Data phase
|
||||
mem_addr = DAddr[12:2];
|
||||
mem_wr_data = DWData;
|
||||
mem_wr_en = DWE && !reset && (DWidth == _word);
|
||||
mem_rd_en = !DWE;
|
||||
end else begin
|
||||
// Instruction phase
|
||||
mem_addr = IAddr[12:2];
|
||||
mem_wr_data = 32'h0;
|
||||
mem_wr_en = 1'b0;
|
||||
mem_rd_en = 1'b1;
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Single memory macro - time-multiplexed
|
||||
//---------------------------------------------------------------------------
|
||||
MemGen_32_11 u_mem (
|
||||
.chip_en (1'b1),
|
||||
.clock (clk_25mhz), // 2x CPU clock - enables dual access per CPU cycle
|
||||
.addr (mem_addr),
|
||||
.rd_en (mem_rd_en),
|
||||
.rd_data (mem_rd_data),
|
||||
.wr_en (mem_wr_en),
|
||||
.wr_data (mem_wr_dat)
|
||||
);
|
||||
|
||||
//---------------------------------------------------------------------------
|
||||
// Output capture
|
||||
//
|
||||
// On each CPU cycle, we capture:
|
||||
// - IRData: the instruction read during instruction phase
|
||||
// - DRData: the data read during data phase
|
||||
//
|
||||
// The macro delivers rd_data one clk_25mhz cycle after the address.
|
||||
//---------------------------------------------------------------------------
|
||||
|
||||
// Capture IRData at the end of the instruction phase (when data phase starts)
|
||||
always_ff @(posedge clk_25mhz) begin
|
||||
if (reset) begin
|
||||
IRData <= 32'h0;
|
||||
end else if (!phase_is_data) begin
|
||||
// We just presented the data address; the read of the previous
|
||||
// instruction address is now available on mem_rd_data
|
||||
// (Note: timing requires verification against macro characteristics)
|
||||
IRData <= mem_rd_data;
|
||||
end
|
||||
end
|
||||
|
||||
// Capture DRData at the end of the data phase (when instruction phase starts)
|
||||
always_ff @(posedge clk_25mhz) begin
|
||||
if (reset) begin
|
||||
DRData <= 32'h0;
|
||||
end else if (phase_is_data) begin
|
||||
DRData <= mem_rd_data;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,142 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||
// Last Modified : 23.Oct.2025 by Aliakbar Merchant [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- ---------- -------------------------------------------------
|
||||
// 22.Oct.2025 A.Merchant Added reset handling condition for Instr. read logic
|
||||
// 22.Oct.2025 A.Merchant Added reset handling condition for data write logic
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
`default_nettype wire
|
||||
|
||||
module main_mem #(
|
||||
parameter int ABits = 13 // Number of address bits
|
||||
//parameter string MEM_INIT_FILE = "" // Optional memory initializations file
|
||||
) (
|
||||
input logic clk, // Clock
|
||||
input logic reset, // Active high sync reset
|
||||
input logic[31:0] DAddr, // Data Address
|
||||
input logic[31:0] IAddr, // Instruction Address
|
||||
input logic[31:0] DWData, // Data to write
|
||||
output logic[31:0] DRData, // Data read
|
||||
output logic[31:0] IRData, // Instruction read
|
||||
input logic DWE, // Data write enable, 1=Write
|
||||
input logic [1:0] DWidth // Access width (byte, half word, word)
|
||||
);
|
||||
|
||||
// Local Parameter
|
||||
localparam logic[1:0] _byte = 2'b00; // byte: 8 bits
|
||||
localparam logic[1:0] _half = 2'b01; // half: 16 bits
|
||||
localparam logic[1:0] _word = 2'b10; // word: 32 bits
|
||||
|
||||
// Local Signals
|
||||
//logic[31:0] RAM[2**(ABits-2)-1:0]; // Memory array 8KB(8192): ignores lowest 2 bits as 32bit-word
|
||||
logic [31:0] irTmp;
|
||||
logic[31:0] drTmp; // Temporary register to hold the data read from RAM.
|
||||
logic [10:0] mem_addr; // 11-bit word address for MemGen_32_11
|
||||
logic [31:0] mem_wdata; // 32-bit data bus for MemGen_32_11
|
||||
logic [31:0] mem_rdata; // 32-bit data bus for MemGen_32_11
|
||||
|
||||
|
||||
MemGen_32_11 RAM (
|
||||
.chip_en (1'b1),
|
||||
.clock (clk),
|
||||
.addr (mem_addr),
|
||||
.rd_en (!DWE),
|
||||
.rd_data (mem_rdata),
|
||||
.wr_en (DWE),
|
||||
.wr_data (mem_wdata)
|
||||
);
|
||||
|
||||
// memory initilizations
|
||||
// initial begin
|
||||
|
||||
//if (MEM_INIT_FILE != "") begin
|
||||
// $readmemh(MEM_INIT_FILE, RAM);
|
||||
// end
|
||||
// end
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
//--------------------------- DATA WRITE LOGIC ---------------------------//
|
||||
//---------------------------------------------------------------------------//
|
||||
|
||||
|
||||
always_ff @(negedge clk) begin
|
||||
if (reset) begin
|
||||
mem_addr <= 0;
|
||||
end else begin
|
||||
if (DWE) begin
|
||||
mem_addr <= DAddr[(ABits-1):2];
|
||||
// RAM[DAddr[(ABits-1):2]] <= DWData;
|
||||
case (DWidth)
|
||||
_word:
|
||||
mem_wdata <= DWData;
|
||||
_half:
|
||||
case (DAddr[1])
|
||||
1'b0: mem_wdata [31:16] <= DWData[15:0];
|
||||
1'b1: mem_wdata [15: 0] <= DWData[15:0];
|
||||
endcase
|
||||
_byte:
|
||||
case (DAddr[1:0])
|
||||
2'b00: mem_wdata [31:24] <= DWData[7:0];
|
||||
2'b01: mem_wdata [23:16] <= DWData[7:0];
|
||||
2'b10: mem_wdata [15: 8] <= DWData[7:0];
|
||||
2'b11: mem_wdata [ 7: 0] <= DWData[7:0];
|
||||
endcase
|
||||
default: ;
|
||||
endcase
|
||||
end else begin
|
||||
mem_addr <= IAddr[(ABits-1):2];
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
//--------------------------- DATA READ LOGIC ----------------------------//
|
||||
//---------------------------------------------------------------------------//
|
||||
always_ff @(negedge clk) begin
|
||||
drTmp <= mem_rdata;
|
||||
end
|
||||
|
||||
always_comb begin
|
||||
case (DWidth)
|
||||
_word:
|
||||
DRData = drTmp;
|
||||
_half:
|
||||
case (DAddr[1])
|
||||
1'b0: DRData = {16'b0, drTmp[31:16]};
|
||||
1'b1: DRData = {16'b0, drTmp[15: 0]};
|
||||
endcase
|
||||
_byte:
|
||||
case (DAddr[1:0])
|
||||
2'b00: DRData = {24'b0, drTmp[31:24]};
|
||||
2'b01: DRData = {24'b0, drTmp[23:16]};
|
||||
2'b10: DRData = {24'b0, drTmp[15: 8]};
|
||||
2'b11: DRData = {24'b0, drTmp[ 7: 0]};
|
||||
endcase
|
||||
default: ;
|
||||
endcase
|
||||
end
|
||||
|
||||
//---------------------------------------------------------------------------//
|
||||
//----------------------- INSTRUCTION READ LOGIC -------------------------//
|
||||
//---------------------------------------------------------------------------//
|
||||
//
|
||||
//fetch intrcution from memory into IRData
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
IRData <= mem_rdata;
|
||||
end
|
||||
else begin
|
||||
IRData <= mem_rdata;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
#--------------------------------------------------------------------
|
||||
# date : Thu May 28 12:01:37 CEST 2026
|
||||
# ppid/pid : 2439771/2439781
|
||||
# hostname : efiapps0.ads1.fh-nuernberg.de
|
||||
# arch/os : x86_64/Linux-4.18.0-553.123.1.el8_10.x86_64
|
||||
# install : /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1
|
||||
# currdir : /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl
|
||||
# logfile : /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl/oasys.log.00
|
||||
# tmpdir : /tmp/oasys.2439771/
|
||||
#--------------------------------------------------------------------
|
||||
# Starting Interactive Session
|
||||
exit
|
||||
#--------------------------------------------------------------------
|
||||
# End Session at Thu May 28 13:20:20 CEST 2026
|
||||
#--------------------------------------------------------------------
|
||||
@@ -0,0 +1,23 @@
|
||||
#--------------------------------------------------------------------
|
||||
# date : Thu May 28 13:29:15 CEST 2026
|
||||
# ppid/pid : 2451524/2451534
|
||||
# hostname : efiapps0.ads1.fh-nuernberg.de
|
||||
# arch/os : x86_64/Linux-4.18.0-553.123.1.el8_10.x86_64
|
||||
# install : /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1
|
||||
# currdir : /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl
|
||||
# logfile : /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl/oasys.log.01
|
||||
# tmpdir : /tmp/oasys.2451524/
|
||||
#--------------------------------------------------------------------
|
||||
# Starting Interactive Session
|
||||
ls
|
||||
cd ..
|
||||
ls
|
||||
cd ..
|
||||
cd ..
|
||||
ls
|
||||
source scripts_risc_v/1_read_design.tcl
|
||||
source scripts_risc_v/2_synthesize_optimize.tcl
|
||||
exit
|
||||
#--------------------------------------------------------------------
|
||||
# End Session at Thu May 28 13:42:47 CEST 2026
|
||||
#--------------------------------------------------------------------
|
||||
@@ -0,0 +1,317 @@
|
||||
|
||||
@/users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl/oasys.log.02:1093
|
||||
libc: 2.28-stable
|
||||
|
||||
Timestamp: 1779968572.056193725
|
||||
---
|
||||
PID=2457562 0.129170598 0.075018 0.054153 program start
|
||||
Complete list of environment variables at program start
|
||||
_ /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/oasysGui
|
||||
BASH_FUNC_which%% {() { ( alias;
|
||||
eval ${which_declare} ) | /usr/bin/which --tty-only --read-alias --read-functions --show-tilde --show-dot $@
|
||||
}}
|
||||
CALIBRE_HOME /applications/SiemensEDA/siemenseda2023/calibre/aok_cal_2023.4_39.23
|
||||
CDS_DDIEXPORT /applications/Cadence/cadence2022/DDIEXPORT2233
|
||||
CDS_GENUS /applications/Cadence/cadence2022/DDIEXPORT2233/GENUS*
|
||||
CDS_INNOVUS /applications/Cadence/cadence2022/DDIEXPORT2233/INNOVUS*
|
||||
CDS_JLS /applications/Cadence/cadence2022/DDIEXPORT2233/JLS*
|
||||
CDS_LIC_FILE 1816@141.75.245.12
|
||||
CDS_SSV /applications/Cadence/cadence2022/SSV2213
|
||||
COLORTERM truecolor
|
||||
DBUS_SESSION_BUS_ADDRESS unix:path=/run/user/1083946113/bus,guid=02a4782d1dbcb9e9f51311946a16bc26
|
||||
DBUS_STARTER_ADDRESS unix:path=/run/user/1083946113/bus,guid=02a4782d1dbcb9e9f51311946a16bc26
|
||||
DBUS_STARTER_BUS_TYPE session
|
||||
DESKTOP_SESSION gnome-classic
|
||||
DISPLAY :10
|
||||
ENV_VER 1
|
||||
FORMALITY /applications/Synopsys/synopsys2022/fm/U-2022.12-SP4
|
||||
GNOME_DESKTOP_SESSION_ID this-is-deprecated
|
||||
GNOME_SHELL_SESSION_MODE classic
|
||||
GNOME_TERMINAL_SCREEN /org/gnome/Terminal/screen/46eff583_4eec_45e6_973b_99403434080c
|
||||
GNOME_TERMINAL_SERVICE :1.207
|
||||
HISTCONTROL ignoredups
|
||||
HISTSIZE 1000
|
||||
HOME /users/ads1/charapallivenkatsaja/linux
|
||||
HOSTNAME efiapps0.ads1.fh-nuernberg.de
|
||||
INVOCATION_ID ad18f9577c3a4ac89ac41411f6a6e0c9
|
||||
JOURNAL_STREAM 9:20654617
|
||||
KRB5CCNAME /var/opt/thinlinc/sessions/charapallivenkatsaja/10/krb5cc
|
||||
LANG en_US.UTF-8
|
||||
LANGUAGE en_US
|
||||
LATTICE /applications/Lattice
|
||||
LC_NUMERIC en_US.UTF-8
|
||||
LD_LIBRARY_PATH /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/lib/Linux-x86_64-O:/opt/thinlinc/lib64:/opt/thinlinc/lib
|
||||
LESSOPEN {||/usr/bin/lesspipe.sh %s}
|
||||
LM_LICENSE_FILE 1818@141.75.245.12:1812@141.75.245.10:1810@141.75.245.10
|
||||
LOGNAME charapallivenkatsaja
|
||||
LS_COLORS {rs=0:di=38;5;33:ln=38;5;51:mh=00:pi=40;38;5;11:so=38;5;13:do=38;5;5:bd=48;5;232;38;5;11:cd=48;5;232;38;5;3:or=48;5;232;38;5;9:mi=01;05;37;41:su=48;5;196;38;5;15:sg=48;5;11;38;5;16:ca=48;5;196;38;5;226:tw=48;5;10;38;5;16:ow=48;5;10;38;5;21:st=48;5;21;38;5;15:ex=38;5;40:*.tar=38;5;9:*.tgz=38;5;9:*.arc=38;5;9:*.arj=38;5;9:*.taz=38;5;9:*.lha=38;5;9:*.lz4=38;5;9:*.lzh=38;5;9:*.lzma=38;5;9:*.tlz=38;5;9:*.txz=38;5;9:*.tzo=38;5;9:*.t7z=38;5;9:*.zip=38;5;9:*.z=38;5;9:*.dz=38;5;9:*.gz=38;5;9:*.lrz=38;5;9:*.lz=38;5;9:*.lzo=38;5;9:*.xz=38;5;9:*.zst=38;5;9:*.tzst=38;5;9:*.bz2=38;5;9:*.bz=38;5;9:*.tbz=38;5;9:*.tbz2=38;5;9:*.tz=38;5;9:*.deb=38;5;9:*.rpm=38;5;9:*.jar=38;5;9:*.war=38;5;9:*.ear=38;5;9:*.sar=38;5;9:*.rar=38;5;9:*.alz=38;5;9:*.ace=38;5;9:*.zoo=38;5;9:*.cpio=38;5;9:*.7z=38;5;9:*.rz=38;5;9:*.cab=38;5;9:*.wim=38;5;9:*.swm=38;5;9:*.dwm=38;5;9:*.esd=38;5;9:*.jpg=38;5;13:*.jpeg=38;5;13:*.mjpg=38;5;13:*.mjpeg=38;5;13:*.gif=38;5;13:*.bmp=38;5;13:*.pbm=38;5;13:*.pgm=38;5;13:*.ppm=38;5;13:*.tga=38;5;13:*.xbm=38;5;13:*.xpm=38;5;13:*.tif=38;5;13:*.tiff=38;5;13:*.png=38;5;13:*.svg=38;5;13:*.svgz=38;5;13:*.mng=38;5;13:*.pcx=38;5;13:*.mov=38;5;13:*.mpg=38;5;13:*.mpeg=38;5;13:*.m2v=38;5;13:*.mkv=38;5;13:*.webm=38;5;13:*.ogm=38;5;13:*.mp4=38;5;13:*.m4v=38;5;13:*.mp4v=38;5;13:*.vob=38;5;13:*.qt=38;5;13:*.nuv=38;5;13:*.wmv=38;5;13:*.asf=38;5;13:*.rm=38;5;13:*.rmvb=38;5;13:*.flc=38;5;13:*.avi=38;5;13:*.fli=38;5;13:*.flv=38;5;13:*.gl=38;5;13:*.dl=38;5;13:*.xcf=38;5;13:*.xwd=38;5;13:*.yuv=38;5;13:*.cgm=38;5;13:*.emf=38;5;13:*.ogv=38;5;13:*.ogx=38;5;13:*.aac=38;5;45:*.au=38;5;45:*.flac=38;5;45:*.m4a=38;5;45:*.mid=38;5;45:*.midi=38;5;45:*.mka=38;5;45:*.mp3=38;5;45:*.mpc=38;5;45:*.ogg=38;5;45:*.ra=38;5;45:*.wav=38;5;45:*.oga=38;5;45:*.opus=38;5;45:*.spx=38;5;45:*.xspf=38;5;45:}
|
||||
MAIL /var/spool/mail/charapallivenkatsaja
|
||||
MANAGERPID 2391729
|
||||
MANPATH /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/doc/man:
|
||||
MGC_AMS_HOME /applications/SiemensEDA/siemenseda2023/amsv
|
||||
MGC_HOME /applications/SiemensEDA/siemenseda2023
|
||||
MGLS_HOME /applications/SiemensEDA/siemenseda2023/questasim/linux_x86_64/mgls
|
||||
MGLS_LICENSE_FILE 1810@141.75.245.10
|
||||
MODELTECH /applications/SiemensEDA/siemenseda2023/questasim
|
||||
MTI_VCO_MODE 64
|
||||
NIOS2_ROOTDIR /applications/intelFPGA/22.1/nios2eds
|
||||
OASYSLD_LICENSE_FILE /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/license.lic
|
||||
PATH /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin:/applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O:/applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/lib/share/formalpro:/applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/lib/share/onespin:/applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/lib/share/slec:/applications/th_tools/scripts:/applications/intelFPGA/22.1/quartus/bin:/applications/intelFPGA/22.1/quartus/qsys/bin:/applications/intelFPGA/22.1/nios2eds:/applications/Lattice/radiant/2023.1/bin/lin64:/applications/Synopsys/synopsys2022/syn/U-2022.12-SP4/amd64/syn/bin:/applications/Synopsys/synopsys2022/scl/2022.12/linux64/bin:/applications/Synopsys/synopsys2022/fm/U-2022.12-SP4/bin:/applications/Synopsys/synopsys2022/txs/U-2022.12-SP4/bin:/applications/Synopsys/synopsys2022/lc/V-2023.12/bin:/applications/th_tools/scripts:/applications/intelFPGA/22.1/quartus/bin:/applications/intelFPGA/22.1/quartus/qsys/bin:/applications/intelFPGA/22.1/nios2eds:/applications/Lattice/radiant/2023.1/bin/lin64:/applications/Synopsys/synopsys2022/syn/U-2022.12-SP4/amd64/syn/bin:/applications/Synopsys/synopsys2022/scl/2022.12/linux64/bin:/applications/Synopsys/synopsys2022/fm/U-2022.12-SP4/bin:/applications/Synopsys/synopsys2022/txs/U-2022.12-SP4/bin:/applications/Synopsys/synopsys2022/lc/V-2023.12/bin:/users/ads1/charapallivenkatsaja/linux/.local/bin:/users/ads1/charapallivenkatsaja/linux/bin:/bin:/usr/bin:/opt/thinlinc/bin:/usr/local/bin:/usr/bin/X11:/sbin:/usr/sbin:/usr/local/sbin:/applications/Cadence/cadence2022/DDIEXPORT2233/bin:/applications/Cadence/cadence2022/SSV2213/bin:/applications/SiemensEDA/siemenseda2023/questasim/bin:/applications/SiemensEDA/siemenseda2023/questasim/linux_x86_64:/applications/SiemensEDA/siemenseda2023/questasim/vco:/applications/SiemensEDA/siemenseda2023/questasim/linux_x86_64/mgls/bin:/applications/SiemensEDA/siemenseda2023/amsv/bin:/applications/SiemensEDA/siemenseda2023/amsv/modeltech/bin:/applications/SiemensEDA/siemenseda2023/calibre/aok_cal_2023.4_39.23/bin:/applications/SiemensEDA/siemenseda2023/tessent/bin:/applications/SiemensEDA/siemenseda2023/oasys/bin:/applications/SiemensEDA/siemenseda2023/precision/bin:/applications/Cadence/cadence2022/DDIEXPORT2233/bin:/applications/Cadence/cadence2022/SSV2213/bin:/applications/SiemensEDA/siemenseda2023/questasim/bin:/applications/SiemensEDA/siemenseda2023/questasim/linux_x86_64:/applications/SiemensEDA/siemenseda2023/questasim/vco:/applications/SiemensEDA/siemenseda2023/questasim/linux_x86_64/mgls/bin:/applications/SiemensEDA/siemenseda2023/amsv/bin:/applications/SiemensEDA/siemenseda2023/amsv/modeltech/bin:/applications/SiemensEDA/siemenseda2023/calibre/aok_cal_2023.4_39.23/bin:/applications/SiemensEDA/siemenseda2023/tessent/bin:/applications/SiemensEDA/siemenseda2023/oasys/bin:/applications/SiemensEDA/siemenseda2023/precision/bin
|
||||
PCSCTUN_COOKIE /var/opt/thinlinc/sessions/charapallivenkatsaja/10/pcsctun-cookie
|
||||
PCSCTUN_SERVER 127.0.0.1:5006
|
||||
PULSE_COOKIE /var/opt/thinlinc/sessions/charapallivenkatsaja/10/pulse-cookie
|
||||
PULSE_RUNTIME_PATH /var/opt/thinlinc/sessions/charapallivenkatsaja/10/pulse
|
||||
PULSE_SERVER {/var/opt/thinlinc/sessions/charapallivenkatsaja/10/pulse/native 127.0.0.1:5005}
|
||||
PWD /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl
|
||||
QSYS_ROOTDIR /applications/intelFPGA/22.1/quartus/qsys/bin
|
||||
QT_IM_MODULE ibus
|
||||
QUARTUS /applications/intelFPGA
|
||||
QUARTUS_ROOTDIR /applications/intelFPGA/22.1/quartus
|
||||
RT_CMD {/applications/SiemensEDA/siemenseda2023/oasys/bin/oasys }
|
||||
RT_HOME /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1
|
||||
RT_LIBPATH /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/lib
|
||||
RT_MANPATH /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/doc/man
|
||||
RT_PID 2457552
|
||||
RT_SIGSTKSZ 16
|
||||
RT_TCL_PATH /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/tcl
|
||||
RT_TMP /tmp/oasys.2457552
|
||||
RT_WRAPPER_SCRIPT /applications/SiemensEDA/siemenseda2023/oasys/bin/oasys
|
||||
SCRIPTS /applications/th_tools/scripts
|
||||
SESSION_MANAGER local/unix:@/tmp/.ICE-unix/2434259,unix/unix:/tmp/.ICE-unix/2434259
|
||||
SHELL /bin/bash
|
||||
SHLVL 4
|
||||
SNPSLMD_LICENSE_FILE 1806@141.75.245.10
|
||||
SSH_ASKPASS /usr/libexec/openssh/gnome-ssh-askpass
|
||||
SSH_AUTH_SOCK /run/user/1083946113/keyring/ssh
|
||||
SYNOPSYS /applications/Synopsys/synopsys2022/syn/U-2022.12-SP4
|
||||
SYNOPSYS_TMAX /applications/Synopsys/synopsys2022/txs/U-2022.12-SP4
|
||||
TCL_LIBRARY /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/tcl/library
|
||||
TERM xterm-256color
|
||||
TLPREFIX /opt/thinlinc
|
||||
TLPROFILE gnome-classic
|
||||
TLSESSIONDATA /var/opt/thinlinc/sessions/charapallivenkatsaja/10
|
||||
TOWN Springfield
|
||||
USER charapallivenkatsaja
|
||||
USERNAME charapallivenkatsaja
|
||||
VTE_VERSION 5204
|
||||
which_declare {declare -f}
|
||||
XAUTHORITY /var/opt/thinlinc/sessions/charapallivenkatsaja/10/Xauthority
|
||||
XDG_CURRENT_DESKTOP GNOME-Classic:GNOME
|
||||
XDG_DATA_DIRS /users/ads1/charapallivenkatsaja/linux/.local/share/flatpak/exports/share:/var/lib/flatpak/exports/share:/usr/local/share:/usr/share
|
||||
XDG_MENU_PREFIX gnome-
|
||||
XDG_RUNTIME_DIR /run/user/1083946113
|
||||
XDG_SESSION_CLASS user
|
||||
XDG_SESSION_DESKTOP gnome-classic
|
||||
XDG_SESSION_ID 6060
|
||||
XDG_SESSION_TYPE x11
|
||||
XMODIFIERS @im=ibus
|
||||
---
|
||||
|
||||
Timestamp: 1779968572.059144838
|
||||
---
|
||||
Soft resource limits:
|
||||
|
||||
Executing: /bin/bash -f -c {ulimit -a -S}
|
||||
core file size (blocks, -c) 0
|
||||
data seg size (kbytes, -d) unlimited
|
||||
scheduling priority (-e) 0
|
||||
file size (blocks, -f) unlimited
|
||||
pending signals (-i) 191837
|
||||
max locked memory (kbytes, -l) 64
|
||||
max memory size (kbytes, -m) unlimited
|
||||
open files (-n) 1024
|
||||
pipe size (512 bytes, -p) 8
|
||||
POSIX message queues (bytes, -q) 819200
|
||||
real-time priority (-r) 0
|
||||
stack size (kbytes, -s) 81920
|
||||
cpu time (seconds, -t) unlimited
|
||||
max user processes (-u) 191837
|
||||
virtual memory (kbytes, -v) unlimited
|
||||
file locks (-x) unlimited
|
||||
---
|
||||
|
||||
Timestamp: 1779968572.060768504
|
||||
---
|
||||
Hard resource limits:
|
||||
|
||||
Executing: /bin/bash -f -c {ulimit -a -H}
|
||||
core file size (blocks, -c) unlimited
|
||||
data seg size (kbytes, -d) unlimited
|
||||
scheduling priority (-e) 0
|
||||
file size (blocks, -f) unlimited
|
||||
pending signals (-i) 191837
|
||||
max locked memory (kbytes, -l) 64
|
||||
max memory size (kbytes, -m) unlimited
|
||||
open files (-n) 262144
|
||||
pipe size (512 bytes, -p) 8
|
||||
POSIX message queues (bytes, -q) 819200
|
||||
real-time priority (-r) 0
|
||||
stack size (kbytes, -s) unlimited
|
||||
cpu time (seconds, -t) unlimited
|
||||
max user processes (-u) 191837
|
||||
virtual memory (kbytes, -v) unlimited
|
||||
file locks (-x) unlimited
|
||||
---
|
||||
|
||||
Timestamp: 1779968572.061645115
|
||||
---
|
||||
CPU Information
|
||||
|
||||
processor : 0
|
||||
vendor_id : AuthenticAMD
|
||||
cpu family : 25
|
||||
model : 1
|
||||
model name : AMD EPYC 73F3 16-Core Processor
|
||||
stepping : 1
|
||||
microcode : 0xa0011d3
|
||||
cpu MHz : 3499.999
|
||||
cache size : 512 KB
|
||||
physical id : 0
|
||||
siblings : 1
|
||||
core id : 0
|
||||
cpu cores : 1
|
||||
apicid : 0
|
||||
initial apicid : 0
|
||||
fpu : yes
|
||||
fpu_exception : yes
|
||||
cpuid level : 16
|
||||
wp : yes
|
||||
flags : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush mmx fxsr sse sse2 syscall nx mmxext fxsr_opt pdpe1gb rdtscp lm constant_tsc rep_good nopl tsc_reliable nonstop_tsc cpuid extd_apicid pni pclmulqdq ssse3 fma cx16 pcid sse4_1 sse4_2 x2apic movbe popcnt aes xsave avx f16c rdrand hypervisor lahf_lm extapic cr8_legacy abm sse4a misalignsse 3dnowprefetch osvw topoext invpcid_single ibpb vmmcall fsgsbase bmi1 avx2 smep bmi2 erms invpcid rdseed adx smap clflushopt clwb sha_ni xsaveopt xsavec xgetbv1 xsaves clzero wbnoinvd arat umip pku ospke vaes vpclmulqdq rdpid overflow_recov succor fsrm
|
||||
bugs : fxsave_leak sysret_ss_attrs null_seg spectre_v1 spectre_v2 spec_store_bypass srso
|
||||
bogomips : 6999.99
|
||||
TLB size : 2560 4K pages
|
||||
clflush size : 64
|
||||
cache_alignment : 64
|
||||
address sizes : 45 bits physical, 48 bits virtual
|
||||
power management:
|
||||
|
||||
|
||||
processor : 1
|
||||
physical id : 2
|
||||
apicid : 2
|
||||
initial apicid : 2
|
||||
|
||||
processor : 2
|
||||
physical id : 4
|
||||
apicid : 4
|
||||
initial apicid : 4
|
||||
|
||||
processor : 3
|
||||
physical id : 6
|
||||
apicid : 6
|
||||
initial apicid : 6
|
||||
|
||||
processor : 4
|
||||
physical id : 8
|
||||
apicid : 8
|
||||
initial apicid : 8
|
||||
|
||||
processor : 5
|
||||
physical id : 10
|
||||
apicid : 10
|
||||
initial apicid : 10
|
||||
|
||||
processor : 6
|
||||
physical id : 12
|
||||
apicid : 12
|
||||
initial apicid : 12
|
||||
|
||||
processor : 7
|
||||
physical id : 14
|
||||
apicid : 14
|
||||
initial apicid : 14
|
||||
|
||||
processor : 8
|
||||
physical id : 16
|
||||
apicid : 16
|
||||
initial apicid : 16
|
||||
|
||||
processor : 9
|
||||
physical id : 18
|
||||
apicid : 18
|
||||
initial apicid : 18
|
||||
|
||||
processor : 10
|
||||
physical id : 20
|
||||
apicid : 20
|
||||
initial apicid : 20
|
||||
|
||||
processor : 11
|
||||
physical id : 22
|
||||
apicid : 22
|
||||
initial apicid : 22
|
||||
|
||||
This host has 12 processors, with most parameters identical to the first one, except as noted above.
|
||||
|
||||
---
|
||||
|
||||
Timestamp: 1779968572.161364465
|
||||
---
|
||||
Miscellaneous system info for process PID=2457562
|
||||
Recorded at Thu May 28 13:42:52 CEST 2026
|
||||
|
||||
Executing: uptime
|
||||
13:42:52 up 20 days, 1:11, 5 users, load average: 1.99, 2.79, 2.57
|
||||
|
||||
Executing: uname -a
|
||||
Linux efiapps0.ads1.fh-nuernberg.de 4.18.0-553.123.1.el8_10.x86_64 #1 SMP Mon May 4 13:45:48 EDT 2026 x86_64 x86_64 x86_64 GNU/Linux
|
||||
|
||||
Executing: free
|
||||
total used free shared buff/cache available
|
||||
Mem: 49166924 12854332 9280556 826488 27032036 34721076
|
||||
Swap: 25165820 8312 25157508
|
||||
|
||||
Executing: ps u 2457562
|
||||
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
|
||||
charapa+ 2457562 13.0 0.1 438180 69168 pts/2 S+ 13:42 0:00 /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/oasysGui --
|
||||
|
||||
Executing: cat /etc/redhat-release
|
||||
Red Hat Enterprise Linux release 8.9 (Ootpa)
|
||||
|
||||
Executing: ldd /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/oasysGui
|
||||
linux-vdso.so.1 (0x00007fff5a525000)
|
||||
libQt5PrintSupport.so.5 => /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/../../lib/Linux-x86_64-O/libQt5PrintSupport.so.5 (0x00007f7623103000)
|
||||
libQt5Widgets.so.5 => /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/../../lib/Linux-x86_64-O/libQt5Widgets.so.5 (0x00007f76226ab000)
|
||||
libQt5Gui.so.5 => /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/../../lib/Linux-x86_64-O/libQt5Gui.so.5 (0x00007f7621d0f000)
|
||||
libQt5Core.so.5 => /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/../../lib/Linux-x86_64-O/libQt5Core.so.5 (0x00007f7621178000)
|
||||
libmemsh-102.so => /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/../../lib/Linux-x86_64-O/libmemsh-102.so (0x00007f76235b0000)
|
||||
libncurses.so.5 => /lib64/libncurses.so.5 (0x00007f7620f51000)
|
||||
libpthread.so.0 => /lib64/libpthread.so.0 (0x00007f7620d31000)
|
||||
libdl.so.2 => /lib64/libdl.so.2 (0x00007f7620b2d000)
|
||||
librt.so.1 => /lib64/librt.so.1 (0x00007f7620925000)
|
||||
libX11.so.6 => /lib64/libX11.so.6 (0x00007f76205e1000)
|
||||
libz.so.1 => /lib64/libz.so.1 (0x00007f76203c9000)
|
||||
libm.so.6 => /lib64/libm.so.6 (0x00007f7620047000)
|
||||
libc.so.6 => /lib64/libc.so.6 (0x00007f761fc71000)
|
||||
libgthread-2.0.so.0 => /lib64/libgthread-2.0.so.0 (0x00007f761fa6f000)
|
||||
libglib-2.0.so.0 => /lib64/libglib-2.0.so.0 (0x00007f761f755000)
|
||||
/lib64/ld-linux-x86-64.so.2 (0x00007f76233a4000)
|
||||
libtinfo.so.5 => /lib64/libtinfo.so.5 (0x00007f761f52a000)
|
||||
libxcb.so.1 => /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/bin/Linux-x86_64-O/../../lib/Linux-x86_64-O/libxcb.so.1 (0x00007f761f2f5000)
|
||||
libgnutls.so.30 => /lib64/libgnutls.so.30 (0x00007f761ef04000)
|
||||
libpcre.so.1 => /lib64/libpcre.so.1 (0x00007f761ec93000)
|
||||
libXau.so.6 => /lib64/libXau.so.6 (0x00007f761ea8f000)
|
||||
libXdmcp.so.6 => /lib64/libXdmcp.so.6 (0x00007f761e889000)
|
||||
libp11-kit.so.0 => /lib64/libp11-kit.so.0 (0x00007f761e55f000)
|
||||
libidn2.so.0 => /lib64/libidn2.so.0 (0x00007f761e341000)
|
||||
libunistring.so.2 => /lib64/libunistring.so.2 (0x00007f761dfc0000)
|
||||
libtasn1.so.6 => /lib64/libtasn1.so.6 (0x00007f761ddad000)
|
||||
libnettle.so.6 => /lib64/libnettle.so.6 (0x00007f761db73000)
|
||||
libhogweed.so.4 => /lib64/libhogweed.so.4 (0x00007f761d943000)
|
||||
libgmp.so.10 => /lib64/libgmp.so.10 (0x00007f761d6ab000)
|
||||
libffi.so.6 => /lib64/libffi.so.6 (0x00007f761d4a2000)
|
||||
|
||||
Examining disk space in the following directories:
|
||||
Current directory: /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl
|
||||
Oasys' temp directory: /tmp/oasys.2457552/ (normalized path: /tmp/oasys.2457552)
|
||||
RT_TMP directory: /tmp/oasys.2457552
|
||||
|
||||
Executing: df /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl /tmp/oasys.2457552 /tmp/oasys.2457552
|
||||
Filesystem 1K-blocks Used Available Use% Mounted on
|
||||
/dev/sdc1 10485760 2530136 7955624 25% /users
|
||||
/dev/sda3 25582384 9713924 15868460 38% /
|
||||
/dev/sda3 25582384 9713924 15868460 38% /
|
||||
|
||||
|
||||
---
|
||||
|
||||
@@ -0,0 +1,29 @@
|
||||
*******************************************************************
|
||||
* Oasys-RTL™ - release 2022.2.R1 *
|
||||
* *
|
||||
* This material contains trade secrets or otherwise confidential *
|
||||
* information owned by Siemens Industry Software Inc. or its *
|
||||
* affiliates (collectively, "SISW"), or its licensors. Access to *
|
||||
* and use of this information is strictly limited as set forth *
|
||||
* in the Customer’s applicable agreements with SISW. *
|
||||
* *
|
||||
* Unpublished work. © 2023 Siemens *
|
||||
* *
|
||||
* Program : ../bin/Linux-x86_64-O/oasysGui *
|
||||
* Version : 22.2-p002 *
|
||||
* Date : Mon Jan 16 21:36:23 PST 2023 *
|
||||
* Build : releases/22.2-54756.0-CentOS_6.5-O *
|
||||
*******************************************************************
|
||||
config sdc-v1.7-cpd cli cmd explore mxdb o2n fp rta mpg-m-w dft
|
||||
loading: oa2tessent-d ctl verify edit bt upf-c aos conc ipc-l vcd o2pp prot int oa2ap
|
||||
checked out license: psyncore
|
||||
|
||||
date : Thu May 28 12:01:37 CEST 2026
|
||||
ppid/pid : 2439771/2439781
|
||||
hostname : efiapps0.ads1.fh-nuernberg.de
|
||||
arch/os : x86_64/Linux-4.18.0-553.123.1.el8_10.x86_64
|
||||
install : /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1
|
||||
currdir : /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl
|
||||
logfile : /users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl/hw/rtl/oasys.log.00
|
||||
tmpdir : /tmp/oasys.2439771/
|
||||
> source /applications/SiemensEDA/siemenseda2023/Oasys-RTL-2022.2.R1/tcl/library/history.tcl
|
||||
File diff suppressed because one or more lines are too long
@@ -0,0 +1,16 @@
|
||||
*******************************************************************
|
||||
* Oasys-RTL™ - release 2022.2.R1 *
|
||||
* *
|
||||
* This material contains trade secrets or otherwise confidential *
|
||||
* information owned by Siemens Industry Software Inc. or its *
|
||||
* affiliates (collectively, "SISW"), or its licensors. Access to *
|
||||
* and use of this information is strictly limited as set forth *
|
||||
* in the Customer’s applicable agreements with SISW. *
|
||||
* *
|
||||
* Unpublished work. © 2023 Siemens *
|
||||
* *
|
||||
* Program : ../bin/Linux-x86_64-O/oasysGui *
|
||||
* Version : 22.2-p002 *
|
||||
* Date : Mon Jan 16 21:36:23 PST 2023 *
|
||||
* Build : releases/22.2-54756.0-CentOS_6.5-O *
|
||||
*******************************************************************
|
||||
@@ -0,0 +1,37 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 Bomin Kim Moved NextPC logic from decoder into PC
|
||||
// 15.Oct.2025 Bomin Kim Removed reset condition from combinational logic
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
module pc (
|
||||
output logic[31:0] CurrentPC,
|
||||
input logic[31:0] JumpOrBranchPC,
|
||||
input logic JumpOrBranch,
|
||||
output logic[31:0] NextPC,
|
||||
input logic reset,
|
||||
input logic clk
|
||||
);
|
||||
|
||||
// NextPC logic; next-state function
|
||||
always_comb begin : Next_PC
|
||||
if (JumpOrBranch) NextPC = JumpOrBranchPC;
|
||||
else NextPC = CurrentPC + 4;
|
||||
end
|
||||
|
||||
// CurrentPC logic; state register
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) CurrentPC <= '0;
|
||||
else CurrentPC <= NextPC;
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,44 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Jun.2025 by Lund University [commit 5b1e415]
|
||||
// Last Modified : 23.Oct.2025 by Bomin Kim [commit 2f8f03d]
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// 15.Oct.2025 Bomin Kim Added reset handling condition
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
module reg_file (
|
||||
input logic[4:0] Rs1,
|
||||
input logic[4:0] Rs2,
|
||||
input logic[4:0] Rd,
|
||||
output logic[31:0] RRs1,
|
||||
output logic[31:0] RRs2,
|
||||
input logic[31:0] WRd,
|
||||
input logic WrReg,
|
||||
input logic reset,
|
||||
input logic clk
|
||||
);
|
||||
|
||||
// Define the registers array
|
||||
logic[31:0] registers[31:1];
|
||||
|
||||
// Register file reading
|
||||
assign RRs1 = Rs1 == 0 ? '0 : registers[Rs1];
|
||||
assign RRs2 = Rs2 == 0 ? '0 : registers[Rs2];
|
||||
|
||||
// Register file writing
|
||||
always_ff @(posedge clk) begin
|
||||
if (reset) begin
|
||||
for (int i=1; i<32; i++)
|
||||
registers[i] <= '0;
|
||||
end else begin
|
||||
if (WrReg & Rd != 0) registers[Rd] <= WRd;
|
||||
end
|
||||
end
|
||||
|
||||
endmodule
|
||||
@@ -0,0 +1,18 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Aug.2025 by Marcus Bednara
|
||||
// Last Modified : 01.Nov.2025 by Hussein Elzomor
|
||||
// ------
|
||||
// Notes : All ${}-variables must be provided by shell or Makefile {using export}
|
||||
// *********************************************************************************************
|
||||
|
||||
hw/rtl/pc.sv
|
||||
hw/rtl/reg_file.sv
|
||||
hw/rtl/alu.sv
|
||||
hw/rtl/MemGen_32_11.sv
|
||||
hw/rtl/main_mem.sv
|
||||
hw/rtl/decoder.sv
|
||||
hw/rtl/cpu.sv
|
||||
@@ -0,0 +1,17 @@
|
||||
if [file exists "work"] {vdel -all}
|
||||
vlib work
|
||||
|
||||
# Comment out either the SystemVerilog or VHDL DUT.
|
||||
# There can be only one!
|
||||
|
||||
# VHDL DUT
|
||||
#vcom -f rtl_flist.f
|
||||
|
||||
vlog -sv dummz_memgen_16.sv
|
||||
|
||||
# SystemVerilog DUT
|
||||
vlog -sv -lint -pedanticerrors -f rtl_flist.f
|
||||
|
||||
vopt work.cpu -o cpu_opt +acc -pedanticerrors
|
||||
|
||||
quit
|
||||
@@ -0,0 +1,37 @@
|
||||
001080B3
|
||||
40210133
|
||||
0031C1B3
|
||||
00426233
|
||||
0052F2B3
|
||||
00631333
|
||||
0073D3B3
|
||||
40845433
|
||||
0094A4B3
|
||||
00A53533
|
||||
00B58593
|
||||
00C64613
|
||||
00D6E693
|
||||
00E77713
|
||||
00F79793
|
||||
01085813
|
||||
4118D893
|
||||
01292913
|
||||
0139B993
|
||||
014A0A03
|
||||
015A9A83
|
||||
016B2B03
|
||||
017BCB83
|
||||
018C5C03
|
||||
019C8CA3
|
||||
01AD1D23
|
||||
01BDADA3
|
||||
01CE0E63
|
||||
01CE1E63
|
||||
01EF4F63
|
||||
01EF5F63
|
||||
00216163
|
||||
00217163
|
||||
0040026F
|
||||
00420267
|
||||
000052B7
|
||||
00006317
|
||||
@@ -0,0 +1,65 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Assembly instructions for decoder test
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
# Iteration over all implemented instructions to test decoder
|
||||
|
||||
# R-instruction # Hex # bin f7 rs2 rs1 f3 rd opcode
|
||||
add x1 , x1 , x1 # 0x001080B3 # 0b 0000000 00001 00001 000 00001 0110011
|
||||
sub x2 , x2 , x2 # 0x40210133 # 0b 0100000 00010 00010 000 00010 0110011
|
||||
xor x3 , x3 , x3 # 0x0031C1B3 # 0b 0000000 00011 00011 100 00011 0110011
|
||||
or x4 , x4 , x4 # 0x00426233 # 0b 0000000 00100 00100 110 00100 0110011
|
||||
and x5 , x5 , x5 # 0x0052F2B3 # 0b 0000000 00101 00101 111 00101 0110011
|
||||
sll x6 , x6 , x6 # 0x00631333 # 0b 0000000 00110 00110 001 00110 0110011
|
||||
srl x7 , x7 , x7 # 0x0073D3B3 # 0b 0000000 00111 00111 101 00111 0110011
|
||||
sra x8 , x8 , x8 # 0x40845433 # 0b 0100000 01000 01000 101 01000 0110011
|
||||
slt x9 , x9 , x9 # 0x0094A4B3 # 0b 0000000 01001 01001 010 01001 0110011
|
||||
sltu x10, x10, x10 # 0x00A53533 # 0b 0000000 01010 01010 011 01010 0110011
|
||||
|
||||
# I-instruction # Hex # bin imm rs1 f3 rd opcode
|
||||
addi x11, x11, 11 # 0x00B58593 # 0b 000000001011 01011 000 01011 0010011
|
||||
xori x12, x12, 12 # 0x00C64613 # 0b 000000001100 01100 100 01100 0010011
|
||||
ori x13, x13, 13 # 0x00D6E693 # 0b 000000001101 01101 110 01101 0010011
|
||||
andi x14, x14, 14 # 0x00E77713 # 0b 000000001110 01110 111 01110 0010011
|
||||
slli x15, x15, 15 # 0x00F79793 # 0b 000000001111 01111 001 01111 0010011
|
||||
srli x16, x16, 16 # 0x01085813 # 0b 000000010000 10000 101 10000 0010011
|
||||
srai x17, x17, 17 # 0x4118D893 # 0b 010000010001 10001 101 10001 0010011
|
||||
slti x18, x18, 18 # 0x01292913 # 0b 000000010010 10010 010 10010 0010011
|
||||
sltiu x19, x19, 19 # 0x0139B993 # 0b 000000010011 10011 011 10011 0010011
|
||||
lb x20, 20(x20) # 0x014A0A03 # 0b 000000010100 10100 000 10100 0000011
|
||||
lh x21, 21(x21) # 0x015A9A83 # 0b 000000010101 10101 001 10101 0000011
|
||||
lw x22, 22(x22) # 0x016B2B03 # 0b 000000010110 10110 010 10110 0000011
|
||||
lbu x23, 23(x23) # 0x017BCB83 # 0b 000000010111 10111 100 10111 0000011
|
||||
lhu x24, 24(x24) # 0x018C5C03 # 0b 000000011000 11000 101 11000 0000011
|
||||
|
||||
# S-instruction # Hex # bin imm rs2 rs1 f3 imm opcode
|
||||
sb x25, 25(x25) # 0x019C8CA3 # 0b 0000000 11001 11001 000 11001 0100011
|
||||
sh x26, 26(x26) # 0x01AD1D23 # 0b 0000000 11010 11010 001 11010 0100011
|
||||
sw x27, 27(x27) # 0x01BDADA3 # 0b 0000000 11011 11011 010 11011 0100011
|
||||
|
||||
# B-instruction # Hex # bin imm rs2 rs1 f3 imm opcode
|
||||
beq x28, x28, 28 # 0x01CE0E63 # 0b 0000000 11100 11100 000 11100 1100011
|
||||
bne x28, x28, 28 # 0x01CE1E63 # 0b 0000000 11100 11100 001 11100 1100011
|
||||
blt x30, x30, 30 # 0x01EF4F63 # 0b 0000000 11110 11110 100 11110 1100011
|
||||
bge x30, x30, 30 # 0x01EF5F63 # 0b 0000000 11110 11110 101 11110 1100011
|
||||
bltu x2 , x2 , 2 # 0x00216163 # 0b 0000000 00010 00010 110 00010 1100011
|
||||
bgeu x2 , x2 , 2 # 0x00217163 # 0b 0000000 00010 00010 111 00010 1100011
|
||||
|
||||
# J-instruction # Hex # bin f7 rd opcode
|
||||
jal x4 , 4 # 0x0040026F # 0b 00000000010000000000 00100 1101111
|
||||
jalr x4 , x4, 4 # 0x00420267 # 0b 00000000010000100000 00100 1100111
|
||||
|
||||
# U-instruction # Hex # bin f7 rd opcode
|
||||
lui x5 , 5 # 0x000052B7 # 0b 00000000000000000101 00101 0110111
|
||||
auipc x6 , 6 # 0x00006317 # 0b 00000000000000000110 00110 0010111
|
||||
@@ -0,0 +1,29 @@
|
||||
// *********************************************************************************************
|
||||
// Description : C Program to calculate the Fibonacci numbers until a given number of terms
|
||||
// File : v1.0
|
||||
// Project Version : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// Project : RISCV_IN3DAYS
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 13.Oct.2025, 11:00:00 by Fuad Mammadzada (fuad.mammadzada@fau.de)
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
asm(".global _start, halt; _start: lui sp 2; addi sp sp -4; jal x0 main");
|
||||
|
||||
int main() {
|
||||
int n = 10; // count of Fibonacci numbers to be evaluated
|
||||
|
||||
int fib_number[20];
|
||||
fib_number[0] = 0;
|
||||
fib_number[1] = 1;
|
||||
|
||||
for (int i = 2; i < n; i++) {
|
||||
fib_number[i] = fib_number[i-1] + fib_number[i-2];
|
||||
}
|
||||
|
||||
asm("j halt");
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
00002137
|
||||
FFC10113
|
||||
0080006F
|
||||
0000006F
|
||||
FB010113
|
||||
00100513
|
||||
00810593
|
||||
00012023
|
||||
00A12223
|
||||
02810613
|
||||
FF85A683
|
||||
00A68533
|
||||
00A5A023
|
||||
00458593
|
||||
FEC598E3
|
||||
FD1FF06F
|
||||
@@ -0,0 +1,38 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Assembly instructions for fibonacci program
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Fuad Mammadzada
|
||||
// Last Modified : 21.Oct.2025 by Fuad Mammadzada
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
# Instruction # Hex code # MemAddr(PC) # Corresponding C code & explanation
|
||||
_start:
|
||||
lui sp, 2 # 0x00002137 # 0x00000000 # Initialize stack pointer value to size of memory (0x00002000)
|
||||
addi sp, sp -4 # 0xFFC10113 # 0x00000004 # Subtract stack pointer value by 4 to point to the last memory address (0x00001FFC)
|
||||
jal x0, main # 0x0080006F # 0x00000008 # Jump to main without saving the return address
|
||||
halt:
|
||||
jal x0, halt # 0x0000006F # 0x0000000C # Halt the program (infinite loop)
|
||||
|
||||
main: # -------- # fibonacci.c:17: int main() {
|
||||
addi sp, sp, -80 # 0xFB010113 # 0x00000010 # fibonacci.c:20: int fib_number[20]; (allocate 20*4B from the stack)
|
||||
addi a0, x0, 1 # 0x00100513 # 0x00000014 # a0 = 0 + 1 (this is later used in fibonacci.c:22)
|
||||
addi a1, sp, 8 # 0x00810593 # 0x00000018 # calculate and save the address of fib_number[2]
|
||||
sw x0, 0(sp) # 0x00012023 # 0x0000001C # fibonacci.c:21: fib_number[0] = x0 = 0
|
||||
sw a0, 4(sp) # 0x00A12223 # 0x00000020 # fibonacci.c:22: fib_number[1] = a0 = 1
|
||||
addi a2, sp, 40 # 0x02810613 # 0x00000024 # fibonacci.c:24: calculate the last array index for the loop condition (since n=10, n*4B)
|
||||
|
||||
.for_loop:
|
||||
lw a3, -8(a1) # 0xFF85A683 # 0x00000028 # fibonacci.c:25: a3 = fib_number[i-2]
|
||||
add a0, a3, a0 # 0x00A68533 # 0x0000002C # fibonacci.c:25: a0 = fib_number[i-1] + fib_number[i-2]
|
||||
sw a0, 0(a1) # 0x00A5A023 # 0x00000030 # fibonacci.c:25: fib_number[i] = a0
|
||||
addi a1, a1, 4 # 0x00458593 # 0x00000034 # fibonacci.c:24: i++
|
||||
bne a1, a2, .for_loop # 0xFEC598E3 # 0x00000038 # fibonacci.c:24: loop back if i != n
|
||||
jal x0, halt # 0xFD1FF06F # 0x0000003C # fibonacci.c:28: asm("j halt");
|
||||
@@ -0,0 +1,43 @@
|
||||
// *********************************************************************************************
|
||||
// Description : C Program to store the sentence 'hello world!' in a char array in memory
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
asm(".global _start, halt; .set DataMem 0x1; _start: lui sp 0x2; addi sp sp -4; jal main;");
|
||||
// DataMem address usage is set manually in the assembly code after its generation.
|
||||
|
||||
void storeChar(char c, char *location)
|
||||
{
|
||||
*location = c;
|
||||
}
|
||||
|
||||
int main()
|
||||
{
|
||||
static char mem[13];
|
||||
|
||||
storeChar('h', &mem[0]);
|
||||
storeChar('e', &mem[1]);
|
||||
storeChar('l', &mem[2]);
|
||||
storeChar('l', &mem[3]);
|
||||
storeChar('o', &mem[4]);
|
||||
storeChar(' ', &mem[5]);
|
||||
storeChar('w', &mem[6]);
|
||||
storeChar('o', &mem[7]);
|
||||
storeChar('r', &mem[8]);
|
||||
storeChar('l', &mem[9]);
|
||||
storeChar('d', &mem[10]);
|
||||
storeChar('!', &mem[11]);
|
||||
storeChar('\0', &mem[12]); // Don't forget the null terminator!
|
||||
|
||||
return 0; // End the main function and return 0 on success
|
||||
}
|
||||
@@ -0,0 +1,92 @@
|
||||
00002137
|
||||
FFC10113
|
||||
03C000EF
|
||||
0000006F
|
||||
FE010113
|
||||
00112E23
|
||||
00812C23
|
||||
02010413
|
||||
FEB42423
|
||||
FEA407A3
|
||||
FE842783
|
||||
FEF44703
|
||||
00E78023
|
||||
01C12083
|
||||
01812403
|
||||
02010113
|
||||
00008067
|
||||
FF010113
|
||||
00112623
|
||||
00812423
|
||||
01010413
|
||||
000015B7
|
||||
00058593
|
||||
06800513
|
||||
00000317
|
||||
FB0300E7
|
||||
000015B7
|
||||
00158593
|
||||
06500513
|
||||
00000317
|
||||
F9C300E7
|
||||
000015B7
|
||||
00258593
|
||||
06C00513
|
||||
00000317
|
||||
F88300E7
|
||||
000015B7
|
||||
00358593
|
||||
06C00513
|
||||
00000317
|
||||
F74300E7
|
||||
000015B7
|
||||
00458593
|
||||
06F00513
|
||||
00000317
|
||||
F60300E7
|
||||
000015B7
|
||||
00558593
|
||||
02000513
|
||||
00000317
|
||||
F4C300E7
|
||||
000015B7
|
||||
00658593
|
||||
07700513
|
||||
00000317
|
||||
F38300E7
|
||||
000015B7
|
||||
00758593
|
||||
06F00513
|
||||
00000317
|
||||
F24300E7
|
||||
000015B7
|
||||
00858593
|
||||
07200513
|
||||
00000317
|
||||
F10300E7
|
||||
000015B7
|
||||
00958593
|
||||
06C00513
|
||||
00000317
|
||||
EFC300E7
|
||||
000015B7
|
||||
00A58593
|
||||
06400513
|
||||
00000317
|
||||
EE8300E7
|
||||
000015B7
|
||||
00B58593
|
||||
02100513
|
||||
00000317
|
||||
ED4300E7
|
||||
000015B7
|
||||
00C58593
|
||||
00000513
|
||||
00000317
|
||||
EC0300E7
|
||||
00000793
|
||||
00078513
|
||||
00C12083
|
||||
00812403
|
||||
01010113
|
||||
00008067
|
||||
@@ -0,0 +1,121 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Assembly instructions for hello world program
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 21.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
# GNU C++17 (crosstool-NG UNKNOWN) version 15.2.0 (riscv32-unknown-linux-gnu)
|
||||
# compiled by GNU C version 16.0.0 20250802 (experimental), GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.24-GMP
|
||||
|
||||
# GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
|
||||
# options passed: -mabi=ilp32d -misa-spec=20191213 -mtls-dialect=trad -march=rv32ifd_zicsr -g
|
||||
.set DataMem,0x1 # Start of Data Memory 0x1000 (translates to 0x400 due to 4 bytes adressing system)
|
||||
_start:
|
||||
lui sp, 0x2 # Initialize stack pointer value to size of memory (0x00002000)
|
||||
addi sp, sp -4 # Subtract stack pointer value by 4 to point to the last memory address (0x00001FFC)
|
||||
jal main # Jump to main and save return address to ra
|
||||
halt:
|
||||
j halt # Get stuck here in a loop forever
|
||||
storeChar:
|
||||
addi sp,sp,-32 # Reserve some space on the stack
|
||||
sw ra,28(sp) # Save the return address on the stack
|
||||
sw s0,24(sp) # Save the caller frame pointer value on the stack
|
||||
addi s0,sp,32 # Store the callee frame pointer value in s0 (end address of the stack frame)
|
||||
sw a1,-24(s0) # arg1, location
|
||||
sb a0,-17(s0) # arg0, c
|
||||
# helloWorld.c:8: *location = c;
|
||||
lw a5,-24(s0) # tmp136, location
|
||||
lbu a4,-17(s0) # tmp137, c
|
||||
sb a4,0(a5) # tmp137, *location_2(D)
|
||||
# helloWorld.c:9: }
|
||||
lw ra,28(sp) # Load the return address from the stack and store it in ra
|
||||
lw s0,24(sp) # Load the caller frame pointer value from the stack and store it in s0
|
||||
addi sp,sp,32 # Free the allocated stack space for the function call
|
||||
jr ra # Return to address stored in ra
|
||||
main:
|
||||
addi sp,sp,-16 # Reserve some space on the stack
|
||||
sw ra,12(sp) # Save the return address on the stack
|
||||
sw s0,8(sp) # Save the caller frame pointer value on the stack
|
||||
addi s0,sp,16 # Store the callee frame pointer value in s0 (end address of the stack frame)
|
||||
# helloWorld.c:15: storeChar('h', &mem[0]);
|
||||
lui a1,DataMem # tmp136, DataMem
|
||||
addi a1,a1,0 # arg1, tmp136 + 0
|
||||
li a0,104 # arg0, 'h'
|
||||
call storeChar #
|
||||
# helloWorld.c:16: storeChar('e', &mem[1]);
|
||||
lui a1,DataMem # tmp137, DataMem
|
||||
addi a1,a1,1 # arg1, tmp137 + 1
|
||||
li a0,101 # arg0, 'e'
|
||||
call storeChar #
|
||||
# helloWorld.c:17: storeChar('l', &mem[2]);
|
||||
lui a1,DataMem # tmp138, DataMem
|
||||
addi a1,a1,2 # arg1, tmp138 + 2
|
||||
li a0,108 # arg0, 'l'
|
||||
call storeChar #
|
||||
# helloWorld.c:18: storeChar('l', &mem[3]);
|
||||
lui a1,DataMem # tmp139, DataMem
|
||||
addi a1,a1,3 # arg1, tmp139 + 3
|
||||
li a0,108 # arg0, 'l'
|
||||
call storeChar #
|
||||
# helloWorld.c:19: storeChar('o', &mem[4]);
|
||||
lui a1,DataMem # tmp140, DataMem
|
||||
addi a1,a1,4 # arg1, tmp140 + 4
|
||||
li a0,111 # arg0, 'o'
|
||||
call storeChar #
|
||||
# helloWorld.c:20: storeChar(' ', &mem[5]);
|
||||
lui a1,DataMem # tmp141, DataMem
|
||||
addi a1,a1,5 # arg1, tmp141 + 5
|
||||
li a0,32 # arg0, ' '
|
||||
call storeChar #
|
||||
# helloWorld.c:21: storeChar('w', &mem[6]);
|
||||
lui a1,DataMem # tmp142, DataMem
|
||||
addi a1,a1,6 # arg1, tmp142 + 6
|
||||
li a0,119 # arg0, 'w'
|
||||
call storeChar #
|
||||
# helloWorld.c:22: storeChar('o', &mem[7]);
|
||||
lui a1,DataMem # tmp143, DataMem
|
||||
addi a1,a1,7 # arg1, tmp143 + 7
|
||||
li a0,111 # arg0, 'o'
|
||||
call storeChar #
|
||||
# helloWorld.c:23: storeChar('r', &mem[8]);
|
||||
lui a1,DataMem # tmp144, DataMem
|
||||
addi a1,a1,8 # arg1, tmp144 + 8
|
||||
li a0,114 # arg0, 'r'
|
||||
call storeChar #
|
||||
# helloWorld.c:24: storeChar('l', &mem[9]);
|
||||
lui a1,DataMem # tmp145, DataMem
|
||||
addi a1,a1,9 # arg1, tmp145 + 9
|
||||
li a0,108 # arg0, 'l'
|
||||
call storeChar #
|
||||
# helloWorld.c:25: storeChar('d', &mem[10]);
|
||||
lui a1,DataMem # tmp146, DataMem
|
||||
addi a1,a1,10 # arg1, tmp146 + 10
|
||||
li a0,100 # arg0, 'd'
|
||||
call storeChar #
|
||||
# helloWorld.c:26: storeChar('!', &mem[11]);
|
||||
lui a1,DataMem # tmp147, DataMem
|
||||
addi a1,a1,11 # arg1, tmp147 + 11
|
||||
li a0,33 # arg0, '!'
|
||||
call storeChar #
|
||||
# helloWorld.c:27: storeChar('\0', &mem[12]); // Don't forget the null terminator!
|
||||
lui a1,DataMem # tmp148, DataMem
|
||||
addi a1,a1,12 # arg1, tmp148 + 12
|
||||
li a0,0 # arg0, '\0
|
||||
call storeChar #
|
||||
# helloWorld.c:29: return 0; // End the main function and return 0 on success
|
||||
li a5,0 # _16,
|
||||
# helloWorld.c:30: }
|
||||
mv a0,a5 #, <retval>
|
||||
lw ra,12(sp) # Load the return address from the stack and store it in ra
|
||||
lw s0,8(sp) # Load the caller frame pointer value from the stack and store it in s0
|
||||
addi sp,sp,16 # Free the allocated stack space for the function call
|
||||
jr ra # Return to address stored in ra
|
||||
@@ -0,0 +1,120 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Simplified assembly instructions for hello world program
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 21.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
# 1 to 1 mapping of the Hex instructions in helloWorld.hex
|
||||
# Simplified version of helloWorld.s
|
||||
## Replaced pseudo instructions with the proper rv32i instructions
|
||||
## Replaced jumps to labels with address offset values
|
||||
|
||||
# Use as a cross reference to identify:
|
||||
## - the instruction being run on your processor
|
||||
## - which part of the program is being run
|
||||
## - confirm registers and memory addresses contain the correct data
|
||||
_start: # Hex # MemAddr(PC)
|
||||
lui x2 2 # 0x00002137 # 0x00000000
|
||||
addi x2 x2 -4 # 0xFFC10113 # 0x00000004
|
||||
jal x1 60 # 0x03C000EF # 0x00000008
|
||||
halt:
|
||||
jal x0 0 # 0x0000006F # 0x0000000C
|
||||
storeChar:
|
||||
addi x2 x2 -32 # 0xFE010113 # 0x00000010
|
||||
sw x1 28(x2) # 0x00112E23 # 0x00000014
|
||||
sw x8 24(x2) # 0x00812C23 # 0x00000018
|
||||
addi x8 x2 32 # 0x02010413 # 0x0000001C
|
||||
sw x11 -24(x8) # 0xFEB42423 # 0x00000020
|
||||
sb x10 -17(x8) # 0xFEA407A3 # 0x00000024
|
||||
lw x15 -24(x8) # 0xFE842783 # 0x00000028
|
||||
lbu x14 -17(x8) # 0xFEF44703 # 0x0000002C
|
||||
sb x14 0(x15) # 0x00E78023 # 0x00000030
|
||||
lw x1 28(x2) # 0x01C12083 # 0x00000034
|
||||
lw x8 24(x2) # 0x01812403 # 0x00000038
|
||||
addi x2 x2 32 # 0x02010113 # 0x0000003C
|
||||
jalr x0 x1 0 # 0x00008067 # 0x00000040
|
||||
main:
|
||||
addi x2 x2 -16 # 0xFF010113 # 0x00000044
|
||||
sw x1 12(x2) # 0x00112623 # 0x00000048
|
||||
sw x8 8(x2) # 0x00812423 # 0x0000004C
|
||||
addi x8 x2 16 # 0x01010413 # 0x00000050
|
||||
lui x11 1 # 0x000015B7 # 0x00000054
|
||||
addi x11 x11 0 # 0x00058593 # 0x00000058
|
||||
addi x10 x0 104 # 0x06800513 # 0x0000005C
|
||||
auipc x6 0 # 0x00000317 # 0x00000060
|
||||
jalr x1 x6 -80 # 0xFB0300E7 # 0x00000064
|
||||
lui x11 1 # 0x000015B7 # 0x00000068
|
||||
addi x11 x11 1 # 0x00158593 # 0x0000006C
|
||||
addi x10 x0 101 # 0x06500513 # 0x00000070
|
||||
auipc x6 0 # 0x00000317 # 0x00000074
|
||||
jalr x1 x6 -100 # 0xF9C300E7 # 0x00000078
|
||||
lui x11 1 # 0x000015B7 # 0x0000007C
|
||||
addi x11 x11 2 # 0x00258593 # 0x00000080
|
||||
addi x10 x0 108 # 0x06C00513 # 0x00000084
|
||||
auipc x6 0 # 0x00000317 # 0x00000088
|
||||
jalr x1 x6 -120 # 0xF88300E7 # 0x0000008C
|
||||
lui x11 1 # 0x000015B7 # 0x00000090
|
||||
addi x11 x11 3 # 0x00358593 # 0x00000094
|
||||
addi x10 x0 108 # 0x06C00513 # 0x00000098
|
||||
auipc x6 0 # 0x00000317 # 0x0000009C
|
||||
jalr x1 x6 -140 # 0xF74300E7 # 0x000000A0
|
||||
lui x11 1 # 0x000015B7 # 0x000000A4
|
||||
addi x11 x11 4 # 0x00458593 # 0x000000A8
|
||||
addi x10 x0 111 # 0x06F00513 # 0x000000AC
|
||||
auipc x6 0 # 0x00000317 # 0x000000B0
|
||||
jalr x1 x6 -160 # 0xF60300E7 # 0x000000B4
|
||||
lui x11 1 # 0x000015B7 # 0x000000B8
|
||||
addi x11 x11 5 # 0x00558593 # 0x000000BC
|
||||
addi x10 x0 32 # 0x02000513 # 0x000000C0
|
||||
auipc x6 0 # 0x00000317 # 0x000000C4
|
||||
jalr x1 x6 -180 # 0xF4C300E7 # 0x000000C8
|
||||
lui x11 1 # 0x000015B7 # 0x000000CC
|
||||
addi x11 x11 6 # 0x00658593 # 0x000000D0
|
||||
addi x10 x0 119 # 0x07700513 # 0x000000D4
|
||||
auipc x6 0 # 0x00000317 # 0x000000D8
|
||||
jalr x1 x6 -200 # 0xF38300E7 # 0x000000DC
|
||||
lui x11 1 # 0x000015B7 # 0x000000E0
|
||||
addi x11 x11 7 # 0x00758593 # 0x000000E4
|
||||
addi x10 x0 111 # 0x06F00513 # 0x000000E8
|
||||
auipc x6 0 # 0x00000317 # 0x000000EC
|
||||
jalr x1 x6 -220 # 0xF24300E7 # 0x000000F0
|
||||
lui x11 1 # 0x000015B7 # 0x000000F4
|
||||
addi x11 x11 8 # 0x00858593 # 0x000000F8
|
||||
addi x10 x0 114 # 0x07200513 # 0x000000FC
|
||||
auipc x6 0 # 0x00000317 # 0x00000100
|
||||
jalr x1 x6 -240 # 0xF10300E7 # 0x00000104
|
||||
lui x11 1 # 0x000015B7 # 0x00000108
|
||||
addi x11 x11 9 # 0x00958593 # 0x0000010C
|
||||
addi x10 x0 108 # 0x06C00513 # 0x00000110
|
||||
auipc x6 0 # 0x00000317 # 0x00000114
|
||||
jalr x1 x6 -260 # 0xEFC300E7 # 0x00000118
|
||||
lui x11 1 # 0x000015B7 # 0x0000011C
|
||||
addi x11 x11 10 # 0x00A58593 # 0x00000120
|
||||
addi x10 x0 100 # 0x06400513 # 0x00000124
|
||||
auipc x6 0 # 0x00000317 # 0x00000128
|
||||
jalr x1 x6 -280 # 0xEE8300E7 # 0x0000012C
|
||||
lui x11 1 # 0x000015B7 # 0x00000130
|
||||
addi x11 x11 11 # 0x00B58593 # 0x00000134
|
||||
addi x10 x0 33 # 0x02100513 # 0x00000138
|
||||
auipc x6 0 # 0x00000317 # 0x0000013C
|
||||
jalr x1 x6 -300 # 0xED4300E7 # 0x00000140
|
||||
lui x11 1 # 0x000015B7 # 0x00000144
|
||||
addi x11 x11 12 # 0x00C58593 # 0x00000148
|
||||
addi x10 x0 0 # 0x00000513 # 0x0000014C
|
||||
auipc x6 0 # 0x00000317 # 0x00000150
|
||||
jalr x1 x6 -320 # 0xEC0300E7 # 0x00000154
|
||||
addi x15 x0 0 # 0x00000793 # 0x00000158
|
||||
addi x10 x15 0 # 0x00078513 # 0x0000015C
|
||||
lw x1 12(x2) # 0x00C12083 # 0x00000160
|
||||
lw x8 8(x2) # 0x00812403 # 0x00000164
|
||||
addi x2 x2 16 # 0x01010113 # 0x00000168
|
||||
jalr x0 x1 0 # 0x00008067 # 0x0000016C
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
@@ -0,0 +1,53 @@
|
||||
// *********************************************************************************************
|
||||
// Description : C Program to find prime factors of a Number
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 15.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
asm(".global _start, halt; _start: lui sp 0x2; addi sp sp -4; jal main");
|
||||
|
||||
int main()
|
||||
{
|
||||
int i, iModulo, j, Number, NumberModulo, isPrime, Prime; // Create variables
|
||||
Number = 39; // Set initial value for Number to be factorized
|
||||
Prime = 0; // Set initial value for Prime to be printed
|
||||
for (i = 2; i <= Number; i++) // Iterate over i from 2 to Number, all possible numbers excluding 1 & 0
|
||||
{
|
||||
NumberModulo = Number;
|
||||
while (NumberModulo > 0) // Calculate Number % i using subtraction and store in NumberModulo
|
||||
{
|
||||
NumberModulo -= i;
|
||||
}
|
||||
if (NumberModulo == 0) // If Number % i == 0, it is possible that it's a prime number
|
||||
{
|
||||
isPrime = 1;
|
||||
for (j = 2; j <= i / 2; j++) // Iterate over j from 2 to i/2
|
||||
{
|
||||
iModulo = i;
|
||||
while (iModulo > 0) // Calculate i % j using subtraction and store in iModulo
|
||||
{
|
||||
iModulo -= j;
|
||||
}
|
||||
if (iModulo == 0) // If i % j == 0, it is not a prime number
|
||||
{
|
||||
isPrime = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (isPrime == 1) // Print i if i is a prime number
|
||||
{
|
||||
Prime = i; // Set variable Prime to the prime number. Used for printing in the TB upon change
|
||||
}
|
||||
}
|
||||
}
|
||||
return 0; // End the main function and return 0 on success
|
||||
}
|
||||
@@ -0,0 +1,71 @@
|
||||
00002137
|
||||
FFC10113
|
||||
008000EF
|
||||
0000006F
|
||||
FD010113
|
||||
02112623
|
||||
02812423
|
||||
03010413
|
||||
02700793
|
||||
00078813
|
||||
FCF42C23
|
||||
FC042A23
|
||||
00200793
|
||||
FEF42623
|
||||
0C00006F
|
||||
FD842783
|
||||
FEF42023
|
||||
0140006F
|
||||
FE042703
|
||||
FEC42783
|
||||
40F707B3
|
||||
FEF42023
|
||||
FE042783
|
||||
FEF046E3
|
||||
FE042783
|
||||
08079463
|
||||
00100793
|
||||
FCF42E23
|
||||
00200793
|
||||
FEF42223
|
||||
0440006F
|
||||
FEC42783
|
||||
FEF42423
|
||||
0140006F
|
||||
FE842703
|
||||
FE442783
|
||||
40F707B3
|
||||
FEF42423
|
||||
FE842783
|
||||
FEF046E3
|
||||
FE842783
|
||||
00079663
|
||||
FC042E23
|
||||
02C0006F
|
||||
FE442783
|
||||
00178793
|
||||
FEF42223
|
||||
FEC42783
|
||||
01F7D713
|
||||
00F707B3
|
||||
4017D793
|
||||
00078713
|
||||
FE442783
|
||||
FAF754E3
|
||||
FDC42703
|
||||
00100793
|
||||
00F71663
|
||||
FEC42883
|
||||
FD142A23
|
||||
FEC42783
|
||||
00178793
|
||||
FEF42623
|
||||
FEC42703
|
||||
FD842783
|
||||
F2E7DEE3
|
||||
00000793
|
||||
00078513
|
||||
02C12083
|
||||
02812403
|
||||
03010113
|
||||
00008067
|
||||
@@ -0,0 +1,140 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Assembly instructions for prime factors program
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 21.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
# GNU C23 (crosstool-NG UNKNOWN) version 15.2.0 (riscv32-unknown-linux-gnu)
|
||||
# compiled by GNU C version 16.0.0 20250802 (experimental), GMP version 6.3.0, MPFR version 4.2.1, MPC version 1.3.1, isl version isl-0.24-GMP
|
||||
|
||||
# GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072
|
||||
# options passed: -mabi=ilp32d -misa-spec=20191213 -mtls-dialect=trad -march=rv32imafdc_zicsr_zifencei_zmmul_zaamo_zalrsc_zca_zcd_zcf -g
|
||||
_start:
|
||||
lui sp, 0x2 # Initialize stack pointer value to size of memory (0x00002000)
|
||||
addi sp, sp -4 # Subtract stack pointer value by 4 to point to the last memory address (0x00001FFC)
|
||||
jal main # Jump to main and save return address to ra
|
||||
halt:
|
||||
j halt # Get stuck here in a loop forever
|
||||
main:
|
||||
addi sp,sp,-48 # Reserve some space on the stack
|
||||
sw ra,44(sp) # Save the return address on the stack
|
||||
sw s0,40(sp) # Save the caller frame pointer value on the stack
|
||||
addi s0,sp,48 # Store the callee frame pointer value in s0 (end address of the stack frame)
|
||||
# primeFactors.c:6: Number = 39; // Set initial value for Number to be factorized
|
||||
li a5,39 # tmp137,39 # Change the Number (39) to different values to test the program
|
||||
mv a6, a5 # ,tmp137 # Used for printing in the TB upon change
|
||||
sw a5,-40(s0) # tmp137, Number
|
||||
# primeFactors.c:7: Prime = 0; // Set initial value for Prime to be printed
|
||||
sw zero,-44(s0) #, Prime
|
||||
loop_i_init:
|
||||
# primeFactors.c:8: for (i = 2; i <= Number; i++) // Iterate over i from 2 to Number, all possible numbers excluding 1 & 0
|
||||
li a5,2 # tmp138,
|
||||
sw a5,-20(s0) # tmp138, i
|
||||
# primeFactors.c:8: for (i = 2; i <= Number; i++) // Iterate over i from 2 to Number, all possible numbers excluding 1 & 0
|
||||
j loop_i_check #
|
||||
num_mod_set:
|
||||
# primeFactors.c:10: NumberModulo = Number;
|
||||
lw a5,-40(s0) # tmp139, Number
|
||||
sw a5,-32(s0) # tmp139, NumberModulo
|
||||
# primeFactors.c:11: while (NumberModulo > 0) // Calculate Number % i using subtraction and store in NumberModulo
|
||||
j num_mod_loop #
|
||||
num_mod_sub_i:
|
||||
# primeFactors.c:13: NumberModulo -= i;
|
||||
lw a4,-32(s0) # tmp141, NumberModulo
|
||||
lw a5,-20(s0) # tmp142, i
|
||||
sub a5,a4,a5 # NumberModulo_21, tmp141, tmp142
|
||||
sw a5,-32(s0) # NumberModulo_21, NumberModulo
|
||||
num_mod_loop:
|
||||
# primeFactors.c:11: while (NumberModulo > 0) // Calculate Number % i using subtraction and store in NumberModulo
|
||||
lw a5,-32(s0) # tmp143, NumberModulo
|
||||
bgt a5,zero,num_mod_sub_i #, tmp143,,
|
||||
num_mod_check:
|
||||
# primeFactors.c:15: if (NumberModulo == 0) // If Number % i == 0, it is possible that it's a prime number
|
||||
lw a5,-32(s0) # tmp144, NumberModulo
|
||||
bne a5,zero,loop_i_inc #, tmp144,,
|
||||
|
||||
# primeFactors.c:17: isPrime = 1;
|
||||
li a5,1 # tmp145,
|
||||
sw a5,-36(s0) # tmp145, isPrime
|
||||
loop_j_init:
|
||||
# primeFactors.c:18: for (j = 2; j <= i / 2; j++) // Iterate over j from 2 to i/2
|
||||
li a5,2 # tmp146,
|
||||
sw a5,-28(s0) # tmp146, j
|
||||
# primeFactors.c:18: for (j = 2; j <= i / 2; j++) // Iterate over j from 2 to i/2
|
||||
j loop_j_check #
|
||||
i_mod_set:
|
||||
# primeFactors.c:20: iModulo = i;
|
||||
lw a5,-20(s0) # tmp147, i
|
||||
sw a5,-24(s0) # tmp147, iModulo
|
||||
# primeFactors.c:21: while (iModulo > 0) // Calculate i % j using subtraction and store in iModulo
|
||||
j i_mod_loop #
|
||||
i_mod_sub_j:
|
||||
# primeFactors.c:23: iModulo -= j;
|
||||
lw a4,-24(s0) # tmp149, iModulo
|
||||
lw a5,-28(s0) # tmp150, j
|
||||
sub a5,a4,a5 # iModulo_18, tmp149, tmp150
|
||||
sw a5,-24(s0) # iModulo_18, iModulo
|
||||
i_mod_loop:
|
||||
# primeFactors.c:21: while (iModulo > 0) // Calculate i % j using subtraction and store in iModulo
|
||||
lw a5,-24(s0) # tmp151, iModulo
|
||||
bgt a5,zero,i_mod_sub_j #, tmp151,,
|
||||
i_mod_check:
|
||||
# primeFactors.c:25: if (iModulo == 0) // If i % j == 0, it is not a prime number
|
||||
lw a5,-24(s0) # tmp152, iModulo
|
||||
bne a5,zero,loop_j_inc #, tmp152,,
|
||||
# primeFactors.c:27: isPrime = 0;
|
||||
sw zero,-36(s0) #, isPrime
|
||||
# primeFactors.c:28: break;
|
||||
j prime_check #
|
||||
loop_j_inc:
|
||||
# primeFactors.c:18: for (j = 2; j <= i / 2; j++) // Iterate over j from 2 to i/2
|
||||
lw a5,-28(s0) # tmp154, j
|
||||
addi a5,a5,1 #, j_16, tmp154
|
||||
sw a5,-28(s0) # j_16, j
|
||||
loop_j_check:
|
||||
# primeFactors.c:18: for (j = 2; j <= i / 2; j++) // Iterate over j from 2 to i/2
|
||||
lw a5,-20(s0) # tmp155, i
|
||||
srli a4,a5,31 #, tmp156, tmp155
|
||||
add a5,a4,a5 # tmp155, tmp157, tmp156
|
||||
srai a5,a5,1 #, _1, tmp157
|
||||
mv a4,a5 # _1, _1
|
||||
# primeFactors.c:18: for (j = 2; j <= i / 2; j++) // Iterate over j from 2 to i/2
|
||||
lw a5,-28(s0) # tmp159, j
|
||||
ble a5,a4,i_mod_set #, tmp159, _1,
|
||||
prime_check:
|
||||
# primeFactors.c:31: if (isPrime == 1) // Print i if i is a prime number
|
||||
lw a4,-36(s0) # tmp160, isPrime
|
||||
li a5,1 # tmp161,
|
||||
bne a4,a5,loop_i_inc #, tmp160, tmp161,
|
||||
prime_set:
|
||||
# primeFactors.c:33: Prime = i; // Set variable Prime to the prime number. Used for printing in the TB upon change
|
||||
lw a7,-20(s0) # tmp162, i
|
||||
sw a7,-44(s0) # tmp162, Prime
|
||||
loop_i_inc:
|
||||
# primeFactors.c:8: for (i = 2; i <= Number; i++) // Iterate over i from 2 to Number, all possible numbers excluding 1 & 0
|
||||
lw a5,-20(s0) # tmp164, i
|
||||
addi a5,a5,1 #, i_20, tmp164
|
||||
sw a5,-20(s0) # i_20, i
|
||||
loop_i_check:
|
||||
# primeFactors.c:8: for (i = 2; i <= Number; i++) // Iterate over i from 2 to Number, all possible numbers excluding 1 & 0
|
||||
lw a4,-20(s0) # tmp165, i
|
||||
lw a5,-40(s0) # tmp166, Number
|
||||
ble a4,a5,num_mod_set #, tmp165, tmp166,
|
||||
return:
|
||||
# primeFactors.c:37: return 0; // return the main function and return 0 on success
|
||||
li a5,0 # _10,
|
||||
# primeFactors.c:38: }
|
||||
mv a0,a5 #, <retval>
|
||||
lw ra,44(sp) # Load the return address from the stack and store it in ra
|
||||
lw s0,40(sp) # Load the caller frame pointer value from the stack and store it in s0
|
||||
addi sp,sp,48 # Free the allocated stack space for the function call
|
||||
jr ra # Return to address stored in ra
|
||||
@@ -0,0 +1,115 @@
|
||||
// *********************************************************************************************
|
||||
// Description : Simplified assembly instructions for prime factors program
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 15.Oct.2025 by Hussein Elzomor
|
||||
// Last Modified : 21.Oct.2025 by Hussein Elzomor
|
||||
// -----
|
||||
// HISTORY : Date By Comments
|
||||
// ----------- --------- -------------------------------------------------
|
||||
// *********************************************************************************************
|
||||
|
||||
|
||||
|
||||
# 1 to 1 mapping of the Hex instructions in primeFactors.hex
|
||||
# Simplified version of primeFactors.s
|
||||
## Replaced pseudo instructions with the proper rv32i instructions
|
||||
## Replaced jumps to labels with address offset values
|
||||
|
||||
# Use as a cross reference to identify:
|
||||
## - the instruction being run on your processor
|
||||
## - which part of the program is being run
|
||||
## - confirm registers and memory addresses contain the correct data
|
||||
_start: # Hex # MemAddr(PC)
|
||||
lui x2 2 # 0x00002137 # 0x00000000
|
||||
addi x2 x2 -4 # 0xFFC10113 # 0x00000004
|
||||
jal x1 8 # 0x008000EF # 0x00000008
|
||||
halt:
|
||||
jal x0 0 # 0x0000006F # 0x0000000C
|
||||
main:
|
||||
addi x2 x2 -48 # 0xFD010113 # 0x00000010
|
||||
sw x1 44(x2) # 0x02112623 # 0x00000014
|
||||
sw x8 40(x2) # 0x02812423 # 0x00000018
|
||||
addi x8 x2 48 # 0x03010413 # 0x0000001C
|
||||
addi x15 x0 39 # 0x02700793 # 0x00000020 # Change the Number (39) to different values to test the program
|
||||
addi x16 x15 0 # 0x00078813 # 0x00000024 # Used for printing in the TB upon change
|
||||
sw x15 -40(x8) # 0xFCF42C23 # 0x00000028
|
||||
sw x0 -44(x8) # 0xFC042A23 # 0x0000002C
|
||||
loop_i_init:
|
||||
addi x15 x0 2 # 0x00200793 # 0x00000030
|
||||
sw x15 -20(x8) # 0xFEF42623 # 0x00000034
|
||||
jal x0 192 # 0x0C00006F # 0x00000038
|
||||
num_mod_set:
|
||||
lw x15 -40(x8) # 0xFD842783 # 0x0000003C
|
||||
sw x15 -32(x8) # 0xFEF42023 # 0x00000040
|
||||
jal x0 20 # 0x0140006F # 0x00000044
|
||||
num_mod_sub_i:
|
||||
lw x14 -32(x8) # 0xFE042703 # 0x00000048
|
||||
lw x15 -20(x8) # 0xFEC42783 # 0x0000004C
|
||||
sub x15 x14 x15 # 0x40F707B3 # 0x00000050
|
||||
sw x15 -32(x8) # 0xFEF42023 # 0x00000054
|
||||
num_mod_loop:
|
||||
lw x15 -32(x8) # 0xFE042783 # 0x00000058
|
||||
blt x0 x15 -20 # 0xFEF046E3 # 0x0000005C
|
||||
num_mod_check:
|
||||
lw x15 -32(x8) # 0xFE042783 # 0x00000060
|
||||
bne x15 x0 136 # 0x08079463 # 0x00000064
|
||||
addi x15 x0 1 # 0x00100793 # 0x00000068
|
||||
sw x15 -36(x8) # 0xFCF42E23 # 0x0000006C
|
||||
loop_j_init:
|
||||
addi x15 x0 2 # 0x00200793 # 0x00000070
|
||||
sw x15 -28(x8) # 0xFEF42223 # 0x00000074
|
||||
jal x0 68 # 0x0440006F # 0x00000078
|
||||
i_mod_set:
|
||||
lw x15 -20(x8) # 0xFEC42783 # 0x0000007C
|
||||
sw x15 -24(x8) # 0xFEF42423 # 0x00000080
|
||||
jal x0 20 # 0x0140006F # 0x00000084
|
||||
i_mod_sub_j:
|
||||
lw x14 -24(x8) # 0xFE842703 # 0x00000088
|
||||
lw x15 -28(x8) # 0xFE442783 # 0x0000008C
|
||||
sub x15 x14 x15 # 0x40F707B3 # 0x00000090
|
||||
sw x15 -24(x8) # 0xFEF42423 # 0x00000094
|
||||
i_mod_loop:
|
||||
lw x15 -24(x8) # 0xFE842783 # 0x00000098
|
||||
blt x0 x15 -20 # 0xFEF046E3 # 0x0000009C
|
||||
i_mod_check:
|
||||
lw x15 -24(x8) # 0xFE842783 # 0x000000A0
|
||||
bne x15 x0 12 # 0x00079663 # 0x000000A4
|
||||
sw x0 -36(x8) # 0xFC042E23 # 0x000000A8
|
||||
jal x0 44 # 0x02C0006F # 0x000000AC
|
||||
loop_j_inc:
|
||||
lw x15 -28(x8) # 0xFE442783 # 0x000000B0
|
||||
addi x15 x15 1 # 0x00178793 # 0x000000B4
|
||||
sw x15 -28(x8) # 0xFEF42223 # 0x000000B8
|
||||
loop_j_check:
|
||||
lw x15 -20(x8) # 0xFEC42783 # 0x000000BC
|
||||
srli x14 x15 31 # 0x01F7D713 # 0x000000C0
|
||||
add x15 x14 x15 # 0x00F707B3 # 0x000000C4
|
||||
srai x15 x15 1 # 0x4017D793 # 0x000000C8
|
||||
addi x14 x15 0 # 0x00078713 # 0x000000CC
|
||||
lw x15 -28(x8) # 0xFE442783 # 0x000000D0
|
||||
bge x14 x15 -88 # 0xFAF754E3 # 0x000000D4
|
||||
prime_check:
|
||||
lw x14 -36(x8) # 0xFDC42703 # 0x000000D8
|
||||
addi x15 x0 1 # 0x00100793 # 0x000000DC
|
||||
bne x14 x15 12 # 0x00F71663 # 0x000000E0
|
||||
prime_set:
|
||||
lw x17 -20(x8) # 0xFEC42883 # 0x000000E4
|
||||
sw x17 -44(x8) # 0xFD142A23 # 0x000000E8 # Used for printing in the TB upon change
|
||||
loop_i_inc:
|
||||
lw x15 -20(x8) # 0xFEC42783 # 0x000000EC
|
||||
addi x15 x15 1 # 0x00178793 # 0x000000F0
|
||||
sw x15 -20(x8) # 0xFEF42623 # 0x000000F4
|
||||
loop_i_check:
|
||||
lw x14 -20(x8) # 0xFEC42703 # 0x000000F8
|
||||
lw x15 -40(x8) # 0xFD842783 # 0x000000FC
|
||||
bge x15 x14 -196 # 0xF2E7DEE3 # 0x00000100
|
||||
return:
|
||||
addi x15 x0 0 # 0x00000793 # 0x00000104
|
||||
addi x10 x15 0 # 0x00078513 # 0x00000108
|
||||
lw x1 44(x2) # 0x02C12083 # 0x0000010C
|
||||
lw x8 40(x2) # 0x02812403 # 0x00000110
|
||||
addi x2 x2 48 # 0x03010113 # 0x00000114
|
||||
jalr x0 x1 0 # 0x00008067 # 0x00000118
|
||||
@@ -0,0 +1,18 @@
|
||||
// *********************************************************************************************
|
||||
// Project Version : v1.0
|
||||
// Project : [BCDC] Microtec Academy Course: Building a RISC-V CPU with SystemVerilog
|
||||
// -----
|
||||
// Copyright (c) : 2025 Fraunhofer IIS, Department IDS
|
||||
// Created : 12.Aug.2025 by Marcus Bednara
|
||||
// Last Modified : 01.Nov.2025 by Hussein Elzomor
|
||||
// ------
|
||||
// Notes : All ${}-variables must be provided by shell or Makefile {using export}
|
||||
// *********************************************************************************************
|
||||
|
||||
// Used with other compilers and simulators (eg. Icarus)
|
||||
hw/dv/rtl/pc_tb.sv
|
||||
hw/dv/rtl/reg_file_tb.sv
|
||||
hw/dv/rtl/alu_tb.sv
|
||||
hw/dv/rtl/main_mem_tb.sv
|
||||
hw/dv/rtl/decoder_tb.sv
|
||||
hw/dv/rtl/cpu_tb.sv
|
||||
@@ -0,0 +1,54 @@
|
||||
# do run.do
|
||||
# QuestaSim-64 vlog 2023.2 Compiler 2023.04 Apr 11 2023
|
||||
# Start time: 13:15:58 on Apr 29,2026
|
||||
# vlog -sv dummz_memgen_16.sv
|
||||
# -- Compiling module MemGen_16_10
|
||||
#
|
||||
# Top level modules:
|
||||
# MemGen_16_10
|
||||
# End time: 13:15:58 on Apr 29,2026, Elapsed time: 0:00:00
|
||||
# Errors: 0, Warnings: 0
|
||||
# QuestaSim-64 vlog 2023.2 Compiler 2023.04 Apr 11 2023
|
||||
# Start time: 13:15:58 on Apr 29,2026
|
||||
# vlog -sv -lint -pedanticerrors -f rtl_flist.f
|
||||
# -- Compiling module pc
|
||||
# -- Compiling module reg_file
|
||||
# -- Compiling module alu
|
||||
# -- Compiling module MemGen_32_11
|
||||
# -- Compiling module main_mem
|
||||
# -- Compiling module decoder
|
||||
# -- Compiling module cpu
|
||||
#
|
||||
# Top level modules:
|
||||
# cpu
|
||||
# End time: 13:15:58 on Apr 29,2026, Elapsed time: 0:00:00
|
||||
# Errors: 0, Warnings: 0
|
||||
# QuestaSim-64 vopt 2023.2 Compiler 2023.04 Apr 11 2023
|
||||
# ** Warning: (vopt-10587) Some optimizations are turned off because the +acc switch is in effect. This will cause your simulation to run slowly. Please use -access/-debug to maintain needed visibility.
|
||||
# Start time: 13:15:58 on Apr 29,2026
|
||||
# vopt work.cpu -o cpu_opt "+acc" -pedanticerrors
|
||||
#
|
||||
# Top level modules:
|
||||
# cpu
|
||||
#
|
||||
# Analyzing design...
|
||||
# -- Loading module cpu
|
||||
# -- Loading module decoder
|
||||
# -- Loading module alu
|
||||
# -- Loading module reg_file
|
||||
# -- Loading module pc
|
||||
# -- Loading module main_mem
|
||||
# -- Loading module MemGen_32_11
|
||||
# -- Loading module MemGen_16_10
|
||||
# Optimizing 8 design-units (inlining 0/11 module instances):
|
||||
# -- Optimizing module decoder(fast)
|
||||
# -- Optimizing module main_mem(fast)
|
||||
# -- Optimizing module MemGen_32_11(fast)
|
||||
# -- Optimizing module cpu(fast)
|
||||
# -- Optimizing module alu(fast)
|
||||
# -- Optimizing module MemGen_16_10(fast)
|
||||
# -- Optimizing module reg_file(fast)
|
||||
# -- Optimizing module pc(fast)
|
||||
# Optimized design name is cpu_opt
|
||||
# End time: 13:15:58 on Apr 29,2026, Elapsed time: 0:00:00
|
||||
# Errors: 0, Warnings: 1
|
||||
Binary file not shown.
@@ -0,0 +1,225 @@
|
||||
m255
|
||||
K4
|
||||
z2
|
||||
Z0 !s99 nomlopt
|
||||
!s11f vlog 2023.2 2023.04, Apr 11 2023
|
||||
13
|
||||
!s112 1.1
|
||||
!i10d 8192
|
||||
!i10e 25
|
||||
!i10f 100
|
||||
cModel Technology
|
||||
Z1 d/users/projekte/projekt01/RISC-V_w_RAM-Macros/riscv_rtl
|
||||
valu
|
||||
Z2 2hw/rtl/pc.sv|hw/rtl/reg_file.sv|hw/rtl/alu.sv|hw/rtl/MemGen_32_11.sv|hw/rtl/main_mem.sv|hw/rtl/decoder.sv|hw/rtl/cpu.sv
|
||||
Z3 DXx6 sv_std 3 std 0 22 9oUSJO;AeEaW`l:M@^WG92
|
||||
Z4 !s110 1777461358
|
||||
!i10b 1
|
||||
!s100 c7@e^4VRKhKUEEThRE>IL3
|
||||
IRF@[`@^VS_z[3JdlC^jk?0
|
||||
S1
|
||||
R1
|
||||
w1776171120
|
||||
8hw/rtl/alu.sv
|
||||
Fhw/rtl/alu.sv
|
||||
!i122 1
|
||||
L0 16 37
|
||||
Z5 VDg1SIo80bB@j0V0VzS_@n1
|
||||
Z6 OL;L;2023.2;77
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
Z7 !s108 1777461358.000000
|
||||
Z8 !s107 hw/rtl/cpu.sv|hw/rtl/decoder.sv|hw/rtl/main_mem.sv|hw/rtl/MemGen_32_11.sv|hw/rtl/alu.sv|hw/rtl/reg_file.sv|hw/rtl/pc.sv|
|
||||
Z9 !s90 -sv|-lint|-pedanticerrors|-f|rtl_flist.f|
|
||||
!i113 0
|
||||
Z10 o-sv -lint -pedanticerrors -L mtiAvm -L mtiRnm -L mtiOvm -L mtiUvm -L mtiUPF -L infact
|
||||
Z11 tCvgOpt 0
|
||||
vcpu
|
||||
R2
|
||||
R3
|
||||
R4
|
||||
!i10b 1
|
||||
!s100 W5YnilUcQ_V2@UXTF:=cJ3
|
||||
I8K0<ghgJc_YmR85lXGmfW2
|
||||
S1
|
||||
R1
|
||||
w1777460652
|
||||
8hw/rtl/cpu.sv
|
||||
Fhw/rtl/cpu.sv
|
||||
!i122 1
|
||||
L0 17 119
|
||||
R5
|
||||
R6
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
R7
|
||||
R8
|
||||
R9
|
||||
!i113 0
|
||||
R10
|
||||
R11
|
||||
Tcpu_opt
|
||||
R4
|
||||
VhhLfkMWVfM1`i62Kl8@Je0
|
||||
04 3 4 work cpu fast 0
|
||||
R0
|
||||
!s12b OEM100
|
||||
!s124 OEM100
|
||||
o+acc -pedanticerrors
|
||||
R11
|
||||
ncpu_opt
|
||||
OL;O;2023.2;77
|
||||
vdecoder
|
||||
R2
|
||||
R3
|
||||
R4
|
||||
!i10b 1
|
||||
!s100 AOnRIdeRg<F25LRRU`T272
|
||||
IaNl5h1BRE2bJmKaFRHz422
|
||||
S1
|
||||
R1
|
||||
w1776171111
|
||||
8hw/rtl/decoder.sv
|
||||
Fhw/rtl/decoder.sv
|
||||
!i122 1
|
||||
L0 17 215
|
||||
R5
|
||||
R6
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
R7
|
||||
R8
|
||||
R9
|
||||
!i113 0
|
||||
R10
|
||||
R11
|
||||
vmain_mem
|
||||
R2
|
||||
R3
|
||||
R4
|
||||
!i10b 1
|
||||
!s100 zFWP0WekD3ahknY:;hE0d0
|
||||
ImPQ<dTThbd9MfP8A0fM:Y0
|
||||
S1
|
||||
R1
|
||||
w1777461330
|
||||
8hw/rtl/main_mem.sv
|
||||
Fhw/rtl/main_mem.sv
|
||||
!i122 1
|
||||
L0 18 124
|
||||
R5
|
||||
R6
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
R7
|
||||
R8
|
||||
R9
|
||||
!i113 0
|
||||
R10
|
||||
R11
|
||||
vMemGen_16_10
|
||||
2dummz_memgen_16.sv
|
||||
R3
|
||||
R4
|
||||
!i10b 1
|
||||
!s100 3g9X:cJgHARa6i>UGGAJE3
|
||||
IlkV3GA3k<Qo5fKa2S4a;z2
|
||||
S1
|
||||
R1
|
||||
w1777456118
|
||||
8dummz_memgen_16.sv
|
||||
Fdummz_memgen_16.sv
|
||||
!i122 0
|
||||
L0 3 23
|
||||
R5
|
||||
R6
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
R7
|
||||
!s107 dummz_memgen_16.sv|
|
||||
!s90 -sv|dummz_memgen_16.sv|
|
||||
!i113 0
|
||||
o-sv -L mtiAvm -L mtiRnm -L mtiOvm -L mtiUvm -L mtiUPF -L infact
|
||||
R11
|
||||
n@mem@gen_16_10
|
||||
vMemGen_32_11
|
||||
R2
|
||||
R3
|
||||
R4
|
||||
!i10b 1
|
||||
!s100 5Kmn;aKb?_?9odF;mHmin0
|
||||
IIUohGZYIVMNhbBKdRFQgN3
|
||||
S1
|
||||
R1
|
||||
w1776876080
|
||||
8hw/rtl/MemGen_32_11.sv
|
||||
Fhw/rtl/MemGen_32_11.sv
|
||||
!i122 1
|
||||
L0 1 60
|
||||
R5
|
||||
R6
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
R7
|
||||
R8
|
||||
R9
|
||||
!i113 0
|
||||
R10
|
||||
R11
|
||||
n@mem@gen_32_11
|
||||
vpc
|
||||
R2
|
||||
R3
|
||||
R4
|
||||
!i10b 1
|
||||
!s100 W^9[[M8gg5o`cM5a_7zD73
|
||||
IfHzX^39KF<jCoSBK5L:Uf3
|
||||
S1
|
||||
R1
|
||||
w1776171082
|
||||
8hw/rtl/pc.sv
|
||||
Fhw/rtl/pc.sv
|
||||
!i122 1
|
||||
L0 16 22
|
||||
R5
|
||||
R6
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
R7
|
||||
R8
|
||||
R9
|
||||
!i113 0
|
||||
R10
|
||||
R11
|
||||
vreg_file
|
||||
R2
|
||||
R3
|
||||
R4
|
||||
!i10b 1
|
||||
!s100 oU`11E]G7DY0zAjMP;e=Q3
|
||||
IU`bM2NHiVnC`Diga59:4A0
|
||||
S1
|
||||
R1
|
||||
w1776171101
|
||||
8hw/rtl/reg_file.sv
|
||||
Fhw/rtl/reg_file.sv
|
||||
!i122 1
|
||||
L0 15 30
|
||||
R5
|
||||
R6
|
||||
r1
|
||||
!s85 0
|
||||
31
|
||||
R7
|
||||
R8
|
||||
R9
|
||||
!i113 0
|
||||
R10
|
||||
R11
|
||||
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user