├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefile ├── README.md ├── docs ├── img │ └── scr1_cluster.svg ├── scr1_eas.pdf └── scr1_um.pdf ├── sim ├── Makefile ├── tests │ ├── benchmarks │ │ ├── coremark │ │ │ ├── Makefile │ │ │ ├── core_portme.c │ │ │ └── core_portme.h │ │ └── dhrystone21 │ │ │ ├── Makefile │ │ │ ├── dhry.h │ │ │ ├── dhry_1.c │ │ │ └── dhry_2.c │ ├── common │ │ ├── LICENSE │ │ ├── common.mk │ │ ├── crt.S │ │ ├── crt_tcm.S │ │ ├── csr.h │ │ ├── link.ld │ │ ├── link_tcm.ld │ │ ├── reloc.h │ │ ├── riscv_csr_encoding.h │ │ ├── riscv_macros.h │ │ ├── sc_print.c │ │ ├── sc_print.h │ │ ├── sc_test.h │ │ └── scr1_specific.h │ ├── hello │ │ ├── Makefile │ │ └── hello.c │ ├── isr_sample │ │ ├── Makefile │ │ ├── isr_sample.S │ │ └── timer.h │ ├── riscv_arch │ │ ├── Makefile │ │ ├── arch_test.h │ │ ├── encoding.h │ │ ├── model_test.h │ │ └── riscv_test.h │ ├── riscv_compliance │ │ ├── Makefile │ │ ├── aw_test_macros.h │ │ ├── compliance_io.h │ │ ├── compliance_test.h │ │ ├── riscv_test.h │ │ ├── riscv_test_macros.h │ │ └── test_macros.h │ └── riscv_isa │ │ ├── Makefile │ │ ├── riscv_test.h │ │ ├── rv32_tests.inc │ │ └── test_macros.h └── verilator_wrap │ ├── scr1_ahb_wrapper.c │ └── scr1_axi_wrapper.c └── src ├── ahb_tb.files ├── ahb_top.files ├── axi_tb.files ├── axi_top.files ├── core.files ├── core ├── pipeline │ ├── scr1_ipic.sv │ ├── scr1_pipe_csr.sv │ ├── scr1_pipe_exu.sv │ ├── scr1_pipe_hdu.sv │ ├── scr1_pipe_ialu.sv │ ├── scr1_pipe_idu.sv │ ├── scr1_pipe_ifu.sv │ ├── scr1_pipe_lsu.sv │ ├── scr1_pipe_mprf.sv │ ├── scr1_pipe_tdu.sv │ ├── scr1_pipe_top.sv │ └── scr1_tracelog.sv ├── primitives │ ├── scr1_cg.sv │ └── scr1_reset_cells.sv ├── scr1_clk_ctrl.sv ├── scr1_core_top.sv ├── scr1_dm.sv ├── scr1_dmi.sv ├── scr1_scu.sv ├── scr1_tapc.sv ├── scr1_tapc_shift_reg.sv └── scr1_tapc_synchronizer.sv ├── includes ├── scr1_ahb.svh ├── scr1_arch_description.svh ├── scr1_arch_types.svh ├── scr1_csr.svh ├── scr1_dm.svh ├── scr1_hdu.svh ├── scr1_ipic.svh ├── scr1_memif.svh ├── scr1_riscv_isa_decoding.svh ├── scr1_scu.svh ├── scr1_search_ms1.svh ├── scr1_tapc.svh └── scr1_tdu.svh ├── tb ├── scr1_memory_tb_ahb.sv ├── scr1_memory_tb_axi.sv ├── scr1_top_tb_ahb.sv ├── scr1_top_tb_axi.sv └── scr1_top_tb_runtests.sv └── top ├── scr1_dmem_ahb.sv ├── scr1_dmem_router.sv ├── scr1_dp_memory.sv ├── scr1_imem_ahb.sv ├── scr1_imem_router.sv ├── scr1_mem_axi.sv ├── scr1_tcm.sv ├── scr1_timer.sv ├── scr1_top_ahb.sv └── scr1_top_axi.sv /.gitignore: -------------------------------------------------------------------------------- 1 | build/** 2 | sim/tests/benchmarks/coremark/src/** -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "dependencies/riscv-tests"] 2 | path = dependencies/riscv-tests 3 | url = https://github.com/riscv/riscv-tests 4 | [submodule "dependencies/riscv-compliance"] 5 | path = dependencies/riscv-compliance 6 | url = https://github.com/riscv/riscv-compliance 7 | [submodule "dependencies/coremark"] 8 | path = dependencies/coremark 9 | url = https://github.com/eembc/coremark 10 | [submodule "dependencies/riscv-arch"] 11 | path = dependencies/riscv-arch 12 | url = https://github.com/riscv/riscv-arch-test 13 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | # Solderpad Hardware Licence Version 2.0 2 | 3 | This licence (the “Licence”) operates as a wraparound licence to the Apache License Version 2.0 (the “Apache License”) and grants to You the rights, and imposes the obligations, set out in the Apache License (which can be found here: http://apache.org/licenses/LICENSE-2.0), with the following extensions. It must be read in conjunction with the Apache License. Section 1 below modifies definitions in the Apache License, and section 2 below replaces sections 2 of the Apache License. You may, at your option, choose to treat any Work released under this License as released under the Apache License (thus ignoring all sections written below entirely). Words in italics indicate changes rom the Apache License, but are indicative and not to be taken into account in interpretation. 4 | 5 | 1. The definitions set out in the Apache License are modified as follows: 6 | 7 | Copyright any reference to ‘copyright’ (whether capitalised or not) includes ‘Rights’ (as defined below). 8 | 9 | Contribution also includes any design, as well as any work of authorship. 10 | 11 | Derivative Works shall not include works that remain reversibly separable from, or merely link (or bind by name) or physically connect to or interoperate with the interfaces of the Work and Derivative Works thereof. 12 | 13 | Object form shall mean any form resulting from mechanical transformation or translation of a Source form or the application of a Source form to physical material, including but not limited to compiled object code, generated documentation, the instantiation of a hardware design or physical object and conversions to other media types, including intermediate forms such as bytecodes, FPGA bitstreams, moulds, artwork and semiconductor topographies (mask works). 14 | 15 | Rights means copyright and any similar right including design right (whether registered or unregistered), semiconductor topography (mask) rights and database rights (but excluding Patents and Trademarks). 16 | 17 | Source form shall mean the preferred form for making modifications, including but not limited to source code, net lists, board layouts, CAD files, documentation source, and configuration files. 18 | 19 | Work also includes a design or work of authorship, whether in Source form or other Object form. 20 | 21 | 2. Grant of Licence 22 | 23 | 2.1 Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable license under the Rights to reproduce, prepare Derivative Works of, make, adapt, repair, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form and do anything in relation to the Work as if the Rights did not exist. 24 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # SCR1 RISC-V Core 2 | 3 | SCR1 is an open-source and free to use RISC-V compatible MCU-class core, designed and maintained by Syntacore. It is industry-grade and silicon-proven (including full-wafer production), works out of the box in all major EDA flows and Verilator, and comes with extensive collateral and documentation. 4 | 5 | ![SCR1 cluster](./docs/img/scr1_cluster.svg) 6 | 7 | ## Key features 8 | 9 | * Open sourced under SHL-license (see LICENSE file) - unrestricted commercial use allowed 10 | * RV32I or RV32E ISA base + optional RVM and RVC standard extensions 11 | * Machine privilege mode only 12 | * 2 to 4 stage pipeline 13 | * Optional Integrated Programmable Interrupt Controller with 16 IRQ lines 14 | * Optional RISC-V Debug subsystem with JTAG interface 15 | * Optional on-chip Tightly-Coupled Memory 16 | * 32-bit AXI4/AHB-Lite external interface 17 | * Written in SystemVerilog 18 | * Optimized for area and power 19 | * 3 predefined recommended configurations 20 | * A number of fine-tuning options for custom configuration 21 | * Verification suite provided 22 | * Extensive documentation 23 | 24 | For more information on core architecture, see [SCR1 External Architecture Specification](https://github.com/syntacore/scr1/blob/master/docs/scr1_eas.pdf). 25 | 26 | For more information on project usage, see [SCR1 User Manual](https://github.com/syntacore/scr1/blob/master/docs/scr1_um.pdf). 27 | 28 | ## Repository contents 29 | 30 | |Folder | Description 31 | |------ | ----------- 32 | |**dependencies**                 | **Dependent submodules** 33 | |├─ riscv-tests                   | Common source files for RISC-V ISA tests 34 | |├─ riscv_arch               | Common source files for RISC-V Architectural tests 35 | |├─ riscv-compliance               | Common source files for RISC-V Compliance tests 36 | |└─ coremark                       | Common source files for EEMBC's CoreMark® benchmark 37 | |**docs** | **SCR1 documentation** 38 | |├─ scr1_eas.pdf                   | SCR1 External Architecture Specification 39 | |└─ scr1_um.pdf                   | SCR1 User Manual 40 | |**sim** | **Tests and scripts for simulation** 41 | |├─ tests/common                   | Common source files for tests 42 | |├─ tests/riscv_isa               | RISC-V ISA tests platform specific source files 43 | |├─ tests/riscv_compliance         | RISC-V Compliance platform specific source files 44 | |├─ tests/benchmarks/dhrystone21   | Dhrystone 2.1 benchmark source files 45 | |├─ tests/benchmarks/coremark     | EEMBC's CoreMark® benchmark platform specific source files 46 | |├─ tests/isr_sample               | Sample program "Interrupt Service Routine" 47 | |├─ tests/hello | Sample program "Hello" 48 | |└─ verilator_wrap | Wrappers for Verilator simulation 49 | |**src** | **SCR1 RTL source and testbench files** 50 | |├─ includes | Header files 51 | |├─ core | Core top source files 52 | |├─ top | Cluster source files 53 | |└─ tb | Testbench files 54 | 55 | ## SCR1 source file lists 56 | 57 | SCR1 source file lists of SCR1 can be found in [./src](https://github.com/syntacore/scr1/tree/master/src): 58 | 59 | * **core.files** - all synthesized file sources of the SCR1 core 60 | * **ahb_top.files** - synthesized file sources of AHB cluster 61 | * **axi_top.files** - synthesized file sources of AXI cluster 62 | * **ahb_tb.files** - testbench file sources for AHB cluster (for simulation only) 63 | * **axi_tb.files** - testbench file sources for AXI cluster (for simulation only) 64 | 65 | Library with header files to include is [./src/includes/](https://github.com/syntacore/scr1/tree/master/src/includes) 66 | 67 | ## Simulation quick start guide 68 | 69 | The project contains testbenches, test sources and scripts to quickly start the SCR1 simulation. Before starting the simulation, make sure you have: 70 | 71 | * installed RISC-V GCC toolchain, 72 | * installed one of the supported simulators, 73 | * initialized submodules with test sources. 74 | 75 | ### Requirements 76 | 77 | #### Operating system 78 | 79 | GCC toolchain and make-scripts are supported by most popular Linux-like operating systems. 80 | 81 | To run from Windows you can use an additional compatibility layer, such as WSL or Cygwin. 82 | 83 | #### RISC-V GCC toolchain 84 | 85 | RISC-V GCC toolchain is required to compile the software. You can use pre-built binaries or build the toolchain from scratch. 86 | 87 | ##### Using pre-built binary tools 88 | 89 | Pre-built RISC-V GCC toolchain with support for all SCR1 architectural configurations is available for download from https://syntacore.com/tools/development-tools. 90 | 91 | 1. Download the archive for your platform. 92 | 2. Extract the archive to preferred directory ``. 93 | 3. Add the `/bin` folder to the $PATH environment variable: 94 | ``` 95 | export PATH=/bin:$PATH 96 | ``` 97 | 98 | ##### Building tools from source 99 | 100 | You can build the RISC-V GCC toolchain from sources, stored in official repo https://github.com/riscv/riscv-gnu-toolchain 101 | 102 | Instructions on how to prepare and build the toolchain can be found on https://github.com/riscv/riscv-gnu-toolchain/blob/master/README.md 103 | 104 | We recommend using the multilib compiler. Please note that RV32IC, RV32E, RV32EM, RV32EMC, RV32EC architectural configurations are not included in the compiler by default. If you plan to use them, you will need to include the appropriate libraries by yourself before building. 105 | 106 | After the building, be sure to add the `/bin` folder to the $PATH environment variable 107 | 108 | 109 | #### HDL simulators 110 | 111 | Currently supported simulators: 112 | 113 | * Verilator (last verified version: v5.014) 114 | * Mentor Graphics ModelSim (last verified version: INTEL FPGA STARTER EDITION 2020.1) 115 | * Synopsys VCS (last verified version: S-2021.09-1) 116 | * Cadence NCSim (last verified version: 22.09-s004) 117 | 118 | Please note that RTL simulator executables should be in your $PATH variable. 119 | 120 | #### Tests preparation 121 | 122 | The simulation package includes the following tests: 123 | 124 | * **hello** - "Hello" sample program 125 | * **isr_sample** - "Interrupt Service Routine" sample program 126 | * **riscv_isa** - RISC-V ISA tests (submodule) 127 | * **riscv_arch** - RISC-V Architectural tests (submodule) 128 | * **riscv_compliance** - RISC-V Compliance tests (submodule) 129 | * **dhrystone21** - Dhrystone 2.1 benchmark 130 | * **coremark** - EEMBC's CoreMark® benchmark (submodule) 131 | 132 | After the main SCR1 repository has been cloned execute the following command: 133 | ``` 134 | git submodule update --init --recursive 135 | ``` 136 | 137 | This command will initialized submodules with test sources. 138 | 139 | ### Running simulation 140 | 141 | To build RTL, compile and run tests from the repo root folder you have to call Makefile. 142 | By default, you may simply call Makefile without any parameters: 143 | ``` sh 144 |    make 145 | ``` 146 | 147 | In this case simulation will run on Verilator with following parameters: `CFG=MAX BUS=AHB TRACE=0 TARGETS="hello isr_sample riscv_isa riscv_compliance dhrystone21 coremark"`. 148 | 149 | Makefile supports: 150 | 151 | * choice of simulator - `run_ = ` 152 | * selection of external interface - `BUS = `, 153 | * configuration setup - `CFG = `, 154 | * parameters for CUSTOM configuration - `ARCH = , VECT_IRQ = <0, 1>, IPIC = <0, 1>, TCM = <0, 1>` 155 | * tests subset to run - `TARGETS = ` 156 | * enabling tracelog - `TRACE = <0, 1>` 157 | * and any additional options to pass to the simulator - `SIM_BUILD_OPTS`. 158 | 159 | Examples: 160 | ``` sh 161 |    make run_verilator_wf CFG=MAX BUS=AXI TARGETS="riscv_isa riscv_compliance" TRACE=1 162 |    make run_vcs CFG=BASE BUS=AHB TARGETS="dhrystone21 coremark" SIM_BUILD_OPTS="-gui" 163 |    make run_modelsim CFG=CUSTOM BUS=AXI ARCH=I VECT_IRQ=1 IPIC=1 TCM=0 TARGETS=isr_sample 164 | ``` 165 | 166 | Build and run parameters can be configured in the `./Makefile`. 167 | 168 | After all the tests have finished, the results can be found in `build//test_results.txt`. 169 | 170 | **IMPORTANT:** To ensure correct rebuild, please clean build directory between simulation runs: 171 | ``` sh 172 |   make clean 173 | ``` 174 | 175 | Please refer to the *"Simulation environment"* chapter of the [SCR1 User Manual](https://github.com/syntacore/scr1/blob/master/docs/scr1_um.pdf) for more information on setting up a simulation run. 176 | 177 | ## SCR1 SDKs 178 | 179 | FPGA-based SDKs are available at the . 180 | 181 | Repo contains: 182 | 183 | * Pre-build images and open designs for several standard FPGAs boards: 184 | * Digilent Arty (Xilinx) 185 | * Digilent Nexys 4 DDR (Xilinx) 186 | * Arria V GX Starter (Intel) 187 | * Terasic DE10-Lite (Intel) 188 | * Software package: 189 | * Bootloader 190 | * Zephyr RTOS 191 | * Tests\SW samples 192 | * User Guides for SDKs and tools 193 | 194 | ## Contacts 195 | 196 | Report an issue: 197 | 198 | Ask a question: scr1@syntacore.com 199 | -------------------------------------------------------------------------------- /docs/scr1_eas.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/docs/scr1_eas.pdf -------------------------------------------------------------------------------- /docs/scr1_um.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/docs/scr1_um.pdf -------------------------------------------------------------------------------- /sim/Makefile: -------------------------------------------------------------------------------- 1 | # src_dir := $(dir $(lastword $(MAKEFILE_LIST))) 2 | rtl_src_dir := $(root_dir)/src/ 3 | rtl_core_files ?= core.files 4 | rtl_top_files ?= ahb_top.files 5 | rtl_tb_files ?= ahb_tb.files 6 | rtl_inc_dir ?= $(root_dir)/src/includes 7 | rtl_inc_tb_dir ?= $(root_dir)/src/tb 8 | top_module ?= scr1_top_tb_ahb 9 | 10 | rtl_core_list := $(addprefix $(rtl_src_dir),$(shell cat $(rtl_src_dir)$(rtl_core_files))) 11 | rtl_top_list := $(addprefix $(rtl_src_dir),$(shell cat $(rtl_src_dir)$(rtl_top_files))) 12 | rtl_tb_list := $(addprefix $(rtl_src_dir),$(shell cat $(rtl_src_dir)$(rtl_tb_files))) 13 | sv_list := $(rtl_core_list) $(rtl_top_list) $(rtl_tb_list) 14 | 15 | ifeq ($(MAKECMDGOALS), $(filter $(MAKECMDGOALS),build_verilator build_verilator_wf)) 16 | ifeq ($(BUS),AHB) 17 | export scr1_wrapper := $(root_dir)/sim/verilator_wrap/scr1_ahb_wrapper.c 18 | endif 19 | ifeq ($(BUS),AXI) 20 | export scr1_wrapper := $(root_dir)/sim/verilator_wrap/scr1_axi_wrapper.c 21 | endif 22 | export verilator_ver ?= $(shell expr `verilator --version | cut -f2 -d' '`) 23 | 24 | export verilator_ver_5x ?= $(shell expr `verilator --version | cut -f2 -d' '` \>= 5) 25 | 26 | ifeq "$(verilator_ver_5x)" "1" 27 | VERILATOR_5X_OPTS ?= --no-timing # conservative way 28 | endif 29 | 30 | 31 | endif 32 | 33 | .PHONY: build_modelsim build_vcs build_ncsim build_verilator build_verilator_wf 34 | 35 | default: build_modelsim 36 | 37 | build_modelsim: $(sv_list) 38 | cd $(bld_dir); \ 39 | vlib work; \ 40 | vmap work work; \ 41 | vlog -work work -O1 -mfcu -sv \ 42 | +incdir+$(rtl_inc_dir) \ 43 | +incdir+$(rtl_inc_tb_dir) \ 44 | +nowarnSVCHK \ 45 | +define+SCR1_TRGT_SIMULATION \ 46 | +define+$(SIM_TRACE_DEF) \ 47 | +define+$(SIM_CFG_DEF) \ 48 | $(SIM_BUILD_OPTS) \ 49 | $(sv_list) 50 | 51 | build_vcs: $(sv_list) 52 | cd $(bld_dir); \ 53 | vcs \ 54 | -full64 \ 55 | -lca \ 56 | -sverilog \ 57 | -notice \ 58 | +lint=all,noVCDE,noNS,noVNGS,noSVA-DIU,noSVA-CE,noSVA-NSVU \ 59 | -timescale=1ns/1ps \ 60 | +incdir+$(rtl_inc_dir) \ 61 | +incdir+$(rtl_inc_tb_dir) \ 62 | +define+SCR1_TRGT_SIMULATION \ 63 | +define+$(SIM_TRACE_DEF) \ 64 | +define+$(SIM_CFG_DEF) \ 65 | -nc \ 66 | -debug_all \ 67 | $(SIM_BUILD_OPTS) \ 68 | $(sv_list) 69 | 70 | build_ncsim: $(sv_list) 71 | cd $(bld_dir); \ 72 | irun \ 73 | -elaborate \ 74 | -64bit \ 75 | -disable_sem2009 \ 76 | -verbose \ 77 | -timescale 1ns/1ps \ 78 | -incdir $(rtl_inc_dir) \ 79 | -incdir $(rtl_inc_tb_dir) \ 80 | -debug \ 81 | +define+SCR1_TRGT_SIMULATION \ 82 | +define+$(SIM_TRACE_DEF) \ 83 | +define+$(SIM_CFG_DEF) \ 84 | $(SIM_BUILD_OPTS) \ 85 | $(sv_list) \ 86 | -top $(top_module) 87 | 88 | build_verilator: $(sv_list) 89 | cd $(bld_dir); \ 90 | verilator \ 91 | -cc \ 92 | -sv \ 93 | +1800-2017ext+sv \ 94 | -Wno-fatal \ 95 | $(VERILATOR_5X_OPTS) \ 96 | --top-module $(top_module) \ 97 | -DSCR1_TRGT_SIMULATION \ 98 | -D$(SIM_TRACE_DEF) \ 99 | -D$(SIM_CFG_DEF) \ 100 | --clk clk \ 101 | --exe $(scr1_wrapper) \ 102 | --Mdir $(bld_dir)/verilator \ 103 | -I$(rtl_inc_dir) \ 104 | -I$(rtl_inc_tb_dir) \ 105 | $(SIM_BUILD_OPTS) \ 106 | $(sv_list); \ 107 | cd verilator; \ 108 | $(MAKE) -f V$(top_module).mk; 109 | 110 | build_verilator_wf: $(sv_list) 111 | cd $(bld_dir); \ 112 | verilator \ 113 | -cc \ 114 | -sv \ 115 | +1800-2017ext+sv \ 116 | -Wno-fatal \ 117 | $(VERILATOR_5X_OPTS) \ 118 | --top-module $(top_module) \ 119 | -DSCR1_TRGT_SIMULATION \ 120 | -D$(SIM_TRACE_DEF) \ 121 | -D$(SIM_CFG_DEF) \ 122 | -CFLAGS -DVCD_TRACE -CFLAGS -DTRACE_LVLV=20 \ 123 | -CFLAGS -DVCD_FNAME=simx.vcd \ 124 | --clk clk \ 125 | --exe $(scr1_wrapper) \ 126 | --trace \ 127 | --trace-params \ 128 | --trace-structs \ 129 | --trace-underscore \ 130 | --Mdir $(bld_dir)/verilator \ 131 | -I$(rtl_inc_dir) \ 132 | -I$(rtl_inc_tb_dir) \ 133 | $(SIM_BUILD_OPTS) \ 134 | $(sv_list); \ 135 | cd verilator; \ 136 | $(MAKE) -f V$(top_module).mk; 137 | 138 | 139 | -------------------------------------------------------------------------------- /sim/tests/benchmarks/coremark/Makefile: -------------------------------------------------------------------------------- 1 | src_dir := $(dir $(lastword $(MAKEFILE_LIST))) 2 | depend_dir := $(src_dir)/../../../../dependencies/coremark 3 | 4 | ADD_FLAGS := -flto 5 | ADD_LDFLAGS := -flto 6 | 7 | ifeq ("$(ITERATIONS)","") 8 | ITERATIONS=1 9 | endif 10 | 11 | ADD_CFLAGS += -DITERATIONS=$(ITERATIONS) 12 | ADD_VPATH := $(depend_dir) 13 | ADD_incs := -I$(src_dir)/src -I$(depend_dir) 14 | 15 | c_src := core_portme.c sc_print.c 16 | coremark_src := ./src/core_list_join.c ./src/core_matrix.c ./src/core_main.c ./src/core_util.c ./src/core_state.c 17 | c_src += core_list_join.c core_matrix.c core_main.c core_util.c core_state.c 18 | 19 | include $(inc_dir)/common.mk 20 | 21 | default: log_requested_tgt $(bld_dir)/coremark.elf $(bld_dir)/coremark.hex $(bld_dir)/coremark.dump 22 | 23 | log_requested_tgt: 24 | echo coremark.hex>> $(bld_dir)/test_info 25 | 26 | clean: 27 | $(RM) $(c_objs) $(asm_objs) $(bld_dir)/coremark.hex $(bld_dir)/coremark.dump 28 | -------------------------------------------------------------------------------- /sim/tests/benchmarks/coremark/core_portme.c: -------------------------------------------------------------------------------- 1 | /* 2 | File : core_portme.c 3 | */ 4 | /* 5 | Author : Shay Gal-On, EEMBC 6 | Legal : TODO! 7 | */ 8 | #include 9 | #include 10 | #include "coremark.h" 11 | #include "core_portme.h" 12 | #include "riscv_csr_encoding.h" 13 | #include "sc_test.h" 14 | 15 | #if VALIDATION_RUN 16 | volatile ee_s32 seed1_volatile=0x3415; 17 | volatile ee_s32 seed2_volatile=0x3415; 18 | volatile ee_s32 seed3_volatile=0x66; 19 | #endif 20 | #if PERFORMANCE_RUN 21 | volatile ee_s32 seed1_volatile=0x0; 22 | volatile ee_s32 seed2_volatile=0x0; 23 | volatile ee_s32 seed3_volatile=0x66; 24 | #endif 25 | #if PROFILE_RUN 26 | volatile ee_s32 seed1_volatile=0x8; 27 | volatile ee_s32 seed2_volatile=0x8; 28 | volatile ee_s32 seed3_volatile=0x8; 29 | #endif 30 | volatile ee_s32 seed4_volatile=ITERATIONS; 31 | volatile ee_s32 seed5_volatile=0; 32 | 33 | /* Porting : Timing functions 34 | How to capture time and convert to seconds must be ported to whatever is supported by the platform. 35 | e.g. Read value from on board RTC, read value from cpu clock cycles performance counter etc. 36 | Sample implementation for standard time.h and windows.h definitions included. 37 | */ 38 | #if 1 39 | CORETIMETYPE barebones_clock() { 40 | unsigned long n; 41 | __asm__ __volatile__ ( 42 | "rdtime %0" 43 | : "=r" (n)); 44 | return n; 45 | } 46 | #define CLOCKS_PER_SEC 10000000 47 | 48 | /* Define : TIMER_RES_DIVIDER 49 | Divider to trade off timer resolution and total time that can be measured. 50 | 51 | Use lower values to increase resolution, but make sure that overflow does not occur. 52 | If there are issues with the return value overflowing, increase this value. 53 | */ 54 | /* #define NSECS_PER_SEC CLOCKS_PER_SEC */ 55 | /* #define CORETIMETYPE clock_t */ 56 | #define GETMYTIME(_t) (*_t=barebones_clock()) 57 | #define MYTIMEDIFF(fin,ini) ((fin)-(ini)) 58 | #define TIMER_RES_DIVIDER 1 59 | #define SAMPLE_TIME_IMPLEMENTATION 1 60 | #define EE_TICKS_PER_SEC (CLOCKS_PER_SEC / TIMER_RES_DIVIDER) 61 | #else 62 | 63 | #endif 64 | 65 | /** Define Host specific (POSIX), or target specific global time variables. */ 66 | static CORETIMETYPE start_time_val, stop_time_val; 67 | 68 | /* Function : start_time 69 | This function will be called right before starting the timed portion of the benchmark. 70 | 71 | Implementation may be capturing a system timer (as implemented in the example code) 72 | or zeroing some system parameters - e.g. setting the cpu clocks cycles to 0. 73 | */ 74 | void start_time(void) { 75 | GETMYTIME(&start_time_val ); 76 | } 77 | /* Function : stop_time 78 | This function will be called right after ending the timed portion of the benchmark. 79 | 80 | Implementation may be capturing a system timer (as implemented in the example code) 81 | or other system parameters - e.g. reading the current value of cpu cycles counter. 82 | */ 83 | void stop_time(void) { 84 | GETMYTIME(&stop_time_val ); 85 | } 86 | /* Function : get_time 87 | Return an abstract "ticks" number that signifies time on the system. 88 | 89 | Actual value returned may be cpu cycles, milliseconds or any other value, 90 | as long as it can be converted to seconds by . 91 | This methodology is taken to accomodate any hardware or simulated platform. 92 | The sample implementation returns millisecs by default, 93 | and the resolution is controlled by 94 | */ 95 | CORE_TICKS get_time(void) { 96 | CORE_TICKS elapsed=(CORE_TICKS)(MYTIMEDIFF(stop_time_val, start_time_val)); 97 | return elapsed; 98 | } 99 | /* Function : time_in_secs 100 | Convert the value returned by get_time to seconds. 101 | 102 | The type is used to accomodate systems with no support for floating point. 103 | Default implementation implemented by the EE_TICKS_PER_SEC macro above. 104 | */ 105 | secs_ret time_in_secs(CORE_TICKS ticks) { 106 | secs_ret retval=((secs_ret)ticks) / (secs_ret)EE_TICKS_PER_SEC; 107 | return retval; 108 | } 109 | 110 | ee_u32 default_num_contexts=1; 111 | 112 | /* Function : portable_init 113 | Target specific initialization code 114 | Test for some common mistakes. 115 | */ 116 | void portable_init(core_portable *p, int *argc, char *argv[]) 117 | { 118 | ee_printf("CoreMark 1.0\n"); 119 | if (sizeof(ee_ptr_int) != sizeof(ee_u8 *)) { 120 | ee_printf("ERROR! Please define ee_ptr_int to a type that holds a pointer! (%u != %u)\n", sizeof(ee_ptr_int), sizeof(ee_u8 *)); 121 | } 122 | if (sizeof(ee_u32) != 4) { 123 | ee_printf("ERROR! Please define ee_u32 to a 32b unsigned type! (%u)\n", sizeof(ee_u32)); 124 | } 125 | p->portable_id=1; 126 | } 127 | /* Function : portable_fini 128 | Target specific final code 129 | */ 130 | void portable_fini(core_portable *p) 131 | { 132 | p->portable_id=0; 133 | 134 | report_results(0, 0, 0, 0, 0); 135 | 136 | /* results[0].iterations * 10000000/(total_time) */ 137 | 138 | /* extern void tohost_exit(long code); */ 139 | 140 | /* tohost_exit(0); */ 141 | } 142 | -------------------------------------------------------------------------------- /sim/tests/benchmarks/coremark/core_portme.h: -------------------------------------------------------------------------------- 1 | /* File : core_portme.h */ 2 | 3 | /* 4 | Author : Shay Gal-On, EEMBC 5 | Legal : TODO! 6 | */ 7 | /* Topic : Description 8 | This file contains configuration constants required to execute on different platforms 9 | */ 10 | #ifndef CORE_PORTME_H 11 | #define CORE_PORTME_H 12 | /************************/ 13 | /* Data types and settings */ 14 | /************************/ 15 | /* Configuration : HAS_FLOAT 16 | Define to 1 if the platform supports floating point. 17 | */ 18 | #ifndef HAS_FLOAT 19 | #define HAS_FLOAT 0 20 | #endif 21 | /* Configuration : HAS_TIME_H 22 | Define to 1 if platform has the time.h header file, 23 | and implementation of functions thereof. 24 | */ 25 | #ifndef HAS_TIME_H 26 | #define HAS_TIME_H 0 27 | #endif 28 | /* Configuration : USE_CLOCK 29 | Define to 1 if platform has the time.h header file, 30 | and implementation of functions thereof. 31 | */ 32 | #ifndef USE_CLOCK 33 | #define USE_CLOCK 0 34 | #endif 35 | /* Configuration : HAS_STDIO 36 | Define to 1 if the platform has stdio.h. 37 | */ 38 | #ifndef HAS_STDIO 39 | #define HAS_STDIO 1 40 | #endif 41 | /* Configuration : HAS_PRINTF 42 | Define to 1 if the platform has stdio.h and implements the printf function. 43 | */ 44 | #ifndef HAS_PRINTF 45 | #define HAS_PRINTF 0 46 | #endif 47 | 48 | #include "sc_print.h" 49 | #define ee_printf sc_printf 50 | 51 | /* static inline int ee_printf(const char *fmt, ...) {} */ 52 | 53 | /* Configuration : CORE_TICKS 54 | Define type of return from the timing functions. 55 | */ 56 | /* #include */ 57 | /* typedef clock_t CORE_TICKS; */ 58 | #include 59 | #include 60 | #define CORETIMETYPE uint32_t 61 | typedef uint32_t CORE_TICKS; 62 | 63 | /* Definitions : COMPILER_VERSION, COMPILER_FLAGS, MEM_LOCATION 64 | Initialize these strings per platform 65 | */ 66 | #ifndef COMPILER_VERSION 67 | #ifdef __GNUC__ 68 | #define COMPILER_VERSION "GCC"__VERSION__ 69 | #else 70 | #define COMPILER_VERSION "Please put compiler version here (e.g. gcc 4.1)" 71 | #endif 72 | #endif 73 | #ifndef COMPILER_FLAGS 74 | #define COMPILER_FLAGS FLAGS_STR /* "Please put compiler flags here (e.g. -o3)" */ 75 | #endif 76 | #ifndef MEM_LOCATION 77 | /* #define MEM_LOCATION "STACK" */ 78 | #define MEM_LOCATION "STATIC" 79 | #endif 80 | 81 | /* Data Types : 82 | To avoid compiler issues, define the data types that need ot be used for 8b, 16b and 32b in . 83 | 84 | *Imprtant* : 85 | ee_ptr_int needs to be the data type used to hold pointers, otherwise coremark may fail!!! 86 | */ 87 | typedef int16_t ee_s16; 88 | typedef uint16_t ee_u16; 89 | typedef int32_t ee_s32; 90 | typedef float ee_f32; 91 | typedef uint8_t ee_u8; 92 | typedef uint32_t ee_u32; 93 | typedef uintptr_t ee_ptr_int; 94 | typedef size_t ee_size_t; 95 | /* align_mem : 96 | This macro is used to align an offset to point to a 32b value. It is used in the Matrix algorithm to initialize the input memory blocks. 97 | */ 98 | #define align_mem(x) (void *)(4 + (((ee_ptr_int)(x) - 1) & ~3)) 99 | 100 | /* Configuration : SEED_METHOD 101 | Defines method to get seed values that cannot be computed at compile time. 102 | 103 | Valid values : 104 | SEED_ARG - from command line. 105 | SEED_FUNC - from a system function. 106 | SEED_VOLATILE - from volatile variables. 107 | */ 108 | #ifndef SEED_METHOD 109 | #define SEED_METHOD SEED_VOLATILE 110 | #endif 111 | 112 | /* Configuration : MEM_METHOD 113 | Defines method to get a block of memry. 114 | 115 | Valid values : 116 | MEM_MALLOC - for platforms that implement malloc and have malloc.h. 117 | MEM_STATIC - to use a static memory array. 118 | MEM_STACK - to allocate the data block on the stack (NYI). 119 | */ 120 | #ifndef MEM_METHOD 121 | /* #define MEM_METHOD MEM_STACK */ 122 | #define MEM_METHOD MEM_STATIC 123 | #endif 124 | 125 | /* Configuration : MULTITHREAD 126 | Define for parallel execution 127 | 128 | Valid values : 129 | 1 - only one context (default). 130 | N>1 - will execute N copies in parallel. 131 | 132 | Note : 133 | If this flag is defined to more then 1, an implementation for launching parallel contexts must be defined. 134 | 135 | Two sample implementations are provided. Use or to enable them. 136 | 137 | It is valid to have a different implementation of and in , 138 | to fit a particular architecture. 139 | */ 140 | #ifndef MULTITHREAD 141 | #define MULTITHREAD 1 142 | #define USE_PTHREAD 0 143 | #define USE_FORK 0 144 | #define USE_SOCKET 0 145 | #endif 146 | 147 | /* Configuration : MAIN_HAS_NOARGC 148 | Needed if platform does not support getting arguments to main. 149 | 150 | Valid values : 151 | 0 - argc/argv to main is supported 152 | 1 - argc/argv to main is not supported 153 | 154 | Note : 155 | This flag only matters if MULTITHREAD has been defined to a value greater then 1. 156 | */ 157 | #ifndef MAIN_HAS_NOARGC 158 | #define MAIN_HAS_NOARGC 1 159 | #endif 160 | 161 | /* Configuration : MAIN_HAS_NORETURN 162 | Needed if platform does not support returning a value from main. 163 | 164 | Valid values : 165 | 0 - main returns an int, and return value will be 0. 166 | 1 - platform does not support returning a value from main 167 | */ 168 | #ifndef MAIN_HAS_NORETURN 169 | #define MAIN_HAS_NORETURN 0 170 | #endif 171 | 172 | /* Variable : default_num_contexts 173 | Not used for this simple port, must cintain the value 1. 174 | */ 175 | extern ee_u32 default_num_contexts; 176 | 177 | typedef struct CORE_PORTABLE_S { 178 | ee_u8 portable_id; 179 | } core_portable; 180 | 181 | /* target specific init/fini */ 182 | void portable_init(core_portable *p, int *argc, char *argv[]); 183 | void portable_fini(core_portable *p); 184 | 185 | #if !defined(PROFILE_RUN) && !defined(PERFORMANCE_RUN) && !defined(VALIDATION_RUN) 186 | #if (TOTAL_DATA_SIZE==1200) 187 | #define PROFILE_RUN 1 188 | #elif (TOTAL_DATA_SIZE==2000) 189 | #define PERFORMANCE_RUN 1 190 | #else 191 | #define VALIDATION_RUN 1 192 | #endif 193 | #endif 194 | 195 | typedef ee_s16 MATDAT; 196 | typedef ee_s32 MATRES; 197 | 198 | 199 | ee_u16 crcu8(ee_u8 data, ee_u16 crc ) __attribute__ ((hot)); 200 | ee_u16 crcu16(ee_u16 newval, ee_u16 crc) __attribute__ ((hot)); 201 | ee_u16 crcu32(ee_u32 newval, ee_u16 crc) __attribute__ ((hot)); 202 | ee_u16 crc16(ee_s16 newval, ee_u16 crc) __attribute__ ((hot)); 203 | ee_s16 matrix_sum(ee_u32 N, MATRES *C, MATDAT clipval) __attribute__ ((hot)); 204 | void matrix_mul_const(ee_u32 N, MATRES *C, MATDAT *A, MATDAT val) __attribute__ ((hot)); 205 | void matrix_mul_vect(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot)); 206 | void matrix_mul_matrix(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot)); 207 | void matrix_mul_matrix_bitextract(ee_u32 N, MATRES *C, MATDAT *A, MATDAT *B) __attribute__ ((hot)); 208 | void matrix_add_const(ee_u32 N, MATDAT *A, MATDAT val) __attribute__ ((hot)); 209 | 210 | #endif /* CORE_PORTME_H */ 211 | -------------------------------------------------------------------------------- /sim/tests/benchmarks/dhrystone21/Makefile: -------------------------------------------------------------------------------- 1 | src_dir := $(dir $(lastword $(MAKEFILE_LIST))) 2 | 3 | ADD_FLAGS := -flto 4 | ADD_LDFLAGS := -flto 5 | ADD_CFLAGS := -DSELF_TIMED=1 -DTIME=1 6 | 7 | c_src := sc_print.c dhry_1.c dhry_2.c 8 | 9 | include $(inc_dir)/common.mk 10 | 11 | default: log_requested_tgt $(bld_dir)/dhrystone21.elf $(bld_dir)/dhrystone21.hex $(bld_dir)/dhrystone21.dump 12 | 13 | log_requested_tgt: 14 | @echo dhrystone21.hex>> $(bld_dir)/test_info 15 | 16 | clean: 17 | $(RM) $(c_objs) $(asm_objs) $(bld_dir)/dhrystone21.elf $(bld_dir)/dhrystone21.hex $(bld_dir)/dhrystone21.dump -------------------------------------------------------------------------------- /sim/tests/benchmarks/dhrystone21/dhry_2.c: -------------------------------------------------------------------------------- 1 | /***************************************************************************** 2 | * The BYTE UNIX Benchmarks - Release 3 3 | * Module: dhry_2.c SID: 3.4 5/15/91 19:30:22 4 | * 5 | ***************************************************************************** 6 | * Bug reports, patches, comments, suggestions should be sent to: 7 | * 8 | * Ben Smith, Rick Grehan or Tom Yager 9 | * ben@bytepb.byte.com rick_g@bytepb.byte.com tyager@bytepb.byte.com 10 | * 11 | ***************************************************************************** 12 | * Modification Log: 13 | * 10/22/97 - code cleanup to remove ANSI C compiler warnings 14 | * Andy Kahn 15 | * 16 | * Adapted from: 17 | * 18 | * "DHRYSTONE" Benchmark Program 19 | * ----------------------------- 20 | * 21 | * **** WARNING **** See warning in n.dhry_1.c 22 | * 23 | * Version: C, Version 2.1 24 | * 25 | * File: dhry_2.c (part 3 of 3) 26 | * 27 | * Date: May 25, 1988 28 | * 29 | * Author: Reinhold P. Weicker 30 | * 31 | ****************************************************************************/ 32 | /* SCCSid is defined in dhry_1.c */ 33 | 34 | #include 35 | #include "dhry.h" 36 | 37 | #ifndef REG 38 | #define REG 39 | /* REG becomes defined as empty */ 40 | /* i.e. no register variables */ 41 | #endif 42 | 43 | extern int Int_Glob; 44 | extern char Ch_1_Glob; 45 | 46 | void Proc_6(Enumeration, Enumeration *); 47 | void Proc_7(One_Fifty, One_Fifty, One_Fifty *); 48 | void Proc_8(Arr_1_Dim, Arr_2_Dim, int, int); 49 | Enumeration Func_1(Capital_Letter, Capital_Letter); 50 | Boolean Func_2(Str_30, Str_30); 51 | Boolean Func_3(Enumeration); 52 | 53 | void Proc_6 (Enumeration Enum_Val_Par, Enumeration *Enum_Ref_Par) 54 | /* executed once */ 55 | /* Enum_Val_Par == Ident_3, Enum_Ref_Par becomes Ident_2 */ 56 | { 57 | *Enum_Ref_Par = Enum_Val_Par; 58 | if (! Func_3 (Enum_Val_Par)) 59 | /* then, not executed */ 60 | *Enum_Ref_Par = Ident_4; 61 | switch (Enum_Val_Par) 62 | { 63 | case Ident_1: 64 | *Enum_Ref_Par = Ident_1; 65 | break; 66 | case Ident_2: 67 | if (Int_Glob > 100) 68 | /* then */ 69 | *Enum_Ref_Par = Ident_1; 70 | else *Enum_Ref_Par = Ident_4; 71 | break; 72 | case Ident_3: /* executed */ 73 | *Enum_Ref_Par = Ident_2; 74 | break; 75 | case Ident_4: break; 76 | case Ident_5: 77 | *Enum_Ref_Par = Ident_3; 78 | break; 79 | } /* switch */ 80 | } /* Proc_6 */ 81 | 82 | void Proc_7 (Int_1_Par_Val, Int_2_Par_Val, Int_Par_Ref) 83 | One_Fifty Int_1_Par_Val; 84 | One_Fifty Int_2_Par_Val; 85 | One_Fifty *Int_Par_Ref; 86 | /**********************************************/ 87 | /* executed three times */ 88 | /* first call: Int_1_Par_Val == 2, Int_2_Par_Val == 3, */ 89 | /* Int_Par_Ref becomes 7 */ 90 | /* second call: Int_1_Par_Val == 10, Int_2_Par_Val == 5, */ 91 | /* Int_Par_Ref becomes 17 */ 92 | /* third call: Int_1_Par_Val == 6, Int_2_Par_Val == 10, */ 93 | /* Int_Par_Ref becomes 18 */ 94 | { 95 | One_Fifty Int_Loc; 96 | 97 | Int_Loc = Int_1_Par_Val + 2; 98 | *Int_Par_Ref = Int_2_Par_Val + Int_Loc; 99 | } /* Proc_7 */ 100 | 101 | 102 | void Proc_8 (Arr_1_Par_Ref, Arr_2_Par_Ref, Int_1_Par_Val, Int_2_Par_Val) 103 | /*********************************************************************/ 104 | /* executed once */ 105 | /* Int_Par_Val_1 == 3 */ 106 | /* Int_Par_Val_2 == 7 */ 107 | Arr_1_Dim Arr_1_Par_Ref; 108 | Arr_2_Dim Arr_2_Par_Ref; 109 | int Int_1_Par_Val; 110 | int Int_2_Par_Val; 111 | { 112 | REG One_Fifty Int_Index; 113 | REG One_Fifty Int_Loc; 114 | 115 | Int_Loc = Int_1_Par_Val + 5; 116 | Arr_1_Par_Ref [Int_Loc] = Int_2_Par_Val; 117 | Arr_1_Par_Ref [Int_Loc+1] = Arr_1_Par_Ref [Int_Loc]; 118 | Arr_1_Par_Ref [Int_Loc+30] = Int_Loc; 119 | for (Int_Index = Int_Loc; Int_Index <= Int_Loc+1; ++Int_Index) 120 | Arr_2_Par_Ref [Int_Loc] [Int_Index] = Int_Loc; 121 | Arr_2_Par_Ref [Int_Loc] [Int_Loc-1] += 1; 122 | Arr_2_Par_Ref [Int_Loc+20] [Int_Loc] = Arr_1_Par_Ref [Int_Loc]; 123 | Int_Glob = 5; 124 | } /* Proc_8 */ 125 | 126 | 127 | Enumeration Func_1 (Capital_Letter Ch_1_Par_Val, Capital_Letter Ch_2_Par_Val) 128 | /*************************************************/ 129 | /* executed three times */ 130 | /* first call: Ch_1_Par_Val == 'H', Ch_2_Par_Val == 'R' */ 131 | /* second call: Ch_1_Par_Val == 'A', Ch_2_Par_Val == 'C' */ 132 | /* third call: Ch_1_Par_Val == 'B', Ch_2_Par_Val == 'C' */ 133 | { 134 | Capital_Letter Ch_1_Loc; 135 | Capital_Letter Ch_2_Loc; 136 | 137 | Ch_1_Loc = Ch_1_Par_Val; 138 | Ch_2_Loc = Ch_1_Loc; 139 | if (Ch_2_Loc != Ch_2_Par_Val) 140 | /* then, executed */ 141 | return (Ident_1); 142 | else /* not executed */ 143 | { 144 | Ch_1_Glob = Ch_1_Loc; 145 | return (Ident_2); 146 | } 147 | } /* Func_1 */ 148 | 149 | 150 | 151 | Boolean Func_2 (Str_1_Par_Ref, Str_2_Par_Ref) 152 | /*************************************************/ 153 | /* executed once */ 154 | /* Str_1_Par_Ref == "DHRYSTONE PROGRAM, 1'ST STRING" */ 155 | /* Str_2_Par_Ref == "DHRYSTONE PROGRAM, 2'ND STRING" */ 156 | 157 | Str_30 Str_1_Par_Ref; 158 | Str_30 Str_2_Par_Ref; 159 | { 160 | REG One_Thirty Int_Loc; 161 | Capital_Letter Ch_Loc; 162 | 163 | Ch_Loc = 'A'; 164 | Int_Loc = 2; 165 | while (Int_Loc <= 2) /* loop body executed once */ 166 | if (Func_1 (Str_1_Par_Ref[Int_Loc], 167 | Str_2_Par_Ref[Int_Loc+1]) == Ident_1) 168 | /* then, executed */ 169 | { 170 | Ch_Loc = 'A'; 171 | Int_Loc += 1; 172 | } /* if, while */ 173 | if (Ch_Loc >= 'W' && Ch_Loc < 'Z') 174 | /* then, not executed */ 175 | Int_Loc = 7; 176 | if (Ch_Loc == 'R') 177 | /* then, not executed */ 178 | return (true); 179 | else /* executed */ 180 | { 181 | if (strcmp (Str_1_Par_Ref, Str_2_Par_Ref) > 0) 182 | /* then, not executed */ 183 | { 184 | Int_Loc += 7; 185 | Int_Glob = Int_Loc; 186 | return (true); 187 | } 188 | else /* executed */ 189 | return (false); 190 | } /* if Ch_Loc */ 191 | } /* Func_2 */ 192 | 193 | 194 | Boolean Func_3 (Enum_Par_Val) 195 | /***************************/ 196 | /* executed once */ 197 | /* Enum_Par_Val == Ident_3 */ 198 | Enumeration Enum_Par_Val; 199 | { 200 | Enumeration Enum_Loc; 201 | 202 | Enum_Loc = Enum_Par_Val; 203 | if (Enum_Loc == Ident_3) 204 | /* then, executed */ 205 | return (true); 206 | else /* not executed */ 207 | return (false); 208 | } /* Func_3 */ 209 | 210 | -------------------------------------------------------------------------------- /sim/tests/common/LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2012-2015, The Regents of the University of California (Regents). 2 | All Rights Reserved. 3 | 4 | Redistribution and use in source and binary forms, with or without 5 | modification, are permitted provided that the following conditions are met: 6 | 1. Redistributions of source code must retain the above copyright 7 | notice, this list of conditions and the following disclaimer. 8 | 2. Redistributions in binary form must reproduce the above copyright 9 | notice, this list of conditions and the following disclaimer in the 10 | documentation and/or other materials provided with the distribution. 11 | 3. Neither the name of the Regents nor the 12 | names of its contributors may be used to endorse or promote products 13 | derived from this software without specific prior written permission. 14 | 15 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 16 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 17 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 18 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 19 | 20 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 21 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 22 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 23 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 24 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 25 | -------------------------------------------------------------------------------- /sim/tests/common/common.mk: -------------------------------------------------------------------------------- 1 | ADD_ASM_MACRO ?= -D__ASSEMBLY__=1 2 | 3 | FLAGS = -O3 -funroll-loops -fpeel-loops -fgcse-sm -fgcse-las $(ADD_FLAGS) 4 | FLAGS_STR = "$(FLAGS)" 5 | 6 | CFLAGS_COMMON = -static -std=gnu99 -fno-common -fno-builtin-printf -DTCM=$(TCM) 7 | CFLAGS_ARCH = -Wa,-march=rv32$(ARCH)_zicsr_zifencei -march=rv32$(ARCH)_zicsr_zifencei -mabi=$(ABI) 8 | 9 | CFLAGS := $(FLAGS) $(EXT_CFLAGS) \ 10 | $(CFLAGS_COMMON) \ 11 | $(CFLAGS_ARCH) \ 12 | -DFLAGS_STR=\"$(FLAGS_STR)\" \ 13 | $(ADD_CFLAGS) 14 | 15 | LDFLAGS ?= -nostartfiles -nostdlib -lc -lgcc -march=rv32$(ARCH)_zicsr_zifencei -mabi=$(ABI) --specs=nano.specs $(ADD_LDFLAGS) 16 | 17 | ifeq (,$(findstring 0,$(TCM))) 18 | ld_script ?= $(inc_dir)/link_tcm.ld 19 | asm_src ?= crt_tcm.S 20 | else 21 | ld_script ?= $(inc_dir)/link.ld 22 | asm_src ?= crt.S 23 | endif 24 | 25 | #this is optional assembly files from project 26 | asm_src += $(asm_src_in_project) 27 | 28 | VPATH += $(src_dir) $(inc_dir) $(ADD_VPATH) 29 | incs += -I$(src_dir) -I$(inc_dir) $(ADD_incs) 30 | 31 | c_objs := $(addprefix $(bld_dir)/,$(patsubst %.c, %.o, $(c_src))) 32 | asm_objs := $(addprefix $(bld_dir)/,$(patsubst %.S, %.o, $(asm_src))) 33 | 34 | $(bld_dir)/%.o: %.S 35 | $(RISCV_GCC) $(CFLAGS) $(ADD_ASM_MACRO) -c $(incs) $< -o $@ 36 | 37 | $(bld_dir)/%.o: %.c 38 | $(RISCV_GCC) $(CFLAGS) -c $(incs) $< -o $@ 39 | 40 | $(bld_dir)/%.elf: $(ld_script) $(c_objs) $(asm_objs) 41 | $(RISCV_GCC) -o $@ -T $^ $(LDFLAGS) 42 | 43 | $(bld_dir)/%.hex: $(bld_dir)/%.elf 44 | $(RISCV_OBJCOPY) $^ $@ 45 | 46 | $(bld_dir)/%.dump: $(bld_dir)/%.elf 47 | $(RISCV_OBJDUMP) -D -w -x -S $^ > $@ 48 | -------------------------------------------------------------------------------- /sim/tests/common/crt.S: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 2 | /// @file 3 | /// 4 | 5 | #include "riscv_csr_encoding.h" 6 | #include "sc_test.h" 7 | 8 | # define LREG lw 9 | # define SREG sw 10 | # define REGBYTES 4 11 | 12 | .globl _start 13 | .globl main 14 | .globl trap_entry 15 | .globl handle_trap 16 | .globl sc_exit 17 | .weak trap_entry, handle_trap 18 | 19 | .text 20 | .org (64*3) 21 | .balign 64 22 | machine_trap_entry: 23 | j trap_entry 24 | 25 | .balign 64 26 | 27 | _start: 28 | #ifndef __RVE_EXT 29 | zero_int_regs 1, 31 30 | #else 31 | zero_int_regs 1, 15 32 | #endif 33 | # Global pointer init 34 | .option push 35 | .option norelax 36 | la gp, __global_pointer$ 37 | .option pop 38 | # clear bss 39 | la a1, __BSS_START__ 40 | la a2, __BSS_END__ 41 | j 4f 42 | 3: sw zero, 0(a1) 43 | add a1, a1, 4 44 | 4: bne a1, a2, 3b 45 | la sp, __C_STACK_TOP__ 46 | 47 | // Timer init 48 | li t0, mtime_ctrl 49 | li t1, (1 << SCR1_MTIME_CTRL_EN) // enable, use internal clock 50 | sw t1, (t0) 51 | li t0, mtime_div 52 | li t1, (100-1) // divide by 100 53 | sw t1, (t0) 54 | li t0, mtimecmp 55 | li t1, -1 56 | sw t1, (t0) // max value for mtimecmp 57 | sw t1, 4(t0) 58 | 59 | li a0, 0 60 | li a1, 0 61 | call main 62 | tail sc_exit 63 | 64 | trap_entry: 65 | addi sp, sp, -272 66 | 67 | SREG x1, 1*REGBYTES(sp) 68 | SREG x2, 2*REGBYTES(sp) 69 | SREG x3, 3*REGBYTES(sp) 70 | SREG x4, 4*REGBYTES(sp) 71 | SREG x5, 5*REGBYTES(sp) 72 | SREG x6, 6*REGBYTES(sp) 73 | SREG x7, 7*REGBYTES(sp) 74 | SREG x8, 8*REGBYTES(sp) 75 | SREG x9, 9*REGBYTES(sp) 76 | SREG x10, 10*REGBYTES(sp) 77 | SREG x11, 11*REGBYTES(sp) 78 | SREG x12, 12*REGBYTES(sp) 79 | SREG x13, 13*REGBYTES(sp) 80 | SREG x14, 14*REGBYTES(sp) 81 | SREG x15, 15*REGBYTES(sp) 82 | #ifndef __RVE_EXT 83 | SREG x16, 16*REGBYTES(sp) 84 | SREG x17, 17*REGBYTES(sp) 85 | SREG x18, 18*REGBYTES(sp) 86 | SREG x19, 19*REGBYTES(sp) 87 | SREG x20, 20*REGBYTES(sp) 88 | SREG x21, 21*REGBYTES(sp) 89 | SREG x22, 22*REGBYTES(sp) 90 | SREG x23, 23*REGBYTES(sp) 91 | SREG x24, 24*REGBYTES(sp) 92 | SREG x25, 25*REGBYTES(sp) 93 | SREG x26, 26*REGBYTES(sp) 94 | SREG x27, 27*REGBYTES(sp) 95 | SREG x28, 28*REGBYTES(sp) 96 | SREG x29, 29*REGBYTES(sp) 97 | SREG x30, 30*REGBYTES(sp) 98 | SREG x31, 31*REGBYTES(sp) 99 | #endif // __RVE_EXT 100 | 101 | csrr a0, mcause 102 | csrr a1, mepc 103 | mv a2, sp 104 | call handle_trap 105 | 106 | LREG x1, 1*REGBYTES(sp) 107 | LREG x2, 2*REGBYTES(sp) 108 | LREG x3, 3*REGBYTES(sp) 109 | LREG x4, 4*REGBYTES(sp) 110 | LREG x5, 5*REGBYTES(sp) 111 | LREG x6, 6*REGBYTES(sp) 112 | LREG x7, 7*REGBYTES(sp) 113 | LREG x8, 8*REGBYTES(sp) 114 | LREG x9, 9*REGBYTES(sp) 115 | LREG x10, 10*REGBYTES(sp) 116 | LREG x11, 11*REGBYTES(sp) 117 | LREG x12, 12*REGBYTES(sp) 118 | LREG x13, 13*REGBYTES(sp) 119 | LREG x14, 14*REGBYTES(sp) 120 | LREG x15, 15*REGBYTES(sp) 121 | #ifndef __RVE_EXT 122 | LREG x16, 16*REGBYTES(sp) 123 | LREG x17, 17*REGBYTES(sp) 124 | LREG x18, 18*REGBYTES(sp) 125 | LREG x19, 19*REGBYTES(sp) 126 | LREG x20, 20*REGBYTES(sp) 127 | LREG x21, 21*REGBYTES(sp) 128 | LREG x22, 22*REGBYTES(sp) 129 | LREG x23, 23*REGBYTES(sp) 130 | LREG x24, 24*REGBYTES(sp) 131 | LREG x25, 25*REGBYTES(sp) 132 | LREG x26, 26*REGBYTES(sp) 133 | LREG x27, 27*REGBYTES(sp) 134 | LREG x28, 28*REGBYTES(sp) 135 | LREG x29, 29*REGBYTES(sp) 136 | LREG x30, 30*REGBYTES(sp) 137 | LREG x31, 31*REGBYTES(sp) 138 | #endif // __RVE_EXT 139 | 140 | addi sp, sp, 272 141 | mret 142 | 143 | handle_trap: 144 | j SIM_EXIT 145 | 146 | // end of crt.S -------------------------------------------------------------------------------- /sim/tests/common/crt_tcm.S: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 2 | /// @file 3 | /// 4 | 5 | #include "riscv_csr_encoding.h" 6 | #include "reloc.h" 7 | #include "sc_test.h" 8 | 9 | # define LREG lw 10 | # define SREG sw 11 | # define REGBYTES 4 12 | 13 | .globl _start 14 | .globl main 15 | .globl trap_entry 16 | .globl handle_trap 17 | .globl sc_exit 18 | .weak trap_entry, handle_trap 19 | 20 | .section .text.init 21 | .org (64*3) 22 | .align 6; 23 | machine_trap_entry: 24 | j trap_entry 25 | 26 | .align 6 27 | _start: 28 | #ifndef __RVE_EXT 29 | zero_int_regs 1, 31 30 | #else 31 | zero_int_regs 1, 15 32 | #endif 33 | # Global pointer init 34 | .option push 35 | .option norelax 36 | la gp, __global_pointer$ 37 | .option pop 38 | 39 | RELOC_PROC; 40 | 41 | // init tdata 42 | mv a1, tp 43 | la a2, _tdata_end 44 | j 6f 45 | 5: lw a3, 0(a0) 46 | sw a3, 0(a1) 47 | add a0, a0, 4 48 | add a1, a1, 4 49 | 6: bne a0, a2, 5b 50 | // clear tbss 51 | j 8f 52 | 7: sw zero, 0(a1) 53 | add a1, a1, 4 54 | 8: bne a1, a4, 7b 55 | 56 | // Timer init 57 | li t0, mtime_ctrl 58 | li t1, (1 << SCR1_MTIME_CTRL_EN) // enable, use internal clock 59 | sw t1, (t0) 60 | li t0, mtime_div 61 | li t1, (100-1) // divide by 100 62 | sw t1, (t0) 63 | li t0, mtimecmp 64 | li t1, -1 65 | sw t1, (t0) // max value for mtimecmp 66 | sw t1, 4(t0) 67 | 68 | li a0, 0 69 | li a1, 0 70 | call main 71 | tail sc_exit 72 | 73 | trap_entry: 74 | addi sp, sp, -272 75 | 76 | SREG x1, 1*REGBYTES(sp) 77 | SREG x2, 2*REGBYTES(sp) 78 | SREG x3, 3*REGBYTES(sp) 79 | SREG x4, 4*REGBYTES(sp) 80 | SREG x5, 5*REGBYTES(sp) 81 | SREG x6, 6*REGBYTES(sp) 82 | SREG x7, 7*REGBYTES(sp) 83 | SREG x8, 8*REGBYTES(sp) 84 | SREG x9, 9*REGBYTES(sp) 85 | SREG x10, 10*REGBYTES(sp) 86 | SREG x11, 11*REGBYTES(sp) 87 | SREG x12, 12*REGBYTES(sp) 88 | SREG x13, 13*REGBYTES(sp) 89 | SREG x14, 14*REGBYTES(sp) 90 | SREG x15, 15*REGBYTES(sp) 91 | #ifndef __RVE_EXT 92 | SREG x16, 16*REGBYTES(sp) 93 | SREG x17, 17*REGBYTES(sp) 94 | SREG x18, 18*REGBYTES(sp) 95 | SREG x19, 19*REGBYTES(sp) 96 | SREG x20, 20*REGBYTES(sp) 97 | SREG x21, 21*REGBYTES(sp) 98 | SREG x22, 22*REGBYTES(sp) 99 | SREG x23, 23*REGBYTES(sp) 100 | SREG x24, 24*REGBYTES(sp) 101 | SREG x25, 25*REGBYTES(sp) 102 | SREG x26, 26*REGBYTES(sp) 103 | SREG x27, 27*REGBYTES(sp) 104 | SREG x28, 28*REGBYTES(sp) 105 | SREG x29, 29*REGBYTES(sp) 106 | SREG x30, 30*REGBYTES(sp) 107 | SREG x31, 31*REGBYTES(sp) 108 | #endif // __RVE_EXT 109 | 110 | csrr a0, mcause 111 | csrr a1, mepc 112 | mv a2, sp 113 | call handle_trap 114 | 115 | LREG x1, 1*REGBYTES(sp) 116 | LREG x2, 2*REGBYTES(sp) 117 | LREG x3, 3*REGBYTES(sp) 118 | LREG x4, 4*REGBYTES(sp) 119 | LREG x5, 5*REGBYTES(sp) 120 | LREG x6, 6*REGBYTES(sp) 121 | LREG x7, 7*REGBYTES(sp) 122 | LREG x8, 8*REGBYTES(sp) 123 | LREG x9, 9*REGBYTES(sp) 124 | LREG x10, 10*REGBYTES(sp) 125 | LREG x11, 11*REGBYTES(sp) 126 | LREG x12, 12*REGBYTES(sp) 127 | LREG x13, 13*REGBYTES(sp) 128 | LREG x14, 14*REGBYTES(sp) 129 | LREG x15, 15*REGBYTES(sp) 130 | #ifndef __RVE_EXT 131 | LREG x16, 16*REGBYTES(sp) 132 | LREG x17, 17*REGBYTES(sp) 133 | LREG x18, 18*REGBYTES(sp) 134 | LREG x19, 19*REGBYTES(sp) 135 | LREG x20, 20*REGBYTES(sp) 136 | LREG x21, 21*REGBYTES(sp) 137 | LREG x22, 22*REGBYTES(sp) 138 | LREG x23, 23*REGBYTES(sp) 139 | LREG x24, 24*REGBYTES(sp) 140 | LREG x25, 25*REGBYTES(sp) 141 | LREG x26, 26*REGBYTES(sp) 142 | LREG x27, 27*REGBYTES(sp) 143 | LREG x28, 28*REGBYTES(sp) 144 | LREG x29, 29*REGBYTES(sp) 145 | LREG x30, 30*REGBYTES(sp) 146 | LREG x31, 31*REGBYTES(sp) 147 | #endif // __RVE_EXT 148 | 149 | addi sp, sp, 272 150 | mret 151 | 152 | handle_trap: 153 | j SIM_EXIT 154 | 155 | // end of crt.S -------------------------------------------------------------------------------- /sim/tests/common/csr.h: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 2 | /// @file 3 | /// Architecture specific CSR's defs and inlines 4 | 5 | #ifndef SCR_CSR_H 6 | #define SCR_CSR_H 7 | 8 | #include 9 | #include 10 | 11 | #define __xstringify(s) __stringify(s) 12 | #define __stringify(s) #s 13 | 14 | #ifdef read_csr 15 | #undef read_csr 16 | #endif 17 | 18 | #ifdef write_csr 19 | #undef write_csr 20 | #endif 21 | 22 | #ifdef swap_csr 23 | #undef swap_csr 24 | #endif 25 | 26 | #ifdef set_csr 27 | #undef set_csr 28 | #endif 29 | 30 | #ifdef clear_csr 31 | #undef clear_csr 32 | #endif 33 | 34 | #ifdef rdtime 35 | #undef rdtime 36 | #endif 37 | 38 | #ifdef rdcycle 39 | #undef rdcycle 40 | #endif 41 | 42 | #ifdef rdinstret 43 | #undef rdinstret 44 | #endif 45 | 46 | #define read_csr(reg) \ 47 | ({ \ 48 | unsigned long __tmp; \ 49 | asm volatile ("csrr %0, " __xstringify(reg) : "=r"(__tmp)); \ 50 | __tmp; \ 51 | }) 52 | 53 | #define write_csr(reg, val) \ 54 | do { \ 55 | if (__builtin_constant_p(val) && (val) == 0) \ 56 | asm volatile ("csrw " __xstringify(reg) ", zero" ::); \ 57 | else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ 58 | asm volatile ("csrw " __xstringify(reg) ", %0" :: "i"(val)); \ 59 | else \ 60 | asm volatile ("csrw " __xstringify(reg) ", %0" :: "r"(val)); \ 61 | } while (0) 62 | 63 | #define swap_csr(reg, val) \ 64 | ({ \ 65 | unsigned long __tmp; \ 66 | if (__builtin_constant_p(val) && (val) == 0) \ 67 | asm volatile ("csrrw %0, " __xstringify(reg) ", zero" : "=r"(__tmp) :); \ 68 | else if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ 69 | asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(val)); \ 70 | else \ 71 | asm volatile ("csrrw %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(val)); \ 72 | __tmp; \ 73 | }) 74 | 75 | #define set_csr(reg, bit) \ 76 | ({ \ 77 | unsigned long __tmp; \ 78 | if (__builtin_constant_p(bit) && (bit) < 32) \ 79 | asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \ 80 | else \ 81 | asm volatile ("csrrs %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \ 82 | __tmp; \ 83 | }) 84 | 85 | #define clear_csr(reg, bit) \ 86 | ({ \ 87 | unsigned long __tmp; \ 88 | if (__builtin_constant_p(bit) && (bit) < 32) \ 89 | asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "i"(bit)); \ 90 | else \ 91 | asm volatile ("csrrc %0, " __xstringify(reg) ", %1" : "=r"(__tmp) : "r"(bit)); \ 92 | __tmp; \ 93 | }) 94 | 95 | #define rdtime() read_csr(time) 96 | #define rdcycle() read_csr(cycle) 97 | #define rdinstret() read_csr(instret) 98 | 99 | static inline unsigned long __attribute__((const)) hartid() 100 | { 101 | unsigned long res; 102 | asm ("csrr %0, mhartid" : "=r"(res)); 103 | return res; 104 | } 105 | 106 | static inline unsigned long __attribute__((const)) impid() 107 | { 108 | unsigned long res; 109 | asm ("csrr %0, mimpid" : "=r"(res)); 110 | return res; 111 | } 112 | 113 | #endif // SCR_CSR_H 114 | -------------------------------------------------------------------------------- /sim/tests/common/link.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 3 | * @file 4 | * @brief bare metal tests' linker script 5 | */ 6 | 7 | OUTPUT_ARCH( "riscv" ) 8 | ENTRY(_start) 9 | 10 | MEMORY { 11 | RAM (rwx) : ORIGIN = 0x0, LENGTH = 64K 12 | } 13 | 14 | STACK_SIZE = 1024; 15 | 16 | CL_SIZE = 32; 17 | 18 | SECTIONS { 19 | 20 | /* code segment */ 21 | .text.init 0 : { 22 | FILL(0); 23 | . = 0x100 - 12; 24 | SIM_EXIT = .; 25 | LONG(0x13); 26 | SIM_STOP = .; 27 | LONG(0x6F); 28 | LONG(-1); 29 | . = 0x100; 30 | PROVIDE(__TEXT_START__ = .); 31 | *(.text.init) 32 | } >RAM 33 | 34 | .text : { 35 | *crt.o(.text .text.*) 36 | *(.text .text.*) 37 | *(sc_test_section) 38 | . = ALIGN(CL_SIZE); 39 | PROVIDE(__TEXT_END__ = .); 40 | } >RAM 41 | 42 | /* data segment */ 43 | .data : { 44 | *(.data .data.*) 45 | . = ALIGN(CL_SIZE); 46 | } >RAM 47 | 48 | .sdata : { 49 | __global_pointer$ = . + 0x800; 50 | *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) 51 | *(.sdata .sdata.* .gnu.linkonce.s.*) 52 | . = ALIGN(CL_SIZE); 53 | } >RAM 54 | 55 | /* thread-local data segment */ 56 | .tdata : { 57 | PROVIDE(_tls_data = .); 58 | PROVIDE(_tdata_begin = .); 59 | *(.tdata .tdata.*) 60 | PROVIDE(_tdata_end = .); 61 | . = ALIGN(CL_SIZE); 62 | } >RAM 63 | 64 | .tbss : { 65 | PROVIDE(__BSS_START__ = .); 66 | *(.tbss .tbss.*) 67 | . = ALIGN(CL_SIZE); 68 | PROVIDE(_tbss_end = .); 69 | } >RAM 70 | 71 | /* bss segment */ 72 | .sbss : { 73 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 74 | *(.scommon) 75 | } >RAM 76 | 77 | .bss : { 78 | *(.bss .bss.*) 79 | . = ALIGN(CL_SIZE); 80 | PROVIDE(__BSS_END__ = .); 81 | } >RAM 82 | 83 | _end = .; 84 | PROVIDE(__end = .); 85 | 86 | /* End of uninitalized data segement */ 87 | 88 | .stack ORIGIN(RAM) + LENGTH(RAM) - STACK_SIZE : { 89 | FILL(0); 90 | PROVIDE(__STACK_START__ = .); 91 | . += STACK_SIZE; 92 | PROVIDE(__C_STACK_TOP__ = .); 93 | PROVIDE(__STACK_END__ = .); 94 | } >RAM 95 | 96 | /DISCARD/ : { 97 | *(.eh_frame .eh_frame.*) 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /sim/tests/common/link_tcm.ld: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 3 | * @file 4 | * @brief bare metal tests' linker script 5 | */ 6 | 7 | OUTPUT_ARCH( "riscv" ) 8 | ENTRY(_start) 9 | 10 | MEMORY { 11 | RAM (rwx) : ORIGIN = 0x0, LENGTH = 64K 12 | TCM (rwx) : ORIGIN = 0x00480000, LENGTH = 64K 13 | } 14 | 15 | STACK_SIZE = 1024; 16 | 17 | CL_SIZE = 32; 18 | 19 | SECTIONS { 20 | 21 | /* code segment */ 22 | .text.init ORIGIN(RAM) : { 23 | FILL(0); 24 | . = 0x100 - 12; 25 | SIM_EXIT = .; 26 | LONG(0x13); 27 | SIM_STOP = .; 28 | LONG(0x6F); 29 | LONG(-1); 30 | . = 0x100; 31 | *crt_tcm.o(.text .text.*) 32 | *(.text.init) 33 | . = ALIGN(CL_SIZE); 34 | } >RAM 35 | 36 | __reloc_start = .; 37 | 38 | .text : { 39 | PROVIDE(__TEXT_START__ = .); 40 | *(.text .text.*) 41 | *(sc_test_section) 42 | . = ALIGN(CL_SIZE); 43 | PROVIDE(__TEXT_END__ = .); 44 | } >TCM AT>RAM 45 | 46 | .rodata ALIGN(CL_SIZE) : { 47 | __global_pointer$ = . + 0x800; 48 | *(.rodata) *(.rodata.*) *(.gnu.linkonce.r.*) 49 | . = ALIGN(CL_SIZE); 50 | LONG(0x13); 51 | . = ALIGN(CL_SIZE); 52 | } >TCM AT>RAM 53 | 54 | 55 | /* data segment */ 56 | .data ALIGN(CL_SIZE) : { 57 | PROVIDE(__DATA_START__ = .); 58 | *(.data .data.*) 59 | . = ALIGN(CL_SIZE); 60 | } >TCM AT>RAM 61 | 62 | 63 | .sdata ALIGN(CL_SIZE) : { 64 | *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) 65 | *(.sdata .sdata.* .gnu.linkonce.s.*) 66 | . = ALIGN(CL_SIZE); 67 | PROVIDE(__DATA_END__ = .); 68 | } >TCM AT>RAM 69 | 70 | /* thread-local data segment */ 71 | .tdata ALIGN(CL_SIZE) : { 72 | PROVIDE(_tls_data = .); 73 | PROVIDE(_tdata_begin = .); 74 | *(.tdata .tdata.*) 75 | PROVIDE(_tdata_end = .); 76 | . = ALIGN(CL_SIZE); 77 | } >TCM AT>RAM 78 | 79 | .tbss ALIGN(CL_SIZE) : { 80 | PROVIDE(_tbss_begin = .); 81 | *(.tbss .tbss.*) 82 | . = ALIGN(CL_SIZE); 83 | PROVIDE(_tbss_end = .); 84 | } >TCM AT>RAM 85 | 86 | /* bss segment */ 87 | .sbss ALIGN(CL_SIZE) : { 88 | PROVIDE(__BSS_START__ = .); 89 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 90 | *(.scommon) 91 | . = ALIGN(CL_SIZE); 92 | } >TCM AT>RAM 93 | 94 | .bss ALIGN(CL_SIZE) : { 95 | *(.dynbss) *(.bss .bss.* .gnu.linkonce.b.*) *(COMMON) 96 | . = ALIGN(CL_SIZE); 97 | PROVIDE(__BSS_END__ = .); 98 | } >TCM AT>RAM 99 | 100 | _end = .; 101 | PROVIDE(__end = .); 102 | 103 | /* End of uninitalized data segement */ 104 | 105 | .stack ORIGIN(TCM) + LENGTH(TCM) - STACK_SIZE : { 106 | PROVIDE(__STACK_START__ = .); 107 | . += STACK_SIZE; 108 | PROVIDE(__C_STACK_TOP__ = .); 109 | PROVIDE(__STACK_END__ = .); 110 | } >TCM 111 | 112 | /DISCARD/ : { 113 | *(.eh_frame .eh_frame.*) 114 | } 115 | } 116 | -------------------------------------------------------------------------------- /sim/tests/common/reloc.h: -------------------------------------------------------------------------------- 1 | #ifndef RELOC_H 2 | #define RELOC_H 3 | 4 | #if (TCM == 1) 5 | #define RELOC_PROC \ 6 | la a0, __reloc_start; \ 7 | la a1, __TEXT_START__; \ 8 | la a2, __DATA_END__; \ 9 | beq a0, a1, 21f; \ 10 | j 2f; \ 11 | 1: lw a3, 0(a0); \ 12 | sw a3, 0(a1); \ 13 | add a0, a0, 4; \ 14 | add a1, a1, 4; \ 15 | 2: bne a1, a2, 1b; \ 16 | /* clear bss */ \ 17 | la a2, __BSS_START__; \ 18 | 21: la a1, __BSS_END__; \ 19 | j 4f; \ 20 | 3: sw zero, 0(a2); \ 21 | add a2, a2, 4; \ 22 | 4: bne a1, a2, 3b; \ 23 | /* init stack */ \ 24 | la sp, __C_STACK_TOP__; \ 25 | /* init hart0 TLS */ \ 26 | la a0, _tdata_begin; \ 27 | la a2, _tbss_end; \ 28 | sub a1, a2, a0; \ 29 | la a4, __STACK_START__; \ 30 | sub tp, a4, a1; 31 | #else // #if TCM 32 | 33 | #define RELOC_PROC 34 | 35 | #endif // #else #if TCM 36 | 37 | #endif // -------------------------------------------------------------------------------- /sim/tests/common/sc_print.c: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 2 | /// @file 3 | /// 4 | 5 | #include 6 | #include 7 | #include "sc_print.h" 8 | 9 | #define SC_SIM_OUTPORT (0xf0000000) 10 | #define CHAR_BIT (8) 11 | 12 | static void 13 | sc_puts(long str, long strlen) { 14 | volatile char *out_ptr = (volatile char*)SC_SIM_OUTPORT; 15 | const char *in_ptr = (const char*)str; 16 | for (long len = strlen; len > 0; --len) 17 | *out_ptr = *in_ptr++; 18 | } 19 | 20 | #undef putchar 21 | int 22 | putchar(int ch) { 23 | static __thread char buf[64] __attribute__((aligned(64))); 24 | static __thread int buflen = 0; 25 | 26 | buf[buflen++] = ch; 27 | 28 | if ( ch == '\n' || buflen == sizeof(buf) ) { 29 | sc_puts((long)buf, buflen); 30 | buflen = 0; 31 | } 32 | 33 | return 0; 34 | } 35 | 36 | static void 37 | printf_putch(int ch, void** data) 38 | { 39 | putchar(ch); 40 | } 41 | 42 | static void 43 | print(const char *str) 44 | { 45 | sc_puts((long)str, strlen(str)); 46 | } 47 | 48 | 49 | static long long 50 | getint(va_list *ap, int lflag) 51 | { 52 | if ( lflag >= 2 ) 53 | return va_arg(*ap, long long); 54 | else if ( lflag ) 55 | return va_arg(*ap, long); 56 | else 57 | return va_arg(*ap, int); 58 | } 59 | 60 | 61 | static unsigned long long 62 | getuint(va_list *ap, int lflag) 63 | { 64 | if ( lflag >= 2 ) 65 | return va_arg(*ap, unsigned long long); 66 | else if ( lflag ) 67 | return va_arg(*ap, unsigned long); 68 | else 69 | return va_arg(*ap, unsigned int); 70 | } 71 | 72 | static inline void 73 | printnum(void(*putch)(int, void**), 74 | void **putdat, 75 | unsigned long long num, 76 | unsigned base, 77 | int width, 78 | int padc, 79 | int hex_A) 80 | { 81 | unsigned digs[sizeof(num) * CHAR_BIT]; 82 | int pos = 0; 83 | 84 | for ( ;; ) { 85 | digs[pos++] = num % base; 86 | if ( num < base ) 87 | break; 88 | num /= base; 89 | } 90 | 91 | while ( width-- > pos ) 92 | putch(padc, putdat); 93 | 94 | while ( pos-- > 0 ) 95 | putch(digs[pos] + (digs[pos] >= 10 ? hex_A - 10 : '0'), putdat); 96 | } 97 | 98 | static void 99 | vprintfmt(void(*putch)(int, void**), void **putdat, const char *fmt, va_list ap) 100 | { 101 | register const char* p; 102 | const char* last_fmt; 103 | register int ch; 104 | int err; 105 | unsigned long long num; 106 | int base; 107 | int lflag; 108 | int width; 109 | int precision; 110 | int altflag; 111 | char padc; 112 | int hex_A = 'a'; 113 | for ( ;; ) { 114 | while ( (ch = *(unsigned char *)fmt) != '%' ) { 115 | if ( ch == '\0' ) 116 | return; 117 | ++fmt; 118 | putch(ch, putdat); 119 | } 120 | ++fmt; 121 | 122 | // Process a %-escape sequence 123 | last_fmt = fmt; 124 | padc = ' '; 125 | width = -1; 126 | precision = -1; 127 | lflag = 0; 128 | altflag = 0; 129 | 130 | reswitch: 131 | switch ( ch = *(unsigned char *)fmt++ ) { 132 | // flag to pad on the right 133 | case '-': 134 | padc = '-'; 135 | goto reswitch; 136 | 137 | // flag to pad with 0's instead of spaces 138 | case '0': 139 | padc = '0'; 140 | goto reswitch; 141 | 142 | // width field 143 | case '1': 144 | case '2': 145 | case '3': 146 | case '4': 147 | case '5': 148 | case '6': 149 | case '7': 150 | case '8': 151 | case '9': 152 | for ( precision = 0;; ++fmt ) { 153 | precision = precision * 10 + ch - '0'; 154 | ch = *fmt; 155 | if ( ch < '0' || ch > '9' ) 156 | break; 157 | } 158 | goto process_precision; 159 | 160 | case '*': 161 | precision = va_arg(ap, int); 162 | goto process_precision; 163 | 164 | case '.': 165 | if ( width < 0 ) 166 | width = 0; 167 | goto reswitch; 168 | 169 | case '#': 170 | altflag = 1; 171 | goto reswitch; 172 | 173 | process_precision: 174 | if ( width < 0 ) { 175 | width = precision; 176 | precision = -1; 177 | } 178 | goto reswitch; 179 | 180 | // long flag (doubled for long long) 181 | case 'l': 182 | lflag++; 183 | goto reswitch; 184 | 185 | // character 186 | case 'c': 187 | putch(va_arg(ap, int), putdat); 188 | break; 189 | 190 | // string 191 | case 's': 192 | if ( (p = va_arg(ap, char *)) == NULL ) 193 | p = "(null)"; 194 | if ( width > 0 && padc != '-' ) 195 | for ( width -= strnlen(p, precision); width > 0; width-- ) 196 | putch(padc, putdat); 197 | for ( ; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width-- ) { 198 | putch(ch, putdat); 199 | p++; 200 | } 201 | for ( ; width > 0; width-- ) 202 | putch(' ', putdat); 203 | break; 204 | 205 | // (signed) decimal 206 | case 'd': 207 | num = getint(&ap, lflag); 208 | if ( (long long)num < 0 ) { 209 | putch('-', putdat); 210 | num = -(long long)num; 211 | } 212 | base = 10; 213 | goto signed_number; 214 | 215 | case 'f': 216 | { 217 | // #ifndef nopfloat 218 | // double num = getdouble(&ap, lflag); 219 | // printdoubleF(putch, putdat, num, width, precision, padc); 220 | // #endif 221 | } 222 | break; 223 | 224 | // unsigned decimal 225 | case 'u': 226 | base = 10; 227 | goto unsigned_number; 228 | 229 | // (unsigned) octal 230 | case 'o': 231 | // should do something with padding so it's always 3 octits 232 | base = 8; 233 | goto unsigned_number; 234 | 235 | // pointer 236 | case 'p': 237 | // static_assert(sizeof(long) == sizeof(void*)); 238 | lflag = 1; 239 | putch('0', putdat); 240 | putch('x', putdat); 241 | /* fall through to 'x' */ 242 | 243 | // (unsigned) hexadecimal 244 | case 'x': 245 | hex_A = 'a'; 246 | base = 16; 247 | goto unsigned_number; 248 | 249 | case 'X': 250 | hex_A = 'A'; 251 | base = 16; 252 | unsigned_number: 253 | num = getuint(&ap, lflag); 254 | signed_number: 255 | printnum(putch, putdat, num, base, width, padc, hex_A); 256 | break; 257 | 258 | // escaped '%' character 259 | case '%': 260 | putch(ch, putdat); 261 | break; 262 | 263 | // unrecognized escape sequence - just print it literally 264 | default: 265 | putch('%', putdat); 266 | fmt = last_fmt; 267 | break; 268 | } 269 | } 270 | } 271 | 272 | int 273 | sc_printf(const char* fmt, ...) 274 | { 275 | va_list ap; 276 | va_start(ap, fmt); 277 | 278 | vprintfmt(printf_putch, NULL, fmt, ap); 279 | 280 | va_end(ap); 281 | return 0; // incorrect return value, but who cares, anyway? 282 | } 283 | -------------------------------------------------------------------------------- /sim/tests/common/sc_print.h: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 2 | /// @file 3 | /// 4 | 5 | #ifndef SC_PRINT_H 6 | #define SC_PRINT_H 7 | 8 | extern int sc_printf(const char* fmt, ...); 9 | 10 | #endif // SC_PRINT_H -------------------------------------------------------------------------------- /sim/tests/common/sc_test.h: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016, 2017. See LICENSE for details 2 | /// @file 3 | /// 4 | 5 | #ifndef SC_TEST_H 6 | #define SC_TEST_H 7 | 8 | #if defined(__ASSEMBLER__) 9 | .altmacro 10 | 11 | .macro zero_int_reg regn 12 | mv x\regn, zero 13 | .endm 14 | 15 | .macro zero_int_regs reg_first, reg_last 16 | .set regn, \reg_first 17 | .rept \reg_last - \reg_first + 1 18 | zero_int_reg %(regn) 19 | .set regn, regn+1 20 | .endr 21 | .endm 22 | 23 | #define report_results(result) \ 24 | li a0, result; \ 25 | la t0, sc_exit; \ 26 | jr t0; 27 | 28 | .pushsection sc_test_section, "ax" 29 | sc_exit: la t0, SIM_EXIT; jr t0; 30 | .balign 32 31 | .popsection 32 | #define sc_pass report_results(0x0) 33 | #define sc_fail report_results(0x1) 34 | 35 | #else 36 | 37 | extern void sc_exit(unsigned result, unsigned res0, unsigned res1, unsigned res2, unsigned res3) 38 | __attribute__ ((noinline, noreturn)); 39 | 40 | static inline void __attribute__ ((noreturn)) 41 | report_results(unsigned result, unsigned res0, unsigned res1, unsigned res2, unsigned res3) 42 | { 43 | sc_exit(result, res0, res1, res2, res3); 44 | } 45 | 46 | #endif 47 | 48 | #endif // SC_TEST_H 49 | -------------------------------------------------------------------------------- /sim/tests/common/scr1_specific.h: -------------------------------------------------------------------------------- 1 | #ifndef __SCR1__SPECIFIC 2 | #define __SCR1__SPECIFIC 3 | 4 | #define mcounten 0x7E0 5 | 6 | // Memory-mapped registers 7 | #define mtime_ctrl 0x00490000 8 | #define mtime_div 0x00490004 9 | #define mtime 0x00490008 10 | #define mtimeh 0x0049000C 11 | #define mtimecmp 0x00490010 12 | #define mtimecmph 0x00490014 13 | 14 | #define SCR1_MTIME_CTRL_EN 0 15 | #define SCR1_MTIME_CTRL_CLKSRC 1 16 | 17 | #define SCR1_MTIME_CTRL_WR_MASK 0x3 18 | #define SCR1_MTIME_DIV_WR_MASK 0x3FF 19 | 20 | #endif // _SCR1__SPECIFIC 21 | -------------------------------------------------------------------------------- /sim/tests/hello/Makefile: -------------------------------------------------------------------------------- 1 | src_dir := $(dir $(lastword $(MAKEFILE_LIST))) 2 | 3 | c_src := sc_print.c hello.c 4 | 5 | include $(inc_dir)/common.mk 6 | 7 | default: log_requested_tgt $(bld_dir)/hello.elf $(bld_dir)/hello.hex $(bld_dir)/hello.dump 8 | 9 | log_requested_tgt: 10 | echo hello.hex>> $(bld_dir)/test_info 11 | 12 | clean: 13 | $(RM) $(c_objs) $(asm_objs) $(bld_dir)/hello.elf $(bld_dir)/hello.hex $(bld_dir)/hello.dump -------------------------------------------------------------------------------- /sim/tests/hello/hello.c: -------------------------------------------------------------------------------- 1 | #include "sc_print.h" 2 | 3 | int main() 4 | { 5 | sc_printf("Hello from SCR1!\n"); 6 | return 0; 7 | } -------------------------------------------------------------------------------- /sim/tests/isr_sample/Makefile: -------------------------------------------------------------------------------- 1 | src_dir := $(dir $(lastword $(MAKEFILE_LIST))) 2 | 3 | LDFLAGS := -nostartfiles -nostdlib -march=rv32$(ARCH)_zicsr_zifencei -mabi=$(ABI) 4 | ADD_ASM_MACRO := -DASM 5 | 6 | ifeq ($(IPIC) ,1) 7 | ADD_ASM_MACRO += -DIPIC_ENABLED 8 | endif 9 | 10 | ifeq ($(VECT_IRQ) ,1) 11 | ADD_ASM_MACRO += -DVECT_IRQ_ENABLED 12 | endif 13 | asm_src := isr_sample.S 14 | 15 | # override ld script 16 | ld_script := $(inc_dir)/link.ld 17 | 18 | include $(inc_dir)/common.mk 19 | 20 | default: log_requested_tgt $(bld_dir)/isr_sample.elf $(bld_dir)/isr_sample.hex $(bld_dir)/isr_sample.dump 21 | 22 | log_requested_tgt: 23 | echo isr_sample.hex >> $(bld_dir)/test_info 24 | 25 | clean: 26 | $(RM)$(asm_objs) $(bld_dir)/isr_sample.elf $(bld_dir)/isr_sample.hex $(bld_dir)/isr_sample.dump 27 | -------------------------------------------------------------------------------- /sim/tests/isr_sample/isr_sample.S: -------------------------------------------------------------------------------- 1 | #include "riscv_macros.h" 2 | #include "sc_test.h" 3 | 4 | .altmacro 5 | // global interrupt bit 6 | #define MSIE (1 << IRQ_M_SOFT) //machine software interrupt enable 7 | #define MTIE (1 << IRQ_M_TIMER) //machine timer interrupt enable 8 | #define MEIE (1 << IRQ_M_EXT) //machine external interrupt enable 9 | #define MCAUSE_EXT_IRQ (1 << 31 | IRQ_M_EXT) 10 | #define MCAUSE_SOFT_IRQ (1 << 31 | IRQ_M_SOFT) 11 | #define MCAUSE_TMR_IRQ (1 << 31 | IRQ_M_TIMER) 12 | 13 | // IPIC 14 | #define IRQ_LINES_ADDR 0xF0000100 // simulation 15 | #define TRIG_EXT_IRQ_ADDR 0xF0000100 // external irq is triggered when tb memory is set to non-zero 16 | #define TRIG_SW_IRQ_ADDR 0xF0000200 // software irq is triggered when tb memory is set to non-zero 17 | 18 | #define IPIC_EOI 0xBF4 // end of interrupt 19 | #define IPIC_SOI 0xBF5 // start of interrupt 20 | #define IPIC_IDX 0xBF6 // index register 21 | #define IPIC_ICSR 0xBF7 // interrupt control status register 22 | 23 | // IPIC Interrupt Constrol Status Register 24 | #define IPIC_ICSR_IP (1 << 0) // interrupt pending 25 | #define IPIC_ICSR_IE (1 << 1) // interrupt enable 26 | #define IPIC_ICSR_IM (1 << 2) // interrupt mode (0/1: level/edge) 27 | #define IPIC_ICSR_INV (1 << 3) // line inversion 28 | #define IPIC_ICSR_IS (1 << 4) // in service 29 | 30 | // Interrupt lines in use 31 | #define IPIC_IRQ_LINE9 9 32 | #define EXT_IRQ_LINE_COMMON 0 33 | 34 | #include "timer.h" 35 | #include "reloc.h" 36 | 37 | .macro jmp_sc_exit 38 | la t0, sc_exit 39 | jr t0 40 | .endm 41 | 42 | .section .text.init 43 | .option norvc 44 | .globl _start 45 | // ----------------------------------------------------------------- 46 | // Trap handlers 47 | // 0xXXXXXX00 48 | .option norvc 49 | .org (64*3) 50 | 51 | //0xXXXXXXC0 52 | .balign 64 53 | machine_trap_entry: 54 | vec_usr_soft: 55 | #ifdef VECT_IRQ_ENABLED 56 | trap_entry: 57 | j _trap_fail 58 | vec_supervisor_soft: 59 | j _trap_fail 60 | vec_reserved1: 61 | j _trap_fail 62 | vec_machine_soft: 63 | j vec_machine_soft_handler 64 | vec_usr_tmr: 65 | j _trap_fail 66 | vec_supervisor_tmr: 67 | j _trap_fail 68 | vec_reserved2: 69 | j _trap_fail 70 | vec_machine_tmr: 71 | j vec_machine_tmr_handler 72 | vec_usr_ext: 73 | j _trap_fail 74 | vec_supervisor_ext: 75 | j _trap_fail 76 | vec_reserved3: 77 | j _trap_fail 78 | vec_machine_ext: 79 | j vec_machine_ext_handler 80 | vec_reserved4: 81 | j _trap_fail 82 | j _trap_fail 83 | j _trap_fail 84 | j _trap_fail 85 | #else 86 | trap_entry: 87 | j direct_irq_handler 88 | vec_supervisor_soft: 89 | j _trap_fail 90 | vec_reserved1: 91 | j _trap_fail 92 | vec_machine_soft: 93 | j _trap_fail 94 | vec_usr_tmr: 95 | j _trap_fail 96 | vec_supervisor_tmr: 97 | j _trap_fail 98 | vec_reserved2: 99 | j _trap_fail 100 | vec_machine_tmr: 101 | j _trap_fail 102 | vec_usr_ext: 103 | j _trap_fail 104 | vec_supervisor_ext: 105 | j _trap_fail 106 | vec_reserved3: 107 | j _trap_fail 108 | vec_machine_ext: 109 | j _trap_fail 110 | vec_reserved4: 111 | j _trap_fail 112 | j _trap_fail 113 | j _trap_fail 114 | j _trap_fail 115 | 116 | #endif // ifdef VECT_IRQ_ENABLED 117 | 118 | 119 | .balign 64 120 | _start: 121 | la t0, machine_trap_entry 122 | csrw mtvec, t0 123 | 124 | la t0, test_start 125 | jr (t0) 126 | 127 | // ----------------------------------------------------------------- 128 | .option norvc 129 | .balign 64 130 | test_start: 131 | 132 | la t0, trap_entry 133 | csrw mtvec, t0 // set mtvec to trap_entry 134 | #ifdef VECT_IRQ_ENABLED 135 | csrsi mtvec, 1 // set vectored mode 136 | #else 137 | csrsi mtvec, 0 // set direct mode 138 | #endif 139 | 140 | /// configuring timer interrupt /// 141 | _reset_mtimecmp; // reset timer 142 | _run_timer; // run timer 143 | csrs mstatus, MSTATUS_MIE // enable global interrupt 144 | li a0, MTIE 145 | csrs mie, a0 // enable timer interrupt 146 | li t2, 0 // reset timer counter = 0 (updated in isr) 147 | _read_mtime s1 // read timer value 148 | addi s1, s1, 256 149 | _write_mtimecmp_32 s1 150 | wfi 151 | 152 | 153 | /// configuring external interrupt /// 154 | csrw mie, zero // disable all interrupts 155 | li t0, IRQ_LINES_ADDR 156 | sh zero, (t0) // set all exterinal interrupt lines low 157 | #ifdef IPIC_ENABLED 158 | li t0, IPIC_IRQ_LINE9 159 | csrw IPIC_IDX, t0 // set IPIC to expect interupt on line 9... 160 | li t0, (IPIC_ICSR_IE | IPIC_ICSR_IM) 161 | csrw IPIC_ICSR, t0 // ....enable interrupt,set edge interrupt mode 162 | #endif 163 | li t0, MEIE 164 | csrs mie, t0 // enable external interrupt 165 | li t0, TRIG_EXT_IRQ_ADDR 166 | #ifdef IPIC_ENABLED 167 | li t1, (1 << IPIC_IRQ_LINE9) 168 | #else 169 | li t1, (1 << EXT_IRQ_LINE_COMMON) 170 | #endif 171 | sh t1, (t0) //send command to generate external interrupt on line 9 to testbench 172 | nop 173 | nop 174 | nop 175 | nop //wait for external interrupt 176 | 177 | 178 | /// configuring software interrupt /// 179 | csrw mie, zero // disable all interrupts 180 | li t0, TRIG_SW_IRQ_ADDR 181 | li t1, 0x00000001 182 | sh t1, (t0) //send command to generate software interrupt 183 | li t0, MSIE 184 | csrs mie, t0 // enable software interrupt 185 | nop 186 | nop 187 | nop 188 | nop //wait for software interrupt 189 | 190 | li s1, 3 191 | li a0, 0 192 | beq t2, s1, 1f 193 | li a0, -1 194 | 1: 195 | jmp_sc_exit 196 | 197 | 198 | #ifndef VECT_IRQ_ENABLED 199 | 200 | direct_irq_handler: 201 | csrr a1, mcause 202 | li a5, MCAUSE_TMR_IRQ //0x80000007 -- mcause = tmr.irq 203 | beq a1, a5, vec_machine_tmr_handler 204 | li a5, MCAUSE_SOFT_IRQ //0x80000003 -- mcause = soft.irq 205 | beq a1, a5, vec_machine_soft_handler 206 | li a5, MCAUSE_EXT_IRQ //0x8000000B -- mcause = ext.irq 207 | beq a1, a5, vec_machine_ext_handler 208 | mret 209 | #endif 210 | 211 | vec_machine_tmr_handler: 212 | csrr a1, mcause 213 | li a5, MCAUSE_TMR_IRQ //0x80000007 -- mcause = tmr.irq 214 | li a0, -1 215 | bne a1, a5, check_fail 216 | csrr t1, mip 217 | li t0, MIP_MTIP 218 | and t0, t1, t0 219 | beqz t0, check_fail 220 | #ifdef IPIC_ENABLED 221 | csrw IPIC_SOI, zero 222 | csrw IPIC_EOI, zero 223 | #endif 224 | _reset_mtimecmp 225 | csrr t1, mip 226 | andi t1, t1, MIP_MTIP 227 | bne t1, zero, check_fail 228 | addi t2, t2, 1 // tmr irq counter update 229 | mret 230 | 231 | vec_machine_ext_handler: 232 | 233 | csrr a1, mcause 234 | li a5, MCAUSE_EXT_IRQ //0x8000000B -- mcause = ext.irq 235 | li a0, -1 236 | bne a1, a5, check_fail 237 | csrr t1, mip 238 | li t0, MIP_MEIP 239 | and t0, t1, t0 240 | beqz t0, check_fail 241 | #ifdef IPIC_ENABLED 242 | csrw IPIC_SOI, zero 243 | csrw IPIC_EOI, zero 244 | #endif 245 | li t0, MEIE 246 | csrc mie, t0 // disable software interrupt 247 | 248 | li t0, TRIG_EXT_IRQ_ADDR 249 | li t1, EXT_IRQ_LINE_COMMON 250 | sh t1, (t0) // send command to disable external interrupt 251 | 252 | csrr t1, mip 253 | li t0, MIP_MEIP 254 | bne t1, zero, check_fail 255 | addi t2, t2, 1 // ext irq counter update 256 | mret 257 | 258 | vec_machine_soft_handler: 259 | csrr a1, mcause 260 | li a5, MCAUSE_SOFT_IRQ //0x80000003 -- mcause = soft.irq 261 | li a0, -1 262 | bne a1, a5, check_fail 263 | csrr t1, mip 264 | li t0, MIP_MSIP 265 | and t0, t1, t0 266 | beqz t0, check_fail 267 | #ifdef IPIC_ENABLED 268 | csrw IPIC_SOI, zero 269 | csrw IPIC_EOI, zero 270 | #endif 271 | li t0, MSIE 272 | csrc mie, t0 // disable software interrupt 273 | li t0, TRIG_SW_IRQ_ADDR 274 | li t1, 0x00000000 275 | sh t1, (t0) // send command to stop generating software interrupt 276 | li t0, MIP_MSIP 277 | csrc mip, t0 278 | csrr t1, mip 279 | li t0, MIP_MSIP 280 | and t1, t1, t0 281 | bne t1, zero, check_fail 282 | addi t2, t2, 1 // ext irq counter update 283 | mret 284 | 285 | check_fail: 286 | la t0, sc_exit 287 | jr t0 288 | 289 | _trap_fail: 290 | li a0, -1 291 | j check_fail 292 | -------------------------------------------------------------------------------- /sim/tests/isr_sample/timer.h: -------------------------------------------------------------------------------- 1 | #ifndef __TIMER__H 2 | #define __TIMER__H 3 | 4 | #define MEM_MTIME_MASK 0xF0000000 5 | #define MEM_MTIME_CTRL 0x00490000 6 | #define MEM_MTIME_DIV 0x00490004 7 | #define MEM_MTIME 0x00490008 8 | #define MEM_MTIMEH 0x0049000C 9 | #define MEM_MTIMECMP 0x00490010 10 | #define MEM_MTIMECMPH 0x00490014 11 | 12 | #define TMP t0 13 | #define TMP2 t1 14 | #define TMP3 t2 15 | 16 | #if defined(__ASSEMBLER__) 17 | 18 | // Reset 19 | .macro _reset_mtime 20 | li TMP, MEM_MTIME 21 | sw zero, 0(TMP) 22 | sw zero, 4(TMP) 23 | .endm 24 | 25 | .macro _reset_mtimecmp 26 | li TMP, MEM_MTIMECMP 27 | not TMP2, zero 28 | sw TMP2, 0(TMP) 29 | sw TMP2, 4(TMP) 30 | .endm 31 | 32 | // Write 33 | .macro _write_mtime_ctrl reg 34 | li TMP, MEM_MTIME_CTRL 35 | sw \reg, 0(TMP) 36 | .endm 37 | 38 | .macro _write_mtime_div reg 39 | li TMP, MEM_MTIME_DIV 40 | sw \reg, 0(TMP) 41 | .endm 42 | 43 | .macro _write_mtimecmp_32 reg 44 | li TMP, MEM_MTIMECMP 45 | li TMP2, -1 46 | sw TMP2, 0(TMP) 47 | sw zero, 4(TMP) 48 | sw \reg, 0(TMP) 49 | .endm 50 | 51 | .macro _write_mtime reg 52 | li TMP, MEM_MTIME 53 | sw \reg, 0(TMP) 54 | .endm 55 | 56 | .macro _read_mtime reg 57 | li TMP, MEM_MTIME 58 | lw \reg, 0(TMP) 59 | .endm 60 | 61 | // Read 62 | .macro _read_mtimecmp reg 63 | li TMP, MEM_MTIMECMP 64 | lw \reg, 0(TMP) 65 | .endm 66 | 67 | .macro _read_mtime_ctrl reg 68 | li TMP, MEM_MTIME_CTRL 69 | lw \reg, 0(TMP) 70 | .endm 71 | 72 | .macro _read_mtime_div reg 73 | li TMP, MEM_MTIME_DIV 74 | lw \reg, 0(TMP) 75 | .endm 76 | 77 | // Misc 78 | .macro _run_timer 79 | li TMP, MEM_MTIME_CTRL 80 | lw TMP2, 0(TMP) 81 | li TMP3, (1 << SCR1_MTIME_CTRL_EN) 82 | or TMP2, TMP2, TMP3 83 | sw TMP2, 0(TMP) 84 | .endm 85 | 86 | .macro _stop_timer 87 | li TMP, MEM_MTIME_CTRL 88 | lw TMP2, 0(TMP) 89 | li TMP3, (1 << SCR1_MTIME_CTRL_EN) 90 | not TMP3, TMP3 91 | and TMP2, TMP2, TMP3 92 | sw TMP2, 0(TMP) 93 | .endm 94 | 95 | #else /// #if defined(__ASSEMBLER__) 96 | 97 | #include 98 | #include "scr1_specific.h" 99 | 100 | static inline void reset_mtime(void) 101 | { 102 | volatile uint32_t *mem_mtime = (volatile uint32_t *)MEM_MTIME; 103 | mem_mtime[0] = 0; 104 | mem_mtime[1] = 0; 105 | } 106 | 107 | static inline void reset_mtimecmp(void) 108 | { 109 | volatile uint32_t *reset_mtimecmp = (volatile uint32_t *)MEM_MTIMECMP; 110 | reset_mtimecmp[0] = -1; 111 | reset_mtimecmp[1] = -1; 112 | } 113 | 114 | static inline void write_mtime_ctrl(uint32_t val) 115 | { 116 | volatile uint32_t *mem_mtime_ctrl = (volatile uint32_t *)MEM_MTIME_CTRL; 117 | *mem_mtime_ctrl = val; 118 | } 119 | 120 | static inline void write_mtime_div(uint32_t val) 121 | { 122 | volatile uint32_t *mem_mtime_div = (volatile uint32_t *)MEM_MTIME_DIV; 123 | *mem_mtime_div = val; 124 | } 125 | 126 | 127 | static inline void write_mtimecmp_32(uint32_t val) 128 | { 129 | volatile uint32_t *mem_mtime_cmp = (volatile uint32_t *)MEM_MTIMECMP; 130 | mem_mtime_cmp[0] = -1; 131 | mem_mtime_cmp[1] = 0; 132 | mem_mtime_cmp[0] = val; 133 | } 134 | 135 | static inline void write_mtime(uint32_t val) 136 | { 137 | volatile uint32_t *mem_mtime = (volatile uint32_t *)MEM_MTIME; 138 | *mem_mtime = val; 139 | } 140 | 141 | static inline uint32_t read_mtime(void) 142 | { 143 | volatile uint32_t *mem_mtime = (volatile uint32_t *)MEM_MTIME; 144 | return *mem_mtime; 145 | } 146 | 147 | static inline uint32_t read_mtimecmp(void) 148 | { 149 | volatile uint32_t *mem_mtime_cmp = (volatile uint32_t *)MEM_MTIMECMP; 150 | return *mem_mtime_cmp; 151 | } 152 | 153 | static inline uint32_t read_mtime_ctrl(void) 154 | { 155 | volatile uint32_t *mem_mtime_ctrl = (volatile uint32_t *)MEM_MTIME_CTRL; 156 | return *mem_mtime_ctrl; 157 | } 158 | 159 | static inline uint32_t read_mtime_div(void) 160 | { 161 | volatile uint32_t *mem_mtime_div = (volatile uint32_t *)MEM_MTIME_DIV; 162 | return *mem_mtime_div; 163 | } 164 | 165 | static inline void run_timer(void) 166 | { 167 | volatile uint32_t *mem_mtime_ctrl = (volatile uint32_t *)MEM_MTIME_CTRL; 168 | *mem_mtime_ctrl |= 1 << SCR1_MTIME_CTRL_EN; 169 | } 170 | 171 | 172 | static inline void stop_timer(void) 173 | { 174 | volatile uint32_t *mem_mtime_ctrl = (volatile uint32_t *)MEM_MTIME_CTRL; 175 | *mem_mtime_ctrl &= ~(1 << SCR1_MTIME_CTRL_EN); 176 | } 177 | 178 | #endif /// #else #if defined(__ASSEMBLER__) 179 | 180 | #endif // #ifndef __TIMER__H 181 | -------------------------------------------------------------------------------- /sim/tests/riscv_arch/model_test.h: -------------------------------------------------------------------------------- 1 | // RISC-V Compliance Test Header File 2 | // Copyright (c) 2017, Codasip Ltd. All Rights Reserved. 3 | // See LICENSE for license details. 4 | // 5 | // Description: Common header file for RV32I tests 6 | 7 | #ifndef _COMPLIANCE_TEST_H 8 | #define _COMPLIANCE_TEST_H 9 | 10 | #include "riscv_test.h" 11 | #include "encoding.h" 12 | 13 | //----------------------------------------------------------------------- 14 | // RV Compliance Macros 15 | //----------------------------------------------------------------------- 16 | 17 | #define RV_COMPLIANCE_HALT \ 18 | 19 | #define RV_COMPLIANCE_RV32M \ 20 | RVTEST_RV32M \ 21 | 22 | #define RV_COMPLIANCE_CODE_BEGIN \ 23 | RVTEST_CODE_BEGIN_OLD \ 24 | 25 | #define RV_COMPLIANCE_CODE_END \ 26 | RVTEST_CODE_END_OLD \ 27 | 28 | #define RV_COMPLIANCE_DATA_BEGIN \ 29 | RVTEST_DATA_BEGIN_OLD \ 30 | 31 | #define RV_COMPLIANCE_DATA_END \ 32 | RVTEST_DATA_END_OLD \ 33 | 34 | #endif// RISC-V Compliance IO Test Header File 35 | 36 | /* 37 | * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com 38 | * 39 | * Licensed under the Apache License, Version 2.0 (the "License"); 40 | * you may not use this file except in compliance with the License. 41 | * You may obtain a copy of the License at 42 | * 43 | * http://www.apache.org/licenses/LICENSE-2.0 44 | * 45 | * Unless required by applicable law or agreed to in writing, software 46 | * distributed under the License is distributed on an "AS IS" BASIS, 47 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 48 | * either express or implied. 49 | * 50 | * See the License for the specific language governing permissions and 51 | * limitations under the License. 52 | * 53 | */ 54 | 55 | #ifndef _COMPLIANCE_IO_H 56 | #define _COMPLIANCE_IO_H 57 | 58 | //----------------------------------------------------------------------- 59 | // RV IO Macros (Non functional) 60 | //----------------------------------------------------------------------- 61 | #ifdef _ARCH_OUTPUT 62 | 63 | #define RVTEST_IO_PUSH(_SP) \ 64 | la _SP, begin_regstate; \ 65 | sw x3, 0(_SP); \ 66 | sw x4, 4(_SP); \ 67 | sw x5, 8(_SP); 68 | 69 | #define RVTEST_IO_POP(_SP) \ 70 | la _SP, begin_regstate; \ 71 | lw x3, 0(_SP); \ 72 | lw x4, 4(_SP); \ 73 | lw x5, 8(_SP); 74 | 75 | #define RVTEST_IO_WRITE_STR(_SP, _STR) \ 76 | .section .data.string; \ 77 | 20001: \ 78 | .string _STR; \ 79 | .section .text.init; \ 80 | RVTEST_IO_PUSH(_SP) \ 81 | li x3, 0xF0000000; \ 82 | la x4, 20001b; \ 83 | 2: lb x5, 0(x4); \ 84 | sb x5, 0(x3); \ 85 | beq x5, zero, 1f; \ 86 | add x4, x4, 1; \ 87 | j 2b; \ 88 | 1: RVTEST_IO_POP(_SP) 89 | 90 | #else // #ifdef _ARCH_OUTPUT 91 | 92 | #define RVTEST_IO_WRITE_STR(_SP, _STR) 93 | 94 | #endif // #end #ifdef _ARCH_OUTPUT 95 | 96 | #define RVTEST_IO_INIT 97 | #define RVTEST_IO_CHECK() 98 | #define RVTEST_IO_ASSERT_GPR_EQ(_SP, _R, _I) 99 | #define RVTEST_IO_ASSERT_SFPR_EQ(_F, _R, _I) 100 | #define RVTEST_IO_ASSERT_DFPR_EQ(_D, _R, _I) 101 | #define RVTEST_IO_ASSERT_EQ(_R, _I) 102 | 103 | #endif // _COMPLIANCE_IO_H 104 | -------------------------------------------------------------------------------- /sim/tests/riscv_compliance/Makefile: -------------------------------------------------------------------------------- 1 | ## @file 2 | ## Syntacore SCR* tests 3 | ## 4 | ## @copyright 2015-2018 Syntacore. All rights reserved. 5 | ## RISCV-Compliance 6 | ## 7 | 8 | ARCH ?=im 9 | override ARCH:=rv32$(ARCH) 10 | 11 | src_dir := $(CURDIR) 12 | RISCV_COMPLIANCE_TESTS := $(src_dir)/../../../dependencies/riscv-compliance/ 13 | 14 | #I IM IMC IC 15 | #EM EMC EC 16 | 17 | ifeq (rv32e,$(findstring rv32e,$(ARCH))) 18 | $(info >>> RV32E - no compliance tests) 19 | else ## ifdef SCR_BASE_RVE_EXT 20 | #ifeq (rv32i,$(findstring rv32i,$(ARCH))) 21 | ifeq ($(ARCH),$(filter $(ARCH),rv32i rv32im rv32imc rv32ic)) 22 | $(info >>> I32 TESTS) 23 | included_i += $(filter %.S,\ 24 | $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32i/src/*)) 25 | included_i += $(filter %.S,\ 26 | $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zicsr/src/*)) 27 | included_i += $(filter %.S,\ 28 | $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zifencei/src/*)) 29 | compliance_set += $(included_i) 30 | endif 31 | 32 | #$(if or ifeq(rv32im,$(findstring rv32im,$(ARCH))), (rv32imc,$(findstring rv32imc,$(ARCH)))) 33 | ifeq ($(ARCH),$(filter $(ARCH), rv32im rv32imc)) 34 | $(info >>> IM32 TESTS) 35 | included_im += $(filter %.S,\ 36 | $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32im/src/*)) 37 | compliance_set += $(included_im) 38 | endif ## 39 | 40 | ifeq (rv32imc,$(findstring rv32imc,$(ARCH))) 41 | $(info >>> IMC32 TESTS) 42 | included_imc += $(filter %.S,\ 43 | $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32imc/src/*)) 44 | compliance_set += $(included_imc) 45 | endif ## ifeq (rv32imc,$(findstring rv32imc,$(ARCH))) 46 | ifeq (rv32ic,$(findstring rv32ic,$(ARCH))) 47 | endif 48 | endif ## 49 | 50 | 51 | $(info >>>$(ARCH) set included) 52 | 53 | ifeq ($(compliance_set),) 54 | $(info >>> No compliance tests included) 55 | endif 56 | 57 | $(info >>>>> compliance set: $(compliance_set)) 58 | 59 | dst_dir := $(bld_dir) 60 | test_name := riscv_compliance 61 | bld_dir := $(addprefix $(dst_dir)/, $(test_name)) 62 | obj_dir := $(bld_dir)/riscv_compliance_objs 63 | 64 | #cut_list += scall csr shamt simple 65 | cut_list += I-MISALIGN_JMP-01 I-MISALIGN_LDST-01 I-EBREAK-01 I-ECALL-01 66 | reference_src += $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32i*/*/*.reference_output) 67 | reference_src += $(wildcard $(RISCV_COMPLIANCE_TESTS)/riscv-test-suite/rv32Zi*/*/*.reference_output) 68 | testnames := $(basename $(notdir $(compliance_set))) 69 | filtered := $(filter-out $(cut_list),$(testnames)) 70 | objs := $(addprefix $(bld_dir)/,$(filtered:%=%.o)) 71 | test_elf := $(addprefix $(dst_dir)/compliance_,$(filtered:%=%.elf)) 72 | test_hex := $(addprefix $(dst_dir)/compliance_,$(filtered:%=%.hex)) 73 | test_dump := $(addprefix $(bld_dir)/compliance_,$(filtered:%=%.dump)) 74 | 75 | compliance_macros_file := $(root_dir)/sim/tests/riscv_compliance/compliance_io.h 76 | compliance_output ?= true 77 | 78 | testnames_i := $(basename $(notdir $(included_i))) 79 | testnames_im := $(basename $(notdir $(included_im))) 80 | testnames_imc := $(basename $(notdir $(included_imc))) 81 | filtered_i := $(filter-out $(cut_list),$(testnames_i)) 82 | filtered_im := $(filter-out $(cut_list),$(testnames_im)) 83 | filtered_imc := $(filter-out $(cut_list),$(testnames_imc)) 84 | 85 | # ARCH_FLAGS := -Wa,-march=rv32im -march=rv32im 86 | # ARCH_FLAGS_C := -Wa,-march=rv32imc -march=rv32imc 87 | CFLAGS := -I$(inc_dir) -I$(src_dir) -DASM -mabi=ilp32 -D__riscv_xlen=32 -w 88 | LDFLAGS := -static -fvisibility=hidden -nostdlib -nostartfiles -T$(inc_dir)/link.ld -march=$(ARCH)_zicsr_zifencei -mabi=ilp32 89 | GCCVERSIONGT7 := $(shell expr `$(RISCV_GCC) -dumpfullversion | cut -f1 -d'.'` \> 7) 90 | ifeq "$(GCCVERSIONGT7)" "1" 91 | LDFLAGS += -mno-relax 92 | endif 93 | VPATH += $(src_dir) $(bld_dir) $(obj_dir) $(asm_path) $(ref_path) $(RISCV_COMPLIANCE_TESTS) 94 | 95 | ifeq ($(compliance_output), true) 96 | CFLAGS += -D_COMPLIANCE_OUTPUT 97 | endif 98 | 99 | default: clean log_requested_tgt check_version cp_asm ref_data $(test_elf) $(test_hex) $(test_dump) 100 | 101 | define compile_template 102 | $(obj_dir)/$(1).o: $(obj_dir) cp_asm 103 | $(RISCV_GCC) -c $$(bld_dir)/compliance_asm/$(1).S $$(CFLAGS) -Wa,$(2) $(2) -o $$@ 104 | endef 105 | 106 | define preprocessing 107 | for test_asm in $(1); do \ 108 | march_tmp=$$test_asm ; \ 109 | march_tmp=$${march_tmp%/src*} ; \ 110 | march_tmp=$$(basename $$march_tmp) ; \ 111 | file_name="$$(basename $${test_asm})" ; \ 112 | $(RISCV_GCC) $(CFLAGS) -Wa,$(2) $(2) -E $$test_asm \ 113 | -o $(bld_dir)/compliance_asm/$$file_name ; \ 114 | done 115 | endef 116 | 117 | $(foreach SRC,$(filtered_i),$(eval $(call compile_template,$(SRC),-march=rv32i_zicsr_zifencei))) 118 | $(foreach SRC,$(filtered_im),$(eval $(call compile_template,$(SRC),-march=rv32im_zicsr_zifencei))) 119 | $(foreach SRC,$(filtered_imc),$(eval $(call compile_template,$(SRC),-march=rv32imc_zicsr_zifencei))) 120 | 121 | 122 | log_requested_tgt: $(bld_dir) 123 | $(foreach test_name, $(filtered), $(eval $(shell echo compliance_$(test_name).hex >> $(bld_dir)/../test_info))) 124 | 125 | $(bld_dir) : 126 | mkdir -p $(bld_dir) 127 | 128 | $(obj_dir) : | ref_data 129 | mkdir -p $(obj_dir) 130 | 131 | $(dst_dir)/compliance_%.elf: $(obj_dir)/%.o | $(dep_files) 132 | $(RISCV_GCC) $^ $(LDFLAGS) -o $@ -g 133 | 134 | $(dst_dir)/compliance_%.hex: $(dst_dir)/compliance_%.elf 135 | $(RISCV_OBJCOPY) $^ $@ 136 | 137 | $(bld_dir)/compliance_%.dump: $(dst_dir)/compliance_%.elf 138 | $(RISCV_OBJDUMP) -D -w -x -S $^ > $@ 139 | 140 | ref_data: 141 | mkdir -p $(bld_dir)/ref_data 142 | for files in $(reference_src) ; do \ 143 | sed_input=$$files ; \ 144 | sed_output=$$(basename $${files%.*}) ; \ 145 | sed "s/\r$$//; \ 146 | s/\(........\)/\1,/g; \ 147 | s/.$$//; s/\(.*\),\(.*\),\(.*\),\(.*\)/\4,\3,\2,\1/;" \ 148 | $$sed_input > $(bld_dir)/ref_data/$$sed_output; \ 149 | done 150 | 151 | cp_asm: 152 | mkdir -p $(bld_dir)/compliance_asm 153 | $(call preprocessing,$(included_i),-march=rv32i_zicsr_zifencei) 154 | $(call preprocessing,$(included_im),-march=rv32im_zicsr_zifencei) 155 | $(call preprocessing,$(included_imc),-march=rv32imc_zicsr_zifencei) 156 | 157 | 158 | riscv_compliance_tests_dir := $(if $(RISCV_COMPLIANCE_TESTS), $(RISCV_COMPLIANCE_TESTS), ./undefined) 159 | riscv_tests_commit := d51259b2a949be3af02e776c39e135402675ac9b 160 | ## commit hash readed from local copy of https://github.com/riscv/riscv-compliance 161 | tmp_commit = $(shell cd $(riscv_compliance_tests_dir) 2>/dev/null && git log -1 | grep "commit" | cut -f2 -d ' ') 162 | is_commit_good = $(if $(subst $(riscv_tests_commit),,$(tmp_commit)),false,true) 163 | 164 | # Color 165 | RED=\033[0;31m 166 | NC=\033[0m 167 | 168 | check_version : $(riscv_compliance_tests_dir) 169 | @if [ ! -d $(riscv_compliance_tests_dir) ]; then \ 170 | echo -e "$(RED)==========================================================================" &&\ 171 | echo " Error! Environment variable RISCV_COMPLIANCE_TESTS='$(riscv_compliance_tests_dir)' " &&\ 172 | echo " directory not exist!" && \ 173 | echo "==========================================================================$(NC)" ; \ 174 | fi 175 | ifneq ($(is_commit_good),true) 176 | @echo -e "$(RED)==========================================================================" 177 | @echo " Warning! Execution of test code is not guaranteed " 178 | @echo " while using the current commit of repository located at : $(riscv_compliance_tests_dir) ." 179 | @echo " " 180 | @echo " riscv_compliance repository must point to commit $(riscv_tests_commit)!" 181 | @echo -e "==========================================================================$(NC)" 182 | endif 183 | 184 | $(riscv_compliance_tests_dir) :. 185 | ifndef RISCV_COMPLIANCE_TESTS 186 | @echo -e "$(RED)==========================================================================" 187 | @echo " Error! Environment variable RISCV_COMPLIANCE_TESTS not set!" 188 | @echo " You must set the environment variable RISCV_COMPLIANCE_TESTS" 189 | @echo " The variable should point to the local copy of the" 190 | @echo " repository https://github.com/riscv/riscv-compliance" 191 | @echo " with the commit $(riscv_tests_commit)" 192 | @echo -e "==========================================================================$(NC)" 193 | exit 1 194 | endif 195 | 196 | clean: 197 | $(RM) -R $(test_elf) $(test_hex) $(bld_dir) 198 | 199 | .PHONY: check_version clean ref_data cp_asm default 200 | -------------------------------------------------------------------------------- /sim/tests/riscv_compliance/compliance_io.h: -------------------------------------------------------------------------------- 1 | // RISC-V Compliance IO Test Header File 2 | 3 | /* 4 | * Copyright (c) 2005-2018 Imperas Software Ltd., www.imperas.com 5 | * 6 | * Licensed under the Apache License, Version 2.0 (the "License"); 7 | * you may not use this file except in compliance with the License. 8 | * You may obtain a copy of the License at 9 | * 10 | * http://www.apache.org/licenses/LICENSE-2.0 11 | * 12 | * Unless required by applicable law or agreed to in writing, software 13 | * distributed under the License is distributed on an "AS IS" BASIS, 14 | * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, 15 | * either express or implied. 16 | * 17 | * See the License for the specific language governing permissions and 18 | * limitations under the License. 19 | * 20 | */ 21 | 22 | #ifndef _COMPLIANCE_IO_H 23 | #define _COMPLIANCE_IO_H 24 | 25 | //----------------------------------------------------------------------- 26 | // RV IO Macros (Non functional) 27 | //----------------------------------------------------------------------- 28 | #ifdef _COMPLIANCE_OUTPUT 29 | 30 | #define RVTEST_IO_PUSH(_SP) \ 31 | la _SP, begin_regstate; \ 32 | sw x3, 0(_SP); \ 33 | sw x4, 4(_SP); \ 34 | sw x5, 8(_SP); 35 | 36 | #define RVTEST_IO_POP(_SP) \ 37 | la _SP, begin_regstate; \ 38 | lw x3, 0(_SP); \ 39 | lw x4, 4(_SP); \ 40 | lw x5, 8(_SP); 41 | 42 | #define RVTEST_IO_WRITE_STR(_SP, _STR) \ 43 | .section .data.string; \ 44 | 20001: \ 45 | .string _STR; \ 46 | .section .text; \ 47 | RVTEST_IO_PUSH(_SP) \ 48 | li x3, 0xF0000000; \ 49 | la x4, 20001b; \ 50 | 2: lb x5, 0(x4); \ 51 | sb x5, 0(x3); \ 52 | beq x5, zero, 1f; \ 53 | add x4, x4, 1; \ 54 | j 2b; \ 55 | 1: RVTEST_IO_POP(_SP) 56 | 57 | #else // #ifdef _COMPLIANCE_OUTPUT 58 | 59 | #define RVTEST_IO_WRITE_STR(_SP, _STR) 60 | 61 | #endif // #end #ifdef _COMPLIANCE_OUTPUT 62 | 63 | #define RVTEST_IO_INIT 64 | #define RVTEST_IO_CHECK() 65 | #define RVTEST_IO_ASSERT_GPR_EQ(_SP, _R, _I) 66 | #define RVTEST_IO_ASSERT_SFPR_EQ(_F, _R, _I) 67 | #define RVTEST_IO_ASSERT_DFPR_EQ(_D, _R, _I) 68 | #define RVTEST_IO_ASSERT_EQ(_R, _I) 69 | 70 | #endif // _COMPLIANCE_IO_H 71 | -------------------------------------------------------------------------------- /sim/tests/riscv_compliance/compliance_test.h: -------------------------------------------------------------------------------- 1 | // RISC-V Compliance Test Header File 2 | // Copyright (c) 2017, Codasip Ltd. All Rights Reserved. 3 | // See LICENSE for license details. 4 | // 5 | // Description: Common header file for RV32I tests 6 | 7 | #ifndef _COMPLIANCE_TEST_H 8 | #define _COMPLIANCE_TEST_H 9 | 10 | //----------------------------------------------------------------------- 11 | // RV Compliance Macros 12 | //----------------------------------------------------------------------- 13 | 14 | #define RV_COMPLIANCE_HALT \ 15 | 16 | #define RV_COMPLIANCE_RV32M \ 17 | RVTEST_RV32M \ 18 | 19 | #define RV_COMPLIANCE_CODE_BEGIN \ 20 | RVTEST_CODE_BEGIN \ 21 | 22 | #define RV_COMPLIANCE_CODE_END \ 23 | RVTEST_CODE_END \ 24 | 25 | #define RV_COMPLIANCE_DATA_BEGIN \ 26 | RVTEST_DATA_BEGIN \ 27 | 28 | #define RV_COMPLIANCE_DATA_END \ 29 | RVTEST_DATA_END \ 30 | 31 | #endif -------------------------------------------------------------------------------- /sim/tests/riscv_compliance/riscv_test.h: -------------------------------------------------------------------------------- 1 | 2 | #ifndef _RISCV_TEST_H 3 | #define _RISCV_TEST_H 4 | 5 | #include "test_macros.h" 6 | 7 | #endif -------------------------------------------------------------------------------- /sim/tests/riscv_isa/Makefile: -------------------------------------------------------------------------------- 1 | 2 | include rv32_tests.inc 3 | 4 | ARCH_tmp := imf 5 | 6 | ifneq (,$(findstring c,$(ARCH_lowercase))) 7 | ARCH_tmp := $(ARCH_tmp)c 8 | endif 9 | 10 | override ARCH := $(ARCH_tmp) 11 | 12 | src_dir := $(CURDIR) 13 | obj_dir := $(bld_dir)/riscv_objs 14 | test_list := $(patsubst %.S, %, $(notdir $(rv32_isa_tests))) 15 | objs := $(addprefix $(obj_dir)/,$(test_list:%=%.o)) 16 | test_elf := $(addprefix $(bld_dir)/,$(test_list:%=%.elf)) 17 | test_hex := $(addprefix $(bld_dir)/,$(test_list:%=%.hex)) 18 | test_dump := $(addprefix $(bld_dir)/,$(test_list:%=%.dump)) 19 | 20 | CFLAGS := -I$(inc_dir) -I$(src_dir) -DASM -Wa,-march=rv32$(ARCH)_zicsr_zifencei -march=rv32$(ARCH)_zicsr_zifencei -mabi=ilp32f -D__riscv_xlen=32 21 | LDFLAGS := -static -fvisibility=hidden -nostdlib -nostartfiles -T$(inc_dir)/link.ld -march=rv32$(ARCH)_zicsr_zifencei -mabi=ilp32f 22 | RISCV_TESTS := $(src_dir)/../../../dependencies/riscv-tests/ 23 | 24 | VPATH += $(src_dir) $(bld_dir) $(obj_dir) $(RISCV_TESTS) 25 | 26 | default: log_requested_tgt check_riscv_tests $(test_elf) $(test_hex) $(test_dump) 27 | 28 | define compile_template 29 | $(obj_dir)/$$(basename $(notdir $(SRC))).o: $$(SRC) | $(obj_dir) 30 | $(RISCV_GCC) -c $$< $(CFLAGS) -o $$@ 31 | endef 32 | 33 | $(foreach SRC,$(rv32_isa_tests), $(eval $(compile_template))) 34 | 35 | log_requested_tgt: 36 | $(foreach test_name, $(test_list), $(eval $(shell echo $(test_name).hex >> $(bld_dir)/test_info))) 37 | 38 | $(obj_dir) : 39 | mkdir -p $(obj_dir) 40 | 41 | $(bld_dir)/%.elf: $(obj_dir)/%.o | $(obj_dir) 42 | $(RISCV_GCC) $^ $(LDFLAGS) -o $@ 43 | 44 | $(bld_dir)/%.hex: $(bld_dir)/%.elf 45 | $(RISCV_OBJCOPY) $^ $@ 46 | 47 | $(bld_dir)/%.dump: $(bld_dir)/%.elf 48 | $(RISCV_OBJDUMP) -D -w -x -S $^ > $@ 49 | 50 | clean: 51 | $(RM) $(test_elf) $(test_hex) $(test_dump) $(objs) 52 | $(RM) -R $(obj_dir) 53 | 54 | 55 | .PHONY: check_riscv_tests 56 | 57 | riscv_tests_dir := $(if $(RISCV_TESTS), $(RISCV_TESTS), ./undefined) 58 | riscv_tests_commit := 5f8a4918c6482e65c67a2b7decd5c2af3e3fe0e5 59 | ## commit hash readed from local copy of https://github.com/riscv/riscv-tests 60 | tmp_commit = $(shell cd $(riscv_tests_dir) 2>/dev/null && git log -1 | grep "commit" | cut -f2 -d ' ') 61 | is_commit_good = $(if $(subst $(riscv_tests_commit),,$(tmp_commit)),false,true) 62 | 63 | # Color 64 | RED=\033[0;31m 65 | NC=\033[0m 66 | 67 | check_riscv_tests : $(riscv_tests_dir) 68 | @if [ ! -d $(riscv_tests_dir) ]; then \ 69 | echo -e "$(RED)==========================================================================" &&\ 70 | echo " Error! Environment variable RISCV_TESTS='$(riscv_tests_dir)' " &&\ 71 | echo " directory not exist!" && \ 72 | echo "==========================================================================$(NC)" ; \ 73 | fi 74 | ifneq ($(is_commit_good),true) 75 | @echo -e "$(RED)==========================================================================" 76 | @echo " Warning! Execution of test code is not guaranteed " 77 | @echo " while using the current commit of repositorylocated at : $(riscv_tests_dir) ." 78 | @echo " " 79 | @echo " Riscv-tests repository must point to commit $(riscv_tests_commit)!" 80 | @echo -e "==========================================================================$(NC)" 81 | endif 82 | 83 | $(riscv_tests_dir) :. 84 | ifndef RISCV_TESTS 85 | @echo -e "$(RED)==========================================================================" 86 | @echo " Error! Environment variable RISCV_TESTS not set!" 87 | @echo " You must set the environment variable RISCV_TESTS" 88 | @echo " The variable should point to the local copy of the" 89 | @echo " repository https://github.com/riscv/riscv-tests" 90 | @echo " with the commit $(riscv_tests_commit)" 91 | @echo -e "==========================================================================$(NC)" 92 | exit 1 93 | endif 94 | -------------------------------------------------------------------------------- /sim/tests/riscv_isa/riscv_test.h: -------------------------------------------------------------------------------- 1 | #ifndef __RISCV__TEST__H 2 | #define __RISCV__TEST__H 3 | 4 | #include "riscv_macros.h" 5 | 6 | #endif // #ifndef __RISCV__TEST__H 7 | -------------------------------------------------------------------------------- /sim/tests/riscv_isa/rv32_tests.inc: -------------------------------------------------------------------------------- 1 | 2 | ARCH_lowercase = $(shell echo $(ARCH) | tr A-Z a-z) 3 | 4 | 5 | rv32_isa_tests += isa/rv32ui/add.S \ 6 | isa/rv32ui/addi.S \ 7 | isa/rv32ui/and.S \ 8 | isa/rv32ui/andi.S \ 9 | isa/rv32ui/auipc.S \ 10 | isa/rv32ui/beq.S \ 11 | isa/rv32ui/bge.S \ 12 | isa/rv32ui/bgeu.S \ 13 | isa/rv32ui/blt.S \ 14 | isa/rv32ui/bltu.S \ 15 | isa/rv32ui/bne.S \ 16 | isa/rv32mi/csr.S \ 17 | isa/rv32ui/fence_i.S \ 18 | isa/rv32mi/illegal.S \ 19 | isa/rv32ui/jal.S \ 20 | isa/rv32ui/jalr.S \ 21 | isa/rv32ui/lb.S \ 22 | isa/rv32ui/lbu.S \ 23 | isa/rv32ui/lh.S \ 24 | isa/rv32ui/lhu.S \ 25 | isa/rv32ui/lui.S \ 26 | isa/rv32ui/lw.S \ 27 | isa/rv32mi/ma_addr.S \ 28 | isa/rv32mi/ma_fetch.S \ 29 | isa/rv32mi/mcsr.S \ 30 | isa/rv32ui/or.S \ 31 | isa/rv32ui/ori.S \ 32 | isa/rv32ui/sb.S \ 33 | isa/rv32mi/sbreak.S \ 34 | isa/rv32mi/scall.S \ 35 | isa/rv32ui/sh.S \ 36 | isa/rv32mi/shamt.S \ 37 | isa/rv32ui/simple.S \ 38 | isa/rv32ui/sll.S \ 39 | isa/rv32ui/slli.S \ 40 | isa/rv32ui/slt.S \ 41 | isa/rv32ui/slti.S \ 42 | isa/rv32ui/sltiu.S \ 43 | isa/rv32ui/sltu.S \ 44 | isa/rv32ui/sra.S \ 45 | isa/rv32ui/srai.S \ 46 | isa/rv32ui/srl.S \ 47 | isa/rv32ui/srli.S \ 48 | isa/rv32ui/sub.S \ 49 | isa/rv32ui/sw.S \ 50 | isa/rv32ui/xor.S \ 51 | isa/rv32ui/xori.S 52 | 53 | ifneq (,$(findstring m,$(ARCH_lowercase))) 54 | rv32_isa_tests += isa/rv32um/div.S \ 55 | isa/rv32um/divu.S \ 56 | isa/rv32um/mul.S \ 57 | isa/rv32um/mulh.S \ 58 | isa/rv32um/mulhsu.S \ 59 | isa/rv32um/mulhu.S \ 60 | isa/rv32um/rem.S \ 61 | isa/rv32um/remu.S 62 | endif ## ifeq (m,$(findstring m,$(ARCH_lowercase))) 63 | 64 | ifneq (,$(findstring c,$(ARCH_lowercase))) 65 | rv32_isa_tests += isa/rv32uc/rvc.S 66 | endif ## ifeq (m,$(findstring c,$(ARCH_lowercase))) -------------------------------------------------------------------------------- /sim/tests/riscv_isa/test_macros.h: -------------------------------------------------------------------------------- 1 | #ifndef __TEST__MACROS__H 2 | #define __TEST__MACROS__H 3 | 4 | #define sptbr satp 5 | #define mbadaddr mtval 6 | 7 | #endif -------------------------------------------------------------------------------- /sim/verilator_wrap/scr1_ahb_wrapper.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "Vscr1_top_tb_ahb.h" 5 | #ifdef VCD_TRACE 6 | #include "verilated_vcd_c.h" 7 | #endif // #ifdef VCD_TRACE 8 | 9 | #define STRINGIFY(s) _STRINGIFY(s) 10 | #define _STRINGIFY(s) #s 11 | 12 | Vscr1_top_tb_ahb *top; 13 | 14 | vluint64_t main_time = 0; 15 | 16 | int main(int argc, char** argv) { 17 | Verilated::commandArgs(argc, argv); 18 | 19 | top = new Vscr1_top_tb_ahb; 20 | 21 | #ifdef VCD_TRACE 22 | Verilated::traceEverOn(true); 23 | VerilatedVcdC* tfp = new VerilatedVcdC; 24 | #ifdef TRACE_LVLV 25 | top->trace(tfp, TRACE_LVLV); 26 | #else 27 | top->trace(tfp, 99); // Trace 99 levels of hierarchy by default 28 | #endif // #ifdef TRACE_LVLV 29 | 30 | #ifdef VCD_FNAME 31 | tfp->open(STRINGIFY(VCD_FNAME)); 32 | #else 33 | tfp->open("./simx.vcd"); 34 | #endif // #ifdef VCD_FNAME 35 | #endif // #ifdef VCD_TRACE 36 | 37 | while (!Verilated::gotFinish()) { 38 | if ((main_time % 10) == 1) { 39 | top->clk = 1; 40 | } 41 | if ((main_time % 10) == 6) { 42 | top->clk = 0; 43 | } 44 | top->eval(); 45 | main_time++; 46 | #ifdef VCD_TRACE 47 | tfp->dump(main_time); 48 | #endif // #ifdef VCD_TRACE 49 | } 50 | top->final(); 51 | #ifdef VCD_TRACE 52 | tfp->close(); 53 | #endif // #ifdef VCD_TRACE 54 | delete top; 55 | } 56 | 57 | -------------------------------------------------------------------------------- /sim/verilator_wrap/scr1_axi_wrapper.c: -------------------------------------------------------------------------------- 1 | 2 | #include 3 | #include 4 | #include "Vscr1_top_tb_axi.h" 5 | #ifdef VCD_TRACE 6 | #include "verilated_vcd_c.h" 7 | #endif // #ifdef VCD_TRACE 8 | 9 | #define STRINGIFY(s) _STRINGIFY(s) 10 | #define _STRINGIFY(s) #s 11 | 12 | Vscr1_top_tb_axi *top; 13 | 14 | vluint64_t main_time = 0; 15 | 16 | int main(int argc, char** argv) { 17 | Verilated::commandArgs(argc, argv); 18 | 19 | top = new Vscr1_top_tb_axi; 20 | #ifdef VCD_TRACE 21 | Verilated::traceEverOn(true); 22 | VerilatedVcdC* tfp = new VerilatedVcdC; 23 | #ifdef TRACE_LVLV 24 | top->trace(tfp, TRACE_LVLV); 25 | #else 26 | top->trace(tfp, 99); // Trace 99 levels of hierarchy by default 27 | #endif // #ifdef TRACE_LVLV 28 | 29 | #ifdef VCD_FNAME 30 | tfp->open(STRINGIFY(VCD_FNAME)); 31 | #else 32 | tfp->open("./simx.vcd"); 33 | #endif // #ifdef VCD_FNAME 34 | #endif // #ifdef VCD_TRACE 35 | 36 | while (!Verilated::gotFinish()) { 37 | if ((main_time % 10) == 1) { 38 | top->clk = 1; 39 | } 40 | if ((main_time % 10) == 6) { 41 | top->clk = 0; 42 | } 43 | top->eval(); 44 | main_time++; 45 | #ifdef VCD_TRACE 46 | tfp->dump(main_time); 47 | #endif // #ifdef VCD_TRACE 48 | } 49 | top->final(); 50 | #ifdef VCD_TRACE 51 | tfp->close(); 52 | #endif // #ifdef VCD_TRACE 53 | delete top; 54 | } 55 | 56 | -------------------------------------------------------------------------------- /src/ahb_tb.files: -------------------------------------------------------------------------------- 1 | core/pipeline/scr1_tracelog.sv 2 | tb/scr1_memory_tb_ahb.sv 3 | tb/scr1_top_tb_ahb.sv -------------------------------------------------------------------------------- /src/ahb_top.files: -------------------------------------------------------------------------------- 1 | top/scr1_dmem_router.sv 2 | top/scr1_imem_router.sv 3 | top/scr1_dp_memory.sv 4 | top/scr1_tcm.sv 5 | top/scr1_timer.sv 6 | top/scr1_dmem_ahb.sv 7 | top/scr1_imem_ahb.sv 8 | top/scr1_top_ahb.sv 9 | -------------------------------------------------------------------------------- /src/axi_tb.files: -------------------------------------------------------------------------------- 1 | core/pipeline/scr1_tracelog.sv 2 | tb/scr1_memory_tb_axi.sv 3 | tb/scr1_top_tb_axi.sv -------------------------------------------------------------------------------- /src/axi_top.files: -------------------------------------------------------------------------------- 1 | top/scr1_dmem_router.sv 2 | top/scr1_imem_router.sv 3 | top/scr1_dp_memory.sv 4 | top/scr1_tcm.sv 5 | top/scr1_timer.sv 6 | top/scr1_mem_axi.sv 7 | top/scr1_top_axi.sv -------------------------------------------------------------------------------- /src/core.files: -------------------------------------------------------------------------------- 1 | core/pipeline/scr1_pipe_hdu.sv 2 | core/pipeline/scr1_pipe_tdu.sv 3 | core/pipeline/scr1_ipic.sv 4 | core/pipeline/scr1_pipe_csr.sv 5 | core/pipeline/scr1_pipe_exu.sv 6 | core/pipeline/scr1_pipe_ialu.sv 7 | core/pipeline/scr1_pipe_idu.sv 8 | core/pipeline/scr1_pipe_ifu.sv 9 | core/pipeline/scr1_pipe_lsu.sv 10 | core/pipeline/scr1_pipe_mprf.sv 11 | core/pipeline/scr1_pipe_top.sv 12 | core/primitives/scr1_reset_cells.sv 13 | core/primitives/scr1_cg.sv 14 | core/scr1_clk_ctrl.sv 15 | core/scr1_tapc_shift_reg.sv 16 | core/scr1_tapc.sv 17 | core/scr1_tapc_synchronizer.sv 18 | core/scr1_core_top.sv 19 | core/scr1_dm.sv 20 | core/scr1_dmi.sv 21 | core/scr1_scu.sv 22 | -------------------------------------------------------------------------------- /src/core/pipeline/scr1_pipe_hdu.sv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/core/pipeline/scr1_pipe_hdu.sv -------------------------------------------------------------------------------- /src/core/pipeline/scr1_pipe_mprf.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Multi Port Register File (MPRF) 4 | /// 5 | 6 | `include "scr1_arch_description.svh" 7 | `include "scr1_arch_types.svh" 8 | 9 | module scr1_pipe_mprf ( 10 | // Common 11 | `ifdef SCR1_MPRF_RST_EN 12 | input logic rst_n, // MPRF reset 13 | `endif // SCR1_MPRF_RST_EN 14 | input logic clk, // MPRF clock 15 | 16 | // EXU <-> MPRF interface 17 | input logic [`SCR1_MPRF_AWIDTH-1:0] exu2mprf_rs1_addr_i, // MPRF rs1 read address 18 | output logic [`SCR1_XLEN-1:0] mprf2exu_rs1_data_o, // MPRF rs1 read data 19 | input logic [`SCR1_MPRF_AWIDTH-1:0] exu2mprf_rs2_addr_i, // MPRF rs2 read address 20 | output logic [`SCR1_XLEN-1:0] mprf2exu_rs2_data_o, // MPRF rs2 read data 21 | input logic exu2mprf_w_req_i, // MPRF write request 22 | input logic [`SCR1_MPRF_AWIDTH-1:0] exu2mprf_rd_addr_i, // MPRF rd write address 23 | input logic [`SCR1_XLEN-1:0] exu2mprf_rd_data_i // MPRF rd write data 24 | ); 25 | 26 | //------------------------------------------------------------------------------- 27 | // Local types declaration 28 | //------------------------------------------------------------------------------- 29 | 30 | logic wr_req_vd; 31 | 32 | logic rs1_addr_vd; 33 | logic rs2_addr_vd; 34 | 35 | `ifdef SCR1_MPRF_RAM 36 | logic rs1_addr_vd_ff; 37 | logic rs2_addr_vd_ff; 38 | 39 | logic rs1_new_data_req; 40 | logic rs2_new_data_req; 41 | logic rs1_new_data_req_ff; 42 | logic rs2_new_data_req_ff; 43 | logic read_new_data_req; 44 | 45 | logic [`SCR1_XLEN-1:0] rd_data_ff; 46 | 47 | logic [`SCR1_XLEN-1:0] rs1_data_ff; 48 | logic [`SCR1_XLEN-1:0] rs2_data_ff; 49 | 50 | // when using RAM, 2 memories are needed because 3 simultaneous independent 51 | // write/read operations can occur 52 | `ifdef SCR1_TRGT_FPGA_INTEL_MAX10 53 | (* ramstyle = "M9K" *) logic [`SCR1_XLEN-1:0] mprf_int [1:`SCR1_MPRF_SIZE-1]; 54 | (* ramstyle = "M9K" *) logic [`SCR1_XLEN-1:0] mprf_int2 [1:`SCR1_MPRF_SIZE-1]; 55 | `elsif SCR1_TRGT_FPGA_INTEL_ARRIAV 56 | (* ramstyle = "M10K" *) logic [`SCR1_XLEN-1:0] mprf_int [1:`SCR1_MPRF_SIZE-1]; 57 | (* ramstyle = "M10K" *) logic [`SCR1_XLEN-1:0] mprf_int2 [1:`SCR1_MPRF_SIZE-1]; 58 | `else 59 | logic [`SCR1_XLEN-1:0] mprf_int [1:`SCR1_MPRF_SIZE-1]; 60 | logic [`SCR1_XLEN-1:0] mprf_int2 [1:`SCR1_MPRF_SIZE-1]; 61 | `endif 62 | `else // distributed logic implementation 63 | type_scr1_mprf_v [1:`SCR1_MPRF_SIZE-1] mprf_int; 64 | `endif 65 | 66 | //------------------------------------------------------------------------------ 67 | // MPRF control logic 68 | //------------------------------------------------------------------------------ 69 | 70 | // control signals common for distributed logic and RAM implementations 71 | assign rs1_addr_vd = |exu2mprf_rs1_addr_i; 72 | assign rs2_addr_vd = |exu2mprf_rs2_addr_i; 73 | 74 | assign wr_req_vd = exu2mprf_w_req_i & |exu2mprf_rd_addr_i; 75 | 76 | // RAM implementation specific control signals 77 | `ifdef SCR1_MPRF_RAM 78 | assign rs1_new_data_req = wr_req_vd & ( exu2mprf_rs1_addr_i == exu2mprf_rd_addr_i ); 79 | assign rs2_new_data_req = wr_req_vd & ( exu2mprf_rs2_addr_i == exu2mprf_rd_addr_i ); 80 | assign read_new_data_req = rs1_new_data_req | rs2_new_data_req; 81 | 82 | always_ff @( posedge clk ) begin 83 | rs1_addr_vd_ff <= rs1_addr_vd; 84 | rs2_addr_vd_ff <= rs2_addr_vd; 85 | rs1_new_data_req_ff <= rs1_new_data_req; 86 | rs2_new_data_req_ff <= rs2_new_data_req; 87 | end 88 | `endif // SCR1_MPRF_RAM 89 | 90 | `ifdef SCR1_MPRF_RAM 91 | //------------------------------------------------------------------------------- 92 | // RAM implementation 93 | //------------------------------------------------------------------------------- 94 | 95 | // RAM is implemented with 2 simple dual-port memories with sync read operation; 96 | // logic for "write-first" RDW behavior is implemented externally to the embedded 97 | // memory blocks 98 | 99 | // bypass new wr_data to the read output if write/read collision occurs 100 | assign mprf2exu_rs1_data_o = ( rs1_new_data_req_ff ) ? rd_data_ff 101 | : (( rs1_addr_vd_ff ) ? rs1_data_ff 102 | : '0 ); 103 | 104 | assign mprf2exu_rs2_data_o = ( rs2_new_data_req_ff ) ? rd_data_ff 105 | : (( rs2_addr_vd_ff ) ? rs2_data_ff 106 | : '0 ); 107 | 108 | always_ff @( posedge clk ) begin 109 | if ( read_new_data_req ) begin 110 | rd_data_ff <= exu2mprf_rd_data_i; 111 | end 112 | end 113 | 114 | // synchronous read operation 115 | always_ff @( posedge clk ) begin 116 | rs1_data_ff <= mprf_int[exu2mprf_rs1_addr_i]; 117 | rs2_data_ff <= mprf_int2[exu2mprf_rs2_addr_i]; 118 | end 119 | 120 | // write operation 121 | always_ff @( posedge clk ) begin 122 | if ( wr_req_vd ) begin 123 | mprf_int[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i; 124 | mprf_int2[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i; 125 | end 126 | end 127 | `else // distributed logic implementation 128 | //------------------------------------------------------------------------------ 129 | // distributed logic implementation 130 | //------------------------------------------------------------------------------ 131 | 132 | // asynchronous read operation 133 | assign mprf2exu_rs1_data_o = ( rs1_addr_vd ) ? mprf_int[exu2mprf_rs1_addr_i] : '0; 134 | assign mprf2exu_rs2_data_o = ( rs2_addr_vd ) ? mprf_int[exu2mprf_rs2_addr_i] : '0; 135 | 136 | // write operation 137 | `ifdef SCR1_MPRF_RST_EN 138 | always_ff @( posedge clk, negedge rst_n ) begin 139 | if ( ~rst_n ) begin 140 | mprf_int <= '{default: '0}; 141 | end else if ( wr_req_vd ) begin 142 | mprf_int[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i; 143 | end 144 | end 145 | `else // ~SCR1_MPRF_RST_EN 146 | always_ff @( posedge clk ) begin 147 | if ( wr_req_vd ) begin 148 | mprf_int[exu2mprf_rd_addr_i] <= exu2mprf_rd_data_i; 149 | end 150 | end 151 | `endif // ~SCR1_MPRF_RST_EN 152 | `endif 153 | 154 | `ifdef SCR1_TRGT_SIMULATION 155 | //------------------------------------------------------------------------------- 156 | // Assertion 157 | //------------------------------------------------------------------------------- 158 | `ifdef SCR1_MPRF_RST_EN 159 | SCR1_SVA_MPRF_WRITEX : assert property ( 160 | @(negedge clk) disable iff (~rst_n) 161 | exu2mprf_w_req_i |-> !$isunknown({exu2mprf_rd_addr_i, (|exu2mprf_rd_addr_i ? exu2mprf_rd_data_i : `SCR1_XLEN'd0)}) 162 | ) else $error("MPRF error: unknown values"); 163 | `endif // SCR1_MPRF_RST_EN 164 | 165 | `endif // SCR1_TRGT_SIMULATION 166 | 167 | endmodule : scr1_pipe_mprf 168 | -------------------------------------------------------------------------------- /src/core/primitives/scr1_cg.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief SCR1 clock gate primitive 4 | /// 5 | 6 | `include "scr1_arch_description.svh" 7 | 8 | `ifdef SCR1_CLKCTRL_EN 9 | module scr1_cg ( 10 | input logic clk, 11 | input logic clk_en, 12 | input logic test_mode, 13 | output logic clk_out 14 | ); 15 | 16 | // The code below is a clock gate model for simulation. 17 | // For synthesis, it should be replaced by implementation-specific 18 | // clock gate code. 19 | 20 | logic latch_en; 21 | 22 | always_latch begin 23 | if (~clk) begin 24 | latch_en <= test_mode | clk_en; 25 | end 26 | end 27 | 28 | assign clk_out = latch_en & clk; 29 | 30 | endmodule : scr1_cg 31 | 32 | `endif // SCR1_CLKCTRL_EN 33 | -------------------------------------------------------------------------------- /src/core/primitives/scr1_reset_cells.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Cells for reset handling 4 | /// 5 | 6 | //-------------------------------------------------------------------- 7 | // Reset Buffer Cell 8 | //-------------------------------------------------------------------- 9 | module scr1_reset_buf_cell ( 10 | input logic rst_n, 11 | input logic clk, 12 | input logic test_mode, 13 | input logic test_rst_n, 14 | input logic reset_n_in, 15 | output logic reset_n_out, 16 | output logic reset_n_status 17 | ); 18 | 19 | logic reset_n_ff; 20 | logic reset_n_status_ff; 21 | logic rst_n_mux; 22 | 23 | assign rst_n_mux = (test_mode == 1'b1) ? test_rst_n : rst_n; 24 | 25 | always_ff @(negedge rst_n_mux, posedge clk) begin 26 | if (~rst_n_mux) begin 27 | reset_n_ff <= 1'b0; 28 | end else begin 29 | reset_n_ff <= reset_n_in; 30 | end 31 | end 32 | 33 | assign reset_n_out = (test_mode == 1'b1) ? test_rst_n : reset_n_ff; 34 | 35 | always_ff @(negedge rst_n_mux, posedge clk) begin 36 | if (~rst_n_mux) begin 37 | reset_n_status_ff <= 1'b0; 38 | end else begin 39 | reset_n_status_ff <= reset_n_in; 40 | end 41 | end 42 | assign reset_n_status = reset_n_status_ff; 43 | 44 | endmodule : scr1_reset_buf_cell 45 | 46 | //-------------------------------------------------------------------- 47 | // Reset CDC Synchronization Cell 48 | //-------------------------------------------------------------------- 49 | module scr1_reset_sync_cell #( 50 | parameter int unsigned STAGES_AMOUNT = 2 51 | ) ( 52 | input logic rst_n, 53 | input logic clk, 54 | input logic test_rst_n, 55 | input logic test_mode, 56 | input logic rst_n_in, 57 | output logic rst_n_out 58 | ); 59 | 60 | logic [STAGES_AMOUNT-1:0] rst_n_dff; 61 | logic local_rst_n_in; 62 | 63 | assign local_rst_n_in = (test_mode == 1'b1) ? test_rst_n : rst_n; 64 | 65 | generate 66 | 67 | if (STAGES_AMOUNT == 1) 68 | 69 | begin : gen_reset_sync_cell_single 70 | always_ff @(negedge local_rst_n_in, posedge clk) begin 71 | if (~local_rst_n_in) begin 72 | rst_n_dff <= 1'b0; 73 | end else begin 74 | rst_n_dff <= rst_n_in; 75 | end 76 | end 77 | end : gen_reset_sync_cell_single 78 | 79 | else // STAGES_AMOUNT > 1 80 | 81 | begin : gen_reset_sync_cell_multi 82 | always_ff @(negedge local_rst_n_in, posedge clk) 83 | begin 84 | if (~local_rst_n_in) begin 85 | rst_n_dff <= '0; 86 | end else begin 87 | rst_n_dff <= {rst_n_dff[STAGES_AMOUNT-2:0], rst_n_in}; 88 | end 89 | end 90 | end : gen_reset_sync_cell_multi 91 | 92 | endgenerate 93 | 94 | assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : rst_n_dff[STAGES_AMOUNT-1]; 95 | 96 | endmodule : scr1_reset_sync_cell 97 | 98 | //-------------------------------------------------------------------- 99 | // Data CDC/RDC Synchronization Cell 100 | //-------------------------------------------------------------------- 101 | module scr1_data_sync_cell #( 102 | parameter int unsigned STAGES_AMOUNT = 1 103 | ) ( 104 | input logic rst_n, 105 | input logic clk, 106 | input logic data_in, 107 | output logic data_out 108 | ); 109 | 110 | logic [STAGES_AMOUNT-1:0] data_dff; 111 | 112 | generate 113 | 114 | if (STAGES_AMOUNT == 1) 115 | 116 | begin : gen_data_sync_cell_single 117 | always_ff @(negedge rst_n, posedge clk) 118 | begin 119 | if (~rst_n) begin 120 | data_dff <= 1'b0; 121 | end else begin 122 | data_dff <= data_in; 123 | end 124 | end 125 | end : gen_data_sync_cell_single 126 | 127 | else // STAGES_AMOUNT > 1 128 | 129 | begin : gen_data_sync_cell_multi 130 | always_ff @(negedge rst_n, posedge clk) 131 | begin 132 | if (~rst_n) begin 133 | data_dff <= '0; 134 | end else begin 135 | data_dff <= {data_dff[STAGES_AMOUNT-2:0], data_in}; 136 | end 137 | end 138 | end : gen_data_sync_cell_multi 139 | 140 | endgenerate 141 | 142 | assign data_out = data_dff[STAGES_AMOUNT-1]; 143 | 144 | endmodule : scr1_data_sync_cell 145 | 146 | //-------------------------------------------------------------------- 147 | // Reset / RDC Qualifyer Adapter Cell 148 | // (Reset Generation Cell w/ RDC Qualifyer Adaptation circuitry) 149 | //-------------------------------------------------------------------- 150 | // Total stages amount = 151 | // 1 Front Sync stage \ 152 | // + 1 (delay introduced by the reset output buffer register) 153 | //-------------------------------------------------------------------- 154 | module scr1_reset_qlfy_adapter_cell_sync ( 155 | input logic rst_n, 156 | input logic clk, 157 | input logic test_rst_n, 158 | input logic test_mode, 159 | input logic reset_n_in_sync, 160 | output logic reset_n_out_qlfy, 161 | output logic reset_n_out, 162 | output logic reset_n_status 163 | ); 164 | 165 | logic rst_n_mux; 166 | logic reset_n_front_ff; 167 | 168 | // Front sync stage 169 | assign rst_n_mux = (test_mode == 1'b1) ? test_rst_n : rst_n; 170 | 171 | always_ff @(negedge rst_n_mux, posedge clk) begin 172 | if (~rst_n_mux) begin 173 | reset_n_front_ff <= 1'b0; 174 | end else begin 175 | reset_n_front_ff <= reset_n_in_sync; 176 | end 177 | end 178 | 179 | // Sync reset output for all reset qualifier chains targeting this reset domain 180 | // (for reset-domain-crossings with the given reset domain as a destination). 181 | assign reset_n_out_qlfy = reset_n_front_ff; 182 | 183 | // Reset output buffer 184 | scr1_reset_buf_cell 185 | i_reset_output_buf ( 186 | .rst_n (rst_n), 187 | .clk (clk), 188 | .test_mode (test_mode), 189 | .test_rst_n (test_rst_n), 190 | .reset_n_in (reset_n_front_ff), 191 | .reset_n_out (reset_n_out), 192 | .reset_n_status (reset_n_status) 193 | ); 194 | 195 | endmodule : scr1_reset_qlfy_adapter_cell_sync 196 | 197 | module scr1_reset_and2_cell ( 198 | input logic [1:0] rst_n_in, 199 | input logic test_rst_n, 200 | input logic test_mode, 201 | output logic rst_n_out 202 | ); 203 | 204 | assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : (&rst_n_in); 205 | 206 | endmodule : scr1_reset_and2_cell 207 | 208 | 209 | module scr1_reset_and3_cell ( 210 | input logic [2:0] rst_n_in, 211 | input logic test_rst_n, 212 | input logic test_mode, 213 | output logic rst_n_out 214 | ); 215 | 216 | assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : (&rst_n_in); 217 | 218 | endmodule : scr1_reset_and3_cell 219 | 220 | 221 | module scr1_reset_mux2_cell ( 222 | input logic [1:0] rst_n_in, 223 | input logic select, 224 | input logic test_rst_n, 225 | input logic test_mode, 226 | output logic rst_n_out 227 | ); 228 | 229 | assign rst_n_out = (test_mode == 1'b1) ? test_rst_n : rst_n_in[select]; 230 | 231 | endmodule : scr1_reset_mux2_cell 232 | -------------------------------------------------------------------------------- /src/core/scr1_clk_ctrl.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief SCR1 clock control 4 | /// 5 | 6 | `include "scr1_arch_description.svh" 7 | 8 | `ifdef SCR1_CLKCTRL_EN 9 | module scr1_clk_ctrl ( 10 | input logic clk, // Clock control module clock 11 | input logic rst_n, // Clock control module reset 12 | input logic test_mode, // DFT Test Mode 13 | input logic test_rst_n, // DFT Test reset 14 | 15 | input logic pipe2clkctl_sleep_req_i, // CLK disable request from pipe 16 | input logic pipe2clkctl_wake_req_i, // CLK enable request from pipe 17 | 18 | output logic clkctl2pipe_clk_alw_on_o, // Not gated pipe CLK 19 | output logic clkctl2pipe_clk_o, // Gated pipe 20 | output logic clkctl2pipe_clk_en_o, // CLK enabled flag 21 | output logic clkctl2pipe_clk_dbgc_o // CLK for pipe debug subsystem 22 | ); 23 | 24 | logic ctrl_rst_n; 25 | 26 | assign clkctl2pipe_clk_alw_on_o = clk; 27 | assign clkctl2pipe_clk_dbgc_o = clk; 28 | assign ctrl_rst_n = (test_mode) ? test_rst_n : rst_n; 29 | 30 | always_ff @(posedge clk, negedge ctrl_rst_n) begin 31 | if (~ctrl_rst_n) begin 32 | clkctl2pipe_clk_en_o <= 1'b1; 33 | end else begin 34 | if (clkctl2pipe_clk_en_o) begin 35 | if (pipe2clkctl_sleep_req_i & ~pipe2clkctl_wake_req_i) begin 36 | clkctl2pipe_clk_en_o <= 1'b0; 37 | end 38 | end else begin // ~clkctl2pipe_clk_en_o 39 | if (pipe2clkctl_wake_req_i) begin 40 | clkctl2pipe_clk_en_o <= 1'b1; 41 | end 42 | end // pipeline 43 | end 44 | end 45 | 46 | scr1_cg i_scr1_cg_pipe ( 47 | .clk (clk ), 48 | .clk_en (clkctl2pipe_clk_en_o), 49 | .test_mode (test_mode ), 50 | .clk_out (clkctl2pipe_clk_o ) 51 | ); 52 | 53 | endmodule : scr1_clk_ctrl 54 | 55 | `endif // SCR1_CLKCTRL_EN 56 | -------------------------------------------------------------------------------- /src/core/scr1_dmi.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Debug Module Interface (DMI) 4 | /// 5 | 6 | //------------------------------------------------------------------------------ 7 | // 8 | // Functionality: 9 | // - Provides TAPC with access to Debug Module (DM) and DTMCS 10 | // 11 | // Structure: 12 | // - DMI <-> TAP interface 13 | // - DMI <-> DM interface 14 | // 15 | //------------------------------------------------------------------------------ 16 | 17 | `include "scr1_arch_description.svh" 18 | 19 | `ifdef SCR1_DBG_EN 20 | `include "scr1_dm.svh" 21 | 22 | module scr1_dmi ( 23 | // System 24 | input logic rst_n, // DMI unit reset 25 | input logic clk, // DMI unit clock 26 | 27 | // TAP interface 28 | input logic tapcsync2dmi_ch_sel_i, // Debug Transport Module Chain Select 29 | input logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0] tapcsync2dmi_ch_id_i, // Debug Transport Module Chain ID 30 | input logic tapcsync2dmi_ch_capture_i, // Debug Transport Module Chain Capture 31 | input logic tapcsync2dmi_ch_shift_i, // Debug Transport Module Chain Shift 32 | input logic tapcsync2dmi_ch_update_i, // Debug Transport Module Chain Update 33 | input logic tapcsync2dmi_ch_tdi_i, // Debug Transport Module Chain TDI 34 | output logic dmi2tapcsync_ch_tdo_o, // Debug Transport Module Chain TDO 35 | 36 | // DM interface 37 | input logic dm2dmi_resp_i, // DMI response 38 | input logic [SCR1_DBG_DMI_DATA_WIDTH-1:0] dm2dmi_rdata_i, // DMI read data 39 | output logic dmi2dm_req_o, // DMI request 40 | output logic dmi2dm_wr_o, // DMI write 41 | output logic [SCR1_DBG_DMI_ADDR_WIDTH-1:0] dmi2dm_addr_o, // DMI address 42 | output logic [SCR1_DBG_DMI_DATA_WIDTH-1:0] dmi2dm_wdata_o // DMI write data 43 | ); 44 | 45 | //------------------------------------------------------------------------------ 46 | // Local parameters declaration 47 | //------------------------------------------------------------------------------ 48 | 49 | // Debug Transport Module Status parameters 50 | //------------------------------------------------------------------------------ 51 | 52 | localparam DTMCS_RESERVEDB_HI = 5'd31; 53 | localparam DTMCS_RESERVEDB_LO = 5'd18; 54 | localparam DTMCS_DMIHARDRESET = 5'd17; 55 | localparam DTMCS_DMIRESET = 5'd16; 56 | localparam DTMCS_RESERVEDA = 5'd15; 57 | localparam DTMCS_IDLE_HI = 5'd14; 58 | localparam DTMCS_IDLE_LO = 5'd12; 59 | localparam DTMCS_DMISTAT_HI = 5'd11; 60 | localparam DTMCS_DMISTAT_LO = 5'd10; 61 | localparam DTMCS_ABITS_HI = 5'd9; 62 | localparam DTMCS_ABITS_LO = 5'd4; 63 | localparam DTMCS_VERSION_HI = 5'd3; 64 | localparam DTMCS_VERSION_LO = 5'd0; 65 | 66 | // Debug Module Interface parameters 67 | //------------------------------------------------------------------------------ 68 | 69 | localparam DMI_OP_LO = 5'd0; 70 | localparam DMI_OP_HI = DMI_OP_LO + SCR1_DBG_DMI_OP_WIDTH - 1; 71 | localparam DMI_DATA_LO = DMI_OP_HI + 1; 72 | localparam DMI_DATA_HI = DMI_DATA_LO + SCR1_DBG_DMI_DATA_WIDTH - 1; 73 | localparam DMI_ADDR_LO = DMI_DATA_HI + 1; 74 | localparam DMI_ADDR_HI = DMI_ADDR_LO + SCR1_DBG_DMI_ADDR_WIDTH - 1; 75 | 76 | //------------------------------------------------------------------------------ 77 | // Local signals declaration 78 | //------------------------------------------------------------------------------ 79 | 80 | // TAP data register 81 | logic tap_dr_upd; 82 | logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0] tap_dr_ff; 83 | logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0] tap_dr_shift; 84 | logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0] tap_dr_rdata; 85 | logic [SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:0] tap_dr_next; 86 | 87 | // DM read data register 88 | logic dm_rdata_upd; 89 | logic [SCR1_DBG_DMI_DATA_WIDTH-1:0] dm_rdata_ff; 90 | 91 | logic tapc_dmi_access_req; 92 | logic tapc_dtmcs_sel; 93 | 94 | //------------------------------------------------------------------------------ 95 | // DMI <-> TAP interface 96 | //------------------------------------------------------------------------------ 97 | 98 | // TAPC read data multiplexer 99 | //------------------------------------------------------------------------------ 100 | 101 | assign tapc_dtmcs_sel = (tapcsync2dmi_ch_id_i == 1'd1); 102 | 103 | // DMI operation is always successful in the current implementation 104 | always_comb begin 105 | tap_dr_rdata = '0; 106 | 107 | if(tapc_dtmcs_sel) begin 108 | tap_dr_rdata[DTMCS_RESERVEDB_HI:DTMCS_RESERVEDB_LO] = 'b0; 109 | tap_dr_rdata[DTMCS_DMIHARDRESET] = 'b0; 110 | tap_dr_rdata[DTMCS_DMIRESET] = 'b0; 111 | tap_dr_rdata[DTMCS_RESERVEDA] = 'b0; 112 | tap_dr_rdata[DTMCS_IDLE_HI:DTMCS_IDLE_LO] = 'b0; 113 | tap_dr_rdata[DTMCS_DMISTAT_HI:DTMCS_DMISTAT_LO] = 'b0; 114 | tap_dr_rdata[DTMCS_ABITS_HI :DTMCS_ABITS_LO] = SCR1_DBG_DMI_ADDR_WIDTH; 115 | tap_dr_rdata[DTMCS_VERSION_LO] = 1'b1; 116 | end else begin 117 | tap_dr_rdata[DMI_ADDR_HI:DMI_ADDR_LO] = 'b0; 118 | tap_dr_rdata[DMI_DATA_HI:DMI_DATA_LO] = dm_rdata_ff; 119 | tap_dr_rdata[DMI_OP_HI :DMI_OP_LO] = 'b0; 120 | end 121 | end 122 | 123 | assign tap_dr_shift = tapc_dtmcs_sel 124 | ? {9'b0, tapcsync2dmi_ch_tdi_i, tap_dr_ff[SCR1_DBG_DMI_DR_DTMCS_WIDTH-1:1]} 125 | : {tapcsync2dmi_ch_tdi_i, tap_dr_ff[SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH-1:1]}; 126 | 127 | // TAP data register 128 | //------------------------------------------------------------------------------ 129 | 130 | assign tap_dr_upd = tapcsync2dmi_ch_capture_i | tapcsync2dmi_ch_shift_i; 131 | 132 | always_ff @(posedge clk, negedge rst_n) begin 133 | if (~rst_n) begin 134 | tap_dr_ff <= '0; 135 | end else if(tap_dr_upd) begin 136 | tap_dr_ff <= tap_dr_next; 137 | end 138 | end 139 | 140 | assign tap_dr_next = tapcsync2dmi_ch_capture_i ? tap_dr_rdata 141 | : tapcsync2dmi_ch_shift_i ? tap_dr_shift 142 | : tap_dr_ff; 143 | 144 | assign dmi2tapcsync_ch_tdo_o = tap_dr_ff[0]; 145 | 146 | //------------------------------------------------------------------------------ 147 | // DMI <-> DM interface 148 | //------------------------------------------------------------------------------ 149 | 150 | assign tapc_dmi_access_req = tapcsync2dmi_ch_update_i & tapcsync2dmi_ch_sel_i 151 | & (tapcsync2dmi_ch_id_i == 2'd2); 152 | 153 | always_comb begin 154 | dmi2dm_req_o = 1'b0; 155 | dmi2dm_wr_o = 1'b0; 156 | dmi2dm_addr_o = 1'b0; 157 | dmi2dm_wdata_o = 1'b0; 158 | 159 | if(tapc_dmi_access_req) begin 160 | dmi2dm_req_o = tap_dr_ff[DMI_OP_HI :DMI_OP_LO] != 2'b00; 161 | dmi2dm_wr_o = tap_dr_ff[DMI_OP_HI :DMI_OP_LO] == 2'b10; 162 | dmi2dm_addr_o = tap_dr_ff[DMI_ADDR_HI:DMI_ADDR_LO]; 163 | dmi2dm_wdata_o = tap_dr_ff[DMI_DATA_HI:DMI_DATA_LO]; 164 | end 165 | end 166 | 167 | // DM read data register 168 | //------------------------------------------------------------------------------ 169 | 170 | assign dm_rdata_upd = dmi2dm_req_o & dm2dmi_resp_i & ~dmi2dm_wr_o; 171 | 172 | always_ff @(posedge clk, negedge rst_n) begin 173 | if (~rst_n) begin 174 | dm_rdata_ff <= '0; 175 | end else if (dm_rdata_upd) begin 176 | dm_rdata_ff <= dm2dmi_rdata_i; 177 | end 178 | end 179 | 180 | endmodule : scr1_dmi 181 | 182 | `endif // SCR1_DBG_EN 183 | -------------------------------------------------------------------------------- /src/core/scr1_tapc.sv: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/core/scr1_tapc.sv -------------------------------------------------------------------------------- /src/core/scr1_tapc_shift_reg.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief TAPC shift register. Parameterized implementation of JTAG TAPC's Shift Register. 4 | /// 5 | 6 | `include "scr1_arch_description.svh" 7 | 8 | `ifdef SCR1_DBG_EN 9 | module scr1_tapc_shift_reg #( 10 | parameter int unsigned SCR1_WIDTH = 8, // Register width, bits 11 | parameter logic [SCR1_WIDTH-1:0] SCR1_RESET_VALUE = '0 // Register's value after reset 12 | ) ( 13 | input logic clk, // Clock 14 | input logic rst_n, // Async reset 15 | input logic rst_n_sync, // Sync reset 16 | // TAP FSM's control signals: 17 | input logic fsm_dr_select, // - for this DR selection (operation enabling); 18 | input logic fsm_dr_capture, // - to capture parallel input's data into shift register; 19 | input logic fsm_dr_shift, // - to enable data shifting; 20 | // Inputs: 21 | input logic din_serial, // - serial (shift_reg[msb/SCR1_WIDTH]); 22 | input logic [SCR1_WIDTH-1:0] din_parallel, // - parallel (shift register's input). 23 | // Outputs: 24 | output logic dout_serial, // - serial (shift_reg[0]); 25 | output logic [SCR1_WIDTH-1:0] dout_parallel // - parallel (shift register's output). 26 | ); 27 | 28 | //------------------------------------------------------------------------------- 29 | // Local signals declaration 30 | //------------------------------------------------------------------------------- 31 | logic [SCR1_WIDTH-1:0] shift_reg; 32 | 33 | //------------------------------------------------------------------------------- 34 | // Shift register 35 | //------------------------------------------------------------------------------- 36 | generate 37 | if (SCR1_WIDTH > 1) 38 | begin : dr_shift_reg 39 | 40 | always_ff @(posedge clk, negedge rst_n) 41 | begin 42 | if (~rst_n) begin 43 | shift_reg <= SCR1_RESET_VALUE; 44 | end 45 | else if (~rst_n_sync) begin 46 | shift_reg <= SCR1_RESET_VALUE; 47 | end 48 | else if (fsm_dr_select & fsm_dr_capture) begin 49 | shift_reg <= din_parallel; 50 | end 51 | else if (fsm_dr_select & fsm_dr_shift) begin 52 | shift_reg <= {din_serial, shift_reg[SCR1_WIDTH-1:1]}; 53 | end 54 | end 55 | 56 | end 57 | else begin : dr_shift_reg 58 | 59 | always_ff @(posedge clk, negedge rst_n) 60 | begin 61 | if (~rst_n) begin 62 | shift_reg <= SCR1_RESET_VALUE; 63 | end 64 | else if (~rst_n_sync) begin 65 | shift_reg <= SCR1_RESET_VALUE; 66 | end 67 | else if (fsm_dr_select & fsm_dr_capture) begin 68 | shift_reg <= din_parallel; 69 | end 70 | else if (fsm_dr_select & fsm_dr_shift) begin 71 | shift_reg <= din_serial; 72 | end 73 | end 74 | 75 | end 76 | endgenerate 77 | 78 | //------------------------------------------------------------------------------- 79 | // Parallel output 80 | //------------------------------------------------------------------------------- 81 | assign dout_parallel = shift_reg; 82 | 83 | //------------------------------------------------------------------------------- 84 | // Serial output 85 | //------------------------------------------------------------------------------- 86 | assign dout_serial = shift_reg[0]; 87 | 88 | `ifdef SCR1_TRGT_SIMULATION 89 | //------------------------------------------------------------------------------- 90 | // Assertion 91 | //------------------------------------------------------------------------------- 92 | 93 | // X checks 94 | SCR1_SVA_TAPC_SHIFTREG_XCHECK : assert property ( 95 | @(negedge clk) disable iff (~rst_n) 96 | !$isunknown({ 97 | rst_n_sync, 98 | fsm_dr_select, 99 | fsm_dr_capture, 100 | fsm_dr_shift, 101 | din_serial, 102 | din_parallel 103 | }) 104 | ) else begin 105 | $error("TAPC Shift Reg error: unknown values"); 106 | end 107 | 108 | `endif // SCR1_TRGT_SIMULATION 109 | 110 | endmodule : scr1_tapc_shift_reg 111 | 112 | `endif // SCR1_DBG_EN 113 | -------------------------------------------------------------------------------- /src/core/scr1_tapc_synchronizer.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief TAPC clock domain crossing synchronizer 4 | /// 5 | 6 | `include "scr1_arch_description.svh" 7 | 8 | `ifdef SCR1_DBG_EN 9 | `include "scr1_tapc.svh" 10 | `include "scr1_dm.svh" 11 | 12 | module scr1_tapc_synchronizer ( 13 | // System common signals 14 | input logic pwrup_rst_n, // Power-Up Reset 15 | input logic dm_rst_n, // Debug Module Reset 16 | input logic clk, // System Clock (SysCLK) 17 | 18 | // JTAG common signals 19 | input logic tapc_trst_n, // JTAG Test Reset (TRSTn) 20 | input logic tapc_tck, // JTAG Test Clock (TCK) 21 | 22 | 23 | // DMI/SCU scan-chains 24 | input logic tapc2tapcsync_scu_ch_sel_i, // SCU Chain Select input (TCK domain) 25 | output logic tapcsync2scu_ch_sel_o, // SCU Chain Select output (SysCLK domain) 26 | input logic tapc2tapcsync_dmi_ch_sel_i, // DMI Chain Select input (TCK domain) 27 | output logic tapcsync2dmi_ch_sel_o, // DMI Chain Select output (SysCLK domain) 28 | 29 | input logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0] tapc2tapcsync_ch_id_i, // DMI/SCU Chain Identifier input (TCK domain) 30 | output logic [SCR1_DBG_DMI_CH_ID_WIDTH-1:0] tapcsync2core_ch_id_o, // DMI/SCU Chain Identifier output (SysCLK domain) 31 | 32 | input logic tapc2tapcsync_ch_capture_i, // DMI/SCU Chain Capture input (TCK domain) 33 | output logic tapcsync2core_ch_capture_o, // DMI/SCU Chain Capture output (SysCLK domain) 34 | 35 | input logic tapc2tapcsync_ch_shift_i, // DMI/SCU Chain Shift input (TCK domain) 36 | output logic tapcsync2core_ch_shift_o, // DMI/SCU Chain Shift output (SysCLK domain) 37 | 38 | input logic tapc2tapcsync_ch_update_i, // DMI/SCU Chain Update input (TCK domain) 39 | output logic tapcsync2core_ch_update_o, // DMI/SCU Chain Update output (SysCLK domain) 40 | 41 | input logic tapc2tapcsync_ch_tdi_i, // DMI/SCU Chain TDI input (TCK domain) 42 | output logic tapcsync2core_ch_tdi_o, // DMI/SCU Chain TDI output (SysCLK domain) 43 | 44 | output logic tapc2tapcsync_ch_tdo_i, // DMI/SCU Chain TDO output (TCK domain) 45 | input logic tapcsync2core_ch_tdo_o // DMI/SCU Chain TDO input (SysCLK domain) 46 | ); 47 | 48 | //------------------------------------------------------------------------------- 49 | // Local signals declaration 50 | //------------------------------------------------------------------------------- 51 | 52 | logic tck_divpos; 53 | logic tck_divneg; 54 | logic tck_rise_load; 55 | logic tck_rise_reset; 56 | logic tck_fall_load; 57 | logic tck_fall_reset; 58 | logic [3:0] tck_divpos_sync; 59 | logic [3:0] tck_divneg_sync; 60 | logic [2:0] dmi_ch_capture_sync; 61 | logic [2:0] dmi_ch_shift_sync; 62 | logic [2:0] dmi_ch_tdi_sync; 63 | 64 | //------------------------------------------------------------------------------- 65 | // Logic 66 | //------------------------------------------------------------------------------- 67 | 68 | always_ff @(posedge tapc_tck, negedge tapc_trst_n) begin 69 | if (~tapc_trst_n) begin 70 | tck_divpos <= 1'b0; 71 | end else begin 72 | tck_divpos <= ~tck_divpos; 73 | end 74 | end 75 | 76 | always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin 77 | if (~tapc_trst_n) begin 78 | tck_divneg <= 1'b0; 79 | end else begin 80 | tck_divneg <= ~tck_divneg; 81 | end 82 | end 83 | 84 | always_ff @(posedge clk, negedge pwrup_rst_n) begin 85 | if (~pwrup_rst_n) begin 86 | tck_divpos_sync <= 4'd0; 87 | tck_divneg_sync <= 4'd0; 88 | end else begin 89 | tck_divpos_sync <= {tck_divpos_sync[2:0], tck_divpos}; 90 | tck_divneg_sync <= {tck_divneg_sync[2:0], tck_divneg}; 91 | end 92 | end 93 | 94 | assign tck_rise_load = tck_divpos_sync[2] ^ tck_divpos_sync[1]; 95 | assign tck_rise_reset = tck_divpos_sync[3] ^ tck_divpos_sync[2]; 96 | assign tck_fall_load = tck_divneg_sync[2] ^ tck_divneg_sync[1]; 97 | assign tck_fall_reset = tck_divneg_sync[3] ^ tck_divneg_sync[2]; 98 | 99 | always_ff @(posedge clk, negedge pwrup_rst_n) begin 100 | if (~pwrup_rst_n) begin 101 | tapcsync2core_ch_update_o <= '0; 102 | end else begin 103 | if (tck_fall_load) begin 104 | tapcsync2core_ch_update_o <= tapc2tapcsync_ch_update_i; 105 | end else if (tck_fall_reset) begin 106 | tapcsync2core_ch_update_o <= '0; 107 | end 108 | end 109 | end 110 | 111 | always_ff @(negedge tapc_tck, negedge tapc_trst_n) begin 112 | if (~tapc_trst_n) begin 113 | dmi_ch_capture_sync[0] <= '0; 114 | dmi_ch_shift_sync[0] <= '0; 115 | end else begin 116 | dmi_ch_capture_sync[0] <= tapc2tapcsync_ch_capture_i; 117 | dmi_ch_shift_sync[0] <= tapc2tapcsync_ch_shift_i; 118 | end 119 | end 120 | 121 | always_ff @(posedge clk, negedge pwrup_rst_n) begin 122 | if (~pwrup_rst_n) begin 123 | dmi_ch_capture_sync[2:1] <= '0; 124 | dmi_ch_shift_sync[2:1] <= '0; 125 | end else begin 126 | dmi_ch_capture_sync[2:1] <= {dmi_ch_capture_sync[1], dmi_ch_capture_sync[0]}; 127 | dmi_ch_shift_sync[2:1] <= {dmi_ch_shift_sync[1], dmi_ch_shift_sync[0]}; 128 | end 129 | end 130 | 131 | always_ff @(posedge clk, negedge pwrup_rst_n) begin 132 | if (~pwrup_rst_n) begin 133 | dmi_ch_tdi_sync <= '0; 134 | end else begin 135 | dmi_ch_tdi_sync <= {dmi_ch_tdi_sync[1:0], tapc2tapcsync_ch_tdi_i}; 136 | end 137 | end 138 | 139 | always_ff @(posedge clk, negedge pwrup_rst_n) begin 140 | if (~pwrup_rst_n) begin 141 | tapcsync2core_ch_capture_o <= '0; 142 | tapcsync2core_ch_shift_o <= '0; 143 | tapcsync2core_ch_tdi_o <= '0; 144 | end else begin 145 | if (tck_rise_load) begin 146 | tapcsync2core_ch_capture_o <= dmi_ch_capture_sync[2]; 147 | tapcsync2core_ch_shift_o <= dmi_ch_shift_sync[2]; 148 | tapcsync2core_ch_tdi_o <= dmi_ch_tdi_sync[2]; 149 | end else if (tck_rise_reset) begin 150 | tapcsync2core_ch_capture_o <= '0; 151 | tapcsync2core_ch_shift_o <= '0; 152 | tapcsync2core_ch_tdi_o <= '0; 153 | end 154 | end 155 | end 156 | 157 | always_ff @(posedge clk, negedge dm_rst_n) begin 158 | if (~dm_rst_n) begin 159 | tapcsync2dmi_ch_sel_o <= '0; 160 | tapcsync2core_ch_id_o <= '0; 161 | end else begin 162 | if (tck_rise_load) begin 163 | tapcsync2dmi_ch_sel_o <= tapc2tapcsync_dmi_ch_sel_i; 164 | tapcsync2core_ch_id_o <= tapc2tapcsync_ch_id_i; 165 | end 166 | end 167 | end 168 | 169 | always_ff @(posedge clk, negedge pwrup_rst_n) begin 170 | if (~pwrup_rst_n) begin 171 | tapcsync2scu_ch_sel_o <= '0; 172 | end else begin 173 | if (tck_rise_load) begin 174 | tapcsync2scu_ch_sel_o <= tapc2tapcsync_scu_ch_sel_i; 175 | end 176 | end 177 | end 178 | 179 | assign tapc2tapcsync_ch_tdo_i = tapcsync2core_ch_tdo_o; 180 | 181 | endmodule : scr1_tapc_synchronizer 182 | 183 | `endif // SCR1_DBG_EN 184 | -------------------------------------------------------------------------------- /src/includes/scr1_ahb.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_ahb.svh -------------------------------------------------------------------------------- /src/includes/scr1_arch_description.svh: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Architecture description file 4 | /// 5 | 6 | `ifndef SCR1_ARCH_DESCRIPTION_SVH 7 | `define SCR1_ARCH_DESCRIPTION_SVH 8 | 9 | 10 | //------------------------------------------------------------------------------ 11 | // CORE FUNDAMENTAL PARAMETERS 12 | //------------------------------------------------------------------------------ 13 | 14 | // SCR1 core identifiers 15 | `define SCR1_MIMPID 32'h22011200 16 | `define SCR1_MVENDORID 32'h00000000 17 | 18 | // Width of main registers and buses 19 | `define SCR1_XLEN 32 20 | `define SCR1_IMEM_AWIDTH `SCR1_XLEN 21 | `define SCR1_IMEM_DWIDTH `SCR1_XLEN 22 | `define SCR1_DMEM_AWIDTH `SCR1_XLEN 23 | `define SCR1_DMEM_DWIDTH `SCR1_XLEN 24 | 25 | // TAP IDCODE 26 | `define SCR1_TAP_IDCODE 'hDEB11001 27 | 28 | 29 | `ifdef SCR1_ARCH_CUSTOM 30 | //------------------------------------------------------------------------------ 31 | // INCLUDE SCR1_ARCH_CUSTOM.SVH 32 | //------------------------------------------------------------------------------ 33 | 34 | // The external file scr1_arch_custom.svh is used for the open SCR1-SDK project, 35 | // and can also be used for any custom projects. 36 | 37 | // The file sets: 38 | // - target platform (FPGA/ASIC), which affects the choice of logical constructs; 39 | // - device build ID; 40 | // - address constants; 41 | // - could enables configuration parameters. 42 | 43 | // Possible targets: 44 | // `define SCR1_TRGT_FPGA_INTEL // target platform is Intel FPGAs 45 | // `define SCR1_TRGT_FPGA_INTEL_MAX10 // target platform is Intel MAX 10 FPGAs (used in the SCR1-SDK project) 46 | // `define SCR1_TRGT_FPGA_INTEL_ARRIAV // target platform is Intel Arria V FPGAs (used in the SCR1-SDK project) 47 | // `define SCR1_TRGT_FPGA_XILINX // target platform is Xilinx FPGAs (used in the SCR1-SDK project) 48 | // `define SCR1_TRGT_ASIC // target platform is ASIC 49 | // `define SCR1_TRGT_SIMULATION // target is simulation (enable simulation code) 50 | 51 | `include "scr1_arch_custom.svh" 52 | 53 | `endif // SCR1_ARCH_CUSTOM 54 | 55 | 56 | //------------------------------------------------------------------------------ 57 | // RECOMMENDED CORE ARCHITECTURE CONFIGURATIONS 58 | //------------------------------------------------------------------------------ 59 | 60 | // Uncomment one of these defines to set the recommended configuration: 61 | 62 | //`define SCR1_CFG_RV32IMC_MAX 63 | //`define SCR1_CFG_RV32IC_BASE 64 | //`define SCR1_CFG_RV32EC_MIN 65 | 66 | // If all defines are commented, custom configuration will be used (see below) 67 | 68 | //------------------------------------------------------------------------------ 69 | // READ-ONLY: settings for recommended configurations 70 | `ifdef SCR1_CFG_RV32IMC_MAX 71 | `define SCR1_RVI_EXT 72 | `define SCR1_RVM_EXT 73 | `define SCR1_RVC_EXT 74 | parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 26; 75 | `define SCR1_MTVEC_MODE_EN 76 | `define SCR1_FAST_MUL 77 | `define SCR1_MPRF_RST_EN 78 | `define SCR1_MCOUNTEN_EN 79 | `define SCR1_DBG_EN 80 | `define SCR1_TDU_EN 81 | parameter int unsigned SCR1_TDU_TRIG_NUM = 4; 82 | `define SCR1_TDU_ICOUNT_EN 83 | `define SCR1_IPIC_EN 84 | `define SCR1_IPIC_SYNC_EN 85 | `define SCR1_TCM_EN 86 | `elsif SCR1_CFG_RV32IC_BASE 87 | `define SCR1_RVI_EXT 88 | `define SCR1_RVC_EXT 89 | parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 16; 90 | `define SCR1_MTVEC_MODE_EN 91 | `define SCR1_NO_DEC_STAGE 92 | `define SCR1_MPRF_RST_EN 93 | `define SCR1_MCOUNTEN_EN 94 | `define SCR1_DBG_EN 95 | `define SCR1_TDU_EN 96 | parameter int unsigned SCR1_TDU_TRIG_NUM = 2; 97 | `define SCR1_TDU_ICOUNT_EN 98 | `define SCR1_IPIC_EN 99 | `define SCR1_IPIC_SYNC_EN 100 | `define SCR1_TCM_EN 101 | `elsif SCR1_CFG_RV32EC_MIN 102 | `define SCR1_RVE_EXT 103 | `define SCR1_RVC_EXT 104 | parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 0; 105 | `define SCR1_NO_DEC_STAGE 106 | `define SCR1_NO_EXE_STAGE 107 | `define SCR1_TCM_EN 108 | 109 | `else // begin custom configuration section 110 | 111 | 112 | //------------------------------------------------------------------------------ 113 | // CUSTOM CORE ARCHITECTURE CONFIGURATION 114 | //------------------------------------------------------------------------------ 115 | 116 | // To fine-tune custom configuration, you can change the values in this section. 117 | // Make sure that the defines of the recommended configurations are commented, 118 | // otherwise this section will be inactive. 119 | 120 | // RISC-V ISA options 121 | //`define SCR1_RVE_EXT // enable RV32E base integer instruction set, otherwise RV32I will be used 122 | `define SCR1_RVM_EXT // enable standard extension "M" for integer hardware multiplier and divider 123 | `define SCR1_RVC_EXT // enable standard extension "C" for compressed instructions 124 | parameter int unsigned SCR1_MTVEC_BASE_WR_BITS = 26; // number of writable high-order bits in MTVEC.base field 125 | // legal values are 0 to 26 126 | // read-only bits are hardwired to reset value 127 | `define SCR1_MTVEC_MODE_EN // enable writable MTVEC.mode field to allow vectored irq mode, otherwise only direct mode is possible 128 | 129 | `ifndef SCR1_RVE_EXT 130 | `define SCR1_RVI_EXT // RV32E base integer instruction set if SCR1_RVE_EXT is not enabled 131 | `endif // ~SCR1_RVE_EXT 132 | 133 | // Core pipeline options (power-performance-area optimization) 134 | `define SCR1_NO_DEC_STAGE // disable register between IFU and IDU 135 | `define SCR1_NO_EXE_STAGE // disable register between IDU and EXU 136 | `define SCR1_NEW_PC_REG // enable register in IFU for New_PC value 137 | `define SCR1_FAST_MUL // enable fast one-cycle multiplication, otherwise multiplication takes 32 cycles 138 | `define SCR1_CLKCTRL_EN // enable global clock gating 139 | `define SCR1_MPRF_RST_EN // enable reset for MPRF 140 | `define SCR1_MCOUNTEN_EN // enable custom MCOUNTEN CSR for counter control 141 | 142 | // Uncore options 143 | `define SCR1_DBG_EN // enable Debug Subsystem (TAPC, DM, SCU, HDU) 144 | `define SCR1_TDU_EN // enable Trigger Debug Unit (hardware breakpoints) 145 | parameter int unsigned SCR1_TDU_TRIG_NUM = 2; // number of hardware triggers 146 | `define SCR1_TDU_ICOUNT_EN // enable hardware triggers on instruction counter 147 | `define SCR1_IPIC_EN // enable Integrated Programmable Interrupt Controller 148 | `define SCR1_IPIC_SYNC_EN // enable IPIC synchronizer 149 | `define SCR1_TCM_EN // enable Tightly-Coupled Memory 150 | 151 | `endif // end custom configuration section 152 | 153 | 154 | //------------------------------------------------------------------------------ 155 | // CORE INTEGRATION OPTIONS 156 | //------------------------------------------------------------------------------ 157 | 158 | // Bypasses on AXI/AHB bridge I/O 159 | `define SCR1_IMEM_AHB_IN_BP // bypass instruction memory AHB bridge input register 160 | `define SCR1_IMEM_AHB_OUT_BP // bypass instruction memory AHB bridge output register 161 | `define SCR1_DMEM_AHB_IN_BP // bypass data memory AHB bridge input register 162 | `define SCR1_DMEM_AHB_OUT_BP // bypass data memory AHB bridge output register 163 | `define SCR1_IMEM_AXI_REQ_BP // bypass instruction memory AXI bridge request register 164 | `define SCR1_IMEM_AXI_RESP_BP // bypass instruction memory AXI bridge response register 165 | `define SCR1_DMEM_AXI_REQ_BP // bypass data memory AXI bridge request register 166 | `define SCR1_DMEM_AXI_RESP_BP // bypass data memory AXI bridge response register 167 | 168 | `ifndef SCR1_ARCH_CUSTOM 169 | // Default address constants (if scr1_arch_custom.svh is not used) 170 | parameter bit [`SCR1_XLEN-1:0] SCR1_ARCH_RST_VECTOR = 'h200; // Reset vector value (start address after reset) 171 | parameter bit [`SCR1_XLEN-1:0] SCR1_ARCH_MTVEC_BASE = 'h1C0; // MTVEC.base field reset value, or constant value for MTVEC.base bits that are hardwired 172 | 173 | parameter bit [`SCR1_DMEM_AWIDTH-1:0] SCR1_TCM_ADDR_MASK = 'hFFFF0000; // TCM mask and size; size in bytes is two's complement of the mask value 174 | parameter bit [`SCR1_DMEM_AWIDTH-1:0] SCR1_TCM_ADDR_PATTERN = 'h00480000; // TCM address match pattern 175 | 176 | parameter bit [`SCR1_DMEM_AWIDTH-1:0] SCR1_TIMER_ADDR_MASK = 'hFFFFFFE0; // Timer mask 177 | parameter bit [`SCR1_DMEM_AWIDTH-1:0] SCR1_TIMER_ADDR_PATTERN = 'h00490000; // Timer address match pattern 178 | 179 | // Device build ID 180 | `define SCR1_ARCH_BUILD_ID `SCR1_MIMPID 181 | 182 | `endif // SCR1_ARCH_CUSTOM 183 | 184 | 185 | //------------------------------------------------------------------------------ 186 | // TARGET-SPECIFIC OPTIONS 187 | //------------------------------------------------------------------------------ 188 | 189 | // RAM-based MPRF can be used for Intel FPGAs only 190 | `ifdef SCR1_TRGT_FPGA_INTEL 191 | `define SCR1_MPRF_RAM // implements MPRF with dedicated RAM blocks 192 | `endif 193 | 194 | // EXU_STAGE_BYPASS and MPRF_RST_EN must be disabled for RAM-based MPRF 195 | `ifdef SCR1_MPRF_RAM 196 | `undef SCR1_NO_EXE_STAGE 197 | `undef SCR1_MPRF_RST_EN 198 | `endif 199 | 200 | 201 | //------------------------------------------------------------------------------ 202 | // SIMULATION OPTIONS 203 | //------------------------------------------------------------------------------ 204 | 205 | //`define SCR1_TRGT_SIMULATION // enable simulation code (automatically defined by root makefile) 206 | //`define SCR1_TRACE_LOG_EN // enable tracelog 207 | //`define SCR1_XPROP_EN // enable X-propagation 208 | 209 | // Addresses used in testbench 210 | localparam [`SCR1_XLEN-1:0] SCR1_SIM_EXIT_ADDR = 32'h0000_00F8; 211 | localparam [`SCR1_XLEN-1:0] SCR1_SIM_PRINT_ADDR = 32'hF000_0000; 212 | localparam [`SCR1_XLEN-1:0] SCR1_SIM_EXT_IRQ_ADDR = 32'hF000_0100; 213 | localparam [`SCR1_XLEN-1:0] SCR1_SIM_SOFT_IRQ_ADDR = 32'hF000_0200; 214 | 215 | `endif // SCR1_ARCH_DESCRIPTION_SVH -------------------------------------------------------------------------------- /src/includes/scr1_arch_types.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_arch_types.svh -------------------------------------------------------------------------------- /src/includes/scr1_csr.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_csr.svh -------------------------------------------------------------------------------- /src/includes/scr1_dm.svh: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Debug Module header file 4 | /// 5 | 6 | `ifndef SCR1_INCLUDE_DM_DEFS 7 | `define SCR1_INCLUDE_DM_DEFS 8 | 9 | `include "scr1_arch_description.svh" 10 | `include "scr1_hdu.svh" 11 | `include "scr1_csr.svh" 12 | 13 | parameter SCR1_DBG_DMI_ADDR_WIDTH = 6'd7; 14 | parameter SCR1_DBG_DMI_DATA_WIDTH = 6'd32; 15 | parameter SCR1_DBG_DMI_OP_WIDTH = 2'd2; 16 | 17 | parameter SCR1_DBG_DMI_CH_ID_WIDTH = 2'd2; 18 | parameter SCR1_DBG_DMI_DR_DTMCS_WIDTH = 6'd32; 19 | parameter SCR1_DBG_DMI_DR_DMI_ACCESS_WIDTH = SCR1_DBG_DMI_OP_WIDTH + 20 | SCR1_DBG_DMI_DATA_WIDTH + 21 | SCR1_DBG_DMI_ADDR_WIDTH; 22 | 23 | // Debug Module addresses 24 | parameter SCR1_DBG_DATA0 = 7'h4; 25 | parameter SCR1_DBG_DATA1 = 7'h5; 26 | parameter SCR1_DBG_DMCONTROL = 7'h10; 27 | parameter SCR1_DBG_DMSTATUS = 7'h11; 28 | parameter SCR1_DBG_HARTINFO = 7'h12; 29 | parameter SCR1_DBG_ABSTRACTCS = 7'h16; 30 | parameter SCR1_DBG_COMMAND = 7'h17; 31 | parameter SCR1_DBG_ABSTRACTAUTO = 7'h18; 32 | parameter SCR1_DBG_PROGBUF0 = 7'h20; 33 | parameter SCR1_DBG_PROGBUF1 = 7'h21; 34 | parameter SCR1_DBG_PROGBUF2 = 7'h22; 35 | parameter SCR1_DBG_PROGBUF3 = 7'h23; 36 | parameter SCR1_DBG_PROGBUF4 = 7'h24; 37 | parameter SCR1_DBG_PROGBUF5 = 7'h25; 38 | parameter SCR1_DBG_HALTSUM0 = 7'h40; 39 | 40 | // DMCONTROL 41 | parameter SCR1_DBG_DMCONTROL_HALTREQ = 5'd31; 42 | parameter SCR1_DBG_DMCONTROL_RESUMEREQ = 5'd30; 43 | parameter SCR1_DBG_DMCONTROL_HARTRESET = 5'd29; 44 | parameter SCR1_DBG_DMCONTROL_ACKHAVERESET = 5'd28; 45 | parameter SCR1_DBG_DMCONTROL_RESERVEDB = 5'd27; 46 | parameter SCR1_DBG_DMCONTROL_HASEL = 5'd26; 47 | parameter SCR1_DBG_DMCONTROL_HARTSELLO_HI = 5'd25; 48 | parameter SCR1_DBG_DMCONTROL_HARTSELLO_LO = 5'd16; 49 | parameter SCR1_DBG_DMCONTROL_HARTSELHI_HI = 5'd15; 50 | parameter SCR1_DBG_DMCONTROL_HARTSELHI_LO = 5'd6; 51 | parameter SCR1_DBG_DMCONTROL_RESERVEDA_HI = 5'd5; 52 | parameter SCR1_DBG_DMCONTROL_RESERVEDA_LO = 5'd2; 53 | parameter SCR1_DBG_DMCONTROL_NDMRESET = 5'd1; 54 | parameter SCR1_DBG_DMCONTROL_DMACTIVE = 5'd0; 55 | 56 | // DMSTATUS 57 | parameter SCR1_DBG_DMSTATUS_RESERVEDC_HI = 5'd31; 58 | parameter SCR1_DBG_DMSTATUS_RESERVEDC_LO = 5'd23; 59 | parameter SCR1_DBG_DMSTATUS_IMPEBREAK = 5'd22; 60 | parameter SCR1_DBG_DMSTATUS_RESERVEDB_HI = 5'd21; 61 | parameter SCR1_DBG_DMSTATUS_RESERVEDB_LO = 5'd20; 62 | parameter SCR1_DBG_DMSTATUS_ALLHAVERESET = 5'd19; 63 | parameter SCR1_DBG_DMSTATUS_ANYHAVERESET = 5'd18; 64 | parameter SCR1_DBG_DMSTATUS_ALLRESUMEACK = 5'd17; 65 | parameter SCR1_DBG_DMSTATUS_ANYRESUMEACK = 5'd16; 66 | parameter SCR1_DBG_DMSTATUS_ALLNONEXISTENT = 5'd15; 67 | parameter SCR1_DBG_DMSTATUS_ANYNONEXISTENT = 5'd14; 68 | parameter SCR1_DBG_DMSTATUS_ALLUNAVAIL = 5'd13; 69 | parameter SCR1_DBG_DMSTATUS_ANYUNAVAIL = 5'd12; 70 | parameter SCR1_DBG_DMSTATUS_ALLRUNNING = 5'd11; 71 | parameter SCR1_DBG_DMSTATUS_ANYRUNNING = 5'd10; 72 | parameter SCR1_DBG_DMSTATUS_ALLHALTED = 5'd9; 73 | parameter SCR1_DBG_DMSTATUS_ANYHALTED = 5'd8; 74 | parameter SCR1_DBG_DMSTATUS_AUTHENTICATED = 5'd7; 75 | parameter SCR1_DBG_DMSTATUS_AUTHBUSY = 5'd6; 76 | parameter SCR1_DBG_DMSTATUS_RESERVEDA = 5'd5; 77 | parameter SCR1_DBG_DMSTATUS_DEVTREEVALID = 5'd4; 78 | parameter SCR1_DBG_DMSTATUS_VERSION_HI = 5'd3; 79 | parameter SCR1_DBG_DMSTATUS_VERSION_LO = 5'd0; 80 | 81 | // COMMANDS 82 | parameter SCR1_DBG_COMMAND_TYPE_HI = 5'd31; 83 | parameter SCR1_DBG_COMMAND_TYPE_LO = 5'd24; 84 | parameter SCR1_DBG_COMMAND_TYPE_WDTH = SCR1_DBG_COMMAND_TYPE_HI 85 | - SCR1_DBG_COMMAND_TYPE_LO; 86 | 87 | parameter SCR1_DBG_COMMAND_ACCESSREG_RESERVEDB = 5'd23; 88 | parameter SCR1_DBG_COMMAND_ACCESSREG_SIZE_HI = 5'd22; 89 | parameter SCR1_DBG_COMMAND_ACCESSREG_SIZE_LO = 5'd20; 90 | parameter SCR1_DBG_COMMAND_ACCESSREG_SIZE_WDTH = SCR1_DBG_COMMAND_ACCESSREG_SIZE_HI 91 | - SCR1_DBG_COMMAND_ACCESSREG_SIZE_LO; 92 | parameter SCR1_DBG_COMMAND_ACCESSREG_RESERVEDA = 5'd19; 93 | parameter SCR1_DBG_COMMAND_ACCESSREG_POSTEXEC = 5'd18; 94 | parameter SCR1_DBG_COMMAND_ACCESSREG_TRANSFER = 5'd17; 95 | parameter SCR1_DBG_COMMAND_ACCESSREG_WRITE = 5'd16; 96 | parameter SCR1_DBG_COMMAND_ACCESSREG_REGNO_HI = 5'd15; 97 | parameter SCR1_DBG_COMMAND_ACCESSREG_REGNO_LO = 5'd0; 98 | 99 | parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMVIRTUAL = 5'd23; 100 | parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMSIZE_HI = 5'd22; 101 | parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMSIZE_LO = 5'd20; 102 | parameter SCR1_DBG_COMMAND_ACCESSMEM_AAMPOSTINC = 5'd19; 103 | parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDB_HI = 5'd18; 104 | parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDB_LO = 5'd17; 105 | parameter SCR1_DBG_COMMAND_ACCESSMEM_WRITE = 5'd16; 106 | parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDA_HI = 5'd13; 107 | parameter SCR1_DBG_COMMAND_ACCESSMEM_RESERVEDA_LO = 5'd0; 108 | 109 | // ABSTRACTCS 110 | parameter SCR1_DBG_ABSTRACTCS_RESERVEDD_HI = 5'd31; 111 | parameter SCR1_DBG_ABSTRACTCS_RESERVEDD_LO = 5'd29; 112 | parameter SCR1_DBG_ABSTRACTCS_PROGBUFSIZE_HI = 5'd28; 113 | parameter SCR1_DBG_ABSTRACTCS_PROGBUFSIZE_LO = 5'd24; 114 | parameter SCR1_DBG_ABSTRACTCS_RESERVEDC_HI = 5'd23; 115 | parameter SCR1_DBG_ABSTRACTCS_RESERVEDC_LO = 5'd13; 116 | parameter SCR1_DBG_ABSTRACTCS_BUSY = 5'd12; 117 | parameter SCR1_DBG_ABSTRACTCS_RESERVEDB = 5'd11; 118 | parameter SCR1_DBG_ABSTRACTCS_CMDERR_HI = 5'd10; 119 | parameter SCR1_DBG_ABSTRACTCS_CMDERR_LO = 5'd8; 120 | parameter SCR1_DBG_ABSTRACTCS_CMDERR_WDTH = SCR1_DBG_ABSTRACTCS_CMDERR_HI 121 | - SCR1_DBG_ABSTRACTCS_CMDERR_LO; 122 | parameter SCR1_DBG_ABSTRACTCS_RESERVEDA_HI = 5'd7; 123 | parameter SCR1_DBG_ABSTRACTCS_RESERVEDA_LO = 5'd4; 124 | parameter SCR1_DBG_ABSTRACTCS_DATACOUNT_HI = 5'd3; 125 | parameter SCR1_DBG_ABSTRACTCS_DATACOUNT_LO = 5'd0; 126 | 127 | // HARTINFO 128 | parameter SCR1_DBG_HARTINFO_RESERVEDB_HI = 5'd31; 129 | parameter SCR1_DBG_HARTINFO_RESERVEDB_LO = 5'd24; 130 | parameter SCR1_DBG_HARTINFO_NSCRATCH_HI = 5'd23; 131 | parameter SCR1_DBG_HARTINFO_NSCRATCH_LO = 5'd20; 132 | parameter SCR1_DBG_HARTINFO_RESERVEDA_HI = 5'd19; 133 | parameter SCR1_DBG_HARTINFO_RESERVEDA_LO = 5'd17; 134 | parameter SCR1_DBG_HARTINFO_DATAACCESS = 5'd16; 135 | parameter SCR1_DBG_HARTINFO_DATASIZE_HI = 5'd15; 136 | parameter SCR1_DBG_HARTINFO_DATASIZE_LO = 5'd12; 137 | parameter SCR1_DBG_HARTINFO_DATAADDR_HI = 5'd11; 138 | parameter SCR1_DBG_HARTINFO_DATAADDR_LO = 5'd0; 139 | 140 | 141 | `endif // SCR1_INCLUDE_DM_DEFS 142 | -------------------------------------------------------------------------------- /src/includes/scr1_hdu.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_hdu.svh -------------------------------------------------------------------------------- /src/includes/scr1_ipic.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_ipic.svh -------------------------------------------------------------------------------- /src/includes/scr1_memif.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_memif.svh -------------------------------------------------------------------------------- /src/includes/scr1_riscv_isa_decoding.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_riscv_isa_decoding.svh -------------------------------------------------------------------------------- /src/includes/scr1_scu.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_scu.svh -------------------------------------------------------------------------------- /src/includes/scr1_search_ms1.svh: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Most significant one search function 4 | /// 5 | 6 | `ifndef SCR1_SEARCH_MS1_SVH 7 | `define SCR1_SEARCH_MS1_SVH 8 | 9 | //------------------------------------------------------------------------------- 10 | // Local types declaration 11 | //------------------------------------------------------------------------------- 12 | typedef struct { 13 | logic vd; 14 | logic idx; 15 | } type_scr1_search_one_2_s; 16 | 17 | typedef struct { 18 | logic vd; 19 | logic [4:0] idx; 20 | } type_scr1_search_one_32_s; 21 | 22 | //------------------------------------------------------------------------------- 23 | // Leading Zeros Count Function 24 | //------------------------------------------------------------------------------- 25 | function automatic type_scr1_search_one_2_s scr1_lead_zeros_cnt_2( 26 | input logic [1:0] din 27 | ); 28 | type_scr1_search_one_2_s tmp; 29 | begin 30 | tmp.vd = |din; 31 | tmp.idx = ~din[1]; 32 | return tmp; 33 | end 34 | endfunction : scr1_lead_zeros_cnt_2 35 | 36 | function automatic logic [4:0] scr1_lead_zeros_cnt_32( 37 | input logic [31:0] din 38 | ); 39 | begin 40 | logic [15:0] stage1_vd; 41 | logic [7:0] stage2_vd; 42 | logic [3:0] stage3_vd; 43 | logic [1:0] stage4_vd; 44 | 45 | logic stage1_idx [15:0]; 46 | logic [1:0] stage2_idx [7:0]; 47 | logic [2:0] stage3_idx [3:0]; 48 | logic [3:0] stage4_idx [1:0]; 49 | type_scr1_search_one_32_s tmp; 50 | logic [4:0] res; 51 | 52 | // Stage 1 53 | for (int unsigned i=0; i<16; ++i) begin 54 | type_scr1_search_one_2_s tmp; 55 | tmp = scr1_lead_zeros_cnt_2(din[(i+1)*2-1-:2]); 56 | stage1_vd[i] = tmp.vd; 57 | stage1_idx[i] = tmp.idx; 58 | end 59 | 60 | // Stage 2 61 | for (int unsigned i=0; i<8; ++i) begin 62 | type_scr1_search_one_2_s tmp; 63 | tmp = scr1_lead_zeros_cnt_2(stage1_vd[(i+1)*2-1-:2]); 64 | stage2_vd[i] = tmp.vd; 65 | stage2_idx[i] = (tmp.idx) ? {tmp.idx, stage1_idx[2*i]} : {tmp.idx, stage1_idx[2*i+1]}; 66 | end 67 | 68 | // Stage 3 69 | for (int unsigned i=0; i<4; ++i) begin 70 | type_scr1_search_one_2_s tmp; 71 | tmp = scr1_lead_zeros_cnt_2(stage2_vd[(i+1)*2-1-:2]); 72 | stage3_vd[i] = tmp.vd; 73 | stage3_idx[i] = (tmp.idx) ? {tmp.idx, stage2_idx[2*i]} : {tmp.idx, stage2_idx[2*i+1]}; 74 | end 75 | 76 | // Stage 4 77 | for (int unsigned i=0; i<2; ++i) begin 78 | type_scr1_search_one_2_s tmp; 79 | tmp = scr1_lead_zeros_cnt_2(stage3_vd[(i+1)*2-1-:2]); 80 | stage4_vd[i] = tmp.vd; 81 | stage4_idx[i] = (tmp.idx) ? {tmp.idx, stage3_idx[2*i]} : {tmp.idx, stage3_idx[2*i+1]}; 82 | end 83 | 84 | // Stage 5 85 | tmp.vd = |stage4_vd; 86 | tmp.idx = (stage4_vd[1]) ? {1'b0, stage4_idx[1]} : {1'b1, stage4_idx[0]}; 87 | 88 | res = tmp.idx; 89 | 90 | return res; 91 | end 92 | endfunction : scr1_lead_zeros_cnt_32 93 | 94 | `endif // SCR1_SEARCH_MS1_SVH 95 | -------------------------------------------------------------------------------- /src/includes/scr1_tapc.svh: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/syntacore/scr1/ebb5e3551a9d93c0ee95f0b767dd878b8927e702/src/includes/scr1_tapc.svh -------------------------------------------------------------------------------- /src/includes/scr1_tdu.svh: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Trigger Debug Module header 4 | /// 5 | 6 | `ifndef SCR1_INCLUDE_TDU_DEFS 7 | `define SCR1_INCLUDE_TDU_DEFS 8 | 9 | //`include "scr1_arch_description.svh" 10 | 11 | `ifdef SCR1_TDU_EN 12 | //`include "scr1_csr.svh" 13 | 14 | `include "scr1_arch_description.svh" 15 | //`include "scr1_arch_types.svh" 16 | `include "scr1_csr.svh" 17 | 18 | parameter int unsigned SCR1_TDU_MTRIG_NUM = SCR1_TDU_TRIG_NUM; 19 | `ifdef SCR1_TDU_ICOUNT_EN 20 | parameter int unsigned SCR1_TDU_ALLTRIG_NUM = SCR1_TDU_MTRIG_NUM + 1'b1; 21 | `else 22 | parameter int unsigned SCR1_TDU_ALLTRIG_NUM = SCR1_TDU_MTRIG_NUM; 23 | `endif 24 | 25 | parameter int unsigned SCR1_TDU_ADDR_W = `SCR1_XLEN; 26 | parameter int unsigned SCR1_TDU_DATA_W = `SCR1_XLEN; 27 | 28 | // Register map 29 | parameter SCR1_CSR_ADDR_TDU_OFFS_W = 3; 30 | parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0] SCR1_CSR_ADDR_TDU_OFFS_TSELECT = SCR1_CSR_ADDR_TDU_OFFS_W'(0); 31 | parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0] SCR1_CSR_ADDR_TDU_OFFS_TDATA1 = SCR1_CSR_ADDR_TDU_OFFS_W'(1); 32 | parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0] SCR1_CSR_ADDR_TDU_OFFS_TDATA2 = SCR1_CSR_ADDR_TDU_OFFS_W'(2); 33 | parameter bit [SCR1_CSR_ADDR_TDU_OFFS_W-1:0] SCR1_CSR_ADDR_TDU_OFFS_TINFO = SCR1_CSR_ADDR_TDU_OFFS_W'(4); 34 | 35 | 36 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TSELECT = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TSELECT; 37 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TDATA1 = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TDATA1; 38 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TDATA2 = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TDATA2; 39 | parameter bit [SCR1_CSR_ADDR_WIDTH-1:0] SCR1_CSR_ADDR_TDU_TINFO = SCR1_CSR_ADDR_TDU_MBASE + SCR1_CSR_ADDR_TDU_OFFS_TINFO; 40 | 41 | // TDATA1 42 | parameter int unsigned SCR1_TDU_TDATA1_TYPE_HI = `SCR1_XLEN-1; 43 | parameter int unsigned SCR1_TDU_TDATA1_TYPE_LO = `SCR1_XLEN-4; 44 | parameter int unsigned SCR1_TDU_TDATA1_DMODE = `SCR1_XLEN-5; 45 | 46 | // TDATA1: constant bits values 47 | parameter bit SCR1_TDU_TDATA1_DMODE_VAL = 1'b0; 48 | 49 | // MCONTROL: bits number 50 | parameter int unsigned SCR1_TDU_MCONTROL_MASKMAX_HI = `SCR1_XLEN-6; 51 | parameter int unsigned SCR1_TDU_MCONTROL_MASKMAX_LO = `SCR1_XLEN-11; 52 | parameter int unsigned SCR1_TDU_MCONTROL_RESERVEDB_HI = `SCR1_XLEN-12; 53 | parameter int unsigned SCR1_TDU_MCONTROL_RESERVEDB_LO = 21; 54 | parameter int unsigned SCR1_TDU_MCONTROL_HIT = 20; 55 | parameter int unsigned SCR1_TDU_MCONTROL_SELECT = 19; 56 | parameter int unsigned SCR1_TDU_MCONTROL_TIMING = 18; 57 | parameter int unsigned SCR1_TDU_MCONTROL_ACTION_HI = 17; 58 | parameter int unsigned SCR1_TDU_MCONTROL_ACTION_LO = 12; 59 | parameter int unsigned SCR1_TDU_MCONTROL_CHAIN = 11; 60 | parameter int unsigned SCR1_TDU_MCONTROL_MATCH_HI = 10; 61 | parameter int unsigned SCR1_TDU_MCONTROL_MATCH_LO = 7; 62 | parameter int unsigned SCR1_TDU_MCONTROL_M = 6; 63 | parameter int unsigned SCR1_TDU_MCONTROL_RESERVEDA = 5; 64 | parameter int unsigned SCR1_TDU_MCONTROL_S = 4; 65 | parameter int unsigned SCR1_TDU_MCONTROL_U = 3; 66 | parameter int unsigned SCR1_TDU_MCONTROL_EXECUTE = 2; 67 | parameter int unsigned SCR1_TDU_MCONTROL_STORE = 1; 68 | parameter int unsigned SCR1_TDU_MCONTROL_LOAD = 0; 69 | 70 | // MCONTROL: constant bits values 71 | parameter bit [SCR1_TDU_TDATA1_TYPE_HI-SCR1_TDU_TDATA1_TYPE_LO:0] 72 | SCR1_TDU_MCONTROL_TYPE_VAL = 2'd2; 73 | 74 | parameter bit SCR1_TDU_MCONTROL_SELECT_VAL = 1'b0; 75 | parameter bit SCR1_TDU_MCONTROL_TIMING_VAL = 1'b0; 76 | 77 | parameter bit [SCR1_TDU_MCONTROL_MASKMAX_HI-SCR1_TDU_MCONTROL_MASKMAX_LO:0] 78 | SCR1_TDU_MCONTROL_MASKMAX_VAL = 1'b0; 79 | 80 | parameter bit SCR1_TDU_MCONTROL_RESERVEDA_VAL = 1'b0; 81 | 82 | // ICOUNT: bits number 83 | parameter int unsigned SCR1_TDU_ICOUNT_DMODE = `SCR1_XLEN-5; 84 | parameter int unsigned SCR1_TDU_ICOUNT_RESERVEDB_HI = `SCR1_XLEN-6; 85 | parameter int unsigned SCR1_TDU_ICOUNT_RESERVEDB_LO = 25; 86 | parameter int unsigned SCR1_TDU_ICOUNT_HIT = 24; 87 | parameter int unsigned SCR1_TDU_ICOUNT_COUNT_HI = 23; 88 | parameter int unsigned SCR1_TDU_ICOUNT_COUNT_LO = 10; 89 | parameter int unsigned SCR1_TDU_ICOUNT_M = 9; 90 | parameter int unsigned SCR1_TDU_ICOUNT_RESERVEDA = 8; 91 | parameter int unsigned SCR1_TDU_ICOUNT_S = 7; 92 | parameter int unsigned SCR1_TDU_ICOUNT_U = 6; 93 | parameter int unsigned SCR1_TDU_ICOUNT_ACTION_HI = 5; 94 | parameter int unsigned SCR1_TDU_ICOUNT_ACTION_LO = 0; 95 | 96 | // ICOUNT: constant bits values 97 | parameter bit [SCR1_TDU_TDATA1_TYPE_HI-SCR1_TDU_TDATA1_TYPE_LO:0] 98 | SCR1_TDU_ICOUNT_TYPE_VAL = 2'd3; 99 | 100 | parameter bit [SCR1_TDU_ICOUNT_RESERVEDB_HI-SCR1_TDU_ICOUNT_RESERVEDB_LO:0] 101 | SCR1_TDU_ICOUNT_RESERVEDB_VAL = 1'b0; 102 | 103 | parameter bit SCR1_TDU_ICOUNT_RESERVEDA_VAL = 1'b0; 104 | 105 | // CPU pipeline monitors 106 | typedef struct packed { 107 | logic vd; 108 | logic req; 109 | logic [`SCR1_XLEN-1:0] addr; 110 | } type_scr1_brkm_instr_mon_s; 111 | 112 | typedef struct packed { 113 | logic vd; 114 | logic load; 115 | logic store; 116 | logic [`SCR1_XLEN-1:0] addr; 117 | } type_scr1_brkm_lsu_mon_s; 118 | 119 | `endif // SCR1_TDU_EN 120 | 121 | `endif // SCR1_INCLUDE_TDU_DEFS 122 | -------------------------------------------------------------------------------- /src/tb/scr1_top_tb_runtests.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief SCR1 testbench run tests 4 | /// 5 | 6 | //------------------------------------------------------------------------------- 7 | // Run tests 8 | //------------------------------------------------------------------------------- 9 | 10 | initial begin 11 | $value$plusargs("imem_pattern=%h", imem_req_ack_stall); 12 | $value$plusargs("dmem_pattern=%h", dmem_req_ack_stall); 13 | 14 | `ifdef SIGNATURE_OUT 15 | $value$plusargs("test_name=%s", s_testname); 16 | b_single_run_flag = 1; 17 | `else // SIGNATURE_OUT 18 | 19 | $value$plusargs("test_info=%s", s_info); 20 | $value$plusargs("test_results=%s", s_results); 21 | 22 | f_info = $fopen(s_info, "r"); 23 | f_results = $fopen(s_results, "a"); 24 | `endif // SIGNATURE_OUT 25 | 26 | fuse_mhartid = 0; 27 | 28 | end 29 | 30 | always_ff @(posedge clk) begin 31 | bit test_pass; 32 | bit test_error; 33 | int unsigned f_test; 34 | watchdogs_cnt <= watchdogs_cnt + 'b1; 35 | if (test_running) begin 36 | test_pass = 1; 37 | rst_init <= 1'b0; 38 | if ((i_top.i_core_top.i_pipe_top.curr_pc == SCR1_SIM_EXIT_ADDR) & ~rst_init & &rst_cnt) begin 39 | `ifdef VERILATOR 40 | logic [255:0] full_filename; 41 | full_filename = test_file; 42 | `else // VERILATOR 43 | string full_filename; 44 | full_filename = test_file; 45 | `endif // VERILATOR 46 | 47 | if (identify_test(test_file)) begin 48 | 49 | logic [31:0] tmpv, start, stop, ref_data, test_data, start_addr, trap_addr; 50 | integer fd; 51 | logic [31:0] code; 52 | `ifdef VERILATOR 53 | logic [2047:0] tmpstr; 54 | `else // VERILATOR 55 | string tmpstr; 56 | `endif // VERILATOR 57 | 58 | test_running <= 1'b0; 59 | test_pass = 1; 60 | test_error = 0; 61 | 62 | $sformat(tmpstr, "riscv64-unknown-elf-readelf -s %s | grep 'begin_signature\\|end_signature\\| _start\\|trap_vector' | awk '{print $2}' > elfinfo", get_filename(test_file)); 63 | fd = $fopen("script.sh", "w"); 64 | if (fd == 0) begin 65 | $write("Can't open script.sh\n"); 66 | test_error = 1; 67 | end 68 | $fwrite(fd, "%s", tmpstr); 69 | $fclose(fd); 70 | 71 | $system("sh script.sh"); 72 | 73 | fd = $fopen("elfinfo", "r"); 74 | if (fd == 0) begin 75 | $write("Can't open elfinfo\n"); 76 | test_error = 1; 77 | end 78 | if ($fscanf(fd,"%h\n%h\n%h\n%h", trap_addr, start, stop, start_addr) != 4) begin 79 | $write("Wrong elfinfo data\n"); 80 | test_error = 1; 81 | end 82 | if ((trap_addr != ADDR_TRAP_VECTOR & trap_addr != ADDR_TRAP_DEFAULT) | start_addr != ADDR_START) begin 83 | $write("\nError trap_vector %h or/and _start %h are incorrectly aligned and are not at their address\n", trap_addr, start_addr); 84 | test_error = 1; 85 | end 86 | if (start > stop) begin 87 | tmpv = start; 88 | start = stop; 89 | stop = tmpv; 90 | end 91 | $fclose(fd); 92 | 93 | `ifdef SIGNATURE_OUT 94 | 95 | $sformat(tmpstr, "%s.signature.output", s_testname); 96 | `ifdef VERILATOR 97 | tmpstr = remove_trailing_whitespaces(tmpstr); 98 | `endif 99 | fd = $fopen(tmpstr, "w"); 100 | while ((start != stop)) begin 101 | test_data = {i_memory_tb.memory[start+3], i_memory_tb.memory[start+2], i_memory_tb.memory[start+1], i_memory_tb.memory[start]}; 102 | $fwrite(fd, "%x", test_data); 103 | $fwrite(fd, "%s", "\n"); 104 | start += 4; 105 | end 106 | $fclose(fd); 107 | `else //SIGNATURE_OUT 108 | if (identify_test(test_file) == COMPLIANCE) begin 109 | $sformat(tmpstr, "riscv_compliance/ref_data/%s", get_ref_filename(test_file)); 110 | end else if (identify_test(test_file) == ARCH) begin 111 | $sformat(tmpstr, "riscv_arch/ref_data/%s", get_ref_filename(test_file)); 112 | end 113 | `ifdef VERILATOR 114 | tmpstr = remove_trailing_whitespaces(tmpstr); 115 | `endif 116 | fd = $fopen(tmpstr,"r"); 117 | if (fd == 0) begin 118 | $write("Can't open reference_data file: %s\n", tmpstr); 119 | test_error = 1; 120 | end 121 | while (!$feof(fd) && (start != stop)) begin 122 | if (($fscanf(fd, "%h", ref_data)=='h1)) begin 123 | test_data = {i_memory_tb.memory[start+3], i_memory_tb.memory[start+2], i_memory_tb.memory[start+1], i_memory_tb.memory[start]}; 124 | test_pass &= (ref_data == test_data); 125 | start += 4; 126 | end else begin 127 | $write("Wrong $fscanf\n"); 128 | test_pass = 0; 129 | end 130 | end 131 | $fclose(fd); 132 | tests_total += 1; 133 | tests_passed += (test_pass & !test_error); 134 | watchdogs_cnt <= '0; 135 | if ((test_pass & !test_error)) begin 136 | $write("\033[0;32mTest passed\033[0m\n"); 137 | end else begin 138 | $write("\033[0;31mTest failed\033[0m\n"); 139 | end 140 | `endif // SIGNATURE_OUT 141 | end else begin 142 | test_running <= 1'b0; 143 | test_pass = (i_top.i_core_top.i_pipe_top.i_pipe_mprf.mprf_int[10] == 0); 144 | tests_total += 1; 145 | tests_passed += (test_pass & !test_error); 146 | watchdogs_cnt <= '0; 147 | `ifndef SIGNATURE_OUT 148 | if ((test_pass & !test_error)) begin 149 | $write("\033[0;32mTest passed\033[0m\n"); 150 | end else begin 151 | $write("\033[0;31mTest failed\033[0m\n"); 152 | end 153 | `endif //SIGNATURE_OUT 154 | end 155 | $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , ((test_pass & !test_error) ? "PASS" : "__FAIL")); 156 | end 157 | end else begin 158 | `ifdef SIGNATURE_OUT 159 | if ((s_testname.len() != 0) && (b_single_run_flag)) begin 160 | $sformat(test_file, "%s.bin", s_testname); 161 | `else // SIGNATURE_OUT 162 | if (f_info) begin 163 | `ifdef VERILATOR 164 | if ($fgets(test_file,f_info)) begin 165 | test_file = test_file >> 8; // < Removing trailing LF symbol ('\n') 166 | `else // VERILATOR 167 | if (!$feof(f_info)) begin 168 | void'($fscanf(f_info, "%s\n", test_file)); 169 | `endif // VERILATOR 170 | `endif // SIGNATURE_OUT 171 | f_test = $fopen(test_file,"r"); 172 | if (f_test != 0) begin 173 | // Launch new test 174 | `ifdef SCR1_TRACE_LOG_EN 175 | i_top.i_core_top.i_pipe_top.i_tracelog.test_name = test_file; 176 | `endif // SCR1_TRACE_LOG_EN 177 | i_memory_tb.test_file = test_file; 178 | i_memory_tb.test_file_init = 1'b1; 179 | `ifndef SIGNATURE_OUT 180 | $write("\033[0;34m---Test: %s\033[0m\n", test_file); 181 | `endif //SIGNATURE_OUT 182 | test_running <= 1'b1; 183 | rst_init <= 1'b1; 184 | `ifdef SIGNATURE_OUT 185 | b_single_run_flag = 0; 186 | `endif 187 | end else begin 188 | $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "__FAIL", "--------"); 189 | end 190 | end else begin 191 | // Exit 192 | `ifndef SIGNATURE_OUT 193 | $display("\n#--------------------------------------"); 194 | $display("# Summary: %0d/%0d tests passed", tests_passed, tests_total); 195 | $display("#--------------------------------------\n"); 196 | $fclose(f_info); 197 | $fclose(f_results); 198 | `endif 199 | $finish(); 200 | end 201 | `ifndef SIGNATURE_OUT 202 | end else begin 203 | $write("\033[0;31mError: could not open file %s\033[0m\n", s_info); 204 | $finish(); 205 | end 206 | `endif // SIGNATURE_OUT 207 | end 208 | if (watchdogs_cnt == TIMEOUT) begin 209 | if (test_file == "watchdog.hex") begin 210 | tests_total += 'b1; 211 | tests_passed += 'b1; 212 | $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , "PASS"); 213 | test_running <= '0; 214 | watchdogs_cnt <= '0; 215 | end else begin 216 | tests_total += 'b1; 217 | tests_passed += 'b0; 218 | $write("\033[0;31mError: TIMEOUT %s\033[0m\n", test_file); 219 | $fwrite(f_results, "%s\t\t%s\t%s\n", test_file, "OK" , "__FAIL"); 220 | test_running <= '0; 221 | watchdogs_cnt <= '0; 222 | end 223 | end 224 | end 225 | -------------------------------------------------------------------------------- /src/top/scr1_dmem_router.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2021. See LICENSE for details 2 | /// @file 3 | /// @brief Data memory router 4 | /// 5 | `include "scr1_memif.svh" 6 | `include "scr1_arch_description.svh" 7 | 8 | module scr1_dmem_router 9 | #( 10 | parameter SCR1_PORT1_ADDR_MASK = `SCR1_DMEM_AWIDTH'hFFFF0000, 11 | parameter SCR1_PORT1_ADDR_PATTERN = `SCR1_DMEM_AWIDTH'h00010000, 12 | parameter SCR1_PORT2_ADDR_MASK = `SCR1_DMEM_AWIDTH'hFFFF0000, 13 | parameter SCR1_PORT2_ADDR_PATTERN = `SCR1_DMEM_AWIDTH'h00020000 14 | ) 15 | ( 16 | // Control signals 17 | input logic rst_n, 18 | input logic clk, 19 | 20 | // Core interface 21 | output logic dmem_req_ack, 22 | input logic dmem_req, 23 | input type_scr1_mem_cmd_e dmem_cmd, 24 | input type_scr1_mem_width_e dmem_width, 25 | input logic [`SCR1_DMEM_AWIDTH-1:0] dmem_addr, 26 | input logic [`SCR1_DMEM_DWIDTH-1:0] dmem_wdata, 27 | output logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata, 28 | output type_scr1_mem_resp_e dmem_resp, 29 | 30 | // PORT0 interface 31 | input logic port0_req_ack, 32 | output logic port0_req, 33 | output type_scr1_mem_cmd_e port0_cmd, 34 | output type_scr1_mem_width_e port0_width, 35 | output logic [`SCR1_DMEM_AWIDTH-1:0] port0_addr, 36 | output logic [`SCR1_DMEM_DWIDTH-1:0] port0_wdata, 37 | input logic [`SCR1_DMEM_DWIDTH-1:0] port0_rdata, 38 | input type_scr1_mem_resp_e port0_resp, 39 | 40 | // PORT1 interface 41 | input logic port1_req_ack, 42 | output logic port1_req, 43 | output type_scr1_mem_cmd_e port1_cmd, 44 | output type_scr1_mem_width_e port1_width, 45 | output logic [`SCR1_DMEM_AWIDTH-1:0] port1_addr, 46 | output logic [`SCR1_DMEM_DWIDTH-1:0] port1_wdata, 47 | input logic [`SCR1_DMEM_DWIDTH-1:0] port1_rdata, 48 | input type_scr1_mem_resp_e port1_resp, 49 | 50 | // PORT2 interface 51 | input logic port2_req_ack, 52 | output logic port2_req, 53 | output type_scr1_mem_cmd_e port2_cmd, 54 | output type_scr1_mem_width_e port2_width, 55 | output logic [`SCR1_DMEM_AWIDTH-1:0] port2_addr, 56 | output logic [`SCR1_DMEM_DWIDTH-1:0] port2_wdata, 57 | input logic [`SCR1_DMEM_DWIDTH-1:0] port2_rdata, 58 | input type_scr1_mem_resp_e port2_resp 59 | ); 60 | 61 | //------------------------------------------------------------------------------- 62 | // Local types declaration 63 | //------------------------------------------------------------------------------- 64 | typedef enum logic { 65 | SCR1_FSM_ADDR, 66 | SCR1_FSM_DATA 67 | } type_scr1_fsm_e; 68 | 69 | typedef enum logic [1:0] { 70 | SCR1_SEL_PORT0, 71 | SCR1_SEL_PORT1, 72 | SCR1_SEL_PORT2 73 | } type_scr1_sel_e; 74 | 75 | //------------------------------------------------------------------------------- 76 | // Local signal declaration 77 | //------------------------------------------------------------------------------- 78 | type_scr1_fsm_e fsm; 79 | type_scr1_sel_e port_sel; 80 | type_scr1_sel_e port_sel_r; 81 | logic [`SCR1_DMEM_DWIDTH-1:0] sel_rdata; 82 | type_scr1_mem_resp_e sel_resp; 83 | logic sel_req_ack; 84 | 85 | //------------------------------------------------------------------------------- 86 | // FSM 87 | //------------------------------------------------------------------------------- 88 | always_comb begin 89 | port_sel = SCR1_SEL_PORT0; 90 | if ((dmem_addr & SCR1_PORT1_ADDR_MASK) == SCR1_PORT1_ADDR_PATTERN) begin 91 | port_sel = SCR1_SEL_PORT1; 92 | end else if ((dmem_addr & SCR1_PORT2_ADDR_MASK) == SCR1_PORT2_ADDR_PATTERN) begin 93 | port_sel = SCR1_SEL_PORT2; 94 | end 95 | end 96 | 97 | always_ff @(negedge rst_n, posedge clk) begin 98 | if (~rst_n) begin 99 | fsm <= SCR1_FSM_ADDR; 100 | port_sel_r <= SCR1_SEL_PORT0; 101 | end else begin 102 | case (fsm) 103 | SCR1_FSM_ADDR : begin 104 | if (dmem_req & sel_req_ack) begin 105 | fsm <= SCR1_FSM_DATA; 106 | port_sel_r <= port_sel; 107 | end 108 | end 109 | SCR1_FSM_DATA : begin 110 | case (sel_resp) 111 | SCR1_MEM_RESP_RDY_OK : begin 112 | if (dmem_req & sel_req_ack) begin 113 | fsm <= SCR1_FSM_DATA; 114 | port_sel_r <= port_sel; 115 | end else begin 116 | fsm <= SCR1_FSM_ADDR; 117 | end 118 | end 119 | SCR1_MEM_RESP_RDY_ER : begin 120 | fsm <= SCR1_FSM_ADDR; 121 | end 122 | default : begin 123 | end 124 | endcase 125 | end 126 | default : begin 127 | end 128 | endcase 129 | end 130 | end 131 | 132 | always_comb begin 133 | if ((fsm == SCR1_FSM_ADDR) | ((fsm == SCR1_FSM_DATA) & (sel_resp == SCR1_MEM_RESP_RDY_OK))) begin 134 | case (port_sel) 135 | SCR1_SEL_PORT0 : sel_req_ack = port0_req_ack; 136 | SCR1_SEL_PORT1 : sel_req_ack = port1_req_ack; 137 | SCR1_SEL_PORT2 : sel_req_ack = port2_req_ack; 138 | default : sel_req_ack = 1'b0; 139 | endcase 140 | end else begin 141 | sel_req_ack = 1'b0; 142 | end 143 | end 144 | 145 | always_comb begin 146 | case (port_sel_r) 147 | SCR1_SEL_PORT0 : begin 148 | sel_rdata = port0_rdata; 149 | sel_resp = port0_resp; 150 | end 151 | SCR1_SEL_PORT1 : begin 152 | sel_rdata = port1_rdata; 153 | sel_resp = port1_resp; 154 | end 155 | SCR1_SEL_PORT2 : begin 156 | sel_rdata = port2_rdata; 157 | sel_resp = port2_resp; 158 | end 159 | default : begin 160 | sel_rdata = '0; 161 | sel_resp = SCR1_MEM_RESP_RDY_ER; 162 | end 163 | endcase 164 | end 165 | 166 | //------------------------------------------------------------------------------- 167 | // Interface to core 168 | //------------------------------------------------------------------------------- 169 | assign dmem_req_ack = sel_req_ack; 170 | assign dmem_rdata = sel_rdata; 171 | assign dmem_resp = sel_resp; 172 | 173 | //------------------------------------------------------------------------------- 174 | // Interface to PORT0 175 | //------------------------------------------------------------------------------- 176 | always_comb begin 177 | port0_req = 1'b0; 178 | case (fsm) 179 | SCR1_FSM_ADDR : begin 180 | port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0); 181 | end 182 | SCR1_FSM_DATA : begin 183 | if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin 184 | port0_req = dmem_req & (port_sel == SCR1_SEL_PORT0); 185 | end 186 | end 187 | default : begin 188 | end 189 | endcase 190 | end 191 | 192 | `ifdef SCR1_XPROP_EN 193 | assign port0_cmd = (port_sel == SCR1_SEL_PORT0) ? dmem_cmd : SCR1_MEM_CMD_ERROR; 194 | assign port0_width = (port_sel == SCR1_SEL_PORT0) ? dmem_width : SCR1_MEM_WIDTH_ERROR; 195 | assign port0_addr = (port_sel == SCR1_SEL_PORT0) ? dmem_addr : 'x; 196 | assign port0_wdata = (port_sel == SCR1_SEL_PORT0) ? dmem_wdata : 'x; 197 | `else // SCR1_XPROP_EN 198 | assign port0_cmd = dmem_cmd ; 199 | assign port0_width = dmem_width; 200 | assign port0_addr = dmem_addr ; 201 | assign port0_wdata = dmem_wdata; 202 | `endif // SCR1_XPROP_EN 203 | 204 | //------------------------------------------------------------------------------- 205 | // Interface to PORT1 206 | //------------------------------------------------------------------------------- 207 | always_comb begin 208 | port1_req = 1'b0; 209 | case (fsm) 210 | SCR1_FSM_ADDR : begin 211 | port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1); 212 | end 213 | SCR1_FSM_DATA : begin 214 | if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin 215 | port1_req = dmem_req & (port_sel == SCR1_SEL_PORT1); 216 | end 217 | end 218 | default : begin 219 | end 220 | endcase 221 | end 222 | 223 | `ifdef SCR1_XPROP_EN 224 | assign port1_cmd = (port_sel == SCR1_SEL_PORT1) ? dmem_cmd : SCR1_MEM_CMD_ERROR; 225 | assign port1_width = (port_sel == SCR1_SEL_PORT1) ? dmem_width : SCR1_MEM_WIDTH_ERROR; 226 | assign port1_addr = (port_sel == SCR1_SEL_PORT1) ? dmem_addr : 'x; 227 | assign port1_wdata = (port_sel == SCR1_SEL_PORT1) ? dmem_wdata : 'x; 228 | `else // SCR1_XPROP_EN 229 | assign port1_cmd = dmem_cmd ; 230 | assign port1_width = dmem_width; 231 | assign port1_addr = dmem_addr ; 232 | assign port1_wdata = dmem_wdata; 233 | `endif // SCR1_XPROP_EN 234 | 235 | //------------------------------------------------------------------------------- 236 | // Interface to PORT2 237 | //------------------------------------------------------------------------------- 238 | always_comb begin 239 | port2_req = 1'b0; 240 | case (fsm) 241 | SCR1_FSM_ADDR : begin 242 | port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2); 243 | end 244 | SCR1_FSM_DATA : begin 245 | if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin 246 | port2_req = dmem_req & (port_sel == SCR1_SEL_PORT2); 247 | end 248 | end 249 | default : begin 250 | end 251 | endcase 252 | end 253 | 254 | `ifdef SCR1_XPROP_EN 255 | assign port2_cmd = (port_sel == SCR1_SEL_PORT2) ? dmem_cmd : SCR1_MEM_CMD_ERROR; 256 | assign port2_width = (port_sel == SCR1_SEL_PORT2) ? dmem_width : SCR1_MEM_WIDTH_ERROR; 257 | assign port2_addr = (port_sel == SCR1_SEL_PORT2) ? dmem_addr : 'x; 258 | assign port2_wdata = (port_sel == SCR1_SEL_PORT2) ? dmem_wdata : 'x; 259 | `else // SCR1_XPROP_EN 260 | assign port2_cmd = dmem_cmd ; 261 | assign port2_width = dmem_width; 262 | assign port2_addr = dmem_addr ; 263 | assign port2_wdata = dmem_wdata; 264 | `endif // SCR1_XPROP_EN 265 | 266 | `ifdef SCR1_TRGT_SIMULATION 267 | //------------------------------------------------------------------------------- 268 | // Assertion 269 | //------------------------------------------------------------------------------- 270 | 271 | SCR1_SVA_DMEM_RT_XCHECK : assert property ( 272 | @(negedge clk) disable iff (~rst_n) 273 | dmem_req |-> !$isunknown({port_sel, dmem_cmd, dmem_width}) 274 | ) else $error("DMEM router Error: unknown values"); 275 | 276 | `endif // SCR1_TRGT_SIMULATION 277 | 278 | endmodule : scr1_dmem_router 279 | -------------------------------------------------------------------------------- /src/top/scr1_dp_memory.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details 2 | /// @file 3 | /// @brief Dual-port synchronous memory with byte enable inputs 4 | /// 5 | 6 | `include "scr1_arch_description.svh" 7 | 8 | `ifdef SCR1_TCM_EN 9 | module scr1_dp_memory 10 | #( 11 | parameter SCR1_WIDTH = 32, 12 | parameter SCR1_SIZE = `SCR1_IMEM_AWIDTH'h00010000, 13 | parameter SCR1_NBYTES = SCR1_WIDTH / 8 14 | ) 15 | ( 16 | input logic clk, 17 | // Port A 18 | input logic rena, 19 | input logic [$clog2(SCR1_SIZE)-1:2] addra, 20 | output logic [SCR1_WIDTH-1:0] qa, 21 | // Port B 22 | input logic renb, 23 | input logic wenb, 24 | input logic [SCR1_NBYTES-1:0] webb, 25 | input logic [$clog2(SCR1_SIZE)-1:2] addrb, 26 | input logic [SCR1_WIDTH-1:0] datab, 27 | output logic [SCR1_WIDTH-1:0] qb 28 | ); 29 | 30 | `ifdef SCR1_TRGT_FPGA_INTEL 31 | //------------------------------------------------------------------------------- 32 | // Local signal declaration 33 | //------------------------------------------------------------------------------- 34 | `ifdef SCR1_TRGT_FPGA_INTEL_MAX10 35 | (* ramstyle = "M9K" *) logic [SCR1_NBYTES-1:0][7:0] memory_array [0:(SCR1_SIZE/SCR1_NBYTES)-1]; 36 | `elsif SCR1_TRGT_FPGA_INTEL_ARRIAV 37 | (* ramstyle = "M10K" *) logic [SCR1_NBYTES-1:0][7:0] memory_array [0:(SCR1_SIZE/SCR1_NBYTES)-1]; 38 | `endif 39 | logic [3:0] wenbb; 40 | //------------------------------------------------------------------------------- 41 | // Port B memory behavioral description 42 | //------------------------------------------------------------------------------- 43 | assign wenbb = {4{wenb}} & webb; 44 | always_ff @(posedge clk) begin 45 | if (wenb) begin 46 | if (wenbb[0]) begin 47 | memory_array[addrb][0] <= datab[0+:8]; 48 | end 49 | if (wenbb[1]) begin 50 | memory_array[addrb][1] <= datab[8+:8]; 51 | end 52 | if (wenbb[2]) begin 53 | memory_array[addrb][2] <= datab[16+:8]; 54 | end 55 | if (wenbb[3]) begin 56 | memory_array[addrb][3] <= datab[24+:8]; 57 | end 58 | end 59 | qb <= memory_array[addrb]; 60 | end 61 | //------------------------------------------------------------------------------- 62 | // Port A memory behavioral description 63 | //------------------------------------------------------------------------------- 64 | always_ff @(posedge clk) begin 65 | qa <= memory_array[addra]; 66 | end 67 | 68 | `else // SCR1_TRGT_FPGA_INTEL 69 | 70 | // CASE: OTHERS - SCR1_TRGT_FPGA_XILINX, SIMULATION, ASIC etc 71 | 72 | localparam int unsigned RAM_SIZE_WORDS = SCR1_SIZE/SCR1_NBYTES; 73 | 74 | //------------------------------------------------------------------------------- 75 | // Local signal declaration 76 | //------------------------------------------------------------------------------- 77 | `ifdef SCR1_TRGT_FPGA_XILINX 78 | (* ram_style = "block" *) logic [SCR1_WIDTH-1:0] ram_block [RAM_SIZE_WORDS-1:0]; 79 | `else // ASIC or SIMULATION 80 | logic [SCR1_WIDTH-1:0] ram_block [RAM_SIZE_WORDS-1:0]; 81 | `endif 82 | //------------------------------------------------------------------------------- 83 | // Port A memory behavioral description 84 | //------------------------------------------------------------------------------- 85 | always_ff @(posedge clk) begin 86 | if (rena) begin 87 | qa <= ram_block[addra]; 88 | end 89 | end 90 | 91 | //------------------------------------------------------------------------------- 92 | // Port B memory behavioral description 93 | //------------------------------------------------------------------------------- 94 | always_ff @(posedge clk) begin 95 | if (wenb) begin 96 | for (int i=0; i 3 | /// @brief Instruction memory router 4 | /// 5 | `include "scr1_memif.svh" 6 | `include "scr1_arch_description.svh" 7 | 8 | module scr1_imem_router 9 | #( 10 | parameter SCR1_ADDR_MASK = `SCR1_IMEM_AWIDTH'hFFFF0000, 11 | parameter SCR1_ADDR_PATTERN = `SCR1_IMEM_AWIDTH'h00010000 12 | ) 13 | ( 14 | // Control signals 15 | input logic rst_n, 16 | input logic clk, 17 | 18 | // Core interface 19 | output logic imem_req_ack, 20 | input logic imem_req, 21 | input type_scr1_mem_cmd_e imem_cmd, 22 | input logic [`SCR1_IMEM_AWIDTH-1:0] imem_addr, 23 | output logic [`SCR1_IMEM_DWIDTH-1:0] imem_rdata, 24 | output type_scr1_mem_resp_e imem_resp, 25 | 26 | // PORT0 interface 27 | input logic port0_req_ack, 28 | output logic port0_req, 29 | output type_scr1_mem_cmd_e port0_cmd, 30 | output logic [`SCR1_IMEM_AWIDTH-1:0] port0_addr, 31 | input logic [`SCR1_IMEM_DWIDTH-1:0] port0_rdata, 32 | input type_scr1_mem_resp_e port0_resp, 33 | 34 | // PORT1 interface 35 | input logic port1_req_ack, 36 | output logic port1_req, 37 | output type_scr1_mem_cmd_e port1_cmd, 38 | output logic [`SCR1_IMEM_AWIDTH-1:0] port1_addr, 39 | input logic [`SCR1_IMEM_DWIDTH-1:0] port1_rdata, 40 | input type_scr1_mem_resp_e port1_resp 41 | ); 42 | 43 | //------------------------------------------------------------------------------- 44 | // Local types declaration 45 | //------------------------------------------------------------------------------- 46 | typedef enum logic { 47 | SCR1_FSM_ADDR, 48 | SCR1_FSM_DATA 49 | } type_scr1_fsm_e; 50 | 51 | //------------------------------------------------------------------------------- 52 | // Local signal declaration 53 | //------------------------------------------------------------------------------- 54 | type_scr1_fsm_e fsm; 55 | logic port_sel; 56 | logic port_sel_r; 57 | logic [`SCR1_IMEM_DWIDTH-1:0] sel_rdata; 58 | type_scr1_mem_resp_e sel_resp; 59 | logic sel_req_ack; 60 | 61 | //------------------------------------------------------------------------------- 62 | // FSM 63 | //------------------------------------------------------------------------------- 64 | assign port_sel = ((imem_addr & SCR1_ADDR_MASK) == SCR1_ADDR_PATTERN); 65 | 66 | always_ff @(negedge rst_n, posedge clk) begin 67 | if (~rst_n) begin 68 | fsm <= SCR1_FSM_ADDR; 69 | port_sel_r <= 1'b0; 70 | end else begin 71 | case (fsm) 72 | SCR1_FSM_ADDR : begin 73 | if (imem_req & sel_req_ack) begin 74 | fsm <= SCR1_FSM_DATA; 75 | port_sel_r <= port_sel; 76 | end 77 | end 78 | SCR1_FSM_DATA : begin 79 | case (sel_resp) 80 | SCR1_MEM_RESP_RDY_OK : begin 81 | if (imem_req & sel_req_ack) begin 82 | fsm <= SCR1_FSM_DATA; 83 | port_sel_r <= port_sel; 84 | end else begin 85 | fsm <= SCR1_FSM_ADDR; 86 | end 87 | end 88 | SCR1_MEM_RESP_RDY_ER : begin 89 | fsm <= SCR1_FSM_ADDR; 90 | end 91 | default : begin 92 | end 93 | endcase 94 | end 95 | default : begin 96 | end 97 | endcase 98 | end 99 | end 100 | 101 | always_comb begin 102 | if ((fsm == SCR1_FSM_ADDR) | ((fsm == SCR1_FSM_DATA) & (sel_resp == SCR1_MEM_RESP_RDY_OK))) begin 103 | sel_req_ack = (port_sel) ? port1_req_ack : port0_req_ack; 104 | end else begin 105 | sel_req_ack = 1'b0; 106 | end 107 | end 108 | 109 | assign sel_rdata = (port_sel_r) ? port1_rdata : port0_rdata; 110 | assign sel_resp = (port_sel_r) ? port1_resp : port0_resp; 111 | 112 | //------------------------------------------------------------------------------- 113 | // Interface to core 114 | //------------------------------------------------------------------------------- 115 | assign imem_req_ack = sel_req_ack; 116 | assign imem_rdata = sel_rdata; 117 | assign imem_resp = sel_resp; 118 | 119 | //------------------------------------------------------------------------------- 120 | // Interface to PORT0 121 | //------------------------------------------------------------------------------- 122 | always_comb begin 123 | port0_req = 1'b0; 124 | case (fsm) 125 | SCR1_FSM_ADDR : begin 126 | port0_req = imem_req & ~port_sel; 127 | end 128 | SCR1_FSM_DATA : begin 129 | if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin 130 | port0_req = imem_req & ~port_sel; 131 | end 132 | end 133 | default : begin 134 | end 135 | endcase 136 | end 137 | 138 | `ifdef SCR1_XPROP_EN 139 | assign port0_cmd = (~port_sel) ? imem_cmd : SCR1_MEM_CMD_ERROR; 140 | assign port0_addr = (~port_sel) ? imem_addr : 'x; 141 | `else // SCR1_XPROP_EN 142 | assign port0_cmd = imem_cmd ; 143 | assign port0_addr = imem_addr; 144 | `endif // SCR1_XPROP_EN 145 | 146 | //------------------------------------------------------------------------------- 147 | // Interface to PORT1 148 | //------------------------------------------------------------------------------- 149 | always_comb begin 150 | port1_req = 1'b0; 151 | case (fsm) 152 | SCR1_FSM_ADDR : begin 153 | port1_req = imem_req & port_sel; 154 | end 155 | SCR1_FSM_DATA : begin 156 | if (sel_resp == SCR1_MEM_RESP_RDY_OK) begin 157 | port1_req = imem_req & port_sel; 158 | end 159 | end 160 | default : begin 161 | end 162 | endcase 163 | end 164 | 165 | `ifdef SCR1_XPROP_EN 166 | assign port1_cmd = (port_sel) ? imem_cmd : SCR1_MEM_CMD_ERROR; 167 | assign port1_addr = (port_sel) ? imem_addr : 'x; 168 | `else // SCR1_XPROP_EN 169 | assign port1_cmd = imem_cmd ; 170 | assign port1_addr = imem_addr; 171 | `endif // SCR1_XPROP_EN 172 | 173 | `ifdef SCR1_TRGT_SIMULATION 174 | //------------------------------------------------------------------------------- 175 | // Assertion 176 | //------------------------------------------------------------------------------- 177 | 178 | SCR1_SVA_IMEM_RT_XCHECK : assert property ( 179 | @(negedge clk) disable iff (~rst_n) 180 | imem_req |-> !$isunknown({port_sel, imem_cmd}) 181 | ) else $error("IMEM router Error: unknown values"); 182 | 183 | `endif // SCR1_TRGT_SIMULATION 184 | 185 | endmodule : scr1_imem_router 186 | -------------------------------------------------------------------------------- /src/top/scr1_tcm.sv: -------------------------------------------------------------------------------- 1 | /// Copyright by Syntacore LLC © 2016-2020. See LICENSE for details 2 | /// @file 3 | /// @brief Tightly-Coupled Memory (TCM) 4 | /// 5 | 6 | `include "scr1_memif.svh" 7 | `include "scr1_arch_description.svh" 8 | 9 | `ifdef SCR1_TCM_EN 10 | module scr1_tcm 11 | #( 12 | parameter SCR1_TCM_SIZE = `SCR1_IMEM_AWIDTH'h00010000 13 | ) 14 | ( 15 | // Control signals 16 | input logic clk, 17 | input logic rst_n, 18 | 19 | // Core instruction interface 20 | output logic imem_req_ack, 21 | input logic imem_req, 22 | input logic [`SCR1_IMEM_AWIDTH-1:0] imem_addr, 23 | output logic [`SCR1_IMEM_DWIDTH-1:0] imem_rdata, 24 | output type_scr1_mem_resp_e imem_resp, 25 | 26 | // Core data interface 27 | output logic dmem_req_ack, 28 | input logic dmem_req, 29 | input type_scr1_mem_cmd_e dmem_cmd, 30 | input type_scr1_mem_width_e dmem_width, 31 | input logic [`SCR1_DMEM_AWIDTH-1:0] dmem_addr, 32 | input logic [`SCR1_DMEM_DWIDTH-1:0] dmem_wdata, 33 | output logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata, 34 | output type_scr1_mem_resp_e dmem_resp 35 | ); 36 | 37 | //------------------------------------------------------------------------------- 38 | // Local signal declaration 39 | //------------------------------------------------------------------------------- 40 | logic imem_req_en; 41 | logic dmem_req_en; 42 | logic imem_rd; 43 | logic dmem_rd; 44 | logic dmem_wr; 45 | logic [`SCR1_DMEM_DWIDTH-1:0] dmem_writedata; 46 | logic [`SCR1_DMEM_DWIDTH-1:0] dmem_rdata_local; 47 | logic [3:0] dmem_byteen; 48 | logic [1:0] dmem_rdata_shift_reg; 49 | //------------------------------------------------------------------------------- 50 | // Core interface 51 | //------------------------------------------------------------------------------- 52 | assign imem_req_en = (imem_resp == SCR1_MEM_RESP_RDY_OK) ^ imem_req; 53 | assign dmem_req_en = (dmem_resp == SCR1_MEM_RESP_RDY_OK) ^ dmem_req; 54 | 55 | always_ff @(posedge clk, negedge rst_n) begin 56 | if (~rst_n) begin 57 | imem_resp <= SCR1_MEM_RESP_NOTRDY; 58 | end else if (imem_req_en) begin 59 | imem_resp <= imem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY; 60 | end 61 | end 62 | 63 | always_ff @(posedge clk, negedge rst_n) begin 64 | if (~rst_n) begin 65 | dmem_resp <= SCR1_MEM_RESP_NOTRDY; 66 | end else if (dmem_req_en) begin 67 | dmem_resp <= dmem_req ? SCR1_MEM_RESP_RDY_OK : SCR1_MEM_RESP_NOTRDY; 68 | end 69 | end 70 | 71 | assign imem_req_ack = 1'b1; 72 | assign dmem_req_ack = 1'b1; 73 | //------------------------------------------------------------------------------- 74 | // Memory data composing 75 | //------------------------------------------------------------------------------- 76 | assign imem_rd = imem_req; 77 | assign dmem_rd = dmem_req & (dmem_cmd == SCR1_MEM_CMD_RD); 78 | assign dmem_wr = dmem_req & (dmem_cmd == SCR1_MEM_CMD_WR); 79 | 80 | always_comb begin 81 | dmem_writedata = dmem_wdata; 82 | dmem_byteen = 4'b1111; 83 | case ( dmem_width ) 84 | SCR1_MEM_WIDTH_BYTE : begin 85 | dmem_writedata = {(`SCR1_DMEM_DWIDTH / 8){dmem_wdata[7:0]}}; 86 | dmem_byteen = 4'b0001 << dmem_addr[1:0]; 87 | end 88 | SCR1_MEM_WIDTH_HWORD : begin 89 | dmem_writedata = {(`SCR1_DMEM_DWIDTH / 16){dmem_wdata[15:0]}}; 90 | dmem_byteen = 4'b0011 << {dmem_addr[1], 1'b0}; 91 | end 92 | default : begin 93 | end 94 | endcase 95 | end 96 | //------------------------------------------------------------------------------- 97 | // Memory instantiation 98 | //------------------------------------------------------------------------------- 99 | scr1_dp_memory #( 100 | .SCR1_WIDTH ( 32 ), 101 | .SCR1_SIZE ( SCR1_TCM_SIZE ) 102 | ) i_dp_memory ( 103 | .clk ( clk ), 104 | // Instruction port 105 | // Port A 106 | .rena ( imem_rd ), 107 | .addra ( imem_addr[$clog2(SCR1_TCM_SIZE)-1:2] ), 108 | .qa ( imem_rdata ), 109 | // Data port 110 | // Port B 111 | .renb ( dmem_rd ), 112 | .wenb ( dmem_wr ), 113 | .webb ( dmem_byteen ), 114 | .addrb ( dmem_addr[$clog2(SCR1_TCM_SIZE)-1:2] ), 115 | .qb ( dmem_rdata_local ), 116 | .datab ( dmem_writedata ) 117 | ); 118 | //------------------------------------------------------------------------------- 119 | // Data memory output generation 120 | //------------------------------------------------------------------------------- 121 | always_ff @(posedge clk) begin 122 | if (dmem_rd) begin 123 | dmem_rdata_shift_reg <= dmem_addr[1:0]; 124 | end 125 | end 126 | 127 | assign dmem_rdata = dmem_rdata_local >> ( 8 * dmem_rdata_shift_reg ); 128 | 129 | endmodule : scr1_tcm 130 | 131 | `endif // SCR1_TCM_EN 132 | --------------------------------------------------------------------------------