diff --git a/.circleci/config.yml b/.circleci/config.yml index 9c6e9f80..fe932ecc 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -6,13 +6,13 @@ version: 2.1 parameters: tools-cache-version: type: string - default: "v6" + default: "v9" # default execution env.s executors: main-env: docker: - - image: ucbbar/chipyard-ci-image:9c650dea + - image: ucbbar/chipyard-ci-image:1d51bb90 environment: JVM_OPTS: -Xmx3200m # Customize the JVM maximum heap limit @@ -41,7 +41,7 @@ commands: - save_cache: key: << parameters.tools-version >>-installed-<< pipeline.parameters.tools-cache-version >>-{{ checksum "../<< parameters.tools-version >>.hash" }} paths: - - "/home/riscvuser/<< parameters.tools-version >>-install" + - "/root/<< parameters.tools-version >>-install" ssh-checkout: description: "Add SSH key and checkout code" @@ -95,7 +95,7 @@ commands: - save_cache: key: << parameters.group-key >>-{{ .Branch }}-{{ .Revision }} paths: - - "/home/riscvuser/project" + - "/root/project" run-tests: description: "Run a set of tests" @@ -190,7 +190,7 @@ jobs: - save_cache: key: extra-tests-{{ .Branch }}-{{ .Revision }} paths: - - "/home/riscvuser/project/tests" + - "/root/project/tests" prepare-chipyard-cores: executor: main-env diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 00000000..2358d787 --- /dev/null +++ b/.sbtopts @@ -0,0 +1,2 @@ +-Dsbt.sourcemode=true +-Dsbt.workspace=$PWD/tools diff --git a/build.sbt b/build.sbt index f44eeb66..3123c4b8 100644 --- a/build.sbt +++ b/build.sbt @@ -183,7 +183,7 @@ lazy val testchipipLib = "edu.berkeley.cs" %% "testchipip" % "1.0-020719-SNAPSHO lazy val chipyard = (project in file("generators/chipyard")) .sourceDependency(testchipip, testchipipLib) - .dependsOn(rocketchip, boom, hwacha, sifive_blocks, sifive_cache, utilities, iocell, + .dependsOn(rocketchip, boom, hwacha, sifive_blocks, sifive_cache, iocell, sha3, // On separate line to allow for cleaner tutorial-setup patches dsptools, `rocket-dsptools`, gemmini, icenet, tracegen, cva6, nvdla, sodor) @@ -192,14 +192,10 @@ lazy val chipyard = (project in file("generators/chipyard")) lazy val tracegen = (project in file("generators/tracegen")) .sourceDependency(testchipip, testchipipLib) - .dependsOn(rocketchip, sifive_cache, boom, utilities) + .dependsOn(rocketchip, sifive_cache, boom) .settings(libraryDependencies ++= rocketLibDeps.value) .settings(commonSettings) -lazy val utilities = (project in file("generators/utilities")) - .sourceDependency(testchipip, testchipipLib) - .settings(commonSettings) - lazy val icenet = (project in file("generators/icenet")) .sourceDependency(testchipip, testchipipLib) .dependsOn(rocketchip) diff --git a/common.mk b/common.mk index 00fdae8e..ce0b9e21 100644 --- a/common.mk +++ b/common.mk @@ -18,9 +18,9 @@ HELP_COMPILATION_VARIABLES += \ " EXTRA_SIM_LDFLAGS = additional LDFLAGS for building simulators" \ " EXTRA_SIM_SOURCES = additional simulation sources needed for simulator" \ " EXTRA_SIM_REQS = additional make requirements to build the simulator" \ -" ENABLE_SBT_THIN_CLIENT = if set, use sbt's experimental thin client" +" ENABLE_SBT_THIN_CLIENT = if set, use sbt's experimental thin client (works best with sbtn or sbt script)" -EXTRA_GENERATOR_REQS ?= +EXTRA_GENERATOR_REQS ?= $(BOOTROM_TARGETS) EXTRA_SIM_CXXFLAGS ?= EXTRA_SIM_LDFLAGS ?= EXTRA_SIM_SOURCES ?= @@ -59,7 +59,12 @@ include $(base_dir)/tools/dromajo/dromajo.mk # Prerequisite lists ######################################################################################### # Returns a list of files in directory $1 with file extension $2. -lookup_srcs = $(shell find -L $(1)/ -name target -prune -o -iname "*.$(2)" -print 2> /dev/null) +# If available, use 'fd' to find the list of files, which is faster than 'find'. +ifeq ($(shell which fd),) + lookup_srcs = $(shell find -L $(1)/ -name target -prune -o -iname "*.$(2)" -print 2> /dev/null) +else + lookup_srcs = $(shell fd -L ".*\.$(2)" $(1)) +endif SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools/barstools/iocell fpga/fpga-shells fpga/src) SCALA_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),scala) @@ -80,10 +85,13 @@ else endif ######################################################################################### -# create list of simulation file inputs +# copy over bootrom files ######################################################################################### -$(sim_files): $(call lookup_srcs,$(base_dir)/generators/utilities/src/main/scala,scala) $(SCALA_BUILDTOOL_DEPS) - $(call run_scala_main,utilities,utilities.GenerateSimFiles,-td $(build_dir) -sim $(sim_name)) +$(build_dir): + mkdir -p $@ + +$(BOOTROM_TARGETS): $(build_dir)/bootrom.%.img: $(TESTCHIP_RSRCS_DIR)/testchipip/bootrom/bootrom.%.img | $(build_dir) + cp -f $< $@ ######################################################################################### # create firrtl file rule and variables @@ -157,16 +165,21 @@ verilog: $(sim_vsrcs) ######################################################################################### .PHONY: run-binary run-binary-fast run-binary-debug run-fast +check-binary: +ifeq (,$(BINARY)) + $(error BINARY variable is not set. Set it to the simulation binary) +endif + # run normal binary with hardware-logged insn dissassembly -run-binary: $(output_dir) $(sim) +run-binary: $(output_dir) $(sim) check-binary (set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log) # run simulator as fast as possible (no insn disassembly) -run-binary-fast: $(output_dir) $(sim) +run-binary-fast: $(output_dir) $(sim) check-binary (set -o pipefail && $(NUMA_PREFIX) $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(PERMISSIVE_OFF) $(BINARY) >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log) run-fast: run-asm-tests-fast run-bmark-tests-fast @@ -177,16 +190,19 @@ run-fast: run-asm-tests-fast run-bmark-tests-fast $(binary_hex): $(output_dir) $(BINARY) $(base_dir)/scripts/smartelf2hex.sh $(BINARY) > $(binary_hex) +run-binary-hex: check-binary run-binary-hex: $(output_dir) $(sim) $(binary_hex) run-binary-hex: run-binary run-binary-hex: override LOADMEM_ADDR = 80000000 run-binary-hex: override LOADMEM = $(binary_hex) run-binary-hex: override SIM_FLAGS += +loadmem=$(LOADMEM) +loadmem_addr=$(LOADMEM_ADDR) +run-binary-debug-hex: check-binary run-binary-debug-hex: $(output_dir) $(sim) $(binary_hex) run-binary-debug-hex: run-binary-debug run-binary-debug-hex: override LOADMEM_ADDR = 80000000 run-binary-debug-hex: override LOADMEM = $(binary_hex) run-binary-debug-hex: override SIM_FLAGS += +loadmem=$(LOADMEM) +loadmem_addr=$(LOADMEM_ADDR) +run-binary-fast-hex: check-binary run-binary-fast-hex: $(output_dir) $(sim) $(binary_hex) run-binary-fast-hex: run-binary-fast run-binary-fast-hex: override LOADMEM_ADDR = 80000000 @@ -234,12 +250,17 @@ SBT_COMMAND ?= shell launch-sbt: cd $(base_dir) && $(SBT_NON_THIN) "$(SBT_COMMAND)" +check-thin-client: +ifeq (,$(ENABLE_SBT_THIN_CLIENT)) + $(error ENABLE_SBT_THIN_CLIENT not set.) +endif + .PHONY: shutdown-sbt-server -shutdown-sbt-server: +shutdown-sbt-server: check-thin-client cd $(base_dir) && $(SBT) "shutdown" .PHONY: start-sbt-server -start-sbt-server: +start-sbt-server: check-thin-client cd $(base_dir) && $(SBT) "exit" ######################################################################################### diff --git a/dockerfiles/Dockerfile b/dockerfiles/Dockerfile index d9fcfa0f..1f8ece33 100644 --- a/dockerfiles/Dockerfile +++ b/dockerfiles/Dockerfile @@ -17,19 +17,7 @@ RUN apt-get update && \ keyboard-configuration \ console-setup -# Adds a new user called riscvuser -RUN groupadd --gid 3434 riscvuser \ - && useradd --uid 3434 --gid riscvuser --shell /bin/bash --create-home riscvuser \ - && echo 'riscvuser ALL=NOPASSWD: ALL' >> /etc/sudoers.d/50-riscvuser \ - && echo 'Defaults env_keep += "DEBIAN_FRONTEND"' >> /etc/sudoers.d/env_keep - -WORKDIR /home/riscvuser -USER riscvuser - -# Update PATH for RISCV toolchain (note: hardcoded for CircleCI) -ENV RISCV="/home/riscvuser/riscv-tools-install" -ENV LD_LIBRARY_PATH="$RISCV/lib" -ENV PATH="$RISCV/bin:$PATH" +WORKDIR /root # Install Chipyard and run ubuntu-req.sh to install necessary dependencies RUN git clone https://github.com/ucb-bar/chipyard.git && \ @@ -38,6 +26,10 @@ RUN git clone https://github.com/ucb-bar/chipyard.git && \ ./scripts/ubuntu-req.sh 1>/dev/null && \ sudo rm -rf /var/lib/apt/lists/* +# Update PATH for RISCV toolchain (note: hardcoded for CircleCI) +ENV RISCV="/root/riscv-tools-install" +ENV LD_LIBRARY_PATH="$RISCV/lib" +ENV PATH="$RISCV/bin:$PATH" # BUILD IMAGE WITH TOOLCHAINS diff --git a/docs/Advanced-Concepts/Chip-Communication.rst b/docs/Advanced-Concepts/Chip-Communication.rst index 6e8d2c0e..b63a3885 100644 --- a/docs/Advanced-Concepts/Chip-Communication.rst +++ b/docs/Advanced-Concepts/Chip-Communication.rst @@ -222,4 +222,4 @@ The following image shows this flow: .. image:: ../_static/images/chip-bringup.png In fact, this exact type of bringup setup is what the following section discusses: -:ref:`Prototyping/VCU118:Introduction to the Bringup Platform`. +:ref:`Prototyping/VCU118:Introduction to the Bringup Design`. diff --git a/docs/Chipyard-Basics/Initial-Repo-Setup.rst b/docs/Chipyard-Basics/Initial-Repo-Setup.rst index a3de22b8..1194009f 100644 --- a/docs/Chipyard-Basics/Initial-Repo-Setup.rst +++ b/docs/Chipyard-Basics/Initial-Repo-Setup.rst @@ -16,7 +16,8 @@ In CentOS-based platforms, we recommend installing the following dependencies: .. include:: /../scripts/centos-req.sh :code: bash -In Ubuntu/Debian-based platforms (Ubuntu), we recommend installing the following dependencies: +In Ubuntu/Debian-based platforms (Ubuntu), we recommend installing the following dependencies. +These dependencies were written based on Ubuntu 16.04 LTS and 18.04 LTS - If they don't work for you, you can try out the Docker image (:ref:`Chipyard-Basics/Initial-Repo-Setup:Pre-built Docker Image`) before manually installing or removing dependencies: .. include:: /../scripts/ubuntu-req.sh :code: bash diff --git a/docs/Prototyping/VCU118.rst b/docs/Prototyping/VCU118.rst index 7f8f2cb9..ece3ac82 100644 --- a/docs/Prototyping/VCU118.rst +++ b/docs/Prototyping/VCU118.rst @@ -47,8 +47,8 @@ After the harness is created, the ``BundleBridgeSource``'s must be connected to This is done with harness binders and io binders (see ``fpga/src/main/scala/vcu118/HarnessBinders.scala`` and ``fpga/src/main/scala/vcu118/IOBinders.scala``). For more information on harness binders and io binders, refer to :ref:`Customization/IOBinders:IOBinders and HarnessBinders`. -Introduction to the Bringup Platform ------------------------------------- +Introduction to the Bringup Design +---------------------------------- An example of a more complicated design used for Chipyard test chips can be viewed in ``fpga/src/main/scala/vcu118/bringup/``. This example extends the default test harness and creates new ``Overlays`` to connect to a DUT (connected to the FMC port). @@ -58,3 +58,108 @@ The TSI Host Widget is used to interact with the DUT from the prototype over a S .. Note:: Remember that since whenever a new test harness is created (or the config changes, or the config packages changes, or...), you need to modify the make invocation. For example, ``make SUB_PROJECT=vcu118 CONFIG=MyNewVCU118Config CONFIG_PACKAGE=this.is.my.scala.package bitstream``. See :ref:`Prototyping/General:Generating a Bitstream` for information on the various make variables. + +Running Linux on VCU118 Designs +------------------------------- + +As mentioned above, the default VCU118 harness is setup with a UART and a SPI SDCard. +These are utilized to both interact with the DUT (with the UART) and load in Linux (with the SDCard). +The following steps describe how to build and run buildroot Linux on the prototype platform. + +Building Linux with FireMarshal +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Since the prototype currently does not have a block device setup for it, we build Linux with the rootfs built into the binary (otherwise known as "initramfs" or "nodisk" version of Linux). +To make building this type of Linux binary easy, we will use the FireMarshal platform (see :ref:`fire-marshal` for more information). + +1. Setup FireMarshal (see :ref:`fire-marshal` on the initial setup). +2. By default, FireMarshal is setup to work with FireSim. + Instead, we want to target the prototype platform. + This is done by switching the FireMarshal "board" from "firechip" to "prototype" using ``marshal-config.yaml``: + +.. code-block:: shell + + # this assumes you do not have a `marshal-config.yaml` file already setup + echo "board-dir : 'boards/prototype'" > $PATH_TO_FIREMARSHAL/marshal-config.yaml + +.. Note:: Refer to the FireMarshal docs on more ways to set the board differently through environment variables and more. + +3. Next, build the workload (a.k.a buildroot Linux) in FireMarshal with the ``nodisk`` option flag. + For the rest of these steps, we will assume you are using the base ``br-base.json`` workload. + This workload has basic support for GPIO and SPI drivers (in addition to the default UART driver) but you can build off it in different workloads (refer to FireMarshal docs on workload inheritance). + +.. code-block:: shell + + ./marshal -v -d build br-base.json # here the -d indicates --nodisk or initramfs + +.. Note:: Using the "board" FireMarshal functionality allows any child workload depending on the ``br-base.json`` workload specification to target a "prototype" platform rather than FireChip platform. + Thus, you can re-use existing workloads that depend on ``br-base.json`` on the prototype platform by just changing the "board"! + +4. The last step to generate the proper binary is to flatten it. + This is done by using FireMarshal's ``install`` feature which will produce a ``*-flat`` binary in the ``$PATH_TO_FIREMARSHAL/images`` directory (in our case ``br-base-bin-nodisk-flat``) from the previously built Linux binary (``br-base-bin-nodisk``). + +.. code-block:: shell + + ./marshal -v -d install -t prototype br-base.json + +Setting up the SDCard +~~~~~~~~~~~~~~~~~~~~~ + +These instructions assume that you have a spare uSDCard that can be loaded with Linux and other files using two partitions. +The 1st partition will be used to store the Linux binary (created with FireMarshal or other means) while the 2nd partition will store a file system that can be accessed from the DUT. +Additionally, these instructions assume you are using Linux with ``sudo`` privileges and ``gdisk``, but you can follow a similar set of steps on Mac (using ``gpt`` or another similar program). + +1. Wipe the GPT on the card using ``gdisk``. + Use the `z` command to zap everything. + For rest of these instructions, we assume the SDCard path is ``/dev/sdc`` (replace this with the path to your SDCard). + +.. code-block:: shell + + sudo gdisk /dev/sdc + +2. The VCU118 bootrom assumes that the Linux binary to load into memory will be located on sector 34 of the SDCard. + Change the default partition alignment to `1` so you can write to sector `34`. + Do this with the `l` command. + +3. Create the new GPT with `o`. + Click yes on all the prompts. + +4. Create a 512MiB partition to store the Linux binary (this can be smaller but it must be larger than the size of the Linux binary). + Use `n` and select sector 34, with size `+1048576` (corresponding to 512MiB). + For the type, search for the `apfs` type and use the hex number given. + +5. Create a second partition to store any other files with the rest of the SDCard. + Use `n` and use the defaults for starting sector and overall size (expand the 2nd partition to the rest of the SDCard space). + For the type, search for the `hfs` and use the hex number given. + +6. Write the changes using `w`. + +7. Setup the filesystem on the 2nd partition. + Note that the ``/dev/sdc2`` points to the 2nd partition. + Use the following command: + +.. code-block:: shell + + sudo mkfs.hfs -v "PrototypeData" /dev/sdc2 + +Transfer and Run Linux from the SDCard +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +After you have a Linux boot binary and the SDCard is setup properly (1st partition at sector 34), you can transfer the binary to the 1st SDCard partition. +In this example, we generated a ``br-base-bin-nodisk-flat`` from FireMarshal and we will load it using ``dd``. +Note that ``sdc1`` points to the 1st partition (remember to change the ``sdc`` to your own SDCard path). + +.. code-block:: shell + + sudo dd if=$PATH_TO_FIREMARSHAL/br-base-bin-nodisk-flat of=/dev/sdc1 + +If you want to add files to the 2nd partition, you can also do this now. + +After loading the SDCard with Linux and potentially other files, you can program the FPGA and plug in the SDCard. +To interact with Linux via the UART console, you can connect to the serial port (in this case called ``ttyUSB1``) using something like ``screen``: + +.. code-block:: shell + + screen -S FPGA_UART_CONSOLE /dev/ttyUSB1 115200 + +Once connected, you should see the binary being loaded as well as Linux output (in some cases you might need to reset the DUT). diff --git a/docs/Tools/Barstools.rst b/docs/Tools/Barstools.rst index f669ba8a..fa4176c4 100644 --- a/docs/Tools/Barstools.rst +++ b/docs/Tools/Barstools.rst @@ -31,6 +31,7 @@ This may include over provisioning (e.g. using a 64x1024 SRAM for a requested 60 Arraying can be done in both width and depth, as well as to solve masking constraints. For example, a 128x2048 array could be composed of four 64x1024 arrays, with two macros in parallel to create two 128x1024 virtual SRAMs which are combinationally muxed to add depth. If this macro requires byte-granularity write masking, but no technology SRAMs support masking, then the tool may choose to use thirty-two 8x1024 arrays in a similar configuration. +You may wish to create a cache of your available SRAM macros either manually, or via a script. A reference script for creating a JSON of your SRAM macros is in the `asap7 technology library folder `__. For information on writing ``.mdf`` files, look at `MDF on github `__ and a brief description in :ref:`Tools/Barstools:SRAM MDF Fields` section. The output of MacroCompiler is a Verilog file containing modules that wrap the technology SRAMs into the specified interface names from the ``.conf``. @@ -73,7 +74,6 @@ Likewise, the ``--force-compile [mem]`` option allows the user to force MacroCom SRAM MDF Fields +++++++++++++++ - Technology SRAM macros described in MDF can be defined at three levels of detail. A single instance can be defined with the `SRAMMacro` format. A group of instances that share the number and type of ports but vary in width and depth can be defined with the `SRAMGroup` format. @@ -82,12 +82,14 @@ A set of groups of SRAMs that can be generated together from a single source lik At the most concrete level the `SRAMMAcro` defines a particular instance of an SRAM. That includes its functional attributes such as its width, depth, and number of access ports. These ports can be read, write, or read and write ports, and the instance can have any number. -In order to correctly map to these functional ports to the physical instance each port is described in a list of sub-structures, in the parent instance's structure. +In order to correctly map these functional ports to the physical instance, each port is described in a list of sub-structures, in the parent instance's structure. Each port is only required to have an address and data field, but can have many other optional fields. -These optional fields include a clock, write enable, read enable, chip enable, mask. +These optional fields include a clock, write enable, read enable, chip enable, mask and its granularity. The mask field can have a different granularity than the data field, e.g. it could be a bit mask or a byte mask. Each field must also specify its polarity, whether it is active high or active low. +The specific JSON file format described above is `here `_. A reference cache of SRAMs from the nangate45 technology library is `available here `_. + In addition to these functional descriptions of the SRAM there are also other fields that specify physical/implementation characteristics. These include the threshold voltage, the mux factor, as well as a list of extra non-functional ports. diff --git a/docs/VLSI/Advanced-Usage.rst b/docs/VLSI/Advanced-Usage.rst index b78eda54..2e2961f5 100644 --- a/docs/VLSI/Advanced-Usage.rst +++ b/docs/VLSI/Advanced-Usage.rst @@ -49,6 +49,28 @@ Say you need to update some power straps settings in ``example.yml`` and want to make redo-par HAMMER_REDO_ARGS='-p example.yml --only_step power_straps' -RTL and Gate-level Simulation ------------------------------ -With the Synopsys plugin, RTL and gate-level simulation is supported using VCS. While this example does not implement any simulation, refer to Hammer's documentation for how to set it up for your design. +RTL/Gate-level Simulation, Power Estimation +------------------------------------------- +With the Synopsys plugin, RTL and gate-level simulation is supported using VCS at the chip-level. Also, post-par power estimation with Voltus in the Cadence plugin is also supported. While the provided example does not implement any simulation, some Make targets are provided in the ``vlsi/`` directory. Here is a brief description: + +* ``sim-rtl``: RTL-level simulation + + * ``sim-rtl-debug``: Also write a VPD waveform + +* ``sim-syn``: Post-synthesis gate-level simulation + + * ``sim-syn-debug``: Also write a VPD waveform + * ``sim-syn-timing-debug``: Timing-annotated with VPD waveform + +* ``sim-par``: Post-par gate-level simulation + + * ``sim-par-debug``: Also write a VPD waveform + * ``sim-par-timing-debug``: Timing-annotated with VPD waveform + +* ``power-par``: Post-par power estimation + + * Note: this will run ``sim-par`` first + +* ``redo-`` can be appended to all above targets to break dependency tracking, like described above. + +The simulation configuration (e.g. binaries) can be edited for your design. See the Makefile and refer to Hammer's documentation for how to set up simulation parameters for your design. diff --git a/docs/VLSI/Tutorial.rst b/docs/VLSI/Tutorial.rst index 27e3a039..5a227d52 100644 --- a/docs/VLSI/Tutorial.rst +++ b/docs/VLSI/Tutorial.rst @@ -50,11 +50,11 @@ Prerequisites ------------- * Python 3.4+ -* numpy and gdspy packages +* numpy and gdspy packages. gdspy must be version 1.4. * Genus, Innovus, and Calibre licenses * For ASAP7 specifically: - * Download the `ASAP7 PDK `__ tarball to a directory of choice but do not extract it. The tech plugin is configured to extract the PDK into a cache directory for you. + * Download the `ASAP7 PDK v1p5 `__ tarball to a directory of choice but do not extract it. The tech plugin is configured to extract the PDK into a cache directory for you. * If you have additional ASAP7 hard macros, their LEF & GDS need to be 4x upscaled @ 4000 DBU precision. They may live outside ``extra_libraries`` at your discretion. * Innovus version must be >= 15.2 or <= 18.1 (ISRs excluded). diff --git a/docs/requirements.txt b/docs/requirements.txt index 4b1565b3..ad19f37d 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -1,4 +1,5 @@ Sphinx==1.8.5 -Pygments==2.2.0 +Pygments==2.7.4 sphinx-autobuild sphinx_rtd_theme==0.2.5b1 +docutils==0.16 diff --git a/fpga/Makefile b/fpga/Makefile index 1437d8bc..8b2ed28b 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -73,6 +73,21 @@ default: $(mcs) fpga_dir := $(base_dir)/fpga/fpga-shells/$(FPGA_BRAND) fpga_common_script_dir := $(fpga_dir)/common/tcl +######################################################################################### +# setup misc. sim files +######################################################################################### +SIM_FILE_REQS += \ + $(ROCKETCHIP_RSRCS_DIR)/vsrc/EICG_wrapper.v + +# copy files but ignore *.h files in *.f (match vcs) +$(sim_files): $(SIM_FILE_REQS) | $(build_dir) + cp -f $^ $(build_dir) + $(foreach file,\ + $^,\ + $(if $(filter %.h,$(file)),\ + ,\ + echo "$(addprefix $(build_dir)/, $(notdir $(file)))" >> $@;)) + ######################################################################################### # import other necessary rules and variables ######################################################################################### diff --git a/fpga/src/main/resources/vcu118/sdboot/sd.c b/fpga/src/main/resources/vcu118/sdboot/sd.c index 47c87d5f..f1bdb61e 100644 --- a/fpga/src/main/resources/vcu118/sdboot/sd.c +++ b/fpga/src/main/resources/vcu118/sdboot/sd.c @@ -8,10 +8,12 @@ #define DEBUG #include "kprintf.h" -#define MAX_CORES 8 - -// A sector is 512 bytes, so ((1 << 11) * 512) = 1 MiB -#define PAYLOAD_SIZE (16 << 11) +// Total payload in B +#define PAYLOAD_SIZE_B (30 << 20) // default: 30MiB +// A sector is 512 bytes, so (1 << 11) * 512B = 1 MiB +#define SECTOR_SIZE_B 512 +// Payload size in # of sectors +#define PAYLOAD_SIZE (PAYLOAD_SIZE_B / SECTOR_SIZE_B) // The sector at which the BBL partition starts #define BBL_PARTITION_START_SECTOR 34 @@ -168,9 +170,11 @@ static int copy(void) int rc = 0; dputs("CMD18"); + + kprintf("LOADING 0x%xB PAYLOAD\r\n", PAYLOAD_SIZE_B); kprintf("LOADING "); - // John: Let's go slow until we get this working + // TODO: Speed up SPI freq. (breaks between these two values) //REG32(spi, SPI_REG_SCKDIV) = (F_CLK / 16666666UL); REG32(spi, SPI_REG_SCKDIV) = (F_CLK / 5000000UL); if (sd_cmd(0x52, BBL_PARTITION_START_SECTOR, 0xE1) != 0x00) { @@ -182,7 +186,7 @@ static int copy(void) long n; crc = 0; - n = 512; + n = SECTOR_SIZE_B; while (sd_dummy() != 0xFE); do { uint8_t x = sd_dummy(); diff --git a/fpga/src/main/scala/vcu118/Configs.scala b/fpga/src/main/scala/vcu118/Configs.scala index 8b17aa98..47a22dcf 100644 --- a/fpga/src/main/scala/vcu118/Configs.scala +++ b/fpga/src/main/scala/vcu118/Configs.scala @@ -17,7 +17,7 @@ import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize} import testchipip.{SerialTLKey} -import chipyard.{BuildSystem, ExtTLMem} +import chipyard.{BuildSystem, ExtTLMem, DefaultClockFrequencyKey} class WithDefaultPeripherals extends Config((site, here, up) => { case PeripheryUARTKey => List(UARTParams(address = BigInt(0x64000000L))) @@ -26,11 +26,10 @@ class WithDefaultPeripherals extends Config((site, here, up) => { }) class WithSystemModifications extends Config((site, here, up) => { - case PeripheryBusKey => up(PeripheryBusKey, site).copy(dtsFrequency = Some(site(FPGAFrequencyKey).toInt*1000000)) - case DTSTimebase => BigInt(1000000) + case DTSTimebase => BigInt((1e6).toLong) case BootROMLocated(x) => up(BootROMLocated(x), site).map { p => // invoke makefile for sdboot - val freqMHz = site(FPGAFrequencyKey).toInt * 1000000 + val freqMHz = (site(DefaultClockFrequencyKey) * 1e6).toLong val make = s"make -C fpga/src/main/resources/vcu118/sdboot PBUS_CLK=${freqMHz} bin" require (make.! == 0, "Failed to build bootrom") p.copy(hang = 0x10000, contentFileName = s"./fpga/src/main/resources/vcu118/sdboot/build/sdboot.bin") @@ -41,18 +40,23 @@ class WithSystemModifications extends Config((site, here, up) => { // DOC include start: AbstractVCU118 and Rocket class WithVCU118Tweaks extends Config( + // harness binders new WithUART ++ new WithSPISDCard ++ new WithDDRMem ++ + // io binders new WithUARTIOPassthrough ++ new WithSPIIOPassthrough ++ new WithTLIOPassthrough ++ + // other configuration new WithDefaultPeripherals ++ new chipyard.config.WithTLBackingMemory ++ // use TL backing memory new WithSystemModifications ++ // setup busses, use sdboot bootrom, setup ext. mem. size new chipyard.config.WithNoDebug ++ // remove debug module new freechips.rocketchip.subsystem.WithoutTLMonitors ++ - new freechips.rocketchip.subsystem.WithNMemoryChannels(1)) + new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ + new WithFPGAFrequency(100) // default 100MHz freq +) class RocketVCU118Config extends Config( new WithVCU118Tweaks ++ @@ -64,9 +68,10 @@ class BoomVCU118Config extends Config( new WithVCU118Tweaks ++ new chipyard.MegaBoomConfig) -class WithFPGAFrequency(MHz: Double) extends Config((site, here, up) => { - case FPGAFrequencyKey => MHz -}) +class WithFPGAFrequency(fMHz: Double) extends Config( + new chipyard.config.WithPeripheryBusFrequency(fMHz) ++ // assumes using PBUS as default freq. + new chipyard.config.WithMemoryBusFrequency(fMHz) +) class WithFPGAFreq25MHz extends WithFPGAFrequency(25) class WithFPGAFreq50MHz extends WithFPGAFrequency(50) diff --git a/fpga/src/main/scala/vcu118/TestHarness.scala b/fpga/src/main/scala/vcu118/TestHarness.scala index 45afe7f7..33161b68 100644 --- a/fpga/src/main/scala/vcu118/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/TestHarness.scala @@ -17,12 +17,10 @@ import sifive.blocks.devices.uart._ import sifive.blocks.devices.spi._ import sifive.blocks.devices.gpio._ -import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort} +import chipyard.{HasHarnessSignalReferences, HasTestHarnessFunctions, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey, HasReferenceClockFreq} import chipyard.iobinders.{HasIOBinders} import chipyard.harness.{ApplyHarnessBinders} -case object FPGAFrequencyKey extends Field[Double](100.0) - class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118ShellBasicOverlays { def dp = designParameters @@ -55,7 +53,8 @@ class VCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118S harnessSysPLL := sysClkNode // create and connect to the dutClock - val dutClock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey)) + println(s"VCU118 FPGA Base Clock Freq: ${dp(DefaultClockFrequencyKey)} MHz") + val dutClock = ClockSinkNode(freqMHz = dp(DefaultClockFrequencyKey)) val dutWrangler = LazyModule(new ResetWrangler) val dutGroup = ClockGroup() dutClock := dutWrangler.node := dutGroup := harnessSysPLL @@ -136,4 +135,11 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod _outer.topDesign match { case d: HasIOBinders => ApplyHarnessBinders(this, d.lazySystem, d.portMap) } + + // check the top-level reference clock is equal to the default + // non-exhaustive since you need all ChipTop clocks to equal the default + _outer.topDesign match { + case d: HasReferenceClockFreq => require(d.refClockFreqMHz == p(DefaultClockFrequencyKey)) + case _ => + } } diff --git a/generators/utilities/src/main/resources/csrc/emulator.cc b/generators/chipyard/src/main/resources/csrc/emulator.cc similarity index 100% rename from generators/utilities/src/main/resources/csrc/emulator.cc rename to generators/chipyard/src/main/resources/csrc/emulator.cc diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index a36285eb..a887bc1c 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -15,6 +15,7 @@ import freechips.rocketchip.rocket.{RocketCoreParams, MulDivParams, DCacheParams import freechips.rocketchip.tilelink.{HasTLBusParams} import freechips.rocketchip.util.{AsyncResetReg, Symmetric} import freechips.rocketchip.prci._ +import freechips.rocketchip.stage.phases.TargetDirKey import testchipip._ import tracegen.{TraceGenSystem} @@ -36,7 +37,7 @@ import chipyard._ // ----------------------- class WithBootROM extends Config((site, here, up) => { - case BootROMLocated(x) => up(BootROMLocated(x), site).map(_.copy(contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")) + case BootROMLocated(x) => up(BootROMLocated(x), site).map(_.copy(contentFileName = s"${site(TargetDirKey)}/bootrom.rv${site(XLen)}.img")) }) // DOC include start: gpio config fragment diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index 7fd682d2..3407b4da 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -13,6 +13,8 @@ import freechips.rocketchip.devices.tilelink._ // DOC include start: DigitalTop class DigitalTop(implicit p: Parameters) extends ChipyardSystem + with testchipip.CanHavePeripheryCustomBootPin // Enables optional custom boot pin + with testchipip.HasPeripheryBootAddrReg // Use programmable boot address register with testchipip.CanHaveTraceIO // Enables optionally adding trace IO with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index da497a54..c1ec2bda 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -321,3 +321,9 @@ class WithSimDromajoBridge extends ComposeHarnessBinder({ ports.map { p => p.traces.map(tileTrace => SimDromajoBridge(tileTrace)(system.p)) } } }) + +class WithTieOffCustomBootPin extends OverrideHarnessBinder({ + (system: CanHavePeripheryCustomBootPin, th: HasHarnessSignalReferences, ports: Seq[Bool]) => { + ports.foreach(_ := false.B) + } +}) diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index 5d153834..448d4b72 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -231,7 +231,7 @@ class WithDebugIOCells extends OverrideLazyIOBinder({ d.disableDebug.foreach { d => d := false.B } // Drive JTAG on-chip IOs d.systemjtag.map { j => - j.reset := clockBundle.reset + j.reset := ResetCatchAndSync(j.jtag.TCK, clockBundle.reset.asBool) j.mfr_id := p(JtagDTMKey).idcodeManufId.U(11.W) j.part_number := p(JtagDTMKey).idcodePartNum.U(16.W) j.version := p(JtagDTMKey).idcodeVersion.U(4.W) @@ -372,6 +372,13 @@ class WithTraceIOPunchthrough extends OverrideIOBinder({ } }) +class WithCustomBootPin extends OverrideIOBinder({ + (system: CanHavePeripheryCustomBootPin) => system.custom_boot_pin.map({ p => + val sys = system.asInstanceOf[BaseSubsystem] + val (port, cells) = IOCell.generateIOFromSignal(p.getWrappedValue, "custom_boot", sys.p(IOCellKey), abstractResetAsAsync = true) + (Seq(port), cells) + }).getOrElse((Nil, Nil)) +}) class WithDontTouchPorts extends OverrideIOBinder({ (system: DontTouch) => system.dontTouchPorts(); (Nil, Nil) diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index da84bd05..6660d159 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -21,6 +21,7 @@ class AbstractConfig extends Config( new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present + new chipyard.harness.WithTieOffCustomBootPin ++ // The IOBinders instantiate ChipTop IOs to match desired digital IOs // IOCells are generated for "Chip-like" IOs, while simulation-only IOs are directly punched through @@ -37,6 +38,7 @@ class AbstractConfig extends Config( new chipyard.iobinders.WithSPIIOCells ++ new chipyard.iobinders.WithTraceIOPunchthrough ++ new chipyard.iobinders.WithExtInterruptIOCells ++ + new chipyard.iobinders.WithCustomBootPin ++ new testchipip.WithDefaultSerialTL ++ // use serialized tilelink port to external serialadapter/harnessRAM new chipyard.config.WithBootROM ++ // use default bootrom diff --git a/generators/chipyard/src/test/scala/clocking/SimplePllConfigurationSpec.scala b/generators/chipyard/src/test/scala/clocking/SimplePllConfigurationSpec.scala index 0abe7c50..d80aafc1 100644 --- a/generators/chipyard/src/test/scala/clocking/SimplePllConfigurationSpec.scala +++ b/generators/chipyard/src/test/scala/clocking/SimplePllConfigurationSpec.scala @@ -3,7 +3,7 @@ package chipyard.clocking import freechips.rocketchip.prci._ -class SimplePllConfigurationSpec extends org.scalatest.FlatSpec { +class SimplePllConfigurationSpec extends org.scalatest.flatspec.AnyFlatSpec { def genConf(freqMHz: Iterable[Double]): SimplePllConfiguration = new SimplePllConfiguration( "testPLL", diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index 95594807..79242d2e 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -37,6 +37,17 @@ object NodeIdx { } +/** + * Specifies DUT clocks for the rational clock bridge + * + * @param allClocks Seq. of RationalClocks that want a clock + * + * @param baseClockName Name of domain that the allClocks is rational to + * + * @param baseFreqRequested Freq. for the reference domain in Hz + */ +case class BuildTopClockParameters(allClocks: Seq[RationalClock], baseClockName: String, baseFreqRequested: Double) + /** * Under FireSim's current multiclock implementation there can be only a * single clock bridge. This requires, therefore, that it be instantiated in @@ -48,8 +59,9 @@ class ClockBridgeInstantiator { // Assumes that the supernode implementation results in duplicated clocks // (i.e. only 1 set of clocks is generated for all BuildTop designs) - private val _buildtopClockMap: LinkedHashMap[String, (RationalClock, Clock)] = LinkedHashMap.empty - private var _buildtopRefTuple: Option[(String, Double)] = None + private var _buildTopClockParams: Option[BuildTopClockParameters] = None + private val _buildTopClockMap: LinkedHashMap[String, (RationalClock, Clock)] = LinkedHashMap.empty + private var _buildTopClockRecord: Option[RecordMap[Clock]] = None /** * Request a clock at a particular frequency @@ -65,41 +77,43 @@ class ClockBridgeInstantiator { } /** - * Get a RecordMap of clocks for a set of input RationalClocks + * Get a RecordMap of clocks for a set of input RationalClocks. Used to drive + * the design elaborated by buildtop * - * @param allClocks Seq. of RationalClocks that want a clock - * - * @param baseClockName Name of domain that the allClocks is rational to - * - * @param baseFreqRequested Freq. for the reference domain in Hz + * @param clockMapParameters Defines the set of required clocks */ - def requestClockRecordMap(allClocks: Seq[RationalClock], baseClockName: String, baseFreqRequested: Double): RecordMap[Clock] = { - require(!_buildtopRefTuple.isDefined, "Can only request one RecordMap of Clocks") + def requestClockRecordMap(clockMapParameters: BuildTopClockParameters): RecordMap[Clock] = { + if (_buildTopClockParams.isDefined) { + require(_buildTopClockParams.get == clockMapParameters, "Must request same set of clocks on repeated invocations.") + } else { + val clockRecord = Wire(RecordMap(clockMapParameters.allClocks.map { c => (c.name, Clock()) }:_*)) + // Build up the mutable structures describing the clocks for the dut + _buildTopClockParams = Some(clockMapParameters) + _buildTopClockRecord = Some(clockRecord) - val ratClockRecordMapWire = Wire(RecordMap(allClocks.map { c => (c.name, Clock()) }:_*)) - - _buildtopRefTuple = Some((baseClockName, baseFreqRequested)) - for (clock <- allClocks) { - val clkWire = Wire(new Clock) - _buildtopClockMap(clock.name) = (clock, clkWire) - ratClockRecordMapWire(clock.name).get := clkWire + for (clock <- clockMapParameters.allClocks) { + val clockWire = Wire(new Clock) + _buildTopClockMap(clock.name) = (clock, clockWire) + clockRecord(clock.name).get := clockWire + } } - ratClockRecordMapWire + _buildTopClockRecord.get } /** * Connect all clocks requested to ClockBridge */ def instantiateFireSimClockBridge: Unit = { - require(_buildtopRefTuple.isDefined, "Must have rational clocks to assign to") - require(_buildtopClockMap.exists(_._1 == _buildtopRefTuple.get._1), - s"Provided base-clock name for rational clocks, ${_buildtopRefTuple.get._1}, doesn't match a name within specified rational clocks." + - "Available clocks:\n " + _buildtopClockMap.map(_._1).mkString("\n ")) + require(_buildTopClockParams.isDefined, "Must have rational clocks to assign to") + val BuildTopClockParameters(allClocks, refRatClockName, refRatClockFreq) = _buildTopClockParams.get + require(_buildTopClockMap.exists(_._1 == refRatClockName), + s"Provided base-clock name for rational clocks, ${refRatClockName}, doesn't match a name within specified rational clocks." + + "Available clocks:\n " + _buildTopClockMap.map(_._1).mkString("\n ")) // Simplify the RationalClocks ratio's - val refRatClock = _buildtopClockMap.find(_._1 == _buildtopRefTuple.get._1).get._2._1 - val simpleRatClocks = _buildtopClockMap.map { t => + val refRatClock = _buildTopClockMap.find(_._1 == refRatClockName).get._2._1 + val simpleRatClocks = _buildTopClockMap.map { t => val ratClock = t._2._1 ratClock.copy( multiplier = ratClock.multiplier * refRatClock.divisor, @@ -108,8 +122,7 @@ class ClockBridgeInstantiator { // Determine all the clock dividers (harness + rational clocks) // Note: Requires that the BuildTop reference frequency is requested with proper freq. - val refRatClockFreq = _buildtopRefTuple.get._2 - val refRatSinkParams = ClockSinkParameters(take=Some(ClockParameters(freqMHz=refRatClockFreq / (1000 * 1000))),name=Some(_buildtopRefTuple.get._1)) + val refRatSinkParams = ClockSinkParameters(take=Some(ClockParameters(freqMHz=refRatClockFreq / (1000 * 1000))),name=Some(refRatClockName)) val harSinkParams = _harnessClockMap.map { case (name, (freq, bundle)) => ClockSinkParameters(take=Some(ClockParameters(freqMHz=freq / (1000 * 1000))),name=Some(name)) }.toSeq @@ -144,7 +157,7 @@ class ClockBridgeInstantiator { // Connect all clocks (harness + BuildTop clocks) for (clock <- allAdjRatClks) { val (_, cbClockField) = cbVecTuples.find(_._1.equalFrequency(clock)).get - _buildtopClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField } + _buildTopClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField } _harnessClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField } } } @@ -197,7 +210,10 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => { chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { reset := th.buildtopReset input_clocks := p(ClockBridgeInstantiatorKey) - .requestClockRecordMap(rationalClockSpecs.toSeq, p(FireSimBaseClockNameKey), pllConfig.referenceFreqMHz * (1000 * 1000)) + .requestClockRecordMap(BuildTopClockParameters( + rationalClockSpecs.toSeq, + p(FireSimBaseClockNameKey), + pllConfig.referenceFreqMHz * (1000 * 1000))) Nil }) // return the reference frequency diff --git a/generators/testchipip b/generators/testchipip index fd7760e2..0743c5a9 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit fd7760e2862661bf6277acfeeb42644797e876d0 +Subproject commit 0743c5a9410af713fb7a1c0025d6331dfedec328 diff --git a/generators/utilities/src/main/resources/bootrom b/generators/utilities/src/main/resources/bootrom deleted file mode 120000 index fb0b1375..00000000 --- a/generators/utilities/src/main/resources/bootrom +++ /dev/null @@ -1 +0,0 @@ -../../../../rocket-chip/bootrom \ No newline at end of file diff --git a/generators/utilities/src/main/scala/Simulator.scala b/generators/utilities/src/main/scala/Simulator.scala deleted file mode 100644 index fa157a36..00000000 --- a/generators/utilities/src/main/scala/Simulator.scala +++ /dev/null @@ -1,143 +0,0 @@ -package utilities - -import java.io.File - -case class GenerateSimConfig( - targetDir: String = ".", - dotFName: String = "sim_files.f", - simulator: Option[Simulator] = Some(VerilatorSimulator) -) - -sealed trait Simulator -object VerilatorSimulator extends Simulator -object VCSSimulator extends Simulator - -trait HasGenerateSimConfig { - val parser = new scopt.OptionParser[GenerateSimConfig]("GenerateSimFiles") { - head("GenerateSimFiles", "0.1") - - opt[String]("simulator") - .abbr("sim") - .valueName("") - .action((x, c) => x match { - case "verilator" => c.copy(simulator = Some(VerilatorSimulator)) - case "vcs" => c.copy(simulator = Some(VCSSimulator)) - case "none" => c.copy(simulator = None) - case _ => throw new Exception(s"Unrecognized simulator $x") - }) - .text("Name of simulator to generate files for (verilator, vcs, none)") - - opt[String]("target-dir") - .abbr("td") - .valueName("") - .action((x, c) => c.copy(targetDir = x)) - .text("Target directory to put files") - - opt[String]("dotFName") - .abbr("df") - .valueName("") - .action((x, c) => c.copy(dotFName = x)) - .text("Name of generated dot-f file") - } -} - -object GenerateSimFiles extends App with HasGenerateSimConfig { - def addOption(file: File, cfg: GenerateSimConfig): String = { - val fname = file.getCanonicalPath - // deal with header files - if (fname.takeRight(2) == ".h") { - cfg.simulator match { - // verilator needs to explicitly include verilator.h, so use the -FI option - case Some(VerilatorSimulator) => s"-FI ${fname}" - // vcs pulls headers in with +incdir, doesn't have anything like verilator.h - case Some(VCSSimulator) => "" - case None => "" - } - } else { // do nothing otherwise - fname - } - } - def writeDotF(lines: Seq[String], cfg: GenerateSimConfig): Unit = { - writeTextToFile(lines.mkString("\n"), new File(cfg.targetDir, cfg.dotFName)) - } - // From FIRRTL - def safeFile[A](fileName: String)(code: => A) = try { code } catch { - case e@ (_: java.io.FileNotFoundException | _: NullPointerException) => throw new Exception(fileName, e) - case t: Throwable => throw t - } - // From FIRRTL - def writeResource(name: String, targetDir: String): File = { - val in = getClass.getResourceAsStream(name) - val p = java.nio.file.Paths.get(name) - val fname = p.getFileName().toString(); - - val f = new File(targetDir, fname) - val out = new java.io.FileOutputStream(f) - safeFile(name)(Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write)) - out.close() - f - } - // From FIRRTL - def writeTextToFile(text: String, file: File) { - val out = new java.io.PrintWriter(file) - out.write(text) - out.close() - } - def resources(sim: Option[Simulator]): Seq[String] = Seq( - "/testchipip/csrc/SimSerial.cc", - "/testchipip/csrc/testchip_tsi.cc", - "/testchipip/csrc/testchip_tsi.h", - "/testchipip/csrc/SimDRAM.cc", - "/testchipip/csrc/mm.h", - "/testchipip/csrc/mm.cc", - "/testchipip/csrc/mm_dramsim2.h", - "/testchipip/csrc/mm_dramsim2.cc", - "/csrc/SimDTM.cc", - "/csrc/SimJTAG.cc", - "/csrc/remote_bitbang.h", - "/csrc/remote_bitbang.cc", - "/vsrc/EICG_wrapper.v", - ) ++ (sim match { - case None => Seq() - case _ => Seq( - "/testchipip/csrc/SimSerial.cc", - "/testchipip/csrc/SimDRAM.cc", - "/testchipip/csrc/mm.h", - "/testchipip/csrc/mm.cc", - "/testchipip/csrc/mm_dramsim2.h", - "/testchipip/csrc/mm_dramsim2.cc", - "/csrc/SimDTM.cc", - "/csrc/SimJTAG.cc", - "/csrc/remote_bitbang.h", - "/csrc/remote_bitbang.cc", - ) - }) ++ (sim match { // simulator specific files to include - case Some(VerilatorSimulator) => Seq( - "/csrc/emulator.cc", - "/csrc/verilator.h", - ) - case Some(VCSSimulator) => Seq( - "/vsrc/TestDriver.v", - ) - case None => Seq() - }) - - def writeBootrom(): Unit = { - firrtl.FileUtils.makeDirectory("./bootrom/") - writeResource("/testchipip/bootrom/bootrom.rv64.img", "./bootrom/") - writeResource("/testchipip/bootrom/bootrom.rv32.img", "./bootrom/") - writeResource("/bootrom/bootrom.img", "./bootrom/") - } - - def writeFiles(cfg: GenerateSimConfig): Unit = { - writeBootrom() - firrtl.FileUtils.makeDirectory(cfg.targetDir) - val files = resources(cfg.simulator).map { writeResource(_, cfg.targetDir) } - writeDotF(files.map(addOption(_, cfg)), cfg) - } - - parser.parse(args, GenerateSimConfig()) match { - case Some(cfg) => writeFiles(cfg) - case _ => // error message already shown - } -} diff --git a/project/build.properties b/project/build.properties index 7de0a938..dbae93bc 100644 --- a/project/build.properties +++ b/project/build.properties @@ -1 +1 @@ -sbt.version=1.4.4 +sbt.version=1.4.9 diff --git a/scripts/build-toolchains.sh b/scripts/build-toolchains.sh index ec2920a2..611f50e0 100755 --- a/scripts/build-toolchains.sh +++ b/scripts/build-toolchains.sh @@ -18,11 +18,12 @@ usage() { echo " ec2fast: if set, pulls in a pre-compiled RISC-V toolchain for an EC2 manager instance" echo "" echo "Options" - echo " --prefix PREFIX : Install destination. If unset, defaults to $(pwd)/riscv-tools-install" - echo " or $(pwd)/esp-tools-install" - echo " --ignore-qemu : Ignore installing QEMU" - echo " --arch -a : Architecture (e.g., rv64gc)" - echo " --help -h : Display this message" + echo " --prefix PREFIX : Install destination. If unset, defaults to $(pwd)/riscv-tools-install" + echo " or $(pwd)/esp-tools-install" + echo " --ignore-qemu : Ignore installing QEMU" + echo " --clean-after-install : Run make clean in calls to module_make and module_build" + echo " --arch -a : Architecture (e.g., rv64gc)" + echo " --help -h : Display this message" exit "$1" } @@ -37,6 +38,7 @@ die() { TOOLCHAIN="riscv-tools" EC2FASTINSTALL="false" IGNOREQEMU="" +CLEANAFTERINSTALL="" RISCV="" ARCH="" @@ -51,9 +53,11 @@ do RISCV=$(realpath $1) ;; --ignore-qemu ) IGNOREQEMU="true" ;; - -a | --arch ) - shift - ARCH=$1 ;; + -a | --arch ) + shift + ARCH=$1 ;; + --clean-after-install ) + CLEANAFTERINSTALL="true" ;; riscv-tools | esp-tools) TOOLCHAIN=$1 ;; ec2fast ) @@ -151,7 +155,26 @@ module_all riscv-tests --prefix="${RISCV}/riscv${XLEN}-unknown-elf" --with-xlen= CC= CXX= SRCDIR="$(pwd)/toolchains" module_all libgloss --prefix="${RISCV}/riscv${XLEN}-unknown-elf" --host=riscv${XLEN}-unknown-elf if [ -z "$IGNOREQEMU" ] ; then -SRCDIR="$(pwd)/toolchains" module_all qemu --prefix="${RISCV}" --target-list=riscv${XLEN}-softmmu + echo "=> Starting qemu build" + dir="$(pwd)/toolchains/qemu" + echo "==> Initializing qemu submodule" + #since we don't want to use the global config we init passing rewrite config in to the command + git -c url.https://github.com/qemu.insteadOf=https://git.qemu.org/git submodule update --init --recursive "$dir" + echo "==> Applying url-rewriting to avoid git.qemu.org" + # and once the clones exist, we recurse through them and set the rewrite + # in the local config so that any further commands by the user have the rewrite. uggh. git, why you so ugly? + git -C "$dir" config --local url.https://github.com/qemu.insteadOf https://git.qemu.org/git + git -C "$dir" submodule foreach --recursive 'git config --local url.https://github.com/qemu.insteadOf https://git.qemu.org/git' + + # check to see whether the rewrite rules are needed any more + # If you find git.qemu.org in any .gitmodules file below qemu, you still need them + # the /dev/null redirection in the submodule grepping is to quiet non-existance of further .gitmodules + ! grep -q 'git\.qemu\.org' "$dir/.gitmodules" && \ + git -C "$dir" submodule foreach --quiet --recursive '! grep -q "git\.qemu\.org" .gitmodules 2>/dev/null' && \ + echo "==> PLEASE REMOVE qemu URL-REWRITING from scripts/build-toolchains.sh. It is no longer needed!" && exit 1 + + # now actually do the build + SRCDIR="$(pwd)/toolchains" module_build qemu --prefix="${RISCV}" --target-list=riscv${XLEN}-softmmu fi # make Dromajo diff --git a/scripts/build-util.sh b/scripts/build-util.sh index 892b274d..1af11aee 100644 --- a/scripts/build-util.sh +++ b/scripts/build-util.sh @@ -49,6 +49,9 @@ module_make() ( # cd "${SRCDIR}/${1}/build" shift "${MAKE}" "$@" | tee "build-${1:-make}.log" + if [ -n "$CLEANAFTERINSTALL" ] ; then + "${MAKE}" clean # get rid of intermediate files + fi ) module_build() ( # [configure-arg..] @@ -81,6 +84,9 @@ module_build() ( # [configure-arg..] "${MAKE}" echo "==> Installing ${name}" "${MAKE}" install + if [ -n "$CLEANAFTERINSTALL" ] ; then + "${MAKE}" clean # get rid of intermediate files + fi } 2>&1 | tee build.log ) diff --git a/scripts/centos-req.sh b/scripts/centos-req.sh index 1a1439d1..8c7ac3a0 100755 --- a/scripts/centos-req.sh +++ b/scripts/centos-req.sh @@ -4,15 +4,21 @@ set -ex sudo yum groupinstall -y "Development tools" sudo yum install -y gmp-devel mpfr-devel libmpc-devel zlib-devel vim git java java-devel -curl https://bintray.com/sbt/rpm/rpm | sudo tee /etc/yum.repos.d/bintray-sbt-rpm.repo + +# Install SBT https://www.scala-sbt.org/release/docs/Installing-sbt-on-Linux.html#Red+Hat+Enterprise+Linux+and+other+RPM-based+distributions +# sudo rm -f /etc/yum.repos.d/bintray-rpm.repo +# Use rm above if sbt installed from bintray before. +curl -L https://www.scala-sbt.org/sbt-rpm.repo > sbt-rpm.repo +sudo mv sbt-rpm.repo /etc/yum.repos.d/ + sudo yum install -y sbt texinfo gengetopt sudo yum install -y expat-devel libusb1-devel ncurses-devel cmake "perl(ExtUtils::MakeMaker)" # deps for poky -sudo yum install -y python36 patch diffstat texi2html texinfo subversion chrpath git wget +sudo yum install -y python38 patch diffstat texi2html texinfo subversion chrpath git wget # deps for qemu sudo yum install -y gtk3-devel # deps for firemarshal -sudo yum install -y python36-pip python36-devel rsync libguestfs-tools makeinfo expat ctags +sudo yum install -y python38-pip python38-devel rsync libguestfs-tools makeinfo expat ctags # Install GNU make 4.x (needed to cross-compile glibc 2.28+) sudo yum install -y centos-release-scl sudo yum install -y devtoolset-8-make @@ -24,4 +30,4 @@ sudo yum install -y python git clone http://git.veripool.org/git/verilator cd verilator git checkout v4.034 -autoconf && ./configure && make -j16 && sudo make install +autoconf && ./configure && make -j$(nproc) && sudo make install diff --git a/scripts/entrypoint.sh b/scripts/entrypoint.sh index 41e5bda5..457656e8 100755 --- a/scripts/entrypoint.sh +++ b/scripts/entrypoint.sh @@ -3,6 +3,6 @@ # used with the dockerfile to set up enviroment variables by running env.sh # adapted from https://stackoverflow.com/questions/55921914/how-to-source-a-script-with-environment-variables-in-a-docker-build-process -. /home/riscvuser/chipyard/env.sh +. /root/chipyard/env.sh exec "$@" diff --git a/scripts/tutorial-patches/build.sbt.patch b/scripts/tutorial-patches/build.sbt.patch index 62cecb8d..325bdfae 100644 --- a/scripts/tutorial-patches/build.sbt.patch +++ b/scripts/tutorial-patches/build.sbt.patch @@ -1,17 +1,17 @@ diff --git a/build.sbt b/build.sbt -index e80b2a5..b1989d9 100644 +index 3123c4b8..487fc428 100644 --- a/build.sbt +++ b/build.sbt @@ -184,7 +184,7 @@ lazy val testchipipLib = "edu.berkeley.cs" %% "testchipip" % "1.0-020719-SNAPSHO lazy val chipyard = (project in file("generators/chipyard")) .sourceDependency(testchipip, testchipipLib) - .dependsOn(rocketchip, boom, hwacha, sifive_blocks, sifive_cache, utilities, iocell, + .dependsOn(rocketchip, boom, hwacha, sifive_blocks, sifive_cache, iocell, - sha3, // On separate line to allow for cleaner tutorial-setup patches +// sha3, // On separate line to allow for cleaner tutorial-setup patches dsptools, `rocket-dsptools`, gemmini, icenet, tracegen, cva6, nvdla, sodor) .settings(libraryDependencies ++= rocketLibDeps.value) -@@ -227,11 +227,11 @@ lazy val sodor = (project in file("generators/riscv-sodor")) +@@ -223,11 +223,11 @@ lazy val sodor = (project in file("generators/riscv-sodor")) .settings(libraryDependencies ++= rocketLibDeps.value) .settings(commonSettings) diff --git a/scripts/ubuntu-req.sh b/scripts/ubuntu-req.sh index b33a6649..ff5fe3ad 100755 --- a/scripts/ubuntu-req.sh +++ b/scripts/ubuntu-req.sh @@ -2,26 +2,31 @@ set -ex -sudo apt-get install -y build-essential bison flex -sudo apt-get install -y libgmp-dev libmpfr-dev libmpc-dev zlib1g-dev vim git default-jdk default-jre -# install sbt: https://www.scala-sbt.org/release/docs/Installing-sbt-on-Linux.html -echo "deb https://dl.bintray.com/sbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list +sudo apt-get install -y build-essential bison flex software-properties-common curl +sudo apt-get install -y libgmp-dev libmpfr-dev libmpc-dev zlib1g-dev vim default-jdk default-jre +# install sbt: https://www.scala-sbt.org/release/docs/Installing-sbt-on-Linux.html#Ubuntu+and+other+Debian-based+distributions +echo "deb https://repo.scala-sbt.org/scalasbt/debian /" | sudo tee -a /etc/apt/sources.list.d/sbt.list curl -sL "https://keyserver.ubuntu.com/pks/lookup?op=get&search=0x2EE0EA64E40A89B84B2DF73499E82A75642AC823" | sudo apt-key add sudo apt-get update sudo apt-get install -y sbt sudo apt-get install -y texinfo gengetopt sudo apt-get install -y libexpat1-dev libusb-dev libncurses5-dev cmake # deps for poky -sudo apt-get install -y python3.6 patch diffstat texi2html texinfo subversion chrpath git wget +sudo apt-get install -y python3.8 patch diffstat texi2html texinfo subversion chrpath wget # deps for qemu sudo apt-get install -y libgtk-3-dev gettext # deps for firemarshal -sudo apt-get install -y python3-pip python3.6-dev rsync libguestfs-tools expat ctags +sudo apt-get install -y python3-pip python3.8-dev rsync libguestfs-tools expat ctags # install DTC sudo apt-get install -y device-tree-compiler sudo apt-get install -y python +# install git >= 2.17 +sudo add-apt-repository ppa:git-core/ppa -y +sudo apt-get update +sudo apt-get install git -y # install verilator +sudo apt-get install -y autoconf git clone http://git.veripool.org/git/verilator cd verilator git checkout v4.034 diff --git a/sims/common-sim-flags.mk b/sims/common-sim-flags.mk index 766dd0d3..7c6c580d 100644 --- a/sims/common-sim-flags.mk +++ b/sims/common-sim-flags.mk @@ -21,3 +21,6 @@ SIM_LDFLAGS = \ -lfesvr \ -ldramsim \ $(EXTRA_SIM_LDFLAGS) + +SIM_FILE_REQS += \ + $(ROCKETCHIP_RSRCS_DIR)/vsrc/EICG_wrapper.v diff --git a/sims/vcs/Makefile b/sims/vcs/Makefile index 405cda54..e364830b 100644 --- a/sims/vcs/Makefile +++ b/sims/vcs/Makefile @@ -31,6 +31,21 @@ include $(base_dir)/vcs.mk default: $(sim) debug: $(sim_debug) +######################################################################################### +# simulaton requirements +######################################################################################### +SIM_FILE_REQS += \ + $(ROCKETCHIP_RSRCS_DIR)/vsrc/TestDriver.v + +# copy files but ignore *.h files in *.f since vcs has +incdir+$(build_dir) +$(sim_files): $(SIM_FILE_REQS) | $(build_dir) + cp -f $^ $(build_dir) + $(foreach file,\ + $^,\ + $(if $(filter %.h,$(file)),\ + ,\ + echo "$(addprefix $(build_dir)/, $(notdir $(file)))" >> $@;)) + ######################################################################################### # import other necessary rules and variables ######################################################################################### diff --git a/sims/verilator/Makefile b/sims/verilator/Makefile index 2b250ee9..a1186acc 100644 --- a/sims/verilator/Makefile +++ b/sims/verilator/Makefile @@ -30,6 +30,8 @@ sim_debug = $(sim_dir)/$(sim_prefix)-$(MODEL_PACKAGE)-$(CONFIG)-debug WAVEFORM_FLAG=-v$(sim_out_name).vcd +include $(base_dir)/sims/common-sim-flags.mk + # If verilator seed unspecified, verilator uses srand as random seed ifdef RANDOM_SEED SEED_FLAG=+verilator+seed+I$(RANDOM_SEED) @@ -41,6 +43,37 @@ endif default: $(sim) debug: $(sim_debug) +######################################################################################### +# simulaton requirements +######################################################################################### +SIM_FILE_REQS += \ + $(CHIPYARD_RSRCS_DIR)/csrc/emulator.cc \ + $(ROCKETCHIP_RSRCS_DIR)/csrc/verilator.h \ + +# the following files are needed for emulator.cc to compile +SIM_FILE_REQS += \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/SimSerial.cc \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/testchip_tsi.cc \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/testchip_tsi.h \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/SimDRAM.cc \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/mm.h \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/mm.cc \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/mm_dramsim2.h \ + $(TESTCHIP_RSRCS_DIR)/testchipip/csrc/mm_dramsim2.cc \ + $(ROCKETCHIP_RSRCS_DIR)/csrc/SimDTM.cc \ + $(ROCKETCHIP_RSRCS_DIR)/csrc/SimJTAG.cc \ + $(ROCKETCHIP_RSRCS_DIR)/csrc/remote_bitbang.h \ + $(ROCKETCHIP_RSRCS_DIR)/csrc/remote_bitbang.cc + +# copy files and add -FI for *.h files in *.f +$(sim_files): $(SIM_FILE_REQS) | $(build_dir) + cp -f $^ $(build_dir) + $(foreach file,\ + $^,\ + $(if $(filter %.h,$(file)),\ + echo "-FI $(addprefix $(build_dir)/, $(notdir $(file)))" >> $@;,\ + echo "$(addprefix $(build_dir)/, $(notdir $(file)))" >> $@;)) + ######################################################################################### # import other necessary rules and variables ######################################################################################### @@ -141,8 +174,6 @@ VERILATOR_NONCC_OPTS = \ #---------------------------------------------------------------------------------------- # gcc configuration/optimization #---------------------------------------------------------------------------------------- -include $(base_dir)/sims/common-sim-flags.mk - VERILATOR_CXXFLAGS = \ $(SIM_CXXFLAGS) \ $(RUNTIME_PROFILING_CFLAGS) \ diff --git a/software/firemarshal b/software/firemarshal index aa8e6aa8..22f9101d 160000 --- a/software/firemarshal +++ b/software/firemarshal @@ -1 +1 @@ -Subproject commit aa8e6aa8714d46b74917ebaa91333f5727e34599 +Subproject commit 22f9101d456f36d9580bd3327a1613e39812d06d diff --git a/software/spec2017 b/software/spec2017 index 8f2812be..83e33110 160000 --- a/software/spec2017 +++ b/software/spec2017 @@ -1 +1 @@ -Subproject commit 8f2812bebc15ae36f15cb8b80f4b50aa7d342b46 +Subproject commit 83e33110472c47aaa762257ed7c053ff1278834c diff --git a/tests/charcount.c b/tests/charcount.c index f8b3641b..6a3d2744 100644 --- a/tests/charcount.c +++ b/tests/charcount.c @@ -1,6 +1,6 @@ #include "rocc.h" -char string[64] = "The quick brown fox jumped over the lazy dog"; +char string[64] __attribute__ ((aligned (64))) = "The quick brown fox jumped over the lazy dog"; static inline unsigned long count_chars(char *start, char needle) { diff --git a/variables.mk b/variables.mk index 2843e53e..5d136e80 100644 --- a/variables.mk +++ b/variables.mk @@ -106,9 +106,12 @@ endif ######################################################################################### # path to rocket-chip and testchipip ######################################################################################### -ROCKETCHIP_DIR = $(base_dir)/generators/rocket-chip -TESTCHIP_DIR = $(base_dir)/generators/testchipip -CHIPYARD_FIRRTL_DIR = $(base_dir)/tools/firrtl +ROCKETCHIP_DIR = $(base_dir)/generators/rocket-chip +ROCKETCHIP_RSRCS_DIR = $(ROCKETCHIP_DIR)/src/main/resources +TESTCHIP_DIR = $(base_dir)/generators/testchipip +TESTCHIP_RSRCS_DIR = $(TESTCHIP_DIR)/src/main/resources +CHIPYARD_FIRRTL_DIR = $(base_dir)/tools/firrtl +CHIPYARD_RSRCS_DIR = $(base_dir)/generators/chipyard/src/main/resources ######################################################################################### # names of various files needed to compile and run things @@ -135,7 +138,11 @@ HARNESS_SMEMS_FILE ?= $(build_dir)/$(long_name).harness.mems.v HARNESS_SMEMS_CONF ?= $(build_dir)/$(long_name).harness.mems.conf HARNESS_SMEMS_FIR ?= $(build_dir)/$(long_name).harness.mems.fir +BOOTROM_FILES ?= bootrom.rv64.img bootrom.rv32.img +BOOTROM_TARGETS ?= $(addprefix $(build_dir)/, $(BOOTROM_FILES)) + # files that contain lists of files needed for VCS or Verilator simulation +SIM_FILE_REQS = sim_files ?= $(build_dir)/sim_files.f sim_top_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.top.f sim_harness_blackboxes ?= $(build_dir)/firrtl_black_box_resource_files.harness.f @@ -152,7 +159,10 @@ JAVA_OPTS ?= -Xmx$(JAVA_HEAP_SIZE) -Xss8M -XX:MaxPermSize=256M -Djava.io.tmpdir= # default sbt launch command ######################################################################################### # by default build chisel3/firrtl and other subprojects from source -override SBT_OPTS += -Dsbt.sourcemode=true -Dsbt.workspace=$(base_dir)/tools +SBT_OPTS_FILE := $(base_dir)/.sbtopts +ifneq (,$(wildcard $(SBT_OPTS_FILE))) +override SBT_OPTS += $(subst $$PWD,$(base_dir),$(shell cat $(SBT_OPTS_FILE))) +endif SCALA_BUILDTOOL_DEPS = $(SBT_SOURCES) @@ -161,6 +171,7 @@ SBT_THIN_CLIENT_TIMESTAMP = $(base_dir)/project/target/active.json ifdef ENABLE_SBT_THIN_CLIENT override SCALA_BUILDTOOL_DEPS += $(SBT_THIN_CLIENT_TIMESTAMP) # enabling speeds up sbt loading +# use with sbt script or sbtn to bypass error code issues SBT_CLIENT_FLAG = --client endif diff --git a/vlsi/sim.mk b/vlsi/sim.mk index 6de46a90..92225737 100644 --- a/vlsi/sim.mk +++ b/vlsi/sim.mk @@ -11,6 +11,8 @@ redo-sim-syn: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) redo-sim-syn: override HAMMER_SIM_RUN_DIR = sim-syn-rundir redo-sim-syn-debug: $(SIM_DEBUG_CONF) redo-sim-syn redo-sim-syn-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) +redo-sim-syn-timing-debug: $(SIM_TIMING_CONF) redo-sim-syn-debug +redo-sim-syn-timing-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_TIMING_CONF) redo-sim-par: $(SIM_CONF) redo-sim-par: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) @@ -32,6 +34,8 @@ sim-syn: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF) sim-syn: override HAMMER_SIM_RUN_DIR = sim-syn-rundir sim-syn-debug: $(SIM_DEBUG_CONF) sim-syn sim-syn-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) +sim-syn-timing-debug: $(SIM_TIMING_CONF) sim-syn-debug +sim-syn-timing-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_TIMING_CONF) $(OBJ_DIR)/sim-syn-rundir/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS) sim-par: $(SIM_CONF)