diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml deleted file mode 100644 index 012ae92..0000000 --- a/.github/workflows/ci.yml +++ /dev/null @@ -1,52 +0,0 @@ -name: Run compliance test suite - -on: [push, pull_request] - -jobs: - compliance: - name: RISC-V Compliance Test - runs-on: ubuntu-22.04 - - steps: - - uses: actions/checkout@v4 - with: - path: serv - - - name: install fusesoc, verilator, gcc and riscof - run: | - sudo apt-get install -y python3-setuptools verilator - pip3 install fusesoc - pip3 install riscof - wget -qO- https://github.com/riscv-collab/riscv-gnu-toolchain/releases/download/2023.07.05/riscv64-elf-ubuntu-22.04-gcc-nightly-2023.07.05-nightly.tar.gz | tar xz - echo $GITHUB_WORKSPACE/riscv/bin >> $GITHUB_PATH - - - - name: set root and SERV directory - run: | - echo "SERV=$GITHUB_WORKSPACE/serv" >> $GITHUB_ENV - - - name: setup workspace - run: fusesoc library add serv $SERV - - - name: Setup SAIL-RISCV Model - run: | - tar -xzf $SERV/verif/bin/sail-riscv.tar.gz - echo $GITHUB_WORKSPACE/sail-riscv >> $GITHUB_PATH - - - name: Init arch tests - run: riscof arch-test --clone - - - name: Run RV32I compliance tests - run: riscof run --config=$SERV/verif/config.ini --suite=riscv-arch-test/riscv-test-suite/rv32i_m/I --env=riscv-arch-test/riscv-test-suite/env --no-browser - - - name: Run RV32IM compliance tests - run: riscof run --config=$SERV/verif/config.ini --suite=riscv-arch-test/riscv-test-suite/rv32i_m/M --env=riscv-arch-test/riscv-test-suite/env --no-browser - - - name: Run RV32IC compliance tests - run: riscof run --config=$SERV/verif/config.ini --suite=riscv-arch-test/riscv-test-suite/rv32i_m/C --env=riscv-arch-test/riscv-test-suite/env --no-browser - - - name: Run RV32I Zifencei compliance tests - run: riscof run --config=$SERV/verif/config.ini --suite=riscv-arch-test/riscv-test-suite/rv32i_m/Zifencei --env=riscv-arch-test/riscv-test-suite/env --no-browser - - - name: Run RV32I Privilege compliance tests - run: riscof run --config=$SERV/verif/config.ini --suite=riscv-arch-test/riscv-test-suite/rv32i_m/privilege --env=riscv-arch-test/riscv-test-suite/env --no-browser diff --git a/.github/workflows/formal.yml b/.github/workflows/formal.yml deleted file mode 100644 index 37425a3..0000000 --- a/.github/workflows/formal.yml +++ /dev/null @@ -1,67 +0,0 @@ -name: Formal verification - -on: [push] -jobs: - formal: - name: Run RISCV-formal verification suite - runs-on: ubuntu-latest - steps: - - name: Checkout riscv-formal - uses: actions/checkout@v4 - with: - repository: YosysHQ/riscv-formal - - name: Checkout SERV - uses: actions/checkout@v4 - with: - path: cores/serv/serv-src - - uses: YosysHQ/setup-oss-cad-suite@v3 - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - name: Prepare formal tests - run: | - cd cores/serv - python3 ../../checks/genchecks.py -# Skip non-instruction tests for now -# - run: make -C cores/serv/checks causal_ch0 -# - run: make -C cores/serv/checks liveness_ch0 -# - run: make -C cores/serv/checks pc_bwd_ch0 -# - run: make -C cores/serv/checks pc_fwd_ch0 -# - run: make -C cores/serv/checks reg_ch0 -# - run: make -C cores/serv/checks unique_ch0 - - run: make -C cores/serv/checks insn_add_ch0 - - run: make -C cores/serv/checks insn_addi_ch0 - - run: make -C cores/serv/checks insn_and_ch0 - - run: make -C cores/serv/checks insn_andi_ch0 - - run: make -C cores/serv/checks insn_auipc_ch0 - - run: make -C cores/serv/checks insn_beq_ch0 - - run: make -C cores/serv/checks insn_bge_ch0 - - run: make -C cores/serv/checks insn_bgeu_ch0 - - run: make -C cores/serv/checks insn_blt_ch0 - - run: make -C cores/serv/checks insn_bltu_ch0 - - run: make -C cores/serv/checks insn_bne_ch0 - - run: make -C cores/serv/checks insn_jal_ch0 - - run: make -C cores/serv/checks insn_jalr_ch0 - - run: make -C cores/serv/checks insn_lb_ch0 - - run: make -C cores/serv/checks insn_lbu_ch0 - - run: make -C cores/serv/checks insn_lh_ch0 - - run: make -C cores/serv/checks insn_lhu_ch0 - - run: make -C cores/serv/checks insn_lui_ch0 - - run: make -C cores/serv/checks insn_lw_ch0 - - run: make -C cores/serv/checks insn_or_ch0 - - run: make -C cores/serv/checks insn_ori_ch0 - - run: make -C cores/serv/checks insn_sb_ch0 - - run: make -C cores/serv/checks insn_sh_ch0 - - run: make -C cores/serv/checks insn_sll_ch0 - - run: make -C cores/serv/checks insn_slli_ch0 - - run: make -C cores/serv/checks insn_slt_ch0 - - run: make -C cores/serv/checks insn_slti_ch0 - - run: make -C cores/serv/checks insn_sltiu_ch0 - - run: make -C cores/serv/checks insn_sltu_ch0 - - run: make -C cores/serv/checks insn_sra_ch0 - - run: make -C cores/serv/checks insn_srai_ch0 - - run: make -C cores/serv/checks insn_srl_ch0 - - run: make -C cores/serv/checks insn_srli_ch0 - - run: make -C cores/serv/checks insn_sub_ch0 - - run: make -C cores/serv/checks insn_sw_ch0 - - run: make -C cores/serv/checks insn_xor_ch0 - - run: make -C cores/serv/checks insn_xori_ch0 diff --git a/.github/workflows/lint.yml b/.github/workflows/lint.yml deleted file mode 100644 index 46cd656..0000000 --- a/.github/workflows/lint.yml +++ /dev/null @@ -1,22 +0,0 @@ -name: Run linter - -on: [push, pull_request] - -jobs: - lint: - runs-on: ubuntu-latest - name: Linter - env: - REPO : serv - VLNV : serv - steps: - - name: Checkout repo - uses: actions/checkout@v4 - with: - path: serv - - run: sudo apt install verilator - - run: pip3 install fusesoc - - run: fusesoc library add $REPO $GITHUB_WORKSPACE/$REPO - - run: fusesoc run --target=lint $VLNV - - run: fusesoc run --target=lint servant - - run: fusesoc run --target=lint serving diff --git a/.github/workflows/openlane.yml b/.github/workflows/openlane.yml deleted file mode 100644 index ab069c6..0000000 --- a/.github/workflows/openlane.yml +++ /dev/null @@ -1,24 +0,0 @@ -name: Build GDS using OpenLANE and sky130 PDK - -on: [push] -jobs: - build-openlane-sky130: - runs-on: ubuntu-latest - env: - REPO : serv - VLNV : serv - steps: - - name: Checkout repo - uses: actions/checkout@v4 - with: - path: serv - - run: echo "EDALIZE_LAUNCHER=el_docker" >> $GITHUB_ENV - - run: pip3 install fusesoc - - run: fusesoc library add $REPO $GITHUB_WORKSPACE/$REPO - - run: fusesoc run --target=sky130 $VLNV - - run: find -name *.gds - - name: Store artifacts - uses: actions/upload-artifact@v4 - with: - name: serv.gds - path: /home/runner/work/serv/serv/serv/build/serv_1.3.0/sky130-openlane/runs/serv_synth_wrapper/results/final/gds/serv_synth_wrapper.gds diff --git a/.github/workflows/pages.yml b/.github/workflows/pages.yml deleted file mode 100644 index f1d0181..0000000 --- a/.github/workflows/pages.yml +++ /dev/null @@ -1,28 +0,0 @@ -name: Build documentation - -on: - push: - branches: - - master - -jobs: - docs: - name: Build documentation - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@v4 - - name: Set up Python - uses: actions/setup-python@v1 - - name: Install dependencies - run: | - python3 -m pip install --upgrade pip - pip install -r doc/requirements.txt - - name: Build sphinx documentation - run: | - make -C doc html - - name: Deploy to gh-pages - uses: JamesIves/github-pages-deploy-action@4.1.1 - with: - branch: gh-pages # The branch the action should deploy to. - folder: doc/_build/html # The folder the action should deploy. diff --git a/.gitmodules b/.gitmodules index e69de29..ef0a528 100644 --- a/.gitmodules +++ b/.gitmodules @@ -0,0 +1,4 @@ +[submodule "zephyr"] + path = zephyr + url = https://github.com/olofk/zephyr + branch = serv diff --git a/.readthedocs.yml b/.readthedocs.yml deleted file mode 100644 index 953a327..0000000 --- a/.readthedocs.yml +++ /dev/null @@ -1,16 +0,0 @@ -# Read the Docs configuration file -# See https://docs.readthedocs.io/en/stable/config-file/v2.html for details - -version: 2 - -sphinx: - configuration: doc/conf.py - -python: - install: - - requirements: doc/requirements.txt - -build: - os: "ubuntu-22.04" - tools: - python: "3.11" diff --git a/NEWS b/NEWS deleted file mode 100644 index b2cf95a..0000000 --- a/NEWS +++ /dev/null @@ -1,38 +0,0 @@ -1.3.0 2024-07-05 Olof Kindgren -====================================================== - -* Zephyr BSP: Port to Zephyr 3.5.0 + support tickless timer -* Make RF RAM IF work with single-port RAM -* Add PC tracing -* Make most modules width-independent -* Avoid releasing trap signal too early -* Improve timer wraparound behavior -* Overhaul documentation -* Add Servile convenience wrapper component -* Base Serving and Serving on Servile -* Add simulation cycle counter to testbench -* Add Hello world ASM example for Servant -* New Servant ports: Arty S7-50, PolarFire Splash Kit, Machdyne Kolibri, GMM-7550, Alchistry AU, ECP5 Evaluation board, Terasic DE1 SoC - -1.2.1 2022-12-25 Olof Kindgren -====================================================== - -* Guarantee at least 2 cycles of o_rst after ice40 PLL is locked -* New Servant ports: ICE-V Wireless -* Add reset input for Arty A7 -* Add Servant documentation -* Updated RISC-V Compliance support from 2.7.4 to 3.x - -1.2.0 2022-07-25 Olof Kindgren -====================================================== - -* New Servant ports: EBAZ4205, Chameleon96, Nexys2, Alinx AX309 -* Support for M ISA extension -* Support for C ISA extension -* Fix occasionally wrong sign on immediates -* Support for producing GDS with OpenLANE -* Fix Model/QuestaSim compatibility -* Add ViDBo support -* Improved documentation -* Less resource usage -* Updated RISC-V Compliance support from 1.0 to 2.7.4 diff --git a/README.md b/README.md index e8680cf..fdcc38e 100644 --- a/README.md +++ b/README.md @@ -2,139 +2,113 @@ # SERV -[![Join the chat at https://gitter.im/librecores/serv](https://badges.gitter.im/librecores/serv.svg)](https://gitter.im/librecores/serv?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) -[![Compliance tests](https://github.com/olofk/serv/actions/workflows/ci.yml/badge.svg)](https://github.com/olofk/serv/actions/workflows/ci.yml) -[![Documentation Status](https://readthedocs.org/projects/serv/badge/?version=latest)](https://serv.readthedocs.io/en/latest/?badge=latest) - SERV is an award-winning bit-serial RISC-V core -In fact, the award-winning SERV is the world's smallest RISC-V CPU. It's the perfect companion whenever you need a bit of computation and silicon real estate is at a premium. +## Prerequisites -How small is it then? Synthesizing the latest version of SERV in its most minimal form, yields the following results for some popular FPGA architectures and a typical CMOS process. +Create a directory to keep all the different parts of the project together. We +will refer to this directory as `$SERV` from now on. -| Lattice iCE40 | Intel Cyclone 10LP | AMD Artix-7 | CMOS | -| ------------- | ------------------ | ----------- | ------ | -| 198 LUT | 239 LUT | 125 LUT | 2.1kGE | -| 164 FF | 164 FF | 164 FF | | +Download the main serv repo +`cd $SERV && git clone https://github.com/olofk/serv` -If you want to know more about SERV, what a bit-serial CPU is and what it's good for, I recommend starting out by watching the fantastic short SERV movies -* [introduction to SERV](https://www.award-winning.me/serv-introduction/) -* [SERV : RISC-V for a fistful of gates](https://www.award-winning.me/serv-for-a-fistful-of-gates/) -* [SERV: 32-bit is the New 8-bit](https://www.award-winning.me/serv-32-bit-is-the-new-8-bit/) -* [Bit by bit - How to fit 8 RISC V cores in a $38 FPGA board (presentation from the Zürich 2019 RISC-V workshop)](https://www.youtube.com/watch?v=xjIxORBRaeQ) +Install FuseSoC -All SERV videos and more can also be found [here](https://www.award-winning.me/videos/). +`pip install fusesoc` -Apart from being the world's smallest RISC-V CPU, SERV also aims at being the best documented RISC-V CPU. For this there is an official [SERV user manual](https://serv.readthedocs.io/en/latest/#) with block diagrams that are correct to the gate-level, cycle-accurate timing diagrams and an in-depth description of how things work. +Initialize the FuseSoC standard libraries -## Systems using SERV +`fusesoc init` -SERV can be easily integrated into any design, but if you are looking at just quickly trying it out, here is a list of some systems that are already using SERV: +Create a workspace directory for FuseSoC -[Servant](https://serv.readthedocs.io/en/latest/servant.html) is the reference platform for SERV. It is a very basic SoC that contains just enough runs Zephyr RTOS. Servant is intended for FPGAs and has been ported to around 20 different FPGA boards. It is also used to run the RISC-V regression test suite. +`mkdir $SERV/workspace` -[CoreScore](https://corescore.store/) is an award-giving benchmark for FPGAs and their synthesis/P&R tools. It tests how many SERV cores that can be put into a particular FPGA. +Register the serv repo as a core library -[Observer](https://github.com/olofk/observer) is a configurable and software-programmable sensor aggregation platform for heterogeneous sensors. +`cd $SERV/workspace && fusesoc library add serv $SERV` -[Subservient](https://github.com/olofk/subservient/) is a small technology-independent SERV-based SoC intended for ASIC implementations together with a single-port SRAM. +Check that the CPU passes the linter -[Litex](https://github.com/enjoy-digital/litex) is a Python-based framework for creating FPGA SoCs. SERV is one of the 30+ supported cores. A Litex-generated SoC has been used to run DooM on SERV. +`cd $SERV/workspace && fusesoc run --target=lint serv` - - - -## Getting started - -:o: Create a root directory to keep all the different parts of the project together. We -will refer to this directory as `$WORKSPACE` from now on. - - $ export WORKSPACE=$(pwd) - -All the following commands will be run from this directory unless otherwise stated. -- Install FuseSoC - - $ pip install fusesoc -- Add the FuseSoC standard library - - $ fusesoc library add fusesoc_cores https://github.com/fusesoc/fusesoc-cores -- The FuseSoC standard library already contain a version of SERV, but if we want to make changes to SERV, run the bundled example or use the Zephyr support, it is better to add SERV as a separate library into the workspace - - - $ fusesoc library add serv https://github.com/olofk/serv - >:warning: The SERV repo will now be available in `$WORKSPACE/fusesoc_libraries/serv`. We will refer to that directory as `$SERV`. -- Install latest version of [Verilator](https://www.veripool.org/wiki/verilator) -- (Optional) To support RISC-V M-extension extension, Multiplication and Division unit (MDU) can be added included into the SERV as a separate library. - - $ fusesoc library add mdu https://github.com/zeeshanrafique23/mdu - MDU will be available in `$WORKSPACE/fusesoc_libraries/mdu` - -We are now ready to do our first exercises with SERV. If everything above is done correctly,we can use Verilator as a linter to check the SERV source code. - - $ fusesoc run --target=lint serv - -If everything worked, the output should look like - - INFO: Preparing ::serv:1.3.0 - INFO: Setting up project - - INFO: Building simulation model - INFO: Running - -After performing all the steps that are mentioned above, the directory structure from the `$WORKSPACE` should look like this: - - . - $WORKSPACE - | - ├── build - │   └── ... - ├── fusesoc.conf - └── fusesoc_libraries -    ├── fusesoc_cores -    │   └── ... -    ├── mdu -    │   └── ... -    └── serv -    └── ... - - -## Running pre-built test software +## Running test software Build and run the single threaded zephyr hello world example with verilator (should be stopped with Ctrl-C): - fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_hello.hex + cd $SERV/workspace + fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/serv/sw/zephyr_hello.hex ..or... the multithreaded version - fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_hello_mt.hex --memsize=16384 + fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/serv/sw/zephyr_hello_mt.hex --memsize=16384 -Both should yield an output ending with +...or... the philosophers example - ***** Booting Zephyr OS zephyr-v1.14.1-4-gc7c2d62513fe ***** - Hello World! service - -For a more advanced example, we can also run the Dining philosophers demo - - fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_phil.hex --memsize=32768 + fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/serv/sw/zephyr_phil.hex --memsize=32768 ...or... the synchronization example - fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_sync.hex --memsize=16384 + fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=$SERV/serv/sw/zephyr_sync.hex --memsize=16384 -...or... the blinky example (note that the ```uart_baudrate``` should not be defined for the blinky test) +Other applications can be tested by compiling and converting to bin and then hex e.g. with makehex.py found in `$SERV/serv/riscv-target/serv` - fusesoc run --target=verilator_tb servant --firmware=$SERV/sw/blinky.hex --memsize=16384 +## Run the compliance tests +Build the verilator model (if not already done) +`cd $SERV/workspace && fusesoc run --target=verilator_tb --setup --build servant` -If the [toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) is installed, other applications can be tested by compiling the assembly program and converting to bin and then hex with makehex.py found in [`$SERV/sw`](/sw/). +Download the tests repo -:bulb:RISC-V Compressed Extension can be enabled by passing `--compressed=1` parameter. +`cd $SERV && git clone https://github.com/riscv/riscv-compliance` -## Verification -SERV is verified using RISC-V compliance tests for the base ISA (RV32I) and the implemented extensions (M, C, Zicsr). The instructions on running Compliance tests using RISCOF framework are given in [verif](/verif/) directory. +Run the compliance tests +`cd $SERV/riscv-compliance && make TARGETDIR=$SERV/serv/riscv-target RISCV_TARGET=serv RISCV_DECICE=rv32i RISCV_ISA=rv32i TARGET_SIM=$SERV/workspace/build/serv_0/verilator_tb-verilator/Vserv_wrapper` + +## Run on hardware + +Only supported so far is a single threaded Zephyr hello world example on the icebreaker tinyFPGA BX and arty A7 35T boards. Some +packages should be installed before running it (and shoud be accessible in your PATH variable): +- [icestorm](https://github.com/cliffordwolf/icestorm). +- [nextpnr](https://github.com/YosysHQ/nextpnr). + +And do not forget to add fusesoc-cores in your fusesoc lib : +- locally: +``` + fusesoc library add fusesoc-cores https://github.com/fusesoc/fusesoc-cores +``` +- globally: +``` + fusesoc library add --global fusesoc-cores https://github.com/fusesoc/fusesoc-cores +``` + +Run with `--memfile=$SERV/sw/blinky.hex` as the last argument to run the LED blink example instead of hello world. + +### TinyFPGA BX + +Pin A6 is used for UART output with 115200 baud rate. + + cd $SERV/workspace + fusesoc run --target=tinyfpga_bx servant + tinyprog --program build/serv_0/tinyfpga_bx-icestorm/serv_0.bin + +### Icebreaker + +Pin 9 is used for UART output with 57600 baud rate. + + cd $SERV/workspace + fusesoc run --target=icebreaker servant + +### Arty A7 35T + +Pin D10 (uart_rxd_out) is used for UART output with 57600 baud rate (to use +blinky.hex change D10 to H5 (led[4]) in data/arty_a7_35t.xdc). + + cd $SERV/workspace + fusesoc run --target=arty_a7_35t servant ## Other targets @@ -154,42 +128,7 @@ This will synthesize for the default Vivado part. To synthesise for a specific d fusesoc run --tool=vivado serv --pnr=none --part=xc7a100tcsg324-1 -## Zephyr support - -SERV, or rather the Servant SoC, can run the [Zephyr RTOS](https://www.zephyrproject.org). The Servant-specific drivers and BSP is located in the zephyr subdirectory of the SERV repository. In order to use Zephyr on Servant, a project directory structure must be set up that allows Zephyr to load the Servant-specific files as a module. - -First, the Zephyr SDK and the "west" build tool must be installed. The [Zephyr getting started guide](https://docs.zephyrproject.org/latest/getting_started/index.html) describes these steps in more detail. - -Assuming that SERV was installed into `$WORKSPACE/fusesoc_libraries/serv` as per the prerequisites, run the following command to make the workspace also work as a Zephyr workspace. - - west init - -Specify the SERV repository as the manifest repository, meaning it will be the main entry point when Zephyr is looking for modules. - - west config manifest.path $SERV - -Get the right versions of all Zephyr submodules - - west update - -It should now be possible to build Zephyr applications for the Servant SoC within the workspace. This can be tested e.g. by building the Zephyr Hello world samples application - - cd zephyr/samples/hello_world - west build -b service - -After a successful build, Zephyr will create an elf and a bin file of the application in `build/zephyr/zephyr.{elf,bin}`. The bin file can be converted to a verilog hex file, which in turn can be preloaded to FPGA on-chip memories and run on a target board, or loaded into simulated RAM model when running simulations. - -To convert the newly built hello world example into a Verilog hex file, run - - python3 $SERV/sw/makehex.py zephyr/samples/hello_world/build/zephyr/zephyr.bin 4096 > hello.hex - -4096 is the number of 32-bit words to write and must be at least the size of the application binary. `hello.hex` is the resulting hex file. Running a simulation can now be done as described in [Running pre-built test software](#running-pre-built-test-software), e.g. - - fusesoc run --target=verilator_tb servant --uart_baudrate=57600 --firmware=/path/to/hello.hex - -Or to create an FPGA image with the application preloaded to on-chip RAM, e.g. for a Nexys A7 board, run - - fusesoc run --target=nexys_a7 servant --memfile=/path/to/hello.hex +At the time of writing, only the icestorm and vivado backends support running synthesis only. ## Good to know @@ -198,3 +137,9 @@ Don't feed serv any illegal instructions after midnight. Many logic expressions The bus interface is kind of Wishbone, but with most signals removed. There's an important difference though. Don't send acks on the instruction or data buses unless serv explicitly asks for something by raising its cyc signal. Otherwise serv becomes very confused. Don't go changing the clock frequency on a whim when running Zephyr. Or well, it's ok I guess, but since the UART is bitbanged, this will change the baud rate as well. As of writing, the UART is running at 115200 baud rate when the CPU is 32 MHz. There are two NOPs in the driver to slow it down a bit, so if those are removed I think it could achieve baud rate 115200 on a 24MHz clock.. in case someone wants to try + +## TODO + +- Applications have to be preloaded to RAM at compile-time +- Store bootloader and register file together in a RAM +- Make it faster and smaller diff --git a/bench/servant_sim.v b/bench/servant_sim.v index 2317279..64da239 100644 --- a/bench/servant_sim.v +++ b/bench/servant_sim.v @@ -1,17 +1,12 @@ `default_nettype none module servant_sim - (input wire wb_clk, - input wire wb_rst, - output wire [31:0] pc_adr, - output wire pc_vld, - output wire q); + (input wire wb_clk, + input wire wb_rst, + output wire q); parameter memfile = ""; parameter memsize = 8192; - parameter width = 1; parameter with_csr = 1; - parameter compressed = 0; - parameter align = compressed; reg [1023:0] firmware_file; initial @@ -23,15 +18,8 @@ module servant_sim servant #(.memfile (memfile), .memsize (memsize), - .width (width), - .debug (1'b1), .sim (1), - .with_csr (with_csr), - .compress (compressed[0:0]), - .align (align[0:0])) + .with_csr (with_csr)) dut(wb_clk, wb_rst, q); - assign pc_adr = dut.wb_mem_adr; - assign pc_vld = dut.wb_mem_ack; - endmodule diff --git a/bench/servant_tb.cpp b/bench/servant_tb.cpp index 92a56b9..b8f294a 100644 --- a/bench/servant_tb.cpp +++ b/bench/servant_tb.cpp @@ -1,12 +1,9 @@ -#include #include #include #include "verilated_vcd_c.h" #include "Vservant_sim.h" -#include - using namespace std; static bool done; @@ -22,8 +19,8 @@ double sc_time_stamp () { // Called by $time in Verilog void INThandler(int signal) { - printf("\nCaught ctrl-c\n"); - done = true; + printf("\nCaught ctrl-c\n"); + done = true; } typedef struct { @@ -49,7 +46,7 @@ void uart_init(uart_context_t *context, uint32_t baud_rate) { context->state = 0; } -bool do_uart(uart_context_t *context, bool rx) { +void do_uart(uart_context_t *context, bool rx) { if (context->state == 0) { if (rx) context->state++; @@ -77,104 +74,80 @@ bool do_uart(uart_context_t *context, bool rx) { else { if (main_time > context->last_update) { context->last_update += context->baud_t; + putchar(context->ch); context->state=1; - return true; } } - return false; } int main(int argc, char **argv, char **env) { - int baud_rate = 0; + vluint64_t sample_time = 0; + uint32_t insn = 0; + uint32_t ex_pc = 0; + int baud_rate = 0; - gpio_context_t gpio_context; - uart_context_t uart_context; - Verilated::commandArgs(argc, argv); + gpio_context_t gpio_context; + uart_context_t uart_context; + Verilated::commandArgs(argc, argv); - Vservant_sim* top = new Vservant_sim; + Vservant_sim* top = new Vservant_sim; - const char *arg = Verilated::commandArgsPlusMatch("uart_baudrate="); - if (arg[0]) { - baud_rate = atoi(arg+15); - if (baud_rate) { - uart_init(&uart_context, baud_rate); - } - } + const char *arg = Verilated::commandArgsPlusMatch("uart_baudrate="); + if (arg[0]) { + baud_rate = atoi(arg+15); + if (baud_rate) { + uart_init(&uart_context, baud_rate); + } + } - VerilatedVcdC * tfp = 0; - const char *vcd = Verilated::commandArgsPlusMatch("vcd="); - if (vcd[0]) { - Verilated::traceEverOn(true); - tfp = new VerilatedVcdC; - top->trace (tfp, 99); - tfp->open ("trace.vcd"); - } + VerilatedVcdC * tfp = 0; + const char *vcd = Verilated::commandArgsPlusMatch("vcd="); + if (vcd[0]) { + Verilated::traceEverOn(true); + tfp = new VerilatedVcdC; + top->trace (tfp, 99); + tfp->open ("trace.vcd"); + } - signal(SIGINT, INThandler); + signal(SIGINT, INThandler); - int tf = 0; - const char *arg_trace_pc = Verilated::commandArgsPlusMatch("trace_pc="); - if (arg_trace_pc[0]) - tf = open("trace.bin", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + vluint64_t timeout = 0; + const char *arg_timeout = Verilated::commandArgsPlusMatch("timeout="); + if (arg_timeout[0]) + timeout = atoi(arg_timeout+9); - vluint64_t timeout = 0; - const char *arg_timeout = Verilated::commandArgsPlusMatch("timeout="); - if (arg_timeout[0]) - timeout = atoi(arg_timeout+9); + vluint64_t vcd_start = 0; + const char *arg_vcd_start = Verilated::commandArgsPlusMatch("vcd_start="); + if (arg_vcd_start[0]) + vcd_start = atoi(arg_vcd_start+11); - vluint64_t vcd_start = 0; - const char *arg_vcd_start = Verilated::commandArgsPlusMatch("vcd_start="); - if (arg_vcd_start[0]) - vcd_start = atoi(arg_vcd_start+11); + bool dump = false; + top->wb_clk = 1; + bool q = top->q; + while (!(done || Verilated::gotFinish())) { + if (tfp && !dump && (main_time > vcd_start)) { + dump = true; + } + top->wb_rst = main_time < 100; + top->eval(); + if (dump) + tfp->dump(main_time); + if (baud_rate) + do_uart(&uart_context, top->q); + else + do_gpio(&gpio_context, top->q); - int cur_cycle = 0; - int last_cycle = 0; - std::time_t last_time = std::time(nullptr); - int cps_file = 0; - const char *arg_cps = Verilated::commandArgsPlusMatch("cps="); - if (arg_cps[0]) - cps_file = open("cps", O_WRONLY | O_CREAT | O_TRUNC, S_IRWXU); + if (timeout && (main_time >= timeout)) { + printf("Timeout: Exiting at time %lu\n", main_time); + done = true; + } - bool dump = false; - top->wb_clk = 1; - bool q = top->q; - while (!(done || Verilated::gotFinish())) { - if (tfp && !dump && (main_time > vcd_start)) { - dump = true; - } - top->wb_rst = main_time < 100; - top->eval(); - if (dump) - tfp->dump(main_time); - if (baud_rate) { - if (do_uart(&uart_context, top->q)) - putchar(uart_context.ch); - } else { - do_gpio(&gpio_context, top->q); - } - if (tf && top->wb_clk && top->pc_vld) - if (write(tf, (void *)&top->pc_adr, 4) < 0) exit(1); - if (timeout && (main_time >= timeout)) { - printf("Timeout: Exiting at time %lu\n", main_time); - done = true; - } + top->wb_clk = !top->wb_clk; + main_time+=31.25; - top->wb_clk = !top->wb_clk; - main_time+=31.25; - - if (cps_file) { - cur_cycle++; - if (std::time(nullptr) > last_time) { - dprintf(cps_file,"%d\n", (cur_cycle-last_cycle)/2); - last_cycle = cur_cycle; - last_time++; - } - } - } - close(cps_file); - close(tf); - if (tfp) - tfp->close(); - exit(0); + } + if (tfp) + tfp->close(); + exit(0); } diff --git a/bench/servant_tb.v b/bench/servant_tb.v index be42a98..41183cd 100644 --- a/bench/servant_tb.v +++ b/bench/servant_tb.v @@ -1,37 +1,24 @@ `default_nettype none module servant_tb; - parameter memfile = "hello_uart.hex"; + parameter memfile = ""; parameter memsize = 8192; - parameter width = 1; parameter with_csr = 1; - localparam baud_rate = - (width == 4) ? 57600*3 : - 57600; - reg wb_clk = 1'b0; reg wb_rst = 1'b1; - wire q; - always #31 wb_clk <= !wb_clk; initial #62 wb_rst <= 1'b0; vlog_tb_utils vtu(); - uart_decoder #(baud_rate) uart_decoder (q); + uart_decoder #(57600) uart_decoder (q); servant_sim #(.memfile (memfile), .memsize (memsize), - .width (width), .with_csr (with_csr)) - dut - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .pc_adr (), - .pc_vld (), - .q (q)); + dut(wb_clk, wb_rst, q); endmodule diff --git a/bench/servant_tb_vidbo.cpp b/bench/servant_tb_vidbo.cpp deleted file mode 100644 index d0a8322..0000000 --- a/bench/servant_tb_vidbo.cpp +++ /dev/null @@ -1,163 +0,0 @@ -#include -#include - -#include "verilated_vcd_c.h" -#include "Vservant_sim.h" - -#include "vidbo.h" - -using namespace std; - -static bool done; - -vluint64_t main_time = 0; // Current simulation time -// This is a 64-bit integer to reduce wrap over issues and -// allow modulus. You can also use a double, if you wish. - -double sc_time_stamp () { // Called by $time in Verilog - return main_time; // converts to double, to match - // what SystemC does -} - -void INThandler(int signal) -{ - printf("\nCaught ctrl-c\n"); - done = true; -} - -typedef struct { - bool last_value; -} gpio_context_t; - -void do_gpio(gpio_context_t *context, bool gpio) { - if (context->last_value != gpio) { - context->last_value = gpio; - printf("%lu output q is %s\n", main_time, gpio ? "ON" : "OFF"); - } -} - -typedef struct { - uint8_t state; - char ch; - uint32_t baud_t; - vluint64_t last_update; -} uart_context_t; - -void uart_init(uart_context_t *context, uint32_t baud_rate) { - context->baud_t = 1000*1000*1000/baud_rate; - context->state = 0; -} - -bool do_uart(uart_context_t *context, bool rx) { - if (context->state == 0) { - if (rx) - context->state++; - } - else if (context->state == 1) { - if (!rx) { - context->last_update = main_time + context->baud_t/2; - context->state++; - } - } - else if(context->state == 2) { - if (main_time > context->last_update) { - context->last_update += context->baud_t; - context->ch = 0; - context->state++; - } - } - else if (context->state < 11) { - if (main_time > context->last_update) { - context->last_update += context->baud_t; - context->ch |= rx << (context->state-3); - context->state++; - } - } - else { - if (main_time > context->last_update) { - context->last_update += context->baud_t; - context->state=1; - return true; - } - } - return false; -} - -int main(int argc, char **argv, char **env) -{ - int baud_rate = 0; - - gpio_context_t gpio_context; - uart_context_t uart_context; - - vidbo_context_t vidbo_context; - vidbo_init(&vidbo_context, 8081); - int poll_vidbo = 0; - - Verilated::commandArgs(argc, argv); - - Vservant_sim* top = new Vservant_sim; - - const char *arg = Verilated::commandArgsPlusMatch("uart_baudrate="); - if (arg[0]) { - baud_rate = atoi(arg+15); - if (baud_rate) { - uart_init(&uart_context, baud_rate); - } - } - - VerilatedVcdC * tfp = 0; - const char *vcd = Verilated::commandArgsPlusMatch("vcd="); - if (vcd[0]) { - Verilated::traceEverOn(true); - tfp = new VerilatedVcdC; - top->trace (tfp, 99); - tfp->open ("trace.vcd"); - } - - signal(SIGINT, INThandler); - - vluint64_t timeout = 0; - const char *arg_timeout = Verilated::commandArgsPlusMatch("timeout="); - if (arg_timeout[0]) - timeout = atoi(arg_timeout+9); - - vluint64_t vcd_start = 0; - const char *arg_vcd_start = Verilated::commandArgsPlusMatch("vcd_start="); - if (arg_vcd_start[0]) - vcd_start = atoi(arg_vcd_start+11); - - bool dump = false; - top->wb_clk = 1; - bool q = top->q; - while (!(done || Verilated::gotFinish())) { - if (tfp && !dump && (main_time > vcd_start)) { - dump = true; - } - top->wb_rst = main_time < 100; - top->eval(); - if (dump) - tfp->dump(main_time); - if (baud_rate) { - if (do_uart(&uart_context, top->q)) - vidbo_send(&vidbo_context, main_time, "serial", "uart", uart_context.ch); - } - if (top->q != gpio_context.last_value) { - vidbo_send(&vidbo_context, main_time, "gpio", "LD0", (top->q) & 0x1); - gpio_context.last_value = top->q; - } - if (timeout && (main_time >= timeout)) { - printf("Timeout: Exiting at time %lu\n", main_time); - done = true; - } - - if (!(poll_vidbo++ % 100000)) vidbo_recv(&vidbo_context, 0); - - top->wb_clk = !top->wb_clk; - main_time+=31.25; - - } - if (tfp) - tfp->close(); - exit(0); -} diff --git a/data/ac701.xdc b/data/ac701.xdc deleted file mode 100644 index ec0e813..0000000 --- a/data/ac701.xdc +++ /dev/null @@ -1,11 +0,0 @@ -## Clock signal -set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_p] -set_property PACKAGE_PIN P3 [get_ports sys_clk_n] -set_property PACKAGE_PIN R3 [get_ports sys_clk_p] -set_property IOSTANDARD DIFF_SSTL15 [get_ports sys_clk_n] - -create_clock -period 5.000 -name clk_p [get_nets sys_clk_p] - -## UART TX -set_property PACKAGE_PIN U19 [get_ports q] -set_property IOSTANDARD LVCMOS18 [get_ports q] diff --git a/data/alchitry_au.xdc b/data/alchitry_au.xdc deleted file mode 100644 index 5853261..0000000 --- a/data/alchitry_au.xdc +++ /dev/null @@ -1,16 +0,0 @@ -## Clock signal -set_property -dict { PACKAGE_PIN N14 IOSTANDARD LVCMOS33 } [get_ports i_clk]; -create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports i_clk]; - -## Reset -set_property -dict {PACKAGE_PIN P6 IOSTANDARD LVCMOS33 } [get_ports i_rst_n]; - -## LED -## set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports q]; - -## USB Serial output -set_property -dict { PACKAGE_PIN P16 IOSTANDARD LVCMOS33 } [get_ports q] - -set_property CONFIG_VOLTAGE 3.3 [current_design] -set_property CFGBVS VCCO [current_design] - diff --git a/data/alhambra.pcf b/data/alhambra.pcf deleted file mode 100644 index 9c902dc..0000000 --- a/data/alhambra.pcf +++ /dev/null @@ -1,5 +0,0 @@ -# 12 MHz clock -set_io i_clk 49 - -# RS232 -set_io q 61 diff --git a/data/arty_a7_35t.xdc b/data/arty_a7_35t.xdc index 18faef3..e6fcbfa 100644 --- a/data/arty_a7_35t.xdc +++ b/data/arty_a7_35t.xdc @@ -1,7 +1,5 @@ set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33 } [get_ports i_clk]; -set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33 } [get_ports i_rst_n]; - set_property -dict {PACKAGE_PIN D10 IOSTANDARD LVCMOS33 } [get_ports q] #set_property -dict {PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports q] diff --git a/data/arty_s7_50t.xdc b/data/arty_s7_50t.xdc deleted file mode 100644 index 30e799b..0000000 --- a/data/arty_s7_50t.xdc +++ /dev/null @@ -1,10 +0,0 @@ -set_property -dict { PACKAGE_PIN R2 IOSTANDARD SSTL135 } [get_ports i_clk]; #IO_L12P_T1_MRCC_34 Sch=ddr3_clk[200] -set_property -dict { PACKAGE_PIN C18 IOSTANDARD LVCMOS33 } [get_ports i_rst_n]; #IO_L11N_T1_SRCC_15 - -set_property -dict { PACKAGE_PIN R12 IOSTANDARD LVCMOS33 } [get_ports q]; #IO_25_14 Sch=uart_rxd_out -#set_property -dict { PACKAGE_PIN E18 IOSTANDARD LVCMOS33 } [get_ports q]; #IO_L16N_T2_A27_15 Sch=led[2] - -set_property CFGBVS VCCO [current_design] -set_property CONFIG_VOLTAGE 3.3 [current_design] - -create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports i_clk]; diff --git a/data/ax309.ucf b/data/ax309.ucf deleted file mode 100644 index b965f99..0000000 --- a/data/ax309.ucf +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG VCCAUX=3.3; - -NET i_clk LOC = T8 | IOSTANDARD = LVCMOS33; -NET i_rst LOC = L3 | IOSTANDARD = LVCMOS33; -NET q LOC = P4 | IOSTANDARD = LVCMOS33; -NET o_uart_tx LOC = D12 | IOSTANDARD = LVCMOS33; - -NET i_clk TNM_NET = sys_clk_pin; -TIMESPEC TS_USER_CLOCK = PERIOD sys_clk_pin 50000 kHz; diff --git a/data/chameleon96/CV_96.v b/data/chameleon96/CV_96.v deleted file mode 100644 index 08aef31..0000000 --- a/data/chameleon96/CV_96.v +++ /dev/null @@ -1,28 +0,0 @@ - -module CV_96 ( - output q, - output uart_txd -); - -wire clk; - -HPS u0( - .h2f_user0_clk( clk) //hps_0_h2f_user0_clock.clk -); - - -servive u1 ( - .i_clk ( clk ), - .i_rst_n ( 1'b1), - .q ( q ), - .uart_txd( uart_txd ) -); - - -endmodule - - - - - - diff --git a/data/chameleon96/HPS.sv b/data/chameleon96/HPS.sv deleted file mode 100644 index bd2455b..0000000 --- a/data/chameleon96/HPS.sv +++ /dev/null @@ -1,108 +0,0 @@ - -module HPS( - output wire [1 - 1 : 0 ] h2f_rst_n - ,output wire [1 - 1 : 0 ] h2f_user0_clk -); - - -cyclonev_hps_interface_clocks_resets clocks_resets( - .f2h_pending_rst_ack({ - 1'b1 // 0:0 - }) -,.f2h_warm_rst_req_n({ - 1'b1 // 0:0 - }) -,.f2h_dbg_rst_req_n({ - 1'b1 // 0:0 - }) -,.h2f_rst_n({ - h2f_rst_n[0:0] // 0:0 - }) -,.f2h_cold_rst_req_n({ - 1'b1 // 0:0 - }) -,.h2f_user0_clk({ - h2f_user0_clk[0:0] // 0:0 - }) -); - - -cyclonev_hps_interface_dbg_apb debug_apb( - .DBG_APB_DISABLE({ - 1'b0 // 0:0 - }) -,.P_CLK_EN({ - 1'b0 // 0:0 - }) -); - - -cyclonev_hps_interface_tpiu_trace tpiu( - .traceclk_ctl({ - 1'b1 // 0:0 - }) -); - - -cyclonev_hps_interface_boot_from_fpga boot_from_fpga( - .boot_from_fpga_ready({ - 1'b0 // 0:0 - }) -,.boot_from_fpga_on_failure({ - 1'b0 // 0:0 - }) -,.bsel_en({ - 1'b0 // 0:0 - }) -,.csel_en({ - 1'b0 // 0:0 - }) -,.csel({ - 2'b01 // 1:0 - }) -,.bsel({ - 3'b001 // 2:0 - }) -); - - -cyclonev_hps_interface_fpga2hps fpga2hps( - .port_size_config({ - 2'b11 // 1:0 - }) -); - - -cyclonev_hps_interface_hps2fpga hps2fpga( - .port_size_config({ - 2'b11 // 1:0 - }) -); - - -cyclonev_hps_interface_fpga2sdram f2sdram( - .cfg_cport_rfifo_map({ - 18'b000000000000000000 // 17:0 - }) -,.cfg_axi_mm_select({ - 6'b000000 // 5:0 - }) -,.cfg_wfifo_cport_map({ - 16'b0000000000000000 // 15:0 - }) -,.cfg_cport_type({ - 12'b000000000000 // 11:0 - }) -,.cfg_rfifo_cport_map({ - 16'b0000000000000000 // 15:0 - }) -,.cfg_port_width({ - 12'b000000000000 // 11:0 - }) -,.cfg_cport_wfifo_map({ - 18'b000000000000000000 // 17:0 - }) -); - -endmodule - diff --git a/data/chameleon96/chain1.cdf b/data/chameleon96/chain1.cdf deleted file mode 100644 index 6bd00a4..0000000 --- a/data/chameleon96/chain1.cdf +++ /dev/null @@ -1,15 +0,0 @@ -/* Quartus Prime Version 17.1.0 Build 590 10/25/2017 SJ Lite Edition */ -JedecChain; - FileRevision(JESD32A); - DefaultMfr(6E); - - P ActionCode(Ign) - Device PartName(SOCVHPS) MfrSpec(OpMask(0)); - P ActionCode(Cfg) - Device PartName(5CSEBA6U19) Path("/home/jordi/bin/fusesoc/build/fusesoc_utils_blinky_1.1/chameleon96-quartus/") File("fusesoc_utils_blinky_1_1.sof") MfrSpec(OpMask(1)); - -ChainEnd; - -AlteraBegin; - ChainType(JTAG); -AlteraEnd; diff --git a/data/chameleon96/chameleon96.sdc b/data/chameleon96/chameleon96.sdc deleted file mode 100755 index f470722..0000000 --- a/data/chameleon96/chameleon96.sdc +++ /dev/null @@ -1,8 +0,0 @@ -# Main system clock (100 Mhz) -create_clock -name "clk" -period 10.000ns [get_pins -compatibility_mode u0|clocks_resets|h2f_user0_clk] - -# Automatically constrain PLL and other generated clocks -derive_pll_clocks -create_base_clocks - -# Automatically calculate clock uncertainty to jitter and other effects. -derive_clock_uncertainty diff --git a/data/chameleon96/pinmap.tcl b/data/chameleon96/pinmap.tcl deleted file mode 100755 index ff72bb1..0000000 --- a/data/chameleon96/pinmap.tcl +++ /dev/null @@ -1,20 +0,0 @@ -# -# Clock / Reset -# -# set_location_assignment PIN_xxxx -to i_clk -# No direct clock. Using internal HPS clock - -# -# GPIO -# -# LED Y19 Yellow WIFI, Y20 Blue Bluetooth -set_location_assignment PIN_Y19 -to q -set_instance_assignment -name IO_STANDARD "2.5 V" -to q - -# FPGA_1V8_HPS_EXP_UART1_TXD_PIN_W14 Pin 5 Low speed connector (WHITE C96 USB/serial cable) Pin 1 GND -set_location_assignment PIN_W14 -to uart_txd -set_instance_assignment -name IO_STANDARD "1.8 V" -to uart_txd - -# No reset button wired to FPGA -# set_location_assignment PIN_xxx -to i_rst_n - diff --git a/data/cmod_a7_35t.xdc b/data/cmod_a7_35t.xdc deleted file mode 100644 index 2653676..0000000 --- a/data/cmod_a7_35t.xdc +++ /dev/null @@ -1,16 +0,0 @@ -## 12 MHz Clock Signal -set_property -dict { PACKAGE_PIN L17 IOSTANDARD LVCMOS33 } [get_ports { i_clk }]; #IO_L12P_T1_MRCC_14 Sch=gclk -create_clock -add -name sys_clk_pin -period 83.33 -waveform {0 41.66} [get_ports { i_clk }]; - -## LEDs -set_property -dict { PACKAGE_PIN A17 IOSTANDARD LVCMOS33 } [get_ports { q }]; #IO_L12N_T1_MRCC_16 Sch=led[1] -#set_property -dict { PACKAGE_PIN C16 IOSTANDARD LVCMOS33 } [get_ports { q }]; #IO_L13P_T2_MRCC_16 Sch=led[2] - -## UART -set_property -dict { PACKAGE_PIN J18 IOSTANDARD LVCMOS33 } [get_ports { o_uart_tx }]; #IO_L7N_T1_D10_14 Sch=uart_rxd_out -#set_property -dict { PACKAGE_PIN J17 IOSTANDARD LVCMOS33 } [get_ports { q }]; #IO_L7P_T1_D09_14 Sch=uart_txd_in - -set_property -dict { PACKAGE_PIN A18 IOSTANDARD LVCMOS33 } [get_ports { i_rst }]; #IO_L19N_T3_VREF_16 Sch=btn[0] - -set_property CFGBVS VCCO [current_design] -set_property CONFIG_VOLTAGE 3.3 [current_design] diff --git a/data/de0_nano.sdc b/data/de0_nano.sdc deleted file mode 100644 index 7a5fcef..0000000 --- a/data/de0_nano.sdc +++ /dev/null @@ -1,8 +0,0 @@ -# Main system clock (50 Mhz) -create_clock -name "clk" -period 20.000ns [get_ports {i_clk}] - -# Automatically constrain PLL and other generated clocks -derive_pll_clocks -create_base_clocks - -# Automatically calculate clock uncertainty to jitter and other effects. -derive_clock_uncertainty diff --git a/data/de0_nano.tcl b/data/de0_nano.tcl deleted file mode 100644 index 0db6ad3..0000000 --- a/data/de0_nano.tcl +++ /dev/null @@ -1,11 +0,0 @@ -set_location_assignment PIN_R8 -to i_clk -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_clk - -set_location_assignment PIN_A15 -to q -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to q - -set_location_assignment PIN_D11 -to uart_txd -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart_txd - -set_location_assignment PIN_J15 -to i_rst_n -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_rst_n diff --git a/data/de10_nano.sdc b/data/de10_nano.sdc deleted file mode 100644 index 7a5fcef..0000000 --- a/data/de10_nano.sdc +++ /dev/null @@ -1,8 +0,0 @@ -# Main system clock (50 Mhz) -create_clock -name "clk" -period 20.000ns [get_ports {i_clk}] - -# Automatically constrain PLL and other generated clocks -derive_pll_clocks -create_base_clocks - -# Automatically calculate clock uncertainty to jitter and other effects. -derive_clock_uncertainty diff --git a/data/de10_nano.tcl b/data/de10_nano.tcl deleted file mode 100644 index af4c557..0000000 --- a/data/de10_nano.tcl +++ /dev/null @@ -1,13 +0,0 @@ -set_location_assignment PIN_V11 -to i_clk -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_clk - -set_location_assignment PIN_W15 -to q -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to q - -# GPIO0 Pin 1 -set_location_assignment PIN_Y15 -to uart_txd -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart_txd - -#KEY[0] -set_location_assignment PIN_AH17 -to i_rst_n -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_rst_n diff --git a/data/de1_soc_revF.sdc b/data/de1_soc_revF.sdc deleted file mode 100644 index 7a5fcef..0000000 --- a/data/de1_soc_revF.sdc +++ /dev/null @@ -1,8 +0,0 @@ -# Main system clock (50 Mhz) -create_clock -name "clk" -period 20.000ns [get_ports {i_clk}] - -# Automatically constrain PLL and other generated clocks -derive_pll_clocks -create_base_clocks - -# Automatically calculate clock uncertainty to jitter and other effects. -derive_clock_uncertainty diff --git a/data/de1_soc_revF.tcl b/data/de1_soc_revF.tcl deleted file mode 100644 index 5604911..0000000 --- a/data/de1_soc_revF.tcl +++ /dev/null @@ -1,11 +0,0 @@ -set_location_assignment PIN_AF14 -to i_clk -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_clk - -set_location_assignment PIN_AA14 -to i_rst_n -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_rst_n - -set_location_assignment PIN_V16 -to q -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to q - -set_location_assignment PIN_AC18 -to uart_txd -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart* diff --git a/data/deca.sdc b/data/deca.sdc deleted file mode 100644 index 7a5fcef..0000000 --- a/data/deca.sdc +++ /dev/null @@ -1,8 +0,0 @@ -# Main system clock (50 Mhz) -create_clock -name "clk" -period 20.000ns [get_ports {i_clk}] - -# Automatically constrain PLL and other generated clocks -derive_pll_clocks -create_base_clocks - -# Automatically calculate clock uncertainty to jitter and other effects. -derive_clock_uncertainty diff --git a/data/deca.tcl b/data/deca.tcl deleted file mode 100644 index f4e511e..0000000 --- a/data/deca.tcl +++ /dev/null @@ -1,19 +0,0 @@ -#MAX10_CLK2_50 3.3V -set_location_assignment PIN_P11 -to i_clk -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_clk - -#LED[0] -set_location_assignment PIN_C7 -to q -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to q - -#P8 3 GPIO0_D0 (P8 1 GND) -set_location_assignment PIN_W18 -to uart_txd -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart_txd - -#KEY[0] -set_location_assignment PIN_H21 -to i_rst_n -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_rst_n - -# Configuration mode that allows Memory Initialisation -set_global_assignment -name INTERNAL_FLASH_UPDATE_MODE "SINGLE IMAGE WITH ERAM" - diff --git a/data/ebaz4205.xdc b/data/ebaz4205.xdc deleted file mode 100644 index 15219c1..0000000 --- a/data/ebaz4205.xdc +++ /dev/null @@ -1,10 +0,0 @@ -## 33.333 MHz Clock signal -set_property -dict { PACKAGE_PIN N18 IOSTANDARD LVCMOS33 } [get_ports i_clk]; -create_clock -add -name sys_clk_pin -period 30.00 -waveform {0 5} [get_ports i_clk]; - -## LED(s) -# set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { q_green }]; -# set_property -dict { PACKAGE_PIN W14 IOSTANDARD LVCMOS33 } [get_ports { q }]; - -## UART on DATA1_8 pin -set_property -dict { PACKAGE_PIN B20 IOSTANDARD LVCMOS33 } [get_ports q]; diff --git a/data/ecp5_evn.lpf b/data/ecp5_evn.lpf deleted file mode 100644 index 81942c9..0000000 --- a/data/ecp5_evn.lpf +++ /dev/null @@ -1,16 +0,0 @@ -# 12MHz clock from FTDI FT2232H -LOCATE COMP "clk" SITE "A10"; -IOBUF PORT "clk" IO_TYPE=LVCMOS33; -FREQUENCY PORT "clk" 12 MHZ; - -# SW4 button -LOCATE COMP "nreset" SITE "P4"; -IOBUF PORT "nreset" IO_TYPE=LVCMOS33; - -# LED0 -LOCATE COMP "led0" SITE "A13"; -IOBUF PORT "led0" IO_TYPE=LVCMOS25; - -# J40 Header Pin #1 -LOCATE COMP "uart_txd" SITE "K2"; -IOBUF PORT "uart_txd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; diff --git a/data/gmm7550.ccf b/data/gmm7550.ccf deleted file mode 100644 index 8dcdfa9..0000000 --- a/data/gmm7550.ccf +++ /dev/null @@ -1,65 +0,0 @@ -## GMM-7550 pins - -# This file is a part of the GMM-7550 VHDL Examples -# -# -# SPDX-License-Identifier: MIT -# -# Copyright (c) 2023 Anton Kuzmin - -# Master clock input (100 MHz) -Pin_in "ser_clk" Loc = "SER_CLK"; - -### SPI - -Pin_inout "CFG_SPI_nCS" Loc = "IO_WA_A8"; -Pin_inout "CFG_SPI_CLK" Loc = "IO_WA_B8"; -Pin_inout "CFG_SPI_IO0" Loc = "IO_WA_B7"; # MOSI -Pin_inout "CFG_SPI_IO1" Loc = "IO_WA_A7"; # MISO -# Pin_inout "CFG_SPI_IO2" Loc = "IO_WA_B6"; # May be reused on the HAT for UART -# Pin_inout "CFG_SPI_IO3" Loc = "IO_WA_A6"; # May be reused on the HAT for UART -## HAT Adapter board - -# This file is a part of the GMM-7550 VHDL Examples -# -# -# SPDX-License-Identifier: MIT -# -# Copyright (c) 2023 Anton Kuzmin - -# D4 CFG_FAILED (Red) -Pin_out "led_red_n" Loc = "IO_WA_A2"; - -# D2 CFG_DONE (Green) -Pin_out "led_green" Loc = "IO_WA_B2"; - -### UART - -Pin_out "uart_tx" Loc = "IO_WA_A6"; # SPI D3, GPIO pin 10 -Pin_in "uart_rx" Loc = "IO_WA_B6"; # SPI D2, GPIO pin 8 - -### Pmod J10 - -Pin_out "J10_EN" Loc = "IO_SA_A7"; - -Pin_inout "J10_IO[0]" Loc = "IO_SA_A0"; -Pin_inout "J10_IO[1]" Loc = "IO_SA_A1"; -Pin_inout "J10_IO[2]" Loc = "IO_SA_A2"; -Pin_inout "J10_IO[3]" Loc = "IO_SA_A3"; -Pin_inout "J10_IO[4]" Loc = "IO_SA_B0"; -Pin_inout "J10_IO[5]" Loc = "IO_SA_B1"; -Pin_inout "J10_IO[6]" Loc = "IO_SA_B2"; -Pin_inout "J10_IO[7]" Loc = "IO_SA_B3"; - -### Pmod J9 - -Pin_out "J9_EN" Loc = "IO_SB_B3"; - -Pin_inout "J9_IO[0]" Loc = "IO_SB_A6"; # CLK_2 -Pin_inout "J9_IO[1]" Loc = "IO_SB_A7"; # CLK_1 -Pin_inout "J9_IO[2]" Loc = "IO_SB_A8"; # CLK_0 -Pin_inout "J9_IO[3]" Loc = "IO_SB_A5"; # CLK_3 -Pin_inout "J9_IO[4]" Loc = "IO_SB_B6"; -Pin_inout "J9_IO[5]" Loc = "IO_SB_B7"; -Pin_inout "J9_IO[6]" Loc = "IO_SB_B8"; -Pin_inout "J9_IO[7]" Loc = "IO_SB_B5"; diff --git a/data/go_board.pcf b/data/go_board.pcf deleted file mode 100644 index 7167cc5..0000000 --- a/data/go_board.pcf +++ /dev/null @@ -1,10 +0,0 @@ -# 20 MHz clock input -set_io i_clk 15 - -# Onboard LEDs 1-4 -set_io o_led1 56 -set_io o_led2 57 -set_io o_led3 59 -set_io o_led4 60 - -set_io o_uart_tx 74 diff --git a/data/icestick.pcf b/data/icestick.pcf deleted file mode 100644 index e99e6a2..0000000 --- a/data/icestick.pcf +++ /dev/null @@ -1,8 +0,0 @@ -# 12 MHz clock input -set_io i_clk 21 - -# Onboard LED (Green) -set_io q 95 - -# UART TX -#set_io q 62 diff --git a/data/icesugar.pcf b/data/icesugar.pcf deleted file mode 100644 index 365ce47..0000000 --- a/data/icesugar.pcf +++ /dev/null @@ -1,5 +0,0 @@ -# 12 MHz clock -set_io i_clk 35 - -# RS232 -set_io q 6 diff --git a/data/icev_wireless.pcf b/data/icev_wireless.pcf deleted file mode 100644 index 71c97ce..0000000 --- a/data/icev_wireless.pcf +++ /dev/null @@ -1,7 +0,0 @@ -# 12 MHz clock -set_io i_clk 35 - -# RS232 -set_io q 9 - -# use q 39 for red, q 40 for green, q 41 for blue LED diff --git a/data/lx9_microboard.ucf b/data/lx9_microboard.ucf deleted file mode 100644 index 3d73549..0000000 --- a/data/lx9_microboard.ucf +++ /dev/null @@ -1,9 +0,0 @@ -CONFIG VCCAUX=3.3; - -NET i_clk LOC = V10 | IOSTANDARD = LVCMOS33; -NET i_rst LOC = V4 | IOSTANDARD = LVCMOS33 | PULLDOWN; -NET q LOC = P4 | IOSTANDARD = LVCMOS18; -NET o_uart_tx LOC = T7 | IOSTANDARD = LVCMOS33; - -NET i_clk TNM_NET = clk; -TIMESPEC TS_USER_CLOCK = PERIOD clk 40000 kHz; diff --git a/data/machdyne_kolibri.pcf b/data/machdyne_kolibri.pcf deleted file mode 100644 index 2f33d46..0000000 --- a/data/machdyne_kolibri.pcf +++ /dev/null @@ -1,4 +0,0 @@ -set_io clk48 G1 -set_io led B11 -set_io tx B1 -set_io rx B2 diff --git a/data/max10_10m08evk.sdc b/data/max10_10m08evk.sdc deleted file mode 100644 index 7a5fcef..0000000 --- a/data/max10_10m08evk.sdc +++ /dev/null @@ -1,8 +0,0 @@ -# Main system clock (50 Mhz) -create_clock -name "clk" -period 20.000ns [get_ports {i_clk}] - -# Automatically constrain PLL and other generated clocks -derive_pll_clocks -create_base_clocks - -# Automatically calculate clock uncertainty to jitter and other effects. -derive_clock_uncertainty diff --git a/data/max10_10m08evk.tcl b/data/max10_10m08evk.tcl deleted file mode 100644 index 4765991..0000000 --- a/data/max10_10m08evk.tcl +++ /dev/null @@ -1,24 +0,0 @@ -#MAX10_CLK2_50 3.3V -set_location_assignment PIN_27 -to i_clk -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_clk - -#LED[0] -set_location_assignment PIN_132 -to q -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to q - -#P8 3 ARDUINO_IO1 -set_location_assignment PIN_75 -to uart_txd -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart_txd - -#KEY[0] -set_location_assignment PIN_121 -to i_rst_n -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_rst_n - -# Configuration mode that allows Memory Initialisation -set_global_assignment -name INTERNAL_FLASH_UPDATE_MODE "SINGLE IMAGE WITH ERAM" - -# Generate SVF File for openFPGALoader -set_global_assignment -name GENERATE_SVF_FILE ON -# set_global_assignment -name GENERATE_JBC_FILE ON -set_global_assignment -name GENERATE_JAM_FILE ON - diff --git a/data/nexys_2.tcl b/data/nexys_2.tcl deleted file mode 100644 index 76dbfbd..0000000 --- a/data/nexys_2.tcl +++ /dev/null @@ -1 +0,0 @@ -project set "Other XST Command Line Options" "-use_new_parser yes" \ No newline at end of file diff --git a/data/nexys_2.ucf b/data/nexys_2.ucf deleted file mode 100644 index 41cea86..0000000 --- a/data/nexys_2.ucf +++ /dev/null @@ -1,8 +0,0 @@ -NET "i_clk" LOC = "B8" | IOSTANDARD = LVCMOS33 ; -NET "i_clk" CLOCK_DEDICATED_ROUTE = FALSE; - -# Pin assignment for Uart tx -NET "q" LOC = "L15" | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 8 ; - -# Pin assignment for LED -# NET "q" LOC = "J14" | IOSTANDARD = LVTTL | SLEW = FAST | DRIVE = 8 ; \ No newline at end of file diff --git a/data/orangecrab_r02.lpf b/data/orangecrab_r02.lpf deleted file mode 100644 index 2a96dde..0000000 --- a/data/orangecrab_r02.lpf +++ /dev/null @@ -1,17 +0,0 @@ -LOCATE COMP "clk" SITE "A9"; -IOBUF PORT "clk" PULLMODE=NONE IO_TYPE=LVCMOS33; -FREQUENCY PORT "clk" 48.000 MHZ; - -LOCATE COMP "r" SITE "K4"; -LOCATE COMP "g" SITE "M3"; -LOCATE COMP "b" SITE "J3"; - -IOBUF PORT "r" IO_TYPE=LVCMOS33; -IOBUF PORT "g" IO_TYPE=LVCMOS33; -IOBUF PORT "b" IO_TYPE=LVCMOS33; - -LOCATE COMP "btn" SITE "J17"; # BTN_PWRn (inverted logic) -IOBUF PORT "btn" PULLMODE=UP IO_TYPE=LVCMOS33; - -LOCATE COMP "tx" SITE "M18"; # FPGA serial output -IOBUF PORT "tx" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; diff --git a/data/params.tcl b/data/params.tcl deleted file mode 100644 index 231da58..0000000 --- a/data/params.tcl +++ /dev/null @@ -1,6 +0,0 @@ -set ::env(CLOCK_PERIOD) "10" -set ::env(CLOCK_PORT) "clk" -set ::env(DIE_AREA) "0 0 200 200" -set ::env(FP_SIZING) absolute -set ::env(DESIGN_IS_CORE) 0 -set ::env(GLB_RT_MAXLAYER) 5 diff --git a/data/pipistrello.ucf b/data/pipistrello.ucf deleted file mode 100644 index a1fe990..0000000 --- a/data/pipistrello.ucf +++ /dev/null @@ -1,12 +0,0 @@ -CONFIG VCCAUX=3.3; - -NET i_clk LOC = H17 | IOSTANDARD = LVTTL; - -NET i_clk TNM_NET = i_clk; -TIMESPEC TS_USER_CLOCK = PERIOD i_clk 50000 kHz; - - -# uart tx -NET q LOC = A10 | IOSTANDARD = LVTTL | DRIVE = 8 | SLEW = FAST ; -# led0 -#NET q LOC = V16 | IOSTANDARD = LVCMOS33; diff --git a/data/polarfire_splashkit.pdc b/data/polarfire_splashkit.pdc deleted file mode 100644 index 00ede93..0000000 --- a/data/polarfire_splashkit.pdc +++ /dev/null @@ -1,11 +0,0 @@ -set_io -port_name {i_clk} -DIRECTION INPUT -pin_name H7 -io_std LVCMOS18 -fixed true -set_io -port_name {resetb} -DIRECTION INPUT -pin_name N4 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led1} -DIRECTION OUTPUT -pin_name P7 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led2} -DIRECTION OUTPUT -pin_name P8 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led3} -DIRECTION OUTPUT -pin_name N7 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led4} -DIRECTION OUTPUT -pin_name N8 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led5} -DIRECTION OUTPUT -pin_name N6 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led6} -DIRECTION OUTPUT -pin_name N5 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led7} -DIRECTION OUTPUT -pin_name M8 -io_std LVCMOS18 -fixed true -set_io -port_name {o_led8} -DIRECTION OUTPUT -pin_name M9 -io_std LVCMOS18 -fixed true -set_io -port_name {o_uart_tx} -DIRECTION OUTPUT -pin_name R4 -io_std LVCMOS18 -fixed true diff --git a/data/sockit.sdc b/data/sockit.sdc deleted file mode 100644 index 7a5fcef..0000000 --- a/data/sockit.sdc +++ /dev/null @@ -1,8 +0,0 @@ -# Main system clock (50 Mhz) -create_clock -name "clk" -period 20.000ns [get_ports {i_clk}] - -# Automatically constrain PLL and other generated clocks -derive_pll_clocks -create_base_clocks - -# Automatically calculate clock uncertainty to jitter and other effects. -derive_clock_uncertainty diff --git a/data/sockit.tcl b/data/sockit.tcl deleted file mode 100644 index 3bb3945..0000000 --- a/data/sockit.tcl +++ /dev/null @@ -1,11 +0,0 @@ -set_location_assignment PIN_AF14 -to i_clk -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_clk - -set_location_assignment PIN_AF10 -to q -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to q - -set_location_assignment PIN_F14 -to uart_txd -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to uart_txd - -set_location_assignment PIN_AE9 -to i_rst_n -set_instance_assignment -name IO_STANDARD "3.3-V LVTTL" -to i_rst_n diff --git a/data/te0802.xdc b/data/te0802.xdc deleted file mode 100644 index d0ab18b..0000000 --- a/data/te0802.xdc +++ /dev/null @@ -1,22 +0,0 @@ -## Clock signal -set_property -dict { PACKAGE_PIN J3 IOSTANDARD LVCMOS18 } [get_ports i_clk]; -create_clock -add -name sys_clk_pin -period 40.00 [get_ports i_clk]; - -## LED 0 -set_property -dict { PACKAGE_PIN P1 IOSTANDARD LVCMOS18 } [get_ports o_led_0]; - -# PMOD A, Connector J5 -# Connector pin, Package pin, PMOD type 4 UART -# 1, F8, CTS -# 2, F7, TXD -# 3, E6, RXD -# 4, E5, RTS -# 5, GND -# 6, VCC -# 7, G6, -# 8, G5, -# 9, C8, -# 10, C7, -# 11, GND -# 12, VCC -set_property -dict { PACKAGE_PIN F7 IOSTANDARD LVCMOS33 } [get_ports o_uart_tx] diff --git a/data/ulx3s.lpf b/data/ulx3s.lpf deleted file mode 100644 index 0ea49d6..0000000 --- a/data/ulx3s.lpf +++ /dev/null @@ -1,14 +0,0 @@ -LOCATE COMP "clk" SITE "G2"; -IOBUF PORT "clk" PULLMODE=NONE IO_TYPE=LVCMOS33; -FREQUENCY PORT "clk" 25.000 MHZ; -LOCATE COMP "q" SITE "B2"; -IOBUF PORT "q" PULLMODE=NONE IO_TYPE=LVCMOS33 DRIVE=4; - -LOCATE COMP "btn0" SITE "D6"; # BTN_PWRn (inverted logic) -IOBUF PORT "btn0" PULLMODE=UP IO_TYPE=LVCMOS33; - -LOCATE COMP "wifi_gpio0" SITE "L2"; -IOBUF PORT "wifi_gpio0" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; - -LOCATE COMP "uart_txd" SITE "L4"; # FPGA transmits to ftdi -IOBUF PORT "uart_txd" PULLMODE=UP IO_TYPE=LVCMOS33 DRIVE=4; diff --git a/data/upduino2.pcf b/data/upduino2.pcf deleted file mode 100644 index 9611af5..0000000 --- a/data/upduino2.pcf +++ /dev/null @@ -1,4 +0,0 @@ -set_io g 39 -set_io b 40 -set_io r 41 -set_io q 14 diff --git a/data/verilator_waiver.vlt b/data/verilator_waiver.vlt deleted file mode 100644 index e6d7bcc..0000000 --- a/data/verilator_waiver.vlt +++ /dev/null @@ -1,12 +0,0 @@ -`verilator_config -// Bits [1:0] in i_wb_rdt are not used at all -lint_off -rule UNUSED -file "*/serv_top.v" -lines 179 - -//Some bits in the instruction word are not used in serv_decode but it's easier -//to just send in the whole word than picking out bits -lint_off -rule UNUSED -file "*/serv_decode.v" -lines 8 - -//Some variables are only used when we connect an Extension with serv_decode -lint_off -rule UNUSED -file "*/serv_top.v" -lines 70 - - diff --git a/data/zcu106.xdc b/data/zcu106.xdc deleted file mode 100644 index 2d6d0d3..0000000 --- a/data/zcu106.xdc +++ /dev/null @@ -1,8 +0,0 @@ -## Clock signal -set_property -dict { PACKAGE_PIN H9 IOSTANDARD LVDS } [get_ports i_clk_p]; -set_property -dict { PACKAGE_PIN G9 IOSTANDARD LVDS } [get_ports i_clk_n]; -create_clock -add -name sys_clk_pin -period 8 [get_nets i_clk]; - -## LED -set_property -dict { PACKAGE_PIN AL11 IOSTANDARD LVCMOS12 } [get_ports q]; -set_property -dict { PACKAGE_PIN AL17 IOSTANDARD LVCMOS12 } [get_ports o_uart_tx] diff --git a/doc/.nojekyll b/doc/.nojekyll deleted file mode 100644 index 65cb711..0000000 --- a/doc/.nojekyll +++ /dev/null @@ -1 +0,0 @@ -This is published to GitHub Pages. It will ignore the _images path etc. otherwise. diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index 298ea9e..0000000 --- a/doc/Makefile +++ /dev/null @@ -1,19 +0,0 @@ -# Minimal makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -SOURCEDIR = . -BUILDDIR = _build - -# Put it first so that "make" without argument is like "make help". -help: - @$(SPHINXBUILD) -M help "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) - -.PHONY: help Makefile - -# Catch-all target: route all unknown targets to Sphinx using the new -# "make mode" option. $(O) is meant as a shortcut for $(SPHINXOPTS). -%: Makefile - @$(SPHINXBUILD) -M $@ "$(SOURCEDIR)" "$(BUILDDIR)" $(SPHINXOPTS) $(O) \ No newline at end of file diff --git a/doc/conf.py b/doc/conf.py deleted file mode 100644 index e2aa689..0000000 --- a/doc/conf.py +++ /dev/null @@ -1,59 +0,0 @@ -# Configuration file for the Sphinx documentation builder. -# -# This file only contains a selection of the most common options. For a full -# list see the documentation: -# http://www.sphinx-doc.org/en/master/config - -# -- Path setup -------------------------------------------------------------- - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use os.path.abspath to make it absolute, like shown here. -# -# import os -# import sys -# sys.path.insert(0, os.path.abspath('.')) - - -# -- Project information ----------------------------------------------------- - -project = 'SERV' -copyright = '2020, Olof Kindgren' -author = 'Olof Kindgren' - - -# -- General configuration --------------------------------------------------- - -# Add any Sphinx extension module names here, as strings. They can be -# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom -# ones. -extensions = [ - 'sphinxcontrib.wavedrom' -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ['_templates'] - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -# This pattern also affects html_static_path and html_extra_path. -exclude_patterns = ['_build', 'Thumbs.db', '.DS_Store'] - - -# -- Options for HTML output ------------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = 'alabaster' - -# Add any paths that contain custom static files (such as style sheets) here, -# relative to this directory. They are copied after the builtin static files, -# so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] - -html_extra_path = ['.nojekyll'] - -master_doc = 'index' - -online_wavedrom_js_url = "https://wavedrom.com" diff --git a/doc/datasheet.rst b/doc/datasheet.rst deleted file mode 100644 index 0c54ad4..0000000 --- a/doc/datasheet.rst +++ /dev/null @@ -1,6 +0,0 @@ -********* -Datasheet -********* - -.. include:: overview.rst -.. include:: interface.rst diff --git a/doc/index.rst b/doc/index.rst deleted file mode 100644 index 227c8ff..0000000 --- a/doc/index.rst +++ /dev/null @@ -1,13 +0,0 @@ -################ -SERV user manual -################ - -Welcome to the user manual of the award-winning SERV, the world's smallest RISC-V CPU. - -.. toctree:: - :maxdepth: 4 - :caption: Contents: - - datasheet.rst - internals.rst - reservoir.rst diff --git a/doc/interface.rst b/doc/interface.rst deleted file mode 100644 index 4e5cd72..0000000 --- a/doc/interface.rst +++ /dev/null @@ -1,222 +0,0 @@ -Interface -========= - -Top level ---------- - -Users of SERV can choose to use either serv_top or serv_rf_top depending on what best fits the application. serv_top contains all the main logic of SERV except for the actual storage for the register file (RF). - -.. image:: serv_top.png - -serv_rf_top is a convenience wrapper that combines serv_top with a memory-based RF (serf_rf_ram) and an adapter between them (serv_rf_ram_if). This allows users to choose between a drop-in implementation when the memory-based RF is good enough or supply an alternative RF implementation, such as a shift-register based one or a combined SRAM for instruction/data memory and RF. - -.. image:: serv_rf_top.png - -This means that serv_top exposes some additional pins to connect the RF which are not in serv_rf_top, while serv_rf_top has some extra parameters for configuring the RF. Aside from that, both modules expose a timer interrupt (only used when WITH_CSR=1), a rvfi formal interface (only available when RISCV_FORMAL is defined), an instruction bus, a data bus, and the extension interface. - -Parameters ----------- - -.. list-table:: Parameters - :header-rows: 1 - :widths: 10 20 80 - - * - Parameter - - Values - - Description - * - MDU - - 0 (default), 1 - - Enables the interface for connecting SERV and the Multiplication and Division Unit (MDU). Note that this only enables the interface and the decoder logic. The MDU itself must be connected externally as well. - * - PRE_REGISTER - - 0, 1 (default) - - | Register signals before or after the decoder - | 0 : Register after the decoder. Faster but uses more resources - | 1 : (default) Register before the decoder. Slower but uses less resources - * - RESET_PC - - 0x00000000 (default) - 0xFFFFFFFC - - Address of first instruction to fetch from memory after reset (Reset vector) - * - RESET_STRATEGY - - "MINI" (default), "NONE" - - | Amount of reset applied to design - | "NONE" : No reset at all. Relies on a POR to set correct initialization values and that core isn't reset during runtime - | "MINI" : Standard setting. Resets the minimal amount of FFs needed to restart execution from the instruction at RESET_PC. - * - RF_WIDTH - - 2 (default), 4, 8, 16, 32 - - (serv_rf_top only) Width of the RF memory. Typically smaller values use less resources, but can be implementation-dependant. - * - WITH_CSR - - 0, 1 (default) - - Enable Zicsr extension. This also enables timer IRQ and exception handling. Note that SERV only implements a small subset of the CSR registers. - -Signals -------- - -.. list-table:: Signals - :header-rows: 1 - :widths: 30 10 5 75 - - * - Signal - - Width - - Direction - - Description - * - clk - - 1 - - in - - Clock - * - i_rst - - 1 - - in - - Synchronous reset - * - i_timer_irq - - 1 - - in - - Timer interrupt - * - o_ibus_adr - - 32 - - out - - Instruction bus address - * - o_ibus_cyc - - 1 - - out - - Instruction bus active cycle - * - i_ibus_rdt - - 32 - - in - - Instruction bus read data - * - i_ibus_ack - - 1 - - in - - Instruction bus cycle acknowledged - * - o_dbus_adr - - 32 - - out - - Data bus address - * - o_dbus_dat - - 32 - - out - - Data bus write data - * - o_dbus_sel - - 4 - - out - - Data bus write data byte select mask - * - o_dbus_we - - 1 - - out - - Data bus write transaction - * - o_dbus_cyc - - 1 - - out - - Data bus active cycle - * - i_dbus_rdt - - 32 - - in - - Data bus return data - * - i_dbus_ack - - 1 - - in - - Data bus return data valid - * - o_ext_rs1 - - 32 - - out - - Extension interface RS1 contents - * - o_ext_rs2 - - 32 - - out - - Extension interface RS2 contents - * - o_ext_funct3 - - 3 - - out - - Extension interface funct3 contents - * - i_ext_rd - - 32 - - in - - Extension interface RD contents - * - i_ext_ready - - 1 - - in - - Extension interface RD contents valid - * - o_mdu_valid - - 1 - - out - - MDU request - * - **serv_top only** - - - - - - - * - o_rf_rreq - - 1 - - out - - RF interface read request - * - o_rf_wreq - - 1 - - out - - RF interface write request - * - i_rf_ready - - 1 - - in - - RF interface request acknowledged - * - o_wreg0 - - 5 + WITH_CSR - - out - - RF interface channel 0 write address - * - o_wreg1 - - 5 + WITH_CSR - - out - - RF interface channel 1 write address - * - o_wen0 - - 1 - - out - - RF interface channel 0 write enable - * - o_wen1 - - 1 - - out - - RF interface channel 1 write enable - * - o_wdata0 - - 1 - - out - - RF interface channel 0 write data - * - o_wdata1 - - 1 - - out - - RF interface channel 1 write data - * - o_rreg0 - - 5 + WITH_CSR - - out - - RF interface channel 0 read address - * - o_rreg1 - - 5 + WITH_CSR - - out - - RF interface channel 1 read address - * - i_rdata0 - - 1 - - in - - RF interface channel 0 read data - * - i_rdata1 - - 1 - - in - - RF interface channel 1 read data - -Extension interface -------------------- - -The SERV CPU, being the smallest RISC-V CPU, has a design that is primarily focused on simplicity and minimalism. However, to increase its utility without complicating the core design, it can be extended using an extension interface. The extension interface allows additional functionality to be added to the SERV CPU core through custom accelerators that are called for when specific instructions are encountered. SERV has built-in support for connecting an MDU (Multiplication/Division Unit) that implements the M ISA extension by setting the MDU parameter. Other accelerators need changes to the decoder. - -When SERV detects instructions to be executed by an external accelerator through the extension interface, it will treat them as :ref:`two-stage operations`. In stage 1, the values in `o_ext_rs1` and `o_ext_rs2` are prepared to be sent to the accelerator. Once stage 1 is completed, SERV will assert the corresponding valid signal for the accelerator (e.g. `o_mdu_valid` for the M extension accelerator). The accelerator can now perform its work and when it has completed its result it will return that value in `i_ext_rd` and strobe `i_ext_ready` for one cycle. The following cycle, SERV will start stage two and store the received result. The waveform below explains this in more detail. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "P...|...|...|..."}, - { name: "init" , wave: "1...|..0|...|...", node: ".......d..", data: "r0"}, - { name: "o_rf_wreq" , wave: "0...|...|10.|...", node: ".........g", data: "r1"}, - { name: "i_rf_ready" , wave: "010.|...|10.|...", node: ".a.......h.", data: "r1"}, - { name: "cnt_en" , wave: "0.1.|..0|.1.|..0", node: "..b.......i"}, - { name: "cnt_done" , wave: "0...|.10|...|.10", node: "......c.."}, - { name: "o_ext_rs1" , wave: ".234567x|...|...", node: "..", data: "d0 d1 ... d30 d31"}, - { name: "o_ext_rs2" , wave: ".234567x|...|...", node: "..", data: "d0 d1 ... d30 d31"}, - { name: "o_mdu_valid", wave: "0...|..1|.0.|...", node: ".......e", data: "0 1 ... 30 31"}, - { name: "i_ext_ready", wave: "0...|...|10.|...", node: ".........f", data: "0 1 ... 30 31"}, - { name: "i_ext_rd" , wave: "....|...|234567x", node: "..", data: "d0 d1 ... d30 d31"}, - ], - edge : [ - "a~>b", "c~>d", "e~>f", "f~>g", "h~>i"] - } diff --git a/doc/internals.rst b/doc/internals.rst deleted file mode 100644 index a78df95..0000000 --- a/doc/internals.rst +++ /dev/null @@ -1,5 +0,0 @@ -********* -Internals -********* - -.. include:: modules.rst diff --git a/doc/life_cycle.png b/doc/life_cycle.png deleted file mode 100644 index 2ab3e93..0000000 Binary files a/doc/life_cycle.png and /dev/null differ diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index 27f573b..0000000 --- a/doc/make.bat +++ /dev/null @@ -1,35 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=. -set BUILDDIR=_build - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd diff --git a/doc/modules.rst b/doc/modules.rst deleted file mode 100644 index ef19849..0000000 --- a/doc/modules.rst +++ /dev/null @@ -1,417 +0,0 @@ -Modules -------- - -SERV is a bit-serial CPU which means that the internal datapath is one bit wide. :ref:`dataflow` shows the internal dataflow. For each instruction, data is read from the register file or the immediate fields of the instruction word and the result of the operation is stored back into the register file. Reading and writing memory is handled through the memory interface module. - -.. _dataflow: - -.. figure:: serv_dataflow.png - - SERV internal dataflow - -serv_rf_top -^^^^^^^^^^^ - -.. image:: serv_rf_top.png - -serv_rf_top is a top-level convenience wrapper that includes SERV and the default RF implementation and just exposes the timer IRQ and instruction/data wishbone buses. - -serv_top -^^^^^^^^ - -serv_top is the top-level of the SERV core without an RF - -serv_alu -^^^^^^^^ - -.. image:: serv_alu.png - -serv_alu handles alu operations. The first input operand (A) comes from i_rs1 and the second operand (B) comes from i_rs2 or i_imm depending on the type of operation. The data passes through the add/sub or bool logic unit and finally ends up in o_rd to be written to the destination register. The output o_cmp is used for conditional branches to decide whether or not to take the branch. - -The add/sub unit can do additions A+B or subtractions A-B by converting it to A+B̅+1. Subtraction mode (i_sub = 1) is also used for the comparisons in the slt* and conditional branch instructions. The +1 used in subtraction mode is done by preloading the carry input with 1. Less-than comparisons are handled by converting the expression Ab","b~>c"] - } - -Decode -^^^^^^ -When the ack appears, two things happen in SERV. The relevant portions of the instruction such as opcode, funct3 and immediate value are saved in serv_decode and serv_immdec. The saved bits of the instruction is then decoded to create the internal control signals that corresponds to the current instruction. The decoded control signals remain static throughout the instruction life cycle. - -The other thing to happen is that a request to start accessing the register file is sent by strobing rf_rreq which prepares the register file for both read and write access. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "0P.|....."}, - { name: "rreq" , wave: "010|.....", node: ".a..."}, - { name: "rreg0" , wave: "x.2|.....", node: "....", data: "r0"}, - { name: "rreg1" , wave: "x.2|.....", node: "....", data: "r1"}, - { name: "ready" , wave: "0..|10...", node: "....b."}, - { name: "rdata0" , wave: "-..|12345", data: "0 1 2 3 4"}, - { name: "rdata1" , wave: "-..|12345", data: "0 1 2 3 4"}, - ], - edge : [ - "a~>b"] - } - -The interface between the core and the register file is described in a protocol where the core strobes rreq and present the registers to read on the following cycle. The register file will prepare to stream out data bit from the two requested registers. The cycle before it sends out the first bit (LSB) it will strobe rf_ready. Writes work in a similar way in that the registers to write has to be presented the cycle after rf_wreq is strobed and that the register file will start accepting data the cycle after it has strobed rf_ready. Note that the delay between rf_wreq and rf_ready does not have to be the same as from rf_rreq to rf_ready. Also note that register data will only be written to a register if the corresponding write enable signal is asserted. In the diagram below, only register r0 will be written to. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "0P....."}, - { name: "wreq" , wave: "010....", node: ".a..."}, - { name: "ready" , wave: "010....", node: ".b."}, - { name: "wreg0" , wave: "x.2....", node: "....", data: "r0"}, - { name: "wreg1" , wave: "x.2....", node: "....", data: "r1"}, - { name: "wen0" , wave: "0.1...."}, - { name: "wen1" , wave: "0......"}, - { name: "wdata0" , wave: "-123456", node: "..c.", data: "0 1 2 3 4"}, - { name: "wdata1" , wave: "-123456", node: "..d.", data: "0 1 2 3 4"}, - ], - edge : [ - "a~>b", "b~>c", "b~>d"] - } - -Execute -^^^^^^^ - -After the instruction has been decoded and the register file prepared for reads (and possibly writes) the core knows whether it is a one-stage or two-stage instruction. These are handled differently and we will begin by looking at one-stage instructions. A stage in SERV is 32 consecutive cycles during which the core is active and processes inputs and creates results one bit at a time, starting with the LSB. - -One-stage instructions -:::::::::::::::::::::: - -Most operations are one-stage operations which finish in 32 cycles + fetch overhead. During a one-stage operation, the RF is read and written simultaneously as well as the PC which is increased by four to point to the next instruction. trap and init signals are low to distinguish from other stages. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "0P..|..."}, - { name: "cnt_en" , wave: "01..|..0", node: "...."}, - { name: "init" , wave: "0...|...", node: "....", data: "r0"}, - { name: "trap" , wave: "0...|...", node: "....", data: "r1"}, - { name: "pc_en" , wave: "01..|..0"}, - { name: "rs1" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - { name: "rs2" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - { name: "imm" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - { name: "rd" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - ], - edge : [ - "a~>b", "b~>c", "b~>d"] - } - -Interrupts and ecall/ebreak -::::::::::::::::::::::::::: - -External timer interrupts and ecall/ebreak are also one-stage operations with some notable differences. The new PC is fetched from the MTVEC CSR and instead of writing to rd, the MEPC and MTVAL CSR registers are written. All this is handled by serv_state raising the trap signal during the instruction's execution. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "0P..|..."}, - { name: "cnt_en" , wave: "01..|..0", node: "...."}, - { name: "init" , wave: "0...|...", node: "....", data: "r0"}, - { name: "trap" , wave: "1...|...", node: "....", data: "r1"}, - { name: "pc_en" , wave: "01..|..0"}, - { name: "rs1" , wave: "x...|...", node: "...", data: "0 1 ... 30 31"}, - { name: "rs2" , wave: "x...|...", node: "...", data: "0 1 ... 30 31"}, - { name: "imm" , wave: "x...|...", node: "...", data: "0 1 ... 30 31"}, - { name: "rd" , wave: "x...|...", node: "...", data: "0 1 ... 30 31"}, - ], - edge : [ - "a~>b", "b~>c", "b~>d"] - } - -Two-stage operations -:::::::::::::::::::: - -Some operations need to be executed in two stages. In the first stage the operands are read out from the instruction immediate fields and the rs1/rs2 registers. In the second stage rd and the PC are updated with the results from the operation. The operation-specific things happen between the aforementioned stages. SERV has four types of four two-stage operations; memory, shift, slt and branch operations. In all cases the first stage is distinguished by having the init signal raised and only performing reads from the RF. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "0P..|..."}, - { name: "cnt_en" , wave: "01..|..0", node: "...."}, - { name: "init" , wave: "1...|..0", node: "....", data: "r0"}, - { name: "trap" , wave: "0...|...", node: "....", data: "r1"}, - { name: "pc_en" , wave: "0...|..."}, - { name: "rs1" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - { name: "rs2" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - { name: "imm" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - { name: "rd" , wave: "x234|56x", node: "...", data: "0 1 ... 30 31"}, - ], - edge : [ - "a~>b", "b~>c", "b~>d"] - } - - -memory operations -+++++++++++++++++ - -Loads and stores are memory operations. In the init stage, the data address to access is calculated, checked for alignment and stored in serv_bufreg. For stores, the data to write is also shifted into the data register in serv_bufreg2. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "P..|..."}, - { name: "trap" , wave: "0..|...", node: "....", data: "r1"}, - { name: "init" , wave: "1.0|...", node: "....", data: "r0"}, - { name: "cnt_en" , wave: "1.0|.1.", node: ".....d"}, - { name: "cnt_done" , wave: "010|.1.", node: ".a...."}, - { name: "o_dbus_cyc", wave: "0.1|.0.", node: "..b.", data: "0 1 ... 30 31"}, - { name: "i_dbus_ack", wave: "0..|10.", node: "....c", data: "0 1 ... 30 31"}, - { name: "o_dbus_adr", wave: "x.2|.x.", node: "...", data: "address"}, - { name: "rs2" , wave: "33x|...", node: ".e.", data: "d30 d31"}, - { name: "o_dbus_dat", wave: "x.3|.x.", node: "..f", data: "data"}, - { name: "o_dbus_sel", wave: "x.4|.x.", node: "...", data: ["write mask"]}, - { name: "o_dbus_we" , wave: "1..|..."}, - ], - edge : [ - "a~>b", "b~>c", "c~>d", "e~>f"] - } - -If the address has correct alignment, the o_dbus_cyc signal is raised to signal an access on the data bus after the init stage has finished and waits for an incoming i_dbus_ack, and incoming data in case of loads. After an incoming ack, o_dbus_cyc is lowered and stage 2 begins. For stores, the only remaining work in stage 2 is to update the PC. For loads, the incoming data is shifted into rd. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "P..|..."}, - { name: "trap" , wave: "0..|...", node: "....", data: "r1"}, - { name: "init" , wave: "1.0|...", node: "....", data: "r0"}, - { name: "cnt_en" , wave: "1.0|.1.", node: ".....d"}, - { name: "cnt_done" , wave: "010|.1.", node: ".a...."}, - { name: "o_dbus_cyc", wave: "0.1|.0.", node: "..b.", data: "0 1 ... 30 31"}, - { name: "i_dbus_ack", wave: "0..|10.", node: "....c", data: "0 1 ... 30 31"}, - { name: "o_dbus_adr", wave: "x.2|.x.", node: "...", data: "address"}, - { name: "o_dbus_we" , wave: "0..|..."}, - { name: "i_dbus_rdt", wave: "x..|3x.", node: "....e", data: "data"}, - { name: "rd" , wave: "x..|.33", node: ".....f", data: "d0 d1"}, - ], - edge : [ - "a~>b", "b~>c", "c~>d", "e~>f"] - } - -If the calculated address in the init stage was misaligned, SERV will raise a exception. Instead of performing an external bus access it will set mcause and raise the trap signal, which causes SERV to store the current PC to mepc, store misaligned address to mtval and set the new PC from mtvec which will enter the exception handler. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "P...."}, - { name: "misalign" , wave: "1....", node: "c..", data: ["write mask"]}, - { name: "trap" , wave: "0.1..", node: "..b.", data: "r1"}, - { name: "init" , wave: "1.0..", node: "....", data: "r0"}, - { name: "cnt_en" , wave: "1.01.", node: "...d"}, - { name: "cnt_done" , wave: "010..", node: ".a...."}, - { name: "o_dbus_cyc", wave: "0....", node: "....", data: "0 1 ... 30 31"}, - { name: "i_dbus_ack", wave: "0....", node: "....", data: "0 1 ... 30 31"}, - ], - edge : [ - "a~>b", "c~>b", "b~>d"] - } - -shift operations -++++++++++++++++ - -Left-shifts and right-shifts are handled somewhat differently in SERV. In both cases the data to be shifted (rs1) is stored in serv_bufreg and the shift amount (rs2 or imm) in serv_bufreg2 during the init stage, but after that the methods diverge. - -For left shifts stage two is started immediately during which rd is updated, but data is not shifted out from serv_bufreg2 until the number of cycles corresponding to the shift amount have passed. This effectively "delays" the data written from rs1 into rd, causing a left shift. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "P...|......."}, - { name: "two_stage_op", wave: "1...|.......", node: "....", data: "r1"}, - { name: "shift_op" , wave: "1...|.......", node: "....", data: "r1"}, - { name: "sh_right" , wave: "0...|.......", node: "....", data: "r1"}, - { name: "trap" , wave: "0...|.......", node: "....", data: "r1"}, - { name: "init" , wave: "1.0.|.......", node: "....", data: "r0"}, - { name: "cnt_en" , wave: "1.01|.......", node: "...b."}, - { name: "cnt_done" , wave: "010.|.......", node: ".a....."}, - { name: "shamt" , wave: "x333|.333333", node: "......c.f", data: "N N-1 ... 0 31 30 29 28 27"}, - { name: "sh_done_r" , wave: "0...|...1...", node: "........d.", data: "0 1 ... 30 31"}, - { name: "bufreg_en" , wave: "1.0.|...1...", node: "........e", data: "0 1 ... 30 31"}, - { name: "bufreg_q" , wave: "x.3.|....456", node: "...", data: "d0 d1 d2 d3"}, - { name: "rd" , wave: "x..2|...3456", node: ".....f", data: "0 d0 d1 d2 d3"}, - ], - edge : [ - "a~>b", "c~>d", "c~>d", "d~>e"] - } - -For right shifts, the opposite happens. Data is immediately shifted out from serv_bufreg after stage one ends, but stage two (and writing to rd) doesn't start until shift amount cycles have passed. After all valid data has been written from serv_bufreg, the remaining cycles are zero-padded or sign-extended depending on logical or arithmetic shifts. - -.. wavedrom:: - - { signal: [ - { name: "clk" , wave: "P...|......|..|.."}, - { name: "two_stage_op", wave: "1...|......|..|..", node: "....", data: "r1"}, - { name: "shift_op" , wave: "1...|......|..|..", node: "....", data: "r1"}, - { name: "sh_right" , wave: "1...|......|..|..", node: "....", data: "r1"}, - { name: "trap" , wave: "0...|......|..|..", node: "....", data: "r1"}, - { name: "init" , wave: "1.0.|......|..|..", node: "....", data: "r0"}, - { name: "cnt_en" , wave: "1.0.|...1..|..|.0", node: "........e"}, - { name: "cnt_done" , wave: "010.|......|..|10", node: ".a......."}, - { name: "shamt" , wave: "x333|.3x...|..|..", node: "......c.f", data: "N N-1 ... 0 31 30 29 ... 27"}, - { name: "sh_done_r" , wave: "0...|...1..|..|..", node: "........d.", data: "0 1 ... 30 31"}, - { name: "bufreg_en" , wave: "1.01|......|..|..", node: "...b.....", data: "0 1 ... 30 31"}, - { name: "bufreg_q" , wave: "x.34|567893|45|..", node: "...", data: "d0 ... dN-3 dN-2 dN-1 dN dN+1 ... d31 sign"}, - { name: "rd" , wave: "x...|...893|45|.x", node: ".....f", data: "dN dN+1 ... d31 sign"}, - ], - edge : [ - "a~>b", "c~>d", "c~>d", "d~>e"] - } diff --git a/doc/overview.rst b/doc/overview.rst deleted file mode 100644 index 2d4bad0..0000000 --- a/doc/overview.rst +++ /dev/null @@ -1,42 +0,0 @@ -Overview -======== - -The SERV RISC-V CPU is an award-winning and highly compact processor core based on the RISC-V instruction set architecture (ISA). It is designed to be the smallest possible RISC-V compliant CPU and is particularly well-suited for embedded systems and applications where silicon area is critical. - -Key Features ------------- - -* **ISA:** RISC-V RV32IZifencei -* **Optional ISA extensions:** C, M, Zicsr -* **Optional features:** Timer interrupts, Extension interface -* **Architecture:** Bit-serial (one bit processed per clock cycle) -* **License:** ISC (available under other commercial licenses upon request) -* **OS support:** Zephyr 3.7 -* **SW support:** Compatible with standard RISC-V toolchains -* **Area:** Smallest RISC-V core available - -Applications ------------- - -* **Embedded Systems:** Ideal for minimalistic embedded control tasks -* **IoT Devices:** Suitable for Internet of Things devices where space and power are limited -* **Education:** Excellent resource for teaching and understanding the RISC-V architecture and CPU design -* **Research:** Platform for research in minimalistic computing designs and for bringing up new fabrication processes - -Area ----- - -.. list-table:: Area for minimal configuration [#]_ - :widths: 25 25 25 25 - :header-rows: 1 - - * - Lattice iCE40 - - Altera Cyclone10LP - - AMD Artix-7 - - CMOS - * - 198LUT/164FF - - 239LUT/164FF - - 125LUT/164FF - - 2.1kGE - -.. [#] Excluding register file diff --git a/doc/requirements.txt b/doc/requirements.txt deleted file mode 100644 index 5ed235f..0000000 --- a/doc/requirements.txt +++ /dev/null @@ -1 +0,0 @@ -git+https://github.com/bavovanachte/sphinx-wavedrom@master#egg=sphinxcontrib-wavedrom diff --git a/doc/reservoir.rst b/doc/reservoir.rst deleted file mode 100644 index 9a9d0a3..0000000 --- a/doc/reservoir.rst +++ /dev/null @@ -1,12 +0,0 @@ -************************** -Building systems with SERV -************************** - -A CPU is only as good as its ecosystem. In order to make use of SERV, it needs to be combined with other components such as memories, accelerators and peripheral controllers. - -Welcome to the reservoir, a pool of ready-made designs and subsystems for different purposes that you can use to quickly get started with SERV or integrate it into larger designs. - -.. include:: servile.rst -.. include:: serving.rst -.. include:: servant.rst -.. include:: subservient.rst diff --git a/doc/serv_alu.png b/doc/serv_alu.png deleted file mode 100644 index 33f0828..0000000 Binary files a/doc/serv_alu.png and /dev/null differ diff --git a/doc/serv_alu_int.png b/doc/serv_alu_int.png deleted file mode 100644 index a58ca45..0000000 Binary files a/doc/serv_alu_int.png and /dev/null differ diff --git a/doc/serv_bufreg.png b/doc/serv_bufreg.png deleted file mode 100644 index de008c8..0000000 Binary files a/doc/serv_bufreg.png and /dev/null differ diff --git a/doc/serv_bufreg2.png b/doc/serv_bufreg2.png deleted file mode 100644 index c3cd073..0000000 Binary files a/doc/serv_bufreg2.png and /dev/null differ diff --git a/doc/serv_bufreg2_int.png b/doc/serv_bufreg2_int.png deleted file mode 100644 index b49fc0a..0000000 Binary files a/doc/serv_bufreg2_int.png and /dev/null differ diff --git a/doc/serv_bufreg_int.png b/doc/serv_bufreg_int.png deleted file mode 100644 index 82294ee..0000000 Binary files a/doc/serv_bufreg_int.png and /dev/null differ diff --git a/doc/serv_csr.png b/doc/serv_csr.png deleted file mode 100644 index 4288eea..0000000 Binary files a/doc/serv_csr.png and /dev/null differ diff --git a/doc/serv_csr_int.png b/doc/serv_csr_int.png deleted file mode 100644 index 5f5a093..0000000 Binary files a/doc/serv_csr_int.png and /dev/null differ diff --git a/doc/serv_ctrl.png b/doc/serv_ctrl.png deleted file mode 100644 index d364776..0000000 Binary files a/doc/serv_ctrl.png and /dev/null differ diff --git a/doc/serv_ctrl_int.png b/doc/serv_ctrl_int.png deleted file mode 100644 index f017a6a..0000000 Binary files a/doc/serv_ctrl_int.png and /dev/null differ diff --git a/doc/serv_dataflow.png b/doc/serv_dataflow.png deleted file mode 100644 index 3e5abe9..0000000 Binary files a/doc/serv_dataflow.png and /dev/null differ diff --git a/doc/serv_decode.png b/doc/serv_decode.png deleted file mode 100644 index 596073f..0000000 Binary files a/doc/serv_decode.png and /dev/null differ diff --git a/doc/serv_decode_int.png b/doc/serv_decode_int.png deleted file mode 100644 index 9cf1e79..0000000 Binary files a/doc/serv_decode_int.png and /dev/null differ diff --git a/doc/serv_immdec.png b/doc/serv_immdec.png deleted file mode 100644 index f0ff1d9..0000000 Binary files a/doc/serv_immdec.png and /dev/null differ diff --git a/doc/serv_immdec_int.png b/doc/serv_immdec_int.png deleted file mode 100644 index 1236b5b..0000000 Binary files a/doc/serv_immdec_int.png and /dev/null differ diff --git a/doc/serv_mem_if.png b/doc/serv_mem_if.png deleted file mode 100644 index a796689..0000000 Binary files a/doc/serv_mem_if.png and /dev/null differ diff --git a/doc/serv_mem_if_int.png b/doc/serv_mem_if_int.png deleted file mode 100644 index b410ff7..0000000 Binary files a/doc/serv_mem_if_int.png and /dev/null differ diff --git a/doc/serv_rf_if.png b/doc/serv_rf_if.png deleted file mode 100644 index ae54de5..0000000 Binary files a/doc/serv_rf_if.png and /dev/null differ diff --git a/doc/serv_rf_if_int.png b/doc/serv_rf_if_int.png deleted file mode 100644 index dcfbed2..0000000 Binary files a/doc/serv_rf_if_int.png and /dev/null differ diff --git a/doc/serv_rf_top.png b/doc/serv_rf_top.png deleted file mode 100644 index 97ff3d8..0000000 Binary files a/doc/serv_rf_top.png and /dev/null differ diff --git a/doc/serv_top.png b/doc/serv_top.png deleted file mode 100644 index 3559967..0000000 Binary files a/doc/serv_top.png and /dev/null differ diff --git a/doc/servant.png b/doc/servant.png deleted file mode 100644 index 61b1928..0000000 Binary files a/doc/servant.png and /dev/null differ diff --git a/doc/servant.rst b/doc/servant.rst deleted file mode 100644 index e5061bf..0000000 --- a/doc/servant.rst +++ /dev/null @@ -1,293 +0,0 @@ -Servant : FPGA Reference platform -================================= - -.. figure:: servant.png - - Servant FPGA Reference platform - -SERV comes with a small FPGA-focused reference platform called Servant, which is capable of running Zephyr RTOS, the regression test suite and other software. The platform consists of SERV, a timer, memory and a 1-bit GPIO output pin. - -Available targets ------------------ - -The servant SoC has been ported to an increasing number of different FPGA boards and is easy to modify for new targets. To see all currently supported targets run: - - fusesoc core show servant - -By default, these targets have the program memory preloaded with a small Zephyr hello world example that writes its output on a UART pin. Don't forget to install the appropriate toolchain (e.g. icestorm, Vivado, Quartus...) and add to your PATH - -Some targets also depend on functionality in the FuseSoC base library (fusesoc-cores). Running `fusesoc library list` should tell you if fusesoc-cores is already available. If not, add it to your workspace with - - fusesoc library add fusesoc-cores https://github.com/fusesoc/fusesoc-cores - -Now we're ready to build. Note, for all the cases below, it's possible to run with `--memfile=$SERV/sw/blinky.hex` -(or any other suitable program) as the last argument to preload the LED blink example -instead of hello world. - -AC701 -^^^^^ - - fusesoc run --target=ac701 servant - -Alchistry AU -^^^^^^^^^^^^ - - fusesoc run --target=alchistry_au servant - - -Alhambra II -^^^^^^^^^^^ - -Pin 61 is used for UART output with 115200 baud rate. This pin is connected to a FT2232H chip in board, that manages the communications between the FPGA and the computer. - - fusesoc run --target=alhambra servant - iceprog -d i:0x0403:0x6010:0 build/servant_1.0.1/alhambra-icestorm/servant_1.0.1.bin - -Alinx ax309 (Spartan6 LX9) -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Pin D12 (the on-board RS232 TX pin) is used for UART output with 115200 baud rate and wired to Pin P4 (LED0). - - fusesoc run --target=ax309 servant - -Arty A7 35T -^^^^^^^^^^^ - -Pin D10 (uart_rxd_out) is used for UART output with 57600 baud rate (to use -blinky.hex change D10 to H5 (led[4]) in data/arty_a7_35t.xdc). - - fusesoc run --target=arty_a7_35t servant - -Arty S7 50T -^^^^^^^^^^^ - -Pin R12 (uart_rxd_out) is used for UART output with 57600 baud rate (to use -blinky.hex change R12 to E18 (led[4]) in data/arty_s7_50t.xdc). - - fusesoc run --target=arty_s7_50t servant - -Chameleon96 (Arrow 96 CV SoC Board) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -FPGA Pin W14 (1V8, pin 5 low speed connector) is used for UART Tx output with 115200 baud rate. No reset key. Yellow Wifi led is q output. - - fusesoc run --target=chameleon96 servant - -CMOD A7 35t -^^^^^^^^^^^ - -FPGA Pin J18 is used for UART output with 57600 baud rate. btn0 is used for reset. - - fusesoc run --target=cmod_a7_35t servant - -CYC1000 -^^^^^^^ - - fusesoc run --target=cyc1000 servant - -DE0 Nano -^^^^^^^^ - -FPGA Pin D11 (Connector JP1, pin 38) is used for UART output with 57600 baud rate. DE0 Nano needs an external 3.3V UART to connect to this pin - - fusesoc run --target=de0_nano servant - -DE10 Nano -^^^^^^^^^ - -FPGA Pin Y15 (Connector JP7, pin 1) is used for UART output with 57600 baud rate. DE10 Nano needs an external 3.3V UART to connect to this pin - - fusesoc run --target=de10_nano servant - - -DE1 SoC revF -^^^^^^^^^^^^ - -FPGA PIN_AC18 (Connector GPIO0, pin 0) is used for UART output with 57600 baud rate. DE1 SoC revF needs an external 3.3V UART to connect to this pin. The UART pin has not been tested. - - fusesoc run --target=de1_soc_revF servant - -DECA development kit -^^^^^^^^^^^^^^^^^^^^ - -FPGA Pin W18 (Pin 3 P8 connector) is used for UART output with 57600 baud rate. Key 0 is reset and Led 0 q output. - - fusesoc run --target=deca servant - -EBAZ4205 'Development' Board -^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Pin B20 is used for UART output with 57600 baud rate. To use `blinky.hex` -change B20 to W14 (red led) in `data/ebaz4205.xdc` file). - - fusesoc run --target=ebaz4205 servant - - fusesoc run --target=ebaz4205 servant --memfile=$SERV/sw/blinky.hex - -Reference: https://github.com/fusesoc/blinky#ebaz4205-development-board - -ECP5 EVN -^^^^^^^^ - - fusesoc run --target=ecp5_evn servant - -Icebreaker -^^^^^^^^^^ - -Pin 9 is used for UART output with 57600 baud rate. - - fusesoc run --target=icebreaker servant - -iCEstick -^^^^^^^^ - -Pin 95 is used as the GPIO output which is connected to the board's green LED. Due to this board's limited Embedded BRAM, programs with a maximum of 7168 bytes can be loaded. The default program for this board is blinky.hex. - - fusesoc run --target=icestick servant - iceprog build/servant_1.3.0/icestick-icestorm/servant_1.3.0.bin - -iCESugar -^^^^^^^^ - -Pin 6 is used for UART output with 115200 baud rate. Thanks to the onboard -debugger, you can just connect the USB Type-C connector to the PC, and a -serial console will show up. - - fusesoc run --target=icesugar servant - -ICE-V Wireless -^^^^^^^^^^^^^^ - -Pin 9 is used for UART output with 57600 baud rate. - - fusesoc run --target=icev_wireless servant - - iceprog build/servant_1.3.0/icestick-icestorm/servant_1.3.0.bin - -GMM7550 -^^^^^^^ - - fusesoc run --target=gmm7550 servant - -LX9 Microboard -^^^^^^^^^^^^^^ - - fusesoc run --target=lx9_microboard servant - -Machdyne Kolibri -^^^^^^^^^^^^^^^^ - -Pin B1 is used for UART output with 115200 baud rate. The serial port on Kolibri is accessible as a USB-CDC device. - - fusesoc run --target=machdyne_kolibri servant - - ldprog -Ks build/servant_1.3.0/machdyne_kolibri-icestorm/servant_1.3.0.bin - -MAX10 10M08 Evaluation Kit -^^^^^^^^^^^^^^^^^^^^^^^^^^ - -FPGA Pin 75 (Arduino_IO01 J5 pin 7) is used for UART output with 57600 baud rate. SW1 is reset and Led 1 q output. - - fusesoc run --target=max10_10m08evk servant - -Nandland Go Board -^^^^^^^^^^^^^^^^^ - -Pin 56 is used as the GPIO output which is connected to the board's LED1. Due to this board's limited Embedded BRAM, programs with a maximum of 7168 bytes can be loaded. The default program for this board is blinky.hex. - - fusesoc run --target=go_board servant - iceprog build/servant_1.3.0/go_board-icestorm/servant_1.3.0.bin - -Nexys 2 -^^^^^^^ - -Pmod pin JA1 is connected to UART tx with 57600 baud rate. A USB to TTL connector is used to display to hello world message on the serial monitor. -(To use blinky.hex change L15 to J14 (led[0]) in data/nexys_2.ucf). - - fusesoc run --target=nexys_2_500 servant --uart_baudrate=57600 --firmware=$SERV/sw/zephyr_hello.hex - - -Nexys A7 -^^^^^^^^ - - fusesoc run --target=nexys_a7 servant - -OrangeCrab R0.2 -^^^^^^^^^^^^^^^ - -Pin D1 is used for UART output with 115200 baud rate. - - fusesoc run --target=orangecrab_r0.2 servant - dfu-util -d 1209:5af0 -D build/servant_1.3.0/orangecrab_r0.2-trellis/servant_1.3.0.bit - -PolarFire Splash Kit -^^^^^^^^^^^^^^^^^^^^ - -Pin R5 is used for UART output with a 115200 baud rate, this is routed through -the onboard FTDI transceiver. LED1 (Pin P7) serves as the generic GPIO. - -Pin P8 is used as the GPIO heartbeat with a 1Hz frequency and is connected to -the board's LED2. - -Pin N4 (user reset) is used for the reset - - fusesoc run --target=polarfire_splashkit servant --memfile=$SERV/sw/zephyr_hello.hex - -Saanlima Pipistrello (Spartan6 LX45) -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Pin A10 (usb_data<1>) is used for UART output with 57600 baud rate (to use -blinky.hex change A10 to V16 (led[0]) in data/pipistrello.ucf). - - fusesoc run --target=pipistrello servant - -SoCKit development kit -^^^^^^^^^^^^^^^^^^^^^^ - -FPGA Pin F14 (HSTC GPIO addon connector J2, pin 2) is used for UART output with 57600 baud rate. - - fusesoc run --target=sockit servant - -Trenz Electronic TE0802 -^^^^^^^^^^^^^^^^^^^^^^^ - -PMOD A marked J5, pin two, on the board is used for UART output with 115200 baud rate. - - fusesoc run --target=te0802 servant - -TinyFPGA BX -^^^^^^^^^^^ - -Pin A6 is used for UART output with 115200 baud rate. - - fusesoc run --target=tinyfpga_bx servant - tinyprog --program build/servant_1.0.1/tinyfpga_bx-icestorm/servant_1.0.1.bin - -ULX3S -^^^^^ - - fusesoc run --target=ulx3s servant - -Upduino2 -^^^^^^^^ - - fusesoc run --target=upduino2 servant - -zcu106 -^^^^^^ - - fusesoc run --target=zcu106 servant - -Porting Servant to a new target -------------------------------- - -Mostly any FPGA board can be used to run the Servant SoC. In its simplest form it just needs an FPGA with a clock input and an output that can be used to connect an UART or a LED. - -The porting process consists of FIXME steps. -We will use `` as a placeholder for the name of the FPGA board. -1. Locate the pins used for clock input and for the outputs. Outputs should preferably be both a LED and an UART, but either works if not both are available. Optionally, locate an input pin connected to the reset as well. This is not required, but can be handy. -2. Write a pin constraints file with your located pins in the format of the FPGA toolchain you intend to use. For Vivado this would be an .xdc file. For Quartus a .tcl file, for nextpnr a .pcf file and so on. Save this as `data/.{pcf,ucf,xdc...}` in the SERV repo. -3. Create a clock generation file -4. Create a top-level -5. Create a fileset -6. Create a target diff --git a/doc/servile.png b/doc/servile.png deleted file mode 100644 index 825ba2f..0000000 Binary files a/doc/servile.png and /dev/null differ diff --git a/doc/servile.rst b/doc/servile.rst deleted file mode 100644 index a7c4bc2..0000000 --- a/doc/servile.rst +++ /dev/null @@ -1,166 +0,0 @@ -Servile : Convenience wrapper -============================= - -.. figure:: servile.png - - Servile convenience wrapper - -Servile is a helper component that takes care of common configuration and is used as a building block in the other designs and subsystems. It exposes a memory bus intended to be connected to a combined data and instruction memory, an extension bus for peripheral controllers and accelerators and an RF interface for connecting to an SRAM for GPR and CSR registers. - -.. figure:: servile_int.png - - Servile block diagram - -Internally, Servile contains logic for optionally instantiating an MDU core for the M extension, an arbiter to route instruction fetches and main memory accesses through the same interface and a mux to split up the memory map into memory (0x00000000-0x3FFFFFFF) and external accesses (0x40000000-0xFFFFFFFF). The mux also contains simulation-only logic to write output to a log file and stop the simulation. - -Parameters ----------- - -.. list-table:: Parameters - :header-rows: 1 - :widths: 10 20 80 - - * - Parameter - - Values - - Description - * - reset_pc - - 0x00000000 (default) - 0xFFFFFFFC - - Address of first instruction to fetch from memory after reset (Reset vector) - * - reset_strategy - - "MINI" (default), "NONE" - - | Amount of reset applied to design - | "NONE" : No reset at all. Relies on a POR to set correct initialization values and that core isn't reset during runtime - | "MINI" : Standard setting. Resets the minimal amount of FFs needed to restart execution from the instruction at RESET_PC. - * - rf_width - - 2 (default), 4, 8, 16, 32 - - Width of the data bus to the RF memory. Typically smaller values use less resources, but can be implementation-dependant. - * - sim - - 0 (default), 1 - - | Enable simulation mode. In simulation mode, two memory addresses have special purposes. - | 0x80000000: Writes to this address puts the byte in the lowest data byte into a log file decided by the "signature" plusarg. - | 0x90000000: Writes to this address ends the simulation. - * - with_c - - 0 (default), 1 - - Enable the C extension. This also makes SERV support misaligned loads and stores. - * - with_csr - - 0 (default), 1 - - Enable the Zicsr extension. This also enables timer IRQ and exception handling. Note that SERV only implements a small subset of the CSR registers. - * - with_mdu - - 0 (default), 1 - - Enables the Multiplication and Division Unit (MDU) to support the M extension. Note that this only enables the interface and the decoder logic. The MDU itself is external from SERV. - -Signals -------- - -.. list-table:: Signals - :header-rows: 1 - :widths: 30 10 5 75 - - * - Signal - - Width - - Direction - - Description - * - i_clk - - 1 - - in - - Clock - * - i_rst - - 1 - - in - - Synchronous reset - * - i_timer_irq - - 1 - - in - - Timer interrupt - * - **Memory interface** - - - - - - Connect to instruction/data memory - * - o_wb_mem_adr - - 32 - - out - - Memory bus address - * - o_wb_mem_dat - - 32 - - out - - Memory bus data - * - o_wb_mem_sel - - 4 - - out - - Memory bus write data byte select mask - * - o_wb_mem_we - - 1 - - out - - Memory bus write transaction - * - o_wb_mem_stb - - 1 - - out - - Memory bus active strobe - * - i_wb_mem_rdt - - 32 - - in - - Memory bus read data - * - i_wb_mem_ack - - 1 - - in - - Memory bus cycle acknowledged - * - **Extension interface** - - - - - - Connect to peripheral controllers - * - o_wb_ext_adr - - 32 - - out - - Data bus address - * - o_wb_ext_dat - - 32 - - out - - Data bus write data - * - o_wb_ext_sel - - 4 - - out - - Data bus write data byte select mask - * - o_wb_ext_we - - 1 - - out - - Data bus write transaction - * - o_wb_ext_stb - - 1 - - out - - Data bus active cycle - * - i_wb_ext_rdt - - 32 - - in - - Data bus return data - * - i_wb_ext_ack - - 1 - - in - - Data bus return data valid - * - **RF (SRAM) interface** - - - - - - - * - o_rf_waddr - - ceil(log2(regs*32/rf_width) - - out - - RF memory write address - * - o_rf_wdata - - rf_width - - out - - RF memory write data - * - o_rf_wen - - 1 - - out - - RF memory write enable - * - o_rf_raddr - - ceil(log2(regs*32/rf_width) - - out - - RF memory read address - * - i_rf_rdata - - rf_width - - out - - RF memory read data - * - o_rf_ren - - 1 - - out - - RF memory read enable diff --git a/doc/servile_int.png b/doc/servile_int.png deleted file mode 100644 index 49277cd..0000000 Binary files a/doc/servile_int.png and /dev/null differ diff --git a/doc/serving.png b/doc/serving.png deleted file mode 100644 index 338106c..0000000 Binary files a/doc/serving.png and /dev/null differ diff --git a/doc/serving.rst b/doc/serving.rst deleted file mode 100644 index e80ae52..0000000 --- a/doc/serving.rst +++ /dev/null @@ -1,94 +0,0 @@ -Serving : FPGA subsystem -======================== - -.. figure:: serving.png - - Serving SoClet - -Serving is ideal for FPGA implementations as it only uses a single combined block RAM for instructions, data and RF that can be preloaded with a RISC-V application. It exposes a wishbone data bus that can be used to connect peripheral controllers. - -Parameters ----------- - -.. list-table:: Parameters - :header-rows: 1 - :widths: 10 20 80 - - * - Parameter - - Values - - Description - * - memfile - - "" (default) - - Verilog hex file containing a RISC-V application to be preloaded into memory - * - memsize - - 1-4294967296 (default 8192) - - Size of memory (in bytes). Needs to be at least large enough to fit the application supplied by memsize. Note that the RF occupies the highest 128 bytes of memory in the RAM. - * - sim - - 0 (default), 1 - - | Enable simulation mode. In simulation mode, two memory addresses have special purposes. - | 0x80000000: Writes to this address puts the byte in the lowest data byte into a log file decided by the "signature" plusarg. - | 0x90000000: Writes to this address ends the simulation. - * - RESET_STRATEGY - - "MINI" (default), "NONE" - - | Amount of reset applied to design - | "NONE" : No reset at all. Relies on a POR to set correct initialization values and that core isn't reset during runtime - | "MINI" : Standard setting. Resets the minimal amount of FFs needed to restart execution from the instruction at RESET_PC. - * - WITH_CSR - - 0 (default), 1 - - Enable the Zicsr extension. This also enables timer IRQ and exception handling. Note that SERV only implements a small subset of the CSR registers. - -Signals -------- - -.. list-table:: Signals - :header-rows: 1 - :widths: 30 10 5 75 - - * - Signal - - Width - - Direction - - Description - * - i_clk - - 1 - - in - - Clock - * - i_rst - - 1 - - in - - Synchronous reset - * - i_timer_irq - - 1 - - in - - Timer interrupt - * - **Extension interface** - - - - - - Connect to peripheral controllers - * - o_wb_adr - - 32 - - out - - Data bus address - * - o_wb_dat - - 32 - - out - - Data bus write data - * - o_wb_sel - - 4 - - out - - Data bus write data byte select mask - * - o_wb_we - - 1 - - out - - Data bus write transaction - * - o_wb_cyc - - 1 - - out - - Data bus active cycle - * - i_wb_rdt - - 32 - - in - - Data bus return data - * - i_wb_ack - - 1 - - in - - Data bus return data valid diff --git a/doc/subservient.png b/doc/subservient.png deleted file mode 100644 index 21589c3..0000000 Binary files a/doc/subservient.png and /dev/null differ diff --git a/doc/subservient.rst b/doc/subservient.rst deleted file mode 100644 index e017e17..0000000 --- a/doc/subservient.rst +++ /dev/null @@ -1,10 +0,0 @@ -Subservient : SERV ASIC macro -============================= - -.. figure:: subservient.png - - Subservient ASIC macro - -`Subservient `_ is a minimal reference system that just requires connecting one single-port SRAM for data, instructions and RF. It is intended to make ASIC integration easier. - - diff --git a/riscv-target/serv/compliance_io.h b/riscv-target/serv/compliance_io.h new file mode 100644 index 0000000..65e0148 --- /dev/null +++ b/riscv-target/serv/compliance_io.h @@ -0,0 +1,36 @@ +// RISC-V Compliance IO Test Header File + +/* + * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, + * either express or implied. + * + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +#ifndef _COMPLIANCE_IO_H +#define _COMPLIANCE_IO_H + +//----------------------------------------------------------------------- +// RV IO Macros (Non functional) +//----------------------------------------------------------------------- + +#define RVTEST_IO_INIT +#define RVTEST_IO_WRITE_STR(_STR) +#define RVTEST_IO_CHECK() +#define RVTEST_IO_ASSERT_GPR_EQ(_R, _I) +#define RVTEST_IO_ASSERT_SFPR_EQ(_F, _R, _I) +#define RVTEST_IO_ASSERT_DFPR_EQ(_D, _R, _I) + +#endif // _COMPLIANCE_IO_H diff --git a/riscv-target/serv/compliance_test.h b/riscv-target/serv/compliance_test.h new file mode 100644 index 0000000..512793b --- /dev/null +++ b/riscv-target/serv/compliance_test.h @@ -0,0 +1,67 @@ +// RISC-V Compliance Test Header File +// Copyright (c) 2017, Codasip Ltd. All Rights Reserved. +// See LICENSE for license details. +// +// Description: Common header file for RV32I tests + +#ifndef _COMPLIANCE_TEST_H +#define _COMPLIANCE_TEST_H + +//----------------------------------------------------------------------- +// RV Compliance Macros +//----------------------------------------------------------------------- + +#define RV_COMPLIANCE_HALT \ +la a0, data_begin; \ + la a1, data_end; \ + li a2, 0x80000000; \ +complience_halt_loop: \ + beq a0, a1, complience_halt_break; \ + addi a3, a0, 4; \ +complience_halt_loop2: \ + addi a3, a3, -1; \ + \ + lb a4, 0 (a3); \ + srai a5, a4, 4; \ + andi a5, a5, 0xF; \ + li a6, 10; \ + blt a5, a6, notLetter; \ + addi a5, a5, 39; \ +notLetter: \ + addi a5, a5, 0x30; \ + sw a5, 0 (a2); \ + \ + srai a5, a4, 0; \ + andi a5, a5, 0xF; \ + li a6, 10; \ + blt a5, a6, notLetter2; \ + addi a5, a5, 39; \ +notLetter2: \ + addi a5, a5, 0x30; \ + sw a5, 0 (a2); \ + bne a0, a3,complience_halt_loop2; \ + addi a0, a0, 4; \ + \ + li a4, '\n'; \ + sw a4, 0 (a2); \ + j complience_halt_loop; \ + j complience_halt_break; \ +complience_halt_break:; \ + lui a0,0x90000000>>12; \ + sw a3,0(a0); + +#define RV_COMPLIANCE_RV32M + +#define RV_COMPLIANCE_CODE_BEGIN \ + .section .text.init; \ + .align 4; \ + .globl _start; \ +_start: \ + +#define RV_COMPLIANCE_CODE_END + +#define RV_COMPLIANCE_DATA_BEGIN .align 4; .global data_begin; data_begin: + +#define RV_COMPLIANCE_DATA_END .align 4; .global data_end; data_end: + +#endif diff --git a/riscv-target/serv/device/rv32i/Makefile.include b/riscv-target/serv/device/rv32i/Makefile.include new file mode 100644 index 0000000..9ef57a7 --- /dev/null +++ b/riscv-target/serv/device/rv32i/Makefile.include @@ -0,0 +1,26 @@ +TARGET_SIM ?= server +ifeq ($(shell command -v $(TARGET_SIM) 2> /dev/null),) + $(error Target simulator executable '$(TARGET_SIM)` not found) +endif + +RUN_TARGET=\ + $(TARGET_SIM) \ + +timeout=100000000 \ + +signature=$(work_dir_isa)/$(*).signature.output \ + +firmware=$(work_dir_isa)/$<.hex 2> $(work_dir_isa)/$@ + +RISCV_PREFIX ?= riscv32-unknown-elf- +RISCV_GCC ?= $(RISCV_PREFIX)gcc +RISCV_OBJCOPY ?= $(RISCV_PREFIX)objcopy +RISCV_OBJDUMP ?= $(RISCV_PREFIX)objdump +RISCV_GCC_OPTS ?= -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles + +COMPILE_TARGET=\ + $$(RISCV_GCC) $(2) $$(RISCV_GCC_OPTS) \ + -I$(ROOTDIR)/riscv-test-env/ \ + -I$(TARGETDIR)/$(RISCV_TARGET)/ \ + -T$(TARGETDIR)/$(RISCV_TARGET)/link.ld $$< \ + -o $(work_dir_isa)/$$@; \ + $$(RISCV_OBJCOPY) -O binary $(work_dir_isa)/$$@ $(work_dir_isa)/$$@.bin; \ + $$(RISCV_OBJDUMP) -D $(work_dir_isa)/$$@ > $(work_dir_isa)/$$@.objdump; \ + python3 $(TARGETDIR)/$(RISCV_TARGET)/makehex.py $(work_dir_isa)/$$@.bin 2048 > $(work_dir_isa)/$$@.hex; diff --git a/verif/plugin-sail_cSim/env/link.ld b/riscv-target/serv/link.ld similarity index 86% rename from verif/plugin-sail_cSim/env/link.ld rename to riscv-target/serv/link.ld index 8ad95e0..db7be33 100644 --- a/verif/plugin-sail_cSim/env/link.ld +++ b/riscv-target/serv/link.ld @@ -1,9 +1,9 @@ OUTPUT_ARCH( "riscv" ) -ENTRY(rvtest_entry_point) +ENTRY(_start) SECTIONS { - . = 0x80000000; + . = 0x00000000; .text.init : { *(.text.init) } . = ALIGN(0x1000); .tohost : { *(.tohost) } diff --git a/riscv-target/serv/makehex.py b/riscv-target/serv/makehex.py new file mode 100644 index 0000000..419b378 --- /dev/null +++ b/riscv-target/serv/makehex.py @@ -0,0 +1,27 @@ +#!/usr/bin/env python3 +# +# This is free and unencumbered software released into the public domain. +# +# Anyone is free to copy, modify, publish, use, compile, sell, or +# distribute this software, either in source code form or as a compiled +# binary, for any purpose, commercial or non-commercial, and by any +# means. + +from sys import argv + +binfile = argv[1] +nwords = int(argv[2]) + +with open(binfile, "rb") as f: + bindata = f.read() + +assert len(bindata) < 4*nwords +assert len(bindata) % 4 == 0 + +for i in range(nwords): + if i < len(bindata) // 4: + w = bindata[4*i : 4*i+4] + print("%02x%02x%02x%02x" % (w[3], w[2], w[1], w[0])) + else: + print("0") + diff --git a/rtl/ser_shift.v b/rtl/ser_shift.v new file mode 100644 index 0000000..8ec995b --- /dev/null +++ b/rtl/ser_shift.v @@ -0,0 +1,30 @@ +`default_nettype none +module ser_shift + ( + input wire i_clk, + input wire i_load, + input wire [4:0] i_shamt, + input wire i_shamt_msb, + input wire i_signbit, + input wire i_right, + output wire o_done, + input wire i_d, + output wire o_q); + + reg signbit; + reg [5:0] cnt; + reg wrapped; + + always @(posedge i_clk) begin + cnt <= cnt + 6'd1; + if (i_load) begin + cnt <= 6'd0; + signbit <= i_signbit & i_right; + end + wrapped <= cnt[5] | (i_shamt_msb & !i_right); + end + + assign o_done = (cnt[4:0] == i_shamt); + assign o_q = (i_right^wrapped) ? i_d : signbit; + +endmodule diff --git a/rtl/serv_aligner.v b/rtl/serv_aligner.v deleted file mode 100644 index 9f9f9d1..0000000 --- a/rtl/serv_aligner.v +++ /dev/null @@ -1,67 +0,0 @@ -module serv_aligner - ( - input wire clk, - input wire rst, - // serv_top - input wire [31:0] i_ibus_adr, - input wire i_ibus_cyc, - output wire [31:0] o_ibus_rdt, - output wire o_ibus_ack, - // serv_rf_top - output wire [31:0] o_wb_ibus_adr, - output wire o_wb_ibus_cyc, - input wire [31:0] i_wb_ibus_rdt, - input wire i_wb_ibus_ack); - - wire [31:0] ibus_rdt_concat; - wire ack_en; - - reg [15:0] lower_hw; - reg ctrl_misal ; - - /* From SERV core to Memory - - o_wb_ibus_adr: Carries address of instruction to memory. In case of misaligned access, - which is caused by pc+2 due to compressed instruction, next instruction is fetched - by pc+4 and concatenation is done to make the instruction aligned. - - o_wb_ibus_cyc: Simply forwarded from SERV to Memory and is only altered by memory or SERV core. - */ - assign o_wb_ibus_adr = ctrl_misal ? (i_ibus_adr+32'b100) : i_ibus_adr; - assign o_wb_ibus_cyc = i_ibus_cyc; - - /* From Memory to SERV core - - o_ibus_ack: Instruction bus acknowledge is send to SERV only when the aligned instruction, - either compressed or un-compressed, is ready to dispatch. - - o_ibus_rdt: Carries the instruction from memory to SERV core. It can be either aligned - instruction coming from memory or made aligned by two bus transactions and concatenation. - */ - assign o_ibus_ack = i_wb_ibus_ack & ack_en; - assign o_ibus_rdt = ctrl_misal ? ibus_rdt_concat : i_wb_ibus_rdt; - - /* 16-bit register used to hold the upper half word of the current instruction in-case - concatenation will be required with the upper half word of upcoming instruction - */ - always @(posedge clk) begin - if(i_wb_ibus_ack)begin - lower_hw <= i_wb_ibus_rdt[31:16]; - end - end - - assign ibus_rdt_concat = {i_wb_ibus_rdt[15:0],lower_hw}; - - /* Two control signals: ack_en, ctrl_misal are set to control the bus transactions between - SERV core and the memory - */ - assign ack_en = !(i_ibus_adr[1] & !ctrl_misal); - - always @(posedge clk ) begin - if(rst) - ctrl_misal <= 0; - else if(i_wb_ibus_ack & i_ibus_adr[1]) - ctrl_misal <= !ctrl_misal; - end - -endmodule diff --git a/rtl/serv_alu.v b/rtl/serv_alu.v index 62755aa..f5c5ea4 100644 --- a/rtl/serv_alu.v +++ b/rtl/serv_alu.v @@ -1,81 +1,113 @@ `default_nettype none module serv_alu - #( - parameter W = 1, - parameter B = W-1 - ) ( input wire clk, - //State + input wire i_rst, input wire i_en, - input wire i_cnt0, - output wire o_cmp, - //Control + input wire i_rs1, + input wire i_rs2, + input wire i_imm, + input wire i_op_b_rs2, + input wire i_buf, + input wire i_init, + input wire i_cnt_done, input wire i_sub, input wire [1:0] i_bool_op, input wire i_cmp_eq, - input wire i_cmp_sig, - input wire [2:0] i_rd_sel, - //Data - input wire [B:0] i_rs1, - input wire [B:0] i_op_b, - input wire [B:0] i_buf, - output wire [B:0] o_rd); + input wire i_cmp_uns, + output wire o_cmp, + input wire i_shamt_en, + input wire i_sh_right, + input wire i_sh_signed, + output wire o_sh_done, + input wire [3:0] i_rd_sel, + output wire o_rd); - wire [B:0] result_add; - wire [B:0] result_slt; + wire result_add; + wire result_eq; + wire result_lt; + wire result_sh; - reg cmp_r; + reg result_lt_r; + + wire [4:0] shamt; + reg shamt_msb; + + reg en_r; + wire shamt_ser; + wire plus_1; wire add_cy; - reg [B:0] add_cy_r; + reg add_cy_r; - //Sign-extended operands - wire rs1_sx = i_rs1[B] & i_cmp_sig; - wire op_b_sx = i_op_b[B] & i_cmp_sig; + wire b_inv_plus_1; + wire b_inv_plus_1_cy; + reg b_inv_plus_1_cy_r; - wire [B:0] add_b = i_op_b^{W{i_sub}}; + wire op_b = i_op_b_rs2 ? i_rs2 : i_imm; + assign shamt_ser = i_sh_right ? op_b : b_inv_plus_1; + shift_reg #(.LEN (5)) shamt_reg + (.clk (clk), + .i_rst (i_rst), + .i_en (i_shamt_en), + .i_d (shamt_ser), + .o_q (shamt[0]), + .o_par (shamt[4:1])); + + ser_shift shift + ( + .i_clk (clk), + .i_load (i_init), + .i_shamt (shamt), + .i_shamt_msb (shamt_msb), + .i_signbit (i_sh_signed & i_rs1), + .i_right (i_sh_right), + .o_done (o_sh_done), + .i_d (i_buf), + .o_q (result_sh)); + + wire add_b = i_sub ? b_inv_plus_1 : op_b; assign {add_cy,result_add} = i_rs1+add_b+add_cy_r; + assign {b_inv_plus_1_cy,b_inv_plus_1} = {1'b0,~op_b}+plus_1+b_inv_plus_1_cy_r; - wire result_lt = rs1_sx + ~op_b_sx + add_cy; + reg lt_r; - wire result_eq = !(|result_add) & (cmp_r | i_cnt0); + wire lt_sign = i_cnt_done & !i_cmp_uns; + wire eq = (i_rs1 == op_b); + + assign result_eq = eq & eq_r; + assign result_lt = eq ? lt_r : op_b^lt_sign; + + assign plus_1 = i_en & !en_r; assign o_cmp = i_cmp_eq ? result_eq : result_lt; - /* - The result_bool expression implements the following operations between - i_rs1 and i_op_b depending on the value of i_bool_op + localparam [15:0] BOOL_LUT = 16'h8E96;//And, Or, =, xor + wire result_bool = BOOL_LUT[{i_bool_op, i_rs1, op_b}]; - 00 xor - 01 0 - 10 or - 11 and + assign o_rd = (i_rd_sel[0] & result_add) | + (i_rd_sel[1] & result_sh) | + (i_rd_sel[2] & result_lt_r & plus_1) | + (i_rd_sel[3] & result_bool); - i_bool_op will be 01 during shift operations, so by outputting zero under - this condition we can safely or result_bool with i_buf - */ - wire [B:0] result_bool = ((i_rs1 ^ i_op_b) & ~{W{i_bool_op[0]}}) | ({W{i_bool_op[1]}} & i_op_b & i_rs1); - assign result_slt[0] = cmp_r & i_cnt0; - generate - if (W>1) begin : gen_w_gt_1 - assign result_slt[B:1] = {B{1'b0}}; - end - endgenerate - - assign o_rd = i_buf | - ({W{i_rd_sel[0]}} & result_add) | - ({W{i_rd_sel[1]}} & result_slt) | - ({W{i_rd_sel[2]}} & result_bool); + reg eq_r; always @(posedge clk) begin - add_cy_r <= {W{1'b0}}; - add_cy_r[0] <= i_en ? add_cy : i_sub; + add_cy_r <= i_en & add_cy; + b_inv_plus_1_cy_r <= i_en & b_inv_plus_1_cy; - if (i_en) - cmp_r <= o_cmp; + lt_r <= result_lt & i_en; + + if (i_en) begin + result_lt_r <= result_lt; + end + eq_r <= result_eq | ~i_en; + en_r <= i_en; + + if (i_shamt_en) + shamt_msb <= b_inv_plus_1_cy; end endmodule diff --git a/rtl/serv_bufreg.v b/rtl/serv_bufreg.v index 0dd1cf7..d0d8685 100644 --- a/rtl/serv_bufreg.v +++ b/rtl/serv_bufreg.v @@ -1,65 +1,42 @@ -module serv_bufreg #( - parameter [0:0] MDU = 0, - parameter W = 1, - parameter B = W-1 -)( +module serv_bufreg + ( input wire i_clk, - //State - input wire i_cnt0, - input wire i_cnt1, + input wire [4:2] i_cnt, + input wire [1:0] i_cnt_r, input wire i_en, input wire i_init, - input wire i_mdu_op, - output wire [1:0] o_lsb, - //Control + input wire i_loop, + input wire i_rs1, input wire i_rs1_en, + input wire i_imm, input wire i_imm_en, input wire i_clr_lsb, - input wire i_sh_signed, - //Data - input wire [B:0] i_rs1, - input wire [B:0] i_imm, - output wire [B:0] o_q, - //External - output wire [31:0] o_dbus_adr, - //Extension - output wire [31:0] o_ext_rs1); + output reg [1:0] o_lsb, + output wire [31:0] o_reg, + output wire o_q); - wire c; - wire [B:0] q; - reg [B:0] c_r; - reg [31:0] data; - wire [B:0] clr_lsb; + wire c, q; + reg c_r; + reg [31:0] data; - assign clr_lsb[0] = i_cnt0 & i_clr_lsb; + wire clr_lsb = (i_cnt[4:2] == 3'd0) & i_cnt_r[0] & i_clr_lsb; - assign {c,q} = {1'b0,(i_rs1 & {W{i_rs1_en}})} + {1'b0,(i_imm & {W{i_imm_en}} & ~clr_lsb)} + c_r; + assign {c,q} = {1'b0,(i_rs1 & i_rs1_en)} + {1'b0,(i_imm & i_imm_en & !clr_lsb)} + c_r; always @(posedge i_clk) begin - //Make sure carry is cleared before loading new data - c_r <= {W{1'b0}}; - c_r[0] <= c & i_en; + //Clear carry when not in INIT state + c_r <= c & i_init; + + if (i_en) + data <= {(i_loop & !i_init) ? o_q : q, data[31:1]}; + + if ((i_cnt[4:2] == 3'd0) & i_cnt_r[0] & i_init) + o_lsb[0] <= q; + if ((i_cnt[4:2] == 3'd0) & i_cnt_r[1] & i_init) + o_lsb[1] <= q; end - reg [1:0] lsb; - - generate - if (W == 1) begin : gen_w_eq_1 - always @(posedge i_clk) begin - if (i_en) - data[31:2] <= {i_init ? q : {W{data[31] & i_sh_signed}}, data[31:3]}; - - if (i_init ? (i_cnt0 | i_cnt1) : i_en) - data[1:0] <= {i_init ? q : data[2], data[1]}; - end - always @(*) lsb = data[1:0]; - assign o_q = data[0] & {W{i_en}}; - end - endgenerate - - - assign o_dbus_adr = {data[31:2], 2'b00}; - assign o_ext_rs1 = data; - assign o_lsb = (MDU & i_mdu_op) ? 2'b00 : lsb; + assign o_q = data[0]; + assign o_reg = data; endmodule diff --git a/rtl/serv_bufreg2.v b/rtl/serv_bufreg2.v deleted file mode 100644 index ee25576..0000000 --- a/rtl/serv_bufreg2.v +++ /dev/null @@ -1,82 +0,0 @@ -module serv_bufreg2 - ( - input wire i_clk, - //State - input wire i_en, - input wire i_init, - input wire i_cnt7, - input wire i_cnt_done, - input wire i_sh_right, - input wire [1:0] i_lsb, - input wire [1:0] i_bytecnt, - output wire o_sh_done, - //Control - input wire i_op_b_sel, - input wire i_shift_op, - //Data - input wire i_rs2, - input wire i_imm, - output wire o_op_b, - output wire o_q, - //External - output wire [31:0] o_dat, - input wire i_load, - input wire [31:0] i_dat); - - reg [31:0] dat; - - /* - Before a store operation, the data to be written needs to be shifted into - place. Depending on the address alignment, we need to shift different - amounts. One formula for calculating this is to say that we shift when - i_lsb + i_bytecnt < 4. Unfortunately, the synthesis tools don't seem to be - clever enough so the hideous expression below is used to achieve the same - thing in a more optimal way. - */ - wire byte_valid - = (!i_lsb[0] & !i_lsb[1]) | - (!i_bytecnt[0] & !i_bytecnt[1]) | - (!i_bytecnt[1] & !i_lsb[1]) | - (!i_bytecnt[1] & !i_lsb[0]) | - (!i_bytecnt[0] & !i_lsb[1]); - - assign o_op_b = i_op_b_sel ? i_rs2 : i_imm; - - wire shift_en = i_shift_op ? (i_en & i_init & (i_bytecnt == 2'b00)) : (i_en & byte_valid); - - wire cnt_en = (i_shift_op & (!i_init | (i_cnt_done & i_sh_right))); - - /* The dat register has three different use cases for store, load and - shift operations. - store : Data to be written is shifted to the correct position in dat during - init by shift_en and is presented on the data bus as o_wb_dat - load : Data from the bus gets latched into dat during i_wb_ack and is then - shifted out at the appropriate time to end up in the correct - position in rd - shift : Data is shifted in during init. After that, the six LSB are used as - a downcounter (with bit 5 initially set to 0) that trigger - o_sh_done when they wrap around to indicate that - the requested number of shifts have been performed - */ - wire [5:0] dat_shamt = cnt_en ? - //Down counter mode - dat[29:24]-1 : - //Shift reg mode with optional clearing of bit 5 - {dat[30] & !(i_shift_op & i_cnt7),dat[29:25]}; - - assign o_sh_done = dat_shamt[5]; - - assign o_q = - ((i_lsb == 2'd3) & dat[24]) | - ((i_lsb == 2'd2) & dat[16]) | - ((i_lsb == 2'd1) & dat[8]) | - ((i_lsb == 2'd0) & dat[0]); - - assign o_dat = dat; - - always @(posedge i_clk) begin - if (shift_en | cnt_en | i_load) - dat <= i_load ? i_dat : {o_op_b, dat[31], dat_shamt, dat[24:1]}; - end - -endmodule diff --git a/rtl/serv_compdec.v b/rtl/serv_compdec.v deleted file mode 100644 index a55e445..0000000 --- a/rtl/serv_compdec.v +++ /dev/null @@ -1,232 +0,0 @@ -/* Copyright lowRISC contributors. -Copyright 2018 ETH Zurich and University of Bologna, see also CREDITS.md. -Licensed under the Apache License, Version 2.0, see LICENSE for details. -SPDX-License-Identifier: Apache-2.0 - -* Adapted to SERV by @Abdulwadoodd as part of the project under spring '22 LFX Mentorship program */ - -/* Decodes RISC-V compressed instructions into their RV32i equivalent. */ - -module serv_compdec - ( - input wire i_clk, - input wire [31:0] i_instr, - input wire i_ack, - output wire [31:0] o_instr, - output reg o_iscomp); - - localparam OPCODE_LOAD = 7'h03; - localparam OPCODE_OP_IMM = 7'h13; - localparam OPCODE_STORE = 7'h23; - localparam OPCODE_OP = 7'h33; - localparam OPCODE_LUI = 7'h37; - localparam OPCODE_BRANCH = 7'h63; - localparam OPCODE_JALR = 7'h67; - localparam OPCODE_JAL = 7'h6f; - - reg [31:0] comp_instr; - reg illegal_instr; - - assign o_instr = illegal_instr ? i_instr : comp_instr; - - always @(posedge i_clk) begin - if(i_ack) - o_iscomp <= !illegal_instr; - end - - always @ (*) begin - // By default, forward incoming instruction, mark it as legal. - comp_instr = i_instr; - illegal_instr = 1'b0; - - // Check if incoming instruction is compressed. - case (i_instr[1:0]) - // C0 - 2'b00: begin - case (i_instr[15:14]) - 2'b00: begin - // c.addi4spn -> addi rd', x2, imm - comp_instr = {2'b0, i_instr[10:7], i_instr[12:11], i_instr[5], - i_instr[6], 2'b00, 5'h02, 3'b000, 2'b01, i_instr[4:2], {OPCODE_OP_IMM}}; - end - - 2'b01: begin - // c.lw -> lw rd', imm(rs1') - comp_instr = {5'b0, i_instr[5], i_instr[12:10], i_instr[6], - 2'b00, 2'b01, i_instr[9:7], 3'b010, 2'b01, i_instr[4:2], {OPCODE_LOAD}}; - end - - 2'b11: begin - // c.sw -> sw rs2', imm(rs1') - comp_instr = {5'b0, i_instr[5], i_instr[12], 2'b01, i_instr[4:2], - 2'b01, i_instr[9:7], 3'b010, i_instr[11:10], i_instr[6], - 2'b00, {OPCODE_STORE}}; - end - - 2'b10: begin - illegal_instr = 1'b1; - end - - endcase - end - - // C1 - - // Register address checks for RV32E are performed in the regular instruction decoder. - // If this check fails, an illegal instruction exception is triggered and the controller - // writes the actual faulting instruction to mtval. - 2'b01: begin - case (i_instr[15:13]) - 3'b000: begin - // c.addi -> addi rd, rd, nzimm - // c.nop - comp_instr = {{6 {i_instr[12]}}, i_instr[12], i_instr[6:2], - i_instr[11:7], 3'b0, i_instr[11:7], {OPCODE_OP_IMM}}; - end - - 3'b001, 3'b101: begin - // 001: c.jal -> jal x1, imm - // 101: c.j -> jal x0, imm - comp_instr = {i_instr[12], i_instr[8], i_instr[10:9], i_instr[6], - i_instr[7], i_instr[2], i_instr[11], i_instr[5:3], - {9 {i_instr[12]}}, 4'b0, ~i_instr[15], {OPCODE_JAL}}; - end - - 3'b010: begin - // c.li -> addi rd, x0, nzimm - // (c.li hints are translated into an addi hint) - comp_instr = {{6 {i_instr[12]}}, i_instr[12], i_instr[6:2], 5'b0, - 3'b0, i_instr[11:7], {OPCODE_OP_IMM}}; - end - - 3'b011: begin - // c.lui -> lui rd, imm - // (c.lui hints are translated into a lui hint) - comp_instr = {{15 {i_instr[12]}}, i_instr[6:2], i_instr[11:7], {OPCODE_LUI}}; - - if (i_instr[11:7] == 5'h02) begin - // c.addi16sp -> addi x2, x2, nzimm - comp_instr = {{3 {i_instr[12]}}, i_instr[4:3], i_instr[5], i_instr[2], - i_instr[6], 4'b0, 5'h02, 3'b000, 5'h02, {OPCODE_OP_IMM}}; - end - - end - - 3'b100: begin - case (i_instr[11:10]) - 2'b00, - 2'b01: begin - // 00: c.srli -> srli rd, rd, shamt - // 01: c.srai -> srai rd, rd, shamt - // (c.srli/c.srai hints are translated into a srli/srai hint) - comp_instr = {1'b0, i_instr[10], 5'b0, i_instr[6:2], 2'b01, i_instr[9:7], - 3'b101, 2'b01, i_instr[9:7], {OPCODE_OP_IMM}}; - end - - 2'b10: begin - // c.andi -> andi rd, rd, imm - comp_instr = {{6 {i_instr[12]}}, i_instr[12], i_instr[6:2], 2'b01, i_instr[9:7], - 3'b111, 2'b01, i_instr[9:7], {OPCODE_OP_IMM}}; - end - - 2'b11: begin - case (i_instr[6:5]) - 2'b00: begin - // c.sub -> sub rd', rd', rs2' - comp_instr = {2'b01, 5'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7], - 3'b000, 2'b01, i_instr[9:7], {OPCODE_OP}}; - end - - 2'b01: begin - // c.xor -> xor rd', rd', rs2' - comp_instr = {7'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7], 3'b100, - 2'b01, i_instr[9:7], {OPCODE_OP}}; - end - - 2'b10: begin - // c.or -> or rd', rd', rs2' - comp_instr = {7'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7], 3'b110, - 2'b01, i_instr[9:7], {OPCODE_OP}}; - end - - 2'b11: begin - // c.and -> and rd', rd', rs2' - comp_instr = {7'b0, 2'b01, i_instr[4:2], 2'b01, i_instr[9:7], 3'b111, - 2'b01, i_instr[9:7], {OPCODE_OP}}; - end - endcase - end - endcase - end - - 3'b110, 3'b111: begin - // 0: c.beqz -> beq rs1', x0, imm - // 1: c.bnez -> bne rs1', x0, imm - comp_instr = {{4 {i_instr[12]}}, i_instr[6:5], i_instr[2], 5'b0, 2'b01, - i_instr[9:7], 2'b00, i_instr[13], i_instr[11:10], i_instr[4:3], - i_instr[12], {OPCODE_BRANCH}}; - end - endcase - end - - // C2 - - // Register address checks for RV32E are performed in the regular instruction decoder. - // If this check fails, an illegal instruction exception is triggered and the controller - // writes the actual faulting instruction to mtval. - 2'b10: begin - case (i_instr[15:14]) - 2'b00: begin - // c.slli -> slli rd, rd, shamt - // (c.ssli hints are translated into a slli hint) - comp_instr = {7'b0, i_instr[6:2], i_instr[11:7], 3'b001, i_instr[11:7], {OPCODE_OP_IMM}}; - end - - 2'b01: begin - // c.lwsp -> lw rd, imm(x2) - comp_instr = {4'b0, i_instr[3:2], i_instr[12], i_instr[6:4], 2'b00, 5'h02, - 3'b010, i_instr[11:7], OPCODE_LOAD}; - end - - 2'b10: begin - if (i_instr[12] == 1'b0) begin - if (i_instr[6:2] != 5'b0) begin - // c.mv -> add rd/rs1, x0, rs2 - // (c.mv hints are translated into an add hint) - comp_instr = {7'b0, i_instr[6:2], 5'b0, 3'b0, i_instr[11:7], {OPCODE_OP}}; - end else begin - // c.jr -> jalr x0, rd/rs1, 0 - comp_instr = {12'b0, i_instr[11:7], 3'b0, 5'b0, {OPCODE_JALR}}; - end - end else begin - if (i_instr[6:2] != 5'b0) begin - // c.add -> add rd, rd, rs2 - // (c.add hints are translated into an add hint) - comp_instr = {7'b0, i_instr[6:2], i_instr[11:7], 3'b0, i_instr[11:7], {OPCODE_OP}}; - end else begin - if (i_instr[11:7] == 5'b0) begin - // c.ebreak -> ebreak - comp_instr = {32'h00_10_00_73}; - end else begin - // c.jalr -> jalr x1, rs1, 0 - comp_instr = {12'b0, i_instr[11:7], 3'b000, 5'b00001, {OPCODE_JALR}}; - end - end - end - end - - 2'b11: begin - // c.swsp -> sw rs2, imm(x2) - comp_instr = {4'b0, i_instr[8:7], i_instr[12], i_instr[6:2], 5'h02, 3'b010, - i_instr[11:9], 2'b00, {OPCODE_STORE}}; - end - endcase - end - - // Incoming instruction is not compressed. - 2'b11: illegal_instr = 1'b1; - - endcase - end - - endmodule diff --git a/rtl/serv_csr.v b/rtl/serv_csr.v index 547accf..40423e1 100644 --- a/rtl/serv_csr.v +++ b/rtl/serv_csr.v @@ -1,158 +1,105 @@ `default_nettype none module serv_csr - #( - parameter RESET_STRATEGY = "MINI", - parameter W = 1, - parameter B = W-1 - ) ( input wire i_clk, - input wire i_rst, - //State - input wire i_trig_irq, input wire i_en, - input wire i_cnt0to3, - input wire i_cnt3, - input wire i_cnt7, - input wire i_cnt11, - input wire i_cnt12, - input wire i_cnt_done, - input wire i_mem_op, - input wire i_mtip, - input wire i_trap, - output reg o_new_irq, - //Control + input wire [4:2] i_cnt, + input wire [3:2] i_cnt_r, input wire i_e_op, input wire i_ebreak, input wire i_mem_cmd, + input wire i_mem_misalign, + //From mpram + input wire i_rf_csr_out, + //to mpram + output wire o_csr_in, + //Stuff + input wire i_mtip, + output wire o_new_irq, + input wire i_pending_irq, + input wire i_trap_taken, input wire i_mstatus_en, input wire i_mie_en, input wire i_mcause_en, input wire [1:0] i_csr_source, input wire i_mret, - input wire i_csr_d_sel, - //Data - input wire [B:0] i_rf_csr_out, - output wire [B:0] o_csr_in, - input wire [B:0] i_csr_imm, - input wire [B:0] i_rs1, - output wire [B:0] o_q); + input wire i_d, + output wire o_q); - localparam [1:0] - CSR_SOURCE_CSR = 2'b00, - CSR_SOURCE_EXT = 2'b01, - CSR_SOURCE_SET = 2'b10, - CSR_SOURCE_CLR = 2'b11; +`include "serv_params.vh" + reg mstatus; reg mstatus_mie; reg mstatus_mpie; reg mie_mtie; reg mcause31; reg [3:0] mcause3_0; - wire [B:0] mcause; + wire mcause; - wire [B:0] csr_in; - wire [B:0] csr_out; + wire csr_in; + wire csr_out; reg timer_irq_r; - wire [B:0] d = i_csr_d_sel ? i_csr_imm : i_rs1; - - assign csr_in = (i_csr_source == CSR_SOURCE_EXT) ? d : - (i_csr_source == CSR_SOURCE_SET) ? csr_out | d : - (i_csr_source == CSR_SOURCE_CLR) ? csr_out & ~d : + assign csr_in = (i_csr_source == CSR_SOURCE_EXT) ? i_d : + (i_csr_source == CSR_SOURCE_SET) ? csr_out | i_d : + (i_csr_source == CSR_SOURCE_CLR) ? csr_out & ~i_d : (i_csr_source == CSR_SOURCE_CSR) ? csr_out : - {W{1'bx}}; + 1'bx; - wire [B:0] mstatus; - - generate - if (W==1) begin : gen_mstatus_w1 - assign mstatus = ((mstatus_mie & i_cnt3) | (i_cnt11 | i_cnt12)); - end else if (W==4) begin : gen_mstatus_w4 - assign mstatus = {i_cnt11 | (mstatus_mie & i_cnt3), 2'b00, i_cnt12}; - end - endgenerate - - assign csr_out = ({W{i_mstatus_en & i_en}} & mstatus) | + assign csr_out = (i_mstatus_en & i_en & mstatus) | i_rf_csr_out | - ({W{i_mcause_en & i_en}} & mcause); + (i_mcause_en & i_en & mcause); assign o_q = csr_out; wire timer_irq = i_mtip & mstatus_mie & mie_mtie; - assign mcause = i_cnt0to3 ? mcause3_0[B:0] : //[3:0] - i_cnt_done ? {mcause31,{B{1'b0}}} //[31] - : {W{1'b0}}; + assign mcause = (i_cnt[4:2] == 3'd0) ? mcause3_0[0] : //[3:0] + ((i_cnt[4:2] == 3'd7) & i_cnt_r[3]) ? mcause31 //[31] + : 1'b0; assign o_csr_in = csr_in; + assign o_new_irq = !timer_irq_r & timer_irq; + + always @(posedge i_clk) begin - if (i_trig_irq) begin - timer_irq_r <= timer_irq; - o_new_irq <= timer_irq & !timer_irq_r; - end - - if (i_mie_en & i_cnt7) - mie_mtie <= csr_in[B]; - - /* - The mie bit in mstatus gets updated under three conditions - - When a trap is taken, the bit is cleared - During an mret instruction, the bit is restored from mpie - During a mstatus CSR access instruction it's assigned when - bit 3 gets updated - - These conditions are all mutually exclusive - */ - if ((i_trap & i_cnt_done) | i_mstatus_en & i_cnt3 & i_en | i_mret) - mstatus_mie <= !i_trap & (i_mret ? mstatus_mpie : csr_in[B]); - /* Note: To save resources mstatus_mpie (mstatus bit 7) is not readable or writable from sw */ - if (i_trap & i_cnt_done) - mstatus_mpie <= mstatus_mie; + if (i_mstatus_en & (i_cnt[4:2] == 3'd0) & i_cnt_r[3]) + mstatus_mie <= csr_in; - /* - The four lowest bits in mcause hold the exception code + if (i_mie_en & (i_cnt[4:2] == 3'd1) & i_cnt_r[3]) + mie_mtie <= csr_in; - These bits get updated under three conditions + mstatus <= (i_cnt[4:2] == 0) & i_cnt_r[2] & mstatus_mie; - During an mcause CSR access function, they are assigned when - bits 0 to 3 gets updated + timer_irq_r <= timer_irq; - During an external interrupt the exception code is set to - 7, since SERV only support timer interrupts - - During an exception, the exception code is assigned to indicate - if it was caused by an ebreak instruction (3), - ecall instruction (11), misaligned load (4), misaligned store (6) - or misaligned jump (0) - - The expressions below are derived from the following truth table - irq => 0111 (timer=7) - e_op => x011 (ebreak=3, ecall=11) - mem => 01x0 (store=6, load=4) - ctrl => 0000 (jump=0) - */ - if (i_mcause_en & i_en & i_cnt0to3 | (i_trap & i_cnt_done)) begin - mcause3_0[3] <= (i_e_op & !i_ebreak) | (!i_trap & csr_in[B]); - mcause3_0[2] <= o_new_irq | i_mem_op | (!i_trap & ((W == 1) ? mcause3_0[3] : csr_in[(W == 1) ? 0 : 2])); - mcause3_0[1] <= o_new_irq | i_e_op | (i_mem_op & i_mem_cmd) | (!i_trap & ((W == 1) ? mcause3_0[2] : csr_in[(W == 1) ? 0 : 1])); - mcause3_0[0] <= o_new_irq | i_e_op | (!i_trap & ((W == 1) ? mcause3_0[1] : csr_in[0])); + if (i_mret) begin + mstatus_mie <= mstatus_mpie; + end + + if (i_trap_taken) begin + mstatus_mpie <= mstatus_mie; + mstatus_mie <= 1'b0; + mcause31 <= i_pending_irq; + mcause3_0 <= i_pending_irq ? 4'd7 : + i_e_op ? {!i_ebreak, 3'b011} : + i_mem_misalign ? {2'b01, i_mem_cmd, 1'b0} : + 4'd0; + end + + if (i_mcause_en & i_en) begin + if (i_cnt[4:2] == 3'd0) + mcause3_0 <= {csr_in, mcause3_0[3:1]}; + if ((i_cnt[4:2] == 3'd7) & i_cnt_r[3]) + mcause31 <= csr_in; end - if (i_mcause_en & i_cnt_done | i_trap) - mcause31 <= i_trap ? o_new_irq : csr_in[B]; - if (i_rst) - if (RESET_STRATEGY != "NONE") begin - o_new_irq <= 1'b0; - mie_mtie <= 1'b0; - end end endmodule diff --git a/rtl/serv_ctrl.v b/rtl/serv_ctrl.v index 3ea2650..2ebd747 100644 --- a/rtl/serv_ctrl.v +++ b/rtl/serv_ctrl.v @@ -1,109 +1,100 @@ `default_nettype none module serv_ctrl - #(parameter RESET_STRATEGY = "MINI", - parameter RESET_PC = 32'd0, - parameter WITH_CSR = 1, - parameter W = 1, - parameter B = W-1 - ) ( - input wire clk, - input wire i_rst, + input wire clk, + input wire i_rst, //State - input wire i_pc_en, - input wire i_cnt12to31, - input wire i_cnt0, - input wire i_cnt1, - input wire i_cnt2, + input wire i_pc_en, + input wire [4:2] i_cnt, + input wire [2:2] i_cnt_r, + input wire i_cnt_done, //Control - input wire i_jump, - input wire i_jal_or_jalr, - input wire i_utype, - input wire i_pc_rel, - input wire i_trap, - input wire i_iscomp, + input wire i_jump, + input wire i_jal_or_jalr, + input wire i_utype, + input wire i_pc_rel, + input wire i_trap, //Data - input wire [B:0] i_imm, - input wire [B:0] i_buf, - input wire [B:0] i_csr_pc, - output wire [B:0] o_rd, - output wire [B:0] o_bad_pc, + input wire i_imm, + input wire i_buf, + input wire i_csr_pc, + output wire o_rd, + output wire o_bad_pc, //External - output reg [31:0] o_ibus_adr); + output wire [31:0] o_ibus_adr, + output wire o_ibus_cyc, + input wire i_ibus_ack); - wire [B:0] pc_plus_4; + parameter RESET_PC = 32'd0; + parameter WITH_CSR = 1; + + reg en_pc_r; + + wire pc_plus_4; wire pc_plus_4_cy; reg pc_plus_4_cy_r; - wire [B:0] pc_plus_4_cy_r_w; - wire [B:0] pc_plus_offset; + wire pc_plus_offset; wire pc_plus_offset_cy; - reg pc_plus_offset_cy_r; - wire [B:0] pc_plus_offset_cy_r_w; - wire [B:0] pc_plus_offset_aligned; - wire [B:0] plus_4; + reg pc_plus_offset_cy_r; + wire pc_plus_offset_aligned; + wire plus_4; - wire [B:0] pc = o_ibus_adr[B:0]; + wire pc; - wire [B:0] new_pc; + wire new_pc; - wire [B:0] offset_a; - wire [B:0] offset_b; + wire offset_a; + wire offset_b; - /* If i_iscomp=1: increment pc by 2 else increment pc by 4 */ - - generate - if (W == 1) begin : gen_plus_4_w_eq_1 - assign plus_4 = i_iscomp ? i_cnt1 : i_cnt2; - end else if (W == 4) begin : gen_plus_4_w_eq_4 - assign plus_4 = (i_cnt0 | i_cnt1) ? (i_iscomp ? 2 : 4) : 0; - end - endgenerate + assign plus_4 = i_cnt_r[2] & (i_cnt[4:2] == 3'd0); + assign o_ibus_adr[0] = pc; assign o_bad_pc = pc_plus_offset_aligned; - assign {pc_plus_4_cy,pc_plus_4} = pc+plus_4+pc_plus_4_cy_r_w; + assign {pc_plus_4_cy,pc_plus_4} = pc+plus_4+pc_plus_4_cy_r; + + shift_reg + #( + .LEN (32), + .INIT (RESET_PC)) + pc_reg + ( + .clk (clk), + .i_rst (i_rst), + .i_en (i_pc_en), + .i_d (new_pc), + .o_q (pc), + .o_par (o_ibus_adr[31:1]) + ); generate - if (|WITH_CSR) begin : gen_csr - if (W == 1) begin : gen_new_pc_w_eq_1 - assign new_pc = i_trap ? (i_csr_pc & !(i_cnt0 || i_cnt1)) : i_jump ? pc_plus_offset_aligned : pc_plus_4; - end else if (W == 4) begin : gen_new_pc_w_eq_4 - assign new_pc = i_trap ? (i_csr_pc & ((i_cnt0 || i_cnt1) ? 4'b1100 : 4'b1111)) : i_jump ? pc_plus_offset_aligned : pc_plus_4; - end - end else begin : gen_no_csr - assign new_pc = i_jump ? pc_plus_offset_aligned : pc_plus_4; - end + if (WITH_CSR) + assign new_pc = i_trap ? (i_csr_pc & en_pc_r) : i_jump ? pc_plus_offset_aligned : pc_plus_4; + else + assign new_pc = i_jump ? pc_plus_offset_aligned : pc_plus_4; endgenerate - assign o_rd = ({W{i_utype}} & pc_plus_offset_aligned) | (pc_plus_4 & {W{i_jal_or_jalr}}); + assign o_rd = (i_utype & pc_plus_offset_aligned) | (pc_plus_4 & i_jal_or_jalr); - assign offset_a = {W{i_pc_rel}} & pc; - assign offset_b = i_utype ? (i_imm & {W{i_cnt12to31}}) : i_buf; - assign {pc_plus_offset_cy,pc_plus_offset} = offset_a+offset_b+pc_plus_offset_cy_r_w; + assign offset_a = i_pc_rel & pc; + assign offset_b = i_utype ? (i_imm & (i_cnt[4] | (i_cnt[3:2] == 2'b11))): i_buf; + assign {pc_plus_offset_cy,pc_plus_offset} = offset_a+offset_b+pc_plus_offset_cy_r; - generate - if (W>1) begin : gen_w_gt_1 - assign pc_plus_offset_aligned[B:1] = pc_plus_offset[B:1]; - assign pc_plus_offset_cy_r_w[B:1] = {B{1'b0}}; - assign pc_plus_4_cy_r_w[B:1] = {B{1'b0}}; - end - endgenerate + assign pc_plus_offset_aligned = pc_plus_offset & en_pc_r; - assign pc_plus_offset_aligned[0] = pc_plus_offset[0] & !i_cnt0; - assign pc_plus_offset_cy_r_w[0] = pc_plus_offset_cy_r; - assign pc_plus_4_cy_r_w[0] = pc_plus_4_cy_r; - - initial if (RESET_STRATEGY == "NONE") o_ibus_adr = RESET_PC; + assign o_ibus_cyc = en_pc_r & !i_pc_en; always @(posedge clk) begin pc_plus_4_cy_r <= i_pc_en & pc_plus_4_cy; pc_plus_offset_cy_r <= i_pc_en & pc_plus_offset_cy; - if (RESET_STRATEGY == "NONE") begin - if (i_pc_en) - o_ibus_adr <= {new_pc, o_ibus_adr[31:W]}; - end else begin - if (i_pc_en | i_rst) - o_ibus_adr <= i_rst ? RESET_PC : {new_pc, o_ibus_adr[31:W]}; + if (i_pc_en) + en_pc_r <= 1'b1; + else if (o_ibus_cyc & i_ibus_ack) + en_pc_r <= 1'b0; + + if (i_rst) begin + en_pc_r <= 1'b1; end end + endmodule diff --git a/rtl/serv_debug.v b/rtl/serv_debug.v deleted file mode 100644 index af3c34f..0000000 --- a/rtl/serv_debug.v +++ /dev/null @@ -1,345 +0,0 @@ -module serv_debug - #(parameter W = 1, - parameter RESET_PC = 0, - //Internally calculated. Do not touch - parameter B=W-1) - ( -`ifdef RISCV_FORMAL - output reg rvfi_valid = 1'b0, - output reg [63:0] rvfi_order = 64'd0, - output reg [31:0] rvfi_insn = 32'd0, - output reg rvfi_trap = 1'b0, - output reg rvfi_halt = 1'b0, // Not used - output reg rvfi_intr = 1'b0, // Not used - output reg [1:0] rvfi_mode = 2'b11, // Not used - output reg [1:0] rvfi_ixl = 2'b01, // Not used - output reg [4:0] rvfi_rs1_addr, - output reg [4:0] rvfi_rs2_addr, - output reg [31:0] rvfi_rs1_rdata, - output reg [31:0] rvfi_rs2_rdata, - output reg [4:0] rvfi_rd_addr, - output wire [31:0] rvfi_rd_wdata, - output reg [31:0] rvfi_pc_rdata, - output wire [31:0] rvfi_pc_wdata, - output reg [31:0] rvfi_mem_addr, - output reg [3:0] rvfi_mem_rmask, - output reg [3:0] rvfi_mem_wmask, - output reg [31:0] rvfi_mem_rdata, - output reg [31:0] rvfi_mem_wdata, - input wire [31:0] i_dbus_adr, - input wire [31:0] i_dbus_dat, - input wire [3:0] i_dbus_sel, - input wire i_dbus_we, - input wire [31:0] i_dbus_rdt, - input wire i_dbus_ack, - input wire i_ctrl_pc_en, - input wire [B:0] rs1, - input wire [B:0] rs2, - input wire [4:0] rs1_addr, - input wire [4:0] rs2_addr, - input wire [3:0] immdec_en, - input wire rd_en, - input wire trap, - input wire i_rf_ready, - input wire i_ibus_cyc, - input wire two_stage_op, - input wire init, - input wire [31:0] i_ibus_adr, -`endif - input wire i_clk, - input wire i_rst, - input wire [31:0] i_ibus_rdt, - input wire i_ibus_ack, - input wire [4:0] i_rd_addr, - input wire i_cnt_en, - input wire [B:0] i_csr_in, - input wire i_csr_mstatus_en, - input wire i_csr_mie_en, - input wire i_csr_mcause_en, - input wire i_csr_en, - input wire [1:0] i_csr_addr, - input wire i_wen0, - input wire [B:0] i_wdata0, - input wire i_cnt_done); - - reg update_rd = 1'b0; - reg update_mscratch; - reg update_mtvec; - reg update_mepc; - reg update_mtval; - reg update_mstatus; - reg update_mie; - reg update_mcause; - - reg [31:0] dbg_rd = 32'hxxxxxxxx; - reg [31:0] dbg_csr = 32'hxxxxxxxx; - reg [31:0] dbg_mstatus = 32'hxxxxxxxx; - reg [31:0] dbg_mie = 32'hxxxxxxxx; - reg [31:0] dbg_mcause = 32'hxxxxxxxx; - reg [31:0] dbg_mscratch = 32'hxxxxxxxx; - reg [31:0] dbg_mtvec = 32'hxxxxxxxx; - reg [31:0] dbg_mepc = 32'hxxxxxxxx; - reg [31:0] dbg_mtval = 32'hxxxxxxxx; - reg [31:0] x1 = 32'hxxxxxxxx; - reg [31:0] x2 = 32'hxxxxxxxx; - reg [31:0] x3 = 32'hxxxxxxxx; - reg [31:0] x4 = 32'hxxxxxxxx; - reg [31:0] x5 = 32'hxxxxxxxx; - reg [31:0] x6 = 32'hxxxxxxxx; - reg [31:0] x7 = 32'hxxxxxxxx; - reg [31:0] x8 = 32'hxxxxxxxx; - reg [31:0] x9 = 32'hxxxxxxxx; - reg [31:0] x10 = 32'hxxxxxxxx; - reg [31:0] x11 = 32'hxxxxxxxx; - reg [31:0] x12 = 32'hxxxxxxxx; - reg [31:0] x13 = 32'hxxxxxxxx; - reg [31:0] x14 = 32'hxxxxxxxx; - reg [31:0] x15 = 32'hxxxxxxxx; - reg [31:0] x16 = 32'hxxxxxxxx; - reg [31:0] x17 = 32'hxxxxxxxx; - reg [31:0] x18 = 32'hxxxxxxxx; - reg [31:0] x19 = 32'hxxxxxxxx; - reg [31:0] x20 = 32'hxxxxxxxx; - reg [31:0] x21 = 32'hxxxxxxxx; - reg [31:0] x22 = 32'hxxxxxxxx; - reg [31:0] x23 = 32'hxxxxxxxx; - reg [31:0] x24 = 32'hxxxxxxxx; - reg [31:0] x25 = 32'hxxxxxxxx; - reg [31:0] x26 = 32'hxxxxxxxx; - reg [31:0] x27 = 32'hxxxxxxxx; - reg [31:0] x28 = 32'hxxxxxxxx; - reg [31:0] x29 = 32'hxxxxxxxx; - reg [31:0] x30 = 32'hxxxxxxxx; - reg [31:0] x31 = 32'hxxxxxxxx; - - always @(posedge i_clk) begin - update_rd <= i_cnt_done & i_wen0; - - if (i_wen0) - dbg_rd <= {i_wdata0,dbg_rd[31:W]}; - - //End of instruction that writes to RF - if (update_rd) begin - case (i_rd_addr) - 5'd1 : x1 <= dbg_rd; - 5'd2 : x2 <= dbg_rd; - 5'd3 : x3 <= dbg_rd; - 5'd4 : x4 <= dbg_rd; - 5'd5 : x5 <= dbg_rd; - 5'd6 : x6 <= dbg_rd; - 5'd7 : x7 <= dbg_rd; - 5'd8 : x8 <= dbg_rd; - 5'd9 : x9 <= dbg_rd; - 5'd10 : x10 <= dbg_rd; - 5'd11 : x11 <= dbg_rd; - 5'd12 : x12 <= dbg_rd; - 5'd13 : x13 <= dbg_rd; - 5'd14 : x14 <= dbg_rd; - 5'd15 : x15 <= dbg_rd; - 5'd16 : x16 <= dbg_rd; - 5'd17 : x17 <= dbg_rd; - 5'd18 : x18 <= dbg_rd; - 5'd19 : x19 <= dbg_rd; - 5'd20 : x20 <= dbg_rd; - 5'd21 : x21 <= dbg_rd; - 5'd22 : x22 <= dbg_rd; - 5'd23 : x23 <= dbg_rd; - 5'd24 : x24 <= dbg_rd; - 5'd25 : x25 <= dbg_rd; - 5'd26 : x26 <= dbg_rd; - 5'd27 : x27 <= dbg_rd; - 5'd28 : x28 <= dbg_rd; - 5'd29 : x29 <= dbg_rd; - 5'd30 : x30 <= dbg_rd; - 5'd31 : x31 <= dbg_rd; - default : ; - endcase - end - - update_mscratch <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b00); - update_mtvec <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b01); - update_mepc <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b10); - update_mtval <= i_cnt_done & i_csr_en & (i_csr_addr == 2'b11); - update_mstatus <= i_cnt_done & i_csr_mstatus_en; - update_mie <= i_cnt_done & i_csr_mie_en; - update_mcause <= i_cnt_done & i_csr_mcause_en; - - if (i_cnt_en) - dbg_csr <= {i_csr_in, dbg_csr[31:W]}; - - if (update_mscratch) dbg_mscratch <= dbg_csr; - if (update_mtvec) dbg_mtvec <= dbg_csr; - if (update_mepc ) dbg_mepc <= dbg_csr; - if (update_mtval) dbg_mtval <= dbg_csr; - if (update_mstatus) dbg_mstatus <= dbg_csr; - if (update_mie) dbg_mie <= dbg_csr; - if (update_mcause) dbg_mcause <= dbg_csr; - end - - reg LUI, AUIPC, JAL, JALR, BEQ, BNE, BLT, BGE, BLTU, BGEU, LB, LH, LW, LBU, LHU, SB, SH, SW, ADDI, SLTI, SLTIU, XORI, ORI, ANDI,SLLI, SRLI, SRAI, ADD, SUB, SLL, SLT, SLTU, XOR, SRL, SRA, OR, AND, FENCE, ECALL, EBREAK; - reg CSRRW, CSRRS, CSRRC, CSRRWI, CSRRSI, CSRRCI; - reg OTHER; - - always @(posedge i_clk) begin - if (i_ibus_ack) begin - LUI <= 1'b0; - AUIPC <= 1'b0; - JAL <= 1'b0; - JALR <= 1'b0; - BEQ <= 1'b0; - BNE <= 1'b0; - BLT <= 1'b0; - BGE <= 1'b0; - BLTU <= 1'b0; - BGEU <= 1'b0; - LB <= 1'b0; - LH <= 1'b0; - LW <= 1'b0; - LBU <= 1'b0; - LHU <= 1'b0; - SB <= 1'b0; - SH <= 1'b0; - SW <= 1'b0; - ADDI <= 1'b0; - SLTI <= 1'b0; - SLTIU <= 1'b0; - XORI <= 1'b0; - ORI <= 1'b0; - ANDI <= 1'b0; - SLLI <= 1'b0; - SRLI <= 1'b0; - SRAI <= 1'b0; - ADD <= 1'b0; - SUB <= 1'b0; - SLL <= 1'b0; - SLT <= 1'b0; - SLTU <= 1'b0; - XOR <= 1'b0; - SRL <= 1'b0; - SRA <= 1'b0; - OR <= 1'b0; - AND <= 1'b0; - FENCE <= 1'b0; - ECALL <= 1'b0; - EBREAK <= 1'b0; - CSRRW <= 1'b0; - CSRRS <= 1'b0; - CSRRC <= 1'b0; - CSRRWI <= 1'b0; - CSRRSI <= 1'b0; - CSRRCI <= 1'b0; - OTHER <= 1'b0; - - casez(i_ibus_rdt) - // 3322222_22222 11111_111 11 - // 1098765_43210 98765_432 10987_65432_10 - 32'b???????_?????_?????_???_?????_01101_11 : LUI <= 1'b1; - 32'b???????_?????_?????_???_?????_00101_11 : AUIPC <= 1'b1; - 32'b???????_?????_?????_???_?????_11011_11 : JAL <= 1'b1; - 32'b???????_?????_?????_000_?????_11001_11 : JALR <= 1'b1; - 32'b???????_?????_?????_000_?????_11000_11 : BEQ <= 1'b1; - 32'b???????_?????_?????_001_?????_11000_11 : BNE <= 1'b1; - 32'b???????_?????_?????_100_?????_11000_11 : BLT <= 1'b1; - 32'b???????_?????_?????_101_?????_11000_11 : BGE <= 1'b1; - 32'b???????_?????_?????_110_?????_11000_11 : BLTU <= 1'b1; - 32'b???????_?????_?????_111_?????_11000_11 : BGEU <= 1'b1; - 32'b???????_?????_?????_000_?????_00000_11 : LB <= 1'b1; - 32'b???????_?????_?????_001_?????_00000_11 : LH <= 1'b1; - 32'b???????_?????_?????_010_?????_00000_11 : LW <= 1'b1; - 32'b???????_?????_?????_100_?????_00000_11 : LBU <= 1'b1; - 32'b???????_?????_?????_101_?????_00000_11 : LHU <= 1'b1; - 32'b???????_?????_?????_000_?????_01000_11 : SB <= 1'b1; - 32'b???????_?????_?????_001_?????_01000_11 : SH <= 1'b1; - 32'b???????_?????_?????_010_?????_01000_11 : SW <= 1'b1; - 32'b???????_?????_?????_000_?????_00100_11 : ADDI <= 1'b1; - 32'b???????_?????_?????_010_?????_00100_11 : SLTI <= 1'b1; - 32'b???????_?????_?????_011_?????_00100_11 : SLTIU <= 1'b1; - 32'b???????_?????_?????_100_?????_00100_11 : XORI <= 1'b1; - 32'b???????_?????_?????_110_?????_00100_11 : ORI <= 1'b1; - 32'b???????_?????_?????_111_?????_00100_11 : ANDI <= 1'b1; - 32'b0000000_?????_?????_001_?????_00100_11 : SLLI <= 1'b1; - 32'b0000000_?????_?????_101_?????_00100_11 : SRLI <= 1'b1; - 32'b0100000_?????_?????_101_?????_00100_11 : SRAI <= 1'b1; - 32'b0000000_?????_?????_000_?????_01100_11 : ADD <= 1'b1; - 32'b0100000_?????_?????_000_?????_01100_11 : SUB <= 1'b1; - 32'b0000000_?????_?????_001_?????_01100_11 : SLL <= 1'b1; - 32'b0000000_?????_?????_010_?????_01100_11 : SLT <= 1'b1; - 32'b0000000_?????_?????_011_?????_01100_11 : SLTU <= 1'b1; - 32'b???????_?????_?????_100_?????_01100_11 : XOR <= 1'b1; - 32'b0000000_?????_?????_101_?????_01100_11 : SRL <= 1'b1; - 32'b0100000_?????_?????_101_?????_01100_11 : SRA <= 1'b1; - 32'b???????_?????_?????_110_?????_01100_11 : OR <= 1'b1; - 32'b???????_?????_?????_111_?????_01100_11 : AND <= 1'b1; - 32'b???????_?????_?????_000_?????_00011_11 : FENCE <= 1'b1; - 32'b0000000_00000_00000_000_00000_11100_11 : ECALL <= 1'b1; - 32'b0000000_00001_00000_000_00000_11100_11 : EBREAK <= 1'b1; - 32'b???????_?????_?????_001_?????_11100_11 : CSRRW <= 1'b1; - 32'b???????_?????_?????_010_?????_11100_11 : CSRRS <= 1'b1; - 32'b???????_?????_?????_011_?????_11100_11 : CSRRC <= 1'b1; - 32'b???????_?????_?????_101_?????_11100_11 : CSRRWI <= 1'b1; - 32'b???????_?????_?????_110_?????_11100_11 : CSRRSI <= 1'b1; - 32'b???????_?????_?????_111_?????_11100_11 : CSRRCI <= 1'b1; - default : OTHER <= 1'b1; - endcase - end - end - -`ifdef RISCV_FORMAL - reg [31:0] pc = RESET_PC; - - wire rs_en = two_stage_op ? init : i_ctrl_pc_en; - - assign rvfi_rd_wdata = update_rd ? dbg_rd : 32'd0; - - always @(posedge i_clk) begin - /* End of instruction */ - rvfi_valid <= i_cnt_done & i_ctrl_pc_en & !i_rst; - rvfi_order <= rvfi_order + {63'd0,rvfi_valid}; - - /* Get instruction word when it's fetched from ibus */ - if (i_ibus_cyc & i_ibus_ack) - rvfi_insn <= i_ibus_rdt; - - - if (i_cnt_done & i_ctrl_pc_en) begin - rvfi_pc_rdata <= pc; - if (!(rd_en & (|i_rd_addr))) begin - rvfi_rd_addr <= 5'd0; - end - end - rvfi_trap <= trap; - if (rvfi_valid) begin - rvfi_trap <= 1'b0; - pc <= rvfi_pc_wdata; - end - - /* RS1 not valid during J, U instructions (immdec_en[1]) */ - /* RS2 not valid during I, J, U instructions (immdec_en[2]) */ - if (i_rf_ready) begin - rvfi_rs1_addr <= !immdec_en[1] ? rs1_addr : 5'd0; - rvfi_rs2_addr <= !immdec_en[2] /*rs2_valid*/ ? rs2_addr : 5'd0; - rvfi_rd_addr <= i_rd_addr; - end - if (rs_en) begin - rvfi_rs1_rdata <= {(!immdec_en[1] ? rs1 : {W{1'b0}}),rvfi_rs1_rdata[31:W]}; - rvfi_rs2_rdata <= {(!immdec_en[2] ? rs2 : {W{1'b0}}),rvfi_rs2_rdata[31:W]}; - end - - if (i_dbus_ack) begin - rvfi_mem_addr <= i_dbus_adr; - rvfi_mem_rmask <= i_dbus_we ? 4'b0000 : i_dbus_sel; - rvfi_mem_wmask <= i_dbus_we ? i_dbus_sel : 4'b0000; - rvfi_mem_rdata <= i_dbus_rdt; - rvfi_mem_wdata <= i_dbus_dat; - end - if (i_ibus_ack) begin - rvfi_mem_rmask <= 4'b0000; - rvfi_mem_wmask <= 4'b0000; - end - end - - assign rvfi_pc_wdata = i_ibus_adr; - -`endif - -endmodule diff --git a/rtl/serv_decode.v b/rtl/serv_decode.v index 2aa5b8a..fad5f8a 100644 --- a/rtl/serv_decode.v +++ b/rtl/serv_decode.v @@ -1,361 +1,240 @@ `default_nettype none module serv_decode - #(parameter [0:0] PRE_REGISTER = 1, - parameter [0:0] MDU = 0) ( - input wire clk, + input wire clk, //Input + input wire i_cnt_en, + input wire i_cnt_done, input wire [31:2] i_wb_rdt, - input wire i_wb_en, + input wire i_wb_en, + input wire i_alu_cmp, //To state - output reg o_sh_right, - output reg o_bne_or_bge, - output reg o_cond_branch, - output reg o_e_op, - output reg o_ebreak, - output reg o_branch_op, - output reg o_shift_op, - output reg o_rd_op, - output reg o_two_stage_op, - output reg o_dbus_en, - //MDU - output reg o_mdu_op, - //Extension - output reg [2:0] o_ext_funct3, + output wire o_take_branch, + output wire o_e_op, + output wire o_ebreak, + output wire o_branch_op, + output wire o_mem_op, + output wire o_shift_op, + output wire o_slt_op, + output wire o_rd_op, //To bufreg - output reg o_bufreg_rs1_en, - output reg o_bufreg_imm_en, - output reg o_bufreg_clr_lsb, - output reg o_bufreg_sh_signed, + output wire o_bufreg_loop, + output wire o_bufreg_rs1_en, + output wire o_bufreg_imm_en, + output wire o_bufreg_clr_lsb, //To ctrl - output reg o_ctrl_jal_or_jalr, - output reg o_ctrl_utype, - output reg o_ctrl_pc_rel, - output reg o_ctrl_mret, + output wire o_ctrl_jal_or_jalr, + output wire o_ctrl_utype, + output wire o_ctrl_pc_rel, + output wire o_ctrl_mret, //To alu - output reg o_alu_sub, - output reg [1:0] o_alu_bool_op, - output reg o_alu_cmp_eq, - output reg o_alu_cmp_sig, - output reg [2:0] o_alu_rd_sel, + output wire o_alu_sub, + output wire [1:0] o_alu_bool_op, + output wire o_alu_cmp_eq, + output wire o_alu_cmp_uns, + output wire o_alu_sh_signed, + output wire o_alu_sh_right, + output wire [3:0] o_alu_rd_sel, + //To RF + output reg [4:0] o_rf_rd_addr, + output reg [4:0] o_rf_rs1_addr, + output reg [4:0] o_rf_rs2_addr, //To mem IF - output reg o_mem_signed, - output reg o_mem_word, - output reg o_mem_half, - output reg o_mem_cmd, + output wire o_mem_signed, + output wire o_mem_word, + output wire o_mem_half, + output wire o_mem_cmd, //To CSR - output reg o_csr_en, - output reg [1:0] o_csr_addr, - output reg o_csr_mstatus_en, - output reg o_csr_mie_en, - output reg o_csr_mcause_en, - output reg [1:0] o_csr_source, - output reg o_csr_d_sel, - output reg o_csr_imm_en, - output reg o_mtval_pc, + output wire o_csr_en, + output wire [1:0] o_csr_addr, + output wire o_csr_mstatus_en, + output wire o_csr_mie_en, + output wire o_csr_mcause_en, + output wire [1:0] o_csr_source, + output wire o_csr_d_sel, + output wire o_csr_imm, //To top - output reg [3:0] o_immdec_ctrl, - output reg [3:0] o_immdec_en, - output reg o_op_b_source, - //To RF IF - output reg o_rd_mem_en, - output reg o_rd_csr_en, - output reg o_rd_alu_en); + output wire o_imm, + output wire o_op_b_source, + output wire o_rd_csr_en, + output wire o_rd_alu_en); + +`include "serv_params.vh" reg [4:0] opcode; reg [2:0] funct3; - reg op20; - reg op21; - reg op22; - reg op26; + reg op20; + reg op21; + reg op22; + reg op26; - reg imm25; reg imm30; - wire co_mdu_op = MDU & (opcode == 5'b01100) & imm25; + wire op_or_opimm = (!opcode[4] & opcode[2] & !opcode[0]); - wire co_two_stage_op = - ~opcode[2] | (funct3[0] & ~funct3[1] & ~opcode[0] & ~opcode[4]) | - (funct3[1] & ~funct3[2] & ~opcode[0] & ~opcode[4]) | co_mdu_op; - wire co_shift_op = (opcode[2] & ~funct3[1]) & !co_mdu_op; - wire co_branch_op = opcode[4]; - wire co_dbus_en = ~opcode[2] & ~opcode[4]; - wire co_mtval_pc = opcode[4]; - wire co_mem_word = funct3[1]; - wire co_rd_alu_en = !opcode[0] & opcode[2] & !opcode[4] & !co_mdu_op; - wire co_rd_mem_en = (!opcode[2] & !opcode[0]) | co_mdu_op; - wire [2:0] co_ext_funct3 = funct3; + assign o_mem_op = !opcode[4] & !opcode[2] & !opcode[0]; + assign o_shift_op = op_or_opimm & (funct3[1:0] == 2'b01); + assign o_slt_op = op_or_opimm & (funct3[2:1] == 2'b01); + assign o_branch_op = opcode[4] & !opcode[2]; + + //Matches system opcodes except CSR accesses (funct3 == 0) + //No idea anymore why the !op21 condition is needed here + assign o_e_op = opcode[4] & opcode[2] & !op21 & !(|funct3); + + assign o_ebreak = op20; //jal,branch = imm //jalr = rs1+imm //mem = rs1+imm //shift = rs1 - wire co_bufreg_rs1_en = !opcode[4] | (!opcode[1] & opcode[0]); - wire co_bufreg_imm_en = !opcode[2]; + assign o_bufreg_rs1_en = !opcode[4] | (!opcode[1] & opcode[0]); + assign o_bufreg_imm_en = !opcode[2]; + + //Loop bufreg contents for shift operations + assign o_bufreg_loop = op_or_opimm; //Clear LSB of immediate for BRANCH and JAL ops //True for BRANCH and JAL //False for JALR/LOAD/STORE/OP/OPIMM? - wire co_bufreg_clr_lsb = opcode[4] & ((opcode[1:0] == 2'b00) | (opcode[1:0] == 2'b11)); + assign o_bufreg_clr_lsb = opcode[4] & ((opcode[1:0] == 2'b00) | (opcode[1:0] == 2'b11)); - //Conditional branch - //True for BRANCH - //False for JAL/JALR - wire co_cond_branch = !opcode[0]; + //Take branch for jump or branch instructions (opcode == 1x0xx) if + //a) It's an unconditional branch (opcode[0] == 1) + //b) It's a conditional branch (opcode[0] == 0) of type beq,blt,bltu (funct3[0] == 0) and ALU compare is true + //c) It's a conditional branch (opcode[0] == 0) of type bne,bge,bgeu (funct3[0] == 1) and ALU compare is false + //Only valid during the last cycle of INIT, when the branch condition has + //been calculated. + assign o_take_branch = opcode[4] & !opcode[2] & (opcode[0] | (i_alu_cmp^funct3[0])); - wire co_ctrl_utype = !opcode[4] & opcode[2] & opcode[0]; - wire co_ctrl_jal_or_jalr = opcode[4] & opcode[0]; + assign o_ctrl_utype = !opcode[4] & opcode[2] & opcode[0]; + assign o_ctrl_jal_or_jalr = opcode[4] & opcode[0]; - //PC-relative operations - //True for jal, b* auipc, ebreak + //True for jal, b* auipc //False for jalr, lui - wire co_ctrl_pc_rel = (opcode[2:0] == 3'b000) | - (opcode[1:0] == 2'b11) | - (opcode[4] & opcode[2]) & op20| - (opcode[4:3] == 2'b00); + assign o_ctrl_pc_rel = (opcode[2:0] == 3'b000) | + (opcode[1:0] == 2'b11) | + (opcode[4:3] == 2'b00); + + assign o_ctrl_mret = (opcode[4] & opcode[2] & op21 & !(|funct3)); + //Write to RD //True for OP-IMM, AUIPC, OP, LUI, SYSTEM, JALR, JAL, LOAD //False for STORE, BRANCH, MISC-MEM - wire co_rd_op = (opcode[2] | - (!opcode[2] & opcode[4] & opcode[0]) | - (!opcode[2] & !opcode[3] & !opcode[0])); + assign o_rd_op = (opcode[2] | + (!opcode[2] & opcode[4] & opcode[0]) | + (!opcode[2] & !opcode[3] & !opcode[0])) & (|o_rf_rd_addr); - // - //funct3 - // - - wire co_sh_right = funct3[2]; - wire co_bne_or_bge = funct3[0]; - - //Matches system ops except eceall/ebreak/mret - wire csr_op = opcode[4] & opcode[2] & (|funct3); - - - //op20 - wire co_ebreak = op20; - - - //opcode & funct3 & op21 - - wire co_ctrl_mret = opcode[4] & opcode[2] & op21 & !(|funct3); - //Matches system opcodes except CSR accesses (funct3 == 0) - //and mret (!op21) - wire co_e_op = opcode[4] & opcode[2] & !op21 & !(|funct3); - - //opcode & funct3 & imm30 - - wire co_bufreg_sh_signed = imm30; + assign o_alu_sub = opcode[3] & imm30/*alu_sub_r*/; /* - True for sub, b*, slt* - False for add* - op opcode f3 i30 - b* 11000 xxx x t - addi 00100 000 x f - slt* 0x100 01x x t - add 01100 000 0 f - sub 01100 000 1 t - */ - wire co_alu_sub = funct3[1] | funct3[0] | (opcode[3] & imm30) | opcode[4]; - - /* - Bits 26, 22, 21 and 20 are enough to uniquely identify the eight supported CSR regs - mtvec, mscratch, mepc and mtval are stored externally (normally in the RF) and are - treated differently from mstatus, mie and mcause which are stored in serv_csr. - - The former get a 2-bit address as seen below while the latter get a - one-hot enable signal each. - - Hex|2 222|Reg |csr - adr|6 210|name |addr - ---|-----|--------|---- - 300|0_000|mstatus | xx - 304|0_100|mie | xx - 305|0_101|mtvec | 01 - 340|1_000|mscratch| 00 - 341|1_001|mepc | 10 - 342|1_010|mcause | xx - 343|1_011|mtval | 11 - + 300 0_000 mstatus RWSC + 304 0_100 mie SCWi + 305 0_101 mtvec RW + 340 1_000 mscratch + 341 1_001 mepc RW + 342 1_010 mcause R + 343 1_011 mtval + 344 1_100 mip CWi */ //true for mtvec,mscratch,mepc and mtval - //false for mstatus, mie, mcause - wire csr_valid = op20 | (op26 & !op21); + //false for mstatus, mie, mcause, mip + wire csr_valid = op20 | (op26 & !op22 & !op21); - wire co_rd_csr_en = csr_op; + //Matches system ops except eceall/ebreak + wire csr_op = opcode[4] & opcode[2] & (|funct3); + assign o_rd_csr_en = csr_op; - wire co_csr_en = csr_op & csr_valid; - wire co_csr_mstatus_en = csr_op & !op26 & !op22 & !op20; - wire co_csr_mie_en = csr_op & !op26 & op22 & !op20; - wire co_csr_mcause_en = csr_op & op21 & !op20; + assign o_csr_en = csr_op & csr_valid; + assign o_csr_mstatus_en = csr_op & !op26 & !op22; + assign o_csr_mie_en = csr_op & !op26 & op22 & !op20; + assign o_csr_mcause_en = csr_op & op21 & !op20; - wire [1:0] co_csr_source = funct3[1:0]; - wire co_csr_d_sel = funct3[2]; - wire co_csr_imm_en = opcode[4] & opcode[2] & funct3[2]; - wire [1:0] co_csr_addr = {op26 & op20, !op26 | op21}; + assign o_csr_source = funct3[1:0]; + assign o_csr_d_sel = funct3[2]; + assign o_csr_imm = o_rf_rs1_addr[0]; - wire co_alu_cmp_eq = funct3[2:1] == 2'b00; + assign o_csr_addr = (op26 & !op20) ? CSR_MSCRATCH : + (op26 & !op21) ? CSR_MEPC : + (op26) ? CSR_MTVAL : + CSR_MTVEC; - wire co_alu_cmp_sig = ~((funct3[0] & funct3[1]) | (funct3[1] & funct3[2])); + assign o_alu_cmp_eq = funct3[2:1] == 2'b00; - wire co_mem_cmd = opcode[3]; - wire co_mem_signed = ~funct3[2]; - wire co_mem_half = funct3[0]; + assign o_alu_cmp_uns = (funct3[0] & funct3[1]) | (funct3[1] & funct3[2]); + assign o_alu_sh_signed = imm30; + assign o_alu_sh_right = funct3[2]; - wire [1:0] co_alu_bool_op = funct3[1:0]; + assign o_mem_cmd = opcode[3]; + assign o_mem_signed = ~funct3[2]; + assign o_mem_word = funct3[1]; + assign o_mem_half = funct3[0]; + + assign o_alu_bool_op = funct3[1:0]; + + reg signbit; + + reg [8:0] imm19_12_20; + reg imm7; + reg [5:0] imm30_25; + reg [4:0] imm24_20; + reg [4:0] imm11_7; + + assign o_alu_rd_sel[0] = (funct3 == 3'b000); // Add/sub + assign o_alu_rd_sel[1] = (funct3[1:0] == 2'b01); //Shift + assign o_alu_rd_sel[2] = (funct3[2:1] == 2'b01); //SLT* + assign o_alu_rd_sel[3] = (funct3[2] & !(funct3[1:0] == 2'b01)); //Bool + always @(posedge clk) begin + if (i_wb_en) begin + o_rf_rd_addr <= i_wb_rdt[11:7]; + o_rf_rs1_addr <= i_wb_rdt[19:15]; + o_rf_rs2_addr <= i_wb_rdt[24:20]; + funct3 <= i_wb_rdt[14:12]; + imm30 <= i_wb_rdt[30]; + opcode <= i_wb_rdt[6:2]; + op20 <= i_wb_rdt[20]; + op21 <= i_wb_rdt[21]; + op22 <= i_wb_rdt[22]; + op26 <= i_wb_rdt[26]; + + //Immediate decoder + signbit <= i_wb_rdt[31]; + imm19_12_20 <= {i_wb_rdt[19:12],i_wb_rdt[20]}; + imm7 <= i_wb_rdt[7]; + imm30_25 <= i_wb_rdt[30:25]; + imm24_20 <= i_wb_rdt[24:20]; + imm11_7 <= i_wb_rdt[11:7]; + end + if (i_cnt_en) begin + imm19_12_20 <= {m3 ? signbit : imm24_20[0], imm19_12_20[8:1]}; + imm7 <= signbit; + imm30_25 <= {m2[1] ? imm7 : m2[0] ? signbit : imm19_12_20[0], imm30_25[5:1]}; + imm24_20 <= {imm30_25[0], imm24_20[4:1]}; + imm11_7 <= {imm30_25[0], imm11_7[4:1]}; + if (csr_op & o_csr_d_sel) + o_rf_rs1_addr <= {1'b0,o_rf_rs1_addr[4:1]}; + end + end - wire [3:0] co_immdec_ctrl; //True for S (STORE) or B (BRANCH) type instructions //False for J type instructions - assign co_immdec_ctrl[0] = opcode[3:0] == 4'b1000; - //True for OP-IMM, LOAD, STORE, JALR (I S) - //False for LUI, AUIPC, JAL (U J) - assign co_immdec_ctrl[1] = (opcode[1:0] == 2'b00) | (opcode[2:1] == 2'b00); - assign co_immdec_ctrl[2] = opcode[4] & !opcode[0]; - assign co_immdec_ctrl[3] = opcode[4]; + wire m1 = opcode[3:0] == 4'b1000; - wire [3:0] co_immdec_en; - assign co_immdec_en[3] = opcode[4] | opcode[3] | opcode[2] | !opcode[0]; //B I J S U - assign co_immdec_en[2] = (opcode[4] & opcode[2]) | !opcode[3] | opcode[0]; // I J U - assign co_immdec_en[1] = (opcode[2:1] == 2'b01) | (opcode[2] & opcode[0]) | co_csr_imm_en;// J U - assign co_immdec_en[0] = ~co_rd_op; //B S + wire [1:0] m2; + assign m2[1] = opcode[4] & !opcode[0]; - wire [2:0] co_alu_rd_sel; - assign co_alu_rd_sel[0] = (funct3 == 3'b000); // Add/sub - assign co_alu_rd_sel[1] = (funct3[2:1] == 2'b01); //SLT* - assign co_alu_rd_sel[2] = funct3[2]; //Bool + //True for OP-IMM, LOAD, STORE, JALR + //False for LUI, AUIPC, JAL + assign m2[0] = (opcode[1:0] == 2'b00) | (opcode[2:1] == 2'b00); + wire m3 = opcode[4]; + + assign o_imm = i_cnt_done ? signbit : m1 ? imm11_7[0] : imm24_20[0]; //0 (OP_B_SOURCE_IMM) when OPIMM //1 (OP_B_SOURCE_RS2) when BRANCH or OP - wire co_op_b_source = opcode[3]; + assign o_op_b_source = opcode[3]; - generate - if (PRE_REGISTER) begin : gen_pre_register + assign o_rd_alu_en = !opcode[0] & opcode[2] & !opcode[4]; - always @(posedge clk) begin - if (i_wb_en) begin - funct3 <= i_wb_rdt[14:12]; - imm30 <= i_wb_rdt[30]; - imm25 <= i_wb_rdt[25]; - opcode <= i_wb_rdt[6:2]; - op20 <= i_wb_rdt[20]; - op21 <= i_wb_rdt[21]; - op22 <= i_wb_rdt[22]; - op26 <= i_wb_rdt[26]; - end - end - - always @(*) begin - o_sh_right = co_sh_right; - o_bne_or_bge = co_bne_or_bge; - o_cond_branch = co_cond_branch; - o_dbus_en = co_dbus_en; - o_mtval_pc = co_mtval_pc; - o_two_stage_op = co_two_stage_op; - o_e_op = co_e_op; - o_ebreak = co_ebreak; - o_branch_op = co_branch_op; - o_shift_op = co_shift_op; - o_rd_op = co_rd_op; - o_mdu_op = co_mdu_op; - o_ext_funct3 = co_ext_funct3; - o_bufreg_rs1_en = co_bufreg_rs1_en; - o_bufreg_imm_en = co_bufreg_imm_en; - o_bufreg_clr_lsb = co_bufreg_clr_lsb; - o_bufreg_sh_signed = co_bufreg_sh_signed; - o_ctrl_jal_or_jalr = co_ctrl_jal_or_jalr; - o_ctrl_utype = co_ctrl_utype; - o_ctrl_pc_rel = co_ctrl_pc_rel; - o_ctrl_mret = co_ctrl_mret; - o_alu_sub = co_alu_sub; - o_alu_bool_op = co_alu_bool_op; - o_alu_cmp_eq = co_alu_cmp_eq; - o_alu_cmp_sig = co_alu_cmp_sig; - o_alu_rd_sel = co_alu_rd_sel; - o_mem_signed = co_mem_signed; - o_mem_word = co_mem_word; - o_mem_half = co_mem_half; - o_mem_cmd = co_mem_cmd; - o_csr_en = co_csr_en; - o_csr_addr = co_csr_addr; - o_csr_mstatus_en = co_csr_mstatus_en; - o_csr_mie_en = co_csr_mie_en; - o_csr_mcause_en = co_csr_mcause_en; - o_csr_source = co_csr_source; - o_csr_d_sel = co_csr_d_sel; - o_csr_imm_en = co_csr_imm_en; - o_immdec_ctrl = co_immdec_ctrl; - o_immdec_en = co_immdec_en; - o_op_b_source = co_op_b_source; - o_rd_csr_en = co_rd_csr_en; - o_rd_alu_en = co_rd_alu_en; - o_rd_mem_en = co_rd_mem_en; - end - - end else begin : gen_post_register - - always @(*) begin - funct3 = i_wb_rdt[14:12]; - imm30 = i_wb_rdt[30]; - imm25 = i_wb_rdt[25]; - opcode = i_wb_rdt[6:2]; - op20 = i_wb_rdt[20]; - op21 = i_wb_rdt[21]; - op22 = i_wb_rdt[22]; - op26 = i_wb_rdt[26]; - end - - always @(posedge clk) begin - if (i_wb_en) begin - o_sh_right <= co_sh_right; - o_bne_or_bge <= co_bne_or_bge; - o_cond_branch <= co_cond_branch; - o_e_op <= co_e_op; - o_ebreak <= co_ebreak; - o_two_stage_op <= co_two_stage_op; - o_dbus_en <= co_dbus_en; - o_mtval_pc <= co_mtval_pc; - o_branch_op <= co_branch_op; - o_shift_op <= co_shift_op; - o_rd_op <= co_rd_op; - o_mdu_op <= co_mdu_op; - o_ext_funct3 <= co_ext_funct3; - o_bufreg_rs1_en <= co_bufreg_rs1_en; - o_bufreg_imm_en <= co_bufreg_imm_en; - o_bufreg_clr_lsb <= co_bufreg_clr_lsb; - o_bufreg_sh_signed <= co_bufreg_sh_signed; - o_ctrl_jal_or_jalr <= co_ctrl_jal_or_jalr; - o_ctrl_utype <= co_ctrl_utype; - o_ctrl_pc_rel <= co_ctrl_pc_rel; - o_ctrl_mret <= co_ctrl_mret; - o_alu_sub <= co_alu_sub; - o_alu_bool_op <= co_alu_bool_op; - o_alu_cmp_eq <= co_alu_cmp_eq; - o_alu_cmp_sig <= co_alu_cmp_sig; - o_alu_rd_sel <= co_alu_rd_sel; - o_mem_signed <= co_mem_signed; - o_mem_word <= co_mem_word; - o_mem_half <= co_mem_half; - o_mem_cmd <= co_mem_cmd; - o_csr_en <= co_csr_en; - o_csr_addr <= co_csr_addr; - o_csr_mstatus_en <= co_csr_mstatus_en; - o_csr_mie_en <= co_csr_mie_en; - o_csr_mcause_en <= co_csr_mcause_en; - o_csr_source <= co_csr_source; - o_csr_d_sel <= co_csr_d_sel; - o_csr_imm_en <= co_csr_imm_en; - o_immdec_ctrl <= co_immdec_ctrl; - o_immdec_en <= co_immdec_en; - o_op_b_source <= co_op_b_source; - o_rd_csr_en <= co_rd_csr_en; - o_rd_alu_en <= co_rd_alu_en; - o_rd_mem_en <= co_rd_mem_en; - end - end - - end - endgenerate endmodule diff --git a/rtl/serv_immdec.v b/rtl/serv_immdec.v deleted file mode 100644 index 1a6e129..0000000 --- a/rtl/serv_immdec.v +++ /dev/null @@ -1,95 +0,0 @@ -`default_nettype none -module serv_immdec - #(parameter SHARED_RFADDR_IMM_REGS = 1) - ( - input wire i_clk, - //State - input wire i_cnt_en, - input wire i_cnt_done, - //Control - input wire [3:0] i_immdec_en, - input wire i_csr_imm_en, - input wire [3:0] i_ctrl, - output wire [4:0] o_rd_addr, - output wire [4:0] o_rs1_addr, - output wire [4:0] o_rs2_addr, - //Data - output wire o_csr_imm, - output wire o_imm, - //External - input wire i_wb_en, - input wire [31:7] i_wb_rdt); - - reg imm31; - - reg [8:0] imm19_12_20; - reg imm7; - reg [5:0] imm30_25; - reg [4:0] imm24_20; - reg [4:0] imm11_7; - - assign o_csr_imm = imm19_12_20[4]; - - wire signbit = imm31 & !i_csr_imm_en; - - generate - if (SHARED_RFADDR_IMM_REGS) begin : gen_shared_imm_regs - assign o_rs1_addr = imm19_12_20[8:4]; - assign o_rs2_addr = imm24_20; - assign o_rd_addr = imm11_7; - - always @(posedge i_clk) begin - if (i_wb_en) begin - /* CSR immediates are always zero-extended, hence clear the signbit */ - imm31 <= i_wb_rdt[31]; - end - if (i_wb_en | (i_cnt_en & i_immdec_en[1])) - imm19_12_20 <= i_wb_en ? {i_wb_rdt[19:12],i_wb_rdt[20]} : {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]}; - if (i_wb_en | (i_cnt_en)) - imm7 <= i_wb_en ? i_wb_rdt[7] : signbit; - - if (i_wb_en | (i_cnt_en & i_immdec_en[3])) - imm30_25 <= i_wb_en ? i_wb_rdt[30:25] : {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]}; - - if (i_wb_en | (i_cnt_en & i_immdec_en[2])) - imm24_20 <= i_wb_en ? i_wb_rdt[24:20] : {imm30_25[0], imm24_20[4:1]}; - - if (i_wb_en | (i_cnt_en & i_immdec_en[0])) - imm11_7 <= i_wb_en ? i_wb_rdt[11:7] : {imm30_25[0], imm11_7[4:1]}; - end - end else begin : gen_separate_imm_regs - reg [4:0] rd_addr; - reg [4:0] rs1_addr; - reg [4:0] rs2_addr; - - assign o_rd_addr = rd_addr; - assign o_rs1_addr = rs1_addr; - assign o_rs2_addr = rs2_addr; - always @(posedge i_clk) begin - if (i_wb_en) begin - /* CSR immediates are always zero-extended, hence clear the signbit */ - imm31 <= i_wb_rdt[31]; - imm19_12_20 <= {i_wb_rdt[19:12],i_wb_rdt[20]}; - imm7 <= i_wb_rdt[7]; - imm30_25 <= i_wb_rdt[30:25]; - imm24_20 <= i_wb_rdt[24:20]; - imm11_7 <= i_wb_rdt[11:7]; - - rd_addr <= i_wb_rdt[11:7]; - rs1_addr <= i_wb_rdt[19:15]; - rs2_addr <= i_wb_rdt[24:20]; - end - if (i_cnt_en) begin - imm19_12_20 <= {i_ctrl[3] ? signbit : imm24_20[0], imm19_12_20[8:1]}; - imm7 <= signbit; - imm30_25 <= {i_ctrl[2] ? imm7 : i_ctrl[1] ? signbit : imm19_12_20[0], imm30_25[5:1]}; - imm24_20 <= {imm30_25[0], imm24_20[4:1]}; - imm11_7 <= {imm30_25[0], imm11_7[4:1]}; - end - end - end - endgenerate - - assign o_imm = i_cnt_done ? signbit : i_ctrl[0] ? imm11_7[0] : imm24_20[0]; - -endmodule diff --git a/rtl/serv_mem_if.v b/rtl/serv_mem_if.v index be68499..91695c7 100644 --- a/rtl/serv_mem_if.v +++ b/rtl/serv_mem_if.v @@ -1,53 +1,81 @@ `default_nettype none module serv_mem_if - #( - parameter [0:0] WITH_CSR = 1, - parameter W = 1, - parameter B = W-1 - ) ( - input wire i_clk, - //State - input wire [1:0] i_bytecnt, - input wire [1:0] i_lsb, - output wire o_misalign, - //Control - input wire i_signed, - input wire i_word, - input wire i_half, - //MDU - input wire i_mdu_op, - //Data - input wire [B:0] i_bufreg2_q, - output wire [B:0] o_rd, + input wire i_clk, + input wire i_en, + input wire i_init, + input wire i_mem_op, + input wire i_signed, + input wire i_word, + input wire i_half, + input wire [1:0] i_bytecnt, + input wire i_rs2, + output wire o_rd, + input wire [1:0] i_lsb, + output wire o_misalign, //External interface - output wire [3:0] o_wb_sel); + output wire [31:0] o_wb_dat, + output wire [3:0] o_wb_sel, + input wire [31:0] i_wb_rdt, + input wire i_wb_ack); - reg signbit; + reg signbit; + reg misalign; - wire dat_valid = - i_mdu_op | - i_word | - (i_bytecnt == 2'b00) | - (i_half & !i_bytecnt[1]); + reg [7:0] dat0; + reg [7:0] dat1; + reg [7:0] dat2; + reg [7:0] dat3; + wire dat0_en; + wire dat1_en; + wire dat2_en; + wire dat3_en; - assign o_rd = dat_valid ? i_bufreg2_q : {W{i_signed & signbit}}; + wire [1:0] dat_sel = i_bytecnt[1] ? i_bytecnt : (i_bytecnt | i_lsb); - assign o_wb_sel[3] = (i_lsb == 2'b11) | i_word | (i_half & i_lsb[1]); + wire dat_cur = (dat_sel == 3) ? dat3[0] : + (dat_sel == 2) ? dat2[0] : + (dat_sel == 1) ? dat1[0] : dat0[0]; + + wire dat_valid = i_word | (i_bytecnt == 2'b00) | (i_half & !i_bytecnt[1]); + assign o_rd = i_mem_op & (dat_valid ? dat_cur : signbit & i_signed); + + assign o_wb_sel[3] = i_word | (i_half & i_lsb[1]) | (i_lsb == 2'b11); assign o_wb_sel[2] = (i_lsb == 2'b10) | i_word; - assign o_wb_sel[1] = (i_lsb == 2'b01) | i_word | (i_half & !i_lsb[1]); + assign o_wb_sel[1] = ((i_word | i_half) & !i_lsb[1]) | (i_lsb == 2'b01); assign o_wb_sel[0] = (i_lsb == 2'b00); + wire wbyte0 = (i_bytecnt == 2'b00); + wire wbyte1 = ((i_bytecnt == 2'b01) & !i_lsb[0]); + wire wbyte2 = ((i_bytecnt == 2'b10) & !i_lsb[1]); + wire wbyte3 = ((i_bytecnt == 2'b11) & !i_lsb[1]); + + assign dat0_en = i_en & (i_init ? wbyte0 : (dat_sel == 2'd0)); + assign dat1_en = i_en & (i_init ? (wbyte0 | wbyte1) : (dat_sel == 2'd1)); + assign dat2_en = i_en & (i_init ? (wbyte0 | wbyte2) : (dat_sel == 2'd2)); + assign dat3_en = i_en & (i_init ? (wbyte0 | wbyte1 | wbyte3) : (dat_sel == 2'd3)); + + assign o_wb_dat = {dat3,dat2,dat1,dat0}; + + assign o_misalign = misalign & i_mem_op; + always @(posedge i_clk) begin + + if (dat0_en) + dat0 <= {i_rs2, dat0[7:1]}; + if (dat1_en) + dat1 <= {i_rs2, dat1[7:1]}; + if (dat2_en) + dat2 <= {i_rs2, dat2[7:1]}; + if (dat3_en) + dat3 <= {i_rs2, dat3[7:1]}; + + if (i_wb_ack) + {dat3,dat2,dat1,dat0} <= i_wb_rdt; + + misalign <= (i_lsb[0] & (i_word | i_half)) | (i_lsb[1] & i_word); if (dat_valid) - signbit <= i_bufreg2_q[B]; + signbit <= dat_cur; + end - - /* - mem_misalign is checked after the init stage to decide whether to do a data - bus transaction or go to the trap state. It is only guaranteed to be correct - at this time - */ - assign o_misalign = WITH_CSR & ((i_lsb[0] & (i_word | i_half)) | (i_lsb[1] & i_word)); - endmodule diff --git a/rtl/serv_params.vh b/rtl/serv_params.vh new file mode 100644 index 0000000..0cf79d9 --- /dev/null +++ b/rtl/serv_params.vh @@ -0,0 +1,11 @@ +localparam [1:0] + CSR_SOURCE_CSR = 2'b00, + CSR_SOURCE_EXT = 2'b01, + CSR_SOURCE_SET = 2'b10, + CSR_SOURCE_CLR = 2'b11; + +localparam [1:0] + CSR_MSCRATCH = 2'b00, + CSR_MTVEC = 2'b01, + CSR_MEPC = 2'b10, + CSR_MTVAL = 2'b11; diff --git a/rtl/serv_rf_if.v b/rtl/serv_rf_if.v index 4394e85..61b1f23 100644 --- a/rtl/serv_rf_if.v +++ b/rtl/serv_rf_if.v @@ -1,89 +1,78 @@ `default_nettype none module serv_rf_if - #(parameter WITH_CSR = 1, - parameter W = 1, - parameter B = W-1 - ) (//RF Interface - input wire i_cnt_en, - output wire [4+WITH_CSR:0] o_wreg0, - output wire [4+WITH_CSR:0] o_wreg1, - output wire o_wen0, - output wire o_wen1, - output wire [B:0] o_wdata0, - output wire [B:0] o_wdata1, - output wire [4+WITH_CSR:0] o_rreg0, - output wire [4+WITH_CSR:0] o_rreg1, - input wire [B:0] i_rdata0, - input wire [B:0] i_rdata1, + output wire [5:0] o_wreg0, + output wire [5:0] o_wreg1, + output wire o_wen0, + output wire o_wen1, + output wire o_wdata0, + output wire o_wdata1, + output wire [5:0] o_rreg0, + output wire [5:0] o_rreg1, + input wire i_rdata0, + input wire i_rdata1, //Trap interface - input wire i_trap, - input wire i_mret, - input wire [B:0] i_mepc, - input wire i_mtval_pc, - input wire [B:0] i_bufreg_q, - input wire [B:0] i_bad_pc, - output wire [B:0] o_csr_pc, + input wire i_trap, + input wire i_mret, + input wire i_mepc, + input wire i_mem_misalign, + input wire i_bufreg_q, + input wire i_bad_pc, + output wire o_csr_pc, //CSR interface - input wire i_csr_en, - input wire [1:0] i_csr_addr, - input wire [B:0] i_csr, - output wire [B:0] o_csr, + input wire i_csr_en, + input wire [1:0] i_csr_addr, + input wire i_csr, + output wire o_csr, //RD write port - input wire i_rd_wen, - input wire [4:0] i_rd_waddr, - input wire [B:0] i_ctrl_rd, - input wire [B:0] i_alu_rd, - input wire i_rd_alu_en, - input wire [B:0] i_csr_rd, - input wire i_rd_csr_en, - input wire [B:0] i_mem_rd, - input wire i_rd_mem_en, + input wire i_rd_wen, + input wire [4:0] i_rd_waddr, + input wire i_ctrl_rd, + input wire i_alu_rd, + input wire i_rd_alu_en, + input wire i_csr_rd, + input wire i_rd_csr_en, + input wire i_mem_rd, //RS1 read port - input wire [4:0] i_rs1_raddr, - output wire [B:0] o_rs1, + input wire [4:0] i_rs1_raddr, + output wire o_rs1, //RS2 read port - input wire [4:0] i_rs2_raddr, - output wire [B:0] o_rs2); + input wire [4:0] i_rs2_raddr, + output wire o_rs2); + parameter WITH_CSR = 1; + +`include "serv_params.vh" /* ********** Write side *********** */ - wire rd_wen = i_rd_wen & (|i_rd_waddr); - generate - if (|WITH_CSR) begin : gen_csr - wire [B:0] rd = - {W{i_rd_alu_en}} & i_alu_rd | - {W{i_rd_csr_en}} & i_csr_rd | - {W{i_rd_mem_en}} & i_mem_rd | - i_ctrl_rd; + if (WITH_CSR) begin + wire rd = (i_ctrl_rd ) | + (i_alu_rd & i_rd_alu_en) | + (i_csr_rd & i_rd_csr_en) | + (i_mem_rd); - wire [B:0] mtval = i_mtval_pc ? i_bad_pc : i_bufreg_q; + wire mtval = i_mem_misalign ? i_bufreg_q : i_bad_pc; assign o_wdata0 = i_trap ? mtval : rd; assign o_wdata1 = i_trap ? i_mepc : i_csr; - /* Port 0 handles writes to mtval during traps and rd otherwise - * Port 1 handles writes to mepc during traps and csr accesses otherwise - * - * GPR registers are mapped to address 0-31 (bits 0xxxxx). - * Following that are four CSR registers - * mscratch 100000 - * mtvec 100001 - * mepc 100010 - * mtval 100011 - */ + //port 0 rd mtval + //port 1 csr mepc + //mepc 100010 + //mtval 100011 + //csr 1000xx + //rd 0xxxxx + assign o_wreg0 = i_trap ? {4'b1000,CSR_MTVAL} : {1'b0,i_rd_waddr}; + assign o_wreg1 = i_trap ? {4'b1000,CSR_MEPC} : {4'b1000,i_csr_addr}; - assign o_wreg0 = i_trap ? {6'b100011} : {1'b0,i_rd_waddr}; - assign o_wreg1 = i_trap ? {6'b100010} : {4'b1000,i_csr_addr}; - - assign o_wen0 = i_cnt_en & (i_trap | rd_wen); - assign o_wen1 = i_cnt_en & (i_trap | i_csr_en); + assign o_wen0 = i_trap | i_rd_wen; + assign o_wen1 = i_trap | i_csr_en; /* ********** Read side *********** @@ -92,62 +81,41 @@ module serv_rf_if //0 : RS1 //1 : RS2 / CSR + assign o_rreg0 = {1'b0, i_rs1_raddr}; - - /* - The address of the second read port (o_rreg1) can get assigned from four - different sources - - Normal operations : i_rs2_raddr - CSR access : i_csr_addr - trap : MTVEC - mret : MEPC - - Address 0-31 in the RF are assigned to the GPRs. After that follows the four - CSRs on addresses 32-35 - - 32 MSCRATCH - 33 MTVEC - 34 MEPC - 35 MTVAL - - The expression below is an optimized version of this logic - */ - wire sel_rs2 = !(i_trap | i_mret | i_csr_en); - assign o_rreg1 = {~sel_rs2, - i_rs2_raddr[4:2] & {3{sel_rs2}}, - {1'b0,i_trap} | {i_mret,1'b0} | ({2{i_csr_en}} & i_csr_addr) | ({2{sel_rs2}} & i_rs2_raddr[1:0])}; + assign o_rreg1 = + i_trap ? {4'b1000, CSR_MTVEC} : + i_mret ? {4'b1000, CSR_MEPC} : + i_csr_en ? {4'b1000, i_csr_addr} : + {1'b0,i_rs2_raddr}; assign o_rs1 = i_rdata0; assign o_rs2 = i_rdata1; - assign o_csr = i_rdata1 & {W{i_csr_en}}; + assign o_csr = i_rdata1 & i_csr_en; assign o_csr_pc = i_rdata1; - end else begin : gen_no_csr - wire [B:0] rd = (i_ctrl_rd) | - i_alu_rd & {W{i_rd_alu_en}} | - i_mem_rd & {W{i_rd_mem_en}}; + end else begin + wire rd = (i_ctrl_rd ) | + (i_alu_rd & i_rd_alu_en) | + (i_mem_rd); assign o_wdata0 = rd; - assign o_wdata1 = {W{1'b0}}; + assign o_wdata1 = 1'b0; - assign o_wreg0 = i_rd_waddr; - assign o_wreg1 = 5'd0; + assign o_wreg0 = {1'b0,i_rd_waddr}; - assign o_wen0 = i_cnt_en & rd_wen; + assign o_wen0 =i_rd_wen; assign o_wen1 = 1'b0; /* ********** Read side *********** */ - assign o_rreg0 = i_rs1_raddr; - assign o_rreg1 = i_rs2_raddr; + assign o_rreg0 = {1'b0, i_rs1_raddr}; + assign o_rreg1 = {1'b0, i_rs2_raddr}; assign o_rs1 = i_rdata0; assign o_rs2 = i_rdata1; - assign o_csr = {W{1'b0}}; - assign o_csr_pc = {W{1'b0}}; end // else: !if(WITH_CSR) endgenerate endmodule diff --git a/rtl/serv_rf_ram.v b/rtl/serv_rf_ram.v index 6c96fa6..9bbc503 100644 --- a/rtl/serv_rf_ram.v +++ b/rtl/serv_rf_ram.v @@ -7,35 +7,16 @@ module serv_rf_ram input wire [width-1:0] i_wdata, input wire i_wen, input wire [$clog2(depth)-1:0] i_raddr, - input wire i_ren, - output wire [width-1:0] o_rdata); - + output reg [width-1:0] o_rdata); + reg [width-1:0] memory [0:depth-1]; - reg [width-1:0] rdata ; always @(posedge i_clk) begin if (i_wen) memory[i_waddr] <= i_wdata; - rdata <= i_ren ? memory[i_raddr] : {width{1'bx}}; + o_rdata <= memory[i_raddr]; end - /* Reads from reg x0 needs to return 0 - Check that the part of the read address corresponding to the register - is zero and gate the output - width LSB of reg index $clog2(width) - 2 4 1 - 4 3 2 - 8 2 3 - 16 1 4 - 32 0 5 - */ - reg regzero; - - always @(posedge i_clk) - regzero <= !(|i_raddr[$clog2(depth)-1:5-$clog2(width)]); - - assign o_rdata = rdata & ~{width{regzero}}; - `ifdef SERV_CLEAR_RAM integer i; initial diff --git a/rtl/serv_rf_ram_if.v b/rtl/serv_rf_ram_if.v index b39ad11..ec94fdb 100644 --- a/rtl/serv_rf_ram_if.v +++ b/rtl/serv_rf_ram_if.v @@ -1,177 +1,159 @@ `default_nettype none module serv_rf_ram_if - #(//Data width. Adjust to preferred width of SRAM data interface - parameter width=8, - - parameter W = 1, - //Select reset strategy. - // "MINI" for resetting minimally required FFs - // "NONE" for relying on FFs having a defined value on startup - parameter reset_strategy="MINI", - - //Number of CSR registers. These are allocated after the normal - // GPR registers in the RAM. + #(parameter width=8, parameter csr_regs=4, - - //Internal parameters calculated from above values. Do not change - parameter B=W-1, - parameter raw=$clog2(32+csr_regs), //Register address width - parameter l2w=$clog2(width), //log2 of width - parameter aw=5+raw-l2w) //Address width + parameter depth=32*(32+csr_regs)/width) ( //SERV side - input wire i_clk, - input wire i_rst, - input wire i_wreq, - input wire i_rreq, - output wire o_ready, - input wire [raw-1:0] i_wreg0, - input wire [raw-1:0] i_wreg1, - input wire i_wen0, - input wire i_wen1, - input wire [B:0] i_wdata0, - input wire [B:0] i_wdata1, - input wire [raw-1:0] i_rreg0, - input wire [raw-1:0] i_rreg1, - output wire [B:0] o_rdata0, - output wire [B:0] o_rdata1, + input wire i_clk, + input wire i_rst, + input wire i_wreq, + input wire i_rreq, + output wire o_ready, + input wire [5:0] i_wreg0, + input wire [5:0] i_wreg1, + input wire i_wen0, + input wire i_wen1, + input wire i_wdata0, + input wire i_wdata1, + input wire [5:0] i_rreg0, + input wire [5:0] i_rreg1, + output wire o_rdata0, + output wire o_rdata1, //RAM side - output wire [aw-1:0] o_waddr, - output wire [width-1:0] o_wdata, - output wire o_wen, - output wire [aw-1:0] o_raddr, - output wire o_ren, - input wire [width-1:0] i_rdata); + output wire [$clog2(depth)-1:0] o_waddr, + output wire [width-1:0] o_wdata, + output wire o_wen, + output wire [$clog2(depth)-1:0] o_raddr, + input wire [width-1:0] i_rdata); - localparam ratio = width/W; - localparam CMSB = 4-$clog2(W); //Counter MSB - localparam l2r = $clog2(ratio); + localparam l2w = $clog2(width); reg rgnt; assign o_ready = rgnt | i_wreq; - reg [CMSB:0] rcnt; - reg rtrig1; /* ********** Write side *********** */ - wire [CMSB:0] wcnt; + reg [4:0] wcnt; + reg wgo; - reg [width-1:0] wdata0_r; - reg [width+W-1:0] wdata1_r; + + reg [width-2:0] wdata0_r; + reg [width-1:0] wdata1_r; reg wen0_r; reg wen1_r; wire wtrig0; wire wtrig1; - assign wtrig0 = rtrig1; - - generate if (ratio == 2) begin : gen_wtrig_ratio_eq_2 + generate if (width == 2) begin + assign wtrig0 = ~wcnt[0]; assign wtrig1 = wcnt[0]; - end else begin : gen_wtrig_ratio_neq_2 + end else begin reg wtrig0_r; always @(posedge i_clk) wtrig0_r <= wtrig0; + assign wtrig0 = (wcnt[l2w-1:0] == {{l2w-1{1'b1}},1'b0}); assign wtrig1 = wtrig0_r; end endgenerate assign o_wdata = wtrig1 ? - wdata1_r[width-1:0] : - wdata0_r; + wdata1_r : + {i_wdata0, wdata0_r}; - wire [raw-1:0] wreg = wtrig1 ? i_wreg1 : i_wreg0; - generate if (width == 32) begin : gen_w_eq_32 - assign o_waddr = wreg; - end else begin : gen_w_neq_32 - assign o_waddr = {wreg, wcnt[CMSB:l2r]}; - end + wire [5:0] wreg = wtrig1 ? i_wreg1 : i_wreg0; + generate if (width == 32) + assign o_waddr = wreg; + else + assign o_waddr = {wreg, wcnt[4:l2w]}; endgenerate - assign o_wen = (wtrig0 & wen0_r) | (wtrig1 & wen1_r); + assign o_wen = wgo & ((wtrig0 & wen0_r) | (wtrig1 & wen1_r)); - assign wcnt = rcnt-4; + reg wreq_r; + + generate if (width > 2) + always @(posedge i_clk) wdata0_r <= {i_wdata0, wdata0_r[width-2:1]}; + else + always @(posedge i_clk) wdata0_r <= i_wdata0; + endgenerate always @(posedge i_clk) begin - if (wcnt[0]) begin - wen0_r <= i_wen0; - wen1_r <= i_wen1; + wen0_r <= i_wen0; + wen1_r <= i_wen1; + wreq_r <= i_wreq | rgnt; + + wdata1_r <= {i_wdata1,wdata1_r[width-1:1]}; + + if (wgo) + wcnt <= wcnt+5'd1; + + if (wreq_r) begin + wgo <= 1'b1; end - wdata0_r <= {i_wdata0,wdata0_r[width-1:W]}; - wdata1_r <= {i_wdata1,wdata1_r[width+W-1:W]}; + if (wcnt == 5'b11111) + wgo <= 1'b0; + if (i_rst) begin + wcnt <= 5'd0; + end end /* ********** Read side *********** */ + reg [4:0] rcnt; wire rtrig0; + reg rtrig1; - wire [raw-1:0] rreg = rtrig0 ? i_rreg1 : i_rreg0; - generate if (width == 32) begin : gen_rreg_eq_32 - assign o_raddr = rreg; - end else begin : gen_rreg_neq_32 - assign o_raddr = {rreg, rcnt[CMSB:l2r]}; - end + wire [5:0] rreg = rtrig0 ? i_rreg1 : i_rreg0; + generate if (width == 32) + assign o_raddr = rreg; + else + assign o_raddr = {rreg, rcnt[4:l2w]}; endgenerate reg [width-1:0] rdata0; - reg [width-1-W:0] rdata1; + reg [width-2:0] rdata1; - reg rgate; + assign o_rdata0 = rdata0[0]; + assign o_rdata1 = rtrig1 ? i_rdata[0] : rdata1[0]; - assign o_rdata0 = rdata0[B:0]; - assign o_rdata1 = rtrig1 ? i_rdata[B:0] : rdata1[B:0]; - - assign rtrig0 = (rcnt[l2r-1:0] == 1); - - generate if (ratio == 2) begin : gen_ren_w_eq_2 - assign o_ren = rgate; - end else begin : gen_ren_w_neq_2 - assign o_ren = rgate & (rcnt[l2r-1:1] == 0); - end - endgenerate + assign rtrig0 = (rcnt[l2w-1:0] == 1); reg rreq_r; - generate if (ratio > 2) begin : gen_rdata1_w_neq_2 - always @(posedge i_clk) begin - rdata1 <= {{W{1'b0}},rdata1[width-W-1:W]}; - if (rtrig1) - rdata1[width-W-1:0] <= i_rdata[width-1:W]; - end - end else begin : gen_rdata1_w_eq_2 - always @(posedge i_clk) if (rtrig1) rdata1 <= i_rdata[W*2-1:W]; - end + generate if (width>2) + always @(posedge i_clk) begin + rdata1 <= {1'b0,rdata1[width-2:1]}; //Optimize? + if (rtrig1) + rdata1[width-2:0] <= i_rdata[width-1:1]; + end + else + always @(posedge i_clk) if (rtrig1) rdata1 <= i_rdata[1]; endgenerate always @(posedge i_clk) begin - if (&rcnt | i_rreq) - rgate <= i_rreq; - rtrig1 <= rtrig0; - rcnt <= rcnt+{{CMSB{1'b0}},1'b1}; - if (i_rreq | i_wreq) - rcnt <= {{CMSB-1{1'b0}},i_wreq,1'b0}; + rcnt <= rcnt+5'd1; + if (i_rreq) + rcnt <= 5'd0; rreq_r <= i_rreq; rgnt <= rreq_r; - rdata0 <= {{W{1'b0}}, rdata0[width-1:W]}; + rdata0 <= {1'b0,rdata0[width-1:1]}; if (rtrig0) rdata0 <= i_rdata; if (i_rst) begin - if (reset_strategy != "NONE") begin - rgate <= 1'b0; - rgnt <= 1'b0; - rreq_r <= 1'b0; - rcnt <= {CMSB+1{1'b0}}; - end + rgnt <= 1'b0; + rreq_r <= 1'b0; end end diff --git a/rtl/serv_rf_top.v b/rtl/serv_rf_top.v index 7b1c21a..b688012 100644 --- a/rtl/serv_rf_top.v +++ b/rtl/serv_rf_top.v @@ -1,37 +1,6 @@ `default_nettype none module serv_rf_top - #(parameter RESET_PC = 32'd0, - /* COMPRESSED=1: Enable the compressed decoder and allowed misaligned jump of pc - COMPRESSED=0: Disable the compressed decoder and does not allow the misaligned jump of pc - */ - parameter [0:0] COMPRESSED = 0, - /* - ALIGN = 1: Fetch the aligned instruction by making two bus transactions if the misaligned address - is given to the instruction bus. - */ - parameter [0:0] ALIGN = COMPRESSED, - /* Multiplication and Division Unit - This parameter enables the interface for connecting SERV and MDU - */ - parameter [0:0] MDU = 0, - /* Register signals before or after the decoder - 0 : Register after the decoder. Faster but uses more resources - 1 : (default) Register before the decoder. Slower but uses less resources - */ - parameter PRE_REGISTER = 1, - /* Amount of reset applied to design - "NONE" : No reset at all. Relies on a POR to set correct initialization - values and that core isn't reset during runtime - "MINI" : Standard setting. Resets the minimal amount of FFs needed to - restart execution from the instruction at RESET_PC - */ - parameter RESET_STRATEGY = "MINI", - parameter [0:0] DEBUG = 1'b0, - parameter WITH_CSR = 1, - parameter W = 1, - parameter RF_WIDTH = W * 2, - parameter RF_L2D = $clog2((32+(WITH_CSR*4))*32/RF_WIDTH)) ( input wire clk, input wire i_rst, @@ -69,45 +38,36 @@ module serv_rf_top output wire o_dbus_we , output wire o_dbus_cyc, input wire [31:0] i_dbus_rdt, - input wire i_dbus_ack, + input wire i_dbus_ack); - // Extension - output wire [31:0] o_ext_rs1, - output wire [31:0] o_ext_rs2, - output wire [ 2:0] o_ext_funct3, - input wire [31:0] i_ext_rd, - input wire i_ext_ready, - // MDU - output wire o_mdu_valid); - - localparam CSR_REGS = WITH_CSR*4; + parameter RESET_PC = 32'd0; + parameter WITH_CSR = 1; + parameter RF_WIDTH = 2; + localparam RF_L2W = $clog2(RF_WIDTH); wire rf_wreq; wire rf_rreq; - wire [4+WITH_CSR:0] wreg0; - wire [4+WITH_CSR:0] wreg1; + wire [5:0] wreg0; + wire [5:0] wreg1; wire wen0; wire wen1; - wire [W-1:0] wdata0; - wire [W-1:0] wdata1; - wire [4+WITH_CSR:0] rreg0; - wire [4+WITH_CSR:0] rreg1; + wire wdata0; + wire wdata1; + wire [5:0] rreg0; + wire [5:0] rreg1; wire rf_ready; - wire [W-1:0] rdata0; - wire [W-1:0] rdata1; + wire rdata0; + wire rdata1; - wire [RF_L2D-1:0] waddr; + wire [10-RF_L2W:0] waddr; wire [RF_WIDTH-1:0] wdata; - wire wen; - wire [RF_L2D-1:0] raddr; - wire ren; + wire wen; + wire [10-RF_L2W:0] raddr; wire [RF_WIDTH-1:0] rdata; serv_rf_ram_if #(.width (RF_WIDTH), - .reset_strategy (RESET_STRATEGY), - .csr_regs (CSR_REGS), - .W(W)) + .csr_regs (WITH_CSR*4)) rf_ram_if (.i_clk (clk), .i_rst (i_rst), @@ -128,31 +88,22 @@ module serv_rf_top .o_wdata (wdata), .o_wen (wen), .o_raddr (raddr), - .o_ren (ren), .i_rdata (rdata)); serv_rf_ram #(.width (RF_WIDTH), - .csr_regs (CSR_REGS)) + .csr_regs (WITH_CSR*4)) rf_ram (.i_clk (clk), .i_waddr (waddr), .i_wdata (wdata), .i_wen (wen), .i_raddr (raddr), - .i_ren (ren), .o_rdata (rdata)); serv_top #(.RESET_PC (RESET_PC), - .PRE_REGISTER (PRE_REGISTER), - .RESET_STRATEGY (RESET_STRATEGY), - .WITH_CSR (WITH_CSR), - .DEBUG (DEBUG), - .MDU(MDU), - .COMPRESSED(COMPRESSED), - .ALIGN(ALIGN), - .W(W)) + .WITH_CSR (WITH_CSR)) cpu ( .clk (clk), @@ -206,16 +157,6 @@ module serv_rf_top .o_dbus_we (o_dbus_we), .o_dbus_cyc (o_dbus_cyc), .i_dbus_rdt (i_dbus_rdt), - .i_dbus_ack (i_dbus_ack), - - //Extension - .o_ext_funct3 (o_ext_funct3), - .i_ext_ready (i_ext_ready), - .i_ext_rd (i_ext_rd), - .o_ext_rs1 (o_ext_rs1), - .o_ext_rs2 (o_ext_rs2), - //MDU - .o_mdu_valid (o_mdu_valid)); + .i_dbus_ack (i_dbus_ack)); endmodule -`default_nettype wire diff --git a/rtl/serv_state.v b/rtl/serv_state.v index bd73b3c..6938c25 100644 --- a/rtl/serv_state.v +++ b/rtl/serv_state.v @@ -1,233 +1,143 @@ module serv_state - #(parameter RESET_STRATEGY = "MINI", - parameter [0:0] WITH_CSR = 1, - parameter [0:0] ALIGN =0, - parameter [0:0] MDU = 0, - parameter W = 1 - ) ( input wire i_clk, input wire i_rst, - //State input wire i_new_irq, - input wire i_alu_cmp, + output wire o_trap_taken, + output reg o_pending_irq, + input wire i_dbus_ack, + input wire i_ibus_ack, + output wire o_rf_rreq, + output wire o_rf_wreq, + input wire i_rf_ready, + output wire o_rf_rd_en, + input wire i_take_branch, + input wire i_branch_op, + input wire i_mem_op, + input wire i_shift_op, + input wire i_slt_op, + input wire i_e_op, + input wire i_rd_op, output wire o_init, - output wire o_cnt_en, - output wire o_cnt0to3, - output wire o_cnt12to31, - output wire o_cnt0, - output wire o_cnt1, - output wire o_cnt2, - output wire o_cnt3, - output wire o_cnt7, - output wire o_cnt11, - output wire o_cnt12, - output wire o_cnt_done, - output wire o_bufreg_en, + output wire o_cnt_en, + output reg [4:0] o_cnt, + output reg [3:0] o_cnt_r, output wire o_ctrl_pc_en, output reg o_ctrl_jump, output wire o_ctrl_trap, input wire i_ctrl_misalign, - input wire i_sh_done, + output wire o_alu_shamt_en, + input wire i_alu_sh_done, + output wire o_dbus_cyc, output wire [1:0] o_mem_bytecnt, input wire i_mem_misalign, - //Control - input wire i_bne_or_bge, - input wire i_cond_branch, - input wire i_dbus_en, - input wire i_two_stage_op, - input wire i_branch_op, - input wire i_shift_op, - input wire i_sh_right, - input wire i_alu_rd_sel1, - input wire i_rd_alu_en, - input wire i_e_op, - input wire i_rd_op, - //MDU - input wire i_mdu_op, - output wire o_mdu_valid, - //Extension - input wire i_mdu_ready, - //External - output wire o_dbus_cyc, - input wire i_dbus_ack, - output wire o_ibus_cyc, - input wire i_ibus_ack, - //RF Interface - output wire o_rf_rreq, - output wire o_rf_wreq, - input wire i_rf_ready, - output wire o_rf_rd_en); + output reg o_cnt_done, + output wire o_bufreg_hold); - reg init_done; - wire misalign_trap_sync; + parameter WITH_CSR = 1; - reg [4:2] o_cnt; - wire [3:0] cnt_r; + localparam [1:0] + IDLE = 2'd0, + INIT = 2'd1, + RUN = 2'd2, + TRAP = 2'd3; + + reg [1:0] state; + + reg stage_two_req; - reg ibus_cyc; //Update PC in RUN or TRAP states assign o_ctrl_pc_en = o_cnt_en & !o_init; + assign o_alu_shamt_en = (o_cnt < 5) & o_init; + assign o_mem_bytecnt = o_cnt[4:3]; - assign o_cnt0to3 = (o_cnt[4:2] == 3'd0); - assign o_cnt12to31 = (o_cnt[4] | (o_cnt[3:2] == 2'b11)); - assign o_cnt0 = (o_cnt[4:2] == 3'd0) & cnt_r[0]; - assign o_cnt1 = (o_cnt[4:2] == 3'd0) & cnt_r[1]; - assign o_cnt2 = (o_cnt[4:2] == 3'd0) & cnt_r[2]; - assign o_cnt3 = (o_cnt[4:2] == 3'd0) & cnt_r[3]; - assign o_cnt7 = (o_cnt[4:2] == 3'd1) & cnt_r[3]; - assign o_cnt11 = (o_cnt[4:2] == 3'd2) & cnt_r[3]; - assign o_cnt12 = (o_cnt[4:2] == 3'd3) & cnt_r[0]; + assign o_cnt_en = (state != IDLE); - //Take branch for jump or branch instructions (opcode == 1x0xx) if - //a) It's an unconditional branch (opcode[0] == 1) - //b) It's a conditional branch (opcode[0] == 0) of type beq,blt,bltu (funct3[0] == 0) and ALU compare is true - //c) It's a conditional branch (opcode[0] == 0) of type bne,bge,bgeu (funct3[0] == 1) and ALU compare is false - //Only valid during the last cycle of INIT, when the branch condition has - //been calculated. - wire take_branch = i_branch_op & (!i_cond_branch | (i_alu_cmp^i_bne_or_bge)); + assign o_init = (state == INIT); - wire last_init = o_cnt_done & o_init; + //slt*, branch/jump, shift, load/store + wire two_stage_op = i_slt_op | i_mem_op | i_branch_op | i_shift_op; - //valid signal for mdu - assign o_mdu_valid = MDU & !o_cnt_en & init_done & i_mdu_op; + reg stage_two_pending; - //Prepare RF for writes when everything is ready to enter stage two - // and the first stage didn't cause a misalign exception - //Left shifts, SLT & Branch ops. First cycle after init - //Right shift. o_sh_done - //Mem ops. i_dbus_ack - //MDU ops. i_mdu_ready - assign o_rf_wreq = (i_shift_op & (i_sh_right ? (i_sh_done & (last_init | !o_cnt_en & init_done)) : last_init)) | - i_dbus_ack | (MDU & i_mdu_ready) | - (i_branch_op & (last_init & !trap_pending)) | - (i_rd_alu_en & i_alu_rd_sel1 & last_init); + assign o_dbus_cyc = (state == IDLE) & stage_two_pending & i_mem_op & !i_mem_misalign; - assign o_dbus_cyc = !o_cnt_en & init_done & i_dbus_en & !i_mem_misalign; + wire trap_pending = (o_ctrl_jump & i_ctrl_misalign) | i_mem_misalign; //Prepare RF for reads when a new instruction is fetched // or when stage one caused an exception (rreq implies a write request too) - assign o_rf_rreq = i_ibus_ack | (trap_pending & last_init); + assign o_rf_rreq = i_ibus_ack | (stage_two_req & trap_pending); - assign o_rf_rd_en = i_rd_op & !o_init; + //Prepare RF for writes when everything is ready to enter stage two + assign o_rf_wreq = ((i_shift_op & i_alu_sh_done & stage_two_pending) | (i_mem_op & i_dbus_ack) | (stage_two_req & (i_slt_op | i_branch_op))) & !trap_pending; - /* - bufreg is used during mem, branch, and shift operations + assign o_rf_rd_en = i_rd_op & o_cnt_en & !o_init; - mem : bufreg is used for dbus address. Shift in data during phase 1. - Shift out during phase 2 if there was a misalignment exception. + //Shift operations require bufreg to hold for one cycle between INIT and RUN before shifting + assign o_bufreg_hold = !o_cnt_en & (stage_two_req | ~i_shift_op); - branch : Shift in during phase 1. Shift out during phase 2 - shift : Shift in during phase 1. Continue shifting between phases (except - for the first cycle after init). Shift out during phase 2 - */ - - assign o_bufreg_en = (o_cnt_en & (o_init | ((o_ctrl_trap | i_branch_op) & i_two_stage_op))) | (i_shift_op & init_done & (i_sh_right | i_sh_done)); - - assign o_ibus_cyc = ibus_cyc & !i_rst; - - assign o_init = i_two_stage_op & !i_new_irq & !init_done; - - assign o_cnt_done = (o_cnt[4:2] == 3'b111) & cnt_r[3]; always @(posedge i_clk) begin - //ibus_cyc changes on three conditions. - //1. i_rst is asserted. Together with the async gating above, o_ibus_cyc - // will be asserted as soon as the reset is released. This is how the - // first instruction is fetched - //2. o_cnt_done and o_ctrl_pc_en are asserted. This means that SERV just - // finished updating the PC, is done with the current instruction and - // o_ibus_cyc gets asserted to fetch a new instruction - //3. When i_ibus_ack, a new instruction is fetched and o_ibus_cyc gets - // deasserted to finish the transaction - if (i_ibus_ack | o_cnt_done | i_rst) - ibus_cyc <= o_ctrl_pc_en | i_rst; + if (o_cnt_done) + o_ctrl_jump <= o_init & i_take_branch; - if (o_cnt_done) begin - init_done <= o_init & !init_done; - o_ctrl_jump <= o_init & take_branch; - end + if (o_cnt_en) + stage_two_pending <= o_init; + + o_cnt_done <= (o_cnt[4:2] == 3'b111) & o_cnt_r[2]; + + //Need a strobe for the first cycle in the IDLE state after INIT + stage_two_req <= o_cnt_done & (state == INIT); + + if (i_rf_ready && !o_cnt_en) + if (i_e_op | o_pending_irq | (stage_two_pending & trap_pending)) + state <= TRAP; + else if (two_stage_op & !stage_two_pending) + state <= INIT; + else + state <= RUN; + + if (o_cnt_done) + state <= IDLE; + + o_cnt <= o_cnt + {4'd0,o_cnt_en}; + if (o_cnt_en) + o_cnt_r <= {o_cnt_r[2:0],o_cnt_r[3]}; if (i_rst) begin - if (RESET_STRATEGY != "NONE") begin - init_done <= 1'b0; - o_ctrl_jump <= 1'b0; - end + state <= IDLE; + o_cnt <= 5'd0; + stage_two_pending <= 1'b0; + o_ctrl_jump <= 1'b0; + o_cnt_r <= 4'b0001; end end generate - /* - Because SERV is 32-bit bit-serial we need a counter than can count 0-31 - to keep track of which bit we are currently processing. o_cnt and cnt_r - are used together to create such a counter. - The top three bits (o_cnt) are implemented as a normal counter, but - instead of the two LSB, cnt_r is a 4-bit shift register which loops 0-3 - When cnt_r[3] is 1, o_cnt will be increased. + if (WITH_CSR) begin + reg irq_sync; + reg misalign_trap_sync; - The counting starts when the core is idle and the i_rf_ready signal - comes in from the RF module by shifting in the i_rf_ready bit as LSB of - the shift register. Counting is stopped by using o_cnt_done to block the - bit that was supposed to be shifted into bit 0 of cnt_r. + assign o_ctrl_trap = i_e_op | o_pending_irq | misalign_trap_sync; + assign o_trap_taken = i_ibus_ack & o_ctrl_trap; - There are two benefit of doing the counter this way - 1. We only need to check four bits instead of five when we want to check - if the counter is at a certain value. For 4-LUT architectures this means - we only need one LUT instead of two for each comparison. - 2. We don't need a separate enable signal to turn on and off the counter - between stages, which saves an extra FF and a unique control signal. We - just need to check if cnt_r is not zero to see if the counter is - currently running - */ - if (W == 1) begin : gen_cnt_w_eq_1 - reg [3:0] cnt_lsb; - always @(posedge i_clk) begin - o_cnt <= o_cnt + {2'd0,cnt_r[3]}; - cnt_lsb <= {cnt_lsb[2:0],(cnt_lsb[3] & !o_cnt_done) | i_rf_ready}; - if (i_rst & (RESET_STRATEGY != "NONE")) begin - o_cnt <= 3'd0; - cnt_lsb <= 4'b0000; - end - end - assign cnt_r = cnt_lsb; - assign o_cnt_en = |cnt_lsb; - end else if (W == 4) begin : gen_cnt_w_eq_4 - reg cnt_en; - always @(posedge i_clk) begin - if (i_rf_ready) cnt_en <= 1; else - if (o_cnt_done) cnt_en <= 0; - o_cnt <= o_cnt + { 2'd0, cnt_en }; - if (i_rst & (RESET_STRATEGY != "NONE")) begin - o_cnt <= 3'd0; - cnt_en <= 1'b0; - end - end - assign cnt_r = 4'b1111; - assign o_cnt_en = cnt_en; - end - endgenerate + always @(posedge i_clk) begin + if (i_ibus_ack) + irq_sync <= 1'b0; + if (i_new_irq) + irq_sync <= 1'b1; - assign o_ctrl_trap = WITH_CSR & (i_e_op | i_new_irq | misalign_trap_sync); + if (i_ibus_ack) + o_pending_irq <= irq_sync; - //trap_pending is only guaranteed to have correct value during the - // last cycle of the init stage - wire trap_pending = WITH_CSR & ((take_branch & i_ctrl_misalign & !ALIGN) | - (i_dbus_en & i_mem_misalign)); - - generate - if (WITH_CSR) begin : gen_csr - reg misalign_trap_sync_r; - - always @(posedge i_clk) begin - if (i_ibus_ack | o_cnt_done | i_rst) - misalign_trap_sync_r <= !(i_ibus_ack | i_rst) & ((trap_pending & o_init) | misalign_trap_sync_r); - end - assign misalign_trap_sync = misalign_trap_sync_r; - end else begin : gen_no_csr - assign misalign_trap_sync = 1'b0; - end + if (stage_two_req) + misalign_trap_sync <= trap_pending; + if (i_ibus_ack) + misalign_trap_sync <= 1'b0; + end // always @ (posedge i_clk) + end // if (WITH_CSR) endgenerate endmodule diff --git a/rtl/serv_synth_wrapper.v b/rtl/serv_synth_wrapper.v deleted file mode 100644 index d377688..0000000 --- a/rtl/serv_synth_wrapper.v +++ /dev/null @@ -1,132 +0,0 @@ -`default_nettype none - -module serv_synth_wrapper - #( - /* Register signals before or after the decoder - 0 : Register after the decoder. Faster but uses more resources - 1 : (default) Register before the decoder. Slower but uses less resources - */ - parameter PRE_REGISTER = 1, - /* Amount of reset applied to design - "NONE" : No reset at all. Relies on a POR to set correct initialization - values and that core isn't reset during runtime - "MINI" : Standard setting. Resets the minimal amount of FFs needed to - restart execution from the instruction at RESET_PC - */ - parameter RESET_STRATEGY = "MINI", - parameter WITH_CSR = 1, - parameter RF_WIDTH = 2, - parameter RF_L2D = $clog2((32+(WITH_CSR*4))*32/RF_WIDTH)) - ( - input wire clk, - input wire i_rst, - input wire i_timer_irq, - output wire [31:0] o_ibus_adr, - output wire o_ibus_cyc, - input wire [31:0] i_ibus_rdt, - input wire i_ibus_ack, - output wire [31:0] o_dbus_adr, - output wire [31:0] o_dbus_dat, - output wire [3:0] o_dbus_sel, - output wire o_dbus_we , - output wire o_dbus_cyc, - input wire [31:0] i_dbus_rdt, - input wire i_dbus_ack, - - output wire [RF_L2D-1:0] o_waddr, - output wire [RF_WIDTH-1:0] o_wdata, - output wire o_wen, - output wire [RF_L2D-1:0] o_raddr, - input wire [RF_WIDTH-1:0] i_rdata); - - localparam CSR_REGS = WITH_CSR*4; - - wire rf_wreq; - wire rf_rreq; - wire [4+WITH_CSR:0] wreg0; - wire [4+WITH_CSR:0] wreg1; - wire wen0; - wire wen1; - wire wdata0; - wire wdata1; - wire [4+WITH_CSR:0] rreg0; - wire [4+WITH_CSR:0] rreg1; - wire rf_ready; - wire rdata0; - wire rdata1; - - serv_rf_ram_if - #(.width (RF_WIDTH), - .reset_strategy (RESET_STRATEGY), - .csr_regs (CSR_REGS)) - rf_ram_if - (.i_clk (clk), - .i_rst (i_rst), - .i_wreq (rf_wreq), - .i_rreq (rf_rreq), - .o_ready (rf_ready), - .i_wreg0 (wreg0), - .i_wreg1 (wreg1), - .i_wen0 (wen0), - .i_wen1 (wen1), - .i_wdata0 (wdata0), - .i_wdata1 (wdata1), - .i_rreg0 (rreg0), - .i_rreg1 (rreg1), - .o_rdata0 (rdata0), - .o_rdata1 (rdata1), - .o_waddr (o_waddr), - .o_wdata (o_wdata), - .o_wen (o_wen), - .o_raddr (o_raddr), - .i_rdata (i_rdata)); - - serv_top - #(.RESET_PC (32'd0), - .PRE_REGISTER (PRE_REGISTER), - .RESET_STRATEGY (RESET_STRATEGY), - .WITH_CSR (WITH_CSR), - .MDU(1'b0)) - cpu - ( - .clk (clk), - .i_rst (i_rst), - .i_timer_irq (i_timer_irq), - .o_rf_rreq (rf_rreq), - .o_rf_wreq (rf_wreq), - .i_rf_ready (rf_ready), - .o_wreg0 (wreg0), - .o_wreg1 (wreg1), - .o_wen0 (wen0), - .o_wen1 (wen1), - .o_wdata0 (wdata0), - .o_wdata1 (wdata1), - .o_rreg0 (rreg0), - .o_rreg1 (rreg1), - .i_rdata0 (rdata0), - .i_rdata1 (rdata1), - - .o_ibus_adr (o_ibus_adr), - .o_ibus_cyc (o_ibus_cyc), - .i_ibus_rdt (i_ibus_rdt), - .i_ibus_ack (i_ibus_ack), - - .o_dbus_adr (o_dbus_adr), - .o_dbus_dat (o_dbus_dat), - .o_dbus_sel (o_dbus_sel), - .o_dbus_we (o_dbus_we), - .o_dbus_cyc (o_dbus_cyc), - .i_dbus_rdt (i_dbus_rdt), - .i_dbus_ack (i_dbus_ack), - - //Extension - .o_ext_funct3 (), - .i_ext_ready (1'b0), - .i_ext_rd (32'd0), - .o_ext_rs1 (), - .o_ext_rs2 (), - //MDU - .o_mdu_valid ()); - -endmodule -`default_nettype wire diff --git a/rtl/serv_top.v b/rtl/serv_top.v index 425f325..503f69a 100644 --- a/rtl/serv_top.v +++ b/rtl/serv_top.v @@ -1,330 +1,231 @@ `default_nettype none module serv_top - #(parameter WITH_CSR = 1, - parameter W = 1, - parameter B = W-1, - parameter PRE_REGISTER = 1, - parameter RESET_STRATEGY = "MINI", - parameter RESET_PC = 32'd0, - parameter [0:0] DEBUG = 1'b0, - parameter [0:0] MDU = 1'b0, - parameter [0:0] COMPRESSED=0, - parameter [0:0] ALIGN = COMPRESSED) - ( - input wire clk, - input wire i_rst, - input wire i_timer_irq, + ( + input wire clk, + input wire i_rst, + input wire i_timer_irq, `ifdef RISCV_FORMAL - output wire rvfi_valid, - output wire [63:0] rvfi_order, - output wire [31:0] rvfi_insn, - output wire rvfi_trap, - output wire rvfi_halt, - output wire rvfi_intr, - output wire [1:0] rvfi_mode, - output wire [1:0] rvfi_ixl, - output wire [4:0] rvfi_rs1_addr, - output wire [4:0] rvfi_rs2_addr, - output wire [31:0] rvfi_rs1_rdata, - output wire [31:0] rvfi_rs2_rdata, - output wire [4:0] rvfi_rd_addr, - output wire [31:0] rvfi_rd_wdata, - output wire [31:0] rvfi_pc_rdata, - output wire [31:0] rvfi_pc_wdata, - output wire [31:0] rvfi_mem_addr, - output wire [3:0] rvfi_mem_rmask, - output wire [3:0] rvfi_mem_wmask, - output wire [31:0] rvfi_mem_rdata, - output wire [31:0] rvfi_mem_wdata, + output reg rvfi_valid = 1'b0, + output reg [63:0] rvfi_order = 64'd0, + output reg [31:0] rvfi_insn = 32'd0, + output reg rvfi_trap = 1'b0, + output reg rvfi_halt = 1'b0, + output reg rvfi_intr = 1'b0, + output reg [1:0] rvfi_mode = 2'b11, + output reg [1:0] rvfi_ixl = 2'b01, + output reg [4:0] rvfi_rs1_addr, + output reg [4:0] rvfi_rs2_addr, + output reg [31:0] rvfi_rs1_rdata, + output reg [31:0] rvfi_rs2_rdata, + output reg [4:0] rvfi_rd_addr, + output reg [31:0] rvfi_rd_wdata, + output reg [31:0] rvfi_pc_rdata, + output reg [31:0] rvfi_pc_wdata, + output reg [31:0] rvfi_mem_addr, + output reg [3:0] rvfi_mem_rmask, + output reg [3:0] rvfi_mem_wmask, + output reg [31:0] rvfi_mem_rdata, + output reg [31:0] rvfi_mem_wdata, `endif //RF Interface - output wire o_rf_rreq, - output wire o_rf_wreq, - input wire i_rf_ready, - output wire [4+WITH_CSR:0] o_wreg0, - output wire [4+WITH_CSR:0] o_wreg1, - output wire o_wen0, - output wire o_wen1, - output wire [B:0] o_wdata0, - output wire [B:0] o_wdata1, - output wire [4+WITH_CSR:0] o_rreg0, - output wire [4+WITH_CSR:0] o_rreg1, - input wire [B:0] i_rdata0, - input wire [B:0] i_rdata1, + output wire o_rf_rreq, + output wire o_rf_wreq, + input wire i_rf_ready, + output wire [5:0] o_wreg0, + output wire [5:0] o_wreg1, + output wire o_wen0, + output wire o_wen1, + output wire o_wdata0, + output wire o_wdata1, + output wire [5:0] o_rreg0, + output wire [5:0] o_rreg1, + input wire i_rdata0, + input wire i_rdata1, - output wire [31:0] o_ibus_adr, - output wire o_ibus_cyc, - input wire [31:0] i_ibus_rdt, - input wire i_ibus_ack, - output wire [31:0] o_dbus_adr, - output wire [31:0] o_dbus_dat, - output wire [3:0] o_dbus_sel, - output wire o_dbus_we , - output wire o_dbus_cyc, - input wire [31:0] i_dbus_rdt, - input wire i_dbus_ack, - //Extension - output wire [ 2:0] o_ext_funct3, - input wire i_ext_ready, - input wire [31:0] i_ext_rd, - output wire [31:0] o_ext_rs1, - output wire [31:0] o_ext_rs2, - //MDU - output wire o_mdu_valid); + output wire [31:0] o_ibus_adr, + output wire o_ibus_cyc, + input wire [31:0] i_ibus_rdt, + input wire i_ibus_ack, + output wire [31:0] o_dbus_adr, + output wire [31:0] o_dbus_dat, + output wire [3:0] o_dbus_sel, + output wire o_dbus_we , + output wire o_dbus_cyc, + input wire [31:0] i_dbus_rdt, + input wire i_dbus_ack); + + parameter WITH_CSR = 1; wire [4:0] rd_addr; wire [4:0] rs1_addr; wire [4:0] rs2_addr; - wire [3:0] immdec_ctrl; - wire [3:0] immdec_en; - - wire sh_right; - wire bne_or_bge; - wire cond_branch; - wire two_stage_op; + wire take_branch; wire e_op; wire ebreak; wire branch_op; + wire mem_op; wire shift_op; + wire slt_op; wire rd_op; - wire mdu_op; wire rd_alu_en; wire rd_csr_en; - wire rd_mem_en; - wire [B:0] ctrl_rd; - wire [B:0] alu_rd; - wire [B:0] mem_rd; - wire [B:0] csr_rd; - wire mtval_pc; + wire ctrl_rd; + wire alu_rd; + wire mem_rd; + wire csr_rd; wire ctrl_pc_en; wire jump; wire jal_or_jalr; wire utype; wire mret; - wire [B:0] imm; + wire imm; wire trap; wire pc_rel; - wire iscomp; wire init; wire cnt_en; - wire cnt0to3; - wire cnt12to31; - wire cnt0; - wire cnt1; - wire cnt2; - wire cnt3; - wire cnt7; - wire cnt11; - wire cnt12; + wire [4:0] cnt; + wire [3:0] cnt_r; wire cnt_done; - wire bufreg_en; - wire bufreg_sh_signed; + wire bufreg_hold; wire bufreg_rs1_en; wire bufreg_imm_en; - wire bufreg_clr_lsb; - wire [B:0] bufreg_q; - wire [B:0] bufreg2_q; - wire [31:0] dbus_rdt; - wire dbus_ack; + wire bufreg_loop; + wire bufreg_q; wire alu_sub; wire [1:0] alu_bool_op; wire alu_cmp_eq; - wire alu_cmp_sig; + wire alu_cmp_uns; wire alu_cmp; - wire [2:0] alu_rd_sel; + wire alu_shamt_en; + wire alu_sh_signed; + wire alu_sh_right; + wire alu_sh_done; + wire [3:0] alu_rd_sel; - wire [B:0] rs1; - wire [B:0] rs2; + wire rs1; + wire rs2; wire rd_en; - wire [B:0] op_b; - wire op_b_sel; + wire op_b_source; + wire op_b; wire mem_signed; wire mem_word; wire mem_half; wire [1:0] mem_bytecnt; - wire sh_done; wire mem_misalign; - wire [B:0] bad_pc; + wire bad_pc; wire csr_mstatus_en; wire csr_mie_en; wire csr_mcause_en; wire [1:0] csr_source; - wire [B:0] csr_imm; + wire csr_imm; wire csr_d_sel; wire csr_en; wire [1:0] csr_addr; - wire [B:0] csr_pc; - wire csr_imm_en; - wire [B:0] csr_in; - wire [B:0] rf_csr_out; - wire dbus_en; + wire csr_pc; + + parameter RESET_PC = 32'd0; wire new_irq; + wire trap_taken; + wire pending_irq; wire [1:0] lsb; - - wire [31:0] i_wb_rdt; - - wire [31:0] wb_ibus_adr; - wire wb_ibus_cyc; - wire [31:0] wb_ibus_rdt; - wire wb_ibus_ack; - - generate - if (ALIGN) begin : gen_align - serv_aligner align - ( - .clk(clk), - .rst(i_rst), - // serv_rf_top - .i_ibus_adr(wb_ibus_adr), - .i_ibus_cyc(wb_ibus_cyc), - .o_ibus_rdt(wb_ibus_rdt), - .o_ibus_ack(wb_ibus_ack), - // servant_arbiter - .o_wb_ibus_adr(o_ibus_adr), - .o_wb_ibus_cyc(o_ibus_cyc), - .i_wb_ibus_rdt(i_ibus_rdt), - .i_wb_ibus_ack(i_ibus_ack)); - end else begin : gen_no_align - assign o_ibus_adr = wb_ibus_adr; - assign o_ibus_cyc = wb_ibus_cyc; - assign wb_ibus_rdt = i_ibus_rdt; - assign wb_ibus_ack = i_ibus_ack; - end - endgenerate - - generate - if (COMPRESSED) begin : gen_compressed - serv_compdec compdec - ( - .i_clk(clk), - .i_instr(wb_ibus_rdt), - .i_ack(wb_ibus_ack), - .o_instr(i_wb_rdt), - .o_iscomp(iscomp)); - end else begin : gen_no_compressed - assign i_wb_rdt = wb_ibus_rdt; - assign iscomp = 1'b0; - end - endgenerate + wire [31:0] bufreg_out; serv_state - #(.RESET_STRATEGY (RESET_STRATEGY), - .WITH_CSR (WITH_CSR[0:0]), - .MDU(MDU), - .ALIGN(ALIGN), - .W(W)) + #(.WITH_CSR (WITH_CSR)) state ( .i_clk (clk), .i_rst (i_rst), - //State .i_new_irq (new_irq), - .i_alu_cmp (alu_cmp), + .o_trap_taken (trap_taken), + .o_pending_irq (pending_irq), + .i_dbus_ack (i_dbus_ack), + .i_ibus_ack (i_ibus_ack), + .o_rf_rreq (o_rf_rreq), + .o_rf_wreq (o_rf_wreq), + .i_rf_ready (i_rf_ready), + .o_rf_rd_en (rd_en), + .i_take_branch (take_branch), + .i_branch_op (branch_op), + .i_mem_op (mem_op), + .i_shift_op (shift_op), + .i_slt_op (slt_op), + .i_e_op (e_op), + .i_rd_op (rd_op), .o_init (init), .o_cnt_en (cnt_en), - .o_cnt0to3 (cnt0to3), - .o_cnt12to31 (cnt12to31), - .o_cnt0 (cnt0), - .o_cnt1 (cnt1), - .o_cnt2 (cnt2), - .o_cnt3 (cnt3), - .o_cnt7 (cnt7), - .o_cnt11 (cnt11), - .o_cnt12 (cnt12), + .o_cnt (cnt), + .o_cnt_r (cnt_r), .o_cnt_done (cnt_done), - .o_bufreg_en (bufreg_en), + .o_bufreg_hold (bufreg_hold), .o_ctrl_pc_en (ctrl_pc_en), .o_ctrl_jump (jump), .o_ctrl_trap (trap), .i_ctrl_misalign(lsb[1]), - .i_sh_done (sh_done), - .o_mem_bytecnt (mem_bytecnt), - .i_mem_misalign (mem_misalign), - //Control - .i_bne_or_bge (bne_or_bge), - .i_cond_branch (cond_branch), - .i_dbus_en (dbus_en), - .i_two_stage_op (two_stage_op), - .i_branch_op (branch_op), - .i_shift_op (shift_op), - .i_sh_right (sh_right), - .i_alu_rd_sel1 (alu_rd_sel[1]), - .i_rd_alu_en (rd_alu_en), - .i_e_op (e_op), - .i_rd_op (rd_op), - //MDU - .i_mdu_op (mdu_op), - .o_mdu_valid (o_mdu_valid), - //Extension - .i_mdu_ready (i_ext_ready), - //External + .o_alu_shamt_en (alu_shamt_en), + .i_alu_sh_done (alu_sh_done), .o_dbus_cyc (o_dbus_cyc), - .i_dbus_ack (i_dbus_ack), - .o_ibus_cyc (wb_ibus_cyc), - .i_ibus_ack (wb_ibus_ack), - //RF Interface - .o_rf_rreq (o_rf_rreq), - .o_rf_wreq (o_rf_wreq), - .i_rf_ready (i_rf_ready), - .o_rf_rd_en (rd_en)); + .o_mem_bytecnt (mem_bytecnt), + .i_mem_misalign (mem_misalign)); - serv_decode - #(.PRE_REGISTER (PRE_REGISTER), - .MDU(MDU)) - decode + wire bufreg_clr_lsb; + + serv_decode decode ( .clk (clk), //Input - .i_wb_rdt (i_wb_rdt[31:2]), - .i_wb_en (wb_ibus_ack), + .i_cnt_en (cnt_en), + .i_cnt_done (cnt_done), + .i_wb_rdt (i_ibus_rdt[31:2]), + .i_wb_en (o_ibus_cyc & i_ibus_ack), + .i_alu_cmp (alu_cmp), //To state - .o_bne_or_bge (bne_or_bge), - .o_cond_branch (cond_branch), - .o_dbus_en (dbus_en), + .o_take_branch (take_branch), .o_e_op (e_op), .o_ebreak (ebreak), .o_branch_op (branch_op), + .o_mem_op (mem_op), .o_shift_op (shift_op), + .o_slt_op (slt_op), .o_rd_op (rd_op), - .o_sh_right (sh_right), - .o_mdu_op (mdu_op), - .o_two_stage_op (two_stage_op), - //Extension - .o_ext_funct3 (o_ext_funct3), - //To bufreg + .o_bufreg_loop (bufreg_loop), .o_bufreg_rs1_en (bufreg_rs1_en), .o_bufreg_imm_en (bufreg_imm_en), .o_bufreg_clr_lsb (bufreg_clr_lsb), - .o_bufreg_sh_signed (bufreg_sh_signed), - //To bufreg2 - .o_op_b_source (op_b_sel), //To ctrl .o_ctrl_jal_or_jalr (jal_or_jalr), .o_ctrl_utype (utype), .o_ctrl_pc_rel (pc_rel), .o_ctrl_mret (mret), //To alu + .o_op_b_source (op_b_source), .o_alu_sub (alu_sub), .o_alu_bool_op (alu_bool_op), .o_alu_cmp_eq (alu_cmp_eq), - .o_alu_cmp_sig (alu_cmp_sig), + .o_alu_cmp_uns (alu_cmp_uns), + .o_alu_sh_signed (alu_sh_signed), + .o_alu_sh_right (alu_sh_right), .o_alu_rd_sel (alu_rd_sel), + //To RF + .o_rf_rd_addr (rd_addr), + .o_rf_rs1_addr (rs1_addr), + .o_rf_rs2_addr (rs2_addr), //To mem IF .o_mem_cmd (o_dbus_we), .o_mem_signed (mem_signed), @@ -338,108 +239,49 @@ module serv_top .o_csr_mcause_en (csr_mcause_en), .o_csr_source (csr_source), .o_csr_d_sel (csr_d_sel), - .o_csr_imm_en (csr_imm_en), - .o_mtval_pc (mtval_pc ), + .o_csr_imm (csr_imm), //To top - .o_immdec_ctrl (immdec_ctrl), - .o_immdec_en (immdec_en), - //To RF IF - .o_rd_mem_en (rd_mem_en), + .o_imm (imm), .o_rd_csr_en (rd_csr_en), .o_rd_alu_en (rd_alu_en)); - serv_immdec immdec - ( - .i_clk (clk), - //State - .i_cnt_en (cnt_en), - .i_cnt_done (cnt_done), - //Control - .i_immdec_en (immdec_en), - .i_csr_imm_en (csr_imm_en), - .i_ctrl (immdec_ctrl), - .o_rd_addr (rd_addr), - .o_rs1_addr (rs1_addr), - .o_rs2_addr (rs2_addr), - //Data - .o_csr_imm (csr_imm), - .o_imm (imm), - //External - .i_wb_en (wb_ibus_ack), - .i_wb_rdt (i_wb_rdt[31:7])); + assign o_dbus_adr = {bufreg_out[31:2], 2'b00}; - serv_bufreg - #(.MDU(MDU)) - bufreg + serv_bufreg bufreg ( .i_clk (clk), - //State - .i_cnt0 (cnt0), - .i_cnt1 (cnt1), - .i_en (bufreg_en), + .i_cnt (cnt[4:2]), + .i_cnt_r (cnt_r[1:0]), + .i_en (!bufreg_hold), .i_init (init), - .i_mdu_op (mdu_op), - .o_lsb (lsb), - //Control - .i_sh_signed (bufreg_sh_signed), - .i_rs1_en (bufreg_rs1_en), - .i_imm_en (bufreg_imm_en), - .i_clr_lsb (bufreg_clr_lsb), - //Data + .i_loop (bufreg_loop), .i_rs1 (rs1), + .i_rs1_en (bufreg_rs1_en), .i_imm (imm), - .o_q (bufreg_q), - //External - .o_dbus_adr (o_dbus_adr), - .o_ext_rs1 (o_ext_rs1)); - - serv_bufreg2 bufreg2 - ( - .i_clk (clk), - //State - .i_en (cnt_en), - .i_init (init), - .i_cnt7 (cnt7), - .i_cnt_done (cnt_done), - .i_sh_right (sh_right), - .i_lsb (lsb), - .i_bytecnt (mem_bytecnt), - .o_sh_done (sh_done), - //Control - .i_op_b_sel (op_b_sel), - .i_shift_op (shift_op), - //Data - .i_rs2 (rs2), - .i_imm (imm), - .o_op_b (op_b), - .o_q (bufreg2_q), - //External - .o_dat (o_dbus_dat), - .i_load (dbus_ack), - .i_dat (dbus_rdt)); + .i_imm_en (bufreg_imm_en), + .i_clr_lsb (bufreg_clr_lsb), + .o_lsb (lsb), + .o_reg (bufreg_out), + .o_q (bufreg_q)); serv_ctrl #(.RESET_PC (RESET_PC), - .RESET_STRATEGY (RESET_STRATEGY), - .WITH_CSR (WITH_CSR), - .W (W)) + .WITH_CSR (WITH_CSR)) ctrl ( .clk (clk), .i_rst (i_rst), //State .i_pc_en (ctrl_pc_en), - .i_cnt12to31 (cnt12to31), - .i_cnt0 (cnt0), - .i_cnt1 (cnt1), - .i_cnt2 (cnt2), + .i_cnt (cnt[4:2]), + .i_cnt_r (cnt_r[2]), + .i_cnt_done (cnt_done), //Control .i_jump (jump), .i_jal_or_jalr (jal_or_jalr), .i_utype (utype), .i_pc_rel (pc_rel), .i_trap (trap | mret), - .i_iscomp (iscomp), //Data .i_imm (imm), .i_buf (bufreg_q), @@ -447,32 +289,42 @@ module serv_top .o_rd (ctrl_rd), .o_bad_pc (bad_pc), //External - .o_ibus_adr (wb_ibus_adr)); + .o_ibus_adr (o_ibus_adr), + .o_ibus_cyc (o_ibus_cyc), + .i_ibus_ack (i_ibus_ack)); - serv_alu #(.W (W)) alu + + serv_alu alu ( .clk (clk), - //State + .i_rst (i_rst), .i_en (cnt_en), - .i_cnt0 (cnt0), - .o_cmp (alu_cmp), - //Control + .i_rs1 (rs1), + .i_rs2 (rs2), + .i_imm (imm), + .i_op_b_rs2 (op_b_source), + .i_buf (bufreg_q), + .i_init (init), + .i_cnt_done (cnt_done), .i_sub (alu_sub), .i_bool_op (alu_bool_op), .i_cmp_eq (alu_cmp_eq), - .i_cmp_sig (alu_cmp_sig), + .i_cmp_uns (alu_cmp_uns), + .o_cmp (alu_cmp), + .i_shamt_en (alu_shamt_en), + .i_sh_right (alu_sh_right), + .i_sh_signed (alu_sh_signed), + .o_sh_done (alu_sh_done), .i_rd_sel (alu_rd_sel), - //Data - .i_rs1 (rs1), - .i_op_b (op_b), - .i_buf (bufreg_q), .o_rd (alu_rd)); + wire csr_in; + wire rf_csr_out; + serv_rf_if - #(.WITH_CSR (WITH_CSR), .W(W)) + #(.WITH_CSR (WITH_CSR)) rf_if (//RF interface - .i_cnt_en (cnt_en), .o_wreg0 (o_wreg0), .o_wreg1 (o_wreg1), .o_wen0 (o_wen0), @@ -487,8 +339,8 @@ module serv_top //Trap interface .i_trap (trap), .i_mret (mret), - .i_mepc (wb_ibus_adr[B:0]), - .i_mtval_pc (mtval_pc), + .i_mepc (o_ibus_adr[0]), + .i_mem_misalign (mem_misalign), .i_bufreg_q (bufreg_q), .i_bad_pc (bad_pc), .o_csr_pc (csr_pc), @@ -505,7 +357,6 @@ module serv_top .i_csr_rd (csr_rd), .i_rd_csr_en (rd_csr_en), .i_mem_rd (mem_rd), - .i_rd_mem_en (rd_mem_en), //RS1 read port .i_rs1_raddr (rs1_addr), @@ -517,147 +368,116 @@ module serv_top //CSR read port .o_csr (rf_csr_out)); - serv_mem_if - #(.WITH_CSR (WITH_CSR[0:0]), - .W (W)) - mem_if + serv_mem_if mem_if ( - .i_clk (clk), - //State - .i_bytecnt (mem_bytecnt), - .i_lsb (lsb), - .o_misalign (mem_misalign), - //Control - .i_mdu_op (mdu_op), - .i_signed (mem_signed), - .i_word (mem_word), - .i_half (mem_half), - //Data - .i_bufreg2_q (bufreg2_q), - .o_rd (mem_rd), + .i_clk (clk), + .i_en (cnt_en), + .i_init (init), + .i_mem_op (mem_op), + .i_signed (mem_signed), + .i_word (mem_word), + .i_half (mem_half), + .i_bytecnt (mem_bytecnt), + .i_rs2 (rs2), + .o_rd (mem_rd), + .i_lsb (lsb), + .o_misalign (mem_misalign), //External interface - .o_wb_sel (o_dbus_sel)); + .o_wb_dat (o_dbus_dat), + .o_wb_sel (o_dbus_sel), + .i_wb_rdt (i_dbus_rdt), + .i_wb_ack (i_dbus_ack)); generate - if (|WITH_CSR) begin : gen_csr - serv_csr - #(.RESET_STRATEGY (RESET_STRATEGY), - .W(W)) - csr + if (WITH_CSR) begin + serv_csr csr ( .i_clk (clk), - .i_rst (i_rst), - //State - .i_trig_irq (wb_ibus_ack), .i_en (cnt_en), - .i_cnt0to3 (cnt0to3), - .i_cnt3 (cnt3), - .i_cnt7 (cnt7), - .i_cnt11 (cnt11), - .i_cnt12 (cnt12), - .i_cnt_done (cnt_done), - .i_mem_op (!mtval_pc), - .i_mtip (i_timer_irq), - .i_trap (trap), - .o_new_irq (new_irq), - //Control + .i_cnt (cnt[4:2]), + .i_cnt_r (cnt_r[3:2]), .i_e_op (e_op), .i_ebreak (ebreak), .i_mem_cmd (o_dbus_we), + .i_mem_misalign (mem_misalign), + .i_rf_csr_out (rf_csr_out), + .o_csr_in (csr_in), + .i_mtip (i_timer_irq), + .o_new_irq (new_irq), + .i_trap_taken (trap_taken), + .i_pending_irq (pending_irq), .i_mstatus_en (csr_mstatus_en), .i_mie_en (csr_mie_en ), .i_mcause_en (csr_mcause_en ), .i_csr_source (csr_source), .i_mret (mret), - .i_csr_d_sel (csr_d_sel), - //Data - .i_rf_csr_out (rf_csr_out), - .o_csr_in (csr_in), - .i_csr_imm (csr_imm), - .i_rs1 (rs1), + .i_d (csr_d_sel ? csr_imm : rs1), .o_q (csr_rd)); - end else begin : gen_no_csr - assign csr_in = {W{1'b0}}; - assign csr_rd = {W{1'b0}}; + end else begin + assign csr_in = 1'b0; + assign csr_rd = 1'b0; assign new_irq = 1'b0; end endgenerate - generate - if (DEBUG) begin : gen_debug - serv_debug #(.W (W), .RESET_PC (RESET_PC)) debug - ( + `ifdef RISCV_FORMAL - .rvfi_valid (rvfi_valid ), - .rvfi_order (rvfi_order ), - .rvfi_insn (rvfi_insn ), - .rvfi_trap (rvfi_trap ), - .rvfi_halt (rvfi_halt ), - .rvfi_intr (rvfi_intr ), - .rvfi_mode (rvfi_mode ), - .rvfi_ixl (rvfi_ixl ), - .rvfi_rs1_addr (rvfi_rs1_addr ), - .rvfi_rs2_addr (rvfi_rs2_addr ), - .rvfi_rs1_rdata (rvfi_rs1_rdata), - .rvfi_rs2_rdata (rvfi_rs2_rdata), - .rvfi_rd_addr (rvfi_rd_addr ), - .rvfi_rd_wdata (rvfi_rd_wdata ), - .rvfi_pc_rdata (rvfi_pc_rdata ), - .rvfi_pc_wdata (rvfi_pc_wdata ), - .rvfi_mem_addr (rvfi_mem_addr ), - .rvfi_mem_rmask (rvfi_mem_rmask), - .rvfi_mem_wmask (rvfi_mem_wmask), - .rvfi_mem_rdata (rvfi_mem_rdata), - .rvfi_mem_wdata (rvfi_mem_wdata), - .i_dbus_adr (o_dbus_adr), - .i_dbus_dat (o_dbus_dat), - .i_dbus_sel (o_dbus_sel), - .i_dbus_we (o_dbus_we ), - .i_dbus_rdt (i_dbus_rdt), - .i_dbus_ack (i_dbus_ack), - .i_ctrl_pc_en (ctrl_pc_en), - .rs1 (rs1), - .rs2 (rs2), - .rs1_addr (rs1_addr), - .rs2_addr (rs2_addr), - .immdec_en (immdec_en), - .rd_en (rd_en), - .trap (trap), - .i_rf_ready (i_rf_ready), - .i_ibus_cyc (o_ibus_cyc), - .two_stage_op (two_stage_op), - .init (init), - .i_ibus_adr (o_ibus_adr), -`endif - .i_clk (clk), - .i_rst (i_rst), - .i_ibus_rdt (i_ibus_rdt), - .i_ibus_ack (i_ibus_ack), - .i_rd_addr (rd_addr ), - .i_cnt_en (cnt_en ), - .i_csr_in (csr_in ), - .i_csr_mstatus_en (csr_mstatus_en), - .i_csr_mie_en (csr_mie_en ), - .i_csr_mcause_en (csr_mcause_en ), - .i_csr_en (csr_en ), - .i_csr_addr (csr_addr), - .i_wen0 (o_wen0), - .i_wdata0 (o_wdata0), - .i_cnt_done (cnt_done)); + reg [31:0] pc = RESET_PC; + + wire rs_en = (branch_op|mem_op|shift_op|slt_op) ? init : ctrl_pc_en; + + always @(posedge clk) begin + rvfi_valid <= cnt_done & ctrl_pc_en & !i_rst; + rvfi_order <= rvfi_order + {63'd0,rvfi_valid}; + if (o_ibus_cyc & i_ibus_ack) + rvfi_insn <= i_ibus_rdt; + if (o_wen0) + rvfi_rd_wdata <= {o_wdata0,rvfi_rd_wdata[31:1]}; + if (cnt_done & ctrl_pc_en) begin + rvfi_pc_rdata <= pc; + if (!rd_en) + rvfi_rd_addr <= 5'd0; + if (!rd_en | !(|rd_addr)) + rvfi_rd_wdata <= 32'd0; end - endgenerate + rvfi_trap <= trap; + if (rvfi_valid) begin + rvfi_trap <= 1'b0; + pc <= rvfi_pc_wdata; + end + + rvfi_halt <= 1'b0; + rvfi_intr <= 1'b0; + rvfi_mode <= 2'd3; + rvfi_ixl = 2'd1; + if (i_rf_ready) begin + rvfi_rs1_addr <= rs1_addr; + rvfi_rs2_addr <= rs2_addr; + rvfi_rd_addr <= rd_addr; + end + if (rs_en) begin + rvfi_rs1_rdata <= {rs1,rvfi_rs1_rdata[31:1]}; + rvfi_rs2_rdata <= {rs2,rvfi_rs2_rdata[31:1]}; + end + + if (i_dbus_ack) begin + rvfi_mem_addr <= o_dbus_adr; + rvfi_mem_rmask <= o_dbus_we ? 4'b0000 : o_dbus_sel; + rvfi_mem_wmask <= o_dbus_we ? o_dbus_sel : 4'b0000; + rvfi_mem_rdata <= i_dbus_rdt; + rvfi_mem_wdata <= o_dbus_dat; + end + if (i_ibus_ack) begin + rvfi_mem_rmask <= 4'b0000; + rvfi_mem_wmask <= 4'b0000; + end + end + /* verilator lint_off COMBDLY */ + always @(o_ibus_adr) + rvfi_pc_wdata <= o_ibus_adr; + /* verilator lint_on COMBDLY */ -generate - if (MDU) begin: gen_mdu - assign dbus_rdt = i_ext_ready ? i_ext_rd:i_dbus_rdt; - assign dbus_ack = i_dbus_ack | i_ext_ready; - end else begin : gen_no_mdu - assign dbus_rdt = i_dbus_rdt; - assign dbus_ack = i_dbus_ack; - end - assign o_ext_rs2 = o_dbus_dat; -endgenerate +`endif endmodule -`default_nettype wire diff --git a/rtl/shift_reg.v b/rtl/shift_reg.v new file mode 100644 index 0000000..64b5ed7 --- /dev/null +++ b/rtl/shift_reg.v @@ -0,0 +1,20 @@ +module shift_reg + #(parameter LEN = 0, + parameter INIT = 0) + ( + input wire clk, + input wire i_rst, + input wire i_en, + input wire i_d, + output wire o_q, + output wire [LEN-2:0] o_par); + + reg [LEN-1:0] data; + assign o_q = data[0]; + assign o_par = data[LEN-1:1]; + always @(posedge clk) + if (i_rst) + data <= INIT; + else if (i_en) + data <= {i_d, data[LEN-1:1]}; +endmodule diff --git a/serv.core b/serv.core index f52b0af..f09c6dd 100644 --- a/serv.core +++ b/serv.core @@ -1,81 +1,42 @@ CAPI=2: -name : ::serv:1.3.0 +name : ::serv:1.0 filesets: core: files: - - "tool_verilator? (data/verilator_waiver.vlt)" : {file_type: vlt} + - rtl/serv_params.vh : {is_include_file : true} + - rtl/shift_reg.v + - rtl/ser_shift.v - rtl/serv_bufreg.v - - rtl/serv_bufreg2.v - rtl/serv_alu.v - rtl/serv_csr.v - rtl/serv_ctrl.v - rtl/serv_decode.v - - rtl/serv_immdec.v - rtl/serv_mem_if.v - rtl/serv_rf_if.v - rtl/serv_rf_ram_if.v - rtl/serv_rf_ram.v - rtl/serv_state.v - - rtl/serv_debug.v - rtl/serv_top.v - rtl/serv_rf_top.v - - rtl/serv_aligner.v - - rtl/serv_compdec.v file_type : verilogSource - openlane: - files: - - data/params.tcl : {file_type : tclSource} - - rtl/serv_synth_wrapper.v : {file_type : verilogSource} - targets: default: filesets : [core] - parameters : - - "is_toplevel? (ALIGN)" - - "is_toplevel? (COMPRESSED)" - - "is_toplevel? (MDU)" - - "is_toplevel? (PRE_REGISTER)" - - "is_toplevel? (RESET_STRATEGY)" - - RISCV_FORMAL - - SERV_CLEAR_RAM - - "is_toplevel? (WITH_CSR)" + parameters : [RISCV_FORMAL, SERV_CLEAR_RAM] toplevel : ["is_toplevel? (serv_rf_top)"] lint: default_tool : verilator - description: Run static code checks (linting) filesets : [core] tools: verilator: mode : lint-only - verilator_options: - - "-Wall" toplevel : serv_rf_top - sky130: - default_tool : openlane - description: Create GDSII for SkyWater 130nm using OpenLANE - filesets : [core, openlane] - toplevel : serv_synth_wrapper - parameters: - MDU: - datatype : int - description: Enables interface for RISC-V standard M-extension - paramtype : vlogparam - - PRE_REGISTER: - datatype : int - description : Register signals before or after the decoder - paramtype : vlogparam - - RESET_STRATEGY: - datatype : str - paramtype : vlogparam - RISCV_FORMAL: datatype : bool paramtype : vlogdefine @@ -84,17 +45,3 @@ parameters: datatype : bool paramtype : vlogdefine - WITH_CSR: - datatype : int - paramtype : vlogparam - - COMPRESSED: - datatype : int - description : Enable/Disable the support for Compressed instructions - paramtype : vlogparam - - ALIGN: - datatype : int - paramtype : vlogparam - description : Enable/Disable the support of misaligned instructions - diff --git a/servant.core b/servant.core index 901250f..4013e26 100644 --- a/servant.core +++ b/servant.core @@ -1,10 +1,13 @@ CAPI=2: -name : ::servant:1.3.0 -description: Simple reference system for SERV +name : ::servant:1.0 filesets: - # Common filesets + service: + files: [servant/ice40_pll.v, servant/service.v] + file_type : verilogSource + depend : ["fusesoc:utils:generators"] + mem_files: files: - sw/blinky.hex : {copyto : blinky.hex} @@ -13,88 +16,25 @@ filesets: servant_tb: files: - - sw/hello_uart.hex : {file_type: user, copyto: .} - bench/servant_sim.v - - bench/uart_decoder.v - - bench/servant_tb.v + - "!tool_verilator? (bench/uart_decoder.v)" + - "!tool_verilator? (bench/servant_tb.v)" + - "tool_verilator? (bench/servant_tb.cpp)" : {file_type : cppSource} file_type : verilogSource depend : [vlog_tb_utils] - service: - files: - - servant/ice40_pll.v - - servant/service_clock_gen.v - - servant/service.v - file_type : verilogSource - depend : ["fusesoc:utils:generators"] - soc: files: + - servant/servant_clock_gen.v - servant/servant_timer.v - servant/servant_gpio.v + - servant/servant_arbiter.v - servant/servant_mux.v - "tool_quartus? (servant/servant_ram_quartus.sv)" : {file_type : systemVerilogSource} - "!tool_quartus? (servant/servant_ram.v)" - servant/servant.v file_type : verilogSource - depend : [servile, "mdu? (mdu)"] - - verilator_tb: - files: - - bench/servant_sim.v - - "vidbo? (bench/servant_tb_vidbo.cpp)" : {file_type : cppSource} - - "!vidbo? (bench/servant_tb.cpp)" : {file_type : cppSource} - file_type : verilogSource - depend : ["vidbo? (vidbo)"] - - # Target-specific filesets. Alphabetically sorted - - ac701: - files: - - servant/servix.v : {file_type : verilogSource} - - servant/servant_ac701.v : {file_type : verilogSource} - - data/ac701.xdc : {file_type : xdc} - - alhambra : {files: [data/alhambra.pcf : {file_type : PCF}]} - - alchitry_au: - files: - - servant/servix_clock_gen.v : {file_type : verilogSource} - - servant/servix.v : {file_type : verilogSource} - - data/alchitry_au.xdc : {file_type : xdc} - - arty_a7_35t: - files: - - servant/servix_clock_gen.v : {file_type : verilogSource} - - servant/servix.v : {file_type : verilogSource} - - data/arty_a7_35t.xdc : {file_type : xdc} - - arty_s7_50t: - files: - - servant/servix_clock_gen.v : {file_type : verilogSource} - - servant/servix.v : {file_type : verilogSource} - - data/arty_s7_50t.xdc : {file_type : xdc} - - ax309: - files: - - servant/servant_ax309_clock_gen.v : {file_type : verilogSource} - - servant/servant_ax309.v : {file_type : verilogSource} - - data/ax309.ucf : {file_type : UCF} - - chameleon96: - files: - - data/chameleon96/chameleon96.sdc : {file_type : SDC} - - data/chameleon96/pinmap.tcl : {file_type: tclSource} - - data/chameleon96/HPS.sv : {file_type : systemVerilogSource} - - data/chameleon96/CV_96.v : {file_type : verilogSource} - - servant/servive_clock_gen.v : {file_type : verilogSource} - - servant/servive.v : {file_type : verilogSource} - - cmod_a7_35t: - files: - - servant/servant_cmod_a7_clock_gen.v : {file_type : verilogSource} - - servant/servant_cmod_a7.v : {file_type : verilogSource} - - data/cmod_a7_35t.xdc : {file_type : xdc} + depend : [serv] cyc1000: files: @@ -103,233 +43,23 @@ filesets: - servant/servclone10_clock_gen.v : {file_type : verilogSource} - servant/servclone10.v : {file_type : verilogSource} - deca: - files: - - data/deca.sdc : {file_type : SDC} - - data/deca.tcl : {file_type : tclSource} - - servant/servive_clock_gen.v : {file_type : verilogSource} - - servant/servive.v : {file_type : verilogSource} - - de0_nano: - files: - - data/de0_nano.sdc : {file_type : SDC} - - data/de0_nano.tcl : {file_type : tclSource} - - servant/servive_clock_gen.v : {file_type : verilogSource} - - servant/servive.v : {file_type : verilogSource} - - de1_soc_revF: - files: - - data/de1_soc_revF.sdc : {file_type : SDC} - - data/de1_soc_revF.tcl : {file_type : tclSource} - - servant/servde1_soc_revF_clock_gen.v : {file_type : verilogSource} - - servant/servde1_soc_revF.v : {file_type : verilogSource} - - - de10_nano: - files: - - data/de10_nano.sdc : {file_type : SDC} - - data/de10_nano.tcl : {file_type : tclSource} - - servant/servive_clock_gen.v : {file_type : verilogSource} - - servant/servive.v : {file_type : verilogSource} - - ebaz4205: - files: - - servant/servix_ebaz4205_clock_gen.v : {file_type : verilogSource} - - servant/servix_ebaz4205.v : {file_type : verilogSource} - - data/ebaz4205.xdc : {file_type : xdc} - - ecp5_evn: - files: - - data/ecp5_evn.lpf : {file_type : LPF} - - servant/ecp5_evn_pll.v : {file_type : verilogSource} - - servant/servant_ecp5_evn_clock_gen.v : {file_type : verilogSource} - - servant/servant_ecp5_evn.v : {file_type : verilogSource} - - go_board: - files: - - data/go_board.pcf : {file_type : PCF} - - servant/service_go_board.v : {file_type : verilogSource} - + tinyfpga_bx: {files: [data/tinyfpga_bx.pcf : {file_type : PCF}]} icebreaker : {files: [data/icebreaker.pcf : {file_type : PCF}]} - icestick : {files: [data/icestick.pcf : {file_type : PCF}]} - - icesugar : {files: [data/icesugar.pcf : {file_type : PCF}]} - - icev_wireless : {files: [data/icev_wireless.pcf : {file_type : PCF}]} - - gmm7550: - files: - - data/gmm7550.ccf : {file_type : CCF} - - servant/servant_gmm7550.v : {file_type : verilogSource} - - lx9_microboard: - files: - - servant/servant_lx9_clock_gen.v : {file_type : verilogSource} - - servant/servant_lx9.v : {file_type : verilogSource} - - data/lx9_microboard.ucf : {file_type : UCF} - - machdyne_kolibri: - files: - - servant/servant_md_kolibri.v : {file_type : verilogSource} - - data/machdyne_kolibri.pcf : {file_type : PCF} - - max10_10m08evk: - files: - - data/max10_10m08evk.sdc : {file_type : SDC} - - data/max10_10m08evk.tcl : {file_type : tclSource} - - servant/servive_clock_gen.v : {file_type : verilogSource} - - servant/servive.v : {file_type : verilogSource} - - nexys_2: - files: - - servant/servax_clock_gen.v : {file_type : verilogSource} - - servant/servax.v : {file_type : verilogSource} - - data/nexys_2.tcl : {file_type : tclSource} - - data/nexys_2.ucf : {file_type : UCF} - nexys_a7: files: - servant/servix_clock_gen.v : {file_type : verilogSource} - servant/servix.v : {file_type : verilogSource} - data/nexys_a7.xdc : {file_type : xdc} - - orangecrab: + arty_a7_35t: files: - - data/orangecrab_r02.lpf : {file_type : LPF} - - servant/servant_orangecrab.v : {file_type : verilogSource} - - pipistrello: - files: - - servant/servis_clock_gen.v : {file_type : verilogSource} - - servant/servis.v : {file_type : verilogSource} - - data/pipistrello.ucf : {file_type : UCF} - - polarfire_splashkit: - files: - - servant/servant_pf.v : {file_type : verilogSource} - - servant/servant_pf_clock_gen.v : {file_type : verilogSource} - - data/polarfire_splashkit.pdc : {file_type : PDC} - - sockit: - files: - - data/sockit.sdc : {file_type : SDC} - - data/sockit.tcl : {file_type : tclSource} - - servant/servive_clock_gen.v : {file_type : verilogSource} - - servant/servive.v : {file_type : verilogSource} - - te0802: - files: - - servant/servant_te0802_clock_gen.v : {file_type : verilogSource} - - servant/servant_te0802.v : {file_type : verilogSource} - - data/te0802.xdc : {file_type : xdc} - - tinyfpga_bx: {files: [data/tinyfpga_bx.pcf : {file_type : PCF}]} - - ulx3s: - files: - - data/ulx3s.lpf : {file_type : LPF} - - servant/ecppll.v : {file_type : verilogSource} - - servant/servant_ecp5_clock_gen.v : {file_type : verilogSource} - - servant/servant_ecp5.v : {file_type : verilogSource} - - upduino2: - files: - - servant/servant_upduino2.v : {file_type : verilogSource} - - data/upduino2.pcf : {file_type : PCF} - - zcu106: - files: - - servant/servus_clock_gen.v : {file_type : verilogSource} - - servant/servus.v : {file_type : verilogSource} - - data/zcu106.xdc : {file_type : xdc} - + - servant/servix_clock_gen.v : {file_type : verilogSource} + - servant/servix.v : {file_type : verilogSource} + - data/arty_a7_35t.xdc : {file_type : xdc} targets: default: filesets : [soc] - ac701: - default_tool: vivado - description: AC701 Evaluation Kit - filesets : [mem_files, soc, ac701] - parameters : [memfile, memsize, frequency=32] - tools: - vivado: {part : xc7a200t-fbg676-2} - toplevel : servant_ac701 - - alchitry_au: - default_tool: vivado - description: Open-hardware Alchitry AU FPGA board - filesets : [mem_files, soc, alchitry_au] - parameters : [memfile, memsize, frequency=16, "mdu? (MDU=1)", WITH_RESET] - tools: - vivado: {part : xc7a35tftg256-1} - toplevel : servix - - alhambra: - default_tool : icestorm - description: Open-hardware iCE40HX4K FPGA board - filesets : [mem_files, soc, service, alhambra] - generate: [ice40pll: {freq_in : 12, freq_out : 32}] - parameters : [memfile, memsize, PLL=ICE40_CORE] - tools: - icestorm: - nextpnr_options : [--hx8k, --package, "tq144:4k", --freq, 32] - pnr: next - toplevel : service - - arty_a7_35t: - default_tool: vivado - description: Digilent Arty A7-35 - filesets : [mem_files, soc, arty_a7_35t] - parameters : [memfile, memsize, frequency=16, "mdu? (MDU=1)", WITH_RESET] - tools: - vivado: {part : xc7a35ticsg324-1L} - toplevel : servix - - arty_s7_50t: - default_tool: vivado - description: Digilent Arty S7-50 - filesets : [mem_files, soc, arty_s7_50t] - parameters : [memfile, memsize, frequency=16, "mdu? (MDU=1)", WITH_RESET] - tools: - vivado: {part : xc7s50csga324-1} - toplevel : servix - - ax309: - default_tool : ise - description : XILINX Spartan-6 XC6SLX9 FPGA Development Board - filesets : [mem_files, soc, ax309] - parameters : [memfile, memsize] - tools: - ise: - family : Spartan6 - device : xc6slx9 - package : ftg256 - speed : -3 - toplevel : servant_ax309 - - chameleon96: - default_tool : quartus - description : Chameleon96 (Arrow 96 CV SoC Board) - filesets : [mem_files, soc, chameleon96] - parameters : [memfile, memsize] - tools: - quartus: - family : Cyclone V - device : 5CSEBA6U19I7 - board_device_index : 2 - toplevel: CV_96 - - cmod_a7_35t: - description: Digilent CMOD A7-35 - filesets : [mem_files, soc, cmod_a7_35t] - flow: vivado - flow_options: - part : xc7a35tcpg236-1 - parameters : [memfile, memsize] - toplevel : servant_cmod_a7 - cyc1000: default_tool: quartus description: cyc1000 FPGA board @@ -341,74 +71,10 @@ targets: device : 10CL025YU256C8G toplevel : servclone10 - de0_nano: - default_tool : quartus - description: Terasic DE0 Nano - filesets : [mem_files, soc, de0_nano] - parameters : [memfile, memsize] - tools: - quartus: - family : Cyclone IV E - device : EP4CE22F17C6 - toplevel: servive - - de10_nano: - default_tool: quartus - description: Terasic DE10 Nano Kit - filesets : [mem_files, soc, de10_nano] - parameters : [memfile, memsize=32768] - tools: - quartus: - family : Cyclone V - device : 5CSEBA6U23I7 - board_device_index : 2 - toplevel : servive - - deca: - default_tool : quartus - description: DECA development kit by Arrow / Terasic - filesets : [mem_files, soc, deca] - parameters : [memfile, memsize] - tools: - quartus: - family : MAX 10 - device : 10M50DAF484C6GES - toplevel: servive - - ebaz4205: - default_tool: vivado - description: EBAZ4205 'Development' Board - filesets : [mem_files, soc, ebaz4205] - parameters : [memfile, memsize, frequency=16] - tools: - vivado: {part : xc7z010clg400-1} - toplevel : servix_ebaz4205 - - ecp5_evn: - default_tool: trellis - description : ECP5 evaluation board - filesets : [mem_files, soc, ecp5_evn] - parameters : [memfile, memsize] - tools: - trellis: - nextpnr_options : [--package, CABGA381, --um5g-85k] - toplevel: servant_ecp5_evn - - go_board: - default_tool : icestorm - description: Nandland Go Board - filesets : [mem_files, soc, go_board] - tools: - icestorm: - nextpnr_options : [--hx1k, --package, vq100, --freq, 20] - pnr: next - toplevel : service_go_board - icebreaker: default_tool : icestorm - description: 1Bit Squared iCEBreaker filesets : [mem_files, soc, service, icebreaker] - generate: [ice40pll : {freq_out : 16}] + generate: [icebreaker_pll] parameters : [memfile, memsize, PLL=ICE40_PAD] tools: icestorm: @@ -416,311 +82,69 @@ targets: pnr: next toplevel : service - icestick: + tinyfpga_bx: default_tool : icestorm - description: Lattice iCEstick - filesets : [mem_files, soc, service, icestick] - generate: [ice40pll: {freq_in : 12, freq_out : 32}] - parameters : [memfile=blinky.hex, memsize=7168, PLL=ICE40_CORE] + filesets : [mem_files, soc, service, tinyfpga_bx] + generate: [tinyfpga_bx_pll] + parameters : [memfile, memsize, PLL=ICE40_CORE] tools: icestorm: - nextpnr_options : [--hx1k, --package, tq144, --freq, 32] + nextpnr_options : [--lp8k, --package, cm81, --freq, 32] pnr: next toplevel : service - icesugar: - default_tool : icestorm - description : iCE40UP5K Development Board by MuseLab - filesets : [mem_files, soc, service, icesugar] - generate: [ice40pll : {freq_in : 12, freq_out : 32}] - parameters : [memfile, memsize, PLL=ICE40_PAD] - tools: - icestorm: - nextpnr_options: [--up5k, --package, sg48, --freq, 32] - pnr: next - toplevel : service - - icev_wireless: - default_tool : icestorm - description: ICE-V Wireless - filesets : [mem_files, soc, service, icev_wireless] - generate: [ice40pll : {freq_out : 16}] - parameters : [memfile, memsize, PLL=ICE40_PAD] - tools: - icestorm: - nextpnr_options: [--up5k, --freq, 16] - pnr: next - toplevel : service - - gmm7550: - default_tool: gatemate - description: CologneChip GateMate FPGA Module - filesets : [mem_files, soc, gmm7550] - parameters : [memfile=blinky.hex, memsize=8192] - toplevel : servant_gmm7550 - tools: - gatemate: - device : CCGM1A1 - yosys_synth_options : [ -nomx8 ] - p_r_options : [ +uCIO -cCP ] - lint: - description: Run static code checks (linting) + default_tool : verilator filesets : [soc] - flow: lint - flow_options: - tool : verilator + tools: + verilator: + mode : lint-only toplevel : servant - lx9_microboard: - default_tool: ise - description : LX9 Microboard - filesets : [mem_files, soc, lx9_microboard] - parameters : [memfile, memsize] - tools: - ise: - family : Spartan6 - device : xc6slx9 - package : csg324 - speed : -2 - toplevel : servant_lx9 - - machdyne_kolibri: - default_tool: icestorm - description : Machdyne Kolibri FPGA Dongle - filesets : [mem_files, soc, machdyne_kolibri] - parameters : [memfile, memsize] - tools: - icestorm: - nextpnr_options : [--hx4k, --package, bg121, --freq, 48] - pnr: next - toplevel : servant_md_kolibri - - max10_10m08evk: - default_tool : quartus - description: MAX10 10M08 evaluation kit - hooks: - post_run: [jbc] - filesets : [mem_files, soc, max10_10m08evk] - parameters : [memfile, memsize] - tools: - quartus: - family : MAX 10 - device : 10M08SAE144C8G - toplevel: servive - - nexys_2_500: - default_tool: ise - description: Digilent Nexys 2-500 - filesets : [mem_files, soc, nexys_2] - parameters : [memfile, memsize, compressed] - tools: - ise: - family : Spartan3E - device : xc3s500e - package : fg320 - speed : -4 - toplevel : servax - - nexys_2_1200: - default_tool: ise - description: Digilent Nexys 2-1200 - filesets : [mem_files, soc, nexys_2] - parameters : [memfile, memsize, compressed] - tools: - ise: - family : Spartan3E - device : xc3s1600e - package : fg320 - speed : -4 - toplevel : servax - nexys_a7: - description: Digilent Nexys A7 + default_tool: vivado filesets : [mem_files, soc, nexys_a7] - flow: vivado - flow_options: - part : xc7a100tcsg324-1 parameters : [memfile, memsize, frequency=32] + tools: + vivado: {part : xc7a100tcsg324-1} toplevel : servix - orangecrab_r0.2: - default_tool: trellis - description : OrangeCrab R0.2 - filesets : [mem_files, soc, orangecrab] - parameters : [memfile, memsize] + arty_a7_35t: + default_tool: vivado + filesets : [mem_files, soc, arty_a7_35t] + parameters : [memfile, memsize, frequency=16] tools: - trellis: - nextpnr_options : [--package, CSFBGA285, --25k] - toplevel: servant_orangecrab - - pipistrello: - default_tool: ise - description : Saanlima pipistrello - filesets : [mem_files, soc, pipistrello] - parameters : [memfile, memsize] - tools: - ise: - family : Spartan6 - device : xc6slx45 - package : csg324 - speed : -3 - toplevel : servis - - polarfire_splashkit: - default_tool: libero - description : Microsemi Polarfire Splash Kit - filesets : [mem_files, soc, polarfire_splashkit] - parameters : [memfile, memsize] - tools: - libero: - family : PolarFire - die : MPF300TS - package : FCG484 - toplevel : servant_pf + vivado: {part : xc7a35ticsg324-1L} + toplevel : servix sim: default_tool: icarus - description: Simulation target filesets : [soc, servant_tb] parameters : - RISCV_FORMAL - - width - - "mdu? (MDU=1)" - SERV_CLEAR_RAM=true - firmware - memsize toplevel : servant_tb - sockit: - default_tool : quartus - description: SoCKit development kit by Arrow / Terasic - filesets : [mem_files, soc, sockit] - parameters : [memfile, memsize] - tools: - quartus: - family : CycloneV - device : 5CSXFC6D6F31C6 - toplevel: servive - - te0802: - default_tool: vivado - description : Trenz Electronic TE0802 - filesets : [mem_files, soc, te0802] - parameters : [memfile, memsize] - tools: - vivado: {part : xczu2cg-sbva484-1-e} - toplevel : servant_te0802 - - tinyfpga_bx: - description: TinyFPGA BX - filesets : [mem_files, soc, service, tinyfpga_bx] - flow: icestorm - flow_options: - nextpnr_options : [--lp8k, --package, cm81, --freq, '32'] - generate: [ice40pll: {freq_in : 16, freq_out : 32}] - parameters : [memfile, memsize, PLL=ICE40_CORE] - toplevel : service - - ulx3s_85: - default_tool: diamond - description : ULX3S 85k version - filesets : [mem_files, soc, ulx3s] - parameters : [memfile, memsize] - tools: - diamond: - part : LFE5U-85F-6BG381C - trellis: - nextpnr_options : [--package, CABGA381, --85k] - toplevel: servant_ecp5 - - upduino2: - default_tool : icestorm - description: Upduino2 - filesets : [mem_files, soc, upduino2] - parameters : [memfile, memsize] - tools: - icestorm: - nextpnr_options: [--package, sg48, --up5k, --freq, 24] - pnr: next - toplevel : servant_upduino2 - verilator_tb: - description: Verilator testbench - filesets : [soc, verilator_tb] - flow: sim - flow_options: - tool: verilator - verilator_options : [--trace] + default_tool: verilator + filesets : [soc, servant_tb] parameters : - RISCV_FORMAL - - "mdu? (MDU=1)" - - cps - firmware - memsize - signature - timeout - - trace_pc - uart_baudrate - vcd - vcd_start - - width - - compressed - - align - - with_csr=1 + tools: + verilator: + verilator_options : [--trace] toplevel : servant_sim - zcu106: - default_tool: vivado - description : Zynq UltraScale+ MPSoC ZCU106 Evaluation Kit - filesets : [mem_files, soc, zcu106] - parameters : [memfile, memsize] - tools: - vivado: {part : xczu7ev-ffvc1156-2-e} - toplevel : servus - parameters: - align: - datatype : int - description : Enable/Disable the Misaligned access of instruction - paramtype : vlogparam - - compressed: - datatype : int - description : Enable/Disable the Compressed extension - paramtype : vlogparam - - cps: - datatype : bool - description: Write simulated cycles per second to a text file named cps - paramtype : plusarg - - firmware: - datatype : file - description : Preload RAM with a hex file at runtime (overrides memfile) - paramtype : plusarg - - frequency: - datatype : int - description : PLL output frequency in MHz - paramtype : vlogparam - - MDU: - datatype : int - description : Enables RISC-V standard M-extension - paramtype : vlogdefine - - memfile: - datatype : file - description : Preload RAM with a hex file at compile-time - paramtype : vlogparam - - memsize: - datatype : int - default : 8192 - description : Memory size in bytes for RAM (default 8kiB) - paramtype : vlogparam - PLL: datatype : str description : PLL type to use for main clock generation @@ -734,23 +158,39 @@ parameters: datatype : bool paramtype : vlogdefine + firmware: + datatype : file + description : Preload RAM with a hex file at runtime (overrides memfile) + paramtype : plusarg + + frequency: + datatype : int + description : PLL output frequency + paramtype : vlogparam + + memfile: + datatype : file + description : Preload RAM with a hex file at compile-time + paramtype : vlogparam + + memsize: + datatype : int + default : 8192 + description : Memory size in bytes for RAM (default 8kiB) + paramtype : vlogparam + signature: datatype : file paramtype : plusarg + uart_baudrate: + datatype : int + description : Treat q output as an UART with the specified baudrate (0 or omitted parameter disables UART decoding) + paramtype : plusarg timeout: datatype : int paramtype : plusarg - trace_pc: - datatype : bool - paramtype : plusarg - - uart_baudrate: - datatype : int - description : Treat q output as an UART with the specified baudrate (0 or omitted parameter disables UART decoding) - paramtype : plusarg - vcd: datatype : bool paramtype : plusarg @@ -760,27 +200,14 @@ parameters: description : Delay start of VCD dumping until the specified time paramtype : plusarg - width: - datatype : int - description : Interal datapath width (1=SERV, 4=QERV) - paramtype : vlogparam - - with_csr: - datatype : int - description : Enable/Disable CSR support - paramtype : vlogparam - - WITH_RESET: - datatype : bool - default : true - description : Enable reset input (for supported targets) - paramtype : vlogdefine - generate: - ice40pll: + icebreaker_pll: generator: icepll + parameters: + freq_out : 16 -scripts: - jbc: - cmd : [quartus_jbcc, "-n", servant_1_2_1_pof.jam, servant_1_2_1_pof.jbc] - + tinyfpga_bx_pll: + generator: icepll + parameters: + freq_in : 16 + freq_out : 32 diff --git a/servant/ecp5_evn_pll.v b/servant/ecp5_evn_pll.v deleted file mode 100644 index 9411158..0000000 --- a/servant/ecp5_evn_pll.v +++ /dev/null @@ -1,48 +0,0 @@ -// generated with "ecppll -n ecp5_evn_pll -i 12 -o 16 --clkin_name clki --clkout0_name clko -f ecp5_evn_pll.v" - -// diamond 3.7 accepts this PLL -// diamond 3.8-3.9 is untested -// diamond 3.10 or higher is likely to abort with error about unable to use feedback signal -// cause of this could be from wrong CPHASE/FPHASE parameters -module ecp5_evn_pll -( - input clki, // 12 MHz, 0 deg - output clko, // 16 MHz, 0 deg - output locked -); -(* FREQUENCY_PIN_CLKI="12" *) -(* FREQUENCY_PIN_CLKOP="16" *) -(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *) -EHXPLLL #( - .PLLRST_ENA("DISABLED"), - .INTFB_WAKE("DISABLED"), - .STDBY_ENABLE("DISABLED"), - .DPHASE_SOURCE("DISABLED"), - .OUTDIVIDER_MUXA("DIVA"), - .OUTDIVIDER_MUXB("DIVB"), - .OUTDIVIDER_MUXC("DIVC"), - .OUTDIVIDER_MUXD("DIVD"), - .CLKI_DIV(3), - .CLKOP_ENABLE("ENABLED"), - .CLKOP_DIV(37), - .CLKOP_CPHASE(18), - .CLKOP_FPHASE(0), - .FEEDBK_PATH("CLKOP"), - .CLKFB_DIV(4) - ) pll_i ( - .RST(1'b0), - .STDBY(1'b0), - .CLKI(clki), - .CLKOP(clko), - .CLKFB(clko), - .CLKINTFB(), - .PHASESEL0(1'b0), - .PHASESEL1(1'b0), - .PHASEDIR(1'b1), - .PHASESTEP(1'b1), - .PHASELOADREG(1'b1), - .PLLWAKESYNC(1'b0), - .ENCLKOP(1'b0), - .LOCK(locked) - ); -endmodule diff --git a/servant/ecppll.v b/servant/ecppll.v deleted file mode 100644 index bae4953..0000000 --- a/servant/ecppll.v +++ /dev/null @@ -1,38 +0,0 @@ -module pll(input clki, - output locked, - output clko -); -wire clkfb; -wire clkos; -wire clkop; -(* ICP_CURRENT="12" *) (* LPF_RESISTOR="8" *) (* MFG_ENABLE_FILTEROPAMP="1" *) (* MFG_GMCREF_SEL="2" *) -EHXPLLL #( - .PLLRST_ENA("DISABLED"), - .INTFB_WAKE("DISABLED"), - .STDBY_ENABLE("DISABLED"), - .DPHASE_SOURCE("DISABLED"), - .CLKOP_FPHASE(0), - .CLKOP_CPHASE(18), - .OUTDIVIDER_MUXA("DIVA"), - .CLKOP_ENABLE("ENABLED"), - .CLKOP_DIV(38), - .CLKFB_DIV(5), - .CLKI_DIV(8), - .FEEDBK_PATH("INT_OP") - ) pll_i ( - .CLKI(clki), - .CLKFB(clkfb), - .CLKINTFB(clkfb), - .CLKOP(clkop), - .RST(1'b0), - .STDBY(1'b0), - .PHASESEL0(1'b0), - .PHASESEL1(1'b0), - .PHASEDIR(1'b0), - .PHASESTEP(1'b0), - .PLLWAKESYNC(1'b0), - .ENCLKOP(1'b0), - .LOCK(locked) - ); -assign clko = clkop; -endmodule diff --git a/servant/ice40_pll.v b/servant/ice40_pll.v index 2e82d96..8daad94 100644 --- a/servant/ice40_pll.v +++ b/servant/ice40_pll.v @@ -11,8 +11,8 @@ module ice40_pll reg [1:0] rst_reg; always @(posedge o_clk) - rst_reg <= {rst_reg[0],locked}; - assign o_rst = ~rst_reg[1]; + rst_reg <= {!locked, rst_reg[1]}; + assign o_rst = rst_reg[0]; generate if (PLL == "ICE40_CORE") begin diff --git a/servant/servant.v b/servant/servant.v index fb027df..a5e6424 100644 --- a/servant/servant.v +++ b/servant/servant.v @@ -7,167 +7,183 @@ module servant parameter memfile = "zephyr_hello.hex"; parameter memsize = 8192; - parameter reset_strategy = "MINI"; - parameter width = 1; parameter sim = 0; - parameter [0:0] debug = 1'b0; parameter with_csr = 1; - parameter [0:0] compress = 0; - parameter [0:0] align = compress; - - -`ifdef MDU - localparam [0:0] with_mdu = 1'b1; -`else - localparam [0:0] with_mdu = 1'b0; -`endif - - localparam aw = $clog2(memsize); - localparam csr_regs = with_csr*4; - - localparam rf_width = width * 2; - localparam rf_l2d = $clog2((32+csr_regs)*32/rf_width); wire timer_irq; + wire [31:0] wb_ibus_adr; + wire wb_ibus_cyc; + wire [31:0] wb_ibus_rdt; + wire wb_ibus_ack; + + wire [31:0] wb_dbus_adr; + wire [31:0] wb_dbus_dat; + wire [3:0] wb_dbus_sel; + wire wb_dbus_we; + wire wb_dbus_cyc; + wire [31:0] wb_dbus_rdt; + wire wb_dbus_ack; + + wire [31:0] wb_dmem_adr; + wire [31:0] wb_dmem_dat; + wire [3:0] wb_dmem_sel; + wire wb_dmem_we; + wire wb_dmem_cyc; + wire [31:0] wb_dmem_rdt; + wire wb_dmem_ack; wire [31:0] wb_mem_adr; wire [31:0] wb_mem_dat; wire [3:0] wb_mem_sel; wire wb_mem_we; - wire wb_mem_stb; + wire wb_mem_cyc; wire [31:0] wb_mem_rdt; wire wb_mem_ack; wire wb_gpio_dat; wire wb_gpio_we; - wire wb_gpio_stb; + wire wb_gpio_cyc; wire wb_gpio_rdt; wire [31:0] wb_timer_dat; wire wb_timer_we; - wire wb_timer_stb; + wire wb_timer_cyc; wire [31:0] wb_timer_rdt; - wire [31:0] wb_ext_adr; - wire [31:0] wb_ext_dat; - wire [3:0] wb_ext_sel; - wire wb_ext_we; - wire wb_ext_stb; - wire [31:0] wb_ext_rdt; - wire wb_ext_ack; + servant_arbiter arbiter + (.i_wb_cpu_dbus_adr (wb_dmem_adr), + .i_wb_cpu_dbus_dat (wb_dmem_dat), + .i_wb_cpu_dbus_sel (wb_dmem_sel), + .i_wb_cpu_dbus_we (wb_dmem_we ), + .i_wb_cpu_dbus_cyc (wb_dmem_cyc), + .o_wb_cpu_dbus_rdt (wb_dmem_rdt), + .o_wb_cpu_dbus_ack (wb_dmem_ack), - wire [rf_l2d-1:0] rf_waddr; - wire [rf_width-1:0] rf_wdata; - wire rf_wen; - wire [rf_l2d-1:0] rf_raddr; - wire rf_ren; - wire [rf_width-1:0] rf_rdata; + .i_wb_cpu_ibus_adr (wb_ibus_adr), + .i_wb_cpu_ibus_cyc (wb_ibus_cyc), + .o_wb_cpu_ibus_rdt (wb_ibus_rdt), + .o_wb_cpu_ibus_ack (wb_ibus_ack), - servant_mux servant_mux + .o_wb_cpu_adr (wb_mem_adr), + .o_wb_cpu_dat (wb_mem_dat), + .o_wb_cpu_sel (wb_mem_sel), + .o_wb_cpu_we (wb_mem_we ), + .o_wb_cpu_cyc (wb_mem_cyc), + .i_wb_cpu_rdt (wb_mem_rdt), + .i_wb_cpu_ack (wb_mem_ack)); + + servant_mux #(sim) servant_mux ( .i_clk (wb_clk), - .i_rst (wb_rst & (reset_strategy != "NONE")), - .i_wb_cpu_adr (wb_ext_adr), - .i_wb_cpu_dat (wb_ext_dat), - .i_wb_cpu_sel (wb_ext_sel), - .i_wb_cpu_we (wb_ext_we), - .i_wb_cpu_cyc (wb_ext_stb), - .o_wb_cpu_rdt (wb_ext_rdt), - .o_wb_cpu_ack (wb_ext_ack), + .i_rst (wb_rst), + .i_wb_cpu_adr (wb_dbus_adr), + .i_wb_cpu_dat (wb_dbus_dat), + .i_wb_cpu_sel (wb_dbus_sel), + .i_wb_cpu_we (wb_dbus_we), + .i_wb_cpu_cyc (wb_dbus_cyc), + .o_wb_cpu_rdt (wb_dbus_rdt), + .o_wb_cpu_ack (wb_dbus_ack), + + .o_wb_mem_adr (wb_dmem_adr), + .o_wb_mem_dat (wb_dmem_dat), + .o_wb_mem_sel (wb_dmem_sel), + .o_wb_mem_we (wb_dmem_we), + .o_wb_mem_cyc (wb_dmem_cyc), + .i_wb_mem_rdt (wb_dmem_rdt), .o_wb_gpio_dat (wb_gpio_dat), .o_wb_gpio_we (wb_gpio_we), - .o_wb_gpio_cyc (wb_gpio_stb), + .o_wb_gpio_cyc (wb_gpio_cyc), .i_wb_gpio_rdt (wb_gpio_rdt), .o_wb_timer_dat (wb_timer_dat), .o_wb_timer_we (wb_timer_we), - .o_wb_timer_cyc (wb_timer_stb), + .o_wb_timer_cyc (wb_timer_cyc), .i_wb_timer_rdt (wb_timer_rdt)); servant_ram #(.memfile (memfile), - .depth (memsize), - .RESET_STRATEGY (reset_strategy)) + .depth (memsize)) ram (// Wishbone interface .i_wb_clk (wb_clk), - .i_wb_rst (wb_rst), .i_wb_adr (wb_mem_adr[$clog2(memsize)-1:2]), - .i_wb_cyc (wb_mem_stb), + .i_wb_cyc (wb_mem_cyc), .i_wb_we (wb_mem_we) , .i_wb_sel (wb_mem_sel), .i_wb_dat (wb_mem_dat), .o_wb_rdt (wb_mem_rdt), .o_wb_ack (wb_mem_ack)); - servant_timer - #(.RESET_STRATEGY (reset_strategy), - .WIDTH (32)) - timer - (.i_clk (wb_clk), - .i_rst (wb_rst), - .o_irq (timer_irq), - .i_wb_cyc (wb_timer_stb), - .i_wb_we (wb_timer_we) , - .i_wb_dat (wb_timer_dat), - .o_wb_dat (wb_timer_rdt)); + generate + if (with_csr) begin + servant_timer + #(.WIDTH (32)) + timer + (.i_clk (wb_clk), + .o_irq (timer_irq), + .i_wb_cyc (wb_timer_cyc), + .i_wb_we (wb_timer_we) , + .i_wb_dat (wb_timer_dat), + .o_wb_dat (wb_timer_rdt)); + end else begin + assign wb_timer_rdt = 32'd0; + assign timer_irq = 1'b0; + end + endgenerate servant_gpio gpio (.i_wb_clk (wb_clk), .i_wb_dat (wb_gpio_dat), .i_wb_we (wb_gpio_we), - .i_wb_cyc (wb_gpio_stb), + .i_wb_cyc (wb_gpio_cyc), .o_wb_rdt (wb_gpio_rdt), .o_gpio (q)); - serv_rf_ram - #(.width (rf_width), - .csr_regs (csr_regs)) - rf_ram - (.i_clk (wb_clk), - .i_waddr (rf_waddr), - .i_wdata (rf_wdata), - .i_wen (rf_wen), - .i_raddr (rf_raddr), - .i_ren (rf_ren), - .o_rdata (rf_rdata)); - - servile - #(.width (width), - .sim (sim[0]), - .debug (debug), - .with_c (compress[0]), - .with_csr (with_csr[0]), - .with_mdu (with_mdu)) + serv_rf_top + #(.RESET_PC (32'h0000_0000), + .WITH_CSR (with_csr)) cpu ( - .i_clk (wb_clk), - .i_rst (wb_rst), + .clk (wb_clk), + .i_rst (wb_rst), .i_timer_irq (timer_irq), +`ifdef RISCV_FORMAL + .rvfi_valid (), + .rvfi_order (), + .rvfi_insn (), + .rvfi_trap (), + .rvfi_halt (), + .rvfi_intr (), + .rvfi_mode (), + .rvfi_ixl (), + .rvfi_rs1_addr (), + .rvfi_rs2_addr (), + .rvfi_rs1_rdata (), + .rvfi_rs2_rdata (), + .rvfi_rd_addr (), + .rvfi_rd_wdata (), + .rvfi_pc_rdata (), + .rvfi_pc_wdata (), + .rvfi_mem_addr (), + .rvfi_mem_rmask (), + .rvfi_mem_wmask (), + .rvfi_mem_rdata (), + .rvfi_mem_wdata (), +`endif - .o_wb_mem_adr (wb_mem_adr), - .o_wb_mem_dat (wb_mem_dat), - .o_wb_mem_sel (wb_mem_sel), - .o_wb_mem_we (wb_mem_we), - .o_wb_mem_stb (wb_mem_stb), - .i_wb_mem_rdt (wb_mem_rdt), - .i_wb_mem_ack (wb_mem_ack), + .o_ibus_adr (wb_ibus_adr), + .o_ibus_cyc (wb_ibus_cyc), + .i_ibus_rdt (wb_ibus_rdt), + .i_ibus_ack (wb_ibus_ack), - .o_wb_ext_adr (wb_ext_adr), - .o_wb_ext_dat (wb_ext_dat), - .o_wb_ext_sel (wb_ext_sel), - .o_wb_ext_we (wb_ext_we), - .o_wb_ext_stb (wb_ext_stb), - .i_wb_ext_rdt (wb_ext_rdt), - .i_wb_ext_ack (wb_ext_ack), - - .o_rf_waddr (rf_waddr), - .o_rf_wdata (rf_wdata), - .o_rf_wen (rf_wen), - .o_rf_raddr (rf_raddr), - .o_rf_ren (rf_ren), - .i_rf_rdata (rf_rdata)); + .o_dbus_adr (wb_dbus_adr), + .o_dbus_dat (wb_dbus_dat), + .o_dbus_sel (wb_dbus_sel), + .o_dbus_we (wb_dbus_we), + .o_dbus_cyc (wb_dbus_cyc), + .i_dbus_rdt (wb_dbus_rdt), + .i_dbus_ack (wb_dbus_ack)); endmodule diff --git a/servant/servant_ac701.v b/servant/servant_ac701.v deleted file mode 100644 index 9f8f6db..0000000 --- a/servant/servant_ac701.v +++ /dev/null @@ -1,62 +0,0 @@ -`default_nettype none -module servant_ac701 -( - input wire sys_clk_p, - input wire sys_clk_n, - input wire btn, - output wire q); - - parameter frequency = 16; - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - parameter PLL = "NONE"; - - wire wb_clk; - reg wb_rst; - wire clk; - wire clkfb; - wire locked; - reg locked_r; - - IBUFDS ibufds - ( - .I (sys_clk_p), - .IB (sys_clk_n), - .O (clk) - ); - - PLLE2_BASE - #(.BANDWIDTH("OPTIMIZED"), - .CLKFBOUT_MULT(8), - .CLKIN1_PERIOD(5.0), //200MHz - .CLKOUT0_DIVIDE((frequency == 32) ? 50 : 100), - .DIVCLK_DIVIDE(1), - .STARTUP_WAIT("FALSE")) - PLLE2_BASE_inst - (.CLKOUT0(wb_clk), - .CLKOUT1(), - .CLKOUT2(), - .CLKOUT3(), - .CLKOUT4(), - .CLKOUT5(), - .CLKFBOUT(clkfb), - .LOCKED(locked), - .CLKIN1(clk), - .PWRDWN(1'b0), - .RST(1'b0), - .CLKFBIN(clkfb)); - - always @(posedge wb_clk) begin - locked_r <= locked; - wb_rst <= !locked_r; - end - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servant_arbiter.v b/servant/servant_arbiter.v new file mode 100644 index 0000000..00b39c8 --- /dev/null +++ b/servant/servant_arbiter.v @@ -0,0 +1,39 @@ +/* Arbitrates between dbus and ibus accesses. + * Relies on the fact that not both masters are active at the same time + */ +module servant_arbiter + ( + input wire [31:0] i_wb_cpu_dbus_adr, + input wire [31:0] i_wb_cpu_dbus_dat, + input wire [3:0] i_wb_cpu_dbus_sel, + input wire i_wb_cpu_dbus_we, + input wire i_wb_cpu_dbus_cyc, + output wire [31:0] o_wb_cpu_dbus_rdt, + output wire o_wb_cpu_dbus_ack, + + input wire [31:0] i_wb_cpu_ibus_adr, + input wire i_wb_cpu_ibus_cyc, + output wire [31:0] o_wb_cpu_ibus_rdt, + output wire o_wb_cpu_ibus_ack, + + output wire [31:0] o_wb_cpu_adr, + output wire [31:0] o_wb_cpu_dat, + output wire [3:0] o_wb_cpu_sel, + output wire o_wb_cpu_we, + output wire o_wb_cpu_cyc, + input wire [31:0] i_wb_cpu_rdt, + input wire i_wb_cpu_ack); + + assign o_wb_cpu_dbus_rdt = i_wb_cpu_rdt; + assign o_wb_cpu_dbus_ack = i_wb_cpu_ack & !i_wb_cpu_ibus_cyc; + + assign o_wb_cpu_ibus_rdt = i_wb_cpu_rdt; + assign o_wb_cpu_ibus_ack = i_wb_cpu_ack & i_wb_cpu_ibus_cyc; + + assign o_wb_cpu_adr = i_wb_cpu_ibus_cyc ? i_wb_cpu_ibus_adr : i_wb_cpu_dbus_adr; + assign o_wb_cpu_dat = i_wb_cpu_dbus_dat; + assign o_wb_cpu_sel = i_wb_cpu_dbus_sel; + assign o_wb_cpu_we = i_wb_cpu_dbus_we & !i_wb_cpu_ibus_cyc; + assign o_wb_cpu_cyc = i_wb_cpu_ibus_cyc | i_wb_cpu_dbus_cyc; + +endmodule diff --git a/servant/servant_ax309.v b/servant/servant_ax309.v deleted file mode 100644 index 78fe8e7..0000000 --- a/servant/servant_ax309.v +++ /dev/null @@ -1,32 +0,0 @@ -`default_nettype none -module servant_ax309 -( - input wire i_clk, - input wire i_rst, - output wire o_uart_tx, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire wb_rst; - - assign o_uart_tx = q; - - servant_ax309_clock_gen - clock_gen - (.i_clk (i_clk), - .i_rst (i_rst), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servant_ax309_clock_gen.v b/servant/servant_ax309_clock_gen.v deleted file mode 100644 index f10b2f1..0000000 --- a/servant/servant_ax309_clock_gen.v +++ /dev/null @@ -1,35 +0,0 @@ -`default_nettype none -module servant_ax309_clock_gen - (input wire i_clk, - input wire i_rst, - output wire o_clk, - output reg o_rst); - - wire clkfb; - wire locked; - reg locked_r; - - PLL_BASE - #(.BANDWIDTH("OPTIMIZED"), - .CLKFBOUT_MULT(16), - .CLKIN_PERIOD(20.0), //50MHz - .CLKOUT1_DIVIDE(25), //32MHz - .DIVCLK_DIVIDE(1)) - PLL_BASE_inst - (.CLKOUT1(o_clk), - .CLKOUT2(), - .CLKOUT3(), - .CLKOUT4(), - .CLKOUT5(), - .CLKFBOUT(clkfb), - .LOCKED(locked), - .CLKIN(i_clk), - .RST(~i_rst), - .CLKFBIN(clkfb)); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule diff --git a/servant/service_clock_gen.v b/servant/servant_clock_gen.v similarity index 95% rename from servant/service_clock_gen.v rename to servant/servant_clock_gen.v index c67f617..c430de8 100644 --- a/servant/service_clock_gen.v +++ b/servant/servant_clock_gen.v @@ -1,5 +1,5 @@ `default_nettype none -module service_clock_gen +module servant_clock_gen ( input wire i_clk, output wire o_clk, diff --git a/servant/servant_cmod_a7.v b/servant/servant_cmod_a7.v deleted file mode 100644 index f95db88..0000000 --- a/servant/servant_cmod_a7.v +++ /dev/null @@ -1,33 +0,0 @@ -`default_nettype none -module servant_cmod_a7 -( - input wire i_clk, - input wire i_rst, - output wire o_uart_tx, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire wb_rst; - - assign o_uart_tx = q; - - servant_cmod_a7_clock_gen - clock_gen - (.i_clk (i_clk), - .i_rst (i_rst), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule -`default_nettype wire diff --git a/servant/servant_cmod_a7_clock_gen.v b/servant/servant_cmod_a7_clock_gen.v deleted file mode 100644 index e94eb84..0000000 --- a/servant/servant_cmod_a7_clock_gen.v +++ /dev/null @@ -1,35 +0,0 @@ -`default_nettype none -module servant_cmod_a7_clock_gen - (input wire i_clk, - input wire i_rst, - output wire o_clk, - output reg o_rst); - - wire clkfb; - wire locked; - reg locked_r; - - MMCME2_BASE - #(.CLKIN1_PERIOD (83.333), //12MHz - - /* Set VCO frequency to 12*64=768 MHz - Allowed values are 2.0 to 64.0. Resulting VCO freq - needs to be 600-1200MHz */ - .CLKFBOUT_MULT_F (64.000), - - .CLKOUT0_DIVIDE_F (48.000)) // 768/48 = 16 MHz - pll - (.CLKIN1 (i_clk), - .RST (i_rst), - .CLKOUT0 (o_clk), - .LOCKED (locked), - .CLKFBOUT (clkfb), - .CLKFBIN (clkfb)); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule -`default_nettype wire diff --git a/servant/servant_ecp5.v b/servant/servant_ecp5.v deleted file mode 100644 index a868d57..0000000 --- a/servant/servant_ecp5.v +++ /dev/null @@ -1,33 +0,0 @@ -`default_nettype none -module servant_ecp5 -( - input wire clk, - input wire btn0, - output wire wifi_gpio0, - output wire uart_txd, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire wb_rst; - - assign wifi_gpio0 = btn0; - assign uart_txd = q; - - servant_ecp5_clock_gen clock_gen - (.i_clk (clk), - .i_rst (!btn0), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servant_ecp5_clock_gen.v b/servant/servant_ecp5_clock_gen.v deleted file mode 100644 index 0c5d24a..0000000 --- a/servant/servant_ecp5_clock_gen.v +++ /dev/null @@ -1,25 +0,0 @@ -`default_nettype none -module servant_ecp5_clock_gen - ( - input i_clk, - input i_rst, - output o_clk, - output o_rst); - - wire locked; - - reg [1:0] rst_reg; - always @(posedge o_clk) - if (i_rst) - rst_reg <= 2'b11; - else - rst_reg <= {!locked, rst_reg[1]}; - - assign o_rst = rst_reg[0]; - - pll pll - (.clki (i_clk), - .clko (o_clk), - .locked (locked)); - -endmodule diff --git a/servant/servant_ecp5_evn.v b/servant/servant_ecp5_evn.v deleted file mode 100644 index 195381e..0000000 --- a/servant/servant_ecp5_evn.v +++ /dev/null @@ -1,31 +0,0 @@ -`default_nettype none -module servant_ecp5_evn -( - input wire clk, - input wire nreset, - output wire led0, - output wire uart_txd); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire wb_rst; - - assign led0 = nreset; - - servant_ecp5_evn_clock_gen clock_gen - (.i_clk (clk), - .i_rst (!nreset), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (uart_txd)); - -endmodule diff --git a/servant/servant_ecp5_evn_clock_gen.v b/servant/servant_ecp5_evn_clock_gen.v deleted file mode 100644 index 69e05ab..0000000 --- a/servant/servant_ecp5_evn_clock_gen.v +++ /dev/null @@ -1,25 +0,0 @@ -`default_nettype none -module servant_ecp5_evn_clock_gen - ( - input i_clk, - input i_rst, - output o_clk, - output o_rst); - - wire locked; - - reg [1:0] rst_reg; - always @(posedge o_clk) - if (i_rst) - rst_reg <= 2'b11; - else - rst_reg <= {!locked, rst_reg[1]}; - - assign o_rst = rst_reg[0]; - - ecp5_evn_pll pll - (.clki (i_clk), - .clko (o_clk), - .locked (locked)); - -endmodule diff --git a/servant/servant_gmm7550.v b/servant/servant_gmm7550.v deleted file mode 100644 index b7a3f38..0000000 --- a/servant/servant_gmm7550.v +++ /dev/null @@ -1,75 +0,0 @@ -`timescale 1ns / 1ps - -module servant_gmm7550( - input wire ser_clk, - output wire led_green, - output wire led_red_n, - output wire uart_tx); - - // parameter memfile = "zephyr_hello.hex"; - parameter memfile = "blinky.hex"; - parameter memsize = 8192; - - wire clk270, clk180, clk90, clk0, usr_ref_out; - wire usr_pll_lock_stdy, usr_pll_lock; - - wire usr_rstn; - reg[4:0] rst; - - wire sys_clk; - wire sys_rst; - wire sys_rst_n; - wire q; - - assign led_red_n = 1'b1; - assign led_green = q; - assign uart_tx = q; - - CC_PLL #( - .REF_CLK("100.0"), // reference input in MHz - .OUT_CLK("32.0"), // pll output frequency in MHz - .PERF_MD("SPEED"), // LOWPOWER, ECONOMY, SPEED - .LOCK_REQ(1), // Lock status required before PLL output enable - .LOW_JITTER(1), // 0: disable, 1: enable low jitter mode - .CI_FILTER_CONST(2), // optional CI filter constant - .CP_FILTER_CONST(4) // optional CP filter constant - ) pll_inst ( - .CLK_REF(ser_clk), .CLK_FEEDBACK(1'b0), .USR_CLK_REF(1'b0), - .USR_LOCKED_STDY_RST(1'b0), .USR_PLL_LOCKED_STDY(usr_pll_lock_stdy), .USR_PLL_LOCKED(usr_pll_lock), - .CLK270(clk270), .CLK180(clk180), .CLK90(clk90), .CLK0(clk0), .CLK_REF_OUT(usr_ref_out) - ); - - assign sys_clk = clk0; - - CC_USR_RSTN usr_rst_inst - (.USR_RSTN(usr_rstn)); - - always @(posedge sys_clk or negedge usr_rstn) - begin - if (!usr_rstn) begin - rst <= 5'b01111; - end else begin - if (usr_pll_lock) begin - if (!rst[4]) begin - rst <= rst - 1; - end else begin - rst <= rst; - end - end else begin - rst <= 5'b01111; - end - end - end - - assign sys_rst = !rst[4]; - assign sys_rst_n = rst[4]; - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (sys_clk), - .wb_rst (sys_rst), - .q (q)); - -endmodule diff --git a/servant/servant_lx9.v b/servant/servant_lx9.v deleted file mode 100644 index 41c2c2a..0000000 --- a/servant/servant_lx9.v +++ /dev/null @@ -1,32 +0,0 @@ -`default_nettype none -module servant_lx9 -( - input wire i_clk, - input wire i_rst, - output wire o_uart_tx, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire wb_rst; - - assign o_uart_tx = q; - - servant_lx9_clock_gen - clock_gen - (.i_clk (i_clk), - .i_rst (i_rst), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servant_lx9_clock_gen.v b/servant/servant_lx9_clock_gen.v deleted file mode 100644 index bd9d4ba..0000000 --- a/servant/servant_lx9_clock_gen.v +++ /dev/null @@ -1,35 +0,0 @@ -`default_nettype none -module servant_lx9_clock_gen - (input wire i_clk, - input wire i_rst, - output wire o_clk, - output reg o_rst); - - wire clkfb; - wire locked; - reg locked_r; - - PLL_BASE - #(.BANDWIDTH("OPTIMIZED"), - .CLKFBOUT_MULT(16), - .CLKIN_PERIOD(25.0), //40MHz - .CLKOUT1_DIVIDE(40), //16MHz - .DIVCLK_DIVIDE(1)) - PLL_BASE_inst - (.CLKOUT1(o_clk), - .CLKOUT2(), - .CLKOUT3(), - .CLKOUT4(), - .CLKOUT5(), - .CLKFBOUT(clkfb), - .LOCKED(locked), - .CLKIN(i_clk), - .RST(i_rst), - .CLKFBIN(clkfb)); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule diff --git a/servant/servant_md_kolibri.v b/servant/servant_md_kolibri.v deleted file mode 100644 index 1306305..0000000 --- a/servant/servant_md_kolibri.v +++ /dev/null @@ -1,46 +0,0 @@ -// based on servant_upduino2.v - -`default_nettype none -module servant_md_kolibri - ( - input wire clk48, - output wire led, - output wire tx); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire clk32; - wire locked; - - reg rst = 1'b1; - - // 48MHz -> 32MHz - SB_PLL40_CORE #( - .FEEDBACK_PATH("SIMPLE"), - .DIVR(4'b0010), // DIVR = 2 - .DIVF(7'b0111111), // DIVF = 63 - .DIVQ(3'b101), // DIVQ = 5 - .FILTER_RANGE(3'b001) // FILTER_RANGE = 1 - ) uut ( - .LOCK(locked), - .RESETB(1'b1), - .BYPASS(1'b0), - .REFERENCECLK(clk48), - .PLLOUTCORE(clk32) - ); - - always @(posedge clk32) - rst <= !locked; - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (clk32), - .wb_rst (rst), - .q (tx)); - - assign led = tx; - -endmodule diff --git a/servant/servant_mux.v b/servant/servant_mux.v index f92467b..8c11eff 100644 --- a/servant/servant_mux.v +++ b/servant/servant_mux.v @@ -16,6 +16,13 @@ module servant_mux output wire [31:0] o_wb_cpu_rdt, output reg o_wb_cpu_ack, + output wire [31:0] o_wb_mem_adr, + output wire [31:0] o_wb_mem_dat, + output wire [3:0] o_wb_mem_sel, + output wire o_wb_mem_we, + output wire o_wb_mem_cyc, + input wire [31:0] i_wb_mem_rdt, + output wire o_wb_gpio_dat, output wire o_wb_gpio_we, output wire o_wb_gpio_cyc, @@ -30,8 +37,8 @@ module servant_mux wire [1:0] s = i_wb_cpu_adr[31:30]; - assign o_wb_cpu_rdt = s[1] ? i_wb_timer_rdt : {31'd0,i_wb_gpio_rdt}; - + assign o_wb_cpu_rdt = s[1] ? i_wb_timer_rdt : + s[0] ? {31'd0,i_wb_gpio_rdt} : i_wb_mem_rdt; always @(posedge i_clk) begin o_wb_cpu_ack <= 1'b0; if (i_wb_cpu_cyc & !o_wb_cpu_ack) @@ -40,12 +47,43 @@ module servant_mux o_wb_cpu_ack <= 1'b0; end + assign o_wb_mem_adr = i_wb_cpu_adr; + assign o_wb_mem_dat = i_wb_cpu_dat; + assign o_wb_mem_sel = i_wb_cpu_sel; + assign o_wb_mem_we = i_wb_cpu_we; + assign o_wb_mem_cyc = i_wb_cpu_cyc & (s == 2'b00); + assign o_wb_gpio_dat = i_wb_cpu_dat[0]; assign o_wb_gpio_we = i_wb_cpu_we; - assign o_wb_gpio_cyc = i_wb_cpu_cyc & !s[1]; + assign o_wb_gpio_cyc = i_wb_cpu_cyc & (s == 2'b01); assign o_wb_timer_dat = i_wb_cpu_dat; assign o_wb_timer_we = i_wb_cpu_we; assign o_wb_timer_cyc = i_wb_cpu_cyc & s[1]; + generate + if (sim) begin + wire sig_en = (i_wb_cpu_adr[31:28] == 4'h8) & i_wb_cpu_cyc & o_wb_cpu_ack; + wire halt_en = (i_wb_cpu_adr[31:28] == 4'h9) & i_wb_cpu_cyc & o_wb_cpu_ack; + + reg [1023:0] signature_file; + integer f = 0; + + initial + /* verilator lint_off WIDTH */ + if ($value$plusargs("signature=%s", signature_file)) begin + $display("Writing signature to %0s", signature_file); + f = $fopen(signature_file, "w"); + end + /* verilator lint_on WIDTH */ + + always @(posedge i_clk) + if (sig_en & (f != 0)) + $fwrite(f, "%c", i_wb_cpu_dat[7:0]); + else if(halt_en) begin + $display("Test complete"); + $finish; + end + end + endgenerate endmodule diff --git a/servant/servant_orangecrab.v b/servant/servant_orangecrab.v deleted file mode 100644 index dc895a9..0000000 --- a/servant/servant_orangecrab.v +++ /dev/null @@ -1,96 +0,0 @@ -`default_nettype none -module servant_orangecrab -( - input wire clk, - input wire btn, - output wire r, - output wire g, - output wire b, - output wire tx -); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire pll_locked; - EHXPLLL #( - .CLKI_DIV(6), - .CLKFB_DIV(4), - .CLKOP_DIV(15), - .CLKOS_DIV(8), - .CLKOS2_DIV(8), - .CLKOS3_DIV(8), - .CLKOP_ENABLE("ENABLED"), - .CLKOS_ENABLE("DISABLED"), - .CLKOS2_ENABLE("DISABLED"), - .CLKOS3_ENABLE("DISABLED"), - .CLKOP_CPHASE(0), - .CLKOS_CPHASE(0), - .CLKOS2_CPHASE(0), - .CLKOS3_CPHASE(0), - .CLKOP_FPHASE(0), - .CLKOS_FPHASE(0), - .CLKOS2_FPHASE(0), - .CLKOS3_FPHASE(0), - .FEEDBK_PATH("CLKOP"), - .CLKOP_TRIM_POL("RISING"), - .CLKOP_TRIM_DELAY(0), - .CLKOS_TRIM_POL("RISING"), - .CLKOS_TRIM_DELAY(0), - .OUTDIVIDER_MUXA("DIVA"), - .OUTDIVIDER_MUXB("DIVB"), - .OUTDIVIDER_MUXC("DIVC"), - .OUTDIVIDER_MUXD("DIVD"), - .PLL_LOCK_MODE(0), - .PLL_LOCK_DELAY(200), - .STDBY_ENABLE("DISABLED"), - .REFIN_RESET("DISABLED"), - .SYNC_ENABLE("DISABLED"), - .INT_LOCK_STICKY("ENABLED"), - .DPHASE_SOURCE("DISABLED"), - .PLLRST_ENA("DISABLED"), - .INTFB_WAKE("DISABLED") - ) uPLL ( - .CLKI(clk), // ref input - .CLKFB(wb_clk), // ext fb input - .PHASESEL1(0), // msbit phs adj select - .PHASESEL0(0), // lsbit phs adj select - .PHASEDIR(0), // phs adj dir - .PHASESTEP(0), // phs adj step - .PHASELOADREG(0), // load phs adj - .STDBY(0), // power down pll - .PLLWAKESYNC(0), // int/ext fb switching @ wakeup - .RST(0), // pll reset - .ENCLKOP(1), // primary output enable - .ENCLKOS(0), // secondary output enable - .ENCLKOS2(0), // secondary output enable - .ENCLKOS3(0), // secondary output enable - .CLKOP(wb_clk), // primary output - .CLKOS(), // secondary output - .CLKOS2(), // secondary output - .CLKOS3(), // secondary output - .LOCK(pll_locked), // lock indicator - .INTLOCK(), // internal lock indicator - .REFCLK(), // output of ref select mux - .CLKINTFB() // internal fb - ); - - reg wb_rst; - always @(posedge wb_clk) - wb_rst <= ~pll_locked; - - wire q; - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - - assign r = q; - assign g = q; - assign b = q; - assign tx = q; -endmodule diff --git a/servant/servant_pf.v b/servant/servant_pf.v deleted file mode 100644 index ae3858b..0000000 --- a/servant/servant_pf.v +++ /dev/null @@ -1,66 +0,0 @@ -`default_nettype none - -module servant_pf ( - input wire i_clk, - input wire resetb, - output wire o_led1, - output wire o_led2, - output wire o_led3 = 1'b0, - output wire o_led4 = 1'b0, - output wire o_led5 = 1'b0, - output wire o_led6 = 1'b0, - output wire o_led7 = 1'b0, - output wire o_led8 = 1'b0, - output wire o_uart_tx); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire clk; - wire rst; - wire q; - wire CLKINT_0_Y; - reg heartbeat; - - CLKINT CLKINT_0( - .A (i_clk), - .Y (CLKINT_0_Y) - ); - - servant_pf_clock_gen #( - .refclk(50), - .frequency(32) - ) clock_gen ( - .i_clk (CLKINT_0_Y), - .o_clk (clk) - ); - - servant #( - .memfile (memfile), - .memsize (memsize) - ) servant ( - .wb_clk (clk), - .wb_rst (rst), - .q (q) - ); - - // heartbeat LED - reg [$clog2(32000000)-1:0] count = 0; - always @(posedge clk) begin - if (rst) begin - count <= 0; - heartbeat <= 0; - end else - count <= count + 1; - if (count == 32000000-1) begin - heartbeat <= !heartbeat; - count <= 0; - end - end - - assign rst = ~resetb; - assign o_led1 = q; - assign o_led2 = heartbeat; - assign o_uart_tx = q; - -endmodule diff --git a/servant/servant_pf_clock_gen.v b/servant/servant_pf_clock_gen.v deleted file mode 100644 index 8723725..0000000 --- a/servant/servant_pf_clock_gen.v +++ /dev/null @@ -1,157 +0,0 @@ -`timescale 1 ns/100 ps - -module servant_pf_clock_gen( - input wire i_clk, - output wire o_clk, - output reg o_lock); - - // for documentation - parameter refclk = 50; - parameter frequency = 32; - - // PLL in internal Post-VCO Feedback mode - localparam [11:0] fbdiv = 12'b100111000000; // 2496 - localparam [5:0] rfdiv = 6'b011001; // 25; - localparam vco = 4992; // refclk * fbdiv / rfdiv; - localparam [6:0] odiv = 7'b0100111; // vco / (4 * frequency); - - wire gnd_net, vcc_net, pll_inst_0_clkint_0; - wire nc0, nc1, nc2, nc3, nc4, nc5, nc6, nc7, nc8, nc9, nc10, nc11, nc12, - nc13, nc14, nc15, nc16, nc17, nc18, nc19, nc20, nc21, nc22, nc23, - nc24, nc25, nc26, nc27, nc28, nc29, nc30, nc31, nc32, nc33, nc34, - nc35, nc36, nc37, nc38, nc39, nc40; - - VCC vcc_inst (.Y(vcc_net)); - GND gnd_inst (.Y(gnd_net)); - - PLL #( - .VCOFREQUENCY(vco), - .DELAY_LINE_SIMULATION_MODE(""), - .DATA_RATE(0.0), - .FORMAL_NAME(""), - .INTERFACE_NAME(""), - .INTERFACE_LEVEL(3'b0), - .SOFTRESET(1'b0), - .SOFT_POWERDOWN_N(1'b1), - .RFDIV_EN(1'b1), - .OUT0_DIV_EN(1'b1), - .OUT1_DIV_EN(1'b0), - .OUT2_DIV_EN(1'b0), - .OUT3_DIV_EN(1'b0), - .SOFT_REF_CLK_SEL(1'b0), - .RESET_ON_LOCK(1'b1), - .BYPASS_CLK_SEL(4'b0), - .BYPASS_GO_EN_N(1'b1), - .BYPASS_PLL(4'b0), - .BYPASS_OUT_DIVIDER(4'b0), - .FF_REQUIRES_LOCK(1'b0), - .FSE_N(1'b0), - .FB_CLK_SEL_0(2'b00), - .FB_CLK_SEL_1(1'b0), - .RFDIV(rfdiv), - .FRAC_EN(1'b0), - .FRAC_DAC_EN(1'b0), - .DIV0_RST_DELAY(3'b000), - .DIV0_VAL(odiv), - .DIV1_RST_DELAY(3'b0), - .DIV1_VAL(7'b1), - .DIV2_RST_DELAY(3'b0), - .DIV2_VAL(7'b1), - .DIV3_RST_DELAY(3'b0), - .DIV3_VAL(7'b1), - .DIV3_CLK_SEL(1'b0), - .BW_INT_CTRL(2'b0), - .BW_PROP_CTRL(2'b01), - .IREF_EN(1'b1), - .IREF_TOGGLE(1'b0), - .LOCK_CNT(4'b1000), - .DESKEW_CAL_CNT(3'b110), - .DESKEW_CAL_EN(1'b1), - .DESKEW_CAL_BYPASS(1'b0), - .SYNC_REF_DIV_EN(1'b0), - .SYNC_REF_DIV_EN_2(1'b0), - .OUT0_PHASE_SEL(3'b000), - .OUT1_PHASE_SEL(3'b0), - .OUT2_PHASE_SEL(3'b0), - .OUT3_PHASE_SEL(3'b0), - .SOFT_LOAD_PHASE_N(1'b1), - .SSM_DIV_VAL(6'b1), - .FB_FRAC_VAL(24'b0), - .SSM_SPREAD_MODE(1'b0), - .SSM_MODULATION(5'b00101), - .FB_INT_VAL(fbdiv), - .SSM_EN_N(1'b1), - .SSM_EXT_WAVE_EN(2'b0), - .SSM_EXT_WAVE_MAX_ADDR(8'b0), - .SSM_RANDOM_EN(1'b0), - .SSM_RANDOM_PATTERN_SEL(3'b0), - .CDMUX0_SEL(2'b0), - .CDMUX1_SEL(1'b1), - .CDMUX2_SEL(1'b0), - .CDELAY0_SEL(8'b0), - .CDELAY0_EN(1'b0), - .DRI_EN(1'b1) - ) pll_inst_0 ( - .LOCK(o_lock), - .SSCG_WAVE_TABLE_ADDR({ - nc0, nc1, nc2, nc3, nc4, nc5, nc6, nc7 - }), - .DELAY_LINE_OUT_OF_RANGE(), - .POWERDOWN_N(vcc_net), - .OUT0_EN(vcc_net), - .OUT1_EN(gnd_net), - .OUT2_EN(gnd_net), - .OUT3_EN(gnd_net), - .REF_CLK_SEL(gnd_net), - .BYPASS_EN_N(vcc_net), - .LOAD_PHASE_N(vcc_net), - .SSCG_WAVE_TABLE({ - gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, - gnd_net - }), - .PHASE_DIRECTION(gnd_net), - .PHASE_ROTATE(gnd_net), - .PHASE_OUT0_SEL(gnd_net), - .PHASE_OUT1_SEL(gnd_net), - .PHASE_OUT2_SEL(gnd_net), - .PHASE_OUT3_SEL(gnd_net), - .DELAY_LINE_MOVE(gnd_net), - .DELAY_LINE_DIRECTION(gnd_net), - .DELAY_LINE_WIDE(gnd_net), - .DELAY_LINE_LOAD(vcc_net), - .REFCLK_SYNC_EN(gnd_net), - .REF_CLK_0(i_clk), - .REF_CLK_1(gnd_net), - .FB_CLK(gnd_net), - .OUT0(pll_inst_0_clkint_0), - .OUT1(), - .OUT2(), - .OUT3(), - .DRI_CLK(gnd_net), - .DRI_CTRL({ - gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, - gnd_net, gnd_net, gnd_net, gnd_net - }), - .DRI_WDATA({ - gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, - gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, - gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, - gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, gnd_net, - gnd_net, gnd_net, gnd_net, gnd_net, gnd_net - }), - .DRI_ARST_N(vcc_net), - .DRI_RDATA({ - nc8, nc9, nc10, nc11, nc12, nc13, nc14, nc15, nc16, nc17, nc18, - nc19, nc20, nc21, nc22, nc23, nc24, nc25, nc26, nc27, nc28, nc29, - nc30, nc31, nc32, nc33, nc34, nc35, nc36, nc37, nc38, nc39, - nc40 - }), - .DRI_INTERRUPT() - ); - - CLKINT clkint_0 ( - .A(pll_inst_0_clkint_0), - .Y(o_clk) - ); - - endmodule diff --git a/servant/servant_ram.v b/servant/servant_ram.v index 635e72d..11e058c 100644 --- a/servant/servant_ram.v +++ b/servant/servant_ram.v @@ -3,10 +3,8 @@ module servant_ram #(//Memory parameters parameter depth = 256, parameter aw = $clog2(depth), - parameter RESET_STRATEGY = "", parameter memfile = "") (input wire i_wb_clk, - input wire i_wb_rst, input wire [aw-1:2] i_wb_adr, input wire [31:0] i_wb_dat, input wire [3:0] i_wb_sel, @@ -22,10 +20,7 @@ module servant_ram wire [aw-3:0] addr = i_wb_adr[aw-1:2]; always @(posedge i_wb_clk) - if (i_wb_rst & (RESET_STRATEGY != "NONE")) - o_wb_ack <= 1'b0; - else - o_wb_ack <= i_wb_cyc & !o_wb_ack; + o_wb_ack <= i_wb_cyc & !o_wb_ack; always @(posedge i_wb_clk) begin if (we[0]) mem[addr][7:0] <= i_wb_dat[7:0]; @@ -37,11 +32,7 @@ module servant_ram initial if(|memfile) begin -`ifndef ISE -`ifndef CCGM $display("Preloading %m from %s", memfile); -`endif -`endif $readmemh(memfile, mem); end diff --git a/servant/servant_ram_quartus.sv b/servant/servant_ram_quartus.sv index 95dcdca..8073359 100644 --- a/servant/servant_ram_quartus.sv +++ b/servant/servant_ram_quartus.sv @@ -3,10 +3,8 @@ module servant_ram #(//Memory parameters parameter depth = 256, parameter aw = $clog2(depth), - parameter RESET_STRATEGY = "", parameter memfile = "") (input wire i_wb_clk, - input wire i_wb_rst, input wire [aw-1:2] i_wb_adr, input wire [31:0] i_wb_dat, input wire [3:0] i_wb_sel, @@ -22,10 +20,7 @@ module servant_ram wire [aw-3:0] addr = i_wb_adr[aw-1:2]; always @(posedge i_wb_clk) - if (i_wb_rst & (RESET_STRATEGY != "NONE")) - o_wb_ack <= 1'b0; - else - o_wb_ack <= i_wb_cyc & !o_wb_ack; + o_wb_ack <= i_wb_cyc & !o_wb_ack; always_ff @(posedge i_wb_clk) begin if(we) begin diff --git a/servant/servant_te0802.v b/servant/servant_te0802.v deleted file mode 100644 index b72b4cc..0000000 --- a/servant/servant_te0802.v +++ /dev/null @@ -1,33 +0,0 @@ -`default_nettype none -module servant_te0802 - ( - input wire i_clk, - output wire o_uart_tx, - output wire o_led_0 - ); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire clk; - wire rst; - wire q; - - assign o_uart_tx = q; - assign o_led_0 = q; - - servant_te0802_clock_gen - clock_gen - (.i_clk (i_clk), - .o_clk (clk), - .o_rst (rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (clk), - .wb_rst (rst), - .q (q)); - -endmodule diff --git a/servant/servant_te0802_clock_gen.v b/servant/servant_te0802_clock_gen.v deleted file mode 100644 index fe118a1..0000000 --- a/servant/servant_te0802_clock_gen.v +++ /dev/null @@ -1,45 +0,0 @@ -`default_nettype none -module servant_te0802_clock_gen - (input wire i_clk, - output wire o_clk, - output reg o_rst); - - wire clkfb; - wire locked; - reg locked_r; - - // Generate a 32 MHz clock from the 25MHz clock input - MMCME4_ADV - #(.DIVCLK_DIVIDE (1), - .CLKFBOUT_MULT_F (48.000), - .CLKOUT0_DIVIDE_F (37.5), - .CLKIN1_PERIOD (40.0), //25MHz - .STARTUP_WAIT ("FALSE")) - mmcm - (.CLKFBOUT (clkfb), - .CLKFBOUTB (), - .CLKOUT0 (o_clk), - .CLKOUT0B (), - .CLKOUT1 (), - .CLKOUT1B (), - .CLKOUT2 (), - .CLKOUT2B (), - .CLKOUT3 (), - .CLKOUT3B (), - .CLKOUT4 (), - .CLKOUT5 (), - .CLKOUT6 (), - .CLKIN1 (i_clk), - .CLKIN2 (1'b0), - .CLKINSEL (1'b1), - .LOCKED (locked), - .PWRDWN (1'b0), - .RST (1'b0), - .CLKFBIN (clkfb)); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule diff --git a/servant/servant_timer.v b/servant/servant_timer.v index 45306e9..28bdb82 100644 --- a/servant/servant_timer.v +++ b/servant/servant_timer.v @@ -1,10 +1,8 @@ `default_nettype none module servant_timer #(parameter WIDTH = 16, - parameter RESET_STRATEGY = "", parameter DIVIDER = 0) (input wire i_clk, - input wire i_rst, output reg o_irq, input wire [31:0] i_wb_dat, input wire i_wb_we, @@ -14,9 +12,9 @@ module servant_timer localparam HIGH = WIDTH-1-DIVIDER; reg [WIDTH-1:0] mtime; - reg signed [HIGH:0] mtimecmp; + reg [HIGH:0] mtimecmp; - wire signed [HIGH:0] mtimeslice = mtime[WIDTH-1:DIVIDER]; + wire [HIGH:0] mtimeslice = mtime[WIDTH-1:DIVIDER]; always @(mtimeslice) begin o_wb_dat = 32'd0; @@ -27,11 +25,6 @@ module servant_timer if (i_wb_cyc & i_wb_we) mtimecmp <= i_wb_dat[HIGH:0]; mtime <= mtime + 'd1; - o_irq <= (mtimeslice - mtimecmp >= 0); - if (RESET_STRATEGY != "NONE") - if (i_rst) begin - mtime <= 0; - mtimecmp <= 0; - end + o_irq <= (mtimeslice >= mtimecmp); end endmodule diff --git a/servant/servant_upduino2.v b/servant/servant_upduino2.v deleted file mode 100644 index 7c43004..0000000 --- a/servant/servant_upduino2.v +++ /dev/null @@ -1,77 +0,0 @@ -`default_nettype none -module servant_upduino2 - ( - output wire g, - output wire b, - output wire r, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - parameter PLL = "NONE"; - - wire clk; - wire clk48; - wire locked; - - SB_HFOSC inthosc - ( - .CLKHFPU(1'b1), - .CLKHFEN(1'b1), - .CLKHF(clk48)); - - SB_PLL40_CORE - #( - .FEEDBACK_PATH("SIMPLE"), - .DIVR(4'b0010), - .DIVF(7'b0111111), - .DIVQ(3'b110), - .FILTER_RANGE(3'b001)) - pll - (.LOCK(locked), - .RESETB(1'b1), - .BYPASS(1'b0), - .REFERENCECLK(clk48), - .PLLOUTCORE(clk)); - - SB_RGBA_DRV - #( - .CURRENT_MODE ("0b1"), - .RGB0_CURRENT ("0b000111"), - .RGB1_CURRENT ("0b000111"), - .RGB2_CURRENT ("0b000111")) - RGBA_DRIVER - ( - .CURREN(1'b1), - .RGBLEDEN(1'b1), - .RGB0PWM(q), - .RGB1PWM(q), - .RGB2PWM(q), - .RGB0(g), - .RGB1(b), - .RGB2(r)); - - reg rst = 1'b1; - -/* - //Delayed reset - reg [25:0] cnt; - always @(posedge clk) begin - if (!cnt[25]) - cnt <= cnt + 1; - rst <= !cnt[25]; - end - */ - - always @(posedge clk) - rst <= !locked; - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (clk), - .wb_rst (rst), - .q (q)); - -endmodule diff --git a/servant/servax.v b/servant/servax.v deleted file mode 100644 index 3f2865e..0000000 --- a/servant/servax.v +++ /dev/null @@ -1,28 +0,0 @@ -`default_nettype none -module servax // top level for nexys 2 (Xilinx's Spartan-3E based) target board -( - input wire i_clk, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - parameter PLL = "NONE"; - - wire wb_clk; - wire wb_rst; - - servax_clock_gen - clock_gen - (.i_clk (i_clk), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule \ No newline at end of file diff --git a/servant/servax_clock_gen.v b/servant/servax_clock_gen.v deleted file mode 100644 index 182288a..0000000 --- a/servant/servax_clock_gen.v +++ /dev/null @@ -1,31 +0,0 @@ -`default_nettype none -module servax_clock_gen - (input wire i_clk, - output wire o_clk, - output reg o_rst); - - wire locked; - reg locked_r; - - - DCM_SP #( - .CLKFX_DIVIDE(25), // Can be any integer from 1 to 32 - .CLKFX_MULTIPLY(8), // Can be any integer from 2 to 32 - .CLKIN_PERIOD(20.0) //50Mhz - ) - DCM_SP_inst ( - .CLKFX(o_clk), // DCM CLK synthesis out (M/D) - .CLKFX180(), // 180 degree CLK synthesis out - .LOCKED(locked), // DCM LOCK status output - .STATUS(), // 8-bit DCM status bits output - .CLKFB(), // DCM clock feedback - .CLKIN(i_clk), // Clock input - .RST(1'b0) // DCM asynchronous reset input - ); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule \ No newline at end of file diff --git a/servant/servde1_soc_revF.v b/servant/servde1_soc_revF.v deleted file mode 100644 index 19d46bd..0000000 --- a/servant/servde1_soc_revF.v +++ /dev/null @@ -1,31 +0,0 @@ -`default_nettype none -module servde1_soc_revF -( - input wire i_clk, - input wire i_rst_n, - output wire q, - output wire uart_txd); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire wb_rst; - - assign uart_txd = q; - - servde1_soc_revF_clock_gen clock_gen - (.i_clk (i_clk), - .i_rst (!i_rst_n), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servde1_soc_revF_clock_gen.v b/servant/servde1_soc_revF_clock_gen.v deleted file mode 100644 index eb7a1dd..0000000 --- a/servant/servde1_soc_revF_clock_gen.v +++ /dev/null @@ -1,34 +0,0 @@ -`default_nettype none -module servde1_soc_revF_clock_gen - (input wire i_clk, - input wire i_rst, - output wire o_clk, - output wire o_rst); - - wire locked; - reg [9:0] r; - - assign o_rst = r[9]; - - always @(posedge o_clk) - if (locked) - r <= {r[8:0],1'b0}; - else - r <= 10'b1111111111; - - wire [5:0] clk; - - assign o_clk = clk[0]; - - altpll - #(.operation_mode ("NORMAL"), - .clk0_divide_by (25), - .clk0_multiply_by (8), - .inclk0_input_frequency (20000)) - pll - (.areset (i_rst), - .inclk ({1'b0, i_clk}), - .clk (clk), - .locked (locked)); - -endmodule diff --git a/servant/service.v b/servant/service.v index ced0975..0f60a99 100644 --- a/servant/service.v +++ b/servant/service.v @@ -11,7 +11,7 @@ module service wire wb_clk; wire wb_rst; - service_clock_gen #(.PLL (PLL)) + servant_clock_gen #(.PLL (PLL)) clock_gen (.i_clk (i_clk), .o_clk (wb_clk), diff --git a/servant/service_go_board.v b/servant/service_go_board.v deleted file mode 100644 index 5dbcf68..0000000 --- a/servant/service_go_board.v +++ /dev/null @@ -1,34 +0,0 @@ -`default_nettype none -module service_go_board - (input wire i_clk, - output wire o_led1, - output wire o_led2 = 1'b0, - output wire o_led3 = 1'b0, - output wire o_led4 = 1'b0, - output wire o_uart_tx); - - parameter memfile = "blinky.hex"; - parameter memsize = 512; - - // Assert reset for 64 clock cycles. Use the 7th bit as the reset signal. - reg [6:0] rst_count; - wire rst_r = !rst_count[6]; - - always @(posedge i_clk) begin - if (rst_r == 1) begin - rst_count <= rst_count + 1; - end - end - - wire q; - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (i_clk), - .wb_rst (rst_r), - .q (q)); - assign o_led1 = q; - assign o_uart_tx = q; - -endmodule diff --git a/servant/servis.v b/servant/servis.v deleted file mode 100644 index f601d31..0000000 --- a/servant/servis.v +++ /dev/null @@ -1,28 +0,0 @@ -`default_nettype none -module servis -( - input wire i_clk, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - parameter PLL = "NONE"; - - wire wb_clk; - wire wb_rst; - - servis_clock_gen - clock_gen - (.i_clk (i_clk), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servis_clock_gen.v b/servant/servis_clock_gen.v deleted file mode 100644 index a8b9067..0000000 --- a/servant/servis_clock_gen.v +++ /dev/null @@ -1,34 +0,0 @@ -`default_nettype none -module servis_clock_gen - (input wire i_clk, - output wire o_clk, - output reg o_rst); - - wire clkfb; - wire locked; - reg locked_r; - - PLL_BASE - #(.BANDWIDTH("OPTIMIZED"), - .CLKFBOUT_MULT(16), - .CLKIN_PERIOD(20.0), //50MHz - .CLKOUT1_DIVIDE(50), //16MHz - .DIVCLK_DIVIDE(1)) - PLL_BASE_inst - (.CLKOUT1(o_clk), - .CLKOUT2(), - .CLKOUT3(), - .CLKOUT4(), - .CLKOUT5(), - .CLKFBOUT(clkfb), - .LOCKED(locked), - .CLKIN(i_clk), - .RST(1'b0), - .CLKFBIN(clkfb)); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule diff --git a/servant/servive.v b/servant/servive.v deleted file mode 100644 index 829eb30..0000000 --- a/servant/servive.v +++ /dev/null @@ -1,31 +0,0 @@ -`default_nettype none -module servive -( - input wire i_clk, - input wire i_rst_n, - output wire q, - output wire uart_txd); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire wb_clk; - wire wb_rst; - - assign uart_txd = q; - - servive_clock_gen clock_gen - (.i_clk (i_clk), - .i_rst (!i_rst_n), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servive_clock_gen.v b/servant/servive_clock_gen.v deleted file mode 100644 index 716e34d..0000000 --- a/servant/servive_clock_gen.v +++ /dev/null @@ -1,34 +0,0 @@ -`default_nettype none -module servive_clock_gen - (input wire i_clk, - input wire i_rst, - output wire o_clk, - output wire o_rst); - - wire locked; - reg [9:0] r; - - assign o_rst = r[9]; - - always @(posedge o_clk) - if (locked) - r <= {r[8:0],1'b0}; - else - r <= 10'b1111111111; - - wire [5:0] clk; - - assign o_clk = clk[0]; - - altpll - #(.operation_mode ("NORMAL"), - .clk0_divide_by (25), - .clk0_multiply_by (8), - .inclk0_input_frequency (20000)) - pll - (.areset (i_rst), - .inclk ({1'b0, i_clk}), - .clk (clk), - .locked (locked)); - -endmodule diff --git a/servant/servix.v b/servant/servix.v index 0b26b1b..9b665ed 100644 --- a/servant/servix.v +++ b/servant/servix.v @@ -2,9 +2,6 @@ module servix ( input wire i_clk, -`ifdef WITH_RESET - input wire i_rst_n, -`endif output wire q); parameter frequency = 32; @@ -19,11 +16,6 @@ module servix #(.frequency (frequency)) clock_gen (.i_clk (i_clk), -`ifdef WITH_RESET - .i_rst (!i_rst_n), -`else - .i_rst (1'b0), -`endif .o_clk (wb_clk), .o_rst (wb_rst)); diff --git a/servant/servix_clock_gen.v b/servant/servix_clock_gen.v index 33b7175..b44e75c 100644 --- a/servant/servix_clock_gen.v +++ b/servant/servix_clock_gen.v @@ -1,7 +1,6 @@ `default_nettype none module servix_clock_gen (input wire i_clk, - input wire i_rst, output wire o_clk, output reg o_rst); @@ -29,7 +28,7 @@ module servix_clock_gen .LOCKED(locked), .CLKIN1(i_clk), .PWRDWN(1'b0), - .RST(i_rst), + .RST(1'b0), .CLKFBIN(clkfb)); always @(posedge o_clk) begin diff --git a/servant/servix_ebaz4205.v b/servant/servix_ebaz4205.v deleted file mode 100644 index 1819c37..0000000 --- a/servant/servix_ebaz4205.v +++ /dev/null @@ -1,30 +0,0 @@ -`default_nettype none -module servix_ebaz4205 -( - input wire i_clk, - output wire q); - - parameter frequency = 32; - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - parameter PLL = "NONE"; - - wire wb_clk; - wire wb_rst; - - servix_ebaz4205_clock_gen - #(.frequency (frequency)) - clock_gen - (.i_clk (i_clk), - .o_clk (wb_clk), - .o_rst (wb_rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (wb_clk), - .wb_rst (wb_rst), - .q (q)); - -endmodule diff --git a/servant/servix_ebaz4205_clock_gen.v b/servant/servix_ebaz4205_clock_gen.v deleted file mode 100644 index 54984a4..0000000 --- a/servant/servix_ebaz4205_clock_gen.v +++ /dev/null @@ -1,40 +0,0 @@ -`default_nettype none -module servix_ebaz4205_clock_gen - (input wire i_clk, - output wire o_clk, - output reg o_rst); - - parameter frequency = 32; - - wire clkfb; - wire locked; - reg locked_r; - - // (33.333 * 48) / 50 => 31.9996 MHz - PLLE2_BASE - #(.BANDWIDTH("OPTIMIZED"), - .CLKFBOUT_MULT(48), - .CLKIN1_PERIOD(30.000300003), // 33.333 MHz - .CLKOUT0_DIVIDE((frequency == 32) ? 50 : 100), - .DIVCLK_DIVIDE(1), - .STARTUP_WAIT("FALSE")) - PLLE2_BASE_inst - (.CLKOUT0(o_clk), - .CLKOUT1(), - .CLKOUT2(), - .CLKOUT3(), - .CLKOUT4(), - .CLKOUT5(), - .CLKFBOUT(clkfb), - .LOCKED(locked), - .CLKIN1(i_clk), - .PWRDWN(1'b0), - .RST(1'b0), - .CLKFBIN(clkfb)); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule diff --git a/servant/servus.v b/servant/servus.v deleted file mode 100644 index 05fa774..0000000 --- a/servant/servus.v +++ /dev/null @@ -1,36 +0,0 @@ -`default_nettype none -module servus - (input wire i_clk_p, - input wire i_clk_n, - output wire o_uart_tx, - output wire q); - - parameter memfile = "zephyr_hello.hex"; - parameter memsize = 8192; - - wire i_clk; - wire clk; - wire rst; - - assign o_uart_tx = q; - - IBUFDS ibufds - (.I (i_clk_p), - .IB (i_clk_n), - .O (i_clk)); - - servus_clock_gen - clock_gen - (.i_clk (i_clk), - .o_clk (clk), - .o_rst (rst)); - - servant - #(.memfile (memfile), - .memsize (memsize)) - servant - (.wb_clk (clk), - .wb_rst (rst), - .q (q)); - -endmodule diff --git a/servant/servus_clock_gen.v b/servant/servus_clock_gen.v deleted file mode 100644 index 0e91c8c..0000000 --- a/servant/servus_clock_gen.v +++ /dev/null @@ -1,44 +0,0 @@ -`default_nettype none -module servus_clock_gen - (input wire i_clk, - output wire o_clk, - output reg o_rst); - - wire clkfb; - wire locked; - reg locked_r; - - MMCME4_ADV - #(.DIVCLK_DIVIDE (5), - .CLKFBOUT_MULT_F (48.000), - .CLKOUT0_DIVIDE_F (75.0), - .CLKIN1_PERIOD (8.0), //125MHz - .STARTUP_WAIT ("FALSE")) - mmcm - (.CLKFBOUT (clkfb), - .CLKFBOUTB (), - .CLKOUT0 (o_clk), - .CLKOUT0B (), - .CLKOUT1 (), - .CLKOUT1B (), - .CLKOUT2 (), - .CLKOUT2B (), - .CLKOUT3 (), - .CLKOUT3B (), - .CLKOUT4 (), - .CLKOUT5 (), - .CLKOUT6 (), - .CLKIN1 (i_clk), - .CLKIN2 (1'b0), - .CLKINSEL (1'b1), - .LOCKED (locked), - .PWRDWN (1'b0), - .RST (1'b0), - .CLKFBIN (clkfb)); - - always @(posedge o_clk) begin - locked_r <= locked; - o_rst <= !locked_r; - end - -endmodule diff --git a/servile.core b/servile.core deleted file mode 100644 index c4ce88e..0000000 --- a/servile.core +++ /dev/null @@ -1,27 +0,0 @@ -CAPI=2: - -name : ::servile:1.3.0 - -description: Convenience wrapper for SERV - -filesets: - rtl: - files: - - servile/servile_rf_mem_if.v - - servile/servile_mux.v - - servile/servile_arbiter.v - - servile/servile.v - file_type: verilogSource - depend : [serv] - -targets: - default: - filesets: [rtl] - - lint: - description: Run static code checks (linting) - filesets: [rtl] - flow: lint - flow_options: - tool: verilator - toplevel: servile diff --git a/servile/servile.v b/servile/servile.v deleted file mode 100644 index 64abc4a..0000000 --- a/servile/servile.v +++ /dev/null @@ -1,279 +0,0 @@ -/* - * servile.v : Top-level for Servile, the SERV convenience wrapper - * - * SPDX-FileCopyrightText: 2024 Olof Kindgren - * SPDX-License-Identifier: Apache-2.0 - */ - -`default_nettype none -module servile - #( - parameter width = 1, - parameter reset_pc = 32'h00000000, - parameter reset_strategy = "MINI", - parameter rf_width = 2*width, - parameter [0:0] sim = 1'b0, - parameter [0:0] debug = 1'b0, - parameter [0:0] with_c = 1'b0, - parameter [0:0] with_csr = 1'b0, - parameter [0:0] with_mdu = 1'b0, - //Internally calculated. Do not touch - parameter B = width-1, - parameter regs = 32+with_csr*4, - parameter rf_l2d = $clog2(regs*32/rf_width)) - ( - input wire i_clk, - input wire i_rst, - input wire i_timer_irq, - - //Memory (WB) interface - output wire [31:0] o_wb_mem_adr, - output wire [31:0] o_wb_mem_dat, - output wire [3:0] o_wb_mem_sel, - output wire o_wb_mem_we , - output wire o_wb_mem_stb, - input wire [31:0] i_wb_mem_rdt, - input wire i_wb_mem_ack, - - //Extension (WB) interface - output wire [31:0] o_wb_ext_adr, - output wire [31:0] o_wb_ext_dat, - output wire [3:0] o_wb_ext_sel, - output wire o_wb_ext_we , - output wire o_wb_ext_stb, - input wire [31:0] i_wb_ext_rdt, - input wire i_wb_ext_ack, - - //RF (SRAM) interface - output wire [rf_l2d-1:0] o_rf_waddr, - output wire [rf_width-1:0] o_rf_wdata, - output wire o_rf_wen, - output wire [rf_l2d-1:0] o_rf_raddr, - input wire [rf_width-1:0] i_rf_rdata, - output wire o_rf_ren); - - - - wire [31:0] wb_ibus_adr; - wire wb_ibus_stb; - wire [31:0] wb_ibus_rdt; - wire wb_ibus_ack; - - wire [31:0] wb_dbus_adr; - wire [31:0] wb_dbus_dat; - wire [3:0] wb_dbus_sel; - wire wb_dbus_we; - wire wb_dbus_stb; - wire [31:0] wb_dbus_rdt; - wire wb_dbus_ack; - - wire [31:0] wb_dmem_adr; - wire [31:0] wb_dmem_dat; - wire [3:0] wb_dmem_sel; - wire wb_dmem_we; - wire wb_dmem_stb; - wire [31:0] wb_dmem_rdt; - wire wb_dmem_ack; - - wire rf_wreq; - wire rf_rreq; - wire [$clog2(regs)-1:0] wreg0; - wire [$clog2(regs)-1:0] wreg1; - wire wen0; - wire wen1; - wire [B:0] wdata0; - wire [B:0] wdata1; - wire [$clog2(regs)-1:0] rreg0; - wire [$clog2(regs)-1:0] rreg1; - wire rf_ready; - wire [B:0] rdata0; - wire [B:0] rdata1; - - wire [31:0] mdu_rs1; - wire [31:0] mdu_rs2; - wire [ 2:0] mdu_op; - wire mdu_valid; - wire [31:0] mdu_rd; - wire mdu_ready; - - servile_mux - #(.sim (sim)) - mux - (.i_clk (i_clk), - .i_rst (i_rst & (reset_strategy != "NONE")), - - .i_wb_cpu_adr (wb_dbus_adr), - .i_wb_cpu_dat (wb_dbus_dat), - .i_wb_cpu_sel (wb_dbus_sel), - .i_wb_cpu_we (wb_dbus_we), - .i_wb_cpu_stb (wb_dbus_stb), - .o_wb_cpu_rdt (wb_dbus_rdt), - .o_wb_cpu_ack (wb_dbus_ack), - - .o_wb_mem_adr (wb_dmem_adr), - .o_wb_mem_dat (wb_dmem_dat), - .o_wb_mem_sel (wb_dmem_sel), - .o_wb_mem_we (wb_dmem_we), - .o_wb_mem_stb (wb_dmem_stb), - .i_wb_mem_rdt (wb_dmem_rdt), - .i_wb_mem_ack (wb_dmem_ack), - - .o_wb_ext_adr (o_wb_ext_adr), - .o_wb_ext_dat (o_wb_ext_dat), - .o_wb_ext_sel (o_wb_ext_sel), - .o_wb_ext_we (o_wb_ext_we), - .o_wb_ext_stb (o_wb_ext_stb), - .i_wb_ext_rdt (i_wb_ext_rdt), - .i_wb_ext_ack (i_wb_ext_ack)); - - servile_arbiter arbiter - (.i_wb_cpu_dbus_adr (wb_dmem_adr), - .i_wb_cpu_dbus_dat (wb_dmem_dat), - .i_wb_cpu_dbus_sel (wb_dmem_sel), - .i_wb_cpu_dbus_we (wb_dmem_we ), - .i_wb_cpu_dbus_stb (wb_dmem_stb), - .o_wb_cpu_dbus_rdt (wb_dmem_rdt), - .o_wb_cpu_dbus_ack (wb_dmem_ack), - - .i_wb_cpu_ibus_adr (wb_ibus_adr), - .i_wb_cpu_ibus_stb (wb_ibus_stb), - .o_wb_cpu_ibus_rdt (wb_ibus_rdt), - .o_wb_cpu_ibus_ack (wb_ibus_ack), - - .o_wb_mem_adr (o_wb_mem_adr), - .o_wb_mem_dat (o_wb_mem_dat), - .o_wb_mem_sel (o_wb_mem_sel), - .o_wb_mem_we (o_wb_mem_we ), - .o_wb_mem_stb (o_wb_mem_stb), - .i_wb_mem_rdt (i_wb_mem_rdt), - .i_wb_mem_ack (i_wb_mem_ack)); - - - - serv_rf_ram_if - #(.width (rf_width), - .W (width), - .reset_strategy (reset_strategy), - .csr_regs (with_csr*4)) - rf_ram_if - (.i_clk (i_clk), - .i_rst (i_rst), - //RF IF - .i_wreq (rf_wreq), - .i_rreq (rf_rreq), - .o_ready (rf_ready), - .i_wreg0 (wreg0), - .i_wreg1 (wreg1), - .i_wen0 (wen0), - .i_wen1 (wen1), - .i_wdata0 (wdata0), - .i_wdata1 (wdata1), - .i_rreg0 (rreg0), - .i_rreg1 (rreg1), - .o_rdata0 (rdata0), - .o_rdata1 (rdata1), - //SRAM IF - .o_waddr (o_rf_waddr), - .o_wdata (o_rf_wdata), - .o_wen (o_rf_wen), - .o_raddr (o_rf_raddr), - .o_ren (o_rf_ren), - .i_rdata (i_rf_rdata)); - - generate - if (with_mdu) begin : gen_mdu - mdu_top mdu_serv - (.i_clk (i_clk), - .i_rst (i_rst), - .i_mdu_rs1 (mdu_rs1), - .i_mdu_rs2 (mdu_rs2), - .i_mdu_op (mdu_op), - .i_mdu_valid (mdu_valid), - .o_mdu_ready (mdu_ready), - .o_mdu_rd (mdu_rd)); - end else begin - assign mdu_ready = 1'b0; - assign mdu_rd = 32'd0; - end - endgenerate - - serv_top - #( - .WITH_CSR (with_csr?1:0), - .W (width), - .PRE_REGISTER (1'b1), - .RESET_STRATEGY (reset_strategy), - .RESET_PC (reset_pc), - .DEBUG (debug), - .MDU (with_mdu), - .COMPRESSED (with_c)) - cpu - ( - .clk (i_clk), - .i_rst (i_rst), - .i_timer_irq (i_timer_irq), - -`ifdef RISCV_FORMAL - .rvfi_valid (), - .rvfi_order (), - .rvfi_insn (), - .rvfi_trap (), - .rvfi_halt (), - .rvfi_intr (), - .rvfi_mode (), - .rvfi_ixl (), - .rvfi_rs1_addr (), - .rvfi_rs2_addr (), - .rvfi_rs1_rdata (), - .rvfi_rs2_rdata (), - .rvfi_rd_addr (), - .rvfi_rd_wdata (), - .rvfi_pc_rdata (), - .rvfi_pc_wdata (), - .rvfi_mem_addr (), - .rvfi_mem_rmask (), - .rvfi_mem_wmask (), - .rvfi_mem_rdata (), - .rvfi_mem_wdata (), -`endif - //RF IF - .o_rf_rreq (rf_rreq), - .o_rf_wreq (rf_wreq), - .i_rf_ready (rf_ready), - .o_wreg0 (wreg0), - .o_wreg1 (wreg1), - .o_wen0 (wen0), - .o_wen1 (wen1), - .o_wdata0 (wdata0), - .o_wdata1 (wdata1), - .o_rreg0 (rreg0), - .o_rreg1 (rreg1), - .i_rdata0 (rdata0), - .i_rdata1 (rdata1), - - //Instruction bus - .o_ibus_adr (wb_ibus_adr), - .o_ibus_cyc (wb_ibus_stb), - .i_ibus_rdt (wb_ibus_rdt), - .i_ibus_ack (wb_ibus_ack), - - //Data bus - .o_dbus_adr (wb_dbus_adr), - .o_dbus_dat (wb_dbus_dat), - .o_dbus_sel (wb_dbus_sel), - .o_dbus_we (wb_dbus_we), - .o_dbus_cyc (wb_dbus_stb), - .i_dbus_rdt (wb_dbus_rdt), - .i_dbus_ack (wb_dbus_ack), - - //Extension IF - .o_ext_rs1 (mdu_rs1), - .o_ext_rs2 (mdu_rs2), - .o_ext_funct3 (mdu_op), - .i_ext_rd (mdu_rd), - .i_ext_ready (mdu_ready), - //MDU - .o_mdu_valid (mdu_valid)); - -endmodule -`default_nettype wire diff --git a/servile/servile_arbiter.v b/servile/servile_arbiter.v deleted file mode 100644 index 720fa2b..0000000 --- a/servile/servile_arbiter.v +++ /dev/null @@ -1,45 +0,0 @@ -/* - * servile_arbiter.v : I/D arbiter for the servile convenience wrapper. - * Relies on the fact that not ibus and dbus are active at the same time. - * - * SPDX-FileCopyrightText: 2024 Olof Kindgren - * SPDX-License-Identifier: Apache-2.0 - */ - -module servile_arbiter - ( - input wire [31:0] i_wb_cpu_dbus_adr, - input wire [31:0] i_wb_cpu_dbus_dat, - input wire [3:0] i_wb_cpu_dbus_sel, - input wire i_wb_cpu_dbus_we, - input wire i_wb_cpu_dbus_stb, - output wire [31:0] o_wb_cpu_dbus_rdt, - output wire o_wb_cpu_dbus_ack, - - input wire [31:0] i_wb_cpu_ibus_adr, - input wire i_wb_cpu_ibus_stb, - output wire [31:0] o_wb_cpu_ibus_rdt, - output wire o_wb_cpu_ibus_ack, - - output wire [31:0] o_wb_mem_adr, - output wire [31:0] o_wb_mem_dat, - output wire [3:0] o_wb_mem_sel, - output wire o_wb_mem_we, - output wire o_wb_mem_stb, - input wire [31:0] i_wb_mem_rdt, - input wire i_wb_mem_ack); - - assign o_wb_cpu_dbus_rdt = i_wb_mem_rdt; - assign o_wb_cpu_dbus_ack = i_wb_mem_ack & !i_wb_cpu_ibus_stb; - - assign o_wb_cpu_ibus_rdt = i_wb_mem_rdt; - assign o_wb_cpu_ibus_ack = i_wb_mem_ack & i_wb_cpu_ibus_stb; - - assign o_wb_mem_adr = i_wb_cpu_ibus_stb ? i_wb_cpu_ibus_adr : i_wb_cpu_dbus_adr; - assign o_wb_mem_dat = i_wb_cpu_dbus_dat; - assign o_wb_mem_sel = i_wb_cpu_dbus_sel; - assign o_wb_mem_we = i_wb_cpu_dbus_we & !i_wb_cpu_ibus_stb; - assign o_wb_mem_stb = i_wb_cpu_ibus_stb | i_wb_cpu_dbus_stb; - - -endmodule diff --git a/servile/servile_mux.v b/servile/servile_mux.v deleted file mode 100644 index e4d8c5c..0000000 --- a/servile/servile_mux.v +++ /dev/null @@ -1,100 +0,0 @@ -/* - * servile_mux.v : Simple Wishbone mux for the servile convenience wrapper. - * - * SPDX-FileCopyrightText: 2024 Olof Kindgren - * SPDX-License-Identifier: Apache-2.0 - */ - -module servile_mux - #(parameter [0:0] sim = 1'b0, //Enable simulation features - parameter [31:0] sim_sig_adr = 32'h80000000, - parameter [31:0] sim_halt_adr = 32'h90000000) - ( - input wire i_clk, - input wire i_rst, - - input wire [31:0] i_wb_cpu_adr, - input wire [31:0] i_wb_cpu_dat, - input wire [3:0] i_wb_cpu_sel, - input wire i_wb_cpu_we, - input wire i_wb_cpu_stb, - output wire [31:0] o_wb_cpu_rdt, - output wire o_wb_cpu_ack, - - output wire [31:0] o_wb_mem_adr, - output wire [31:0] o_wb_mem_dat, - output wire [3:0] o_wb_mem_sel, - output wire o_wb_mem_we, - output wire o_wb_mem_stb, - input wire [31:0] i_wb_mem_rdt, - input wire i_wb_mem_ack, - - output wire [31:0] o_wb_ext_adr, - output wire [31:0] o_wb_ext_dat, - output wire [3:0] o_wb_ext_sel, - output wire o_wb_ext_we, - output wire o_wb_ext_stb, - input wire [31:0] i_wb_ext_rdt, - input wire i_wb_ext_ack); - - wire sig_en; - wire halt_en; - reg sim_ack; - - wire ext = (i_wb_cpu_adr[31:30] != 2'b00); - - assign o_wb_cpu_rdt = ext ? i_wb_ext_rdt : i_wb_mem_rdt; - assign o_wb_cpu_ack = i_wb_ext_ack | i_wb_mem_ack | sim_ack; - - assign o_wb_mem_adr = i_wb_cpu_adr; - assign o_wb_mem_dat = i_wb_cpu_dat; - assign o_wb_mem_sel = i_wb_cpu_sel; - assign o_wb_mem_we = i_wb_cpu_we; - assign o_wb_mem_stb = i_wb_cpu_stb & !ext & !(sig_en|halt_en); - - assign o_wb_ext_adr = i_wb_cpu_adr; - assign o_wb_ext_dat = i_wb_cpu_dat; - assign o_wb_ext_sel = i_wb_cpu_sel; - assign o_wb_ext_we = i_wb_cpu_we; - assign o_wb_ext_stb = i_wb_cpu_stb & ext & !(sig_en|halt_en); - - generate - if (sim) begin - - integer f = 0; - - assign sig_en = |f & i_wb_cpu_we & (i_wb_cpu_adr == sim_sig_adr); - assign halt_en = i_wb_cpu_we & (i_wb_cpu_adr == sim_halt_adr); - - reg [1023:0] signature_file; - - initial - /* verilator lint_off WIDTH */ - if ($value$plusargs("signature=%s", signature_file)) begin - $display("Writing signature to %0s", signature_file); - f = $fopen(signature_file, "w"); - end - /* verilator lint_on WIDTH */ - - always @(posedge i_clk) begin - sim_ack <= 1'b0; - if (i_wb_cpu_stb & !sim_ack) begin - sim_ack <= sig_en|halt_en; - if (sig_en & (f != 0)) - $fwrite(f, "%c", i_wb_cpu_dat[7:0]); - else if(halt_en) begin - $display("Test complete"); - $finish; - end - end - if (i_rst) - sim_ack <= 1'b0; - end - end else begin - assign sig_en = 1'b0; - assign halt_en = 1'b0; - initial sim_ack = 1'b0; - end - endgenerate - -endmodule diff --git a/servile/servile_rf_mem_if.v b/servile/servile_rf_mem_if.v deleted file mode 100644 index 5b44a91..0000000 --- a/servile/servile_rf_mem_if.v +++ /dev/null @@ -1,77 +0,0 @@ -/* - * servile_rf_mem_if.v : Arbiter to allow a shared SRAM for RF and memory accesses. RF is mapped to the highest 128 bytes of the memory. Requires 8-bit RF accesses. - * - * SPDX-FileCopyrightText: 2024 Olof Kindgren - * SPDX-License-Identifier: Apache-2.0 - */ - -`default_nettype none -module servile_rf_mem_if - #(//Memory parameters - parameter depth = 256, - //RF parameters - parameter rf_regs = 32, - //Internally calculated. Do not touch - parameter rf_depth = $clog2(rf_regs*4), - parameter aw = $clog2(depth)) - ( - input wire i_clk, - input wire i_rst, - input wire [rf_depth-1:0] i_waddr, - input wire [7:0] i_wdata, - input wire i_wen, - input wire [rf_depth-1:0] i_raddr, - output wire [7:0] o_rdata, - input wire i_ren, - - output wire [aw-1:0] o_sram_waddr, - output wire [7:0] o_sram_wdata, - output wire o_sram_wen, - output wire [aw-1:0] o_sram_raddr, - input wire [7:0] i_sram_rdata, - output wire o_sram_ren, - - input wire [aw-1:2] i_wb_adr, - input wire [31:0] i_wb_dat, - input wire [3:0] i_wb_sel, - input wire i_wb_we, - input wire i_wb_stb, - output wire [31:0] o_wb_rdt, - output reg o_wb_ack); - - reg [1:0] bsel; - - wire wb_en = i_wb_stb & !i_wen & !o_wb_ack; - - wire wb_we = i_wb_we & i_wb_sel[bsel]; - - wire [aw-1:0] rf_waddr = ~{{aw-rf_depth{1'b0}},i_waddr}; - wire [aw-1:0] rf_raddr = ~{{aw-rf_depth{1'b0}},i_raddr}; - - assign o_sram_waddr = wb_en ? {i_wb_adr[aw-1:2],bsel} : rf_waddr; - assign o_sram_wdata = wb_en ? i_wb_dat[bsel*8+:8] : i_wdata; - assign o_sram_wen = wb_en ? wb_we : i_wen; - assign o_sram_raddr = wb_en ? {i_wb_adr[aw-1:2],bsel} : rf_raddr; - assign o_sram_ren = wb_en ? !i_wb_we : i_ren; - - reg [23:0] wb_rdt; - assign o_wb_rdt = {i_sram_rdata, wb_rdt}; - - reg regzero; - always @(posedge i_clk) begin - - if (wb_en) bsel <= bsel + 2'd1; - o_wb_ack <= wb_en & &bsel; - if (bsel == 2'b01) wb_rdt[7:0] <= i_sram_rdata; - if (bsel == 2'b10) wb_rdt[15:8] <= i_sram_rdata; - if (bsel == 2'b11) wb_rdt[23:16] <= i_sram_rdata; - if (i_rst) begin - bsel <= 2'd0; - o_wb_ack <= 1'b0; - end - regzero <= &i_raddr[rf_depth-1:2]; - end - - assign o_rdata = regzero ? 8'd0 : i_sram_rdata; - -endmodule diff --git a/serving.core b/serving.core deleted file mode 100644 index f80f0b6..0000000 --- a/serving.core +++ /dev/null @@ -1,25 +0,0 @@ -CAPI=2: - -name : ::serving:1.3.0 -description: SERV-based subsystem for FPGAs - -filesets: - rtl: - files: - - serving/serving_ram.v - - serving/serving.v - file_type : verilogSource - depend : [servile] - -targets: - default: - filesets : [rtl] - - lint: - default_tool : verilator - description: Run static code checks (linting) - filesets : [rtl] - tools: - verilator: - mode : lint-only - toplevel : serving diff --git a/serving/serving.v b/serving/serving.v deleted file mode 100644 index 1a12054..0000000 --- a/serving/serving.v +++ /dev/null @@ -1,147 +0,0 @@ -/* serving.v : Top-level for the serving SoC - * - * ISC License - * - * Copyright (C) 2020 Olof Kindgren - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`default_nettype none -module serving - ( - input wire i_clk, - input wire i_rst, - input wire i_timer_irq, - - output wire [31:0] o_wb_adr, - output wire [31:0] o_wb_dat, - output wire [3:0] o_wb_sel, - output wire o_wb_we , - output wire o_wb_stb, - input wire [31:0] i_wb_rdt, - input wire i_wb_ack); - - parameter memfile = ""; - parameter memsize = 8192; - parameter sim = 1'b0; - parameter RESET_STRATEGY = "NONE"; - parameter WITH_CSR = 1; - localparam regs = 32+WITH_CSR*4; - - localparam rf_width = 8; - - wire [31:0] wb_mem_adr; - wire [31:0] wb_mem_dat; - wire [3:0] wb_mem_sel; - wire wb_mem_we; - wire wb_mem_stb; - wire [31:0] wb_mem_rdt; - wire wb_mem_ack; - - wire [6+WITH_CSR:0] rf_waddr; - wire [rf_width-1:0] rf_wdata; - wire rf_wen; - wire [6+WITH_CSR:0] rf_raddr; - wire [rf_width-1:0] rf_rdata; - wire rf_ren; - - wire [$clog2(memsize)-1:0] sram_waddr; - wire [rf_width-1:0] sram_wdata; - wire sram_wen; - wire [$clog2(memsize)-1:0] sram_raddr; - wire [rf_width-1:0] sram_rdata; - wire sram_ren; - - serving_ram - #(.memfile (memfile), - .depth (memsize)) - ram - (// Wishbone interface - .i_clk (i_clk), - .i_waddr (sram_waddr), - .i_wdata (sram_wdata), - .i_wen (sram_wen), - .i_raddr (sram_raddr), - .o_rdata (sram_rdata)/*, - .i_ren (rf_ren)*/); - - servile_rf_mem_if - #(.depth (memsize), - .rf_regs (regs)) - rf_mem_if - (// Wishbone interface - .i_clk (i_clk), - .i_rst (i_rst), - - .i_waddr (rf_waddr), - .i_wdata (rf_wdata), - .i_wen (rf_wen), - .i_raddr (rf_raddr), - .o_rdata (rf_rdata), - .i_ren (rf_ren), - - .o_sram_waddr (sram_waddr), - .o_sram_wdata (sram_wdata), - .o_sram_wen (sram_wen), - .o_sram_raddr (sram_raddr), - .i_sram_rdata (sram_rdata), - .o_sram_ren (sram_ren), - - .i_wb_adr (wb_mem_adr[$clog2(memsize)-1:2]), - .i_wb_stb (wb_mem_stb), - .i_wb_we (wb_mem_we) , - .i_wb_sel (wb_mem_sel), - .i_wb_dat (wb_mem_dat), - .o_wb_rdt (wb_mem_rdt), - .o_wb_ack (wb_mem_ack)); - - servile - #(.reset_pc (32'h0000_0000), - .reset_strategy (RESET_STRATEGY), - .rf_width (rf_width), - .sim (sim), - .with_csr (WITH_CSR)) - servile - ( - .i_clk (i_clk), - .i_rst (i_rst), - .i_timer_irq (i_timer_irq), - //Memory interface - .o_wb_mem_adr (wb_mem_adr), - .o_wb_mem_dat (wb_mem_dat), - .o_wb_mem_sel (wb_mem_sel), - .o_wb_mem_we (wb_mem_we), - .o_wb_mem_stb (wb_mem_stb), - .i_wb_mem_rdt (wb_mem_rdt), - .i_wb_mem_ack (wb_mem_ack), - - //Extension interface - .o_wb_ext_adr (o_wb_adr), - .o_wb_ext_dat (o_wb_dat), - .o_wb_ext_sel (o_wb_sel), - .o_wb_ext_we (o_wb_we), - .o_wb_ext_stb (o_wb_stb), - .i_wb_ext_rdt (i_wb_rdt), - .i_wb_ext_ack (i_wb_ack), - - //RF IF - .o_rf_waddr (rf_waddr), - .o_rf_wdata (rf_wdata), - .o_rf_wen (rf_wen), - .o_rf_raddr (rf_raddr), - .o_rf_ren (rf_ren), - .i_rf_rdata (rf_rdata)); - - -endmodule diff --git a/serving/serving_ram.v b/serving/serving_ram.v deleted file mode 100644 index a8017ce..0000000 --- a/serving/serving_ram.v +++ /dev/null @@ -1,45 +0,0 @@ -/* serving_ram.v : I/D SRAM for the serving SoC - * - * ISC License - * - * Copyright (C) 2020 Olof Kindgren - * - * Permission to use, copy, modify, and/or distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -`default_nettype none -module serving_ram - #(//Memory parameters - parameter depth = 256, - parameter aw = $clog2(depth), - parameter memfile = "") - (input wire i_clk, - input wire [aw-1:0] i_waddr, - input wire [7:0] i_wdata, - input wire i_wen, - input wire [aw-1:0] i_raddr, - output reg [7:0] o_rdata); - - reg [7:0] mem [0:depth-1] /* verilator public */; - - always @(posedge i_clk) begin - if (i_wen) mem[i_waddr] <= i_wdata; - o_rdata <= mem[i_raddr]; - end - - initial - if(|memfile) begin - $display("Preloading %m from %s", memfile); - $readmemh(memfile, mem); - end -endmodule diff --git a/sw/Makefile b/sw/Makefile index f82ddc6..15fb42e 100644 --- a/sw/Makefile +++ b/sw/Makefile @@ -1,11 +1,9 @@ -TOOLCHAIN_PREFIX?=riscv64-unknown-elf- - -%.elf: %.S link.ld - $(TOOLCHAIN_PREFIX)gcc -nostartfiles -nostdlib -march=rv32i_zicsr -mabi=ilp32 -Tlink.ld -o$@ $< +%.elf: %.S + riscv64-unknown-elf-gcc -nostartfiles -march=rv32i -mabi=ilp32 -Tlink.ld -o$@ $< %.bin: %.elf - $(TOOLCHAIN_PREFIX)objcopy -O binary $< $@ + riscv64-unknown-elf-objcopy -O binary $< $@ %.hex: %.bin - python3 makehex.py $< > $@ + python3 makehex.py $< 2048 > $@ clean: rm -f *.elf *.bin *.hex diff --git a/sw/blinky.S b/sw/blinky.S index 50a94dd..80bc620 100644 --- a/sw/blinky.S +++ b/sw/blinky.S @@ -29,8 +29,6 @@ _start: /* Set timer value to control blink speed */ li t1, DELAY - /* Clear t0 */ - addi t0, zero, 0 bl1: /* Write to LEDs */ sb t0, 0(a0) diff --git a/sw/blinky.hex b/sw/blinky.hex index 725cc19..b9847be 100644 --- a/sw/blinky.hex +++ b/sw/blinky.hex @@ -1,11 +1,2048 @@ 40000537 00050513 00100337 -00000293 00550023 -0012C293 -000073B3 +0012c293 +000073b3 00138393 -FE731EE3 -FEDFF06F -00000000 +fe731ee3 +fedff06f +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 +0 diff --git a/sw/hello_uart.S b/sw/hello_uart.S deleted file mode 100644 index 726f1ed..0000000 --- a/sw/hello_uart.S +++ /dev/null @@ -1,58 +0,0 @@ -#define GPIO_ADDR 0x40000000 -#define HALT_ADDR 0x90000000 - - /* - a0 = GPIO address - a1 = String address - t0 = Character to write - */ - -.globl _start -_start: - /* Load gpio address to a0 */ - li a0, GPIO_ADDR - - /* Set GPIO high initially */ - addi t0, zero, 1 - sb t0, 0(a0) - - /* Load string address to a1 */ - la a1, str - -next_char: - /* Read char from string */ - lbu t0, 0(a1) - - /* If zero, we reached end of string and will exit the simulation */ - beqz t0, halt - - /* Bitbanged UART loop */ - ori t0, t0, 0x100 - slli t0, t0, 1 -1: sb t0, 0(a0) - srli t0, t0, 1 - - /* - * Adding delay nops to achieve an approximate - * baud rate of 57600 at 16MHz - */ - nop - nop - bnez t0, 1b - - /* Increase address to next char in string */ - addi a1, a1, 1 - - j next_char - - /* Writing anything to HALT_ADDR will exit simulation */ -halt: li t0, HALT_ADDR - sw zero, 0(t0) - /* - * Loop to prevent PC from keep reading memory in case - * we run on real HW and not in simulation - */ - j halt -str: - .section .data - .string "Hi, I'm Servant!\n" diff --git a/sw/hello_uart.hex b/sw/hello_uart.hex deleted file mode 100644 index 6940815..0000000 --- a/sw/hello_uart.hex +++ /dev/null @@ -1,24 +0,0 @@ -40000537 -00100293 -00550023 -00000597 -04058593 -0005C283 -02028463 -1002E293 -00129293 -00550023 -0012D293 -00000013 -00000013 -FE0298E3 -00158593 -FD9FF06F -900002B7 -0002A023 -FF9FF06F -202C6948 -206D2749 -76726553 -21746E61 -0000000A diff --git a/sw/link.ld b/sw/link.ld index 3398348..db7be33 100644 --- a/sw/link.ld +++ b/sw/link.ld @@ -4,7 +4,15 @@ ENTRY(_start) SECTIONS { . = 0x00000000; + .text.init : { *(.text.init) } + . = ALIGN(0x1000); + .tohost : { *(.tohost) } + . = ALIGN(0x1000); .text : { *(.text) } + . = ALIGN(0x1000); .data : { *(.data) } + .data.string : { *(.data.string)} .bss : { *(.bss) } + _end = .; } + diff --git a/sw/makehex.py b/sw/makehex.py index 332b375..419b378 100644 --- a/sw/makehex.py +++ b/sw/makehex.py @@ -7,19 +7,21 @@ # binary, for any purpose, commercial or non-commercial, and by any # means. -import sys +from sys import argv + +binfile = argv[1] +nwords = int(argv[2]) + +with open(binfile, "rb") as f: + bindata = f.read() + +assert len(bindata) < 4*nwords +assert len(bindata) % 4 == 0 + +for i in range(nwords): + if i < len(bindata) // 4: + w = bindata[4*i : 4*i+4] + print("%02x%02x%02x%02x" % (w[3], w[2], w[1], w[0])) + else: + print("0") -with open(sys.argv[1], "rb") as f: - cnt = 3 - s = ["00"]*4 - while True: - data = f.read(1) - if not data: - print(''.join(s)) - exit(0) - s[cnt] = "{:02X}".format(data[0]) - if cnt == 0: - print(''.join(s)) - s = ["00"]*4 - cnt = 4 - cnt -= 1 diff --git a/verif/Readme.md b/verif/Readme.md deleted file mode 100644 index c7513b3..0000000 --- a/verif/Readme.md +++ /dev/null @@ -1,72 +0,0 @@ -# SERV Verification using RISCOF -SERV uses the [RISCOF](https://riscof.readthedocs.io/en/stable/index.html) which is python-based standard RISC-V Architectural Compliance Test Framework. This framework runs the Compliance tests in real-time on DUT and Reference and compare the signature results generated by both to decide if the tests are passed. -In our case, DUT is SERV core and reference is the [sail-riscv](https://github.com/riscv/sail-riscv), which is the golden model for the formal specification of RISC-V architecture. - - -## Prerequisites - -> :warning: Make sure to complete all the steps described in [Getting Started](/README.md). Once it's done, start setting up the following tools. - -- [RISC-V GCC Toolchain](https://github.com/riscv-collab/riscv-gnu-toolchain) - Install toolchain by running following command. - - sudo apt-get install -y gcc-riscv64-unknown-elf -> :bulb: By default, RISCOF plugins uses [RV32](https://github.com/riscv-collab/riscv-gnu-toolchain#:~:text=To%20build%20the%2032%2Dbit%20RV32GC%20toolchain%2C%20use%3A) toolchain for compiling native `rv32` code. For SERV, this dependency has been removed from the plugin as RV64 is sufficient for 32-bit systems as well. - -- [SAIL-RISCV](https://github.com/riscv/sail-riscv) - The reference model can be built by following [these](https://riscof.readthedocs.io/en/stable/installation.html#install-plugin-models) instructions. The pre-built binaries of sail-riscv is available in [`bin`](/verif/bin/) directory. Extract the tarball somewhere and add the directory containing `riscv_sim_RV32` to your PATH - -- [RISCOF](https://riscof.readthedocs.io/en/stable/installation.html#install-python) - If you have installed [Python](https://riscof.readthedocs.io/en/stable/installation.html#install-python), run the following command to [install RISCOF](https://riscof.readthedocs.io/en/stable/installation.html#). - - pip3 install riscof - -- [riscv-arch-tests](https://github.com/riscv-non-isa/riscv-arch-test) - Compliance tests are installed into the workspace by running: - - $ riscof arch-test --clone - -or alternatively - - $ riscof arch-test --update - -if the tests are already installed and just needs to be updated. - -> Make sure to have the directory structure that looks like this. - - - - . - | - ├── fusesoc.conf - ├── fusesoc_libraries - | ├── fusesoc_cores - | │   └── ... - | ├── mdu - | │   └── ... - | └── serv - | ├── ... - | ├── verif - | | ├── bin - | | | └── ... - | |   ├── config.ini - | |   ├── plugin-sail_cSim - | | | └── ... - | |   ├── plugin-serv - | | | └── ... - | └── ... - ├── riscv-arch-test - └── ... - -## Running Compliance tests -After completing all the steps in [Getting started](/README.md) followed by the [Prerequisites](#prerequisites), we are all set to run the compliance tests. - -:o: All the RISCOF commands will be run from the workspace - - riscof run --config=$SERV/verif/config.ini \ - --suite=riscv-arch-test/riscv-test-suite/rv32i_m/I \ - --env=riscv-arch-test/riscv-test-suite/env - -- `--config` - Configuration file is passed using this flag which contains the paths and the names of DUT and Reference plugins. -- `--suite` - The arch-tests are passed to RISCOF using this flag. In the above command, it points `I` test directory. We can change path to `M`, `C`, `privilege` or `Zifencei` directories to run the respective tests. -- `--env` - The header files of test framework are passed using this flag. - -> :bulb: Other optional arguments of RISCOF command can be found [here](https://riscof.readthedocs.io/en/stable/commands.html#run) - -When RISCOF run command successfully executed: an `html` report is generated which depicts the results of the tests. And a directory named `riscof_work` is created in the workspace which contains all the log files, signatures, executables for Reference model and/or DUT. \ No newline at end of file diff --git a/verif/bin/Readme.md b/verif/bin/Readme.md deleted file mode 100644 index fd40c39..0000000 --- a/verif/bin/Readme.md +++ /dev/null @@ -1,16 +0,0 @@ -# Pre-build SAIL RISC-V Model Binaries - -SAIL RISC-V is the Golden reference model simulator for the formal specification of the RISC-V Architecture. The binaries are build by following the [instructions](https://riscof.readthedocs.io/en/stable/installation.html#install-plugin-models) available in RISCOF documentation. - -These binaries are build for both 32-bit and 64-bit architecture: - -- `riscv_sim_RV32` -- `riscv_sim_RV64` - -> :warning: SAIL model binaries must be available in the `$PATH` variable. To do that: -- Extract `sail-riscv.tar.gz` using - - tar -xzf sail-riscv.tar.gz sail-riscv -- Binaries will be extracted in the directory named `sail-riscv`. Export the path of this directory to `$PATH` variable - - export PATH=/path/to/sail-riscv:$PATH \ No newline at end of file diff --git a/verif/bin/sail-riscv.tar.gz b/verif/bin/sail-riscv.tar.gz deleted file mode 100644 index b6418b9..0000000 Binary files a/verif/bin/sail-riscv.tar.gz and /dev/null differ diff --git a/verif/config.ini b/verif/config.ini deleted file mode 100644 index 176c80b..0000000 --- a/verif/config.ini +++ /dev/null @@ -1,14 +0,0 @@ -[RISCOF] -ReferencePlugin=sail_cSim -ReferencePluginPath=plugin-sail_cSim -DUTPlugin=serv -DUTPluginPath=plugin-serv - -[serv] -pluginpath=plugin-serv -ispec=plugin-serv/serv_isa.yaml -pspec=plugin-serv/serv_platform.yaml -target_run=1 - -[sail_cSim] -pluginpath=plugin-sail_cSim diff --git a/verif/plugin-sail_cSim/env/model_test.h b/verif/plugin-sail_cSim/env/model_test.h deleted file mode 100644 index 3c86dd5..0000000 --- a/verif/plugin-sail_cSim/env/model_test.h +++ /dev/null @@ -1,55 +0,0 @@ -#ifndef _COMPLIANCE_MODEL_H -#define _COMPLIANCE_MODEL_H - -#define RVMODEL_DATA_SECTION \ - .pushsection .tohost,"aw",@progbits; \ - .align 8; .global tohost; tohost: .dword 0; \ - .align 8; .global fromhost; fromhost: .dword 0; \ - .popsection; \ - .align 8; .global begin_regstate; begin_regstate: \ - .word 128; \ - .align 8; .global end_regstate; end_regstate: \ - .word 4; - -//RV_COMPLIANCE_HALT -#define RVMODEL_HALT \ - li x1, 1; \ - write_tohost: \ - sw x1, tohost, t5; \ - j write_tohost; - -#define RVMODEL_BOOT - -//RV_COMPLIANCE_DATA_BEGIN -#define RVMODEL_DATA_BEGIN \ - RVMODEL_DATA_SECTION \ - .align 4;\ - .global begin_signature; begin_signature: - -//RV_COMPLIANCE_DATA_END -#define RVMODEL_DATA_END \ - .align 4; .global end_signature; end_signature: - -//RVTEST_IO_INIT -#define RVMODEL_IO_INIT -//RVTEST_IO_WRITE_STR -#define RVMODEL_IO_WRITE_STR(_R, _STR) -//RVTEST_IO_CHECK -#define RVMODEL_IO_CHECK() -//RVTEST_IO_ASSERT_GPR_EQ -#define RVMODEL_IO_ASSERT_GPR_EQ(_S, _R, _I) -//RVTEST_IO_ASSERT_SFPR_EQ -#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) -//RVTEST_IO_ASSERT_DFPR_EQ -#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) - -#define RVMODEL_SET_MSW_INT - -#define RVMODEL_CLEAR_MSW_INT - -#define RVMODEL_CLEAR_MTIMER_INT - -#define RVMODEL_CLEAR_MEXT_INT - - -#endif // _COMPLIANCE_MODEL_H diff --git a/verif/plugin-sail_cSim/riscof_sail_cSim.py b/verif/plugin-sail_cSim/riscof_sail_cSim.py deleted file mode 100644 index ff9a4ce..0000000 --- a/verif/plugin-sail_cSim/riscof_sail_cSim.py +++ /dev/null @@ -1,109 +0,0 @@ -import os -import shutil -import logging - -import riscof.utils as utils -from riscof.pluginTemplate import pluginTemplate - -logger = logging.getLogger() - -class sail_cSim(pluginTemplate): - __model__ = "sail_c_simulator" - __version__ = "0.5.0" - - def __init__(self, *args, **kwargs): - sclass = super().__init__(*args, **kwargs) - config = kwargs.get('config') - if config is None: - logger.error("Config node for sail_cSim missing.") - raise SystemExit(1) - config_dir = kwargs.get('config_dir') - self.num_jobs = str(config['jobs'] if 'jobs' in config else 1) - self.pluginpath = os.path.join(config_dir, config['pluginpath']) - self.sail_exe = { '32' : os.path.join(config['PATH'] if 'PATH' in config else "","riscv_sim_RV32"), - '64' : os.path.join(config['PATH'] if 'PATH' in config else "","riscv_sim_RV64")} - self.isa_spec = os.path.abspath(config['ispec']) if 'ispec' in config else '' - self.platform_spec = os.path.abspath(config['pspec']) if 'ispec' in config else '' - self.make = config['make'] if 'make' in config else 'make' - logger.debug("SAIL CSim plugin initialised using the following configuration.") - for entry in config: - logger.debug(entry+' : '+config[entry]) - return sclass - - def initialise(self, suite, work_dir, archtest_env): - self.suite = suite - self.work_dir = work_dir - self.objdump_cmd = 'riscv64-unknown-elf-objdump -D {0} > {1}.disass;' - self.compile_cmd = 'riscv64-unknown-elf-gcc -march={0} \ - -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles\ - -T '+self.pluginpath+'/env/link.ld\ - -I '+self.pluginpath+'/env/\ - -I ' + archtest_env - - def build(self, isa_yaml, platform_yaml): - ispec = utils.load_yaml(isa_yaml)['hart0'] - self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') - self.isa = 'rv' + self.xlen - self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') - if "I" in ispec["ISA"]: - self.isa += 'i' - if "M" in ispec["ISA"]: - self.isa += 'm' - if "C" in ispec["ISA"]: - self.isa += 'c' - if "F" in ispec["ISA"]: - self.isa += 'f' - if "D" in ispec["ISA"]: - self.isa += 'd' - objdump = "riscv64-unknown-elf-objdump".format(self.xlen) - if shutil.which(objdump) is None: - logger.error(objdump+": executable not found. Please check environment setup.") - raise SystemExit(1) - compiler = "riscv64-unknown-elf-gcc".format(self.xlen) - if shutil.which(compiler) is None: - logger.error(compiler+": executable not found. Please check environment setup.") - raise SystemExit(1) - if shutil.which(self.sail_exe[self.xlen]) is None: - logger.error(self.sail_exe[self.xlen]+ ": executable not found. Please check environment setup.") - raise SystemExit(1) - if shutil.which(self.make) is None: - logger.error(self.make+": executable not found. Please check environment setup.") - raise SystemExit(1) - - def runTests(self, testList, cgf_file=None): - if os.path.exists(self.work_dir+ "/Makefile." + self.name[:-1]): - os.remove(self.work_dir+ "/Makefile." + self.name[:-1]) - make = utils.makeUtil(makefilePath=os.path.join(self.work_dir, "Makefile." + self.name[:-1])) - make.makeCommand = self.make + ' -j' + self.num_jobs - for file in testList: - testentry = testList[file] - test = testentry['test_path'] - test_dir = testentry['work_dir'] - file_name = 'sail-{0}'.format(test.rsplit('/',1)[1][:-2]) - elf = '{0}.elf'.format(file_name) - - execute = "@cd "+testentry['work_dir']+";" - cmd = self.compile_cmd.format(testentry['isa'].lower()) + ' ' + test + ' -o ' + elf - compile_cmd = cmd + ' -D' + " -D".join(testentry['macros']) - execute+=compile_cmd+";" - execute += self.objdump_cmd.format(elf, file_name) - sig_file = os.path.join(test_dir, self.name[:-1] + ".signature") - execute += self.sail_exe[self.xlen] + ' --test-signature={0} {1} > {2}.log 2>&1;'.format(sig_file, elf, file_name) - - cov_str = ' ' - for label in testentry['coverage_labels']: - cov_str+=' -l '+label - - if cgf_file is not None: - coverage_cmd = 'riscv_isac --verbose info coverage -d \ - -t {0}.log --parser-name c_sail -o coverage.rpt \ - --sig-label begin_signature end_signature \ - --test-label rvtest_code_begin rvtest_code_end \ - -e ref.elf -c {1} -x{2} {3};'.format(\ - file_name, ' -c '.join(cgf_file), self.xlen, cov_str) - else: - coverage_cmd = '' - execute+=coverage_cmd - - make.add_target(execute) - make.execute_all(self.work_dir) diff --git a/verif/plugin-serv/env/link.ld b/verif/plugin-serv/env/link.ld deleted file mode 100644 index 0225e89..0000000 --- a/verif/plugin-serv/env/link.ld +++ /dev/null @@ -1,15 +0,0 @@ -OUTPUT_ARCH( "riscv" ) -ENTRY(rvtest_entry_point) - -SECTIONS -{ - . = 0x00000000; - .text.init : { *(.text.init) } - .tohost : { *(.tohost) } - .text : { *(.text) } - .data : { *(.data) } - .data.string : { *(.data.string)} - .bss : { *(.bss) } - _end = .; -} - diff --git a/verif/plugin-serv/env/model_test.h b/verif/plugin-serv/env/model_test.h deleted file mode 100644 index f7ffdf1..0000000 --- a/verif/plugin-serv/env/model_test.h +++ /dev/null @@ -1,66 +0,0 @@ -#ifndef _COMPLIANCE_MODEL_H -#define _COMPLIANCE_MODEL_H - -#define RVMODEL_HALT \ - la a0, begin_signature; \ - la a1, end_signature; \ - li a2, 0x80000000; \ - compliance_halt_loop: \ - beq a0, a1, compliance_halt_break; \ - addi a3, a0, 4; \ - compliance_halt_loop2: \ - addi a3, a3, -1; \ - \ - lb a4, 0 (a3); \ - srai a5, a4, 4; \ - andi a5, a5, 0xF; \ - li a6, 10; \ - blt a5, a6, notLetter; \ - addi a5, a5, 39; \ - notLetter: \ - addi a5, a5, 0x30; \ - sw a5, 0 (a2); \ - \ - srai a5, a4, 0; \ - andi a5, a5, 0xF; \ - li a6, 10; \ - blt a5, a6, notLetter2; \ - addi a5, a5, 39; \ - notLetter2: \ - addi a5, a5, 0x30; \ - sw a5, 0 (a2); \ - bne a0, a3,compliance_halt_loop2; \ - addi a0, a0, 4; \ - \ - li a4, '\n'; \ - sw a4, 0 (a2); \ - j compliance_halt_loop; \ - j compliance_halt_break; \ - compliance_halt_break:; \ - lui a0,0x90000000>>12; \ - sw a3,0(a0); - - -#define RVMODEL_DATA_BEGIN \ - .align 4; .global begin_signature; begin_signature: \ - -#define RVMODEL_DATA_END \ - .align 4; .global end_signature; end_signature: \ - - -#define RVMODEL_BOOT - -#define LOCAL_IO_WRITE_STR(_STR) RVMODEL_IO_WRITE_STR(x31, _STR) -#define RVMODEL_IO_WRITE_STR(_SP, _STR) -#define LOCAL_IO_PUSH(_SP) -#define LOCAL_IO_POP(_SP) -#define RVMODEL_IO_ASSERT_GPR_EQ(_SP, _R, _I) -#define RVMODEL_IO_ASSERT_SFPR_EQ(_F, _R, _I) -#define RVMODEL_IO_ASSERT_DFPR_EQ(_D, _R, _I) - -#define RVMODEL_SET_MSW_INT -#define RVMODEL_CLEAR_MSW_INT -#define RVMODEL_CLEAR_MTIMER_INT -#define RVMODEL_CLEAR_MEXT_INT - -#endif // _COMPLIANCE_MODEL_H diff --git a/verif/plugin-serv/riscof_serv.py b/verif/plugin-serv/riscof_serv.py deleted file mode 100644 index 938b27c..0000000 --- a/verif/plugin-serv/riscof_serv.py +++ /dev/null @@ -1,106 +0,0 @@ -import os -import logging - -import riscof.utils as utils -from riscof.pluginTemplate import pluginTemplate - -logger = logging.getLogger() - -class serv(pluginTemplate): - __model__ = "serv" - __version__ = "1.3.0" - - def __init__(self, *args, **kwargs): - sclass = super().__init__(*args, **kwargs) - config = kwargs.get('config') - config_dir = kwargs.get('config_dir') - if config is None: - print("Please enter input file paths in configuration.") - raise SystemExit(1) - self.pluginpath=os.path.join(config_dir, config['pluginpath']) - self.isa_spec = os.path.join(config_dir, config['ispec']) - self.platform_spec = os.path.join(config_dir, config['pspec']) - if 'target_run' in config and config['target_run']=='0': - self.target_run = False - else: - self.target_run = True - return sclass - - def initialise(self, suite, work_dir, archtest_env): - self.work_dir = work_dir - self.suite_dir = suite - self.compile_cmd = 'riscv64-unknown-elf-gcc -march={0} \ - -static -mcmodel=medany -fvisibility=hidden -nostdlib -nostartfiles -g\ - -T '+self.pluginpath+'/env/link.ld\ - -I '+self.pluginpath+'/env/\ - -I ' + archtest_env + ' {1} -o {2} {3}' - - add_mdu = 'fusesoc library add mdu https://github.com/zeeshanrafique23/mdu' - utils.shellCommand(add_mdu).run() - - build_serv = 'fusesoc run --target=verilator_tb --flag=mdu\ - --build --build-root=servant_test servant\ - --memsize=8388608 --compressed=1' - utils.shellCommand(build_serv).run() - - def build(self, isa_yaml, platform_yaml): - ispec = utils.load_yaml(isa_yaml)['hart0'] - self.xlen = ('64' if 64 in ispec['supported_xlen'] else '32') - self.isa = 'rv' + self.xlen - if "I" in ispec["ISA"]: - self.isa += 'i' - if "M" in ispec["ISA"]: - self.isa += 'm' - if "C" in ispec["ISA"]: - self.isa += 'c' - self.compile_cmd = self.compile_cmd+' -mabi='+('lp64 ' if 64 in ispec['supported_xlen'] else 'ilp32 ') - - def runTests(self, testList): - for testentry in testList.values(): - test = testentry['test_path'] - test_dir = testentry['work_dir'] - file_name = os.path.basename(test)[:-2] - - elf = file_name+'.elf' - compile_macros= ' -D' + " -D".join(testentry['macros']) - marchstr = testentry['isa'].lower() - - compile_run = self.compile_cmd.format(marchstr, test, elf, compile_macros) - utils.shellCommand(compile_run).run(cwd=test_dir) - - objcopy_run = f'riscv64-unknown-elf-objcopy -O binary {elf} {file_name}.bin' - utils.shellCommand(objcopy_run).run(cwd=test_dir) - - self.makehex(f"{test_dir}/{file_name}.bin", f"{test_dir}/{file_name}.hex") - - #The behavior of --build-root in FuseSoC has changed since version 2.2.1 - #Check first for executable model in the new location and else fall back - #to the old one - exe = 'servant_test/verilator_tb/Vservant_sim' - if not os.path.exists(exe): - exe = 'servant_test/servant_1.3.0/verilator_tb/Vservant_sim' - - sigdump_run = [exe, - "+timeout=1000000000", - f"+signature={test_dir}/DUT-serv.signature", - f"+firmware={test_dir}/{file_name}.hex"] - - utils.shellCommand(' '.join(sigdump_run)).run() - if not self.target_run: - raise SystemExit - - def makehex(self, binfile, hexfile): - with open(binfile, "rb") as f, open(hexfile, "w") as fout: - cnt = 3 - s = ["00"]*4 - while True: - data = f.read(1) - if not data: - fout.write(''.join(s)+'\n') - return - s[cnt] = "{:02X}".format(data[0]) - if cnt == 0: - fout.write(''.join(s)+'\n') - s = ["00"]*4 - cnt = 4 - cnt -= 1 diff --git a/verif/plugin-serv/serv_isa.yaml b/verif/plugin-serv/serv_isa.yaml deleted file mode 100644 index fe8f8b1..0000000 --- a/verif/plugin-serv/serv_isa.yaml +++ /dev/null @@ -1,29 +0,0 @@ -hart_ids: [0] -hart0: - ISA: RV32IMCZicsr_Zifencei - physical_addr_sz: 32 - User_Spec_Version: '2.3' - supported_xlen: [32] - misa: - reset-val: 0x40001104 - rv32: - accessible: true - mxl: - implemented: true - type: - warl: - dependency_fields: [] - legal: - - mxl[1:0] in [0x1] - wr_illegal: - - Unchanged - extensions: - implemented: true - type: - warl: - dependency_fields: [] - legal: - - extensions[25:0] bitmask [0x0001104, 0x0000000] - wr_illegal: - - Unchanged - diff --git a/verif/plugin-serv/serv_platform.yaml b/verif/plugin-serv/serv_platform.yaml deleted file mode 100644 index 4b99ed9..0000000 --- a/verif/plugin-serv/serv_platform.yaml +++ /dev/null @@ -1,4 +0,0 @@ -nmi: - label: nmi_vector -reset: - label: reset_vector diff --git a/west.yml b/west.yml deleted file mode 100644 index f76966f..0000000 --- a/west.yml +++ /dev/null @@ -1,9 +0,0 @@ -manifest: - remotes: - - name: zephyrproject-rtos - url-base: https://github.com/zephyrproject-rtos - projects: - - name: zephyr - remote: zephyrproject-rtos - revision: v4.0.0 - import: true diff --git a/zephyr b/zephyr new file mode 160000 index 0000000..a690d52 --- /dev/null +++ b/zephyr @@ -0,0 +1 @@ +Subproject commit a690d52fa69f812924aa38f20c45f707c64fa16f diff --git a/zephyr/CMakeLists.txt b/zephyr/CMakeLists.txt deleted file mode 100644 index 359918e..0000000 --- a/zephyr/CMakeLists.txt +++ /dev/null @@ -1,4 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -add_subdirectory(drivers) diff --git a/zephyr/Kconfig b/zephyr/Kconfig deleted file mode 100644 index b4e2f3b..0000000 --- a/zephyr/Kconfig +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -menu "SweRVolf" - -rsource "drivers/Kconfig" - -endmenu diff --git a/zephyr/boards/riscv/service/Kconfig.board b/zephyr/boards/riscv/service/Kconfig.board deleted file mode 100644 index 87eff30..0000000 --- a/zephyr/boards/riscv/service/Kconfig.board +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# -# SPDX-License-Identifier: Apache-2.0 - -config BOARD_SERVICE - bool "servant SoC for iCE40" - depends on SOC_RISCV32_SERVANT diff --git a/zephyr/boards/riscv/service/Kconfig.defconfig b/zephyr/boards/riscv/service/Kconfig.defconfig deleted file mode 100644 index b0eb0e9..0000000 --- a/zephyr/boards/riscv/service/Kconfig.defconfig +++ /dev/null @@ -1,7 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# -# SPDX-License-Identifier: Apache-2.0 - -config BOARD - default "service" - depends on BOARD_SERVICE diff --git a/zephyr/boards/riscv/service/board.h b/zephyr/boards/riscv/service/board.h deleted file mode 100644 index a0822eb..0000000 --- a/zephyr/boards/riscv/service/board.h +++ /dev/null @@ -1,12 +0,0 @@ -/* - * Copyright (c) 2020 Olof Kindgren - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __INC_BOARD_H -#define __INC_BOARD_H - -#include - -#endif /* __INC_BOARD_H */ diff --git a/zephyr/boards/riscv/service/service.dts b/zephyr/boards/riscv/service/service.dts deleted file mode 100644 index 34dcde3..0000000 --- a/zephyr/boards/riscv/service/service.dts +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright (c) 2020 Olof Kindgren - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/dts-v1/; - -#include - -/ { - chosen { - zephyr,sram = &ram; - zephyr,console = &uart0; - }; - - ram: memory@0 { - compatible = "mmio-sram"; - reg = <0x0 0x8000>; - }; - - soc { - compatible = "olofk,serv"; - #address-cells = <1>; - #size-cells = <1>; - - uart0: serial@0 { - reg = <0x0 0x1>; - compatible = "olofk,serial"; - }; - }; -}; - diff --git a/zephyr/boards/riscv/service/service.yaml b/zephyr/boards/riscv/service/service.yaml deleted file mode 100644 index e5cd539..0000000 --- a/zephyr/boards/riscv/service/service.yaml +++ /dev/null @@ -1,16 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# -# SPDX-License-Identifier: Apache-2.0 - -identifier: service -name: servant SoC for iCE40 -type: mcu -arch: riscv32 -toolchain: - - zephyr -ram: 32 -vendor: olofk -testing: - ignore_tags: - - net - - bluetooth diff --git a/zephyr/boards/riscv/service/service_defconfig b/zephyr/boards/riscv/service/service_defconfig deleted file mode 100644 index a38551c..0000000 --- a/zephyr/boards/riscv/service/service_defconfig +++ /dev/null @@ -1,12 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# -# SPDX-License-Identifier: Apache-2.0 - -CONFIG_BOARD_SERVICE=y -CONFIG_CONSOLE=y -CONFIG_SERIAL=y -CONFIG_UART_BITBANG=y - -CONFIG_UART_CONSOLE=y - -CONFIG_XIP=n diff --git a/zephyr/drivers/CMakeLists.txt b/zephyr/drivers/CMakeLists.txt deleted file mode 100644 index 0ba409a..0000000 --- a/zephyr/drivers/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -add_subdirectory_ifdef(CONFIG_SERIAL_HAS_DRIVER serial) -add_subdirectory_ifdef(CONFIG_SYS_CLOCK_EXISTS timer) - diff --git a/zephyr/drivers/Kconfig b/zephyr/drivers/Kconfig deleted file mode 100644 index b46ef2f..0000000 --- a/zephyr/drivers/Kconfig +++ /dev/null @@ -1,10 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -menu "Device Drivers" - -rsource "serial/Kconfig" - -rsource "timer/Kconfig" - -endmenu diff --git a/zephyr/drivers/serial/CMakeLists.txt b/zephyr/drivers/serial/CMakeLists.txt deleted file mode 100644 index 1fd55b0..0000000 --- a/zephyr/drivers/serial/CMakeLists.txt +++ /dev/null @@ -1,6 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -set(ZEPHYR_CURRENT_LIBRARY drivers__serial) - -zephyr_library_sources_ifdef(CONFIG_UART_BITBANG uart_bitbang.c) diff --git a/zephyr/drivers/serial/Kconfig b/zephyr/drivers/serial/Kconfig deleted file mode 100644 index 39a1388..0000000 --- a/zephyr/drivers/serial/Kconfig +++ /dev/null @@ -1,13 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -if SERIAL - -menuconfig UART_BITBANG - bool "SERV bitbang serial driver" - select SERIAL_HAS_DRIVER - help - Enables the SERV bitbang serial driver. - Hardcoded to send at ~57600 baud rate with a 16MHz clock - -endif diff --git a/zephyr/drivers/serial/uart_bitbang.c b/zephyr/drivers/serial/uart_bitbang.c deleted file mode 100644 index 927b3a0..0000000 --- a/zephyr/drivers/serial/uart_bitbang.c +++ /dev/null @@ -1,78 +0,0 @@ -/* - * Copyright (c) 2020 Olof Kindgren - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include -#include -#include -#include -#include - -#define DT_DRV_COMPAT olofk_serial - -#define reg_uart_data (*(volatile uint32_t*)UART_BITBANG_BASE) - -static struct k_spinlock lock; - -static void uart_bitbang_poll_out(const struct device *dev, unsigned char c) -{ - ARG_UNUSED(dev); - - k_spinlock_key_t key = k_spin_lock(&lock); - - int cout = (c|0x100) << 1; - do { - reg_uart_data = cout; - cout >>= 1; - __asm__ __volatile__ ("nop"); - __asm__ __volatile__ ("nop"); - } while (cout); - - k_spin_unlock(&lock, key); -} - -static int uart_bitbang_poll_in(const struct device *dev, unsigned char *c) -{ - ARG_UNUSED(dev); - - *c = reg_uart_data; - return 0; -} - -static int uart_bitbang_init(const struct device *dev) -{ - ARG_UNUSED(dev); - reg_uart_data = 1; - return 0; -} - -static const struct uart_driver_api uart_bitbang_driver_api = { - .poll_in = uart_bitbang_poll_in, - .poll_out = uart_bitbang_poll_out, - .err_check = NULL, -}; - -struct my_dev_data { - -}; - -struct my_dev_cfg { - -}; - -#define CREATE_MY_DEVICE(inst) \ - static struct my_dev_data my_data_##inst = { \ - }; \ - static const struct my_dev_cfg my_cfg_##inst = { \ - }; \ - DEVICE_DT_INST_DEFINE(inst, \ - uart_bitbang_init, \ - NULL, \ - &my_data_##inst, \ - &my_cfg_##inst, \ - PRE_KERNEL_1, CONFIG_SERIAL_INIT_PRIORITY, \ - &uart_bitbang_driver_api); - -DT_INST_FOREACH_STATUS_OKAY(CREATE_MY_DEVICE) diff --git a/zephyr/drivers/timer/CMakeLists.txt b/zephyr/drivers/timer/CMakeLists.txt deleted file mode 100644 index 0a14e26..0000000 --- a/zephyr/drivers/timer/CMakeLists.txt +++ /dev/null @@ -1,5 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -zephyr_library_sources_ifdef(CONFIG_SERV_TIMER serv_timer.c) - diff --git a/zephyr/drivers/timer/Kconfig b/zephyr/drivers/timer/Kconfig deleted file mode 100644 index 24b9356..0000000 --- a/zephyr/drivers/timer/Kconfig +++ /dev/null @@ -1,9 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -config SERV_TIMER - bool "SERV Timer" - select TICKLESS_CAPABLE - help - This module implements a kernel device driver for the SERV - timer driver. It provides the standard "system clock driver" interfaces. diff --git a/zephyr/drivers/timer/serv_timer.c b/zephyr/drivers/timer/serv_timer.c deleted file mode 100644 index d48b771..0000000 --- a/zephyr/drivers/timer/serv_timer.c +++ /dev/null @@ -1,128 +0,0 @@ -/* - * Copyright (c) 2020 Olof Kindgren - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - This is basically a 32-bit version of riscv_machine_timer.c for Zephyr -*/ -#include -#include -#include -#include -#include - -#define CYC_PER_TICK ((uint32_t)((uint32_t)sys_clock_hw_cycles_per_sec() \ - / (uint32_t)CONFIG_SYS_CLOCK_TICKS_PER_SEC)) -#define MAX_CYC 0xffffffffu -#define MAX_TICKS ((MAX_CYC - CYC_PER_TICK) / CYC_PER_TICK) -#define MIN_DELAY 1000 - -#define TICKLESS IS_ENABLED(CONFIG_TICKLESS_KERNEL) - -static struct k_spinlock lock; -static uint32_t last_count; - -static ALWAYS_INLINE void set_mtimecmp(uint32_t time) -{ - sys_write32(time, SERV_TIMER_BASE); -} - -static ALWAYS_INLINE uint32_t mtime(void) -{ - return sys_read32(SERV_TIMER_BASE); -} - -static void timer_isr(void *arg) -{ - ARG_UNUSED(arg); - - k_spinlock_key_t key = k_spin_lock(&lock); - uint32_t now = mtime(); - uint32_t dticks = ((now - last_count) / CYC_PER_TICK); - - last_count += dticks * CYC_PER_TICK; - - if (!TICKLESS) { - uint32_t next = last_count + CYC_PER_TICK; - - if ((int32_t)(next - now) < MIN_DELAY) { - next += CYC_PER_TICK; - } - set_mtimecmp(next); - } - - k_spin_unlock(&lock, key); - sys_clock_announce(IS_ENABLED(CONFIG_TICKLESS_KERNEL) ? dticks : 1); -} - -int sys_clock_driver_init() -{ - IRQ_CONNECT(RISCV_MACHINE_TIMER_IRQ, 0, timer_isr, NULL, 0); - last_count = mtime(); - set_mtimecmp(last_count + (uint32_t)CYC_PER_TICK); - irq_enable(RISCV_MACHINE_TIMER_IRQ); - return 0; -} - -void sys_clock_set_timeout(int32_t ticks, bool idle) -{ - ARG_UNUSED(idle); - -#if defined(CONFIG_TICKLESS_KERNEL) - /* RISCV has no idle handler yet, so if we try to spin on the - * logic below to reset the comparator, we'll always bump it - * forward to the "next tick" due to MIN_DELAY handling and - * the interrupt will never fire! Just rely on the fact that - * the OS gave us the proper timeout already. - */ - if (idle) { - return; - } - - ticks = ticks == K_TICKS_FOREVER ? MAX_TICKS : ticks; - ticks = MAX(MIN(ticks - 1, (int32_t)MAX_TICKS), 0); - - k_spinlock_key_t key = k_spin_lock(&lock); - uint32_t now = mtime(); - uint32_t adj, cyc = ticks * CYC_PER_TICK; - - /* Round up to next tick boundary. */ - adj = (now - last_count) + (CYC_PER_TICK - 1); - if (cyc <= MAX_CYC - adj) { - cyc += adj; - } else { - cyc = MAX_CYC; - } - cyc = (cyc / CYC_PER_TICK) * CYC_PER_TICK; - - if ((int32_t)(cyc + last_count - now) < MIN_DELAY) { - cyc += CYC_PER_TICK; - } - - set_mtimecmp(cyc + last_count); - k_spin_unlock(&lock, key); -#endif -} - -uint32_t sys_clock_elapsed(void) -{ - if (!IS_ENABLED(CONFIG_TICKLESS_KERNEL)) { - return 0; - } - - k_spinlock_key_t key = k_spin_lock(&lock); - uint32_t ret = (mtime() - last_count) / CYC_PER_TICK; - - k_spin_unlock(&lock, key); - return ret; -} - -uint32_t sys_timer_cycle_get_32(void) -{ - return mtime(); -} - -SYS_INIT(sys_clock_driver_init, PRE_KERNEL_2, - CONFIG_SYSTEM_CLOCK_INIT_PRIORITY); diff --git a/zephyr/dts/riscv/serv.dtsi b/zephyr/dts/riscv/serv.dtsi deleted file mode 100644 index f33dc7a..0000000 --- a/zephyr/dts/riscv/serv.dtsi +++ /dev/null @@ -1,23 +0,0 @@ -/* - * Copyright (c) 2020 Olof Kindgren - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/ { - #address-cells = <1>; - #size-cells = <1>; - compatible = "olofk,servant"; - - cpus { - #address-cells = <1>; - #size-cells = <0>; - - cpu0: cpu@0 { - compatible = "olofk,serv"; - riscv,isa = "rv32i_zicsr"; - reg = <0>; - device_type = "cpu"; - }; - }; -}; diff --git a/zephyr/module.yml b/zephyr/module.yml deleted file mode 100644 index 07da43f..0000000 --- a/zephyr/module.yml +++ /dev/null @@ -1,5 +0,0 @@ -build: - settings: - board_root: zephyr - dts_root: zephyr - soc_root: zephyr diff --git a/zephyr/soc/riscv/servant/CMakeLists.txt b/zephyr/soc/riscv/servant/CMakeLists.txt deleted file mode 100644 index aee4e42..0000000 --- a/zephyr/soc/riscv/servant/CMakeLists.txt +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -zephyr_sources( - soc_irq.S - vector.S - cpu_idle.c - irq.c) diff --git a/zephyr/soc/riscv/servant/Kconfig.defconfig b/zephyr/soc/riscv/servant/Kconfig.defconfig deleted file mode 100644 index 607f6ff..0000000 --- a/zephyr/soc/riscv/servant/Kconfig.defconfig +++ /dev/null @@ -1,38 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -if SOC_RISCV32_SERVANT - -config SOC - string - default "servant" - -config SYS_CLOCK_HW_CYCLES_PER_SEC - int - default 16000000 - -config RISCV_SOC_INTERRUPT_INIT - bool - default y - -config NUM_IRQS - int - default 8 - -config SERV_TIMER - bool - default y - -config ARCH_HAS_CUSTOM_CPU_IDLE - bool - default y - -config ARCH_HAS_CUSTOM_CPU_ATOMIC_IDLE - bool - default y - -config RISCV_SOC_EXCEPTION_FROM_IRQ - bool - default y - -endif # SOC_RISCV32_SERVANT diff --git a/zephyr/soc/riscv/servant/Kconfig.soc b/zephyr/soc/riscv/servant/Kconfig.soc deleted file mode 100644 index 932055c..0000000 --- a/zephyr/soc/riscv/servant/Kconfig.soc +++ /dev/null @@ -1,8 +0,0 @@ -# Copyright (c) 2020 Olof Kindgren -# SPDX-License-Identifier: Apache-2.0 - -config SOC_RISCV32_SERVANT - bool "servant SoC" - select RISCV - select ATOMIC_OPERATIONS_C - select RISCV_ISA_EXT_ZICSR diff --git a/zephyr/soc/riscv/servant/cpu_idle.c b/zephyr/soc/riscv/servant/cpu_idle.c deleted file mode 100644 index dc318c6..0000000 --- a/zephyr/soc/riscv/servant/cpu_idle.c +++ /dev/null @@ -1,22 +0,0 @@ -#include -#include - -// Override arch_cpu_idle() and arch_cpu_atomic_idle() to prevent insertion -// of `wfi` instructions, which lock up our system. This was introduced in -// Zephyr 3.6.0 with commit 5fb6e267f629dedb8382da6bcad8018b1bb8930a. -// -// This is probably a hardware bug in SERV. This issue is tracked as #131. -// https://github.com/olofk/serv/issues/131 - -void arch_cpu_idle(void) -{ - sys_trace_idle(); - irq_unlock(MSTATUS_IEN); -} - -void arch_cpu_atomic_idle(unsigned int key) -{ - sys_trace_idle(); - irq_unlock(key); -} - diff --git a/zephyr/soc/riscv/servant/irq.c b/zephyr/soc/riscv/servant/irq.c deleted file mode 100644 index 61a343f..0000000 --- a/zephyr/soc/riscv/servant/irq.c +++ /dev/null @@ -1,58 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file - * @brief interrupt management code for riscv SOCs supporting the riscv - privileged architecture specification - */ -#include - -void arch_irq_enable(unsigned int irq) -{ - uint32_t mie; - - /* - * CSR mie register is updated using atomic instruction csrrs - * (atomic read and set bits in CSR register) - */ - __asm__ volatile ("csrrs %0, mie, %1\n" - : "=r" (mie) - : "r" (1 << irq)); -} - -void arch_irq_disable(unsigned int irq) -{ - uint32_t mie; - - /* - * Use atomic instruction csrrc to disable device interrupt in mie CSR. - * (atomic read and clear bits in CSR register) - */ - __asm__ volatile ("csrrc %0, mie, %1\n" - : "=r" (mie) - : "r" (1 << irq)); -}; - -int arch_irq_is_enabled(unsigned int irq) -{ - uint32_t mie; - - __asm__ volatile ("csrr %0, mie" : "=r" (mie)); - - return !!(mie & (1 << irq)); -} - -#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) -void soc_interrupt_init(void) -{ - /* ensure that all interrupts are disabled */ - (void)irq_lock(); - - __asm__ volatile ("csrwi mie, 0\n" - "csrwi mip, 0\n"); -} -#endif diff --git a/zephyr/soc/riscv/servant/linker.ld b/zephyr/soc/riscv/servant/linker.ld deleted file mode 100644 index 0d220a2..0000000 --- a/zephyr/soc/riscv/servant/linker.ld +++ /dev/null @@ -1,7 +0,0 @@ -/* - * Copyright (c) 2018 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include diff --git a/zephyr/soc/riscv/servant/soc.h b/zephyr/soc/riscv/servant/soc.h deleted file mode 100644 index 58ff95b..0000000 --- a/zephyr/soc/riscv/servant/soc.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * Copyright (c) 2020 Olof Kindgren - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#ifndef __RISCV32_SERVANT_SOC_H_ -#define __RISCV32_SERVANT_SOC_H_ - -#include - -/* Bitbang UART configuration */ -#define UART_BITBANG_BASE 0x40000000 - -/* Timer configuration */ -#define SERV_TIMER_BASE 0x80000000 -#define SERV_TIMER_IRQ 7 - -#endif /* __RISCV32_SERVANT_SOC_H_ */ diff --git a/zephyr/soc/riscv/servant/soc_common.h b/zephyr/soc/riscv/servant/soc_common.h deleted file mode 100644 index 37c8d6d..0000000 --- a/zephyr/soc/riscv/servant/soc_common.h +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/** - * @file configuration macros for riscv SOCs supporting the riscv - * privileged architecture specification - */ - -#ifndef __SOC_COMMON_H_ -#define __SOC_COMMON_H_ - -/* IRQ numbers */ -#define RISCV_MACHINE_SOFT_IRQ 3 /* Machine Software Interrupt */ -#define RISCV_MACHINE_TIMER_IRQ 7 /* Machine Timer Interrupt */ -#define RISCV_MACHINE_EXT_IRQ 11 /* Machine External Interrupt */ - -/* ECALL Exception numbers */ -#define SOC_MCAUSE_ECALL_EXP 11 /* Machine ECALL instruction */ -#define SOC_MCAUSE_USER_ECALL_EXP 8 /* User ECALL instruction */ - -/* SOC-specific MCAUSE bitfields */ -#ifdef CONFIG_64BIT -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 63) -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFFFFFFFFFF -#else -/* Interrupt Mask */ -#define SOC_MCAUSE_IRQ_MASK (1 << 31) -/* Exception code Mask */ -#define SOC_MCAUSE_EXP_MASK 0x7FFFFFFF -#endif - -/* SOC-Specific EXIT ISR command */ -#define SOC_ERET mret - -#ifndef _ASMLANGUAGE - -#if defined(CONFIG_RISCV_SOC_INTERRUPT_INIT) -void soc_interrupt_init(void); -#endif - -#if defined(CONFIG_RISCV_HAS_PLIC) -void riscv_plic_irq_enable(uint32_t irq); -void riscv_plic_irq_disable(uint32_t irq); -int riscv_plic_irq_is_enabled(uint32_t irq); -void riscv_plic_set_priority(uint32_t irq, uint32_t priority); -int riscv_plic_get_irq(void); -#endif - -#endif /* !_ASMLANGUAGE */ - -#endif /* __SOC_COMMON_H_ */ diff --git a/zephyr/soc/riscv/servant/soc_irq.S b/zephyr/soc/riscv/servant/soc_irq.S deleted file mode 100644 index bbaef8c..0000000 --- a/zephyr/soc/riscv/servant/soc_irq.S +++ /dev/null @@ -1,56 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * - * SPDX-License-Identifier: Apache-2.0 - */ - -/* - * common interrupt management code for riscv SOCs supporting the riscv - * privileged architecture specification - */ -#include -#include -#include - -/* exports */ -GTEXT(__soc_handle_irq) - -/* - * SOC-specific function to handle pending IRQ number generating the interrupt. - * Exception number is given as parameter via register a0. - */ -SECTION_FUNC(exception.other, __soc_handle_irq) - /* Clear exception number from CSR mip register */ - li t1, 1 - sll t0, t1, a0 - csrrc t1, mip, t0 - - /* Return */ - jalr x0, ra - -/* - * __soc_is_irq is defined as .weak to allow re-implementation by - * SOCs that does not truly follow the riscv privilege specification. - */ -WTEXT(__soc_is_irq) - -/* - * SOC-specific function to determine if the exception is the result of a - * an interrupt or an exception - * return 1 (interrupt) or 0 (exception) - * - */ -SECTION_FUNC(exception.other, __soc_is_irq) - /* Read mcause and check if interrupt bit is set */ - csrr t0, mcause - li t1, SOC_MCAUSE_IRQ_MASK - and t0, t0, t1 - - /* If interrupt bit is not set, return with 0 */ - addi a0, x0, 0 - beqz t0, not_interrupt - addi a0, a0, 1 - -not_interrupt: - /* return */ - jalr x0, ra diff --git a/zephyr/soc/riscv/servant/vector.S b/zephyr/soc/riscv/servant/vector.S deleted file mode 100644 index 3fa9897..0000000 --- a/zephyr/soc/riscv/servant/vector.S +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright (c) 2017 Jean-Paul Etienne - * Contributors: 2018 Antmicro - * - * SPDX-License-Identifier: Apache-2.0 - */ - -#include - -/* exports */ -GTEXT(__start) - -/* imports */ -GTEXT(__initialize) -GTEXT(_isr_wrapper) - -SECTION_FUNC(vectors, __start) - .option norvc; - - /* - * Set mtvec (Machine Trap-Vector Base-Address Register) - * to __isr_wrapper. - */ - la t0, _isr_wrapper - csrw mtvec, t0 - - /* Jump to __initialize */ - tail __initialize