{"id":19875217,"url":"https://github.com/wren6991/hazard3","last_synced_at":"2026-02-16T07:33:14.768Z","repository":{"id":41490073,"uuid":"369765988","full_name":"Wren6991/Hazard3","owner":"Wren6991","description":"3-stage RV32IMACZb* processor with debug","archived":false,"fork":false,"pushed_at":"2025-12-14T13:40:53.000Z","size":4372,"stargazers_count":967,"open_issues_count":2,"forks_count":73,"subscribers_count":20,"default_branch":"stable","last_synced_at":"2025-12-16T20:18:03.097Z","etag":null,"topics":["jtag","risc-v","riscv"],"latest_commit_sha":null,"homepage":"","language":"Verilog","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/Wren6991.png","metadata":{"files":{"readme":"Readme.md","changelog":null,"contributing":"Contributing.md","funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2021-05-22T09:20:12.000Z","updated_at":"2025-12-16T18:45:16.000Z","dependencies_parsed_at":"2023-01-29T17:15:14.734Z","dependency_job_id":"1115a96e-62c1-4f07-945c-aa9c98b5ef33","html_url":"https://github.com/Wren6991/Hazard3","commit_stats":null,"previous_names":[],"tags_count":7,"template":false,"template_full_name":null,"purl":"pkg:github/Wren6991/Hazard3","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wren6991%2FHazard3","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wren6991%2FHazard3/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wren6991%2FHazard3/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wren6991%2FHazard3/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/Wren6991","download_url":"https://codeload.github.com/Wren6991/Hazard3/tar.gz/refs/heads/stable","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/Wren6991%2FHazard3/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29502934,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-16T05:57:17.024Z","status":"ssl_error","status_checked_at":"2026-02-16T05:56:49.929Z","response_time":115,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.5:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["jtag","risc-v","riscv"],"created_at":"2024-11-12T16:27:18.302Z","updated_at":"2026-02-16T07:33:14.762Z","avatar_url":"https://github.com/Wren6991.png","language":"Verilog","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Hazard3\n\nHazard3 is a 3-stage RISC-V processor, implementing the `RV32I` or `RV32E` instruction set and the following optional extensions:\n\n* `M`: integer multiply/divide/modulo\n* `A` : atomic memory operations, with AHB5 global exclusives\n* `C`: compressed instructions\n* `Zicsr`: CSR access\n* `Zilsd`: load/store pair instructions\n* `Zba`: address generation\n* `Zbb`: basic bit manipulation\n* `Zbc`: carry-less multiplication\n* `Zbs`: single-bit manipulation\n* `Zbkb`: basic bit manipulation for scalar cryptography\n* `Zbkx`: crossbar permutation instructions\n* `Zcb`: basic additional compressed instructions\n* `Zclsd`: compressed load/store pair instructions\n* `Zcmp`: push/pop instructions\n* Debug, Machine and User privilege/execution modes\n* Privileged instructions `ecall`, `ebreak`, `mret` and `wfi`\n* Physical memory protection (PMP) with up to 16 regions (configurable support for NAPOT and/or TOR matching)\n* External debug support (JTAG or APB)\n* Instruction address trigger unit (hardware breakpoints)\n\nDownload the Hazard3 reference manual [here (PDF)](https://github.com/Wren6991/Hazard3/releases/download/v1.1/hazard3.pdf). You can also [read the documentation online](https://wren.wtf/hazard3/doc).\n\nThis repository contains the source for the Hazard3 core and its associated debug components. The [example SoC integration](example_soc/soc/example_soc.v) shows how you can assemble these components to create a minimal system with a JTAG-enabled RISC-V processor, some RAM, a serial port and a platform timer.\n\nPlease read [Contributing.md](Contributing.md) before raising an issue or pull request.\n\n# Cloning This Repository\n\nFor the purpose of using Hazard3 in your design, this repository is self-contained. However, you need the submodules for simulation scripts, tests and example SoC components. In the latter case you should do a recursive clone:\n\n```bash\ngit clone --recursive https://github.com/Wren6991/Hazard3.git hazard3\n```\n\nTo initialise submodules in an already-cloned repository:\n\n```bash\ngit submodule update --init --recursive\n```\n\nThe default branch for clones is [stable](https://github.com/Wren6991/Hazard3/tree/stable). I strongly recommend this branch for ASIC tapeouts. The head of stable is always the latest non-development release under [releases](https://github.com/Wren6991/Hazard3/releases).\n\nSee the [develop](https://github.com/Wren6991/Hazard3/tree/develop) branch to try the latest features and optimisations.\n\n# Running Hello World\n\nThese instructions walk through:\n\n* Setting up the tools for building the Hazard3 simulator from Verilog source\n* Setting up the tools for building RISC-V binaries to run on the simulator\n* Building a \"Hello, world!\" binary and running it on the simulator\n\nThese instructions are for Ubuntu 24.04. If you are running on Windows you may have some success with Ubuntu under WSL.\n\nYou will need:\n\n* A recent Yosys build to process the Verilog (these instructions were last tested with `a0e94e506`)\n* A `riscv32-unknown-elf-` toolchain to build software for the core\n* A native `clang-16` to build the simulator\n\n`clang-17` is also known to work fine. `clang-18` does work, but has a serious compile time regression with CXXRTL output, which is why the `tb_cxxrtl` Makefile explicitly selects `clang-16`.\n\n## Yosys\n\nThe [Yosys GitHub repo](https://github.com/YosysHQ/yosys) has instructions for building Yosys from source.\n\nThe following steps work for me on Ubuntu 24.04 using version `a0e94e506` mentioned above.\n\n```bash\nsudo apt install build-essential clang lld bison flex libreadline-dev gawk tcl-dev libffi-dev git graphviz xdot pkg-config python3 libboost-system-dev libboost-python-dev libboost-filesystem-dev zlib1g-dev\n\ngit clone https://github.com/YosysHQ/yosys.git\ncd yosys\ngit submodule update --init\nmake -j$(nproc)\nsudo make install\n```\n\n## RISC-V Toolchain\n\nI recommend _building_ a toolchain to get libraries with the correct ISA support. Follow the below instructions to build a 32-bit version of the [RISC-V GNU toolchain](https://github.com/riscv/riscv-gnu-toolchain) with a multilib setup suitable for Hazard3 development.\n\n```bash\n# Prerequisites for Ubuntu 24.04\nsudo apt install autoconf automake autotools-dev curl python3 python3-pip libmpc-dev libmpfr-dev libgmp-dev gawk build-essential bison flex texinfo gperf libtool patchutils bc zlib1g-dev libexpat-dev ninja-build git cmake libglib2.0-dev libslirp-dev\n\ncd /tmp\ngit clone https://github.com/riscv/riscv-gnu-toolchain\ncd riscv-gnu-toolchain\n\n./configure --prefix=/opt/riscv/gcc15 --with-arch=rv32ia_zicsr_zifencei --with-abi=ilp32 --with-multilib-generator=\"rv32i_zicsr_zifencei-ilp32--;rv32im_zicsr_zifencei-ilp32--;rv32ia_zicsr_zifencei-ilp32--;rv32ima_zicsr_zifencei-ilp32--;rv32ic_zicsr_zifencei-ilp32--;rv32imc_zicsr_zifencei-ilp32--;rv32iac_zicsr_zifencei-ilp32--;rv32imac_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zicsr_zifencei-ilp32--;rv32imc_zba_zbb_zbs_zicsr_zifencei-ilp32--;rv32imac_zba_zbb_zbs_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zicsr_zifencei-ilp32--;rv32imc_zba_zbb_zbs_zbkb_zicsr_zifencei-ilp32--;rv32imac_zba_zbb_zbs_zbkb_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zicsr_zifencei-ilp32--;rv32imc_zba_zbb_zbc_zbs_zbkb_zicsr_zifencei-ilp32--;rv32imac_zba_zbb_zbc_zbs_zbkb_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32imc_zba_zbb_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32imac_zba_zbb_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32imc_zba_zbb_zbc_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32imac_zba_zbb_zbc_zbs_zbkb_zbkx_zicsr_zifencei-ilp32--;rv32i_zca_zicsr_zifencei-ilp32--;rv32im_zca_zicsr_zifencei-ilp32--;rv32ia_zca_zicsr_zifencei-ilp32--;rv32ima_zca_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zca_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zca_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zca_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zca_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zca_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zca_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zbkx_zca_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zbkx_zca_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zbkx_zca_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zbkx_zca_zicsr_zifencei-ilp32--;rv32i_zca_zcb_zicsr_zifencei-ilp32--;rv32im_zca_zcb_zicsr_zifencei-ilp32--;rv32ia_zca_zcb_zicsr_zifencei-ilp32--;rv32ima_zca_zcb_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zca_zcb_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zca_zcb_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zca_zcb_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zca_zcb_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zca_zcb_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zca_zcb_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zbkx_zca_zcb_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zbkx_zca_zcb_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zbkx_zca_zcb_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zbkx_zca_zcb_zicsr_zifencei-ilp32--;rv32i_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32im_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32ia_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32ima_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbs_zbkb_zbkx_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbs_zbkb_zbkx_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32im_zba_zbb_zbc_zbs_zbkb_zbkx_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32ima_zba_zbb_zbc_zbs_zbkb_zbkx_zca_zcb_zcmp_zicsr_zifencei-ilp32--;rv32i_zmmul_zicsr_zifencei-ilp32--;rv32ia_zmmul_zicsr_zifencei-ilp32--;rv32ic_zmmul_zicsr_zifencei-ilp32--;rv32iac_zmmul_zicsr_zifencei-ilp32--;rv32i_zca_zmmul_zicsr_zifencei-ilp32--;rv32ia_zca_zmmul_zicsr_zifencei-ilp32--;rv32i_zca_zcb_zmmul_zicsr_zifencei-ilp32--;rv32ia_zca_zcb_zmmul_zicsr_zifencei-ilp32--;rv32i_zca_zcb_zcmp_zmmul_zicsr_zifencei-ilp32--;rv32ia_zca_zcb_zcmp_zmmul_zicsr_zifencei-ilp32--;rv32e_zicsr_zifencei-ilp32e--;rv32ema_zicsr_zifencei-ilp32e--;rv32emac_zicsr_zifencei-ilp32e--;rv32ema_zicsr_zifencei_zba_zbb_zbc_zbkb_zbkx_zbs_zca_zcb_zcmp-ilp32e--\"\nsudo mkdir -p /opt/riscv/gcc15\nsudo chown $(whoami) /opt/riscv/gcc15\nmake -j $(nproc)\n```\n\nThe `--with-multilib-generator=` flag builds multiple versions of the standard library, to match possible `-march` flags provided at link time. The multilib-generator command line above was generated using [multilib-gen-gen.py](test/sim/common/multilib-gen-gen.py)\n\nMake sure this toolchain can be found on your `PATH` (as `riscv32-unknown-elf-*`):\n\n```bash\nexport PATH=\"$PATH:/opt/riscv/gcc15/bin\"\n```\n\n### Non-multilib (Smaller Install Size)\n\nFor a faster build and a smaller install size, use this `./configure` line instead:\n\n```bash\n./configure --prefix=/opt/riscv/gcc15 --with-arch=rv32imac_zicsr_zifencei_zba_zbb_zbkb_zbs --with-abi=ilp32\n```\n\nAdjust the `--with-arch` line as necessary for your Hazard3 configuration. You may need to adjust architectures used in software Makefiles in this repository to fit your chosen architecture variant.\n\n### Building Toolchain on MacOS\n\nThese are my hacks to build the latest `riscv-gnu-toolchain` on MacOS Sequoia on M4 (Arm).\n\n```bash\nbrew install python3 gawk gnu-sed make gmp mpfr libmpc isl zlib expat texinfo flock libslirp\ngit clone https://github.com/riscv/riscv-gnu-toolchain\ncd riscv-gnu-toolchain\ngit submodule update --init -- binutils gdb\n# HACK for a macro definition which conflicts with a system header:\ngsed -i 's,#        define fdopen,//#define fdopen,' binutils/zlib/zutil.h gdb/zlib/zutil.h\n\nexport PATH=\"/opt/homebrew/bin:$PATH\"\nexport LDFLAGS=\"-L/opt/homebrew/lib\"\nexport CPPFLAGS=\"-I/opt/homebrew/include\"\n./configure --prefix=/opt/riscv/gcc15 --with-arch=rv32imac_zicsr_zifencei_zba_zbb_zbkb_zbs --with-abi=ilp32\ngmake -j10\n```\n\n## Actually Running Hello World\n\nMake sure you have done a _recursive_ clone of the Hazard3 repository. Build the CXXRTL-based simulator:\n\n```bash\ncd hazard3\ncd test/sim/tb_cxxrtl\nmake\n```\n\nBuild and run the hello world binary:\n\n```bash\ncd ../hellow\nmake\n```\n\nAll going well you should see something like:\n\n```\n$ make\nmkdir -p tmp/\nriscv32-unknown-elf-gcc -march=rv32imac_zicsr_zifencei_zba_zbb_zbkb_zbs -Os -Wl,--no-warn-rwx-segments ../common/init.S main.c -T ../common/memmap.ld -I../common -o tmp/hellow.elf\nriscv32-unknown-elf-objcopy -O binary tmp/hellow.elf tmp/hellow.bin\nriscv32-unknown-elf-objdump -h tmp/hellow.elf \u003e tmp/hellow.dis\nriscv32-unknown-elf-objdump -d tmp/hellow.elf \u003e\u003e tmp/hellow.dis\n../tb_cxxrtl/tb --bin tmp/hellow.bin --vcd tmp/hellow_run.vcd --cycles 100000\nHello world from Hazard3 + CXXRTL!\nCPU requested halt. Exit code 123\nRan for 897 cycles\n```\n\nThis will have created a waveform dump called `tmp/hellow_run.vcd` which you can view with GTKWave:\n\n```bash\ngtkwave tmp/hellow_run.vcd\n```\n\nInstalling GTKWave on Ubuntu 24.04 is just `sudo apt install gtkwave`.\n\n# Loading Hello World with the Debugger\n\nInvoking the simulator built in the previous step, with no arguments, shows the following usage message:\n\n```\n$ ./tb\nAt least one of --bin or --port must be specified.\nUsage: tb [--bin x.bin] [--vcd x.vcd] [--dump start end] [--cycles n] [--port n]\n    --bin x.bin      : Flat binary file loaded to address 0x0 in RAM\n    --vcd x.vcd      : Path to dump waveforms to\n    --dump start end : Print out memory contents from start to end (exclusive)\n                       after execution finishes. Can be passed multiple times.\n    --cycles n       : Maximum number of cycles to run before exiting.\n                       Default is 0 (no maximum).\n    --port n         : Port number to listen for openocd remote bitbang. Sim\n                       runs in lockstep with JTAG bitbang, not free-running.\n```\n\nThis simulator contains:\n\n- Hardware:\n\t- The processor\n\t- A Debug Module (DM)\n\t- A JTAG Debug Transport Module (DTM)\n- Software:\n\t- RAM model\n\t- Routines for loading binary files, dumping VCDs\n\t- Routines for bitbanging the JTAG DTM through a TCP socket\n\nRunning hello world in the previous section used the `--bin` argument to load the linked hello world executable directly into the testbench's RAM. If we invoke the simulator with the `--port` argument, it will instead wait for a connection on that port, and then accept JTAG bitbang commands in OpenOCD's `remote-bitbang` format. The simulation runs in lockstep with the JTAG bitbanging, for more predictable results.\n\nWe need to build a copy of `riscv-openocd` before going any further. OpenOCD's role is to translate the abstract debug commands issued by gdb, e.g. \"set the program counter to address `x`\", to more concrete operations, e.g. \"shift this JTAG DR\".\n\n## Building riscv-openocd\n\nWe need a recent build of [riscv-openocd](https://github.com/riscv/riscv-openocd) with the `remote-bitbang` protocol enabled.\n\nOn Ubuntu:\n\n```bash\ncd /tmp\ngit clone https://github.com/riscv/riscv-openocd.git\ncd riscv-openocd\n./bootstrap\n# Prefix is optional\n./configure --enable-remote-bitbang --enable-ftdi --program-prefix=riscv-\nmake -j $(nproc)\nsudo make install\n```\n\nOn MacOS:\n\n```bash\nbrew install autoconf automake libusb\ncd /tmp\ngit clone https://github.com/riscv/riscv-openocd.git\ncd riscv-openocd\n./bootstrap\n# Workarounds:\n# - System clang has a warning for the GCC constant VLA thing, and OpenOCD is -Werror by default\n# - amtjtagaccel driver tries to pull in a Linux header\nCFLAGS=-Wno-gnu-folding-constant ./configure --enable-remote-bitbang --enable-ftdi --enable-amtjtagaccel=no --program-prefix=riscv-\n```\n## Loading and Running\n\nYou're going to want three terminal tabs in the `tb_cxxrtl` directory.\n\n```bash\ncd hazard3/test/sim/tb_cxxrtl\n```\n\nIn the first of them type:\n\n```bash\n./tb --port 9824\n```\n\nYou should see something like\n\n```\nWaiting for connection on port 9824\n```\n\nThe simulation will start once OpenOCD connects. In your second terminal in the same directory, start riscv-openocd:\n\n```bash\nriscv-openocd -f openocd.cfg\n```\n\nIf you see something like:\n\n```\nInfo : Initializing remote_bitbang driver\nInfo : Connecting to localhost:9824\nInfo : remote_bitbang driver initialized\nInfo : Note: The adapter \"remote_bitbang\" doesn't support configurable speed\nInfo : JTAG tap: hazard3.cpu tap/device found: 0xdeadbeef (mfg: 0x777 (Fabric of Truth Inc), part: 0xeadb, ver: 0xd)\nInfo : [hazard3.cpu] datacount=1 progbufsize=2\nInfo : [hazard3.cpu] Examined RISC-V core\nInfo : [hazard3.cpu]  XLEN=32, misa=0x40901107\n[hazard3.cpu] Target successfully examined.\nInfo : [hazard3.cpu] Examination succeed\nInfo : [hazard3.cpu] starting gdb server on 3333\nInfo : Listening on port 3333 for gdb connections\nhazard3.cpu halted due to debug-request.\nInfo : Listening on port 6666 for tcl connections\nInfo : Listening on port 4444 for telnet connections\n```\n\nThen openocd is successfully connected to the processor's debug hardware. We're going to use riscv-gdb to load and run the hello world executable, which is what the third terminal is for:\n\n```bash\nriscv32-unknown-elf-gdb\n# Remaining commands are typed into the gdb prompt. This one tells gdb to shut up:\nset confirm off\n# Connect to openocd on its default port:\ntarget extended-remote localhost:3333\n# Load hello world, and check that it loaded correctly\nfile ../hellow/tmp/hellow.elf\nload\ncompare-sections\n# The processor will quit the simulation when after returning from main(), by\n# writing to a magic MMIO register. openocd will be quite unhappy that the\n# other end of its socket disappeared, so to avoid the resulting error\n# messages, add a breakpoint before _exit.\nbreak _exit\nrun\n# Should break at _exit. Check the terminal with the simulator, you should see\n# the hello world message. The exit code is in register a0, it should be 123:\ninfo reg a0\n```\n\n# Simulating with Verilator\n\nThere is a Verilator harness with the same features and interface as the CXXRTL harness, except it does not support VCD dumping. First build Verilator:\n\n```\ngit clone https://github.com/verilator/verilator.git\ncd verilator\nmkdir build\ncd build\ncmake ..\nmake -j$(nproc)\nsudo make install\n```\n\nThen go to the Hazard3 repository and build the simulator. You should be able to run the hello world binary you compiled earlier:\n\n```bash\ncd test/sim/tb_verilator\nmake tb\n./tb --bin ../hellow/tmp/hellow.bin\n```\n\n# Building an Example SoC\n\nThere is a tiny [example SoC](example_soc/soc/example_soc.v) which builds on iCEBreaker, ULX3S and Arty A7-100T boards. The SoC contains:\n\n- A Hazard3 processor, in a single-ported RV32IMA configuration, with debug support\n- A Debug Transport Module and Debug Module to access Hazard3's debug interface\n- 128 kB of RAM (fits in UP5k SPRAMs)\n- A UART\n- A standard RISC-V platform timer\n\nNote there is no software tree for this SoC. For now you'll have to read the source and hack on the test software build. At least you can attach to the processor, poke registers/memory, and convince yourself you really are debugging a RISC-V core.\n\n## Comparison of Supported Boards\n\nOn [iCEBreaker](https://1bitsquared.com/products/icebreaker) (a iCE40 UP5k development board), the processor can be debugged using the onboard FT2232H bridge, through a standard RISCV-V JTAG-DTM exposed on four IO pins. Connecting JTAG requires two solder jumpers to be bridged on the back to connect the JTAG -- see the comments in the [pin constraints file](example_soc/synth/fpga_icebreaker.pcf). FT2232H is a dual-channel FTDI device, so the UART and JTAG can be accessed simultaneously for a very civilised debug experience, with JTAG running at the full 30 MHz supported by the FTDI.\n\n[ULX3S](https://radiona.org/ulx3s/) is based on a much larger ECP5 FPGA. Thanks to [this ECP5 JTAG adapter](hdl/debug/dtm/hazard3_ecp5_jtag_dtm.v), it is possible to attach the guts of a RISC-V JTAG-DTM to the custom DR hooks in ECP5's chip TAP. With the right config file you can then convince OpenOCD that the FPGA's own TAP *is* a JTAG-DTM. You can debug Hazard3 on ULX3S using the same micro USB cable you use to load the bitstream, no soldering required. The downside is that the FT231X device on the ULX3S is actually a UART bridge which supports JTAG by bitbanging the auxiliary UART signals, which is incredibly slow. The UART cannot be used simultaneously with JTAG access. The debugging experience is worse than iCEBreaker because of this.\n\nArty A7-100T uses an Artix-7 FPGA. This is the fastest and most capacious of the boards supported by this example SoC integration, but it's also the most expensive. The board has an FT2232H debug probe, similar to iCEBreaker. The probe is intended for programming the FPGA, or for Xilinx debug functionality like ILA. Using the probe, you can tunnel RISC-V debug traffic through the Artix-7 chip TAP [in a similar way](hdl/debug/dtm/hazard3_xilinx7_jtag_dtm.v) to ECP5, using the `BSCANE2` primitive. There is no performance cost to this tunnelling as the DTM registers are exposed directly as DRs on the FPGA chip TAP, so this is an excellent combination of a fast FPGA and a fast debug interface.\n\n## Building for iCEBreaker\n\nYou must have `nextpnr-ice40`, `yosys`, and `iceprog` (from icestorm) on your PATH.\n\n```bash\ncd hazard3\ncd example_soc/synth\nmake -f Icebreaker.mk prog\n# Should be able to attach to the processor\nriscv-openocd -f ../icebreaker-openocd.cfg\n```\n\n## Building for ULX3S\n\nYou must have `nextpnr-ecp5`, `yosys` and [ujprog](https://github.com/f32c/tools/blob/master/ujprog/README.md) on your PATH.\n\n```bash\ncd hazard3\ncd example_soc/synth\nmake -f ULX3S.mk flash\n# Should be able to attach to the processor\nriscv-openocd -f ../ulx3s-openocd.cfg\n```\n\n## Building for Arty A7-100T\n\nThese scripts use Vivado to build and load the bitstream. You must have `vivado` on your `PATH`; I used version 2025.1. The free version of Vivado supports the A7-100T, so just type some swear words into AMD's export compliance form and away you go.\n\n```bash\ncd hazard3\ncd example_soc/synth_vivado\nmake prog\n# Should be able to attach to the processor\nriscv-openocd -f ../arty7-openocd.cfg\n```\n\nVivado and OpenOCD cannot simultaneously connect to the FTDI. If OpenOCD is connected then Vivado will fail to reprogram the FPGA.\n\n# Performance\n\n## RP2350\n\nThe RP2350 configuration of Hazard3 achieves 4.15 CoreMark/MHz.\n\n```\n2K performance run parameters for coremark.\nCoreMark Size    : 666\nTotal ticks      : 14440822\nTotal time (secs): 14.440822\nIterations/Sec   : 4.154888\nIterations       : 60\nCompiler version : GCC15.1.0\nCompiler flags   : -O3 -g -march=rv32ima_zicsr_zifencei_zba_zbb_zbkb_zbs -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -DPERFORMANCE_RUN=1  \nMemory location  : STACK\nseedcrc          : 0xe9f5\n[0]crclist       : 0xe714\n[0]crcmatrix     : 0x1fd7\n[0]crcstate      : 0x8e3a\n[0]crcfinal      : 0xa14c\nCorrect operation validated. See README.md for run and reporting rules.\nCoreMark 1.0 : 4.154888 / GCC15.1.0 -O3 -g -march=rv32ima_zicsr_zifencei_zba_zbb_zbkb_zbs -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -DPERFORMANCE_RUN=1   / STACK\n```\n\nTo reproduce this in the RTL simulator, use the top-level Makefile in [test/sim/coremark](test/sim/coremark) after you have followed all the steps to get set up for running a \"Hello, world!\" binary above. Expect the simulation to take a couple of minutes.\n\n```bash\ncd test/sim/coremark\nmake\n```\n\nThe default flags are appropriate for the non-multilib toolchain build, and achieve 4.10 CoreMark/MHz. To achieve the full 4.15 CoreMark/MHz, change the ISA variant in `core_portme.mak` to `rv32ima_zicsr_zifencei_zba_zbb_zbkb_zbs`. See the comments in that file for an explanation of why this makes a difference.\n\nSee the RP2350 datasheet for details of the Hazard3 configuration used by that chip. The default `tb_cxxrtl` build uses the same configuration as RP2350, except that it also enables the Zbc extension (which is not emitted by GCC 14 as it is not useful for general-purpose code).\n\n## Maximum\n\nAs of GCC 15, GCC can infer `clmul` and `clmulh` instructions in the CoreMark CRC function. The Zbc extension was dropped from the RP2350 configuration as compilers were not able to exploit it at the time. Enabling Zbc increases the score to 4.25 CoreMark/MHz.\n\n```\nCoreMark Size    : 666\nTotal ticks      : 14121622\nTotal time (secs): 14.121622\nIterations/Sec   : 4.248804\nIterations       : 60\nCompiler version : GCC15.1.0\nCompiler flags   : -O3 -g -march=rv32ima_zicsr_zifencei_zba_zbb_zbkb_zbs_zbc -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -falign-functions=4 -falign-jumps=4 -falign-loops=4 -DPERFORMANCE_RUN=1  \nMemory location  : STACK\nseedcrc          : 0xe9f5\n[0]crclist       : 0xe714\n[0]crcmatrix     : 0x1fd7\n[0]crcstate      : 0x8e3a\n[0]crcfinal      : 0xa14c\nCorrect operation validated. See README.md for run and reporting rules.\nCoreMark 1.0 : 4.248804 / GCC15.1.0 -O3 -g -march=rv32ima_zicsr_zifencei_zba_zbb_zbkb_zbs_zbc -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -falign-functions=4 -falign-jumps=4 -falign-loops=4 -DPERFORMANCE_RUN=1   / STACK\n```\n\n## RV32E\n\nReducing the number of GPRs from 31 to 15 carries around a 5% penalty, at 4.02 CoreMark/MHz.\n\n```\n2K performance run parameters for coremark.\nCoreMark Size    : 666\nTotal ticks      : 14908801\nTotal time (secs): 14.908801\nIterations/Sec   : 4.024469\nIterations       : 60\nCompiler version : GCC15.1.0\nCompiler flags   : -O3 -g -march=rv32ema_zba_zbb_zbc_zbkb_zbkx_zbs_zicsr_zifencei -mabi=ilp32e -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -falign-functions=4 -falign-jumps=4 -falign-loops=4 -DPERFORMANCE_RUN=1  \nMemory location  : STACK\nseedcrc          : 0xe9f5\n[0]crclist       : 0xe714\n[0]crcmatrix     : 0x1fd7\n[0]crcstate      : 0x8e3a\n[0]crcfinal      : 0xa14c\nCorrect operation validated. See README.md for run and reporting rules.\nCoreMark 1.0 : 4.024469 / GCC15.1.0 -O3 -g -march=rv32ema_zba_zbb_zbc_zbkb_zbkx_zbs_zicsr_zifencei -mabi=ilp32e -mbranch-cost=1 -funroll-all-loops --param max-inline-insns-auto=200 -finline-limit=10000 -fno-code-hoisting -fno-if-conversion2 -falign-functions=4 -falign-jumps=4 -falign-loops=4 -DPERFORMANCE_RUN=1   / STACK\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwren6991%2Fhazard3","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fwren6991%2Fhazard3","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fwren6991%2Fhazard3/lists"}