diff --git a/.github/workflows/mill-ci.yml b/.github/workflows/mill-ci.yml index 5ffecd1658..0d03a2eb5a 100644 --- a/.github/workflows/mill-ci.yml +++ b/.github/workflows/mill-ci.yml @@ -72,7 +72,7 @@ jobs: if: ${{ false }} # disable for now, I prefer adding firesim-based simulation framework in the future. strategy: matrix: - config: ["DefaultRV32Config,32,RV32IMACZicsr_Zifencei", "DefaultConfig,64,RV64IMACZicsr_Zifencei", "BitManipCryptoConfig,64,RV64IZba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh_Zksed_Zksh", "BitManipCrypto32Config,32,RV32IZba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh_Zksed_Zksh"] + config: ["DefaultRV32Config,32,RV32IMACZicsr_Zifencei", "DefaultConfig,64,RV64IMACZicsr_Zifencei"] steps: - uses: actions/checkout@v2 with: diff --git a/.gitmodules b/.gitmodules index 77819d7f76..fa1f58748f 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,9 +1,9 @@ -[submodule "hardfloat"] - path = hardfloat +[submodule "dependencies/hardfloat"] + path = dependencies/hardfloat url = https://github.com/ucb-bar/berkeley-hardfloat.git -[submodule "torture"] - path = torture - url = https://github.com/ucb-bar/riscv-torture.git -[submodule "cde"] - path = cde +[submodule "dependencies/cde"] + path = dependencies/cde url = https://github.com/chipsalliance/cde.git +[submodule "dependencies/chisel"] + path = dependencies/chisel + url = https://github.com/chipsalliance/chisel.git diff --git a/Makefile b/Makefile new file mode 100644 index 0000000000..a252f896a3 --- /dev/null +++ b/Makefile @@ -0,0 +1,14 @@ +base_dir=$(abspath ./) + +CHISEL_VERSION=3.6.0 +MODEL ?= TestHarness +PROJECT ?= freechips.rocketchip.system +CFG_PROJECT ?= $(PROJECT) +CONFIG ?= $(CFG_PROJECT).DefaultConfig +MILL ?= mill + +verilog: + cd $(base_dir) && $(MILL) emulator[freechips.rocketchip.system.TestHarness,$(CONFIG)].mfccompiler.compile + +clean: + rm -rf out/ diff --git a/Makefrag b/Makefrag deleted file mode 100644 index 829d26f0e3..0000000000 --- a/Makefrag +++ /dev/null @@ -1,74 +0,0 @@ -# check RISCV environment variable -ifndef RISCV -$(error Please set environment variable RISCV. Please take a look at README) -endif - -MODEL ?= TestHarness -PROJECT ?= freechips.rocketchip.system -CFG_PROJECT ?= $(PROJECT) -CONFIG ?= $(CFG_PROJECT).DefaultConfig -# TODO: For now must match rocketchip.Generator -comma := , -space := $() $() -splitConfigs := $(subst $(comma), ,$(CONFIG)) -configBases := $(foreach config,$(splitConfigs),$(lastword $(subst ., ,$(config)))) -CONFIG_STR := $(subst $(space),_,$(configBases)) -long_name ?= $(PROJECT).$(CONFIG_STR) - -VLSI_MEM_GEN ?= $(base_dir)/scripts/vlsi_mem_gen - -CXX ?= g++ -CXXFLAGS := -O1 -JVM_MEMORY ?= 2G - -EMPTY := -SPACE := $(EMPTY) $(EMPTY) -COMMA := , - -MILL ?= mill -SHELL := /bin/bash - -FIRRTL_TRANSFORMS := \ - firrtl.passes.InlineInstances \ - -FIRRTL_TEST_JAR ?= $(base_dir)/firrtl/utils/bin/firrtl-test.jar - -JAVA ?= java -Xmx$(JVM_MEMORY) -Xss8M -FIRRTL ?= $(JAVA) -cp $(ROCKET_CHIP_JAR) firrtl.stage.FirrtlMain -GENERATOR ?= $(JAVA) -cp $(ROCKET_CHIP_JAR) $(PROJECT).Generator - -scala_srcs := $(shell find $(base_dir) -name "*.scala" -o -name "*.sc") -resource_dirs := $(shell find $(base_dir) -type d -path "*/src/main/resources") -resources := $(foreach d,$(resource_dirs),$(shell find $(d) -type f)) -all_srcs := $(scala_srcs) $(resources) - -ROCKET_CHIP_JAR := $(base_dir)/out/rocketchip/assembly.dest/out.jar -$(ROCKET_CHIP_JAR): $(all_srcs) - cd $(base_dir) && $(MILL) rocketchip.assembly - -rc_resource_dir := $(base_dir)/src/main/resources -csrc := $(rc_resource_dir)/csrc -vsrc := $(rc_resource_dir)/vsrc - -disasm := 2> -which_disasm := $(shell which spike-dasm 2> /dev/null) -ifneq ($(which_disasm),) - disasm := 3>&1 1>&2 2>&3 | $(which_disasm) $(DISASM_EXTENSION) > -endif - -timeout_cycles = 100000000 - -bootrom_img = $(base_dir)/bootrom/bootrom.img - -#-------------------------------------------------------------------- -# Build Tests -#-------------------------------------------------------------------- - -%.hex: - $(MAKE) -C $(dir $@) $(notdir $@) - -%.riscv.hex: %.riscv - $(MAKE) -C $(dir $@) $(notdir $@) - -clean-run-output: - rm -f $(output_dir)/{*.out,*.run,*.vpd} diff --git a/README.md b/README.md index fd4499e112..32059adb55 100644 --- a/README.md +++ b/README.md @@ -34,25 +34,6 @@ For possible time adjustments, they will be negotiated in Slack and published in $ cd rocket-chip $ git submodule update --init -### Setting up the RISCV environment variable - -To build the rocket-chip repository, you must point the RISCV -environment variable to your rocket-tools installation directory. - - $ export RISCV=/path/to/riscv/toolchain/installation - -The rocket-tools repository known to work with rocket-chip is noted -in the file riscv-tools.hash. However, any recent rocket-tools should work. -You can build rocket-tools as follows: - - $ git clone https://github.com/freechipsproject/rocket-tools - $ cd rocket-tools - $ git submodule update --init --recursive - $ export RISCV=/path/to/install/riscv/toolchain - $ export MAKEFLAGS="$MAKEFLAGS -jN" # Assuming you have N cores on your host system - $ ./build.sh - $ ./build-rv32ima.sh (if you are using RV32). - ### Install Necessary Dependencies You may need to install some additional packages to use this repository. @@ -63,36 +44,13 @@ Rather than list all dependencies here, please see the appropriate section of th ### Building The Project -First, to build the C simulator: - - $ cd emulator - $ make - -Or to build the VCS simulator: - - $ cd vsim - $ make - -In either case, you can run a set of assembly tests or simple benchmarks -(Assuming you have N cores on your host system): - - $ make -jN run-asm-tests - $ make -jN run-bmark-tests +Generating verilog -To build a C simulator that is capable of VCD waveform generation: - - $ cd emulator - $ make debug - -And to run the assembly tests on the C simulator and generate waveforms: - - $ make -jN run-asm-tests-debug - $ make -jN run-bmark-tests-debug + $ make verilog -To generate FPGA- or VLSI-synthesizable Verilog (output will be in `vsim/generated-src`): +Generating verilog for a specific Config - $ cd vsim - $ make verilog + $ make verilog CONFIG=DefaultSmallConfig ### Keeping Your Repo Up-to-Date @@ -224,460 +182,6 @@ Directory in which Synopsys VCS simulations are compiled and run. * **vsrc** Verilog sources containing interfaces, harnesses and VPI. - -### Extending the Top-Level Design - -See [this description](https://github.com/ucb-bar/project-template) of how to create -you own top-level design with custom devices. - -## How should I use the Rocket chip generator? - -Chisel can generate code for three targets: a high-performance -cycle-accurate Verilator, Verilog optimized for FPGAs, and Verilog -for VLSI. The rocket-chip generator can target all three backends. You -will need a Java runtime installed on your machine, since Chisel is -overlaid on top of [Scala](http://www.scala-lang.org/). Chisel RTL (i.e. -rocket-chip source code) is a Scala program executing on top of your -Java runtime. To begin, ensure that the ROCKETCHIP environment variable -points to the rocket-chip repository. - - $ git clone https://github.com/ucb-bar/rocket-chip.git - $ cd rocket-chip - $ export ROCKETCHIP=`pwd` - $ git submodule update --init - -Before going any further, you must point the RISCV environment variable -to your rocket-tools installation directory. If you do not yet have -rocket-tools installed, follow the directions in the -[rocket-tools/README](https://github.com/freechipsproject/rocket-tools/blob/master/README.md). - - export RISCV=/path/to/install/riscv/toolchain - -Otherwise, you will see the following error message while executing any -command in the rocket-chip generator: - - *** Please set environment variable RISCV. Please take a look at README. - -### 1) Using the high-performance cycle-accurate Verilator - -Your next step is to get the Verilator working. Assuming you have N -cores on your host system, do the following: - - $ cd $ROCKETCHIP/emulator - $ make -jN run - -By doing so, the build system will generate C++ code for the -cycle-accurate emulator, compile the emulator, compile all RISC-V -assembly tests and benchmarks, and run both tests and benchmarks on the -emulator. If Make finished without any errors, it means that the -generated Rocket chip has passed all assembly tests and benchmarks! - -You can also run assembly tests and benchmarks separately: - - $ make -jN run-asm-tests - $ make -jN run-bmark-tests - -To generate vcd waveforms, you can run one of the following commands: - - $ make -jN run-debug - $ make -jN run-asm-tests-debug - $ make -jN run-bmark-tests-debug - -Or call out individual assembly tests or benchmarks: - - $ make output/rv64ui-p-add.out - $ make output/rv64ui-p-add.vcd - -Now take a look in the emulator/generated-src directory. You will find -Chisel generated Verilog code and its associated C++ code generated by -Verilator. - - $ ls $ROCKETCHIP/emulator/generated-src - freechips.rocketchip.system.DefaultConfig - freechips.rocketchip.system.DefaultConfig.0x0.0.regmap.json - freechips.rocketchip.system.DefaultConfig.0x0.1.regmap.json - freechips.rocketchip.system.DefaultConfig.0x2000000.0.regmap.json - freechips.rocketchip.system.DefaultConfig.0x40.0.regmap.json - freechips.rocketchip.system.DefaultConfig.0xc000000.0.regmap.json - freechips.rocketchip.system.DefaultConfig.anno.json - freechips.rocketchip.system.DefaultConfig.behav_srams.v - freechips.rocketchip.system.DefaultConfig.conf - freechips.rocketchip.system.DefaultConfig.d - freechips.rocketchip.system.DefaultConfig.dts - freechips.rocketchip.system.DefaultConfig.fir - freechips.rocketchip.system.DefaultConfig.graphml - freechips.rocketchip.system.DefaultConfig.json - freechips.rocketchip.system.DefaultConfig.memmap.json - freechips.rocketchip.system.DefaultConfig.plusArgs - freechips.rocketchip.system.DefaultConfig.rom.conf - freechips.rocketchip.system.DefaultConfig.v - TestHarness.anno.json - $ ls $ROCKETCHIP/emulator/generated-src/freechips.rocketchip.system.DefaultConfig - VTestHarness__1.cpp - VTestHarness__2.cpp - VTestHarness__3.cpp - ... - -Also, output of the executed assembly tests and benchmarks can be found -at emulator/output/\*.out. Each file has a cycle-by-cycle dump of -write-back stage of the pipeline. Here's an excerpt of -emulator/output/rv64ui-p-add.out: - - C0: 483 [1] pc=[00000002138] W[r 3=000000007fff7fff][1] R[r 1=000000007fffffff] R[r 2=ffffffffffff8000] inst=[002081b3] add s1, ra, s0 - C0: 484 [1] pc=[0000000213c] W[r29=000000007fff8000][1] R[r31=ffffffff80007ffe] R[r31=0000000000000005] inst=[7fff8eb7] lui t3, 0x7fff8 - C0: 485 [0] pc=[00000002140] W[r 0=0000000000000000][0] R[r 0=0000000000000000] R[r 0=0000000000000000] inst=[00000000] unknown - -The first [1] at cycle 483, core 0, shows that there's a -valid instruction at PC 0x2138 in the writeback stage, which is -0x002081b3 (add s1, ra, s0). The second [1] tells us that the register -file is writing r3 with the corresponding value 0x7fff7fff. When the add -instruction was in the decode stage, the pipeline had read r1 and r2 -with the corresponding values next to it. Similarly at cycle 484, -there's a valid instruction (lui instruction) at PC 0x213c in the -writeback stage. At cycle 485, there isn't a valid instruction in the -writeback stage, perhaps, because of a instruction cache miss at PC -0x2140. - -### 2) Mapping a Rocket core to an FPGA - -You can generate synthesizable Verilog with the following commands: - - $ cd $ROCKETCHIP/vsim - $ make verilog CONFIG=freechips.rocketchip.system.DefaultFPGAConfig - -The Verilog used for the FPGA tools will be generated in -vsim/generated-src. Please proceed further with the directions shown in -the [README](https://github.com/sifive/freedom/blob/master/README.md) -of the freedom repository. You can also run Rocket Chip on Amazon EC2 F1 -with [FireSim](https://github.com/firesim/firesim). - - -If you have access to VCS, you will be able to run assembly -tests and benchmarks in simulation with the following commands -(again assuming you have N cores on your host machine): - - $ cd $ROCKETCHIP/vsim - $ make -jN run CONFIG=freechips.rocketchip.system.DefaultFPGAConfig - -The generated output looks similar to those generated from the emulator. -Look into vsim/output/\*.out for the output of the executed assembly -tests and benchmarks. - -### 3) Pushing a Rocket core through the VLSI tools - -You can generate Verilog for your VLSI flow with the following commands: - - $ cd $ROCKETCHIP/vsim - $ make verilog - -Now take a look at vsim/generated-src, and the contents of the -Top.DefaultConfig.conf file: - - $ cd $ROCKETCHIP/vsim/generated-src - freechips.rocketchip.system.DefaultConfig - freechips.rocketchip.system.DefaultConfig.0x0.0.regmap.json - freechips.rocketchip.system.DefaultConfig.0x0.1.regmap.json - freechips.rocketchip.system.DefaultConfig.0x2000000.0.regmap.json - freechips.rocketchip.system.DefaultConfig.0x40.0.regmap.json - freechips.rocketchip.system.DefaultConfig.0xc000000.0.regmap.json - freechips.rocketchip.system.DefaultConfig.anno.json - freechips.rocketchip.system.DefaultConfig.behav_srams.v - freechips.rocketchip.system.DefaultConfig.conf - freechips.rocketchip.system.DefaultConfig.d - freechips.rocketchip.system.DefaultConfig.dts - freechips.rocketchip.system.DefaultConfig.fir - freechips.rocketchip.system.DefaultConfig.graphml - freechips.rocketchip.system.DefaultConfig.json - freechips.rocketchip.system.DefaultConfig.memmap.json - freechips.rocketchip.system.DefaultConfig.plusArgs - freechips.rocketchip.system.DefaultConfig.rom.conf - freechips.rocketchip.system.DefaultConfig.v - TestHarness.anno.json - $ cat $ROCKETCHIP/vsim/generated-src/*.conf - name data_arrays_0_ext depth 512 width 256 ports mrw mask_gran 8 - name tag_array_ext depth 64 width 88 ports mrw mask_gran 22 - name tag_array_0_ext depth 64 width 84 ports mrw mask_gran 21 - name data_arrays_0_1_ext depth 512 width 128 ports mrw mask_gran 32 - name mem_ext depth 33554432 width 64 ports mwrite,read mask_gran 8 - name mem_2_ext depth 512 width 64 ports mwrite,read mask_gran 8 - -The conf file contains information for all SRAMs instantiated in the -flow. If you take a close look at the $ROCKETCHIP/Makefrag, you will see -that during Verilog generation, the build system calls a $(mem\_gen) -script with the generated configuration file as an argument, which will -fill in the Verilog for the SRAMs. Currently, the $(mem\_gen) script -points to vsim/vlsi\_mem\_gen, which simply instantiates behavioral -SRAMs. You will see those SRAMs being appended at the end of -vsim/generated-src/Top.DefaultConfig.v. To target vendor-specific -SRAMs, you will need to make necessary changes to vsim/vlsi\_mem\_gen. - -Similarly, if you have access to VCS, you can run assembly tests and -benchmarks with the following commands (again assuming you have N cores -on your host machine): - - $ cd $ROCKETCHIP/vsim - $ make -jN run - -The generated output looks similar to those generated from the emulator. -Look into vsim/output/\*.out for the output of the executed assembly -tests and benchmarks. - -## How can I parameterize my Rocket chip? - -By now, you probably figured out that all generated files have a configuration -name attached, e.g. `freechips.rocketchip.system.DefaultConfig`. Take a look at -`src/main/scala/system/Configs.scala`. Search for `NSets` and `NWays` defined in -`BaseConfig`. You can change those numbers to get a Rocket core with different -cache parameters. For example, by changing L1I, NWays to 4, you will get -a 32KB 4-way set-associative L1 instruction cache rather than a 16KB 2-way -set-associative L1 instruction cache. -Towards the end, you can also find that `DefaultSmallConfig` inherits all -parameters from `BaseConfig` but overrides the same parameters of -`WithNSmallCores`. - -Now take a look at `vsim/Makefile`. Search for the `CONFIG` variable. -By default, it is set to `freechips.rocketchip.system.DefaultConfig`. You can also change the -CONFIG variable on the make command line: - - $ cd $ROCKETCHIP/vsim - $ make -jN CONFIG=freechips.rocketchip.system.DefaultSmallConfig run-asm-tests - -Or, even by defining CONFIG as an environment variable: - - $ export CONFIG=freechips.rocketchip.system.DefaultSmallConfig - $ make -jN run-asm-tests - -This parameterization is one of the many strengths of processor -generators written in Chisel, and will be more detailed in a future blog -post, so please stay tuned. - -To override specific configuration items, such as the number of external interrupts, -you can create your own Configuration(s) and compose them with Config's ++ operator - - class WithNExtInterrupts(nExt: Int) extends Config { - (site, here, up) => { - case NExtInterrupts => nExt - } - } - class MyConfig extends Config (new WithNExtInterrupts(16) ++ new DefaultSmallConfig) - -Then you can build as usual with `CONFIG=.MyConfig`. - -## Debugging with GDB - -### 1) Generating the Remote Bit-Bang (RBB) Emulator - -The objective of this section is to use GNU debugger to debug RISC-V programs running on the emulator in the same fashion as in [Spike](https://github.com/riscv/riscv-isa-sim#debugging-with-gdb). - -For that we need to add a Remote Bit-Bang client to the emulator. We can do so by extending our Config with JtagDTMSystem, which will add a DebugTransportModuleJTAG to the DUT and connect a SimJTAG module in the Test Harness. This will allow OpenOCD to interface with the emulator, and GDB can interface with OpenOCD. In the following example we add this Config alteration to `src/main/scala/system/Configs.scala`: - - class DefaultConfigRBB extends Config( - new WithJtagDTMSystem ++ new WithNBigCores(1) ++ new WithCoherentBusTopology ++ new BaseConfig) - - class QuadCoreConfigRBB extends Config( - new WithJtagDTMSystem ++ new WithNBigCores(4) ++ new WithCoherentBusTopology ++ new BaseConfig) - -To build the emulator with `DefaultConfigRBB` configuration we use the command: - - rocket-chip$ cd emulator - emulator$ CONFIG=freechips.rocketchip.system.DefaultConfigRBB make - -We can also build a debug version capable of generating VCD waveforms using the command: - - emulator$ CONFIG=freechips.rocketchip.system.DefaultConfigRBB make debug - -By default the emulator is generated under the name `emulator-freechips.rocketchip.system-DefaultConfigRBB` in the first case and `emulator-freechips.rocketchip.system-DefaultConfigRBB-debug` in the second. - -### 2) Compiling and executing a custom program using the emulator - -We suppose that `helloworld` is our program, you can use `crt.S`, `syscalls.c` and the linker script `test.ld` to construct your own program, check examples stated in [riscv-tests](https://github.com/riscv/riscv-tests). Note that `test.ld` loads the program at 0x80000000 so you will need to use `-mcmodel=medany` otherwise you will get relocation errors. See [All Aboard, Part 4: The RISC-V Code Models](https://www.sifive.com/blog/2017/09/11/all-aboard-part-4-risc-v-code-models/) for more details. - -In our case we will use the following example: - -``` -char text[] = "Vafgehpgvba frgf jnag gb or serr!"; - -// Don't use the stack, because sp isn't set up. -volatile int wait = 1; - -int main() -{ - while (wait) - ; - - // Doesn't actually go on the stack, because there are lots of GPRs. - int i = 0; - while (text[i]) { - char lower = text[i] | 32; - if (lower >= 'a' && lower <= 'm') - text[i] += 13; - else if (lower > 'm' && lower <= 'z') - text[i] -= 13; - i++; - } - - while (!wait) - ; -} -``` - -First we can test if your program executes well in the simple version of emulator before moving to debugging in step 3 : - - $ ./emulator-freechips.rocketchip.system-DefaultConfig helloworld - -Additional verbose information (clock cycle, pc, instruction being executed) can be printed using the following command: - - $ ./emulator-freechips.rocketchip.system-DefaultConfig +verbose helloworld 2>&1 | spike-dasm - -VCD output files can be obtained using the `-debug` version of the emulator and are specified using `-v` or `--vcd=FILE` arguments. A detailed log file of all executed instructions can also be obtained from the emulator, this is an example: - - $ ./emulator-freechips.rocketchip.system-DefaultConfig-debug +verbose -v output.vcd helloworld 2>&1 | spike-dasm > output.log - -Please note that generated VCD waveforms and execution log files can be very voluminous depending on the size of the .elf file (i.e. code size + debugging symbols). - -Please note also that the time it takes the emulator to load your program depends on executable size. Stripping the .elf executable will unsurprisingly make it run faster. For this you can use `$RISCV/bin/riscv64-unknown-elf-strip` tool to reduce the size. This is good for accelerating your simulation but not for debugging. Keep in mind that the HTIF communication interface between our system and the emulator relies on `tohost` and `fromhost` symbols to communicate. This is why you may get the following error when you try to run a totally stripped executable on the emulator: - - $ ./emulator-freechips.rocketchip.system-DefaultConfig totally-stripped-helloworld - This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1. - Listening on port 46529 - warning: tohost and fromhost symbols not in ELF; can't communicate with target - -To resolve this, we need to strip all the .elf executable but keep `tohost` and `fromhost` symbols using the following command: - - $riscv64-unknown-elf-strip -s -Kfromhost -Ktohost helloworld - -More details on the GNU strip tool can be found [here](https://www.thegeekstuff.com/2012/09/strip-command-examples/). - -The interest of this step is to make sure your program executes well. To perform debugging you need the original unstripped version, as explained in step 3. - -### 3) Launch the emulator - -First, do not forget to compile your program with `-g -Og` flags to provide debugging support as explained [here](https://github.com/riscv/riscv-isa-sim#debugging-with-gdb). - -We can then launch the Remote Bit-Bang enabled emulator with: - - ./emulator-freechips.rocketchip.system-DefaultConfigRBB +jtag_rbb_enable=1 --rbb-port=9823 helloworld - This emulator compiled with JTAG Remote Bitbang client. To enable, use +jtag_rbb_enable=1. - Listening on port 9823 - Attempting to accept client socket - -You can also use the `emulator-freechips.rocketchip.system-DefaultConfigRBB-debug` version instead if you would like to generate VCD waveforms. - -Please note that if the argument `--rbb-port` is not passed, a default free TCP port on your computer will be chosen randomly. - -Please note also that when debugging with GDB, the .elf file is not actually loaded by the FESVR. In contrast with Spike, it must be loaded from GDB as explained in step 5. So the `helloworld` argument may be replaced by any dummy name. - -### 4) Launch OpenOCD - -You will need a RISC-V Enabled OpenOCD binary. This is installed with rocket-tools in `$(RISCV)/bin/openocd`, or can be compiled manually from riscv-openocd. OpenOCD requires a configuration file, in which we define the RBB port we will use, which is in our case `9823`. - - $ cat cemulator.cfg - interface remote_bitbang - remote_bitbang_host localhost - remote_bitbang_port 9823 - - set _CHIPNAME riscv - jtag newtap $_CHIPNAME cpu -irlen 5 - - set _TARGETNAME $_CHIPNAME.cpu - target create $_TARGETNAME riscv -chain-position $_TARGETNAME - - gdb_report_data_abort enable - - init - halt - -Then we launch OpenOCD in another terminal using the command - - $(RISCV)/bin/openocd -f ./cemulator.cfg - Open On-Chip Debugger 0.10.0+dev-00112-g3c1c6e0 (2018-04-12-10:40) - Licensed under GNU GPL v2 - For bug reports, read - http://openocd.org/doc/doxygen/bugs.html - Warn : Adapter driver 'remote_bitbang' did not declare which transports it allows; assuming legacy JTAG-only - Info : only one transport option; autoselect 'jtag' - Info : Initializing remote_bitbang driver - Info : Connecting to localhost:9823 - Info : remote_bitbang driver initialized - Info : This adapter doesn't support configurable speed - Info : JTAG tap: riscv.cpu tap/device found: 0x00000001 (mfg: 0x000 (), part: 0x0000, ver: 0x0) - Info : datacount=2 progbufsize=16 - Info : Disabling abstract command reads from CSRs. - Info : Disabling abstract command writes to CSRs. - Info : [0] Found 1 triggers - Info : Examined RISC-V core; found 1 harts - Info : hart 0: XLEN=64, 1 triggers - Info : Listening on port 3333 for gdb connections - Info : Listening on port 6666 for tcl connections - Info : Listening on port 4444 for telnet connections - -A `-d` flag can be added to the command to show further debug information. - -### 5) Launch GDB - -In another terminal launch GDB and point to the elf file you would like to load then run it with the debugger (in this example, `helloworld`): - - $ riscv64-unknown-elf-gdb helloworld - GNU gdb (GDB) 8.0.50.20170724-git - Copyright (C) 2017 Free Software Foundation, Inc. - License GPLv3+: GNU GPL version 3 or later - This is free software: you are free to change and redistribute it. - There is NO WARRANTY, to the extent permitted by law. Type "show copying" - and "show warranty" for details. - This GDB was configured as "--host=x86_64-pc-linux-gnu --target=riscv64-unknown-elf". - Type "show configuration" for configuration details. - For bug reporting instructions, please see: - . - Find the GDB manual and other documentation resources online at: - . - For help, type "help". - Type "apropos word" to search for commands related to "word"... - Reading symbols from ./proj1.out...done. - (gdb) - -Compared to Spike, the C Emulator is very slow, so several problems may be encountered due to timeouts between issuing commands and response from the emulator. To solve this problem, we increase the timeout with the GDB `set remotetimeout` command. - -After that we load our program by performing a `load` command. This automatically sets the `$PC` to the `_start` symbol in our .elf file. - - (gdb) set remotetimeout 2000 - (gdb) target remote localhost:3333 - Remote debugging using localhost:3333 - 0x0000000000010050 in ?? () - (gdb) load - Loading section .text.init, size 0x2cc lma 0x80000000 - Loading section .tohost, size 0x48 lma 0x80001000 - Loading section .text, size 0x98c lma 0x80001048 - Loading section .rodata, size 0x158 lma 0x800019d4 - Loading section .rodata.str1.8, size 0x20 lma 0x80001b30 - Loading section .data, size 0x22 lma 0x80001b50 - Loading section .sdata, size 0x4 lma 0x80001b74 - Start address 0x80000000, load size 3646 - Transfer rate: 40 bytes/sec, 520 bytes/write. - (gdb) - -Now we can proceed as with Spike, debugging works in a similar way: - - (gdb) print wait - $1 = 1 - (gdb) print wait=0 - $2 = 0 - (gdb) print text - $3 = "Vafgehpgvba frgf jnag gb or serr!" - (gdb) c - Continuing. - - ^C - Program received signal SIGINT, Interrupt. - main (argc=0, argv=) at src/main.c:33 - 33 while (!wait) - (gdb) print wait - $4 = 0 - (gdb) print text - $5 = "Instruction sets want to be free!" - (gdb) - -Further information about GDB debugging is available [here](https://sourceware.org/gdb/onlinedocs/gdb/) and [here](https://sourceware.org/gdb/onlinedocs/gdb/Remote-Debugging.html#Remote-Debugging). - ## IDEs Support The Rocket Chip Scala build uses [mill](https://github.com/com-lihaoyi/mill) as build tool. diff --git a/build.sc b/build.sc index bfd9eb3e0e..b19e7a8927 100644 --- a/build.sc +++ b/build.sc @@ -2,20 +2,35 @@ import mill._ import mill.scalalib._ import mill.scalalib.publish._ import coursier.maven.MavenRepository -import $file.hardfloat.common -import $file.cde.common +import $file.dependencies.hardfloat.common +import $file.dependencies.cde.common +import $file.dependencies.chisel.build import $file.common object v { - val scala = "2.13.10" + val scala = "2.13.12" // the first version in this Map is the mainly supported version which will be used to run tests val chiselCrossVersions = Map( - "3.6.0" -> (ivy"edu.berkeley.cs::chisel3:3.6.0", ivy"edu.berkeley.cs:::chisel3-plugin:3.6.0"), - "5.0.0" -> (ivy"org.chipsalliance::chisel:5.0.0", ivy"org.chipsalliance:::chisel-plugin:5.0.0"), + "5.1.0" -> (ivy"org.chipsalliance::chisel:5.1.0", ivy"org.chipsalliance:::chisel-plugin:5.1.0"), + // build from project from source + "source" -> (ivy"org.chipsalliance::chisel:99", ivy"org.chipsalliance:::chisel-plugin:99"), ) val mainargs = ivy"com.lihaoyi::mainargs:0.5.0" val json4sJackson = ivy"org.json4s::json4s-jackson:4.0.5" val scalaReflect = ivy"org.scala-lang:scala-reflect:${scala}" + val sonatypesSnapshots = Seq( + MavenRepository("https://s01.oss.sonatype.org/content/repositories/snapshots") + ) +} + +// Build form source only for dev +object chisel extends Chisel + +trait Chisel + extends millbuild.dependencies.chisel.build.Chisel { + def crossValue = v.scala + override def millSourcePath = os.pwd / "dependencies" / "chisel" + def scalaVersion = T(v.scala) } object macros extends Macros @@ -33,33 +48,35 @@ trait Macros object hardfloat extends mill.define.Cross[Hardfloat](v.chiselCrossVersions.keys.toSeq) trait Hardfloat - extends millbuild.hardfloat.common.HardfloatModule + extends millbuild.dependencies.hardfloat.common.HardfloatModule with RocketChipPublishModule with Cross.Module[String] { def scalaVersion: T[String] = T(v.scala) - override def millSourcePath = os.pwd / "hardfloat" / "hardfloat" + override def millSourcePath = os.pwd / "dependencies" / "hardfloat" / "hardfloat" - def chiselModule = None + def chiselModule = Option.when(crossValue == "source")(chisel) - def chiselPluginJar = None + def chiselPluginJar = T(Option.when(crossValue == "source")(chisel.pluginModule.jar())) - def chiselIvy = Some(v.chiselCrossVersions(crossValue)._1) + def chiselIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._1) - def chiselPluginIvy = Some(v.chiselCrossVersions(crossValue)._2) + def chiselPluginIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._2) + + def repositoriesTask = T.task(super.repositoriesTask() ++ v.sonatypesSnapshots) } object cde extends CDE trait CDE - extends millbuild.cde.common.CDEModule + extends millbuild.dependencies.cde.common.CDEModule with RocketChipPublishModule with ScalaModule { def scalaVersion: T[String] = T(v.scala) - override def millSourcePath = os.pwd / "cde" / "cde" + override def millSourcePath = os.pwd / "dependencies" / "cde" / "cde" } object rocketchip extends Cross[RocketChip](v.chiselCrossVersions.keys.toSeq) @@ -73,13 +90,13 @@ trait RocketChip override def millSourcePath = super.millSourcePath / os.up - def chiselModule = None + def chiselModule = Option.when(crossValue == "source")(chisel) - def chiselPluginJar = None + def chiselPluginJar = T(Option.when(crossValue == "source")(chisel.pluginModule.jar())) - def chiselIvy = Some(v.chiselCrossVersions(crossValue)._1) + def chiselIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._1) - def chiselPluginIvy = Some(v.chiselCrossVersions(crossValue)._2) + def chiselPluginIvy = Option.when(crossValue != "source")(v.chiselCrossVersions(crossValue)._2) def macrosModule = macros @@ -90,6 +107,8 @@ trait RocketChip def mainargsIvy = v.mainargs def json4sJacksonIvy = v.json4sJackson + + def repositoriesTask = T.task(super.repositoriesTask() ++ v.sonatypesSnapshots) } trait RocketChipPublishModule @@ -141,7 +160,6 @@ trait Emulator extends Cross.Module2[String, String] { os.proc("firtool", generator.chirrtl().path, s"--annotation-file=${generator.chiselAnno().path}", - "-disable-infer-rw", "--disable-annotation-unknown", "-dedup", "-O=debug", @@ -185,7 +203,7 @@ trait Emulator extends Cross.Module2[String, String] { "debug_rob.cc", "emulator.cc", "remote_bitbang.cc", - ).map(c => PathRef(csrcDir().path / c)) + ).map(c => PathRef(csrcDir().path / c)) } def CMakeListsString = T { @@ -295,8 +313,6 @@ object emulator extends Cross[Emulator]( // ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config"), ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultFP16Config"), - ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.BitManipCryptoConfig"), - ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.BitManipCrypto32Config"), ) object `runnable-riscv-test` extends mill.Cross[RiscvTest]( @@ -384,9 +400,6 @@ object `runnable-arch-test` extends mill.Cross[ArchTest]( // For CI within reasonable time ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultConfig", "64", "RV64IMACZicsr_Zifencei"), ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.DefaultRV32Config", "32", "RV32IMACZicsr_Zifencei"), - - ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.BitManipCryptoConfig", "64", "RV64IZba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh_Zksed_Zksh"), - ("freechips.rocketchip.system.TestHarness", "freechips.rocketchip.system.BitManipCrypto32Config", "32", "RV32IZba_Zbb_Zbc_Zbkb_Zbkc_Zbkx_Zbs_Zknd_Zkne_Zknh_Zksed_Zksh"), ) object `runnable-jtag-dtm-test` extends mill.Cross[JTAGDTMTest]( diff --git a/cde b/dependencies/cde similarity index 100% rename from cde rename to dependencies/cde diff --git a/dependencies/chisel b/dependencies/chisel new file mode 160000 index 0000000000..e3bcc90db3 --- /dev/null +++ b/dependencies/chisel @@ -0,0 +1 @@ +Subproject commit e3bcc90db37f1aec9f8048813f4f0666098d9bee diff --git a/hardfloat b/dependencies/hardfloat similarity index 100% rename from hardfloat rename to dependencies/hardfloat diff --git a/emulator/.gitignore b/emulator/.gitignore deleted file mode 100644 index f5ce32e2bf..0000000000 --- a/emulator/.gitignore +++ /dev/null @@ -1,11 +0,0 @@ -*~ -*.o -*.a -*.log -output/ -emulator-* -generated-src -generated-src-debug -kernel -kernel.hex -verilator/ diff --git a/emulator/Makefile b/emulator/Makefile deleted file mode 100644 index 95fd1ebac5..0000000000 --- a/emulator/Makefile +++ /dev/null @@ -1,61 +0,0 @@ -default: all - -base_dir = $(abspath ..) -generated_dir = $(abspath ./generated-src) -generated_dir_debug = $(abspath ./generated-src-debug) -sim_dir = . -output_dir = $(sim_dir)/output - -include $(base_dir)/Makefrag - -CXXSRCS := emulator SimDTM SimJTAG remote_bitbang debug_rob -CXXFLAGS := $(CXXFLAGS) -std=c++17 -I$(RISCV)/include -LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(abspath $(sim_dir)) -lfesvr -lpthread - -emu = emulator-$(PROJECT)-$(CONFIG) -emu_debug = emulator-$(PROJECT)-$(CONFIG)-debug - -include $(sim_dir)/Makefrag-verilator - -all: $(emu) -debug: $(emu_debug) - -clean: - rm -rf *.o *.a emulator-* $(generated_dir) $(generated_dir_debug) DVEfiles $(output_dir) - -.PHONY: default all debug clean - -#-------------------------------------------------------------------- -# Run assembly tests and benchmarks -#-------------------------------------------------------------------- - -ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),) --include $(generated_dir)/$(long_name).d -endif - -$(output_dir)/%.run: $(output_dir)/% $(emu) - ./$(emu) +max-cycles=$(timeout_cycles) $< 2> /dev/null 2> $@ && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.out: $(output_dir)/% $(emu) - ./$(emu) +max-cycles=$(timeout_cycles) +verbose $< $(disasm) $@ && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.vcd: $(output_dir)/% $(emu_debug) - ./$(emu_debug) +max-cycles=$(timeout_cycles) +verbose -v$@ $< $(disasm) $(patsubst %.vcd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.vpd: $(output_dir)/% $(emu_debug) - rm -rf $@.vcd && mkfifo $@.vcd - vcd2vpd $@.vcd $@ > /dev/null & - ./$(emu_debug) +max-cycles=$(timeout_cycles) +verbose -v$@.vcd $< $(disasm) $(patsubst %.vpd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.fst: $(output_dir)/% $(emu_debug) - rm -rf $@.vcd && mkfifo $@.vcd - vcd2fst -Z $@.vcd $@ & - ./$(emu_debug) +max-cycles=$(timeout_cycles) +verbose -v$@.vcd $< $(disasm) $(patsubst %.fst,%.out,$@) && [ $$PIPESTATUS -eq 0 ] - -run: run-asm-tests run-bmark-tests -run-debug: run-asm-tests-debug run-bmark-tests-debug -run-fast: run-asm-tests-fast run-bmark-tests-fast - -.PHONY: run-asm-tests run-bmark-tests -.PHONY: run-asm-tests-debug run-bmark-tests-debug -.PHONY: run run-debug run-fast diff --git a/emulator/Makefrag-verilator b/emulator/Makefrag-verilator deleted file mode 100644 index caad7c9bd9..0000000000 --- a/emulator/Makefrag-verilator +++ /dev/null @@ -1,98 +0,0 @@ -#-------------------------------------------------------------------- -# Verilator Generation -#-------------------------------------------------------------------- -firrtl = $(generated_dir)/$(long_name).fir -verilog = \ - $(generated_dir)/$(long_name).v \ - $(generated_dir)/$(long_name).behav_srams.v \ - -.SECONDARY: $(firrtl) $(verilog) - -$(generated_dir)/%.fir $(generated_dir)/%.d: $(ROCKET_CHIP_JAR) $(bootrom_img) - mkdir -p $(dir $@) - cd $(base_dir) && $(GENERATOR) -td $(generated_dir) -T $(PROJECT).$(MODEL) -C $(CONFIG) $(CHISEL_OPTIONS) - -%.v %.conf: %.fir $(ROCKET_CHIP_JAR) - mkdir -p $(dir $@) - $(FIRRTL) $(patsubst %,-i %,$(filter %.fir,$^)) \ - -o $*.v \ - -X verilog \ - --infer-rw $(MODEL) \ - --repl-seq-mem -c:$(MODEL):-o:$*.conf \ - -faf $*.anno.json \ - -td $(generated_dir)/$(long_name)/ \ - -fct $(subst $(SPACE),$(COMMA),$(FIRRTL_TRANSFORMS)) \ - $(FIRRTL_OPTIONS) \ - -$(generated_dir)/$(long_name).behav_srams.v : $(generated_dir)/$(long_name).conf $(VLSI_MEM_GEN) - cd $(generated_dir) && \ - $(VLSI_MEM_GEN) $(generated_dir)/$(long_name).conf > $@.tmp && \ - mv -f $@.tmp $@ - -# Build and install our own Verilator, to work around versionining issues. -VERILATOR_VERSION ?= $(shell cat $(base_dir)/verilator.hash) -VERILATOR_SRCDIR ?= verilator/src/verilator-$(VERILATOR_VERSION) -VERILATOR_TARGET := $(abspath verilator/install/bin/verilator) -INSTALLED_VERILATOR ?= $(VERILATOR_TARGET) -$(VERILATOR_TARGET): $(VERILATOR_SRCDIR)/bin/verilator - $(MAKE) -C $(VERILATOR_SRCDIR) installbin installdata - touch $@ - -$(VERILATOR_SRCDIR)/bin/verilator: $(VERILATOR_SRCDIR)/Makefile - $(MAKE) -C $(VERILATOR_SRCDIR) verilator_bin - touch $@ - -$(VERILATOR_SRCDIR)/Makefile: $(VERILATOR_SRCDIR)/configure - mkdir -p $(dir $@) - cd $(dir $@) && ./configure CFG_CXXFLAGS_STD_NEWEST=-std=c++17 --prefix=$(abspath verilator/install) - -$(VERILATOR_SRCDIR)/configure: verilator/verilator-$(VERILATOR_VERSION).tar.gz - rm -rf $(dir $@) - mkdir -p $(dir $@) - cat $^ | tar -xz --strip-components=1 -C $(dir $@) - cd $(dir $@) && autoconf - touch $@ - -verilator/verilator-$(VERILATOR_VERSION).tar.gz: - mkdir -p $(dir $@) - wget https://github.com/verilator/verilator/archive/refs/tags/v$(VERILATOR_VERSION).tar.gz -O $@ - -verilator: $(INSTALLED_VERILATOR) - -# Run Verilator to produce a fast binary to emulate this circuit. -VERILATOR := $(INSTALLED_VERILATOR) --cc --exe -VERILATOR_THREADS ?= 2 -# --max-num-width is set to 1024^2 to avoid an error with compiling a Verilated -# circuit with a width greater than the default of 65536, which can easily -# happen with Chisel-generated Verilog code. See -# https://github.com/chipsalliance/rocket-chip/pull/2377#issuecomment-605846516 -VERILATOR_FLAGS := --top-module $(MODEL) \ - +define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \ - +define+RANDOMIZE_GARBAGE_ASSIGN \ - +define+STOP_COND=\$$c\(\"done_reset\"\) --assert \ - --output-split 20000 \ - --output-split-cfuncs 20000 \ - --threads $(VERILATOR_THREADS) -Wno-UNOPTTHREADS \ - -Wno-STMTDLY -Wno-LATCH -Wno-WIDTH --x-assign unique \ - -I$(vsrc) \ - -O3 -CFLAGS "$(CXXFLAGS) -DVERILATOR -DTEST_HARNESS=V$(MODEL) -include $(csrc)/verilator.h -include $(generated_dir)/$(PROJECT).$(CONFIG_STR).plusArgs" \ - --max-num-width 1048576 -cppfiles = $(addprefix $(csrc)/, $(addsuffix .cc, $(CXXSRCS))) -headers = $(wildcard $(csrc)/*.h) - -model_header = $(generated_dir)/$(long_name)/V$(MODEL).h -model_header_debug = $(generated_dir_debug)/$(long_name)/V$(MODEL).h - -$(emu): $(verilog) $(cppfiles) $(headers) $(INSTALLED_VERILATOR) - mkdir -p $(generated_dir)/$(long_name) - $(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(generated_dir)/$(long_name) \ - -o $(abspath $(sim_dir))/$@ $(verilog) $(cppfiles) -LDFLAGS "$(LDFLAGS)" \ - -CFLAGS "-I$(generated_dir) -include $(model_header)" - $(MAKE) VM_PARALLEL_BUILDS=1 -C $(generated_dir)/$(long_name) -f V$(MODEL).mk - -$(emu_debug): $(verilog) $(cppfiles) $(headers) $(generated_dir)/$(long_name).d $(INSTALLED_VERILATOR) - mkdir -p $(generated_dir_debug)/$(long_name) - $(VERILATOR) $(VERILATOR_FLAGS) -Mdir $(generated_dir_debug)/$(long_name) --trace \ - -o $(abspath $(sim_dir))/$@ $(verilog) $(cppfiles) -LDFLAGS "$(LDFLAGS)" \ - -CFLAGS "-I$(generated_dir_debug) -include $(model_header_debug)" - $(MAKE) VM_PARALLEL_BUILDS=1 -C $(generated_dir_debug)/$(long_name) -f V$(MODEL).mk diff --git a/flake.lock b/flake.lock index b0128cb6f9..e0cf2cdc54 100644 --- a/flake.lock +++ b/flake.lock @@ -1,12 +1,15 @@ { "nodes": { "flake-utils": { + "inputs": { + "systems": "systems" + }, "locked": { - "lastModified": 1676283394, - "narHash": "sha256-XX2f9c3iySLCw54rJ/CZs+ZK6IQy7GXNY4nSOyu2QG4=", + "lastModified": 1694529238, + "narHash": "sha256-zsNZZGTGnMOf9YpHKJqMSsa0dXbfmxeoJ7xHlrt+xmY=", "owner": "numtide", "repo": "flake-utils", - "rev": "3db36a8b464d0c4532ba1c7dda728f4576d6d073", + "rev": "ff7b65b44d01cf9ba6a71320833626af21126384", "type": "github" }, "original": { @@ -17,11 +20,11 @@ }, "nixpkgs": { "locked": { - "lastModified": 1676300157, - "narHash": "sha256-1HjRzfp6LOLfcj/HJHdVKWAkX9QRAouoh6AjzJiIerU=", + "lastModified": 1696019113, + "narHash": "sha256-X3+DKYWJm93DRSdC5M6K5hLqzSya9BjibtBsuARoPco=", "owner": "NixOS", "repo": "nixpkgs", - "rev": "545c7a31e5dedea4a6d372712a18e00ce097d462", + "rev": "f5892ddac112a1e9b3612c39af1b72987ee5783a", "type": "github" }, "original": { @@ -36,6 +39,21 @@ "flake-utils": "flake-utils", "nixpkgs": "nixpkgs" } + }, + "systems": { + "locked": { + "lastModified": 1681028828, + "narHash": "sha256-Vy1rq5AaRuLzOxct8nz4T6wlgyUR7zLU309k9mBC768=", + "owner": "nix-systems", + "repo": "default", + "rev": "da67096a3b9bf56a91d16901293e51ba5b49a27e", + "type": "github" + }, + "original": { + "owner": "nix-systems", + "repo": "default", + "type": "github" + } } }, "root": "root", diff --git a/flake.nix b/flake.nix index d9a19fcf54..28d32e91fb 100644 --- a/flake.nix +++ b/flake.nix @@ -20,7 +20,8 @@ mill dtc verilator cmake ninja - python3 python3Packages.bootstrapped-pip + python3 + python3Packages.pip pkgsCross.riscv64-embedded.buildPackages.gcc pkgsCross.riscv64-embedded.buildPackages.gdb openocd diff --git a/scripts/arch-test/emulator/riscof_emulator.py b/scripts/arch-test/emulator/riscof_emulator.py index 82658c725a..d0ea02253a 100644 --- a/scripts/arch-test/emulator/riscof_emulator.py +++ b/scripts/arch-test/emulator/riscof_emulator.py @@ -111,30 +111,6 @@ def build(self, isa_yaml, platform_yaml): self.isa += '_Zicsr' if "Zifencei" in ispec["ISA"]: self.isa += '_Zifencei' - if "Zba" in ispec["ISA"]: - self.isa += '_Zba' - if "Zbb" in ispec["ISA"]: - self.isa += '_Zbb' - if "Zbc" in ispec["ISA"]: - self.isa += '_Zbc' - if "Zbkb" in ispec["ISA"]: - self.isa += '_Zbkb' - if "Zbkc" in ispec["ISA"]: - self.isa += '_Zbkc' - if "Zbkx" in ispec["ISA"]: - self.isa += '_Zbkx' - if "Zbs" in ispec["ISA"]: - self.isa += '_Zbs' - if "Zknd" in ispec["ISA"]: - self.isa += '_Zknd' - if "Zkne" in ispec["ISA"]: - self.isa += '_Zkne' - if "Zknh" in ispec["ISA"]: - self.isa += '_Zknh' - if "Zksed" in ispec["ISA"]: - self.isa += '_Zksed' - if "Zksh" in ispec["ISA"]: - self.isa += '_Zksh' #TODO: The following assumes you are using the riscv-gcc toolchain. If # not please change appropriately diff --git a/scripts/arch-test/spike/riscof_spike.py b/scripts/arch-test/spike/riscof_spike.py index 1186c5cb5e..5bb68dd028 100644 --- a/scripts/arch-test/spike/riscof_spike.py +++ b/scripts/arch-test/spike/riscof_spike.py @@ -111,30 +111,6 @@ def build(self, isa_yaml, platform_yaml): self.isa += '_Zicsr' if "Zifencei" in ispec["ISA"]: self.isa += '_Zifencei' - if "Zba" in ispec["ISA"]: - self.isa += '_Zba' - if "Zbb" in ispec["ISA"]: - self.isa += '_Zbb' - if "Zbc" in ispec["ISA"]: - self.isa += '_Zbc' - if "Zbkb" in ispec["ISA"]: - self.isa += '_Zbkb' - if "Zbkc" in ispec["ISA"]: - self.isa += '_Zbkc' - if "Zbkx" in ispec["ISA"]: - self.isa += '_Zbkx' - if "Zbs" in ispec["ISA"]: - self.isa += '_Zbs' - if "Zknd" in ispec["ISA"]: - self.isa += '_Zknd' - if "Zkne" in ispec["ISA"]: - self.isa += '_Zkne' - if "Zknh" in ispec["ISA"]: - self.isa += '_Zknh' - if "Zksed" in ispec["ISA"]: - self.isa += '_Zksed' - if "Zksh" in ispec["ISA"]: - self.isa += '_Zksh' #TODO: The following assumes you are using the riscv-gcc toolchain. If # not please change appropriately diff --git a/src/main/scala/devices/debug/Custom.scala b/src/main/scala/devices/debug/Custom.scala index 22086988a2..64e3f944ca 100644 --- a/src/main/scala/devices/debug/Custom.scala +++ b/src/main/scala/devices/debug/Custom.scala @@ -5,8 +5,7 @@ package freechips.rocketchip.devices.debug import chisel3._ import chisel3.util._ import chisel3.experimental.SourceInfo -import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, NexusNode, RenderedEdge, - SimpleNodeImp, SinkNode, SourceNode, ValName} +import freechips.rocketchip.diplomacy._ import org.chipsalliance.cde.config.Parameters case class DebugCustomParams( @@ -68,7 +67,7 @@ class DebugCustomXbar( ) lazy val module = new Impl - class Impl extends LazyModuleImp(this) { + class Impl extends LazyRawModuleImp(this) { // require only one sink require(node.out.size == 1, "Must have exactly one sink node, not ${node.out.size}") // send address to all sources diff --git a/src/main/scala/devices/debug/Debug.scala b/src/main/scala/devices/debug/Debug.scala index fec2caa14a..d8f8371fd7 100755 --- a/src/main/scala/devices/debug/Debug.scala +++ b/src/main/scala/devices/debug/Debug.scala @@ -693,7 +693,8 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La }) val dmOuter = LazyModule( new TLDebugModuleOuter(device)) - val intnode = IntSyncCrossingSource(alreadyRegistered = true) :*= dmOuter.intnode + val intnode = IntSyncIdentityNode() + intnode :*= IntSyncCrossingSource(alreadyRegistered = true) :*= dmOuter.intnode val dmiBypass = LazyModule(new TLBusBypass(beatBytes=4, bufferError=false, maxAtomic=0, maxTransfer=4)) val dmiInnerNode = TLAsyncCrossingSource() := dmiBypass.node := dmiXbar.node @@ -727,6 +728,7 @@ class TLDebugModuleOuterAsync(device: Device)(implicit p: Parameters) extends La childClock := io.dmi_clock childReset := io.dmi_reset + override def provideImplicitClockToLazyChildren = true withClockAndReset(childClock, childReset) { dmi2tlOpt.foreach { _.module.io.dmi <> io.dmi.get } @@ -1898,6 +1900,7 @@ class TLDebugModuleInnerAsync(device: Device, getNComponents: () => Int, beatByt childClock := io.debug_clock childReset := io.debug_reset + override def provideImplicitClockToLazyChildren = true val dmactive_synced = withClockAndReset(childClock, childReset) { val dmactive_synced = AsyncResetSynchronizerShiftReg(in=io.dmactive, sync=3, name=Some("dmactiveSync")) @@ -1986,6 +1989,7 @@ class TLDebugModule(beatBytes: Int)(implicit p: Parameters) extends LazyModule { childClock := io.tl_clock childReset := io.tl_reset + override def provideImplicitClockToLazyChildren = true dmOuter.module.io.dmi.foreach { dmOuterDMI => dmOuterDMI <> io.dmi.get.dmi diff --git a/src/main/scala/devices/debug/Periphery.scala b/src/main/scala/devices/debug/Periphery.scala index 8d015a0816..fcf5826dc0 100644 --- a/src/main/scala/devices/debug/Periphery.scala +++ b/src/main/scala/devices/debug/Periphery.scala @@ -99,7 +99,7 @@ trait HasPeripheryDebug { this: BaseSubsystem => tlDM } - lazy val debugNode = debugOpt.map(_.intnode).getOrElse(IntSyncXbar() := NullIntSyncSource()) + val debugNode = debugOpt.map(_.intnode) val psd = InModuleBody { val psd = IO(new PSDIO) @@ -323,6 +323,9 @@ object Debug { debug.clockeddmi.foreach { d => d.dmi.req.valid := false.B + d.dmi.req.bits.addr := 0.U + d.dmi.req.bits.data := 0.U + d.dmi.req.bits.op := 0.U d.dmi.resp.ready := true.B d.dmiClock := false.B.asClock d.dmiReset := true.B.asAsyncReset @@ -344,6 +347,7 @@ object Debug { t.out.ack := t.out.req } debug.disableDebug.foreach { x => x := false.B } + debug.dmactiveAck := false.B debug.ndreset }.getOrElse(false.B) } diff --git a/src/main/scala/devices/tilelink/BootROM.scala b/src/main/scala/devices/tilelink/BootROM.scala index 9ffdac9e65..2bbcb16be9 100644 --- a/src/main/scala/devices/tilelink/BootROM.scala +++ b/src/main/scala/devices/tilelink/BootROM.scala @@ -5,10 +5,9 @@ package freechips.rocketchip.devices.tilelink import chisel3._ import chisel3.util.log2Ceil import org.chipsalliance.cde.config.{Field, Parameters} -import freechips.rocketchip.subsystem.{BaseSubsystem, HierarchicalLocation, HasTiles, TLBusWrapperLocation} +import freechips.rocketchip.subsystem._ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.tilelink._ -import freechips.rocketchip.prci.{ClockSinkDomain} import java.nio.ByteBuffer import java.nio.file.{Files, Paths} @@ -66,11 +65,10 @@ object BootROM { * at a configurable location, but also drives the tiles' reset vectors to point * at its 'hang' address parameter value. */ - def attach(params: BootROMParams, subsystem: BaseSubsystem with HasTiles, where: TLBusWrapperLocation) + def attach(params: BootROMParams, subsystem: BaseSubsystem with HasHierarchicalElements with HasTileInputConstants, where: TLBusWrapperLocation) (implicit p: Parameters): TLROM = { val tlbus = subsystem.locateTLBusWrapper(where) - val bootROMDomainWrapper = LazyModule(new ClockSinkDomain(take = None)) - bootROMDomainWrapper.clockNode := tlbus.fixedClockNode + val bootROMDomainWrapper = tlbus.generateSynchronousDomain.suggestName("bootrom_domain") val bootROMResetVectorSourceNode = BundleBridgeSource[UInt]() lazy val contents = { diff --git a/src/main/scala/devices/tilelink/CLINT.scala b/src/main/scala/devices/tilelink/CLINT.scala index 8156706ee8..d83bde2289 100644 --- a/src/main/scala/devices/tilelink/CLINT.scala +++ b/src/main/scala/devices/tilelink/CLINT.scala @@ -102,18 +102,17 @@ class CLINT(params: CLINTParams, beatBytes: Int)(implicit p: Parameters) extends /** Trait that will connect a CLINT to a subsystem */ trait CanHavePeripheryCLINT { this: BaseSubsystem => - val clintOpt = p(CLINTKey).map { params => + val (clintOpt, clintDomainOpt, clintTickOpt) = p(CLINTKey).map { params => val tlbus = locateTLBusWrapper(p(CLINTAttachKey).slaveWhere) - val clint = LazyModule(new CLINT(params, cbus.beatBytes)) - clint.node := tlbus.coupleTo("clint") { TLFragmenter(tlbus) := _ } - - // Override the implicit clock and reset -- could instead include a clockNode in the clint, and make it a RawModuleImp? - InModuleBody { - clint.module.clock := tlbus.module.clock - clint.module.reset := tlbus.module.reset - } - - clint - - } + val clintDomainWrapper = tlbus.generateSynchronousDomain.suggestName("clint_domain") + val clint = clintDomainWrapper { LazyModule(new CLINT(params, cbus.beatBytes)) } + clintDomainWrapper { clint.node := tlbus.coupleTo("clint") { TLFragmenter(tlbus) := _ } } + val clintTick = clintDomainWrapper { InModuleBody { + val tick = IO(Input(Bool())) + clint.module.io.rtcTick := tick + tick + }} + + (clint, clintDomainWrapper, clintTick) + }.unzip3 } diff --git a/src/main/scala/devices/tilelink/Plic.scala b/src/main/scala/devices/tilelink/Plic.scala index 3e6de57042..8d87e74f37 100644 --- a/src/main/scala/devices/tilelink/Plic.scala +++ b/src/main/scala/devices/tilelink/Plic.scala @@ -12,7 +12,6 @@ import freechips.rocketchip.tilelink._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.util._ import freechips.rocketchip.util.property -import freechips.rocketchip.prci.{ClockSinkDomain} import chisel3.experimental.SourceInfo import scala.math.min @@ -355,15 +354,14 @@ class PLICFanIn(nDevices: Int, prioBits: Int) extends Module { /** Trait that will connect a PLIC to a subsystem */ trait CanHavePeripheryPLIC { this: BaseSubsystem => - val plicOpt = p(PLICKey).map { params => + val (plicOpt, plicDomainOpt) = p(PLICKey).map { params => val tlbus = locateTLBusWrapper(p(PLICAttachKey).slaveWhere) - val plicDomainWrapper = LazyModule(new ClockSinkDomain(take = None)) - plicDomainWrapper.clockNode := tlbus.fixedClockNode + val plicDomainWrapper = tlbus.generateSynchronousDomain val plic = plicDomainWrapper { LazyModule(new TLPLIC(params, tlbus.beatBytes)) } - plic.node := tlbus.coupleTo("plic") { TLFragmenter(tlbus) := _ } - plic.intnode :=* ibus.toPLIC + plicDomainWrapper { plic.node := tlbus.coupleTo("plic") { TLFragmenter(tlbus) := _ } } + plicDomainWrapper { plic.intnode :=* ibus.toPLIC } - plic - } + (plic, plicDomainWrapper) + }.unzip } diff --git a/src/main/scala/diplomacy/BundleBridge.scala b/src/main/scala/diplomacy/BundleBridge.scala index e02d6f4f96..f8a70371a6 100644 --- a/src/main/scala/diplomacy/BundleBridge.scala +++ b/src/main/scala/diplomacy/BundleBridge.scala @@ -124,7 +124,7 @@ class BundleBridgeNexus[T <: Data]( val node = BundleBridgeNexusNode[T](default, inputRequiresOutput) lazy val module = new Impl - class Impl extends LazyModuleImp(this) { + class Impl extends LazyRawModuleImp(this) { val defaultWireOpt = default.map(_()) val inputs: Seq[T] = node.in.map(_._1) inputs.foreach { i => require(DataMirror.checkTypeEquivalence(i, inputs.head), diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index a761a841ee..a6b0791f23 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -415,7 +415,11 @@ class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModul // the default is that these are disabled childClock := false.B.asClock childReset := chisel3.DontCare - val (auto, dangles) = withClockAndReset(childClock, childReset) { + + def provideImplicitClockToLazyChildren: Boolean = false + val (auto, dangles) = if (provideImplicitClockToLazyChildren) { + withClockAndReset(childClock, childReset) { instantiate() } + } else { instantiate() } } @@ -427,6 +431,10 @@ class LazyRawModuleImp(val wrapper: LazyModule) extends RawModule with LazyModul class SimpleLazyModule(implicit p: Parameters) extends LazyModule { lazy val module = new LazyModuleImp(this) } +class SimpleLazyRawModule(implicit p: Parameters) extends LazyModule { + lazy val module = new LazyRawModuleImp(this) +} + /** Allows dynamic creation of [[Module]] hierarchy and "shoving" logic into a [[LazyModule]]. */ trait LazyScope { diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index bb0ccd71ab..cf7a283e73 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -30,25 +30,24 @@ class GroundTestBaseConfig extends Config( case DebugModuleKey => None case CLINTKey => None case PLICKey => None - case SubsystemExternalResetVectorKey => true + case HasTilesExternalResetVectorKey => true }) ) class WithTraceGen( n: Int = 2, - overrideIdOffset: Option[Int] = None, overrideMemOffset: Option[BigInt] = None)( params: Seq[DCacheParams] = List.fill(n){ DCacheParams(nSets = 16, nWays = 1) }, nReqs: Int = 8192 ) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => { val prev = up(TilesLocated(InSubsystem), site) - val idOffset = overrideIdOffset.getOrElse(prev.size) + val idOffset = up(NumTiles) val memOffset: BigInt = overrideMemOffset.orElse(site(ExtMem).map(_.master.base)).getOrElse(0x0L) params.zipWithIndex.map { case (dcp, i) => TraceGenTileAttachParams( tileParams = TraceGenParams( - hartId = i + idOffset, + tileId = i + idOffset, dcache = Some(dcp), wordBits = site(XLen), addrBits = 32, @@ -68,4 +67,5 @@ class WithTraceGen( ) } ++ prev } + case NumTiles => up(NumTiles) + n }) diff --git a/src/main/scala/groundtest/GroundTestSubsystem.scala b/src/main/scala/groundtest/GroundTestSubsystem.scala index ba3215f7f5..379ed58aac 100644 --- a/src/main/scala/groundtest/GroundTestSubsystem.scala +++ b/src/main/scala/groundtest/GroundTestSubsystem.scala @@ -4,15 +4,21 @@ package freechips.rocketchip.groundtest import chisel3._ import org.chipsalliance.cde.config.{Parameters} -import freechips.rocketchip.diplomacy.{AddressSet, LazyModule} -import freechips.rocketchip.interrupts.{IntSinkNode, IntSinkPortSimple} -import freechips.rocketchip.subsystem.{BaseSubsystem, BaseSubsystemModuleImp, HasTiles, CanHaveMasterAXI4MemPort} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.tile.{NMI} +import freechips.rocketchip.devices.tilelink.{CLINTConsts} +import freechips.rocketchip.subsystem._ import freechips.rocketchip.tilelink.{TLRAM, TLFragmenter} import freechips.rocketchip.interrupts.{NullIntSyncSource} class GroundTestSubsystem(implicit p: Parameters) extends BaseSubsystem - with HasTiles + with InstantiatesHierarchicalElements + with HasHierarchicalElementsRootContext + with HasHierarchicalElements + with HasTileNotificationSinks + with HasTileInputConstants with CanHaveMasterAXI4MemPort { val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), beatBytes=pbus.beatBytes)) @@ -24,16 +30,18 @@ class GroundTestSubsystem(implicit p: Parameters) // No PLIC in ground test; so just sink the interrupts to nowhere IntSinkNode(IntSinkPortSimple()) :=* ibus.toPLIC - val tileStatusNodes = tiles.collect { case t: GroundTestTile => t.statusNode.makeSink() } - - // no debug module - val debugNode = NullIntSyncSource() + val tileStatusNodes = totalTiles.values.collect { case t: GroundTestTile => t.statusNode.makeSink() } + val clintOpt = None + val clintDomainOpt = None + val debugOpt = None + val plicOpt = None + val plicDomainOpt = None override lazy val module = new GroundTestSubsystemModuleImp(this) } class GroundTestSubsystemModuleImp[+L <: GroundTestSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) { val success = IO(Output(Bool())) - val status = dontTouch(DebugCombiner(outer.tileStatusNodes.map(_.bundle))) + val status = dontTouch(DebugCombiner(outer.tileStatusNodes.map(_.bundle).toSeq)) success := outer.tileCeaseSinkNode.in.head._1.asUInt.andR } diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 912016f8ea..f7bef2d439 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -34,7 +34,7 @@ abstract class GroundTestTile( with SourcesExternalNotifications { val cpuDevice: SimpleDevice = new SimpleDevice("groundtest", Nil) - val intOutwardNode: IntOutwardNode = IntIdentityNode() + val intOutwardNode = None val slaveNode: TLInwardNode = TLIdentityNode() val statusNode = BundleBridgeSource(() => new GroundTestStatus) diff --git a/src/main/scala/groundtest/TraceGen.scala b/src/main/scala/groundtest/TraceGen.scala index 5c5cba9b5f..f60c41517c 100644 --- a/src/main/scala/groundtest/TraceGen.scala +++ b/src/main/scala/groundtest/TraceGen.scala @@ -26,7 +26,7 @@ import freechips.rocketchip.diplomacy.{ClockCrossingType} import freechips.rocketchip.rocket._ import freechips.rocketchip.tile._ import freechips.rocketchip.tilelink._ -import freechips.rocketchip.subsystem.{TileCrossingParamsLike, CanAttachTile} +import freechips.rocketchip.subsystem.{HierarchicalElementCrossingParamsLike, CanAttachTile} import freechips.rocketchip.util._ import freechips.rocketchip.prci.{ClockSinkParameters} @@ -68,15 +68,15 @@ case class TraceGenParams( memStart: BigInt, //p(ExtMem).base numGens: Int, dcache: Option[DCacheParams] = Some(DCacheParams()), - hartId: Int = 0 + tileId: Int = 0 ) extends InstantiableTileParams[TraceGenTile] with GroundTestTileParams { - def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): TraceGenTile = { + def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): TraceGenTile = { new TraceGenTile(this, crossing, lookup) } - val beuAddr = None val blockerCtrlAddr = None - val name = None + val baseName = "tracegentile" + val uniqueName = s"${baseName}_$tileId" val clockSinkParams = ClockSinkParameters() } @@ -105,7 +105,7 @@ trait HasTraceGenParams { case class TraceGenTileAttachParams( tileParams: TraceGenParams, - crossingParams: TileCrossingParamsLike + crossingParams: HierarchicalElementCrossingParamsLike ) extends CanAttachTile { type TileType = TraceGenTile val lookup: LookupByHartIdImpl = HartsWontDeduplicate(tileParams) @@ -617,7 +617,7 @@ class TraceGenTile private( q: Parameters ) extends GroundTestTile(params, crossing, lookup, q) { - def this(params: TraceGenParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) = + def this(params: TraceGenParams, crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) = this(params, crossing.crossingType, lookup, p) val masterNode: TLOutwardNode = TLIdentityNode() := visibilityNode := dcacheOpt.map(_.node).getOrElse(TLTempNode()) @@ -644,5 +644,5 @@ class TraceGenTileModuleImp(outer: TraceGenTile) extends GroundTestTileModuleImp status.timeout.bits := 0.U status.error.valid := false.B - assert(!tracegen.io.timeout, s"TraceGen tile ${outer.tileParams.hartId}: request timed out") + assert(!tracegen.io.timeout, s"TraceGen tile ${outer.tileParams.tileId}: request timed out") } diff --git a/src/main/scala/interrupts/Crossing.scala b/src/main/scala/interrupts/Crossing.scala index 77a1548052..b113dfdc53 100644 --- a/src/main/scala/interrupts/Crossing.scala +++ b/src/main/scala/interrupts/Crossing.scala @@ -35,14 +35,16 @@ class IntSyncCrossingSource(alreadyRegistered: Boolean = false)(implicit p: Para { val node = IntSyncSourceNode(alreadyRegistered) - lazy val module = new Impl + lazy val module = if (alreadyRegistered) (new ImplRegistered) else (new Impl) + class Impl extends LazyModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => - if (alreadyRegistered) { - out.sync := in - } else { - out.sync := AsyncResetReg(Cat(in.reverse)).asBools - } + out.sync := AsyncResetReg(Cat(in.reverse)).asBools + } + } + class ImplRegistered extends LazyRawModuleImp(this) { + (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => + out.sync := in } } } @@ -85,7 +87,7 @@ class IntSyncSyncCrossingSink()(implicit p: Parameters) extends LazyModule val node = IntSyncSinkNode(0) lazy val module = new Impl - class Impl extends LazyModuleImp(this) { + class Impl extends LazyRawModuleImp(this) { (node.in zip node.out) foreach { case ((in, edgeIn), (out, edgeOut)) => out := in.sync } diff --git a/src/main/scala/interrupts/NullIntSource.scala b/src/main/scala/interrupts/NullIntSource.scala index d906ac36fd..ec2528aa70 100644 --- a/src/main/scala/interrupts/NullIntSource.scala +++ b/src/main/scala/interrupts/NullIntSource.scala @@ -12,7 +12,7 @@ class NullIntSource(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: val intnode = IntSourceNode(IntSourcePortSimple(num, ports, sources)) lazy val module = new Impl - class Impl extends LazyModuleImp(this) { + class Impl extends LazyRawModuleImp(this) { intnode.out.foreach { case (o, _) => o.foreach { _ := false.B } } } } @@ -26,6 +26,6 @@ object NullIntSource { object NullIntSyncSource { def apply(num: Int = 1, ports: Int = 1, sources: Int = 1)(implicit p: Parameters): IntSyncOutwardNode = { - IntSyncCrossingSource() := NullIntSource(num, ports, sources) + IntSyncCrossingSource(alreadyRegistered = true) := NullIntSource(num, ports, sources) } } diff --git a/src/main/scala/interrupts/Xbar.scala b/src/main/scala/interrupts/Xbar.scala index 472fead695..b2560106b6 100644 --- a/src/main/scala/interrupts/Xbar.scala +++ b/src/main/scala/interrupts/Xbar.scala @@ -19,7 +19,7 @@ class IntXbar()(implicit p: Parameters) extends LazyModule } lazy val module = new Impl - class Impl extends LazyModuleImp(this) { + class Impl extends LazyRawModuleImp(this) { val cat = intnode.in.map { case (i, e) => i.take(e.source.num) }.flatten intnode.out.foreach { case (o, _) => o := cat } } diff --git a/src/main/scala/prci/ClockBundles.scala b/src/main/scala/prci/ClockBundles.scala index 900e437a5a..0cf06cca6e 100644 --- a/src/main/scala/prci/ClockBundles.scala +++ b/src/main/scala/prci/ClockBundles.scala @@ -5,7 +5,7 @@ import chisel3._ import freechips.rocketchip.util.RecordMap -class ClockBundle(val params: ClockBundleParameters) extends Bundle +class ClockBundle(val params: ClockBundleParameters = ClockBundleParameters()) extends Bundle { val clock = Output(Clock()) val reset = Output(Reset()) diff --git a/src/main/scala/prci/ClockDomain.scala b/src/main/scala/prci/ClockDomain.scala index 665372ca50..7bc10c6947 100644 --- a/src/main/scala/prci/ClockDomain.scala +++ b/src/main/scala/prci/ClockDomain.scala @@ -4,13 +4,15 @@ import chisel3._ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ -abstract class Domain(implicit p: Parameters) extends LazyModule with HasDomainCrossing { +abstract class Domain(implicit p: Parameters) extends LazyModule with HasDomainCrossing +{ def clockBundle: ClockBundle lazy val module = new Impl class Impl extends LazyRawModuleImp(this) { childClock := clockBundle.clock childReset := clockBundle.reset + override def provideImplicitClockToLazyChildren = true // these are just for backwards compatibility with external devices // that were manually wiring themselves to the domain's clock/reset input: diff --git a/src/main/scala/prci/ClockGroup.scala b/src/main/scala/prci/ClockGroup.scala index ce2b8f98c9..f4c648bafe 100644 --- a/src/main/scala/prci/ClockGroup.scala +++ b/src/main/scala/prci/ClockGroup.scala @@ -4,7 +4,7 @@ package freechips.rocketchip.prci import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy._ -case class ClockGroupNode(groupName: String)(implicit valName: ValName) +case class ClockGroupingNode(groupName: String)(implicit valName: ValName) extends MixedNexusNode(ClockGroupImp, ClockImp)( dFn = { _ => ClockSourceParameters() }, uFn = { seq => ClockGroupSinkParameters(name = groupName, members = seq) }) @@ -14,7 +14,7 @@ case class ClockGroupNode(groupName: String)(implicit valName: ValName) class ClockGroup(groupName: String)(implicit p: Parameters) extends LazyModule { - val node = ClockGroupNode(groupName) + val node = ClockGroupingNode(groupName) lazy val module = new Impl class Impl extends LazyRawModuleImp(this) { @@ -107,7 +107,7 @@ class FixedClockBroadcast(fixedClockOpt: Option[ClockParameters])(implicit p: Pa object FixedClockBroadcast { - def apply(fixedClockOpt: Option[ClockParameters])(implicit p: Parameters, valName: ValName) = LazyModule(new FixedClockBroadcast(fixedClockOpt)).node + def apply(fixedClockOpt: Option[ClockParameters] = None)(implicit p: Parameters, valName: ValName) = LazyModule(new FixedClockBroadcast(fixedClockOpt)).node } case class PRCIClockGroupNode()(implicit valName: ValName) diff --git a/src/main/scala/prci/ClockGroupDriver.scala b/src/main/scala/prci/ClockGroupDriver.scala deleted file mode 100644 index 63ff42f1e4..0000000000 --- a/src/main/scala/prci/ClockGroupDriver.scala +++ /dev/null @@ -1,46 +0,0 @@ -// See LICENSE.SiFive for license details. -package freechips.rocketchip.prci - -import chisel3._ -import org.chipsalliance.cde.config.Parameters -import freechips.rocketchip.diplomacy.{InModuleBody, ModuleValue, ValName} -import freechips.rocketchip.util.{RecordMap} - -/** Used to parameterize the creation of simple clock group drivers */ -case class ClockGroupDriverParameters( - num: Int = 1, - driveFn: ClockGroupDriver.DriveFn = ClockGroupDriver.driveFromImplicitClock -) { - def drive(node: ClockGroupEphemeralNode)(implicit p: Parameters, vn: ValName): ModuleValue[RecordMap[ClockBundle]] = { - driveFn(node, num, p, vn) - } -} - -object ClockGroupDriver { - type DriveFn = (ClockGroupEphemeralNode, Int, Parameters, ValName) => ModuleValue[RecordMap[ClockBundle]] - - /** Drive all members of all groups from the Chisel implicit clock */ - def driveFromImplicitClock: DriveFn = { (groups, num, p, vn) => - implicit val pp = p - val dummyClockGroupSourceNode: ClockGroupSourceNode = SimpleClockGroupSource(num) - groups :*= dummyClockGroupSourceNode - InModuleBody { RecordMap[ClockBundle]() } - } - - /** Drive all members of all groups from a flattened IO representation */ - def driveFromIOs: DriveFn = { (groups, num, p, vn) => - implicit val pp = p - val ioClockGroupSourceNode = ClockGroupSourceNode(List.fill(num) { ClockGroupSourceParameters() }) - groups :*= ioClockGroupSourceNode - InModuleBody { - val bundles = ioClockGroupSourceNode.out.map(_._1) - val elements = bundles.map(_.member.elements).flatten - val io = IO(Flipped(RecordMap(elements.map { case (name, data) => - name -> data.cloneType - }:_*))) - - elements.foreach { case (name, data) => io(name).foreach { data := _ } } - io.suggestName(vn.name) - } - } -} diff --git a/src/main/scala/prci/package.scala b/src/main/scala/prci/package.scala index e427add8d4..864126a03f 100644 --- a/src/main/scala/prci/package.scala +++ b/src/main/scala/prci/package.scala @@ -9,6 +9,9 @@ package object prci type ClockInwardNode = InwardNodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle] type ClockOutwardNode = OutwardNodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle] type ClockNode = NodeHandle[ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle, ClockSourceParameters, ClockSinkParameters, ClockEdgeParameters, ClockBundle] + + type ClockGroupNode = NodeHandle[ClockGroupSourceParameters, ClockGroupSinkParameters, ClockGroupEdgeParameters, ClockGroupBundle, ClockGroupSourceParameters, ClockGroupSinkParameters, ClockGroupEdgeParameters, ClockGroupBundle] + def asyncMux[T](xType: ClockCrossingType, async: T, notasync: T): T = xType match { case _: AsynchronousCrossing => async case _ => notasync diff --git a/src/main/scala/rocket/ABLU.scala b/src/main/scala/rocket/ABLU.scala deleted file mode 100644 index d6dcef1cdc..0000000000 --- a/src/main/scala/rocket/ABLU.scala +++ /dev/null @@ -1,365 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package freechips.rocketchip.rocket - -import chisel3._ -import chisel3.util._ -import org.chipsalliance.cde.config.Parameters -import freechips.rocketchip.tile.CoreModule - -// These are for the ABLU unit, which uses an alternate function encoding -class ABLUFN extends ALUFN -{ - override val SZ_ALU_FN = 39 - override def FN_X = BitPat("b??_???_????_????_????__????__??_????_????_????_????") - override def FN_ADD = "b00_000_0000_0000_0000__0001__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SL = "b00_000_0000_1100_0000__0001__00_0000_0000_0000_0010".U(SZ_ALU_FN.W) - override def FN_SEQ = "b00_100_0000_0000_0000__0001__00_0000_0000_0100_0000".U(SZ_ALU_FN.W) - override def FN_SNE = "b00_110_0000_0000_0000__0001__00_0000_0000_0100_0000".U(SZ_ALU_FN.W) - override def FN_XOR = "b00_000_0000_0000_0000__0001__00_0000_0000_0000_1000".U(SZ_ALU_FN.W) - override def FN_SR = "b00_000_0000_0000_0000__0001__00_0000_0000_0000_0010".U(SZ_ALU_FN.W) - override def FN_OR = "b00_000_0000_0000_0000__0001__00_0000_0000_0001_0000".U(SZ_ALU_FN.W) - override def FN_AND = "b00_000_0000_0000_0000__0001__00_0000_0000_0000_0100".U(SZ_ALU_FN.W) - override def FN_SUB = "b00_000_0000_0000_0011__0001__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SRA = "b00_000_0000_0001_0000__0001__00_0000_0000_0000_0010".U(SZ_ALU_FN.W) - override def FN_SLT = "b00_000_0000_0000_0011__0001__00_0000_0000_0100_0000".U(SZ_ALU_FN.W) - override def FN_SGE = "b00_010_0000_0000_0011__0001__00_0000_0000_0100_0000".U(SZ_ALU_FN.W) - override def FN_SLTU = "b00_001_0000_0000_0011__0001__00_0000_0000_0100_0000".U(SZ_ALU_FN.W) - override def FN_SGEU = "b00_011_0000_0000_0011__0001__00_0000_0000_0100_0000".U(SZ_ALU_FN.W) - - // from Zb - // Zba: UW is encoded here becuase it is DW_64 - override def FN_ADDUW = "b00_000_0000_0000_1000__0001__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SLLIUW = "b00_000_0000_1100_1000__0001__00_0000_0000_0000_0010".U(SZ_ALU_FN.W) - override def FN_SH1ADD = "b00_000_0000_0000_0000__0010__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SH1ADDUW = "b00_000_0000_0000_1000__0010__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SH2ADD = "b00_000_0000_0000_0000__0100__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SH2ADDUW = "b00_000_0000_0000_1000__0100__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SH3ADD = "b00_000_0000_0000_0000__1000__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - override def FN_SH3ADDUW = "b00_000_0000_0000_1000__1000__00_0000_0000_0000_0001".U(SZ_ALU_FN.W) - // Zbb - override def FN_ROR = "b00_000_0000_0010_0000__0001__00_0000_0000_0000_0010".U(SZ_ALU_FN.W) - override def FN_ROL = "b00_000_0000_1110_0000__0001__00_0000_0000_0000_0010".U(SZ_ALU_FN.W) - override def FN_ANDN = "b00_000_0000_0000_0010__0001__00_0000_0000_0000_0100".U(SZ_ALU_FN.W) - override def FN_ORN = "b00_000_0000_0000_0010__0001__00_0000_0000_0001_0000".U(SZ_ALU_FN.W) - override def FN_XNOR = "b00_000_0000_0000_0010__0001__00_0000_0000_0000_1000".U(SZ_ALU_FN.W) - override def FN_REV8 = "b00_000_0000_0000_0000__0001__00_0001_0000_0000_0000".U(SZ_ALU_FN.W) - override def FN_ORCB = "b10_000_0000_0000_0000__0001__00_0010_0000_0000_0000".U(SZ_ALU_FN.W) - override def FN_SEXTB = "b00_000_0000_0000_0000__0001__00_0000_1000_0000_0000".U(SZ_ALU_FN.W) - override def FN_SEXTH = "b01_000_0000_0000_0000__0001__00_0000_0100_0000_0000".U(SZ_ALU_FN.W) - override def FN_ZEXTH = "b00_000_0000_0000_0000__0001__00_0000_0100_0000_0000".U(SZ_ALU_FN.W) - override def FN_MAX = "b00_000_0000_0000_0011__0001__00_0000_0000_1000_0000".U(SZ_ALU_FN.W) - override def FN_MAXU = "b00_001_0000_0000_0011__0001__00_0000_0000_1000_0000".U(SZ_ALU_FN.W) - override def FN_MIN = "b00_010_0000_0000_0011__0001__00_0000_0000_1000_0000".U(SZ_ALU_FN.W) - override def FN_MINU = "b00_011_0000_0000_0011__0001__00_0000_0000_1000_0000".U(SZ_ALU_FN.W) - override def FN_CPOP = "b00_000_0000_0000_0000__0001__00_0000_0001_0000_0000".U(SZ_ALU_FN.W) - override def FN_CLZ = "b00_000_1101_1110_0000__0001__00_0000_0010_0000_0000".U(SZ_ALU_FN.W) - override def FN_CTZ = "b00_000_1101_0000_0000__0001__00_0000_0010_0000_0000".U(SZ_ALU_FN.W) - // Zbs - override def FN_BCLR = "b00_000_1110_1000_0100__0001__00_0000_0000_0000_0100".U(SZ_ALU_FN.W) - override def FN_BEXT = "b00_000_1000_1000_0100__0001__00_0000_0000_0010_0000".U(SZ_ALU_FN.W) - override def FN_BINV = "b00_000_1000_1000_0100__0001__00_0000_0000_0000_1000".U(SZ_ALU_FN.W) - override def FN_BSET = "b00_000_1000_1000_0100__0001__00_0000_0000_0001_0000".U(SZ_ALU_FN.W) - // Zbk - override def FN_BREV8 = "b00_000_0000_0000_0000__0001__00_0010_0000_0000_0000".U(SZ_ALU_FN.W) - override def FN_PACK = "b00_000_0000_0000_0000__0001__00_0100_0000_0000_0000".U(SZ_ALU_FN.W) - override def FN_PACKH = "b00_000_0000_0000_0000__0001__00_1000_0000_0000_0000".U(SZ_ALU_FN.W) - override def FN_ZIP = "b00_000_0000_0000_0000__0001__01_0000_0000_0000_0000".U(SZ_ALU_FN.W) - override def FN_UNZIP = "b00_000_0000_0000_0000__0001__10_0000_0000_0000_0000".U(SZ_ALU_FN.W) - def SZ_ZBK_FN = 5 - override def FN_CLMUL = "b00001".U(SZ_ZBK_FN.W) // These use the BitManipCrypto FU, not ABLU - override def FN_CLMULR = "b00010".U(SZ_ZBK_FN.W) - override def FN_CLMULH = "b00100".U(SZ_ZBK_FN.W) - override def FN_XPERM8 = "b01000".U(SZ_ZBK_FN.W) - override def FN_XPERM4 = "b10000".U(SZ_ZBK_FN.W) - // Zkn: These use the CryptoNIST unit - def SZ_ZKN_FN = 17 - override def FN_AES_DS = "b0010__0001__0_0000_0001".U(SZ_ZKN_FN.W) - override def FN_AES_DSM = "b0000__0010__0_0000_0001".U(SZ_ZKN_FN.W) - override def FN_AES_ES = "b0011__0001__0_0000_0001".U(SZ_ZKN_FN.W) - override def FN_AES_ESM = "b0001__0010__0_0000_0001".U(SZ_ZKN_FN.W) - override def FN_AES_IM = "b1000__0010__0_0000_0001".U(SZ_ZKN_FN.W) - override def FN_AES_KS1 = "b0101__0100__0_0000_0001".U(SZ_ZKN_FN.W) - override def FN_AES_KS2 = "b0000__1000__0_0000_0001".U(SZ_ZKN_FN.W) - override def FN_SHA256_SIG0 = "b0000__0001__0_0000_0010".U(SZ_ZKN_FN.W) - override def FN_SHA256_SIG1 = "b0000__0001__0_0000_0100".U(SZ_ZKN_FN.W) - override def FN_SHA256_SUM0 = "b0000__0001__0_0000_1000".U(SZ_ZKN_FN.W) - override def FN_SHA256_SUM1 = "b0000__0001__0_0001_0000".U(SZ_ZKN_FN.W) - override def FN_SHA512_SIG0 = "b0000__0001__0_0010_0000".U(SZ_ZKN_FN.W) - override def FN_SHA512_SIG1 = "b0000__0001__0_0100_0000".U(SZ_ZKN_FN.W) - override def FN_SHA512_SUM0 = "b0000__0001__0_1000_0000".U(SZ_ZKN_FN.W) - override def FN_SHA512_SUM1 = "b0000__0001__1_0000_0000".U(SZ_ZKN_FN.W) - // Zks: Thses use the CryptoSM unit - def SZ_ZKS_FN = 4 - override def FN_SM4ED = "b01_01".U(SZ_ZKS_FN.W) - override def FN_SM4KS = "b00_01".U(SZ_ZKS_FN.W) - override def FN_SM3P0 = "b10_10".U(SZ_ZKS_FN.W) - override def FN_SM3P1 = "b00_10".U(SZ_ZKS_FN.W) - - - override def FN_DIV = FN_XOR - override def FN_DIVU = FN_SR - override def FN_REM = FN_OR - override def FN_REMU = FN_AND - - override def FN_MUL = FN_ADD - override def FN_MULH = FN_SL - override def FN_MULHSU = FN_SEQ - override def FN_MULHU = FN_SNE - - // not implemented functions for this fn - override def isMulFN(fn: UInt, cmp: UInt) = ??? - override def isCmp(cmd: UInt) = ??? - override def cmpUnsigned(cmd: UInt) = ??? - override def cmpInverted(cmd: UInt) = ??? - override def cmpEq(cmd: UInt) = ??? - - override def isSub(cmd: UInt) = cmd(22) - def isIn2Inv(cmd: UInt) = cmd(23) - def isZBS(cmd: UInt) = cmd(24) - def isUW(cmd: UInt) = cmd(25) - def isSRA(cmd: UInt) = cmd(26) - def isRotate(cmd: UInt) = cmd(27) - def isLeft(cmd: UInt) = cmd(28) - def isLeftZBS(cmd: UInt) = cmd(29) - def isCZ(cmd: UInt) = cmd(30) - def isBCLR(cmd: UInt) = cmd(31) - def isCZBCLR(cmd: UInt) = cmd(32) - def isCZZBS(cmd: UInt) = cmd(33) - def isUnsigned(cmd: UInt) = cmd(34) - def isInverted(cmd: UInt) = cmd(35) - def isSEQSNE(cmd: UInt) = cmd(36) - def isSEXT(cmd: UInt) = cmd(37) - def isORC(cmd: UInt) = cmd(38) - def shxadd1H(cmd: UInt) = cmd(21,18) - def out1H(cmd: UInt) = cmd(17,0) - // Zbk - def isClmul(cmd: UInt) = cmd(0) - def zbkOut1H(cmd: UInt) = cmd(4,0) - // Zkn - def isEnc(cmd: UInt) = cmd(13) - def isNotMix(cmd: UInt) = cmd(14) - override def isKs1(cmd: UInt) = cmd(15) - def isIm(cmd: UInt) = cmd(16) - def aes1H(cmd: UInt) = cmd(12,9) - def zknOut1H(cmd: UInt) = cmd(8,0) - // Zks - def isEd(cmd: UInt) = cmd(2) - def isP0(cmd: UInt) = cmd(3) - def zksOut1H(cmd: UInt) = cmd(1,0) -} - -object ABLUFN { - def apply() = new ABLUFN -} - -class ABLU(implicit p: Parameters) extends AbstractALU(new ABLUFN)(p) { - val isSub = aluFn.isSub(io.fn) - val isIn2Inv = aluFn.isIn2Inv(io.fn) - val isZBS = aluFn.isZBS(io.fn) - val isUW = aluFn.isUW(io.fn) - val isSRA = aluFn.isSRA(io.fn) - val isRotate = aluFn.isRotate(io.fn) - val isLeft = aluFn.isLeft(io.fn) - val isLeftZBS = aluFn.isLeftZBS(io.fn) - val isCZ = aluFn.isCZ(io.fn) - val isBCLR = aluFn.isBCLR(io.fn) - val isCZBCLR = aluFn.isCZBCLR(io.fn) - val isCZZBS = aluFn.isCZZBS(io.fn) - val isUnsigned = aluFn.isUnsigned(io.fn) - val isInverted = aluFn.isInverted(io.fn) - val isSEQSNE = aluFn.isSEQSNE(io.fn) - val isSEXT = aluFn.isSEXT(io.fn) - val isORC = aluFn.isORC(io.fn) - val shxadd1H = aluFn.shxadd1H(io.fn) - val out1H = aluFn.out1H(io.fn) - - // process input - // used by SUB, ANDN, ORN, XNOR - val in2_inv = Mux(isIn2Inv, ~io.in2, io.in2) - val shamt = - if (xLen == 32) io.in2(4,0) - else { - require(xLen == 64) - Cat(io.in2(5) & (io.dw === DW_64), io.in2(4,0)) - } - val in1_ext = - if (xLen == 32) io.in1 - else { - require(xLen == 64) - val in1_hi_orig = io.in1(63,32) - // note that CLZW uses rotate - val in1_hi_rotate = io.in1(31,0) - // note that sext fills 0 for ADDW/SUBW, but it works - val in1_hi_sext = Fill(32, isSRA & io.in1(31)) // 31 to 63 then to 64 in shout_r - val in1_hi_zext = Fill(32, 0.U) - val in1_hi = Mux(io.dw === DW_64, - Mux(isUW, in1_hi_zext, in1_hi_orig), - Mux(isRotate, in1_hi_rotate, in1_hi_sext)) - Cat(in1_hi, io.in1(31,0)) - } - // one arm: SL, ROL, SLLIUW, CLZ - // another arm: SR, SRA, ROR, CTZ, ADD, SUB, ZBS - // note that CLZW is not included here - // in1 capable of right hand operation - // isLeft - val in1_r = Mux(isLeft, Reverse(in1_ext), in1_ext) - - // shifter - val shin = Mux(isZBS, - if (xLen == 32) (BigInt(1) << 31).U(32.W) - else { - require(xLen == 64) - (BigInt(1) << 63).U(64.W) - }, in1_r) - // TODO: Merge shift and rotate (manual barrel or upstream to Chisel) - val shout_r = (Cat(isSRA & shin(xLen-1), shin).asSInt >> shamt)(xLen-1,0) - val roout_r = shin.rotateRight(shamt)(xLen-1,0) - val shro_r = Mux(isRotate, roout_r, shout_r) - // one arm: SL, ROL, SLLIUW, ZBS - // another arm: SR, SRA, ROR - val shro = Mux(isLeftZBS, Reverse(shro_r), shro_r) - - // adder - val adder_in1 = - Mux1H(shxadd1H, Seq( - if (xLen == 32) in1_r - else { - require(xLen == 64) - // for CLZW/CTZW - Mux(io.dw === DW_64, in1_r, Cat(Fill(32, 1.U(1.W)), in1_r(31,0))) - }, - (in1_ext << 1)(xLen-1,0), - (in1_ext << 2)(xLen-1,0), - (in1_ext << 3)(xLen-1,0))) - // out = in1 - 1 when isCLZ/isCTZ - // note that when isCZ, isSub is 0 as ~0 = ~1+1 = -1 - val adder_in2 = Mux(isCZ, - ~0.U(xLen.W), in2_inv) - // adder_out = adder_in1 + adder_in2 + isSub - val adder_out = (Cat(adder_in1, 1.U(1.W)) + Cat(adder_in2, isSub))(xLen,1) - io.adder_out := adder_out - - // logic - // AND, OR, XOR - // ANDN, ORN, XNOR - // BCLR, BEXT, BINV, BSET - val out_inv = Mux(isCZBCLR, ~Mux(isBCLR, shro, adder_out), shro) - val logic_in2 = Mux(isCZZBS, out_inv, in2_inv) - // also BINV - val xor = adder_in1 ^ logic_in2 - // also BCLR - val and = adder_in1 & logic_in2 - // also BSET - val or = adder_in1 | logic_in2 - val bext = and.orR - - // SLT, SLTU - // BEQ, BNE, BLT, BGE - // MAX, MIN - val slt = - Mux(io.in1(xLen-1) === io.in2(xLen-1), adder_out(xLen-1), - Mux(isUnsigned, io.in2(xLen-1), io.in1(xLen-1))) - val cmp = isInverted ^ Mux(isSEQSNE, ~(xor.orR), slt) - io.cmp_out := cmp - // MAX, MAXU, MIN, MINU - val max_min = Mux(cmp, io.in2, io.in1) - - // counter - // CLZ, CPOP, CTZ - val cpop = PopCount( - if (xLen == 32) io.in1 - else { - require(xLen == 64) - Mux(io.dw === DW_64, io.in1, Cat(Fill(32, 0.U(1.W)), io.in1(31,0))) - }) - // ctz_in = ~adder_out & adder_in1 // all zero or one hot - val ctz_in = and - val ctz_out = Cat(~ctz_in.orR, VecInit((0 to log2Ceil(xLen)-1).map( - x => { - val bits = ctz_in.asBools.zipWithIndex - VecInit( - bits - filter { case (_, i) => i % (1 << (x + 1)) >= (1 << x) } - map { case (b, _) => b } - ).asUInt.orR - } - ).toSeq).asUInt) - - // ZEXT/SEXT - val exth = Cat(Fill(xLen-16, Mux(isSEXT, io.in1(15), 0.U)), io.in1(15,0)) - val extb = Cat(Fill(xLen-8, io.in1(7)), io.in1(7,0)) - - // REV/ORC - def asBytes(in: UInt): Vec[UInt] = VecInit(in.asBools.grouped(8).map(VecInit(_).asUInt).toSeq) - val in1_bytes = asBytes(io.in1) - val rev8 = VecInit(in1_bytes.reverse.toSeq).asUInt - val orc_brev8 = VecInit(in1_bytes.map(x => { - val orc = Mux(x.orR, 0xFF.U(8.W), 0.U(8.W)) - // BREV8 only in Zbk - if (usingBitManipCrypto) - Mux(isORC, orc, Reverse(x)) - else orc - }).toSeq).asUInt - - // pack - def sext(in: UInt): UInt = { - val in_hi_32 = Fill(32, in(31)) - Cat(in_hi_32, in) - } - val pack = if (usingBitManipCrypto) { - if (xLen == 32) Cat(io.in2(xLen/2-1,0), io.in1(xLen/2-1,0)) - else { - require(xLen == 64) - Mux(io.dw === DW_64, - Cat(io.in2(xLen/2-1,0), io.in1(xLen/2-1,0)), - sext(Cat(io.in2(xLen/4-1,0), io.in1(xLen/4-1,0)))) - } - } else 0.U - val packh = if (usingBitManipCrypto) Cat(0.U((xLen-16).W), io.in2(7,0), io.in1(7,0)) else 0.U - - // zip - val zip = if (xLen == 32 && usingBitManipCrypto) { - val lo = io.in1(15,0).asBools - val hi = io.in1(31,16).asBools - VecInit(lo.zip(hi).map { case (l, h) => VecInit(Seq(l, h)).asUInt }).asUInt - } else 0.U - val unzip = if (xLen == 32 && usingBitManipCrypto) { - val bits = io.in1.asBools.zipWithIndex - val lo = VecInit(bits filter { case (_, i) => i % 2 == 0 } map { case (b, _) => b }).asUInt - val hi = VecInit(bits filter { case (_, i) => i % 2 != 0 } map { case (b, _) => b }).asUInt - Cat(hi, lo) - } else 0.U - - val out = Mux1H(out1H, Seq( - adder_out, - shro, - and, - xor, - // - or, - bext, - cmp, - max_min, - // - cpop, - ctz_out, - exth, - extb, - // - rev8, - orc_brev8, - pack, - packh, - // - zip, - unzip)) - - val out_w = - if (xLen == 32) out - else { - require(xLen == 64) - Mux(io.dw === DW_64, out, Cat(Fill(32, out(31)), out(31,0))) - } - io.out := out_w -} diff --git a/src/main/scala/rocket/ALU.scala b/src/main/scala/rocket/ALU.scala index 68e7db4a98..20c2bdffeb 100644 --- a/src/main/scala/rocket/ALU.scala +++ b/src/main/scala/rocket/ALU.scala @@ -28,73 +28,6 @@ class ALUFN { def FN_SLTU = 14.U def FN_SGEU = 15.U - // The Base ALU does not support any Zb FNs - // from Zb - // Zba: UW is encoded here becuase it is DW_64 - def FN_ADDUW : UInt = ??? - def FN_SLLIUW : UInt = ??? - def FN_SH1ADD : UInt = ??? - def FN_SH1ADDUW : UInt = ??? - def FN_SH2ADD : UInt = ??? - def FN_SH2ADDUW : UInt = ??? - def FN_SH3ADD : UInt = ??? - def FN_SH3ADDUW : UInt = ??? - // Zbb - def FN_ROR : UInt = ??? - def FN_ROL : UInt = ??? - def FN_ANDN : UInt = ??? - def FN_ORN : UInt = ??? - def FN_XNOR : UInt = ??? - def FN_REV8 : UInt = ??? - def FN_ORCB : UInt = ??? - def FN_SEXTB : UInt = ??? - def FN_SEXTH : UInt = ??? - def FN_ZEXTH : UInt = ??? - def FN_MAX : UInt = ??? - def FN_MAXU : UInt = ??? - def FN_MIN : UInt = ??? - def FN_MINU : UInt = ??? - def FN_CPOP : UInt = ??? - def FN_CLZ : UInt = ??? - def FN_CTZ : UInt = ??? - // Zbs - def FN_BCLR : UInt = ??? - def FN_BEXT : UInt = ??? - def FN_BINV : UInt = ??? - def FN_BSET : UInt = ??? - // Zbk - def FN_BREV8 : UInt = ??? - def FN_PACK : UInt = ??? - def FN_PACKH : UInt = ??? - def FN_ZIP : UInt = ??? - def FN_UNZIP : UInt = ??? - def FN_CLMUL : UInt = ??? - def FN_CLMULR : UInt = ??? - def FN_CLMULH : UInt = ??? - def FN_XPERM8 : UInt = ??? - def FN_XPERM4 : UInt = ??? - // Zkn - def FN_AES_DS : UInt = ??? - def FN_AES_DSM : UInt = ??? - def FN_AES_ES : UInt = ??? - def FN_AES_ESM : UInt = ??? - def FN_AES_IM : UInt = ??? - def FN_AES_KS1 : UInt = ??? - def FN_AES_KS2 : UInt = ??? - def FN_SHA256_SIG0 : UInt = ??? - def FN_SHA256_SIG1 : UInt = ??? - def FN_SHA256_SUM0 : UInt = ??? - def FN_SHA256_SUM1 : UInt = ??? - def FN_SHA512_SIG0 : UInt = ??? - def FN_SHA512_SIG1 : UInt = ??? - def FN_SHA512_SUM0 : UInt = ??? - def FN_SHA512_SUM1 : UInt = ??? - //Zks - def FN_SM4ED : UInt = ??? - def FN_SM4KS : UInt = ??? - def FN_SM3P0 : UInt = ??? - def FN_SM3P1 : UInt = ??? - // Mul/div reuse some integer FNs def FN_DIV = FN_XOR def FN_DIVU = FN_SR @@ -112,9 +45,6 @@ class ALUFN { def cmpUnsigned(cmd: UInt) = cmd(1) def cmpInverted(cmd: UInt) = cmd(0) def cmpEq(cmd: UInt) = !cmd(3) - - // Only CryptoNIST uses this - def isKs1(cmd: UInt): Bool = ??? } object ALUFN { @@ -175,7 +105,7 @@ class ALU(implicit p: Parameters) extends AbstractALU(new ALUFN)(p) { val shift_logic = (aluFn.isCmp (io.fn) && slt) | logic | shout val shift_logic_cond = cond_out match { case Some(co) => shift_logic | co - case _ => shift_logic + case _ => shift_logic } val out = Mux(io.fn === aluFn.FN_ADD || io.fn === aluFn.FN_SUB, io.adder_out, shift_logic_cond) diff --git a/src/main/scala/rocket/BitManipCrypto.scala b/src/main/scala/rocket/BitManipCrypto.scala index c09768b82e..e69de29bb2 100644 --- a/src/main/scala/rocket/BitManipCrypto.scala +++ b/src/main/scala/rocket/BitManipCrypto.scala @@ -1,59 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.rocket - -import chisel3._ -import chisel3.util._ -import org.chipsalliance.cde.config.Parameters - - -class BitManipCryptoInterface(xLen: Int) extends Bundle { - val fn = Input(UInt(ABLUFN().SZ_ZBK_FN.W)) - val dw = Input(Bool()) - val rs1 = Input(UInt(xLen.W)) - val rs2 = Input(UInt(xLen.W)) - val rd = Output(UInt(xLen.W)) -} - -class BitManipCrypto(xLen: Int)(implicit val p: Parameters) extends Module with HasRocketCoreParameters { - val fn = ABLUFN() - val io = IO(new BitManipCryptoInterface(xLen)) - - val isClmul = fn.isClmul(io.fn) - val out1H = fn.zbkOut1H(io.fn) - - // helper - def asBytes(in: UInt): Vec[UInt] = VecInit(in.asBools.grouped(8).map(VecInit(_).asUInt).toSeq) - def asNibbles(in: UInt): Vec[UInt] = VecInit(in.asBools.grouped(4).map(VecInit(_).asUInt).toSeq) - - // xperm - val rs1_bytes = asBytes(io.rs1) - val rs2_bytes = asBytes(io.rs2) - val rs1_nibbles = asNibbles(io.rs1) - val rs2_nibbles = asNibbles(io.rs2) - // only instantiate clmul when usingBitManip && !usingBitManipCrypto - val xperm8 = if (usingBitManipCrypto) VecInit(rs2_bytes.map( - x => Mux(x(7,log2Ceil(xLen/8)).orR, 0.U(8.W), rs1_bytes(x)) // return 0 when x overflow - ).toSeq).asUInt else 0.U - val xperm4 = if (usingBitManipCrypto) VecInit(rs2_nibbles.map( - x => if (xLen == 32) Mux(x(3,log2Ceil(xLen/4)).orR, 0.U(4.W), rs1_nibbles(x)) // return 0 when x overflow - else { - require(xLen == 64) - rs1_nibbles(x) - } - ).toSeq).asUInt else 0.U - - // clmul - val clmul_rs1 = Mux(isClmul, io.rs1, Reverse(io.rs1)) - val clmul_rs2 = Mux(isClmul, io.rs2, Reverse(io.rs2)) - val clmul = clmul_rs2.asBools.zipWithIndex.map({ - case (b, i) => Mux(b, clmul_rs1 << i, 0.U) - }).reduce(_ ^ _)(xLen-1,0) - val clmulr = Reverse(clmul) - val clmulh = Cat(0.U(1.W), clmulr(xLen-1,1)) - - // according to FN_xxx above - io.rd := Mux1H(out1H, Seq( - clmul, clmulr, clmulh, - xperm8, xperm4)) -} diff --git a/src/main/scala/rocket/CSR.scala b/src/main/scala/rocket/CSR.scala index 74e7a1e7e2..9daed06411 100644 --- a/src/main/scala/rocket/CSR.scala +++ b/src/main/scala/rocket/CSR.scala @@ -255,10 +255,10 @@ class CSRDecodeIO(implicit p: Parameters) extends CoreBundle { val virtual_system_illegal = Output(Bool()) } -class CSRFileIO(implicit p: Parameters) extends CoreBundle +class CSRFileIO(hasBeu: Boolean)(implicit p: Parameters) extends CoreBundle with HasCoreParameters { val ungated_clock = Input(Clock()) - val interrupts = Input(new CoreInterrupts()) + val interrupts = Input(new CoreInterrupts(hasBeu)) val hartid = Input(UInt(hartIdLen.W)) val rw = new Bundle { val addr = Input(UInt(CSR.ADDRSZ.W)) @@ -376,10 +376,11 @@ class VType(implicit p: Parameters) extends CoreBundle { class CSRFile( perfEventSets: EventSets = new EventSets(Seq()), customCSRs: Seq[CustomCSR] = Nil, - roccCSRs: Seq[CustomCSR] = Nil)(implicit p: Parameters) + roccCSRs: Seq[CustomCSR] = Nil, + hasBeu: Boolean = false)(implicit p: Parameters) extends CoreModule()(p) with HasCoreParameters { - val io = IO(new CSRFileIO { + val io = IO(new CSRFileIO(hasBeu) { val customCSRs = Vec(CSRFile.this.customCSRs.size, new CustomCSRIO) val roccCSRs = Vec(CSRFile.this.roccCSRs.size, new CustomCSRIO) }) @@ -629,8 +630,6 @@ class CSRFile( (if (fLen >= 32) "F" else "") + (if (fLen >= 64) "D" else "") + (if (usingVector) "V" else "") + - // The current spec does not define what sub-extensions constitute the 'B' misa bit - // (if (usingBitManip) "B" else "") + (if (usingCompressed) "C" else "") val isaString = (if (coreParams.useRVE) "E" else "I") + isaMaskString + diff --git a/src/main/scala/rocket/CryptoNIST.scala b/src/main/scala/rocket/CryptoNIST.scala index ad59a860c1..e69de29bb2 100644 --- a/src/main/scala/rocket/CryptoNIST.scala +++ b/src/main/scala/rocket/CryptoNIST.scala @@ -1,261 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package freechips.rocketchip.rocket - -import chisel3._ -import chisel3.util._ -import freechips.rocketchip.util._ - -class CryptoNISTInterface(xLen: Int) extends Bundle { - val fn = Input(UInt(ABLUFN().SZ_ZKN_FN.W)) - val hl = Input(Bool()) - val bs = Input(UInt(2.W)) - val rs1 = Input(UInt(xLen.W)) - val rs2 = Input(UInt(xLen.W)) - val rd = Output(UInt(xLen.W)) -} - -object AES { - val rcon: Seq[Int] = Seq( - 0x01, 0x02, 0x04, 0x08, - 0x10, 0x20, 0x40, 0x80, - 0x1b, 0x36, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00 - ) -} - -class AESSBox extends Module { - val io = IO(new Bundle { - val isEnc = Input(Bool()) - val in = Input(UInt(8.W)) - val out = Output(UInt(8.W)) - }) - - val enc = SBoxAESEncIn(io.in) - val dec = SBoxAESDecIn(io.in) - val mid = SBoxMid(Mux(io.isEnc, enc, dec)) - io.out := Mux(io.isEnc, SBoxAESEncOut(mid), SBoxAESDecOut(mid)) -} - -class GFMul(y: Int) extends Module { - val io = IO(new Bundle { - val in = Input(UInt(8.W)) - val out = Output(UInt(8.W)) - }) - - // x*f(x) = 2*in in GF - def xt(in: UInt): UInt = (in << 1)(7,0) ^ Mux(in(7), 0x1b.U(8.W), 0x00.U(8.W)) - // 4*in in GF - def xt2(in: UInt): UInt = xt(xt(in)) - // 8*in in GF - def xt3(in: UInt): UInt = xt(xt2(in)) - - require(y != 0) - io.out := VecInit( - (if ((y & 0x1) != 0) Seq( (io.in)) else Nil) ++ - (if ((y & 0x2) != 0) Seq( xt(io.in)) else Nil) ++ - (if ((y & 0x4) != 0) Seq(xt2(io.in)) else Nil) ++ - (if ((y & 0x8) != 0) Seq(xt3(io.in)) else Nil) - ).reduce(_ ^ _) -} - -class ShiftRows(enc: Boolean) extends Module { - val io = IO(new Bundle { - val in1 = Input(UInt(64.W)) - val in2 = Input(UInt(64.W)) - val out = Output(UInt(64.W)) - }) - - val stride = if (enc) 5 else 13 - val indexes = Seq.tabulate(4)(x => (x * stride) % 16) ++ - Seq.tabulate(4)(x => (x * stride + 4) % 16) - - def asBytes(in: UInt): Vec[UInt] = VecInit(in.asBools.grouped(8).map(VecInit(_).asUInt).toSeq) - val bytes = asBytes(io.in1) ++ asBytes(io.in2) - - io.out := VecInit(indexes.map(bytes(_)).toSeq).asUInt -} - -class MixColumn8(enc: Boolean) extends Module { - val io = IO(new Bundle { - val in = Input(UInt(8.W)) - val out = Output(UInt(32.W)) - }) - - def m(x: UInt, y: Int): UInt = { - val m = Module(new GFMul(y)) - m.io.in := x - m.io.out - } - - val out = if (enc) Cat(m(io.in, 3), io.in, io.in, m(io.in, 2)) - else Cat(m(io.in, 0xb), m(io.in, 0xd), m(io.in, 9), m(io.in, 0xe)) - io.out := out -} - -class MixColumn32(enc: Boolean) extends Module { - val io = IO(new Bundle { - val in = Input(UInt(32.W)) - val out = Output(UInt(32.W)) - }) - - def asBytes(in: UInt): Vec[UInt] = VecInit(in.asBools.grouped(8).map(VecInit(_).asUInt).toSeq) - io.out := asBytes(io.in).zipWithIndex.map({ - case (b, i) => { - val m = Module(new MixColumn8(enc)) - m.io.in := b - m.io.out.rotateLeft(i * 8) - } - }).reduce(_ ^ _) -} - -class MixColumn64(enc: Boolean) extends Module { - val io = IO(new Bundle { - val in = Input(UInt(64.W)) - val out = Output(UInt(64.W)) - }) - - io.out := VecInit(io.in.asBools.grouped(32).map(VecInit(_).asUInt).map({ - x => { - val m = Module(new MixColumn32(enc)) - m.io.in := x - m.io.out - } - }).toSeq).asUInt -} - -class CryptoNIST(xLen:Int) extends Module { - val fn = ABLUFN() - val io = IO(new CryptoNISTInterface(xLen)) - - val isEnc = fn.isEnc(io.fn) - val isNotMix = fn.isNotMix(io.fn) - val isKs1 = fn.isKs1(io.fn) - val isIm = fn.isIm(io.fn) - val aes1H = fn.aes1H(io.fn) - val out1H = fn.zknOut1H(io.fn) - - // helper - def asBytes(in: UInt): Vec[UInt] = VecInit(in.asBools.grouped(8).map(VecInit(_).asUInt).toSeq) - - // aes - val aes = if (xLen == 32) { - val si = asBytes(io.rs2)(io.bs) - val so = { - val m = Module(new AESSBox) - m.io.in := si - m.io.isEnc := isEnc - m.io.out - } - val mixed_so = Mux(isNotMix, Cat(0.U(24.W), so), { - val mc_enc = Module(new MixColumn8(true)) - val mc_dec = Module(new MixColumn8(false)) - mc_enc.io.in := so - mc_dec.io.in := so - Mux(isEnc, mc_enc.io.out, mc_dec.io.out) - }) - // Vec rightRotate = UInt rotateLeft as Vec is big endian while UInt is little endian - // FIXME: use chisel3.stdlib.BarrelShifter after chisel3 3.6.0 - io.rs1 ^ BarrelShifter.rightRotate(asBytes(mixed_so), io.bs).asUInt - } else { - require(xLen == 64) - // var name from rvk spec enc/dec - val sr = { - val sr_enc = Module(new ShiftRows(true)) - val sr_dec = Module(new ShiftRows(false)) - sr_enc.io.in1 := io.rs1 - sr_enc.io.in2 := io.rs2 - sr_dec.io.in1 := io.rs1 - sr_dec.io.in2 := io.rs2 - Mux(isEnc, sr_enc.io.out, sr_dec.io.out) - } - // var name from rvk spec ks1 - val rnum = io.rs2(3,0) - val tmp1 = io.rs1(63,32) - val tmp2 = Mux(rnum === 0xA.U, tmp1, tmp1.rotateRight(8)) - // reuse 8 Sbox here - val si = Mux(isKs1, Cat(0.U(32.W), tmp2), sr) - val so = VecInit(asBytes(si).map(x => { - val m = Module(new AESSBox) - m.io.in := x - m.io.isEnc := isEnc - m.io.out - }).toSeq).asUInt - val mixed = { - val mc_in = Mux(isIm, io.rs1, so) - val mc_enc = Module(new MixColumn64(true)) - val mc_dec = Module(new MixColumn64(false)) - mc_enc.io.in := mc_in - mc_dec.io.in := mc_in - // for isIm, it is also dec - Mux(isEnc, mc_enc.io.out, mc_dec.io.out) - } - // var name from rvk spec ks1 - val rc = VecInit(AES.rcon.map(_.U(8.W)).toSeq)(rnum) - val tmp4 = so(31,0) ^ rc - val ks1 = Cat(tmp4, tmp4) - // var name from rvk spec ks2 - val w0 = tmp1 ^ io.rs2(31,0) - val w1 = w0 ^ io.rs2(63,32) - val ks2 = Cat(w1, w0) - Mux1H(aes1H, Seq(so, mixed, ks1, ks2)) - } - - // sha - def sext(in: UInt): UInt = if (xLen == 32) in - else { - require(xLen == 64) - val in_hi_32 = Fill(32, in(31)) - Cat(in_hi_32, in) - } - val inb = io.rs1(31,0) - val sha256sig0 = sext(inb.rotateRight(7) ^ inb.rotateRight(18) ^ (inb >> 3)) - val sha256sig1 = sext(inb.rotateRight(17) ^ inb.rotateRight(19) ^ (inb >> 10)) - val sha256sum0 = sext(inb.rotateRight(2) ^ inb.rotateRight(13) ^ inb.rotateRight(22)) - val sha256sum1 = sext(inb.rotateRight(6) ^ inb.rotateRight(11) ^ inb.rotateRight(25)) - - val sha512sig0 = if (xLen == 32) { - val sha512sig0_rs1 = (io.rs1 >> 1 ) ^ (io.rs1 >> 7) ^ (io.rs1 >> 8) - val sha512sig0_rs2h = (io.rs2 << 31) ^ (io.rs2 << 24) - val sha512sig0_rs2l = sha512sig0_rs2h ^ (io.rs2 << 25) - sha512sig0_rs1 ^ Mux(io.hl, sha512sig0_rs2h, sha512sig0_rs2l) - } else { - require(xLen == 64) - io.rs1.rotateRight(1) ^ io.rs1.rotateRight(8) ^ io.rs1 >> 7 - } - - val sha512sig1 = if (xLen == 32) { - val sha512sig1_rs1 = (io.rs1 << 3 ) ^ (io.rs1 >> 6) ^ (io.rs1 >> 19) - val sha512sig1_rs2h = (io.rs2 >> 29) ^ (io.rs2 << 13) - val sha512sig1_rs2l = sha512sig1_rs2h ^ (io.rs2 << 26) - sha512sig1_rs1 ^ Mux(io.hl, sha512sig1_rs2h, sha512sig1_rs2l) - } else { - require(xLen == 64) - io.rs1.rotateRight(19) ^ io.rs1.rotateRight(61) ^ io.rs1 >> 6 - } - - val sha512sum0 = if (xLen == 32) { - val sha512sum0_rs1 = (io.rs1 << 25) ^ (io.rs1 << 30) ^ (io.rs1 >> 28) - val sha512sum0_rs2 = (io.rs2 >> 7) ^ (io.rs2 >> 2) ^ (io.rs2 << 4) - sha512sum0_rs1 ^ sha512sum0_rs2 - } else { - require(xLen == 64) - io.rs1.rotateRight(28) ^ io.rs1.rotateRight(34) ^ io.rs1.rotateRight(39) - } - - val sha512sum1 = if (xLen == 32) { - val sha512sum1_rs1 = (io.rs1 << 23) ^ (io.rs1 >> 14) ^ (io.rs1 >> 18) - val sha512sum1_rs2 = (io.rs2 >> 9) ^ (io.rs2 << 18) ^ (io.rs2 << 14) - sha512sum1_rs1 ^ sha512sum1_rs2 - } else { - require(xLen == 64) - io.rs1.rotateRight(14) ^ io.rs1.rotateRight(18) ^ io.rs1.rotateRight(41) - } - - io.rd := Mux1H(out1H, Seq( - aes, - sha256sig0, sha256sig1, - sha256sum0, sha256sum1, - sha512sig0, sha512sig1, - sha512sum0, sha512sum1)) -} diff --git a/src/main/scala/rocket/CryptoSM.scala b/src/main/scala/rocket/CryptoSM.scala deleted file mode 100644 index 5092e16444..0000000000 --- a/src/main/scala/rocket/CryptoSM.scala +++ /dev/null @@ -1,56 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -package freechips.rocketchip.rocket - -import chisel3._ -import chisel3.util._ -import freechips.rocketchip.util._ - -class CryptoSMInterface(xLen: Int) extends Bundle { - val fn = Input(UInt(ABLUFN().SZ_ZKS_FN.W)) - val bs = Input(UInt(2.W)) - val rs1 = Input(UInt(xLen.W)) - val rs2 = Input(UInt(xLen.W)) - val rd = Output(UInt(xLen.W)) -} - -class CryptoSM(xLen:Int) extends Module { - val fn = ABLUFN() - val io = IO(new CryptoSMInterface(xLen)) - - val isEd = fn.isEd(io.fn) - val isP0 = fn.isP0(io.fn) - val out1H = fn.zksOut1H(io.fn) - - // helper - def sext(in: UInt): UInt = if (xLen == 32) in - else { - require(xLen == 64) - val in_hi_32 = Fill(32, in(31)) - Cat(in_hi_32, in) - } - def asBytes(in: UInt): Vec[UInt] = VecInit(in.asBools.grouped(8).map(VecInit(_).asUInt).toSeq) - - // sm4 - // dynamic selection should be merged into aes rv32 logic! - val si = asBytes(io.rs2(31,0))(io.bs) - // this can also be merged into AESSbox for rv32 - val so = SBoxSM4Out(SBoxMid(SBoxSM4In(si))) - val x = Cat(0.U(24.W), so) - val y = Mux(isEd, - x ^ (x << 8) ^ (x << 2) ^ (x << 18) ^ ((x & 0x3F.U) << 26) ^ ((x & 0xC0.U) << 10), - x ^ ((x & 0x7.U) << 29) ^ ((x & 0xFE.U) << 7) ^ ((x & 0x1.U) << 23) ^ ((x & 0xF8.U) << 13))(31,0) - // dynamic rotate should be merged into aes rv32 logic! - // Vec rightRotate = UInt rotateLeft as Vec is big endian while UInt is little endian - // FIXME: use chisel3.stdlib.BarrelShifter after chisel3 3.6.0 - val z = BarrelShifter.rightRotate(asBytes(y), io.bs).asUInt - val sm4 = sext(z ^ io.rs1(31,0)) - - // sm3 - val r1 = io.rs1(31,0) - val sm3 = sext(Mux(isP0, - r1 ^ r1.rotateLeft(9) ^ r1.rotateLeft(17), - r1 ^ r1.rotateLeft(15) ^ r1.rotateLeft(23))) - - io.rd := Mux1H(out1H, Seq(sm4, sm3)) -} diff --git a/src/main/scala/rocket/DCache.scala b/src/main/scala/rocket/DCache.scala index 1f8a3e65a4..23e46770ca 100644 --- a/src/main/scala/rocket/DCache.scala +++ b/src/main/scala/rocket/DCache.scala @@ -115,6 +115,17 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { // tags val replacer = ReplacementPolicy.fromString(cacheParams.replacementPolicy, nWays) + + /** Metadata Arbiter: + * 0: Tag update on reset + * 1: Tag update on ECC error + * 2: Tag update on hit + * 3: Tag update on refill + * 4: Tag update on release + * 5: Tag update on flush + * 6: Tag update on probe + * 7: Tag update on CPU request + */ val metaArb = Module(new Arbiter(new DCacheMetadataReq, 8) with InlineInstance) val tag_array = DescribedSRAM( @@ -126,6 +137,12 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) { // data val data = Module(new DCacheDataArray) + /** Data Arbiter + * 0: data from pending store buffer + * 1: data from TL-D refill + * 2: release to TL-A + * 3: hit path to CPU + */ val dataArb = Module(new Arbiter(new DCacheDataReq, 4) with InlineInstance) dataArb.io.in.tail.foreach(_.bits.wdata := dataArb.io.in.head.bits.wdata) // tie off write ports by default data.io.req.bits <> dataArb.io.out.bits diff --git a/src/main/scala/rocket/Frontend.scala b/src/main/scala/rocket/Frontend.scala index f6c0ad52b6..30297c5033 100644 --- a/src/main/scala/rocket/Frontend.scala +++ b/src/main/scala/rocket/Frontend.scala @@ -61,9 +61,9 @@ class FrontendIO(implicit p: Parameters) extends CoreBundle()(p) { val progress = Output(Bool()) } -class Frontend(val icacheParams: ICacheParams, staticIdForMetadataUseOnly: Int)(implicit p: Parameters) extends LazyModule { +class Frontend(val icacheParams: ICacheParams, tileId: Int)(implicit p: Parameters) extends LazyModule { lazy val module = new FrontendModule(this) - val icache = LazyModule(new ICache(icacheParams, staticIdForMetadataUseOnly)) + val icache = LazyModule(new ICache(icacheParams, tileId)) val masterNode = icache.masterNode val slaveNode = icache.slaveNode val resetVectorSinkNode = BundleBridgeSink[UInt](Some(() => UInt(masterNode.edges.out.head.bundle.addressBits.W))) @@ -383,7 +383,7 @@ class FrontendModule(outer: Frontend) extends LazyModuleImp(outer) /** Mix-ins for constructing tiles that have an ICache-based pipeline frontend */ trait HasICacheFrontend extends CanHavePTW { this: BaseTile => val module: HasICacheFrontendModule - val frontend = LazyModule(new Frontend(tileParams.icache.get, staticIdForMetadataUseOnly)) + val frontend = LazyModule(new Frontend(tileParams.icache.get, tileId)) tlMasterXbar.node := TLWidthWidget(tileParams.icache.get.rowBits/8) := frontend.masterNode connectTLSlave(frontend.slaveNode, tileParams.core.fetchBytes) frontend.icache.hartIdSinkNodeOpt.foreach { _ := hartIdNexusNode } diff --git a/src/main/scala/rocket/HellaCache.scala b/src/main/scala/rocket/HellaCache.scala index 7360ab89fc..41c8bdfdfe 100644 --- a/src/main/scala/rocket/HellaCache.scala +++ b/src/main/scala/rocket/HellaCache.scala @@ -188,17 +188,17 @@ class HellaCacheIO(implicit p: Parameters) extends CoreBundle()(p) { /** Base classes for Diplomatic TL2 HellaCaches */ -abstract class HellaCache(staticIdForMetadataUseOnly: Int)(implicit p: Parameters) extends LazyModule +abstract class HellaCache(tileId: Int)(implicit p: Parameters) extends LazyModule with HasNonDiplomaticTileParameters { protected val cfg = tileParams.dcache.get protected def cacheClientParameters = cfg.scratch.map(x => Seq()).getOrElse(Seq(TLMasterParameters.v1( - name = s"Core ${staticIdForMetadataUseOnly} DCache", + name = s"Core ${tileId} DCache", sourceId = IdRange(0, 1 max cfg.nMSHRs), supportsProbe = TransferSizes(cfg.blockBytes, cfg.blockBytes)))) protected def mmioClientParameters = Seq(TLMasterParameters.v1( - name = s"Core ${staticIdForMetadataUseOnly} DCache MMIO", + name = s"Core ${tileId} DCache MMIO", sourceId = IdRange(firstMMIO, firstMMIO + cfg.nMMIOs), requestFifo = true)) @@ -254,9 +254,9 @@ case object BuildHellaCache extends Field[BaseTile => Parameters => HellaCache]( object HellaCacheFactory { def apply(tile: BaseTile)(p: Parameters): HellaCache = { if (tile.tileParams.dcache.get.nMSHRs == 0) - new DCache(tile.staticIdForMetadataUseOnly, tile.crossing)(p) + new DCache(tile.tileId, tile.crossing)(p) else - new NonBlockingDCache(tile.staticIdForMetadataUseOnly)(p) + new NonBlockingDCache(tile.tileId)(p) } } diff --git a/src/main/scala/rocket/IDecode.scala b/src/main/scala/rocket/IDecode.scala index c0d8f70e37..7c3aea6ecb 100644 --- a/src/main/scala/rocket/IDecode.scala +++ b/src/main/scala/rocket/IDecode.scala @@ -7,7 +7,6 @@ import chisel3._ import chisel3.util._ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.util._ -import freechips.rocketchip.scie.SCIE import Instructions._ import CustomInstructions._ @@ -26,10 +25,6 @@ class IntCtrlSigs(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends Bu val jalr = Bool() val rxs2 = Bool() val rxs1 = Bool() - val scie = Bool() - val zbk = Bool() - val zkn = Bool() - val zks = Bool() val sel_alu2 = Bits(A2_X.getWidth.W) val sel_alu1 = Bits(A1_X.getWidth.W) val sel_imm = Bits(IMM_X.getWidth.W) @@ -52,19 +47,19 @@ class IntCtrlSigs(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends Bu val vec = Bool() def default: List[BitPat] = - // jal renf1 fence.i - // val | jalr | renf2 | - // | fp_val| | renx2 | | renf3 | - // | | rocc| | | renx1 s_alu1 mem_val | | | wfd | - // | | | br| | | | scie s_alu2 | imm dw alu | mem_cmd | | | | mul | - // | | | | | | | | | zbk | | | | | | | | | | | | div | fence - // | | | | | | | | | | zkn | | | | | | | | | | | | | wxd | | amo - // | | | | | | | | | | | zks | | | | | | | | | | | | | | | | | dp - List(N,X,X,X,X,X,X,X,X,X,X,X, A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, X,X,X,X,X,X,X,CSR.X,X,X,X,X) + // jal renf1 fence.i + // val | jalr | renf2 | + // | fp_val| | renx2 | | renf3 | + // | | rocc| | | renx1 s_alu1 mem_val | | | wfd | + // | | | br| | | | s_alu2 | imm dw alu | mem_cmd | | | | mul | + // | | | | | | | | | | | | | | | | | | | | div | fence + // | | | | | | | | | | | | | | | | | | | | | wxd | | amo + // | | | | | | | | | | | | | | | | | | | | | | | | | dp + List(N,X,X,X,X,X,X,X, A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, X,X,X,X,X,X,X,CSR.X,X,X,X,X) def decode(inst: UInt, table: Iterable[(BitPat, List[BitPat])]) = { val decoder = DecodeLogic(inst, default, table) - val sigs = Seq(legal, fp, rocc, branch, jal, jalr, rxs2, rxs1, scie, zbk, zkn, zks, sel_alu2, + val sigs = Seq(legal, fp, rocc, branch, jal, jalr, rxs2, rxs1, sel_alu2, sel_alu1, sel_imm, alu_dw, alu_fn, mem, mem_cmd, rfs1, rfs2, rfs3, wfd, mul, div, wxd, csr, fence_i, fence, amo, dp) sigs zip decoder map {case(s,d) => s := d} @@ -75,62 +70,62 @@ class IntCtrlSigs(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends Bu class IDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - BNE-> List(Y,N,N,Y,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SNE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - BEQ-> List(Y,N,N,Y,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SEQ, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - BLT-> List(Y,N,N,Y,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - BLTU-> List(Y,N,N,Y,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - BGE-> List(Y,N,N,Y,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SGE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - BGEU-> List(Y,N,N,Y,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SGEU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - - JAL-> List(Y,N,N,N,Y,N,N,N,N,N,N,N,A2_SIZE,A1_PC, IMM_UJ,DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - JALR-> List(Y,N,N,N,N,Y,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - AUIPC-> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_IMM, A1_PC, IMM_U, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - - LB-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - LH-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - LW-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - LBU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - LHU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SB-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - SH-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - SW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - - LUI-> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ADDI-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLTI -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLTIU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ANDI-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ORI-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - XORI-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ADD-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SUB-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLT-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLTU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - AND-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - OR-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - XOR-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLL-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRL-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRA-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - - FENCE-> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.N,N,Y,N,N), - - ECALL-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - EBREAK-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - MRET-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - WFI-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - CSRRW-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N), - CSRRS-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N), - CSRRC-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N), - CSRRWI-> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N), - CSRRSI-> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N), - CSRRCI-> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N)) + BNE-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SNE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + BEQ-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SEQ, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + BLT-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + BLTU-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + BGE-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SGE, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + BGEU-> List(Y,N,N,Y,N,N,Y,Y,A2_RS2, A1_RS1, IMM_SB,DW_XPR,aluFn.FN_SGEU, N,M_X, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + + JAL-> List(Y,N,N,N,Y,N,N,N,A2_SIZE,A1_PC, IMM_UJ,DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + JALR-> List(Y,N,N,N,N,Y,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + AUIPC-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_PC, IMM_U, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + + LB-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + LH-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + LW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + LBU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + LHU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SB-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + SH-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + SW-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + + LUI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_U, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ADDI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SLTI -> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SLTIU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ANDI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ORI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + XORI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ADD-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SUB-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SLT-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SLT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SLTU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SLTU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + AND-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_AND, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + OR-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_OR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + XOR-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_XOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SLL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRA-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + + FENCE-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.N,N,Y,N,N), + + ECALL-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + EBREAK-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + MRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + WFI-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + CSRRW-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N), + CSRRS-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N), + CSRRC-> List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N), + CSRRWI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.W,N,N,N,N), + CSRRSI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.S,N,N,N,N), + CSRRCI-> List(Y,N,N,N,N,N,N,N,A2_IMM, A1_ZERO,IMM_Z, DW_XPR,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.C,N,N,N,N)) } class CeaseDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - CEASE-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) + CEASE-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) } @@ -139,14 +134,14 @@ class FenceIDecode(flushDCache: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: private val (v, cmd) = if (flushDCache) (Y, BitPat(M_FLUSH_ALL)) else (N, M_X) val table: Array[(BitPat, List[BitPat])] = Array( - FENCE_I-> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, v,cmd, N,N,N,N,N,N,N,CSR.N,Y,Y,N,N)) + FENCE_I-> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, v,cmd, N,N,N,N,N,N,N,CSR.N,Y,Y,N,N)) } class ConditionalZeroDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - CZERO_EQZ-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_CZEQZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CZERO_NEZ-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_CZNEZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) + CZERO_EQZ-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_CZEQZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CZERO_NEZ-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_CZNEZ, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) } class CFlushDecode(supportsFlushLine: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants @@ -155,94 +150,94 @@ class CFlushDecode(supportsFlushLine: Boolean, aluFn: ALUFN = ALUFN())(implicit val table: Array[(BitPat, List[BitPat])] = Array( zapRs1(CFLUSH_D_L1)-> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N), + List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N), zapRs1(CDISCARD_D_L1)-> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N)) + List(Y,N,N,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_FLUSH_ALL,N,N,N,N,N,N,N,CSR.I,N,N,N,N)) } class SVMDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - SFENCE_VMA->List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_SFENCE, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) + SFENCE_VMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_SFENCE, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) } class SDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - SRET-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) + SRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) } class HypervisorDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - HFENCE_VVMA->List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HFENCEV, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - HFENCE_GVMA->List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HFENCEG, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + HFENCE_VVMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HFENCEV, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + HFENCE_GVMA->List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HFENCEG, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - HLV_B -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HLV_BU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HLV_H -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HLV_HU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HLVX_HU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HLV_W-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HLVX_WU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HLV_B -> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HLV_BU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HLV_H -> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HLV_HU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HLVX_HU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HLV_W-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HLVX_WU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_HLVX, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HSV_B-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - HSV_H-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - HSV_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) + HSV_B-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + HSV_H-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + HSV_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) } class DebugDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - DRET-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) + DRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) } class NMIDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - MNRET-> List(Y,N,N,N,N,N,N,X,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) + MNRET-> List(Y,N,N,N,N,N,N,X,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,N,CSR.I,N,N,N,N)) } class I32Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( Instructions32.SLLI-> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), Instructions32.SRLI-> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), Instructions32.SRAI-> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) + List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) } class I64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - LD-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - LWU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SD-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), - - SLLI-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRLI-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRAI-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - - ADDIW-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLLIW-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRLIW-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRAIW-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ADDW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SUBW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLLW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRLW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SRAW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) + LD-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + LWU-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SD-> List(Y,N,N,N,N,N,Y,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.N,N,N,N,N), + + SLLI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRLI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRAI-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + + ADDIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SLLIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRLIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRAIW-> List(Y,N,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_32,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + ADDW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_ADD, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SUBW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SUB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SLLW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRLW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + SRAW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32,aluFn.FN_SRA, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) } class Hypervisor64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - HLV_D-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), - HSV_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N), - HLV_WU-> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N)) + HLV_D-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N), + HSV_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO, A1_RS1, IMM_I, DW_XPR, aluFn.FN_ADD, Y,M_XWR, N,N,N,N,N,N,N,CSR.I,N,N,N,N), + HLV_WU-> List(Y,N,N,N,N,N,N,Y,A2_ZERO, A1_RS1, IMM_X, DW_XPR, aluFn.FN_ADD, Y,M_XRD, N,N,N,N,N,N,Y,CSR.I,N,N,N,N)) } class MDecode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants @@ -250,15 +245,15 @@ class MDecode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Par val M = if (pipelinedMul) Y else N val D = if (pipelinedMul) N else Y val table: Array[(BitPat, List[BitPat])] = Array( - MUL-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), - MULH-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULH, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), - MULHU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHU, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), - MULHSU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHSU,N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), - - DIV-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), - DIVU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), - REM-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), - REMU-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N)) + MUL-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), + MULH-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULH, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), + MULHU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHU, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), + MULHSU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_MULHSU,N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), + + DIV-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), + DIVU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), + REM-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), + REMU-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_XPR,aluFn.FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N)) } class M64Decode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants @@ -266,494 +261,213 @@ class M64Decode(pipelinedMul: Boolean, aluFn: ALUFN = ALUFN())(implicit val p: P val M = if (pipelinedMul) Y else N val D = if (pipelinedMul) N else Y val table: Array[(BitPat, List[BitPat])] = Array( - MULW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), + MULW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_MUL, N,M_X, N,N,N,N,M,D,Y,CSR.N,N,N,N,N), - DIVW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), - DIVUW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), - REMW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), - REMUW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N)) + DIVW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIV, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), + DIVUW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_DIVU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), + REMW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_REM, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N), + REMUW-> List(Y,N,N,N,N,N,Y,Y,A2_RS2, A1_RS1, IMM_X, DW_32, aluFn.FN_REMU, N,M_X, N,N,N,N,N,Y,Y,CSR.N,N,N,N,N)) } class ADecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - AMOADD_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOXOR_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOSWAP_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOAND_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOOR_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMIN_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMINU_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMAX_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMAXU_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - - LR_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - SC_W-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N)) + AMOADD_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOXOR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOSWAP_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOAND_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOOR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMIN_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMINU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMAX_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMAXU_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + + LR_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + SC_W-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N)) } class A64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - AMOADD_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOSWAP_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOXOR_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOAND_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOOR_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMIN_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMINU_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMAX_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - AMOMAXU_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - - LR_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), - SC_D-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N)) + AMOADD_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_ADD, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOSWAP_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_SWAP, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOXOR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_XOR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOAND_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_AND, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOOR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_OR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMIN_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MIN, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMINU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MINU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMAX_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAX, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + AMOMAXU_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XA_MAXU, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + + LR_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XLR, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N), + SC_D-> List(Y,N,N,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, Y,M_XSC, N,N,N,N,N,N,Y,CSR.N,N,N,Y,N)) } class HDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - FCVT_S_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FCVT_H_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FSGNJ_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSGNJX_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSGNJN_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMIN_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMAX_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FADD_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSUB_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMUL_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMADD_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FMSUB_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FNMADD_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FNMSUB_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FCLASS_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FMV_X_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_W_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_WU_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FEQ_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), - FLT_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), - FLE_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), - FMV_H_X-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FCVT_H_W-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FCVT_H_WU-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FLH-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FSH-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N), - FDIV_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSQRT_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N)) + FCVT_S_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FCVT_H_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FSGNJ_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSGNJX_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSGNJN_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMIN_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMAX_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMUL_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FMSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FNMADD_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FNMSUB_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FCLASS_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FMV_X_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_W_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_WU_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FEQ_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), + FLT_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), + FLE_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), + FMV_H_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FCVT_H_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FCVT_H_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FLH-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FSH-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N), + FDIV_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSQRT_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N)) } class FDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - FSGNJ_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSGNJX_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSGNJN_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMIN_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMAX_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FADD_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSUB_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMUL_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FMADD_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FMSUB_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FNMADD_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FNMSUB_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), - FCLASS_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FMV_X_W-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_W_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_WU_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FEQ_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), - FLT_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), - FLE_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), - FMV_W_X-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FCVT_S_W-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FCVT_S_WU-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FLW-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FSW-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N), - FDIV_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), - FSQRT_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N)) + FSGNJ_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSGNJX_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSGNJN_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMIN_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMAX_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMUL_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FMADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FMSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FNMADD_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FNMSUB_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,N), + FCLASS_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FMV_X_W-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_W_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_WU_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FEQ_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), + FLT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), + FLE_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,N), + FMV_W_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FCVT_S_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FCVT_S_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FLW-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FSW-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,N), + FDIV_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N), + FSQRT_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,N)) } class DDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - FCVT_S_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FCVT_D_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FSGNJ_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FSGNJX_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FSGNJN_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FMIN_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FMAX_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FADD_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FSUB_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FMUL_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FMADD_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), - FMSUB_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), - FNMADD_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), - FNMSUB_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), - FCLASS_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), - FCVT_W_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), - FCVT_WU_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), - FEQ_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y), - FLT_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y), - FLE_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y), - FCVT_D_W-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FCVT_D_WU-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FLD-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FSD-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,Y), - FDIV_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), - FSQRT_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y)) + FCVT_S_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FCVT_D_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FSGNJ_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FSGNJX_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FSGNJN_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FMIN_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FMAX_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FMUL_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FMADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), + FMSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), + FNMADD_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), + FNMSUB_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,Y,Y,N,N,N,CSR.N,N,N,N,Y), + FCLASS_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), + FCVT_W_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), + FCVT_WU_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), + FEQ_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y), + FLT_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y), + FLE_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,N,N,N,Y,CSR.N,N,N,N,Y), + FCVT_D_W-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FCVT_D_WU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FLD-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_I, DW_XPR,aluFn.FN_ADD, Y,M_XRD, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FSD-> List(Y,Y,N,N,N,N,N,Y,A2_IMM, A1_RS1, IMM_S, DW_XPR,aluFn.FN_ADD, Y,M_XWR, N,Y,N,N,N,N,N,CSR.N,N,N,N,Y), + FDIV_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y), + FSQRT_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,Y,N,Y,N,N,N,CSR.N,N,N,N,Y)) } class HDDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - FCVT_D_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FCVT_H_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y)) + FCVT_D_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FCVT_H_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,Y,N,N,N,CSR.N,N,N,N,Y)) } class H64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - FCVT_L_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_LU_H-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_H_L-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FCVT_H_LU-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N)) + FCVT_L_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_LU_H-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_H_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FCVT_H_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N)) } class F64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - FCVT_L_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_LU_S-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), - FCVT_S_L-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), - FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N)) + FCVT_L_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_LU_S-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,N), + FCVT_S_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N), + FCVT_S_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,N)) } class D64Decode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - FMV_X_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), - FCVT_L_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), - FCVT_LU_D-> List(Y,Y,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), - FMV_D_X-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FCVT_D_L-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), - FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y)) -} - -class SCIEDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants -{ - val table: Array[(BitPat, List[BitPat])] = Array( - SCIE.opcode-> - List(Y,N,N,N,N,N,Y,Y,Y,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) + FMV_X_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), + FCVT_L_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), + FCVT_LU_D-> List(Y,Y,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, Y,N,N,N,N,N,Y,CSR.N,N,N,N,Y), + FMV_D_X-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FCVT_D_L-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y), + FCVT_D_LU-> List(Y,Y,N,N,N,N,N,Y,A2_X, A1_RS1, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,Y,N,N,N,CSR.N,N,N,N,Y)) } class VCFGDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - VSETVLI -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - VSETIVLI -> List(Y,N,N,N,N,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - VSETVL -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - - -trait UsesABLUFN { - val aluFn = ABLUFN() -} - -class ZBADecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - SH1ADD -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR, aluFn.FN_SH1ADD,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SH2ADD -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR, aluFn.FN_SH2ADD,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SH3ADD -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR, aluFn.FN_SH3ADD,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBA64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - ADD_UW -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_64,aluFn.FN_ADDUW ,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SLLI_UW -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_64,aluFn.FN_SLLIUW ,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SH1ADD_UW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_64,aluFn.FN_SH1ADDUW,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SH2ADD_UW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_64,aluFn.FN_SH2ADDUW,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SH3ADD_UW-> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_64,aluFn.FN_SH3ADDUW,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// In both Zbb and Zbkb -class ZBBNDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - ANDN -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ANDN, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ORN -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ORN , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - XNOR -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_XNOR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// In both Zbb and Zbkb -class ZBBRDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - ROR -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ROL -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ROL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBBR32Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.RORI -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBBR64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - RORI -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - RORW -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_32, aluFn.FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - ROLW -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_32, aluFn.FN_ROL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - RORIW -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_32, aluFn.FN_ROR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// Only in Zbb -class ZBBCDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - CLZ -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_CLZ , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CTZ -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_CTZ , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CPOP -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_CPOP, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBBC64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - CLZW -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_32,aluFn.FN_CLZ , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CTZW -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_32,aluFn.FN_CTZ , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CPOPW -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_32,aluFn.FN_CPOP, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// Only in Zbb -class ZBBMDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - MAX -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_MAX , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - MAXU -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_MAXU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - MIN -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_MIN , N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - MINU -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_MINU, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// Only in Zbb -class ZBBSEDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - SEXT_H -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_SEXTH, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SEXT_B -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_SEXTB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBBZE64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - ZEXT_H -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ZEXTH, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBBZE32Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.ZEXT_H -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ZEXTH, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBBORCBDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - ORC_B -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ORCB, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// In both Zbb and Zbkb -class ZBBREV864Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - REV8 -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_REV8, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// In both Zbb and Zbkb -class ZBBREV832Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.REV8-> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X,A1_RS1, IMM_X, DW_XPR,aluFn.FN_REV8, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -// Only in Zbkb -class ZBKBDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - PACK -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_PACK, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - PACKH -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_PACKH, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - BREV8 -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X ,A1_RS1, IMM_X, DW_XPR,aluFn.FN_BREV8, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBKB64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - PACKW -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_32, aluFn.FN_PACK, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBKB32Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.ZIP -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_ZIP, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.UNZIP -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_UNZIP, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) + VSETVLI -> List(Y,N,N,N,N,N,N,Y,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + VSETIVLI -> List(Y,N,N,N,N,N,N,N,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + VSETVL -> List(Y,N,N,N,N,N,Y,Y,A2_X, A1_X, IMM_X, DW_X, aluFn.FN_X, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) } -// also in Zbkc but Zbkc does not have CLMULR -class ZBCDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - CLMUL -> List(Y,N,N,N,N,N,Y,Y,N,Y,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_CLMUL, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CLMULH -> List(Y,N,N,N,N,N,Y,Y,N,Y,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_CLMULH, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBCRDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - CLMULR -> List(Y,N,N,N,N,N,Y,Y,N,Y,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_CLMULR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBKXDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - XPERM8 -> List(Y,N,N,N,N,N,Y,Y,N,Y,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_XPERM8, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - XPERM4 -> List(Y,N,N,N,N,N,Y,Y,N,Y,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_XPERM4, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBSDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - BCLR -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_BCLR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - BEXT -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_BEXT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - BINV -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_BINV, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - BSET -> List(Y,N,N,N,N,N,Y,Y,N,N,N,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_BSET, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBS32Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.BCLRI -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BCLR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.BEXTI -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BEXT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.BINVI -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BINV, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.BSETI -> - List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BSET, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZBS64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - BCLRI -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BCLR, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - BEXTI -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BEXT, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - BINVI -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BINV, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - BSETI -> List(Y,N,N,N,N,N,N,Y,N,N,N,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_BSET, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZKND32Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.AES32DSI -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_DS, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.AES32DSMI-> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_DSM,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} -class ZKND64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - AES64DS -> List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_DS, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - AES64DSM -> List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_DSM,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - AES64IM -> List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_IM, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - AES64KS1I ->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_IMM,A1_RS1, IMM_I, DW_XPR,aluFn.FN_AES_KS1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - AES64KS2 -> List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_KS2,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} -class ZKNE32Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.AES32ESI -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_ES, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.AES32ESMI -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_ESM,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} -class ZKNE64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - AES64ES -> List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_ES, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - AES64ESM -> List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_XPR,aluFn.FN_AES_ESM,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZKNHDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - SHA256SIG0->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA256_SIG0,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SHA256SIG1->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA256_SIG1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SHA256SUM0->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA256_SUM0,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SHA256SUM1->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA256_SUM1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} -class ZKNH32Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - Instructions32.SHA512SIG0L -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SIG0,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.SHA512SIG1L -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SIG1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.SHA512SIG0H -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SIG0,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.SHA512SIG1H -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SIG1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.SHA512SUM0R -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SUM0,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - Instructions32.SHA512SUM1R -> - List(Y,N,N,N,N,N,Y,Y,N,N,Y,N,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SUM1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} -class ZKNH64Decode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - SHA512SIG0->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SIG0,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SHA512SIG1->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SIG1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SHA512SUM0->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SUM0,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SHA512SUM1->List(Y,N,N,N,N,N,N,Y,N,N,Y,N,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SHA512_SUM1,N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} - -class ZKSDecode(implicit val p: Parameters) extends DecodeConstants with UsesABLUFN -{ - val table: Array[(BitPat, List[BitPat])] = Array( - SM4ED -> List(Y,N,N,N,N,N,Y,Y,N,N,N,Y,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SM4ED, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SM4KS -> List(Y,N,N,N,N,N,Y,Y,N,N,N,Y,A2_RS2,A1_RS1, IMM_X, DW_X, aluFn.FN_SM4KS, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SM3P0 -> List(Y,N,N,N,N,N,N,Y,N,N,N,Y,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SM3P0, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - SM3P1 -> List(Y,N,N,N,N,N,N,Y,N,N,N,Y,A2_X ,A1_RS1, IMM_X, DW_X, aluFn.FN_SM3P1, N,M_X, N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) -} class RoCCDecode(aluFn: ALUFN = ALUFN())(implicit val p: Parameters) extends DecodeConstants { val table: Array[(BitPat, List[BitPat])] = Array( - CUSTOM0-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM0_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM0_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM0_RD-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM0_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM0_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM1-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM1_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM1_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM1_RD-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM1_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM1_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM2-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM2_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM2_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM2_RD-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM2_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM2_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM3-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM3_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM3_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), - CUSTOM3_RD-> List(Y,N,Y,N,N,N,N,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM3_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), - CUSTOM3_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) + CUSTOM0-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM0_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM0_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM0_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM0_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM0_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM1-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM1_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM1_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM1_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM1_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM1_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM2-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM2_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM2_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM2_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM2_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM2_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM3-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM3_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM3_RS1_RS2-> List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,N,CSR.N,N,N,N,N), + CUSTOM3_RD-> List(Y,N,Y,N,N,N,N,N,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM3_RD_RS1-> List(Y,N,Y,N,N,N,N,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N), + CUSTOM3_RD_RS1_RS2->List(Y,N,Y,N,N,N,Y,Y,A2_ZERO,A1_RS1, IMM_X, DW_XPR,aluFn.FN_ADD, N,M_X,N,N,N,N,N,N,Y,CSR.N,N,N,N,N)) } diff --git a/src/main/scala/rocket/PTW.scala b/src/main/scala/rocket/PTW.scala index 876dfe478e..f0338807d3 100644 --- a/src/main/scala/rocket/PTW.scala +++ b/src/main/scala/rocket/PTW.scala @@ -677,8 +677,10 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( r_pte := OptimizationBarrier( // l2tlb hit->find a leaf PTE(l2_pte), respond to L1TLB Mux(l2_hit && !l2_error, l2_pte, + // S2 PTE cache hit -> proceed to the next level of walking, update the r_pte with hgatp + Mux(state === s_req && stage2_pte_cache_hit, makeHypervisorRootPTE(r_hgatp, stage2_pte_cache_data, l2_pte), // pte cache hit->find a non-leaf PTE(pte_cache),continue to request mem - Mux(state === s_req && !stage2_pte_cache_hit && pte_cache_hit, makePTE(pte_cache_data, l2_pte), + Mux(state === s_req && pte_cache_hit, makePTE(pte_cache_data, l2_pte), // 2-stage translation Mux(do_switch, makeHypervisorRootPTE(r_hgatp, pte.ppn, r_pte), // when mem respond, store mem.resp.pte @@ -687,7 +689,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()( Mux(state === s_fragment_superpage && !homogeneous && count =/= (pgLevels - 1).U, makePTE(makeFragmentedSuperpagePPN(r_pte.ppn)(count), r_pte), // when tlb request come->request mem, use root address in satp(or vsatp,hgatp) Mux(arb.io.out.fire, Mux(arb.io.out.bits.bits.stage2, makeHypervisorRootPTE(io.dpath.hgatp, io.dpath.vsatp.ppn, r_pte), makePTE(satp.ppn, r_pte)), - r_pte))))))) + r_pte)))))))) when (l2_hit && !l2_error) { assert(state === s_req || state === s_wait1) diff --git a/src/main/scala/rocket/RocketCore.scala b/src/main/scala/rocket/RocketCore.scala index 3ab0eb1fa9..ca5e864859 100644 --- a/src/main/scala/rocket/RocketCore.scala +++ b/src/main/scala/rocket/RocketCore.scala @@ -10,7 +10,6 @@ import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.tile._ import freechips.rocketchip.util._ import freechips.rocketchip.util.property -import freechips.rocketchip.scie._ import scala.collection.mutable.ArrayBuffer case class RocketCoreParams( @@ -24,11 +23,6 @@ case class RocketCoreParams( useAtomicsOnlyForIO: Boolean = false, useCompressed: Boolean = true, useRVE: Boolean = false, - useSCIE: Boolean = false, - useBitManip: Boolean = false, - useBitManipCrypto: Boolean = false, - useCryptoNIST: Boolean = false, - useCryptoSM: Boolean = false, useConditionalZero: Boolean = false, nLocalInterrupts: Int = 0, useNMI: Boolean = false, @@ -69,7 +63,8 @@ case class RocketCoreParams( val instBits: Int = if (useCompressed) 16 else 32 val lrscCycles: Int = 80 // worst case is 14 mispredicted branches + slop val traceHasWdata: Boolean = debugROB // ooo wb, so no wdata in trace unless debugROB - val useVector = vector.isDefined + override val useVector = vector.isDefined + override val vectorUseDCache = vector.map(_.useDCache).getOrElse(false) override def vLen = vector.map(_.vLen).getOrElse(0) override def vMemDataBits = vector.map(_.vMemDataBits).getOrElse(0) override val customIsaExt = Option.when(haveCease)("xrocket") // CEASE instruction @@ -85,12 +80,10 @@ trait HasRocketCoreParameters extends HasCoreParameters { val mulDivParams = rocketParams.mulDiv.getOrElse(MulDivParams()) // TODO ask andrew about this - val usingABLU = usingBitManip || usingBitManipCrypto - val aluFn = if (usingABLU) new ABLUFN else new ALUFN + val aluFn = new ALUFN require(!fastLoadByte || fastLoadWord) require(!rocketParams.haveFSDirty, "rocket doesn't support setting fs dirty from outside, please disable haveFSDirty") - require(!(usingABLU && usingConditionalZero), "Zicond is not yet implemented in ABLU") } class RocketCustomCSRs(implicit p: Parameters) extends CustomCSRs with HasRocketCoreParameters { @@ -124,9 +117,35 @@ class RocketCustomCSRs(implicit p: Parameters) extends CustomCSRs with HasRocket override def decls = super.decls :+ marchid :+ mvendorid :+ mimpid } +class CoreInterrupts(val hasBeu: Boolean)(implicit p: Parameters) extends TileInterrupts()(p) { + val buserror = Option.when(hasBeu)(Bool()) +} + +trait HasRocketCoreIO extends HasRocketCoreParameters { + implicit val p: Parameters + def nTotalRoCCCSRs: Int + val io = IO(new CoreBundle()(p) { + val hartid = Input(UInt(hartIdLen.W)) + val reset_vector = Input(UInt(resetVectorLen.W)) + val interrupts = Input(new CoreInterrupts(tileParams.asInstanceOf[RocketTileParams].beuAddr.isDefined)) + val imem = new FrontendIO + val dmem = new HellaCacheIO + val ptw = Flipped(new DatapathPTWIO()) + val fpu = Flipped(new FPUCoreIO()) + val rocc = Flipped(new RoCCCoreIO(nTotalRoCCCSRs)) + val trace = Output(new TraceBundle) + val bpwatch = Output(Vec(coreParams.nBreakpoints, new BPWatch(coreParams.retireWidth))) + val cease = Output(Bool()) + val wfi = Output(Bool()) + val traceStall = Input(Bool()) + val vector = if (usingVector) Some(Flipped(new VectorCoreIO)) else None + }) +} + + class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) with HasRocketCoreParameters - with HasCoreIO { + with HasRocketCoreIO { def nTotalRoCCCSRs = tile.roccCSRs.flatten.size val clock_en_reg = RegInit(true.B) @@ -189,22 +208,12 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val pipelinedMul = usingMulDiv && mulDivParams.mulUnroll == xLen val decode_table = { - require(!usingRoCC || !rocketParams.useSCIE) (if (usingMulDiv) new MDecode(pipelinedMul, aluFn) +: (xLen > 32).option(new M64Decode(pipelinedMul, aluFn)).toSeq else Nil) ++: (if (usingAtomics) new ADecode(aluFn) +: (xLen > 32).option(new A64Decode(aluFn)).toSeq else Nil) ++: (if (fLen >= 32) new FDecode(aluFn) +: (xLen > 32).option(new F64Decode(aluFn)).toSeq else Nil) ++: (if (fLen >= 64) new DDecode(aluFn) +: (xLen > 32).option(new D64Decode(aluFn)).toSeq else Nil) ++: (if (minFLen == 16) new HDecode(aluFn) +: (xLen > 32).option(new H64Decode(aluFn)).toSeq ++: (fLen >= 64).option(new HDDecode(aluFn)).toSeq else Nil) ++: (usingRoCC.option(new RoCCDecode(aluFn))) ++: - (rocketParams.useSCIE.option(new SCIEDecode(aluFn))) ++: - (if (usingBitManip) new ZBADecode +: (xLen == 64).option(new ZBA64Decode).toSeq ++: new ZBBMDecode +: new ZBBORCBDecode +: new ZBCRDecode +: new ZBSDecode +: (xLen == 32).option(new ZBS32Decode).toSeq ++: (xLen == 64).option(new ZBS64Decode).toSeq ++: new ZBBSEDecode +: new ZBBCDecode +: (xLen == 64).option(new ZBBC64Decode).toSeq else Nil) ++: - (if (usingBitManip && !usingBitManipCrypto) (xLen == 32).option(new ZBBZE32Decode).toSeq ++: (xLen == 64).option(new ZBBZE64Decode).toSeq else Nil) ++: - (if (usingBitManip || usingBitManipCrypto) new ZBBNDecode +: new ZBCDecode +: new ZBBRDecode +: (xLen == 32).option(new ZBBR32Decode).toSeq ++: (xLen == 64).option(new ZBBR64Decode).toSeq ++: (xLen == 32).option(new ZBBREV832Decode).toSeq ++: (xLen == 64).option(new ZBBREV864Decode).toSeq else Nil) ++: - (if (usingBitManipCrypto) new ZBKXDecode +: new ZBKBDecode +: (xLen == 32).option(new ZBKB32Decode).toSeq ++: (xLen == 64).option(new ZBKB64Decode).toSeq else Nil) ++: - (if (usingCryptoNIST) (xLen == 32).option(new ZKND32Decode).toSeq ++: (xLen == 64).option(new ZKND64Decode).toSeq else Nil) ++: - (if (usingCryptoNIST) (xLen == 32).option(new ZKNE32Decode).toSeq ++: (xLen == 64).option(new ZKNE64Decode).toSeq else Nil) ++: - (if (usingCryptoNIST) new ZKNHDecode +: (xLen == 32).option(new ZKNH32Decode).toSeq ++: (xLen == 64).option(new ZKNH64Decode).toSeq else Nil) ++: - (usingCryptoSM.option(new ZKSDecode)) ++: (if (xLen == 32) new I32Decode(aluFn) else new I64Decode(aluFn)) +: (usingVM.option(new SVMDecode(aluFn))) ++: (usingSupervisor.option(new SDecode(aluFn))) ++: @@ -238,8 +247,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val ex_reg_hls = Reg(Bool()) val ex_reg_inst = Reg(Bits()) val ex_reg_raw_inst = Reg(UInt()) - val ex_scie_unpipelined = Reg(Bool()) - val ex_scie_pipelined = Reg(Bool()) val ex_reg_wphit = Reg(Vec(nBreakpoints, Bool())) val ex_reg_set_vconfig = Reg(Bool()) @@ -261,8 +268,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val mem_reg_mem_size = Reg(UInt()) val mem_reg_hls_or_dv = Reg(Bool()) val mem_reg_raw_inst = Reg(UInt()) - val mem_scie_unpipelined = Reg(Bool()) - val mem_scie_pipelined = Reg(Bool()) val mem_reg_wdata = Reg(Bits()) val mem_reg_rs2 = Reg(Bits()) val mem_br_taken = Reg(Bool()) @@ -322,7 +327,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) val ctrl_killd = Wire(Bool()) val id_npc = (ibuf.io.pc.asSInt + ImmGen(IMM_UJ, id_inst(0))).asUInt - val csr = Module(new CSRFile(perfEvents, coreParams.customCSRs.decls, tile.roccCSRs.flatten)) + val csr = Module(new CSRFile(perfEvents, coreParams.customCSRs.decls, tile.roccCSRs.flatten, tile.rocketParams.beuAddr.isDefined)) val id_csr_en = id_ctrl.csr.isOneOf(CSR.S, CSR.C, CSR.W) val id_system_insn = id_ctrl.csr === CSR.I val id_csr_ren = id_ctrl.csr.isOneOf(CSR.S, CSR.C) && id_expanded_inst(0).rs1 === 0.U @@ -343,10 +348,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) id_ctrl.jalr := false.B id_ctrl.rxs2 := v_decode.io.read_rs2 id_ctrl.rxs1 := v_decode.io.read_rs1 - id_ctrl.scie := false.B - id_ctrl.zbk := false.B - id_ctrl.zkn := false.B - id_ctrl.zks := false.B id_ctrl.mem := false.B id_ctrl.rfs1 := v_decode.io.read_frs1 id_ctrl.rfs2 := false.B @@ -365,13 +366,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) } - val id_scie_decoder = if (!rocketParams.useSCIE) WireDefault(0.U.asTypeOf(new SCIEDecoderInterface)) else { - val d = Module(new SCIEDecoder) - assert(!io.imem.resp.valid || PopCount(d.io.unpipelined :: d.io.pipelined :: d.io.multicycle :: Nil) <= 1.U) - d.io.insn := id_raw_inst(0) - d.io - } - val id_illegal_rnum = if (usingCryptoNIST) (id_ctrl.zkn && aluFn.isKs1(id_ctrl.alu_fn) && id_inst(0)(23,20) > 0xA.U(4.W)) else false.B val id_illegal_insn = !id_ctrl.legal || (id_ctrl.mul || id_ctrl.div) && !csr.io.status.isa('m'-'a') || id_ctrl.amo && !csr.io.status.isa('a'-'a') || @@ -379,14 +373,12 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) (id_ctrl.vec) && (csr.io.decode(0).vector_illegal || csr.io.vector.map(_.vconfig.vtype.vill).getOrElse(false.B)) || id_ctrl.dp && !csr.io.status.isa('d'-'a') || ibuf.io.inst(0).bits.rvc && !csr.io.status.isa('c'-'a') || - id_raddr2_illegal && !id_ctrl.scie && id_ctrl.rxs2 || - id_raddr1_illegal && !id_ctrl.scie && id_ctrl.rxs1 || - id_waddr_illegal && !id_ctrl.scie && id_ctrl.wxd || + id_raddr2_illegal && id_ctrl.rxs2 || + id_raddr1_illegal && id_ctrl.rxs1 || + id_waddr_illegal && id_ctrl.wxd || id_ctrl.rocc && csr.io.decode(0).rocc_illegal || - id_ctrl.scie && !(id_scie_decoder.unpipelined || id_scie_decoder.pipelined) || id_csr_en && (csr.io.decode(0).read_illegal || !id_csr_ren && csr.io.decode(0).write_illegal) || - !ibuf.io.inst(0).bits.rvc && (id_system_insn && csr.io.decode(0).system_illegal) || - id_illegal_rnum + !ibuf.io.inst(0).bits.rvc && (id_system_insn && csr.io.decode(0).system_illegal) val id_virtual_insn = id_ctrl.legal && ((id_csr_en && !(!id_csr_ren && csr.io.decode(0).write_illegal) && csr.io.decode(0).virtual_access_illegal) || (!ibuf.io.inst(0).bits.rvc && id_system_insn && csr.io.decode(0).virtual_system_illegal)) @@ -489,7 +481,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) } else { (None, None) } val alu = Module(aluFn match { - case _: ABLUFN => new ABLU case _: ALUFN => new ALU }) alu.io.dw := ex_ctrl.alu_dw @@ -497,52 +488,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) alu.io.in2 := ex_op2.asUInt alu.io.in1 := ex_op1.asUInt - val ex_scie_unpipelined_wdata = if (!rocketParams.useSCIE) 0.U else { - val u = Module(new SCIEUnpipelined(xLen)) - u.io.insn := ex_reg_inst - u.io.rs1 := ex_rs(0) - u.io.rs2 := ex_rs(1) - u.io.rd - } - - val mem_scie_pipelined_wdata = if (!rocketParams.useSCIE) 0.U else { - val u = Module(new SCIEPipelined(xLen)) - u.io.clock := Module.clock - u.io.valid := ex_reg_valid && ex_scie_pipelined - u.io.insn := ex_reg_inst - u.io.rs1 := ex_rs(0) - u.io.rs2 := ex_rs(1) - u.io.rd - } - - val ex_zbk_wdata = if (!usingBitManipCrypto && !usingBitManip) 0.U else { - val zbk = Module(new BitManipCrypto(xLen)) - zbk.io.fn := ex_ctrl.alu_fn - zbk.io.dw := ex_ctrl.alu_dw - zbk.io.rs1 := ex_op1.asUInt - zbk.io.rs2 := ex_op2.asUInt - zbk.io.rd - } - - val ex_zkn_wdata = if (!usingCryptoNIST) 0.U else { - val zkn = Module(new CryptoNIST(xLen)) - zkn.io.fn := ex_ctrl.alu_fn - zkn.io.hl := ex_reg_inst(27) - zkn.io.bs := ex_reg_inst(31,30) - zkn.io.rs1 := ex_op1.asUInt - zkn.io.rs2 := ex_op2.asUInt - zkn.io.rd - } - - val ex_zks_wdata = if (!usingCryptoSM) 0.U else { - val zks = Module(new CryptoSM(xLen)) - zks.io.fn := ex_ctrl.alu_fn - zks.io.bs := ex_reg_inst(31,30) - zks.io.rs1 := ex_op1.asUInt - zks.io.rs2 := ex_op2.asUInt - zks.io.rd - } - // multiplier and divider val div = Module(new MulDiv(if (pipelinedMul) mulDivParams.copy(mulUnroll = 0) else mulDivParams, width = xLen, aluFn = aluFn)) div.io.req.valid := ex_reg_valid && ex_ctrl.div @@ -567,8 +512,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) ex_ctrl := id_ctrl ex_reg_rvc := ibuf.io.inst(0).bits.rvc ex_ctrl.csr := id_csr - ex_scie_unpipelined := id_ctrl.scie && id_scie_decoder.unpipelined - ex_scie_pipelined := id_ctrl.scie && id_scie_decoder.pipelined when (id_ctrl.fence && id_fence_succ === 0.U) { id_reg_pause := true.B } when (id_fence_next) { id_reg_fence := true.B } when (id_xcpt) { // pass PC down ALU writeback pipeline for badaddr @@ -677,8 +620,6 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) mem_reg_sfence := false.B }.elsewhen (ex_pc_valid) { mem_ctrl := ex_ctrl - mem_scie_unpipelined := ex_scie_unpipelined - mem_scie_pipelined := ex_scie_pipelined mem_reg_rvc := ex_reg_rvc mem_reg_load := ex_ctrl.mem && isRead(ex_ctrl.mem_cmd) mem_reg_store := ex_ctrl.mem && isWrite(ex_ctrl.mem_cmd) @@ -696,13 +637,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) mem_reg_hls_or_dv := io.dmem.req.bits.dv mem_reg_pc := ex_reg_pc // IDecode ensured they are 1H - mem_reg_wdata := Mux1H(Seq( - ex_scie_unpipelined -> ex_scie_unpipelined_wdata, - ex_ctrl.zbk -> ex_zbk_wdata, - ex_ctrl.zkn -> ex_zkn_wdata, - ex_ctrl.zks -> ex_zks_wdata, - ex_reg_set_vconfig -> ex_new_vl.getOrElse(0.U), - (!ex_scie_unpipelined && !ex_ctrl.zbk && !ex_ctrl.zks && !ex_reg_set_vconfig) -> alu.io.out)) + mem_reg_wdata := Mux(ex_reg_set_vconfig, ex_new_vl.getOrElse(alu.io.out), alu.io.out) mem_br_taken := alu.io.cmp_out @@ -755,8 +690,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) when (mem_pc_valid) { wb_ctrl := mem_ctrl wb_reg_sfence := mem_reg_sfence - wb_reg_wdata := Mux(mem_scie_pipelined, mem_scie_pipelined_wdata, - Mux(!mem_reg_xcpt && mem_ctrl.fp && mem_ctrl.wxd, io.fpu.toint_data, mem_int_wdata)) + wb_reg_wdata := Mux(!mem_reg_xcpt && mem_ctrl.fp && mem_ctrl.wxd, io.fpu.toint_data, mem_int_wdata) when (mem_ctrl.rocc || mem_reg_sfence || mem_reg_set_vconfig) { wb_reg_rs2 := mem_reg_rs2 } @@ -1011,7 +945,7 @@ class Rocket(tile: RocketTile)(implicit p: Parameters) extends CoreModule()(p) sboard.set(wb_set_sboard && wb_wen, wb_waddr) // stall for RAW/WAW hazards on CSRs, loads, AMOs, and mul/div in execute stage. - val ex_cannot_bypass = ex_ctrl.csr =/= CSR.N || ex_ctrl.jalr || ex_ctrl.mem || ex_ctrl.mul || ex_ctrl.div || ex_ctrl.fp || ex_ctrl.rocc || ex_scie_pipelined + val ex_cannot_bypass = ex_ctrl.csr =/= CSR.N || ex_ctrl.jalr || ex_ctrl.mem || ex_ctrl.mul || ex_ctrl.div || ex_ctrl.fp || ex_ctrl.rocc val data_hazard_ex = ex_ctrl.wxd && checkHazards(hazard_targets, _ === ex_waddr) val fp_data_hazard_ex = id_ctrl.fp && ex_ctrl.wfd && checkHazards(fp_hazard_targets, _ === ex_waddr) val id_ex_hazard = ex_reg_valid && (data_hazard_ex && ex_cannot_bypass || fp_data_hazard_ex) diff --git a/src/main/scala/rocket/SimpleHellaCacheIF.scala b/src/main/scala/rocket/SimpleHellaCacheIF.scala index 2604dbba08..a722770a43 100644 --- a/src/main/scala/rocket/SimpleHellaCacheIF.scala +++ b/src/main/scala/rocket/SimpleHellaCacheIF.scala @@ -126,8 +126,7 @@ class SimpleHellaCacheIF(implicit p: Parameters) extends Module io.cache.req <> req_arb.io.out io.cache.s1_kill := false.B - io.cache.s1_data.data := RegEnable(req_arb.io.out.bits.data, s0_req_fire) - io.cache.s1_data.mask := RegEnable(req_arb.io.out.bits.mask, s0_req_fire) + io.cache.s1_data := RegEnable(req_arb.io.out.bits, s0_req_fire) io.cache.s2_kill := false.B replayq.io.nack.valid := io.cache.s2_nack && s2_req_fire diff --git a/src/main/scala/rocket/VectorUnit.scala b/src/main/scala/rocket/VectorUnit.scala index 8cbf884d0f..5d0fe52212 100644 --- a/src/main/scala/rocket/VectorUnit.scala +++ b/src/main/scala/rocket/VectorUnit.scala @@ -11,7 +11,8 @@ case class RocketCoreVectorParams( build: Parameters => RocketVectorUnit, vLen: Int, vMemDataBits: Int, - decoder: Parameters => RocketVectorDecoder + decoder: Parameters => RocketVectorDecoder, + useDCache: Boolean ) class VectorCoreIO(implicit p: Parameters) extends CoreBundle()(p) { diff --git a/src/main/scala/scie/SCIE.scala b/src/main/scala/scie/SCIE.scala deleted file mode 100644 index a9e46f51a7..0000000000 --- a/src/main/scala/scie/SCIE.scala +++ /dev/null @@ -1,206 +0,0 @@ -// See LICENSE.SiFive for license details. - -package freechips.rocketchip.scie - -import chisel3._ -import chisel3.util.{BitPat, HasBlackBoxInline} -import chisel3.experimental.fromIntToIntParam - -object SCIE { - val opcode = BitPat("b?????????????????????????0?01011") - val iLen = 32 -} - -class SCIEDecoderInterface extends Bundle { - val insn = Input(UInt(SCIE.iLen.W)) - val unpipelined = Output(Bool()) - val pipelined = Output(Bool()) - val multicycle = Output(Bool()) -} - -class SCIEDecoder extends BlackBox with HasBlackBoxInline { - val io = IO(new SCIEDecoderInterface) - - setInline("SCIEDecoder.v", - s""" - |module SCIEDecoder ( - | input [${SCIE.iLen-1}:0] insn, - | output unpipelined, - | output pipelined, - | output multicycle); - | - | /* This module decodes a SCIE instruction and indicates which functional unit - | to send the instruction to (unpipelined, pipelined, or multicycle). The - | outputs are don't-cares unless insn lies within the custom-0 or custom-1 - | major opcodes. If it is within custom-0 or custom-1, then at most one of - | the outputs may be high. If none are high, an illegal-instruction trap - | occurs. If multiple are high, the behavior is undefined. - | - | This example implementation permits Funct3 = 0 or 1 within both custom-0 - | and custom-1 as Unpipelined instructions. - | - | It also permits Funct3 = 2 or 3 within custom-0 as Pipelined instructions. - | */ - | - | wire [2:0] funct3 = insn[14:12]; - | - | assign unpipelined = funct3 <= 3'h1; - | assign pipelined = funct3 == 3'h2 || funct3 == 3'h3; - | assign multicycle = 1'b0; - | - |endmodule - """.stripMargin) -} - -class SCIEUnpipelinedInterface(xLen: Int) extends Bundle { - val insn = Input(UInt(SCIE.iLen.W)) - val rs1 = Input(UInt(xLen.W)) - val rs2 = Input(UInt(xLen.W)) - val rd = Output(UInt(xLen.W)) -} - -class SCIEUnpipelined(xLen: Int) extends BlackBox(Map("XLEN" -> xLen)) with HasBlackBoxInline { - val io = IO(new SCIEUnpipelinedInterface(xLen)) - - setInline("SCIEUnpipelined.v", - s""" - |module SCIEUnpipelined #(parameter XLEN = 32) ( - | input [${SCIE.iLen-1}:0] insn, - | input [XLEN-1:0] rs1, - | input [XLEN-1:0] rs2, - | output [XLEN-1:0] rd); - | - | /* This example SCIE implementation provides the following instructions: - | - | Major opcode custom-0: - | Funct3 = 0: MIN (rd = rs1 < rs2 ? rs1 : rs2) - | Funct3 = 1: MAX (rd = rs1 > rs2 ? rs1 : rs2) - | - | Major opcode custom-1: - | Funct3 = 0: MINI (rd = rs1 < imm[11:0] ? rs1 : imm[11:0]) - | Funct3 = 1: MAXI (rd = rs1 > imm[11:0] ? rs1 : imm[11:0]) - | */ - | - | /* Decode the instruction. */ - | wire use_immediate = insn[5]; - | wire pick_smaller = !insn[12]; - | - | /* Mux the operands. */ - | wire [XLEN-1:0] immediate = {{(XLEN-12){insn[31]}}, insn[31:20]}; - | wire [XLEN-1:0] rhs = use_immediate ? immediate : rs2; - | wire [XLEN-1:0] lhs = rs1; - | - | /* Perform the computation. */ - | wire lhs_smaller = $$signed(lhs) < $$signed(rhs); - | wire [XLEN-1:0] result = lhs_smaller == pick_smaller ? lhs : rhs; - | - | /* Drive the output. */ - | assign rd = result; - | - |endmodule - """.stripMargin) -} - -class SCIEPipelinedInterface(xLen: Int) extends Bundle { - val clock = Input(Clock()) - val valid = Input(Bool()) - val insn = Input(UInt(SCIE.iLen.W)) - val rs1 = Input(UInt(xLen.W)) - val rs2 = Input(UInt(xLen.W)) - val rd = Output(UInt(xLen.W)) -} - -class SCIEPipelined(xLen: Int) extends BlackBox(Map("XLEN" -> xLen)) with HasBlackBoxInline { - val io = IO(new SCIEPipelinedInterface(xLen)) - - setInline("SCIEPipelined.v", - s""" - |module SCIEPipelined #(parameter XLEN = 32) ( - | input clock, - | input valid, - | input [${SCIE.iLen-1}:0] insn, - | input [XLEN-1:0] rs1, - | input [XLEN-1:0] rs2, - | output [XLEN-1:0] rd); - | - | /* This example SCIE implementation provides the following instructions: - | - | Major opcode custom-0: - | Funct3 = 2: AD.U8, compute absolute differences of packed uint8 - | rd[7:0] = abs(rs1[7:0] - rs2[7:0]) - | rd[15:8] = abs(rs1[15:8] - rs2[15:8]) - | ... - | rd[XLEN-1:XLEN-8] = abs(rs1[XLEN-1:XLEN-8] - rs2[XLEN-1:XLEN-8]) - | - | Funct3 = 3: SAD.U8, compute sum of absolute differences of packed uint8 - | tmp[7:0] = abs(rs1[7:0] - rs2[7:0]) - | tmp[15:8] = abs(rs1[15:8] - rs2[15:8]) - | ... - | tmp[XLEN-1:XLEN-8] = abs(rs1[XLEN-1:XLEN-8] - rs2[XLEN-1:XLEN-8]) - | - | rd = tmp[7:0] + tmp[15:8] + ... + tmp[XLEN-1:XLEN-8] - | */ - | - | integer i; - | reg [XLEN-1:0] absolute_differences; - | reg funct3_0; - | reg [XLEN-1:0] result; - | - |`ifndef RANDOM - |`define RANDOM $$random - |`endif - | - | always @(posedge clock) - | begin - | /* Gating using the valid signal is optional, but saves power. */ - | if (valid) - | begin - | /* Register Funct3[0] opcode bit for result muxing in next stage. */ - | funct3_0 <= insn[12]; - | - | /* Compute each absolute difference and register each result. */ - | for (i = 0; i < XLEN/8; i = i + 1) - | begin - | absolute_differences[8*i +: 8] <= rs1[8*i +: 8] < rs2[8*i +: 8] ? - | rs2[8*i +: 8] - rs1[8*i +: 8] : - | rs1[8*i +: 8] - rs2[8*i +: 8]; - | end - | end - | end - | - | /* In the second pipeline stage, compute the final result. */ - | always @(*) - | begin - | if (!funct3_0) - | begin - | /* If Funct3[0] = 0, the output is the packed absolute differences. */ - | result = absolute_differences; - | end - | else - | begin - | /* If Funct3[0] = 1, the output is their sum. */ - | result = {XLEN{1'b0}}; - | for (i = 0; i < XLEN/8; i = i + 1) - | begin - | result = result + {{(XLEN-8){1'b0}}, absolute_differences[8*i +: 8]}; - | end - | end - | end - | - | /* Drive the output. */ - | assign rd = result; - | - | /* Suppress Xs at simulation start */ - | `ifdef RANDOMIZE_REG_INIT - | initial begin - | `ifndef VERILATOR - | #`RANDOMIZE_DELAY begin end - | `endif - | absolute_differences = {(XLEN / 32){`RANDOM}}; - | funct3_0 = absolute_differences[0]; - | end - | `endif - | - |endmodule - """.stripMargin) -} diff --git a/src/main/scala/subsystem/Attachable.scala b/src/main/scala/subsystem/Attachable.scala index 7809280a11..06f2269421 100644 --- a/src/main/scala/subsystem/Attachable.scala +++ b/src/main/scala/subsystem/Attachable.scala @@ -4,7 +4,7 @@ package freechips.rocketchip.subsystem import org.chipsalliance.cde.config.Parameters import freechips.rocketchip.diplomacy.{LazyModule, LazyScope} -import freechips.rocketchip.prci.ClockGroupEphemeralNode +import freechips.rocketchip.prci.ClockGroupNode import freechips.rocketchip.tilelink.TLBusWrapper import freechips.rocketchip.util.{Location, LocationMap} @@ -23,13 +23,14 @@ trait LazyScopeWithParameters extends LazyScope { this: LazyModule => /** Layers of hierarchy with this trait contain attachment points for neworks of power, clock, reset, and interrupt resources */ trait HasPRCILocations extends LazyScopeWithParameters { this: LazyModule => - implicit val asyncClockGroupsNode: ClockGroupEphemeralNode + val allClockGroupsNode: ClockGroupNode val ibus: InterruptBusWrapper val anyLocationMap = LocationMap.empty[Any] } /** Layers of hierarchy with this trait contain attachment points for TileLink interfaces */ trait HasTileLinkLocations extends HasPRCILocations { this: LazyModule => + val busContextName: String val tlBusWrapperLocationMap = LocationMap.empty[TLBusWrapper] def locateTLBusWrapper(location: Location[TLBusWrapper]): TLBusWrapper = locateTLBusWrapper(location.name) def locateTLBusWrapper(name: String): TLBusWrapper = tlBusWrapperLocationMap(Location[TLBusWrapper](name)) diff --git a/src/main/scala/subsystem/BankedL2Params.scala b/src/main/scala/subsystem/BankedCoherenceParams.scala similarity index 92% rename from src/main/scala/subsystem/BankedL2Params.scala rename to src/main/scala/subsystem/BankedCoherenceParams.scala index 402dd53780..84a7d015c3 100644 --- a/src/main/scala/subsystem/BankedL2Params.scala +++ b/src/main/scala/subsystem/BankedCoherenceParams.scala @@ -14,7 +14,7 @@ import CoherenceManagerWrapper._ /** Global cache coherence granularity, which applies to all caches, for now. */ case object CacheBlockBytes extends Field[Int](64) -/** L2 Broadcast Hub configuration */ +/** LLC Broadcast Hub configuration */ case object BroadcastKey extends Field(BroadcastParams()) case class BroadcastParams( @@ -23,10 +23,11 @@ case class BroadcastParams( controlAddress: Option[BigInt] = None, filterFactory: TLBroadcast.ProbeFilterFactory = BroadcastFilter.factory) -/** L2 memory subsystem configuration */ -case object BankedL2Key extends Field(BankedL2Params()) +/** Coherence manager configuration */ +case object SubsystemBankedCoherenceKey extends Field(BankedCoherenceParams()) +case class ClusterBankedCoherenceKey(clusterId: Int) extends Field(BankedCoherenceParams(nBanks=0)) -case class BankedL2Params( +case class BankedCoherenceParams( nBanks: Int = 1, coherenceManager: CoherenceManagerInstantiationFn = broadcastManager ) { diff --git a/src/main/scala/subsystem/BaseSubsystem.scala b/src/main/scala/subsystem/BaseSubsystem.scala index 926e1d2292..347466709f 100644 --- a/src/main/scala/subsystem/BaseSubsystem.scala +++ b/src/main/scala/subsystem/BaseSubsystem.scala @@ -2,6 +2,7 @@ package freechips.rocketchip.subsystem +import chisel3.{Flipped, IO} import chisel3.util._ import org.chipsalliance.cde.config.{Field, Parameters} import freechips.rocketchip.diplomacy._ @@ -9,8 +10,7 @@ import freechips.rocketchip.prci._ import freechips.rocketchip.tilelink.TLBusWrapper import freechips.rocketchip.util._ -case object SubsystemDriveAsyncClockGroupsKey extends Field[Option[ClockGroupDriverParameters]](Some(ClockGroupDriverParameters(1))) -case object AsyncClockGroupsKey extends Field[() => ClockGroupEphemeralNode](() => ClockGroupEphemeralNode()(ValName("clock_sources"))) +case object SubsystemDriveClockGroupsFromIO extends Field[Boolean](true) case class TLNetworkTopologyLocated(where: HierarchicalLocation) extends Field[Seq[CanInstantiateWithinContextThatHasTileLinkLocations with CanConnectWithinContextThatHasTileLinkLocations]] case class TLManagerViewpointLocated(where: HierarchicalLocation) extends Field[Location[TLBusWrapper]](SBUS) @@ -26,7 +26,7 @@ abstract class BareSubsystem(implicit p: Parameters) extends LazyModule with Bin lazy val json = JSON(bindingTree) } -abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends LazyModuleImp(_outer) { +abstract class BareSubsystemModuleImp[+L <: BareSubsystem](_outer: L) extends LazyRawModuleImp(_outer) { val outer = _outer ElaborationArtefacts.add("graphml", outer.graphML) ElaborationArtefacts.add("dts", outer.dts) @@ -47,11 +47,22 @@ case object SubsystemResetSchemeKey extends Field[SubsystemResetScheme](ResetSyn */ trait HasConfigurablePRCILocations { this: HasPRCILocations => val ibus = LazyModule(new InterruptBusWrapper) - implicit val asyncClockGroupsNode = p(AsyncClockGroupsKey)() - val clock_sources: ModuleValue[RecordMap[ClockBundle]] = - p(SubsystemDriveAsyncClockGroupsKey) - .map(_.drive(asyncClockGroupsNode)) - .getOrElse(InModuleBody { RecordMap[ClockBundle]() }) + val allClockGroupsNode = ClockGroupIdentityNode() + val io_clocks = if (p(SubsystemDriveClockGroupsFromIO)) { + val aggregator = ClockGroupAggregator() + val source = ClockGroupSourceNode(Seq(ClockGroupSourceParameters())) + allClockGroupsNode :*= aggregator := source + Some(InModuleBody { + val elements = source.out.map(_._1.member.elements).flatten + val io = IO(Flipped(RecordMap(elements.map { case (name, data) => + name -> data.cloneType + }:_*))) + elements.foreach { case (name, data) => io(name).foreach { data := _ } } + io + }) + } else { + None + } } /** Look up the topology configuration for the TL buses located within this layer of the hierarchy */ @@ -77,9 +88,11 @@ abstract class BaseSubsystem(val location: HierarchicalLocation = InSubsystem) { override val module: BaseSubsystemModuleImp[BaseSubsystem] + val busContextName = "subsystem" + // TODO must there really always be an "sbus"? val sbus = tlBusWrapperLocationMap(SBUS) - tlBusWrapperLocationMap.lift(SBUS).map { _.clockGroupNode := asyncClockGroupsNode } + tlBusWrapperLocationMap.lift(SBUS).map { _.clockGroupNode := allClockGroupsNode } // TODO: Preserve legacy implicit-clock behavior for IBUS for now. If binding // a PLIC to the CBUS, ensure it is synchronously coupled to the SBUS. diff --git a/src/main/scala/subsystem/BusTopology.scala b/src/main/scala/subsystem/BusTopology.scala index 239a016647..a9d77b5b12 100644 --- a/src/main/scala/subsystem/BusTopology.scala +++ b/src/main/scala/subsystem/BusTopology.scala @@ -23,12 +23,16 @@ case object MemoryBusKey extends Field[MemoryBusParams] // dynamically-configured topologies. class TLBusWrapperLocation(name: String) extends Location[TLBusWrapper](name) -case object SBUS extends TLBusWrapperLocation("subsystem_sbus") -case object PBUS extends TLBusWrapperLocation("subsystem_pbus") -case object FBUS extends TLBusWrapperLocation("subsystem_fbus") -case object MBUS extends TLBusWrapperLocation("subsystem_mbus") -case object CBUS extends TLBusWrapperLocation("subsystem_cbus") -case object L2 extends TLBusWrapperLocation("subsystem_l2") +case object SBUS extends TLBusWrapperLocation("sbus") +case object PBUS extends TLBusWrapperLocation("pbus") +case object FBUS extends TLBusWrapperLocation("fbus") +case object MBUS extends TLBusWrapperLocation("mbus") +case object CBUS extends TLBusWrapperLocation("cbus") +case object COH extends TLBusWrapperLocation("coh") +case class CSBUS(clusterId: Int) extends TLBusWrapperLocation(s"csbus$clusterId") +case class CMBUS(clusterId: Int) extends TLBusWrapperLocation(s"cmbus$clusterId") +case class CCBUS(clusterId: Int) extends TLBusWrapperLocation(s"ccbus$clusterId") +case class CCOH (clusterId: Int) extends TLBusWrapperLocation(s"ccoh$clusterId") /** Parameterizes the subsystem in terms of optional clock-crossings * that are insertable between some of the five traditional tilelink bus wrappers. @@ -89,20 +93,40 @@ case class HierarchicalBusTopologyParams( /** Parameterization of a topology containing a banked coherence manager and a bus for attaching memory devices. */ case class CoherentBusTopologyParams( - sbus: SystemBusParams, // TODO remove this after better width propagation mbus: MemoryBusParams, - l2: BankedL2Params, + coherence: BankedCoherenceParams, sbusToMbusXType: ClockCrossingType = NoCrossing, driveMBusClockFromSBus: Boolean = true ) extends TLBusWrapperTopology( - instantiations = (if (l2.nBanks == 0) Nil else List( + instantiations = (if (coherence.nBanks == 0) Nil else List( (MBUS, mbus), - (L2, CoherenceManagerWrapperParams(mbus.blockBytes, mbus.beatBytes, l2.nBanks, L2.name, sbus.dtsFrequency)(l2.coherenceManager)))), - connections = if (l2.nBanks == 0) Nil else List( - (SBUS, L2, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()), - (L2, MBUS, TLBusWrapperConnection.crossTo( + (COH, CoherenceManagerWrapperParams(mbus.blockBytes, mbus.beatBytes, coherence.nBanks, COH.name)(coherence.coherenceManager)))), + connections = if (coherence.nBanks == 0) Nil else List( + (SBUS, COH, TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()), + (COH, MBUS, TLBusWrapperConnection.crossTo( xType = sbusToMbusXType, driveClockFromMaster = if (driveMBusClockFromSBus) Some(true) else None, nodeBinding = BIND_QUERY)) ) ) + +case class ClusterBusTopologyParams( + clusterId: Int, + csbus: SystemBusParams, + ccbus: PeripheryBusParams, + coherence: BankedCoherenceParams +) extends TLBusWrapperTopology( + instantiations = List( + (CSBUS(clusterId), csbus), + (CCBUS(clusterId), ccbus)) ++ (if (coherence.nBanks == 0) Nil else List( + (CMBUS(clusterId), csbus), + (CCOH (clusterId), CoherenceManagerWrapperParams(csbus.blockBytes, csbus.beatBytes, coherence.nBanks, CCOH(clusterId).name)(coherence.coherenceManager)))), + connections = if (coherence.nBanks == 0) Nil else List( + (CSBUS(clusterId), CCOH (clusterId), TLBusWrapperConnection(driveClockFromMaster = Some(true), nodeBinding = BIND_STAR)()), + (CCOH (clusterId), CMBUS(clusterId), TLBusWrapperConnection.crossTo( + xType = NoCrossing, + driveClockFromMaster = Some(true), + nodeBinding = BIND_QUERY)) + ) +) + diff --git a/src/main/scala/subsystem/Cluster.scala b/src/main/scala/subsystem/Cluster.scala new file mode 100644 index 0000000000..7e2ca886a1 --- /dev/null +++ b/src/main/scala/subsystem/Cluster.scala @@ -0,0 +1,233 @@ +package freechips.rocketchip.subsystem + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config.{Field, Parameters} +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.prci._ +import freechips.rocketchip.tile.{RocketTile, NMI, TraceBundle} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.devices.debug.{TLDebugModule} +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.util._ +import scala.collection.immutable.SortedMap + +case class ClustersLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachCluster]](Nil) + +case class ClusterParams( + val clusterId: Int, + val clockSinkParams: ClockSinkParameters = ClockSinkParameters() +) extends HierarchicalElementParams { + val baseName = "cluster" + val uniqueName = s"${baseName}_$clusterId" + def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByClusterIdImpl)(implicit p: Parameters): Cluster = { + new Cluster(this, crossing.crossingType, lookup) + } +} + +class Cluster( + val thisClusterParams: ClusterParams, + crossing: ClockCrossingType, + lookup: LookupByClusterIdImpl)(implicit p: Parameters) extends BaseHierarchicalElement(crossing)(p) + with Attachable + with HasConfigurableTLNetworkTopology + with InstantiatesHierarchicalElements + with HasHierarchicalElements +{ + val busContextName = thisClusterParams.baseName + lazy val clusterId = thisClusterParams.clusterId + lazy val location = InCluster(clusterId) + + lazy val allClockGroupsNode = ClockGroupIdentityNode() + + val csbus = tlBusWrapperLocationMap(CSBUS(clusterId)) // like the sbus in the base subsystem + val ccbus = tlBusWrapperLocationMap(CCBUS(clusterId)) // like the cbus in the base subsystem + val cmbus = tlBusWrapperLocationMap.lift(CMBUS(clusterId)).getOrElse(csbus) + + csbus.clockGroupNode := allClockGroupsNode + ccbus.clockGroupNode := allClockGroupsNode + + val slaveNode = ccbus.inwardNode + val masterNode = cmbus.outwardNode + + + + lazy val ibus = LazyModule(new InterruptBusWrapper) + ibus.clockNode := csbus.fixedClockNode + + def msipDomain = this + def meipDomain = this + def seipDomain = this + lazy val msipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap) + lazy val meipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap) + lazy val seipNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap) + lazy val tileToPlicNodes = totalTileIdList.map { i => (i, IntIdentityNode()) }.to(SortedMap) + lazy val debugNodes = totalTileIdList.map { i => (i, IntSyncIdentityNode()) }.to(SortedMap) + lazy val nmiNodes = totalTiles.filter { case (i,t) => t.tileParams.core.useNMI } + .mapValues(_ => BundleBridgeIdentityNode[NMI]()).to(SortedMap) + lazy val tileHartIdNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.to(SortedMap) + lazy val tileResetVectorNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[UInt]()) }.to(SortedMap) + lazy val traceCoreNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[TraceCoreInterface]()) }.to(SortedMap) + lazy val traceNodes = totalTileIdList.map { i => (i, BundleBridgeIdentityNode[TraceBundle]()) }.to(SortedMap) + + // TODO fix: shouldn't need to connect dummy notifications + tileHaltXbarNode := NullIntSource() + tileWFIXbarNode := NullIntSource() + tileCeaseXbarNode := NullIntSource() + + override lazy val module = new ClusterModuleImp(this) +} + +class ClusterModuleImp(outer: Cluster) extends BaseHierarchicalElementModuleImp[Cluster](outer) + +case class InCluster(id: Int) extends HierarchicalLocation(s"Cluster$id") + +class ClusterPRCIDomain( + clockSinkParams: ClockSinkParameters, + crossingParams: HierarchicalElementCrossingParamsLike, + clusterParams: ClusterParams, + lookup: LookupByClusterIdImpl) + (implicit p: Parameters) extends HierarchicalElementPRCIDomain[Cluster](clockSinkParams, crossingParams) +{ + val element = element_reset_domain { + LazyModule(clusterParams.instantiate(crossingParams, lookup)) + } + // Nothing should depend on the clocks coming from clockNode anyways + clockNode := element.csbus.fixedClockNode +} + + +trait CanAttachCluster { + type ClusterContextType <: DefaultHierarchicalElementContextType + + def clusterParams: ClusterParams + def crossingParams: HierarchicalElementCrossingParamsLike + + def instantiate(allClusterParams: Seq[ClusterParams], instantiatedClusters: SortedMap[Int, ClusterPRCIDomain])(implicit p: Parameters): ClusterPRCIDomain = { + val clockSinkParams = clusterParams.clockSinkParams.copy(name = Some(clusterParams.uniqueName)) + val cluster_prci_domain = LazyModule(new ClusterPRCIDomain( + clockSinkParams, crossingParams, clusterParams, PriorityMuxClusterIdFromSeq(allClusterParams))) + cluster_prci_domain + } + + def connect(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = { + connectMasterPorts(domain, context) + connectSlavePorts(domain, context) + connectInterrupts(domain, context) + connectPRC(domain, context) + connectOutputNotifications(domain, context) + connectInputConstants(domain, context) + connectTrace(domain, context) + } + + def connectMasterPorts(domain: ClusterPRCIDomain, context: Attachable): Unit = { + implicit val p = context.p + val dataBus = context.locateTLBusWrapper(crossingParams.master.where) + dataBus.coupleFrom(clusterParams.baseName) { bus => + bus :=* crossingParams.master.injectNode(context) :=* domain.crossMasterPort(crossingParams.crossingType) + } + } + def connectSlavePorts(domain: ClusterPRCIDomain, context: Attachable): Unit = { + implicit val p = context.p + val controlBus = context.locateTLBusWrapper(crossingParams.slave.where) + controlBus.coupleTo(clusterParams.baseName) { bus => + domain.crossSlavePort(crossingParams.crossingType) :*= crossingParams.slave.injectNode(context) :*= TLWidthWidget(controlBus.beatBytes) :*= bus + } + } + def connectInterrupts(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = { + implicit val p = context.p + + domain.element.debugNodes.foreach { case (hartid, node) => + node := context.debugNodes(hartid) + } + + domain.element.msipNodes.foreach { case (hartid, node) => context.msipDomain { + domain.crossIntIn(crossingParams.crossingType, node) := context.msipNodes(hartid) + }} + + domain.element.meipNodes.foreach { case (hartid, node) => context.meipDomain { + domain.crossIntIn(crossingParams.crossingType, node) := context.meipNodes(hartid) + }} + + domain.element.seipNodes.foreach { case (hartid, node) => context.seipDomain { + domain.crossIntIn(crossingParams.crossingType, node) := context.seipNodes(hartid) + }} + + domain.element.tileToPlicNodes.foreach { case (hartid, node) => + FlipRendering { implicit p => + context.tileToPlicNodes(hartid) :=* domain.crossIntOut(crossingParams.crossingType, node) } + } + context.ibus.fromSync :=* domain.crossIntOut(crossingParams.crossingType, domain.element.ibus.toPLIC) + + domain.element.nmiNodes.foreach { case (hartid, node) => + node := context.nmiNodes(hartid) + } + } + + def connectPRC(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = { + implicit val p = context.p + domain.element.allClockGroupsNode :*= context.allClockGroupsNode + domain { + domain.element_reset_domain.clockNode := crossingParams.resetCrossingType.injectClockNode := domain.clockNode + } + } + + def connectOutputNotifications(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = { + implicit val p = context.p + context.tileHaltXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.tileHaltXbarNode) + context.tileWFIXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.tileWFIXbarNode) + context.tileCeaseXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.tileCeaseXbarNode) + + } + + def connectInputConstants(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = { + implicit val p = context.p + val tlBusToGetPrefixFrom = context.locateTLBusWrapper(crossingParams.mmioBaseAddressPrefixWhere) + domain.element.tileHartIdNodes.foreach { case (hartid, node) => + node := context.tileHartIdNodes(hartid) + } + domain.element.tileResetVectorNodes.foreach { case (hartid, node) => + node := context.tileResetVectorNodes(hartid) + } + } + + def connectTrace(domain: ClusterPRCIDomain, context: ClusterContextType): Unit = { + implicit val p = context.p + domain.element.traceNodes.foreach { case (hartid, node) => + val traceNexusNode = BundleBridgeBlockDuringReset[TraceBundle]( + resetCrossingType = crossingParams.resetCrossingType) + context.traceNodes(hartid) := traceNexusNode := node + } + domain.element.traceCoreNodes.foreach { case (hartid, node) => + val traceCoreNexusNode = BundleBridgeBlockDuringReset[TraceCoreInterface]( + resetCrossingType = crossingParams.resetCrossingType) + context.traceCoreNodes(hartid) :*= traceCoreNexusNode := node + } + } +} + +case class ClusterAttachParams( + clusterParams: ClusterParams, + crossingParams: HierarchicalElementCrossingParamsLike +) extends CanAttachCluster + +case class CloneClusterAttachParams( + sourceClusterId: Int, + cloneParams: CanAttachCluster +) extends CanAttachCluster { + def clusterParams = cloneParams.clusterParams + def crossingParams = cloneParams.crossingParams + + override def instantiate(allClusterParams: Seq[ClusterParams], instantiatedClusters: SortedMap[Int, ClusterPRCIDomain])(implicit p: Parameters): ClusterPRCIDomain = { + require(instantiatedClusters.contains(sourceClusterId)) + val clockSinkParams = clusterParams.clockSinkParams.copy(name = Some(clusterParams.uniqueName)) + val cluster_prci_domain = CloneLazyModule( + new ClusterPRCIDomain(clockSinkParams, crossingParams, clusterParams, PriorityMuxClusterIdFromSeq(allClusterParams)), + instantiatedClusters(sourceClusterId) + ) + cluster_prci_domain + } +} diff --git a/src/main/scala/subsystem/Configs.scala b/src/main/scala/subsystem/Configs.scala index 7b4a8368ac..57bec6d4ce 100644 --- a/src/main/scala/subsystem/Configs.scala +++ b/src/main/scala/subsystem/Configs.scala @@ -16,7 +16,8 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { // Tile parameters case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */ case XLen => 64 // Applies to all cores - case MaxHartIdBits => log2Up((site(TilesLocated(InSubsystem)).map(_.tileParams.hartId) :+ 0).max+1) + case MaxHartIdBits => log2Up((site(PossibleTileLocations).flatMap(loc => site(TilesLocated(loc))) + .map(_.tileParams.tileId) :+ 0).max+1) // Interconnect parameters case SystemBusKey => SystemBusParams( beatBytes = site(XLen)/8, @@ -24,6 +25,7 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { case ControlBusKey => PeripheryBusParams( beatBytes = site(XLen)/8, blockBytes = site(CacheBlockBytes), + dtsFrequency = Some(100000000), // Default to 100 MHz cbus clock errorDevice = Some(BuiltInErrorDeviceParams( errorParams = DevNullParams(List(AddressSet(0x3000, 0xfff)), maxAtomic=site(XLen)/8, maxTransfer=4096)))) case PeripheryBusKey => PeripheryBusParams( @@ -38,11 +40,12 @@ class BaseSubsystemConfig extends Config ((site, here, up) => { blockBytes = site(CacheBlockBytes)) // Additional device Parameters case BootROMLocated(InSubsystem) => Some(BootROMParams(contentFileName = "./bootrom/bootrom.img")) - case SubsystemExternalResetVectorKey => false + case HasTilesExternalResetVectorKey => false case DebugModuleKey => Some(DefaultDebugModuleParams(site(XLen))) case CLINTKey => Some(CLINTParams()) case PLICKey => Some(PLICParams()) case TilesLocated(InSubsystem) => Nil + case PossibleTileLocations => Seq(InSubsystem) }) /* Composable partial function Configs to set individual parameters */ @@ -80,21 +83,20 @@ class WithCoherentBusTopology extends Config((site, here, up) => { fbusToSbusXType = site(FbusToSbusXTypeKey)), driveClocksFromSBus = site(DriveClocksFromSBus)), CoherentBusTopologyParams( - sbus = site(SystemBusKey), mbus = site(MemoryBusKey), - l2 = site(BankedL2Key), + coherence = site(SubsystemBankedCoherenceKey), sbusToMbusXType = site(SbusToMbusXTypeKey), driveMBusClockFromSBus = site(DriveClocksFromSBus))) }) class WithNBigCores( n: Int, - overrideIdOffset: Option[Int] = None, - crossing: RocketCrossingParams = RocketCrossingParams() + location: HierarchicalLocation, + crossing: RocketCrossingParams, ) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => { - val prev = up(TilesLocated(InSubsystem), site) - val idOffset = overrideIdOffset.getOrElse(prev.size) + case TilesLocated(`location`) => { + val prev = up(TilesLocated(`location`), site) + val idOffset = up(NumTiles) val big = RocketTileParams( core = RocketCoreParams(mulDiv = Some(MulDivParams( mulUnroll = 8, @@ -108,20 +110,31 @@ class WithNBigCores( rowBits = site(SystemBusKey).beatBits, blockBytes = site(CacheBlockBytes)))) List.tabulate(n)(i => RocketTileAttachParams( - big.copy(hartId = i + idOffset), + big.copy(tileId = i + idOffset), crossing )) ++ prev } -}) + case NumTiles => up(NumTiles) + n +}) { + def this(n: Int, location: HierarchicalLocation = InSubsystem) = this(n, location, RocketCrossingParams( + master = HierarchicalElementMasterPortParams.locationDefault(location), + slave = HierarchicalElementSlavePortParams.locationDefault(location), + mmioBaseAddressPrefixWhere = location match { + case InSubsystem => CBUS + case InCluster(clusterId) => CCBUS(clusterId) + } + )) +} + + class WithNMedCores( n: Int, - overrideIdOffset: Option[Int] = None, - crossing: RocketCrossingParams = RocketCrossingParams() + crossing: RocketCrossingParams = RocketCrossingParams(), ) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => { val prev = up(TilesLocated(InSubsystem), site) - val idOffset = overrideIdOffset.getOrElse(prev.size) + val idOffset = up(NumTiles) val med = RocketTileParams( core = RocketCoreParams(fpu = None), btb = None, @@ -141,20 +154,20 @@ class WithNMedCores( nTLBWays = 4, blockBytes = site(CacheBlockBytes)))) List.tabulate(n)(i => RocketTileAttachParams( - med.copy(hartId = i + idOffset), + med.copy(tileId = i + idOffset), crossing )) ++ prev } + case NumTiles => up(NumTiles) + n }) class WithNSmallCores( n: Int, - overrideIdOffset: Option[Int] = None, crossing: RocketCrossingParams = RocketCrossingParams() ) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => { val prev = up(TilesLocated(InSubsystem), site) - val idOffset = overrideIdOffset.getOrElse(prev.size) + val idOffset = up(NumTiles) val small = RocketTileParams( core = RocketCoreParams(useVM = false, fpu = None), btb = None, @@ -174,10 +187,11 @@ class WithNSmallCores( nTLBWays = 4, blockBytes = site(CacheBlockBytes)))) List.tabulate(n)(i => RocketTileAttachParams( - small.copy(hartId = i + idOffset), + small.copy(tileId = i + idOffset), crossing )) ++ prev } + case NumTiles => up(NumTiles) + n }) class With1TinyCore extends Config((site, here, up) => { @@ -210,13 +224,38 @@ class With1TinyCore extends Config((site, here, up) => { tiny, RocketCrossingParams( crossingType = SynchronousCrossing(), - master = TileMasterPortParams()) + master = HierarchicalElementMasterPortParams()) )) } + case NumTiles => 1 + case ClustersLocated(_) => Nil +}) + +class WithCluster( + clusterId: Int, + location: HierarchicalLocation = InSubsystem, + crossing: RocketCrossingParams = RocketCrossingParams() // TODO make this not rocket +) extends Config((site, here, up) => { + case ClustersLocated(`location`) => up(ClustersLocated(location)) :+ ClusterAttachParams( + ClusterParams(clusterId = clusterId), + crossing) + case TLNetworkTopologyLocated(InCluster(`clusterId`)) => List( + ClusterBusTopologyParams( + clusterId = clusterId, + csbus = site(SystemBusKey), + ccbus = site(ControlBusKey).copy(errorDevice = None), + coherence = site(ClusterBankedCoherenceKey(clusterId)) + ) + ) + case PossibleTileLocations => up(PossibleTileLocations) :+ InCluster(clusterId) +}) + +class WithClusterBanks(clusterId: Int, nBanks: Int = 1) extends Config((site, here, up) => { + case ClusterBankedCoherenceKey(`clusterId`) => up(ClusterBankedCoherenceKey(clusterId)).copy(nBanks=nBanks) }) class WithNBanks(n: Int) extends Config((site, here, up) => { - case BankedL2Key => up(BankedL2Key, site).copy(nBanks = n) + case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey, site).copy(nBanks = n) }) class WithNTrackersPerBank(n: Int) extends Config((site, here, up) => { @@ -225,7 +264,7 @@ class WithNTrackersPerBank(n: Int) extends Config((site, here, up) => { // This is the number of icache sets for all Rocket tiles class WithL1ICacheSets(sets: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( icache = tp.tileParams.icache.map(_.copy(nSets = sets)))) case t => t @@ -234,7 +273,7 @@ class WithL1ICacheSets(sets: Int) extends Config((site, here, up) => { // This is the number of icache sets for all Rocket tiles class WithL1DCacheSets(sets: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( dcache = tp.tileParams.dcache.map(_.copy(nSets = sets)))) case t => t @@ -242,7 +281,7 @@ class WithL1DCacheSets(sets: Int) extends Config((site, here, up) => { }) class WithL1ICacheWays(ways: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( icache = tp.tileParams.icache.map(_.copy(nWays = ways)))) case t => t @@ -250,7 +289,7 @@ class WithL1ICacheWays(ways: Int) extends Config((site, here, up) => { }) class WithL1DCacheWays(ways: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( dcache = tp.tileParams.dcache.map(_.copy(nWays = ways)))) case t => t @@ -288,22 +327,22 @@ class WithBufferlessBroadcastHub extends Config((site, here, up) => { * DO NOT use this configuration. */ class WithIncoherentTiles extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( master = tp.crossingParams.master match { - case x: TileMasterPortParams => x.copy(cork = Some(true)) + case x: HierarchicalElementMasterPortParams => x.copy(cork = Some(true)) case _ => throw new Exception("Unrecognized type for RocketCrossingParams.master") })) case t => t } - case BankedL2Key => up(BankedL2Key, site).copy( + case SubsystemBankedCoherenceKey => up(SubsystemBankedCoherenceKey, site).copy( coherenceManager = CoherenceManagerWrapper.incoherentManager ) }) class WithRV32 extends Config((site, here, up) => { case XLen => 32 - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy( fpu = tp.tileParams.core.fpu.map(_.copy(fLen = 32)), @@ -313,7 +352,7 @@ class WithRV32 extends Config((site, here, up) => { }) class WithFP16 extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy( fpu = tp.tileParams.core.fpu.map(_.copy(minFLen = 16)) @@ -324,7 +363,7 @@ class WithFP16 extends Config((site, here, up) => { }) class WithNonblockingL1(nMSHRs: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( dcache = tp.tileParams.dcache.map(_.copy(nMSHRs = nMSHRs)))) case t => t @@ -332,7 +371,7 @@ class WithNonblockingL1(nMSHRs: Int) extends Config((site, here, up) => { }) class WithNBreakpoints(hwbp: Int) extends Config ((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(nBreakpoints = hwbp))) case t => t @@ -340,7 +379,7 @@ class WithNBreakpoints(hwbp: Int) extends Config ((site, here, up) => { }) class WithHypervisor(hext: Boolean = true) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useHypervisor = hext))) case t => t @@ -368,7 +407,7 @@ class WithRoccExample extends Config((site, here, up) => { }) class WithDefaultBtb extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( btb = Some(BTBParams()))) case t => t @@ -376,7 +415,7 @@ class WithDefaultBtb extends Config((site, here, up) => { }) class WithFastMulDiv extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(mulDiv = Some( MulDivParams(mulUnroll = 8, mulEarlyOut = (site(XLen) > 32), divEarlyOut = true))))) @@ -385,7 +424,7 @@ class WithFastMulDiv extends Config((site, here, up) => { }) class WithoutMulDiv extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(mulDiv = None))) case t => t @@ -393,7 +432,7 @@ class WithoutMulDiv extends Config((site, here, up) => { }) class WithoutFPU extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(fpu = None))) case t => t @@ -401,45 +440,13 @@ class WithoutFPU extends Config((site, here, up) => { }) class WithFPUWithoutDivSqrt extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(fpu = tp.tileParams.core.fpu.map(_.copy(divSqrt = false))))) case t => t } }) -class WithBitManip extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(useBitManip = true))) - case t => t - } -}) - -class WithBitManipCrypto extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(useBitManipCrypto = true))) - case t => t - } -}) - -class WithCryptoNIST extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(useCryptoNIST = true))) - case t => t - } -}) - -class WithCryptoSM extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { - case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( - core = tp.tileParams.core.copy(useCryptoSM = true))) - case t => t - } -}) - class WithRocketDebugROB(enable: Boolean = true) extends Config((site, here, up) => { case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( @@ -473,7 +480,7 @@ class WithClockGateModel(file: String = "/vsrc/EICG_wrapper.v") extends Config(( }) class WithSynchronousRocketTiles extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( crossingType = SynchronousCrossing())) case t => t @@ -481,7 +488,7 @@ class WithSynchronousRocketTiles extends Config((site, here, up) => { }) class WithAsynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( crossingType = AsynchronousCrossing())) case t => t @@ -489,7 +496,7 @@ class WithAsynchronousRocketTiles(depth: Int, sync: Int) extends Config((site, h }) class WithRationalRocketTiles extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(crossingParams = tp.crossingParams.copy( crossingType = RationalCrossing())) case t => t @@ -499,7 +506,6 @@ class WithRationalRocketTiles extends Config((site, here, up) => { class WithEdgeDataBits(dataBits: Int) extends Config((site, here, up) => { case MemoryBusKey => up(MemoryBusKey, site).copy(beatBytes = dataBits/8) case ExtIn => up(ExtIn, site).map(_.copy(beatBytes = dataBits/8)) - }) class WithJtagDTM extends Config ((site, here, up) => { @@ -592,7 +598,7 @@ class WithScratchpadsBaseAddress(address: BigInt) extends Config((site, here, up }) class WithScratchpadsOnly extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => up(TilesLocated(InSubsystem), site) map { + case TilesLocated(location) => up(TilesLocated(location), site) map { case tp: RocketTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( core = tp.tileParams.core.copy(useVM = false), dcache = tp.tileParams.dcache.map(_.copy( @@ -651,16 +657,41 @@ class WithDontDriveBusClocksFromSBus extends Config((site, here, up) => { case DriveClocksFromSBus => false }) -class WithCloneRocketTiles(n: Int = 1, cloneHart: Int = 0, overrideIdOffset: Option[Int] = None) extends Config((site, here, up) => { - case TilesLocated(InSubsystem) => { - val prev = up(TilesLocated(InSubsystem), site) - val idOffset = overrideIdOffset.getOrElse(prev.size) - val tileAttachParams = prev(cloneHart).asInstanceOf[RocketTileAttachParams] +class WithCloneRocketTiles( + n: Int = 1, + cloneTileId: Int = 0, + location: HierarchicalLocation = InSubsystem, + cloneLocation: HierarchicalLocation = InSubsystem +) extends Config((site, here, up) => { + case TilesLocated(`location`) => { + val prev = up(TilesLocated(location), site) + val idOffset = up(NumTiles) + val tileAttachParams = up(TilesLocated(cloneLocation)).find(_.tileParams.tileId == cloneTileId) + .get.asInstanceOf[RocketTileAttachParams] (0 until n).map { i => - CloneTileAttachParams(cloneHart, tileAttachParams.copy( - tileParams = tileAttachParams.tileParams.copy(hartId = i + idOffset) + CloneTileAttachParams(cloneTileId, tileAttachParams.copy( + tileParams = tileAttachParams.tileParams.copy(tileId = i + idOffset) )) } ++ prev } + case NumTiles => up(NumTiles) + n }) +class WithCloneCluster( + clusterId: Int, + cloneClusterId: Int = 0, + location: HierarchicalLocation = InSubsystem, + cloneLocation: HierarchicalLocation = InSubsystem +) extends Config((site, here, up) => { + case ClustersLocated(`location`) => { + val prev = up(ClustersLocated(location)) + val clusterAttachParams = up(ClustersLocated(cloneLocation)).find(_.clusterParams.clusterId == cloneClusterId) + .get.asInstanceOf[ClusterAttachParams] + prev :+ CloneClusterAttachParams( + cloneClusterId, + clusterAttachParams.copy(clusterParams = clusterAttachParams.clusterParams.copy(clusterId = clusterId)) + ) + } + case TLNetworkTopologyLocated(InCluster(`clusterId`)) => site(TLNetworkTopologyLocated(InCluster(cloneClusterId))) + case PossibleTileLocations => up(PossibleTileLocations) :+ InCluster(clusterId) +}) diff --git a/src/main/scala/subsystem/HasHierarchicalElements.scala b/src/main/scala/subsystem/HasHierarchicalElements.scala new file mode 100644 index 0000000000..63f2ff14f1 --- /dev/null +++ b/src/main/scala/subsystem/HasHierarchicalElements.scala @@ -0,0 +1,234 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import chisel3._ +import chisel3.dontTouch +import org.chipsalliance.cde.config.{Field, Parameters} +import freechips.rocketchip.devices.debug.{TLDebugModule, HasPeripheryDebug} +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.tile._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.prci.{ClockGroup, ResetCrossingType, ClockGroupNode, ClockDomain} +import freechips.rocketchip.util._ +import freechips.rocketchip.rocket.{TracedInstruction} +import scala.collection.immutable.SortedMap + +/** A default implementation of parameterizing the connectivity of the port where the tile is the master. + * Optional timing buffers and/or an optional CacheCork can be inserted in the interconnect's clock domain. + */ +case class HierarchicalElementMasterPortParams( + buffers: Int = 0, + cork: Option[Boolean] = None, + where: TLBusWrapperLocation = SBUS +) extends HierarchicalElementPortParamsLike { + def injectNode(context: Attachable)(implicit p: Parameters): TLNode = { + (TLBuffer.chainNode(buffers) :=* cork.map { u => TLCacheCork(unsafe = u) } .getOrElse { TLTempNode() }) + } +} + +object HierarchicalElementMasterPortParams { + def locationDefault(loc: HierarchicalLocation) = loc match { + case InSubsystem => HierarchicalElementMasterPortParams() + case InCluster(clusterId) => HierarchicalElementMasterPortParams(where=CSBUS(clusterId)) + } +} + +/** A default implementation of parameterizing the connectivity of the port giving access to slaves inside the tile. + * Optional timing buffers and/or an optional BusBlocker adapter can be inserted in the interconnect's clock domain. + */ +case class HierarchicalElementSlavePortParams( + buffers: Int = 0, + blockerCtrlAddr: Option[BigInt] = None, + blockerCtrlWhere: TLBusWrapperLocation = CBUS, + where: TLBusWrapperLocation = CBUS +) extends HierarchicalElementPortParamsLike { + def injectNode(context: Attachable)(implicit p: Parameters): TLNode = { + val controlBus = context.locateTLBusWrapper(where) + val blockerBus = context.locateTLBusWrapper(blockerCtrlWhere) + blockerCtrlAddr + .map { BasicBusBlockerParams(_, blockerBus.beatBytes, controlBus.beatBytes) } + .map { bbbp => + val blocker = LazyModule(new BasicBusBlocker(bbbp)) + blockerBus.coupleTo("tile_slave_port_bus_blocker") { blocker.controlNode := TLFragmenter(blockerBus) := _ } + blocker.node :*= TLBuffer.chainNode(buffers) + } .getOrElse { TLBuffer.chainNode(buffers) } + } +} + +object HierarchicalElementSlavePortParams { + def locationDefault(loc: HierarchicalLocation) = loc match { + case InSubsystem => HierarchicalElementSlavePortParams() + case InCluster(clusterId) => HierarchicalElementSlavePortParams(where=CCBUS(clusterId), blockerCtrlWhere=CCBUS(clusterId)) + } +} + +/** InstantiatesTiles adds a Config-urable sequence of HierarchicalElements of any type + * to the subsystem class into which it is mixed. + */ +trait InstantiatesHierarchicalElements { this: LazyModule with Attachable => + val location: HierarchicalLocation + + /** Record the order in which to instantiate all tiles, based on statically-assigned ids. + * + * Note that these ids, which are often used as the tiles' default hartid input, + * may or may not be those actually reflected at runtime in e.g. the $mhartid CSR + */ + val tileAttachParams: Seq[CanAttachTile] = p(TilesLocated(location)).sortBy(_.tileParams.tileId) + val tileParams: Seq[TileParams] = tileAttachParams.map(_.tileParams) + val tileCrossingTypes: Seq[ClockCrossingType] = tileAttachParams.map(_.crossingParams.crossingType) + + /** The actual list of instantiated tiles in this block. */ + val tile_prci_domains: SortedMap[Int, TilePRCIDomain[_]] = tileAttachParams.foldLeft(SortedMap[Int, TilePRCIDomain[_]]()) { + case (instantiated, params) => instantiated + (params.tileParams.tileId -> params.instantiate(tileParams, instantiated)(p)) + } + + val clusterAttachParams: Seq[CanAttachCluster] = p(ClustersLocated(location)).sortBy(_.clusterParams.clusterId) + val clusterParams: Seq[ClusterParams] = clusterAttachParams.map(_.clusterParams) + val clusterCrossingTypes: Seq[ClockCrossingType] = clusterAttachParams.map(_.crossingParams.crossingType) + val cluster_prci_domains: SortedMap[Int, ClusterPRCIDomain] = clusterAttachParams.foldLeft(SortedMap[Int, ClusterPRCIDomain]()) { + case (instantiated, params) => instantiated + (params.clusterParams.clusterId -> params.instantiate(clusterParams, instantiated)(p)) + } + + val element_prci_domains: Seq[HierarchicalElementPRCIDomain[_]] = tile_prci_domains.values.toSeq ++ cluster_prci_domains.values.toSeq + + val leafTiles: SortedMap[Int, BaseTile] = SortedMap(tile_prci_domains.mapValues(_.element.asInstanceOf[BaseTile]).toSeq.sortBy(_._1):_*) + val totalTiles: SortedMap[Int, BaseTile] = (leafTiles ++ cluster_prci_domains.values.map(_.element.totalTiles).flatten) + + // Helper functions for accessing certain parameters that are popular to refer to in subsystem code + def nLeafTiles: Int = leafTiles.size + def nTotalTiles: Int = totalTiles.size + def leafTileIdList: Seq[Int] = leafTiles.keys.toSeq.sorted + def totalTileIdList: Seq[Int] = totalTiles.keys.toSeq.sorted + def localIntCounts: SortedMap[Int, Int] = totalTiles.mapValues(_.tileParams.core.nLocalInterrupts).to(SortedMap) + + require(totalTileIdList.distinct.size == totalTiles.size, s"Every tile must be statically assigned a unique id, but got:\n${totalTileIdList}") +} + +/** HasTiles instantiates and also connects a Config-urable sequence of tiles of any type to subsystem interconnect resources. */ +trait HasHierarchicalElements extends DefaultHierarchicalElementContextType +{ this: LazyModule with Attachable with InstantiatesHierarchicalElements => + implicit val p: Parameters + + // connect all the tiles to interconnect attachment points made available in this subsystem context + tileAttachParams.foreach { params => + params.connect(tile_prci_domains(params.tileParams.tileId).asInstanceOf[TilePRCIDomain[params.TileType]], this.asInstanceOf[params.TileContextType]) + } + clusterAttachParams.foreach { params => + params.connect(cluster_prci_domains(params.clusterParams.clusterId).asInstanceOf[ClusterPRCIDomain], this.asInstanceOf[params.ClusterContextType]) + } +} + +/** Provides some Chisel connectivity to certain tile IOs + * This trait is intended for the root subsystem + */ +trait HasHierarchicalElementsRootContextModuleImp extends LazyRawModuleImp { + val outer: InstantiatesHierarchicalElements with HasHierarchicalElements with HasHierarchicalElementsRootContext with HasTileInputConstants + + val reset_vector = outer.tileResetVectorIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"reset_vector_$i") } + val tile_hartids = outer.tileHartIdIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"tile_hartids_$i") } + + val meip = if (outer.meipIONode.isDefined) Some(IO(Input(Vec(outer.meipIONode.get.out.size, Bool())))) else None + meip.foreach { m => + m.zipWithIndex.foreach{ case (pin, i) => + (outer.meipIONode.get.out(i)._1)(0) := pin + } + } + val seip = if (outer.seipIONode.isDefined) Some(IO(Input(Vec(outer.seipIONode.get.out.size, Bool())))) else None + seip.foreach { s => + s.zipWithIndex.foreach{ case (pin, i) => + (outer.seipIONode.get.out(i)._1)(0) := pin + } + } + val nmi = outer.nmiIONodes.map { case (i, node) => + node.makeIO(s"nmi_$i") + } +} + +/** Most tile types require only these traits in order for their standardized connect functions to apply. + * + * BaseTiles subtypes with different needs can extend this trait to provide themselves with + * additional external connection points. + */ +trait DefaultHierarchicalElementContextType + extends Attachable + with HasTileNotificationSinks +{ this: LazyModule with Attachable => + def msipDomain: LazyScope + val msipNodes: SortedMap[Int, IntNode] + def meipDomain: LazyScope + val meipNodes: SortedMap[Int, IntNode] + def seipDomain: LazyScope + val seipNodes: SortedMap[Int, IntNode] + val tileToPlicNodes: SortedMap[Int, IntNode] + val debugNodes: SortedMap[Int, IntSyncNode] + val nmiNodes: SortedMap[Int, BundleBridgeNode[NMI]] + val tileHartIdNodes: SortedMap[Int, BundleBridgeNode[UInt]] + val tileResetVectorNodes: SortedMap[Int, BundleBridgeNode[UInt]] + val traceCoreNodes: SortedMap[Int, BundleBridgeNode[TraceCoreInterface]] + val traceNodes: SortedMap[Int, BundleBridgeNode[TraceBundle]] +} + +/** This trait provides the tile attachment context for the root (outermost) subsystem */ +trait HasHierarchicalElementsRootContext +{ this: HasHierarchicalElements + with HasTileNotificationSinks + with InstantiatesHierarchicalElements => + + val clintOpt: Option[CLINT] + val clintDomainOpt: Option[ClockDomain] + val plicOpt: Option[TLPLIC] + val plicDomainOpt: Option[ClockDomain] + val debugOpt: Option[TLDebugModule] + + def msipDomain = clintDomainOpt.getOrElse(this) + def meipDomain = plicDomainOpt.getOrElse(this) + def seipDomain = plicDomainOpt.getOrElse(this) + + val msipNodes: SortedMap[Int, IntNode] = (0 until nTotalTiles).map { i => + (i, IntEphemeralNode()) + }.to(SortedMap) + msipNodes.foreach { + _._2 := clintOpt.map(_.intnode).getOrElse(NullIntSource(sources = CLINTConsts.ints)) + } + + val meipIONode = Option.when(plicOpt.isEmpty)(IntNexusNode( + sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) }, + sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, + outputRequiresInput = false, + inputRequiresOutput = false)) + val meipNodes: SortedMap[Int, IntNode] = (0 until nTotalTiles).map { i => + (i, IntEphemeralNode() := plicOpt.map(_.intnode).getOrElse(meipIONode.get)) + }.to(SortedMap) + + val seipIONode = Option.when(plicOpt.isEmpty)(IntNexusNode( + sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) }, + sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, + outputRequiresInput = false, + inputRequiresOutput = false)) + val seipNodes: SortedMap[Int, IntNode] = totalTiles.filter { case (_, t) => t.tileParams.core.hasSupervisorMode } + .mapValues( _ => IntEphemeralNode() := plicOpt.map(_.intnode).getOrElse(seipIONode.get)).to(SortedMap) + + val tileToPlicNodes: SortedMap[Int, IntNode] = (0 until nTotalTiles).map { i => + plicOpt.map(o => (i, o.intnode :=* IntEphemeralNode())) + }.flatten.to(SortedMap) + + val debugNodes: SortedMap[Int, IntSyncNode] = (0 until nTotalTiles).map { i => + (i, IntSyncIdentityNode()) + }.to(SortedMap) + + debugNodes.foreach { case (hartid, node) => + node := debugOpt.map(_.intnode).getOrElse(NullIntSyncSource()) + } + + val nmiHarts = totalTiles.filter { case (_, t) => t.tileParams.core.useNMI }.keys + val nmiIONodes = nmiHarts.map { i => (i, BundleBridgeSource[NMI]()) }.to(SortedMap) + val nmiNodes: SortedMap[Int, BundleBridgeNode[NMI]] = nmiIONodes.map { case (i, n) => + (i, BundleBridgeEphemeralNode[NMI]() := n) + }.to(SortedMap) + + val traceCoreNodes: SortedMap[Int, BundleBridgeSink[TraceCoreInterface]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[TraceCoreInterface]()) }.to(SortedMap) + val traceNodes: SortedMap[Int, BundleBridgeSink[TraceBundle]] = (0 until nTotalTiles).map { i => (i, BundleBridgeSink[TraceBundle]()) }.to(SortedMap) +} diff --git a/src/main/scala/subsystem/HasTiles.scala b/src/main/scala/subsystem/HasTiles.scala index 5c65ed4cd8..ff06ccff4a 100644 --- a/src/main/scala/subsystem/HasTiles.scala +++ b/src/main/scala/subsystem/HasTiles.scala @@ -5,17 +5,26 @@ package freechips.rocketchip.subsystem import chisel3._ import chisel3.dontTouch import org.chipsalliance.cde.config.{Field, Parameters} -import freechips.rocketchip.devices.tilelink.{BasicBusBlocker, BasicBusBlockerParams, CLINTConsts, PLICKey, CanHavePeripheryPLIC, CanHavePeripheryCLINT} +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.devices.debug.{TLDebugModule} import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.tile._ import freechips.rocketchip.tilelink._ -import freechips.rocketchip.prci.{ClockGroup, ResetCrossingType, ClockGroupNode} +import freechips.rocketchip.prci._ import freechips.rocketchip.util._ +import freechips.rocketchip.rocket.{TracedInstruction} +import scala.collection.immutable.SortedMap /** Entry point for Config-uring the presence of Tiles */ case class TilesLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachTile]](Nil) +/** List of HierarchicalLocations which might contain a Tile */ +case object PossibleTileLocations extends Field[Seq[HierarchicalLocation]](Nil) + +/** For determining static tile id */ +case object NumTiles extends Field[Int](0) + /** Whether to add timing-closure registers along the path of the hart id * as it propagates through the subsystem and into the tile. * @@ -24,112 +33,17 @@ case class TilesLocated(loc: HierarchicalLocation) extends Field[Seq[CanAttachTi */ case object InsertTimingClosureRegistersOnHartIds extends Field[Boolean](false) -/** Whether per-tile hart ids are going to be driven as inputs into the subsystem, +/** Whether per-tile hart ids are going to be driven as inputs into a HasTiles block, * and if so, what their width should be. */ -case object SubsystemExternalHartIdWidthKey extends Field[Option[Int]](None) +case object HasTilesExternalHartIdWidthKey extends Field[Option[Int]](None) -/** Whether per-tile reset vectors are going to be driven as inputs into the subsystem. +/** Whether per-tile reset vectors are going to be driven as inputs into a HasTiles block. * * Unlike the hart ids, the reset vector width is determined by the sinks within the tiles, * based on the size of the address map visible to the tiles. */ -case object SubsystemExternalResetVectorKey extends Field[Boolean](true) - -/** An interface for describing the parameteization of how Tiles are connected to interconnects */ -trait TileCrossingParamsLike { - /** The type of clock crossing that should be inserted at the tile boundary. */ - def crossingType: ClockCrossingType - /** Parameters describing the contents and behavior of the point where the tile is attached as an interconnect master. */ - def master: TilePortParamsLike - /** Parameters describing the contents and behavior of the point where the tile is attached as an interconnect slave. */ - def slave: TilePortParamsLike - /** The subnetwork location of the device selecting the apparent base address of MMIO devices inside the tile */ - def mmioBaseAddressPrefixWhere: TLBusWrapperLocation - /** Inject a reset management subgraph that effects the tile child reset only */ - def resetCrossingType: ResetCrossingType - /** Keep the tile clock separate from the interconnect clock (e.g. even if they are synchronous to one another) */ - def forceSeparateClockReset: Boolean -} - -/** An interface for describing the parameterization of how a particular tile port is connected to an interconnect */ -trait TilePortParamsLike { - /** The subnetwork location of the interconnect to which this tile port should be connected. */ - def where: TLBusWrapperLocation - /** Allows port-specific adapters to be injected into the interconnect side of the attachment point. */ - def injectNode(context: Attachable)(implicit p: Parameters): TLNode -} - -/** A default implementation of parameterizing the connectivity of the port where the tile is the master. - * Optional timing buffers and/or an optional CacheCork can be inserted in the interconnect's clock domain. - */ -case class TileMasterPortParams( - buffers: Int = 0, - cork: Option[Boolean] = None, - where: TLBusWrapperLocation = SBUS -) extends TilePortParamsLike { - def injectNode(context: Attachable)(implicit p: Parameters): TLNode = { - (TLBuffer.chainNode(buffers) :=* cork.map { u => TLCacheCork(unsafe = u) } .getOrElse { TLTempNode() }) - } -} - -/** A default implementation of parameterizing the connectivity of the port giving access to slaves inside the tile. - * Optional timing buffers and/or an optional BusBlocker adapter can be inserted in the interconnect's clock domain. - */ -case class TileSlavePortParams( - buffers: Int = 0, - blockerCtrlAddr: Option[BigInt] = None, - blockerCtrlWhere: TLBusWrapperLocation = CBUS, - where: TLBusWrapperLocation = CBUS -) extends TilePortParamsLike { - def injectNode(context: Attachable)(implicit p: Parameters): TLNode = { - val controlBus = context.locateTLBusWrapper(where) - val blockerBus = context.locateTLBusWrapper(blockerCtrlWhere) - blockerCtrlAddr - .map { BasicBusBlockerParams(_, blockerBus.beatBytes, controlBus.beatBytes) } - .map { bbbp => - val blocker = LazyModule(new BasicBusBlocker(bbbp)) - blockerBus.coupleTo("tile_slave_port_bus_blocker") { blocker.controlNode := TLFragmenter(blockerBus) := _ } - blocker.node :*= TLBuffer.chainNode(buffers) - } .getOrElse { TLBuffer.chainNode(buffers) } - } -} - -/** These are sources of interrupts that are driven into the tile. - * They need to be instantiated before tiles are attached to the subsystem containing them. - */ -trait HasTileInterruptSources - extends CanHavePeripheryPLIC - with CanHavePeripheryCLINT - with InstantiatesTiles -{ this: BaseSubsystem => // TODO ideally this bound would be softened to LazyModule - /** meipNode is used to create a single bit subsystem input in Configs without a PLIC */ - val meipNode = p(PLICKey) match { - case Some(_) => None - case None => Some(IntNexusNode( - sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) }, - sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, - outputRequiresInput = false, - inputRequiresOutput = false)) - } - val seipNode = p(PLICKey) match { - case Some(_) => None - case None => Some(IntNexusNode( - sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(1))) }, - sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, - outputRequiresInput = false, - inputRequiresOutput = false)) - } - /** Source of Non-maskable Interrupt (NMI) input bundle to each tile. */ - val tileNMINode = BundleBridgeEphemeralNode[NMI]() - val tileNMIIONodes: Seq[BundleBridgeSource[NMI]] = { - Seq.fill(tiles.size) { - val nmiSource = BundleBridgeSource[NMI]() - tileNMINode := nmiSource - nmiSource - } - } -} +case object HasTilesExternalResetVectorKey extends Field[Boolean](true) /** These are sources of "constants" that are driven into the tile. * @@ -137,9 +51,11 @@ trait HasTileInterruptSources * they may be either tied to a contant value or programmed during boot or reset. * They need to be instantiated before tiles are attached within the subsystem containing them. */ -trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem => +trait HasTileInputConstants { this: LazyModule with Attachable with InstantiatesHierarchicalElements => /** tileHartIdNode is used to collect publishers and subscribers of hartids. */ - val tileHartIdNode = BundleBridgeEphemeralNode[UInt]() + val tileHartIdNodes: SortedMap[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i => + (i, BundleBridgeEphemeralNode[UInt]()) + }.to(SortedMap) /** tileHartIdNexusNode is a BundleBridgeNexus that collects dynamic hart prefixes. * @@ -156,7 +72,7 @@ trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem => val tileHartIdNexusNode = LazyModule(new BundleBridgeNexus[UInt]( inputFn = BundleBridgeNexus.orReduction[UInt](registered = p(InsertTimingClosureRegistersOnHartIds)) _, outputFn = (prefix: UInt, n: Int) => Seq.tabulate(n) { i => - val y = dontTouch(prefix | hartIdList(i).U(p(MaxHartIdBits).W)) // dontTouch to keep constant prop from breaking tile dedup + val y = dontTouch(prefix | totalTileIdList(i).U(p(MaxHartIdBits).W)) // dontTouch to keep constant prop from breaking tile dedup if (p(InsertTimingClosureRegistersOnHartIds)) BundleBridgeNexus.safeRegNext(y) else y }, default = Some(() => 0.U(p(MaxHartIdBits).W)), @@ -166,7 +82,9 @@ trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem => // TODO: Replace the DebugModuleHartSelFuncs config key with logic to consume the dynamic hart IDs /** tileResetVectorNode is used to collect publishers and subscribers of tile reset vector addresses. */ - val tileResetVectorNode = BundleBridgeEphemeralNode[UInt]() + val tileResetVectorNodes: SortedMap[Int, BundleBridgeEphemeralNode[UInt]] = (0 until nTotalTiles).map { i => + (i, BundleBridgeEphemeralNode[UInt]()) + }.to(SortedMap) /** tileResetVectorNexusNode is a BundleBridgeNexus that accepts a single reset vector source, and broadcasts it to all tiles. */ val tileResetVectorNexusNode = BundleBroadcast[UInt]( @@ -177,26 +95,32 @@ trait HasTileInputConstants extends InstantiatesTiles { this: BaseSubsystem => * * Or, if such IOs are not configured to exist, tileHartIdNexusNode is used to supply an id to each tile. */ - val tileHartIdIONodes: Seq[BundleBridgeSource[UInt]] = p(SubsystemExternalHartIdWidthKey) match { - case Some(w) => Seq.fill(tiles.size) { + val tileHartIdIONodes: Seq[BundleBridgeSource[UInt]] = p(HasTilesExternalHartIdWidthKey) match { + case Some(w) => (0 until nTotalTiles).map { i => val hartIdSource = BundleBridgeSource(() => UInt(w.W)) - tileHartIdNode := hartIdSource + tileHartIdNodes(i) := hartIdSource hartIdSource } - case None => { tileHartIdNode :*= tileHartIdNexusNode; Nil } + case None => { + (0 until nTotalTiles).map { i => tileHartIdNodes(i) :*= tileHartIdNexusNode } + Nil + } } /** tileResetVectorIONodes may generate subsystem IOs, one per tile, allowing the parent to assign unique reset vectors. * * Or, if such IOs are not configured to exist, tileResetVectorNexusNode is used to supply a single reset vector to every tile. */ - val tileResetVectorIONodes: Seq[BundleBridgeSource[UInt]] = p(SubsystemExternalResetVectorKey) match { - case true => Seq.fill(tiles.size) { + val tileResetVectorIONodes: Seq[BundleBridgeSource[UInt]] = p(HasTilesExternalResetVectorKey) match { + case true => (0 until nTotalTiles).map { i => val resetVectorSource = BundleBridgeSource[UInt]() - tileResetVectorNode := resetVectorSource + tileResetVectorNodes(i) := resetVectorSource resetVectorSource } - case false => { tileResetVectorNode :*= tileResetVectorNexusNode; Nil } + case false => { + (0 until nTotalTiles).map { i => tileResetVectorNodes(i) :*= tileResetVectorNexusNode } + Nil + } } } @@ -218,20 +142,6 @@ trait HasTileNotificationSinks { this: LazyModule => tileCeaseSinkNode := tileCeaseXbarNode } -/** Most tile types require only these traits in order for their standardized connect functions to apply. - * - * BaseTiles subtypes with different needs can extend this trait to provide themselves with - * additional external connection points. - */ -trait DefaultTileContextType - extends Attachable - with HasTileInterruptSources - with HasTileNotificationSinks - with HasTileInputConstants -{ this: BaseSubsystem => - val debugNode: IntSyncOutwardNode -} // TODO: ideally this bound would be softened to LazyModule - /** Standardized interface by which parameterized tiles can be attached to contexts containing interconnect resources. * * Sub-classes of this trait can optionally override the individual connect functions in order to specialize @@ -240,15 +150,15 @@ trait DefaultTileContextType */ trait CanAttachTile { type TileType <: BaseTile - type TileContextType <: DefaultTileContextType + type TileContextType <: DefaultHierarchicalElementContextType def tileParams: InstantiableTileParams[TileType] - def crossingParams: TileCrossingParamsLike + def crossingParams: HierarchicalElementCrossingParamsLike /** Narrow waist through which all tiles are intended to pass while being instantiated. */ - def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: Seq[TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { - val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(s"${tileParams.name.getOrElse("core")}_${tileParams.hartId}")) + def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: SortedMap[Int, TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { + val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(tileParams.uniqueName)) val tile_prci_domain = LazyModule(new TilePRCIDomain[TileType](clockSinkParams, crossingParams) { self => - val tile = self.tile_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) } + val element = self.element_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) } }) tile_prci_domain } @@ -261,13 +171,14 @@ trait CanAttachTile { connectPRC(domain, context) connectOutputNotifications(domain, context) connectInputConstants(domain, context) + connectTrace(domain, context) } /** Connect the port where the tile is the master to a TileLink interconnect. */ def connectMasterPorts(domain: TilePRCIDomain[TileType], context: Attachable): Unit = { implicit val p = context.p val dataBus = context.locateTLBusWrapper(crossingParams.master.where) - dataBus.coupleFrom(tileParams.name.getOrElse("tile")) { bus => + dataBus.coupleFrom(tileParams.baseName) { bus => bus :=* crossingParams.master.injectNode(context) :=* domain.crossMasterPort(crossingParams.crossingType) } } @@ -277,7 +188,7 @@ trait CanAttachTile { implicit val p = context.p DisableMonitors { implicit p => val controlBus = context.locateTLBusWrapper(crossingParams.slave.where) - controlBus.coupleTo(tileParams.name.getOrElse("tile")) { bus => + controlBus.coupleTo(tileParams.baseName) { bus => domain.crossSlavePort(crossingParams.crossingType) :*= crossingParams.slave.injectNode(context) :*= TLWidthWidget(controlBus.beatBytes) :*= bus } } @@ -291,61 +202,66 @@ trait CanAttachTile { // we stub out missing interrupts with constant sources here. // 1. Debug interrupt is definitely asynchronous in all cases. - domain.tile.intInwardNode := domain { IntSyncAsyncCrossingSink(3) } := context.debugNode + domain.element.intInwardNode := domain { IntSyncAsyncCrossingSink(3) } := + context.debugNodes(domain.element.tileId) - // 2. The CLINT and PLIC output interrupts are synchronous to the TileLink bus clock, + // 2. The CLINT and PLIC output interrupts are synchronous to the CLINT/PLIC respectively, // so might need to be synchronized depending on the Tile's crossing type. // From CLINT: "msip" and "mtip" - domain.crossIntIn(crossingParams.crossingType) := - context.clintOpt.map { _.intnode } - .getOrElse { NullIntSource(sources = CLINTConsts.ints) } + context.msipDomain { + domain.crossIntIn(crossingParams.crossingType, domain.element.intInwardNode) := + context.msipNodes(domain.element.tileId) + } // From PLIC: "meip" - domain.crossIntIn(crossingParams.crossingType) := - context.plicOpt .map { _.intnode } - .getOrElse { context.meipNode.get } + context.meipDomain { + domain.crossIntIn(crossingParams.crossingType, domain.element.intInwardNode) := + context.meipNodes(domain.element.tileId) + } // From PLIC: "seip" (only if supervisor mode is enabled) - if (domain.tile.tileParams.core.hasSupervisorMode) { - domain.crossIntIn(crossingParams.crossingType) := - context.plicOpt .map { _.intnode } - .getOrElse { context.seipNode.get } + if (domain.element.tileParams.core.hasSupervisorMode) { + context.seipDomain { + domain.crossIntIn(crossingParams.crossingType, domain.element.intInwardNode) := + context.seipNodes(domain.element.tileId) + } } // 3. Local Interrupts ("lip") are required to already be synchronous to the Tile's clock. - // (they are connected to domain.tile.intInwardNode in a seperate trait) + // (they are connected to domain.element.intInwardNode in a seperate trait) // 4. Interrupts coming out of the tile are sent to the PLIC, // so might need to be synchronized depending on the Tile's crossing type. - context.plicOpt.foreach { plic => - FlipRendering { implicit p => - plic.intnode :=* domain.crossIntOut(crossingParams.crossingType, domain.tile.intOutwardNode) - } + context.tileToPlicNodes.get(domain.element.tileId).foreach { node => + FlipRendering { implicit p => domain.element.intOutwardNode.foreach { out => + node :*= domain.crossIntOut(crossingParams.crossingType, out) + }} } // 5. Connect NMI inputs to the tile. These inputs are synchronous to the respective core_clock. - domain.tile.nmiNode := context.tileNMINode + domain.element.nmiNode.foreach(_ := context.nmiNodes(domain.element.tileId)) } /** Notifications of tile status are connected to be broadcast without needing to be clock-crossed. */ def connectOutputNotifications(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = { implicit val p = context.p - context.tileHaltXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.haltNode) - context.tileWFIXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.wfiNode) - context.tileCeaseXbarNode :=* domain.crossIntOut(NoCrossing, domain.tile.ceaseNode) + domain { + context.tileHaltXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.haltNode) + context.tileWFIXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.wfiNode) + context.tileCeaseXbarNode :=* domain.crossIntOut(NoCrossing, domain.element.ceaseNode) + } // TODO should context be forced to have a trace sink connected here? // for now this just ensures domain.trace[Core]Node has been crossed without connecting it externally - domain.crossTracesOut() } /** Connect inputs to the tile that are assumed to be constant during normal operation, and so are not clock-crossed. */ def connectInputConstants(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = { implicit val p = context.p val tlBusToGetPrefixFrom = context.locateTLBusWrapper(crossingParams.mmioBaseAddressPrefixWhere) - domain.tile.hartIdNode := context.tileHartIdNode - domain.tile.resetVectorNode := context.tileResetVectorNode - tlBusToGetPrefixFrom.prefixNode.foreach { domain.tile.mmioAddressPrefixNode := _ } + domain.element.hartIdNode := context.tileHartIdNodes(domain.element.tileId) + domain.element.resetVectorNode := context.tileResetVectorNodes(domain.element.tileId) + tlBusToGetPrefixFrom.prefixNode.foreach { domain.element.mmioAddressPrefixNode := _ } } /** Connect power/reset/clock resources. */ @@ -362,19 +278,30 @@ trait CanAttachTile { case _: RationalCrossing => domain.clockNode := tlBusToGetClockDriverFrom.clockNode case _: AsynchronousCrossing => { val tileClockGroup = ClockGroup() - tileClockGroup := context.asyncClockGroupsNode + tileClockGroup := context.allClockGroupsNode domain.clockNode := tileClockGroup } }) domain { - domain.tile_reset_domain.clockNode := crossingParams.resetCrossingType.injectClockNode := domain.clockNode + domain.element_reset_domain.clockNode := crossingParams.resetCrossingType.injectClockNode := domain.clockNode } } + + /** Function to handle all trace crossings when tile is instantiated inside domains */ + def connectTrace(domain: TilePRCIDomain[TileType], context: TileContextType): Unit = { + implicit val p = context.p + val traceCrossingNode = BundleBridgeBlockDuringReset[TraceBundle]( + resetCrossingType = crossingParams.resetCrossingType) + context.traceNodes(domain.element.tileId) := traceCrossingNode := domain.element.traceNode + val traceCoreCrossingNode = BundleBridgeBlockDuringReset[TraceCoreInterface]( + resetCrossingType = crossingParams.resetCrossingType) + context.traceCoreNodes(domain.element.tileId) :*= traceCoreCrossingNode := domain.element.traceCoreNode + } } case class CloneTileAttachParams( - sourceHart: Int, + sourceTileId: Int, cloneParams: CanAttachTile ) extends CanAttachTile { type TileType = cloneParams.TileType @@ -382,78 +309,18 @@ case class CloneTileAttachParams( def tileParams = cloneParams.tileParams def crossingParams = cloneParams.crossingParams - require(sourceHart < tileParams.hartId) - override def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: Seq[TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { - val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(s"${tileParams.name.getOrElse("core")}_${tileParams.hartId}")) + override def instantiate(allTileParams: Seq[TileParams], instantiatedTiles: SortedMap[Int, TilePRCIDomain[_]])(implicit p: Parameters): TilePRCIDomain[TileType] = { + require(instantiatedTiles.contains(sourceTileId)) + val clockSinkParams = tileParams.clockSinkParams.copy(name = Some(tileParams.uniqueName)) val tile_prci_domain = CloneLazyModule( new TilePRCIDomain[TileType](clockSinkParams, crossingParams) { self => - val tile = self.tile_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) } + val element = self.element_reset_domain { LazyModule(tileParams.instantiate(crossingParams, PriorityMuxHartIdFromSeq(allTileParams))) } }, - instantiatedTiles(sourceHart).asInstanceOf[TilePRCIDomain[TileType]] + instantiatedTiles(sourceTileId).asInstanceOf[TilePRCIDomain[TileType]] ) - tile_prci_domain - } -} - - -/** InstantiatesTiles adds a Config-urable sequence of tiles of any type - * to the subsystem class into which it is mixed. - */ -trait InstantiatesTiles { this: BaseSubsystem => - /** Record the order in which to instantiate all tiles, based on statically-assigned ids. - * - * Note that these ids, which are often used as the tiles' default hartid input, - * may or may not be those actually reflected at runtime in e.g. the $mhartid CSR - */ - val tileAttachParams: Seq[CanAttachTile] = p(TilesLocated(location)).sortBy(_.tileParams.hartId) - val tileParams: Seq[TileParams] = tileAttachParams.map(_.tileParams) - val tileCrossingTypes: Seq[ClockCrossingType] = tileAttachParams.map(_.crossingParams.crossingType) - - /** The actual list of instantiated tiles in this subsystem. */ - val tile_prci_domains: Seq[TilePRCIDomain[_]] = tileAttachParams.foldLeft(Seq[TilePRCIDomain[_]]()) { - case (instantiated, params) => instantiated :+ params.instantiate(tileParams, instantiated)(p) - } - - val tiles: Seq[BaseTile] = tile_prci_domains.map(_.tile.asInstanceOf[BaseTile]) - - // Helper functions for accessing certain parameters that are popular to refer to in subsystem code - def nTiles: Int = tileAttachParams.size - def hartIdList: Seq[Int] = tileParams.map(_.hartId) - def localIntCounts: Seq[Int] = tileParams.map(_.core.nLocalInterrupts) - - require(hartIdList.distinct.size == tiles.size, s"Every tile must be statically assigned a unique id, but got:\n${hartIdList}") -} - -/** HasTiles instantiates and also connects a Config-urable sequence of tiles of any type to subsystem interconnect resources. */ -trait HasTiles extends InstantiatesTiles with HasCoreMonitorBundles with DefaultTileContextType -{ this: BaseSubsystem => // TODO: ideally this bound would be softened to Attachable - implicit val p: Parameters - - // connect all the tiles to interconnect attachment points made available in this subsystem context - tileAttachParams.zip(tile_prci_domains).foreach { case (params, td) => - params.connect(td.asInstanceOf[TilePRCIDomain[params.TileType]], this.asInstanceOf[params.TileContextType]) + tile_prci_domain } } -/** Provides some Chisel connectivity to certain tile IOs */ -trait HasTilesModuleImp extends LazyModuleImp { - val outer: HasTiles with HasTileInterruptSources with HasTileInputConstants - - val reset_vector = outer.tileResetVectorIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"reset_vector_$i") } - val tile_hartids = outer.tileHartIdIONodes.zipWithIndex.map { case (n, i) => n.makeIO(s"tile_hartids_$i") } - val meip = if(outer.meipNode.isDefined) Some(IO(Input(Vec(outer.meipNode.get.out.size, Bool())))) else None - meip.foreach { m => - m.zipWithIndex.foreach{ case (pin, i) => - (outer.meipNode.get.out(i)._1)(0) := pin - } - } - val seip = if(outer.seipNode.isDefined) Some(IO(Input(Vec(outer.seipNode.get.out.size, Bool())))) else None - seip.foreach { s => - s.zipWithIndex.foreach{ case (pin, i) => - (outer.seipNode.get.out(i)._1)(0) := pin - } - } - val nmi = outer.tiles.zip(outer.tileNMIIONodes).zipWithIndex.map { case ((tile, n), i) => tile.tileParams.core.useNMI.option(n.makeIO(s"nmi_$i")) } -} diff --git a/src/main/scala/subsystem/HierarchicalElement.scala b/src/main/scala/subsystem/HierarchicalElement.scala new file mode 100644 index 0000000000..18a7c189f3 --- /dev/null +++ b/src/main/scala/subsystem/HierarchicalElement.scala @@ -0,0 +1,83 @@ +package freechips.rocketchip.subsystem + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config.Parameters +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.prci._ +import freechips.rocketchip.tile.{LookupByHartIdImpl, TraceBundle} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.util._ +import freechips.rocketchip.devices.debug.{TLDebugModule} +import freechips.rocketchip.devices.tilelink._ + +trait HierarchicalElementParams { + val baseName: String // duplicated instances shouuld share a base name + val uniqueName: String + val clockSinkParams: ClockSinkParameters +} + +abstract class InstantiableHierarchicalElementParams[ElementType <: BaseHierarchicalElement] extends HierarchicalElementParams + +/** An interface for describing the parameteization of how HierarchicalElements are connected to interconnects */ +trait HierarchicalElementCrossingParamsLike { + /** The type of clock crossing that should be inserted at the element boundary. */ + def crossingType: ClockCrossingType + /** Parameters describing the contents and behavior of the point where the element is attached as an interconnect master. */ + def master: HierarchicalElementPortParamsLike + /** Parameters describing the contents and behavior of the point where the element is attached as an interconnect slave. */ + def slave: HierarchicalElementPortParamsLike + /** The subnetwork location of the device selecting the apparent base address of MMIO devices inside the element */ + def mmioBaseAddressPrefixWhere: TLBusWrapperLocation + /** Inject a reset management subgraph that effects the element child reset only */ + def resetCrossingType: ResetCrossingType + /** Keep the element clock separate from the interconnect clock (e.g. even if they are synchronous to one another) */ + def forceSeparateClockReset: Boolean +} + +/** An interface for describing the parameterization of how a particular element port is connected to an interconnect */ +trait HierarchicalElementPortParamsLike { + /** The subnetwork location of the interconnect to which this element port should be connected. */ + def where: TLBusWrapperLocation + /** Allows port-specific adapters to be injected into the interconnect side of the attachment point. */ + def injectNode(context: Attachable)(implicit p: Parameters): TLNode +} + +abstract class BaseHierarchicalElement (val crossing: ClockCrossingType)(implicit p: Parameters) + extends LazyModule()(p) + with CrossesToOnlyOneClockDomain +{ + def module: BaseHierarchicalElementModuleImp[BaseHierarchicalElement] + + protected val tlOtherMastersNode = TLIdentityNode() + protected val tlMasterXbar = LazyModule(new TLXbar) + protected val tlSlaveXbar = LazyModule(new TLXbar) + protected val intXbar = LazyModule(new IntXbar) + + def masterNode: TLOutwardNode + def slaveNode: TLInwardNode + + /** Helper function to insert additional buffers on master ports at the boundary of the tile. + * + * The boundary buffering needed to cut feed-through paths is + * microarchitecture specific, so this may need to be overridden + * in subclasses of this class. + */ + def makeMasterBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none) + + /** Helper function to insert additional buffers on slave ports at the boundary of the tile. + * + * The boundary buffering needed to cut feed-through paths is + * microarchitecture specific, so this may need to be overridden + * in subclasses of this class. + */ + def makeSlaveBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none) + + +} + +abstract class BaseHierarchicalElementModuleImp[+L <: BaseHierarchicalElement](val outer: L) extends LazyModuleImp(outer) + diff --git a/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala b/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala new file mode 100644 index 0000000000..a76b7c4340 --- /dev/null +++ b/src/main/scala/subsystem/HierarchicalElementPRCIDomain.scala @@ -0,0 +1,96 @@ +package freechips.rocketchip.subsystem + +import chisel3._ +import chisel3.util._ + +import org.chipsalliance.cde.config.Parameters +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.interrupts._ +import freechips.rocketchip.prci._ +import freechips.rocketchip.tile.{RocketTile, TraceBundle} +import freechips.rocketchip.subsystem._ +import freechips.rocketchip.tilelink._ +import freechips.rocketchip.devices.debug.{TLDebugModule} +import freechips.rocketchip.devices.tilelink._ +import freechips.rocketchip.util.{TraceCoreInterface} + + +/** A wrapper containing all logic within a managed reset domain for a element. + * + * This does not add a layer of the module hierarchy. + */ +class HierarchicalElementResetDomain(clockSinkParams: ClockSinkParameters, resetCrossingType: ResetCrossingType) + (implicit p: Parameters) + extends ResetDomain + with CrossesToOnlyOneResetDomain +{ + def crossing = resetCrossingType + val clockNode = ClockSinkNode(Seq(clockSinkParams)) + def clockBundle = clockNode.in.head._1 + override def shouldBeInlined = true +} + +/** A wrapper containing all logic necessary to safely place a tile + * inside of a particular Power/Reset/Clock/Interrupt domain. + * + * This adds a layer to the module hierarchy which is a parent of the tile + * and should contain all logic related to clock crossings, isolation cells, + * hierarchical P&R boundary buffers, core-local interrupt handling, + * and any other IOs related to PRCI control. + */ +abstract class HierarchicalElementPRCIDomain[T <: BaseHierarchicalElement]( + clockSinkParams: ClockSinkParameters, + crossingParams: HierarchicalElementCrossingParamsLike) + (implicit p: Parameters) + extends ClockDomain +{ + val element: T + val element_reset_domain = LazyModule(new HierarchicalElementResetDomain(clockSinkParams, crossingParams.resetCrossingType)) + val tapClockNode = ClockIdentityNode() + val clockNode = FixedClockBroadcast() :=* tapClockNode + lazy val clockBundle = tapClockNode.in.head._1 + + /** External code looking to connect and clock-cross the interrupts driven into this tile can call this. */ + def crossIntIn(crossingType: ClockCrossingType, tileNode: IntInwardNode): IntInwardNode = { + // Unlike the other crossing helpers, here nothing is is blocked during reset because we know these are inputs and assume that tile reset is longer than uncore reset + val intInClockXing = this.crossIn(tileNode) + intInClockXing(crossingType) + } + + /** External code looking to connect and clock/reset-cross + * - interrupts raised by devices inside this tile + * - notifications raise by the cores and caches + * can call this function to instantiate the required crossing hardware. + * Takes crossingType as an argument because some interrupts are supposed to be synchronous + * Takes tileNode as an argument because tiles might have multiple outbound interrupt nodes + */ + def crossIntOut(crossingType: ClockCrossingType, tileNode: IntOutwardNode): IntOutwardNode = { + val intOutResetXing = this { element_reset_domain.crossIntOut(tileNode) } + val intOutClockXing = this.crossOut(intOutResetXing) + intOutClockXing(crossingType) + } + + /** External code looking to connect the ports where this tile is slaved to an interconnect + * (while also crossing clock domains) can call this. + */ + def crossSlavePort(crossingType: ClockCrossingType): TLInwardNode = { DisableMonitors { implicit p => FlipRendering { implicit p => + val tlSlaveResetXing = this { + element_reset_domain.crossTLIn(element.slaveNode) :*= + element { element.makeSlaveBoundaryBuffers(crossingType) } + } + val tlSlaveClockXing = this.crossIn(tlSlaveResetXing) + tlSlaveClockXing(crossingType) + } } } + + /** External code looking to connect the ports where this tile masters an interconnect + * (while also crossing clock domains) can call this. + */ + def crossMasterPort(crossingType: ClockCrossingType): TLOutwardNode = { + val tlMasterResetXing = this { DisableMonitors { implicit p => + element { element.makeMasterBoundaryBuffers(crossingType) } :=* + element_reset_domain.crossTLOut(element.masterNode) + } } + val tlMasterClockXing = this.crossOut(tlMasterResetXing) + tlMasterClockXing(crossingType) + } +} diff --git a/src/main/scala/subsystem/InterruptBus.scala b/src/main/scala/subsystem/InterruptBus.scala index e50f82a9ad..2815e3f086 100644 --- a/src/main/scala/subsystem/InterruptBus.scala +++ b/src/main/scala/subsystem/InterruptBus.scala @@ -45,7 +45,7 @@ abstract trait HasExtInterrupts { this: BaseSubsystem => */ trait HasAsyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem => if (nExtInterrupts > 0) { - ibus.fromAsync := extInterrupts + ibus { ibus.fromAsync := extInterrupts } } } @@ -54,7 +54,7 @@ trait HasAsyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem => */ trait HasSyncExtInterrupts extends HasExtInterrupts { this: BaseSubsystem => if (nExtInterrupts > 0) { - ibus.fromSync := extInterrupts + ibus { ibus.fromSync := extInterrupts } } } @@ -70,7 +70,7 @@ trait HasExtInterruptsBundle { /** This trait performs the translation from a UInt IO into Diplomatic Interrupts. * The wiring must be done in the concrete LazyModuleImp. */ -trait HasExtInterruptsModuleImp extends LazyModuleImp with HasExtInterruptsBundle { +trait HasExtInterruptsModuleImp extends LazyRawModuleImp with HasExtInterruptsBundle { val outer: HasExtInterrupts val interrupts = IO(Input(UInt(outer.nExtInterrupts.W))) diff --git a/src/main/scala/subsystem/LookupByClusterId.scala b/src/main/scala/subsystem/LookupByClusterId.scala new file mode 100644 index 0000000000..d0c5c21a5a --- /dev/null +++ b/src/main/scala/subsystem/LookupByClusterId.scala @@ -0,0 +1,19 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.subsystem + +import chisel3._ +import chisel3.util._ + +abstract class LookupByClusterIdImpl { + def apply[T <: Data](f: ClusterParams => Option[T], clusterId: UInt): T +} + +case class ClustersWontDeduplicate(t: ClusterParams) extends LookupByClusterIdImpl { + def apply[T <: Data](f: ClusterParams => Option[T], clusterId: UInt): T = f(t).get +} + +case class PriorityMuxClusterIdFromSeq(seq: Seq[ClusterParams]) extends LookupByClusterIdImpl { + def apply[T <: Data](f: ClusterParams => Option[T], clusterId: UInt): T = + PriorityMux(seq.collect { case t if f(t).isDefined => (t.clusterId.U === clusterId) -> f(t).get }) +} diff --git a/src/main/scala/subsystem/RTC.scala b/src/main/scala/subsystem/RTC.scala index 499633f679..2c67d45357 100644 --- a/src/main/scala/subsystem/RTC.scala +++ b/src/main/scala/subsystem/RTC.scala @@ -4,26 +4,28 @@ package freechips.rocketchip.subsystem import chisel3._ import chisel3.util.Counter -import freechips.rocketchip.diplomacy.{LazyModuleImp, DTSTimebase} -import freechips.rocketchip.devices.tilelink.CanHavePeripheryCLINT +import freechips.rocketchip.diplomacy.{LazyRawModuleImp, DTSTimebase} +import freechips.rocketchip.devices.tilelink.{CLINTAttachKey, CanHavePeripheryCLINT} -trait HasRTCModuleImp extends LazyModuleImp { +trait HasRTCModuleImp extends LazyRawModuleImp { val outer: BaseSubsystem with CanHavePeripheryCLINT - private val pbusFreq = outer.p(PeripheryBusKey).dtsFrequency.get - private val rtcFreq = outer.p(DTSTimebase) - private val internalPeriod: BigInt = pbusFreq / rtcFreq - - val pbus = outer.locateTLBusWrapper(PBUS) - // check whether pbusFreq >= rtcFreq - require(internalPeriod > 0) - // check wehther the integer division is within 5% of the real division - require((pbusFreq - rtcFreq * internalPeriod) * 100 / pbusFreq <= 5) // Use the static period to toggle the RTC - chisel3.withClockAndReset(pbus.module.clock, pbus.module.reset) { - val (_, int_rtc_tick) = Counter(true.B, internalPeriod.toInt) - outer.clintOpt.foreach { clint => - clint.module.io.rtcTick := int_rtc_tick + outer.clintDomainOpt.map { domain => { + val bus = outer.locateTLBusWrapper(p(CLINTAttachKey).slaveWhere) + val busFreq = bus.dtsFrequency.get + val rtcFreq = outer.p(DTSTimebase) + val internalPeriod: BigInt = busFreq / rtcFreq + + + // check whether pbusFreq >= rtcFreq + require(internalPeriod > 0) + // check wehther the integer division is within 5% of the real division + require((busFreq - rtcFreq * internalPeriod) * 100 / busFreq <= 5) + + withClockAndReset (domain.module.clock, domain.module.reset) { + val (_, int_rtc_tick) = Counter(true.B, internalPeriod.toInt) + outer.clintTickOpt.foreach { _ := int_rtc_tick } } - } + }} } diff --git a/src/main/scala/subsystem/RocketSubsystem.scala b/src/main/scala/subsystem/RocketSubsystem.scala index e9e1f55551..ba70ab0c24 100644 --- a/src/main/scala/subsystem/RocketSubsystem.scala +++ b/src/main/scala/subsystem/RocketSubsystem.scala @@ -7,32 +7,47 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.prci.{ResetCrossingType, NoResetCrossing} import freechips.rocketchip.tile._ import freechips.rocketchip.devices.debug.{HasPeripheryDebug} +import freechips.rocketchip.util.{HasCoreMonitorBundles} +import freechips.rocketchip.devices.tilelink.{CanHavePeripheryCLINT, CanHavePeripheryPLIC} case class RocketCrossingParams( crossingType: ClockCrossingType = SynchronousCrossing(), - master: TilePortParamsLike = TileMasterPortParams(), - slave: TileSlavePortParams = TileSlavePortParams(), + master: HierarchicalElementPortParamsLike = HierarchicalElementMasterPortParams(), + slave: HierarchicalElementSlavePortParams = HierarchicalElementSlavePortParams(), mmioBaseAddressPrefixWhere: TLBusWrapperLocation = CBUS, resetCrossingType: ResetCrossingType = NoResetCrossing(), forceSeparateClockReset: Boolean = false -) extends TileCrossingParamsLike +) extends HierarchicalElementCrossingParamsLike case class RocketTileAttachParams( tileParams: RocketTileParams, crossingParams: RocketCrossingParams ) extends CanAttachTile { type TileType = RocketTile } -trait HasRocketTiles extends HasTiles { this: BaseSubsystem => - val rocketTiles = tiles.collect { case r: RocketTile => r } +trait HasRocketTiles { + this: BaseSubsystem with InstantiatesHierarchicalElements => + val rocketTiles = totalTiles.values.collect { case r: RocketTile => r } def coreMonitorBundles = (rocketTiles map { t => t.module.core.rocketImpl.coreMonitorBundle }).toList } -class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem with HasRocketTiles with HasPeripheryDebug { +class RocketSubsystem(implicit p: Parameters) extends BaseSubsystem + with InstantiatesHierarchicalElements + with HasTileNotificationSinks + with HasTileInputConstants + with CanHavePeripheryCLINT + with CanHavePeripheryPLIC + with HasPeripheryDebug + with HasHierarchicalElementsRootContext + with HasHierarchicalElements + with HasCoreMonitorBundles + with HasRocketTiles +{ override lazy val module = new RocketSubsystemModuleImp(this) } class RocketSubsystemModuleImp[+L <: RocketSubsystem](_outer: L) extends BaseSubsystemModuleImp(_outer) - with HasTilesModuleImp + with HasHierarchicalElementsRootContextModuleImp + diff --git a/src/main/scala/system/Configs.scala b/src/main/scala/system/Configs.scala index bb418b9ec9..9827cf428c 100644 --- a/src/main/scala/system/Configs.scala +++ b/src/main/scala/system/Configs.scala @@ -27,9 +27,6 @@ class DefaultSmallConfig extends Config(new WithNSmallCores(1) ++ new WithCohere class DefaultRV32Config extends Config(new WithRV32 ++ new DefaultConfig) class DefaultFP16Config extends Config(new WithFP16 ++ new DefaultConfig) -class BitManipCryptoConfig extends Config(new WithBitManip ++ new WithCryptoNIST ++ new WithCryptoSM ++ new DefaultConfig) -class BitManipCrypto32Config extends Config(new WithBitManip ++ new WithCryptoNIST ++ new WithCryptoSM ++ new DefaultRV32Config) - class HypervisorConfig extends Config(new WithHypervisor ++ new DefaultConfig) class DualBankConfig extends Config(new WithNBanks(2) ++ new DefaultConfig) @@ -37,6 +34,17 @@ class DualCoreConfig extends Config(new WithNBigCores(2) ++ new WithCoherentBusT class DualChannelConfig extends Config(new WithNMemoryChannels(2) ++ new DefaultConfig) class EightChannelConfig extends Config(new WithNMemoryChannels(8) ++ new DefaultConfig) +class ClusterConfig extends Config( + new WithNBigCores(2, InCluster(3)) ++ + new WithNBigCores(2, InCluster(1)) ++ + new WithNBigCores(2, InCluster(0)) ++ + new WithCluster(3, location=InCluster(2)) ++ + new WithCluster(2) ++ + new WithCluster(1) ++ + new WithCluster(0) ++ + new DefaultConfig +) + class DualChannelDualBankConfig extends Config( new WithNMemoryChannels(2) ++ new WithNBanks(4) ++ new DefaultConfig diff --git a/src/main/scala/system/TestHarness.scala b/src/main/scala/system/TestHarness.scala index a1e37dea16..788716258f 100644 --- a/src/main/scala/system/TestHarness.scala +++ b/src/main/scala/system/TestHarness.scala @@ -16,8 +16,10 @@ class TestHarness()(implicit p: Parameters) extends Module { val ldut = LazyModule(new ExampleRocketSystem) val dut = Module(ldut.module) + ldut.io_clocks.get.elements.values.foreach(_.clock := clock) // Allow the debug ndreset to reset the dut, but not until the initial reset has completed - dut.reset := (reset.asBool | ldut.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)).asBool + val dut_reset = (reset.asBool | ldut.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)).asBool + ldut.io_clocks.get.elements.values.foreach(_.reset := dut_reset) dut.dontTouchPorts() dut.tieOffInterrupts() diff --git a/src/main/scala/tile/BaseTile.scala b/src/main/scala/tile/BaseTile.scala index df20aa0aa2..76c8f7b113 100644 --- a/src/main/scala/tile/BaseTile.scala +++ b/src/main/scala/tile/BaseTile.scala @@ -18,20 +18,19 @@ case object TileVisibilityNodeKey extends Field[TLEphemeralNode] case object TileKey extends Field[TileParams] case object LookupByHartId extends Field[LookupByHartIdImpl] -trait TileParams { +trait TileParams extends HierarchicalElementParams { val core: CoreParams val icache: Option[ICacheParams] val dcache: Option[DCacheParams] val btb: Option[BTBParams] - val hartId: Int - val beuAddr: Option[BigInt] + val tileId: Int // may not be hartid val blockerCtrlAddr: Option[BigInt] - val name: Option[String] - val clockSinkParams: ClockSinkParameters } -abstract class InstantiableTileParams[TileType <: BaseTile] extends TileParams { - def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl) +abstract class InstantiableTileParams[TileType <: BaseTile] + extends InstantiableHierarchicalElementParams[TileType] + with TileParams { + def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl) (implicit p: Parameters): TileType } @@ -77,15 +76,7 @@ trait HasNonDiplomaticTileParameters { xLen match { case 32 => 34; case 64 => 56 } } - /** Use staticIdForMetadataUseOnly to emit information during the build or identify a component to diplomacy. - * - * Including it in a constructed Chisel circuit by converting it to a UInt will prevent - * Chisel/FIRRTL from being able to deduplicate tiles that are otherwise homogeneous, - * a property which is important for hierarchical place & route flows. - */ - def staticIdForMetadataUseOnly: Int = tileParams.hartId - @deprecated("use hartIdSinkNodeOpt.map(_.bundle) or staticIdForMetadataUseOnly", "rocket-chip 1.3") - def hartId: Int = staticIdForMetadataUseOnly + def tileId: Int = tileParams.tileId def cacheBlockBytes = p(CacheBlockBytes) def lgCacheBlockBytes = log2Up(cacheBlockBytes) @@ -93,7 +84,7 @@ trait HasNonDiplomaticTileParameters { // TODO make HellaCacheIO diplomatic and remove this brittle collection of hacks // Core PTW DTIM coprocessors - def dcacheArbPorts = 1 + usingVM.toInt + usingDataScratchpad.toInt + p(BuildRoCC).size + tileParams.core.useVector.toInt + def dcacheArbPorts = 1 + usingVM.toInt + usingDataScratchpad.toInt + p(BuildRoCC).size + (tileParams.core.useVector && tileParams.core.vectorUseDCache).toInt // TODO merge with isaString in CSR.scala def isaDTS: String = { @@ -113,11 +104,6 @@ trait HasNonDiplomaticTileParameters { Option.when(tileParams.core.useConditionalZero)(Seq("zicond")) ++ Some(Seq("zicsr", "zifencei", "zihpm")) ++ Option.when(tileParams.core.fpu.nonEmpty && tileParams.core.fpu.get.fLen >= 16 && tileParams.core.fpu.get.minFLen <= 16)(Seq("zfh")) ++ - Option.when(tileParams.core.useBitManip)(Seq("zba", "zbb", "zbc")) ++ - Option.when(tileParams.core.hasBitManipCrypto)(Seq("zbkb", "zbkc", "zbkx")) ++ - Option.when(tileParams.core.useBitManip)(Seq("zbs")) ++ - Option.when(tileParams.core.useCryptoNIST)(Seq("zknd", "zkne", "zknh")) ++ - Option.when(tileParams.core.useCryptoSM)(Seq("zksed", "zksh")) ++ tileParams.core.customIsaExt.map(Seq(_)) ).flatten val multiLetterString = multiLetterExt.mkString("_") @@ -196,9 +182,8 @@ trait HasTileParameters extends HasNonDiplomaticTileParameters { } /** Base class for all Tiles that use TileLink */ -abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters) - extends LazyModule()(q) - with CrossesToOnlyOneClockDomain +abstract class BaseTile private (crossing: ClockCrossingType, q: Parameters) + extends BaseHierarchicalElement(crossing)(q) with HasNonDiplomaticTileParameters { // Public constructor alters Parameters to supply some legacy compatibility keys @@ -210,19 +195,12 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters) ))) } + def intInwardNode: IntInwardNode // Interrupts to the core from external devices + def intOutwardNode: Option[IntOutwardNode] // Interrupts from tile-internal devices (e.g. BEU) + def haltNode: IntOutwardNode // Unrecoverable error has occurred; suggest reset + def ceaseNode: IntOutwardNode // Tile has ceased to retire instructions + def wfiNode: IntOutwardNode // Tile is waiting for an interrupt def module: BaseTileModuleImp[BaseTile] - def masterNode: TLOutwardNode - def slaveNode: TLInwardNode - def intInwardNode: IntInwardNode // Interrupts to the core from external devices - def intOutwardNode: IntOutwardNode // Interrupts from tile-internal devices (e.g. BEU) - def haltNode: IntOutwardNode // Unrecoverable error has occurred; suggest reset - def ceaseNode: IntOutwardNode // Tile has ceased to retire instructions - def wfiNode: IntOutwardNode // Tile is waiting for an interrupt - - protected val tlOtherMastersNode = TLIdentityNode() - protected val tlMasterXbar = LazyModule(new TLXbar) - protected val tlSlaveXbar = LazyModule(new TLXbar) - protected val intXbar = LazyModule(new IntXbar) /** Node for broadcasting a hart id to diplomatic consumers within the tile. */ val hartIdNexusNode: BundleBridgeNode[UInt] = BundleBroadcast[UInt](registered = p(InsertTimingClosureRegistersOnHartIds)) @@ -255,10 +233,10 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters) resetVectorSinkNode := resetVectorNexusNode := BundleBridgeNameNode("reset_vector") /** Nodes for connecting NMI interrupt sources and vectors into the tile */ - val nmiNexusNode: BundleBridgeNode[NMI] = BundleBroadcast[NMI]() - val nmiSinkNode = BundleBridgeSink[NMI](Some(() => new NMI(visiblePhysAddrBits))) - val nmiNode: BundleBridgeInwardNode[NMI] = - nmiSinkNode := nmiNexusNode := BundleBridgeNameNode("nmi") + val nmiSinkNode = Option.when(tileParams.core.useNMI) { + BundleBridgeSink[NMI](Some(() => new NMI(visiblePhysAddrBits))) + } + val nmiNode: Option[BundleBridgeInwardNode[NMI]] = nmiSinkNode.map(_ := BundleBridgeNameNode("nmi")) /** Node for broadcasting an address prefix to diplomatic consumers within the tile. * @@ -284,15 +262,14 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters) protected def traceRetireWidth = tileParams.core.retireWidth /** Node for the core to drive legacy "raw" instruction trace. */ val traceSourceNode = BundleBridgeSource(() => new TraceBundle) - private val traceNexus = BundleBroadcast[TraceBundle]() // backwards compatiblity; not blocked during stretched reset /** Node for external consumers to source a legacy instruction trace from the core. */ - val traceNode: BundleBridgeOutwardNode[TraceBundle] = traceNexus := traceSourceNode + val traceNode = traceSourceNode - protected def traceCoreParams = new TraceCoreParams() + def traceCoreParams = new TraceCoreParams() /** Node for core to drive instruction trace conforming to RISC-V Processor Trace spec V1.0 */ val traceCoreSourceNode = BundleBridgeSource(() => new TraceCoreInterface(traceCoreParams)) /** Node for external consumers to source a V1.0 instruction trace from the core. */ - val traceCoreNode: BundleBridgeOutwardNode[TraceCoreInterface] = traceCoreSourceNode + val traceCoreNode = traceCoreSourceNode /** Node to broadcast collected trace sideband signals into the tile. */ val traceAuxNexusNode = BundleBridgeNexus[TraceAux](default = Some(() => { @@ -352,22 +329,6 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters) "hardware-exec-breakpoint-count" -> tileParams.core.nBreakpoints.asProperty ) - /** Helper function to insert additional buffers on master ports at the boundary of the tile. - * - * The boundary buffering needed to cut feed-through paths is - * microarchitecture specific, so this may need to be overridden - * in subclasses of this class. - */ - def makeMasterBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none) - - /** Helper function to insert additional buffers on slave ports at the boundary of the tile. - * - * The boundary buffering needed to cut feed-through paths is - * microarchitecture specific, so this may need to be overridden - * in subclasses of this class. - */ - def makeSlaveBoundaryBuffers(crossing: ClockCrossingType)(implicit p: Parameters) = TLBuffer(BufferParams.none) - /** Can be used to access derived params calculated by HasCoreParameters * * However, callers must ensure they do not access a diplomatically-determined parameter @@ -378,7 +339,7 @@ abstract class BaseTile private (val crossing: ClockCrossingType, q: Parameters) new C } - this.suggestName(tileParams.name) + this.suggestName(tileParams.baseName) } -abstract class BaseTileModuleImp[+L <: BaseTile](val outer: L) extends LazyModuleImp(outer) with HasTileParameters +abstract class BaseTileModuleImp[+L <: BaseTile](outer: L) extends BaseHierarchicalElementModuleImp[L](outer) diff --git a/src/main/scala/tile/Core.scala b/src/main/scala/tile/Core.scala index 8b4574b3c8..dd3e0058be 100644 --- a/src/main/scala/tile/Core.scala +++ b/src/main/scala/tile/Core.scala @@ -22,12 +22,8 @@ trait CoreParams { val useAtomics: Boolean val useAtomicsOnlyForIO: Boolean val useCompressed: Boolean - val useBitManip: Boolean - val useBitManipCrypto: Boolean - val useVector: Boolean - val useSCIE: Boolean - val useCryptoNIST: Boolean - val useCryptoSM: Boolean + val useVector: Boolean = false + val vectorUseDCache: Boolean = false val useRVE: Boolean val useConditionalZero: Boolean val mulDiv: Option[MulDivParams] @@ -60,7 +56,6 @@ trait CoreParams { def customCSRs(implicit p: Parameters): CustomCSRs = new CustomCSRs def hasSupervisorMode: Boolean = useSupervisor || useVM - def hasBitManipCrypto: Boolean = useBitManipCrypto || useCryptoNIST || useCryptoSM def instBytes: Int = instBits / 8 def fetchBytes: Int = fetchWidth * instBytes def lrscCycles: Int @@ -86,12 +81,7 @@ trait HasCoreParameters extends HasTileParameters { val usingAtomicsOnlyForIO = coreParams.useAtomicsOnlyForIO val usingAtomicsInCache = usingAtomics && !usingAtomicsOnlyForIO val usingCompressed = coreParams.useCompressed - val usingBitManip = coreParams.useBitManip - val usingBitManipCrypto = coreParams.hasBitManipCrypto val usingVector = coreParams.useVector - val usingSCIE = coreParams.useSCIE - val usingCryptoNIST = coreParams.useCryptoNIST - val usingCryptoSM = coreParams.useCryptoSM val usingNMI = coreParams.useNMI val usingConditionalZero = coreParams.useConditionalZero @@ -124,7 +114,6 @@ trait HasCoreParameters extends HasTileParameters { if (usingVector) { require(isPow2(vLen), s"vLen ($vLen) must be a power of 2") require(eLen >= 32 && vLen % eLen == 0, s"eLen must divide vLen ($vLen) and be no less than 32") - require(vMemDataBits >= eLen && vLen % vMemDataBits == 0, s"vMemDataBits ($vMemDataBits) must divide vLen ($vLen) and be no less than eLen ($eLen)") } lazy val hartIdLen: Int = p(MaxHartIdBits) @@ -147,34 +136,9 @@ abstract class CoreModule(implicit val p: Parameters) extends Module abstract class CoreBundle(implicit val p: Parameters) extends ParameterizedBundle()(p) with HasCoreParameters -class CoreInterrupts(implicit p: Parameters) extends TileInterrupts()(p) { - val buserror = tileParams.beuAddr.map(a => Bool()) -} - // This is a raw commit trace from the core, not the TraceCoreInterface class TraceBundle(implicit val p: Parameters) extends Bundle with HasCoreParameters { val insns = Vec(coreParams.retireWidth, new TracedInstruction) val time = UInt(64.W) val custom = coreParams.traceCustom } - -trait HasCoreIO extends HasTileParameters { - implicit val p: Parameters - def nTotalRoCCCSRs: Int - val io = IO(new CoreBundle()(p) { - val hartid = Input(UInt(hartIdLen.W)) - val reset_vector = Input(UInt(resetVectorLen.W)) - val interrupts = Input(new CoreInterrupts()) - val imem = new FrontendIO - val dmem = new HellaCacheIO - val ptw = Flipped(new DatapathPTWIO()) - val fpu = Flipped(new FPUCoreIO()) - val rocc = Flipped(new RoCCCoreIO(nTotalRoCCCSRs)) - val trace = Output(new TraceBundle) - val bpwatch = Output(Vec(coreParams.nBreakpoints, new BPWatch(coreParams.retireWidth))) - val cease = Output(Bool()) - val wfi = Output(Bool()) - val traceStall = Input(Bool()) - val vector = if (usingVector) Some(Flipped(new VectorCoreIO)) else None - }) -} diff --git a/src/main/scala/tile/LookupByHartId.scala b/src/main/scala/tile/LookupByHartId.scala index 263dd43c66..631bb8f651 100644 --- a/src/main/scala/tile/LookupByHartId.scala +++ b/src/main/scala/tile/LookupByHartId.scala @@ -10,10 +10,10 @@ abstract class LookupByHartIdImpl { } case class HartsWontDeduplicate(t: TileParams) extends LookupByHartIdImpl { - def apply[T <: Data](f: TileParams => Option[T], hartId: UInt): T = f(t).get + def apply[T <: Data](f: TileParams => Option[T], tileId: UInt): T = f(t).get } case class PriorityMuxHartIdFromSeq(seq: Seq[TileParams]) extends LookupByHartIdImpl { - def apply[T <: Data](f: TileParams => Option[T], hartId: UInt): T = - PriorityMux(seq.collect { case t if f(t).isDefined => (t.hartId.U === hartId) -> f(t).get }) + def apply[T <: Data](f: TileParams => Option[T], tileId: UInt): T = + PriorityMux(seq.collect { case t if f(t).isDefined => (t.tileId.U === tileId) -> f(t).get }) } diff --git a/src/main/scala/tile/RocketTile.scala b/src/main/scala/tile/RocketTile.scala index ad70b15b38..9af4871b33 100644 --- a/src/main/scala/tile/RocketTile.scala +++ b/src/main/scala/tile/RocketTile.scala @@ -10,7 +10,7 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.rocket._ -import freechips.rocketchip.subsystem.TileCrossingParamsLike +import freechips.rocketchip.subsystem.HierarchicalElementCrossingParamsLike import freechips.rocketchip.util._ import freechips.rocketchip.prci.{ClockSinkParameters} @@ -22,8 +22,7 @@ case class RocketTileParams( dcache: Option[DCacheParams] = Some(DCacheParams()), btb: Option[BTBParams] = Some(BTBParams()), dataScratchpadBytes: Int = 0, - name: Option[String] = Some("tile"), - hartId: Int = 0, + tileId: Int = 0, beuAddr: Option[BigInt] = None, blockerCtrlAddr: Option[BigInt] = None, clockSinkParams: ClockSinkParameters = ClockSinkParameters(), @@ -31,7 +30,9 @@ case class RocketTileParams( ) extends InstantiableTileParams[RocketTile] { require(icache.isDefined) require(dcache.isDefined) - def instantiate(crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): RocketTile = { + val baseName = "rockettile" + val uniqueName = s"${baseName}_$tileId" + def instantiate(crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters): RocketTile = { new RocketTile(this, crossing, lookup) } } @@ -49,10 +50,10 @@ class RocketTile private( with HasICacheFrontend { // Private constructor ensures altered LazyModule.p is used implicitly - def this(params: RocketTileParams, crossing: TileCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) = + def this(params: RocketTileParams, crossing: HierarchicalElementCrossingParamsLike, lookup: LookupByHartIdImpl)(implicit p: Parameters) = this(params, crossing.crossingType, lookup, p) - val intOutwardNode = IntIdentityNode() + val intOutwardNode = rocketParams.beuAddr map { _ => IntIdentityNode() } val slaveNode = TLIdentityNode() val masterNode = visibilityNode @@ -63,7 +64,7 @@ class RocketTile private( val bus_error_unit = rocketParams.beuAddr map { a => val beu = LazyModule(new BusErrorUnit(new L1BusErrors, BusErrorUnitParams(a))) - intOutwardNode := beu.intNode + intOutwardNode.get := beu.intNode connectTLSlave(beu.node, xBytes) beu } @@ -105,7 +106,7 @@ class RocketTile private( ResourceBinding { - Resource(cpuDevice, "reg").bind(ResourceAddress(staticIdForMetadataUseOnly)) + Resource(cpuDevice, "reg").bind(ResourceAddress(tileId)) } override lazy val module = new RocketTileModuleImp(this) @@ -158,7 +159,7 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) beu.module.io.errors.icache := outer.frontend.module.io.errors } - core.io.interrupts.nmi.foreach { nmi => nmi := outer.nmiSinkNode.bundle } + core.io.interrupts.nmi.foreach { nmi => nmi := outer.nmiSinkNode.get.bundle } // Pass through various external constants and reports that were bundle-bridged into the tile outer.traceSourceNode.bundle <> core.io.trace @@ -193,7 +194,7 @@ class RocketTileModuleImp(outer: RocketTile) extends BaseTileModuleImp(outer) core.io.rocc.resp <> respArb.get.io.out core.io.rocc.busy <> (cmdRouter.get.io.busy || outer.roccs.map(_.module.io.busy).reduce(_ || _)) core.io.rocc.interrupt := outer.roccs.map(_.module.io.interrupt).reduce(_ || _) - (core.io.rocc.csrs zip roccCSRIOs.flatten).foreach { t => t._2 := t._1 } + (core.io.rocc.csrs zip roccCSRIOs.flatten).foreach { t => t._2 <> t._1 } } else { // tie off core.io.rocc.cmd.ready := false.B @@ -224,18 +225,24 @@ trait HasFpuOpt { this: RocketTileModuleImp => fpuOpt.foreach { fpu => val nRoCCFPUPorts = outer.roccs.count(_.usesFPU) val nFPUPorts = nRoCCFPUPorts + outer.rocketParams.core.useVector.toInt - val fpArb = Module(new InOrderArbiter(new FPInput()(outer.p), new FPResult()(outer.p), nFPUPorts)) - fpu.io.cp_req <> fpArb.io.out_req - fpArb.io.out_resp <> fpu.io.cp_resp - - val fp_rocc_ios = outer.roccs.filter(_.usesFPU).map(_.module.io) - for (i <- 0 until nRoCCFPUPorts) { - fpArb.io.in_req(i) <> fp_rocc_ios(i).fpu_req - fp_rocc_ios(i).fpu_resp <> fpArb.io.in_resp(i) + if (nFPUPorts > 0) { + val fpArb = Module(new InOrderArbiter(new FPInput()(outer.p), new FPResult()(outer.p), nFPUPorts)) + fpu.io.cp_req <> fpArb.io.out_req + fpArb.io.out_resp <> fpu.io.cp_resp + + val fp_rocc_ios = outer.roccs.filter(_.usesFPU).map(_.module.io) + for (i <- 0 until nRoCCFPUPorts) { + fpArb.io.in_req(i) <> fp_rocc_ios(i).fpu_req + fp_rocc_ios(i).fpu_resp <> fpArb.io.in_resp(i) + } + outer.vector_unit.foreach(vu => { + fpArb.io.in_req(nRoCCFPUPorts) <> vu.module.io.fp_req + vu.module.io.fp_resp <> fpArb.io.in_resp(nRoCCFPUPorts) + }) + } else { + fpu.io.cp_req.valid := false.B + fpu.io.cp_req.bits := DontCare + fpu.io.cp_resp.ready := false.B } - outer.vector_unit.foreach(vu => { - fpArb.io.in_req(nRoCCFPUPorts) <> vu.module.io.fp_req - vu.module.io.fp_resp <> fpArb.io.in_resp(nRoCCFPUPorts) - }) } } diff --git a/src/main/scala/tile/TilePRCIDomain.scala b/src/main/scala/tile/TilePRCIDomain.scala index 73972bec4d..d4066a6347 100644 --- a/src/main/scala/tile/TilePRCIDomain.scala +++ b/src/main/scala/tile/TilePRCIDomain.scala @@ -8,24 +8,10 @@ import freechips.rocketchip.diplomacy._ import freechips.rocketchip.interrupts._ import freechips.rocketchip.prci._ import freechips.rocketchip.rocket.{TracedInstruction} -import freechips.rocketchip.subsystem.{TileCrossingParamsLike, CrossesToOnlyOneResetDomain} +import freechips.rocketchip.subsystem._ import freechips.rocketchip.tilelink._ import freechips.rocketchip.util.{TraceCoreInterface} -/** A wrapper containing all logic within a managed reset domain for a tile. - * - * This does not add a layer of the module hierarchy. - */ -class TileResetDomain(clockSinkParams: ClockSinkParameters, resetCrossingType: ResetCrossingType) - (implicit p: Parameters) - extends ResetDomain - with CrossesToOnlyOneResetDomain -{ - def crossing = resetCrossingType - val clockNode = ClockSinkNode(Seq(clockSinkParams)) - def clockBundle = clockNode.in.head._1 - override def shouldBeInlined = true -} /** A wrapper containing all logic necessary to safely place a tile * inside of a particular Power/Reset/Clock/Interrupt domain. @@ -37,77 +23,9 @@ class TileResetDomain(clockSinkParams: ClockSinkParameters, resetCrossingType: R */ abstract class TilePRCIDomain[T <: BaseTile]( clockSinkParams: ClockSinkParameters, - crossingParams: TileCrossingParamsLike) + crossingParams: HierarchicalElementCrossingParamsLike) (implicit p: Parameters) - extends ClockDomain + extends HierarchicalElementPRCIDomain[T](clockSinkParams, crossingParams) { - val tile: T - val tile_reset_domain = LazyModule(new TileResetDomain(clockSinkParams, crossingParams.resetCrossingType)) - val tapClockNode = ClockIdentityNode() - val clockNode = FixedClockBroadcast(None) :=* tapClockNode - lazy val clockBundle = tapClockNode.in.head._1 - - private val traceSignalName = "trace" - private val traceCoreSignalName = "tracecore" - /** Node to broadcast legacy "raw" instruction trace while surpressing it during (async) reset. */ - val traceNode: BundleBridgeIdentityNode[TraceBundle] = BundleBridgeNameNode(traceSignalName) - /** Node to broadcast standardized instruction trace while surpressing it during (async) reset. */ - val traceCoreNode: BundleBridgeIdentityNode[TraceCoreInterface] = BundleBridgeNameNode(traceCoreSignalName) - - /** Function to handle all trace crossings when tile is instantiated inside domains */ - def crossTracesOut(): Unit = this { - val traceNexusNode = BundleBridgeBlockDuringReset[TraceBundle]( - resetCrossingType = crossingParams.resetCrossingType, - name = Some(traceSignalName)) - traceNode :*= traceNexusNode := tile.traceNode - - val traceCoreNexusNode = BundleBridgeBlockDuringReset[TraceCoreInterface]( - resetCrossingType = crossingParams.resetCrossingType, - name = Some(traceCoreSignalName)) - traceCoreNode :*= traceCoreNexusNode := tile.traceCoreNode - } - - /** External code looking to connect and clock-cross the interrupts driven into this tile can call this. */ - def crossIntIn(crossingType: ClockCrossingType): IntInwardNode = { - // Unlike the other crossing helpers, here nothing is is blocked during reset because we know these are inputs and assume that tile reset is longer than uncore reset - val intInClockXing = this.crossIn(tile.intInwardNode) - intInClockXing(crossingType) - } - - /** External code looking to connect and clock/reset-cross - * - interrupts raised by devices inside this tile - * - notifications raise by the cores and caches - * can call this function to instantiate the required crossing hardware. - * Takes crossingType as an argument because some interrupts are supposed to be synchronous - * Takes tileNode as an argument because tiles might have multiple outbound interrupt nodes - */ - def crossIntOut(crossingType: ClockCrossingType, tileNode: IntOutwardNode): IntOutwardNode = { - val intOutResetXing = this { tile_reset_domain.crossIntOut(tileNode) } - val intOutClockXing = this.crossOut(intOutResetXing) - intOutClockXing(crossingType) - } - - /** External code looking to connect the ports where this tile is slaved to an interconnect - * (while also crossing clock domains) can call this. - */ - def crossSlavePort(crossingType: ClockCrossingType): TLInwardNode = { DisableMonitors { implicit p => FlipRendering { implicit p => - val tlSlaveResetXing = this { - tile_reset_domain.crossTLIn(tile.slaveNode) :*= - tile { tile.makeSlaveBoundaryBuffers(crossingType) } - } - val tlSlaveClockXing = this.crossIn(tlSlaveResetXing) - tlSlaveClockXing(crossingType) - } } } - - /** External code looking to connect the ports where this tile masters an interconnect - * (while also crossing clock domains) can call this. - */ - def crossMasterPort(crossingType: ClockCrossingType): TLOutwardNode = { - val tlMasterResetXing = this { DisableMonitors { implicit p => - tile { tile.makeMasterBoundaryBuffers(crossingType) } :=* - tile_reset_domain.crossTLOut(tile.masterNode) - } } - val tlMasterClockXing = this.crossOut(tlMasterResetXing) - tlMasterClockXing(crossingType) - } + def tile_reset_domain = element_reset_domain } diff --git a/src/main/scala/tilelink/BusWrapper.scala b/src/main/scala/tilelink/BusWrapper.scala index 657bba873f..b07844cef6 100644 --- a/src/main/scala/tilelink/BusWrapper.scala +++ b/src/main/scala/tilelink/BusWrapper.scala @@ -72,6 +72,11 @@ abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implici def unifyManagers: List[TLManagerParameters] = ManagerUnification(busView.manager.managers) def crossOutHelper = this.crossOut(outwardNode)(ValName("bus_xing")) def crossInHelper = this.crossIn(inwardNode)(ValName("bus_xing")) + def generateSynchronousDomain: ClockSinkDomain = { + val domain = LazyModule(new ClockSinkDomain(take = fixedClockOpt)) + domain.clockNode := fixedClockNode + domain + } protected val addressPrefixNexusNode = BundleBroadcast[UInt](registered = false, default = Some(() => 0.U(1.W))) @@ -89,15 +94,15 @@ abstract class TLBusWrapper(params: HasTLBusParams, val busName: String)(implici def coupleFrom[T](name: String)(gen: TLInwardNode => T): T = from(name) { gen(inwardNode :*=* TLNameNode("tl")) } - def crossToBus(bus: TLBusWrapper, xType: ClockCrossingType)(implicit asyncClockGroupNode: ClockGroupEphemeralNode): NoHandle = { - bus.clockGroupNode := asyncMux(xType, asyncClockGroupNode, this.clockGroupNode) + def crossToBus(bus: TLBusWrapper, xType: ClockCrossingType, allClockGroupNode: ClockGroupEphemeralNode): NoHandle = { + bus.clockGroupNode := asyncMux(xType, allClockGroupNode, this.clockGroupNode) coupleTo(s"bus_named_${bus.busName}") { bus.crossInHelper(xType) :*= TLWidthWidget(beatBytes) :*= _ } } - def crossFromBus(bus: TLBusWrapper, xType: ClockCrossingType)(implicit asyncClockGroupNode: ClockGroupEphemeralNode): NoHandle = { - bus.clockGroupNode := asyncMux(xType, asyncClockGroupNode, this.clockGroupNode) + def crossFromBus(bus: TLBusWrapper, xType: ClockCrossingType, allClockGroupNode: ClockGroupEphemeralNode): NoHandle = { + bus.clockGroupNode := asyncMux(xType, allClockGroupNode, this.clockGroupNode) coupleFrom(s"bus_named_${bus.busName}") { _ :=* TLWidthWidget(bus.beatBytes) :=* bus.crossOutHelper(xType) } @@ -178,8 +183,8 @@ class TLBusWrapperConnection val masterTLBus = context.locateTLBusWrapper(master) val slaveTLBus = context.locateTLBusWrapper(slave) def bindClocks(implicit p: Parameters) = driveClockFromMaster match { - case Some(true) => slaveTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, masterTLBus.clockGroupNode) - case Some(false) => masterTLBus.clockGroupNode := asyncMux(xType, context.asyncClockGroupsNode, slaveTLBus.clockGroupNode) + case Some(true) => slaveTLBus.clockGroupNode := asyncMux(xType, context.allClockGroupsNode, masterTLBus.clockGroupNode) + case Some(false) => masterTLBus.clockGroupNode := asyncMux(xType, context.allClockGroupsNode, slaveTLBus.clockGroupNode) case None => } def bindTLNodes(implicit p: Parameters) = nodeBinding match { @@ -240,8 +245,8 @@ case class AddressAdjusterWrapperParams( { val dtsFrequency = None def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): AddressAdjusterWrapper = { - val aaWrapper = LazyModule(new AddressAdjusterWrapper(this, loc.name)) - aaWrapper.suggestName(loc.name + "_wrapper") + val aaWrapper = LazyModule(new AddressAdjusterWrapper(this, context.busContextName + "_" + loc.name)) + aaWrapper.suggestName(context.busContextName + "_" + loc.name + "_wrapper") context.tlBusWrapperLocationMap += (loc -> aaWrapper) aaWrapper } @@ -270,8 +275,8 @@ case class TLJBarWrapperParams( { val dtsFrequency = None def instantiate(context: HasTileLinkLocations, loc: Location[TLBusWrapper])(implicit p: Parameters): TLJBarWrapper = { - val jbarWrapper = LazyModule(new TLJBarWrapper(this, loc.name)) - jbarWrapper.suggestName(loc.name + "_wrapper") + val jbarWrapper = LazyModule(new TLJBarWrapper(this, context.busContextName + "_" + loc.name)) + jbarWrapper.suggestName(context.busContextName + "_" + loc.name + "_wrapper") context.tlBusWrapperLocationMap += (loc -> jbarWrapper) jbarWrapper } diff --git a/src/main/scala/tilelink/Delayer.scala b/src/main/scala/tilelink/Delayer.scala index eb70bc5e4d..58d08e4bc4 100644 --- a/src/main/scala/tilelink/Delayer.scala +++ b/src/main/scala/tilelink/Delayer.scala @@ -30,6 +30,8 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule anoise.size := LFSRNoiseMaker(anoise.params.sizeBits) anoise.source := LFSRNoiseMaker(anoise.params.sourceBits) anoise.address := LFSRNoiseMaker(anoise.params.addressBits) + anoise.user := DontCare + anoise.echo := DontCare anoise.mask := LFSRNoiseMaker(anoise.params.dataBits/8) anoise.data := LFSRNoiseMaker(anoise.params.dataBits) anoise.corrupt := LFSRNoiseMaker(1) @@ -50,6 +52,8 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule cnoise.size := LFSRNoiseMaker(cnoise.params.sizeBits) cnoise.source := LFSRNoiseMaker(cnoise.params.sourceBits) cnoise.address := LFSRNoiseMaker(cnoise.params.addressBits) + cnoise.user := DontCare + cnoise.echo := DontCare cnoise.data := LFSRNoiseMaker(cnoise.params.dataBits) cnoise.corrupt := LFSRNoiseMaker(1)(0) @@ -60,6 +64,8 @@ class TLDelayer(q: Double)(implicit p: Parameters) extends LazyModule dnoise.source := LFSRNoiseMaker(dnoise.params.sourceBits) dnoise.sink := LFSRNoiseMaker(dnoise.params.sinkBits) dnoise.denied := LFSRNoiseMaker(1)(0) + dnoise.user := DontCare + dnoise.echo := DontCare dnoise.data := LFSRNoiseMaker(dnoise.params.dataBits) dnoise.corrupt := LFSRNoiseMaker(1)(0) diff --git a/src/main/scala/tilelink/Edges.scala b/src/main/scala/tilelink/Edges.scala index 2c555c03ac..ce34cbb98a 100644 --- a/src/main/scala/tilelink/Edges.scala +++ b/src/main/scala/tilelink/Edges.scala @@ -345,14 +345,15 @@ class TLEdgeOut( require (manager.anySupportAcquireB, s"TileLink: No managers visible from this edge support Acquires, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsAcquireBFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a :#= DontCare a.opcode := TLMessages.AcquireBlock a.param := growPermissions a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask(toAddress, lgSize) - a.data := 0.U + a.data := DontCare a.corrupt := false.B (legal, a) } @@ -366,8 +367,10 @@ class TLEdgeOut( a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask(toAddress, lgSize) - a.data := 0.U + a.data := DontCare a.corrupt := false.B (legal, a) } @@ -376,13 +379,14 @@ class TLEdgeOut( require (manager.anySupportAcquireB, s"TileLink: No managers visible from this edge support Acquires, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsAcquireBFast(toAddress, lgSize) val c = Wire(new TLBundleC(bundle)) - c :#= DontCare c.opcode := TLMessages.Release c.param := shrinkPermissions c.size := lgSize c.source := fromSource c.address := toAddress - c.data := 0.U + c.user := DontCare + c.echo := DontCare + c.data := DontCare c.corrupt := false.B (legal, c) } @@ -391,12 +395,13 @@ class TLEdgeOut( require (manager.anySupportAcquireB, s"TileLink: No managers visible from this edge support Acquires, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsAcquireBFast(toAddress, lgSize) val c = Wire(new TLBundleC(bundle)) - c :#= DontCare c.opcode := TLMessages.ReleaseData c.param := shrinkPermissions c.size := lgSize c.source := fromSource c.address := toAddress + c.user := DontCare + c.echo := DontCare c.data := data c.corrupt := corrupt (legal, c) @@ -410,13 +415,14 @@ class TLEdgeOut( def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt): TLBundleC = { val c = Wire(new TLBundleC(bundle)) - c :#= DontCare c.opcode := TLMessages.ProbeAck c.param := reportPermissions c.size := lgSize c.source := fromSource c.address := toAddress - c.data := 0.U + c.user := DontCare + c.echo := DontCare + c.data := DontCare c.corrupt := false.B c } @@ -426,12 +432,13 @@ class TLEdgeOut( def ProbeAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, reportPermissions: UInt, data: UInt, corrupt: Bool): TLBundleC = { val c = Wire(new TLBundleC(bundle)) - c :#= DontCare c.opcode := TLMessages.ProbeAckData c.param := reportPermissions c.size := lgSize c.source := fromSource c.address := toAddress + c.user := DontCare + c.echo := DontCare c.data := data c.corrupt := corrupt c @@ -452,14 +459,15 @@ class TLEdgeOut( require (manager.anySupportGet, s"TileLink: No managers visible from this edge support Gets, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsGetFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a :#= DontCare a.opcode := TLMessages.Get a.param := 0.U a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask(toAddress, lgSize) - a.data := 0.U + a.data := DontCare a.corrupt := false.B (legal, a) } @@ -471,12 +479,13 @@ class TLEdgeOut( require (manager.anySupportPutFull, s"TileLink: No managers visible from this edge support Puts, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsPutFullFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a :#= DontCare a.opcode := TLMessages.PutFullData a.param := 0.U a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask(toAddress, lgSize) a.data := data a.corrupt := corrupt @@ -490,12 +499,13 @@ class TLEdgeOut( require (manager.anySupportPutPartial, s"TileLink: No managers visible from this edge support masked Puts, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsPutPartialFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a :#= DontCare a.opcode := TLMessages.PutPartialData a.param := 0.U a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask a.data := data a.corrupt := corrupt @@ -506,12 +516,13 @@ class TLEdgeOut( require (manager.anySupportArithmetic, s"TileLink: No managers visible from this edge support arithmetic AMOs, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsArithmeticFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a :#= DontCare a.opcode := TLMessages.ArithmeticData a.param := atomic a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask(toAddress, lgSize) a.data := data a.corrupt := corrupt @@ -522,12 +533,13 @@ class TLEdgeOut( require (manager.anySupportLogical, s"TileLink: No managers visible from this edge support logical AMOs, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsLogicalFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a :#= DontCare a.opcode := TLMessages.LogicalData a.param := atomic a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask(toAddress, lgSize) a.data := data a.corrupt := corrupt @@ -538,14 +550,15 @@ class TLEdgeOut( require (manager.anySupportHint, s"TileLink: No managers visible from this edge support Hints, but one of these clients would try to request one: ${client.clients}") val legal = manager.supportsHintFast(toAddress, lgSize) val a = Wire(new TLBundleA(bundle)) - a :#= DontCare a.opcode := TLMessages.Hint a.param := param a.size := lgSize a.source := fromSource a.address := toAddress + a.user := DontCare + a.echo := DontCare a.mask := mask(toAddress, lgSize) - a.data := 0.U + a.data := DontCare a.corrupt := false.B (legal, a) } @@ -553,13 +566,14 @@ class TLEdgeOut( def AccessAck(b: TLBundleB): TLBundleC = AccessAck(b.source, address(b), b.size) def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt) = { val c = Wire(new TLBundleC(bundle)) - c :#= DontCare c.opcode := TLMessages.AccessAck c.param := 0.U c.size := lgSize c.source := fromSource c.address := toAddress - c.data := 0.U + c.user := DontCare + c.echo := DontCare + c.data := DontCare c.corrupt := false.B c } @@ -569,12 +583,13 @@ class TLEdgeOut( def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt): TLBundleC = AccessAck(fromSource, toAddress, lgSize, data, false.B) def AccessAck(fromSource: UInt, toAddress: UInt, lgSize: UInt, data: UInt, corrupt: Bool) = { val c = Wire(new TLBundleC(bundle)) - c :#= DontCare c.opcode := TLMessages.AccessAckData c.param := 0.U c.size := lgSize c.source := fromSource c.address := toAddress + c.user := DontCare + c.echo := DontCare c.data := data c.corrupt := corrupt c @@ -583,13 +598,14 @@ class TLEdgeOut( def HintAck(b: TLBundleB): TLBundleC = HintAck(b.source, address(b), b.size) def HintAck(fromSource: UInt, toAddress: UInt, lgSize: UInt) = { val c = Wire(new TLBundleC(bundle)) - c :#= DontCare c.opcode := TLMessages.HintAck c.param := 0.U c.size := lgSize c.source := fromSource c.address := toAddress - c.data := 0.U + c.user := DontCare + c.echo := DontCare + c.data := DontCare c.corrupt := false.B c } @@ -620,7 +636,7 @@ class TLEdgeIn( b.source := toSource b.address := fromAddress b.mask := mask(fromAddress, lgSize) - b.data := 0.U + b.data := DontCare b.corrupt := false.B (legal, b) } @@ -634,7 +650,9 @@ class TLEdgeIn( d.source := toSource d.sink := fromSink d.denied := denied - d.data := 0.U + d.user := DontCare + d.echo := DontCare + d.data := DontCare d.corrupt := false.B d } @@ -648,6 +666,8 @@ class TLEdgeIn( d.source := toSource d.sink := fromSink d.denied := denied + d.user := DontCare + d.echo := DontCare d.data := data d.corrupt := corrupt d @@ -662,7 +682,9 @@ class TLEdgeIn( d.source := toSource d.sink := 0.U d.denied := denied - d.data := 0.U + d.user := DontCare + d.echo := DontCare + d.data := DontCare d.corrupt := false.B d } @@ -678,7 +700,7 @@ class TLEdgeIn( b.source := toSource b.address := fromAddress b.mask := mask(fromAddress, lgSize) - b.data := 0.U + b.data := DontCare b.corrupt := false.B (legal, b) } @@ -759,7 +781,7 @@ class TLEdgeIn( b.source := toSource b.address := fromAddress b.mask := mask(fromAddress, lgSize) - b.data := 0.U + b.data := DontCare b.corrupt := false.B (legal, b) } @@ -775,7 +797,9 @@ class TLEdgeIn( d.source := toSource d.sink := 0.U d.denied := denied - d.data := 0.U + d.user := DontCare + d.echo := DontCare + d.data := DontCare d.corrupt := false.B d } @@ -791,6 +815,8 @@ class TLEdgeIn( d.source := toSource d.sink := 0.U d.denied := denied + d.user := DontCare + d.echo := DontCare d.data := data d.corrupt := corrupt d @@ -807,7 +833,9 @@ class TLEdgeIn( d.source := toSource d.sink := 0.U d.denied := denied - d.data := 0.U + d.user := DontCare + d.echo := DontCare + d.data := DontCare d.corrupt := false.B d } diff --git a/src/main/scala/tilelink/Monitor.scala b/src/main/scala/tilelink/Monitor.scala index f34e388e54..013912a562 100644 --- a/src/main/scala/tilelink/Monitor.scala +++ b/src/main/scala/tilelink/Monitor.scala @@ -587,7 +587,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec } if (edge.manager.minLatency > 0) { - assume(a_set =/= d_clr || !a_set.orR, s"'A' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra) + assume(a_set =/= d_clr || !a_set.orR, s"'A' and 'D' concurrent, despite minlatency > 0" + extra) } inflight := (inflight | a_set) & ~d_clr @@ -696,7 +696,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec } if (edge.manager.minLatency > 0) { - assume(a_set_wo_ready =/= d_clr_wo_ready || !a_set_wo_ready.orR, s"'A' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra) + assume(a_set_wo_ready =/= d_clr_wo_ready || !a_set_wo_ready.orR, s"'A' and 'D' concurrent, despite minlatency > 0" + extra) } inflight := (inflight | a_set) & ~d_clr @@ -804,7 +804,7 @@ class TLMonitor(args: TLMonitorArgs, monitorDir: MonitorDirection = MonitorDirec if (edge.manager.minLatency > 0) { when (c_set_wo_ready.orR) { - assume(c_set_wo_ready =/= d_clr_wo_ready, s"'C' and 'D' concurrent, despite minlatency ${edge.manager.minLatency}" + extra) + assume(c_set_wo_ready =/= d_clr_wo_ready, s"'C' and 'D' concurrent, despite minlatency > 0" + extra) } } diff --git a/src/main/scala/tilelink/SourceShrinker.scala b/src/main/scala/tilelink/SourceShrinker.scala index c2b56e49a8..16fac848d6 100644 --- a/src/main/scala/tilelink/SourceShrinker.scala +++ b/src/main/scala/tilelink/SourceShrinker.scala @@ -34,10 +34,6 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod lazy val module = new Impl class Impl extends LazyModuleImp(this) { node.in.zip(node.out).foreach { case ((in, edgeIn), (out, edgeOut)) => - // Acquires cannot pass this adapter; it makes Probes impossible - require (!edgeIn.client.anySupportProbe || - !edgeOut.manager.anySupportAcquireB) - out.b.ready := true.B out.c.valid := false.B out.e.valid := false.B @@ -49,6 +45,10 @@ class TLSourceShrinker(maxInFlight: Int)(implicit p: Parameters) extends LazyMod out.a <> in.a in.d <> out.d } else { + // Acquires cannot pass this adapter; it makes Probes impossible + require (!edgeIn.client.anySupportProbe || + !edgeOut.manager.anySupportAcquireB) + // State tracking val sourceIdMap = Mem(maxInFlight, UInt(edgeIn.bundle.sourceBits.W)) val allocated = RegInit(0.U(maxInFlight.W)) diff --git a/src/main/scala/tilelink/ToAXI4.scala b/src/main/scala/tilelink/ToAXI4.scala index 2c8ab84bb3..5aa6426f84 100644 --- a/src/main/scala/tilelink/ToAXI4.scala +++ b/src/main/scala/tilelink/ToAXI4.scala @@ -145,8 +145,8 @@ class TLToAXI4(val combinational: Boolean = true, val adapterName: Option[String val depth = if (combinational) 1 else 2 val out_arw = Wire(Decoupled(new AXI4BundleARW(out.params))) val out_w = Wire(chiselTypeOf(out.w)) - out.w :<>= Queue.irrevocable(out_w, entries=depth, combinational) - val queue_arw = Queue.irrevocable(out_arw, entries=depth, combinational) + out.w :<>= Queue.irrevocable(out_w, entries=depth, flow=combinational) + val queue_arw = Queue.irrevocable(out_arw, entries=depth, flow=combinational) // Fan out the ARW channel to AR and AW out.ar.bits := queue_arw.bits diff --git a/src/main/scala/util/BarrelShifter.scala b/src/main/scala/util/BarrelShifter.scala index cd6e439d69..e69de29bb2 100644 --- a/src/main/scala/util/BarrelShifter.scala +++ b/src/main/scala/util/BarrelShifter.scala @@ -1,94 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 - -// FIXME: use chisel3.stdlib.BarrelShifter after chisel3 3.6.0 -package freechips.rocketchip.util - -import chisel3._ -import chisel3.util.{Mux1H, UIntToOH} - -/** A Barrel Shifter implementation for Vec type. - * - * @param inputs input signal to be shifted, should be a [[Vec]] type. - * @param shiftInput input signal to indicate the shift number, encoded in UInt. - * @param shiftGranularity how many bits will be resolved in each layer. - * For a smaller `shiftGranularity`, latency will be high, but area is smaller. - * For a large `shiftGranularity`, latency will be low, but area is higher. - * - * @example {{{ - * val input = 0xAABBCCDD.U(32.W) - * val bytes = VecInit(input.asBools.grouped(8).map(VecInit(_).asUInt).toSeq) - * val shamt = 1.U(2.W) - * val output = BarrelShifter.leftRotate(bytes, shamt).asUInt // big endian - * // output = 0xDDAABBCC.U(32.W) - * // The depth of Mux is 2, whereas originally - * // the depth of Mux is log(32) = 5 - * val output = BarrelShifter.leftRotate(bytes, shamt, 2).asUInt // depth is 1 now - * }}} - */ -object BarrelShifter { - private trait ShiftType - - private object LeftShift extends ShiftType - - private object RightShift extends ShiftType - - private object LeftRotate extends ShiftType - - private object RightRotate extends ShiftType - - private def apply[T <: Data]( - inputs: Vec[T], - shiftInput: UInt, - shiftType: ShiftType, - shiftGranularity: Int = 1 - ): Vec[T] = { - require(shiftGranularity > 0) - val elementType: T = chiselTypeOf(inputs.head) - shiftInput.asBools - .grouped(shiftGranularity) - .map(VecInit(_).asUInt) - .zipWithIndex - .foldLeft(inputs) { - case (prev, (shiftBits, layer)) => - Mux1H( - UIntToOH(shiftBits), - Seq.tabulate(1 << shiftBits.getWidth)(i => { - // For each layer of barrel shifter, it needs to - // Mux between shift 0 and i * 2^(depthOfLayer*granularity) - // - // e.g, when depth = 2 and granu = 1, the first layer Mux between 0 and 1 - // while the second layer Mux between 0 and 2, thus Vec.shift(UInt(2.W)) - // - // e.g, when depth = 2 and granu = 2, the first layer Mux between 0, 1, 2 and 3 - // while the second layer Mux between 0, 4, 8, and 12, thus achieving Vec.shift(UInt(4.W)) - // - // Also, shift no more than inputs length since prev.drop will not warn about overflow - // this is for Vec with length not the exponential of 2, e.g. 13 - val layerShift: Int = (i * (1 << (layer * shiftGranularity))).min(prev.length) - VecInit(shiftType match { - case LeftRotate => - prev.drop(layerShift) ++ prev.take(layerShift) - case LeftShift => - prev.drop(layerShift) ++ Seq.fill(layerShift)(0.U.asTypeOf(elementType)) - case RightRotate => - prev.takeRight(layerShift) ++ prev.dropRight(layerShift) - case RightShift => - Seq.fill(layerShift)(0.U.asTypeOf(elementType)) ++ prev.dropRight(layerShift) - }) - }) - ) - } - } - - def leftShift[T <: Data](inputs: Vec[T], shift: UInt, layerSize: Int = 1): Vec[T] = - apply(inputs, shift, LeftShift, layerSize) - - def rightShift[T <: Data](inputs: Vec[T], shift: UInt, layerSize: Int = 1): Vec[T] = - apply(inputs, shift, RightShift, layerSize) - - def leftRotate[T <: Data](inputs: Vec[T], shift: UInt, layerSize: Int = 1): Vec[T] = - apply(inputs, shift, LeftRotate, layerSize) - - def rightRotate[T <: Data](inputs: Vec[T], shift: UInt, layerSize: Int = 1): Vec[T] = - apply(inputs, shift, RightRotate, layerSize) -} diff --git a/src/main/scala/util/DelayQueue.scala b/src/main/scala/util/DelayQueue.scala new file mode 100644 index 0000000000..cdfa2f5074 --- /dev/null +++ b/src/main/scala/util/DelayQueue.scala @@ -0,0 +1,96 @@ +// See LICENSE.SiFive for license details. + +package freechips.rocketchip.util + +import chisel3._ +import chisel3.util._ + +/** A queue that delays elements by a certain cycle count. + * + * @param gen queue element type + * @param entries queue size + * + * @param enq enqueue + * @param deq dequeue + * @param timer cycle count timer + * @param entries cycle delay + */ +class DelayQueue[T <: Data](gen: T, entries: Int) extends Module { + val io = IO(new Bundle { + val enq = Flipped(DecoupledIO(gen)) + val deq = DecoupledIO(gen) + val timer = Input(UInt()) + val delay = Input(UInt()) + }) + + val q = Module(new Queue(new Bundle { + val data = gen + val time = UInt(io.timer.getWidth.W) + }, entries, flow=true)) + + val delay_r = RegInit(0.U(io.delay.getWidth.W)) + when (delay_r =/= io.delay) { + delay_r := io.delay + assert(q.io.count == 0, "Undefined behavior when delay is changed while queue has elements.") + } + + q.io.enq.bits.data := io.enq.bits + q.io.enq.bits.time := io.timer + q.io.enq.valid := io.enq.fire + io.enq.ready := q.io.enq.ready + + io.deq.bits := q.io.deq.bits.data + io.deq.valid := q.io.deq.valid && ((io.timer - q.io.deq.bits.time) >= delay_r) + q.io.deq.ready := io.deq.fire +} + +object DelayQueue { + /** Helper to connect a delay queue. + * + * @param source decoupled queue input + * @param timer cycle count timer + * @param delay cycle delay + * @param depth queue size + */ + def apply[T <: Data](source: DecoupledIO[T], timer: UInt, delay: UInt, depth: Int): DecoupledIO[T] = { + val delayQueue = Module(new DelayQueue(chiselTypeOf(source.bits), depth)) + delayQueue.io.enq <> source + delayQueue.io.timer := timer + delayQueue.io.delay := delay + delayQueue.io.deq + } + + /** Helper to connect a delay queue and instantiate a timer to keep track of cycle count. + * + * @param source decoupled queue input + * @param timerWidth width of cycle count timer + * @param delay cycle delay + * @param depth queue size + */ + def apply[T <: Data](source: DecoupledIO[T], timerWidth: Int, delay: UInt, depth: Int): DecoupledIO[T] = { + val timer = RegInit(0.U(timerWidth.W)) + timer := timer + 1.U + apply(source, timer, delay, depth) + } + + /** Helper to connect a delay queue that delays elements by a statically defined cycle count. + * + * @param source decoupled queue input + * @param delay static cycle delay + */ + def apply[T <: Data](source: DecoupledIO[T], delay: Int): DecoupledIO[T] = { + val mDelay = delay.max(1) + apply(source, (1 + log2Ceil(mDelay)), delay.U, mDelay) + } + + /** Helper to connect a delay queue that delays elements by a dynamically set cycle count. + * + * @param source decoupled queue input + * @param delay cycle delay + * @param maxDelay maximum cycle delay + */ + def apply[T <: Data](source: DecoupledIO[T], delay: UInt, maxDelay: Int = 4096): DecoupledIO[T] = { + val mDelay = maxDelay.max(1) + apply(source, (1 + log2Ceil(mDelay)), delay, mDelay) + } +} diff --git a/src/main/scala/util/SBox.scala b/src/main/scala/util/SBox.scala deleted file mode 100644 index 210e7ab618..0000000000 --- a/src/main/scala/util/SBox.scala +++ /dev/null @@ -1,344 +0,0 @@ -// SPDX-License-Identifier: Apache-2.0 -// -// This is translated from https://github.com/riscv/riscv-crypto -// -// 2020-01-29 Markku-Juhani O. Saarinen -// Copyright (c) 2020, PQShield Ltd. All rights reserved. -// Converted to Chisel in 2022 - -/* - [BoPe12] Boyar J., Peralta R. "A Small Depth-16 Circuit for the AES - S-Box." Proc.SEC 2012. IFIP AICT 376. Springer, pp. 287-298 (2012) - DOI: https://doi.org/10.1007/978-3-642-30436-1_24 - Preprint: https://eprint.iacr.org/2011/332.pdf - - [Ny93] Nyberg K., "Differentially Uniform Mappings for Cryptography", - Proc. EUROCRYPT '93, LNCS 765, Springer, pp. 55-64 (1993) - DOI: https://doi.org/10.1007/3-540-48285-7_6 -*/ - -package freechips.rocketchip.util - -import chisel3._ - -// top (inner) linear layer for AES -object SBoxAESEncIn { - def apply(x: UInt): UInt = { - val t = Wire(Vec(6, Bool())) - val y = Wire(Vec(21, Bool())) - t( 0) := x( 3) ^ x( 1) - t( 1) := x( 6) ^ x( 5) - t( 2) := x( 6) ^ x( 2) - t( 3) := x( 5) ^ x( 2) - t( 4) := x( 4) ^ x( 0) - t( 5) := x( 1) ^ x( 0) - y( 0) := x( 0) - y( 1) := x( 7) ^ x( 4) - y( 2) := x( 7) ^ x( 2) - y( 3) := x( 7) ^ x( 1) - y( 4) := x( 4) ^ x( 2) - y( 5) := y( 1) ^ t( 0) - y( 6) := x( 0) ^ y( 5) - y( 7) := x( 0) ^ t( 1) - y( 8) := y( 5) ^ t( 1) - y( 9) := y( 3) ^ y( 4) - y(10) := y( 5) ^ t( 2) - y(11) := t( 0) ^ t( 2) - y(12) := t( 0) ^ t( 3) - y(13) := y( 7) ^ y(12) - y(14) := t( 1) ^ t( 4) - y(15) := y( 1) ^ y(14) - y(16) := t( 1) ^ t( 5) - y(17) := y( 2) ^ y(16) - y(18) := y( 2) ^ y( 8) - y(19) := y(15) ^ y(13) - y(20) := y( 1) ^ t( 3) - y.asUInt - } -} - -// top (inner) linear layer for AES^-1 -object SBoxAESDecIn { - def apply(x: UInt): UInt = { - val t = Wire(Vec(5, Bool())) - val y = Wire(Vec(21, Bool())) - t( 0) := x( 1) ^ x( 0) - t( 1) := x( 6) ^ x( 1) - t( 2) := x( 5) ^ ~x( 2) - t( 3) := x( 2) ^ ~x( 1) - t( 4) := x( 5) ^ ~x( 3) - y( 0) := x( 7) ^ t( 2) - y( 1) := x( 4) ^ x( 3) - y( 2) := x( 7) ^ ~x( 6) - y( 3) := y( 1) ^ t( 0) - y( 4) := x( 3) ^ y( 6) - y( 5) := y(16) ^ t( 2) - y( 6) := x( 6) ^ ~y(17) - y( 7) := x( 0) ^ ~y( 1) - y( 8) := y( 2) ^ y(18) - y( 9) := y( 2) ^ t( 0) - y(10) := y( 8) ^ t( 3) - y(11) := y( 8) ^ y(20) - y(12) := t( 1) ^ t( 4) - y(13) := x( 5) ^ ~y(14) - y(14) := y(16) ^ t( 0) - y(15) := y(18) ^ t( 1) - y(16) := x( 6) ^ ~x( 4) - y(17) := x( 7) ^ x( 4) - y(18) := x( 3) ^ ~x( 0) - y(19) := x( 5) ^ ~y( 1) - y(20) := y( 1) ^ t( 3) - y.asUInt - } -} - -// top (inner) linear layer for SM4 -object SBoxSM4In { - def apply(x: UInt): UInt = { - val t = Wire(Vec(7, Bool())) - val y = Wire(Vec(21, Bool())) - t( 0) := x(3) ^ x( 4) - t( 1) := x(2) ^ x( 7) - t( 2) := x(7) ^ y(18) - t( 3) := x(1) ^ t( 1) - t( 4) := x(6) ^ x( 7) - t( 5) := x(0) ^ y(18) - t( 6) := x(3) ^ x( 6) - y( 0) := x(5) ^ ~y(10) - y( 1) := t(0) ^ t( 3) - y( 2) := x(0) ^ t( 0) - y( 3) := x(3) ^ y( 4) - y( 4) := x(0) ^ t( 3) - y( 5) := x(5) ^ t( 5) - y( 6) := x(0) ^ ~x( 1) - y( 7) := t(0) ^ ~y(10) - y( 8) := t(0) ^ t( 5) - y( 9) := x(3) - y(10) := x(1) ^ y(18) - y(11) := t(0) ^ t( 4) - y(12) := x(5) ^ t( 4) - y(13) := x(5) ^ ~y( 1) - y(14) := x(4) ^ ~t( 2) - y(15) := x(1) ^ ~t( 6) - y(16) := x(0) ^ ~t( 2) - y(17) := t(0) ^ ~t( 2) - y(18) := x(2) ^ x( 6) - y(19) := x(5) ^ ~y(14) - y(20) := x(0) ^ t( 1) - y.asUInt - } -} - -// The shared non-linear middle part for AES, AES^-1, and SM4. -object SBoxMid { - def apply(x: UInt): UInt = { - val t = Wire(Vec(46, Bool())) - val y = Wire(Vec(18, Bool())) - t( 0) := x( 3) ^ x(12) - t( 1) := x( 9) & x( 5) - t( 2) := x(17) & x( 6) - t( 3) := x(10) ^ t( 1) - t( 4) := x(14) & x( 0) - t( 5) := t( 4) ^ t( 1) - t( 6) := x( 3) & x(12) - t( 7) := x(16) & x( 7) - t( 8) := t( 0) ^ t( 6) - t( 9) := x(15) & x(13) - t(10) := t( 9) ^ t( 6) - t(11) := x( 1) & x(11) - t(12) := x( 4) & x(20) - t(13) := t(12) ^ t(11) - t(14) := x( 2) & x( 8) - t(15) := t(14) ^ t(11) - t(16) := t( 3) ^ t( 2) - t(17) := t( 5) ^ x(18) - t(18) := t( 8) ^ t( 7) - t(19) := t(10) ^ t(15) - t(20) := t(16) ^ t(13) - t(21) := t(17) ^ t(15) - t(22) := t(18) ^ t(13) - t(23) := t(19) ^ x(19) - t(24) := t(22) ^ t(23) - t(25) := t(22) & t(20) - t(26) := t(21) ^ t(25) - t(27) := t(20) ^ t(21) - t(28) := t(23) ^ t(25) - t(29) := t(28) & t(27) - t(30) := t(26) & t(24) - t(31) := t(20) & t(23) - t(32) := t(27) & t(31) - t(33) := t(27) ^ t(25) - t(34) := t(21) & t(22) - t(35) := t(24) & t(34) - t(36) := t(24) ^ t(25) - t(37) := t(21) ^ t(29) - t(38) := t(32) ^ t(33) - t(39) := t(23) ^ t(30) - t(40) := t(35) ^ t(36) - t(41) := t(38) ^ t(40) - t(42) := t(37) ^ t(39) - t(43) := t(37) ^ t(38) - t(44) := t(39) ^ t(40) - t(45) := t(42) ^ t(41) - y( 0) := t(38) & x( 7) - y( 1) := t(37) & x(13) - y( 2) := t(42) & x(11) - y( 3) := t(45) & x(20) - y( 4) := t(41) & x( 8) - y( 5) := t(44) & x( 9) - y( 6) := t(40) & x(17) - y( 7) := t(39) & x(14) - y( 8) := t(43) & x( 3) - y( 9) := t(38) & x(16) - y(10) := t(37) & x(15) - y(11) := t(42) & x( 1) - y(12) := t(45) & x( 4) - y(13) := t(41) & x( 2) - y(14) := t(44) & x( 5) - y(15) := t(40) & x( 6) - y(16) := t(39) & x( 0) - y(17) := t(43) & x(12) - y.asUInt - } -} - -// bottom (outer) linear layer for AES -object SBoxAESEncOut { - def apply(x: UInt): UInt = { - val t = Wire(Vec(30, Bool())) - val y = Wire(Vec(8, Bool())) - t( 0) := x(11) ^ x(12) - t( 1) := x( 0) ^ x( 6) - t( 2) := x(14) ^ x(16) - t( 3) := x(15) ^ x( 5) - t( 4) := x( 4) ^ x( 8) - t( 5) := x(17) ^ x(11) - t( 6) := x(12) ^ t( 5) - t( 7) := x(14) ^ t( 3) - t( 8) := x( 1) ^ x( 9) - t( 9) := x( 2) ^ x( 3) - t(10) := x( 3) ^ t( 4) - t(11) := x(10) ^ t( 2) - t(12) := x(16) ^ x( 1) - t(13) := x( 0) ^ t( 0) - t(14) := x( 2) ^ x(11) - t(15) := x( 5) ^ t( 1) - t(16) := x( 6) ^ t( 0) - t(17) := x( 7) ^ t( 1) - t(18) := x( 8) ^ t( 8) - t(19) := x(13) ^ t( 4) - t(20) := t( 0) ^ t( 1) - t(21) := t( 1) ^ t( 7) - t(22) := t( 3) ^ t(12) - t(23) := t(18) ^ t( 2) - t(24) := t(15) ^ t( 9) - t(25) := t( 6) ^ t(10) - t(26) := t( 7) ^ t( 9) - t(27) := t( 8) ^ t(10) - t(28) := t(11) ^ t(14) - t(29) := t(11) ^ t(17) - y( 0) := t( 6) ^ ~t(23) - y( 1) := t(13) ^ ~t(27) - y( 2) := t(25) ^ t(29) - y( 3) := t(20) ^ t(22) - y( 4) := t( 6) ^ t(21) - y( 5) := t(19) ^ ~t(28) - y( 6) := t(16) ^ ~t(26) - y( 7) := t( 6) ^ t(24) - y.asUInt - } -} - -// bottom (outer) linear layer for AES^-1 -object SBoxAESDecOut { - def apply(x: UInt): UInt = { - val t = Wire(Vec(30, Bool())) - val y = Wire(Vec(8, Bool())) - t( 0) := x( 2) ^ x(11) - t( 1) := x( 8) ^ x( 9) - t( 2) := x( 4) ^ x(12) - t( 3) := x(15) ^ x( 0) - t( 4) := x(16) ^ x( 6) - t( 5) := x(14) ^ x( 1) - t( 6) := x(17) ^ x(10) - t( 7) := t( 0) ^ t( 1) - t( 8) := x( 0) ^ x( 3) - t( 9) := x( 5) ^ x(13) - t(10) := x( 7) ^ t( 4) - t(11) := t( 0) ^ t( 3) - t(12) := x(14) ^ x(16) - t(13) := x(17) ^ x( 1) - t(14) := x(17) ^ x(12) - t(15) := x( 4) ^ x( 9) - t(16) := x( 7) ^ x(11) - t(17) := x( 8) ^ t( 2) - t(18) := x(13) ^ t( 5) - t(19) := t( 2) ^ t( 3) - t(20) := t( 4) ^ t( 6) - t(21) := 0.U - t(22) := t( 2) ^ t( 7) - t(23) := t( 7) ^ t( 8) - t(24) := t( 5) ^ t( 7) - t(25) := t( 6) ^ t(10) - t(26) := t( 9) ^ t(11) - t(27) := t(10) ^ t(18) - t(28) := t(11) ^ t(25) - t(29) := t(15) ^ t(20) - y( 0) := t( 9) ^ t(16) - y( 1) := t(14) ^ t(23) - y( 2) := t(19) ^ t(24) - y( 3) := t(23) ^ t(27) - y( 4) := t(12) ^ t(22) - y( 5) := t(17) ^ t(28) - y( 6) := t(26) ^ t(29) - y( 7) := t(13) ^ t(22) - y.asUInt - } -} - -// bottom (outer) linear layer for SM4 -object SBoxSM4Out { - def apply(x: UInt): UInt = { - val t = Wire(Vec(30, Bool())) - val y = Wire(Vec(8, Bool())) - t( 0) := x( 4) ^ x( 7) - t( 1) := x(13) ^ x(15) - t( 2) := x( 2) ^ x(16) - t( 3) := x( 6) ^ t( 0) - t( 4) := x(12) ^ t( 1) - t( 5) := x( 9) ^ x(10) - t( 6) := x(11) ^ t( 2) - t( 7) := x( 1) ^ t( 4) - t( 8) := x( 0) ^ x(17) - t( 9) := x( 3) ^ x(17) - t(10) := x( 8) ^ t( 3) - t(11) := t( 2) ^ t( 5) - t(12) := x(14) ^ t( 6) - t(13) := t( 7) ^ t( 9) - t(14) := x( 0) ^ x( 6) - t(15) := x( 7) ^ x(16) - t(16) := x( 5) ^ x(13) - t(17) := x( 3) ^ x(15) - t(18) := x(10) ^ x(12) - t(19) := x( 9) ^ t( 1) - t(20) := x( 4) ^ t( 4) - t(21) := x(14) ^ t( 3) - t(22) := x(16) ^ t( 5) - t(23) := t( 7) ^ t(14) - t(24) := t( 8) ^ t(11) - t(25) := t( 0) ^ t(12) - t(26) := t(17) ^ t( 3) - t(27) := t(18) ^ t(10) - t(28) := t(19) ^ t( 6) - t(29) := t( 8) ^ t(10) - y( 0) := t(11) ^ ~t(13) - y( 1) := t(15) ^ ~t(23) - y( 2) := t(20) ^ t(24) - y( 3) := t(16) ^ t(25) - y( 4) := t(26) ^ ~t(22) - y( 5) := t(21) ^ t(13) - y( 6) := t(27) ^ ~t(12) - y( 7) := t(28) ^ ~t(29) - y.asUInt - } -} diff --git a/torture b/torture deleted file mode 160000 index 99d8b2b441..0000000000 --- a/torture +++ /dev/null @@ -1 +0,0 @@ -Subproject commit 99d8b2b441ecaa18b852505bb7718ee04e2753f5 diff --git a/vsim/.gitignore b/vsim/.gitignore deleted file mode 100644 index 8dca1ac958..0000000000 --- a/vsim/.gitignore +++ /dev/null @@ -1,17 +0,0 @@ -simv* -csrc -*.vpd -*.key -DVE* -.vcs* -timestamp -*.out -*.h -*.log -*.cmd -*.daidir -*.ucli -*.a -*.vcd -generated-src -output diff --git a/vsim/Makefile b/vsim/Makefile deleted file mode 100644 index ec59925c13..0000000000 --- a/vsim/Makefile +++ /dev/null @@ -1,34 +0,0 @@ -#======================================================================= -# Makefile for Verilog simulation w/ VCS -#----------------------------------------------------------------------- -# Yunsup Lee (yunsup@cs.berkeley.edu) -# -# This makefile will build a rtl simulator and run various tests to -# verify proper functionality. -# - -default: all - -base_dir = $(abspath ..) -generated_dir = $(abspath ./generated-src) -mem_gen = $(VLSI_MEM_GEN) -sim_dir = . -output_dir = $(sim_dir)/output - -BACKEND ?= v -TB ?= TestDriver - -include $(base_dir)/Makefrag -include $(sim_dir)/Makefrag -ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),) --include $(generated_dir)/$(long_name).d -endif -include $(base_dir)/vsim/Makefrag-verilog - -all: $(simv) -debug: $(simv_debug) - -clean: - rm -rf $(junk) simv* csrc *.key DVE* *.h *.a *.daidir $(generated_dir) - -.PHONY: default all debug clean diff --git a/vsim/Makefrag b/vsim/Makefrag deleted file mode 100644 index 51d75fc30a..0000000000 --- a/vsim/Makefrag +++ /dev/null @@ -1,90 +0,0 @@ -#-------------------------------------------------------------------- -# Sources -#-------------------------------------------------------------------- - -# Verilog sources - -bb_vsrcs = \ - $(vsrc)/plusarg_reader.v \ - $(vsrc)/ClockDivider2.v \ - $(vsrc)/ClockDivider3.v \ - $(vsrc)/AsyncResetReg.v \ - $(vsrc)/EICG_wrapper.v \ - -sim_vsrcs = \ - $(generated_dir)/$(long_name).v \ - $(generated_dir)/$(long_name).behav_srams.v \ - $(vsrc)/$(TB).v \ - $(vsrc)/SimDTM.v \ - $(vsrc)/SimJTAG.v \ - $(vsrc)/debug_rob.v \ - $(bb_vsrcs) - -# C sources - -sim_csrcs = \ - $(csrc)/SimDTM.cc \ - $(csrc)/SimJTAG.cc \ - $(csrc)/debug_rob.cc \ - $(csrc)/remote_bitbang.cc - -#-------------------------------------------------------------------- -# Build Verilog -#-------------------------------------------------------------------- - -verilog: $(sim_vsrcs) - -.PHONY: verilog - -#-------------------------------------------------------------------- -# Build rules -#-------------------------------------------------------------------- - -VCS = vcs -full64 - -VCS_OPTS = -notice -line +lint=all,noVCDE,noONGS,noUI -error=PCWM-L -timescale=1ns/10ps -quiet \ - +rad +v2k +vcs+lic+wait \ - +vc+list -CC "-I$(VCS_HOME)/include" \ - -CC "-I$(RISCV)/include" \ - -CC "-std=c++17" \ - -CC "-Wl,-rpath,$(RISCV)/lib" \ - $(RISCV)/lib/libfesvr.a \ - -sverilog \ - +incdir+$(generated_dir) \ - +define+CLOCK_PERIOD=1.0 $(sim_vsrcs) $(sim_csrcs) \ - +define+PRINTF_COND=$(TB).printf_cond \ - +define+STOP_COND=!$(TB).reset \ - +define+RANDOMIZE_MEM_INIT \ - +define+RANDOMIZE_REG_INIT \ - +define+RANDOMIZE_GARBAGE_ASSIGN \ - +define+RANDOMIZE_INVALID_ASSIGN \ - +define+RANDOMIZE_DELAY=0.1 \ - +define+MODEL=$(MODEL) \ - +define+FSDB \ - +libext+.v \ - -#-------------------------------------------------------------------- -# Build the simulator -#-------------------------------------------------------------------- - -simv = $(sim_dir)/simv-$(PROJECT)-$(CONFIG_STR) -$(simv) : $(sim_vsrcs) $(sim_csrcs) - cd $(sim_dir) && \ - rm -rf csrc && \ - $(VCS) $(VCS_OPTS) -o $(simv) \ - -debug_pp \ - -simv_debug = $(sim_dir)/simv-$(PROJECT)-$(CONFIG_STR)-debug -$(simv_debug) : $(sim_vsrcs) $(sim_csrcs) - cd $(sim_dir) && \ - rm -rf csrc && \ - $(VCS) $(VCS_OPTS) -o $(simv_debug) \ - +define+DEBUG -debug_pp -debug_access+all -kdb -lca \ - -#-------------------------------------------------------------------- -# Run -#-------------------------------------------------------------------- - -seed = $(shell date +%s) -exec_simv = $(simv) +permissive -q +ntb_random_seed_automatic +permissive-off -exec_simv_debug = $(simv_debug) +permissive -q +ntb_random_seed_automatic +permissive-off diff --git a/vsim/Makefrag-verilog b/vsim/Makefrag-verilog deleted file mode 100644 index fa4dac18f9..0000000000 --- a/vsim/Makefrag-verilog +++ /dev/null @@ -1,60 +0,0 @@ -#-------------------------------------------------------------------- -# Verilog Generation -#-------------------------------------------------------------------- -firrtl = $(generated_dir)/$(long_name).fir -verilog = $(generated_dir)/$(long_name).v - -# If I don't mark these as .SECONDARY then make will delete these internal -# files. -.SECONDARY: $(firrtl) $(verilog) - -$(generated_dir)/%.fir $(generated_dir)/%.d: $(ROCKET_CHIP_JAR) $(bootrom_img) - mkdir -p $(dir $@) - cd $(base_dir) && $(GENERATOR) -td $(generated_dir) -T $(PROJECT).$(MODEL) -C $(CONFIG) - -$(generated_dir)/%.v $(generated_dir)/%.conf: $(generated_dir)/%.fir $(ROCKET_CHIP_JAR) - mkdir -p $(dir $@) - $(FIRRTL) -i $< \ - -o $(generated_dir)/$*.v \ - -X verilog \ - --infer-rw $(MODEL) \ - --repl-seq-mem -c:$(MODEL):-o:$(generated_dir)/$*.conf \ - -faf $(generated_dir)/$*.anno.json \ - -td $(generated_dir)/$(long_name)/ \ - -fct $(subst $(SPACE),$(COMMA),$(FIRRTL_TRANSFORMS)) \ - -$(generated_dir)/$(long_name).behav_srams.v : $(generated_dir)/$(long_name).conf $(mem_gen) - cd $(generated_dir) && \ - rm -f $@ && \ - $(mem_gen) $(generated_dir)/$(long_name).conf >> $@.tmp && \ - mv $@.tmp $@ - -#-------------------------------------------------------------------- -# Run -#-------------------------------------------------------------------- -.PRECIOUS: $(output_dir)/%.vpd - -$(output_dir)/%.run: $(output_dir)/% $(simv) - cd $(sim_dir) && $(exec_simv) +permissive +max-cycles=$(timeout_cycles) +permissive-off $< 2> /dev/null 2> $@ && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.out: $(output_dir)/% $(simv) - cd $(sim_dir) && $(exec_simv) +permissive +verbose +max-cycles=$(timeout_cycles) +permissive-off $< $(disasm) $@ && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.vcd: $(output_dir)/% $(simv_debug) - cd $(sim_dir) && $(exec_simv_debug) +permissive +verbose +vcdfile=$@ +max-cycles=$(timeout_cycles) +permissive-off $< $(disasm) $(patsubst %.vcd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.vpd: $(output_dir)/% $(simv_debug) - cd $(sim_dir) && $(exec_simv_debug) +permissive +verbose +fsdbfile=$@ +max-cycles=$(timeout_cycles) +permissive-off $< $(disasm) $(patsubst %.vpd,%.out,$@) && [ $$PIPESTATUS -eq 0 ] - -$(output_dir)/%.saif: $(output_dir)/% $(simv_debug) - cd $(sim_dir) && rm -f $(output_dir)/pipe-$*.vcd && vcd2saif -input $(output_dir)/pipe-$*.vcd -pipe "$(exec_simv_debug) +permissive +verbose +vcdfile=$(output_dir)/pipe-$*.vcd +max-cycles=$(bmark_timeout_cycles) +permissive-off $<" -output $@ > $(patsubst %.saif,%.out,$@) 2>&1 - -run: run-asm-tests run-bmark-tests -run-debug: run-asm-tests-debug run-bmark-tests-debug -run-fast: run-asm-tests-fast run-bmark-tests-fast - -.PHONY: run-asm-tests run-bmark-tests -.PHONY: run-asm-tests-debug run-bmark-tests-debug -.PHONY: run run-debug run-fast - -junk += $(output_dir)