├── .editorconfig ├── .gitignore ├── .gitmodules ├── .vscode ├── launch.json └── settings.json ├── Dockerfile ├── LICENSE.txt ├── Makefile ├── README.md ├── doc └── riscv_soc.png ├── docker-compose.yml ├── fpga ├── .editorconfig ├── .gitignore ├── Makefile ├── constraints │ ├── xc7a100tcsg324-1 │ │ ├── arty-config.xdc │ │ └── master.xdc │ ├── xc7a35ticsg324-1L │ │ ├── arty-config.xdc │ │ └── master.xdc │ └── xc7z020clg400-1 │ │ ├── master.xdc │ │ └── zynq.xdc ├── ips │ └── ips.tcl └── main │ ├── main.mk │ └── tcl │ ├── bitstream.tcl │ ├── import.tcl │ ├── opt.tcl │ ├── place.tcl │ ├── prep_ips.tcl │ ├── program_mcs.tcl │ ├── report.tcl │ ├── route.tcl │ ├── run.tcl │ ├── start.tcl │ ├── synthesis.tcl │ └── write_cfgmem.tcl ├── ips └── utils │ ├── ahb3lite_if.sv │ ├── ahb_dummy.sv │ ├── ahb_ri5cy_rom.sv │ ├── ahb_to_ri5cy.sv │ ├── apb4_if.sv │ ├── apb_timer │ ├── LICENSE │ ├── README.md │ ├── apb_timer.sv │ ├── src_files.yml │ └── timer.sv │ ├── cluster_clock_inverter.sv │ ├── filter_oor.sv │ ├── io_generic_fifo.sv │ ├── pulp_clock_mux2.sv │ ├── ri5cy_to_ahb.sv │ └── rst_ctrl_unit.sv ├── sw ├── boot_rom │ ├── .gitignore │ ├── Makefile │ ├── init │ │ ├── startup.c │ │ └── vector.S │ ├── scripts │ │ ├── freedom-bin2hex.py │ │ └── gen_rom.py │ ├── sections.ld │ └── src │ │ └── main.c ├── common │ ├── API │ │ ├── inc │ │ │ ├── event.h │ │ │ ├── gpio.h │ │ │ ├── timer.h │ │ │ └── uart.h │ │ └── src │ │ │ ├── event.c │ │ │ ├── gpio.c │ │ │ ├── timer.c │ │ │ └── uart.c │ └── base │ │ ├── encoding.h │ │ └── riscv_soc_utils.h └── hello_world │ ├── .gitignore │ ├── Makefile │ ├── init │ ├── startup.c │ └── vector.S │ ├── scripts │ ├── freedom-bin2hex.py │ └── gen_rom.py │ ├── sections.ld │ └── src │ └── main.c └── tb ├── cpp ├── jtag_rbb.cpp ├── jtag_rbb.hpp └── testbench.cpp ├── debug ├── bus-pirate.cfg ├── esp-prog.cfg ├── riscv_pulp.cfg └── riscv_pulp_fpga.cfg ├── inc ├── config_ri5cy.v └── config_soc.v ├── waveform_template ├── ahb_size.tmpl └── gtkwave_tmpl.gtkw └── wrappers ├── fpga_wrapper └── fpga_wrapper.sv ├── ri5cy_ahb_wrapper.sv └── riscv_soc.sv /.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | indent_style = space 9 | indent_size = 4 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [{*.md,*.rst}] 16 | trim_trailing_whitespace = false 17 | 18 | [{*.v,*.sv}] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | [{Makefile,*.mk,*.bat}] 23 | indent_style = tab 24 | indent_size = 2 25 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | /**/*.o 2 | /**/*.baremetal 3 | /**/*.asm 4 | obj 5 | obj_dir 6 | output_icarus 7 | output_verilator 8 | INCA_libs 9 | irun.* 10 | .simvision 11 | waves.shm 12 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "ips/ahb3lite_memory"] 2 | path = ips/ahb3lite_memory 3 | url = https://github.com/aignacio/ahb3lite_memory.git 4 | [submodule "ips/ahb3lite_interconnect"] 5 | path = ips/ahb3lite_interconnect 6 | url = https://github.com/RoaLogic/ahb3lite_interconnect.git 7 | [submodule "ips/ahb3lite_apb_bridge"] 8 | path = ips/ahb3lite_apb_bridge 9 | url = https://github.com/aignacio/ahb3lite_apb_bridge.git 10 | [submodule "ips/ahb3lite_pkg"] 11 | path = ips/ahb3lite_pkg 12 | url = https://github.com/RoaLogic/ahb3lite_pkg.git 13 | [submodule "ips/apb4_mux"] 14 | path = ips/apb4_mux 15 | url = https://github.com/RoaLogic/apb4_mux.git 16 | [submodule "ips/apb_gpio"] 17 | path = ips/apb_gpio 18 | url = https://github.com/pulp-platform/apb_gpio.git 19 | [submodule "ips/riscv"] 20 | path = ips/riscv 21 | url = https://github.com/pulp-platform/riscv.git 22 | [submodule "ips/memory"] 23 | path = ips/memory 24 | url = https://github.com/RoaLogic/memory.git 25 | [submodule "ips/fpnew"] 26 | path = ips/fpnew 27 | url = https://github.com/pulp-platform/fpnew.git 28 | [submodule "ips/common_cells"] 29 | path = ips/common_cells 30 | url = https://github.com/pulp-platform/common_cells.git 31 | [submodule "tb/cpp/elfio"] 32 | path = tb/cpp/elfio 33 | url = https://github.com/serge1/ELFIO.git 34 | [submodule "ips/riscv-dbg"] 35 | path = ips/riscv-dbg 36 | url = https://github.com/pulp-platform/riscv-dbg.git 37 | [submodule "ips/apb_uart_sv"] 38 | path = ips/apb_uart_sv 39 | url = https://github.com/pulp-platform/apb_uart_sv.git 40 | [submodule "ips/apb_event_unit"] 41 | path = ips/apb_event_unit 42 | url = https://github.com/pulp-platform/apb_event_unit.git 43 | [submodule "ips/apb_uart"] 44 | path = ips/apb_uart 45 | url = https://github.com/pulp-platform/apb_uart.git 46 | -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "localhost RISC-V launch", 9 | "type": "cppdbg", 10 | "targetArchitecture":"ARM", 11 | "request": "launch", 12 | "program": "${workspaceFolder}/sw/hello_world/output/hello_world.elf", 13 | "cwd": "${workspaceRoot}/sw/hello_world/output", 14 | "args": [], 15 | "stopAtEntry": true, 16 | "environment": [], 17 | "externalConsole": true, 18 | "MIMode": "gdb", 19 | "miDebuggerServerAddress": "localhost:3333", 20 | "customLaunchSetupCommands": [ 21 | { "text": "file ${workspaceFolder}/sw/hello_world/output/hello_world.elf", "description": "Loading ELF File" }, 22 | { "text": "target remote : 3333", "description": "Connecting to the target", "ignoreFailures": true }, 23 | { "text": "load", "description": "load ELF file to the target", "ignoreFailures": true } 24 | ], 25 | "launchCompleteCommand": "None", 26 | "debugServerArgs": "-f ${workspaceFolder}/tb/debug/riscv_pulp.cfg", 27 | "logging": { "engineLogging": true }, 28 | "linux": { 29 | "MIMode": "gdb", 30 | "miDebuggerPath": "riscv-none-embed-gdb", 31 | "debugServerPath": "riscv-openocd" 32 | } 33 | }, 34 | { 35 | "name": "RISC-V launch", 36 | "type": "cppdbg", 37 | "targetArchitecture":"ARM", 38 | "request": "launch", 39 | "program": "${workspaceFolder}/sw/hello_world/output/hello_world.elf", 40 | "cwd": "${workspaceRoot}/sw/hello_world/output", 41 | "args": [], 42 | "stopAtEntry": true, 43 | "environment": [], 44 | "externalConsole": true, 45 | "MIMode": "gdb", 46 | "miDebuggerServerAddress": "localhost:3333", 47 | "customLaunchSetupCommands": [ 48 | { "text": "file ${workspaceFolder}/sw/hello_world/output/hello_world.elf", "description": "Loading ELF File" }, 49 | { "text": "target remote : 3333", "description": "Connecting to the target", "ignoreFailures": true }, 50 | { "text": "load", "description": "load ELF file to the target", "ignoreFailures": true } 51 | ], 52 | "launchCompleteCommand": "None", 53 | // "debugServerArgs": "-f ${workspaceFolder}/tb/debug/esp-prog.cfg -f ${workspaceFolder}/tb/debug/riscv_pulp_fpga.cfg", 54 | "logging": { "engineLogging": true }, 55 | "linux": { 56 | "MIMode": "gdb", 57 | "miDebuggerPath": "riscv-none-embed-gdb"//, 58 | // "debugServerPath": "riscv-openocd" 59 | } 60 | } 61 | ] 62 | } 63 | -------------------------------------------------------------------------------- /.vscode/settings.json: -------------------------------------------------------------------------------- 1 | { 2 | "files.associations": { 3 | "*.config": "bat", 4 | "riscv_soc_utils.h": "c", 5 | "timer.h": "c", 6 | "ostream": "cpp" 7 | } 8 | } -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM debian:bullseye 2 | 3 | LABEL maintainer="Anderson Ignacio da Silva " 4 | RUN apt-get update && \ 5 | apt-get install -y verilator git gtkwave make build-essential 6 | 7 | COPY . /rv 8 | RUN cd /rv && \ 9 | make JTAG_BOOT=1 JTAG_PORT=8080 MAX_THREAD=12 verilator 10 | EXPOSE 8080/tcp 11 | WORKDIR /rv/output_verilator 12 | CMD ./riscv_soc 13 | 14 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | Apache License 2 | Version 2.0, January 2004 3 | http://www.apache.org/licenses/ 4 | 5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 6 | 7 | 1. Definitions. 8 | 9 | "License" shall mean the terms and conditions for use, reproduction, 10 | and distribution as defined by Sections 1 through 9 of this document. 11 | 12 | "Licensor" shall mean the copyright owner or entity authorized by 13 | the copyright owner that is granting the License. 14 | 15 | "Legal Entity" shall mean the union of the acting entity and all 16 | other entities that control, are controlled by, or are under common 17 | control with that entity. For the purposes of this definition, 18 | "control" means (i) the power, direct or indirect, to cause the 19 | direction or management of such entity, whether by contract or 20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 21 | outstanding shares, or (iii) beneficial ownership of such entity. 22 | 23 | "You" (or "Your") shall mean an individual or Legal Entity 24 | exercising permissions granted by this License. 25 | 26 | "Source" form shall mean the preferred form for making modifications, 27 | including but not limited to software source code, documentation 28 | source, and configuration files. 29 | 30 | "Object" form shall mean any form resulting from mechanical 31 | transformation or translation of a Source form, including but 32 | not limited to compiled object code, generated documentation, 33 | and conversions to other media types. 34 | 35 | "Work" shall mean the work of authorship, whether in Source or 36 | Object form, made available under the License, as indicated by a 37 | copyright notice that is included in or attached to the work 38 | (an example is provided in the Appendix below). 39 | 40 | "Derivative Works" shall mean any work, whether in Source or Object 41 | form, that is based on (or derived from) the Work and for which the 42 | editorial revisions, annotations, elaborations, or other modifications 43 | represent, as a whole, an original work of authorship. For the purposes 44 | of this License, Derivative Works shall not include works that remain 45 | separable from, or merely link (or bind by name) to the interfaces of, 46 | the Work and Derivative Works thereof. 47 | 48 | "Contribution" shall mean any work of authorship, including 49 | the original version of the Work and any modifications or additions 50 | to that Work or Derivative Works thereof, that is intentionally 51 | submitted to Licensor for inclusion in the Work by the copyright owner 52 | or by an individual or Legal Entity authorized to submit on behalf of 53 | the copyright owner. For the purposes of this definition, "submitted" 54 | means any form of electronic, verbal, or written communication sent 55 | to the Licensor or its representatives, including but not limited to 56 | communication on electronic mailing lists, source code control systems, 57 | and issue tracking systems that are managed by, or on behalf of, the 58 | Licensor for the purpose of discussing and improving the Work, but 59 | excluding communication that is conspicuously marked or otherwise 60 | designated in writing by the copyright owner as "Not a Contribution." 61 | 62 | "Contributor" shall mean Licensor and any individual or Legal Entity 63 | on behalf of whom a Contribution has been received by Licensor and 64 | subsequently incorporated within the Work. 65 | 66 | 2. Grant of Copyright License. Subject to the terms and conditions of 67 | this License, each Contributor hereby grants to You a perpetual, 68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 69 | copyright license to reproduce, prepare Derivative Works of, 70 | publicly display, publicly perform, sublicense, and distribute the 71 | Work and such Derivative Works in Source or Object form. 72 | 73 | 3. Grant of Patent License. Subject to the terms and conditions of 74 | this License, each Contributor hereby grants to You a perpetual, 75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 76 | (except as stated in this section) patent license to make, have made, 77 | use, offer to sell, sell, import, and otherwise transfer the Work, 78 | where such license applies only to those patent claims licensable 79 | by such Contributor that are necessarily infringed by their 80 | Contribution(s) alone or by combination of their Contribution(s) 81 | with the Work to which such Contribution(s) was submitted. If You 82 | institute patent litigation against any entity (including a 83 | cross-claim or counterclaim in a lawsuit) alleging that the Work 84 | or a Contribution incorporated within the Work constitutes direct 85 | or contributory patent infringement, then any patent licenses 86 | granted to You under this License for that Work shall terminate 87 | as of the date such litigation is filed. 88 | 89 | 4. Redistribution. You may reproduce and distribute copies of the 90 | Work or Derivative Works thereof in any medium, with or without 91 | modifications, and in Source or Object form, provided that You 92 | meet the following conditions: 93 | 94 | (a) You must give any other recipients of the Work or 95 | Derivative Works a copy of this License; and 96 | 97 | (b) You must cause any modified files to carry prominent notices 98 | stating that You changed the files; and 99 | 100 | (c) You must retain, in the Source form of any Derivative Works 101 | that You distribute, all copyright, patent, trademark, and 102 | attribution notices from the Source form of the Work, 103 | excluding those notices that do not pertain to any part of 104 | the Derivative Works; and 105 | 106 | (d) If the Work includes a "NOTICE" text file as part of its 107 | distribution, then any Derivative Works that You distribute must 108 | include a readable copy of the attribution notices contained 109 | within such NOTICE file, excluding those notices that do not 110 | pertain to any part of the Derivative Works, in at least one 111 | of the following places: within a NOTICE text file distributed 112 | as part of the Derivative Works; within the Source form or 113 | documentation, if provided along with the Derivative Works; or, 114 | within a display generated by the Derivative Works, if and 115 | wherever such third-party notices normally appear. The contents 116 | of the NOTICE file are for informational purposes only and 117 | do not modify the License. You may add Your own attribution 118 | notices within Derivative Works that You distribute, alongside 119 | or as an addendum to the NOTICE text from the Work, provided 120 | that such additional attribution notices cannot be construed 121 | as modifying the License. 122 | 123 | You may add Your own copyright statement to Your modifications and 124 | may provide additional or different license terms and conditions 125 | for use, reproduction, or distribution of Your modifications, or 126 | for any such Derivative Works as a whole, provided Your use, 127 | reproduction, and distribution of the Work otherwise complies with 128 | the conditions stated in this License. 129 | 130 | 5. Submission of Contributions. Unless You explicitly state otherwise, 131 | any Contribution intentionally submitted for inclusion in the Work 132 | by You to the Licensor shall be under the terms and conditions of 133 | this License, without any additional terms or conditions. 134 | Notwithstanding the above, nothing herein shall supersede or modify 135 | the terms of any separate license agreement you may have executed 136 | with Licensor regarding such Contributions. 137 | 138 | 6. Trademarks. This License does not grant permission to use the trade 139 | names, trademarks, service marks, or product names of the Licensor, 140 | except as required for reasonable and customary use in describing the 141 | origin of the Work and reproducing the content of the NOTICE file. 142 | 143 | 7. Disclaimer of Warranty. Unless required by applicable law or 144 | agreed to in writing, Licensor provides the Work (and each 145 | Contributor provides its Contributions) on an "AS IS" BASIS, 146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 147 | implied, including, without limitation, any warranties or conditions 148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 149 | PARTICULAR PURPOSE. You are solely responsible for determining the 150 | appropriateness of using or redistributing the Work and assume any 151 | risks associated with Your exercise of permissions under this License. 152 | 153 | 8. Limitation of Liability. In no event and under no legal theory, 154 | whether in tort (including negligence), contract, or otherwise, 155 | unless required by applicable law (such as deliberate and grossly 156 | negligent acts) or agreed to in writing, shall any Contributor be 157 | liable to You for damages, including any direct, indirect, special, 158 | incidental, or consequential damages of any character arising as a 159 | result of this License or out of the use or inability to use the 160 | Work (including but not limited to damages for loss of goodwill, 161 | work stoppage, computer failure or malfunction, or any and all 162 | other commercial damages or losses), even if such Contributor 163 | has been advised of the possibility of such damages. 164 | 165 | 9. Accepting Warranty or Additional Liability. While redistributing 166 | the Work or Derivative Works thereof, You may choose to offer, 167 | and charge a fee for, acceptance of support, warranty, indemnity, 168 | or other liability obligations and/or rights consistent with this 169 | License. However, in accepting such obligations, You may act only 170 | on Your own behalf and on Your sole responsibility, not on behalf 171 | of any other Contributor, and only if You agree to indemnify, 172 | defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason 174 | of your accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | 178 | APPENDIX: How to apply the Apache License to your work. 179 | 180 | To apply the Apache License to your work, attach the following 181 | boilerplate notice, with the fields enclosed by brackets "[]" 182 | replaced with your own identifying information. (Don't include 183 | the brackets!) The text should be enclosed in the appropriate 184 | comment syntax for the file format. We also recommend that a 185 | file or class name and description of purpose be included on the 186 | same "printed page" as the copyright notice for easier 187 | identification within third-party archives. 188 | 189 | Copyright [aignacio] [Anderson Ignacio da Silva] 190 | 191 | Licensed under the Apache License, Version 2.0 (the "License"); 192 | you may not use this file except in compliance with the License. 193 | You may obtain a copy of the License at 194 | 195 | http://www.apache.org/licenses/LICENSE-2.0 196 | 197 | Unless required by applicable law or agreed to in writing, software 198 | distributed under the License is distributed on an "AS IS" BASIS, 199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 200 | See the License for the specific language governing permissions and 201 | limitations under the License. 202 | -------------------------------------------------------------------------------- /Makefile: -------------------------------------------------------------------------------- 1 | # SHELL := /bin/bash 2 | RISCV_TOOLCHAIN ?= riscv-none-embed 3 | export RISCV_TOOLCHAIN 4 | ##### Project variables 5 | PROJECT_NAME := riscv 6 | VERILATOR_TB := tb 7 | IPS_FOLDER := ips 8 | EN_VCD ?= 0 9 | # Define here the size of the RAMs once it need to check if the program fits 10 | IRAM_KB_SIZE ?= 32 11 | DRAM_KB_SIZE ?= 32 12 | JTAG_BOOT ?= 0 13 | JTAG_PORT ?= 8080 14 | MAX_THREAD ?= $(shell nproc --all) 15 | VERILAT ?= 1 16 | ##### FPGA makefile variables 17 | FPGA_BOARD ?= artix_a35 18 | CPU_CORES ?= 8 19 | FPGA_WRAPPER ?= artix_wrapper 20 | SYNTH_MODE ?= none 21 | 22 | ifeq ($(FPGA_BOARD),artix_a35) 23 | XILINX_BOARD := digilentinc.com:arty-a7-35:part0:1.0 24 | XILINX_PART := xc7a35ticsg324-1L 25 | XILINX_TARGET := arty 26 | HW_PART := xc7a35t_0 27 | MEM_PART := mt25ql128-spi-x1_x2_x4 28 | else ifeq ($(FPGA_BOARD),artix_a100) 29 | XILINX_BOARD := digilentinc.com:arty-a7-100:part0:1.0 30 | XILINX_PART := xc7a100tcsg324-1 31 | XILINX_TARGET := arty 32 | HW_PART := xc7a100t_0 33 | MEM_PART := s25fl128sxxxxxx0-spi-x1_x2_x4 34 | else ifeq ($(FPGA_BOARD),pynq) 35 | XILINX_BOARD := www.digilentinc.com:pynq-z1:part0:1.0 36 | XILINX_PART := xc7z020clg400-1 37 | XILINX_TARGET := arty 38 | HW_PART := xc7z020_1 39 | MEM_PART := s25fl128s-3.3v-qspi-x4-single 40 | else 41 | XILINX_BOARD := digilentinc.com:arty-a7-35:part0:1.0 42 | XILINX_PART := xc7a35ticsg324-1L 43 | XILINX_TARGET := arty 44 | HW_PART := xc7a35t_0 45 | MEM_PART := mt25ql128-spi-x1_x2_x4 46 | endif 47 | 48 | # Synthesis modes 49 | # • rebuilt - This will attempt to rebuild the original hierarchy of the RTL design after synthesis 50 | # has completed. This is the default setting. 51 | # • full - Flatten the hierarchy of the design. 52 | # • none - Do not flatten the hierarchy of the design. This will preserve the hierarchy of the 53 | # design, but will also limit the design optimization that can be performed by the synthesis 54 | # tool. 55 | 56 | ##### Verilator Specific Simulation variables 57 | OUT_VERILATOR := output_verilator 58 | TEST_PROG ?= hello_world 59 | TB_VERILATOR := $(VERILATOR_TB)/cpp/testbench.cpp 60 | 61 | DEPEND := git \ 62 | gtkwave \ 63 | verilator 64 | 65 | # All the ips that are needed to build 66 | SOC_IPS := ahb3lite_pkg \ 67 | ahb3lite_memory \ 68 | ahb3lite_interconnect/rtl \ 69 | ahb3lite_apb_bridge \ 70 | apb_gpio \ 71 | memory \ 72 | apb4_mux \ 73 | apb_uart \ 74 | apb_uart_sv/apb_uart.sv \ 75 | apb_uart_sv/uart_interrupt.sv \ 76 | apb_uart_sv/uart_rx.sv \ 77 | apb_uart_sv/uart_tx.sv \ 78 | apb_event_unit \ 79 | utils 80 | 81 | # RI5CY RTLs files 82 | COMMON_CELLS := ips/common_cells/include/common_cells/registers.svh \ 83 | ips/common_cells/src/cdc_2phase.sv \ 84 | ips/common_cells/src/deprecated/fifo_v2.sv \ 85 | ips/common_cells/src/fifo_v3.sv \ 86 | ips/common_cells/src/rstgen.sv \ 87 | ips/common_cells/src/rstgen_bypass.sv 88 | 89 | SRC_FPNEW := ips/fpnew/src/fpnew_pkg.sv \ 90 | ips/fpnew/src/fpu_div_sqrt_mvp/hdl/defs_div_sqrt_mvp.sv \ 91 | ips/fpnew/src/fpu_div_sqrt_mvp/hdl/preprocess_mvp.sv \ 92 | ips/fpnew/src/fpu_div_sqrt_mvp/hdl/nrbd_nrsc_mvp.sv \ 93 | ips/fpnew/src/fpu_div_sqrt_mvp/hdl/norm_div_sqrt_mvp.sv \ 94 | ips/fpnew/src/fpu_div_sqrt_mvp/hdl/control_mvp.sv \ 95 | ips/fpnew/src/fpu_div_sqrt_mvp/hdl/iteration_div_sqrt_mvp.sv \ 96 | ips/fpnew/src/fpu_div_sqrt_mvp/hdl/div_sqrt_top_mvp.sv \ 97 | ips/fpnew/src/fpnew_cast_multi.sv \ 98 | ips/fpnew/src/fpnew_top.sv \ 99 | ips/fpnew/src/fpnew_opgroup_fmt_slice.sv \ 100 | ips/fpnew/src/fpnew_rounding.sv \ 101 | ips/fpnew/src/fpnew_noncomp.sv \ 102 | ips/fpnew/src/fpnew_opgroup_block.sv \ 103 | ips/fpnew/src/fpnew_fma_multi.sv \ 104 | ips/fpnew/src/fpnew_fma.sv \ 105 | ips/fpnew/src/fpnew_classifier.sv \ 106 | ips/fpnew/src/fpnew_divsqrt_multi.sv \ 107 | ips/fpnew/src/fpnew_opgroup_multifmt_slice.sv \ 108 | ips/fpnew/src/common_cells/src/lzc.sv \ 109 | ips/fpnew/src/common_cells/src/rr_arb_tree.sv 110 | 111 | SRC_RI5CY := ips/riscv/tb/dm/riscv_tb_pkg.sv \ 112 | ips/riscv/tb/dm/boot_rom.sv \ 113 | ips/riscv/tb/core/cluster_clock_gating.sv \ 114 | ips/riscv/rtl/include/apu_core_package.sv \ 115 | ips/riscv/rtl/include/riscv_defines.sv \ 116 | ips/riscv/rtl/register_file_test_wrap.sv \ 117 | ips/riscv/rtl/riscv_alu.sv \ 118 | ips/riscv/rtl/riscv_alu_basic.sv \ 119 | ips/riscv/rtl/riscv_alu_div.sv \ 120 | ips/riscv/rtl/riscv_compressed_decoder.sv \ 121 | ips/riscv/rtl/riscv_controller.sv \ 122 | ips/riscv/rtl/riscv_cs_registers.sv \ 123 | ips/riscv/rtl/riscv_fetch_fifo.sv \ 124 | ips/riscv/rtl/riscv_decoder.sv \ 125 | ips/riscv/rtl/riscv_int_controller.sv \ 126 | ips/riscv/rtl/riscv_ex_stage.sv \ 127 | ips/riscv/rtl/riscv_hwloop_controller.sv \ 128 | ips/riscv/rtl/riscv_hwloop_regs.sv \ 129 | ips/riscv/rtl/riscv_id_stage.sv \ 130 | ips/riscv/rtl/riscv_if_stage.sv \ 131 | ips/riscv/rtl/riscv_load_store_unit.sv \ 132 | ips/riscv/rtl/riscv_mult.sv \ 133 | ips/riscv/rtl/riscv_prefetch_buffer.sv \ 134 | ips/riscv/rtl/riscv_prefetch_L0_buffer.sv \ 135 | ips/riscv/rtl/riscv_register_file.sv \ 136 | ips/riscv/rtl/riscv_core.sv \ 137 | ips/riscv/rtl/riscv_apu_disp.sv \ 138 | ips/riscv/rtl/riscv_L0_buffer.sv \ 139 | ips/riscv/rtl/riscv_pmp.sv 140 | 141 | SRC_RI5CY_DBG := ips/riscv-dbg/src/dm_pkg.sv \ 142 | ips/riscv-dbg/src/dmi_jtag.sv \ 143 | ips/riscv-dbg/src/dm_csrs.sv \ 144 | ips/riscv-dbg/src/dmi_jtag_tap.sv \ 145 | ips/riscv-dbg/src/dmi_cdc.sv \ 146 | ips/riscv-dbg/src/dm_top.sv \ 147 | ips/riscv-dbg/src/dm_sba.sv \ 148 | ips/riscv-dbg/src/dm_mem.sv \ 149 | ips/riscv-dbg/debug_rom/debug_rom.sv 150 | 151 | # All sources needed to build the verilator model and FPGA 152 | BOOT_ROM := sw/boot_rom/output/prog_rom.sv 153 | SRC_VHDL := $(foreach IP,$(SOC_IPS),$(shell find $(IPS_FOLDER)/$(IP) -type f -name *.vhd)) 154 | SRC_VERILOG := $(foreach IP,$(SOC_IPS),$(shell find $(IPS_FOLDER)/$(IP) -type f -name *.v)) 155 | SRC_VERILOG += $(foreach IP,$(SOC_IPS),$(shell find $(IPS_FOLDER)/$(IP) -type f -name *.sv)) 156 | SRC_VERILOG += $(SRC_RI5CY_DBG) 157 | SRC_VERILOG += $(wildcard $(VERILATOR_TB)/wrappers/*.sv) 158 | SRC_VERILOG += $(wildcard $(VERILATOR_TB)/wrappers/*.v) 159 | SRC_VERILOG += $(COMMON_CELLS) 160 | SRC_VERILOG += $(SRC_FPNEW) 161 | SRC_VERILOG += $(SRC_RI5CY) 162 | INC_VERILOG := $(VERILATOR_TB)/inc \ 163 | $(IPS_FOLDER)/riscv/rtl/include \ 164 | $(IPS_FOLDER)/common_cells/include \ 165 | $(IPS_FOLDER)/apb_event_unit/include 166 | INCS_VERILOG := $(addprefix +incdir+,$(INC_VERILOG)) 167 | MACRO_VLOG := IRAM_KB_SIZE=$(IRAM_KB_SIZE) \ 168 | DRAM_KB_SIZE=$(DRAM_KB_SIZE) \ 169 | JTAG_BOOT=$(JTAG_BOOT) 170 | MACROS_VLOG := $(addprefix +define+,$(MACRO_VLOG)) 171 | MACROS_VLOG += $(addprefix +define+,SIMULATION) # Added later cause MACRO_VLOG it's used by 172 | # vivado, so SIMULATION should not be included 173 | 174 | ##### Verilator configuration stuff 175 | ROOT_MOD_VERI := $(PROJECT_NAME)_soc 176 | VERILATOR_EXE := $(OUT_VERILATOR)/$(ROOT_MOD_VERI) 177 | SRC_CPP := $(wildcard $(VERILATOR_TB)/cpp/*.cpp) 178 | INC_CPP := ../tb/cpp/elfio 179 | INCS_CPP := $(addprefix -I,$(INC_CPP)) 180 | WAVEFORM_VCD ?= /tmp/$(ROOT_MOD_VERI).vcd #$(OUT_VERILATOR)/$(ROOT_MOD_VERI).vcd 181 | WAVEFORM_VERI := $(VERILATOR_TB)/waveform_template/gtkwave_tmpl.gtkw 182 | VERIL_FLAGS := -O3 \ 183 | -Wno-CASEINCOMPLETE \ 184 | -Wno-WIDTH \ 185 | -Wno-COMBDLY \ 186 | -Wno-UNOPTFLAT \ 187 | -Wno-LITENDIAN \ 188 | -Wno-UNSIGNED \ 189 | -Wno-IMPLICIT \ 190 | -Wno-CASEWITHX \ 191 | -Wno-CASEX \ 192 | -Wno-BLKANDNBLK \ 193 | -Wno-CMPCONST \ 194 | -Wno-MODDUP \ 195 | --exe \ 196 | --threads $(MAX_THREAD) \ 197 | --trace \ 198 | --trace-depth 10000 \ 199 | --trace-max-array 10000 \ 200 | --trace-max-width 10000 \ 201 | --cc 202 | CPPFLAGS_VERI := "$(INCS_CPP) -O3 -g3 -Wall \ 203 | -Werror -Wno-aligned-new \ 204 | -DWAVEFORM_VCD=\"$(WAVEFORM_VCD)\" \ 205 | -DIRAM_KB_SIZE=\"$(IRAM_KB_SIZE)\" \ 206 | -DDRAM_KB_SIZE=\"$(DRAM_KB_SIZE)\" \ 207 | -DJTAG_BOOT=\"$(JTAG_BOOT)\" \ 208 | -DJTAG_PORT=\"$(JTAG_PORT)\" \ 209 | -DEN_VCD=\"$(EN_VCD)\"" 210 | # WARN: rtls order matters in verilator compilation seq. 211 | VERIL_ARGS := -CFLAGS $(CPPFLAGS_VERI) \ 212 | --top-module $(ROOT_MOD_VERI) \ 213 | --Mdir $(OUT_VERILATOR) \ 214 | $(VERIL_FLAGS) \ 215 | $(INCS_CPP) \ 216 | $(INCS_VERILOG) \ 217 | $(MACROS_VLOG) \ 218 | $(SRC_VERILOG) \ 219 | $(SRC_CPP) \ 220 | -o \ 221 | $(ROOT_MOD_VERI) 222 | 223 | export SRC_VHDL 224 | export SRC_VERILOG 225 | export INC_VERILOG 226 | export MACRO_VLOG 227 | export PROJECT_NAME 228 | export XILINX_BOARD 229 | export XILINX_PART 230 | export XILINX_TARGET 231 | export CPU_CORES 232 | export FPGA_WRAPPER 233 | export SYNTH_MODE 234 | export FPGA_BOARD 235 | export HW_PART 236 | export MEM_PART 237 | export BOOT_ROM 238 | ######################################################################## 239 | ###################### DO NOT EDIT ANYTHING BELOW ###################### 240 | ######################################################################## 241 | .PHONY: all help 242 | help: 243 | @echo "Rules list:" 244 | @echo "all - build riscv_soc without enabling JTAG" 245 | @echo "run - exec. verilator loading from elf file NO JTAG" 246 | @echo "wave - open gtkwave with waveform vcd dump" 247 | @echo "gdb - run gdb to connect to the target and load" 248 | @echo "fpga - synthetize riscv_soc throught vivado for fpga targets" 249 | @echo "clean_fpga - clean fpga build" 250 | @echo "clean - clean verilator output builds" 251 | @echo "check - check dependencies for running the project" 252 | @echo "install - install dependencies through apt-get" 253 | @echo "docker - build docker image with verilator + jtag" 254 | @echo "openocd - run openocd to connect with verilator RBB" 255 | @echo "openocd_fpga - run openocd to connect with fpga" 256 | 257 | all: verilator 258 | 259 | ####################### FPGA synthesis rules ####################### 260 | .PHONY: openocd_fpga program_mcs mcs fpga clean_fpga 261 | fpga: $(SRC_VERILOG) $(BOOT_ROM) 262 | +@make -C fpga force 263 | 264 | error: 265 | cat fpga/main/output/console.log | grep --color "ERROR:" 266 | 267 | sw/boot_rom/%.sv: 268 | +@make -C sw/boot_rom all 269 | 270 | mcs: 271 | +@make -C fpga $@ 272 | 273 | program_mcs: 274 | +@make -C fpga $@ 275 | 276 | openocd_fpga: 277 | riscv-openocd -f tb/debug/esp-prog.cfg -f tb/debug/riscv_pulp_fpga.cfg 278 | 279 | clean_fpga: 280 | +@make -C fpga clean 281 | +@make -C sw/boot_rom clean 282 | 283 | ####################### verilator simulation rules ####################### 284 | .PHONY: wave run verilator sw openocd gdb clean 285 | wave: 286 | gtkwave -go $(WAVEFORM_VCD) $(WAVEFORM_VERI) 287 | 288 | run: sw $(VERILATOR_EXE) 289 | $(VERILATOR_EXE) sw/$(TEST_PROG)/output/$(TEST_PROG).elf 290 | 291 | verilator: $(VERILATOR_EXE) 292 | @echo "\n" 293 | @echo "Emulator builded, for usage please follow:" 294 | @echo "\033[96m\e[1m./$(VERILATOR_EXE) myprogram.elf\033[0m" 295 | @echo "\n" 296 | 297 | $(VERILATOR_EXE): $(OUT_VERILATOR)/V$(ROOT_MOD_VERI).mk 298 | +@make -C $(OUT_VERILATOR) -f V$(ROOT_MOD_VERI).mk 299 | 300 | $(OUT_VERILATOR)/V$(ROOT_MOD_VERI).mk: $(SRC_VERILOG) $(SRC_CPP) $(TB_VERILATOR) 301 | verilator $(VERIL_ARGS) 302 | 303 | sw: 304 | +@make -C sw/$(TEST_PROG) VERILAT=$(VERILAT) all 305 | 306 | openocd: 307 | riscv-openocd -f tb/debug/riscv_pulp.cfg 308 | 309 | gdb: sw 310 | $(RISCV_TOOLCHAIN)-gdb sw/$(TEST_PROG)/output/$(TEST_PROG).elf -ex "target remote : 3333" -ex "load" -ex "c" 311 | 312 | clean: 313 | $(info Cleaning verilator simulation files...) 314 | $(info rm -rf $(OUT_VERILATOR)) 315 | @rm -rf $(OUT_VERILATOR) 316 | 317 | ####################### check for dependencies ####################### 318 | .PHONY: check install docker rundocker 319 | check: 320 | $(foreach program,$(DEPEND),$(call check_program,$(program))) 321 | 322 | install: 323 | $(foreach program,$(DEPEND),$(call install_program,$(program))) 324 | 325 | docker: 326 | docker build -t riscv_model dockerfile 327 | 328 | rundocker: 329 | docker run --rm -it -p 8080:8080 riscv_model:latest 330 | ####################### functions ####################### 331 | define check_program 332 | $(info Checking program [$(1)]...) 333 | $(if $(shell which $(1)),,$(error The program $(1) it's not installed!)) 334 | endef 335 | 336 | define install_program 337 | $(info Installing [$(1)]...) 338 | sudo apt-get install -fy $(1) 339 | endef 340 | -------------------------------------------------------------------------------- /doc/riscv_soc.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/aignacio/riscv_verilator_model/b69f8ca1ef90c3cf7d9b7e1eab8d2f01048e5054/doc/riscv_soc.png -------------------------------------------------------------------------------- /docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: '2' 2 | services: 3 | verilator: 4 | build: . 5 | image: aignacio/riscv_verilator_model:latest 6 | restart: always 7 | ports: 8 | - "8080:8080" 9 | -------------------------------------------------------------------------------- /fpga/.editorconfig: -------------------------------------------------------------------------------- 1 | # EditorConfig helps developers define and maintain consistent 2 | # coding styles between different editors and IDEs 3 | # http://editorconfig.org 4 | 5 | root = true 6 | 7 | [*] 8 | indent_style = space 9 | indent_size = 4 10 | end_of_line = lf 11 | charset = utf-8 12 | trim_trailing_whitespace = true 13 | insert_final_newline = true 14 | 15 | [{*.md,*.rst}] 16 | trim_trailing_whitespace = false 17 | 18 | [{*.v,*.sv}] 19 | indent_style = space 20 | indent_size = 2 21 | 22 | [{Makefile,*.mk,*.bat}] 23 | indent_style = tab 24 | indent_size = 2 25 | -------------------------------------------------------------------------------- /fpga/.gitignore: -------------------------------------------------------------------------------- 1 | main/output/* 2 | vivado* 3 | .Xil 4 | -------------------------------------------------------------------------------- /fpga/Makefile: -------------------------------------------------------------------------------- 1 | .EXPORT_ALL_VARIABLES: 2 | ################# PROJECT DEPENDENT SETTINGS ################# 3 | PROJECT := $(PROJECT_NAME)_$(FPGA_BOARD) 4 | PROJECT_NAME := $(shell echo $(PROJECT) | tr A-Z a-z) 5 | 6 | ### Project files 7 | PATH_FILES := $(abspath ../) 8 | # List all include folders 9 | INCL_DIR := $(addprefix $(PATH_FILES)/,$(INC_VERILOG)) 10 | # You can list below all files in the verilog/system verilog format 11 | PRJ_FILES_V := $(addprefix $(PATH_FILES)/,$(SRC_VERILOG)) \ 12 | $(addprefix $(PATH_FILES)/,$(BOOT_ROM)) \ 13 | $(addprefix $(PATH_FILES)/,$(SRC_VHDL)) \ 14 | $(PATH_FILES)/tb/wrappers/fpga_wrapper/fpga_wrapper.sv 15 | MACROS_VLOG := $(MACRO_VLOG) 16 | 17 | ### You can list below all files in the manifest format (.F - List of all verilog files) 18 | PRJ_FILES_F := 19 | 20 | ################# INDEPENDENT SETTINGS ################# 21 | .PHONY: help 22 | help: 23 | @echo "Targets available:" 24 | @echo "\tall - Build the project folder" 25 | @echo "\tmcs - [TARGET DEPENDENT] Generate the mcs file to program SPI flash" 26 | @echo "\tprogram_mcs - [TARGET DEPENDENT] Program the memory file into the SPI flash through Vivado" 27 | @echo "\tclean - Clean the project builded" 28 | @echo "\tforce - Force rebuild the project" 29 | 30 | .PHONY: clean force all mcs program_mcs 31 | 32 | force: clean 33 | $(MAKE) -C main -f main.mk all 34 | 35 | all: 36 | $(MAKE) -C main -f main.mk all 37 | 38 | mcs: 39 | $(MAKE) -C main -f main.mk mcs 40 | 41 | program_mcs: 42 | $(MAKE) -C main -f main.mk program_mcs 43 | 44 | clean: 45 | $(MAKE) -C main -f main.mk clean 46 | -------------------------------------------------------------------------------- /fpga/constraints/xc7a100tcsg324-1/arty-config.xdc: -------------------------------------------------------------------------------- 1 | set_property CONFIG_VOLTAGE 3.3 [current_design] 2 | set_property CFGBVS VCCO [current_design] 3 | set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] 4 | set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_tck] 5 | 6 | ## Clock signal 7 | create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk_sys] 8 | -------------------------------------------------------------------------------- /fpga/constraints/xc7a100tcsg324-1/master.xdc: -------------------------------------------------------------------------------- 1 | set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports reset_n] 2 | set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports clk_sys] 3 | 4 | ## Pmod Header JD 5 | ## JD1 - tdi 6 | ## JD2 - tdo 7 | ## JD3 - tck 8 | ## JD4 - tms 9 | set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports jtag_tdi] 10 | set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33} [get_ports jtag_tdo] 11 | set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports jtag_tck] 12 | set_property -dict {PACKAGE_PIN F3 IOSTANDARD LVCMOS33} [get_ports jtag_tms] 13 | 14 | ## Switches 15 | set_property -dict {PACKAGE_PIN A8 IOSTANDARD LVCMOS33} [get_ports {gpio_in[0]}] 16 | set_property -dict {PACKAGE_PIN C11 IOSTANDARD LVCMOS33} [get_ports {gpio_in[1]}] 17 | set_property -dict {PACKAGE_PIN C10 IOSTANDARD LVCMOS33} [get_ports {gpio_in[2]}] 18 | set_property -dict {PACKAGE_PIN A10 IOSTANDARD LVCMOS33} [get_ports {gpio_in[3]}] 19 | 20 | ## RGB LEDs 21 | set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {gpio_out[11]}] 22 | set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {gpio_out[10]}] 23 | set_property -dict {PACKAGE_PIN G6 IOSTANDARD LVCMOS33} [get_ports {gpio_out[9]}] 24 | 25 | set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {gpio_out[8]}] 26 | set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {gpio_out[7]}] 27 | set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {gpio_out[6]}] 28 | 29 | set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {gpio_out[5]}] 30 | set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {gpio_out[4]}] 31 | set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {gpio_out[3]}] 32 | 33 | set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {gpio_out[2]}] 34 | set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {gpio_out[1]}] 35 | set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {gpio_out[0]}] 36 | 37 | set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { clk_locked }] 38 | 39 | ## USB-UART Interface 40 | set_property -dict {PACKAGE_PIN D10 IOSTANDARD LVCMOS33} [get_ports tx_o] 41 | set_property -dict {PACKAGE_PIN A9 IOSTANDARD LVCMOS33} [get_ports rx_i] 42 | ## JA1 43 | ## JA2 44 | set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33} [get_ports tx_o] 45 | set_property -dict {PACKAGE_PIN B11 IOSTANDARD LVCMOS33} [get_ports rx_i] 46 | -------------------------------------------------------------------------------- /fpga/constraints/xc7a35ticsg324-1L/arty-config.xdc: -------------------------------------------------------------------------------- 1 | set_property CONFIG_VOLTAGE 3.3 [current_design] 2 | set_property CFGBVS VCCO [current_design] 3 | set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] 4 | set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_tck] 5 | 6 | ## Clock signal 7 | create_clock -period 10.000 -name sys_clk_pin -waveform {0.000 5.000} -add [get_ports clk_sys] 8 | -------------------------------------------------------------------------------- /fpga/constraints/xc7a35ticsg324-1L/master.xdc: -------------------------------------------------------------------------------- 1 | set_property -dict {PACKAGE_PIN C2 IOSTANDARD LVCMOS33} [get_ports reset_n] 2 | set_property -dict {PACKAGE_PIN E3 IOSTANDARD LVCMOS33} [get_ports clk_sys] 3 | 4 | ## Pmod Header JD 5 | ## JD1 - tdi 6 | ## JD2 - tdo 7 | ## JD3 - tck 8 | ## JD4 - tms 9 | set_property -dict {PACKAGE_PIN D4 IOSTANDARD LVCMOS33} [get_ports jtag_tdi] 10 | set_property -dict {PACKAGE_PIN D3 IOSTANDARD LVCMOS33} [get_ports jtag_tdo] 11 | set_property -dict {PACKAGE_PIN F4 IOSTANDARD LVCMOS33} [get_ports jtag_tck] 12 | set_property -dict {PACKAGE_PIN F3 IOSTANDARD LVCMOS33} [get_ports jtag_tms] 13 | 14 | ## Switches 15 | set_property -dict {PACKAGE_PIN A8 IOSTANDARD LVCMOS33} [get_ports {gpio_in[0]}] 16 | set_property -dict {PACKAGE_PIN C11 IOSTANDARD LVCMOS33} [get_ports {gpio_in[1]}] 17 | set_property -dict {PACKAGE_PIN C10 IOSTANDARD LVCMOS33} [get_ports {gpio_in[2]}] 18 | set_property -dict {PACKAGE_PIN A10 IOSTANDARD LVCMOS33} [get_ports {gpio_in[3]}] 19 | 20 | ## RGB LEDs 21 | set_property -dict {PACKAGE_PIN E1 IOSTANDARD LVCMOS33} [get_ports {gpio_out[11]}] 22 | set_property -dict {PACKAGE_PIN F6 IOSTANDARD LVCMOS33} [get_ports {gpio_out[10]}] 23 | set_property -dict {PACKAGE_PIN G6 IOSTANDARD LVCMOS33} [get_ports {gpio_out[9]}] 24 | 25 | set_property -dict {PACKAGE_PIN G4 IOSTANDARD LVCMOS33} [get_ports {gpio_out[8]}] 26 | set_property -dict {PACKAGE_PIN J4 IOSTANDARD LVCMOS33} [get_ports {gpio_out[7]}] 27 | set_property -dict {PACKAGE_PIN G3 IOSTANDARD LVCMOS33} [get_ports {gpio_out[6]}] 28 | 29 | set_property -dict {PACKAGE_PIN H4 IOSTANDARD LVCMOS33} [get_ports {gpio_out[5]}] 30 | set_property -dict {PACKAGE_PIN J2 IOSTANDARD LVCMOS33} [get_ports {gpio_out[4]}] 31 | set_property -dict {PACKAGE_PIN J3 IOSTANDARD LVCMOS33} [get_ports {gpio_out[3]}] 32 | 33 | set_property -dict {PACKAGE_PIN K2 IOSTANDARD LVCMOS33} [get_ports {gpio_out[2]}] 34 | set_property -dict {PACKAGE_PIN H6 IOSTANDARD LVCMOS33} [get_ports {gpio_out[1]}] 35 | set_property -dict {PACKAGE_PIN K1 IOSTANDARD LVCMOS33} [get_ports {gpio_out[0]}] 36 | 37 | set_property -dict { PACKAGE_PIN H5 IOSTANDARD LVCMOS33 } [get_ports { clk_locked }] 38 | 39 | ## USB-UART Interface 40 | set_property -dict {PACKAGE_PIN D10 IOSTANDARD LVCMOS33} [get_ports tx_o] 41 | set_property -dict {PACKAGE_PIN A9 IOSTANDARD LVCMOS33} [get_ports rx_i] 42 | ## JA1 43 | ## JA2 44 | set_property -dict {PACKAGE_PIN G13 IOSTANDARD LVCMOS33} [get_ports tx_mirror_o] 45 | set_property -dict {PACKAGE_PIN B11 IOSTANDARD LVCMOS33} [get_ports rx_mirror_i] 46 | -------------------------------------------------------------------------------- /fpga/constraints/xc7z020clg400-1/master.xdc: -------------------------------------------------------------------------------- 1 | set_property -dict { PACKAGE_PIN H16 IOSTANDARD LVCMOS33 } [get_ports { clk_sys }] 2 | 3 | # BTN_1 4 | set_property -dict { PACKAGE_PIN D20 IOSTANDARD LVCMOS33 } [get_ports { reset_n }] 5 | 6 | ##Pmod Header JA 7 | set_property -dict { PACKAGE_PIN Y18 IOSTANDARD LVCMOS33 } [get_ports { jtag_tck }] 8 | set_property -dict { PACKAGE_PIN Y19 IOSTANDARD LVCMOS33 } [get_ports { jtag_tms }] 9 | set_property -dict { PACKAGE_PIN Y16 IOSTANDARD LVCMOS33 } [get_ports { jtag_tdi }] 10 | set_property -dict { PACKAGE_PIN Y17 IOSTANDARD LVCMOS33 } [get_ports { jtag_tdo }] 11 | 12 | # ## Switches 13 | set_property -dict { PACKAGE_PIN M20 IOSTANDARD LVCMOS33 } [get_ports { gpio_in[0] }] 14 | set_property -dict { PACKAGE_PIN M19 IOSTANDARD LVCMOS33 } [get_ports { gpio_in[1] }] 15 | 16 | ##Buttons 17 | set_property -dict { PACKAGE_PIN D19 IOSTANDARD LVCMOS33 } [get_ports { gpio_in[2] }] 18 | 19 | # ## RGB LEDs 20 | set_property -dict { PACKAGE_PIN L15 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[0] }] 21 | set_property -dict { PACKAGE_PIN G17 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[1] }] 22 | set_property -dict { PACKAGE_PIN N15 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[2] }] 23 | set_property -dict { PACKAGE_PIN G14 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[3] }] 24 | set_property -dict { PACKAGE_PIN L14 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[4] }] 25 | set_property -dict { PACKAGE_PIN M15 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[5] }] 26 | 27 | ##LEDs 28 | set_property -dict { PACKAGE_PIN R14 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[6] }] 29 | set_property -dict { PACKAGE_PIN P14 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[7] }] 30 | set_property -dict { PACKAGE_PIN N16 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[8] }] 31 | set_property -dict { PACKAGE_PIN M14 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[9] }] 32 | 33 | set_property -dict { PACKAGE_PIN U5 IOSTANDARD LVCMOS33 } [get_ports { gpio_in[3] }] 34 | set_property -dict { PACKAGE_PIN V5 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[11] }] 35 | set_property -dict { PACKAGE_PIN V6 IOSTANDARD LVCMOS33 } [get_ports { gpio_out[10] }] 36 | set_property -dict { PACKAGE_PIN U7 IOSTANDARD LVCMOS33 } [get_ports { clk_locked }] 37 | 38 | ## USB-UART Interface 39 | #IO_L4P_T0_34 Sch=jb_p[4] 40 | set_property -dict { PACKAGE_PIN V12 IOSTANDARD LVCMOS33 } [get_ports { tx_o }] 41 | #IO_L4N_T0_34 Sch=jb_n[4] 42 | set_property -dict { PACKAGE_PIN W13 IOSTANDARD LVCMOS33 } [get_ports { rx_i }] 43 | -------------------------------------------------------------------------------- /fpga/constraints/xc7z020clg400-1/zynq.xdc: -------------------------------------------------------------------------------- 1 | set_property CONFIG_VOLTAGE 3.3 [current_design] 2 | set_property CFGBVS VCCO [current_design] 3 | set_property BITSTREAM.CONFIG.SPI_BUSWIDTH 4 [current_design] 4 | set_property CLOCK_DEDICATED_ROUTE FALSE [get_nets jtag_tck] 5 | 6 | ## Clock signal 7 | create_clock -add -name sys_clk_pin -period 8.00 -waveform {0.000 4.000} [get_ports { clk_sys }]; 8 | -------------------------------------------------------------------------------- /fpga/ips/ips.tcl: -------------------------------------------------------------------------------- 1 | create_ip -vendor xilinx.com -library ip -name clk_wiz -module_name mmcm -dir $ipdir -force 2 | 3 | set fpga_board $::env(FPGA_BOARD) 4 | 5 | if { $fpga_board == "pynq" } { 6 | puts "Using clock synthesis for PYNQ board...." 7 | set_property -dict [list \ 8 | CONFIG.PRIMITIVE {MMCM} \ 9 | CONFIG.PRIM_IN_FREQ {125} \ 10 | CONFIG.CLKOUT2_USED {true} \ 11 | CONFIG.PRIMARY_PORT {clk_in} \ 12 | CONFIG.CLK_OUT1_PORT {core_clk} \ 13 | CONFIG.CLK_OUT2_PORT {periph_clk} \ 14 | CONFIG.CLK_OUT3_PORT {status_clk} \ 15 | CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {25} \ 16 | CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {12.5} \ 17 | CONFIG.RESET_TYPE {ACTIVE_LOW} \ 18 | CONFIG.CLKIN1_JITTER_PS {80.0} \ 19 | CONFIG.CLKOUT1_DRIVES {BUFG} \ 20 | CONFIG.CLKOUT2_DRIVES {BUFG} \ 21 | CONFIG.CLKOUT4_DRIVES {BUFG} \ 22 | CONFIG.CLKOUT5_DRIVES {BUFG} \ 23 | CONFIG.CLKOUT6_DRIVES {BUFG} \ 24 | CONFIG.CLKOUT7_DRIVES {BUFG} \ 25 | CONFIG.FEEDBACK_SOURCE {FDBK_AUTO} \ 26 | CONFIG.MMCM_DIVCLK_DIVIDE {1} \ 27 | CONFIG.MMCM_CLKFBOUT_MULT_F {8.000} \ 28 | CONFIG.MMCM_CLKIN1_PERIOD {8.000} \ 29 | CONFIG.MMCM_COMPENSATION {ZHOLD} \ 30 | CONFIG.MMCM_CLKOUT0_DIVIDE_F {40.000} \ 31 | CONFIG.MMCM_CLKOUT1_DIVIDE {80} \ 32 | CONFIG.MMCM_CLKOUT2_DIVIDE {100} \ 33 | CONFIG.NUM_OUT_CLKS {3} \ 34 | CONFIG.RESET_PORT {resetn} \ 35 | CONFIG.CLKOUT1_JITTER {165.419} \ 36 | CONFIG.CLKOUT1_PHASE_ERROR {96.948} \ 37 | CONFIG.CLKOUT2_JITTER {189.342} \ 38 | CONFIG.CLKOUT2_PHASE_ERROR {96.948}] [get_ips mmcm] 39 | } else { 40 | set_property -dict [list \ 41 | CONFIG.PRIMITIVE {MMCM} \ 42 | CONFIG.RESET_TYPE {ACTIVE_LOW} \ 43 | CONFIG.PRIMARY_PORT {clk_in} \ 44 | CONFIG.CLKOUT1_USED {true} \ 45 | CONFIG.CLKOUT2_USED {true} \ 46 | CONFIG.CLK_OUT1_PORT {core_clk} \ 47 | CONFIG.CLK_OUT2_PORT {periph_clk} \ 48 | CONFIG.CLKOUT1_REQUESTED_OUT_FREQ {30} \ 49 | CONFIG.CLKOUT2_REQUESTED_OUT_FREQ {15} \ 50 | ] [get_ips mmcm] 51 | } 52 | 53 | -------------------------------------------------------------------------------- /fpga/main/main.mk: -------------------------------------------------------------------------------- 1 | OUT_DIR := output 2 | export OUT_DIR 3 | 4 | .PHONY: all 5 | all: 6 | ifneq ($(wildcard ./$(OUT_DIR)/),) 7 | @echo "Project has already been build, nothing to do!"; 8 | else 9 | @mkdir $(OUT_DIR) 10 | @echo "Start building the $(PROJECT)...." 11 | # After tclargs, we add all the custom options by tcl arguments 12 | vivado -mode batch \ 13 | -notrace \ 14 | -nojournal \ 15 | -source tcl/run.tcl \ 16 | -log $(OUT_DIR)/console.log \ 17 | -tclargs \ 18 | -top-module "$(FPGA_WRAPPER)" \ 19 | -xil_board "$(XILINX_BOARD)" \ 20 | -xil_part "$(XILINX_PART)" \ 21 | -v "$(PRJ_FILES_V)" \ 22 | -F "$(PRJ_FILES_F)" \ 23 | -synth_mode "$(SYNTH_MODE)" 24 | endif 25 | 26 | .PHONY: mcs 27 | mcs: 28 | vivado -mode batch \ 29 | -notrace \ 30 | -nojournal \ 31 | -source tcl/write_cfgmem.tcl \ 32 | -log $(OUT_DIR)/console_mcs_gen.log \ 33 | -tclargs \ 34 | -xil_board "$(XILINX_TARGET)" \ 35 | -xil_part "$(XILINX_PART)" \ 36 | -mcsfile "$(OUT_DIR)/$(PROJECT_NAME).mcs" \ 37 | -bitfile "$(OUT_DIR)/$(PROJECT_NAME).bit"\ 38 | -datafile "" 39 | 40 | .PHONY: program_mcs 41 | program_mcs: 42 | vivado -mode batch \ 43 | -notrace \ 44 | -nojournal \ 45 | -source tcl/program_mcs.tcl \ 46 | -tclargs \ 47 | -mcs "$(OUT_DIR)/$(PROJECT_NAME).mcs" 48 | 49 | .PHONY: clean 50 | clean: 51 | ifneq ($(wildcard ./$(OUT_DIR)/),) 52 | @echo -n "Cleaning $(PROJECT)..." 53 | @rm -rf $(OUT_DIR) 54 | @rm -rf vivado* 55 | @rm -rf .Xil* 56 | else 57 | @echo "Nothing to clean at $(PROJECT)..." 58 | endif 59 | 60 | -------------------------------------------------------------------------------- /fpga/main/tcl/bitstream.tcl: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | # Write a bitstream for the current design 4 | write_bitstream -force [file join $wrkdir "${prj_name}.bit"] 5 | 6 | # Save the timing delays for cells in the design in SDF format 7 | write_sdf -force [file join $wrkdir "${prj_name}.sdf"] 8 | 9 | # Export the current netlist in verilog format 10 | write_verilog -mode timesim -force [file join ${wrkdir} "${prj_name}.v"] 11 | -------------------------------------------------------------------------------- /fpga/main/tcl/import.tcl: -------------------------------------------------------------------------------- 1 | puts "Adding tcl of IPs into the project..." 2 | 3 | set obj [current_fileset -constrset] 4 | 5 | add_files -quiet -norecurse -fileset $obj [lsort [glob -directory ../ips -nocomplain {*.tcl}]] 6 | 7 | puts "Adding files into the project..." 8 | 9 | set constraints_dir [file join ../constraints/ $part] 10 | 11 | set obj [current_fileset -constrset] 12 | 13 | puts "-----> Adding constraints files (.xdc)..." 14 | 15 | add_files -quiet -norecurse -fileset $obj [lsort [glob -directory $constraints_dir -nocomplain {*.xdc}]] 16 | 17 | set obj [current_fileset] 18 | 19 | puts "-----> Adding system/verilog files (.sv,.v)..." 20 | 21 | # Add verilog files standalone 22 | proc load_vsrc {obj vsrc_files} { 23 | foreach var $vsrc_files { 24 | puts " -> Adding $var" 25 | } 26 | add_files -norecurse -fileset $obj $vsrc_files 27 | } 28 | 29 | # Add verilog files from manifest 30 | proc load_vsrc_manifest {obj vsrc_manifest} { 31 | # For each manifest file (.F) do 32 | foreach manifest_file $vsrc_manifest { 33 | set abs_files {} 34 | # Reads the manifest file for get all .v or .sv 35 | set fp_verilog_files [open $manifest_file r] 36 | # Convert .v .sv into a list 37 | set files [lsearch -not -exact -all -inline [split [read $fp_verilog_files] "\n"] {}] 38 | # Get the dir of the manifest file (.F) 39 | set dir_verilog_files [file dirname [glob $manifest_file *.F]] 40 | foreach path $files { 41 | # Concatenate the directory of the manifest file (.F) with the file list (.v .sv) to have the abs path 42 | lappend abs_files $dir_verilog_files/$path 43 | } 44 | # Load the list of verilog files 45 | load_vsrc $obj $abs_files 46 | close $fp_verilog_files 47 | } 48 | } 49 | 50 | load_vsrc $obj $vsrc_files 51 | 52 | load_vsrc_manifest $obj $vsrc_manifest 53 | -------------------------------------------------------------------------------- /fpga/main/tcl/opt.tcl: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | # Optimize the netlist 4 | opt_design -directive Explore 5 | 6 | # Checkpoint the current design 7 | write_checkpoint -force [file join $wrkdir post_opt] 8 | -------------------------------------------------------------------------------- /fpga/main/tcl/place.tcl: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | # Place the current design 4 | place_design -directive Explore 5 | 6 | # Optimize the current placed netlist 7 | phys_opt_design -directive Explore 8 | 9 | # Optimize dynamic power using intelligent clock gating 10 | power_opt_design 11 | 12 | # Checkpoint the current design 13 | write_checkpoint -force [file join $wrkdir post_place] 14 | -------------------------------------------------------------------------------- /fpga/main/tcl/prep_ips.tcl: -------------------------------------------------------------------------------- 1 | # Helper function that recursively includes files given a directory and a 2 | # pattern/suffix extensions 3 | proc recglob { basedir pattern } { 4 | set dirlist [glob -nocomplain -directory $basedir -type d *] 5 | set findlist [glob -nocomplain -directory $basedir $pattern] 6 | foreach dir $dirlist { 7 | set reclist [recglob $dir $pattern] 8 | set findlist [concat $findlist $reclist] 9 | } 10 | return $findlist 11 | } 12 | 13 | # Helper function to find all subdirectories containing ".vh" files 14 | proc findincludedir { basedir pattern } { 15 | set vhfiles [recglob $basedir $pattern] 16 | set vhdirs {} 17 | foreach match $vhfiles { 18 | lappend vhdirs [file dir $match] 19 | } 20 | set uniquevhdirs [lsort -unique $vhdirs] 21 | return $uniquevhdirs 22 | } 23 | 24 | # Create the diretory for IPs 25 | file mkdir $ipdir 26 | 27 | # Update the IP catalog 28 | update_ip_catalog -rebuild 29 | 30 | # Generate IP implementations. Vivado TCL emitted from Chisel Blackboxes 31 | source ../ips/ips.tcl 32 | 33 | # AR 58526 34 | set xci_files [get_files -all {*.xci}] 35 | foreach xci_file $xci_files { 36 | set_property GENERATE_SYNTH_CHECKPOINT {false} -quiet $xci_file 37 | } 38 | 39 | # Get a list of IPs in the current design 40 | set obj [get_ips] 41 | 42 | # Generate target data for the included IPs in the design 43 | generate_target all $obj 44 | 45 | # Export the IP user files 46 | export_ip_user_files -of_objects $obj -no_script -force 47 | 48 | # Get the list of active source and constraint files 49 | set obj [current_fileset] 50 | -------------------------------------------------------------------------------- /fpga/main/tcl/program_mcs.tcl: -------------------------------------------------------------------------------- 1 | while {[llength $argv]} { 2 | set argv [lassign $argv[set argv {}] flag] 3 | switch -glob $flag { 4 | -mcs { 5 | set argv [lassign $argv[set argv {}] mcs] 6 | } 7 | default { 8 | return -code error [list {unknown option} $flag] 9 | } 10 | } 11 | } 12 | 13 | set hw_part $::env(HW_PART) 14 | set mem_part $::env(MEM_PART) 15 | 16 | puts "Configuration file used: $mcs" 17 | puts "Configuration hw part used: $hw_part" 18 | puts "Configuration mem part used: $mem_part" 19 | puts "Starting to connect with ARTIX A7 DIGILENT FPGA BOARD..." 20 | open_hw 21 | connect_hw_server 22 | open_hw_target 23 | current_hw_device [get_hw_devices $hw_part] 24 | refresh_hw_device -update_hw_probes false [lindex [get_hw_devices $hw_part] 0] 25 | 26 | puts "Creating the configuration file memory..." 27 | create_hw_cfgmem -hw_device [lindex [get_hw_devices $hw_part] 0] [lindex [get_cfgmem_parts $mem_part] 0] 28 | set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 29 | set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 30 | set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 31 | set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 32 | set_property PROGRAM.CHECKSUM 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 33 | refresh_hw_device [lindex [get_hw_devices $hw_part] 0] 34 | 35 | set_property PROGRAM.ADDRESS_RANGE {use_file} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 36 | set_property PROGRAM.FILES $mcs [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 37 | set_property PROGRAM.PRM_FILE {} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 38 | set_property PROGRAM.UNUSED_PIN_TERMINATION {pull-none} [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 39 | set_property PROGRAM.BLANK_CHECK 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 40 | set_property PROGRAM.ERASE 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 41 | set_property PROGRAM.CFG_PROGRAM 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 42 | set_property PROGRAM.VERIFY 1 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 43 | set_property PROGRAM.CHECKSUM 0 [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 44 | 45 | puts "Programming the SPI FLASH memory..." 46 | startgroup 47 | if {![string equal [get_property PROGRAM.HW_CFGMEM_TYPE [lindex [get_hw_devices $hw_part] 0]] [get_property MEM_TYPE [get_property CFGMEM_PART [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]]]]] } { create_hw_bitstream -hw_device [lindex [get_hw_devices $hw_part] 0] [get_property PROGRAM.HW_CFGMEM_BITFILE [ lindex [get_hw_devices $hw_part] 0]]; program_hw_devices [lindex [get_hw_devices $hw_part] 0]; }; 48 | program_hw_cfgmem -hw_cfgmem [ get_property PROGRAM.HW_CFGMEM [lindex [get_hw_devices $hw_part] 0]] 49 | endgroup 50 | -------------------------------------------------------------------------------- /fpga/main/tcl/report.tcl: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | # Create a report directory 4 | set rptdir [file join $wrkdir report] 5 | file mkdir $rptdir 6 | 7 | # Create a datasheet for the current design 8 | report_datasheet -file [file join $rptdir datasheet.txt] 9 | 10 | # Report utilization of the current device 11 | set rptutil [file join $rptdir utilization.txt] 12 | report_utilization -hierarchical -file $rptutil 13 | 14 | # Report information about clock nets in the design 15 | report_clock_utilization -file $rptutil -append 16 | 17 | # Report the RAM resources utilized in the implemented design 18 | report_ram_utilization -file $rptutil -append -detail 19 | 20 | # Report timing summary for a max of 10 paths per group 21 | report_timing_summary -file [file join $rptdir timing.txt] -max_paths 10 22 | 23 | # Report the highest fanout of nets in the implemented design 24 | report_high_fanout_nets -file [file join $rptdir fanout.txt] -timing -load_types -max_nets 25 25 | 26 | # Run DRC 27 | report_drc -file [file join $rptdir drc.txt] 28 | 29 | # Report details of the IO banks in the design 30 | report_io -file [file join $rptdir io.txt] 31 | 32 | # Report a table of all clocks in the design 33 | report_clocks -file [file join $rptdir clocks.txt] 34 | 35 | # Fail loudly if timing not met 36 | # 37 | # We would ideally elevate critical warning Route 35-39 to an error, but it is 38 | # currently not being emitted with our flow for some reason. 39 | # https://forums.xilinx.com/t5/Implementation/Making-timing-violations-fatal-to-the-Vivado-build/m-p/716957#M15979 40 | set timing_slack [get_property SLACK [get_timing_paths]] 41 | if {$timing_slack < 0} { 42 | puts "Failed to meet timing by $timing_slack, see [file join $rptdir timing.txt]" 43 | exit 1 44 | } 45 | -------------------------------------------------------------------------------- /fpga/main/tcl/route.tcl: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | # Route the current design 4 | route_design -directive Explore 5 | 6 | # Optimize the current design post routing 7 | phys_opt_design -directive Explore 8 | 9 | # Checkpoint the current design 10 | write_checkpoint -force [file join $wrkdir post_route] 11 | -------------------------------------------------------------------------------- /fpga/main/tcl/run.tcl: -------------------------------------------------------------------------------- 1 | set scriptdir [file dirname [info script]] 2 | 3 | # Create the and set working variables 4 | source [file join $scriptdir "start.tcl"] 5 | 6 | # Import all the RTL files 7 | source [file join $scriptdir "import.tcl"] 8 | 9 | # Initialize IPs building files 10 | source [file join $scriptdir "prep_ips.tcl"] 11 | 12 | # Synthesize the design 13 | source [file join $scriptdir "synthesis.tcl"] 14 | 15 | # Post synthesis optimization 16 | source [file join $scriptdir "opt.tcl"] 17 | 18 | # Place the design 19 | source [file join $scriptdir "place.tcl"] 20 | 21 | # Route the design 22 | source [file join $scriptdir "route.tcl"] 23 | 24 | # Generate bitstream and save verilog netlist 25 | source [file join $scriptdir "bitstream.tcl"] 26 | 27 | # Create reports for the current implementation 28 | source [file join $scriptdir "report.tcl"] 29 | -------------------------------------------------------------------------------- /fpga/main/tcl/start.tcl: -------------------------------------------------------------------------------- 1 | set prj_name $::env(PROJECT_NAME) 2 | 3 | set out_dir $::env(OUT_DIR) 4 | 5 | set inc_dir $::env(INCL_DIR) 6 | 7 | set macros_vlog $::env(MACROS_VLOG) 8 | 9 | # For +incdir+ 10 | set include_directories {} 11 | foreach var $inc_dir { 12 | puts " -> Including dir $var" 13 | lappend include_directories $var 14 | } 15 | 16 | # For +define+ 17 | set defined_macros {} 18 | foreach var $macros_vlog { 19 | puts " -> Adding verilog macro $var" 20 | lappend defined_macros $var 21 | } 22 | 23 | while {[llength $argv]} { 24 | set argv [lassign $argv[set argv {}] flag] 25 | switch -glob $flag { 26 | -top-module { 27 | set argv [lassign $argv[set argv {}] top] 28 | } 29 | -F { 30 | set argv [lassign $argv[set argv {}] vsrc_manifest] 31 | } 32 | -synth_mode { 33 | set argv [lassign $argv[set argv {}] synth_mode] 34 | } 35 | -v { 36 | set argv [lassign $argv[set argv {}] vsrc_files] 37 | } 38 | -xil_board { 39 | set argv [lassign $argv[set argv {}] board] 40 | } 41 | -xil_part { 42 | set argv [lassign $argv[set argv {}] part] 43 | } 44 | default { 45 | return -code error [list {unknown option} $flag] 46 | } 47 | } 48 | } 49 | 50 | if {![info exists synth_mode]} { 51 | return -code error [list {--synth_mode option is required}] 52 | } 53 | 54 | if {![info exists top]} { 55 | return -code error [list {--top-module option is required}] 56 | } 57 | 58 | if {![info exists board]} { 59 | return -code error [list {--xil_board option is required}] 60 | } 61 | 62 | if {![info exists part]} { 63 | return -code error [list {--xil_part option is required}] 64 | } 65 | 66 | # set tcl_files [glob $constraints_dir/*.xdc] 67 | 68 | # Creates a work directory 69 | set wrkdir [file join [pwd] $out_dir] 70 | 71 | # Creates a ip work directory 72 | set ipdir [file join $wrkdir ip] 73 | 74 | # Create an in-memory project 75 | puts "Creating project with name: $prj_name" 76 | 77 | create_project -part $part -force $wrkdir/$prj_name 78 | 79 | # Set the board part, target language, default library, and IP directory 80 | # paths for the current project 81 | set_property -dict [list \ 82 | BOARD_PART $board \ 83 | TARGET_LANGUAGE {Verilog} \ 84 | DEFAULT_LIB {xil_defaultlib} \ 85 | IP_REPO_PATHS $ipdir \ 86 | ] [current_project] 87 | 88 | puts "Creating fileset of sources..." 89 | 90 | if {[get_filesets -quiet sources_1] eq ""} { 91 | create_fileset -srcset sources_1 92 | } 93 | 94 | set obj [current_fileset] 95 | 96 | puts "Creating fileset of simulation..." 97 | 98 | if {[get_filesets -quiet sim_1] eq ""} { 99 | create_fileset -simset sim_1 100 | } 101 | 102 | set obj [current_fileset -simset] 103 | 104 | puts "Creating fileset of constraints..." 105 | 106 | if {[get_filesets -quiet constrs_1] eq ""} { 107 | create_fileset -constrset constrs_1 108 | } 109 | -------------------------------------------------------------------------------- /fpga/main/tcl/synthesis.tcl: -------------------------------------------------------------------------------- 1 | # Read the specified list of IP files 2 | read_ip [glob -directory $ipdir [file join * {*.xci}]] 3 | 4 | # Synthesize the design 5 | synth_design -top $top -flatten_hierarchy $synth_mode -include_dirs $include_directories -verilog_define $defined_macros 6 | 7 | # Checkpoint the current design 8 | write_checkpoint -force [file join $wrkdir post_synth] 9 | -------------------------------------------------------------------------------- /fpga/main/tcl/write_cfgmem.tcl: -------------------------------------------------------------------------------- 1 | # Create an MCS-format memory configuration file from a bitstream and an 2 | # optional data file. 3 | while {[llength $argv]} { 4 | set argv [lassign $argv[set argv {}] flag] 5 | switch -glob $flag { 6 | -xil_board { 7 | set argv [lassign $argv[set argv {}] board] 8 | } 9 | -xil_part { 10 | set argv [lassign $argv[set argv {}] part_fpga] 11 | } 12 | -mcsfile { 13 | set argv [lassign $argv[set argv {}] mcsfile] 14 | } 15 | -bitfile { 16 | set argv [lassign $argv[set argv {}] bitfile] 17 | } 18 | -datafile { 19 | set argv [lassign $argv[set argv {}] datafile] 20 | } 21 | default { 22 | return -code error [list {unknown option} $flag] 23 | } 24 | } 25 | } 26 | 27 | namespace eval ::program::boards {} 28 | 29 | set ::program::boards::spec [dict create \ 30 | arty [dict create iface spix4 size 16 bitaddr 0x0 memdev {n25q128-3.3v-spi-x1_x2_x4}] \ 31 | arty_a7_100 [dict create iface spix4 size 16 bitaddr 0x0 memdev {s25fl128sxxxxxx0-spi-x1_x2_x4}] \ 32 | vc707 [dict create iface bpix16 size 128 bitaddr 0x3000000 ] \ 33 | vcu118 [dict create iface spix8 size 256 bitaddr 0x0 memdev {mt25qu01g-spi-x1_x2_x4_x8}]] 34 | 35 | if {![dict exists $::program::boards::spec $board]} { 36 | puts {Unsupported board} 37 | exit 1 38 | } 39 | 40 | set board [dict get $::program::boards::spec $board] 41 | 42 | write_cfgmem -format mcs -interface [dict get $board iface] -size [dict get $board size] \ 43 | -loadbit "up [dict get $board bitaddr] $bitfile" \ 44 | -loaddata [expr {$datafile ne "" ? "up 0x400000 $datafile" : ""}] \ 45 | -file $mcsfile -force 46 | -------------------------------------------------------------------------------- /ips/utils/ahb3lite_if.sv: -------------------------------------------------------------------------------- 1 | interface ahb3lite_if #( 2 | parameter HADDR_SIZE = 32, 3 | parameter HDATA_SIZE = 32 4 | ); 5 | logic HSEL; 6 | logic [HADDR_SIZE -1:0] HADDR; 7 | logic [HDATA_SIZE -1:0] HWDATA; 8 | logic [HDATA_SIZE -1:0] HRDATA; 9 | logic HWRITE; 10 | logic [2:0] HSIZE; 11 | logic [2:0] HBURST; 12 | logic [3:0] HPROT; 13 | logic [1:0] HTRANS; 14 | logic HMASTLOCK; 15 | logic HREADY; 16 | logic HREADYOUT; 17 | logic HRESP; 18 | 19 | endinterface 20 | -------------------------------------------------------------------------------- /ips/utils/ahb_dummy.sv: -------------------------------------------------------------------------------- 1 | module ahb_dummy #( 2 | parameter HADDR_SIZE = 32, 3 | parameter HDATA_SIZE = 32 4 | ) 5 | ( 6 | input HRESETn, 7 | input HCLK, 8 | input HSEL, 9 | input [HADDR_SIZE-1:0] HADDR, 10 | input [HDATA_SIZE-1:0] HWDATA, 11 | output [HDATA_SIZE-1:0] HRDATA, 12 | input HWRITE, 13 | input [ 2:0] HSIZE, 14 | input [ 2:0] HBURST, 15 | input [ 3:0] HPROT, 16 | input [ 1:0] HTRANS, 17 | output HREADYOUT, 18 | input HREADY, 19 | output HRESP 20 | ); 21 | assign HRESP = 1'b0; 22 | assign HREADYOUT = 1'b1; 23 | assign HRDATA = 32'd0; 24 | endmodule 25 | -------------------------------------------------------------------------------- /ips/utils/ahb_ri5cy_rom.sv: -------------------------------------------------------------------------------- 1 | 2 | module ahb_ri5cy_rom # ( 3 | parameter AHB_ADDR_WIDTH = 32, 4 | parameter AHB_DATA_WIDTH = 32, 5 | parameter JTAG_BOOT = 0 6 | )( 7 | input clk, 8 | input rstn, 9 | // AHB slave signals 10 | input hsel_i, 11 | input [AHB_ADDR_WIDTH-1:0] haddr_i, 12 | input [AHB_DATA_WIDTH-1:0] hwdata_i, 13 | input hwrite_i, 14 | input [2:0] hsize_i, 15 | input [2:0] hburst_i, 16 | input [3:0] hprot_i, 17 | input [1:0] htrans_i, 18 | input hmastlock_i, 19 | input hready_i, 20 | output [AHB_DATA_WIDTH-1:0] hrdata_o, 21 | output hreadyout_o, 22 | output hresp_o 23 | ); 24 | localparam IDLE_HTRANS = 2'b00, 25 | BUSY_HTRANS = 2'b01, 26 | NONSEQ_HTRANS = 2'b10, 27 | SEQ_HTRANS = 2'b11; 28 | 29 | localparam BYTE = 3'b000, 30 | HALFWORD = 3'b001, 31 | WORD = 3'b010; 32 | 33 | localparam IDLE = 0, 34 | WAIT_REQ = 1, 35 | NEW_REQ = 2; 36 | 37 | logic req_o; 38 | logic [2:0] fsm_st, next_st; 39 | logic [31:0] rdata; 40 | 41 | assign hrdata_o = rdata; // Keep looping while(1) or READ from boot_rom 42 | assign hreadyout_o = 1'b1; 43 | assign hresp_o = 1'b0; 44 | 45 | always @ (posedge clk) begin 46 | if (~rstn) 47 | fsm_st <= IDLE; 48 | else 49 | fsm_st <= next_st; 50 | end 51 | 52 | always @ (*) begin 53 | case(fsm_st) 54 | IDLE: 55 | if (~hready_i) 56 | next_st = IDLE; 57 | else if (hsel_i) 58 | next_st = WAIT_REQ; 59 | else 60 | next_st = IDLE; 61 | WAIT_REQ: 62 | if (~hready_i) 63 | next_st = WAIT_REQ; 64 | else if (hsel_i) 65 | next_st = NEW_REQ; 66 | else 67 | next_st = IDLE; 68 | NEW_REQ: begin 69 | if (~hready_i) 70 | next_st = NEW_REQ; 71 | else if (hsel_i) 72 | next_st = WAIT_REQ; 73 | else 74 | next_st = IDLE; 75 | end 76 | default: begin 77 | next_st = IDLE; 78 | end 79 | endcase 80 | end 81 | 82 | always @ (*) begin 83 | case(fsm_st) 84 | IDLE: 85 | if (hready_i) 86 | if (hsel_i && ~hwrite_i) 87 | req_o = 1'b1; 88 | else 89 | req_o = 1'b0; 90 | else 91 | req_o = 1'b0; 92 | WAIT_REQ: req_o = 1'b1; 93 | NEW_REQ: req_o = 1'b1; 94 | default: req_o = 1'b0; 95 | endcase 96 | end 97 | 98 | // In verilator case we do not use boot_rom 99 | // cause we have elf bootloader 100 | `ifndef VERILATOR 101 | boot_rom_generic rom ( 102 | .rst_n(rstn), 103 | .clk(clk), 104 | .en(req_o), 105 | .raddr_i(haddr_i[15:0]), 106 | .dout_o(rdata) 107 | ); 108 | `else 109 | assign rdata = 'h6f; // While(true) 110 | `endif 111 | endmodule 112 | -------------------------------------------------------------------------------- /ips/utils/ahb_to_ri5cy.sv: -------------------------------------------------------------------------------- 1 | 2 | module ahb_to_ri5cy # ( 3 | parameter AHB_ADDR_WIDTH = 32, 4 | parameter AHB_DATA_WIDTH = 32 5 | )( 6 | input clk, 7 | input rstn, 8 | // Custom RI5CY memory interface 9 | output logic req_o, 10 | output logic we_o, 11 | output logic [3:0] be_o, 12 | output logic [31:0] addr_o, 13 | output logic [31:0] wdata_o, 14 | input [31:0] rdata_i, 15 | // AHB slave signals 16 | input hsel_i, 17 | input [AHB_ADDR_WIDTH-1:0] haddr_i, 18 | input [AHB_DATA_WIDTH-1:0] hwdata_i, 19 | input hwrite_i, 20 | input [2:0] hsize_i, 21 | input [2:0] hburst_i, 22 | input [3:0] hprot_i, 23 | input [1:0] htrans_i, 24 | input hmastlock_i, 25 | input hready_i, 26 | output [AHB_DATA_WIDTH-1:0] hrdata_o, 27 | output hreadyout_o, 28 | output hresp_o 29 | ); 30 | localparam IDLE_HTRANS = 2'b00, 31 | BUSY_HTRANS = 2'b01, 32 | NONSEQ_HTRANS = 2'b10, 33 | SEQ_HTRANS = 2'b11; 34 | 35 | localparam BYTE = 3'b000, 36 | HALFWORD = 3'b001, 37 | WORD = 3'b010; 38 | 39 | localparam IDLE = 0, 40 | WAIT_REQ = 1, 41 | NEW_REQ = 2, 42 | WRITE_REQ = 3; 43 | 44 | logic [2:0] fsm_st, next_st; 45 | logic [3:0] be; 46 | logic [3:0] be_saved; 47 | logic [31:0] haddr_saved; 48 | logic [31:0] hrdata_saved; 49 | logic rdata_mem, lock; 50 | 51 | assign wr_req = hsel_i && hwrite_i; 52 | assign rd_req = hsel_i && ~hwrite_i; 53 | assign hrdata_o = lock ? hrdata_saved : rdata_i; 54 | assign hreadyout_o = (fsm_st == WRITE_REQ) ? 1'b0 : 1'b1; 55 | assign hresp_o = 1'b0; 56 | 57 | always @ (*) begin 58 | case(fsm_st) 59 | WRITE_REQ: begin 60 | addr_o = haddr_saved; 61 | we_o = 1'b1; 62 | wdata_o = hwdata_i; 63 | be_o = be_saved; 64 | end 65 | default: begin 66 | addr_o = haddr_i; 67 | we_o = hwrite_i; 68 | wdata_o = hwdata_i; 69 | be_o = be; 70 | end 71 | endcase 72 | end 73 | 74 | always @ (posedge clk) begin 75 | if (rstn == 1'b0) begin 76 | be_saved <= 4'd0; 77 | haddr_saved <= 32'h0; 78 | hrdata_saved <= 32'h0; 79 | rdata_mem <= 1'b0; 80 | lock <= 1'b0; 81 | end 82 | else begin 83 | if (hsel_i == 1'b1) begin 84 | be_saved <= be; 85 | haddr_saved <= haddr_i; 86 | end 87 | 88 | if (rd_req) 89 | rdata_mem <= 1'b1; 90 | else 91 | rdata_mem <= 1'b0; 92 | 93 | if (~hready_i && rdata_mem && ~lock) begin 94 | hrdata_saved <= rdata_i; 95 | lock <= 1'b1; 96 | end 97 | 98 | if (hready_i) 99 | lock <= 1'b0; 100 | end 101 | end 102 | 103 | always @ (*) begin 104 | case (hsize_i) 105 | WORD: be = 4'b1111; 106 | HALFWORD: be = 4'b0011; 107 | BYTE: be = 4'b0001; 108 | default: be = 4'b0000; 109 | endcase 110 | end 111 | 112 | always @ (posedge clk) begin 113 | if (rstn == 1'b0) 114 | fsm_st <= IDLE; 115 | else 116 | if (hready_i == 1'b0 && 117 | fsm_st != IDLE && 118 | fsm_st != WRITE_REQ && 119 | next_st != WRITE_REQ) 120 | fsm_st <= fsm_st; // Wait.... 121 | else 122 | fsm_st <= next_st; // In this case, go ahead 123 | end 124 | 125 | always @ (*) begin 126 | case(fsm_st) 127 | IDLE: 128 | if (wr_req) 129 | next_st = WRITE_REQ; 130 | else if (rd_req) 131 | next_st = WAIT_REQ; 132 | else 133 | next_st = IDLE; 134 | WAIT_REQ: 135 | if (wr_req) 136 | next_st = WRITE_REQ; 137 | else if (rd_req) 138 | next_st = NEW_REQ; 139 | else 140 | next_st = IDLE; 141 | NEW_REQ: 142 | if (wr_req) 143 | next_st = WRITE_REQ; 144 | else if (rd_req) 145 | next_st = WAIT_REQ; 146 | else 147 | next_st = IDLE; 148 | WRITE_REQ: 149 | next_st = IDLE; 150 | default: begin 151 | next_st = IDLE; 152 | end 153 | endcase 154 | end 155 | 156 | always @ (*) begin 157 | case(fsm_st) 158 | IDLE: 159 | if (wr_req) 160 | req_o = 1'b0; 161 | else if (rd_req) 162 | req_o = 1'b1; 163 | else 164 | req_o = 1'b0; 165 | WAIT_REQ: 166 | if (wr_req) 167 | req_o = 1'b0; 168 | else if (rd_req) 169 | req_o = 1'b1; 170 | else 171 | req_o = 1'b0; 172 | NEW_REQ: 173 | if (wr_req) 174 | req_o = 1'b0; 175 | else if (rd_req) 176 | req_o = 1'b1; 177 | else 178 | req_o = 1'b0; 179 | WRITE_REQ: 180 | req_o = 1'b1; 181 | default: req_o = 1'b0; 182 | endcase 183 | end 184 | endmodule 185 | -------------------------------------------------------------------------------- /ips/utils/apb4_if.sv: -------------------------------------------------------------------------------- 1 | interface apb4_if # ( 2 | parameter PADDR_SIZE = 32, 3 | parameter PDATA_SIZE = 32 4 | ); 5 | logic PSEL; 6 | logic PENABLE; 7 | logic [2:0] PPROT; 8 | logic PWRITE; 9 | logic [PDATA_SIZE/8-1:0] PSTRB; 10 | logic [PADDR_SIZE-1:0] PADDR; 11 | logic [PDATA_SIZE-1:0] PWDATA; 12 | logic [PDATA_SIZE-1:0] PRDATA; 13 | logic PREADY; 14 | logic PSLVERR; 15 | 16 | endinterface 17 | -------------------------------------------------------------------------------- /ips/utils/apb_timer/LICENSE: -------------------------------------------------------------------------------- 1 | SOLDERPAD HARDWARE LICENSE version 0.51 2 | 3 | This license is based closely on the Apache License Version 2.0, but is not 4 | approved or endorsed by the Apache Foundation. A copy of the non-modified 5 | Apache License 2.0 can be found at http://www.apache.org/licenses/LICENSE-2.0. 6 | 7 | As this license is not currently OSI or FSF approved, the Licensor permits any 8 | Work licensed under this License, at the option of the Licensee, to be treated 9 | as licensed under the Apache License Version 2.0 (which is so approved). 10 | 11 | This License is licensed under the terms of this License and in particular 12 | clause 7 below (Disclaimer of Warranties) applies in relation to its use. 13 | 14 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 15 | 16 | 1. Definitions. 17 | 18 | “License” shall mean the terms and conditions for use, reproduction, and 19 | distribution as defined by Sections 1 through 9 of this document. 20 | 21 | “Licensor” shall mean the Rights owner or entity authorized by the Rights owner 22 | that is granting the License. 23 | 24 | “Legal Entity” shall mean the union of the acting entity and all other entities 25 | that control, are controlled by, or are under common control with that entity. 26 | For the purposes of this definition, “control” means (i) the power, direct or 27 | indirect, to cause the direction or management of such entity, whether by 28 | contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the 29 | outstanding shares, or (iii) beneficial ownership of such entity. 30 | 31 | “You” (or “Your”) shall mean an individual or Legal Entity exercising 32 | permissions granted by this License. 33 | 34 | “Rights” means copyright and any similar right including design right (whether 35 | registered or unregistered), semiconductor topography (mask) rights and 36 | database rights (but excluding Patents and Trademarks). 37 | 38 | “Source” form shall mean the preferred form for making modifications, including 39 | but not limited to source code, net lists, board layouts, CAD files, 40 | documentation source, and configuration files. 41 | 42 | “Object” form shall mean any form resulting from mechanical transformation or 43 | translation of a Source form, including but not limited to compiled object 44 | code, generated documentation, the instantiation of a hardware design and 45 | conversions to other media types, including intermediate forms such as 46 | bytecodes, FPGA bitstreams, artwork and semiconductor topographies (mask 47 | works). 48 | 49 | “Work” shall mean the work of authorship, whether in Source form or other 50 | Object form, made available under the License, as indicated by a Rights notice 51 | that is included in or attached to the work (an example is provided in the 52 | Appendix below). 53 | 54 | “Derivative Works” shall mean any work, whether in Source or Object form, that 55 | is based on (or derived from) the Work and for which the editorial revisions, 56 | annotations, elaborations, or other modifications represent, as a whole, an 57 | original work of authorship. For the purposes of this License, Derivative Works 58 | shall not include works that remain separable from, or merely link (or bind by 59 | name) or physically connect to or interoperate with the interfaces of, the Work 60 | and Derivative Works thereof. 61 | 62 | “Contribution” shall mean any design or work of authorship, including the 63 | original version of the Work and any modifications or additions to that Work or 64 | Derivative Works thereof, that is intentionally submitted to Licensor for 65 | inclusion in the Work by the Rights owner or by an individual or Legal Entity 66 | authorized to submit on behalf of the Rights owner. For the purposes of this 67 | definition, “submitted” means any form of electronic, verbal, or written 68 | communication sent to the Licensor or its representatives, including but not 69 | limited to communication on electronic mailing lists, source code control 70 | systems, and issue tracking systems that are managed by, or on behalf of, the 71 | Licensor for the purpose of discussing and improving the Work, but excluding 72 | communication that is conspicuously marked or otherwise designated in writing 73 | by the Rights owner as “Not a Contribution.” 74 | 75 | “Contributor” shall mean Licensor and any individual or Legal Entity on behalf 76 | of whom a Contribution has been received by Licensor and subsequently 77 | incorporated within the Work. 78 | 79 | 2. Grant of License. Subject to the terms and conditions of this License, each 80 | Contributor hereby grants to You a perpetual, worldwide, non-exclusive, 81 | no-charge, royalty-free, irrevocable license under the Rights to reproduce, 82 | prepare Derivative Works of, publicly display, publicly perform, sublicense, 83 | and distribute the Work and such Derivative Works in Source or Object form and 84 | do anything in relation to the Work as if the Rights did not exist. 85 | 86 | 3. Grant of Patent License. Subject to the terms and conditions of this 87 | License, each Contributor hereby grants to You a perpetual, worldwide, 88 | non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this 89 | section) patent license to make, have made, use, offer to sell, sell, import, 90 | and otherwise transfer the Work, where such license applies only to those 91 | patent claims licensable by such Contributor that are necessarily infringed by 92 | their Contribution(s) alone or by combination of their Contribution(s) with the 93 | Work to which such Contribution(s) was submitted. If You institute patent 94 | litigation against any entity (including a cross-claim or counterclaim in a 95 | lawsuit) alleging that the Work or a Contribution incorporated within the Work 96 | constitutes direct or contributory patent infringement, then any patent 97 | licenses granted to You under this License for that Work shall terminate as of 98 | the date such litigation is filed. 99 | 100 | 4. Redistribution. You may reproduce and distribute copies of the Work or 101 | Derivative Works thereof in any medium, with or without modifications, and in 102 | Source or Object form, provided that You meet the following conditions: 103 | 104 | You must give any other recipients of the Work or Derivative Works a copy 105 | of this License; and 106 | 107 | You must cause any modified files to carry prominent notices stating that 108 | You changed the files; and 109 | 110 | You must retain, in the Source form of any Derivative Works that You 111 | distribute, all copyright, patent, trademark, and attribution notices from 112 | the Source form of the Work, excluding those notices that do not pertain to 113 | any part of the Derivative Works; and 114 | 115 | If the Work includes a “NOTICE” text file as part of its distribution, then 116 | any Derivative Works that You distribute must include a readable copy of 117 | the attribution notices contained within such NOTICE file, excluding those 118 | notices that do not pertain to any part of the Derivative Works, in at 119 | least one of the following places: within a NOTICE text file distributed as 120 | part of the Derivative Works; within the Source form or documentation, if 121 | provided along with the Derivative Works; or, within a display generated by 122 | the Derivative Works, if and wherever such third-party notices normally 123 | appear. The contents of the NOTICE file are for informational purposes only 124 | and do not modify the License. You may add Your own attribution notices 125 | within Derivative Works that You distribute, alongside or as an addendum to 126 | the NOTICE text from the Work, provided that such additional attribution 127 | notices cannot be construed as modifying the License. You may add Your own 128 | copyright statement to Your modifications and may provide additional or 129 | different license terms and conditions for use, reproduction, or 130 | distribution of Your modifications, or for any such Derivative Works as a 131 | whole, provided Your use, reproduction, and distribution of the Work 132 | otherwise complies with the conditions stated in this License. 133 | 134 | 5. Submission of Contributions. Unless You explicitly state otherwise, any 135 | Contribution intentionally submitted for inclusion in the Work by You to the 136 | Licensor shall be under the terms and conditions of this License, without any 137 | additional terms or conditions. Notwithstanding the above, nothing herein shall 138 | supersede or modify the terms of any separate license agreement you may have 139 | executed with Licensor regarding such Contributions. 140 | 141 | 6. Trademarks. This License does not grant permission to use the trade names, 142 | trademarks, service marks, or product names of the Licensor, except as required 143 | for reasonable and customary use in describing the origin of the Work and 144 | reproducing the content of the NOTICE file. 145 | 146 | 7. Disclaimer of Warranty. Unless required by applicable law or agreed to in 147 | writing, Licensor provides the Work (and each Contributor provides its 148 | Contributions) on an “AS IS” BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 149 | KIND, either express or implied, including, without limitation, any warranties 150 | or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 151 | PARTICULAR PURPOSE. You are solely responsible for determining the 152 | appropriateness of using or redistributing the Work and assume any risks 153 | associated with Your exercise of permissions under this License. 154 | 155 | 8. Limitation of Liability. In no event and under no legal theory, whether in 156 | tort (including negligence), contract, or otherwise, unless required by 157 | applicable law (such as deliberate and grossly negligent acts) or agreed to in 158 | writing, shall any Contributor be liable to You for damages, including any 159 | direct, indirect, special, incidental, or consequential damages of any 160 | character arising as a result of this License or out of the use or inability to 161 | use the Work (including but not limited to damages for loss of goodwill, work 162 | stoppage, computer failure or malfunction, or any and all other commercial 163 | damages or losses), even if such Contributor has been advised of the 164 | possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing the Work or 167 | Derivative Works thereof, You may choose to offer, and charge a fee for, 168 | acceptance of support, warranty, indemnity, or other liability obligations 169 | and/or rights consistent with this License. However, in accepting such 170 | obligations, You may act only on Your own behalf and on Your sole 171 | responsibility, not on behalf of any other Contributor, and only if You agree 172 | to indemnify, defend, and hold each Contributor harmless for any liability 173 | incurred by, or claims asserted against, such Contributor by reason of your 174 | accepting any such warranty or additional liability. 175 | 176 | END OF TERMS AND CONDITIONS 177 | -------------------------------------------------------------------------------- /ips/utils/apb_timer/README.md: -------------------------------------------------------------------------------- 1 | # APB Timer 2 | 3 | This unit provides a simple timer via the APB bus. 4 | It supports an arbitrary number of 32-bit wide timers. Each timer has three 5 | registers, the timer register, the timer compare register and the timer control 6 | register. 7 | -------------------------------------------------------------------------------- /ips/utils/apb_timer/apb_timer.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2015 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | `define REGS_MAX_ADR_TIMER 2'd2 12 | 13 | module apb_timer 14 | #( 15 | parameter APB_ADDR_WIDTH = 12, //APB slaves are 4KB by default 16 | parameter TIMER_CNT = 2 // how many timers should be instantiated 17 | ) 18 | ( 19 | input logic HCLK, 20 | input logic HRESETn, 21 | input logic [APB_ADDR_WIDTH-1:0] PADDR, 22 | input logic [31:0] PWDATA, 23 | input logic PWRITE, 24 | input logic PSEL, 25 | input logic PENABLE, 26 | output logic [31:0] PRDATA, 27 | output logic PREADY, 28 | output logic PSLVERR, 29 | 30 | output logic [(TIMER_CNT * 2) - 1:0] irq_o // overflow and cmp interrupt 31 | ); 32 | 33 | logic [TIMER_CNT-1:0] psel_int, pready, pslverr; 34 | logic [$clog2(TIMER_CNT) - 1:0] slave_address_int; 35 | logic [TIMER_CNT-1:0] [31:0] prdata; 36 | 37 | assign slave_address_int = PADDR[$clog2(TIMER_CNT)+ `REGS_MAX_ADR_TIMER + 1:`REGS_MAX_ADR_TIMER + 2]; 38 | 39 | always_comb 40 | begin 41 | psel_int = '0; 42 | psel_int[slave_address_int] = PSEL; 43 | end 44 | 45 | // output mux 46 | always_comb 47 | begin 48 | 49 | if (psel_int != '0) 50 | begin 51 | PRDATA = prdata[slave_address_int]; 52 | PREADY = pready[slave_address_int]; 53 | PSLVERR = pslverr[slave_address_int]; 54 | end 55 | else 56 | begin 57 | PRDATA = '0; 58 | PREADY = 1'b1; 59 | PSLVERR = 1'b0; 60 | end 61 | end 62 | 63 | 64 | genvar k; 65 | 66 | generate 67 | for(k = 0; k < TIMER_CNT; k++) 68 | begin : TIMER_GEN 69 | timer timer_i 70 | ( 71 | .HCLK ( HCLK ), 72 | .HRESETn ( HRESETn ), 73 | 74 | .PADDR ( PADDR ), 75 | .PWDATA ( PWDATA ), 76 | .PWRITE ( PWRITE ), 77 | .PSEL ( psel_int[k] ), 78 | .PENABLE ( PENABLE ), 79 | .PRDATA ( prdata[k] ), 80 | .PREADY ( pready[k] ), 81 | .PSLVERR ( pslverr[k] ), 82 | 83 | .irq_o ( irq_o[2*k+1 : 2*k] ) 84 | ); 85 | end 86 | endgenerate 87 | endmodule 88 | -------------------------------------------------------------------------------- /ips/utils/apb_timer/src_files.yml: -------------------------------------------------------------------------------- 1 | apb_timer: 2 | files: [ 3 | apb_timer.sv, 4 | timer.sv, 5 | ] 6 | -------------------------------------------------------------------------------- /ips/utils/apb_timer/timer.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2015 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | // define three registers per timer - timer, cmp and prescaler registers 12 | `define REGS_MAX_IDX_TIMER 'd2 13 | `define REG_TIMER 2'b00 14 | `define REG_TIMER_CTRL 2'b01 15 | `define REG_CMP 2'b10 16 | `define PRESCALER_STARTBIT 'd3 17 | `define PRESCALER_STOPBIT 'd5 18 | `define ENABLE_BIT 'd0 19 | 20 | module timer 21 | #( 22 | parameter APB_ADDR_WIDTH = 12 //APB slaves are 4KB by default 23 | ) 24 | ( 25 | input logic HCLK, 26 | input logic HRESETn, 27 | input logic [APB_ADDR_WIDTH-1:0] PADDR, 28 | input logic [31:0] PWDATA, 29 | input logic PWRITE, 30 | input logic PSEL, 31 | input logic PENABLE, 32 | output logic [31:0] PRDATA, 33 | output logic PREADY, 34 | output logic PSLVERR, 35 | 36 | output logic [1:0] irq_o // overflow and cmp interrupt 37 | ); 38 | 39 | // APB register interface 40 | logic [`REGS_MAX_IDX_TIMER-1:0] register_adr; 41 | assign register_adr = PADDR[`REGS_MAX_IDX_TIMER + 2:2]; 42 | // APB logic: we are always ready to capture the data into our regs 43 | // not supporting transfare failure 44 | assign PREADY = 1'b1; 45 | assign PSLVERR = 1'b0; 46 | // registers 47 | logic [0:`REGS_MAX_IDX_TIMER] [31:0] regs_q, regs_n; 48 | logic [31:0] cycle_counter_n, cycle_counter_q; 49 | 50 | logic [2:0] prescaler_int; 51 | 52 | //irq logic 53 | always_comb 54 | begin 55 | irq_o = 2'b0; 56 | 57 | // overlow irq 58 | if (regs_q[`REG_TIMER] == 32'hffff_ffff) 59 | irq_o[0] = 1'b1; 60 | 61 | // compare match irq if compare reg ist set 62 | if (regs_q[`REG_CMP] != 'b0 && regs_q[`REG_TIMER] == regs_q[`REG_CMP]) 63 | irq_o[1] = 1'b1; 64 | 65 | end 66 | 67 | assign prescaler_int = regs_q[`REG_TIMER_CTRL][`PRESCALER_STOPBIT:`PRESCALER_STARTBIT]; 68 | // register write logic 69 | always_comb 70 | begin 71 | regs_n = regs_q; 72 | cycle_counter_n = cycle_counter_q + 1; 73 | 74 | // reset timer after cmp or overflow 75 | if (irq_o[0] == 1'b1 || irq_o[1] == 1'b1) 76 | regs_n[`REG_TIMER] = 1'b0; 77 | else if(regs_q[`REG_TIMER_CTRL][`ENABLE_BIT] && prescaler_int != 'b0 && prescaler_int == cycle_counter_q) // prescaler 78 | begin 79 | regs_n[`REG_TIMER] = regs_q[`REG_TIMER] + 1; //prescaler mode 80 | end 81 | else if (regs_q[`REG_TIMER_CTRL][`ENABLE_BIT] && regs_q[`REG_TIMER_CTRL][`PRESCALER_STOPBIT:`PRESCALER_STARTBIT] == 'b0) // normal count mode 82 | regs_n[`REG_TIMER] = regs_q[`REG_TIMER] + 1; 83 | 84 | // reset prescaler cycle counter 85 | if (cycle_counter_q >= regs_q[`REG_TIMER_CTRL]) 86 | cycle_counter_n = 32'b0; 87 | 88 | // written from APB bus - gets priority 89 | if (PSEL && PENABLE && PWRITE) 90 | begin 91 | 92 | case (register_adr) 93 | `REG_TIMER: 94 | regs_n[`REG_TIMER] = PWDATA; 95 | 96 | `REG_TIMER_CTRL: 97 | regs_n[`REG_TIMER_CTRL] = PWDATA; 98 | 99 | `REG_CMP: 100 | begin 101 | regs_n[`REG_CMP] = PWDATA; 102 | regs_n[`REG_TIMER] = 32'b0; // reset timer if compare register is written 103 | end 104 | endcase 105 | end 106 | end 107 | 108 | // APB register read logic 109 | always_comb 110 | begin 111 | PRDATA = 'b0; 112 | 113 | if (PSEL && PENABLE && !PWRITE) 114 | begin 115 | 116 | case (register_adr) 117 | `REG_TIMER: 118 | PRDATA = regs_q[`REG_TIMER]; 119 | 120 | `REG_TIMER_CTRL: 121 | PRDATA = regs_q[`REG_TIMER_CTRL]; 122 | 123 | `REG_CMP: 124 | PRDATA = regs_q[`REG_CMP]; 125 | endcase 126 | 127 | end 128 | end 129 | // synchronouse part 130 | always_ff @(posedge HCLK, negedge HRESETn) 131 | begin 132 | if(~HRESETn) 133 | begin 134 | regs_q <= '{default: 32'b0}; 135 | cycle_counter_q <= 32'b0; 136 | end 137 | else 138 | begin 139 | regs_q <= regs_n; 140 | cycle_counter_q <= cycle_counter_n; 141 | end 142 | end 143 | 144 | 145 | endmodule 146 | -------------------------------------------------------------------------------- /ips/utils/cluster_clock_inverter.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | module cluster_clock_inverter 12 | ( 13 | input logic clk_i, 14 | output logic clk_o 15 | ); 16 | 17 | assign clk_o = ~clk_i; 18 | 19 | endmodule 20 | -------------------------------------------------------------------------------- /ips/utils/filter_oor.sv: -------------------------------------------------------------------------------- 1 | `include "config_soc.v" 2 | 3 | module filter_oor ( 4 | input [31:0] addr_i, 5 | input input_sel_i, 6 | output valid_o, 7 | output error_o 8 | ); 9 | logic enable_valid; 10 | logic [`AHB_SLAVES_NUM-1:0] en_addr; 11 | 12 | assign valid_o = enable_valid ? input_sel_i : '0; 13 | assign error_o = input_sel_i && ~enable_valid; 14 | 15 | genvar i; 16 | generate 17 | for (i=0; i < `AHB_SLAVES_NUM; i++) begin 18 | assign en_addr[i] = (addr_i >= ahb_addr[0][i] && addr_i <= ahb_addr[1][i]) ? 1'b1 : 1'b0; 19 | end 20 | endgenerate 21 | 22 | always @ (*) begin 23 | if (input_sel_i && |en_addr) begin 24 | enable_valid = 1; 25 | end 26 | else begin 27 | enable_valid = 0; 28 | end 29 | end 30 | endmodule 31 | 32 | -------------------------------------------------------------------------------- /ips/utils/io_generic_fifo.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | module io_generic_fifo 12 | #( 13 | parameter DATA_WIDTH = 32, 14 | parameter BUFFER_DEPTH = 16, 15 | parameter LOG_BUFFER_DEPTH = $clog2(BUFFER_DEPTH) 16 | ) 17 | ( 18 | input logic clk_i, 19 | input logic rstn_i, 20 | 21 | input logic clr_i, 22 | 23 | output logic [LOG_BUFFER_DEPTH:0] elements_o, 24 | 25 | output logic [DATA_WIDTH-1 : 0] data_o, 26 | output logic valid_o, 27 | input logic ready_i, 28 | 29 | input logic valid_i, 30 | input logic [DATA_WIDTH-1 : 0] data_i, 31 | output logic ready_o 32 | ); 33 | 34 | // Internal data structures 35 | /* verilator lint_off WIDTH */ 36 | logic [LOG_BUFFER_DEPTH-1:0] pointer_in; // location to which we last wrote 37 | logic [LOG_BUFFER_DEPTH-1:0] pointer_out; // location from which we last sent 38 | /* lint_off */ 39 | logic [LOG_BUFFER_DEPTH:0] elements; // number of elements in the buffer 40 | logic [DATA_WIDTH-1:0] buffer [BUFFER_DEPTH - 1 : 0]; 41 | 42 | logic full; 43 | 44 | int unsigned loop1; 45 | 46 | assign full = (elements == BUFFER_DEPTH); 47 | assign elements_o = elements; 48 | 49 | always_ff @(posedge clk_i, negedge rstn_i) 50 | begin: elements_sequential 51 | if (rstn_i == 1'b0) 52 | elements <= 0; 53 | else 54 | begin 55 | if (clr_i) 56 | elements <= 0; 57 | else 58 | begin 59 | // ------------------ 60 | // Are we filling up? 61 | // ------------------ 62 | // One out, none in 63 | if (ready_i && valid_o && (!valid_i || full)) 64 | elements <= elements - 1; 65 | // None out, one in 66 | else if ((!valid_o || !ready_i) && valid_i && !full) 67 | elements <= elements + 1; 68 | // Else, either one out and one in, or none out and none in - stays unchanged 69 | end 70 | end 71 | end 72 | 73 | genvar i; 74 | always_ff @(posedge clk_i, negedge rstn_i) 75 | begin: buffers_sequential 76 | if (rstn_i == 1'b0) 77 | begin 78 | // for (loop1 = 0 ; loop1 < BUFFER_DEPTH ; loop1 = loop1 + 1) 79 | buffer[0] <= 'h0; 80 | buffer[1] <= 'h0; 81 | buffer[2] <= 'h0; 82 | buffer[3] <= 'h0; 83 | buffer[4] <= 'h0; 84 | buffer[5] <= 'h0; 85 | buffer[6] <= 'h0; 86 | buffer[7] <= 'h0; 87 | buffer[8] <= 'h0; 88 | buffer[9] <= 'h0; 89 | buffer[10] <= 'h0; 90 | buffer[11] <= 'h0; 91 | buffer[12] <= 'h0; 92 | buffer[13] <= 'h0; 93 | buffer[14] <= 'h0; 94 | buffer[15] <= 'h0; 95 | end 96 | else 97 | begin 98 | // Update the memory 99 | if (valid_i && !full) 100 | buffer[pointer_in] <= data_i; 101 | end 102 | end 103 | 104 | always_ff @(posedge clk_i, negedge rstn_i) 105 | begin: sequential 106 | if (rstn_i == 1'b0) 107 | begin 108 | pointer_out <= 0; 109 | pointer_in <= 0; 110 | end 111 | else 112 | begin 113 | if(clr_i) 114 | begin 115 | pointer_out <= 0; 116 | pointer_in <= 0; 117 | end 118 | else 119 | begin 120 | // ------------------------------------ 121 | // Check what to do with the input side 122 | // ------------------------------------ 123 | // We have some input, increase by 1 the input pointer 124 | if (valid_i && !full) 125 | begin 126 | if (pointer_in == $unsigned(BUFFER_DEPTH - 1)) 127 | pointer_in <= 0; 128 | else 129 | pointer_in <= pointer_in + 1; 130 | end 131 | // Else we don't have any input, the input pointer stays the same 132 | 133 | // ------------------------------------- 134 | // Check what to do with the output side 135 | // ------------------------------------- 136 | // We had pushed one flit out, we can try to go for the next one 137 | if (ready_i && valid_o) 138 | begin 139 | if (pointer_out == $unsigned(BUFFER_DEPTH - 1)) 140 | pointer_out <= 0; 141 | else 142 | pointer_out <= pointer_out + 1; 143 | end 144 | // Else stay on the same output location 145 | end 146 | end 147 | end 148 | 149 | // Update output ports 150 | assign data_o = buffer[pointer_out]; 151 | assign valid_o = (elements != 0); 152 | 153 | assign ready_o = ~full; 154 | 155 | endmodule 156 | -------------------------------------------------------------------------------- /ips/utils/pulp_clock_mux2.sv: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | module pulp_clock_mux2 12 | ( 13 | input logic clk0_i, 14 | input logic clk1_i, 15 | input logic clk_sel_i, 16 | output logic clk_o 17 | ); 18 | 19 | always_comb 20 | begin 21 | if (clk_sel_i == 1'b0) 22 | clk_o = clk0_i; 23 | else 24 | clk_o = clk1_i; 25 | end 26 | 27 | endmodule 28 | -------------------------------------------------------------------------------- /ips/utils/ri5cy_to_ahb.sv: -------------------------------------------------------------------------------- 1 | 2 | module ri5cy_to_ahb # ( 3 | parameter AHB_ADDR_WIDTH = 32, 4 | parameter AHB_DATA_WIDTH = 32 5 | )( 6 | input clk, 7 | input rstn, 8 | // Custom RI5CY memory interface 9 | input req_i, 10 | input we_i, 11 | input [3:0] be_i, 12 | input [31:0] addr_i, 13 | input [31:0] wdata_i, 14 | output gnt_o, 15 | output rvalid_o, 16 | output [31:0] rdata_o, 17 | // AHB master signals 18 | output hsel_o, 19 | output [AHB_ADDR_WIDTH-1:0] haddr_o, 20 | output [AHB_DATA_WIDTH-1:0] hwdata_o, 21 | output hwrite_o, 22 | output [2:0] hsize_o, 23 | output [2:0] hburst_o, 24 | output [3:0] hprot_o, 25 | output [1:0] htrans_o, 26 | output hmastlock_o, 27 | output hready_o, 28 | input [AHB_DATA_WIDTH-1:0] hrdata_i, 29 | input hreadyout_i, 30 | input hresp_i 31 | ); 32 | localparam IDLE_HTRANS = 2'b00, 33 | BUSY_HTRANS = 2'b01, 34 | NONSEQ_HTRANS = 2'b10, 35 | SEQ_HTRANS = 2'b11; 36 | 37 | localparam BYTE = 3'b000, 38 | HALFWORD = 3'b001, 39 | WORD = 3'b010; 40 | 41 | localparam IDLE = 0, 42 | WAIT_REQ = 1, 43 | NEW_REQ = 2; 44 | 45 | logic rvalid, rvalid_en; 46 | logic [2:0] hsize; 47 | logic [31:0] haddr, hwdata_tmp, hwmask; 48 | logic error_on_transfer; 49 | logic [2:0] fsm_st, next_st; 50 | 51 | assign hprot_o = 4'b0011; // If a master is not capable of generating accurate 52 | // protection information, ARM Limited the master 53 | // sets HPROT_o to b0011 to correspond to a non-cacheable, 54 | // non-bufferable, privileged, data access recommends that: 55 | assign hmastlock_o = 1'b0; // If the master requires locked accesses then it must also 56 | // assert the HMASTLOCK_o signal. This signal indicates to any 57 | // slave that the current transfer sequence is indivisible 58 | // and must therefore be processed before any other transact 59 | // ions are processed. After a locked transfer, it is recomm 60 | // ended that the master inserts an IDLE transfer. 61 | assign htrans_o = (req_i) ? NONSEQ_HTRANS : IDLE_HTRANS; // We use just single non-sequential transfer or idle htrans 62 | // Indicates that no data transfer is required. A master uses 63 | // an IDLE transfer when it does not want to perform a data 64 | // transfer. 65 | 66 | assign error_on_transfer = hresp_i; 67 | assign haddr = addr_i; 68 | assign gnt_o = req_i; 69 | assign hready_o = hreadyout_i; 70 | assign hburst_o = 3'b000; // Always single burst 71 | assign hwrite_o = we_i; 72 | assign hsize_o = hsize; 73 | assign haddr_o = haddr; 74 | assign hwdata_o = hwdata_tmp; 75 | assign hsel_o = req_i; 76 | assign rvalid_o = rvalid; 77 | assign rdata_o = hrdata_i; 78 | 79 | genvar i; 80 | for (i=0;i<4;i++) begin 81 | assign hwmask[i*8+:8] = {8{be_i[i]}} & wdata_i[i*8+:8]; 82 | end 83 | 84 | always @ (*) begin 85 | if (be_i == 4'b1111 || be_i == 4'b1110) begin 86 | hsize = WORD; 87 | end 88 | else if (be_i == 4'b0011 || be_i == 4'b0110 || be_i == 4'b1100) begin 89 | hsize = HALFWORD; 90 | end 91 | else begin 92 | hsize = BYTE; 93 | end 94 | end 95 | 96 | always @ (posedge clk) begin 97 | if (~rstn) 98 | fsm_st <= IDLE; 99 | else 100 | fsm_st <= next_st; 101 | end 102 | 103 | always @ (*) begin 104 | case(fsm_st) 105 | IDLE: 106 | if (~hreadyout_i) 107 | next_st = IDLE; 108 | else if (req_i) 109 | next_st = WAIT_REQ; 110 | else 111 | next_st = IDLE; 112 | WAIT_REQ: 113 | if (~hreadyout_i) 114 | next_st = WAIT_REQ; 115 | else if (req_i) 116 | next_st = NEW_REQ; 117 | else 118 | next_st = IDLE; 119 | NEW_REQ: begin 120 | if (~hreadyout_i) 121 | next_st = NEW_REQ; 122 | else if (req_i) 123 | next_st = WAIT_REQ; 124 | else 125 | next_st = IDLE; 126 | end 127 | default: begin 128 | next_st = IDLE; 129 | end 130 | endcase 131 | end 132 | 133 | always @ (posedge clk) begin 134 | if (~rstn) begin 135 | hwdata_tmp <= 32'h0; 136 | end 137 | else begin 138 | if (req_i && hreadyout_i) 139 | hwdata_tmp <= hwmask; 140 | end 141 | end 142 | 143 | always @ (*) begin 144 | case(fsm_st) 145 | IDLE: 146 | rvalid = 1'b0; 147 | WAIT_REQ: 148 | if (hreadyout_i == 1'b0) 149 | rvalid = 1'b0; 150 | else 151 | rvalid = 1'b1; 152 | NEW_REQ: 153 | if (hreadyout_i == 1'b0) 154 | rvalid = 1'b0; 155 | else 156 | rvalid = 1'b1; 157 | default: 158 | rvalid = 1'b0; 159 | endcase 160 | end 161 | endmodule 162 | -------------------------------------------------------------------------------- /ips/utils/rst_ctrl_unit.sv: -------------------------------------------------------------------------------- 1 | module rst_ctrl_unit # ( 2 | parameter PADDR_SIZE = 32, 3 | parameter PDATA_SIZE = 32, 4 | parameter DEFAULT_BOOT_ADDR = 32'h1A00_0000 5 | )( 6 | input PCLK, 7 | input RESETn, 8 | // AHB slave signals 9 | input PSEL, 10 | input PENABLE, 11 | input [PADDR_SIZE-1:0] PADDR, 12 | input [PDATA_SIZE-1:0] PWDATA, 13 | input PWRITE, 14 | output [PDATA_SIZE-1:0] PRDATA, 15 | output PREADY, 16 | output PSLVERR, 17 | output [31:0] rst_addr_o 18 | ); 19 | localparam IDLE = 0, 20 | WAIT_REQ = 1, 21 | NEW_REQ = 2; 22 | 23 | logic req; 24 | logic [2:0] fsm_st, next_st; 25 | logic [31:0] rst_addr; 26 | logic want_write; 27 | 28 | assign rst_addr_o = rst_addr; 29 | assign PRDATA = rst_addr; 30 | assign PREADY = 1'b1; 31 | assign PSLVERR = 1'b0; 32 | 33 | always @ (posedge PCLK) begin 34 | if (~RESETn) 35 | fsm_st <= IDLE; 36 | else 37 | fsm_st <= next_st; 38 | end 39 | 40 | always @ (*) begin 41 | case(fsm_st) 42 | IDLE: 43 | if (PSEL) 44 | next_st = WAIT_REQ; 45 | else 46 | next_st = IDLE; 47 | WAIT_REQ: 48 | if (PSEL) 49 | next_st = NEW_REQ; 50 | else 51 | next_st = IDLE; 52 | NEW_REQ: begin 53 | if (PSEL) 54 | next_st = WAIT_REQ; 55 | else 56 | next_st = IDLE; 57 | end 58 | default: begin 59 | next_st = IDLE; 60 | end 61 | endcase 62 | end 63 | 64 | always @ (*) begin 65 | case(fsm_st) 66 | IDLE: 67 | if (PSEL && ~PWRITE) 68 | req = 1'b1; 69 | else 70 | req = 1'b0; 71 | WAIT_REQ: req = 1'b1; 72 | NEW_REQ: req = 1'b1; 73 | default: req = 1'b0; 74 | endcase 75 | end 76 | 77 | always @ (posedge PCLK) begin 78 | if (~RESETn) begin 79 | rst_addr <= DEFAULT_BOOT_ADDR; 80 | want_write <= 1'b0; 81 | end 82 | else begin 83 | if (PSEL && PWRITE) 84 | want_write <= 1'b1; 85 | else if (PSEL && ~PWRITE) 86 | want_write <= 1'b0; 87 | 88 | if (req && want_write) begin 89 | rst_addr <= PWDATA; 90 | end 91 | end 92 | end 93 | endmodule 94 | -------------------------------------------------------------------------------- /sw/boot_rom/.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | output_temp 3 | -------------------------------------------------------------------------------- /sw/boot_rom/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX ?= riscv-none-embed- 2 | CC := $(PREFIX)gcc 3 | OBJDUMP := $(PREFIX)objdump 4 | OBJCOPY := $(PREFIX)objcopy 5 | GDB := $(PREFIX)gdb 6 | SIZE := $(PREFIX)size 7 | VERILAT ?= 0 8 | 9 | CFLAGS := -march=rv32im \ 10 | -mabi=ilp32 \ 11 | -Wall \ 12 | -Wno-unused \ 13 | -ffreestanding \ 14 | -O0 -g \ 15 | --specs=nano.specs \ 16 | -Wall -Wno-main 17 | # -mstrict-align = Add this to avoid misaligned access 18 | LDFLAGS := -g \ 19 | -Wl,-gc-sections \ 20 | -Wl,-Map=output/image.map \ 21 | -march=rv32im \ 22 | -mabi=ilp32 \ 23 | -nostartfiles \ 24 | --specs=nano.specs \ 25 | --specs=nosys.specs \ 26 | -lm -lc -lgcc 27 | 28 | TARGET_NAME := $(notdir $(shell pwd)) 29 | ODIR := output 30 | TEMP := output_temp 31 | TARGET := $(ODIR)/$(TARGET_NAME) 32 | LD_SCRIPT := -Tsections.ld 33 | MACROS := -DVERILATOR=$(VERILAT) 34 | COMMON := ../common 35 | INC := $(COMMON)/base 36 | INC_API := $(COMMON)/API/inc 37 | _OBJ := $(patsubst init/%,%.o,$(basename $(wildcard init/*.S))) 38 | _OBJ += $(patsubst init/%,%.o,$(basename $(wildcard init/*.c))) 39 | _OBJ += $(patsubst $(COMMON)/API/src/%,%.o,$(basename $(wildcard $(COMMON)/API/src/*.c))) 40 | _OBJ += $(patsubst src/%,%.o,$(basename $(wildcard src/*.c))) 41 | OBJ := $(patsubst %,$(TEMP)/%,$(_OBJ)) 42 | 43 | $(shell mkdir -p $(ODIR)_temp) 44 | $(shell mkdir -p $(ODIR)) 45 | 46 | .PHONY: all clean default debug 47 | 48 | default: all 49 | 50 | all: $(TARGET).asm 51 | @echo "$(TARGET_NAME) builded" 52 | $(SIZE) -t $(TARGET).elf 53 | 54 | $(TARGET).asm: $(ODIR)/prog_rom.sv 55 | @echo "Generating disassembly of the code..." 56 | $(OBJDUMP) -t -D -h $(TARGET).elf > $@ 57 | 58 | $(ODIR)/prog_rom.sv: $(TARGET).data 59 | @echo "Generating behavioral ROM in verilog with hex file" 60 | python scripts/gen_rom.py --in_hex $< --out_v $@ 61 | 62 | $(TARGET).data: $(TARGET).bin 63 | @echo "Generating hex format from elf to run in digital simulations..." 64 | python scripts/freedom-bin2hex.py --bit-width 32 $< $@ 65 | 66 | $(TARGET).bin: $(TARGET).elf 67 | @echo "Generating binary format of the elf executable..." 68 | $(OBJCOPY) -O binary $< $@ 69 | 70 | $(TARGET).elf: $(OBJ) 71 | @echo "Linking $@" 72 | $(CC) $(LD_SCRIPT) -I$(INC_API) -I$(INC) $(OBJ) -o $@ $(LDFLAGS) 73 | 74 | $(TEMP)/%.o: init/%.S 75 | @echo "Building $@" 76 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 77 | 78 | $(TEMP)/%.o: init/%.c 79 | @echo "Building $@" 80 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 81 | 82 | $(TEMP)/%.o: src/%.c 83 | @echo "Building $@" 84 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 85 | 86 | $(TEMP)/%.o: $(COMMON)/API/src/%.c 87 | @echo "Building $@" 88 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 89 | 90 | debug: 91 | @echo "Use disass /m name_of_the_function to search for a function in assembly/c\n" 92 | $(GDB) $(TARGET).elf 93 | 94 | clean: 95 | @echo "Cleaning all..." 96 | rm -rf $(ODIR) 97 | rm -rf $(TEMP) 98 | -------------------------------------------------------------------------------- /sw/boot_rom/init/startup.c: -------------------------------------------------------------------------------- 1 | /** 2 | * RISC-V bootup test 3 | * Author: Daniele Lacamera 4 | * Modified by: Anderson Ignacio 5 | * 6 | * MIT License 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include "encoding.h" 28 | #include "riscv_soc_utils.h" 29 | 30 | extern void trap_entry(void); 31 | extern void trap_exit(void); 32 | 33 | extern uint32_t _start_vector; 34 | extern uint32_t _stored_data; 35 | extern uint32_t _start_data; 36 | extern uint32_t _end_data; 37 | extern uint32_t _start_bss; 38 | extern uint32_t _end_bss; 39 | extern uint32_t _start_stack; 40 | extern uint32_t _end_stack; 41 | extern uint32_t _start_heap; 42 | extern uint32_t _end_heap; 43 | extern uint32_t __global_pointer$; 44 | 45 | extern void main(void); 46 | 47 | void __attribute__((naked,__section__(".init"))) _start(void) { 48 | register uint32_t *src, *dst; 49 | 50 | asm volatile("la gp, __global_pointer$"); 51 | asm volatile("la sp, _start_stack"); 52 | 53 | /* Set up vectored interrupt, with starting at offset 0x100 */ 54 | asm volatile("csrw mtvec, %0":: "r"((uint8_t *)(&_start_vector) + 1)); 55 | 56 | src = (uint32_t *) &_stored_data; 57 | dst = (uint32_t *) &_start_data; 58 | 59 | /* Copy the .data section from flash to RAM. */ 60 | while (dst < (uint32_t *)&_end_data) { 61 | *dst = *src; 62 | dst++; 63 | src++; 64 | } 65 | 66 | /* Initialize the BSS section to 0 */ 67 | dst = &_start_bss; 68 | while (dst < (uint32_t *)&_end_bss) { 69 | *dst = 0U; 70 | dst++; 71 | } 72 | 73 | main(); 74 | } 75 | 76 | void __attribute__((weak)) isr_synctrap(void) { 77 | static uint32_t synctrap_cause = 0; 78 | asm volatile("csrr %0,mcause" : "=r"(synctrap_cause)); 79 | asm volatile("ebreak"); 80 | } 81 | 82 | void __attribute__((weak)) isr_m_external(void) { 83 | write_csr(mip, (0 << IRQ_M_EXT)); 84 | return; 85 | while(1); 86 | } 87 | -------------------------------------------------------------------------------- /sw/boot_rom/init/vector.S: -------------------------------------------------------------------------------- 1 | /** 2 | * RISC-V bootup test 3 | * Author: Daniele Lacamera 4 | * Modified by: Anderson Ignacio 5 | * 6 | * MIT License 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | .macro trap_entry 27 | # Allocate space on the stack, we need to save the 28 | # context of 16*32-bit registers what's equals to 29 | # 16*(4 bytes) = 64 bytes 30 | addi sp, sp, -64 31 | # Start saving the "Caller" registers in the stack 32 | sw ra, 0(sp) 33 | sw t0, 4(sp) 34 | sw t1, 8(sp) 35 | sw t2, 12(sp) 36 | sw a0, 16(sp) 37 | sw a1, 20(sp) 38 | sw a2, 24(sp) 39 | sw a3, 28(sp) 40 | sw a4, 32(sp) 41 | sw a5, 36(sp) 42 | sw a6, 40(sp) 43 | sw a7, 44(sp) 44 | sw t3, 48(sp) 45 | sw t4, 52(sp) 46 | sw t5, 56(sp) 47 | sw t6, 60(sp) 48 | .endm 49 | 50 | .macro trap_exit 51 | # We'll return from the trap entry, so we restore 52 | # the context stored in the stack... 53 | lw ra, 0(sp) 54 | lw t0, 4(sp) 55 | lw t1, 8(sp) 56 | lw t2, 12(sp) 57 | lw a0, 16(sp) 58 | lw a1, 20(sp) 59 | lw a2, 24(sp) 60 | lw a3, 28(sp) 61 | lw a4, 32(sp) 62 | lw a5, 36(sp) 63 | lw a6, 40(sp) 64 | lw a7, 44(sp) 65 | lw t3, 48(sp) 66 | lw t4, 52(sp) 67 | lw t5, 56(sp) 68 | lw t6, 60(sp) 69 | # ...and we deallocate space on the stack return 70 | addi sp, sp, 64 71 | # ing from the trap with mret 72 | mret 73 | .endm 74 | 75 | .option norvc 76 | .section .isr_vector 77 | # In this section we're going to list all PC addresses that the hardware 78 | # will go to jump on trap execution, in the code below we consider that 79 | # vectored interrupt are actived (i.e MTVEC[1:0] = 1) 80 | # synchronous trap = exceptions 81 | # asynchronous trap = interrupts 82 | .align 8 # Align to the next 2^8=256 bytes, or 0x100 offset address 83 | trap_vectors: 84 | j _synctrap # Base trap address (also sync trap address) 85 | j trap_machine_external_int 86 | j trap_machine_external_int 87 | j trap_machine_external_int 88 | j trap_machine_external_int 89 | j trap_machine_external_int 90 | j trap_machine_external_int 91 | j trap_machine_external_int 92 | j trap_machine_external_int 93 | j trap_machine_external_int 94 | j trap_machine_external_int 95 | j trap_machine_external_int 96 | j trap_machine_external_int 97 | j trap_machine_external_int 98 | j trap_machine_external_int 99 | j trap_machine_external_int 100 | j trap_machine_external_int 101 | j trap_machine_external_int 102 | j trap_machine_external_int 103 | j trap_machine_external_int 104 | j trap_machine_external_int 105 | j trap_machine_external_int 106 | j trap_machine_external_int 107 | j trap_machine_external_int 108 | j trap_machine_external_int 109 | j trap_machine_external_int 110 | j trap_machine_external_int 111 | j trap_machine_external_int 112 | j trap_machine_external_int 113 | j trap_machine_external_int 114 | j trap_machine_external_int 115 | j trap_machine_external_int 116 | 117 | _synctrap: 118 | trap_entry 119 | jal isr_synctrap 120 | trap_exit 121 | trap_machine_external_int: 122 | trap_entry 123 | jal isr_m_external 124 | trap_exit 125 | -------------------------------------------------------------------------------- /sw/boot_rom/scripts/freedom-bin2hex.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 SiFive, Inc 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | import argparse 5 | import sys 6 | 7 | try: 8 | # Python 3 9 | from itertools import zip_longest 10 | except ImportError: 11 | # Python 2 12 | from itertools import izip_longest as zip_longest 13 | 14 | 15 | # Copied from https://docs.python.org/3/library/itertools.html 16 | def grouper(iterable, n, fillvalue=None): 17 | """Collect data into fixed-length chunks or blocks""" 18 | # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx 19 | args = [iter(iterable)] * n 20 | return zip_longest(*args, fillvalue=fillvalue) 21 | 22 | 23 | def convert(bit_width, infile, outfile): 24 | byte_width = bit_width // 8 25 | if sys.version_info >= (3, 0): 26 | for row in grouper(infile.read(), byte_width, fillvalue=0): 27 | # Reverse because in Verilog most-significant bit of vectors is first. 28 | hex_row = ''.join('{:02x}'.format(b) for b in reversed(row)) 29 | outfile.write(hex_row + '\n') 30 | else: 31 | for row in grouper(infile.read(), byte_width, fillvalue='\x00'): 32 | # Reverse because in Verilog most-significant bit of vectors is first. 33 | hex_row = ''.join('{:02x}'.format(ord(b)) for b in reversed(row)) 34 | outfile.write(hex_row + '\n') 35 | 36 | 37 | def main(): 38 | parser = argparse.ArgumentParser( 39 | description='Convert a binary file to a format that can be read in ' 40 | 'verilog via $readmemh(). By default read from stdin ' 41 | 'and write to stdout.' 42 | ) 43 | if sys.version_info >= (3, 0): 44 | parser.add_argument('infile', 45 | nargs='?', 46 | type=argparse.FileType('rb'), 47 | default=sys.stdin.buffer) 48 | else: 49 | parser.add_argument('infile', 50 | nargs='?', 51 | type=argparse.FileType('rb'), 52 | default=sys.stdin) 53 | parser.add_argument('outfile', 54 | nargs='?', 55 | type=argparse.FileType('w'), 56 | default=sys.stdout) 57 | parser.add_argument('--bit-width', '-w', 58 | type=int, 59 | required=True, 60 | help='How many bits per row.') 61 | args = parser.parse_args() 62 | 63 | if args.bit_width % 8 != 0: 64 | sys.exit("Cannot handle non-multiple-of-8 bit width yet.") 65 | convert(args.bit_width, args.infile, args.outfile) 66 | 67 | 68 | if __name__ == '__main__': 69 | main() 70 | -------------------------------------------------------------------------------- /sw/boot_rom/scripts/gen_rom.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | # Copyright https://github.com/aignacio 3 | import argparse 4 | import sys 5 | import math 6 | 7 | def gen_rom(hex, rom_mem): 8 | address_width = math.ceil(math.log(sum(1 for line in hex),2)); 9 | rom_mem.write("module boot_rom_generic (\n"); 10 | rom_mem.write(" input rst_n,\n"); 11 | rom_mem.write(" input clk,\n"); 12 | rom_mem.write(" input [%d:0] raddr_i,\n" % (address_width-1)); 13 | rom_mem.write(" output reg [31:0] dout_o\n"); 14 | rom_mem.write(");\n\n"); 15 | rom_mem.write("(*rom_style = \"block\" *) const logic [0:%d] [31:0] mem_array = {\n" % (2**(address_width)-1)); 16 | hex.seek(0); 17 | hex_lines = hex.readlines()[:-1] 18 | hex.seek(0); 19 | last_line = hex.readlines() 20 | for line in hex_lines: 21 | rom_mem.write(" 32\'h%s,\n" % line.rstrip()); 22 | rom_mem.write(" 32\'h%s\n" % last_line[-1].rstrip()); 23 | rom_mem.write(" };\n\n"); 24 | rom_mem.write(" always @(posedge clk)\n"); 25 | rom_mem.write(" if (rst_n == 1\'b0)\n"); 26 | rom_mem.write(" dout_o <= 32\'d0;\n"); 27 | rom_mem.write(" else\n"); 28 | rom_mem.write(" dout_o <= mem_array[raddr_i];\n"); 29 | rom_mem.write("endmodule\n"); 30 | 31 | def gen_rom_xilinx(hex, rom_mem): 32 | address_width = math.ceil(math.log(sum(1 for line in hex),2))+1; 33 | rom_mem.write("// -----------------------------------------------------\n"); 34 | rom_mem.write("// Please don't edit this code, its automatic generated!\n"); 35 | rom_mem.write("// -> Check: gen_rom.py \n"); 36 | rom_mem.write("// -----------------------------------------------------\n"); 37 | rom_mem.write("module boot_rom_generic (\n"); 38 | rom_mem.write(" input rst_n,\n"); 39 | rom_mem.write(" input clk,\n"); 40 | rom_mem.write(" input en,\n"); 41 | rom_mem.write(" input [%d:0] raddr_i,\n" % (address_width-1)); 42 | rom_mem.write(" output [31:0] dout_o\n"); 43 | rom_mem.write(");\n\n"); 44 | rom_mem.write(" (*rom_style = \"block\" *) reg [31:0] mem;\n\n"); 45 | rom_mem.write(" assign dout_o = mem;\n"); 46 | rom_mem.write(" always @(posedge clk)\n"); 47 | rom_mem.write(" if(en)\n"); 48 | rom_mem.write(" case(raddr_i)\n"); 49 | hex.seek(0); 50 | hex_lines = hex.readlines()[:-1] 51 | hex.seek(0); 52 | last_line = hex.readlines(); 53 | address_index = 0; 54 | for line in hex_lines: 55 | rom_mem.write(" %d\'d%06d: mem <= 32'h%s;\n" % (address_width,address_index*4,line.rstrip())); 56 | address_index += 1; 57 | rom_mem.write(" endcase\n\n"); 58 | rom_mem.write("endmodule\n"); 59 | 60 | def main(): 61 | parser = argparse.ArgumentParser( 62 | description='Convert a hexadecimal program file into behavioral rom memory.' 63 | ) 64 | if sys.version_info >= (3, 0): 65 | parser.add_argument('--in_hex', 66 | help="Input file in hex format compatible with $readmemh - 32bits/line", 67 | nargs='?', 68 | type=argparse.FileType('r'), 69 | default=sys.stdin.buffer) 70 | else: 71 | parser.add_argument('--in_hex', 72 | help="Input file in hex format compatible with $readmemh - 32bits/line", 73 | nargs='?', 74 | type=argparse.FileType('rb'), 75 | default=sys.stdin) 76 | 77 | parser.add_argument('--out_v', 78 | help="Output file with in verilog of the behavioral ROM memory ", 79 | nargs='?', 80 | type=argparse.FileType('w'), 81 | default=sys.stdout) 82 | 83 | args = parser.parse_args() 84 | gen_rom_xilinx(args.in_hex, args.out_v) 85 | 86 | if __name__ == '__main__': 87 | main() 88 | -------------------------------------------------------------------------------- /sw/boot_rom/sections.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * RISC-V bootup test 3 | * Author: Daniele Lacamera 4 | * Modified by: Anderson Ignacio 5 | * 6 | * MIT License 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | OUTPUT_ARCH( "riscv" ) 26 | 27 | ENTRY( _start ) 28 | 29 | MEMORY 30 | { 31 | IRAM(rxai!w) : ORIGIN = 0x1A000000, LENGTH = 64K 32 | DRAM(wxa!ri) : ORIGIN = 0x30000000, LENGTH = 32K 33 | } 34 | 35 | _stack_size = 0x2000; /* 8k */ 36 | 37 | SECTIONS 38 | { 39 | .text : 40 | { 41 | _start_text = .; 42 | *(.init) 43 | . = ORIGIN(IRAM) + 0x100; 44 | _start_vector = .; 45 | KEEP(*(.isr_vector)) 46 | *(.text*) 47 | _edata = .; 48 | *(.rodata*) 49 | *(.srodata*) 50 | . = ALIGN(4); 51 | _end_text = .; 52 | } > IRAM 53 | 54 | /* Start of LMA address of data/bss */ 55 | _stored_data = .; 56 | 57 | /* VMA of data/bss/stack/heap should be the DRAM */ 58 | .data : AT (_stored_data) { 59 | __DATA_BEGIN__ = .; 60 | _start_data = .; 61 | *(.data .data.* .gnu.linkonce.d.*) 62 | SORT(CONSTRUCTORS) 63 | __SDATA_BEGIN__ = .; 64 | *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) 65 | *(.sdata .sdata.* .sdata2.* .gnu.linkonce.s.*) 66 | _end_data = .; 67 | } > DRAM 68 | 69 | _start_bss = .; 70 | 71 | .bss : { 72 | __BSS_START__ = .; 73 | *(.dynbss) 74 | *(.bss .bss.* .gnu.linkonce.b.*) 75 | *(COMMON) 76 | /* Align here to ensure that the .bss section occupies space up to 77 | _end. Align after .bss to ensure correct alignment even if the 78 | .bss section disappears because there are no input sections. 79 | FIXME: Why do we need it? When there is no .bss section, we do not 80 | pad the .data section. */ 81 | . = ALIGN(. != 0 ? 32 / 8 : 1); 82 | } > DRAM 83 | 84 | .sbss : { 85 | *(.dynsbss) 86 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 87 | *(.scommon) 88 | __BSS_END__ = .; 89 | } > DRAM 90 | 91 | __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800)); 92 | } 93 | 94 | PROVIDE(_end_bss = __BSS_END__); 95 | PROVIDE(_start_stack = ORIGIN(DRAM) + LENGTH(DRAM)); 96 | PROVIDE(_end_stack = ORIGIN(DRAM) + (LENGTH(DRAM) - _stack_size)); 97 | PROVIDE(_start_heap = __BSS_END__); 98 | PROVIDE(_end_heap = _end_stack); 99 | PROVIDE(end = _start_heap); 100 | -------------------------------------------------------------------------------- /sw/boot_rom/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "riscv_soc_utils.h" 7 | #include "gpio.h" 8 | #include "uart.h" 9 | #include "encoding.h" 10 | 11 | extern uint32_t _start_vector; 12 | volatile uint32_t* const printf_buffer = (uint32_t*) PRINTF_VERILATOR; 13 | 14 | size_t _write(int fildes, const void *buf, size_t nbyte) { 15 | const uint8_t* cbuf = (const uint8_t*) buf; 16 | for (size_t i = 0; i < nbyte; ++i) { 17 | #warning "[PLEASE READ] PRINTF output will be redirected to UART peripheral" 18 | uart_send((const char *)&cbuf[i],1); 19 | } 20 | return nbyte; 21 | } 22 | 23 | int main(void) { 24 | int test = 0; 25 | bool toggle = false; 26 | 27 | for (int i = 0;i<11;i++) 28 | set_gpio_pin_direction(i,DIR_OUT); 29 | for (int i = 12;i<16;i++) 30 | set_gpio_pin_direction(i,DIR_IN); 31 | for (int i = 0;i<12;i++) 32 | set_gpio_pin_value(i,false); 33 | 34 | while(1){ 35 | // greens = 1,4,7,10 36 | // blues = 2,5,8,11 37 | // red = 0,3,6,9 38 | for (int j = 0; j<3;j++){ 39 | for (int i = j;i<12;i+=3){ 40 | set_gpio_pin_value(i,true); 41 | for (int i=0;i<100000;i++); 42 | } 43 | for (int i = j;i<12;i+=3){ 44 | set_gpio_pin_value(i,false); 45 | for (int i=0;i<100000;i++); 46 | } 47 | } 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /sw/common/API/inc/event.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | /** 12 | * @file 13 | * @brief Event library for PULPino. 14 | * 15 | * Contains event manipulating functions and event related 16 | * registers. 17 | * 18 | * @author Florian Zaruba 19 | * 20 | * @version 1.0 21 | * 22 | * @date 2/10/2015 23 | * 24 | */ 25 | 26 | #ifndef __EVENT_H__ 27 | #define __EVENT_H__ 28 | 29 | #include 30 | #include 31 | 32 | #define REG_IRQ_ENABLE 0x00 33 | #define REG_IRQ_PENDING 0x04 34 | #define REG_IRQ_SET_PENDING 0x08 35 | #define REG_IRQ_CLEAR_PENDING 0x0C 36 | 37 | #define REG_EVENT_ENABLE 0x10 38 | #define REG_EVENT_PENDING 0x14 39 | #define REG_EVENT_SET_PENDING 0x18 40 | #define REG_EVENT_CLEAR_PENDING 0x1C 41 | 42 | #define REG_SLEEP_CTRL 0x20 43 | #define REG_SLEEP_STATUS 0x24 44 | 45 | 46 | // pointer to mem of event unit - PointerEventunit 47 | #define __PE__(a) *(volatile int*) (EVENT_UNIT_BASE_ADDR + a) 48 | 49 | // interrupt enable register 50 | #define IER __PE__(REG_IRQ_ENABLE) 51 | 52 | // interrupt pending register 53 | #define IPR __PE__(REG_IRQ_PENDING) 54 | 55 | // interrupt set pending register 56 | #define ISP __PE__(REG_IRQ_SET_PENDING) 57 | 58 | // interrupt clear pending register 59 | #define ICP __PE__(REG_IRQ_CLEAR_PENDING) 60 | 61 | // event enable register 62 | #define EER __PE__(REG_EVENT_ENABLE) 63 | 64 | // event pending register 65 | #define EPR __PE__(REG_EVENT_PENDING) 66 | 67 | // event set pending register 68 | #define ESP __PE__(REG_EVENT_SET_PENDING) 69 | 70 | // event clear pending register 71 | #define ECP __PE__(REG_EVENT_CLEAR_PENDING) 72 | 73 | // sleep control register 74 | #define SCR __PE__(REG_SLEEP_CTRL) 75 | 76 | // sleep status register 77 | #define SSR __PE__(REG_SLEEP_STATUS) 78 | 79 | void cfg_int(bool int_en); 80 | void int_periph_enable(unsigned int periph_mask); 81 | void int_periph_disable(unsigned int periph_mask); 82 | void int_periph_clear(unsigned int periph_mask); 83 | 84 | #endif 85 | -------------------------------------------------------------------------------- /sw/common/API/inc/gpio.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | /** 12 | * @file 13 | * @brief GPIO library. 14 | * 15 | * Provides GPIO helper function like setting 16 | * input/output direction and reading/writing the pins. 17 | * 18 | */ 19 | #ifndef _GPIO_H_ 20 | #define _GPIO_H_ 21 | 22 | #include 23 | 24 | #define GPIO_REG_PADDIR ( GPIO_BASE_ADDR + 0x00 ) 25 | #define GPIO_REG_PADIN ( GPIO_BASE_ADDR + 0x04 ) 26 | #define GPIO_REG_PADOUT ( GPIO_BASE_ADDR + 0x08 ) 27 | #define GPIO_REG_INTEN ( GPIO_BASE_ADDR + 0x0C ) 28 | #define GPIO_REG_INTTYPE0 ( GPIO_BASE_ADDR + 0x10 ) 29 | #define GPIO_REG_INTTYPE1 ( GPIO_BASE_ADDR + 0x14 ) 30 | #define GPIO_REG_INTSTATUS ( GPIO_BASE_ADDR + 0x18 ) 31 | #define GPIO_REG_ENPIN ( GPIO_BASE_ADDR + 0x1C ) 32 | 33 | #define GPIO_REG_PADCFG0 ( GPIO_BASE_ADDR + 0x20 ) 34 | #define GPIO_REG_PADCFG1 ( GPIO_BASE_ADDR + 0x24 ) 35 | #define GPIO_REG_PADCFG2 ( GPIO_BASE_ADDR + 0x28 ) 36 | #define GPIO_REG_PADCFG3 ( GPIO_BASE_ADDR + 0x2C ) 37 | #define GPIO_REG_PADCFG4 ( GPIO_BASE_ADDR + 0x30 ) 38 | #define GPIO_REG_PADCFG5 ( GPIO_BASE_ADDR + 0x24 ) 39 | #define GPIO_REG_PADCFG6 ( GPIO_BASE_ADDR + 0x38 ) 40 | #define GPIO_REG_PADCFG7 ( GPIO_BASE_ADDR + 0x3C ) 41 | 42 | // #define SOC_CTRL_PADFUN ( SOC_CTRL_BASE_ADDR + 0x00 ) 43 | 44 | #define PADDIR REGP(GPIO_REG_PADDIR) 45 | #define PADIN REGP(GPIO_REG_PADIN) 46 | #define PADOUT REGP(GPIO_REG_PADOUT) 47 | #define INTEN REGP(GPIO_REG_INTEN) 48 | #define INTTYPE0 REGP(GPIO_REG_INTTYPE0) 49 | #define INTTYPE1 REGP(GPIO_REG_INTTYPE1) 50 | #define INTSTATUS REGP(GPIO_REG_INTSTATUS) 51 | 52 | #define PADCFG0 REGP(GPIO_REG_PADCFG0) 53 | #define PADCFG1 REGP(GPIO_REG_PADCFG1) 54 | #define PADCFG2 REGP(GPIO_REG_PADCFG2) 55 | #define PADCFG3 REGP(GPIO_REG_PADCFG3) 56 | #define PADCFG4 REGP(GPIO_REG_PADCFG4) 57 | #define PADCFG5 REGP(GPIO_REG_PADCFG5) 58 | #define PADCFG6 REGP(GPIO_REG_PADCFG6) 59 | #define PADCFG7 REGP(GPIO_REG_PADCFG7) 60 | 61 | // #define PADFUN REGP(SOC_CTRL_PADFUN) 62 | 63 | 64 | #define FUNC_GPIO 1 65 | 66 | #define DIR_IN 0 67 | #define DIR_OUT 1 68 | 69 | #define GPIO_IRQ_FALL 0x3 70 | #define GPIO_IRQ_RISE 0x2 71 | #define GPIO_IRQ_LEV0 0x0 72 | #define GPIO_IRQ_LEV1 0x1 73 | 74 | // void set_pin_function(int pinnumber, int function); 75 | // int get_pin_function(int pinnumber); 76 | void enable_gpio_pins_read(int pins); 77 | int read_enabled_irqs(); 78 | 79 | void set_gpio_pin_direction(int pinnumber, int direction); 80 | int get_gpio_pin_direction(int pinnumber); 81 | 82 | void set_gpio_pin_value(int pinnumber, int value); 83 | int get_gpio_pin_value(int pinnumber); 84 | 85 | void set_gpio_pin_irq_type(int pinnumber, int type); 86 | void set_gpio_pin_irq_en(int pinnumber, int enable); 87 | int get_gpio_irq_status(); 88 | 89 | #endif // _GPIO_H_ 90 | -------------------------------------------------------------------------------- /sw/common/API/inc/timer.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | /** 12 | * @file 13 | * @brief Timer library. 14 | * 15 | * Provides Timer function like writing the appropriate 16 | * timer registers and uttility functions to cycle count 17 | * certain events. Used in bench.h. 18 | * 19 | * @author Florian Zaruba 20 | * 21 | * @version 1.0 22 | * 23 | * @date 2/10/2015 24 | * 25 | */ 26 | #ifndef __TIMER_H__ 27 | #define __TIMER_H__ 28 | 29 | #include 30 | 31 | #define TIMERA_ADDR 0x00 32 | #define TIMERA_CTRL 0x04 33 | #define TIMERA_OUPUT_CMP 0x08 34 | 35 | #define TIMERB_ADDR 0x10 36 | #define TIMERB_CTRL 0x14 37 | #define TIMERB_OUPUT_CMP 0x18 38 | 39 | /* pointer to mem of timer unit - PointerTimer */ 40 | #define __PT__(a) *(volatile int*) (TIMER_BASE_ADDR + a) 41 | 42 | /** timer A register - contains the actual cycle counter */ 43 | #define TIRA __PT__(TIMERA_ADDR) 44 | 45 | /** timer A control register */ 46 | #define TPRA __PT__(TIMERA_CTRL) 47 | 48 | /** timer A output compare register */ 49 | #define TOCRA __PT__(TIMERA_OUPUT_CMP) 50 | 51 | /** timer A register - contains the actual cycle counter */ 52 | #define TIRB __PT__(TIMERB_ADDR) 53 | 54 | /** timer A control register */ 55 | #define TPRB __PT__(TIMERB_CTRL) 56 | 57 | /** timer A output compare register */ 58 | #define TOCRB __PT__(TIMERB_OUPUT_CMP) 59 | 60 | 61 | void reset_timer(void); 62 | 63 | void start_timer(void); 64 | 65 | void stop_timer(void); 66 | 67 | int get_time(void); 68 | 69 | void set_cmp(int value); 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /sw/common/API/inc/uart.h: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | /** 12 | * @file 13 | * @brief 16750 UART library. 14 | * 15 | * Provides UART helper function like setting 16 | * control registers and reading/writing over 17 | * the serial interface. 18 | * 19 | */ 20 | #ifndef _UART_H 21 | #define _UART_H 22 | 23 | #include 24 | #include 25 | 26 | // #if VERILATOR == 1 27 | // #define UART_REG_RBR ( UART_BASE_ADDR + 0x00) // Receiver Buffer Register (Read Only) 28 | // #define UART_REG_DLL ( UART_BASE_ADDR + 0x00) // Divisor Latch (LS) 29 | // #define UART_REG_THR ( UART_BASE_ADDR + 0x00) // Transmitter Holding Register (Write Only) 30 | // #define UART_REG_DLM ( UART_BASE_ADDR + 0x01) // Divisor Latch (MS) 31 | // #define UART_REG_IER ( UART_BASE_ADDR + 0x01) // Interrupt Enable Register 32 | // #define UART_REG_IIR ( UART_BASE_ADDR + 0x02) // Interrupt Identity Register (Read Only) 33 | // #define UART_REG_FCR ( UART_BASE_ADDR + 0x02) // FIFO Control Register (Write Only) 34 | // #define UART_REG_LCR ( UART_BASE_ADDR + 0x03) // Line Control Register 35 | // #define UART_REG_MCR ( UART_BASE_ADDR + 0x04) // MODEM Control Register 36 | // #define UART_REG_LSR ( UART_BASE_ADDR + 0x05) // Line Status Register 37 | // #define UART_REG_MSR ( UART_BASE_ADDR + 0x06) // MODEM Status Register 38 | // #define UART_REG_SCR ( UART_BASE_ADDR + 0x07) // Scratch Register 39 | // #else 40 | #define UART_REG_RBR ( UART_BASE_ADDR + 0x00) // Receiver Buffer Register (Read Only) 41 | #define UART_REG_DLL ( UART_BASE_ADDR + 0x00) // Divisor Latch (LS) 42 | #define UART_REG_THR ( UART_BASE_ADDR + 0x00) // Transmitter Holding Register (Write Only) 43 | #define UART_REG_DLM ( UART_BASE_ADDR + 0x04) // Divisor Latch (MS) 44 | #define UART_REG_IER ( UART_BASE_ADDR + 0x04) // Interrupt Enable Register 45 | #define UART_REG_IIR ( UART_BASE_ADDR + 0x08) // Interrupt Identity Register (Read Only) 46 | #define UART_REG_FCR ( UART_BASE_ADDR + 0x08) // FIFO Control Register (Write Only) 47 | #define UART_REG_LCR ( UART_BASE_ADDR + 0x0C) // Line Control Register 48 | #define UART_REG_MCR ( UART_BASE_ADDR + 0x10) // MODEM Control Register 49 | #define UART_REG_LSR ( UART_BASE_ADDR + 0x14) // Line Status Register 50 | #define UART_REG_MSR ( UART_BASE_ADDR + 0x18) // MODEM Status Register 51 | #define UART_REG_SCR ( UART_BASE_ADDR + 0x1C) // Scratch Register 52 | // #endif 53 | 54 | #define RBR_UART REGP_8(UART_REG_RBR) 55 | #define DLL_UART REGP_8(UART_REG_DLL) 56 | #define THR_UART REGP_8(UART_REG_THR) 57 | #define DLM_UART REGP_8(UART_REG_DLM) 58 | #define IER_UART REGP_8(UART_REG_IER) 59 | #define IIR_UART REGP_8(UART_REG_IIR) 60 | #define FCR_UART REGP_8(UART_REG_FCR) 61 | #define LCR_UART REGP_8(UART_REG_LCR) 62 | #define MCR_UART REGP_8(UART_REG_MCR) 63 | #define LSR_UART REGP_8(UART_REG_LSR) 64 | #define MSR_UART REGP_8(UART_REG_MSR) 65 | #define SCR_UART REGP_8(UART_REG_SCR) 66 | 67 | #define DLAB 1<<7 //DLAB bit in LCR reg 68 | #define ERBFI 1 //ERBFI bit in IER reg 69 | #define ETBEI 1<<1 //ETBEI bit in IER reg 70 | #define PE 1<<2 //PE bit in LSR reg 71 | #define THRE 1<<5 //THRE bit in LSR reg 72 | #define DR 1 //DR bit in LSR reg 73 | 74 | 75 | #define UART_FIFO_DEPTH 64 76 | 77 | //UART_FIFO_DEPTH but to be compatible with Arduino_libs and also if in future designs it differed 78 | #define SERIAL_RX_BUFFER_SIZE UART_FIFO_DEPTH 79 | #define SERIAL_TX_BUFFER_SIZE UART_FIFO_DEPTH 80 | 81 | void uart_set_cfg(int parity, uint16_t clk_counter); 82 | 83 | void uart_send(const char* str, unsigned int len); 84 | void uart_sendchar(const char c); 85 | 86 | char uart_getchar(); 87 | 88 | void uart_wait_tx_done(void); 89 | 90 | #endif 91 | -------------------------------------------------------------------------------- /sw/common/API/src/event.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include "encoding.h" 4 | 5 | void cfg_int(bool int_en){ 6 | int mstatus_csr = read_csr(mstatus); 7 | 8 | if (int_en) 9 | write_csr(mstatus, mstatus_csr|0x8); 10 | else 11 | write_csr(mstatus, mstatus_csr&0xFFFFFFF7); 12 | } 13 | 14 | void int_periph_enable(unsigned int periph_mask) { 15 | IER |= (periph_mask); 16 | } 17 | 18 | void int_periph_disable(unsigned int periph_mask) { 19 | IER &= ~(periph_mask); 20 | } 21 | 22 | void int_periph_clear(unsigned int periph_mask) { 23 | ICP |= (periph_mask); 24 | } 25 | -------------------------------------------------------------------------------- /sw/common/API/src/gpio.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | #include 11 | 12 | // void set_pin_function(int pinnumber, int function) { 13 | // volatile int old_function; 14 | // int addr; 15 | // old_function = *(volatile int*) (SOC_CTRL_PADFUN); 16 | // old_function = old_function & (~(1 << pinnumber)); 17 | // old_function = old_function | (function << pinnumber); 18 | // *(volatile int*) (SOC_CTRL_PADFUN) = old_function; 19 | // } 20 | 21 | // int get_pin_function(int pinnumber) { 22 | // volatile int old_function; 23 | // old_function = *(volatile int*) (SOC_CTRL_PADFUN); 24 | // old_function = (old_function >> pinnumber & 0x01); 25 | // return old_function; 26 | // } 27 | 28 | void set_gpio_pin_direction(int pinnumber, int direction) { 29 | volatile int old_dir; 30 | old_dir = *(volatile int*) (GPIO_REG_PADDIR); 31 | if (direction == 0) 32 | old_dir &= ~(1 << pinnumber); 33 | else 34 | old_dir |= 1 << pinnumber; 35 | *(volatile int*) (GPIO_REG_PADDIR) = old_dir; 36 | } 37 | 38 | int get_gpio_pin_direction(int pinnumber) { 39 | volatile int old_dir; 40 | old_dir = *(volatile int*) (GPIO_REG_PADDIR); 41 | old_dir = (old_dir >> (pinnumber*2) & 0x01); 42 | return old_dir; 43 | 44 | } 45 | 46 | void set_gpio_pin_value(int pinnumber, int value) { 47 | volatile int v; 48 | v = *(volatile int*) (GPIO_REG_PADOUT); 49 | if (value == 0) 50 | v &= ~(1 << pinnumber); 51 | else 52 | v |= 1 << pinnumber; 53 | *(volatile int*) (GPIO_REG_PADOUT) = v; 54 | } 55 | 56 | int get_gpio_pin_value(int pinnumber) { 57 | volatile int v; 58 | v = *(volatile int*) (GPIO_REG_PADIN); 59 | v = (v >> pinnumber) & 0x01; 60 | return v; 61 | } 62 | 63 | void set_gpio_pin_irq_en(int pinnumber, int enable) { 64 | int v; 65 | v = *(volatile int*) (GPIO_REG_INTEN); 66 | if (enable == 0) 67 | v &= ~(1 << pinnumber); 68 | else 69 | v |= 1 << pinnumber; 70 | *(volatile int*) (GPIO_REG_INTEN) = v; 71 | } 72 | 73 | void set_gpio_pin_irq_type(int pinnumber, int type) { 74 | int type0; 75 | int type1; 76 | 77 | type0 = *(volatile int*) (GPIO_REG_INTTYPE0); 78 | type1 = *(volatile int*) (GPIO_REG_INTTYPE1); 79 | 80 | if ((type & 0x1) == 0) 81 | type0 &= ~(1 << pinnumber); 82 | else 83 | type0 |= 1 << pinnumber; 84 | 85 | if ((type & 0x2) == 0) 86 | type1 &= ~(1 << pinnumber); 87 | else 88 | type1 |= 1 << pinnumber; 89 | 90 | *(volatile int*) (GPIO_REG_INTTYPE0) = type0; 91 | *(volatile int*) (GPIO_REG_INTTYPE1) = type1; 92 | } 93 | 94 | int get_gpio_irq_status() { 95 | return *(volatile int*) (GPIO_REG_INTSTATUS); 96 | } 97 | 98 | void enable_gpio_pins_read(int pins){ 99 | *(volatile int*) (GPIO_REG_ENPIN) = pins; 100 | } 101 | 102 | int read_enabled_irqs(){ 103 | int value = *(volatile int*) (GPIO_REG_INTEN); 104 | return value; 105 | } 106 | -------------------------------------------------------------------------------- /sw/common/API/src/timer.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | #include "timer.h" 12 | 13 | void reset_timer(void) { 14 | TIRA = 0; 15 | } 16 | 17 | void start_timer(void) { 18 | TPRA = 0x1; 19 | } 20 | 21 | void stop_timer(void) { 22 | TPRA = 0x0; 23 | } 24 | 25 | int get_time(void) { 26 | return TIRA; 27 | } 28 | 29 | void set_cmp(int value) { 30 | TOCRA = value; 31 | } 32 | -------------------------------------------------------------------------------- /sw/common/API/src/uart.c: -------------------------------------------------------------------------------- 1 | // Copyright 2017 ETH Zurich and University of Bologna. 2 | // Copyright and related rights are licensed under the Solderpad Hardware 3 | // License, Version 0.51 (the “License”); you may not use this file except in 4 | // compliance with the License. You may obtain a copy of the License at 5 | // http://solderpad.org/licenses/SHL-0.51. Unless required by applicable law 6 | // or agreed to in writing, software, hardware and materials distributed under 7 | // this License is distributed on an “AS IS” BASIS, WITHOUT WARRANTIES OR 8 | // CONDITIONS OF ANY KIND, either express or implied. See the License for the 9 | // specific language governing permissions and limitations under the License. 10 | 11 | #include 12 | /** 13 | * Setup UART. The UART defaults to 8 bit character mode with 1 stop bit. 14 | * 15 | * parity Enable/disable parity mode 16 | * clk_counter Clock counter value that is used to derive the UART clock. 17 | * It has to be in the range of 1..2^16. 18 | * There is a prescaler in place that already divides the SoC 19 | * clock by 16. Since this is a counter, a value of 1 means that 20 | * the SoC clock divided by 16*2 = 32 is used. A value of 31 would mean 21 | * that we use the SoC clock divided by 16*32 = 512. 22 | */ 23 | void uart_set_cfg(int parity, uint16_t clk_counter) { 24 | unsigned int i; 25 | // CGREG |= (1 << CGUART); // don't clock gate UART 26 | *(volatile unsigned int*)(UART_REG_LCR) = 0x83; //sets 8N1 and set DLAB to 1 27 | *(volatile unsigned int*)(UART_REG_DLM) = (clk_counter >> 8) & 0xFF; 28 | *(volatile unsigned int*)(UART_REG_DLL) = clk_counter & 0xFF; 29 | *(volatile unsigned int*)(UART_REG_FCR) = 0x27; //enables 16byte FIFO and clear FIFOs 30 | *(volatile unsigned int*)(UART_REG_LCR) = 0x03; //sets 8N1 and set DLAB to 0 31 | 32 | *(volatile unsigned int*)(UART_REG_IER) = ((*(volatile unsigned int*)(UART_REG_IER)) & 0xF0) | 0x01; // set IER (interrupt enable register) on UART 33 | } 34 | 35 | void uart_send(const char* str, unsigned int len) { 36 | unsigned int i; 37 | 38 | while(len > 0) { 39 | // process this in batches of 16 bytes to actually use the FIFO in the UART 40 | 41 | // wait until there is space in the fifo 42 | while( (*(volatile unsigned int*)(UART_REG_LSR) & 0x20) == 0); 43 | 44 | // for(i = 0; (i < UART_FIFO_DEPTH) && (len > 0); i++) { 45 | // load FIFO 46 | *(volatile unsigned int*)(UART_REG_THR) = *str++; 47 | 48 | len--; 49 | //} 50 | } 51 | } 52 | 53 | char uart_getchar() { 54 | while((*((volatile int*)UART_REG_LSR) & 0x1) != 0x1); 55 | 56 | return *(volatile int*)UART_REG_RBR; 57 | } 58 | 59 | void uart_sendchar(const char c) { 60 | // wait until there is space in the fifo 61 | while( (*(volatile unsigned int*)(UART_REG_LSR) & 0x20) == 0); 62 | 63 | // load FIFO 64 | *(volatile unsigned int*)(UART_REG_THR) = c; 65 | } 66 | 67 | void uart_wait_tx_done(void) { 68 | // wait until there is space in the fifo 69 | while( (*(volatile unsigned int*)(UART_REG_LSR) & 0x40) == 0); 70 | } 71 | -------------------------------------------------------------------------------- /sw/common/base/riscv_soc_utils.h: -------------------------------------------------------------------------------- 1 | #ifndef RISCV_SOC_UTILS_H 2 | #define RISCV_SOC_UTILS_H 3 | 4 | #define BOOT_ROM 0X1A000000 5 | #define DEBUG_MODULE 0x1B000000 6 | #define PRINTF_VERILATOR 0x1C000000 7 | #define IRAM_ADDR 0x20000000 8 | #define DRAM_ADDR 0x30000000 9 | #define APB_BUS_ADDR 0x40000000 10 | 11 | #define GPIO_BASE_ADDR (APB_BUS_ADDR+0x00000) 12 | #define UART_BASE_ADDR (APB_BUS_ADDR+0x10000) 13 | #define TIMER_BASE_ADDR (APB_BUS_ADDR+0x20000) 14 | #define EVENT_UNIT_BASE_ADDR (APB_BUS_ADDR+0x30000) 15 | #define RST_CTRL_BASE_ADDR (APB_BUS_ADDR+0x40000) 16 | 17 | // ISRS wire signals 18 | #define UART_EVENT 1 << 23 19 | #define GPIO_EVENT 1 << 24 20 | #define TIMER_A_OVERFLOW 1 << 25 21 | #define TIMER_A_OUTPUT_CMP 1 << 26 22 | #define TIMER_B_OVERFLOW 1 << 27 23 | #define TIMER_B_OUTPUT_CMP 1 << 28 24 | 25 | #endif 26 | -------------------------------------------------------------------------------- /sw/hello_world/.gitignore: -------------------------------------------------------------------------------- 1 | output 2 | output_temp 3 | -------------------------------------------------------------------------------- /sw/hello_world/Makefile: -------------------------------------------------------------------------------- 1 | PREFIX ?= riscv-none-embed- 2 | CC := $(PREFIX)gcc 3 | OBJDUMP := $(PREFIX)objdump 4 | OBJCOPY := $(PREFIX)objcopy 5 | GDB := $(PREFIX)gdb 6 | SIZE := $(PREFIX)size 7 | VERILAT ?= 0 8 | 9 | CFLAGS := -march=rv32imc \ 10 | -mabi=ilp32 \ 11 | -Wall \ 12 | -Wno-unused \ 13 | -ffreestanding \ 14 | -O0 -g \ 15 | --specs=nano.specs \ 16 | -Wall -Wno-main 17 | # -mstrict-align = Add this to avoid misaligned access 18 | LDFLAGS := -g \ 19 | -Wl,-gc-sections \ 20 | -Wl,-Map=output/image.map \ 21 | -march=rv32imc \ 22 | -mabi=ilp32 \ 23 | -nostartfiles \ 24 | --specs=nano.specs \ 25 | --specs=nosys.specs \ 26 | -lm -lc -lgcc 27 | 28 | TARGET_NAME := $(notdir $(shell pwd)) 29 | ODIR := output 30 | TEMP := output_temp 31 | TARGET := $(ODIR)/$(TARGET_NAME) 32 | LD_SCRIPT := -Tsections.ld 33 | MACROS := -DVERILATOR=$(VERILAT) 34 | COMMON := ../common 35 | INC := $(COMMON)/base 36 | INC_API := $(COMMON)/API/inc 37 | _OBJ := $(patsubst init/%,%.o,$(basename $(wildcard init/*.S))) 38 | _OBJ += $(patsubst init/%,%.o,$(basename $(wildcard init/*.c))) 39 | _OBJ += $(patsubst $(COMMON)/API/src/%,%.o,$(basename $(wildcard $(COMMON)/API/src/*.c))) 40 | _OBJ += $(patsubst src/%,%.o,$(basename $(wildcard src/*.c))) 41 | OBJ := $(patsubst %,$(TEMP)/%,$(_OBJ)) 42 | 43 | $(shell mkdir -p $(ODIR)_temp) 44 | $(shell mkdir -p $(ODIR)) 45 | 46 | .PHONY: all clean default 47 | 48 | default: all 49 | 50 | all: $(TARGET).asm 51 | @echo "$(TARGET_NAME) builded" 52 | $(SIZE) -t $(TARGET).elf 53 | 54 | $(ODIR)/prog_rom.v: $(TARGET).data 55 | @echo "Generating behavioral ROM in verilog with hex file" 56 | python scripts/gen_rom.py --in_hex $< --out_v $@ 57 | 58 | $(TARGET).data: $(TARGET).bin 59 | @echo "Generating hex format from elf to run in digital simulations..." 60 | python scripts/freedom-bin2hex.py --bit-width 32 $< $@ 61 | 62 | $(TARGET).asm: $(TARGET).elf 63 | @echo "Generating disassembly of the code..." 64 | $(OBJDUMP) -t -D -h $< > $@ 65 | 66 | $(TARGET).bin: $(TARGET).elf 67 | @echo "Generating binary format of the elf executable..." 68 | $(OBJCOPY) -O binary $< $@ 69 | 70 | $(TARGET).elf: $(OBJ) 71 | @echo "Linking $@" 72 | $(CC) $(LD_SCRIPT) -I$(INC_API) -I$(INC) $(OBJ) -o $@ $(LDFLAGS) 73 | 74 | $(TEMP)/%.o: init/%.S 75 | @echo "Building $@" 76 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 77 | 78 | $(TEMP)/%.o: init/%.c 79 | @echo "Building $@" 80 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 81 | 82 | $(TEMP)/%.o: src/%.c 83 | @echo "Building $@" 84 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 85 | 86 | $(TEMP)/%.o: $(COMMON)/API/src/%.c 87 | @echo "Building $@" 88 | $(CC) $(CFLAGS) -save-temps=obj $(MACROS) -I$(INC_API) -I$(INC) -c $< -o $@ 89 | 90 | debug: 91 | @echo "Use disass /m name_of_the_function to search for a function in assembly/c\n" 92 | $(GDB) $(TARGET).elf 93 | 94 | test: 95 | @echo 96 | clean: 97 | @echo "Cleaning all..." 98 | rm -rf $(ODIR) 99 | rm -rf $(TEMP) 100 | -------------------------------------------------------------------------------- /sw/hello_world/init/startup.c: -------------------------------------------------------------------------------- 1 | /** 2 | * RISC-V bootup test 3 | * Author: Daniele Lacamera 4 | * Modified by: Anderson Ignacio 5 | * 6 | * MIT License 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | #include 27 | #include 28 | 29 | #include "encoding.h" 30 | #include "riscv_soc_utils.h" 31 | 32 | extern void trap_entry(void); 33 | extern void trap_exit(void); 34 | 35 | extern uint32_t _start_vector; 36 | extern uint32_t _stored_data; 37 | extern uint32_t _start_data; 38 | extern uint32_t _end_data; 39 | extern uint32_t _start_bss; 40 | extern uint32_t _end_bss; 41 | extern uint32_t _start_stack; 42 | extern uint32_t _end_stack; 43 | extern uint32_t _start_heap; 44 | extern uint32_t _end_heap; 45 | extern uint32_t __global_pointer$; 46 | 47 | extern void main(void); 48 | 49 | void __attribute__((naked,__section__(".init"))) _start(void) { 50 | 51 | asm volatile("la gp, __global_pointer$"); 52 | asm volatile("la sp, _start_stack"); 53 | 54 | /* Set up vectored interrupt, with starting at offset 0x100 */ 55 | // asm volatile("csrw mtvec, %0":: "r"((uint8_t *)(&_start_vector) + 1)); 56 | 57 | write_csr(mtvec,&_start_vector); 58 | 59 | main(); 60 | } 61 | 62 | void __attribute__((weak)) isr_synctrap(void) { 63 | static uint32_t synctrap_cause = 0; 64 | asm volatile("csrr %0,mcause" : "=r"(synctrap_cause)); 65 | asm volatile("ebreak"); 66 | } 67 | 68 | void __attribute__((weak)) isr_m_external(void) { 69 | // write_csr(mip, (0 << IRQ_M_EXT)); 70 | while(1); 71 | return; 72 | } 73 | -------------------------------------------------------------------------------- /sw/hello_world/init/vector.S: -------------------------------------------------------------------------------- 1 | /** 2 | * RISC-V bootup test 3 | * Author: Daniele Lacamera 4 | * Modified by: Anderson Ignacio 5 | * 6 | * MIT License 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | 26 | .macro trap_entry 27 | # Allocate space on the stack, we need to save the 28 | # context of 16*32-bit registers what's equals to 29 | # 16*(4 bytes) = 64 bytes 30 | addi sp, sp, -64 31 | # Start saving the "Caller" registers in the stack 32 | sw ra, 0(sp) 33 | sw t0, 4(sp) 34 | sw t1, 8(sp) 35 | sw t2, 12(sp) 36 | sw a0, 16(sp) 37 | sw a1, 20(sp) 38 | sw a2, 24(sp) 39 | sw a3, 28(sp) 40 | sw a4, 32(sp) 41 | sw a5, 36(sp) 42 | sw a6, 40(sp) 43 | sw a7, 44(sp) 44 | sw t3, 48(sp) 45 | sw t4, 52(sp) 46 | sw t5, 56(sp) 47 | sw t6, 60(sp) 48 | .endm 49 | 50 | .macro trap_exit 51 | # We'll return from the trap entry, so we restore 52 | # the context stored in the stack... 53 | lw ra, 0(sp) 54 | lw t0, 4(sp) 55 | lw t1, 8(sp) 56 | lw t2, 12(sp) 57 | lw a0, 16(sp) 58 | lw a1, 20(sp) 59 | lw a2, 24(sp) 60 | lw a3, 28(sp) 61 | lw a4, 32(sp) 62 | lw a5, 36(sp) 63 | lw a6, 40(sp) 64 | lw a7, 44(sp) 65 | lw t3, 48(sp) 66 | lw t4, 52(sp) 67 | lw t5, 56(sp) 68 | lw t6, 60(sp) 69 | # ...and we deallocate space on the stack return 70 | addi sp, sp, 64 71 | # ing from the trap with mret 72 | mret 73 | .endm 74 | 75 | .option norvc 76 | .section .isr_vector 77 | # In this section we're going to list all PC addresses that the hardware 78 | # will go to jump on trap execution, in the code below we consider that 79 | # vectored interrupt are actived (i.e MTVEC[1:0] = 1) 80 | # synchronous trap = exceptions 81 | # asynchronous trap = interrupts 82 | .align 8 # Align to the next 2^8=256 bytes, or 0x100 offset address 83 | trap_vectors: 84 | j _synctrap # Base trap address (also sync trap address) 85 | j trap_machine_external_int 86 | j trap_machine_external_int 87 | j trap_machine_external_int 88 | j trap_machine_external_int 89 | j trap_machine_external_int 90 | j trap_machine_external_int 91 | j trap_machine_external_int 92 | j trap_machine_external_int 93 | j trap_machine_external_int 94 | j trap_machine_external_int 95 | j trap_machine_external_int 96 | j trap_machine_external_int 97 | j trap_machine_external_int 98 | j trap_machine_external_int 99 | j trap_machine_external_int 100 | j trap_machine_external_int 101 | j trap_machine_external_int 102 | j trap_machine_external_int 103 | j trap_machine_external_int 104 | j trap_machine_external_int 105 | j trap_machine_external_int 106 | j trap_machine_external_int 107 | j uart_trap 108 | j gpio_trap 109 | j trap_machine_external_int 110 | j machine_timer_trap 111 | j trap_machine_external_int 112 | j trap_machine_external_int 113 | j trap_machine_external_int 114 | j trap_machine_external_int 115 | j trap_machine_external_int 116 | 117 | _synctrap: 118 | trap_entry 119 | jal isr_synctrap 120 | trap_exit 121 | trap_machine_external_int: 122 | trap_entry 123 | jal isr_m_external 124 | trap_exit 125 | machine_timer_trap: 126 | trap_entry 127 | jal isr_m_timer 128 | trap_exit 129 | uart_trap: 130 | trap_entry 131 | jal isr_uart 132 | trap_exit 133 | gpio_trap: 134 | trap_entry 135 | jal isr_gpio 136 | trap_exit 137 | -------------------------------------------------------------------------------- /sw/hello_world/scripts/freedom-bin2hex.py: -------------------------------------------------------------------------------- 1 | # Copyright 2018 SiFive, Inc 2 | # SPDX-License-Identifier: Apache-2.0 3 | 4 | import argparse 5 | import sys 6 | 7 | try: 8 | # Python 3 9 | from itertools import zip_longest 10 | except ImportError: 11 | # Python 2 12 | from itertools import izip_longest as zip_longest 13 | 14 | 15 | # Copied from https://docs.python.org/3/library/itertools.html 16 | def grouper(iterable, n, fillvalue=None): 17 | """Collect data into fixed-length chunks or blocks""" 18 | # grouper('ABCDEFG', 3, 'x') --> ABC DEF Gxx 19 | args = [iter(iterable)] * n 20 | return zip_longest(*args, fillvalue=fillvalue) 21 | 22 | 23 | def convert(bit_width, infile, outfile): 24 | byte_width = bit_width // 8 25 | if sys.version_info >= (3, 0): 26 | for row in grouper(infile.read(), byte_width, fillvalue=0): 27 | # Reverse because in Verilog most-significant bit of vectors is first. 28 | hex_row = ''.join('{:02x}'.format(b) for b in reversed(row)) 29 | outfile.write(hex_row + '\n') 30 | else: 31 | for row in grouper(infile.read(), byte_width, fillvalue='\x00'): 32 | # Reverse because in Verilog most-significant bit of vectors is first. 33 | hex_row = ''.join('{:02x}'.format(ord(b)) for b in reversed(row)) 34 | outfile.write(hex_row + '\n') 35 | 36 | 37 | def main(): 38 | parser = argparse.ArgumentParser( 39 | description='Convert a binary file to a format that can be read in ' 40 | 'verilog via $readmemh(). By default read from stdin ' 41 | 'and write to stdout.' 42 | ) 43 | if sys.version_info >= (3, 0): 44 | parser.add_argument('infile', 45 | nargs='?', 46 | type=argparse.FileType('rb'), 47 | default=sys.stdin.buffer) 48 | else: 49 | parser.add_argument('infile', 50 | nargs='?', 51 | type=argparse.FileType('rb'), 52 | default=sys.stdin) 53 | parser.add_argument('outfile', 54 | nargs='?', 55 | type=argparse.FileType('w'), 56 | default=sys.stdout) 57 | parser.add_argument('--bit-width', '-w', 58 | type=int, 59 | required=True, 60 | help='How many bits per row.') 61 | args = parser.parse_args() 62 | 63 | if args.bit_width % 8 != 0: 64 | sys.exit("Cannot handle non-multiple-of-8 bit width yet.") 65 | convert(args.bit_width, args.infile, args.outfile) 66 | 67 | 68 | if __name__ == '__main__': 69 | main() 70 | -------------------------------------------------------------------------------- /sw/hello_world/scripts/gen_rom.py: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python3 2 | # Copyright https://github.com/aignacio 3 | import argparse 4 | import sys 5 | import math 6 | 7 | def gen_rom(hex, rom_mem): 8 | address_width = math.ceil(math.log(sum(1 for line in hex),2)); 9 | rom_mem.write("module boot_rom_generic (\n"); 10 | rom_mem.write(" input rst_n,\n"); 11 | rom_mem.write(" input clk,\n"); 12 | rom_mem.write(" input [%d:0] raddr_i,\n" % (address_width-1)); 13 | rom_mem.write(" output reg [31:0] dout_o\n"); 14 | rom_mem.write(");\n\n"); 15 | rom_mem.write(" const logic [0:%d] [31:0] mem_array = {\n" % (2**(address_width)-1)); 16 | hex.seek(0); 17 | hex_lines = hex.readlines()[:-1] 18 | hex.seek(0); 19 | last_line = hex.readlines() 20 | for line in hex_lines: 21 | rom_mem.write(" 32\'h%s,\n" % line.rstrip()); 22 | rom_mem.write(" 32\'h%s\n" % last_line[-1].rstrip()); 23 | rom_mem.write(" };\n\n"); 24 | rom_mem.write(" always @(posedge clk)\n"); 25 | rom_mem.write(" if (rst_n == 1\'b0)\n"); 26 | rom_mem.write(" dout_o <= 32\'d0;\n"); 27 | rom_mem.write(" else\n"); 28 | rom_mem.write(" dout_o <= mem_array[raddr_i];\n"); 29 | rom_mem.write("endmodule\n"); 30 | 31 | # def gen_rom_xilinx(hex, rom_mem): 32 | # address_width = math.ceil(math.log(sum(1 for line in hex),2)); 33 | # rom_mem.write("module boot_rom_generic (\n"); 34 | # rom_mem.write(" input rst_n,\n"); 35 | # rom_mem.write(" input clk,\n"); 36 | # rom_mem.write(" input [%d:0] raddr_i,\n" % (address_width-1)); 37 | # rom_mem.write(" output [31:0] dout_o\n"); 38 | # rom_mem.write(");\n\n"); 39 | # rom_mem.write("(\*rom_style = \"block\" \*) reg [0:%d] [31:0] mem_array;\n\n" % (2**(address_width)-1)); 40 | # rom_mem.write(" always @(posedge clk)\n"); 41 | # rom_mem.write(" case(raddr_i)\n"); 42 | # hex.seek(0); 43 | # address_index = 0; 44 | # for line in hex: 45 | # rom_mem.write(" %d\'h\n" % (line.rstrip())); 46 | # address_index += 1; 47 | # rom_mem.write(" endcase\n\n"); 48 | # rom_mem.write("assign dout_o = mem_array;\n\n"); 49 | # rom_mem.write("endmodule\n"); 50 | 51 | def main(): 52 | parser = argparse.ArgumentParser( 53 | description='Convert a hexadecimal program file into behavioral rom memory.' 54 | ) 55 | if sys.version_info >= (3, 0): 56 | parser.add_argument('--in_hex', 57 | help="Input file in hex format compatible with $readmemh - 32bits/line", 58 | nargs='?', 59 | type=argparse.FileType('r'), 60 | default=sys.stdin.buffer) 61 | else: 62 | parser.add_argument('--in_hex', 63 | help="Input file in hex format compatible with $readmemh - 32bits/line", 64 | nargs='?', 65 | type=argparse.FileType('rb'), 66 | default=sys.stdin) 67 | 68 | parser.add_argument('--out_v', 69 | help="Output file with in verilog of the behavioral ROM memory ", 70 | nargs='?', 71 | type=argparse.FileType('w'), 72 | default=sys.stdout) 73 | 74 | args = parser.parse_args() 75 | gen_rom(args.in_hex, args.out_v) 76 | 77 | if __name__ == '__main__': 78 | main() 79 | -------------------------------------------------------------------------------- /sw/hello_world/sections.ld: -------------------------------------------------------------------------------- 1 | /** 2 | * RISC-V bootup test 3 | * Author: Daniele Lacamera 4 | * Modified by: Anderson Ignacio 5 | * 6 | * MIT License 7 | * Permission is hereby granted, free of charge, to any person obtaining a copy 8 | * of this software and associated documentation files (the "Software"), to deal 9 | * in the Software without restriction, including without limitation the rights 10 | * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 11 | * copies of the Software, and to permit persons to whom the Software is 12 | * furnished to do so, subject to the following conditions: 13 | * 14 | * The above copyright notice and this permission notice shall be included in all 15 | * copies or substantial portions of the Software. 16 | * 17 | * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 20 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 21 | * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 22 | * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 23 | * SOFTWARE. 24 | */ 25 | OUTPUT_ARCH( "riscv" ) 26 | 27 | ENTRY( _start ) 28 | 29 | MEMORY 30 | { 31 | IRAM(rxai!w) : ORIGIN = 0x20000000, LENGTH = 32K 32 | DRAM(wxa!ri) : ORIGIN = 0x30000000, LENGTH = 32K 33 | } 34 | 35 | _stack_size = 0x2000; /* 8k */ 36 | 37 | SECTIONS 38 | { 39 | .text : 40 | { 41 | _start_text = .; 42 | *(.init) 43 | . = ORIGIN(IRAM) + 0x100; 44 | _start_vector = .; 45 | KEEP(*(.isr_vector)) 46 | *(.text*) 47 | _edata = .; 48 | *(.rodata*) 49 | *(.srodata*) 50 | . = ALIGN(4); 51 | _end_text = .; 52 | } > IRAM 53 | 54 | /* Start of LMA address of data/bss */ 55 | _stored_data = .; 56 | 57 | /* VMA of data/bss/stack/heap should be the DRAM */ 58 | .data : { 59 | __DATA_BEGIN__ = .; 60 | _start_data = .; 61 | *(.data .data.* .gnu.linkonce.d.*) 62 | SORT(CONSTRUCTORS) 63 | __SDATA_BEGIN__ = .; 64 | *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata .srodata.*) 65 | *(.sdata .sdata.* .sdata2.* .gnu.linkonce.s.*) 66 | _end_data = .; 67 | } > DRAM 68 | 69 | _start_bss = .; 70 | 71 | .bss : { 72 | __BSS_START__ = .; 73 | *(.dynbss) 74 | *(.bss .bss.* .gnu.linkonce.b.*) 75 | *(COMMON) 76 | /* Align here to ensure that the .bss section occupies space up to 77 | _end. Align after .bss to ensure correct alignment even if the 78 | .bss section disappears because there are no input sections. 79 | FIXME: Why do we need it? When there is no .bss section, we do not 80 | pad the .data section. */ 81 | . = ALIGN(. != 0 ? 32 / 8 : 1); 82 | } > DRAM 83 | 84 | .sbss : { 85 | *(.dynsbss) 86 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 87 | *(.scommon) 88 | __BSS_END__ = .; 89 | } > DRAM 90 | 91 | __global_pointer$ = MIN(__SDATA_BEGIN__ + 0x800, MAX(__DATA_BEGIN__ + 0x800, __BSS_END__ - 0x800)); 92 | } 93 | 94 | PROVIDE(_start_stack = ORIGIN(DRAM) + LENGTH(DRAM)); 95 | PROVIDE(_end_stack = ORIGIN(DRAM) + (LENGTH(DRAM) - _stack_size)); 96 | PROVIDE(_start_heap = __BSS_END__); 97 | PROVIDE(_end_heap = _end_stack); 98 | PROVIDE(end = _start_heap); 99 | -------------------------------------------------------------------------------- /sw/hello_world/src/main.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include "riscv_soc_utils.h" 7 | #include "gpio.h" 8 | #include "event.h" 9 | #include "uart.h" 10 | #include "encoding.h" 11 | #include "timer.h" 12 | 13 | #define SW_0 1 << 28 14 | #define SW_1 1 << 29 15 | #define SW_2 1 << 30 16 | #define SW_3 1 << 31 17 | 18 | bool run_leds = false; 19 | 20 | extern uint32_t _start; 21 | volatile uint32_t* const printf_buffer = (uint32_t*) PRINTF_VERILATOR; 22 | 23 | size_t _write(int fildes, const void *buf, size_t nbyte) { 24 | const uint8_t* cbuf = (const uint8_t*) buf; 25 | for (size_t i = 0; i < nbyte; ++i) { 26 | #if VERILATOR == 1 27 | #warning "[PLEASE READ] PRINTF output will be redirected to verilator dump peripheral" 28 | *printf_buffer = cbuf[i]; 29 | #else 30 | #warning "[PLEASE READ] PRINTF output will be redirected to UART peripheral" 31 | uart_sendchar((char)cbuf[i]); 32 | #endif 33 | } 34 | return nbyte; 35 | } 36 | 37 | void loop_leds(){ 38 | run_leds = false; 39 | // greens = 1,4,7,10 40 | // blues = 2,5,8,11 41 | // red = 0,3,6,9 42 | for (int j = 0; j<3;j++){ 43 | for (int i = j;i<12;i+=3){ 44 | set_gpio_pin_value(i,true); 45 | for (int t=0;t<100000;t++); 46 | } 47 | for (int i = j;i<12;i+=3){ 48 | set_gpio_pin_value(i,false); 49 | for (int t=0;t<100000;t++); 50 | } 51 | } 52 | } 53 | 54 | void isr_gpio(void) { 55 | int_periph_clear(GPIO_EVENT); 56 | printf("\n\rGPIO ISR!"); 57 | run_leds = true; 58 | } 59 | 60 | void isr_uart(void) { 61 | uint8_t uart_rx = *(volatile int*) UART_REG_RBR; 62 | 63 | int_periph_clear(UART_EVENT); 64 | printf("\n\rUART ISR received = %c",uart_rx); 65 | if (uart_rx == 'a') 66 | run_leds = true; 67 | } 68 | 69 | void isr_m_timer(void) { 70 | int_periph_clear(TIMER_A_OUTPUT_CMP); 71 | printf("\n\rTimer ISR!"); 72 | } 73 | 74 | void setup_irqs(){ 75 | int_periph_clear(UART_EVENT); 76 | int_periph_clear(TIMER_A_OUTPUT_CMP); 77 | int_periph_clear(GPIO_EVENT); 78 | 79 | for (int i = 28;i<32;i++) 80 | set_gpio_pin_irq_en(i, 1); 81 | 82 | for (int i = 28;i<32;i++) 83 | set_gpio_pin_irq_type(i, GPIO_IRQ_LEV1); 84 | 85 | #if VERILATOR == 0 86 | set_cmp(20000000); 87 | #else 88 | set_cmp(10000); 89 | #endif 90 | 91 | int_periph_enable(GPIO_EVENT); 92 | int_periph_enable(TIMER_A_OUTPUT_CMP); 93 | int_periph_enable(UART_EVENT); 94 | #if VERILATOR == 0 95 | int_periph_enable(UART_EVENT); 96 | #endif 97 | cfg_int(true); 98 | } 99 | 100 | void setup_gpios(){ 101 | for (int i = 0;i<12;i++) 102 | set_gpio_pin_direction(i,DIR_OUT); 103 | for (int i = 28;i<32;i++) 104 | set_gpio_pin_direction(i,DIR_IN); 105 | for (int i = 0;i<12;i+=1) 106 | set_gpio_pin_value(i,false); 107 | 108 | enable_gpio_pins_read(SW_0|SW_1|SW_2|SW_3); 109 | } 110 | 111 | int main(void) { 112 | // Set the reset address to the entry point 113 | volatile uint32_t *address_rst = (uint32_t *)RST_CTRL_BASE_ADDR; 114 | int test = 0; 115 | 116 | *(address_rst) = (uint32_t )&_start; 117 | 118 | // To calculate uart speed, 119 | // consider the following: 120 | // baud_rate = periph_clk / 2^(parameter) 121 | // uart_set_cfg(0, 7); 122 | // 7 => 117187 ~> 115200 123 | uart_set_cfg(0, 7); 124 | 125 | setup_gpios(); 126 | setup_irqs(); 127 | start_timer(); 128 | 129 | while(1){ 130 | if (run_leds) 131 | loop_leds(); 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /tb/cpp/jtag_rbb.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "jtag_rbb.hpp" 10 | 11 | using namespace std; 12 | 13 | jtag_rbb::jtag_rbb (int portnum){ 14 | int opt = 1; 15 | port_value = portnum; 16 | 17 | // Creating socket file descriptor 18 | if ((server_fd = socket(AF_INET, SOCK_STREAM, 0)) == 0) { 19 | perror("Error on socket creation for JTAG adapter"); 20 | exit(EXIT_FAILURE); 21 | } 22 | 23 | fcntl(server_fd, F_SETFL, O_NONBLOCK); 24 | 25 | if (setsockopt(server_fd, SOL_SOCKET, SO_REUSEADDR, &opt, sizeof(int)) == -1) { 26 | fprintf(stderr, "remote_bitbang failed setsockopt: %s (%d)\n", 27 | strerror(errno), errno); 28 | abort(); 29 | } 30 | 31 | memset(&address, 0, sizeof(address)); 32 | address.sin_family = AF_INET; 33 | address.sin_addr.s_addr = INADDR_ANY; 34 | address.sin_port = htons( portnum ); 35 | 36 | if (bind(server_fd, (struct sockaddr *)&address, sizeof(address))<0) { 37 | fprintf(stderr, "remote_bitbang failed to bind socket: %s (%d)\n", 38 | strerror(errno), errno); 39 | abort(); 40 | } 41 | 42 | if (listen(server_fd, 1) == -1) { 43 | fprintf(stderr, "remote_bitbang failed to listen on socket: %s (%d)\n", 44 | strerror(errno), errno); 45 | abort(); 46 | } 47 | 48 | if (getsockname(server_fd, (struct sockaddr *) &address, &addrlen) == -1) { 49 | fprintf(stderr, "remote_bitbang getsockname failed: %s (%d)\n", 50 | strerror(errno), errno); 51 | abort(); 52 | } 53 | 54 | // // Blocking method to wait for client connection 55 | // this->accept_client(); 56 | } 57 | 58 | void jtag_rbb::reset(char trst, char srst){ 59 | *trst_pin = trst; 60 | *srst_pin = srst; 61 | 62 | if (trst == 1) 63 | *trstn_pin = 0; 64 | else 65 | *trstn_pin = 1; 66 | } 67 | 68 | void jtag_rbb::set_pins(char tck, char tms, char tdi){ 69 | // printf("\n\tTCK=%d \tTMS=%d \tTDI=%d", tck, tms, tdi); 70 | *tck_pin = tck; 71 | *tms_pin = tms; 72 | *tdi_pin = tdi; 73 | } 74 | 75 | void jtag_rbb::read_cmd(bool block_or_nonblocking){ 76 | char tosend = '?'; 77 | int dosend = 0; 78 | int again = 1; 79 | 80 | // Non-blocking read 81 | if (block_or_nonblocking == true) { 82 | // Blocking wait for command 83 | while (again) { 84 | auto num_read = read(client_sck, &cmd_bb, sizeof(cmd_bb)); 85 | if (num_read == -1) { 86 | if (errno == EAGAIN) { 87 | // We'll try again the next call. 88 | //fprintf(stderr, "Received no command. Will try again on the next call\n"); 89 | } else { 90 | fprintf(stderr, "remote_bitbang failed to read on socket: %s (%d)\n", 91 | strerror(errno), errno); 92 | again = 0; 93 | abort(); 94 | } 95 | } else if (num_read == 0) { 96 | fprintf(stderr, "No Command Received.\n"); 97 | again = 1; 98 | } else { 99 | again = 0; 100 | } 101 | } 102 | } 103 | else { 104 | auto num_read = read(client_sck, &cmd_bb, sizeof(cmd_bb)); 105 | if (num_read <= 0) return; 106 | } 107 | 108 | dosend = 0; 109 | 110 | // Implemented protocol following this file: 111 | // >>>> https://github.com/ntfreak/openocd/blob/8b8b66559d5fbfeb1dd408a1af17dc0be52b5a9f/doc/manual/jtag/drivers/remote_bitbang.txt 112 | switch (cmd_bb) { 113 | case 'B': break; //printf("\nRBB: B = No LEDs available to blink..."); break; 114 | case 'b': break; //printf("\nRBB: b = No LEDs available to blink..."); break; 115 | case 'r': this->reset(0, 0); break; 116 | case 's': this->reset(0, 1); break; 117 | case 't': this->reset(1, 0); break; 118 | case 'u': this->reset(1, 1); break; 119 | case '0': this->set_pins(0, 0, 0); break; 120 | case '1': this->set_pins(0, 0, 1); break; 121 | case '2': this->set_pins(0, 1, 0); break; 122 | case '3': this->set_pins(0, 1, 1); break; 123 | case '4': this->set_pins(1, 0, 0); break; 124 | case '5': this->set_pins(1, 0, 1); break; 125 | case '6': this->set_pins(1, 1, 0); break; 126 | case '7': this->set_pins(1, 1, 1); break; 127 | case 'R': dosend = 1; tosend = *tdo_pin ? '1' : '0'; break; 128 | case 'Q': quit = 1; break; 129 | default: 130 | fprintf(stderr, "Remote_bitbang got unsupported command '%c'\n", cmd_bb); 131 | } 132 | 133 | if (dosend){ 134 | while (1) { 135 | // printf("\nWaiting TDO..."); 136 | ssize_t bytes = write(client_sck, &tosend, sizeof(tosend)); 137 | if (bytes == -1) { 138 | fprintf(stderr, "failed to write to socket: %s (%d)\n", strerror(errno), errno); 139 | abort(); 140 | } 141 | if (bytes > 0) { 142 | break; 143 | } 144 | } 145 | } 146 | 147 | if (quit) { 148 | // The remote disconnected. 149 | fprintf(stderr, "\nRemote end disconnected\n"); 150 | close(client_sck); 151 | client_sck = 0; 152 | exit(EXIT_SUCCESS); 153 | } 154 | } 155 | 156 | void jtag_rbb::accept_client(){ 157 | int again = 1; 158 | 159 | printf("\nWaiting for connection from OpenOCD RBB tcp:%d\n",port_value); 160 | 161 | while (again != 0) { 162 | client_sck = accept(server_fd, NULL, NULL); 163 | if (client_sck == -1) { 164 | if (errno == EAGAIN) { 165 | // No client waiting to connect right now. 166 | } else { 167 | fprintf(stderr, "failed to accept on socket: %s (%d)\n", strerror(errno),errno); 168 | again = 0; 169 | abort(); 170 | } 171 | } else { 172 | fcntl(client_sck, F_SETFL, O_NONBLOCK); 173 | fprintf(stderr, "Accepted successfully."); 174 | again = 0; 175 | } 176 | } 177 | } 178 | -------------------------------------------------------------------------------- /tb/cpp/jtag_rbb.hpp: -------------------------------------------------------------------------------- 1 | #ifndef JTAG_RBB_HPP 2 | #define JTAG_RBB_HPP 3 | 4 | #include 5 | #include 6 | 7 | class jtag_rbb{ 8 | int server_fd, client_sck; 9 | struct sockaddr_in address; 10 | char cmd_bb; 11 | int port_value; 12 | socklen_t addrlen = sizeof(address); 13 | char buffer[1024] = {0}; 14 | 15 | public: 16 | int quit = 0; 17 | unsigned char *tck_pin, 18 | *tms_pin, 19 | *tdi_pin, 20 | *tdo_pin, 21 | *trst_pin, 22 | *trstn_pin, 23 | *srst_pin; 24 | 25 | jtag_rbb(int portnum); 26 | void accept_client(); 27 | void read_cmd(bool block_or_nonblocking); 28 | void reset(char trst, char srst); 29 | void set_pins(char tck, char tms, char tdi); 30 | }; 31 | 32 | #endif 33 | -------------------------------------------------------------------------------- /tb/cpp/testbench.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include "jtag_rbb.hpp" 8 | #include "elfio/elfio/elfio.hpp" 9 | #include "verilated.h" 10 | #include "verilated_vcd_c.h" 11 | #include "Vriscv_soc.h" 12 | #include "Vriscv_soc__Syms.h" 13 | 14 | #define STRINGIZE(x) #x 15 | #define STRINGIZE_VALUE_OF(x) STRINGIZE(x) 16 | 17 | using namespace std; 18 | 19 | void goingout(int s){ 20 | printf("Caught signal %d\n",s); 21 | exit(1); 22 | } 23 | 24 | template class testbench { 25 | VerilatedVcdC *trace = new VerilatedVcdC; 26 | unsigned long tick_counter; 27 | bool getDataNextCycle; 28 | 29 | public: 30 | module *core = new module; 31 | bool loaded = false; 32 | 33 | testbench() { 34 | Verilated::traceEverOn(true); 35 | tick_counter = 0l; 36 | } 37 | 38 | ~testbench(void) { 39 | delete core; 40 | core = NULL; 41 | } 42 | 43 | virtual void reset_n(int rst_cyc) { 44 | for (int i=0;ireset_n = 0; 46 | core->jtag_trstn = 0; 47 | this->tick(); 48 | } 49 | core->reset_n = 1; 50 | core->jtag_trstn = 1; 51 | this->tick(); 52 | } 53 | 54 | virtual void opentrace(const char *vcdname) { 55 | core->trace(trace, 99); 56 | trace->open(vcdname); 57 | } 58 | 59 | virtual void close(void) { 60 | if (trace) { 61 | trace->close(); 62 | trace = NULL; 63 | } 64 | } 65 | 66 | virtual void tick(void) { 67 | 68 | if (getDataNextCycle) { 69 | getDataNextCycle = false; 70 | printf("%c",core->riscv_soc->getbufferReq()); 71 | } 72 | 73 | if (core->riscv_soc->printfbufferReq()) 74 | getDataNextCycle = true; 75 | 76 | core->core_clk = 0; 77 | core->eval(); 78 | tick_counter++; 79 | if(trace) trace->dump(tick_counter); 80 | 81 | core->core_clk = 1; 82 | core->eval(); 83 | tick_counter++; 84 | if(trace) trace->dump(tick_counter); 85 | } 86 | 87 | virtual bool done(void) { 88 | return (Verilated::gotFinish()); 89 | } 90 | }; 91 | 92 | bool loadELF(testbench *cpu, const char *program_path, const bool en_print){ 93 | ELFIO::elfio program; 94 | 95 | program.load(program_path); 96 | 97 | if (program.get_class() != ELFCLASS32 || 98 | program.get_machine() != 0xf3){ 99 | cout << "\n[ERROR] Error loading ELF file, headers does not match with ELFCLASS32/RISC-V!" << endl; 100 | return false; 101 | } 102 | 103 | ELFIO::Elf_Half seg_num = program.segments.size(); 104 | 105 | if (en_print){ 106 | printf( "\n[ELF Loader]" \ 107 | "\nProgram path: %s" \ 108 | "\nNumber of segments (program headers): %d",program_path,seg_num); 109 | } 110 | 111 | for (uint8_t i = 0; iget_physical_address(); 114 | const ELFIO::Elf64_Addr vma_addr = (uint32_t)p_seg->get_virtual_address(); 115 | const uint32_t mem_size = (uint32_t)p_seg->get_memory_size(); 116 | const uint32_t file_size = (uint32_t)p_seg->get_file_size(); 117 | // const char *data_pointer = p_seg->get_data(); 118 | 119 | if (en_print){ 120 | printf("\nSegment [%d] - LMA[0x%x] VMA[0x%x]", i,(uint32_t)lma_addr,(uint32_t)vma_addr); 121 | printf("\nFile size [%d] - Memory size [%d]",file_size,mem_size); 122 | } 123 | 124 | // Notes about loading .data and .bss 125 | // > According to: 126 | // https://www.cs.bgu.ac.il/~caspl112/wiki.files/lab9/elf.pdf 127 | // Page 34: 128 | // The array element specifies a loadable segment, described by p_filesz and p_memsz. 129 | // The bytes from the file are mapped to the beginning of the memory segment. If the 130 | // segment’s memory size (p_memsz) is larger than the file size (p_filesz), the ‘‘extra’’ 131 | // bytes are defined to hold the value 0 and to follow the segment’s initialized area. The file 132 | // size may not be larger than the memory size. Loadable segment entries in the program 133 | // header table appear in ascending order, sorted on the p_vaddr member. 134 | if (mem_size >= (IRAM_KB_SIZE*1024)){ 135 | printf("\n\n[ELF Loader] ERROR:"); 136 | printf("\nELF program: %d bytes", mem_size); 137 | printf("\nVerilator model memory size: %d bytes", (IRAM_KB_SIZE*1024)); 138 | if (lma_addr >= 0xA0000000 && lma_addr < 0xB0000000) 139 | printf("\nIncrease your verilator model IRAM by %d kb\n", (mem_size - (IRAM_KB_SIZE*1024))/1024); 140 | else 141 | printf("\nIncrease your verilator model DRAM by %d kb\n", ((mem_size - (IRAM_KB_SIZE*1024))/1024)+1); 142 | return false; 143 | } 144 | 145 | if (lma_addr >= 0x20000000 && lma_addr <0x30000000){ 146 | // IRAM Address 147 | if (en_print) printf("\nIRAM address space"); 148 | for (uint32_t p = 0; p < mem_size; p+=4){ 149 | uint32_t word_line = ((uint8_t)p_seg->get_data()[p+3]<<24)+((uint8_t)p_seg->get_data()[p+2]<<16)+((uint8_t)p_seg->get_data()[p+1]<<8)+(uint8_t)p_seg->get_data()[p]; 150 | // if (en_print) printf("\nIRAM = %8x - %8x", p, word_line); 151 | cpu->core->riscv_soc->writeWordIRAM(p/4,word_line); 152 | } 153 | } 154 | else { 155 | // DRAM Address 156 | if (en_print) printf("\nDRAM address space"); 157 | for (uint32_t p = 0; p < mem_size; p+=4){ 158 | uint32_t word_line; 159 | if (p >= file_size) { 160 | word_line = 0; 161 | } 162 | else { 163 | word_line = ((uint8_t)p_seg->get_data()[p+3]<<24)+((uint8_t)p_seg->get_data()[p+2]<<16)+((uint8_t)p_seg->get_data()[p+1]<<8)+(uint8_t)p_seg->get_data()[p]; 164 | } 165 | // if (en_print) printf("\nDRAM = %8x - %8x", p, word_line); 166 | cpu->core->riscv_soc->writeWordDRAM(p/4,word_line); 167 | } 168 | } 169 | } 170 | 171 | ELFIO::Elf64_Addr entry_point = program.get_entry(); 172 | 173 | if(en_print) printf("\nEntry point: %8x", (uint32_t) entry_point); 174 | 175 | cpu->core->riscv_soc->writeRstAddr((uint32_t) entry_point); 176 | cpu->loaded = true; 177 | cout << endl << endl; 178 | return true; 179 | } 180 | 181 | int main(int argc, char** argv, char** env){ 182 | Verilated::commandArgs(argc, argv); 183 | auto *rbb = new jtag_rbb(JTAG_PORT); 184 | unsigned char srst_pin; 185 | unsigned char trst_pin; 186 | auto *soc = new testbench; 187 | int test = 50; 188 | 189 | if (EN_VCD) 190 | soc->opentrace(STRINGIZE_VALUE_OF(WAVEFORM_VCD)); 191 | 192 | rbb->tck_pin = &soc->core->jtag_tck; 193 | rbb->tms_pin = &soc->core->jtag_tms; 194 | rbb->tdi_pin = &soc->core->jtag_tdi; 195 | rbb->tdo_pin = &soc->core->jtag_tdo; 196 | rbb->trst_pin = &trst_pin; // Must pass a address to the object member 197 | rbb->srst_pin = &srst_pin; // Must pass a address to the object member 198 | rbb->trstn_pin = &soc->core->jtag_trstn; 199 | 200 | cout << "\n[RISCV SoC] Emulator started"; 201 | if (EN_VCD) 202 | cout << "\n[VCD File] " << STRINGIZE_VALUE_OF(WAVEFORM_VCD); 203 | cout << "\n[IRAM KB Size] " << STRINGIZE_VALUE_OF(IRAM_KB_SIZE) << "KB"; 204 | cout << "\n[DRAM KB Size] " << STRINGIZE_VALUE_OF(DRAM_KB_SIZE) << "KB \n"; 205 | 206 | soc->core->rx_i = 1; 207 | soc->reset_n(1); 208 | 209 | if (JTAG_BOOT){ 210 | rbb->accept_client(); 211 | soc->core->riscv_soc->writeRstAddr(0x1A000000); 212 | } 213 | else 214 | if (!loadELF(soc, argv[1], true)) exit(1); 215 | 216 | soc->core->fetch_enable_i = 1; 217 | 218 | struct sigaction sigIntHandler; 219 | sigIntHandler.sa_handler = goingout; 220 | sigemptyset(&sigIntHandler.sa_mask); 221 | sigIntHandler.sa_flags = 0; 222 | sigaction(SIGINT, &sigIntHandler, NULL); 223 | 224 | while(true) { 225 | if (JTAG_BOOT) 226 | rbb->read_cmd(false); 227 | soc->tick(); 228 | } 229 | soc->close(); 230 | exit(EXIT_SUCCESS); 231 | } 232 | 233 | static vluint64_t cpuTime = 0; 234 | 235 | double sc_time_stamp (){ 236 | return cpuTime; 237 | } 238 | -------------------------------------------------------------------------------- /tb/debug/bus-pirate.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # Buspirate with OpenOCD support 3 | # 4 | # http://dangerousprototypes.com/bus-pirate-manual/ 5 | # 6 | 7 | interface buspirate 8 | 9 | # you need to specify port on which BP lives 10 | buspirate_port /dev/ttyUSB0 11 | 12 | # communication speed setting 13 | buspirate_speed normal ;# or fast 14 | 15 | # voltage regulator Enabled = 1 Disabled = 0 16 | #buspirate_vreg 0 17 | 18 | # pin mode normal or open-drain (jtag only) 19 | #buspirate_mode normal 20 | 21 | # pullup state Enabled = 1 Disabled = 0 22 | #buspirate_pullup 0 23 | 24 | # this depends on the cable, you are safe with this option 25 | reset_config srst_only 26 | 27 | 28 | -------------------------------------------------------------------------------- /tb/debug/esp-prog.cfg: -------------------------------------------------------------------------------- 1 | # 2 | # Driver for the FT2232H JTAG chip on the Espressif DevkitJ board 3 | # 4 | interface ftdi 5 | ftdi_vid_pid 0x0403 0x6010 6 | 7 | # interface 1 is the uart 8 | ftdi_channel 0 9 | # just TCK TDI TDO TMS, no reset 10 | ftdi_layout_init 0x0008 0x000b 11 | 12 | ftdi_device_desc "Dual RS232-HS" 13 | 14 | reset_config none 15 | 16 | # The speed of the JTAG interface, in KHz. If you get DSR/DIR errors (and they 17 | # do not relate to OpenOCD trying to read from a memory range without physical 18 | # memory being present there), you can try lowering this. 19 | # 20 | # On DevKit-J, this can go as high as 20MHz if CPU frequency is 80MHz, or 26MHz 21 | # if CPU frequency is 160MHz or 240MHz. 22 | -------------------------------------------------------------------------------- /tb/debug/riscv_pulp.cfg: -------------------------------------------------------------------------------- 1 | #debug_level 4 2 | #log_output openocd_apu.text 3 | adapter_khz 10000 4 | 5 | interface remote_bitbang 6 | remote_bitbang_host localhost 7 | 8 | remote_bitbang_port 8080 9 | 10 | set _CHIPNAME riscv 11 | jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x249511C3 12 | 13 | foreach t [jtag names] { 14 | puts [format "TAP: %s\n" $t] 15 | } 16 | 17 | set _TARGETNAME $_CHIPNAME.cpu 18 | #target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid 0x3e0 19 | target create $_TARGETNAME riscv -chain-position $_TARGETNAME -rtos riscv 20 | 21 | riscv set_reset_timeout_sec 2000 22 | riscv set_command_timeout_sec 2000 23 | 24 | # prefer to use sba for system bus access 25 | riscv set_prefer_sba on 26 | 27 | # dump jtag chain 28 | scan_chain 29 | 30 | init 31 | 32 | halt 33 | echo "Ready for Remote Connections" 34 | -------------------------------------------------------------------------------- /tb/debug/riscv_pulp_fpga.cfg: -------------------------------------------------------------------------------- 1 | #debug_level 4 2 | #log_output openocd_apu.text 3 | adapter_khz 20000 4 | 5 | # interface remote_bitbang 6 | # remote_bitbang_host localhost 7 | 8 | # remote_bitbang_port 8080 9 | 10 | set _CHIPNAME riscv 11 | jtag newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x249511C3 12 | 13 | foreach t [jtag names] { 14 | puts [format "TAP: %s\n" $t] 15 | } 16 | 17 | set _TARGETNAME $_CHIPNAME.cpu 18 | #target create $_TARGETNAME riscv -chain-position $_TARGETNAME -coreid 0x3e0 19 | target create $_TARGETNAME riscv -chain-position $_TARGETNAME -rtos riscv 20 | 21 | riscv set_reset_timeout_sec 2000 22 | riscv set_command_timeout_sec 2000 23 | 24 | # prefer to use sba for system bus access 25 | riscv set_prefer_sba on 26 | 27 | # dump jtag chain 28 | scan_chain 29 | 30 | init 31 | 32 | halt 33 | echo "Ready for Remote Connections" 34 | -------------------------------------------------------------------------------- /tb/inc/config_ri5cy.v: -------------------------------------------------------------------------------- 1 | `ifndef CONFIG_RI5CY_V 2 | `define CONFIG_RI5CY_V 3 | `define N_EXT_PERF_COUNTERS 0 4 | `define INSTR_RDATA_WIDTH 32 5 | `define PULP_SECURE 1 6 | `define N_PMP_ENTRIES 16 7 | `define USE_PMP 1 8 | `define PULP_CLUSTER 1 9 | `define FPU 0 10 | `define Zfinx 0 11 | `define FP_DIVSQRT 0 12 | `define SHARED_FP 0 13 | `define SHARED_DSP_MULT 0 14 | `define SHARED_INT_DIV 0 15 | `define SHARED_FP_DIVSQRT 0 16 | `define WAPUTYPE 0 17 | `define APU_NARGS_CPU 3 18 | `define APU_WOP_CPU 6 19 | `define APU_NDSFLAGS_CPU 15 20 | `define APU_NUSFLAGS_CPU 5 21 | `define DM_HaltAddress 32'h1B00_0800 22 | `define CORE_ID 4'd0 23 | `define CLUSTER_ID 6'd0 24 | `define CORE_MHARTID {`CLUSTER_ID, 1'b0, `CORE_ID} 25 | // Debug Parameters 26 | `define SELECTABLE_HARTS 1 27 | `define N_OF_HARTS 1 28 | `define JTAG_DECODE_ID 32'h249511C3 29 | `endif 30 | -------------------------------------------------------------------------------- /tb/inc/config_soc.v: -------------------------------------------------------------------------------- 1 | `ifndef CONFIG_SOC_V 2 | `define CONFIG_SOC_V 3 | `define AHB_MASTERS_NUM 3 // Number of masters AHB 4 | `define AHB_SLAVES_NUM 6 // Number of slaves AHB 5 | `define AHB_HADDR_SIZE 32 // bit-width AHB address haddr 6 | `define AHB_HDATA_SIZE 32 // bit-width AHB data 7 | 8 | `define APB_SLAVES_NUM 5 // Number of slaves APB 9 | `define APB_PADDR_SIZE 32 // bit-width APB address 10 | `define APB_ADDR_WIDTH 16 // Effective address 11 | `define APB_PDATA_SIZE 32 // bit-width APB data 12 | `define APB_BASE_ADDR_ALL 32'h4000_0000 13 | 14 | `define DRAM_SIZE `DRAM_KB_SIZE*1024/4 15 | `define AHB_DRAM_ADDR_WIDTH $clog2((`DRAM_KB_SIZE*1024/4)*4) 16 | 17 | `define IRAM_SIZE `IRAM_KB_SIZE*1024/4 18 | `define AHB_IRAM_ADDR_WIDTH $clog2((`IRAM_KB_SIZE*1024/4)*4) 19 | 20 | `define USE_RI5CY 21 | `define USE_RI5CY_JTAG 22 | 23 | localparam [31:0] ahb_addr [2][`AHB_SLAVES_NUM] = '{ 24 | '{32'h1A00_0000, 25 | 32'h1B00_0000, 26 | 32'h1C00_0000, 27 | 32'h2000_0000, 28 | 32'h3000_0000, 29 | 32'h4000_0000}, 30 | '{32'h1A00_FFFF, 31 | 32'h1B00_FFFF, 32 | 32'h1C00_FFFF, 33 | 32'h200F_FFFF, 34 | 32'h300F_FFFF, 35 | 32'h400F_FFFF} 36 | }; 37 | 38 | localparam [31:0] apb_addr [2][`APB_SLAVES_NUM] = '{ 39 | '{`APB_BASE_ADDR_ALL+32'h0000_0000, 40 | `APB_BASE_ADDR_ALL+32'h0001_0000, 41 | `APB_BASE_ADDR_ALL+32'h0002_0000, 42 | `APB_BASE_ADDR_ALL+32'h0003_0000, 43 | `APB_BASE_ADDR_ALL+32'h0004_0000}, 44 | '{`APB_BASE_ADDR_ALL+32'h0000_FFFF, 45 | `APB_BASE_ADDR_ALL+32'h0001_FFFF, 46 | `APB_BASE_ADDR_ALL+32'h0002_FFFF, 47 | `APB_BASE_ADDR_ALL+32'h0003_FFFF, 48 | `APB_BASE_ADDR_ALL+32'h0004_FFFF} 49 | }; 50 | `endif 51 | -------------------------------------------------------------------------------- /tb/waveform_template/ahb_size.tmpl: -------------------------------------------------------------------------------- 1 | 0 BYTE 2 | 1 HALF_WORD 3 | 2 WORD 4 | -------------------------------------------------------------------------------- /tb/waveform_template/gtkwave_tmpl.gtkw: -------------------------------------------------------------------------------- 1 | [*] 2 | [*] GTKWave Analyzer v3.3.98 (w)1999-2019 BSI 3 | [*] Wed Oct 16 09:46:32 2019 4 | [*] 5 | [dumpfile] "/tmp/riscv_soc.vcd" 6 | [dumpfile_mtime] "Wed Oct 16 09:46:06 2019" 7 | [dumpfile_size] 49534968 8 | [optimize_vcd] 9 | [savefile] "/home/aignacio/projects/riscv_verilator_model/tb/waveform_template/gtkwave_tmpl.gtkw" 10 | [timestart] 1 11 | [size] 2560 1341 12 | [pos] 922 182 13 | *-10.769713 3986 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 14 | [treeopen] TOP. 15 | [treeopen] TOP.riscv_soc. 16 | [treeopen] TOP.riscv_soc.data_ram.ram_inst. 17 | [treeopen] TOP.riscv_soc.data_ram.ram_inst.genblk2. 18 | [treeopen] TOP.riscv_soc.data_ram.ram_inst.genblk2.genblk2. 19 | [treeopen] TOP.riscv_soc.instr_ram.ram_inst. 20 | [treeopen] TOP.riscv_soc.instr_ram.ram_inst.genblk2. 21 | [treeopen] TOP.riscv_soc.instr_ram.ram_inst.genblk2.genblk2. 22 | [treeopen] TOP.riscv_soc.riscv_cpu. 23 | [treeopen] TOP.riscv_soc.riscv_cpu.riscv_core_i. 24 | [treeopen] TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i. 25 | [treeopen] TOP.riscv_soc.riscv_cpu.riscv_core_i.if_stage_i. 26 | [sst_width] 365 27 | [signals_width] 297 28 | [sst_expanded] 1 29 | [sst_vpaned_height] 610 30 | @28 31 | TOP.periph_clk 32 | TOP.core_clk 33 | TOP.riscv_soc.dm_debug_req[0] 34 | TOP.riscv_soc.ndmreset_n 35 | TOP.riscv_soc.reset_n 36 | TOP.riscv_soc.rx_i 37 | TOP.riscv_soc.tx_o 38 | @22 39 | TOP.riscv_soc.gpio_out[11:0] 40 | TOP.riscv_soc.gpio_in[3:0] 41 | TOP.riscv_soc.riscv_cpu.boot_addr_i[31:0] 42 | TOP.riscv_soc.riscv_cpu.riscv_core_i.id_stage_i.pc_id_i[31:0] 43 | TOP.riscv_soc.riscv_cpu.riscv_core_i.id_stage_i.instr[31:0] 44 | @c00200 45 | -instr_ahb 46 | @22 47 | TOP.riscv_soc.riscv_cpu.instr_haddr_o[31:0] 48 | @28 49 | TOP.riscv_soc.riscv_cpu.instr_hburst_o[2:0] 50 | TOP.riscv_soc.riscv_cpu.instr_hmastlock_o 51 | @22 52 | TOP.riscv_soc.riscv_cpu.instr_hprot_o[3:0] 53 | TOP.riscv_soc.riscv_cpu.instr_hrdata_i[31:0] 54 | @28 55 | TOP.riscv_soc.riscv_cpu.instr_hready_o 56 | TOP.riscv_soc.riscv_cpu.instr_hreadyout_i 57 | TOP.riscv_soc.riscv_cpu.instr_hresp_i 58 | [color] 2 59 | TOP.riscv_soc.riscv_cpu.instr_hsel_o 60 | @2024 61 | ^1 /home/aignacio/projects/riscv_verilator_model/tb/waveform_template/ahb_size.tmpl 62 | TOP.riscv_soc.riscv_cpu.instr_hsize_o[2:0] 63 | @28 64 | TOP.riscv_soc.riscv_cpu.instr_htrans_o[1:0] 65 | @22 66 | TOP.riscv_soc.riscv_cpu.instr_hwdata_o[31:0] 67 | @28 68 | TOP.riscv_soc.riscv_cpu.instr_hwrite_o 69 | @1401200 70 | -instr_ahb 71 | @c00200 72 | -data_ahb 73 | @22 74 | TOP.riscv_soc.riscv_cpu.data_haddr_o[31:0] 75 | @28 76 | TOP.riscv_soc.riscv_cpu.data_hburst_o[2:0] 77 | TOP.riscv_soc.riscv_cpu.data_hmastlock_o 78 | @22 79 | TOP.riscv_soc.riscv_cpu.data_hprot_o[3:0] 80 | TOP.riscv_soc.riscv_cpu.data_hrdata_i[31:0] 81 | @28 82 | TOP.riscv_soc.riscv_cpu.data_hready_o 83 | TOP.riscv_soc.riscv_cpu.data_hreadyout_i 84 | TOP.riscv_soc.riscv_cpu.data_hresp_i 85 | [color] 2 86 | TOP.riscv_soc.riscv_cpu.data_hsel_o 87 | @2024 88 | ^1 /home/aignacio/projects/riscv_verilator_model/tb/waveform_template/ahb_size.tmpl 89 | TOP.riscv_soc.riscv_cpu.data_hsize_o[2:0] 90 | @28 91 | TOP.riscv_soc.riscv_cpu.data_htrans_o[1:0] 92 | @22 93 | TOP.riscv_soc.riscv_cpu.data_hwdata_o[31:0] 94 | @28 95 | TOP.riscv_soc.riscv_cpu.data_hwrite_o 96 | @1401200 97 | -data_ahb 98 | @c00022 99 | TOP.riscv_soc.apb_event_unit.irq_i[31:0] 100 | @28 101 | (0)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 102 | (1)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 103 | (2)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 104 | (3)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 105 | (4)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 106 | (5)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 107 | (6)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 108 | (7)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 109 | (8)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 110 | (9)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 111 | (10)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 112 | (11)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 113 | (12)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 114 | (13)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 115 | (14)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 116 | (15)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 117 | (16)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 118 | (17)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 119 | (18)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 120 | (19)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 121 | (20)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 122 | (21)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 123 | (22)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 124 | (23)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 125 | (24)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 126 | (25)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 127 | (26)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 128 | (27)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 129 | (28)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 130 | (29)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 131 | (30)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 132 | (31)TOP.riscv_soc.apb_event_unit.irq_i[31:0] 133 | @1401200 134 | -group_end 135 | @28 136 | TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_we_int 137 | @22 138 | TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_addr_i[11:0] 139 | @c00022 140 | TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 141 | @28 142 | (0)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 143 | (1)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 144 | (2)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 145 | (3)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 146 | (4)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 147 | (5)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 148 | (6)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 149 | (7)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 150 | (8)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 151 | (9)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 152 | (10)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 153 | (11)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 154 | (12)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 155 | (13)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 156 | (14)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 157 | (15)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 158 | (16)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 159 | (17)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 160 | (18)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 161 | (19)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 162 | (20)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 163 | (21)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 164 | (22)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 165 | (23)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 166 | (24)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 167 | (25)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 168 | (26)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 169 | (27)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 170 | (28)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 171 | (29)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 172 | (30)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 173 | (31)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_i[31:0] 174 | @1401200 175 | -group_end 176 | @800022 177 | TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 178 | @c00022 179 | #{TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:8]} (0)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (1)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (2)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (3)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (4)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (5)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (6)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (7)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (8)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (9)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (10)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (11)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (12)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (13)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (14)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (15)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (16)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (17)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (18)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (19)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (20)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (21)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (22)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] (23)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 180 | @28 181 | (0)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 182 | (1)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 183 | (2)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 184 | (3)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 185 | (4)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 186 | (5)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 187 | (6)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 188 | (7)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 189 | (8)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 190 | (9)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 191 | (10)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 192 | (11)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 193 | (12)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 194 | (13)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 195 | (14)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 196 | (15)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 197 | (16)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 198 | (17)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 199 | (18)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 200 | (19)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 201 | (20)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 202 | (21)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 203 | (22)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 204 | (23)TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.csr_wdata_int[31:0] 205 | @1401200 206 | -group_end 207 | @1001200 208 | -group_end 209 | @22 210 | TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.mtvec_n[23:0] 211 | TOP.riscv_soc.riscv_cpu.riscv_core_i.cs_registers_i.mtvec_q[23:0] 212 | TOP.riscv_soc.riscv_cpu.riscv_core_i.if_stage_i.m_trap_base_addr_i[23:0] 213 | @23 214 | TOP.riscv_soc.apb_event_unit.irq_i[31:0] 215 | @c00022 216 | TOP.riscv_soc.apb_event_unit.irq_o[31:0] 217 | @28 218 | (0)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 219 | (1)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 220 | (2)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 221 | (3)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 222 | (4)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 223 | (5)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 224 | (6)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 225 | (7)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 226 | (8)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 227 | (9)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 228 | (10)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 229 | (11)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 230 | (12)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 231 | (13)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 232 | (14)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 233 | (15)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 234 | (16)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 235 | (17)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 236 | (18)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 237 | (19)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 238 | (20)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 239 | (21)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 240 | (22)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 241 | (23)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 242 | (24)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 243 | (25)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 244 | (26)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 245 | (27)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 246 | (28)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 247 | (29)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 248 | (30)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 249 | (31)TOP.riscv_soc.apb_event_unit.irq_o[31:0] 250 | TOP.riscv_soc.apb_uart.event_o 251 | @1401200 252 | -group_end 253 | @800028 254 | TOP.riscv_soc.apb_uart.uart_interrupt_i.IER_i[2:0] 255 | @28 256 | (0)TOP.riscv_soc.apb_uart.uart_interrupt_i.IER_i[2:0] 257 | (1)TOP.riscv_soc.apb_uart.uart_interrupt_i.IER_i[2:0] 258 | (2)TOP.riscv_soc.apb_uart.uart_interrupt_i.IER_i[2:0] 259 | @1001200 260 | -group_end 261 | @28 262 | TOP.riscv_soc.apb_uart.uart_interrupt_i.trigger_level_reached 263 | TOP.riscv_soc.apb_uart.uart_interrupt_i.RDA_i 264 | [pattern_trace] 1 265 | [pattern_trace] 0 266 | -------------------------------------------------------------------------------- /tb/wrappers/fpga_wrapper/fpga_wrapper.sv: -------------------------------------------------------------------------------- 1 | `include "config_soc.v" 2 | 3 | module artix_wrapper ( 4 | input clk_sys, 5 | input reset_n, 6 | // JTAG Interface 7 | input jtag_tck, 8 | input jtag_tms, 9 | input jtag_tdi, 10 | output jtag_tdo, 11 | // Peripherals 12 | output [11:0] gpio_out, 13 | input [3:0] gpio_in, 14 | input rx_i, 15 | output tx_o, 16 | input rx_mirror_i, 17 | output tx_mirror_o, 18 | // Status 19 | output clk_locked 20 | ); 21 | logic core_clk; 22 | logic periph_clk; 23 | logic status_clk; 24 | logic locked; 25 | logic fetch_enable; 26 | logic rx, tx; 27 | 28 | assign fetch_enable = locked; 29 | assign clk_locked = locked; 30 | assign tx_o = tx; 31 | assign tx_mirror_o = tx; 32 | assign rx = rx_i; 33 | 34 | mmcm clk_mmcm ( 35 | // Clock in ports 36 | .clk_in(clk_sys), 37 | // Clock out ports 38 | .core_clk(core_clk), 39 | .periph_clk(periph_clk), 40 | // Status and control signals 41 | .resetn(reset_n), 42 | .locked(locked) 43 | ); 44 | 45 | riscv_soc #( 46 | .USE_SAME_CLOCK_CORE_PERIPH(0) 47 | ) riscv ( 48 | .core_clk(core_clk), 49 | .periph_clk(periph_clk), 50 | .reset_n(reset_n), 51 | .fetch_enable_i(fetch_enable), 52 | .gpio_out(gpio_out), 53 | .gpio_in(gpio_in), 54 | .rx_i(rx), 55 | .tx_o(tx), 56 | .jtag_tck(jtag_tck), 57 | .jtag_tms(jtag_tms), 58 | .jtag_tdi(jtag_tdi), 59 | .jtag_tdo(jtag_tdo), 60 | .jtag_trstn(reset_n) 61 | ); 62 | endmodule 63 | -------------------------------------------------------------------------------- /tb/wrappers/ri5cy_ahb_wrapper.sv: -------------------------------------------------------------------------------- 1 | module ri5cy_ahb_wrapper #( 2 | parameter AHB_ADDR_WIDTH = 32, 3 | parameter AHB_DATA_WIDTH = 32, 4 | parameter N_EXT_PERF_COUNTERS = 0, 5 | parameter INSTR_RDATA_WIDTH = 32, 6 | parameter PULP_SECURE = 0, 7 | parameter N_PMP_ENTRIES = 16, 8 | parameter USE_PMP = 1, 9 | parameter PULP_CLUSTER = 1, 10 | parameter FPU = 0, 11 | parameter Zfinx = 0, 12 | parameter FP_DIVSQRT = 0, 13 | parameter SHARED_FP = 0, 14 | parameter SHARED_DSP_MULT = 0, 15 | parameter SHARED_INT_DIV = 0, 16 | parameter SHARED_FP_DIVSQRT = 0, 17 | parameter WAPUTYPE = 0, 18 | parameter APU_NARGS_CPU = 3, 19 | parameter APU_WOP_CPU = 6, 20 | parameter APU_NDSFLAGS_CPU = 15, 21 | parameter APU_NUSFLAGS_CPU = 5, 22 | parameter DM_HaltAddress = 32'h1A110800 23 | )( 24 | input core_clk, 25 | input core_rstn, 26 | // Control signals 27 | input clk_en_i, 28 | input [31:0] boot_addr_i, 29 | input [3:0] core_id_i, 30 | input [5:0] cluster_id_i, 31 | input fetch_enable_i, 32 | output core_busy_o, 33 | input [N_EXT_PERF_COUNTERS-1:0] ext_perf_counters_i, 34 | input debug_req_i, 35 | output sec_lvl_o, 36 | // IRQ Signals 37 | input irq_i, 38 | input [4:0] irq_id_i, 39 | output irq_ack_o, 40 | output [4:0] irq_id_o, 41 | input irq_sec_i, 42 | // APU interface signals 43 | output apu_master_req_o, 44 | output apu_master_ready_o, 45 | input apu_master_gnt_i, 46 | // APU request channel 47 | output [APU_NARGS_CPU-1:0][31:0] apu_master_operands_o, 48 | output [APU_WOP_CPU-1:0] apu_master_op_o, 49 | output [WAPUTYPE-1:0] apu_master_type_o, 50 | output [APU_NDSFLAGS_CPU-1:0] apu_master_flags_o, 51 | // APU response channel 52 | input apu_master_valid_i, 53 | input [31:0] apu_master_result_i, 54 | input [APU_NUSFLAGS_CPU-1:0] apu_master_flags_i, 55 | // AHB Master instruction interface 56 | output instr_hsel_o, 57 | output [AHB_ADDR_WIDTH-1:0] instr_haddr_o, 58 | output [AHB_DATA_WIDTH-1:0] instr_hwdata_o, 59 | output instr_hwrite_o, 60 | output [2:0] instr_hsize_o, 61 | output [2:0] instr_hburst_o, 62 | output [3:0] instr_hprot_o, 63 | output [1:0] instr_htrans_o, 64 | output instr_hmastlock_o, 65 | output instr_hready_o, 66 | input [AHB_DATA_WIDTH-1:0] instr_hrdata_i, 67 | input instr_hreadyout_i, 68 | input instr_hresp_i, 69 | // AHB Master data interface 70 | output data_hsel_o, 71 | output [AHB_ADDR_WIDTH-1:0] data_haddr_o, 72 | output [AHB_DATA_WIDTH-1:0] data_hwdata_o, 73 | output data_hwrite_o, 74 | output [2:0] data_hsize_o, 75 | output [2:0] data_hburst_o, 76 | output [3:0] data_hprot_o, 77 | output [1:0] data_htrans_o, 78 | output data_hmastlock_o, 79 | output data_hready_o, 80 | input [AHB_DATA_WIDTH-1:0] data_hrdata_i, 81 | input data_hreadyout_i, 82 | input data_hresp_i 83 | ); 84 | logic instr_hsel; 85 | logic data_hsel; 86 | logic error_instr_oor; 87 | logic error_data_oor; 88 | 89 | logic [31:0] instr_addr; 90 | logic instr_req; 91 | logic [31:0] instr_rdata; 92 | logic instr_gnt; 93 | logic instr_rvalid; 94 | 95 | logic data_req; 96 | logic data_gnt; 97 | logic data_rvalid; 98 | logic data_we; 99 | logic [3:0] data_be; 100 | logic [31:0] data_addr; 101 | logic [31:0] data_wdata; 102 | logic [31:0] data_rdata; 103 | 104 | filter_oor ahb_instr_filter( 105 | .addr_i(instr_haddr_o), 106 | .input_sel_i(instr_hsel), 107 | .valid_o(instr_hsel_o), 108 | .error_o(error_instr_oor) 109 | ); 110 | 111 | filter_oor ahb_data_filter( 112 | .addr_i(data_haddr_o), 113 | .input_sel_i(data_hsel), 114 | .valid_o(data_hsel_o), 115 | .error_o(error_data_oor) 116 | ); 117 | 118 | ri5cy_to_ahb # ( 119 | .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), 120 | .AHB_DATA_WIDTH(AHB_DATA_WIDTH) 121 | ) instr_ahb ( 122 | .clk(core_clk), 123 | .rstn(core_rstn), 124 | // Custom RI5CY memory interface 125 | .req_i(instr_req), 126 | .we_i('0), 127 | .be_i('hf), 128 | .addr_i(instr_addr), 129 | .wdata_i('0), 130 | .gnt_o(instr_gnt), 131 | .rvalid_o(instr_rvalid), 132 | .rdata_o(instr_rdata), 133 | // AHB master signals 134 | .hsel_o(instr_hsel), 135 | .haddr_o(instr_haddr_o), 136 | .hwdata_o(instr_hwdata_o), 137 | .hwrite_o(instr_hwrite_o), 138 | .hsize_o(instr_hsize_o), 139 | .hburst_o(instr_hburst_o), 140 | .hprot_o(instr_hprot_o), 141 | .htrans_o(instr_htrans_o), 142 | .hmastlock_o(instr_hmastlock_o), 143 | .hready_o(instr_hready_o), 144 | .hrdata_i(instr_hrdata_i), 145 | .hreadyout_i(instr_hreadyout_i), 146 | .hresp_i(instr_hresp_i) 147 | ); 148 | 149 | ri5cy_to_ahb # ( 150 | .AHB_ADDR_WIDTH(AHB_ADDR_WIDTH), 151 | .AHB_DATA_WIDTH(AHB_DATA_WIDTH) 152 | ) data_ahb ( 153 | .clk(core_clk), 154 | .rstn(core_rstn), 155 | // Custom RI5CY memory interface 156 | .req_i(data_req), 157 | .we_i(data_we), 158 | .be_i(data_be), 159 | .addr_i(data_addr), 160 | .wdata_i(data_wdata), 161 | .gnt_o(data_gnt), 162 | .rvalid_o(data_rvalid), 163 | .rdata_o(data_rdata), 164 | // AHB master signals 165 | .hsel_o(data_hsel), 166 | .haddr_o(data_haddr_o), 167 | .hwdata_o(data_hwdata_o), 168 | .hwrite_o(data_hwrite_o), 169 | .hsize_o(data_hsize_o), 170 | .hburst_o(data_hburst_o), 171 | .hprot_o(data_hprot_o), 172 | .htrans_o(data_htrans_o), 173 | .hmastlock_o(data_hmastlock_o), 174 | .hready_o(data_hready_o), 175 | .hrdata_i(data_hrdata_i), 176 | .hreadyout_i(data_hreadyout_i), 177 | .hresp_i(data_hresp_i) 178 | ); 179 | 180 | riscv_core #( 181 | .INSTR_RDATA_WIDTH(INSTR_RDATA_WIDTH), 182 | .PULP_SECURE(PULP_SECURE), 183 | .N_EXT_PERF_COUNTERS(N_EXT_PERF_COUNTERS), 184 | .N_PMP_ENTRIES(N_PMP_ENTRIES), 185 | .USE_PMP(USE_PMP), 186 | .PULP_CLUSTER(PULP_CLUSTER), 187 | .FPU(FPU), 188 | .Zfinx(Zfinx), 189 | .FP_DIVSQRT(FP_DIVSQRT), 190 | .SHARED_FP(SHARED_FP), 191 | .SHARED_DSP_MULT(SHARED_DSP_MULT), 192 | .SHARED_INT_DIV(SHARED_INT_DIV), 193 | .SHARED_FP_DIVSQRT(SHARED_FP_DIVSQRT), 194 | .WAPUTYPE(WAPUTYPE), 195 | .APU_NARGS_CPU(APU_NARGS_CPU), 196 | .APU_WOP_CPU(APU_WOP_CPU), 197 | .APU_NDSFLAGS_CPU(APU_NDSFLAGS_CPU), 198 | .APU_NUSFLAGS_CPU(APU_NUSFLAGS_CPU), 199 | .DM_HaltAddress(DM_HaltAddress) 200 | ) riscv_core_i ( 201 | .clk_i ( core_clk ), 202 | .rst_ni ( core_rstn ), 203 | 204 | .clock_en_i ( clk_en_i ), 205 | .fregfile_disable_i ( '0 ), 206 | .test_en_i ( '0 ), 207 | 208 | .boot_addr_i ( boot_addr_i ), 209 | .core_id_i ( core_id_i ), 210 | .cluster_id_i ( cluster_id_i ), 211 | 212 | .instr_addr_o ( instr_addr ), 213 | .instr_req_o ( instr_req ), 214 | .instr_rdata_i ( instr_rdata ), 215 | .instr_gnt_i ( instr_gnt ), 216 | .instr_rvalid_i ( instr_rvalid ), 217 | 218 | .data_addr_o ( data_addr ), 219 | .data_wdata_o ( data_wdata ), 220 | .data_we_o ( data_we ), 221 | .data_req_o ( data_req ), 222 | .data_be_o ( data_be ), 223 | .data_rdata_i ( data_rdata ), 224 | .data_gnt_i ( data_gnt ), 225 | .data_rvalid_i ( data_rvalid ), 226 | 227 | .apu_master_req_o ( apu_master_req_o ), 228 | .apu_master_ready_o ( apu_master_ready_o ), 229 | .apu_master_gnt_i ( apu_master_gnt_i ), 230 | .apu_master_operands_o ( apu_master_operands_o ), 231 | .apu_master_op_o ( apu_master_op_o ), 232 | .apu_master_type_o ( apu_master_type_o ), 233 | .apu_master_flags_o ( apu_master_flags_o ), 234 | .apu_master_valid_i ( apu_master_valid_i ), 235 | .apu_master_result_i ( apu_master_result_i ), 236 | .apu_master_flags_i ( apu_master_flags_i ), 237 | 238 | .irq_i ( irq_i ), 239 | .irq_id_i ( irq_id_i ), 240 | .irq_ack_o ( irq_ack_o ), 241 | .irq_id_o ( irq_id_o ), 242 | .irq_sec_i ( irq_sec_i ), 243 | 244 | .sec_lvl_o ( sec_lvl_o ), 245 | 246 | .debug_req_i ( debug_req_i ), 247 | 248 | .fetch_enable_i ( fetch_enable_i ), 249 | .core_busy_o ( core_busy_o ), 250 | 251 | .ext_perf_counters_i ( ) 252 | ); 253 | endmodule 254 | --------------------------------------------------------------------------------