├── .gitignore ├── .gitmodules ├── LICENSE ├── Makefrag ├── Makefrag-variables ├── README.md ├── build.sbt ├── project ├── build.properties └── plugins.sbt ├── scripts ├── check_commit_log └── init-submodules ├── src └── main │ ├── resources │ └── project-template │ │ └── csrc │ │ └── emulator.cc │ └── scala │ └── example │ ├── Configs.scala │ ├── PWM.scala │ ├── Simulator.scala │ ├── TestHarness.scala │ └── Top.scala ├── tests ├── .gitignore ├── Makefile ├── accum.c ├── blkdev.c ├── charcount.c ├── crt.S ├── encoding.h ├── link.ld ├── mmio.h ├── nic.h ├── pwm.c ├── rocc.h ├── syscalls.c └── util.h ├── verisim ├── .gitignore ├── Makefile └── Makefrag-verilator └── vsim ├── .gitignore └── Makefile /.gitignore: -------------------------------------------------------------------------------- 1 | bootrom 2 | /Makefrag.pkgs 3 | target 4 | *.jar 5 | *.stamp 6 | .*.swp 7 | /vsim 8 | /verisim/generated-src* 9 | /verisim/simulator-* 10 | /verisim/verilator 11 | simv* 12 | *.vcd 13 | .DS_Store 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "rocket-chip"] 2 | path = rocket-chip 3 | url = https://github.com/ucb-bar/rocket-chip.git 4 | [submodule "testchipip"] 5 | path = testchipip 6 | url = https://github.com/ucb-bar/testchipip.git 7 | [submodule "hwacha"] 8 | path = hwacha 9 | url = https://github.com/ucb-bar/hwacha.git 10 | [submodule "esp-tools"] 11 | path = riscv-tools 12 | url = https://github.com/ucb-bar/esp-tools.git 13 | [submodule "torture"] 14 | path = torture 15 | url = https://github.com/ucb-bar/riscv-torture.git 16 | branch = hwacha 17 | [submodule "barstools"] 18 | path = barstools 19 | url = https://github.com/ucb-bar/barstools.git 20 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017, 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 | 7 | 1. Redistributions of source code must retain the above copyright 8 | notice, this list of conditions and the following disclaimer. 9 | 10 | 2. Redistributions in binary form must reproduce the above copyright 11 | notice, this list of conditions and the following disclaimer in the 12 | documentation and/or other materials provided with the distribution. 13 | 14 | 3. Neither the name of the Regents nor the 15 | names of its contributors may be used to endorse or promote products 16 | derived from this software without specific prior written permission. 17 | 18 | IN NO EVENT SHALL REGENTS BE LIABLE TO ANY PARTY FOR DIRECT, INDIRECT, 19 | SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES, INCLUDING LOST PROFITS, ARISING 20 | OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN IF REGENTS HAS 21 | BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 22 | 23 | REGENTS SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, BUT NOT LIMITED TO, 24 | THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 25 | PURPOSE. THE SOFTWARE AND ACCOMPANYING DOCUMENTATION, IF ANY, PROVIDED 26 | HEREUNDER IS PROVIDED "AS IS". REGENTS HAS NO OBLIGATION TO PROVIDE 27 | MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 28 | -------------------------------------------------------------------------------- /Makefrag: -------------------------------------------------------------------------------- 1 | ROCKETCHIP_DIR=$(base_dir)/rocket-chip 2 | TESTCHIP_DIR = $(base_dir)/testchipip 3 | 4 | SBT ?= java -Xmx$(JVM_HEAP_SIZE) -Xss8M -XX:MaxPermSize=256M -jar $(ROCKETCHIP_DIR)/sbt-launch.jar ++$(SCALA_VERSION) 5 | 6 | lookup_scala_srcs = $(shell find $(1)/ -iname "*.scala" 2> /dev/null) 7 | 8 | PACKAGES=rocket-chip testchipip barstools hwacha 9 | SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/$(pkg)/src/main/scala)) $(call lookup_scala_srcs,$(base_dir)/src/main/scala) 10 | 11 | ROCKET_CLASSES ?= "$(ROCKETCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes:$(ROCKETCHIP_DIR)/chisel3/target/scala-$(SCALA_VERSION_MAJOR)/*" 12 | TESTCHIPIP_CLASSES ?= "$(TESTCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes" 13 | FIRRTL_JAR ?= $(ROCKETCHIP_DIR)/lib/firrtl.jar 14 | 15 | $(FIRRTL_JAR): $(call lookup_scala_srcs, $(ROCKETCHIP_DIR)/firrtl/src/main/scala) 16 | $(MAKE) -C $(ROCKETCHIP_DIR)/firrtl SBT="$(SBT)" root_dir=$(ROCKETCHIP_DIR)/firrtl build-scala 17 | mkdir -p $(dir $@) 18 | cp -p $(ROCKETCHIP_DIR)/firrtl/utils/bin/firrtl.jar $@ 19 | touch $@ 20 | 21 | build_dir=$(sim_dir)/generated-src 22 | 23 | CHISEL_ARGS ?= 24 | 25 | $(sim_dotf): $(SCALA_SOURCES) $(FIRRTL_JAR) 26 | cd $(base_dir) && $(SBT) "runMain example.GenerateSimFiles -td $(build_dir) -sim $(sim_name)" 27 | 28 | .PHONY: firrtl 29 | firrtl: $(FIRRTL_FILE) 30 | 31 | $(FIRRTL_FILE) $(ANNO_FILE): $(SCALA_SOURCES) $(sim_dotf) 32 | mkdir -p $(build_dir) 33 | cd $(base_dir) && $(SBT) "runMain $(GENERATOR_PROJECT).Generator $(CHISEL_ARGS) $(build_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)" 34 | 35 | .PHONY: top-v 36 | top-v: $(VERILOG_FILE) 37 | 38 | $(VERILOG_FILE) $(SMEMS_CONF) $(TOP_ANNO) $(TOP_FIR) $(sim_top_blackboxes): $(FIRRTL_FILE) $(ANNO_FILE) 39 | cd $(base_dir) && $(SBT) "project tapeout" "runMain barstools.tapeout.transforms.GenerateTop -o $(VERILOG_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(MODEL) -faf $(ANNO_FILE) -tsaof $(TOP_ANNO) -tsf $(TOP_FIR) $(REPL_SEQ_MEM) -td $(build_dir)" 40 | cp $(build_dir)/firrtl_black_box_resource_files.f $(sim_top_blackboxes) 41 | 42 | $(HARNESS_FILE) $(HARNESS_ANNO) $(HARNESS_FIR) $(sim_harness_blackboxes): $(FIRRTL_FILE) $(ANNO_FILE) $(sim_top_blackboxes) 43 | cd $(base_dir) && $(SBT) "project tapeout" "runMain barstools.tapeout.transforms.GenerateHarness -o $(HARNESS_FILE) -i $(FIRRTL_FILE) --syn-top $(TOP) --harness-top $(MODEL) -faf $(ANNO_FILE) -thaof $(HARNESS_ANNO) -thf $(HARNESS_FIR) $(HARNESS_REPL_SEQ_MEM) -td $(build_dir)" 44 | grep -v "SimSerial.cc\|SimDTM.cc\|SimJTAG.cc" $(build_dir)/firrtl_black_box_resource_files.f > $(sim_harness_blackboxes) 45 | 46 | # This file is for simulation only. VLSI flows should replace this file with one containing hard SRAMs 47 | MACROCOMPILER_MODE ?= --mode synflops 48 | $(SMEMS_FILE) $(SMEMS_FIR): $(SMEMS_CONF) 49 | cd $(base_dir) && $(SBT) "project barstools-macros" "runMain barstools.macros.MacroCompiler -n $(SMEMS_CONF) -v $(SMEMS_FILE) -f $(SMEMS_FIR) $(MACROCOMPILER_MODE)" 50 | 51 | HARNESS_MACROCOMPILER_MODE = --mode synflops 52 | $(HARNESS_SMEMS_FILE) $(HARNESS_SMEMS_FIR): $(HARNESS_SMEMS_CONF) 53 | cd $(base_dir) && $(SBT) "project barstools-macros" "runMain barstools.macros.MacroCompiler -n $(HARNESS_SMEMS_CONF) -v $(HARNESS_SMEMS_FILE) -f $(HARNESS_SMEMS_FIR) $(HARNESS_MACROCOMPILER_MODE)" 54 | 55 | output_dir=$(sim_dir)/output 56 | 57 | # Assembly/Benchmark Testing 58 | .PRECIOUS: $(output_dir)/%.vpd $(output_dir)/%.vcd 59 | 60 | perm_off = $(if $(findstring +permissive,$(exec_sim)),+permissive-off,) 61 | 62 | $(output_dir)/%.run: $(output_dir)/% $(sim) 63 | cd $(sim_dir) && $(exec_sim) +max-cycles=$(timeout_cycles) $(perm_off) $< 2> /dev/null 2> $@ && [ $$PIPESTATUS -eq 0 ] 64 | 65 | $(output_dir)/%.out: $(output_dir)/% $(sim) 66 | cd $(sim_dir) && $(exec_sim) +verbose +max-cycles=$(timeout_cycles) $(perm_off) $< $(disasm) $@ && [ $$PIPESTATUS -eq 0 ] 67 | 68 | run-regression-tests: $(addprefix $(output_dir)/,$(addsuffix .out,$(regression-tests))) 69 | 70 | run-regression-tests-fast: $(addprefix $(output_dir)/,$(addsuffix .run,$(regression-tests))) 71 | 72 | run-regression-tests-debug: $(addprefix $(output_dir)/,$(addsuffix .vpd,$(regression-tests))) 73 | 74 | run: run-asm-tests run-bmark-tests 75 | run-debug: run-asm-tests-debug run-bmark-tests-debug 76 | run-fast: run-asm-tests-fast run-bmark-tests-fast 77 | 78 | .PHONY: run-asm-tests run-bmark-tests 79 | .PHONY: run-asm-tests-debug run-bmark-tests-debug 80 | .PHONY: run run-debug run-fast 81 | -------------------------------------------------------------------------------- /Makefrag-variables: -------------------------------------------------------------------------------- 1 | PROJECT ?= freechips.rocketchip.system 2 | MODEL ?= TestHarness 3 | CONFIG ?= ExampleHwachaConfig 4 | CFG_PROJECT ?= example 5 | GENERATOR_PROJECT ?= hwacha 6 | TOP ?= ExampleRocketSystem 7 | TB ?= TestDriver 8 | 9 | JVM_HEAP_SIZE ?= 16G 10 | 11 | SCALA_VERSION=2.12.4 12 | SCALA_VERSION_MAJOR=$(basename $(SCALA_VERSION)) 13 | 14 | ifneq ($(GENERATOR_PROJECT),example) 15 | long_name=$(PROJECT).$(CONFIG) 16 | else 17 | long_name=$(PROJECT).$(MODEL).$(CONFIG) 18 | endif 19 | 20 | FIRRTL_FILE ?=$(build_dir)/$(long_name).fir 21 | ANNO_FILE ?=$(build_dir)/$(long_name).anno.json 22 | VERILOG_FILE ?=$(build_dir)/$(long_name).top.v 23 | TOP_FIR ?=$(build_dir)/$(long_name).top.fir 24 | TOP_ANNO ?=$(build_dir)/$(long_name).top.anno.json 25 | HARNESS_FILE ?=$(build_dir)/$(long_name).harness.v 26 | HARNESS_FIR ?=$(build_dir)/$(long_name).harness.fir 27 | HARNESS_ANNO ?=$(build_dir)/$(long_name).harness.anno.json 28 | HARNESS_SMEMS_FILE ?=$(build_dir)/$(long_name).harness.mems.v 29 | HARNESS_SMEMS_CONF ?=$(build_dir)/$(long_name).harness.mems.conf 30 | HARNESS_SMEMS_FIR ?=$(build_dir)/$(long_name).harness.mems.fir 31 | SMEMS_FILE ?=$(build_dir)/$(long_name).mems.v 32 | SMEMS_CONF ?=$(build_dir)/$(long_name).mems.conf 33 | SMEMS_FIR ?=$(build_dir)/$(long_name).mems.fir 34 | sim_dotf ?= $(build_dir)/sim_files.f 35 | sim_harness_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.harness.f 36 | sim_top_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.top.f 37 | 38 | REPL_SEQ_MEM = --infer-rw --repl-seq-mem -c:$(MODEL):-o:$(SMEMS_CONF) 39 | HARNESS_REPL_SEQ_MEM = --infer-rw --repl-seq-mem -c:$(MODEL):-o:$(HARNESS_SMEMS_CONF) 40 | 41 | rocketchip_vsrc_dir = $(ROCKETCHIP_DIR)/src/main/resources/vsrc 42 | rocketchip_csrc_dir = $(ROCKETCHIP_DIR)/src/main/resources/csrc 43 | 44 | sim_vsrcs = \ 45 | $(VERILOG_FILE) \ 46 | $(HARNESS_FILE) \ 47 | $(HARNESS_SMEMS_FILE) \ 48 | $(SMEMS_FILE) 49 | 50 | # Assembly/Benchmark Testing 51 | disasm := 2> 52 | which_disasm := $(shell which spike-dasm 2> /dev/null) 53 | ifneq ($(which_disasm),) 54 | disasm = 3>&1 1>&2 2>&3 | $(which_disasm) $(DISASM_EXTENSION) > 55 | endif 56 | 57 | timeout_cycles = 10000000 58 | bmark_timeout_cycles = 100000000 59 | 60 | junk += $(output_dir) 61 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # UCB-BAR Hwacha Project Template 2 | 3 | | **`hwacha-template` has been deprecated. Users are encouraged to migrate to [Chipyard](https://github.com/ucb-bar/chipyard).** | 4 | |---| 5 | 6 | This is a template for building a rocket-chip with Hwacha. 7 | 8 | ## Submodules and Subdirectories 9 | 10 | The submodules and subdirectories for the project template are organized as 11 | follows. 12 | 13 | * rocket-chip - contains code for the RocketChip generator, Chisel HCL, and FIRRTL 14 | * hwacha - contains code for the Hwacha accelerator 15 | * riscv-tools - contains the code for the compiler toolchain that targets Hwacha 16 | * testchipip - contains the serial adapter, block device, and associated verilog and C++ code 17 | * verisim - directory in which Verilator simulations are compiled and run 18 | * vsim - directory in which Synopsys VCS simulations are compiled and run 19 | * src/main/scala - scala source files for your project extension go here 20 | 21 | ## Getting started 22 | 23 | ### Checking out the sources 24 | 25 | After cloning this repo, you will need to initialize all of the submodules 26 | 27 | git clone https://github.com/ucb-bar/hwacha-template.git 28 | cd hwacha-template 29 | ./scripts/init-submodules 30 | 31 | ### Building the tools 32 | 33 | The tools repo contains the cross-compiler toolchain, frontend server, and 34 | proxy kernel, which you will need in order to compile code to RISC-V 35 | instructions and run them on your design. There are detailed instructions at 36 | [esp-tools](https://github.com/ucb-bar/esp-tools). But to get a basic installation, just 37 | the following steps are necessary. 38 | 39 | # You may want to add the following two lines to your shell profile 40 | export RISCV=/path/to/install/dir 41 | export PATH=$RISCV/bin:$PATH 42 | 43 | cd riscv-tools 44 | ./build.sh 45 | 46 | ### Compiling and running the Verilator simulation 47 | 48 | To compile the example design, run make in the "verisim" directory. 49 | This will elaborate the ExampleHwachaConfig in the example project. 50 | 51 | An executable called simulator-example-ExampleHwachaConfig will be produced. 52 | You can then use this executable to run any compatible RV64 code. For instance, 53 | to run one of the riscv-tools assembly tests. 54 | 55 | make ${PWD}/output/rv64ui-p-simple.out 56 | 57 | To run all assembly tests or simple benchmarks: 58 | 59 | make run-asm-tests 60 | make run-bmark-tests 61 | 62 | To generate waveforms: 63 | 64 | make run-asm-tests-debug 65 | make run-bmark-tests-debug 66 | 67 | To only run the Hwacha assembly tests: 68 | 69 | make run-rv64uv-p-asm-tests 70 | make run-rv64uv-vp-asm-tests 71 | 72 | --- 73 | **NOTE** 74 | 75 | The Hwacha AMO tests are expected to fail. 76 | This is a current limitation of the example open-source configurations, 77 | which only instantiate an L2 broadcast hub that does not support AMOs 78 | (not a full TileLink2-compliant L2 cache). 79 | 80 | --- 81 | 82 | If you later create your own project, you can use environment variables to 83 | build an alternate configuration. The different variables are 84 | 85 | * PROJECT: The package that contains your test harness class 86 | * CFG_PROJECT: The package that contains your config class 87 | * GENERATOR_PROJECT: The package that contains your Generator class 88 | * MODEL: The class name of your test harness 89 | * CONFIG: The class name of your config 90 | 91 | You can manually override them like this 92 | 93 | make PROJECT=yourproject CONFIG=YourConfig 94 | ./simulator-yourproject-YourConfig ... 95 | 96 | ### Running random tests with torture ### 97 | 98 | RISC-V Torture is included as a submodule and includes the ability to test 99 | Hwacha. 100 | You can run a single test like so: 101 | 102 | make rgentest R_SIM=../vsim/simv-freechips.rocketchip.system-ExampleHwachaConfig 103 | 104 | You can run a nightly test, which runs for a set amount of time or a set 105 | number of failures like this: 106 | 107 | make rnight R_SIM=../vsim/simv-freechips.rocketchip.system-ExampleHwachaConfig OPTIONS="-C config/mem_vec.config -t 5 -m 30" 108 | 109 | ## THE REMAINDER OF THIS FILE IS COPIED FROM PROJECT-TEMPLATE ## 110 | 111 | ## Using the block device 112 | 113 | The default example project just provides the Rocket coreplex, memory, and 114 | serial line. But testchipip also provides a simulated block device that can 115 | be used for non-volatile storage. You can build a simulator including the 116 | block device using the blkdev package. 117 | 118 | make CONFIG=SimBlockDeviceConfig 119 | ./simulator-example-SimBlockDeviceConfig +blkdev=block-device.img ... 120 | 121 | By passing the +blkdev argument on the simulator command line, you can allow 122 | the RTL simulation to read and write from a file. Take a look at tests/blkdev.c 123 | for an example of how Rocket can program the block device controller. 124 | 125 | ## Adding an MMIO peripheral 126 | 127 | You can RocketChip to create your own memory-mapped IO device and add it into 128 | the SoC design. The easiest way to create a TileLink peripheral is to use the 129 | TLRegisterRouter, which abstracts away the details of handling the TileLink 130 | protocol and provides a convenient interface for specifying memory-mapped 131 | registers. To create a RegisterRouter-based peripheral, you will need to 132 | specify a parameter case class for the configuration settings, a bundle trait 133 | with the extra top-level ports, and a module implementation containing the 134 | actual RTL. 135 | 136 | ```scala 137 | case class PWMParams(address: BigInt, beatBytes: Int) 138 | 139 | trait PWMTLBundle extends Bundle { 140 | val pwmout = Output(Bool()) 141 | } 142 | 143 | trait PWMTLModule { 144 | val io: PWMTLBundle 145 | implicit val p: Parameters 146 | def params: PWMParams 147 | 148 | val w = params.beatBytes * 8 149 | val period = Reg(UInt(w.W)) 150 | val duty = Reg(UInt(w.W)) 151 | val enable = RegInit(false.B) 152 | 153 | // ... Use the registers to drive io.pwmout ... 154 | 155 | regmap( 156 | 0x00 -> Seq( 157 | RegField(w, period)), 158 | 0x04 -> Seq( 159 | RegField(w, duty)), 160 | 0x08 -> Seq( 161 | RegField(1, enable))) 162 | } 163 | ``` 164 | 165 | Once you have these classes, you can construct the final peripheral by 166 | extending the TLRegisterRouter and passing the proper arguments. The first 167 | set of arguments determines where the register router will be placed in the 168 | global address map and what information will be put in its device tree entry. 169 | The second set of arguments is the IO bundle constructor, which we create 170 | by extending TLRegBundle with our bundle trait. The final set of arguments 171 | is the module constructor, which we create by extends TLRegModule with our 172 | module trait. 173 | 174 | ```scala 175 | class PWMTL(c: PWMParams)(implicit p: Parameters) 176 | extends TLRegisterRouter( 177 | c.address, "pwm", Seq("ucbbar,pwm"), 178 | beatBytes = c.beatBytes)( 179 | new TLRegBundle(c, _) with PWMTLBundle)( 180 | new TLRegModule(c, _, _) with PWMTLModule) 181 | ``` 182 | 183 | The full module code with comments can be found in src/main/scala/example/PWM.scala. 184 | 185 | After creating the module, we need to hook it up to our SoC. Rocketchip 186 | accomplishes this using the [cake pattern](http://www.cakesolutions.net/teamblogs/2011/12/19/cake-pattern-in-depth). 187 | This basically involves placing code inside traits. In the RocketChip cake, 188 | there are two kinds of traits: a LazyModule trait and a module implementation 189 | trait. 190 | 191 | The LazyModule trait runs setup code that must execute before all the hardware 192 | gets elaborated. For a simple memory-mapped peripheral, this just involves 193 | connecting the peripheral's TileLink node to the MMIO crossbar. 194 | 195 | ```scala 196 | trait HasPeripheryPWM extends HasSystemNetworks { 197 | implicit val p: Parameters 198 | 199 | private val address = 0x2000 200 | 201 | val pwm = LazyModule(new PWMTL( 202 | PWMParams(address, peripheryBusConfig.beatBytes))(p)) 203 | 204 | pwm.node := TLFragmenter( 205 | peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) 206 | } 207 | ``` 208 | 209 | Note that the PWMTL class we created from the register router is itself a 210 | LazyModule. Register routers have a TileLike node simply named "node", which 211 | we can hook up to the RocketChip peripheryBus. This will automatically add 212 | address map and device tree entries for the peripheral. 213 | 214 | The module implementation trait is where we instantiate our PWM module and 215 | connect it to the rest of the SoC. Since this module has an extra `pwmout` 216 | output, we declare that in this trait, using Chisel's multi-IO 217 | functionality. We then connect the PWMTL's pwmout to the pwmout we declared. 218 | 219 | ```scala 220 | trait HasPeripheryPWMModuleImp extends LazyMultiIOModuleImp { 221 | implicit val p: Parameters 222 | val outer: HasPeripheryPWM 223 | 224 | val pwmout = IO(Output(Bool())) 225 | 226 | pwmout := outer.pwm.module.io.pwmout 227 | } 228 | ``` 229 | 230 | Now we want to mix our traits into the system as a whole. This code is from 231 | src/main/scala/example/Top.scala. 232 | 233 | ```scala 234 | class ExampleTopWithPWM(q: Parameters) extends ExampleTop(q) 235 | with PeripheryPWM { 236 | override lazy val module = Module( 237 | new ExampleTopWithPWMModule(p, this)) 238 | } 239 | 240 | class ExampleTopWithPWMModule(l: ExampleTopWithPWM) 241 | extends ExampleTopModule(l) with HasPeripheryPWMModuleImp 242 | ``` 243 | 244 | Just as we need separate traits for LazyModule and module implementation, we 245 | need two classes to build the system. The ExampleTop classes already have the 246 | basic peripherals included for us, so we will just extend those. 247 | 248 | The ExampleTop class includes the pre-elaboration code and also a lazy val to 249 | produce the module implementation (hence LazyModule). The ExampleTopModule 250 | class is the actual RTL that gets synthesized. 251 | 252 | Finally, we need to add a configuration class in 253 | src/main/scala/example/Configs.scala that tells the TestHarness to instantiate 254 | ExampleTopWithPWM instead of the default ExampleTop. 255 | 256 | ```scala 257 | class WithPWM extends Config((site, here, up) => { 258 | case BuildTop => (p: Parameters) => 259 | Module(LazyModule(new ExampleTopWithPWM()(p)).module) 260 | }) 261 | 262 | class PWMConfig extends Config(new WithPWM ++ new BaseExampleConfig) 263 | ``` 264 | 265 | Now we can test that the PWM is working. The test program is in tests/pwm.c 266 | 267 | ```c 268 | #define PWM_PERIOD 0x2000 269 | #define PWM_DUTY 0x2008 270 | #define PWM_ENABLE 0x2010 271 | 272 | static inline void write_reg(unsigned long addr, unsigned long data) 273 | { 274 | volatile unsigned long *ptr = (volatile unsigned long *) addr; 275 | *ptr = data; 276 | } 277 | 278 | static inline unsigned long read_reg(unsigned long addr) 279 | { 280 | volatile unsigned long *ptr = (volatile unsigned long *) addr; 281 | return *ptr; 282 | } 283 | 284 | int main(void) 285 | { 286 | write_reg(PWM_PERIOD, 20); 287 | write_reg(PWM_DUTY, 5); 288 | write_reg(PWM_ENABLE, 1); 289 | } 290 | ``` 291 | 292 | This just writes out to the registers we defined earlier. The base of the 293 | module's MMIO region is at 0x2000. This will be printed out in the address 294 | map portion when you generated the verilog code. 295 | 296 | Compiling this program with make produces a `pwm.riscv` executable. 297 | 298 | Now with all of that done, we can go ahead and run our simulation. 299 | 300 | cd verisim 301 | make CONFIG=PWMConfig 302 | ./simulator-example-PWMConfig ../tests/pwm.riscv 303 | 304 | ## Adding a DMA port 305 | 306 | In the example above, we gave allowed the processor to communicate with the 307 | peripheral through MMIO. However, for IO devices (like a disk or network 308 | driver), we may want to have the device write directly to the coherent 309 | memory system instead. To add a device like that, you would do the following. 310 | 311 | ```scala 312 | class DMADevice(implicit p: Parameters) extends LazyModule { 313 | val node = TLClientNode(TLClientParameters( 314 | name = "dma-device", sourceId = IdRange(0, 1))) 315 | 316 | lazy val module = new DMADeviceModule(this) 317 | } 318 | 319 | class DMADeviceModule(outer: DMADevice) extends LazyModuleImp(outer) { 320 | val io = IO(new Bundle { 321 | val mem = outer.node.bundleOut 322 | val ext = new ExtBundle 323 | }) 324 | 325 | // ... rest of the code ... 326 | } 327 | 328 | trait HasPeripheryDMA extends HasSystemNetworks { 329 | implicit val p: Parameters 330 | 331 | val dma = LazyModule(new DMADevice) 332 | 333 | fsb.node := dma.node 334 | } 335 | 336 | trait HasPeripheryDMAModuleImp extends LazyMultiIOModuleImp { 337 | val ext = IO(new ExtBundle) 338 | ext <> outer.dma.module.io.ext 339 | } 340 | ``` 341 | 342 | The `ExtBundle` contains the signals we connect off-chip that we get data from. 343 | The DMADevice also has a Tilelink client port that we connect into the L1-L2 344 | crossbar through the front-side buffer (fsb). The sourceId variable given in 345 | the TLClientNode instantiation determines the range of ids that can be used 346 | in acquire messages from this device. Since we specified [0, 1) as our range, 347 | only the ID 0 can be used. 348 | 349 | ## Adding a RoCC accelerator 350 | 351 | Besides peripheral devices, a RocketChip-based SoC can also be customized with 352 | coprocessor accelerators. Each core can have up to four accelerators that 353 | are controlled by custom instructions and share resources with the CPU. 354 | 355 | ### A RoCC instruction 356 | 357 | Coprocessor instructions have the following form. 358 | 359 | customX rd, rs1, rs2, funct 360 | 361 | The X will be a number 0-3, and determines the opcode of the instruction, 362 | which controls which accelerator an instruction will be routed to. 363 | The `rd`, `rs1`, and `rs2` fields are the register numbers of the destination 364 | register and two source registers. The `funct` field is a 7-bit integer that 365 | the accelerator can use to distinguish different instructions from each other. 366 | 367 | ### Creating an accelerator 368 | 369 | RoCC accelerators are lazy modules that extend the LazyRoCC class. 370 | Their implementation should extends the LazyRoCCModule class. 371 | 372 | ```scala 373 | class CustomAccelerator(opcodes: OpcodeSet) 374 | (implicit p: Parameters) extends LazyRoCC(opcodes) { 375 | override lazy val module = new CustomAcceleratorModule(this) 376 | } 377 | 378 | class CustomAcceleratorModule(outer: CustomAccelerator) 379 | extends LazyRoCCModuleImp(outer) { 380 | val cmd = Queue(io.cmd) 381 | // The parts of the command are as follows 382 | // inst - the parts of the instruction itself 383 | // opcode 384 | // rd - destination register number 385 | // rs1 - first source register number 386 | // rs2 - second source register number 387 | // funct 388 | // xd - is the destination register being used? 389 | // xs1 - is the first source register being used? 390 | // xs2 - is the second source register being used? 391 | // rs1 - the value of source register 1 392 | // rs2 - the value of source register 2 393 | ... 394 | } 395 | ``` 396 | 397 | The `opcodes` parameter for `LazyRoCC` is 398 | the set of custom opcodes that will map to this accelerator. More on this 399 | in the next subsection. 400 | 401 | The `LazyRoCC` class contains two TLOutputNode instances, `atlNode` and `tlNode`. 402 | The former connects into a tile-local arbiter along with the backside of the 403 | L1 instruction cache. The latter connects directly to the L1-L2 crossbar. 404 | The corresponding Tilelink ports in the module implementation's IO bundle 405 | are `atl` and `tl`, respectively. 406 | 407 | The other interfaces available to the accelerator are `mem`, which provides 408 | access to the L1 cache; `ptw` which provides access to the page-table walker; 409 | the `busy` signal, which indicates when the accelerator is still handling an 410 | instruction; and the `interrupt` signal, which can be used to interrupt the CPU. 411 | 412 | Look at the examples in rocket-chip/src/main/scala/tile/LazyRocc.scala for 413 | detailed information on the different IOs. 414 | 415 | ### Adding RoCC accelerator to Config 416 | 417 | RoCC accelerators can be added to a core by overriding the `BuildRoCC` parameter 418 | in the configuration. This takes a sequence of functions producing `LazyRoCC` 419 | objects, one for each accelerator you wish to add. 420 | 421 | For instance, if we wanted to add the previously defined accelerator and 422 | route custom0 and custom1 instructions to it, we could do the following. 423 | 424 | ```scala 425 | class WithCustomAccelerator extends Config((site, here, up) => { 426 | case BuildRoCC => Seq((p: Parameters) => LazyModule( 427 | new CustomAccelerator(OpcodeSet.custom0 | OpcodeSet.custom1)(p))) 428 | }) 429 | 430 | class CustomAcceleratorConfig extends Config( 431 | new WithCustomAccelerator ++ new DefaultExampleConfig) 432 | ``` 433 | 434 | ## Adding a submodule 435 | 436 | While developing, you want to include Chisel code in a submodule so that it 437 | can be shared by different projects. To add a submodule to the project 438 | template, make sure that your project is organized as follows. 439 | 440 | yourproject/ 441 | build.sbt 442 | src/main/scala/ 443 | YourFile.scala 444 | 445 | Put this in a git repository and make it accessible. Then add it as a submodule 446 | to the project template. 447 | 448 | git submodule add https://git-repository.com/yourproject.git 449 | 450 | Then add `yourproject` to the project-template build.sbt file. 451 | 452 | ```scala 453 | lazy val yourproject = project.settings(commonSettings).dependsOn(rocketchip) 454 | ``` 455 | 456 | You can then import the classes defined in the submodule in a new project if 457 | you add it as a dependency. For instance, if you want to use this code in 458 | the `example` project, change the final line in build.sbt to the following. 459 | 460 | ```scala 461 | lazy val example = (project in file(".")).settings(commonSettings).dependsOn(testchipip, yourproject) 462 | ``` 463 | 464 | Finally, add `yourproject` to the `PACKAGES` variable in the `Makefrag`. This will allow make to detect 465 | that your source files have changed when building the verilog/firrtl files. 466 | -------------------------------------------------------------------------------- /build.sbt: -------------------------------------------------------------------------------- 1 | lazy val commonSettings = Seq( 2 | organization := "edu.berkeley.cs", 3 | version := "1.0", 4 | scalaVersion := "2.12.4", 5 | traceLevel := 15, 6 | test in assembly := {}, 7 | assemblyMergeStrategy in assembly := { _ match { 8 | case PathList("META-INF", "MANIFEST.MF") => MergeStrategy.discard 9 | case _ => MergeStrategy.first}}, 10 | scalacOptions ++= Seq("-deprecation","-unchecked","-Xsource:2.11"), 11 | libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.1" % "test", 12 | libraryDependencies += "org.json4s" %% "json4s-native" % "3.5.3", 13 | libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value, 14 | libraryDependencies += "edu.berkeley.cs" %% "firrtl-interpreter" % "1.2-SNAPSHOT", 15 | libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.1", 16 | addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full), 17 | resolvers ++= Seq( 18 | Resolver.sonatypeRepo("snapshots"), 19 | Resolver.sonatypeRepo("releases"), 20 | Resolver.mavenLocal)) 21 | 22 | lazy val rocketchip = RootProject(file("rocket-chip")) 23 | 24 | lazy val testchipip = project.settings(commonSettings) 25 | .dependsOn(rocketchip) 26 | 27 | lazy val hwacha = project.settings(commonSettings) 28 | .dependsOn(rocketchip) 29 | 30 | // Checks for -DROCKET_USE_MAVEN. 31 | // If it's there, use a maven dependency. 32 | // Else, depend on subprojects in git submodules. 33 | def conditionalDependsOn(prj: Project): Project = { 34 | if (sys.props.contains("ROCKET_USE_MAVEN")) { 35 | prj.settings(Seq( 36 | libraryDependencies += "edu.berkeley.cs" %% "testchipip" % "1.0-020719-SNAPSHOT", 37 | )) 38 | } else { 39 | prj.dependsOn(testchipip) 40 | } 41 | } 42 | lazy val example = conditionalDependsOn(project in file(".")) 43 | .settings(commonSettings) 44 | .dependsOn(hwacha) 45 | 46 | lazy val tapeout = conditionalDependsOn(project in file("./barstools/tapeout/")) 47 | .settings(commonSettings) 48 | 49 | lazy val mdf = (project in file("./barstools/mdf/scalalib/")) 50 | 51 | lazy val `barstools-macros` = conditionalDependsOn(project in file("./barstools/macros/")) 52 | .enablePlugins(sbtassembly.AssemblyPlugin) 53 | .settings(commonSettings) 54 | .dependsOn(mdf) 55 | 56 | -------------------------------------------------------------------------------- /project/build.properties: -------------------------------------------------------------------------------- 1 | sbt.version=1.2.8 2 | -------------------------------------------------------------------------------- /project/plugins.sbt: -------------------------------------------------------------------------------- 1 | addSbtPlugin("com.eed3si9n" % "sbt-assembly" % "0.14.5") 2 | -------------------------------------------------------------------------------- /scripts/check_commit_log: -------------------------------------------------------------------------------- 1 | #! /usr/bin/env python 2 | 3 | import sys 4 | from sets import Set 5 | 6 | if len(sys.argv) < 3: 7 | print "usage: %s " % sys.argv[0] 8 | exit(-1) 9 | 10 | slog = map(lambda x: x.strip(), open(sys.argv[1]).readlines()) 11 | vlog = map(lambda x: x.strip(), open(sys.argv[2]).readlines()) 12 | 13 | spike_arf = {} 14 | spike_srf = {} 15 | spike_vrf = {} 16 | spike_prf = {} 17 | vsim_arf = {} 18 | vsim_srf = {} 19 | vsim_vrf = {} 20 | vsim_prf = {} 21 | 22 | nvdpr = 256 23 | nppr = 16 24 | nlanes = 1 25 | lstride = 1 26 | lstrip = 1< c: 122 | diverged = True 123 | print l 124 | cycle = c 125 | except IndexError: 126 | print "not matching number of writes" 127 | print "vsim", v 128 | print "spike", s 129 | 130 | compare_keys('arf', spike_arf, vsim_arf) 131 | for addr in sorted(vsim_arf.keys()): 132 | compare_data('arf[%02d]' % addr, spike_arf[addr], vsim_arf[addr]) 133 | 134 | compare_keys('srf', spike_srf, vsim_srf) 135 | for addr in sorted(vsim_srf.keys()): 136 | if addr != 0: 137 | compare_data('srf[%02d]' % addr, spike_srf[addr], vsim_srf[addr]) 138 | 139 | compare_keys('vrf', spike_vrf, vsim_vrf) 140 | for eidx in sorted(vsim_vrf.keys()): 141 | try: 142 | compare_keys('vrf[%02d]' % eidx, spike_vrf[eidx], vsim_vrf[eidx]) 143 | for addr in sorted(vsim_vrf[eidx].keys()): 144 | compare_data('vrf[%02d][%03d]' % (eidx, addr), spike_vrf[eidx][addr], vsim_vrf[eidx][addr]) 145 | except KeyError: 146 | print "something is very wrong with", eidx, addr 147 | 148 | compare_keys('prf', spike_prf, vsim_prf) 149 | for eidx in sorted(vsim_prf.keys()): 150 | try: 151 | compare_keys('prf[%02d]' % eidx, spike_prf[eidx], vsim_prf[eidx]) 152 | for addr in sorted(vsim_prf[eidx].keys()): 153 | compare_data('prf[%02d][%02d]' % (eidx, addr), spike_prf[eidx][addr], vsim_prf[eidx][addr]) 154 | except KeyError: 155 | print "something is very wrong with", eidx, addr 156 | 157 | if diverged: 158 | print "DOESN'T MATCH: earliest cycle", cycle 159 | else: 160 | print "ZARRO BOOGS FOUND" 161 | -------------------------------------------------------------------------------- /scripts/init-submodules: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | # top-level 5 | git submodule update --init rocket-chip riscv-tools testchipip hwacha torture barstools 6 | # rocket-chip (skip tools) 7 | git -C rocket-chip submodule update --init --recursive hardfloat chisel3 firrtl 8 | # esp-tools (skip llvm, openocd and only init gnu-toolchain) 9 | git -C riscv-tools submodule update --init --recursive riscv-isa-sim riscv-fesvr riscv-pk riscv-opcodes riscv-tests 10 | git -C riscv-tools submodule update --init riscv-gnu-toolchain 11 | # esp-gnu-toolchain (skip dejagnu, glibc, qemu) 12 | git -C riscv-tools/riscv-gnu-toolchain submodule update --init --recursive riscv-binutils-gdb riscv-gcc riscv-newlib 13 | # barstools submodules 14 | git -C barstools submodule update --init --recursive 15 | # torture submodules 16 | git -C torture submodule update --init --recursive 17 | -------------------------------------------------------------------------------- /src/main/resources/project-template/csrc/emulator.cc: -------------------------------------------------------------------------------- 1 | // See LICENSE.SiFive for license details. 2 | // See LICENSE.Berkeley for license details. 3 | 4 | #include "verilated.h" 5 | #if VM_TRACE 6 | #include 7 | #include "verilated_vcd_c.h" 8 | #endif 9 | #include 10 | #include 11 | #include "remote_bitbang.h" 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | 20 | // For option parsing, which is split across this file, Verilog, and 21 | // FESVR's HTIF, a few external files must be pulled in. The list of 22 | // files and what they provide is enumerated: 23 | // 24 | // $RISCV/include/fesvr/htif.h: 25 | // defines: 26 | // - HTIF_USAGE_OPTIONS 27 | // - HTIF_LONG_OPTIONS_OPTIND 28 | // - HTIF_LONG_OPTIONS 29 | // $(ROCKETCHIP_DIR)/generated-src(-debug)?/$(CONFIG).plusArgs: 30 | // defines: 31 | // - PLUSARG_USAGE_OPTIONS 32 | // variables: 33 | // - static const char * verilog_plusargs 34 | 35 | extern tsi_t* tsi; 36 | extern dtm_t* dtm; 37 | extern remote_bitbang_t * jtag; 38 | 39 | static uint64_t trace_count = 0; 40 | bool verbose; 41 | bool done_reset; 42 | 43 | void handle_sigterm(int sig) 44 | { 45 | dtm->stop(); 46 | } 47 | 48 | double sc_time_stamp() 49 | { 50 | return trace_count; 51 | } 52 | 53 | extern "C" int vpi_get_vlog_info(void* arg) 54 | { 55 | return 0; 56 | } 57 | 58 | static void usage(const char * program_name) 59 | { 60 | printf("Usage: %s [EMULATOR OPTION]... [VERILOG PLUSARG]... [HOST OPTION]... BINARY [TARGET OPTION]...\n", 61 | program_name); 62 | fputs("\ 63 | Run a BINARY on the Rocket Chip emulator.\n\ 64 | \n\ 65 | Mandatory arguments to long options are mandatory for short options too.\n\ 66 | \n\ 67 | EMULATOR OPTIONS\n\ 68 | -c, --cycle-count Print the cycle count before exiting\n\ 69 | +cycle-count\n\ 70 | -h, --help Display this help and exit\n\ 71 | -m, --max-cycles=CYCLES Kill the emulation after CYCLES\n\ 72 | +max-cycles=CYCLES\n\ 73 | -s, --seed=SEED Use random number seed SEED\n\ 74 | -r, --rbb-port=PORT Use PORT for remote bit bang (with OpenOCD and GDB) \n\ 75 | If not specified, a random port will be chosen\n\ 76 | automatically.\n\ 77 | -V, --verbose Enable all Chisel printfs (cycle-by-cycle info)\n\ 78 | +verbose\n\ 79 | ", stdout); 80 | #if VM_TRACE == 0 81 | fputs("\ 82 | \n\ 83 | EMULATOR DEBUG OPTIONS (only supported in debug build -- try `make debug`)\n", 84 | stdout); 85 | #endif 86 | fputs("\ 87 | -v, --vcd=FILE, Write vcd trace to FILE (or '-' for stdout)\n\ 88 | -x, --dump-start=CYCLE Start VCD tracing at CYCLE\n\ 89 | +dump-start\n\ 90 | ", stdout); 91 | fputs("\n" PLUSARG_USAGE_OPTIONS, stdout); 92 | fputs("\n" HTIF_USAGE_OPTIONS, stdout); 93 | printf("\n" 94 | "EXAMPLES\n" 95 | " - run a bare metal test:\n" 96 | " %s $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n" 97 | " - run a bare metal test showing cycle-by-cycle information:\n" 98 | " %s +verbose $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add 2>&1 | spike-dasm\n" 99 | #if VM_TRACE 100 | " - run a bare metal test to generate a VCD waveform:\n" 101 | " %s -v rv64ui-p-add.vcd $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n" 102 | #endif 103 | " - run an ELF (you wrote, called 'hello') using the proxy kernel:\n" 104 | " %s pk hello\n", 105 | program_name, program_name, program_name 106 | #if VM_TRACE 107 | , program_name 108 | #endif 109 | ); 110 | } 111 | 112 | int main(int argc, char** argv) 113 | { 114 | unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid(); 115 | uint64_t max_cycles = -1; 116 | int ret = 0; 117 | bool print_cycles = false; 118 | // Port numbers are 16 bit unsigned integers. 119 | uint16_t rbb_port = 0; 120 | #if VM_TRACE 121 | FILE * vcdfile = NULL; 122 | uint64_t start = 0; 123 | #endif 124 | char ** htif_argv = NULL; 125 | int verilog_plusargs_legal = 1; 126 | 127 | while (1) { 128 | static struct option long_options[] = { 129 | {"cycle-count", no_argument, 0, 'c' }, 130 | {"help", no_argument, 0, 'h' }, 131 | {"max-cycles", required_argument, 0, 'm' }, 132 | {"seed", required_argument, 0, 's' }, 133 | {"rbb-port", required_argument, 0, 'r' }, 134 | {"verbose", no_argument, 0, 'V' }, 135 | #if VM_TRACE 136 | {"vcd", required_argument, 0, 'v' }, 137 | {"dump-start", required_argument, 0, 'x' }, 138 | #endif 139 | HTIF_LONG_OPTIONS 140 | }; 141 | int option_index = 0; 142 | #if VM_TRACE 143 | int c = getopt_long(argc, argv, "-chm:s:r:v:Vx:", long_options, &option_index); 144 | #else 145 | int c = getopt_long(argc, argv, "-chm:s:r:V", long_options, &option_index); 146 | #endif 147 | if (c == -1) break; 148 | retry: 149 | switch (c) { 150 | // Process long and short EMULATOR options 151 | case '?': usage(argv[0]); return 1; 152 | case 'c': print_cycles = true; break; 153 | case 'h': usage(argv[0]); return 0; 154 | case 'm': max_cycles = atoll(optarg); break; 155 | case 's': random_seed = atoi(optarg); break; 156 | case 'r': rbb_port = atoi(optarg); break; 157 | case 'V': verbose = true; break; 158 | #if VM_TRACE 159 | case 'v': { 160 | vcdfile = strcmp(optarg, "-") == 0 ? stdout : fopen(optarg, "w"); 161 | if (!vcdfile) { 162 | std::cerr << "Unable to open " << optarg << " for VCD write\n"; 163 | return 1; 164 | } 165 | break; 166 | } 167 | case 'x': start = atoll(optarg); break; 168 | #endif 169 | // Process legacy '+' EMULATOR arguments by replacing them with 170 | // their getopt equivalents 171 | case 1: { 172 | std::string arg = optarg; 173 | if (arg.substr(0, 1) != "+") { 174 | optind--; 175 | goto done_processing; 176 | } 177 | if (arg == "+verbose") 178 | c = 'V'; 179 | else if (arg.substr(0, 12) == "+max-cycles=") { 180 | c = 'm'; 181 | optarg = optarg+12; 182 | } 183 | #if VM_TRACE 184 | else if (arg.substr(0, 12) == "+dump-start=") { 185 | c = 'x'; 186 | optarg = optarg+12; 187 | } 188 | #endif 189 | else if (arg.substr(0, 12) == "+cycle-count") 190 | c = 'c'; 191 | // If we don't find a legacy '+' EMULATOR argument, it still could be 192 | // a VERILOG_PLUSARG and not an error. 193 | else if (verilog_plusargs_legal) { 194 | const char ** plusarg = &verilog_plusargs[0]; 195 | int legal_verilog_plusarg = 0; 196 | while (*plusarg && (legal_verilog_plusarg == 0)){ 197 | if (arg.substr(1, strlen(*plusarg)) == *plusarg) { 198 | legal_verilog_plusarg = 1; 199 | } 200 | plusarg ++; 201 | } 202 | if (!legal_verilog_plusarg) { 203 | verilog_plusargs_legal = 0; 204 | } else { 205 | c = 'P'; 206 | } 207 | goto retry; 208 | } 209 | // If we STILL don't find a legacy '+' argument, it still could be 210 | // an HTIF (HOST) argument and not an error. If this is the case, then 211 | // we're done processing EMULATOR and VERILOG arguments. 212 | else { 213 | static struct option htif_long_options [] = { HTIF_LONG_OPTIONS }; 214 | struct option * htif_option = &htif_long_options[0]; 215 | while (htif_option->name) { 216 | if (arg.substr(1, strlen(htif_option->name)) == htif_option->name) { 217 | optind--; 218 | goto done_processing; 219 | } 220 | htif_option++; 221 | } 222 | std::cerr << argv[0] << ": invalid plus-arg (Verilog or HTIF) \"" 223 | << arg << "\"\n"; 224 | c = '?'; 225 | } 226 | goto retry; 227 | } 228 | case 'P': break; // Nothing to do here, Verilog PlusArg 229 | // Realize that we've hit HTIF (HOST) arguments or error out 230 | default: 231 | if (c >= HTIF_LONG_OPTIONS_OPTIND) { 232 | optind--; 233 | goto done_processing; 234 | } 235 | c = '?'; 236 | goto retry; 237 | } 238 | } 239 | 240 | done_processing: 241 | if (optind == argc) { 242 | std::cerr << "No binary specified for emulator\n"; 243 | usage(argv[0]); 244 | return 1; 245 | } 246 | int htif_argc = 1 + argc - optind; 247 | htif_argv = (char **) malloc((htif_argc) * sizeof (char *)); 248 | htif_argv[0] = argv[0]; 249 | for (int i = 1; optind < argc;) htif_argv[i++] = argv[optind++]; 250 | 251 | if (verbose) 252 | fprintf(stderr, "using random seed %u\n", random_seed); 253 | 254 | srand(random_seed); 255 | srand48(random_seed); 256 | 257 | Verilated::randReset(2); 258 | Verilated::commandArgs(argc, argv); 259 | TEST_HARNESS *tile = new TEST_HARNESS; 260 | 261 | #if VM_TRACE 262 | Verilated::traceEverOn(true); // Verilator must compute traced signals 263 | std::unique_ptr vcdfd(new VerilatedVcdFILE(vcdfile)); 264 | std::unique_ptr tfp(new VerilatedVcdC(vcdfd.get())); 265 | if (vcdfile) { 266 | tile->trace(tfp.get(), 99); // Trace 99 levels of hierarchy 267 | tfp->open(""); 268 | } 269 | #endif 270 | 271 | jtag = new remote_bitbang_t(rbb_port); 272 | dtm = new dtm_t(htif_argc, htif_argv); 273 | tsi = new tsi_t(htif_argc, htif_argv); 274 | 275 | signal(SIGTERM, handle_sigterm); 276 | 277 | bool dump; 278 | // reset for several cycles to handle pipelined reset 279 | for (int i = 0; i < 10; i++) { 280 | tile->reset = 1; 281 | tile->clock = 0; 282 | tile->eval(); 283 | #if VM_TRACE 284 | dump = tfp && trace_count >= start; 285 | if (dump) 286 | tfp->dump(static_cast(trace_count * 2)); 287 | #endif 288 | tile->clock = 1; 289 | tile->eval(); 290 | #if VM_TRACE 291 | if (dump) 292 | tfp->dump(static_cast(trace_count * 2 + 1)); 293 | #endif 294 | trace_count ++; 295 | } 296 | tile->reset = 0; 297 | done_reset = true; 298 | 299 | while (!dtm->done() && !jtag->done() && !tsi->done() && 300 | !tile->io_success && trace_count < max_cycles) { 301 | tile->clock = 0; 302 | tile->eval(); 303 | #if VM_TRACE 304 | dump = tfp && trace_count >= start; 305 | if (dump) 306 | tfp->dump(static_cast(trace_count * 2)); 307 | #endif 308 | 309 | tile->clock = 1; 310 | tile->eval(); 311 | #if VM_TRACE 312 | if (dump) 313 | tfp->dump(static_cast(trace_count * 2 + 1)); 314 | #endif 315 | trace_count++; 316 | } 317 | 318 | #if VM_TRACE 319 | if (tfp) 320 | tfp->close(); 321 | if (vcdfile) 322 | fclose(vcdfile); 323 | #endif 324 | 325 | if (dtm->exit_code()) 326 | { 327 | fprintf(stderr, "*** FAILED *** via dtm (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count); 328 | ret = dtm->exit_code(); 329 | } 330 | else if (tsi->exit_code()) 331 | { 332 | fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", tsi->exit_code(), random_seed, trace_count); 333 | ret = tsi->exit_code(); 334 | } 335 | else if (jtag->exit_code()) 336 | { 337 | fprintf(stderr, "*** FAILED *** via jtag (code = %d, seed %d) after %ld cycles\n", jtag->exit_code(), random_seed, trace_count); 338 | ret = jtag->exit_code(); 339 | } 340 | else if (trace_count == max_cycles) 341 | { 342 | fprintf(stderr, "*** FAILED *** via trace_count (timeout, seed %d) after %ld cycles\n", random_seed, trace_count); 343 | ret = 2; 344 | } 345 | else if (verbose || print_cycles) 346 | { 347 | fprintf(stderr, "*** PASSED *** Completed after %ld cycles\n", trace_count); 348 | } 349 | 350 | if (dtm) delete dtm; 351 | if (tsi) delete tsi; 352 | if (jtag) delete jtag; 353 | if (tile) delete tile; 354 | if (htif_argv) free(htif_argv); 355 | return ret; 356 | } 357 | -------------------------------------------------------------------------------- /src/main/scala/example/Configs.scala: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import chisel3._ 4 | import freechips.rocketchip.config.{Parameters, Config} 5 | import freechips.rocketchip.subsystem.{WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, WithExtMemSize, WithNBanks} 6 | import freechips.rocketchip.diplomacy.{LazyModule, ValName} 7 | import freechips.rocketchip.devices.tilelink.BootROMParams 8 | import freechips.rocketchip.tile.XLen 9 | import testchipip._ 10 | 11 | class WithBootROM extends Config((site, here, up) => { 12 | case BootROMParams => BootROMParams( 13 | contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img") 14 | }) 15 | 16 | object ConfigValName { 17 | implicit val valName = ValName("TestHarness") 18 | } 19 | import ConfigValName._ 20 | 21 | class WithExampleTop extends Config((site, here, up) => { 22 | case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => { 23 | Module(LazyModule(new ExampleTop()(p)).module) 24 | } 25 | }) 26 | 27 | class WithPWM extends Config((site, here, up) => { 28 | case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => 29 | Module(LazyModule(new ExampleTopWithPWMTL()(p)).module) 30 | }) 31 | 32 | class WithPWMAXI4 extends Config((site, here, up) => { 33 | case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => 34 | Module(LazyModule(new ExampleTopWithPWMAXI4()(p)).module) 35 | }) 36 | 37 | class WithBlockDeviceModel extends Config((site, here, up) => { 38 | case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => { 39 | val top = Module(LazyModule(new ExampleTopWithBlockDevice()(p)).module) 40 | top.connectBlockDeviceModel() 41 | top 42 | } 43 | }) 44 | 45 | class WithSimBlockDevice extends Config((site, here, up) => { 46 | case BuildTop => (clock: Clock, reset: Bool, p: Parameters) => { 47 | val top = Module(LazyModule(new ExampleTopWithBlockDevice()(p)).module) 48 | top.connectSimBlockDevice(clock, reset) 49 | top 50 | } 51 | }) 52 | 53 | class ExampleHwachaConfig extends Config( 54 | new WithBootROM ++ 55 | new hwacha.ISCA2016Config) 56 | 57 | class SingleBankHwachaConfig extends Config( 58 | new WithNBanks(1) ++ 59 | new WithBootROM ++ 60 | new hwacha.ISCA2016Config) 61 | 62 | class ExampleHwacha4LaneConfig extends Config( 63 | new WithBootROM ++ 64 | new hwacha.ISCA2016L4Config) 65 | 66 | class BaseExampleConfig extends Config( 67 | new WithBootROM ++ 68 | new freechips.rocketchip.system.DefaultConfig) 69 | 70 | class DefaultExampleConfig extends Config( 71 | new WithExampleTop ++ new BaseExampleConfig) 72 | 73 | class RoccExampleConfig extends Config( 74 | new WithRoccExample ++ new DefaultExampleConfig) 75 | 76 | class PWMConfig extends Config(new WithPWM ++ new BaseExampleConfig) 77 | 78 | class PWMAXI4Config extends Config(new WithPWMAXI4 ++ new BaseExampleConfig) 79 | 80 | class SimBlockDeviceConfig extends Config( 81 | new WithBlockDevice ++ new WithSimBlockDevice ++ new BaseExampleConfig) 82 | 83 | class BlockDeviceModelConfig extends Config( 84 | new WithBlockDevice ++ new WithBlockDeviceModel ++ new BaseExampleConfig) 85 | 86 | class WithTwoTrackers extends WithNBlockDeviceTrackers(2) 87 | class WithFourTrackers extends WithNBlockDeviceTrackers(4) 88 | 89 | class WithTwoMemChannels extends WithNMemoryChannels(2) 90 | class WithFourMemChannels extends WithNMemoryChannels(4) 91 | 92 | // 16GB of off chip memory 93 | class BigMemoryConfig extends Config( 94 | new WithExtMemSize((1<<30) * 16L) ++ new DefaultExampleConfig) 95 | // 1GB of off chip memory 96 | class GB1MemoryConfig extends Config( 97 | new WithExtMemSize((1<<30) * 1L) ++ new DefaultExampleConfig) 98 | class GB2MemoryConfig extends Config( 99 | new WithExtMemSize((1<<30) * 2L) ++ new DefaultExampleConfig) 100 | class GB4MemoryConfig extends Config( 101 | new WithExtMemSize((1<<30) * 4L) ++ new DefaultExampleConfig) 102 | class GB8MemoryConfig extends Config( 103 | new WithExtMemSize((1<<30) * 8L) ++ new DefaultExampleConfig) 104 | 105 | class DualCoreConfig extends Config( 106 | // Core gets tacked onto existing list 107 | new WithNBigCores(2) ++ new DefaultExampleConfig) 108 | 109 | class RV32ExampleConfig extends Config( 110 | new WithRV32 ++ new DefaultExampleConfig) 111 | -------------------------------------------------------------------------------- /src/main/scala/example/PWM.scala: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import chisel3._ 4 | import chisel3.util._ 5 | import freechips.rocketchip.amba.axi4._ 6 | import freechips.rocketchip.subsystem.BaseSubsystem 7 | import freechips.rocketchip.config.{Parameters, Field} 8 | import freechips.rocketchip.diplomacy._ 9 | import freechips.rocketchip.regmapper.{HasRegMap, RegField} 10 | import freechips.rocketchip.tilelink._ 11 | import freechips.rocketchip.util.UIntIsOneOf 12 | 13 | case class PWMParams(address: BigInt, beatBytes: Int) 14 | 15 | class PWMBase(w: Int) extends Module { 16 | val io = IO(new Bundle { 17 | val pwmout = Output(Bool()) 18 | val period = Input(UInt(w.W)) 19 | val duty = Input(UInt(w.W)) 20 | val enable = Input(Bool()) 21 | }) 22 | 23 | // The counter should count up until period is reached 24 | val counter = Reg(UInt(w.W)) 25 | 26 | when (counter >= (io.period - 1.U)) { 27 | counter := 0.U 28 | } .otherwise { 29 | counter := counter + 1.U 30 | } 31 | 32 | // If PWM is enabled, pwmout is high when counter < duty 33 | // If PWM is not enabled, it will always be low 34 | io.pwmout := io.enable && (counter < io.duty) 35 | } 36 | 37 | trait PWMBundle extends Bundle { 38 | val pwmout = Output(Bool()) 39 | } 40 | 41 | trait PWMModule extends HasRegMap { 42 | val io: PWMBundle 43 | implicit val p: Parameters 44 | def params: PWMParams 45 | 46 | // How many clock cycles in a PWM cycle? 47 | val period = Reg(UInt(32.W)) 48 | // For how many cycles should the clock be high? 49 | val duty = Reg(UInt(32.W)) 50 | // Is the PWM even running at all? 51 | val enable = RegInit(false.B) 52 | 53 | val base = Module(new PWMBase(32)) 54 | io.pwmout := base.io.pwmout 55 | base.io.period := period 56 | base.io.duty := duty 57 | base.io.enable := enable 58 | 59 | regmap( 60 | 0x00 -> Seq( 61 | RegField(32, period)), 62 | 0x04 -> Seq( 63 | RegField(32, duty)), 64 | 0x08 -> Seq( 65 | RegField(1, enable))) 66 | } 67 | 68 | class PWMTL(c: PWMParams)(implicit p: Parameters) 69 | extends TLRegisterRouter( 70 | c.address, "pwm", Seq("ucbbar,pwm"), 71 | beatBytes = c.beatBytes)( 72 | new TLRegBundle(c, _) with PWMBundle)( 73 | new TLRegModule(c, _, _) with PWMModule) 74 | 75 | class PWMAXI4(c: PWMParams)(implicit p: Parameters) 76 | extends AXI4RegisterRouter(c.address, beatBytes = c.beatBytes)( 77 | new AXI4RegBundle(c, _) with PWMBundle)( 78 | new AXI4RegModule(c, _, _) with PWMModule) 79 | 80 | trait HasPeripheryPWMTL { this: BaseSubsystem => 81 | implicit val p: Parameters 82 | 83 | private val address = 0x2000 84 | private val portName = "pwm" 85 | 86 | val pwm = LazyModule(new PWMTL( 87 | PWMParams(address, pbus.beatBytes))(p)) 88 | 89 | pbus.toVariableWidthSlave(Some(portName)) { pwm.node } 90 | } 91 | 92 | trait HasPeripheryPWMTLModuleImp extends LazyModuleImp { 93 | implicit val p: Parameters 94 | val outer: HasPeripheryPWMTL 95 | 96 | val pwmout = IO(Output(Bool())) 97 | 98 | pwmout := outer.pwm.module.io.pwmout 99 | } 100 | 101 | trait HasPeripheryPWMAXI4 { this: BaseSubsystem => 102 | implicit val p: Parameters 103 | 104 | private val address = 0x2000 105 | private val portName = "pwm" 106 | 107 | val pwm = LazyModule(new PWMAXI4( 108 | PWMParams(address, pbus.beatBytes))(p)) 109 | 110 | pbus.toSlave(Some(portName)) { 111 | pwm.node := 112 | AXI4Buffer () := 113 | TLToAXI4() := 114 | // toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needs 115 | TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true) 116 | } 117 | } 118 | 119 | trait HasPeripheryPWMAXI4ModuleImp extends LazyModuleImp { 120 | implicit val p: Parameters 121 | val outer: HasPeripheryPWMAXI4 122 | 123 | val pwmout = IO(Output(Bool())) 124 | 125 | pwmout := outer.pwm.module.io.pwmout 126 | } 127 | -------------------------------------------------------------------------------- /src/main/scala/example/Simulator.scala: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import java.io.File 4 | 5 | case class GenerateSimConfig( 6 | targetDir: String = ".", 7 | dotFName: String = "sim_files.f", 8 | simulator: Simulator = VerilatorSimulator, 9 | ) 10 | 11 | sealed trait Simulator 12 | object VerilatorSimulator extends Simulator 13 | object VCSSimulator extends Simulator 14 | 15 | trait HasGenerateSimConfig { 16 | val parser = new scopt.OptionParser[GenerateSimConfig]("GenerateSimFiles") { 17 | head("GenerateSimFiles", "0.1") 18 | 19 | opt[String]("simulator") 20 | .abbr("sim") 21 | .valueName("") 22 | .action((x, c) => x match { 23 | case "verilator" => c.copy(simulator = VerilatorSimulator) 24 | case "vcs" => c.copy(simulator = VCSSimulator) 25 | case _ => throw new Exception(s"Unrecognized simulator $x") 26 | }) 27 | .text("Name of simulator to generate files for (verilator, vcs)") 28 | 29 | opt[String]("target-dir") 30 | .abbr("td") 31 | .valueName("") 32 | .action((x, c) => c.copy(targetDir = x)) 33 | .text("Target director to put files") 34 | 35 | opt[String]("dotFName") 36 | .abbr("df") 37 | .valueName("") 38 | .action((x, c) => c.copy(dotFName = x)) 39 | .text("Name of generated dot-f file") 40 | } 41 | } 42 | 43 | object GenerateSimFiles extends App with HasGenerateSimConfig { 44 | def addOption(file: File, cfg: GenerateSimConfig): String = { 45 | val fname = file.getCanonicalPath 46 | // deal with header files 47 | if (fname.takeRight(2) == ".h") { 48 | cfg.simulator match { 49 | // verilator needs to explicitly include verilator.h, so use the -FI option 50 | case VerilatorSimulator => s"-FI ${fname}" 51 | // vcs pulls headers in with +incdir, doesn't have anything like verilator.h 52 | case VCSSimulator => "" 53 | } 54 | } else { // do nothing otherwise 55 | fname 56 | } 57 | } 58 | def writeDotF(lines: Seq[String], cfg: GenerateSimConfig): Unit = { 59 | writeTextToFile(lines.mkString("\n"), new File(cfg.targetDir, cfg.dotFName)) 60 | } 61 | // From FIRRTL 62 | def safeFile[A](fileName: String)(code: => A) = try { code } catch { 63 | case e@ (_: java.io.FileNotFoundException | _: NullPointerException) => throw new Exception(fileName, e) 64 | case t: Throwable => throw t 65 | } 66 | // From FIRRTL 67 | def writeResource(name: String, targetDir: String): File = { 68 | val in = getClass.getResourceAsStream(name) 69 | val p = java.nio.file.Paths.get(name) 70 | val fname = p.getFileName().toString(); 71 | 72 | val f = new File(targetDir, fname) 73 | val out = new java.io.FileOutputStream(f) 74 | safeFile(name)(Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write)) 75 | out.close() 76 | f 77 | } 78 | // From FIRRTL 79 | def writeTextToFile(text: String, file: File) { 80 | val out = new java.io.PrintWriter(file) 81 | out.write(text) 82 | out.close() 83 | } 84 | def resources(sim: Simulator): Seq[String] = Seq( 85 | "/testchipip/csrc/SimSerial.cc", 86 | "/csrc/SimDTM.cc", 87 | "/csrc/SimJTAG.cc", 88 | "/csrc/remote_bitbang.h", 89 | "/csrc/remote_bitbang.cc", 90 | "/vsrc/EICG_wrapper.v", 91 | ) ++ (sim match { // simulator specific files to include 92 | case VerilatorSimulator => Seq( 93 | "/project-template/csrc/emulator.cc", 94 | "/csrc/verilator.h", 95 | ) 96 | case VCSSimulator => Seq( 97 | "/vsrc/TestDriver.v", 98 | ) 99 | }) 100 | 101 | def writeBootrom(): Unit = { 102 | firrtl.FileUtils.makeDirectory("./bootrom/") 103 | writeResource("/testchipip/bootrom/bootrom.rv64.img", "./bootrom/") 104 | } 105 | 106 | def writeFiles(cfg: GenerateSimConfig): Unit = { 107 | writeBootrom() 108 | firrtl.FileUtils.makeDirectory(cfg.targetDir) 109 | val files = resources(cfg.simulator).map { writeResource(_, cfg.targetDir) } 110 | writeDotF(files.map(addOption(_, cfg)), cfg) 111 | } 112 | 113 | parser.parse(args, GenerateSimConfig()) match { 114 | case Some(cfg) => writeFiles(cfg) 115 | case _ => // error message already shown 116 | } 117 | } 118 | -------------------------------------------------------------------------------- /src/main/scala/example/TestHarness.scala: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import chisel3._ 4 | import chisel3.experimental._ 5 | import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxSourceHelper} 6 | import freechips.rocketchip.diplomacy.LazyModule 7 | import freechips.rocketchip.config.{Field, Parameters} 8 | import freechips.rocketchip.util.GeneratorApp 9 | import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite} 10 | import freechips.rocketchip.subsystem.RocketTilesKey 11 | import freechips.rocketchip.tile.XLen 12 | import scala.collection.mutable.LinkedHashSet 13 | 14 | case object BuildTop extends Field[(Clock, Bool, Parameters) => ExampleTopModule[ExampleTop]] 15 | 16 | class TestHarness(implicit val p: Parameters) extends Module { 17 | val io = IO(new Bundle { 18 | val success = Output(Bool()) 19 | }) 20 | 21 | val dut = p(BuildTop)(clock, reset.toBool, p) 22 | dut.debug := DontCare 23 | dut.connectSimAXIMem() 24 | dut.connectSimAXIMMIO() 25 | dut.dontTouchPorts() 26 | dut.tieOffInterrupts() 27 | dut.l2_frontend_bus_axi4.foreach(axi => { 28 | axi.tieoff() 29 | experimental.DataMirror.directionOf(axi.ar.ready) match { 30 | case core.ActualDirection.Input => 31 | axi.r.bits := DontCare 32 | axi.b.bits := DontCare 33 | case core.ActualDirection.Output => 34 | axi.aw.bits := DontCare 35 | axi.ar.bits := DontCare 36 | axi.w.bits := DontCare 37 | } 38 | }) 39 | io.success := dut.connectSimSerial() 40 | } 41 | 42 | object Generator extends GeneratorApp { 43 | //Copied from rocketchip 44 | val rv64RegrTestNames = LinkedHashSet( 45 | "rv64ud-v-fcvt", 46 | "rv64ud-p-fdiv", 47 | "rv64ud-v-fadd", 48 | "rv64uf-v-fadd", 49 | "rv64um-v-mul", 50 | "rv64mi-p-breakpoint", 51 | "rv64uc-v-rvc", 52 | "rv64ud-v-structural", 53 | "rv64si-p-wfi", 54 | "rv64um-v-divw", 55 | "rv64ua-v-lrsc", 56 | "rv64ui-v-fence_i", 57 | "rv64ud-v-fcvt_w", 58 | "rv64uf-v-fmin", 59 | "rv64ui-v-sb", 60 | "rv64ua-v-amomax_d", 61 | "rv64ud-v-move", 62 | "rv64ud-v-fclass", 63 | "rv64ua-v-amoand_d", 64 | "rv64ua-v-amoxor_d", 65 | "rv64si-p-sbreak", 66 | "rv64ud-v-fmadd", 67 | "rv64uf-v-ldst", 68 | "rv64um-v-mulh", 69 | "rv64si-p-dirty") 70 | 71 | val rv32RegrTestNames = LinkedHashSet( 72 | "rv32mi-p-ma_addr", 73 | "rv32mi-p-csr", 74 | "rv32ui-p-sh", 75 | "rv32ui-p-lh", 76 | "rv32uc-p-rvc", 77 | "rv32mi-p-sbreak", 78 | "rv32ui-p-sll") 79 | 80 | 81 | override def addTestSuites { 82 | import freechips.rocketchip.system.DefaultTestSuites._ 83 | val xlen = params(XLen) 84 | // TODO: for now only generate tests for the first core in the first subsystem 85 | params(RocketTilesKey).headOption.map { tileParams => 86 | val coreParams = tileParams.core 87 | val vm = coreParams.useVM 88 | val env = if (vm) List("p","v") else List("p") 89 | coreParams.fpu foreach { case cfg => 90 | if (xlen == 32) { 91 | TestGeneration.addSuites(env.map(rv32uf)) 92 | if (cfg.fLen >= 64) 93 | TestGeneration.addSuites(env.map(rv32ud)) 94 | } else { 95 | TestGeneration.addSuite(rv32udBenchmarks) 96 | TestGeneration.addSuites(env.map(rv64uf)) 97 | if (cfg.fLen >= 64) 98 | TestGeneration.addSuites(env.map(rv64ud)) 99 | } 100 | } 101 | if (coreParams.useAtomics) { 102 | if (tileParams.dcache.flatMap(_.scratch).isEmpty) 103 | TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua)) 104 | else 105 | TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC)) 106 | } 107 | if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc)) 108 | val (rvi, rvu) = 109 | if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u) 110 | else ((if (vm) rv32i else rv32pi), rv32u) 111 | 112 | TestGeneration.addSuites(rvi.map(_("p"))) 113 | TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env)))) 114 | TestGeneration.addSuite(benchmarks) 115 | TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames)) 116 | } 117 | } 118 | //End copied from rocketchip 119 | val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs 120 | generateFirrtl 121 | generateTestSuiteMakefrags 122 | generateAnno 123 | generateTestSuiteMakefrags 124 | generateArtefacts 125 | } 126 | -------------------------------------------------------------------------------- /src/main/scala/example/Top.scala: -------------------------------------------------------------------------------- 1 | package example 2 | 3 | import chisel3._ 4 | import freechips.rocketchip.subsystem._ 5 | import freechips.rocketchip.system._ 6 | import freechips.rocketchip.config.Parameters 7 | import freechips.rocketchip.devices.tilelink._ 8 | import freechips.rocketchip.util.DontTouch 9 | import testchipip._ 10 | 11 | class ExampleTop(implicit p: Parameters) extends ExampleRocketSystem //RocketSubsystem 12 | with CanHaveMasterAXI4MemPort 13 | with HasPeripheryBootROM 14 | // with HasSystemErrorSlave 15 | // with HasSyncExtInterrupts 16 | with HasNoDebug 17 | with HasPeripherySerial { 18 | override lazy val module = new ExampleTopModule(this) 19 | } 20 | 21 | class ExampleTopModule[+L <: ExampleTop](l: L) extends ExampleRocketSystemModuleImp(l) // RocketSubsystemModuleImp(l) 22 | with HasRTCModuleImp 23 | with CanHaveMasterAXI4MemPortModuleImp 24 | with HasPeripheryBootROMModuleImp 25 | // with HasExtInterruptsModuleImp 26 | with HasNoDebugModuleImp 27 | with HasPeripherySerialModuleImp 28 | with DontTouch 29 | 30 | class ExampleTopWithPWMTL(implicit p: Parameters) extends ExampleTop 31 | with HasPeripheryPWMTL { 32 | override lazy val module = new ExampleTopWithPWMTLModule(this) 33 | } 34 | 35 | class ExampleTopWithPWMTLModule(l: ExampleTopWithPWMTL) 36 | extends ExampleTopModule(l) with HasPeripheryPWMTLModuleImp 37 | 38 | class ExampleTopWithPWMAXI4(implicit p: Parameters) extends ExampleTop 39 | with HasPeripheryPWMAXI4 { 40 | override lazy val module = new ExampleTopWithPWMAXI4Module(this) 41 | } 42 | 43 | class ExampleTopWithPWMAXI4Module(l: ExampleTopWithPWMAXI4) 44 | extends ExampleTopModule(l) with HasPeripheryPWMAXI4ModuleImp 45 | 46 | class ExampleTopWithBlockDevice(implicit p: Parameters) extends ExampleTop 47 | with HasPeripheryBlockDevice { 48 | override lazy val module = new ExampleTopWithBlockDeviceModule(this) 49 | } 50 | 51 | class ExampleTopWithBlockDeviceModule(l: ExampleTopWithBlockDevice) 52 | extends ExampleTopModule(l) 53 | with HasPeripheryBlockDeviceModuleImp 54 | -------------------------------------------------------------------------------- /tests/.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.riscv 3 | *.dump 4 | -------------------------------------------------------------------------------- /tests/Makefile: -------------------------------------------------------------------------------- 1 | GCC=riscv64-unknown-elf-gcc 2 | OBJDUMP=riscv64-unknown-elf-objdump 3 | CFLAGS=-mcmodel=medany -std=gnu99 -O2 -fno-common -fno-builtin-printf -Wall 4 | LDFLAGS=-static -nostdlib -nostartfiles -lgcc 5 | 6 | PROGRAMS = pwm blkdev accum charcount 7 | 8 | default: $(addsuffix .riscv,$(PROGRAMS)) 9 | 10 | dumps: $(addsuffix .dump,$(PROGRAMS)) 11 | 12 | %.o: %.S 13 | $(GCC) $(CFLAGS) -D__ASSEMBLY__=1 -c $< -o $@ 14 | 15 | %.o: %.c mmio.h 16 | $(GCC) $(CFLAGS) -c $< -o $@ 17 | 18 | %.riscv: %.o crt.o syscalls.o link.ld 19 | $(GCC) -T link.ld $(LDFLAGS) $< crt.o syscalls.o -o $@ 20 | 21 | %.dump: %.riscv 22 | $(OBJDUMP) -D $< > $@ 23 | 24 | clean: 25 | rm -f *.riscv *.o *.dump 26 | -------------------------------------------------------------------------------- /tests/accum.c: -------------------------------------------------------------------------------- 1 | #include "rocc.h" 2 | 3 | static inline void accum_write(int idx, unsigned long data) 4 | { 5 | ROCC_INSTRUCTION_SS(0, data, idx, 0); 6 | } 7 | 8 | static inline unsigned long accum_read(int idx) 9 | { 10 | unsigned long value; 11 | ROCC_INSTRUCTION_DSS(0, value, 0, idx, 1); 12 | return value; 13 | } 14 | 15 | static inline void accum_load(int idx, void *ptr) 16 | { 17 | asm volatile ("fence"); 18 | ROCC_INSTRUCTION_SS(0, (uintptr_t) ptr, idx, 2); 19 | } 20 | 21 | static inline void accum_add(int idx, unsigned long addend) 22 | { 23 | ROCC_INSTRUCTION_SS(0, addend, idx, 3); 24 | } 25 | 26 | unsigned long data = 0x3421L; 27 | 28 | int main(void) 29 | { 30 | unsigned long result; 31 | 32 | accum_load(0, &data); 33 | accum_add(0, 2); 34 | result = accum_read(0); 35 | 36 | if (result != data + 2) 37 | return 1; 38 | 39 | accum_write(0, 3); 40 | accum_add(0, 1); 41 | result = accum_read(0); 42 | 43 | if (result != 4) 44 | return 2; 45 | 46 | return 0; 47 | } 48 | -------------------------------------------------------------------------------- /tests/blkdev.c: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include "mmio.h" 5 | 6 | #define BLKDEV_BASE 0x10015000 7 | #define BLKDEV_ADDR BLKDEV_BASE 8 | #define BLKDEV_OFFSET (BLKDEV_BASE + 8) 9 | #define BLKDEV_LEN (BLKDEV_BASE + 12) 10 | #define BLKDEV_WRITE (BLKDEV_BASE + 16) 11 | #define BLKDEV_REQUEST (BLKDEV_BASE + 17) 12 | #define BLKDEV_NREQUEST (BLKDEV_BASE + 18) 13 | #define BLKDEV_COMPLETE (BLKDEV_BASE + 19) 14 | #define BLKDEV_NCOMPLETE (BLKDEV_BASE + 20) 15 | #define BLKDEV_NSECTORS (BLKDEV_BASE + 24) 16 | #define BLKDEV_MAX_REQUEST_LENGTH (BLKDEV_BASE + 28) 17 | #define BLKDEV_SECTOR_SIZE 512 18 | #define BLKDEV_SECTOR_SHIFT 9 19 | 20 | size_t blkdev_nsectors(void) 21 | { 22 | return reg_read32(BLKDEV_NSECTORS); 23 | } 24 | 25 | size_t blkdev_max_req_len(void) 26 | { 27 | return reg_read32(BLKDEV_MAX_REQUEST_LENGTH); 28 | } 29 | 30 | void blkdev_read(void *addr, unsigned long offset, size_t nsectors) 31 | { 32 | int req_tag, resp_tag, ntags, i; 33 | size_t nsectors_per_tag; 34 | 35 | ntags = reg_read8(BLKDEV_NREQUEST); 36 | nsectors_per_tag = nsectors / ntags; 37 | 38 | printf("sending %d reads\n", ntags); 39 | 40 | for (i = 0; i < ntags; i++) { 41 | reg_write64(BLKDEV_ADDR, (unsigned long) addr); 42 | reg_write32(BLKDEV_OFFSET, offset); 43 | reg_write32(BLKDEV_LEN, nsectors_per_tag); 44 | reg_write8(BLKDEV_WRITE, 0); 45 | 46 | req_tag = reg_read8(BLKDEV_REQUEST); 47 | addr += (nsectors_per_tag << BLKDEV_SECTOR_SHIFT); 48 | offset += nsectors_per_tag; 49 | } 50 | 51 | while (reg_read8(BLKDEV_NCOMPLETE) < ntags); 52 | 53 | for (i = 0; i < ntags; i++) { 54 | resp_tag = reg_read8(BLKDEV_COMPLETE); 55 | printf("completed read %d\n", resp_tag); 56 | } 57 | } 58 | 59 | void blkdev_write(unsigned long offset, void *addr, size_t nsectors) 60 | { 61 | int req_tag, resp_tag, ntags, i; 62 | size_t nsectors_per_tag; 63 | 64 | ntags = reg_read8(BLKDEV_NREQUEST); 65 | nsectors_per_tag = nsectors / ntags; 66 | 67 | printf("sending %d writes\n", ntags); 68 | 69 | for (i = 0; i < ntags; i++) { 70 | reg_write64(BLKDEV_ADDR, (unsigned long) addr); 71 | reg_write32(BLKDEV_OFFSET, offset); 72 | reg_write32(BLKDEV_LEN, nsectors_per_tag); 73 | reg_write8(BLKDEV_WRITE, 1); 74 | 75 | req_tag = reg_read8(BLKDEV_REQUEST); 76 | addr += (nsectors_per_tag << BLKDEV_SECTOR_SHIFT); 77 | offset += nsectors_per_tag; 78 | } 79 | 80 | while (reg_read8(BLKDEV_NCOMPLETE) < ntags); 81 | 82 | for (i = 0; i < ntags; i++) { 83 | resp_tag = reg_read8(BLKDEV_COMPLETE); 84 | printf("completed write %d\n", resp_tag); 85 | } 86 | } 87 | 88 | #define TEST_NSECTORS 4 89 | #define TEST_SIZE (TEST_NSECTORS * BLKDEV_SECTOR_SIZE / sizeof(int)) 90 | 91 | unsigned int test_data[TEST_SIZE]; 92 | unsigned int res_data[TEST_SIZE]; 93 | 94 | int main(void) 95 | { 96 | unsigned int nsectors = blkdev_nsectors(); 97 | unsigned int max_req_len = blkdev_max_req_len(); 98 | 99 | if (nsectors < TEST_NSECTORS) { 100 | printf("Error: blkdev nsectors not large enough: %u < %u\n", 101 | nsectors, TEST_NSECTORS); 102 | return 1; 103 | } 104 | 105 | if (max_req_len < TEST_NSECTORS) { 106 | printf("Error: blkdev max_req_len not large enough: %u < %u\n", 107 | max_req_len, TEST_NSECTORS); 108 | return 1; 109 | } 110 | 111 | printf("blkdev: %u sectors %u max request length\n", 112 | nsectors, max_req_len); 113 | 114 | for (int i = 0; i < TEST_SIZE; i++) { 115 | test_data[i] = i << 8; 116 | } 117 | 118 | asm volatile ("fence"); 119 | 120 | blkdev_write(0, (void *) test_data, TEST_NSECTORS); 121 | blkdev_read((void *) res_data, 0, TEST_NSECTORS); 122 | 123 | for (int i = 0; i < TEST_SIZE; i++) { 124 | if (test_data[i] != res_data[i]) { 125 | printf("data mismatch at %d: %x != %x\n", 126 | i, test_data[i], res_data[i]); 127 | return 1; 128 | } 129 | } 130 | 131 | printf("All correct\n"); 132 | 133 | return 0; 134 | } 135 | -------------------------------------------------------------------------------- /tests/charcount.c: -------------------------------------------------------------------------------- 1 | #include "rocc.h" 2 | 3 | char string[64] = "The quick brown fox jumped over the lazy dog"; 4 | 5 | static inline unsigned long count_chars(char *start, char needle) 6 | { 7 | unsigned long count; 8 | asm volatile ("fence"); 9 | ROCC_INSTRUCTION_DSS(2, count, start, needle, 0); 10 | return count; 11 | } 12 | 13 | int main(void) 14 | { 15 | unsigned long count = count_chars(string + 14, 'o'); 16 | if (count != 3) 17 | return count + 1; 18 | return 0; 19 | } 20 | -------------------------------------------------------------------------------- /tests/crt.S: -------------------------------------------------------------------------------- 1 | # See LICENSE for license details. 2 | 3 | #include "encoding.h" 4 | 5 | #if __riscv_xlen == 64 6 | # define LREG ld 7 | # define SREG sd 8 | # define REGBYTES 8 9 | #else 10 | # define LREG lw 11 | # define SREG sw 12 | # define REGBYTES 4 13 | #endif 14 | 15 | .section ".text.init" 16 | .globl _start 17 | _start: 18 | li x1, 0 19 | li x2, 0 20 | li x3, 0 21 | li x4, 0 22 | li x5, 0 23 | li x6, 0 24 | li x7, 0 25 | li x8, 0 26 | li x9, 0 27 | li x10,0 28 | li x11,0 29 | li x12,0 30 | li x13,0 31 | li x14,0 32 | li x15,0 33 | li x16,0 34 | li x17,0 35 | li x18,0 36 | li x19,0 37 | li x20,0 38 | li x21,0 39 | li x22,0 40 | li x23,0 41 | li x24,0 42 | li x25,0 43 | li x26,0 44 | li x27,0 45 | li x28,0 46 | li x29,0 47 | li x30,0 48 | li x31,0 49 | 50 | # enable FPU and accelerator if present 51 | li t0, MSTATUS_FS | MSTATUS_XS 52 | csrs mstatus, t0 53 | 54 | # make sure XLEN agrees with compilation choice 55 | li t0, 1 56 | slli t0, t0, 31 57 | #if __riscv_xlen == 64 58 | bgez t0, 1f 59 | #else 60 | bltz t0, 1f 61 | #endif 62 | 2: 63 | li a0, 1 64 | sw a0, tohost, t0 65 | j 2b 66 | 1: 67 | 68 | #ifdef __riscv_flen 69 | # initialize FPU if we have one 70 | la t0, 1f 71 | csrw mtvec, t0 72 | 73 | fssr x0 74 | fmv.s.x f0, x0 75 | fmv.s.x f1, x0 76 | fmv.s.x f2, x0 77 | fmv.s.x f3, x0 78 | fmv.s.x f4, x0 79 | fmv.s.x f5, x0 80 | fmv.s.x f6, x0 81 | fmv.s.x f7, x0 82 | fmv.s.x f8, x0 83 | fmv.s.x f9, x0 84 | fmv.s.x f10,x0 85 | fmv.s.x f11,x0 86 | fmv.s.x f12,x0 87 | fmv.s.x f13,x0 88 | fmv.s.x f14,x0 89 | fmv.s.x f15,x0 90 | fmv.s.x f16,x0 91 | fmv.s.x f17,x0 92 | fmv.s.x f18,x0 93 | fmv.s.x f19,x0 94 | fmv.s.x f20,x0 95 | fmv.s.x f21,x0 96 | fmv.s.x f22,x0 97 | fmv.s.x f23,x0 98 | fmv.s.x f24,x0 99 | fmv.s.x f25,x0 100 | fmv.s.x f26,x0 101 | fmv.s.x f27,x0 102 | fmv.s.x f28,x0 103 | fmv.s.x f29,x0 104 | fmv.s.x f30,x0 105 | fmv.s.x f31,x0 106 | 1: 107 | #endif 108 | 109 | # initialize trap vector 110 | la t0, trap_entry 111 | csrw mtvec, t0 112 | 113 | # initialize global pointer 114 | .option push 115 | .option norelax 116 | la gp, __global_pointer$ 117 | .option pop 118 | 119 | la tp, _end + 63 120 | and tp, tp, -64 121 | 122 | # get core id 123 | csrr a0, mhartid 124 | # for now, assume only 1 core 125 | li a1, 1 126 | 1:bgeu a0, a1, 1b 127 | 128 | # give each core 128KB of stack + TLS 129 | #define STKSHIFT 17 130 | sll a2, a0, STKSHIFT 131 | add tp, tp, a2 132 | add sp, a0, 1 133 | sll sp, sp, STKSHIFT 134 | add sp, sp, tp 135 | 136 | j _init 137 | 138 | .align 2 139 | trap_entry: 140 | addi sp, sp, -272 141 | 142 | SREG x1, 1*REGBYTES(sp) 143 | SREG x2, 2*REGBYTES(sp) 144 | SREG x3, 3*REGBYTES(sp) 145 | SREG x4, 4*REGBYTES(sp) 146 | SREG x5, 5*REGBYTES(sp) 147 | SREG x6, 6*REGBYTES(sp) 148 | SREG x7, 7*REGBYTES(sp) 149 | SREG x8, 8*REGBYTES(sp) 150 | SREG x9, 9*REGBYTES(sp) 151 | SREG x10, 10*REGBYTES(sp) 152 | SREG x11, 11*REGBYTES(sp) 153 | SREG x12, 12*REGBYTES(sp) 154 | SREG x13, 13*REGBYTES(sp) 155 | SREG x14, 14*REGBYTES(sp) 156 | SREG x15, 15*REGBYTES(sp) 157 | SREG x16, 16*REGBYTES(sp) 158 | SREG x17, 17*REGBYTES(sp) 159 | SREG x18, 18*REGBYTES(sp) 160 | SREG x19, 19*REGBYTES(sp) 161 | SREG x20, 20*REGBYTES(sp) 162 | SREG x21, 21*REGBYTES(sp) 163 | SREG x22, 22*REGBYTES(sp) 164 | SREG x23, 23*REGBYTES(sp) 165 | SREG x24, 24*REGBYTES(sp) 166 | SREG x25, 25*REGBYTES(sp) 167 | SREG x26, 26*REGBYTES(sp) 168 | SREG x27, 27*REGBYTES(sp) 169 | SREG x28, 28*REGBYTES(sp) 170 | SREG x29, 29*REGBYTES(sp) 171 | SREG x30, 30*REGBYTES(sp) 172 | SREG x31, 31*REGBYTES(sp) 173 | 174 | csrr a0, mcause 175 | csrr a1, mepc 176 | mv a2, sp 177 | jal handle_trap 178 | csrw mepc, a0 179 | 180 | # Remain in M-mode after eret 181 | li t0, MSTATUS_MPP 182 | csrs mstatus, t0 183 | 184 | LREG x1, 1*REGBYTES(sp) 185 | LREG x2, 2*REGBYTES(sp) 186 | LREG x3, 3*REGBYTES(sp) 187 | LREG x4, 4*REGBYTES(sp) 188 | LREG x5, 5*REGBYTES(sp) 189 | LREG x6, 6*REGBYTES(sp) 190 | LREG x7, 7*REGBYTES(sp) 191 | LREG x8, 8*REGBYTES(sp) 192 | LREG x9, 9*REGBYTES(sp) 193 | LREG x10, 10*REGBYTES(sp) 194 | LREG x11, 11*REGBYTES(sp) 195 | LREG x12, 12*REGBYTES(sp) 196 | LREG x13, 13*REGBYTES(sp) 197 | LREG x14, 14*REGBYTES(sp) 198 | LREG x15, 15*REGBYTES(sp) 199 | LREG x16, 16*REGBYTES(sp) 200 | LREG x17, 17*REGBYTES(sp) 201 | LREG x18, 18*REGBYTES(sp) 202 | LREG x19, 19*REGBYTES(sp) 203 | LREG x20, 20*REGBYTES(sp) 204 | LREG x21, 21*REGBYTES(sp) 205 | LREG x22, 22*REGBYTES(sp) 206 | LREG x23, 23*REGBYTES(sp) 207 | LREG x24, 24*REGBYTES(sp) 208 | LREG x25, 25*REGBYTES(sp) 209 | LREG x26, 26*REGBYTES(sp) 210 | LREG x27, 27*REGBYTES(sp) 211 | LREG x28, 28*REGBYTES(sp) 212 | LREG x29, 29*REGBYTES(sp) 213 | LREG x30, 30*REGBYTES(sp) 214 | LREG x31, 31*REGBYTES(sp) 215 | 216 | addi sp, sp, 272 217 | mret 218 | 219 | .section ".tdata.begin" 220 | .globl _tdata_begin 221 | _tdata_begin: 222 | 223 | .section ".tdata.end" 224 | .globl _tdata_end 225 | _tdata_end: 226 | 227 | .section ".tbss.end" 228 | .globl _tbss_end 229 | _tbss_end: 230 | 231 | .section ".tohost","aw",@progbits 232 | .align 6 233 | .globl tohost 234 | tohost: .dword 0 235 | .align 6 236 | .globl fromhost 237 | fromhost: .dword 0 238 | -------------------------------------------------------------------------------- /tests/encoding.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef RISCV_CSR_ENCODING_H 4 | #define RISCV_CSR_ENCODING_H 5 | 6 | #define MSTATUS_UIE 0x00000001 7 | #define MSTATUS_SIE 0x00000002 8 | #define MSTATUS_HIE 0x00000004 9 | #define MSTATUS_MIE 0x00000008 10 | #define MSTATUS_UPIE 0x00000010 11 | #define MSTATUS_SPIE 0x00000020 12 | #define MSTATUS_HPIE 0x00000040 13 | #define MSTATUS_MPIE 0x00000080 14 | #define MSTATUS_SPP 0x00000100 15 | #define MSTATUS_HPP 0x00000600 16 | #define MSTATUS_MPP 0x00001800 17 | #define MSTATUS_FS 0x00006000 18 | #define MSTATUS_XS 0x00018000 19 | #define MSTATUS_MPRV 0x00020000 20 | #define MSTATUS_PUM 0x00040000 21 | #define MSTATUS_MXR 0x00080000 22 | #define MSTATUS_VM 0x1F000000 23 | #define MSTATUS32_SD 0x80000000 24 | #define MSTATUS64_SD 0x8000000000000000 25 | 26 | #define SSTATUS_UIE 0x00000001 27 | #define SSTATUS_SIE 0x00000002 28 | #define SSTATUS_UPIE 0x00000010 29 | #define SSTATUS_SPIE 0x00000020 30 | #define SSTATUS_SPP 0x00000100 31 | #define SSTATUS_FS 0x00006000 32 | #define SSTATUS_XS 0x00018000 33 | #define SSTATUS_PUM 0x00040000 34 | #define SSTATUS32_SD 0x80000000 35 | #define SSTATUS64_SD 0x8000000000000000 36 | 37 | #define DCSR_XDEBUGVER (3U<<30) 38 | #define DCSR_NDRESET (1<<29) 39 | #define DCSR_FULLRESET (1<<28) 40 | #define DCSR_EBREAKM (1<<15) 41 | #define DCSR_EBREAKH (1<<14) 42 | #define DCSR_EBREAKS (1<<13) 43 | #define DCSR_EBREAKU (1<<12) 44 | #define DCSR_STOPCYCLE (1<<10) 45 | #define DCSR_STOPTIME (1<<9) 46 | #define DCSR_CAUSE (7<<6) 47 | #define DCSR_DEBUGINT (1<<5) 48 | #define DCSR_HALT (1<<3) 49 | #define DCSR_STEP (1<<2) 50 | #define DCSR_PRV (3<<0) 51 | 52 | #define DCSR_CAUSE_NONE 0 53 | #define DCSR_CAUSE_SWBP 1 54 | #define DCSR_CAUSE_HWBP 2 55 | #define DCSR_CAUSE_DEBUGINT 3 56 | #define DCSR_CAUSE_STEP 4 57 | #define DCSR_CAUSE_HALT 5 58 | 59 | #define MCONTROL_TYPE(xlen) (0xfULL<<((xlen)-4)) 60 | #define MCONTROL_DMODE(xlen) (1ULL<<((xlen)-5)) 61 | #define MCONTROL_MASKMAX(xlen) (0x3fULL<<((xlen)-11)) 62 | 63 | #define MCONTROL_SELECT (1<<19) 64 | #define MCONTROL_TIMING (1<<18) 65 | #define MCONTROL_ACTION (0x3f<<12) 66 | #define MCONTROL_CHAIN (1<<11) 67 | #define MCONTROL_MATCH (0xf<<7) 68 | #define MCONTROL_M (1<<6) 69 | #define MCONTROL_H (1<<5) 70 | #define MCONTROL_S (1<<4) 71 | #define MCONTROL_U (1<<3) 72 | #define MCONTROL_EXECUTE (1<<2) 73 | #define MCONTROL_STORE (1<<1) 74 | #define MCONTROL_LOAD (1<<0) 75 | 76 | #define MCONTROL_TYPE_NONE 0 77 | #define MCONTROL_TYPE_MATCH 2 78 | 79 | #define MCONTROL_ACTION_DEBUG_EXCEPTION 0 80 | #define MCONTROL_ACTION_DEBUG_MODE 1 81 | #define MCONTROL_ACTION_TRACE_START 2 82 | #define MCONTROL_ACTION_TRACE_STOP 3 83 | #define MCONTROL_ACTION_TRACE_EMIT 4 84 | 85 | #define MCONTROL_MATCH_EQUAL 0 86 | #define MCONTROL_MATCH_NAPOT 1 87 | #define MCONTROL_MATCH_GE 2 88 | #define MCONTROL_MATCH_LT 3 89 | #define MCONTROL_MATCH_MASK_LOW 4 90 | #define MCONTROL_MATCH_MASK_HIGH 5 91 | 92 | #define MIP_SSIP (1 << IRQ_S_SOFT) 93 | #define MIP_HSIP (1 << IRQ_H_SOFT) 94 | #define MIP_MSIP (1 << IRQ_M_SOFT) 95 | #define MIP_STIP (1 << IRQ_S_TIMER) 96 | #define MIP_HTIP (1 << IRQ_H_TIMER) 97 | #define MIP_MTIP (1 << IRQ_M_TIMER) 98 | #define MIP_SEIP (1 << IRQ_S_EXT) 99 | #define MIP_HEIP (1 << IRQ_H_EXT) 100 | #define MIP_MEIP (1 << IRQ_M_EXT) 101 | 102 | #define SIP_SSIP MIP_SSIP 103 | #define SIP_STIP MIP_STIP 104 | 105 | #define PRV_U 0 106 | #define PRV_S 1 107 | #define PRV_H 2 108 | #define PRV_M 3 109 | 110 | #define VM_MBARE 0 111 | #define VM_MBB 1 112 | #define VM_MBBID 2 113 | #define VM_SV32 8 114 | #define VM_SV39 9 115 | #define VM_SV48 10 116 | 117 | #define IRQ_S_SOFT 1 118 | #define IRQ_H_SOFT 2 119 | #define IRQ_M_SOFT 3 120 | #define IRQ_S_TIMER 5 121 | #define IRQ_H_TIMER 6 122 | #define IRQ_M_TIMER 7 123 | #define IRQ_S_EXT 9 124 | #define IRQ_H_EXT 10 125 | #define IRQ_M_EXT 11 126 | #define IRQ_COP 12 127 | #define IRQ_HOST 13 128 | 129 | #define DEFAULT_RSTVEC 0x00001000 130 | #define DEFAULT_NMIVEC 0x00001004 131 | #define DEFAULT_MTVEC 0x00001010 132 | #define CONFIG_STRING_ADDR 0x0000100C 133 | #define EXT_IO_BASE 0x40000000 134 | #define DRAM_BASE 0x80000000 135 | 136 | // page table entry (PTE) fields 137 | #define PTE_V 0x001 // Valid 138 | #define PTE_R 0x002 // Read 139 | #define PTE_W 0x004 // Write 140 | #define PTE_X 0x008 // Execute 141 | #define PTE_U 0x010 // User 142 | #define PTE_G 0x020 // Global 143 | #define PTE_A 0x040 // Accessed 144 | #define PTE_D 0x080 // Dirty 145 | #define PTE_SOFT 0x300 // Reserved for Software 146 | 147 | #define PTE_PPN_SHIFT 10 148 | 149 | #define PTE_TABLE(PTE) (((PTE) & (PTE_V | PTE_R | PTE_W | PTE_X)) == PTE_V) 150 | 151 | #ifdef __riscv 152 | 153 | #ifdef __riscv64 154 | # define MSTATUS_SD MSTATUS64_SD 155 | # define SSTATUS_SD SSTATUS64_SD 156 | # define RISCV_PGLEVEL_BITS 9 157 | #else 158 | # define MSTATUS_SD MSTATUS32_SD 159 | # define SSTATUS_SD SSTATUS32_SD 160 | # define RISCV_PGLEVEL_BITS 10 161 | #endif 162 | #define RISCV_PGSHIFT 12 163 | #define RISCV_PGSIZE (1 << RISCV_PGSHIFT) 164 | 165 | #ifndef __ASSEMBLER__ 166 | 167 | #ifdef __GNUC__ 168 | 169 | #define read_csr(reg) ({ unsigned long __tmp; \ 170 | asm volatile ("csrr %0, " #reg : "=r"(__tmp)); \ 171 | __tmp; }) 172 | 173 | #define write_csr(reg, val) ({ \ 174 | if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ 175 | asm volatile ("csrw " #reg ", %0" :: "i"(val)); \ 176 | else \ 177 | asm volatile ("csrw " #reg ", %0" :: "r"(val)); }) 178 | 179 | #define swap_csr(reg, val) ({ unsigned long __tmp; \ 180 | if (__builtin_constant_p(val) && (unsigned long)(val) < 32) \ 181 | asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "i"(val)); \ 182 | else \ 183 | asm volatile ("csrrw %0, " #reg ", %1" : "=r"(__tmp) : "r"(val)); \ 184 | __tmp; }) 185 | 186 | #define set_csr(reg, bit) ({ unsigned long __tmp; \ 187 | if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ 188 | asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ 189 | else \ 190 | asm volatile ("csrrs %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ 191 | __tmp; }) 192 | 193 | #define clear_csr(reg, bit) ({ unsigned long __tmp; \ 194 | if (__builtin_constant_p(bit) && (unsigned long)(bit) < 32) \ 195 | asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "i"(bit)); \ 196 | else \ 197 | asm volatile ("csrrc %0, " #reg ", %1" : "=r"(__tmp) : "r"(bit)); \ 198 | __tmp; }) 199 | 200 | #define rdtime() read_csr(time) 201 | #define rdcycle() read_csr(cycle) 202 | #define rdinstret() read_csr(instret) 203 | 204 | #endif 205 | 206 | #endif 207 | 208 | #endif 209 | 210 | #endif 211 | /* Automatically generated by parse-opcodes */ 212 | #ifndef RISCV_ENCODING_H 213 | #define RISCV_ENCODING_H 214 | #define MATCH_BEQ 0x63 215 | #define MASK_BEQ 0x707f 216 | #define MATCH_BNE 0x1063 217 | #define MASK_BNE 0x707f 218 | #define MATCH_BLT 0x4063 219 | #define MASK_BLT 0x707f 220 | #define MATCH_BGE 0x5063 221 | #define MASK_BGE 0x707f 222 | #define MATCH_BLTU 0x6063 223 | #define MASK_BLTU 0x707f 224 | #define MATCH_BGEU 0x7063 225 | #define MASK_BGEU 0x707f 226 | #define MATCH_JALR 0x67 227 | #define MASK_JALR 0x707f 228 | #define MATCH_JAL 0x6f 229 | #define MASK_JAL 0x7f 230 | #define MATCH_LUI 0x37 231 | #define MASK_LUI 0x7f 232 | #define MATCH_AUIPC 0x17 233 | #define MASK_AUIPC 0x7f 234 | #define MATCH_ADDI 0x13 235 | #define MASK_ADDI 0x707f 236 | #define MATCH_SLLI 0x1013 237 | #define MASK_SLLI 0xfc00707f 238 | #define MATCH_SLTI 0x2013 239 | #define MASK_SLTI 0x707f 240 | #define MATCH_SLTIU 0x3013 241 | #define MASK_SLTIU 0x707f 242 | #define MATCH_XORI 0x4013 243 | #define MASK_XORI 0x707f 244 | #define MATCH_SRLI 0x5013 245 | #define MASK_SRLI 0xfc00707f 246 | #define MATCH_SRAI 0x40005013 247 | #define MASK_SRAI 0xfc00707f 248 | #define MATCH_ORI 0x6013 249 | #define MASK_ORI 0x707f 250 | #define MATCH_ANDI 0x7013 251 | #define MASK_ANDI 0x707f 252 | #define MATCH_ADD 0x33 253 | #define MASK_ADD 0xfe00707f 254 | #define MATCH_SUB 0x40000033 255 | #define MASK_SUB 0xfe00707f 256 | #define MATCH_SLL 0x1033 257 | #define MASK_SLL 0xfe00707f 258 | #define MATCH_SLT 0x2033 259 | #define MASK_SLT 0xfe00707f 260 | #define MATCH_SLTU 0x3033 261 | #define MASK_SLTU 0xfe00707f 262 | #define MATCH_XOR 0x4033 263 | #define MASK_XOR 0xfe00707f 264 | #define MATCH_SRL 0x5033 265 | #define MASK_SRL 0xfe00707f 266 | #define MATCH_SRA 0x40005033 267 | #define MASK_SRA 0xfe00707f 268 | #define MATCH_OR 0x6033 269 | #define MASK_OR 0xfe00707f 270 | #define MATCH_AND 0x7033 271 | #define MASK_AND 0xfe00707f 272 | #define MATCH_ADDIW 0x1b 273 | #define MASK_ADDIW 0x707f 274 | #define MATCH_SLLIW 0x101b 275 | #define MASK_SLLIW 0xfe00707f 276 | #define MATCH_SRLIW 0x501b 277 | #define MASK_SRLIW 0xfe00707f 278 | #define MATCH_SRAIW 0x4000501b 279 | #define MASK_SRAIW 0xfe00707f 280 | #define MATCH_ADDW 0x3b 281 | #define MASK_ADDW 0xfe00707f 282 | #define MATCH_SUBW 0x4000003b 283 | #define MASK_SUBW 0xfe00707f 284 | #define MATCH_SLLW 0x103b 285 | #define MASK_SLLW 0xfe00707f 286 | #define MATCH_SRLW 0x503b 287 | #define MASK_SRLW 0xfe00707f 288 | #define MATCH_SRAW 0x4000503b 289 | #define MASK_SRAW 0xfe00707f 290 | #define MATCH_LB 0x3 291 | #define MASK_LB 0x707f 292 | #define MATCH_LH 0x1003 293 | #define MASK_LH 0x707f 294 | #define MATCH_LW 0x2003 295 | #define MASK_LW 0x707f 296 | #define MATCH_LD 0x3003 297 | #define MASK_LD 0x707f 298 | #define MATCH_LBU 0x4003 299 | #define MASK_LBU 0x707f 300 | #define MATCH_LHU 0x5003 301 | #define MASK_LHU 0x707f 302 | #define MATCH_LWU 0x6003 303 | #define MASK_LWU 0x707f 304 | #define MATCH_SB 0x23 305 | #define MASK_SB 0x707f 306 | #define MATCH_SH 0x1023 307 | #define MASK_SH 0x707f 308 | #define MATCH_SW 0x2023 309 | #define MASK_SW 0x707f 310 | #define MATCH_SD 0x3023 311 | #define MASK_SD 0x707f 312 | #define MATCH_FENCE 0xf 313 | #define MASK_FENCE 0x707f 314 | #define MATCH_FENCE_I 0x100f 315 | #define MASK_FENCE_I 0x707f 316 | #define MATCH_MUL 0x2000033 317 | #define MASK_MUL 0xfe00707f 318 | #define MATCH_MULH 0x2001033 319 | #define MASK_MULH 0xfe00707f 320 | #define MATCH_MULHSU 0x2002033 321 | #define MASK_MULHSU 0xfe00707f 322 | #define MATCH_MULHU 0x2003033 323 | #define MASK_MULHU 0xfe00707f 324 | #define MATCH_DIV 0x2004033 325 | #define MASK_DIV 0xfe00707f 326 | #define MATCH_DIVU 0x2005033 327 | #define MASK_DIVU 0xfe00707f 328 | #define MATCH_REM 0x2006033 329 | #define MASK_REM 0xfe00707f 330 | #define MATCH_REMU 0x2007033 331 | #define MASK_REMU 0xfe00707f 332 | #define MATCH_MULW 0x200003b 333 | #define MASK_MULW 0xfe00707f 334 | #define MATCH_DIVW 0x200403b 335 | #define MASK_DIVW 0xfe00707f 336 | #define MATCH_DIVUW 0x200503b 337 | #define MASK_DIVUW 0xfe00707f 338 | #define MATCH_REMW 0x200603b 339 | #define MASK_REMW 0xfe00707f 340 | #define MATCH_REMUW 0x200703b 341 | #define MASK_REMUW 0xfe00707f 342 | #define MATCH_AMOADD_W 0x202f 343 | #define MASK_AMOADD_W 0xf800707f 344 | #define MATCH_AMOXOR_W 0x2000202f 345 | #define MASK_AMOXOR_W 0xf800707f 346 | #define MATCH_AMOOR_W 0x4000202f 347 | #define MASK_AMOOR_W 0xf800707f 348 | #define MATCH_AMOAND_W 0x6000202f 349 | #define MASK_AMOAND_W 0xf800707f 350 | #define MATCH_AMOMIN_W 0x8000202f 351 | #define MASK_AMOMIN_W 0xf800707f 352 | #define MATCH_AMOMAX_W 0xa000202f 353 | #define MASK_AMOMAX_W 0xf800707f 354 | #define MATCH_AMOMINU_W 0xc000202f 355 | #define MASK_AMOMINU_W 0xf800707f 356 | #define MATCH_AMOMAXU_W 0xe000202f 357 | #define MASK_AMOMAXU_W 0xf800707f 358 | #define MATCH_AMOSWAP_W 0x800202f 359 | #define MASK_AMOSWAP_W 0xf800707f 360 | #define MATCH_LR_W 0x1000202f 361 | #define MASK_LR_W 0xf9f0707f 362 | #define MATCH_SC_W 0x1800202f 363 | #define MASK_SC_W 0xf800707f 364 | #define MATCH_AMOADD_D 0x302f 365 | #define MASK_AMOADD_D 0xf800707f 366 | #define MATCH_AMOXOR_D 0x2000302f 367 | #define MASK_AMOXOR_D 0xf800707f 368 | #define MATCH_AMOOR_D 0x4000302f 369 | #define MASK_AMOOR_D 0xf800707f 370 | #define MATCH_AMOAND_D 0x6000302f 371 | #define MASK_AMOAND_D 0xf800707f 372 | #define MATCH_AMOMIN_D 0x8000302f 373 | #define MASK_AMOMIN_D 0xf800707f 374 | #define MATCH_AMOMAX_D 0xa000302f 375 | #define MASK_AMOMAX_D 0xf800707f 376 | #define MATCH_AMOMINU_D 0xc000302f 377 | #define MASK_AMOMINU_D 0xf800707f 378 | #define MATCH_AMOMAXU_D 0xe000302f 379 | #define MASK_AMOMAXU_D 0xf800707f 380 | #define MATCH_AMOSWAP_D 0x800302f 381 | #define MASK_AMOSWAP_D 0xf800707f 382 | #define MATCH_LR_D 0x1000302f 383 | #define MASK_LR_D 0xf9f0707f 384 | #define MATCH_SC_D 0x1800302f 385 | #define MASK_SC_D 0xf800707f 386 | #define MATCH_ECALL 0x73 387 | #define MASK_ECALL 0xffffffff 388 | #define MATCH_EBREAK 0x100073 389 | #define MASK_EBREAK 0xffffffff 390 | #define MATCH_URET 0x200073 391 | #define MASK_URET 0xffffffff 392 | #define MATCH_SRET 0x10200073 393 | #define MASK_SRET 0xffffffff 394 | #define MATCH_HRET 0x20200073 395 | #define MASK_HRET 0xffffffff 396 | #define MATCH_MRET 0x30200073 397 | #define MASK_MRET 0xffffffff 398 | #define MATCH_DRET 0x7b200073 399 | #define MASK_DRET 0xffffffff 400 | #define MATCH_SFENCE_VM 0x10400073 401 | #define MASK_SFENCE_VM 0xfff07fff 402 | #define MATCH_WFI 0x10500073 403 | #define MASK_WFI 0xffffffff 404 | #define MATCH_CSRRW 0x1073 405 | #define MASK_CSRRW 0x707f 406 | #define MATCH_CSRRS 0x2073 407 | #define MASK_CSRRS 0x707f 408 | #define MATCH_CSRRC 0x3073 409 | #define MASK_CSRRC 0x707f 410 | #define MATCH_CSRRWI 0x5073 411 | #define MASK_CSRRWI 0x707f 412 | #define MATCH_CSRRSI 0x6073 413 | #define MASK_CSRRSI 0x707f 414 | #define MATCH_CSRRCI 0x7073 415 | #define MASK_CSRRCI 0x707f 416 | #define MATCH_FADD_S 0x53 417 | #define MASK_FADD_S 0xfe00007f 418 | #define MATCH_FSUB_S 0x8000053 419 | #define MASK_FSUB_S 0xfe00007f 420 | #define MATCH_FMUL_S 0x10000053 421 | #define MASK_FMUL_S 0xfe00007f 422 | #define MATCH_FDIV_S 0x18000053 423 | #define MASK_FDIV_S 0xfe00007f 424 | #define MATCH_FSGNJ_S 0x20000053 425 | #define MASK_FSGNJ_S 0xfe00707f 426 | #define MATCH_FSGNJN_S 0x20001053 427 | #define MASK_FSGNJN_S 0xfe00707f 428 | #define MATCH_FSGNJX_S 0x20002053 429 | #define MASK_FSGNJX_S 0xfe00707f 430 | #define MATCH_FMIN_S 0x28000053 431 | #define MASK_FMIN_S 0xfe00707f 432 | #define MATCH_FMAX_S 0x28001053 433 | #define MASK_FMAX_S 0xfe00707f 434 | #define MATCH_FSQRT_S 0x58000053 435 | #define MASK_FSQRT_S 0xfff0007f 436 | #define MATCH_FADD_D 0x2000053 437 | #define MASK_FADD_D 0xfe00007f 438 | #define MATCH_FSUB_D 0xa000053 439 | #define MASK_FSUB_D 0xfe00007f 440 | #define MATCH_FMUL_D 0x12000053 441 | #define MASK_FMUL_D 0xfe00007f 442 | #define MATCH_FDIV_D 0x1a000053 443 | #define MASK_FDIV_D 0xfe00007f 444 | #define MATCH_FSGNJ_D 0x22000053 445 | #define MASK_FSGNJ_D 0xfe00707f 446 | #define MATCH_FSGNJN_D 0x22001053 447 | #define MASK_FSGNJN_D 0xfe00707f 448 | #define MATCH_FSGNJX_D 0x22002053 449 | #define MASK_FSGNJX_D 0xfe00707f 450 | #define MATCH_FMIN_D 0x2a000053 451 | #define MASK_FMIN_D 0xfe00707f 452 | #define MATCH_FMAX_D 0x2a001053 453 | #define MASK_FMAX_D 0xfe00707f 454 | #define MATCH_FCVT_S_D 0x40100053 455 | #define MASK_FCVT_S_D 0xfff0007f 456 | #define MATCH_FCVT_D_S 0x42000053 457 | #define MASK_FCVT_D_S 0xfff0007f 458 | #define MATCH_FSQRT_D 0x5a000053 459 | #define MASK_FSQRT_D 0xfff0007f 460 | #define MATCH_FLE_S 0xa0000053 461 | #define MASK_FLE_S 0xfe00707f 462 | #define MATCH_FLT_S 0xa0001053 463 | #define MASK_FLT_S 0xfe00707f 464 | #define MATCH_FEQ_S 0xa0002053 465 | #define MASK_FEQ_S 0xfe00707f 466 | #define MATCH_FLE_D 0xa2000053 467 | #define MASK_FLE_D 0xfe00707f 468 | #define MATCH_FLT_D 0xa2001053 469 | #define MASK_FLT_D 0xfe00707f 470 | #define MATCH_FEQ_D 0xa2002053 471 | #define MASK_FEQ_D 0xfe00707f 472 | #define MATCH_FCVT_W_S 0xc0000053 473 | #define MASK_FCVT_W_S 0xfff0007f 474 | #define MATCH_FCVT_WU_S 0xc0100053 475 | #define MASK_FCVT_WU_S 0xfff0007f 476 | #define MATCH_FCVT_L_S 0xc0200053 477 | #define MASK_FCVT_L_S 0xfff0007f 478 | #define MATCH_FCVT_LU_S 0xc0300053 479 | #define MASK_FCVT_LU_S 0xfff0007f 480 | #define MATCH_FMV_X_S 0xe0000053 481 | #define MASK_FMV_X_S 0xfff0707f 482 | #define MATCH_FCLASS_S 0xe0001053 483 | #define MASK_FCLASS_S 0xfff0707f 484 | #define MATCH_FCVT_W_D 0xc2000053 485 | #define MASK_FCVT_W_D 0xfff0007f 486 | #define MATCH_FCVT_WU_D 0xc2100053 487 | #define MASK_FCVT_WU_D 0xfff0007f 488 | #define MATCH_FCVT_L_D 0xc2200053 489 | #define MASK_FCVT_L_D 0xfff0007f 490 | #define MATCH_FCVT_LU_D 0xc2300053 491 | #define MASK_FCVT_LU_D 0xfff0007f 492 | #define MATCH_FMV_X_D 0xe2000053 493 | #define MASK_FMV_X_D 0xfff0707f 494 | #define MATCH_FCLASS_D 0xe2001053 495 | #define MASK_FCLASS_D 0xfff0707f 496 | #define MATCH_FCVT_S_W 0xd0000053 497 | #define MASK_FCVT_S_W 0xfff0007f 498 | #define MATCH_FCVT_S_WU 0xd0100053 499 | #define MASK_FCVT_S_WU 0xfff0007f 500 | #define MATCH_FCVT_S_L 0xd0200053 501 | #define MASK_FCVT_S_L 0xfff0007f 502 | #define MATCH_FCVT_S_LU 0xd0300053 503 | #define MASK_FCVT_S_LU 0xfff0007f 504 | #define MATCH_FMV_S_X 0xf0000053 505 | #define MASK_FMV_S_X 0xfff0707f 506 | #define MATCH_FCVT_D_W 0xd2000053 507 | #define MASK_FCVT_D_W 0xfff0007f 508 | #define MATCH_FCVT_D_WU 0xd2100053 509 | #define MASK_FCVT_D_WU 0xfff0007f 510 | #define MATCH_FCVT_D_L 0xd2200053 511 | #define MASK_FCVT_D_L 0xfff0007f 512 | #define MATCH_FCVT_D_LU 0xd2300053 513 | #define MASK_FCVT_D_LU 0xfff0007f 514 | #define MATCH_FMV_D_X 0xf2000053 515 | #define MASK_FMV_D_X 0xfff0707f 516 | #define MATCH_FLW 0x2007 517 | #define MASK_FLW 0x707f 518 | #define MATCH_FLD 0x3007 519 | #define MASK_FLD 0x707f 520 | #define MATCH_FSW 0x2027 521 | #define MASK_FSW 0x707f 522 | #define MATCH_FSD 0x3027 523 | #define MASK_FSD 0x707f 524 | #define MATCH_FMADD_S 0x43 525 | #define MASK_FMADD_S 0x600007f 526 | #define MATCH_FMSUB_S 0x47 527 | #define MASK_FMSUB_S 0x600007f 528 | #define MATCH_FNMSUB_S 0x4b 529 | #define MASK_FNMSUB_S 0x600007f 530 | #define MATCH_FNMADD_S 0x4f 531 | #define MASK_FNMADD_S 0x600007f 532 | #define MATCH_FMADD_D 0x2000043 533 | #define MASK_FMADD_D 0x600007f 534 | #define MATCH_FMSUB_D 0x2000047 535 | #define MASK_FMSUB_D 0x600007f 536 | #define MATCH_FNMSUB_D 0x200004b 537 | #define MASK_FNMSUB_D 0x600007f 538 | #define MATCH_FNMADD_D 0x200004f 539 | #define MASK_FNMADD_D 0x600007f 540 | #define MATCH_C_NOP 0x1 541 | #define MASK_C_NOP 0xffff 542 | #define MATCH_C_ADDI16SP 0x6101 543 | #define MASK_C_ADDI16SP 0xef83 544 | #define MATCH_C_JR 0x8002 545 | #define MASK_C_JR 0xf07f 546 | #define MATCH_C_JALR 0x9002 547 | #define MASK_C_JALR 0xf07f 548 | #define MATCH_C_EBREAK 0x9002 549 | #define MASK_C_EBREAK 0xffff 550 | #define MATCH_C_LD 0x6000 551 | #define MASK_C_LD 0xe003 552 | #define MATCH_C_SD 0xe000 553 | #define MASK_C_SD 0xe003 554 | #define MATCH_C_ADDIW 0x2001 555 | #define MASK_C_ADDIW 0xe003 556 | #define MATCH_C_LDSP 0x6002 557 | #define MASK_C_LDSP 0xe003 558 | #define MATCH_C_SDSP 0xe002 559 | #define MASK_C_SDSP 0xe003 560 | #define MATCH_C_ADDI4SPN 0x0 561 | #define MASK_C_ADDI4SPN 0xe003 562 | #define MATCH_C_FLD 0x2000 563 | #define MASK_C_FLD 0xe003 564 | #define MATCH_C_LW 0x4000 565 | #define MASK_C_LW 0xe003 566 | #define MATCH_C_FLW 0x6000 567 | #define MASK_C_FLW 0xe003 568 | #define MATCH_C_FSD 0xa000 569 | #define MASK_C_FSD 0xe003 570 | #define MATCH_C_SW 0xc000 571 | #define MASK_C_SW 0xe003 572 | #define MATCH_C_FSW 0xe000 573 | #define MASK_C_FSW 0xe003 574 | #define MATCH_C_ADDI 0x1 575 | #define MASK_C_ADDI 0xe003 576 | #define MATCH_C_JAL 0x2001 577 | #define MASK_C_JAL 0xe003 578 | #define MATCH_C_LI 0x4001 579 | #define MASK_C_LI 0xe003 580 | #define MATCH_C_LUI 0x6001 581 | #define MASK_C_LUI 0xe003 582 | #define MATCH_C_SRLI 0x8001 583 | #define MASK_C_SRLI 0xec03 584 | #define MATCH_C_SRAI 0x8401 585 | #define MASK_C_SRAI 0xec03 586 | #define MATCH_C_ANDI 0x8801 587 | #define MASK_C_ANDI 0xec03 588 | #define MATCH_C_SUB 0x8c01 589 | #define MASK_C_SUB 0xfc63 590 | #define MATCH_C_XOR 0x8c21 591 | #define MASK_C_XOR 0xfc63 592 | #define MATCH_C_OR 0x8c41 593 | #define MASK_C_OR 0xfc63 594 | #define MATCH_C_AND 0x8c61 595 | #define MASK_C_AND 0xfc63 596 | #define MATCH_C_SUBW 0x9c01 597 | #define MASK_C_SUBW 0xfc63 598 | #define MATCH_C_ADDW 0x9c21 599 | #define MASK_C_ADDW 0xfc63 600 | #define MATCH_C_J 0xa001 601 | #define MASK_C_J 0xe003 602 | #define MATCH_C_BEQZ 0xc001 603 | #define MASK_C_BEQZ 0xe003 604 | #define MATCH_C_BNEZ 0xe001 605 | #define MASK_C_BNEZ 0xe003 606 | #define MATCH_C_SLLI 0x2 607 | #define MASK_C_SLLI 0xe003 608 | #define MATCH_C_FLDSP 0x2002 609 | #define MASK_C_FLDSP 0xe003 610 | #define MATCH_C_LWSP 0x4002 611 | #define MASK_C_LWSP 0xe003 612 | #define MATCH_C_FLWSP 0x6002 613 | #define MASK_C_FLWSP 0xe003 614 | #define MATCH_C_MV 0x8002 615 | #define MASK_C_MV 0xf003 616 | #define MATCH_C_ADD 0x9002 617 | #define MASK_C_ADD 0xf003 618 | #define MATCH_C_FSDSP 0xa002 619 | #define MASK_C_FSDSP 0xe003 620 | #define MATCH_C_SWSP 0xc002 621 | #define MASK_C_SWSP 0xe003 622 | #define MATCH_C_FSWSP 0xe002 623 | #define MASK_C_FSWSP 0xe003 624 | #define MATCH_CUSTOM0 0xb 625 | #define MASK_CUSTOM0 0x707f 626 | #define MATCH_CUSTOM0_RS1 0x200b 627 | #define MASK_CUSTOM0_RS1 0x707f 628 | #define MATCH_CUSTOM0_RS1_RS2 0x300b 629 | #define MASK_CUSTOM0_RS1_RS2 0x707f 630 | #define MATCH_CUSTOM0_RD 0x400b 631 | #define MASK_CUSTOM0_RD 0x707f 632 | #define MATCH_CUSTOM0_RD_RS1 0x600b 633 | #define MASK_CUSTOM0_RD_RS1 0x707f 634 | #define MATCH_CUSTOM0_RD_RS1_RS2 0x700b 635 | #define MASK_CUSTOM0_RD_RS1_RS2 0x707f 636 | #define MATCH_CUSTOM1 0x2b 637 | #define MASK_CUSTOM1 0x707f 638 | #define MATCH_CUSTOM1_RS1 0x202b 639 | #define MASK_CUSTOM1_RS1 0x707f 640 | #define MATCH_CUSTOM1_RS1_RS2 0x302b 641 | #define MASK_CUSTOM1_RS1_RS2 0x707f 642 | #define MATCH_CUSTOM1_RD 0x402b 643 | #define MASK_CUSTOM1_RD 0x707f 644 | #define MATCH_CUSTOM1_RD_RS1 0x602b 645 | #define MASK_CUSTOM1_RD_RS1 0x707f 646 | #define MATCH_CUSTOM1_RD_RS1_RS2 0x702b 647 | #define MASK_CUSTOM1_RD_RS1_RS2 0x707f 648 | #define MATCH_CUSTOM2 0x5b 649 | #define MASK_CUSTOM2 0x707f 650 | #define MATCH_CUSTOM2_RS1 0x205b 651 | #define MASK_CUSTOM2_RS1 0x707f 652 | #define MATCH_CUSTOM2_RS1_RS2 0x305b 653 | #define MASK_CUSTOM2_RS1_RS2 0x707f 654 | #define MATCH_CUSTOM2_RD 0x405b 655 | #define MASK_CUSTOM2_RD 0x707f 656 | #define MATCH_CUSTOM2_RD_RS1 0x605b 657 | #define MASK_CUSTOM2_RD_RS1 0x707f 658 | #define MATCH_CUSTOM2_RD_RS1_RS2 0x705b 659 | #define MASK_CUSTOM2_RD_RS1_RS2 0x707f 660 | #define MATCH_CUSTOM3 0x7b 661 | #define MASK_CUSTOM3 0x707f 662 | #define MATCH_CUSTOM3_RS1 0x207b 663 | #define MASK_CUSTOM3_RS1 0x707f 664 | #define MATCH_CUSTOM3_RS1_RS2 0x307b 665 | #define MASK_CUSTOM3_RS1_RS2 0x707f 666 | #define MATCH_CUSTOM3_RD 0x407b 667 | #define MASK_CUSTOM3_RD 0x707f 668 | #define MATCH_CUSTOM3_RD_RS1 0x607b 669 | #define MASK_CUSTOM3_RD_RS1 0x707f 670 | #define MATCH_CUSTOM3_RD_RS1_RS2 0x707b 671 | #define MASK_CUSTOM3_RD_RS1_RS2 0x707f 672 | #define CSR_FFLAGS 0x1 673 | #define CSR_FRM 0x2 674 | #define CSR_FCSR 0x3 675 | #define CSR_CYCLE 0xc00 676 | #define CSR_TIME 0xc01 677 | #define CSR_INSTRET 0xc02 678 | #define CSR_HPMCOUNTER3 0xc03 679 | #define CSR_HPMCOUNTER4 0xc04 680 | #define CSR_HPMCOUNTER5 0xc05 681 | #define CSR_HPMCOUNTER6 0xc06 682 | #define CSR_HPMCOUNTER7 0xc07 683 | #define CSR_HPMCOUNTER8 0xc08 684 | #define CSR_HPMCOUNTER9 0xc09 685 | #define CSR_HPMCOUNTER10 0xc0a 686 | #define CSR_HPMCOUNTER11 0xc0b 687 | #define CSR_HPMCOUNTER12 0xc0c 688 | #define CSR_HPMCOUNTER13 0xc0d 689 | #define CSR_HPMCOUNTER14 0xc0e 690 | #define CSR_HPMCOUNTER15 0xc0f 691 | #define CSR_HPMCOUNTER16 0xc10 692 | #define CSR_HPMCOUNTER17 0xc11 693 | #define CSR_HPMCOUNTER18 0xc12 694 | #define CSR_HPMCOUNTER19 0xc13 695 | #define CSR_HPMCOUNTER20 0xc14 696 | #define CSR_HPMCOUNTER21 0xc15 697 | #define CSR_HPMCOUNTER22 0xc16 698 | #define CSR_HPMCOUNTER23 0xc17 699 | #define CSR_HPMCOUNTER24 0xc18 700 | #define CSR_HPMCOUNTER25 0xc19 701 | #define CSR_HPMCOUNTER26 0xc1a 702 | #define CSR_HPMCOUNTER27 0xc1b 703 | #define CSR_HPMCOUNTER28 0xc1c 704 | #define CSR_HPMCOUNTER29 0xc1d 705 | #define CSR_HPMCOUNTER30 0xc1e 706 | #define CSR_HPMCOUNTER31 0xc1f 707 | #define CSR_SSTATUS 0x100 708 | #define CSR_SIE 0x104 709 | #define CSR_STVEC 0x105 710 | #define CSR_SSCRATCH 0x140 711 | #define CSR_SEPC 0x141 712 | #define CSR_SCAUSE 0x142 713 | #define CSR_SBADADDR 0x143 714 | #define CSR_SIP 0x144 715 | #define CSR_SPTBR 0x180 716 | #define CSR_MSTATUS 0x300 717 | #define CSR_MISA 0x301 718 | #define CSR_MEDELEG 0x302 719 | #define CSR_MIDELEG 0x303 720 | #define CSR_MIE 0x304 721 | #define CSR_MTVEC 0x305 722 | #define CSR_MSCRATCH 0x340 723 | #define CSR_MEPC 0x341 724 | #define CSR_MCAUSE 0x342 725 | #define CSR_MBADADDR 0x343 726 | #define CSR_MIP 0x344 727 | #define CSR_TSELECT 0x7a0 728 | #define CSR_TDATA1 0x7a1 729 | #define CSR_TDATA2 0x7a2 730 | #define CSR_TDATA3 0x7a3 731 | #define CSR_DCSR 0x7b0 732 | #define CSR_DPC 0x7b1 733 | #define CSR_DSCRATCH 0x7b2 734 | #define CSR_MCYCLE 0xb00 735 | #define CSR_MINSTRET 0xb02 736 | #define CSR_MHPMCOUNTER3 0xb03 737 | #define CSR_MHPMCOUNTER4 0xb04 738 | #define CSR_MHPMCOUNTER5 0xb05 739 | #define CSR_MHPMCOUNTER6 0xb06 740 | #define CSR_MHPMCOUNTER7 0xb07 741 | #define CSR_MHPMCOUNTER8 0xb08 742 | #define CSR_MHPMCOUNTER9 0xb09 743 | #define CSR_MHPMCOUNTER10 0xb0a 744 | #define CSR_MHPMCOUNTER11 0xb0b 745 | #define CSR_MHPMCOUNTER12 0xb0c 746 | #define CSR_MHPMCOUNTER13 0xb0d 747 | #define CSR_MHPMCOUNTER14 0xb0e 748 | #define CSR_MHPMCOUNTER15 0xb0f 749 | #define CSR_MHPMCOUNTER16 0xb10 750 | #define CSR_MHPMCOUNTER17 0xb11 751 | #define CSR_MHPMCOUNTER18 0xb12 752 | #define CSR_MHPMCOUNTER19 0xb13 753 | #define CSR_MHPMCOUNTER20 0xb14 754 | #define CSR_MHPMCOUNTER21 0xb15 755 | #define CSR_MHPMCOUNTER22 0xb16 756 | #define CSR_MHPMCOUNTER23 0xb17 757 | #define CSR_MHPMCOUNTER24 0xb18 758 | #define CSR_MHPMCOUNTER25 0xb19 759 | #define CSR_MHPMCOUNTER26 0xb1a 760 | #define CSR_MHPMCOUNTER27 0xb1b 761 | #define CSR_MHPMCOUNTER28 0xb1c 762 | #define CSR_MHPMCOUNTER29 0xb1d 763 | #define CSR_MHPMCOUNTER30 0xb1e 764 | #define CSR_MHPMCOUNTER31 0xb1f 765 | #define CSR_MUCOUNTEREN 0x320 766 | #define CSR_MSCOUNTEREN 0x321 767 | #define CSR_MHPMEVENT3 0x323 768 | #define CSR_MHPMEVENT4 0x324 769 | #define CSR_MHPMEVENT5 0x325 770 | #define CSR_MHPMEVENT6 0x326 771 | #define CSR_MHPMEVENT7 0x327 772 | #define CSR_MHPMEVENT8 0x328 773 | #define CSR_MHPMEVENT9 0x329 774 | #define CSR_MHPMEVENT10 0x32a 775 | #define CSR_MHPMEVENT11 0x32b 776 | #define CSR_MHPMEVENT12 0x32c 777 | #define CSR_MHPMEVENT13 0x32d 778 | #define CSR_MHPMEVENT14 0x32e 779 | #define CSR_MHPMEVENT15 0x32f 780 | #define CSR_MHPMEVENT16 0x330 781 | #define CSR_MHPMEVENT17 0x331 782 | #define CSR_MHPMEVENT18 0x332 783 | #define CSR_MHPMEVENT19 0x333 784 | #define CSR_MHPMEVENT20 0x334 785 | #define CSR_MHPMEVENT21 0x335 786 | #define CSR_MHPMEVENT22 0x336 787 | #define CSR_MHPMEVENT23 0x337 788 | #define CSR_MHPMEVENT24 0x338 789 | #define CSR_MHPMEVENT25 0x339 790 | #define CSR_MHPMEVENT26 0x33a 791 | #define CSR_MHPMEVENT27 0x33b 792 | #define CSR_MHPMEVENT28 0x33c 793 | #define CSR_MHPMEVENT29 0x33d 794 | #define CSR_MHPMEVENT30 0x33e 795 | #define CSR_MHPMEVENT31 0x33f 796 | #define CSR_MVENDORID 0xf11 797 | #define CSR_MARCHID 0xf12 798 | #define CSR_MIMPID 0xf13 799 | #define CSR_MHARTID 0xf14 800 | #define CSR_CYCLEH 0xc80 801 | #define CSR_TIMEH 0xc81 802 | #define CSR_INSTRETH 0xc82 803 | #define CSR_HPMCOUNTER3H 0xc83 804 | #define CSR_HPMCOUNTER4H 0xc84 805 | #define CSR_HPMCOUNTER5H 0xc85 806 | #define CSR_HPMCOUNTER6H 0xc86 807 | #define CSR_HPMCOUNTER7H 0xc87 808 | #define CSR_HPMCOUNTER8H 0xc88 809 | #define CSR_HPMCOUNTER9H 0xc89 810 | #define CSR_HPMCOUNTER10H 0xc8a 811 | #define CSR_HPMCOUNTER11H 0xc8b 812 | #define CSR_HPMCOUNTER12H 0xc8c 813 | #define CSR_HPMCOUNTER13H 0xc8d 814 | #define CSR_HPMCOUNTER14H 0xc8e 815 | #define CSR_HPMCOUNTER15H 0xc8f 816 | #define CSR_HPMCOUNTER16H 0xc90 817 | #define CSR_HPMCOUNTER17H 0xc91 818 | #define CSR_HPMCOUNTER18H 0xc92 819 | #define CSR_HPMCOUNTER19H 0xc93 820 | #define CSR_HPMCOUNTER20H 0xc94 821 | #define CSR_HPMCOUNTER21H 0xc95 822 | #define CSR_HPMCOUNTER22H 0xc96 823 | #define CSR_HPMCOUNTER23H 0xc97 824 | #define CSR_HPMCOUNTER24H 0xc98 825 | #define CSR_HPMCOUNTER25H 0xc99 826 | #define CSR_HPMCOUNTER26H 0xc9a 827 | #define CSR_HPMCOUNTER27H 0xc9b 828 | #define CSR_HPMCOUNTER28H 0xc9c 829 | #define CSR_HPMCOUNTER29H 0xc9d 830 | #define CSR_HPMCOUNTER30H 0xc9e 831 | #define CSR_HPMCOUNTER31H 0xc9f 832 | #define CSR_MCYCLEH 0xb80 833 | #define CSR_MINSTRETH 0xb82 834 | #define CSR_MHPMCOUNTER3H 0xb83 835 | #define CSR_MHPMCOUNTER4H 0xb84 836 | #define CSR_MHPMCOUNTER5H 0xb85 837 | #define CSR_MHPMCOUNTER6H 0xb86 838 | #define CSR_MHPMCOUNTER7H 0xb87 839 | #define CSR_MHPMCOUNTER8H 0xb88 840 | #define CSR_MHPMCOUNTER9H 0xb89 841 | #define CSR_MHPMCOUNTER10H 0xb8a 842 | #define CSR_MHPMCOUNTER11H 0xb8b 843 | #define CSR_MHPMCOUNTER12H 0xb8c 844 | #define CSR_MHPMCOUNTER13H 0xb8d 845 | #define CSR_MHPMCOUNTER14H 0xb8e 846 | #define CSR_MHPMCOUNTER15H 0xb8f 847 | #define CSR_MHPMCOUNTER16H 0xb90 848 | #define CSR_MHPMCOUNTER17H 0xb91 849 | #define CSR_MHPMCOUNTER18H 0xb92 850 | #define CSR_MHPMCOUNTER19H 0xb93 851 | #define CSR_MHPMCOUNTER20H 0xb94 852 | #define CSR_MHPMCOUNTER21H 0xb95 853 | #define CSR_MHPMCOUNTER22H 0xb96 854 | #define CSR_MHPMCOUNTER23H 0xb97 855 | #define CSR_MHPMCOUNTER24H 0xb98 856 | #define CSR_MHPMCOUNTER25H 0xb99 857 | #define CSR_MHPMCOUNTER26H 0xb9a 858 | #define CSR_MHPMCOUNTER27H 0xb9b 859 | #define CSR_MHPMCOUNTER28H 0xb9c 860 | #define CSR_MHPMCOUNTER29H 0xb9d 861 | #define CSR_MHPMCOUNTER30H 0xb9e 862 | #define CSR_MHPMCOUNTER31H 0xb9f 863 | #define CAUSE_MISALIGNED_FETCH 0x0 864 | #define CAUSE_FAULT_FETCH 0x1 865 | #define CAUSE_ILLEGAL_INSTRUCTION 0x2 866 | #define CAUSE_BREAKPOINT 0x3 867 | #define CAUSE_MISALIGNED_LOAD 0x4 868 | #define CAUSE_FAULT_LOAD 0x5 869 | #define CAUSE_MISALIGNED_STORE 0x6 870 | #define CAUSE_FAULT_STORE 0x7 871 | #define CAUSE_USER_ECALL 0x8 872 | #define CAUSE_SUPERVISOR_ECALL 0x9 873 | #define CAUSE_HYPERVISOR_ECALL 0xa 874 | #define CAUSE_MACHINE_ECALL 0xb 875 | #endif 876 | #ifdef DECLARE_INSN 877 | DECLARE_INSN(beq, MATCH_BEQ, MASK_BEQ) 878 | DECLARE_INSN(bne, MATCH_BNE, MASK_BNE) 879 | DECLARE_INSN(blt, MATCH_BLT, MASK_BLT) 880 | DECLARE_INSN(bge, MATCH_BGE, MASK_BGE) 881 | DECLARE_INSN(bltu, MATCH_BLTU, MASK_BLTU) 882 | DECLARE_INSN(bgeu, MATCH_BGEU, MASK_BGEU) 883 | DECLARE_INSN(jalr, MATCH_JALR, MASK_JALR) 884 | DECLARE_INSN(jal, MATCH_JAL, MASK_JAL) 885 | DECLARE_INSN(lui, MATCH_LUI, MASK_LUI) 886 | DECLARE_INSN(auipc, MATCH_AUIPC, MASK_AUIPC) 887 | DECLARE_INSN(addi, MATCH_ADDI, MASK_ADDI) 888 | DECLARE_INSN(slli, MATCH_SLLI, MASK_SLLI) 889 | DECLARE_INSN(slti, MATCH_SLTI, MASK_SLTI) 890 | DECLARE_INSN(sltiu, MATCH_SLTIU, MASK_SLTIU) 891 | DECLARE_INSN(xori, MATCH_XORI, MASK_XORI) 892 | DECLARE_INSN(srli, MATCH_SRLI, MASK_SRLI) 893 | DECLARE_INSN(srai, MATCH_SRAI, MASK_SRAI) 894 | DECLARE_INSN(ori, MATCH_ORI, MASK_ORI) 895 | DECLARE_INSN(andi, MATCH_ANDI, MASK_ANDI) 896 | DECLARE_INSN(add, MATCH_ADD, MASK_ADD) 897 | DECLARE_INSN(sub, MATCH_SUB, MASK_SUB) 898 | DECLARE_INSN(sll, MATCH_SLL, MASK_SLL) 899 | DECLARE_INSN(slt, MATCH_SLT, MASK_SLT) 900 | DECLARE_INSN(sltu, MATCH_SLTU, MASK_SLTU) 901 | DECLARE_INSN(xor, MATCH_XOR, MASK_XOR) 902 | DECLARE_INSN(srl, MATCH_SRL, MASK_SRL) 903 | DECLARE_INSN(sra, MATCH_SRA, MASK_SRA) 904 | DECLARE_INSN(or, MATCH_OR, MASK_OR) 905 | DECLARE_INSN(and, MATCH_AND, MASK_AND) 906 | DECLARE_INSN(addiw, MATCH_ADDIW, MASK_ADDIW) 907 | DECLARE_INSN(slliw, MATCH_SLLIW, MASK_SLLIW) 908 | DECLARE_INSN(srliw, MATCH_SRLIW, MASK_SRLIW) 909 | DECLARE_INSN(sraiw, MATCH_SRAIW, MASK_SRAIW) 910 | DECLARE_INSN(addw, MATCH_ADDW, MASK_ADDW) 911 | DECLARE_INSN(subw, MATCH_SUBW, MASK_SUBW) 912 | DECLARE_INSN(sllw, MATCH_SLLW, MASK_SLLW) 913 | DECLARE_INSN(srlw, MATCH_SRLW, MASK_SRLW) 914 | DECLARE_INSN(sraw, MATCH_SRAW, MASK_SRAW) 915 | DECLARE_INSN(lb, MATCH_LB, MASK_LB) 916 | DECLARE_INSN(lh, MATCH_LH, MASK_LH) 917 | DECLARE_INSN(lw, MATCH_LW, MASK_LW) 918 | DECLARE_INSN(ld, MATCH_LD, MASK_LD) 919 | DECLARE_INSN(lbu, MATCH_LBU, MASK_LBU) 920 | DECLARE_INSN(lhu, MATCH_LHU, MASK_LHU) 921 | DECLARE_INSN(lwu, MATCH_LWU, MASK_LWU) 922 | DECLARE_INSN(sb, MATCH_SB, MASK_SB) 923 | DECLARE_INSN(sh, MATCH_SH, MASK_SH) 924 | DECLARE_INSN(sw, MATCH_SW, MASK_SW) 925 | DECLARE_INSN(sd, MATCH_SD, MASK_SD) 926 | DECLARE_INSN(fence, MATCH_FENCE, MASK_FENCE) 927 | DECLARE_INSN(fence_i, MATCH_FENCE_I, MASK_FENCE_I) 928 | DECLARE_INSN(mul, MATCH_MUL, MASK_MUL) 929 | DECLARE_INSN(mulh, MATCH_MULH, MASK_MULH) 930 | DECLARE_INSN(mulhsu, MATCH_MULHSU, MASK_MULHSU) 931 | DECLARE_INSN(mulhu, MATCH_MULHU, MASK_MULHU) 932 | DECLARE_INSN(div, MATCH_DIV, MASK_DIV) 933 | DECLARE_INSN(divu, MATCH_DIVU, MASK_DIVU) 934 | DECLARE_INSN(rem, MATCH_REM, MASK_REM) 935 | DECLARE_INSN(remu, MATCH_REMU, MASK_REMU) 936 | DECLARE_INSN(mulw, MATCH_MULW, MASK_MULW) 937 | DECLARE_INSN(divw, MATCH_DIVW, MASK_DIVW) 938 | DECLARE_INSN(divuw, MATCH_DIVUW, MASK_DIVUW) 939 | DECLARE_INSN(remw, MATCH_REMW, MASK_REMW) 940 | DECLARE_INSN(remuw, MATCH_REMUW, MASK_REMUW) 941 | DECLARE_INSN(amoadd_w, MATCH_AMOADD_W, MASK_AMOADD_W) 942 | DECLARE_INSN(amoxor_w, MATCH_AMOXOR_W, MASK_AMOXOR_W) 943 | DECLARE_INSN(amoor_w, MATCH_AMOOR_W, MASK_AMOOR_W) 944 | DECLARE_INSN(amoand_w, MATCH_AMOAND_W, MASK_AMOAND_W) 945 | DECLARE_INSN(amomin_w, MATCH_AMOMIN_W, MASK_AMOMIN_W) 946 | DECLARE_INSN(amomax_w, MATCH_AMOMAX_W, MASK_AMOMAX_W) 947 | DECLARE_INSN(amominu_w, MATCH_AMOMINU_W, MASK_AMOMINU_W) 948 | DECLARE_INSN(amomaxu_w, MATCH_AMOMAXU_W, MASK_AMOMAXU_W) 949 | DECLARE_INSN(amoswap_w, MATCH_AMOSWAP_W, MASK_AMOSWAP_W) 950 | DECLARE_INSN(lr_w, MATCH_LR_W, MASK_LR_W) 951 | DECLARE_INSN(sc_w, MATCH_SC_W, MASK_SC_W) 952 | DECLARE_INSN(amoadd_d, MATCH_AMOADD_D, MASK_AMOADD_D) 953 | DECLARE_INSN(amoxor_d, MATCH_AMOXOR_D, MASK_AMOXOR_D) 954 | DECLARE_INSN(amoor_d, MATCH_AMOOR_D, MASK_AMOOR_D) 955 | DECLARE_INSN(amoand_d, MATCH_AMOAND_D, MASK_AMOAND_D) 956 | DECLARE_INSN(amomin_d, MATCH_AMOMIN_D, MASK_AMOMIN_D) 957 | DECLARE_INSN(amomax_d, MATCH_AMOMAX_D, MASK_AMOMAX_D) 958 | DECLARE_INSN(amominu_d, MATCH_AMOMINU_D, MASK_AMOMINU_D) 959 | DECLARE_INSN(amomaxu_d, MATCH_AMOMAXU_D, MASK_AMOMAXU_D) 960 | DECLARE_INSN(amoswap_d, MATCH_AMOSWAP_D, MASK_AMOSWAP_D) 961 | DECLARE_INSN(lr_d, MATCH_LR_D, MASK_LR_D) 962 | DECLARE_INSN(sc_d, MATCH_SC_D, MASK_SC_D) 963 | DECLARE_INSN(ecall, MATCH_ECALL, MASK_ECALL) 964 | DECLARE_INSN(ebreak, MATCH_EBREAK, MASK_EBREAK) 965 | DECLARE_INSN(uret, MATCH_URET, MASK_URET) 966 | DECLARE_INSN(sret, MATCH_SRET, MASK_SRET) 967 | DECLARE_INSN(hret, MATCH_HRET, MASK_HRET) 968 | DECLARE_INSN(mret, MATCH_MRET, MASK_MRET) 969 | DECLARE_INSN(dret, MATCH_DRET, MASK_DRET) 970 | DECLARE_INSN(sfence_vm, MATCH_SFENCE_VM, MASK_SFENCE_VM) 971 | DECLARE_INSN(wfi, MATCH_WFI, MASK_WFI) 972 | DECLARE_INSN(csrrw, MATCH_CSRRW, MASK_CSRRW) 973 | DECLARE_INSN(csrrs, MATCH_CSRRS, MASK_CSRRS) 974 | DECLARE_INSN(csrrc, MATCH_CSRRC, MASK_CSRRC) 975 | DECLARE_INSN(csrrwi, MATCH_CSRRWI, MASK_CSRRWI) 976 | DECLARE_INSN(csrrsi, MATCH_CSRRSI, MASK_CSRRSI) 977 | DECLARE_INSN(csrrci, MATCH_CSRRCI, MASK_CSRRCI) 978 | DECLARE_INSN(fadd_s, MATCH_FADD_S, MASK_FADD_S) 979 | DECLARE_INSN(fsub_s, MATCH_FSUB_S, MASK_FSUB_S) 980 | DECLARE_INSN(fmul_s, MATCH_FMUL_S, MASK_FMUL_S) 981 | DECLARE_INSN(fdiv_s, MATCH_FDIV_S, MASK_FDIV_S) 982 | DECLARE_INSN(fsgnj_s, MATCH_FSGNJ_S, MASK_FSGNJ_S) 983 | DECLARE_INSN(fsgnjn_s, MATCH_FSGNJN_S, MASK_FSGNJN_S) 984 | DECLARE_INSN(fsgnjx_s, MATCH_FSGNJX_S, MASK_FSGNJX_S) 985 | DECLARE_INSN(fmin_s, MATCH_FMIN_S, MASK_FMIN_S) 986 | DECLARE_INSN(fmax_s, MATCH_FMAX_S, MASK_FMAX_S) 987 | DECLARE_INSN(fsqrt_s, MATCH_FSQRT_S, MASK_FSQRT_S) 988 | DECLARE_INSN(fadd_d, MATCH_FADD_D, MASK_FADD_D) 989 | DECLARE_INSN(fsub_d, MATCH_FSUB_D, MASK_FSUB_D) 990 | DECLARE_INSN(fmul_d, MATCH_FMUL_D, MASK_FMUL_D) 991 | DECLARE_INSN(fdiv_d, MATCH_FDIV_D, MASK_FDIV_D) 992 | DECLARE_INSN(fsgnj_d, MATCH_FSGNJ_D, MASK_FSGNJ_D) 993 | DECLARE_INSN(fsgnjn_d, MATCH_FSGNJN_D, MASK_FSGNJN_D) 994 | DECLARE_INSN(fsgnjx_d, MATCH_FSGNJX_D, MASK_FSGNJX_D) 995 | DECLARE_INSN(fmin_d, MATCH_FMIN_D, MASK_FMIN_D) 996 | DECLARE_INSN(fmax_d, MATCH_FMAX_D, MASK_FMAX_D) 997 | DECLARE_INSN(fcvt_s_d, MATCH_FCVT_S_D, MASK_FCVT_S_D) 998 | DECLARE_INSN(fcvt_d_s, MATCH_FCVT_D_S, MASK_FCVT_D_S) 999 | DECLARE_INSN(fsqrt_d, MATCH_FSQRT_D, MASK_FSQRT_D) 1000 | DECLARE_INSN(fle_s, MATCH_FLE_S, MASK_FLE_S) 1001 | DECLARE_INSN(flt_s, MATCH_FLT_S, MASK_FLT_S) 1002 | DECLARE_INSN(feq_s, MATCH_FEQ_S, MASK_FEQ_S) 1003 | DECLARE_INSN(fle_d, MATCH_FLE_D, MASK_FLE_D) 1004 | DECLARE_INSN(flt_d, MATCH_FLT_D, MASK_FLT_D) 1005 | DECLARE_INSN(feq_d, MATCH_FEQ_D, MASK_FEQ_D) 1006 | DECLARE_INSN(fcvt_w_s, MATCH_FCVT_W_S, MASK_FCVT_W_S) 1007 | DECLARE_INSN(fcvt_wu_s, MATCH_FCVT_WU_S, MASK_FCVT_WU_S) 1008 | DECLARE_INSN(fcvt_l_s, MATCH_FCVT_L_S, MASK_FCVT_L_S) 1009 | DECLARE_INSN(fcvt_lu_s, MATCH_FCVT_LU_S, MASK_FCVT_LU_S) 1010 | DECLARE_INSN(fmv_x_s, MATCH_FMV_X_S, MASK_FMV_X_S) 1011 | DECLARE_INSN(fclass_s, MATCH_FCLASS_S, MASK_FCLASS_S) 1012 | DECLARE_INSN(fcvt_w_d, MATCH_FCVT_W_D, MASK_FCVT_W_D) 1013 | DECLARE_INSN(fcvt_wu_d, MATCH_FCVT_WU_D, MASK_FCVT_WU_D) 1014 | DECLARE_INSN(fcvt_l_d, MATCH_FCVT_L_D, MASK_FCVT_L_D) 1015 | DECLARE_INSN(fcvt_lu_d, MATCH_FCVT_LU_D, MASK_FCVT_LU_D) 1016 | DECLARE_INSN(fmv_x_d, MATCH_FMV_X_D, MASK_FMV_X_D) 1017 | DECLARE_INSN(fclass_d, MATCH_FCLASS_D, MASK_FCLASS_D) 1018 | DECLARE_INSN(fcvt_s_w, MATCH_FCVT_S_W, MASK_FCVT_S_W) 1019 | DECLARE_INSN(fcvt_s_wu, MATCH_FCVT_S_WU, MASK_FCVT_S_WU) 1020 | DECLARE_INSN(fcvt_s_l, MATCH_FCVT_S_L, MASK_FCVT_S_L) 1021 | DECLARE_INSN(fcvt_s_lu, MATCH_FCVT_S_LU, MASK_FCVT_S_LU) 1022 | DECLARE_INSN(fmv_s_x, MATCH_FMV_S_X, MASK_FMV_S_X) 1023 | DECLARE_INSN(fcvt_d_w, MATCH_FCVT_D_W, MASK_FCVT_D_W) 1024 | DECLARE_INSN(fcvt_d_wu, MATCH_FCVT_D_WU, MASK_FCVT_D_WU) 1025 | DECLARE_INSN(fcvt_d_l, MATCH_FCVT_D_L, MASK_FCVT_D_L) 1026 | DECLARE_INSN(fcvt_d_lu, MATCH_FCVT_D_LU, MASK_FCVT_D_LU) 1027 | DECLARE_INSN(fmv_d_x, MATCH_FMV_D_X, MASK_FMV_D_X) 1028 | DECLARE_INSN(flw, MATCH_FLW, MASK_FLW) 1029 | DECLARE_INSN(fld, MATCH_FLD, MASK_FLD) 1030 | DECLARE_INSN(fsw, MATCH_FSW, MASK_FSW) 1031 | DECLARE_INSN(fsd, MATCH_FSD, MASK_FSD) 1032 | DECLARE_INSN(fmadd_s, MATCH_FMADD_S, MASK_FMADD_S) 1033 | DECLARE_INSN(fmsub_s, MATCH_FMSUB_S, MASK_FMSUB_S) 1034 | DECLARE_INSN(fnmsub_s, MATCH_FNMSUB_S, MASK_FNMSUB_S) 1035 | DECLARE_INSN(fnmadd_s, MATCH_FNMADD_S, MASK_FNMADD_S) 1036 | DECLARE_INSN(fmadd_d, MATCH_FMADD_D, MASK_FMADD_D) 1037 | DECLARE_INSN(fmsub_d, MATCH_FMSUB_D, MASK_FMSUB_D) 1038 | DECLARE_INSN(fnmsub_d, MATCH_FNMSUB_D, MASK_FNMSUB_D) 1039 | DECLARE_INSN(fnmadd_d, MATCH_FNMADD_D, MASK_FNMADD_D) 1040 | DECLARE_INSN(c_nop, MATCH_C_NOP, MASK_C_NOP) 1041 | DECLARE_INSN(c_addi16sp, MATCH_C_ADDI16SP, MASK_C_ADDI16SP) 1042 | DECLARE_INSN(c_jr, MATCH_C_JR, MASK_C_JR) 1043 | DECLARE_INSN(c_jalr, MATCH_C_JALR, MASK_C_JALR) 1044 | DECLARE_INSN(c_ebreak, MATCH_C_EBREAK, MASK_C_EBREAK) 1045 | DECLARE_INSN(c_ld, MATCH_C_LD, MASK_C_LD) 1046 | DECLARE_INSN(c_sd, MATCH_C_SD, MASK_C_SD) 1047 | DECLARE_INSN(c_addiw, MATCH_C_ADDIW, MASK_C_ADDIW) 1048 | DECLARE_INSN(c_ldsp, MATCH_C_LDSP, MASK_C_LDSP) 1049 | DECLARE_INSN(c_sdsp, MATCH_C_SDSP, MASK_C_SDSP) 1050 | DECLARE_INSN(c_addi4spn, MATCH_C_ADDI4SPN, MASK_C_ADDI4SPN) 1051 | DECLARE_INSN(c_fld, MATCH_C_FLD, MASK_C_FLD) 1052 | DECLARE_INSN(c_lw, MATCH_C_LW, MASK_C_LW) 1053 | DECLARE_INSN(c_flw, MATCH_C_FLW, MASK_C_FLW) 1054 | DECLARE_INSN(c_fsd, MATCH_C_FSD, MASK_C_FSD) 1055 | DECLARE_INSN(c_sw, MATCH_C_SW, MASK_C_SW) 1056 | DECLARE_INSN(c_fsw, MATCH_C_FSW, MASK_C_FSW) 1057 | DECLARE_INSN(c_addi, MATCH_C_ADDI, MASK_C_ADDI) 1058 | DECLARE_INSN(c_jal, MATCH_C_JAL, MASK_C_JAL) 1059 | DECLARE_INSN(c_li, MATCH_C_LI, MASK_C_LI) 1060 | DECLARE_INSN(c_lui, MATCH_C_LUI, MASK_C_LUI) 1061 | DECLARE_INSN(c_srli, MATCH_C_SRLI, MASK_C_SRLI) 1062 | DECLARE_INSN(c_srai, MATCH_C_SRAI, MASK_C_SRAI) 1063 | DECLARE_INSN(c_andi, MATCH_C_ANDI, MASK_C_ANDI) 1064 | DECLARE_INSN(c_sub, MATCH_C_SUB, MASK_C_SUB) 1065 | DECLARE_INSN(c_xor, MATCH_C_XOR, MASK_C_XOR) 1066 | DECLARE_INSN(c_or, MATCH_C_OR, MASK_C_OR) 1067 | DECLARE_INSN(c_and, MATCH_C_AND, MASK_C_AND) 1068 | DECLARE_INSN(c_subw, MATCH_C_SUBW, MASK_C_SUBW) 1069 | DECLARE_INSN(c_addw, MATCH_C_ADDW, MASK_C_ADDW) 1070 | DECLARE_INSN(c_j, MATCH_C_J, MASK_C_J) 1071 | DECLARE_INSN(c_beqz, MATCH_C_BEQZ, MASK_C_BEQZ) 1072 | DECLARE_INSN(c_bnez, MATCH_C_BNEZ, MASK_C_BNEZ) 1073 | DECLARE_INSN(c_slli, MATCH_C_SLLI, MASK_C_SLLI) 1074 | DECLARE_INSN(c_fldsp, MATCH_C_FLDSP, MASK_C_FLDSP) 1075 | DECLARE_INSN(c_lwsp, MATCH_C_LWSP, MASK_C_LWSP) 1076 | DECLARE_INSN(c_flwsp, MATCH_C_FLWSP, MASK_C_FLWSP) 1077 | DECLARE_INSN(c_mv, MATCH_C_MV, MASK_C_MV) 1078 | DECLARE_INSN(c_add, MATCH_C_ADD, MASK_C_ADD) 1079 | DECLARE_INSN(c_fsdsp, MATCH_C_FSDSP, MASK_C_FSDSP) 1080 | DECLARE_INSN(c_swsp, MATCH_C_SWSP, MASK_C_SWSP) 1081 | DECLARE_INSN(c_fswsp, MATCH_C_FSWSP, MASK_C_FSWSP) 1082 | DECLARE_INSN(custom0, MATCH_CUSTOM0, MASK_CUSTOM0) 1083 | DECLARE_INSN(custom0_rs1, MATCH_CUSTOM0_RS1, MASK_CUSTOM0_RS1) 1084 | DECLARE_INSN(custom0_rs1_rs2, MATCH_CUSTOM0_RS1_RS2, MASK_CUSTOM0_RS1_RS2) 1085 | DECLARE_INSN(custom0_rd, MATCH_CUSTOM0_RD, MASK_CUSTOM0_RD) 1086 | DECLARE_INSN(custom0_rd_rs1, MATCH_CUSTOM0_RD_RS1, MASK_CUSTOM0_RD_RS1) 1087 | DECLARE_INSN(custom0_rd_rs1_rs2, MATCH_CUSTOM0_RD_RS1_RS2, MASK_CUSTOM0_RD_RS1_RS2) 1088 | DECLARE_INSN(custom1, MATCH_CUSTOM1, MASK_CUSTOM1) 1089 | DECLARE_INSN(custom1_rs1, MATCH_CUSTOM1_RS1, MASK_CUSTOM1_RS1) 1090 | DECLARE_INSN(custom1_rs1_rs2, MATCH_CUSTOM1_RS1_RS2, MASK_CUSTOM1_RS1_RS2) 1091 | DECLARE_INSN(custom1_rd, MATCH_CUSTOM1_RD, MASK_CUSTOM1_RD) 1092 | DECLARE_INSN(custom1_rd_rs1, MATCH_CUSTOM1_RD_RS1, MASK_CUSTOM1_RD_RS1) 1093 | DECLARE_INSN(custom1_rd_rs1_rs2, MATCH_CUSTOM1_RD_RS1_RS2, MASK_CUSTOM1_RD_RS1_RS2) 1094 | DECLARE_INSN(custom2, MATCH_CUSTOM2, MASK_CUSTOM2) 1095 | DECLARE_INSN(custom2_rs1, MATCH_CUSTOM2_RS1, MASK_CUSTOM2_RS1) 1096 | DECLARE_INSN(custom2_rs1_rs2, MATCH_CUSTOM2_RS1_RS2, MASK_CUSTOM2_RS1_RS2) 1097 | DECLARE_INSN(custom2_rd, MATCH_CUSTOM2_RD, MASK_CUSTOM2_RD) 1098 | DECLARE_INSN(custom2_rd_rs1, MATCH_CUSTOM2_RD_RS1, MASK_CUSTOM2_RD_RS1) 1099 | DECLARE_INSN(custom2_rd_rs1_rs2, MATCH_CUSTOM2_RD_RS1_RS2, MASK_CUSTOM2_RD_RS1_RS2) 1100 | DECLARE_INSN(custom3, MATCH_CUSTOM3, MASK_CUSTOM3) 1101 | DECLARE_INSN(custom3_rs1, MATCH_CUSTOM3_RS1, MASK_CUSTOM3_RS1) 1102 | DECLARE_INSN(custom3_rs1_rs2, MATCH_CUSTOM3_RS1_RS2, MASK_CUSTOM3_RS1_RS2) 1103 | DECLARE_INSN(custom3_rd, MATCH_CUSTOM3_RD, MASK_CUSTOM3_RD) 1104 | DECLARE_INSN(custom3_rd_rs1, MATCH_CUSTOM3_RD_RS1, MASK_CUSTOM3_RD_RS1) 1105 | DECLARE_INSN(custom3_rd_rs1_rs2, MATCH_CUSTOM3_RD_RS1_RS2, MASK_CUSTOM3_RD_RS1_RS2) 1106 | #endif 1107 | #ifdef DECLARE_CSR 1108 | DECLARE_CSR(fflags, CSR_FFLAGS) 1109 | DECLARE_CSR(frm, CSR_FRM) 1110 | DECLARE_CSR(fcsr, CSR_FCSR) 1111 | DECLARE_CSR(cycle, CSR_CYCLE) 1112 | DECLARE_CSR(time, CSR_TIME) 1113 | DECLARE_CSR(instret, CSR_INSTRET) 1114 | DECLARE_CSR(hpmcounter3, CSR_HPMCOUNTER3) 1115 | DECLARE_CSR(hpmcounter4, CSR_HPMCOUNTER4) 1116 | DECLARE_CSR(hpmcounter5, CSR_HPMCOUNTER5) 1117 | DECLARE_CSR(hpmcounter6, CSR_HPMCOUNTER6) 1118 | DECLARE_CSR(hpmcounter7, CSR_HPMCOUNTER7) 1119 | DECLARE_CSR(hpmcounter8, CSR_HPMCOUNTER8) 1120 | DECLARE_CSR(hpmcounter9, CSR_HPMCOUNTER9) 1121 | DECLARE_CSR(hpmcounter10, CSR_HPMCOUNTER10) 1122 | DECLARE_CSR(hpmcounter11, CSR_HPMCOUNTER11) 1123 | DECLARE_CSR(hpmcounter12, CSR_HPMCOUNTER12) 1124 | DECLARE_CSR(hpmcounter13, CSR_HPMCOUNTER13) 1125 | DECLARE_CSR(hpmcounter14, CSR_HPMCOUNTER14) 1126 | DECLARE_CSR(hpmcounter15, CSR_HPMCOUNTER15) 1127 | DECLARE_CSR(hpmcounter16, CSR_HPMCOUNTER16) 1128 | DECLARE_CSR(hpmcounter17, CSR_HPMCOUNTER17) 1129 | DECLARE_CSR(hpmcounter18, CSR_HPMCOUNTER18) 1130 | DECLARE_CSR(hpmcounter19, CSR_HPMCOUNTER19) 1131 | DECLARE_CSR(hpmcounter20, CSR_HPMCOUNTER20) 1132 | DECLARE_CSR(hpmcounter21, CSR_HPMCOUNTER21) 1133 | DECLARE_CSR(hpmcounter22, CSR_HPMCOUNTER22) 1134 | DECLARE_CSR(hpmcounter23, CSR_HPMCOUNTER23) 1135 | DECLARE_CSR(hpmcounter24, CSR_HPMCOUNTER24) 1136 | DECLARE_CSR(hpmcounter25, CSR_HPMCOUNTER25) 1137 | DECLARE_CSR(hpmcounter26, CSR_HPMCOUNTER26) 1138 | DECLARE_CSR(hpmcounter27, CSR_HPMCOUNTER27) 1139 | DECLARE_CSR(hpmcounter28, CSR_HPMCOUNTER28) 1140 | DECLARE_CSR(hpmcounter29, CSR_HPMCOUNTER29) 1141 | DECLARE_CSR(hpmcounter30, CSR_HPMCOUNTER30) 1142 | DECLARE_CSR(hpmcounter31, CSR_HPMCOUNTER31) 1143 | DECLARE_CSR(sstatus, CSR_SSTATUS) 1144 | DECLARE_CSR(sie, CSR_SIE) 1145 | DECLARE_CSR(stvec, CSR_STVEC) 1146 | DECLARE_CSR(sscratch, CSR_SSCRATCH) 1147 | DECLARE_CSR(sepc, CSR_SEPC) 1148 | DECLARE_CSR(scause, CSR_SCAUSE) 1149 | DECLARE_CSR(sbadaddr, CSR_SBADADDR) 1150 | DECLARE_CSR(sip, CSR_SIP) 1151 | DECLARE_CSR(sptbr, CSR_SPTBR) 1152 | DECLARE_CSR(mstatus, CSR_MSTATUS) 1153 | DECLARE_CSR(misa, CSR_MISA) 1154 | DECLARE_CSR(medeleg, CSR_MEDELEG) 1155 | DECLARE_CSR(mideleg, CSR_MIDELEG) 1156 | DECLARE_CSR(mie, CSR_MIE) 1157 | DECLARE_CSR(mtvec, CSR_MTVEC) 1158 | DECLARE_CSR(mscratch, CSR_MSCRATCH) 1159 | DECLARE_CSR(mepc, CSR_MEPC) 1160 | DECLARE_CSR(mcause, CSR_MCAUSE) 1161 | DECLARE_CSR(mbadaddr, CSR_MBADADDR) 1162 | DECLARE_CSR(mip, CSR_MIP) 1163 | DECLARE_CSR(tselect, CSR_TSELECT) 1164 | DECLARE_CSR(tdata1, CSR_TDATA1) 1165 | DECLARE_CSR(tdata2, CSR_TDATA2) 1166 | DECLARE_CSR(tdata3, CSR_TDATA3) 1167 | DECLARE_CSR(dcsr, CSR_DCSR) 1168 | DECLARE_CSR(dpc, CSR_DPC) 1169 | DECLARE_CSR(dscratch, CSR_DSCRATCH) 1170 | DECLARE_CSR(mcycle, CSR_MCYCLE) 1171 | DECLARE_CSR(minstret, CSR_MINSTRET) 1172 | DECLARE_CSR(mhpmcounter3, CSR_MHPMCOUNTER3) 1173 | DECLARE_CSR(mhpmcounter4, CSR_MHPMCOUNTER4) 1174 | DECLARE_CSR(mhpmcounter5, CSR_MHPMCOUNTER5) 1175 | DECLARE_CSR(mhpmcounter6, CSR_MHPMCOUNTER6) 1176 | DECLARE_CSR(mhpmcounter7, CSR_MHPMCOUNTER7) 1177 | DECLARE_CSR(mhpmcounter8, CSR_MHPMCOUNTER8) 1178 | DECLARE_CSR(mhpmcounter9, CSR_MHPMCOUNTER9) 1179 | DECLARE_CSR(mhpmcounter10, CSR_MHPMCOUNTER10) 1180 | DECLARE_CSR(mhpmcounter11, CSR_MHPMCOUNTER11) 1181 | DECLARE_CSR(mhpmcounter12, CSR_MHPMCOUNTER12) 1182 | DECLARE_CSR(mhpmcounter13, CSR_MHPMCOUNTER13) 1183 | DECLARE_CSR(mhpmcounter14, CSR_MHPMCOUNTER14) 1184 | DECLARE_CSR(mhpmcounter15, CSR_MHPMCOUNTER15) 1185 | DECLARE_CSR(mhpmcounter16, CSR_MHPMCOUNTER16) 1186 | DECLARE_CSR(mhpmcounter17, CSR_MHPMCOUNTER17) 1187 | DECLARE_CSR(mhpmcounter18, CSR_MHPMCOUNTER18) 1188 | DECLARE_CSR(mhpmcounter19, CSR_MHPMCOUNTER19) 1189 | DECLARE_CSR(mhpmcounter20, CSR_MHPMCOUNTER20) 1190 | DECLARE_CSR(mhpmcounter21, CSR_MHPMCOUNTER21) 1191 | DECLARE_CSR(mhpmcounter22, CSR_MHPMCOUNTER22) 1192 | DECLARE_CSR(mhpmcounter23, CSR_MHPMCOUNTER23) 1193 | DECLARE_CSR(mhpmcounter24, CSR_MHPMCOUNTER24) 1194 | DECLARE_CSR(mhpmcounter25, CSR_MHPMCOUNTER25) 1195 | DECLARE_CSR(mhpmcounter26, CSR_MHPMCOUNTER26) 1196 | DECLARE_CSR(mhpmcounter27, CSR_MHPMCOUNTER27) 1197 | DECLARE_CSR(mhpmcounter28, CSR_MHPMCOUNTER28) 1198 | DECLARE_CSR(mhpmcounter29, CSR_MHPMCOUNTER29) 1199 | DECLARE_CSR(mhpmcounter30, CSR_MHPMCOUNTER30) 1200 | DECLARE_CSR(mhpmcounter31, CSR_MHPMCOUNTER31) 1201 | DECLARE_CSR(mucounteren, CSR_MUCOUNTEREN) 1202 | DECLARE_CSR(mscounteren, CSR_MSCOUNTEREN) 1203 | DECLARE_CSR(mhpmevent3, CSR_MHPMEVENT3) 1204 | DECLARE_CSR(mhpmevent4, CSR_MHPMEVENT4) 1205 | DECLARE_CSR(mhpmevent5, CSR_MHPMEVENT5) 1206 | DECLARE_CSR(mhpmevent6, CSR_MHPMEVENT6) 1207 | DECLARE_CSR(mhpmevent7, CSR_MHPMEVENT7) 1208 | DECLARE_CSR(mhpmevent8, CSR_MHPMEVENT8) 1209 | DECLARE_CSR(mhpmevent9, CSR_MHPMEVENT9) 1210 | DECLARE_CSR(mhpmevent10, CSR_MHPMEVENT10) 1211 | DECLARE_CSR(mhpmevent11, CSR_MHPMEVENT11) 1212 | DECLARE_CSR(mhpmevent12, CSR_MHPMEVENT12) 1213 | DECLARE_CSR(mhpmevent13, CSR_MHPMEVENT13) 1214 | DECLARE_CSR(mhpmevent14, CSR_MHPMEVENT14) 1215 | DECLARE_CSR(mhpmevent15, CSR_MHPMEVENT15) 1216 | DECLARE_CSR(mhpmevent16, CSR_MHPMEVENT16) 1217 | DECLARE_CSR(mhpmevent17, CSR_MHPMEVENT17) 1218 | DECLARE_CSR(mhpmevent18, CSR_MHPMEVENT18) 1219 | DECLARE_CSR(mhpmevent19, CSR_MHPMEVENT19) 1220 | DECLARE_CSR(mhpmevent20, CSR_MHPMEVENT20) 1221 | DECLARE_CSR(mhpmevent21, CSR_MHPMEVENT21) 1222 | DECLARE_CSR(mhpmevent22, CSR_MHPMEVENT22) 1223 | DECLARE_CSR(mhpmevent23, CSR_MHPMEVENT23) 1224 | DECLARE_CSR(mhpmevent24, CSR_MHPMEVENT24) 1225 | DECLARE_CSR(mhpmevent25, CSR_MHPMEVENT25) 1226 | DECLARE_CSR(mhpmevent26, CSR_MHPMEVENT26) 1227 | DECLARE_CSR(mhpmevent27, CSR_MHPMEVENT27) 1228 | DECLARE_CSR(mhpmevent28, CSR_MHPMEVENT28) 1229 | DECLARE_CSR(mhpmevent29, CSR_MHPMEVENT29) 1230 | DECLARE_CSR(mhpmevent30, CSR_MHPMEVENT30) 1231 | DECLARE_CSR(mhpmevent31, CSR_MHPMEVENT31) 1232 | DECLARE_CSR(mvendorid, CSR_MVENDORID) 1233 | DECLARE_CSR(marchid, CSR_MARCHID) 1234 | DECLARE_CSR(mimpid, CSR_MIMPID) 1235 | DECLARE_CSR(mhartid, CSR_MHARTID) 1236 | DECLARE_CSR(cycleh, CSR_CYCLEH) 1237 | DECLARE_CSR(timeh, CSR_TIMEH) 1238 | DECLARE_CSR(instreth, CSR_INSTRETH) 1239 | DECLARE_CSR(hpmcounter3h, CSR_HPMCOUNTER3H) 1240 | DECLARE_CSR(hpmcounter4h, CSR_HPMCOUNTER4H) 1241 | DECLARE_CSR(hpmcounter5h, CSR_HPMCOUNTER5H) 1242 | DECLARE_CSR(hpmcounter6h, CSR_HPMCOUNTER6H) 1243 | DECLARE_CSR(hpmcounter7h, CSR_HPMCOUNTER7H) 1244 | DECLARE_CSR(hpmcounter8h, CSR_HPMCOUNTER8H) 1245 | DECLARE_CSR(hpmcounter9h, CSR_HPMCOUNTER9H) 1246 | DECLARE_CSR(hpmcounter10h, CSR_HPMCOUNTER10H) 1247 | DECLARE_CSR(hpmcounter11h, CSR_HPMCOUNTER11H) 1248 | DECLARE_CSR(hpmcounter12h, CSR_HPMCOUNTER12H) 1249 | DECLARE_CSR(hpmcounter13h, CSR_HPMCOUNTER13H) 1250 | DECLARE_CSR(hpmcounter14h, CSR_HPMCOUNTER14H) 1251 | DECLARE_CSR(hpmcounter15h, CSR_HPMCOUNTER15H) 1252 | DECLARE_CSR(hpmcounter16h, CSR_HPMCOUNTER16H) 1253 | DECLARE_CSR(hpmcounter17h, CSR_HPMCOUNTER17H) 1254 | DECLARE_CSR(hpmcounter18h, CSR_HPMCOUNTER18H) 1255 | DECLARE_CSR(hpmcounter19h, CSR_HPMCOUNTER19H) 1256 | DECLARE_CSR(hpmcounter20h, CSR_HPMCOUNTER20H) 1257 | DECLARE_CSR(hpmcounter21h, CSR_HPMCOUNTER21H) 1258 | DECLARE_CSR(hpmcounter22h, CSR_HPMCOUNTER22H) 1259 | DECLARE_CSR(hpmcounter23h, CSR_HPMCOUNTER23H) 1260 | DECLARE_CSR(hpmcounter24h, CSR_HPMCOUNTER24H) 1261 | DECLARE_CSR(hpmcounter25h, CSR_HPMCOUNTER25H) 1262 | DECLARE_CSR(hpmcounter26h, CSR_HPMCOUNTER26H) 1263 | DECLARE_CSR(hpmcounter27h, CSR_HPMCOUNTER27H) 1264 | DECLARE_CSR(hpmcounter28h, CSR_HPMCOUNTER28H) 1265 | DECLARE_CSR(hpmcounter29h, CSR_HPMCOUNTER29H) 1266 | DECLARE_CSR(hpmcounter30h, CSR_HPMCOUNTER30H) 1267 | DECLARE_CSR(hpmcounter31h, CSR_HPMCOUNTER31H) 1268 | DECLARE_CSR(mcycleh, CSR_MCYCLEH) 1269 | DECLARE_CSR(minstreth, CSR_MINSTRETH) 1270 | DECLARE_CSR(mhpmcounter3h, CSR_MHPMCOUNTER3H) 1271 | DECLARE_CSR(mhpmcounter4h, CSR_MHPMCOUNTER4H) 1272 | DECLARE_CSR(mhpmcounter5h, CSR_MHPMCOUNTER5H) 1273 | DECLARE_CSR(mhpmcounter6h, CSR_MHPMCOUNTER6H) 1274 | DECLARE_CSR(mhpmcounter7h, CSR_MHPMCOUNTER7H) 1275 | DECLARE_CSR(mhpmcounter8h, CSR_MHPMCOUNTER8H) 1276 | DECLARE_CSR(mhpmcounter9h, CSR_MHPMCOUNTER9H) 1277 | DECLARE_CSR(mhpmcounter10h, CSR_MHPMCOUNTER10H) 1278 | DECLARE_CSR(mhpmcounter11h, CSR_MHPMCOUNTER11H) 1279 | DECLARE_CSR(mhpmcounter12h, CSR_MHPMCOUNTER12H) 1280 | DECLARE_CSR(mhpmcounter13h, CSR_MHPMCOUNTER13H) 1281 | DECLARE_CSR(mhpmcounter14h, CSR_MHPMCOUNTER14H) 1282 | DECLARE_CSR(mhpmcounter15h, CSR_MHPMCOUNTER15H) 1283 | DECLARE_CSR(mhpmcounter16h, CSR_MHPMCOUNTER16H) 1284 | DECLARE_CSR(mhpmcounter17h, CSR_MHPMCOUNTER17H) 1285 | DECLARE_CSR(mhpmcounter18h, CSR_MHPMCOUNTER18H) 1286 | DECLARE_CSR(mhpmcounter19h, CSR_MHPMCOUNTER19H) 1287 | DECLARE_CSR(mhpmcounter20h, CSR_MHPMCOUNTER20H) 1288 | DECLARE_CSR(mhpmcounter21h, CSR_MHPMCOUNTER21H) 1289 | DECLARE_CSR(mhpmcounter22h, CSR_MHPMCOUNTER22H) 1290 | DECLARE_CSR(mhpmcounter23h, CSR_MHPMCOUNTER23H) 1291 | DECLARE_CSR(mhpmcounter24h, CSR_MHPMCOUNTER24H) 1292 | DECLARE_CSR(mhpmcounter25h, CSR_MHPMCOUNTER25H) 1293 | DECLARE_CSR(mhpmcounter26h, CSR_MHPMCOUNTER26H) 1294 | DECLARE_CSR(mhpmcounter27h, CSR_MHPMCOUNTER27H) 1295 | DECLARE_CSR(mhpmcounter28h, CSR_MHPMCOUNTER28H) 1296 | DECLARE_CSR(mhpmcounter29h, CSR_MHPMCOUNTER29H) 1297 | DECLARE_CSR(mhpmcounter30h, CSR_MHPMCOUNTER30H) 1298 | DECLARE_CSR(mhpmcounter31h, CSR_MHPMCOUNTER31H) 1299 | #endif 1300 | #ifdef DECLARE_CAUSE 1301 | DECLARE_CAUSE("misaligned fetch", CAUSE_MISALIGNED_FETCH) 1302 | DECLARE_CAUSE("fault fetch", CAUSE_FAULT_FETCH) 1303 | DECLARE_CAUSE("illegal instruction", CAUSE_ILLEGAL_INSTRUCTION) 1304 | DECLARE_CAUSE("breakpoint", CAUSE_BREAKPOINT) 1305 | DECLARE_CAUSE("misaligned load", CAUSE_MISALIGNED_LOAD) 1306 | DECLARE_CAUSE("fault load", CAUSE_FAULT_LOAD) 1307 | DECLARE_CAUSE("misaligned store", CAUSE_MISALIGNED_STORE) 1308 | DECLARE_CAUSE("fault store", CAUSE_FAULT_STORE) 1309 | DECLARE_CAUSE("user_ecall", CAUSE_USER_ECALL) 1310 | DECLARE_CAUSE("supervisor_ecall", CAUSE_SUPERVISOR_ECALL) 1311 | DECLARE_CAUSE("hypervisor_ecall", CAUSE_HYPERVISOR_ECALL) 1312 | DECLARE_CAUSE("machine_ecall", CAUSE_MACHINE_ECALL) 1313 | #endif 1314 | -------------------------------------------------------------------------------- /tests/link.ld: -------------------------------------------------------------------------------- 1 | /*======================================================================*/ 2 | /* Proxy kernel linker script */ 3 | /*======================================================================*/ 4 | /* This is the linker script used when building the proxy kernel. */ 5 | 6 | /*----------------------------------------------------------------------*/ 7 | /* Setup */ 8 | /*----------------------------------------------------------------------*/ 9 | 10 | /* The OUTPUT_ARCH command specifies the machine architecture where the 11 | argument is one of the names used in the BFD library. More 12 | specifically one of the entires in bfd/cpu-mips.c */ 13 | 14 | OUTPUT_ARCH( "riscv" ) 15 | ENTRY(_start) 16 | 17 | /*----------------------------------------------------------------------*/ 18 | /* Sections */ 19 | /*----------------------------------------------------------------------*/ 20 | 21 | SECTIONS 22 | { 23 | 24 | /* text: test code section */ 25 | . = 0x80000000; 26 | .text.init : { *(.text.init) } 27 | 28 | .tohost ALIGN(0x1000) : { *(.tohost) } 29 | 30 | .text : { *(.text) } 31 | 32 | /* data segment */ 33 | .data ALIGN(0x40) : { *(.data) } 34 | 35 | .sdata : { 36 | __global_pointer$ = . + 0x800; 37 | *(.srodata.cst16) *(.srodata.cst8) *(.srodata.cst4) *(.srodata.cst2) *(.srodata*) 38 | *(.sdata .sdata.* .gnu.linkonce.s.*) 39 | } 40 | 41 | /* bss segment */ 42 | .sbss : { 43 | *(.sbss .sbss.* .gnu.linkonce.sb.*) 44 | *(.scommon) 45 | } 46 | .bss ALIGN(0x40) : { *(.bss) } 47 | 48 | /* thread-local data segment */ 49 | .tdata : 50 | { 51 | _tls_data = .; 52 | *(.tdata.begin) 53 | *(.tdata) 54 | *(.tdata.end) 55 | } 56 | .tbss : 57 | { 58 | *(.tbss) 59 | *(.tbss.end) 60 | } 61 | 62 | /* End of uninitalized data segement */ 63 | _end = .; 64 | } 65 | 66 | -------------------------------------------------------------------------------- /tests/mmio.h: -------------------------------------------------------------------------------- 1 | #ifndef __MMIO_H__ 2 | #define __MMIO_H__ 3 | 4 | #include 5 | 6 | static inline void reg_write8(uintptr_t addr, uint8_t data) 7 | { 8 | volatile uint8_t *ptr = (volatile uint8_t *) addr; 9 | *ptr = data; 10 | } 11 | 12 | static inline uint8_t reg_read8(uintptr_t addr) 13 | { 14 | volatile uint8_t *ptr = (volatile uint8_t *) addr; 15 | return *ptr; 16 | } 17 | 18 | static inline void reg_write16(uintptr_t addr, uint16_t data) 19 | { 20 | volatile uint16_t *ptr = (volatile uint16_t *) addr; 21 | *ptr = data; 22 | } 23 | 24 | static inline uint16_t reg_read16(uintptr_t addr) 25 | { 26 | volatile uint16_t *ptr = (volatile uint16_t *) addr; 27 | return *ptr; 28 | } 29 | 30 | static inline void reg_write32(uintptr_t addr, uint32_t data) 31 | { 32 | volatile uint32_t *ptr = (volatile uint32_t *) addr; 33 | *ptr = data; 34 | } 35 | 36 | static inline uint32_t reg_read32(uintptr_t addr) 37 | { 38 | volatile uint32_t *ptr = (volatile uint32_t *) addr; 39 | return *ptr; 40 | } 41 | 42 | static inline void reg_write64(unsigned long addr, uint64_t data) 43 | { 44 | volatile uint64_t *ptr = (volatile uint64_t *) addr; 45 | *ptr = data; 46 | } 47 | 48 | static inline uint64_t reg_read64(unsigned long addr) 49 | { 50 | volatile uint64_t *ptr = (volatile uint64_t *) addr; 51 | return *ptr; 52 | } 53 | 54 | #endif 55 | -------------------------------------------------------------------------------- /tests/nic.h: -------------------------------------------------------------------------------- 1 | #define SIMPLENIC_BASE 0x10016000L 2 | #define SIMPLENIC_SEND_REQ (SIMPLENIC_BASE + 0) 3 | #define SIMPLENIC_RECV_REQ (SIMPLENIC_BASE + 8) 4 | #define SIMPLENIC_SEND_COMP (SIMPLENIC_BASE + 16) 5 | #define SIMPLENIC_RECV_COMP (SIMPLENIC_BASE + 18) 6 | #define SIMPLENIC_COUNTS (SIMPLENIC_BASE + 20) 7 | #define SIMPLENIC_MACADDR (SIMPLENIC_BASE + 24) 8 | 9 | static inline int nic_send_req_avail(void) 10 | { 11 | return reg_read16(SIMPLENIC_COUNTS) & 0xf; 12 | } 13 | 14 | static inline int nic_recv_req_avail(void) 15 | { 16 | return (reg_read16(SIMPLENIC_COUNTS) >> 4) & 0xf; 17 | } 18 | 19 | static inline int nic_send_comp_avail(void) 20 | { 21 | return (reg_read16(SIMPLENIC_COUNTS) >> 8) & 0xf; 22 | } 23 | 24 | static inline int nic_recv_comp_avail(void) 25 | { 26 | return (reg_read16(SIMPLENIC_COUNTS) >> 12) & 0xf; 27 | } 28 | 29 | static void nic_send(void *data, unsigned long len) 30 | { 31 | uintptr_t addr = ((uintptr_t) data) & ((1L << 48) - 1); 32 | unsigned long packet = (len << 48) | addr; 33 | 34 | while (nic_send_req_avail() == 0); 35 | reg_write64(SIMPLENIC_SEND_REQ, packet); 36 | 37 | while (nic_send_comp_avail() == 0); 38 | reg_read16(SIMPLENIC_SEND_COMP); 39 | } 40 | 41 | static int nic_recv(void *dest) 42 | { 43 | uintptr_t addr = (uintptr_t) dest; 44 | int len; 45 | 46 | while (nic_recv_req_avail() == 0); 47 | reg_write64(SIMPLENIC_RECV_REQ, addr); 48 | 49 | // Poll for completion 50 | while (nic_recv_comp_avail() == 0); 51 | len = reg_read16(SIMPLENIC_RECV_COMP); 52 | asm volatile ("fence"); 53 | 54 | return len; 55 | } 56 | 57 | static inline uint64_t nic_macaddr(void) 58 | { 59 | return reg_read64(SIMPLENIC_MACADDR); 60 | } 61 | -------------------------------------------------------------------------------- /tests/pwm.c: -------------------------------------------------------------------------------- 1 | #define PWM_PERIOD 0x2000 2 | #define PWM_DUTY 0x2004 3 | #define PWM_ENABLE 0x2008 4 | 5 | #include "mmio.h" 6 | 7 | int main(void) 8 | { 9 | reg_write32(PWM_PERIOD, 20); 10 | reg_write32(PWM_DUTY, 5); 11 | reg_write32(PWM_ENABLE, 1); 12 | 13 | return 0; 14 | } 15 | -------------------------------------------------------------------------------- /tests/rocc.h: -------------------------------------------------------------------------------- 1 | // Based on code by Schuyler Eldridge. Copyright (c) Boston University 2 | // https://github.com/seldridge/rocket-rocc-examples/blob/master/src/main/c/rocc.h 3 | 4 | #ifndef SRC_MAIN_C_ROCC_H 5 | #define SRC_MAIN_C_ROCC_H 6 | 7 | #include 8 | 9 | #define STR1(x) #x 10 | #define STR(x) STR1(x) 11 | #define EXTRACT(a, size, offset) (((~(~0 << size) << offset) & a) >> offset) 12 | 13 | #define CUSTOMX_OPCODE(x) CUSTOM_ ## x 14 | #define CUSTOM_0 0b0001011 15 | #define CUSTOM_1 0b0101011 16 | #define CUSTOM_2 0b1011011 17 | #define CUSTOM_3 0b1111011 18 | 19 | #define CUSTOMX(X, xd, xs1, xs2, rd, rs1, rs2, funct) \ 20 | CUSTOMX_OPCODE(X) | \ 21 | (rd << (7)) | \ 22 | (xs2 << (7+5)) | \ 23 | (xs1 << (7+5+1)) | \ 24 | (xd << (7+5+2)) | \ 25 | (rs1 << (7+5+3)) | \ 26 | (rs2 << (7+5+3+5)) | \ 27 | (EXTRACT(funct, 7, 0) << (7+5+3+5+5)) 28 | 29 | // Standard macro that passes rd, rs1, and rs2 via registers 30 | #define ROCC_INSTRUCTION_DSS(X, rd, rs1, rs2, funct) \ 31 | ROCC_INSTRUCTION_R_R_R(X, rd, rs1, rs2, funct, 10, 11, 12) 32 | 33 | #define ROCC_INSTRUCTION_DS(X, rd, rs1, funct) \ 34 | ROCC_INSTRUCTION_R_R_I(X, rd, rs1, 0, funct, 10, 11) 35 | 36 | #define ROCC_INSTRUCTION_D(X, rd, funct) \ 37 | ROCC_INSTRUCTION_R_I_I(X, rd, 0, 0, funct, 10) 38 | 39 | #define ROCC_INSTRUCTION_SS(X, rs1, rs2, funct) \ 40 | ROCC_INSTRUCTION_I_R_R(X, 0, rs1, rs2, funct, 11, 12) 41 | 42 | #define ROCC_INSTRUCTION_S(X, rs1, funct) \ 43 | ROCC_INSTRUCTION_I_R_I(X, 0, rs1, 0, funct, 11) 44 | 45 | #define ROCC_INSTRUCTION(X, funct) \ 46 | ROCC_INSTRUCTION_I_I_I(X, 0, 0, 0, funct) 47 | 48 | // rd, rs1, and rs2 are data 49 | // rd_n, rs_1, and rs2_n are the register numbers to use 50 | #define ROCC_INSTRUCTION_R_R_R(X, rd, rs1, rs2, funct, rd_n, rs1_n, rs2_n) { \ 51 | register uint64_t rd_ asm ("x" # rd_n); \ 52 | register uint64_t rs1_ asm ("x" # rs1_n) = (uint64_t) rs1; \ 53 | register uint64_t rs2_ asm ("x" # rs2_n) = (uint64_t) rs2; \ 54 | asm volatile ( \ 55 | ".word " STR(CUSTOMX(X, 1, 1, 1, rd_n, rs1_n, rs2_n, funct)) "\n\t" \ 56 | : "=r" (rd_) \ 57 | : [_rs1] "r" (rs1_), [_rs2] "r" (rs2_)); \ 58 | rd = rd_; \ 59 | } 60 | 61 | #define ROCC_INSTRUCTION_R_R_I(X, rd, rs1, rs2, funct, rd_n, rs1_n) { \ 62 | register uint64_t rd_ asm ("x" # rd_n); \ 63 | register uint64_t rs1_ asm ("x" # rs1_n) = (uint64_t) rs1; \ 64 | asm volatile ( \ 65 | ".word " STR(CUSTOMX(X, 1, 1, 0, rd_n, rs1_n, rs2, funct)) "\n\t" \ 66 | : "=r" (rd_) : [_rs1] "r" (rs1_)); \ 67 | rd = rd_; \ 68 | } 69 | 70 | #define ROCC_INSTRUCTION_R_I_I(X, rd, rs1, rs2, funct, rd_n) { \ 71 | register uint64_t rd_ asm ("x" # rd_n); \ 72 | asm volatile ( \ 73 | ".word " STR(CUSTOMX(X, 1, 0, 0, rd_n, rs1, rs2, funct)) "\n\t" \ 74 | : "=r" (rd_)); \ 75 | rd = rd_; \ 76 | } 77 | 78 | #define ROCC_INSTRUCTION_I_R_R(X, rd, rs1, rs2, funct, rs1_n, rs2_n) { \ 79 | register uint64_t rs1_ asm ("x" # rs1_n) = (uint64_t) rs1; \ 80 | register uint64_t rs2_ asm ("x" # rs2_n) = (uint64_t) rs2; \ 81 | asm volatile ( \ 82 | ".word " STR(CUSTOMX(X, 0, 1, 1, rd, rs1_n, rs2_n, funct)) "\n\t" \ 83 | :: [_rs1] "r" (rs1_), [_rs2] "r" (rs2_)); \ 84 | } 85 | 86 | #define ROCC_INSTRUCTION_I_R_I(X, rd, rs1, rs2, funct, rs1_n) { \ 87 | register uint64_t rs1_ asm ("x" # rs1_n) = (uint64_t) rs1; \ 88 | asm volatile ( \ 89 | ".word " STR(CUSTOMX(X, 0, 1, 0, rd, rs1_n, rs2, funct)) "\n\t" \ 90 | :: [_rs1] "r" (rs1_)); \ 91 | } 92 | 93 | #define ROCC_INSTRUCTION_I_I_I(X, rd, rs1, rs2, funct) { \ 94 | asm volatile ( \ 95 | ".word " STR(CUSTOMX(X, 0, 0, 0, rd, rs1, rs2, funct)) "\n\t" ); \ 96 | } 97 | 98 | #endif // SRC_MAIN_C_ACCUMULATOR_H 99 | -------------------------------------------------------------------------------- /tests/syscalls.c: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include "util.h" 10 | 11 | #define SYS_write 64 12 | 13 | #undef strcmp 14 | 15 | extern volatile uint64_t tohost; 16 | extern volatile uint64_t fromhost; 17 | 18 | static uintptr_t syscall(uintptr_t which, uint64_t arg0, uint64_t arg1, uint64_t arg2) 19 | { 20 | volatile uint64_t magic_mem[8] __attribute__((aligned(64))); 21 | magic_mem[0] = which; 22 | magic_mem[1] = arg0; 23 | magic_mem[2] = arg1; 24 | magic_mem[3] = arg2; 25 | __sync_synchronize(); 26 | 27 | tohost = (uintptr_t)magic_mem; 28 | while (fromhost == 0) 29 | ; 30 | fromhost = 0; 31 | 32 | __sync_synchronize(); 33 | return magic_mem[0]; 34 | } 35 | 36 | #define NUM_COUNTERS 2 37 | static uintptr_t counters[NUM_COUNTERS]; 38 | static char* counter_names[NUM_COUNTERS]; 39 | 40 | void setStats(int enable) 41 | { 42 | int i = 0; 43 | #define READ_CTR(name) do { \ 44 | while (i >= NUM_COUNTERS) ; \ 45 | uintptr_t csr = read_csr(name); \ 46 | if (!enable) { csr -= counters[i]; counter_names[i] = #name; } \ 47 | counters[i++] = csr; \ 48 | } while (0) 49 | 50 | READ_CTR(mcycle); 51 | READ_CTR(minstret); 52 | 53 | #undef READ_CTR 54 | } 55 | 56 | void __attribute__((noreturn)) tohost_exit(uintptr_t code) 57 | { 58 | tohost = (code << 1) | 1; 59 | while (1); 60 | } 61 | 62 | uintptr_t __attribute__((weak)) handle_trap(uintptr_t cause, uintptr_t epc, uintptr_t regs[32]) 63 | { 64 | tohost_exit(1337); 65 | } 66 | 67 | void exit(int code) 68 | { 69 | tohost_exit(code); 70 | } 71 | 72 | void abort() 73 | { 74 | exit(128 + SIGABRT); 75 | } 76 | 77 | void printstr(const char* s) 78 | { 79 | syscall(SYS_write, 1, (uintptr_t)s, strlen(s)); 80 | } 81 | 82 | void __attribute__((weak)) thread_entry(int cid, int nc) 83 | { 84 | // multi-threaded programs override this function. 85 | // for the case of single-threaded programs, only let core 0 proceed. 86 | while (cid != 0); 87 | } 88 | 89 | int __attribute__((weak)) main(int argc, char** argv) 90 | { 91 | // single-threaded programs override this function. 92 | printstr("Implement main(), foo!\n"); 93 | return -1; 94 | } 95 | 96 | static void init_tls() 97 | { 98 | register void* thread_pointer asm("tp"); 99 | extern char _tls_data; 100 | extern __thread char _tdata_begin, _tdata_end, _tbss_end; 101 | size_t tdata_size = &_tdata_end - &_tdata_begin; 102 | memcpy(thread_pointer, &_tls_data, tdata_size); 103 | size_t tbss_size = &_tbss_end - &_tdata_end; 104 | memset(thread_pointer + tdata_size, 0, tbss_size); 105 | } 106 | 107 | void _init(int cid, int nc) 108 | { 109 | init_tls(); 110 | thread_entry(cid, nc); 111 | 112 | // only single-threaded programs should ever get here. 113 | int ret = main(0, 0); 114 | 115 | char buf[NUM_COUNTERS * 32] __attribute__((aligned(64))); 116 | char* pbuf = buf; 117 | for (int i = 0; i < NUM_COUNTERS; i++) 118 | if (counters[i]) 119 | pbuf += sprintf(pbuf, "%s = %d\n", counter_names[i], counters[i]); 120 | if (pbuf != buf) 121 | printstr(buf); 122 | 123 | exit(ret); 124 | } 125 | 126 | #undef putchar 127 | int putchar(int ch) 128 | { 129 | static __thread char buf[64] __attribute__((aligned(64))); 130 | static __thread int buflen = 0; 131 | 132 | buf[buflen++] = ch; 133 | 134 | if (ch == '\n' || buflen == sizeof(buf)) 135 | { 136 | syscall(SYS_write, 1, (uintptr_t)buf, buflen); 137 | buflen = 0; 138 | } 139 | 140 | return 0; 141 | } 142 | 143 | void printhex(uint64_t x) 144 | { 145 | char str[17]; 146 | int i; 147 | for (i = 0; i < 16; i++) 148 | { 149 | str[15-i] = (x & 0xF) + ((x & 0xF) < 10 ? '0' : 'a'-10); 150 | x >>= 4; 151 | } 152 | str[16] = 0; 153 | 154 | printstr(str); 155 | } 156 | 157 | static inline void printnum(void (*putch)(int, void**), void **putdat, 158 | unsigned long long num, unsigned base, int width, int padc) 159 | { 160 | unsigned digs[sizeof(num)*CHAR_BIT]; 161 | int pos = 0; 162 | 163 | while (1) 164 | { 165 | digs[pos++] = num % base; 166 | if (num < base) 167 | break; 168 | num /= base; 169 | } 170 | 171 | while (width-- > pos) 172 | putch(padc, putdat); 173 | 174 | while (pos-- > 0) 175 | putch(digs[pos] + (digs[pos] >= 10 ? 'a' - 10 : '0'), putdat); 176 | } 177 | 178 | static unsigned long long getuint(va_list *ap, int lflag) 179 | { 180 | if (lflag >= 2) 181 | return va_arg(*ap, unsigned long long); 182 | else if (lflag) 183 | return va_arg(*ap, unsigned long); 184 | else 185 | return va_arg(*ap, unsigned int); 186 | } 187 | 188 | static long long getint(va_list *ap, int lflag) 189 | { 190 | if (lflag >= 2) 191 | return va_arg(*ap, long long); 192 | else if (lflag) 193 | return va_arg(*ap, long); 194 | else 195 | return va_arg(*ap, int); 196 | } 197 | 198 | static void vprintfmt(void (*putch)(int, void**), void **putdat, const char *fmt, va_list ap) 199 | { 200 | register const char* p; 201 | const char* last_fmt; 202 | register int ch, err; 203 | unsigned long long num; 204 | int base, lflag, width, precision, altflag; 205 | char padc; 206 | 207 | while (1) { 208 | while ((ch = *(unsigned char *) fmt) != '%') { 209 | if (ch == '\0') 210 | return; 211 | fmt++; 212 | putch(ch, putdat); 213 | } 214 | fmt++; 215 | 216 | // Process a %-escape sequence 217 | last_fmt = fmt; 218 | padc = ' '; 219 | width = -1; 220 | precision = -1; 221 | lflag = 0; 222 | altflag = 0; 223 | reswitch: 224 | switch (ch = *(unsigned char *) fmt++) { 225 | 226 | // flag to pad on the right 227 | case '-': 228 | padc = '-'; 229 | goto reswitch; 230 | 231 | // flag to pad with 0's instead of spaces 232 | case '0': 233 | padc = '0'; 234 | goto reswitch; 235 | 236 | // width field 237 | case '1': 238 | case '2': 239 | case '3': 240 | case '4': 241 | case '5': 242 | case '6': 243 | case '7': 244 | case '8': 245 | case '9': 246 | for (precision = 0; ; ++fmt) { 247 | precision = precision * 10 + ch - '0'; 248 | ch = *fmt; 249 | if (ch < '0' || ch > '9') 250 | break; 251 | } 252 | goto process_precision; 253 | 254 | case '*': 255 | precision = va_arg(ap, int); 256 | goto process_precision; 257 | 258 | case '.': 259 | if (width < 0) 260 | width = 0; 261 | goto reswitch; 262 | 263 | case '#': 264 | altflag = 1; 265 | goto reswitch; 266 | 267 | process_precision: 268 | if (width < 0) 269 | width = precision, precision = -1; 270 | goto reswitch; 271 | 272 | // long flag (doubled for long long) 273 | case 'l': 274 | lflag++; 275 | goto reswitch; 276 | 277 | // character 278 | case 'c': 279 | putch(va_arg(ap, int), putdat); 280 | break; 281 | 282 | // string 283 | case 's': 284 | if ((p = va_arg(ap, char *)) == NULL) 285 | p = "(null)"; 286 | if (width > 0 && padc != '-') 287 | for (width -= strnlen(p, precision); width > 0; width--) 288 | putch(padc, putdat); 289 | for (; (ch = *p) != '\0' && (precision < 0 || --precision >= 0); width--) { 290 | putch(ch, putdat); 291 | p++; 292 | } 293 | for (; width > 0; width--) 294 | putch(' ', putdat); 295 | break; 296 | 297 | // (signed) decimal 298 | case 'd': 299 | num = getint(&ap, lflag); 300 | if ((long long) num < 0) { 301 | putch('-', putdat); 302 | num = -(long long) num; 303 | } 304 | base = 10; 305 | goto signed_number; 306 | 307 | // unsigned decimal 308 | case 'u': 309 | base = 10; 310 | goto unsigned_number; 311 | 312 | // (unsigned) octal 313 | case 'o': 314 | // should do something with padding so it's always 3 octits 315 | base = 8; 316 | goto unsigned_number; 317 | 318 | // pointer 319 | case 'p': 320 | static_assert(sizeof(long) == sizeof(void*)); 321 | lflag = 1; 322 | putch('0', putdat); 323 | putch('x', putdat); 324 | /* fall through to 'x' */ 325 | 326 | // (unsigned) hexadecimal 327 | case 'x': 328 | base = 16; 329 | unsigned_number: 330 | num = getuint(&ap, lflag); 331 | signed_number: 332 | printnum(putch, putdat, num, base, width, padc); 333 | break; 334 | 335 | // escaped '%' character 336 | case '%': 337 | putch(ch, putdat); 338 | break; 339 | 340 | // unrecognized escape sequence - just print it literally 341 | default: 342 | putch('%', putdat); 343 | fmt = last_fmt; 344 | break; 345 | } 346 | } 347 | } 348 | 349 | int printf(const char* fmt, ...) 350 | { 351 | va_list ap; 352 | va_start(ap, fmt); 353 | 354 | vprintfmt((void*)putchar, 0, fmt, ap); 355 | 356 | va_end(ap); 357 | return 0; // incorrect return value, but who cares, anyway? 358 | } 359 | 360 | int sprintf(char* str, const char* fmt, ...) 361 | { 362 | va_list ap; 363 | char* str0 = str; 364 | va_start(ap, fmt); 365 | 366 | void sprintf_putch(int ch, void** data) 367 | { 368 | char** pstr = (char**)data; 369 | **pstr = ch; 370 | (*pstr)++; 371 | } 372 | 373 | vprintfmt(sprintf_putch, (void**)&str, fmt, ap); 374 | *str = 0; 375 | 376 | va_end(ap); 377 | return str - str0; 378 | } 379 | 380 | void* memcpy(void* dest, const void* src, size_t len) 381 | { 382 | if ((((uintptr_t)dest | (uintptr_t)src | len) & (sizeof(uintptr_t)-1)) == 0) { 383 | const uintptr_t* s = src; 384 | uintptr_t *d = dest; 385 | while (d < (uintptr_t*)(dest + len)) 386 | *d++ = *s++; 387 | } else { 388 | const char* s = src; 389 | char *d = dest; 390 | while (d < (char*)(dest + len)) 391 | *d++ = *s++; 392 | } 393 | return dest; 394 | } 395 | 396 | void* memset(void* dest, int byte, size_t len) 397 | { 398 | if ((((uintptr_t)dest | len) & (sizeof(uintptr_t)-1)) == 0) { 399 | uintptr_t word = byte & 0xFF; 400 | word |= word << 8; 401 | word |= word << 16; 402 | word |= word << 16 << 16; 403 | 404 | uintptr_t *d = dest; 405 | while (d < (uintptr_t*)(dest + len)) 406 | *d++ = word; 407 | } else { 408 | char *d = dest; 409 | while (d < (char*)(dest + len)) 410 | *d++ = byte; 411 | } 412 | return dest; 413 | } 414 | 415 | size_t strlen(const char *s) 416 | { 417 | const char *p = s; 418 | while (*p) 419 | p++; 420 | return p - s; 421 | } 422 | 423 | size_t strnlen(const char *s, size_t n) 424 | { 425 | const char *p = s; 426 | while (n-- && *p) 427 | p++; 428 | return p - s; 429 | } 430 | 431 | int strcmp(const char* s1, const char* s2) 432 | { 433 | unsigned char c1, c2; 434 | 435 | do { 436 | c1 = *s1++; 437 | c2 = *s2++; 438 | } while (c1 != 0 && c1 == c2); 439 | 440 | return c1 - c2; 441 | } 442 | 443 | char* strcpy(char* dest, const char* src) 444 | { 445 | char* d = dest; 446 | while ((*d++ = *src++)) 447 | ; 448 | return dest; 449 | } 450 | 451 | long atol(const char* str) 452 | { 453 | long res = 0; 454 | int sign = 0; 455 | 456 | while (*str == ' ') 457 | str++; 458 | 459 | if (*str == '-' || *str == '+') { 460 | sign = *str == '-'; 461 | str++; 462 | } 463 | 464 | while (*str) { 465 | res *= 10; 466 | res += *str++ - '0'; 467 | } 468 | 469 | return sign ? -res : res; 470 | } 471 | -------------------------------------------------------------------------------- /tests/util.h: -------------------------------------------------------------------------------- 1 | // See LICENSE for license details. 2 | 3 | #ifndef __UTIL_H 4 | #define __UTIL_H 5 | 6 | //-------------------------------------------------------------------------- 7 | // Macros 8 | 9 | // Set HOST_DEBUG to 1 if you are going to compile this for a host 10 | // machine (ie Athena/Linux) for debug purposes and set HOST_DEBUG 11 | // to 0 if you are compiling with the smips-gcc toolchain. 12 | 13 | #ifndef HOST_DEBUG 14 | #define HOST_DEBUG 0 15 | #endif 16 | 17 | // Set PREALLOCATE to 1 if you want to preallocate the benchmark 18 | // function before starting stats. If you have instruction/data 19 | // caches and you don't want to count the overhead of misses, then 20 | // you will need to use preallocation. 21 | 22 | #ifndef PREALLOCATE 23 | #define PREALLOCATE 0 24 | #endif 25 | 26 | // Set SET_STATS to 1 if you want to carve out the piece that actually 27 | // does the computation. 28 | 29 | #if HOST_DEBUG 30 | #include 31 | static void setStats(int enable) {} 32 | #else 33 | extern void setStats(int enable); 34 | #endif 35 | 36 | #include 37 | 38 | #define static_assert(cond) switch(0) { case 0: case !!(long)(cond): ; } 39 | 40 | static void printArray(const char name[], int n, const int arr[]) 41 | { 42 | #if HOST_DEBUG 43 | int i; 44 | printf( " %10s :", name ); 45 | for ( i = 0; i < n; i++ ) 46 | printf( " %3d ", arr[i] ); 47 | printf( "\n" ); 48 | #endif 49 | } 50 | 51 | static void printDoubleArray(const char name[], int n, const double arr[]) 52 | { 53 | #if HOST_DEBUG 54 | int i; 55 | printf( " %10s :", name ); 56 | for ( i = 0; i < n; i++ ) 57 | printf( " %g ", arr[i] ); 58 | printf( "\n" ); 59 | #endif 60 | } 61 | 62 | static int verify(int n, const volatile int* test, const int* verify) 63 | { 64 | int i; 65 | // Unrolled for faster verification 66 | for (i = 0; i < n/2*2; i+=2) 67 | { 68 | int t0 = test[i], t1 = test[i+1]; 69 | int v0 = verify[i], v1 = verify[i+1]; 70 | if (t0 != v0) return i+1; 71 | if (t1 != v1) return i+2; 72 | } 73 | if (n % 2 != 0 && test[n-1] != verify[n-1]) 74 | return n; 75 | return 0; 76 | } 77 | 78 | static int verifyDouble(int n, const volatile double* test, const double* verify) 79 | { 80 | int i; 81 | // Unrolled for faster verification 82 | for (i = 0; i < n/2*2; i+=2) 83 | { 84 | double t0 = test[i], t1 = test[i+1]; 85 | double v0 = verify[i], v1 = verify[i+1]; 86 | int eq1 = t0 == v0, eq2 = t1 == v1; 87 | if (!(eq1 & eq2)) return i+1+eq1; 88 | } 89 | if (n % 2 != 0 && test[n-1] != verify[n-1]) 90 | return n; 91 | return 0; 92 | } 93 | 94 | static void __attribute__((noinline)) barrier(int ncores) 95 | { 96 | static volatile int sense; 97 | static volatile int count; 98 | static __thread int threadsense; 99 | 100 | __sync_synchronize(); 101 | 102 | threadsense = !threadsense; 103 | if (__sync_fetch_and_add(&count, 1) == ncores-1) 104 | { 105 | count = 0; 106 | sense = threadsense; 107 | } 108 | else while(sense != threadsense) 109 | ; 110 | 111 | __sync_synchronize(); 112 | } 113 | 114 | static uint64_t lfsr(uint64_t x) 115 | { 116 | uint64_t bit = (x ^ (x >> 1)) & 1; 117 | return (x >> 1) | (bit << 62); 118 | } 119 | 120 | #ifdef __riscv 121 | #include "encoding.h" 122 | #endif 123 | 124 | #define stringify_1(s) #s 125 | #define stringify(s) stringify_1(s) 126 | #define stats(code, iter) do { \ 127 | unsigned long _c = -read_csr(mcycle), _i = -read_csr(minstret); \ 128 | code; \ 129 | _c += read_csr(mcycle), _i += read_csr(minstret); \ 130 | if (cid == 0) \ 131 | printf("\n%s: %ld cycles, %ld.%ld cycles/iter, %ld.%ld CPI\n", \ 132 | stringify(code), _c, _c/iter, 10*_c/iter%10, _c/_i, 10*_c/_i%10); \ 133 | } while(0) 134 | 135 | #endif //__UTIL_H 136 | -------------------------------------------------------------------------------- /verisim/.gitignore: -------------------------------------------------------------------------------- 1 | !.gitignore 2 | !Makefile 3 | !Makefrag-verilator 4 | -------------------------------------------------------------------------------- /verisim/Makefile: -------------------------------------------------------------------------------- 1 | base_dir=$(abspath ..) 2 | sim_dir=$(abspath .) 3 | 4 | include $(base_dir)/Makefrag-variables 5 | sim_name = verilator 6 | 7 | sim = $(sim_dir)/simulator-$(PROJECT)-$(CONFIG) 8 | sim_debug = $(sim_dir)/simulator-$(PROJECT)-$(CONFIG)-debug 9 | tether_file = $(build_dir)/$(CONFIG).tether 10 | 11 | default: $(sim) 12 | 13 | debug: $(sim_debug) 14 | 15 | CXXFLAGS := $(CXXFLAGS) -O1 -std=c++11 -I$(RISCV)/include -D__STDC_FORMAT_MACROS 16 | LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(sim_dir) -lfesvr -lpthread 17 | 18 | include $(base_dir)/Makefrag 19 | include $(sim_dir)/Makefrag-verilator 20 | ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),) 21 | -include $(build_dir)/$(long_name).d 22 | endif 23 | 24 | model_dir = $(build_dir)/$(long_name) 25 | model_dir_debug = $(build_dir)/$(long_name).debug 26 | 27 | model_header = $(model_dir)/V$(MODEL).h 28 | model_header_debug = $(model_dir_debug)/V$(MODEL).h 29 | 30 | model_mk = $(model_dir)/V$(MODEL).mk 31 | model_mk_debug = $(model_dir_debug)/V$(MODEL).mk 32 | 33 | $(model_mk): $(sim_vsrcs) $(sim_dotf) $(INSTALLED_VERILATOR) 34 | rm -rf $(build_dir)/$(long_name) 35 | mkdir -p $(build_dir)/$(long_name) 36 | $(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name) \ 37 | -o $(sim) $(sim_vsrcs) -f $(sim_dotf) -f $(sim_top_blackboxes) -f $(sim_harness_blackboxes) -LDFLAGS "$(LDFLAGS)" \ 38 | -CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(model_header)" 39 | touch $@ 40 | 41 | $(sim): $(model_mk) 42 | $(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name) -f V$(MODEL).mk 43 | 44 | 45 | $(model_mk_debug): $(sim_vsrcs) $(sim_dotf) $(INSTALLED_VERILATOR) 46 | rm -rf $(build_dir)/$(long_name) 47 | mkdir -p $(build_dir)/$(long_name).debug 48 | $(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(build_dir)/$(long_name).debug --trace \ 49 | -o $(sim_debug) $(sim_vsrcs) -f $(sim_dotf) -f $(sim_top_blackboxes) -f $(sim_harness_blackboxes) -LDFLAGS "$(LDFLAGS)" \ 50 | -CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(model_header_debug)" 51 | touch $@ 52 | 53 | $(sim_debug): $(model_mk_debug) 54 | $(MAKE) VM_PARALLEL_BUILDS=1 -C $(build_dir)/$(long_name).debug -f V$(MODEL).mk 55 | 56 | 57 | exec_sim = $(sim) 58 | exec_sim_debug = $(sim_debug) 59 | 60 | $(output_dir)/%.vcd: $(output_dir)/% $(sim_debug) 61 | cd $(sim_dir) && $(exec_sim_debug) +verbose -v$@ +max-cycles=$(timeout_cycles) $(perm_off) $< $(disasm) $(patsubst %.vcd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] 62 | 63 | $(output_dir)/%.vpd: $(output_dir)/% $(sim_debug) 64 | if command -v vcd2vpd > /dev/null 2>&1 ; then rm -f $<.vcd && mkfifo $<.vcd && { vcd2vpd $<.vcd $@ & } fi && \ 65 | cd $(sim_dir) && $(exec_sim_debug) +verbose -v$<.vcd +max-cycles=$(timeout_cycles) $(perm_off) $< $(disasm) $(patsubst %.vpd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] 66 | touch $@ 67 | 68 | clean: 69 | rm -rf $(build_dir) ./simulator-* 70 | 71 | .PHONY: clean default debug 72 | -------------------------------------------------------------------------------- /verisim/Makefrag-verilator: -------------------------------------------------------------------------------- 1 | # Build and install our own Verilator, to work around versionining issues. 2 | VERILATOR_VERSION=3.920 3 | VERILATOR_SRCDIR=verilator/src/verilator-$(VERILATOR_VERSION) 4 | INSTALLED_VERILATOR=$(abspath verilator/install/bin/verilator) 5 | $(INSTALLED_VERILATOR): $(VERILATOR_SRCDIR)/bin/verilator 6 | $(MAKE) -C $(VERILATOR_SRCDIR) installbin installdata 7 | touch $@ 8 | 9 | $(VERILATOR_SRCDIR)/bin/verilator: $(VERILATOR_SRCDIR)/Makefile 10 | $(MAKE) -C $(VERILATOR_SRCDIR) verilator_bin 11 | touch $@ 12 | 13 | $(VERILATOR_SRCDIR)/Makefile: $(VERILATOR_SRCDIR)/configure 14 | mkdir -p $(dir $@) 15 | cd $(dir $@) && ./configure --prefix=$(abspath verilator/install) 16 | 17 | $(VERILATOR_SRCDIR)/configure: verilator/verilator-$(VERILATOR_VERSION).tar.gz 18 | rm -rf $(dir $@) 19 | mkdir -p $(dir $@) 20 | cat $^ | tar -xz --strip-components=1 -C $(dir $@) 21 | touch $@ 22 | 23 | verilator/verilator-$(VERILATOR_VERSION).tar.gz: 24 | mkdir -p $(dir $@) 25 | wget http://www.veripool.org/ftp/verilator-$(VERILATOR_VERSION).tgz -O $@ 26 | 27 | # Run Verilator to produce a fast binary to emulate this circuit. 28 | VERILATOR := $(INSTALLED_VERILATOR) --cc --exe 29 | VERILATOR_FLAGS := --top-module $(MODEL) \ 30 | +define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \ 31 | +define+RANDOMIZE_GARBAGE_ASSIGN \ 32 | +define+STOP_COND=\$$c\(\"done_reset\"\) --assert \ 33 | --output-split 20000 \ 34 | --output-split-cfuncs 20000 \ 35 | -Wno-STMTDLY --x-assign unique \ 36 | -O3 -CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(MODEL) -DVERILATOR" 37 | -------------------------------------------------------------------------------- /vsim/.gitignore: -------------------------------------------------------------------------------- 1 | !Makefile 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /vsim/Makefile: -------------------------------------------------------------------------------- 1 | base_dir=$(abspath ..) 2 | sim_dir=$(abspath .) 3 | 4 | include $(base_dir)/Makefrag-variables 5 | 6 | sim_name = vcs 7 | 8 | sim = $(sim_dir)/simv-$(PROJECT)-$(CONFIG) 9 | sim_debug = $(sim_dir)/simv-$(PROJECT)-$(CONFIG)-debug 10 | 11 | default: $(sim) 12 | 13 | debug: $(sim_debug) 14 | 15 | include $(base_dir)/Makefrag 16 | ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),) 17 | -include $(build_dir)/$(long_name).d 18 | endif 19 | 20 | VCS = vcs -full64 21 | 22 | VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -error=PCWM-L -timescale=1ns/10ps -quiet \ 23 | +rad +v2k +vcs+lic+wait \ 24 | +vc+list -CC "-I$(VCS_HOME)/include" \ 25 | -CC "-I$(RISCV)/include" \ 26 | -CC "-std=c++11" \ 27 | -CC "-Wl,-rpath,$(RISCV)/lib" \ 28 | -f $(sim_top_blackboxes) -f $(sim_harness_blackboxes) -f $(sim_dotf) \ 29 | $(RISCV)/lib/libfesvr.so \ 30 | -sverilog \ 31 | +incdir+$(build_dir) \ 32 | +define+CLOCK_PERIOD=1.0 $(sim_vsrcs) \ 33 | +define+PRINTF_COND=$(TB).printf_cond \ 34 | +define+STOP_COND=!$(TB).reset \ 35 | +define+RANDOMIZE_MEM_INIT \ 36 | +define+RANDOMIZE_REG_INIT \ 37 | +define+RANDOMIZE_GARBAGE_ASSIGN \ 38 | +define+RANDOMIZE_INVALID_ASSIGN \ 39 | +define+RANDOMIZE_DELAY=2 \ 40 | +libext+.v \ 41 | 42 | verilog: $(sim_vsrcs) 43 | 44 | $(sim): $(sim_vsrcs) $(sim_dotf) 45 | rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \ 46 | -debug_pp 47 | 48 | $(sim_debug) : $(sim_vsrcs) $(sim_dotf) 49 | rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \ 50 | +define+DEBUG -debug_pp 51 | 52 | exec_sim=$(sim) +permissive -q +ntb_random_seed_automatic 53 | exec_sim_debug=$(sim_debug) +permissive -q +ntb_random_seed_automatic 54 | 55 | $(output_dir)/%.vpd: $(output_dir)/% $(sim_debug) 56 | cd $(sim_dir) && $(exec_sim_debug) +verbose +vcdplusfile=$@ +max-cycles=$(timeout_cycles) $(perm_off) $< $(disasm) $(patsubst %.vpd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] 57 | 58 | $(output_dir)/%.saif: $(output_dir)/% $(sim_debug) 59 | cd $(sim_dir) && rm -f $(output_dir)/pipe-$*.vcd && vcd2saif -input $(output_dir)/pipe-$*.vcd -pipe "$(exec_sim_debug) +verbose +vcdfile=$(output_dir)/pipe-$*.vcd +max-cycles=$(bmark_timeout_cycles) $(perm_off) $<" -output $@ > $(patsubst %.saif,%.out,$@) 2>&1 60 | 61 | clean: 62 | rm -rf $(build_dir) csrc simv-* ucli.key vc_hdrs.h 63 | 64 | .PHONY: clean default debug 65 | --------------------------------------------------------------------------------