diff --git a/.circleci/check-commit.sh b/.circleci/check-commit.sh index 42b4a093ca..1b59191e71 100755 --- a/.circleci/check-commit.sh +++ b/.circleci/check-commit.sh @@ -90,7 +90,7 @@ else fi search -submodules=("DRAMSim2" "axe" "barstools" "chisel-testers" "dsptools" "firrtl-interpreter" "torture" "treadle") +submodules=("DRAMSim2" "axe" "barstools" "chisel-testers" "dsptools" "rocket-dsp-utils" "firrtl-interpreter" "torture" "treadle") dir="tools" if [ "$CIRCLE_BRANCH" == "master" ] || [ "$CIRCLE_BRANCH" == "dev" ] then diff --git a/.circleci/config.yml b/.circleci/config.yml index b708165877..b6ac717824 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: "v11" # default execution env.s executors: main-env: docker: - - image: ucbbar/chipyard-image:1.0.1 + - 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" @@ -112,7 +112,7 @@ commands: default: "run-tests.sh" timeout: type: string - default: "10m" + default: "25m" steps: - setup-tools: tools-version: "<< parameters.tools-version >>" @@ -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 @@ -231,7 +231,7 @@ jobs: - run-tests: group-key: "group-cores" project-key: "chipyard-hetero" - timeout: "15m" + timeout: "20m" chipyard-boom-run-tests: executor: main-env steps: @@ -287,6 +287,7 @@ jobs: executor: main-env steps: - run-tests: + tools-version: "esp-tools" group-key: "group-accels" project-key: "chipyard-sha3" chipyard-streaming-fir-run-tests: @@ -308,6 +309,7 @@ jobs: tools-version: "esp-tools" group-key: "group-accels" project-key: "chipyard-hwacha" + timeout: "30m" chipyard-gemmini-run-tests: executor: main-env steps: @@ -520,4 +522,3 @@ workflows: - prepare-chipyard-fpga: requires: - install-riscv-toolchain - diff --git a/.circleci/images/Dockerfile b/.circleci/images/Dockerfile deleted file mode 100644 index 7d03185026..0000000000 --- a/.circleci/images/Dockerfile +++ /dev/null @@ -1,216 +0,0 @@ -### Note: This DockerFile is adapted from https://github.com/CircleCI-Public/example-images/openjdk - -FROM openjdk:11.0.1-jdk-sid - -# man directory is missing in some base images -# https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=863199 -RUN apt-get update \ - && mkdir -p /usr/share/man/man1 \ - && apt-get install -y \ - bzip2 \ - ca-certificates \ - curl \ - git \ - gnupg \ - gzip \ - libfl2 \ - libfl-dev \ - locales \ - mercurial \ - netcat \ - net-tools \ - openssh-client \ - parallel \ - sudo \ - tar \ - unzip \ - wget \ - xvfb \ - xxd \ - zip \ - ccache \ - libgoogle-perftools-dev \ - numactl \ - zlib1g - -# Set timezone to UTC by default -RUN ln -sf /usr/share/zoneinfo/Etc/UTC /etc/localtime - -# Use unicode -RUN locale-gen C.UTF-8 || true -ENV LANG=C.UTF-8 - -# install jq -RUN JQ_URL="https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/jq-latest" \ - && curl --silent --show-error --location --fail --retry 3 --output /usr/bin/jq $JQ_URL \ - && chmod +x /usr/bin/jq \ - && jq --version - -# Install Docker - -# Docker.com returns the URL of the latest binary when you hit a directory listing -# We curl this URL and `grep` the version out. -# The output looks like this: - -#> # To install, run the following commands as root: -#> curl -fsSLO https://download.docker.com/linux/static/stable/x86_64/docker-17.05.0-ce.tgz && tar --strip-components=1 -xvzf docker-17.05.0-ce.tgz -C /usr/local/bin -#> -#> # Then start docker in daemon mode: -#> /usr/local/bin/dockerd - -RUN set -ex \ - && export DOCKER_VERSION=$(curl --silent --fail --retry 3 https://download.docker.com/linux/static/stable/x86_64/ | grep -o -e 'docker-[.0-9]*-ce\.tgz' | sort -r | head -n 1) \ - && DOCKER_URL="https://download.docker.com/linux/static/stable/x86_64/${DOCKER_VERSION}" \ - && echo Docker URL: $DOCKER_URL \ - && curl --silent --show-error --location --fail --retry 3 --output /tmp/docker.tgz "${DOCKER_URL}" \ - && ls -lha /tmp/docker.tgz \ - && tar -xz -C /tmp -f /tmp/docker.tgz \ - && mv /tmp/docker/* /usr/bin \ - && rm -rf /tmp/docker /tmp/docker.tgz \ - && which docker \ - && (docker version || true) - -# docker compose -RUN COMPOSE_URL="https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/docker-compose-latest" \ - && curl --silent --show-error --location --fail --retry 3 --output /usr/bin/docker-compose $COMPOSE_URL \ - && chmod +x /usr/bin/docker-compose \ - && docker-compose version - -# install dockerize -RUN DOCKERIZE_URL="https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/dockerize-latest.tar.gz" \ - && curl --silent --show-error --location --fail --retry 3 --output /tmp/dockerize-linux-amd64.tar.gz $DOCKERIZE_URL \ - && tar -C /usr/local/bin -xzvf /tmp/dockerize-linux-amd64.tar.gz \ - && rm -rf /tmp/dockerize-linux-amd64.tar.gz \ - && dockerize --version - -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 - -# BEGIN IMAGE CUSTOMIZATIONS - -# cacerts from OpenJDK 9-slim to workaround http://bugs.java.com/view_bug.do?bug_id=8189357 -# AND https://github.com/docker-library/openjdk/issues/145 -# -# Created by running: -# docker run --rm openjdk:9-slim cat /etc/ssl/certs/java/cacerts | # aws s3 cp - s3://circle-downloads/circleci-images/cache/linux-amd64/openjdk-9-slim-cacerts --acl public-read -RUN if java -fullversion 2>&1 | grep -q '"9.'; then curl --silent --show-error --location --fail --retry 3 --output /etc/ssl/certs/java/cacerts https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/openjdk-9-slim-cacerts; fi - -# Install Maven Version: 3.6.3 -RUN curl --silent --show-error --location --fail --retry 3 --output /tmp/apache-maven.tar.gz https://www.apache.org/dist/maven/maven-3/3.6.3/binaries/apache-maven-3.6.3-bin.tar.gz \ - && tar xf /tmp/apache-maven.tar.gz -C /opt/ \ - && rm /tmp/apache-maven.tar.gz \ - && ln -s /opt/apache-maven-* /opt/apache-maven \ - && /opt/apache-maven/bin/mvn -version - -# Install Ant Version: 1.10.5 -RUN curl --silent --show-error --location --fail --retry 3 --output /tmp/apache-ant.tar.gz https://archive.apache.org/dist/ant/binaries/apache-ant-1.10.5-bin.tar.gz \ - && tar xf /tmp/apache-ant.tar.gz -C /opt/ \ - && ln -s /opt/apache-ant-* /opt/apache-ant \ - && rm -rf /tmp/apache-ant.tar.gz \ - && /opt/apache-ant/bin/ant -version - -ENV ANT_HOME=/opt/apache-ant - -# Install Gradle Version: 5.0 -RUN curl --silent --show-error --location --fail --retry 3 --output /tmp/gradle.zip https://services.gradle.org/distributions/gradle-5.0-bin.zip \ - && unzip -d /opt /tmp/gradle.zip \ - && rm /tmp/gradle.zip \ - && ln -s /opt/gradle-* /opt/gradle \ - && /opt/gradle/bin/gradle -version - -# Install sbt from https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/sbt-latest.tgz -RUN curl --silent --show-error --location --fail --retry 3 --output /tmp/sbt.tgz https://circle-downloads.s3.amazonaws.com/circleci-images/cache/linux-amd64/sbt-latest.tgz \ - && tar -xzf /tmp/sbt.tgz -C /opt/ \ - && rm /tmp/sbt.tgz \ - && /opt/sbt/bin/sbt sbtVersion - -# Install openjfx -RUN apt-get update -RUN apt-get install -y --no-install-recommends openjfx - -# Add build-essential -RUN apt-get install -y build-essential - -# Add RISCV toolchain necessary dependencies -RUN apt-get update -RUN apt-get install -y \ - autoconf \ - automake \ - autotools-dev \ - babeltrace \ - bc \ - curl \ - device-tree-compiler \ - expat \ - flex \ - gawk \ - gperf \ - g++ \ - libexpat-dev \ - libgmp-dev \ - libmpc-dev \ - libmpfr-dev \ - libtool \ - libusb-1.0-0-dev \ - make \ - patchutils \ - pkg-config \ - python \ - python-pexpect-doc \ - python3 \ - texinfo \ - zlib1g-dev \ - rsync - -# Use specific bison version to bypass Verilator 4.034 issues -# TODO: When Verilator is bumped, use apt to get newest bison -RUN wget https://ftp.gnu.org/gnu/bison/bison-3.5.4.tar.gz \ - && tar -xvf bison-3.5.4.tar.gz \ - && cd bison-3.5.4 \ - && ./configure && make && make install - -# Check bison version is 3.5.4 -RUN bison --version - -# Add minimal QEMU dependencies -RUN apt-get install -y \ - libfdt-dev \ - libglib2.0-dev \ - libpixman-1-dev - -# Install verilator -RUN git clone http://git.veripool.org/git/verilator \ - && cd verilator \ - && git pull \ - && git checkout v4.034 \ - && autoconf && ./configure && make && make install - -# Update PATH for Java tools -ENV PATH="/opt/sbt/bin:/opt/apache-maven/bin:/opt/apache-ant/bin:/opt/gradle/bin:$PATH" - -# Add HOME environment variable -ENV HOME="/home/riscvuser" - -# Update PATH for RISCV toolchain (note: hardcoded for CircleCI) -ENV RISCV="$HOME/riscv-tools-install" -ENV LD_LIBRARY_PATH="$RISCV/lib" -ENV PATH="$RISCV/bin:$PATH" - -WORKDIR $HOME -USER riscvuser - -# smoke test with path -RUN mvn -version \ - && ant -version \ - && gradle -version \ - && sbt sbtVersion \ - && verilator --version - -# remove extra folders -RUN rm -rf project/ - -# END IMAGE CUSTOMIZATIONS - -CMD ["/bin/sh"] diff --git a/.circleci/images/README.md b/.circleci/images/README.md deleted file mode 100644 index a2172ba27f..0000000000 --- a/.circleci/images/README.md +++ /dev/null @@ -1,18 +0,0 @@ -General -------- -This DockerFile contains the necessary steps to build a Docker container that can run -projects with riscv-tools, chisel3, firrtl, and verilator. It installs the necessary -apt-get packages and sets the environment variables needed in CircleCI. - -Build and Deploy the Container ------------------------------- - - sudo docker build . # to test build before building it with a tag - sudo docker build -t :tag . # to build with tag (ex. 0.0.3) - sudo docker login # login into the account to push to - sudo docker push :tag # to push to repo with tag - -Path Names ----------- -Older docker images (when this Dockerfile was in `riscv-boom/riscv-boom`) can be found in the `riscvboom/riscvboom-images`. -Current up-to-date images are located in `ucbbar/chipyard-image` diff --git a/.circleci/run-tests.sh b/.circleci/run-tests.sh index 5ea53c7826..ab3cf5ccf1 100755 --- a/.circleci/run-tests.sh +++ b/.circleci/run-tests.sh @@ -65,8 +65,11 @@ case $1 in $LOCAL_SIM_DIR/simulator-chipyard-GemminiRocketConfig $GEMMINI_SOFTWARE_DIR/build/bareMetalC/mvin_mvout-baremetal ;; chipyard-sha3) + export RISCV=$LOCAL_ESP_DIR + export LD_LIBRARY_PATH=$LOCAL_ESP_DIR/lib + export PATH=$RISCV/bin:$PATH (cd $LOCAL_CHIPYARD_DIR/generators/sha3/software && ./build.sh) - $LOCAL_SIM_DIR/simulator-chipyard-Sha3RocketConfig $LOCAL_CHIPYARD_DIR/generators/sha3/software/benchmarks/bare/sha3-rocc.riscv + $LOCAL_SIM_DIR/simulator-chipyard-Sha3RocketConfig $LOCAL_CHIPYARD_DIR/generators/sha3/software/tests/bare/sha3-rocc.riscv ;; chipyard-streaming-passthrough) make -C $LOCAL_CHIPYARD_DIR/tests diff --git a/.gitmodules b/.gitmodules index 6f99f693bd..6e5288e6cd 100644 --- a/.gitmodules +++ b/.gitmodules @@ -134,3 +134,9 @@ [submodule "fpga/fpga-shells"] path = fpga/fpga-shells url = https://github.com/sifive/fpga-shells.git +[submodule "tools/api-config-chipsalliance"] + path = tools/api-config-chipsalliance + url = https://github.com/chipsalliance/api-config-chipsalliance.git +[submodule "tools/rocket-dsp-utils"] + path = tools/rocket-dsp-utils + url = https://github.com/ucb-bar/rocket-dsp-utils diff --git a/.java_tmp/.gitignore b/.java_tmp/.gitignore new file mode 100644 index 0000000000..5e7d2734cf --- /dev/null +++ b/.java_tmp/.gitignore @@ -0,0 +1,4 @@ +# Ignore everything in this directory +* +# Except this file +!.gitignore diff --git a/.sbtopts b/.sbtopts new file mode 100644 index 0000000000..2358d78748 --- /dev/null +++ b/.sbtopts @@ -0,0 +1,2 @@ +-Dsbt.sourcemode=true +-Dsbt.workspace=$PWD/tools diff --git a/CHANGELOG.md b/CHANGELOG.md index 749c925b33..b28fe77db2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,47 @@ This changelog follows the format defined here: https://keepachangelog.com/en/1.0.0/ +## [1.5.0] - 2021-06-13 + +A more detailed account of everything included is included in the dev to master PR for this release: https://github.com/ucb-bar/chipyard/pull/773 + +### Added +* FireMarshal support for FPGA prototypes (#849) +* Hammer update to include power estimation flows, rail analysis, hierarchical sim support, and improved ASAP7 plugin with dummy SRAMs (#886) +* Docker image +* Support specifying architecture when building tools. (#802) +* Add Config fragments: WithMultiRoCCFromBuildRoCC, PMP (#809, #821) +* Add support for simulating an AXI memory interface over the default TL serial link (#812) +* Add option to add async queues between chip-serialIO and harness serdes (#828) +* Spike support for multiple extensions, and add sha3 spike model to esp-tools (#837, #897) +* Default generator support for I2C and PWM (#885) + +### Changed +* Gemmini bump to version 0.5 +* FireSim bump to version 1.12 +* FireMarshal bump to version 1.12 +* Changes default FireSim frequency from 3.2 GHz (dual clock domains) to 1 GHz (single clock domain) +* Bump pygments from 2.2.0 to 2.7.4 in docs +* Hammer tutorial example is now a TinyRocketConfig (#886) +* Sha3 Spike model moved from sha3 repo to esp-isa-sim + +### Fixed +* Avoid permissions conflict on shared protocjar.webcache (#774) +* Passing MBus clock frequency to SimDRAM (#790) +* Fix parsing of --ignore-qemu option (#791) +* FPGA Prototype - Support Adding Pullup R's to Bringup GPIOs (#806) +* Use "tile" instead of "core" to assign frequencies in WithTileFrequency config. fragment (#807) +* Fix IOCell generation for clock and reset to use IOCellKey (#824) +* Fix TileResetCtrl to be ahead of reset synchronizers (#826) +* Fix memory alignment in character count RoCC test (#853) +* Synchronize JTAG reset to JTAG.TCK. (#859) +* Updates to system requirements scripts (#874) +* Rocket-dsp-utils integration and cleanup for dsptools (#888) + +### Removed +* Dummy DCO collateral from Hammer tutorial example (#886) + + ## [1.4.0] - 2021-01-19 A more detailed account of everything included is included in the dev to master PR for this release: https://github.com/ucb-bar/chipyard/pull/599 diff --git a/README.md b/README.md index 1263bf37f0..d364a7422e 100644 --- a/README.md +++ b/README.md @@ -50,6 +50,7 @@ If used for research, please cite Chipyard by the following publication: * **Chipyard** * A. Amid, et al. *IEEE Micro'20* [PDF](https://ieeexplore.ieee.org/document/9099108). * A. Amid, et al. *DAC'20* [PDF](https://ieeexplore.ieee.org/document/9218756). + * A. Amid, et al. *ISCAS'21* [PDF](https://ieeexplore.ieee.org/abstract/document/9401515). These additional publications cover many of the internal components used in Chipyard. However, for the most up-to-date details, users should refer to the Chipyard docs. @@ -57,6 +58,7 @@ These additional publications cover many of the internal components used in Chip * **Rocket Chip**: K. Asanovic, et al., *UCB EECS TR*. [PDF](http://www2.eecs.berkeley.edu/Pubs/TechRpts/2016/EECS-2016-17.pdf). * **BOOM**: C. Celio, et al., *Hot Chips 30*. [PDF](https://www.hotchips.org/hc30/1conf/1.03_Berkeley_BROOM_HC30.Berkeley.Celio.v02.pdf). * **SonicBOOM (BOOMv3)**: J. Zhao, et al., *CARRV'20*. [PDF](https://carrv.github.io/2020/papers/CARRV2020_paper_15_Zhao.pdf). + * **COBRA (BOOM Branch Prediction)**: J. Zhao, et al., *ISPASS'21*. [PDF](https://ieeexplore.ieee.org/document/9408173). * **Hwacha**: Y. Lee, et al., *ESSCIRC'14*. [PDF](http://hwacha.org/papers/riscv-esscirc2014.pdf). * **Gemmini**: H. Genc, et al., *arXiv*. [PDF](https://arxiv.org/pdf/1911.09925). * **Sims** @@ -69,12 +71,13 @@ These additional publications cover many of the internal components used in Chip * **Chisel**: J. Bachrach, et al., *DAC'12*. [PDF](https://people.eecs.berkeley.edu/~krste/papers/chisel-dac2012.pdf). * **FIRRTL**: A. Izraelevitz, et al., *ICCAD'17*. [PDF](https://ieeexplore.ieee.org/document/8203780). * **Chisel DSP**: A. Wang, et al., *DAC'18*. [PDF](https://ieeexplore.ieee.org/document/8465790). + * **FireMarshal**: N. Pemberton, et al., *ISPASS'21*. [PDF](https://ieeexplore.ieee.org/document/9408192). * **VLSI** * **Hammer**: E. Wang, et al., *ISQED'20*. [PDF](https://www.isqed.org/English/Archives/2020/Technical_Sessions/113.html). -[hwacha]:http://hwacha.org +[hwacha]:https://www2.eecs.berkeley.edu/Pubs/TechRpts/2015/EECS-2015-262.pdf [hammer]:https://github.com/ucb-bar/hammer [firesim]:https://fires.im [ucb-bar]: http://bar.eecs.berkeley.edu diff --git a/build.sbt b/build.sbt index f44eeb66b8..d3e99cc981 100644 --- a/build.sbt +++ b/build.sbt @@ -183,23 +183,19 @@ 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`, + dsptools, `rocket-dsp-utils`, gemmini, icenet, tracegen, cva6, nvdla, sodor) .settings(libraryDependencies ++= rocketLibDeps.value) .settings(commonSettings) 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) @@ -282,8 +278,16 @@ lazy val dsptools = freshProject("dsptools", file("./tools/dsptools")) "org.scalacheck" %% "scalacheck" % "1.14.3" % "test", )) -lazy val `rocket-dsptools` = freshProject("rocket-dsptools", file("./tools/dsptools/rocket")) - .dependsOn(rocketchip, dsptools) +lazy val `api-config-chipsalliance` = freshProject("api-config-chipsalliance", file("./tools/api-config-chipsalliance")) + .settings( + commonSettings, + libraryDependencies ++= Seq( + "org.scalatest" %% "scalatest" % "3.0.+" % "test", + "org.scalacheck" %% "scalacheck" % "1.14.3" % "test", + )) + +lazy val `rocket-dsp-utils` = freshProject("rocket-dsp-utils", file("./tools/rocket-dsp-utils")) + .dependsOn(rocketchip, `api-config-chipsalliance`, dsptools) .settings(libraryDependencies ++= rocketLibDeps.value) .settings(commonSettings) diff --git a/common.mk b/common.mk index 00fdae8e41..ce0b9e2111 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 new file mode 100644 index 0000000000..1f8ece33e4 --- /dev/null +++ b/dockerfiles/Dockerfile @@ -0,0 +1,59 @@ +### This is a full chipyard setup + +# BUILD BASE FOR CI + +FROM ubuntu:18.04 as base +ARG CHIPYARD_HASH + +MAINTAINER https://groups.google.com/forum/#!forum/chipyard + +# Install dependencies for ubuntu-req.sh +RUN apt-get update && \ + DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends \ + curl \ + git \ + sudo \ + ca-certificates \ + keyboard-configuration \ + console-setup + +WORKDIR /root + +# Install Chipyard and run ubuntu-req.sh to install necessary dependencies +RUN git clone https://github.com/ucb-bar/chipyard.git && \ + cd chipyard && \ + git checkout $CHIPYARD_HASH && \ + ./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 + +# Use above build as base +FROM base as base-with-tools + +# Init submodules +RUN cd chipyard && \ + export MAKEFLAGS=-"j $(nproc)" && \ + ./scripts/init-submodules-no-riscv-tools.sh 1>/dev/null + +# Install riscv-tools +RUN cd chipyard && \ + export MAKEFLAGS=-"j $(nproc)" && \ + ./scripts/build-toolchains.sh riscv-tools 1>/dev/null + +# Install esp-tools +RUN cd chipyard && \ + export MAKEFLAGS=-"j $(nproc)" && \ + ./scripts/build-toolchains.sh esp-tools 1>/dev/null + +# Run script to set environment variables on entry +ENTRYPOINT ["chipyard/scripts/entrypoint.sh"] + +# END IMAGE CUSTOMIZATIONS + +CMD ["/bin/sh"] diff --git a/dockerfiles/README.md b/dockerfiles/README.md new file mode 100644 index 0000000000..09ede71513 --- /dev/null +++ b/dockerfiles/README.md @@ -0,0 +1,22 @@ +General +------- +This DockerFile contains the necessary steps to build a Docker container that can run +projects with riscv-tools, chisel3, firrtl, and verilator. When run up to the base stage, it installs the necessary +apt-get packages and sets the environment variables needed for CircleCI. When run up to the base-with-tools stage, it initializes and installs the necessary toolchains for running simulations and testing projects. + +Build and Deploy the Container +------------------------------ + + sudo docker build --target base . # to build the image for the CI + sudo docker build --target base --build-arg CHIPYARD_HASH= . # to build the image for the CI from a specific chipyard commit + sudo docker build --target base-with-tools . # to build the full image + sudo docker tag :tag . # to tag the image after the build (ex. 0.0.3) + sudo docker login # login into the account to push to + sudo docker push :tag # to push to repo with tag + sudo docker run -it bash # to run an interactive version of the container + +Path Names +---------- +Older docker images (when this Dockerfile was in `riscv-boom/riscv-boom`) can be found in the `riscvboom/riscvboom-images`. +Current up-to-date images are located in `ucbbar/chipyard-image`. NOTE: Less recent images in this path may not have toolchains initialized +Current up-to-date CI images are located in `ucbbar/chipyard-ci-image`. diff --git a/docs/Advanced-Concepts/Chip-Communication.rst b/docs/Advanced-Concepts/Chip-Communication.rst index 50c5ac9a1d..b63a38855b 100644 --- a/docs/Advanced-Concepts/Chip-Communication.rst +++ b/docs/Advanced-Concepts/Chip-Communication.rst @@ -7,7 +7,7 @@ There are two types of DUTs that can be made: `tethered` or `standalone` DUTs. A `tethered` DUT is where a host computer (or just host) must send transactions to the DUT to bringup a program. This differs from a `standalone` DUT that can bringup itself (has its own bootrom, loads programs itself, etc). An example of a tethered DUT is a Chipyard simulation where the host loads the test program into the DUTs memory and signals to the DUT that the program is ready to run. -An example of a standalone DUT is a Chipyard simulation where a program can be loaded from an SDCard by default. +An example of a standalone DUT is a Chipyard simulation where a program can be loaded from an SDCard out of reset. In this section, we mainly describe how to communicate to tethered DUTs. There are two ways the host (otherwise known as the outside world) can communicate with a tethered Chipyard DUT: @@ -45,33 +45,21 @@ Using the Tethered Serial Interface (TSI) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ By default, Chipyard uses the Tethered Serial Interface (TSI) to communicate with the DUT. -TSI protocol is an implementation of HTIF that is used to send commands to the -RISC-V DUT. These TSI commands are simple R/W commands -that are able to probe the DUT's memory space. During simulation, the host sends TSI commands to a -simulation stub called ``SimSerial`` (C++ class) that resides in a ``SimSerial`` Verilog module -(both are located in the ``generators/testchipip`` project). This ``SimSerial`` Verilog module then -sends the TSI command recieved by the simulation stub into the DUT which then converts the TSI -command into a TileLink request. This conversion is done by the ``SerialAdapter`` module -(located in the ``generators/testchipip`` project). In simulation, FESVR -resets the DUT, writes into memory the test program, and indicates to the DUT to start the program -through an interrupt (see :ref:`customization/Boot-Process:Chipyard Boot Process`). Using TSI is currently the fastest -mechanism to communicate with the DUT in simulation. - -In the case of a chip tapeout bringup, TSI commands can be sent over a custom communication -medium to communicate with the chip. For example, some Berkeley tapeouts have a FPGA -with a RISC-V soft-core that runs FESVR. The FESVR on the soft-core sends TSI commands -to a TSI-to-TileLink converter living on the FPGA (i.e. ``SerialAdapter``). After the transaction is -converted to TileLink, the ``TLSerdesser`` (located in ``generators/testchipip``) serializes the -transaction and sends it to the chip (this ``TLSerdesser`` is sometimes also referred to as a -serial-link or serdes). Once the serialized transaction is received on the -chip, it is deserialized and masters a bus on the chip. The following image shows this flow: - -.. image:: ../_static/images/chip-bringup.png - -.. note:: - The ``TLSerdesser`` can also be used as a slave (client), so it can sink memory requests from the chip - and connect to off-chip backing memory. Or in other words, ``TLSerdesser`` creates a bi-directional TileLink - interface. +TSI protocol is an implementation of HTIF that is used to send commands to the RISC-V DUT. +These TSI commands are simple R/W commands that are able to access the DUT's memory space. +During simulation, the host sends TSI commands to a simulation stub in the test harness called ``SimSerial`` +(C++ class) that resides in a ``SimSerial`` Verilog module (both are located in the ``generators/testchipip`` +project). +This ``SimSerial`` Verilog module then sends the TSI command recieved by the simulation stub +to an adapter that converts the TSI command into a TileLink request. +This conversion is done by the ``SerialAdapter`` module (located in the ``generators/testchipip`` project). +After the transaction is converted to TileLink, the ``TLSerdesser`` (located in ``generators/testchipip``) serializes the +transaction and sends it to the chip (this ``TLSerdesser`` is sometimes also referred to as a digital serial-link or SerDes). +Once the serialized transaction is received on the chip, it is deserialized and masters a TileLink bus on the chip +which handles the request. +In simulation, FESVR resets the DUT, writes into memory the test program, and indicates to the DUT to start the program +through an interrupt (see :ref:`customization/Boot-Process:Chipyard Boot Process`). +Using TSI is currently the fastest mechanism to communicate with the DUT in simulation (compared to DMI/JTAG) and is also used by FireSim. Using the Debug Module Interface (DMI) ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ @@ -90,14 +78,14 @@ command into a TileLink request. This conversion is done by the DTM named ``Debu When the DTM receives the program to load, it starts to write the binary byte-wise into memory. This is considerably slower than the TSI protocol communication pipeline (i.e. ``SimSerial``/``SerialAdapter``/TileLink) which directly writes the program binary to memory. -Thus, Chipyard removes the DTM by default in favor of the TSI protocol for DUT communication. Starting the TSI or DMI Simulation ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -All default Chipyard configurations use TSI to communicate between the simulation and the simulated SoC/DUT. Hence, when running a -software RTL simulation, as is indicated in the :ref:`simulation/Software-RTL-Simulation:Software RTL Simulation` section, you are in-fact using TSI to communicate with the DUT. As a -reminder, to run a software RTL simulation, run: +All default Chipyard configurations use TSI to communicate between the simulation and the simulated SoC/DUT. +Hence, when running a software RTL simulation, as is indicated in the +:ref:`simulation/Software-RTL-Simulation:Software RTL Simulation` section, you are in-fact using TSI to communicate with the DUT. +As a reminder, to run a software RTL simulation, run: .. code-block:: bash @@ -105,11 +93,10 @@ reminder, to run a software RTL simulation, run: # or cd sims/vcs - make CONFIG=LargeBoomConfig run-asm-tests - -FireSim FPGA-accelerated simulations use TSI by default as well. + make CONFIG=RocketConfig run-asm-tests -If you would like to build and simulate a Chipyard configuration with a DTM configured for DMI communication, then you must tie-off the TSI interface, and instantiate the `SimDTM`. Note that we use `WithTiedOffSerial ++ WithSimDebug` instead of `WithTiedOffDebug ++ WithSimSerial`. +If you would like to build and simulate a Chipyard configuration with a DTM configured for DMI communication, +then you must tie-off the serial-link interface, and instantiate the `SimDTM`. .. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala :language: scala @@ -129,14 +116,110 @@ Then you can run simulations with the new DMI-enabled top-level and test-harness Using the JTAG Interface ------------------------ -The main way to use JTAG with a Rocket Chip based system is to instantiate the Debug Transfer Module (DTM) -and configure it to use a JTAG interface. The default Chipyard designs instantiate the DTM and configure it -to use JTAG. You may attach OpenOCD and GDB to any of the default JTAG-enabled designs. +Another way to interface with the DUT is to use JTAG. +Similar to the :ref:`Advanced-Concepts/Chip-Communication:Using the Debug Module interface (DMI)` section, in order to use the JTAG protocol, +the DUT needs to contain a Debug Transfer Module (DTM) configured to use JTAG instead of DMI. +Once the JTAG port is exposed, the host can communicate over JTAG to the DUT through a simulation stub +called ``SimJTAG`` (C++ class) that resides in a ``SimJTAG`` Verilog module (both reside in the ``generators/rocket-chip`` project). +This simulation stub creates a socket that OpenOCD and GDB can connect to when the simulation is running. +The default Chipyard designs instantiate the DTM configured to use JTAG (i.e. ``RocketConfig``). + +.. note:: + As mentioned, default Chipyard designs are enabled with JTAG. + However, they also use TSI/Serialized-TL with FESVR in case the JTAG interface isn't used. + This allows users to choose how to communicate with the DUT (use TSI or JTAG). Debugging with JTAG -~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ +~~~~~~~~~~~~~~~~~~~ + +Roughly the steps to debug with JTAG in simulation are as follows: + +1. Build a Chipyard JTAG-enabled RTL design. Remember default Chipyard designs are JTAG ready. + +.. code-block:: bash + + cd sims/verilator + # or + cd sims/vcs + + make CONFIG=RocketConfig + +2. Run the simulation with remote bit-bang enabled. Since we hope to load/run the binary using JTAG, + we can pass ``none`` as a binary (prevents FESVR from loading the program). (Adapted from: https://github.com/chipsalliance/rocket-chip#3-launch-the-emulator) + +.. code-block:: bash + + # note: this uses Chipyard make invocation to run the simulation to properly wrap the simulation args + make CONFIG=RocketConfig BINARY=none SIM_FLAGS="+jtag_rbb_enable=1 --rbb-port=9823" run-binary -Please refer to the following resources on how to debug with JTAG. +3. `Follow the instructions here to connect to the simulation using OpenOCD + GDB. `__ + +.. note:: + This section was adapted from the instruction in Rocket Chip and riscv-isa-sim. For more information refer + to that documentation: `Rocket Chip GDB Docs `__, + `riscv-isa-sim GDB Docs `__ + +Example Test Chip Bringup Communication +--------------------------------------- + +Intro to Typical Chipyard Test Chip +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Most, if not all, Chipyard configurations are tethered using TSI (over a serial-link) and have access +to external memory through an AXI port (backing AXI memory). +The following image shows the DUT with these set of default signals: + +.. image:: ../_static/images/default-chipyard-config-communication.png + +In this setup, the serial-link is connected to the TSI/FESVR peripherals while the AXI port is connected +to a simulated AXI memory. +However, AXI ports tend to have many signals, and thus wires, associated with them so instead of creating an AXI port off the DUT, +one can send the memory transactions over the bi-directional serial-link (``TLSerdesser``) so that the main +interface to the DUT is the serial-link (which has comparatively less signals than an AXI port). +This new setup (shown below) is a typical Chipyard test chip setup: + +.. image:: ../_static/images/bringup-chipyard-config-communication.png + +Simulation Setup of the Example Test Chip +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +To test this type of configuration (TSI/memory transactions over the serial-link), most of the same TSI collateral +would be used. +The main difference is that the TileLink-to-AXI converters and simulated AXI memory resides on the other side of the +serial-link. + +.. image:: ../_static/images/chip-bringup-simulation.png + +.. note:: + Here the simulated AXI memory and the converters can be in a different clock domain in the test harness + than the reference clock of the DUT. + For example, the DUT can be clocked at 3.2GHz while the simulated AXI memory can be clocked at 1GHz. + This functionality is done in the harness binder that instantiates the TSI collateral, TL-to-AXI converters, + and simulated AXI memory. + See :ref:`Advanced-Concepts/Harness-Clocks:Creating Clocks in the Test Harness` on how to generate a clock + in a harness binder. + +This type of simulation setup is done in the following multi-clock configuration: + +.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala + :language: scala + :start-after: DOC include start: MulticlockAXIOverSerialConfig + :end-before: DOC include end: MulticlockAXIOverSerialConfig + +Bringup Setup of the Example Test Chip after Tapeout +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +Assuming this example test chip is taped out and now ready to be tested, we can communicate with the chip using this serial-link. +For example, a common test setup used at Berkeley to evaluate Chipyard-based test-chips includes an FPGA running a RISC-V soft-core that is able to speak to the DUT (over an FMC). +This RISC-V soft-core would serve as the host of the test that will run on the DUT. +This is done by the RISC-V soft-core running FESVR, sending TSI commands to a ``SerialAdapter`` / ``TLSerdesser`` programmed on the FPGA. +Once the commands are converted to serialized TileLink, then they can be sent over some medium to the DUT +(like an FMC cable or a set of wires connecting FPGA outputs to the DUT board). +Similar to simulation, if the chip requests offchip memory, it can then send the transaction back over the serial-link. +Then the request can be serviced by the FPGA DRAM. +The following image shows this flow: + +.. image:: ../_static/images/chip-bringup.png -* https://github.com/chipsalliance/rocket-chip#-debugging-with-gdb -* https://github.com/riscv/riscv-isa-sim#debugging-with-gdb +In fact, this exact type of bringup setup is what the following section discusses: +:ref:`Prototyping/VCU118:Introduction to the Bringup Design`. diff --git a/docs/Advanced-Concepts/Harness-Clocks.rst b/docs/Advanced-Concepts/Harness-Clocks.rst new file mode 100644 index 0000000000..ef2249749e --- /dev/null +++ b/docs/Advanced-Concepts/Harness-Clocks.rst @@ -0,0 +1,38 @@ +.. _harness-clocks: + +Creating Clocks in the Test Harness +=================================== + +Chipyard currently allows the SoC design (everything under ``ChipTop``) to +have independent clock domains through diplomacy. +This implies that some reference clock enters the ``ChipTop`` and then is divided down into +separate clock domains. +From the perspective of the ``TestHarness`` module, the ``ChipTop`` clock and reset is +provided from a clock and reset called ``buildtopClock`` and ``buildtopReset``. +In the default case, this ``buildtopClock`` and ``buildtopReset`` is directly wired to the +clock and reset IO's of the ``TestHarness`` module. +However, the ``TestHarness`` has the ability to generate a standalone clock and reset signal +that is separate from the reference clock/reset of ``ChipTop``. +This allows harness components (including harness binders) the ability to "request" a clock +for a new clock domain. +This is useful for simulating systems in which modules in the harness have independent clock domains +from the DUT. + +Requests for a harness clock is done by the ``HarnessClockInstantiator`` class in ``generators/chipyard/src/main/scala/TestHarness.scala``. +This class is accessed in harness components by referencing the Rocket Chip parameters key ``p(HarnessClockInstantiatorKey)``. +Then you can request a clock and syncronized reset at a particular frequency by invoking the ``requestClockBundle`` function. +Take the following example: + +.. literalinclude:: ../../generators/chipyard/src/main/scala/HarnessBinders.scala + :language: scala + :start-after: DOC include start: HarnessClockInstantiatorEx + :end-before: DOC include end: HarnessClockInstantiatorEx + +Here you can see the ``p(HarnessClockInstantiatorKey)`` is used to request a clock and reset at ``memFreq`` frequency. + +.. note:: + In the case that the reference clock entering ``ChipTop`` is not the overall reference clock of the simulation + (i.e. the clock/reset coming into the ``TestHarness`` module), the ``buildtopClock`` and ``buildtopReset`` can + differ from the implicit ``TestHarness`` clock and reset. For example, if the ``ChipTop`` reference is 500MHz but an + extra harness clock is requested at 1GHz, the ``TestHarness`` implicit clock/reset will be at 1GHz while the ``buildtopClock`` + and ``buildtopReset`` will be at 500MHz. diff --git a/docs/Advanced-Concepts/index.rst b/docs/Advanced-Concepts/index.rst index 12b1271629..b294d11b52 100644 --- a/docs/Advanced-Concepts/index.rst +++ b/docs/Advanced-Concepts/index.rst @@ -14,4 +14,5 @@ They expect you to know about Chisel, Parameters, configs, etc. Debugging-BOOM Resources CDEs + Harness-Clocks diff --git a/docs/Chipyard-Basics/Initial-Repo-Setup.rst b/docs/Chipyard-Basics/Initial-Repo-Setup.rst index 78301088d8..1194009ff9 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 @@ -66,6 +67,22 @@ You can put this in your ``.bashrc`` or equivalent environment setup file to get These variables need to be set for the ``make`` system to work properly. +Pre-built Docker Image +------------------------------------------- + +An alternative to setting up the Chipyard repository locally is to pull the pre-built Docker image from Docker Hub. The image comes with all dependencies installed, Chipyard cloned, and toolchains initialized. This image sets up baseline Chipyard (not including FireMarshal, FireSim, and Hammer initializations). Each image comes with a tag that corresponds to the version of Chipyard cloned/set-up in that image. Not including a tag during the pull will pull the image with the latest version of Chipyard. +First, pull the Docker image. Run: + +.. code-block:: shell + + sudo docker pull ucbbar/chipyard-image: + +To run the Docker container in an interactive shell, run: + +.. code-block:: shell + + sudo docker run -it ucbbar/chipyard-image bash + What's Next? ------------------------------------------- diff --git a/docs/Customization/Heterogeneous-SoCs.rst b/docs/Customization/Heterogeneous-SoCs.rst index 6ff88129c3..7e31108bb0 100644 --- a/docs/Customization/Heterogeneous-SoCs.rst +++ b/docs/Customization/Heterogeneous-SoCs.rst @@ -17,8 +17,8 @@ The following example shows a dual core BOOM with a single core Rocket. .. literalinclude:: ../../generators/chipyard/src/main/scala/config/HeteroConfigs.scala :language: scala - :start-after: DOC include start: DualBoomAndRocket - :end-before: DOC include end: DualBoomAndRocket + :start-after: DOC include start: DualBoomAndSingleRocket + :end-before: DOC include end: DualBoomAndSingleRocket Adding Hwachas @@ -48,7 +48,7 @@ An example is shown below with two BOOM cores, and one Rocket tile with a RoCC a :start-after: DOC include start: DualBoomAndRocketOneHwacha :end-before: DOC include end: DualBoomAndRocketOneHwacha -The ``WithMultiRoCCHwacha`` config fragment assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``2`` corresponds to the Rocket core). +The ``WithMultiRoCCHwacha`` config fragment assigns a Hwacha accelerator to a particular ``hartId`` (in this case, the ``hartId`` of ``0`` corresponds to the Rocket core). Finally, the ``WithMultiRoCC`` config fragment is called. This config fragment sets the ``BuildRoCC`` key to use the ``MultiRoCCKey`` instead of the default. This must be used after all the RoCC parameters are set because it needs to override the ``BuildRoCC`` parameter. @@ -56,6 +56,29 @@ If this is used earlier in the configuration sequence, then MultiRoCC does not w This config fragment can be changed to put more accelerators on more cores by changing the arguments to cover more ``hartId``'s (i.e. ``WithMultiRoCCHwacha(0,1,3,6,...)``). +Since config fragments are applied from right-to-left (or bottom-to-top as they are formatted here), the right-most config fragment specifying a core (which is ``freechips.rocketchip.subsystem.WithNBigCores`` in the example above) gets the first hart ID. +Consider this config: + +.. code-block:: scala + + class RocketThenBoomHartIdTestConfig extends Config( + new boom.common.WithNLargeBooms(2) ++ + new freechips.rocketchip.subsystem.WithNBigCores(3) ++ + new chipyard.config.AbstractConfig) + +This specifies an SoC with three Rocket cores and two BOOM cores. +The Rocket cores would have hart IDs 0, 1, and 2, while the BOOM cores would have hard IDs 3 and 4. +On the other hand, consider this config which reverses the order of those two fragments: + +.. code-block:: scala + + class BoomThenRocketHartIdTestConfig extends Config( + new freechips.rocketchip.subsystem.WithNBigCores(3) ++ + new boom.common.WithNLargeBooms(2) ++ + new chipyard.config.AbstractConfig) + +This also specifies an SoC with three Rocket cores and two BOOM cores, but because the BOOM config fragment is evaluated before the Rocket config fragment, the hart IDs are reversed. +The BOOM cores would have hart IDs 0 and 1, while the Rocket cores would have hard IDs 2, 3, and 4. .. [1] Note, in this section "core" and "tile" are used interchangeably but there is subtle distinction between a "core" and "tile" ("tile" contains a "core", L1D/I$, PTW). For many places in the documentation, we usually use "core" to mean "tile" (doesn't make a large difference but worth the mention). diff --git a/docs/Prototyping/VCU118.rst b/docs/Prototyping/VCU118.rst index 7f8f2cb90e..ece3ac821e 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 6bd8f0363d..fa4176c453 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. @@ -100,7 +102,7 @@ Separating the Top module from the TestHarness module Unlike the FireSim and Software simulation flows, a VLSI flow needs to separate the test harness and the chip (a.k.a. DUT) into separate files. This is necessary to facilitate post-synthesis and post-place-and-route simulation, as the module names in the RTL and gate-level verilog files would collide. -Simulations after you the design goes through a VLSI flow will use the verilog netlist generated from the flow and will need an untouched test harness to drive it. +Simulations, after your design goes through a VLSI flow, will use the verilog netlist generated from the flow and will need an untouched test harness to drive it. Separating these components into separate files makes this straightforward. Without the separation the file that included the test harness would also redefine the DUT which is often disallowed in simulation tools. To do this, there is a FIRRTL ``App`` in :ref:`Tools/Barstools:Barstools` called ``GenerateTopAndHarness``, which runs the appropriate transforms to elaborate the modules separately. diff --git a/docs/VLSI/Advanced-Usage.rst b/docs/VLSI/Advanced-Usage.rst index b78eda54fe..2e2961f579 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/Basic-Flow.rst b/docs/VLSI/Basic-Flow.rst index 27178a5422..20d36de1fd 100644 --- a/docs/VLSI/Basic-Flow.rst +++ b/docs/VLSI/Basic-Flow.rst @@ -63,17 +63,19 @@ We will do so by calling ``make buildfile`` with appropriate Chipyard configurat As in the rest of the Chipyard flows, we specify our SoC configuration using the ``CONFIG`` make variable. However, unlike the rest of the Chipyard flows, in the case of physical design we might be interested in working in a hierarchical fashion and therefore we would like to work on a single module. Therefore, we can also specify a ``VLSI_TOP`` make variable with the same of a specific Verilog module (which should also match the name of the equivalent Chisel module) which we would like to work on. -The makefile will automatically call tools such as Barstools and the MacroCopmiler (:ref:`Tools/Barstools:barstools`) in order to make the generated Verilog more VLSI friendly. -By default, the MacroCopmiler will attempt to map memories into the SRAM options within the Hammer technology plugin. However, if you are wokring with a new process technology are prefer to work with flipflop arrays, you can configure the MacroCompiler using the ``MACROCOMPILER_MODE`` make variable. For example, the ASAP7 process technology does not have associated SRAMs, and therefore the ASAP7 Hammer tutorial (:ref:`tutorial`) uses the ``MACROCOMPILER_MODE='--mode synflops'`` option (Note that synthesizing a design with only flipflops is very slow and will often may not meet constraints). +The makefile will automatically call tools such as Barstools and the MacroCompiler (:ref:`Tools/Barstools:barstools`) in order to make the generated Verilog more VLSI friendly. +By default, the MacroCompiler will attempt to map memories into the SRAM options within the Hammer technology plugin. However, if you are working with a new process technology and prefer to work with flip-flop arrays, you can configure the MacroCompiler using the ``MACROCOMPILER_MODE`` make variable. For example, if your technology plugin does not have an SRAM compiler ready, you can use the ``MACROCOMPILER_MODE='--mode synflops'`` option (Note that synthesizing a design with only flipflops is very slow and will often may not meet constraints). We call the ``make buildfile`` command while also specifying the name of the process technology we are working with (same ``tech_name`` for the configuration files and plugin name) and the configuration files we created. Note, in the ASAP7 tutorial ((:ref:`tutorial`)) these configuration files are merged into a single file called ``example-asap7.yml``. Hence, if we want to monolithically place and route the entire SoC, the relevant command would be + .. code-block:: shell make buildfile CONFIG= tech_name= INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml" -In a more typical scenario of working on a single module, for example the Gemmini accelerator within the GemminiRocketConfig Chipyard SoC configuration, the relevant command would be +In a more typical scenario of working on a single module, for example the Gemmini accelerator within the GemminiRocketConfig Chipyard SoC configuration, the relevant command would be: + .. code-block:: shell make buildfile CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml" @@ -89,12 +91,14 @@ Synthesis In order to run synthesis, we run ``make syn`` with the matching Make variables. Post-synthesis logs and collateral will be saved in ``build//syn-rundir``. The raw QoR data (area, timing, gate counts, etc.) will be found in ``build//syn-rundir/reports``. -Hence, if we want to monolithically synthesize the entire SoC, the relevant command would be +Hence, if we want to monolithically synthesize the entire SoC, the relevant command would be: + .. code-block:: shell make syn CONFIG= tech_name= INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml" -In a more typical scenario of working on a single module, for example the Gemmini accelerator within the GemminiRocketConfig Chipyard SoC configuration, the relevant command would be +In a more typical scenario of working on a single module, for example the Gemmini accelerator within the GemminiRocketConfig Chipyard SoC configuration, the relevant command would be: + .. code-block:: shell make syn CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml" @@ -108,7 +112,8 @@ In order to run place-and-route, we run ``make par`` with the matching Make vari Post-PnR logs and collateral will be saved in ``build//par-rundir``. Specifically, the resulting GDSII file will be in that directory with the suffix ``*.gds``. and timing reports can be found in ``build//par-rundir/timingReports``. Place-and-route is requires more design details in contrast to synthesis. For example, place-and-route requires some basic floorplanning constraints. The default ``example-design.yml`` configuration file template allows the tool (specifically, the Cadence Innovus tool) to use it's automatic floorplanning capability within the top level of the design (``ChipTop``). However, if we choose to place-and-route a specific block which is not the SoC top level, we need to change the top-level path name to match the ``VLSI_TOP`` make parameter we are using. -Hence, if we want to monolitically place-and-route the entire SoC with the default tech plug-in parameters for power-straps and corners, the relevant command would be +Hence, if we want to monolitically place-and-route the entire SoC with the default tech plug-in parameters for power-straps and corners, the relevant command would be: + .. code-block:: shell make par CONFIG= tech_name= INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml" @@ -130,7 +135,8 @@ In a more typical scenario of working on a single module, for example the Gemmin top: 0 bottom: 0 -The relevant ``make`` command would then be +The relevant ``make`` command would then be: + .. code-block:: shell make par CONFIG=GemminiRocketConfig VLSI_TOP=Gemmini tech_name=tsmintel3 INPUT_CONFS="example-design.yml example-tools.yml example-tech.yml" diff --git a/docs/VLSI/Hammer.rst b/docs/VLSI/Hammer.rst index ddfc071b48..df803b1db2 100644 --- a/docs/VLSI/Hammer.rst +++ b/docs/VLSI/Hammer.rst @@ -43,6 +43,8 @@ The types of tools (by Hammer names) supported currently include: * drc * lvs * sram_generator +* sim +* power * pcb Several configuration variables are needed to configure your tool plugin of choice. diff --git a/docs/VLSI/Tutorial.rst b/docs/VLSI/Tutorial.rst index 27e3a039a0..38eee0b507 100644 --- a/docs/VLSI/Tutorial.rst +++ b/docs/VLSI/Tutorial.rst @@ -9,7 +9,7 @@ Project Structure This example gives a suggested file structure and build system. The ``vlsi/`` folder will eventually contain the following files and folders: -* Makefile +* Makefile, sim.mk, power.mk * Integration of Hammer's build system into Chipyard and abstracts away some Hammer commands. @@ -26,17 +26,13 @@ This example gives a suggested file structure and build system. The ``vlsi/`` fo * Entry point to Hammer. Contains example placeholders for hooks. -* example.v - - * Verilog wrapper around the accelerator and dummy hard macro. - -* example-asap7.yml +* example-asap7.yml, example-tools.yml * Hammer IR for this tutorial. -* extra_libraries +* example-design.yml, example-nangate45.yml, example-tech.yml - * Contains collateral for the dummy hard macro. + * Hammer IR not used for this tutorial but provided as templates. * generated-src @@ -46,15 +42,19 @@ This example gives a suggested file structure and build system. The ``vlsi/`` fo * Core, tool, tech repositories. +* view_gds.py + + * A convenience script to view a layout using gdspy. Note that this will be very slow for large layouts (e.g. a Rocket core)! + 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. Note: v1p5 of the PDK is not publicly available, and you will need to contact the developers for it. The v1p7 version that is `publicly released `__ currently has several critical issues which prevent it from being fully integrated into the Hammer flow. * 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). @@ -78,17 +78,13 @@ Pull the Hammer environment into the shell: Building the Design -------------------- -To elaborate the ``Sha3RocketConfig`` (Rocket Chip w/ the accelerator) and set up all prerequisites for the build system to push just the accelerator + hard macro through the flow: +To elaborate the ``TinyRocketConfig`` and set up all prerequisites for the build system to push the design and SRAM macros through the flow: .. code-block:: shell - make buildfile MACROCOMPILER_MODE='--mode synflops' CONFIG=Sha3RocketConfig VLSI_TOP=Sha3AccelwBB - -The ``MACROCOMPILER_MODE='--mode synflops'`` is needed because the ASAP7 process does not yet have a memory compiler, so flip-flop arrays are used instead. This will dramatically increase the synthesis runtime if your design has a lot of memory state (e.g. large caches). This change is automatically inferred by the makefile but is included here for completeness. + make buildfile CONFIG=TinyRocketConfig -The ``CONFIG=Sha3RocketConfig`` selects the target generator config in the same manner as the rest of the Chipyard framework. This elaborates a Rocket Chip with the Sha3Accel module. - -The ``VLSI_TOP=Sha3AccelwBB`` indicates that we are only interested in physical design of the accelerator block. If this variable is not set, the entire SoC will be pushed through physical design. Note that you should not set the ``TOP`` variable because it is used during Chisel elaboration. +The ``CONFIG=TinyRocketConfig`` selects the target generator config in the same manner as the rest of the Chipyard framework. This elaborates a stripped-down Rocket Chip in the interest of minimizing tool runtime. For the curious, ``make buildfile`` generates a set of Make targets in ``build/hammer.d``. It needs to be re-run if environment variables are changed. It is recommended that you edit these variables directly in the Makefile rather than exporting them to your shell environment. @@ -105,13 +101,13 @@ example.yml ^^^^^^^^^^^ This contains the Hammer configuration for this example project. Example clock constraints, power straps definitions, placement constraints, and pin constraints are given. Additional configuration for the extra libraries and tools are at the bottom. -First, set ``technology.asap7.tarball_dir`` to the absolute path of where the downloaded the ASAP7 PDK tarball lives. +First, set ``technology.asap7.tarball_dir`` to the absolute path to the directory where the downloaded the ASAP7 PDK tarball lives. Synthesis ^^^^^^^^^ .. code-block:: shell - make syn + make syn CONFIG=TinyRocketConfig Post-synthesis logs and collateral are in ``build/syn-rundir``. The raw QoR data is available at ``build/syn-rundir/reports``, and methods to extract this information for design space exploration are a WIP. @@ -119,7 +115,7 @@ Place-and-Route ^^^^^^^^^^^^^^^ .. code-block:: shell - make par + make par CONFIG=TinyRocketConfig After completion, the final database can be opened in an interactive Innovus session via ``./build/par-rundir/generated-scripts/open_chip``. @@ -131,7 +127,7 @@ Timing reports are found in ``build/par-rundir/timingReports``. They are gzipped .. code-block:: shell - python3 view_gds.py build/par-rundir/Sha3AccelwBB.gds + python3 view_gds.py build/chipyard.TestHarness.TinyRocketConfig/par-rundir/ChipTop.gds By default, this script only shows the M2 thru M4 routing. Layers can be toggled in the layout viewer's side pane and ``view_gds.py`` has a mapping of layer numbers to layer names. @@ -141,9 +137,36 @@ To run DRC & LVS, and view the results in Calibre: .. code-block:: shell - make drc + make drc CONFIG=TinyRocketConfig ./build/drc-rundir/generated-scripts/view-drc - make lvs + make lvs CONFIG=TinyRocketConfig ./build/lvs-rundir/generated-scripts/view-lvs Some DRC errors are expected from this PDK, as explained in the `ASAP7 plugin readme `__. +Furthermore, the dummy SRAMs that are provided in this tutorial and PDK do not have any geometry inside, so will certainly cause DRC and LVS errors. + +Simulation +^^^^^^^^^^ +Simulation with VCS is supported, and can be run at the RTL- or gate-level (post-synthesis and P&R). The simulation infrastructure as included here is intended for running RISC-V binaries on a Chipyard config. For example, for an RTL-level simulation: + +.. code-block:: shell + + make sim-rtl CONFIG=TinyRocketConfig BINARY=$RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-simple + +Post-synthesis and post-P&R simulations use the ``sim-syn`` and ``sim-par`` targets, respectively. + +There are also ``-debug`` and ``-debug-timing``, which will instruct VCS to write a SAIF + VPD and do timing-annotated simulations, respectively. See the ``sim.mk`` file for all available targets. + +Note that for the ASAP7 example, gate-level simulations will currently timeout. + +Power/Rail Analysis +^^^^^^^^^^^^^^^^^^^ +Post-P&R power and rail (IR drop) analysis is supported with Voltus: + +.. code-block:: shell + + make power-par CONFIG=TinyRocketConfig + +If you append the ``BINARY`` variable to the command, it will use the activity file generated from a ``sim--debug`` run and report dynamic power & IR drop from the toggles encoded in the waveform. + +Note that for ASAP7, to bypass gate-level simulation, you will need to run the power tool manually (see the generated commands in the generated ``hammer.d`` buildfile). Static and active (vectorless) power & IR drop will be reported. diff --git a/docs/_static/images/bringup-chipyard-config-communication.png b/docs/_static/images/bringup-chipyard-config-communication.png new file mode 100644 index 0000000000..9da84dcfe4 Binary files /dev/null and b/docs/_static/images/bringup-chipyard-config-communication.png differ diff --git a/docs/_static/images/chip-bringup-simulation.png b/docs/_static/images/chip-bringup-simulation.png new file mode 100644 index 0000000000..007f808b98 Binary files /dev/null and b/docs/_static/images/chip-bringup-simulation.png differ diff --git a/docs/_static/images/chip-bringup.png b/docs/_static/images/chip-bringup.png index 4e8d060271..07c80f0528 100644 Binary files a/docs/_static/images/chip-bringup.png and b/docs/_static/images/chip-bringup.png differ diff --git a/docs/_static/images/chip-communication.png b/docs/_static/images/chip-communication.png index 4492bd8b81..8c0f8a1daf 100644 Binary files a/docs/_static/images/chip-communication.png and b/docs/_static/images/chip-communication.png differ diff --git a/docs/_static/images/default-chipyard-config-communication.png b/docs/_static/images/default-chipyard-config-communication.png new file mode 100644 index 0000000000..9763e1d44f Binary files /dev/null and b/docs/_static/images/default-chipyard-config-communication.png differ diff --git a/docs/requirements.txt b/docs/requirements.txt index 0407da5ea3..ad19f37ddc 100644 --- a/docs/requirements.txt +++ b/docs/requirements.txt @@ -2,3 +2,4 @@ Sphinx==1.8.5 Pygments==2.7.4 sphinx-autobuild sphinx_rtd_theme==0.2.5b1 +docutils==0.16 diff --git a/fpga/Makefile b/fpga/Makefile index 1437d8bc76..8b2ed28bcd 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 47c87d5f4e..f1bdb61e2c 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/arty/HarnessBinders.scala b/fpga/src/main/scala/arty/HarnessBinders.scala index ef7b180595..a8c54dc638 100644 --- a/fpga/src/main/scala/arty/HarnessBinders.scala +++ b/fpga/src/main/scala/arty/HarnessBinders.scala @@ -13,6 +13,7 @@ import sifive.blocks.devices.pinctrl._ import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly} import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder} +import chipyard.iobinders.JTAGChipIO class WithArtyResetHarnessBinder extends ComposeHarnessBinder({ (system: HasPeripheryDebugModuleImp, th: ArtyFPGATestHarness, ports: Seq[Bool]) => { @@ -31,11 +32,18 @@ class WithArtyResetHarnessBinder extends ComposeHarnessBinder({ class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({ (system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => { ports.map { - case j: JTAGIO => - withClockAndReset(th.harnessClock, th.hReset) { + case j: JTAGChipIO => + withClockAndReset(th.buildtopClock, th.hReset) { + val jtag_wire = Wire(new JTAGIO) + jtag_wire.TDO.data := j.TDO + jtag_wire.TDO.driven := true.B + j.TCK := jtag_wire.TCK + j.TMS := jtag_wire.TMS + j.TDI := jtag_wire.TDI + val io_jtag = Wire(new JTAGPins(() => new BasePin(), false)).suggestName("jtag") - JTAGPinsFromPort(io_jtag, j) + JTAGPinsFromPort(io_jtag, jtag_wire) io_jtag.TCK.i.ival := IBUFG(IOBUF(th.jd_2).asClock).asBool diff --git a/fpga/src/main/scala/arty/TestHarness.scala b/fpga/src/main/scala/arty/TestHarness.scala index 503d2de60a..db7ddc0131 100644 --- a/fpga/src/main/scala/arty/TestHarness.scala +++ b/fpga/src/main/scala/arty/TestHarness.scala @@ -27,8 +27,8 @@ class ArtyFPGATestHarness(override implicit val p: Parameters) extends ArtyShell val dut = Module(lazyDut.module) } - val harnessClock = clock_32MHz - val harnessReset = hReset + val buildtopClock = clock_32MHz + val buildtopReset = hReset val success = false.B val dutReset = dReset diff --git a/fpga/src/main/scala/vcu118/Configs.scala b/fpga/src/main/scala/vcu118/Configs.scala index 8b17aa98e6..47a22dcf7a 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 5002817fc9..33161b6829 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 @@ -121,13 +120,13 @@ class VCU118FPGATestHarnessImp(_outer: VCU118FPGATestHarness) extends LazyRawMod val hReset = Wire(Reset()) hReset := _outer.dutClock.in.head._1.reset - val harnessClock = _outer.dutClock.in.head._1.clock - val harnessReset = WireInit(hReset) + val buildtopClock = _outer.dutClock.in.head._1.clock + val buildtopReset = WireInit(hReset) val dutReset = hReset.asAsyncReset val success = false.B - childClock := harnessClock - childReset := harnessReset + childClock := buildtopClock + childReset := buildtopReset // harness binders are non-lazy _outer.topDesign match { case d: HasTestHarnessFunctions => @@ -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/fpga/src/main/scala/vcu118/bringup/BringupGPIOs.scala b/fpga/src/main/scala/vcu118/bringup/BringupGPIOs.scala index 1e11dfa2d4..40c33bfa4e 100644 --- a/fpga/src/main/scala/vcu118/bringup/BringupGPIOs.scala +++ b/fpga/src/main/scala/vcu118/bringup/BringupGPIOs.scala @@ -3,21 +3,21 @@ package chipyard.fpga.vcu118.bringup import scala.collection.mutable.{LinkedHashMap} object BringupGPIOs { - // map of the pin name (akin to die pin name) to (fpga package pin, IOSTANDARD) + // map of the pin name (akin to die pin name) to (fpga package pin, IOSTANDARD, add pullup resistor?) val pinMapping = LinkedHashMap( // these connect to LEDs and switches on the VCU118 (and use 1.2V) - "led0" -> ("AT32", "LVCMOS12"), // 0 - "led1" -> ("AV34", "LVCMOS12"), // 1 - "led2" -> ("AY30", "LVCMOS12"), // 2 - "led3" -> ("BB32", "LVCMOS12"), // 3 - "led4" -> ("BF32", "LVCMOS12"), // 4 - "led5" -> ("AU37", "LVCMOS12"), // 5 - "led6" -> ("AV36", "LVCMOS12"), // 6 - "led7" -> ("BA37", "LVCMOS12"), // 7 - "sw0" -> ("B17", "LVCMOS12"), // 8 - "sw1" -> ("G16", "LVCMOS12"), // 9 - "sw2" -> ("J16", "LVCMOS12"), // 10 - "sw3" -> ("D21", "LVCMOS12") // 11 + "led0" -> ("AT32", "LVCMOS12", false), // 0 + "led1" -> ("AV34", "LVCMOS12", false), // 1 + "led2" -> ("AY30", "LVCMOS12", false), // 2 + "led3" -> ("BB32", "LVCMOS12", false), // 3 + "led4" -> ("BF32", "LVCMOS12", false), // 4 + "led5" -> ("AU37", "LVCMOS12", false), // 5 + "led6" -> ("AV36", "LVCMOS12", false), // 6 + "led7" -> ("BA37", "LVCMOS12", false), // 7 + "sw0" -> ("B17", "LVCMOS12", false), // 8 + "sw1" -> ("G16", "LVCMOS12", false), // 9 + "sw2" -> ("J16", "LVCMOS12", false), // 10 + "sw3" -> ("D21", "LVCMOS12", false) // 11 ) // return list of names (ordered) diff --git a/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala b/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala index a47a6a3b50..43d559f0d6 100644 --- a/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala +++ b/fpga/src/main/scala/vcu118/bringup/CustomOverlays.scala @@ -94,14 +94,15 @@ class BringupGPIOVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: require(gpioNames.length == io.gpio.length) val packagePinsWithIOStdWithPackageIOs = (gpioNames zip io.gpio).map { case (name, io) => - val (pin, iostd) = BringupGPIOs.pinMapping(name) - (pin, iostd, IOPin(io)) + val (pin, iostd, pullupEnable) = BringupGPIOs.pinMapping(name) + (pin, iostd, pullupEnable, IOPin(io)) } - packagePinsWithIOStdWithPackageIOs foreach { case (pin, iostd, io) => { + packagePinsWithIOStdWithPackageIOs foreach { case (pin, iostd, pullupEnable, io) => { shell.xdc.addPackagePin(io, pin) shell.xdc.addIOStandard(io, iostd) if (iostd == "LVCMOS12") { shell.xdc.addDriveStrength(io, "8") } + if (pullupEnable) { shell.xdc.addPullup(io) } } } } } } 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/ChipTop.scala b/generators/chipyard/src/main/scala/ChipTop.scala index 61a043b6ed..8d05d10e64 100644 --- a/generators/chipyard/src/main/scala/ChipTop.scala +++ b/generators/chipyard/src/main/scala/ChipTop.scala @@ -15,6 +15,9 @@ import barstools.iocell.chisel._ case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters) => new DigitalTop()(p)) +trait HasReferenceClockFreq { + def refClockFreqMHz: Double +} /** * The base class used for building chips. This constructor instantiates a module specified by the BuildSystem parameter, @@ -24,15 +27,16 @@ case object BuildSystem extends Field[Parameters => LazyModule]((p: Parameters) */ class ChipTop(implicit p: Parameters) extends LazyModule with BindingScope - with HasTestHarnessFunctions with HasIOBinders { + with HasTestHarnessFunctions with HasReferenceClockFreq with HasIOBinders { // The system module specified by BuildSystem lazy val lazySystem = LazyModule(p(BuildSystem)(p)).suggestName("system") - // The implicitClockSinkNode provides the implicit clock and reset for the System + // The implicitClockSinkNode provides the implicit clock and reset for the system (connected by clocking scheme) val implicitClockSinkNode = ClockSinkNode(Seq(ClockSinkParameters(name = Some("implicit_clock")))) // Generate Clocks and Reset - p(ClockingSchemeKey)(this) + val mvRefClkFreq = p(ClockingSchemeKey)(this) + def refClockFreqMHz: Double = mvRefClkFreq.getWrappedValue // NOTE: Making this a LazyRawModule is moderately dangerous, as anonymous children // of ChipTop (ex: ClockGroup) do not receive clock or reset. diff --git a/generators/chipyard/src/main/scala/Clocks.scala b/generators/chipyard/src/main/scala/Clocks.scala index e4d48b5900..b5553347bd 100644 --- a/generators/chipyard/src/main/scala/Clocks.scala +++ b/generators/chipyard/src/main/scala/Clocks.scala @@ -7,25 +7,26 @@ import scala.collection.mutable.{ArrayBuffer} import freechips.rocketchip.prci._ import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey, InstantiatesTiles} import freechips.rocketchip.config.{Parameters, Field, Config} -import freechips.rocketchip.diplomacy.{OutwardNodeHandle, InModuleBody, LazyModule} +import freechips.rocketchip.diplomacy.{ModuleValue, OutwardNodeHandle, InModuleBody, LazyModule} import freechips.rocketchip.util.{ResetCatchAndSync} import barstools.iocell.chisel._ import testchipip.{TLTileResetCtrl} import chipyard.clocking._ +import chipyard.iobinders._ /** * A simple reset implementation that punches out reset ports - * for standard Module classes. Three basic reset schemes - * are provided. See [[GlobalResetScheme]]. + * for standard Module classes. The ChipTop reset pin is Async. + * Synchronization is performed in the ClockGroupResetSynchronizer */ object GenerateReset { def apply(chiptop: ChipTop, clock: Clock): Reset = { implicit val p = chiptop.p // this needs directionality so generateIOFromSignal works val async_reset_wire = Wire(Input(AsyncReset())) - val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(async_reset_wire, "reset", + val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(async_reset_wire, "reset", p(IOCellKey), abstractResetAsAsync = true) chiptop.iocells ++= resetIOCell @@ -38,7 +39,7 @@ object GenerateReset { } -case object ClockingSchemeKey extends Field[ChipTop => Unit](ClockingSchemeGenerators.dividerOnlyClockGenerator) +case object ClockingSchemeKey extends Field[ChipTop => ModuleValue[Double]](ClockingSchemeGenerators.dividerOnlyClockGenerator) /* * This is a Seq of assignment functions, that accept a clock name and return an optional frequency. * Functions that appear later in this seq have higher precedence that earlier ones. @@ -59,7 +60,7 @@ class ClockNameContainsAssignment(name: String, fMHz: Double) extends Config((si }) object ClockingSchemeGenerators { - val dividerOnlyClockGenerator: ChipTop => Unit = { chiptop => + val dividerOnlyClockGenerator: ChipTop => ModuleValue[Double] = { chiptop => implicit val p = chiptop.p // Requires existence of undriven asyncClockGroups in subsystem @@ -70,31 +71,40 @@ object ClockingSchemeGenerators { // Add a control register for each tile's reset val resetSetter = chiptop.lazySystem match { - case sys: BaseSubsystem with InstantiatesTiles => TLTileResetCtrl(sys) - case _ => ClockGroupEphemeralNode() + case sys: BaseSubsystem with InstantiatesTiles => Some(TLTileResetCtrl(sys)) + case _ => None } + val resetSetterResetProvider = resetSetter.map(_.tileResetProviderNode).getOrElse(ClockGroupEphemeralNode()) val aggregator = LazyModule(new ClockGroupAggregator("allClocks")).node + // provides the implicit clock to the system (chiptop.implicitClockSinkNode := ClockGroup() := aggregator) + // provides the system clock (ex. the bus clocks) (systemAsyncClockGroup - :*= resetSetter :*= ClockGroupNamePrefixer() :*= aggregator) val referenceClockSource = ClockSourceNode(Seq(ClockSourceParameters())) + val dividerOnlyClkGenerator = LazyModule(new DividerOnlyClockGenerator("buildTopClockGenerator")) + // provides all the divided clocks (from the top-level clock) (aggregator := ClockGroupFrequencySpecifier(p(ClockFrequencyAssignersKey), p(DefaultClockFrequencyKey)) := ClockGroupResetSynchronizer() - := DividerOnlyClockGenerator() + := resetSetterResetProvider + := dividerOnlyClkGenerator.node := referenceClockSource) + val asyncResetBroadcast = FixedClockBroadcast(None) + resetSetter.foreach(_.asyncResetSinkNode := asyncResetBroadcast) + val asyncResetSource = ClockSourceNode(Seq(ClockSourceParameters())) + asyncResetBroadcast := asyncResetSource InModuleBody { val clock_wire = Wire(Input(Clock())) val reset_wire = GenerateReset(chiptop, clock_wire) - val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock") + val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey)) chiptop.iocells ++= clockIOCell referenceClockSource.out.unzip._1.map { o => @@ -102,9 +112,17 @@ object ClockingSchemeGenerators { o.reset := reset_wire } + asyncResetSource.out.unzip._1.map { o => + o.clock := false.B.asClock // async reset broadcast network does not provide a clock + o.reset := reset_wire + } + chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { - clock_io := th.harnessClock + clock_io := th.buildtopClock Nil }) + + // return the reference frequency + dividerOnlyClkGenerator.module.referenceFreq } } } diff --git a/generators/chipyard/src/main/scala/ConfigFragments.scala b/generators/chipyard/src/main/scala/ConfigFragments.scala index 667e514896..5d9dc81e87 100644 --- a/generators/chipyard/src/main/scala/ConfigFragments.scala +++ b/generators/chipyard/src/main/scala/ConfigFragments.scala @@ -15,12 +15,13 @@ 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} import hwacha.{Hwacha} -import gemmini.{Gemmini, GemminiConfigs} +import gemmini._ import boom.common.{BoomTileAttachParams} import cva6.{CVA6TileAttachParams} @@ -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 @@ -83,6 +84,17 @@ class WithMultiRoCC extends Config((site, here, up) => { case BuildRoCC => site(MultiRoCCKey).getOrElse(site(TileKey).hartId, Nil) }) +/** + * Assigns what was previously in the BuildRoCC key to specific harts with MultiRoCCKey + * Must be paired with WithMultiRoCC + */ +class WithMultiRoCCFromBuildRoCC(harts: Int*) extends Config((site, here, up) => { + case BuildRoCC => Nil + case MultiRoCCKey => up(MultiRoCCKey, site) ++ harts.distinct.map { i => + (i -> up(BuildRoCC, site)) + } +}) + /** * Config fragment to add Hwachas to cores based on hart * @@ -108,11 +120,12 @@ class WithMultiRoCCHwacha(harts: Int*) extends Config( }) ) -class WithMultiRoCCGemmini(harts: Int*) extends Config((site, here, up) => { +class WithMultiRoCCGemmini[T <: Data : Arithmetic, U <: Data, V <: Data]( + harts: Int*)(gemminiConfig: GemminiArrayConfig[T,U,V] = GemminiConfigs.defaultConfig) extends Config((site, here, up) => { case MultiRoCCKey => up(MultiRoCCKey, site) ++ harts.distinct.map { i => (i -> Seq((p: Parameters) => { implicit val q = p - val gemmini = LazyModule(new Gemmini(OpcodeSet.custom3, GemminiConfigs.defaultConfig)) + val gemmini = LazyModule(new Gemmini(gemminiConfig)) gemmini })) } @@ -139,6 +152,16 @@ class WithNPerfCounters(n: Int = 29) extends Config((site, here, up) => { } }) +class WithNPMPs(n: Int = 8) 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(nPMPs = n))) + case tp: BoomTileAttachParams => tp.copy(tileParams = tp.tileParams.copy( + core = tp.tileParams.core.copy(nPMPs = n))) + case other => other + } +}) + class WithRocketICacheScratchpad extends Config((site, here, up) => { case RocketTilesKey => up(RocketTilesKey, site) map { r => r.copy(icache = r.icache.map(_.copy(itimAddr = Some(0x300000 + r.hartId * 0x10000)))) @@ -193,7 +216,31 @@ class WithTLBackingMemory extends Config((site, here, up) => { case ExtTLMem => up(ExtMem, site) // enable TL backing memory }) -class WithTileFrequency(fMHz: Double) extends ClockNameContainsAssignment("core", fMHz) +class WithSerialTLBackingMemory extends Config((site, here, up) => { + case ExtMem => None + case SerialTLKey => up(SerialTLKey, site).map { k => k.copy( + memParams = { + val memPortParams = up(ExtMem, site).get + require(memPortParams.nMemoryChannels == 1) + memPortParams.master + }, + isMemoryDevice = true + )} +}) + +/** + * Mixins to define either a specific tile frequency for a single hart or all harts + * + * @param fMHz Frequency in MHz of the tile or all tiles + * @param hartId Optional hartid to assign the frequency to (if unspecified default to all harts) + */ +class WithTileFrequency(fMHz: Double, hartId: Option[Int] = None) extends ClockNameContainsAssignment({ + hartId match { + case Some(id) => s"tile_$id" + case None => "tile" + } + }, + fMHz) class WithPeripheryBusFrequencyAsDefault extends Config((site, here, up) => { case DefaultClockFrequencyKey => (site(PeripheryBusKey).dtsFrequency.get / (1000 * 1000)).toDouble @@ -273,3 +320,18 @@ class WithControlBusFrequency(freqMHz: Double) extends Config((site, here, up) = class WithRationalMemoryBusCrossing extends WithSbusToMbusCrossingType(RationalCrossing(Symmetric)) class WithAsynchrousMemoryBusCrossing extends WithSbusToMbusCrossingType(AsynchronousCrossing()) + +class WithTestChipBusFreqs extends Config( + // Frequency specifications + new chipyard.config.WithTileFrequency(1600.0) ++ // Matches the maximum frequency of U540 + new chipyard.config.WithSystemBusFrequency(800.0) ++ // Put the system bus at a lower freq, representative of ncore working at a lower frequency than the tiles. Same freq as U540 + new chipyard.config.WithMemoryBusFrequency(1000.0) ++ // 2x the U540 freq (appropriate for a 128b Mbus) + new chipyard.config.WithPeripheryBusFrequency(800.0) ++ // Match the sbus and pbus frequency + new chipyard.config.WithSystemBusFrequencyAsDefault ++ // All unspecified clock frequencies, notably the implicit clock, will use the sbus freq (800 MHz) + // Crossing specifications + new chipyard.config.WithCbusToPbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossing between PBUS and CBUS + new chipyard.config.WithSbusToMbusCrossingType(AsynchronousCrossing()) ++ // Add Async crossings between backside of L2 and MBUS + new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore + new boom.common.WithRationalBoomTiles ++ // Add rational crossings between BoomTile and uncore + new testchipip.WithAsynchronousSerialSlaveCrossing // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS +) diff --git a/generators/chipyard/src/main/scala/DigitalTop.scala b/generators/chipyard/src/main/scala/DigitalTop.scala index 7fd682d2b8..a91fa47953 100644 --- a/generators/chipyard/src/main/scala/DigitalTop.scala +++ b/generators/chipyard/src/main/scala/DigitalTop.scala @@ -13,10 +13,14 @@ 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 with testchipip.CanHavePeripheryTLSerial // Enables optionally adding the backing memory and serial adapter + with sifive.blocks.devices.i2c.HasPeripheryI2C // Enables optionally adding the sifive I2C + with sifive.blocks.devices.pwm.HasPeripheryPWM // Enables optionally adding the sifive PWM with sifive.blocks.devices.uart.HasPeripheryUART // Enables optionally adding the sifive UART with sifive.blocks.devices.gpio.HasPeripheryGPIO // Enables optionally adding the sifive GPIOs with sifive.blocks.devices.spi.HasPeripherySPIFlash // Enables optionally adding the sifive SPI flash controller @@ -33,6 +37,8 @@ class DigitalTop(implicit p: Parameters) extends ChipyardSystem class DigitalTopModule[+L <: DigitalTop](l: L) extends ChipyardSystemModule(l) with testchipip.CanHaveTraceIOModuleImp + with sifive.blocks.devices.i2c.HasPeripheryI2CModuleImp + with sifive.blocks.devices.pwm.HasPeripheryPWMModuleImp with sifive.blocks.devices.uart.HasPeripheryUARTModuleImp with sifive.blocks.devices.gpio.HasPeripheryGPIOModuleImp with sifive.blocks.devices.spi.HasPeripherySPIFlashModuleImp diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index 02ab3732d8..c1ec2bdafb 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -1,7 +1,8 @@ package chipyard.harness import chisel3._ -import chisel3.experimental.{Analog, BaseModule} +import chisel3.util._ +import chisel3.experimental.{Analog, BaseModule, DataMirror, Direction} import freechips.rocketchip.config.{Field, Config, Parameters} import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike} @@ -10,6 +11,7 @@ import freechips.rocketchip.devices.debug._ import freechips.rocketchip.jtag.{JTAGIO} import freechips.rocketchip.system.{SimAXIMem} import freechips.rocketchip.subsystem._ +import freechips.rocketchip.util._ import sifive.blocks.devices.gpio._ import sifive.blocks.devices.uart._ @@ -19,8 +21,8 @@ import barstools.iocell.chisel._ import testchipip._ -import chipyard.HasHarnessSignalReferences -import chipyard.iobinders.GetSystemParameters +import chipyard.{HasHarnessSignalReferences, HarnessClockInstantiatorKey} +import chipyard.iobinders.{GetSystemParameters, JTAGChipIO} import tracegen.{TraceGenSystemModuleImp} import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} @@ -88,21 +90,21 @@ class WithUARTAdapter extends OverrideHarnessBinder({ class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({ (system: HasPeripherySPIFlashModuleImp, th: HasHarnessSignalReferences, ports: Seq[SPIChipIO]) => { - SimSPIFlashModel.connect(ports, th.harnessReset, rdOnly)(system.p) + SimSPIFlashModel.connect(ports, th.buildtopReset, rdOnly)(system.p) } }) class WithSimBlockDevice extends OverrideHarnessBinder({ (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { implicit val p: Parameters = GetSystemParameters(system) - ports.map { b => SimBlockDevice.connect(b.clock, th.harnessReset.asBool, Some(b.bits)) } + ports.map { b => SimBlockDevice.connect(b.clock, th.buildtopReset.asBool, Some(b.bits)) } } }) class WithBlockDeviceModel extends OverrideHarnessBinder({ (system: CanHavePeripheryBlockDevice, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[BlockDeviceIO]]) => { implicit val p: Parameters = GetSystemParameters(system) - ports.map { b => withClockAndReset(b.clock, th.harnessReset) { BlockDeviceModel.connect(Some(b.bits)) } } + ports.map { b => withClockAndReset(b.clock, th.buildtopReset) { BlockDeviceModel.connect(Some(b.bits)) } } } }) @@ -110,7 +112,7 @@ class WithLoopbackNIC extends OverrideHarnessBinder({ (system: CanHavePeripheryIceNIC, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { implicit val p: Parameters = GetSystemParameters(system) ports.map { n => - withClockAndReset(n.clock, th.harnessReset) { + withClockAndReset(n.clock, th.buildtopReset) { NicLoopback.connect(Some(n.bits), p(NICKey)) } } @@ -120,7 +122,7 @@ class WithLoopbackNIC extends OverrideHarnessBinder({ class WithSimNetwork extends OverrideHarnessBinder({ (system: CanHavePeripheryIceNIC, th: BaseModule with HasHarnessSignalReferences, ports: Seq[ClockedIO[NICIOvonly]]) => { implicit val p: Parameters = GetSystemParameters(system) - ports.map { n => SimNetwork.connect(Some(n.bits), n.clock, th.harnessReset.asBool) } + ports.map { n => SimNetwork.connect(Some(n.bits), n.clock, th.buildtopReset.asBool) } } }) @@ -137,14 +139,73 @@ class WithSimAXIMem extends OverrideHarnessBinder({ } }) -class WithBlackBoxSimMem extends OverrideHarnessBinder({ +class WithSimAXIMemOverSerialTL extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + implicit val p = chipyard.iobinders.GetSystemParameters(system) + + p(SerialTLKey).map({ sVal => + require(sVal.axiMemOverSerialTLParams.isDefined) + val axiDomainParams = sVal.axiMemOverSerialTLParams.get + require(sVal.isMemoryDevice) + + val memFreq = axiDomainParams.getMemFrequency(system.asInstanceOf[HasTileLinkLocations]) + + ports.map({ port => +// DOC include start: HarnessClockInstantiatorEx + withClockAndReset(th.buildtopClock, th.buildtopReset) { + val memOverSerialTLClockBundle = p(HarnessClockInstantiatorKey).requestClockBundle("mem_over_serial_tl_clock", memFreq) + val serial_bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) + val harnessMultiClockAXIRAM = SerialAdapter.connectHarnessMultiClockAXIRAM( + system.serdesser.get, + serial_bits, + memOverSerialTLClockBundle, + th.buildtopReset) +// DOC include end: HarnessClockInstantiatorEx + val success = SerialAdapter.connectSimSerial(harnessMultiClockAXIRAM.module.io.tsi_ser, th.buildtopClock, th.buildtopReset.asBool) + when (success) { th.success := true.B } + + // connect SimDRAM from the AXI port coming from the harness multi clock axi ram + (harnessMultiClockAXIRAM.mem_axi4 zip harnessMultiClockAXIRAM.memNode.edges.in).map { case (axi_port, edge) => + val memSize = sVal.memParams.size + val lineSize = p(CacheBlockBytes) + val mem = Module(new SimDRAM(memSize, lineSize, BigInt(memFreq.toLong), edge.bundle)).suggestName("simdram") + mem.io.axi <> axi_port.bits + mem.io.clock := axi_port.clock + mem.io.reset := axi_port.reset + } + } + }) + }) + } +}) + +class WithBlackBoxSimMem(additionalLatency: Int = 0) extends OverrideHarnessBinder({ (system: CanHaveMasterAXI4MemPort, th: HasHarnessSignalReferences, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => { val p: Parameters = chipyard.iobinders.GetSystemParameters(system) (ports zip system.memAXI4Node.edges.in).map { case (port, edge) => val memSize = p(ExtMem).get.master.size val lineSize = p(CacheBlockBytes) - val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle)).suggestName("simdram") + val clockFreq = p(MemoryBusKey).dtsFrequency.get + val mem = Module(new SimDRAM(memSize, lineSize, clockFreq, edge.bundle)).suggestName("simdram") mem.io.axi <> port.bits + // Bug in Chisel implementation. See https://github.com/chipsalliance/chisel3/pull/1781 + def Decoupled[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = { + require(DataMirror.directionOf(irr.bits) == Direction.Output, "Only safe to cast produced Irrevocable bits to Decoupled.") + val d = Wire(new DecoupledIO(chiselTypeOf(irr.bits))) + d.bits := irr.bits + d.valid := irr.valid + irr.ready := d.ready + d + } + if (additionalLatency > 0) { + withClockAndReset (port.clock, port.reset) { + mem.io.axi.aw <> (0 until additionalLatency).foldLeft(Decoupled(port.bits.aw))((t, _) => Queue(t, 1, pipe=true)) + mem.io.axi.w <> (0 until additionalLatency).foldLeft(Decoupled(port.bits.w ))((t, _) => Queue(t, 1, pipe=true)) + port.bits.b <> (0 until additionalLatency).foldLeft(Decoupled(mem.io.axi.b))((t, _) => Queue(t, 1, pipe=true)) + mem.io.axi.ar <> (0 until additionalLatency).foldLeft(Decoupled(port.bits.ar))((t, _) => Queue(t, 1, pipe=true)) + port.bits.r <> (0 until additionalLatency).foldLeft(Decoupled(mem.io.axi.r))((t, _) => Queue(t, 1, pipe=true)) + } + } mem.io.clock := port.clock mem.io.reset := port.reset } @@ -183,11 +244,17 @@ class WithSimDebug extends OverrideHarnessBinder({ case d: ClockedDMIIO => val dtm_success = WireInit(false.B) when (dtm_success) { th.success := true.B } - val dtm = Module(new SimDTM).connect(th.harnessClock, th.harnessReset.asBool, d, dtm_success) - case j: JTAGIO => + val dtm = Module(new SimDTM).connect(th.buildtopClock, th.buildtopReset.asBool, d, dtm_success) + case j: JTAGChipIO => val dtm_success = WireInit(false.B) when (dtm_success) { th.success := true.B } - val jtag = Module(new SimJTAG(tickDelay=3)).connect(j, th.harnessClock, th.harnessReset.asBool, ~(th.harnessReset.asBool), dtm_success) + val jtag_wire = Wire(new JTAGIO) + jtag_wire.TDO.data := j.TDO + jtag_wire.TDO.driven := true.B + j.TCK := jtag_wire.TCK + j.TMS := jtag_wire.TMS + j.TDI := jtag_wire.TDI + val jtag = Module(new SimJTAG(tickDelay=3)).connect(jtag_wire, th.buildtopClock, th.buildtopReset.asBool, ~(th.buildtopReset.asBool), dtm_success) } } }) @@ -195,11 +262,10 @@ class WithSimDebug extends OverrideHarnessBinder({ class WithTiedOffDebug extends OverrideHarnessBinder({ (system: HasPeripheryDebug, th: HasHarnessSignalReferences, ports: Seq[Data]) => { ports.map { - case j: JTAGIO => + case j: JTAGChipIO => j.TCK := true.B.asClock j.TMS := true.B j.TDI := true.B - j.TRSTn.foreach { r => r := true.B } case d: ClockedDMIIO => d.dmi.req.valid := false.B d.dmi.req.bits := DontCare @@ -221,8 +287,11 @@ class WithSerialAdapterTiedOff extends OverrideHarnessBinder({ (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { implicit val p = chipyard.iobinders.GetSystemParameters(system) ports.map({ port => - val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) - SerialAdapter.tieoff(ram.module.io.tsi_ser) + val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) + withClockAndReset(th.buildtopClock, th.buildtopReset) { + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset) + SerialAdapter.tieoff(ram.module.io.tsi_ser) + } }) } }) @@ -231,9 +300,12 @@ class WithSimSerial extends OverrideHarnessBinder({ (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { implicit val p = chipyard.iobinders.GetSystemParameters(system) ports.map({ port => - val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) - val success = SerialAdapter.connectSimSerial(ram.module.io.tsi_ser, port.clock, th.harnessReset.asBool) - when (success) { th.success := true.B } + val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) + withClockAndReset(th.buildtopClock, th.buildtopReset) { + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset) + val success = SerialAdapter.connectSimSerial(ram.module.io.tsi_ser, th.buildtopClock, th.buildtopReset.asBool) + when (success) { th.success := true.B } + } }) } }) @@ -249,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 ab6ccdf8d2..448d4b729d 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -199,6 +199,13 @@ class WithExtInterruptIOCells extends OverrideIOBinder({ } }) +// Rocketchip's JTAGIO exposes the oe signal, which doesn't go off-chip +class JTAGChipIO extends Bundle { + val TCK = Input(Clock()) + val TMS = Input(Bool()) + val TDI = Input(Bool()) + val TDO = Output(Bool()) +} class WithDebugIOCells extends OverrideLazyIOBinder({ (system: HasPeripheryDebug) => { @@ -224,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) @@ -238,7 +245,12 @@ class WithDebugIOCells extends OverrideLazyIOBinder({ } val jtagTuple = debug.systemjtag.map { j => - IOCell.generateIOFromSignal(j.jtag, "jtag", p(IOCellKey), abstractResetAsAsync = true) + val jtag_wire = Wire(new JTAGChipIO) + j.jtag.TCK := jtag_wire.TCK + j.jtag.TMS := jtag_wire.TMS + j.jtag.TDI := jtag_wire.TDI + jtag_wire.TDO := j.jtag.TDO.data + IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true) } val apbTuple = debug.apb.map { a => @@ -260,7 +272,6 @@ class WithSerialTLIOCells extends OverrideIOBinder({ }).getOrElse((Nil, Nil)) }) - class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({ (system: CanHaveMasterAXI4MemPort) => { implicit val p: Parameters = GetSystemParameters(system) @@ -361,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/TestHarness.scala b/generators/chipyard/src/main/scala/TestHarness.scala index c638c0813c..ba09e6dcd4 100644 --- a/generators/chipyard/src/main/scala/TestHarness.scala +++ b/generators/chipyard/src/main/scala/TestHarness.scala @@ -1,12 +1,16 @@ package chipyard import chisel3._ -import scala.collection.mutable.{ArrayBuffer} + +import scala.collection.mutable.{ArrayBuffer, LinkedHashMap} import freechips.rocketchip.diplomacy.{LazyModule} import freechips.rocketchip.config.{Field, Parameters} +import freechips.rocketchip.util.{ResetCatchAndSync} +import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters, ClockSinkParameters, ClockParameters} import chipyard.harness.{ApplyHarnessBinders, HarnessBinders} import chipyard.iobinders.HasIOBinders +import chipyard.clocking.{SimplePllConfiguration, ClockDividerN} // ------------------------------- // Chipyard Test Harness @@ -19,26 +23,84 @@ trait HasTestHarnessFunctions { } trait HasHarnessSignalReferences { - def harnessClock: Clock - def harnessReset: Reset + // clock/reset of the chiptop reference clock (can be different than the implicit harness clock/reset) + def buildtopClock: Clock + def buildtopReset: Reset def dutReset: Reset def success: Bool } +class HarnessClockInstantiator { + private val _clockMap: LinkedHashMap[String, (Double, ClockBundle)] = LinkedHashMap.empty + + // request a clock bundle at a particular frequency + def requestClockBundle(name: String, freqRequested: Double): ClockBundle = { + val clockBundle = Wire(new ClockBundle(ClockBundleParameters())) + _clockMap(name) = (freqRequested, clockBundle) + clockBundle + } + + // connect all clock wires specified to a divider only PLL + def instantiateHarnessDividerPLL(refClock: ClockBundle): Unit = { + val sinks = _clockMap.map({ case (name, (freq, bundle)) => + ClockSinkParameters(take=Some(ClockParameters(freqMHz=freq / (1000 * 1000))), name=Some(name)) + }).toSeq + + val pllConfig = new SimplePllConfiguration("harnessDividerOnlyClockGenerator", sinks) + pllConfig.emitSummaries() + + val dividedClocks = LinkedHashMap[Int, Clock]() + def instantiateDivider(div: Int): Clock = { + val divider = Module(new ClockDividerN(div)) + divider.suggestName(s"ClockDivideBy${div}") + divider.io.clk_in := refClock.clock + dividedClocks(div) = divider.io.clk_out + divider.io.clk_out + } + + // connect wires to clock source + for (sinkParams <- sinks) { + // bypass the reference freq. (don't create a divider + reset sync) + val (divClock, divReset) = if (sinkParams.take.get.freqMHz != pllConfig.referenceFreqMHz) { + val div = pllConfig.sinkDividerMap(sinkParams) + val divClock = dividedClocks.getOrElse(div, instantiateDivider(div)) + (divClock, ResetCatchAndSync(divClock, refClock.reset.asBool)) + } else { + (refClock.clock, refClock.reset) + } + + _clockMap(sinkParams.name.get)._2.clock := divClock + _clockMap(sinkParams.name.get)._2.reset := divReset + } + } +} + +case object HarnessClockInstantiatorKey extends Field[HarnessClockInstantiator](new HarnessClockInstantiator) + class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSignalReferences { val io = IO(new Bundle { val success = Output(Bool()) }) + val buildtopClock = Wire(Clock()) + val buildtopReset = Wire(Reset()) + val lazyDut = LazyModule(p(BuildTop)(p)).suggestName("chiptop") val dut = Module(lazyDut.module) + io.success := false.B - val harnessClock = clock - val harnessReset = WireInit(reset) - val success = io.success + val freqMHz = lazyDut match { + case d: HasReferenceClockFreq => d.refClockFreqMHz + case _ => p(DefaultClockFrequencyKey) + } + val refClkBundle = p(HarnessClockInstantiatorKey).requestClockBundle("buildtop_reference_clock", freqMHz * (1000 * 1000)) + + buildtopClock := refClkBundle.clock + buildtopReset := WireInit(refClkBundle.reset) + val dutReset = refClkBundle.reset.asAsyncReset - val dutReset = reset.asAsyncReset + val success = io.success lazyDut match { case d: HasTestHarnessFunctions => d.harnessFunctions.foreach(_(this)) @@ -46,5 +108,10 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign lazyDut match { case d: HasIOBinders => ApplyHarnessBinders(this, d.lazySystem, d.portMap) } + + val implicitHarnessClockBundle = Wire(new ClockBundle(ClockBundleParameters())) + implicitHarnessClockBundle.clock := clock + implicitHarnessClockBundle.reset := reset + p(HarnessClockInstantiatorKey).instantiateHarnessDividerPLL(implicitHarnessClockBundle) } diff --git a/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala b/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala index 2b66619661..b272c80ce3 100644 --- a/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala +++ b/generators/chipyard/src/main/scala/clocking/DividerOnlyClockGenerator.scala @@ -51,7 +51,7 @@ object FrequencyUtils { require(!requestedOutputs.contains(0.0)) val requestedFreqs = requestedOutputs.map(_.freqMHz) val fastestFreq = requestedFreqs.max - require(fastestFreq < maximumAllowableFreqMHz) + require(fastestFreq <= maximumAllowableFreqMHz) val candidateFreqs = Seq.tabulate(Math.ceil(maximumAllowableFreqMHz / fastestFreq).toInt)(i => (i + 1) * fastestFreq) @@ -89,6 +89,7 @@ class SimplePllConfiguration( ElaborationArtefacts.add(s"${name}.freq-summary", summaryString) println(summaryString) } + def referenceSinkParams(): ClockSinkParameters = sinkDividerMap.find(_._2 == 1).get._1 } case class DividerOnlyClockGeneratorNode(pllName: String)(implicit valName: ValName) @@ -144,7 +145,3 @@ class DividerOnlyClockGenerator(pllName: String)(implicit p: Parameters, valName } } } - -object DividerOnlyClockGenerator { - def apply()(implicit p: Parameters, valName: ValName) = LazyModule(new DividerOnlyClockGenerator(valName.name)).node -} diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 73c2b006ae..6660d159ec 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 @@ -45,6 +47,8 @@ class AbstractConfig extends Config( new chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks new chipyard.config.WithInheritBusFrequencyAssignments ++ // Unspecified clocks within a bus will receive the bus frequency if set new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ // Unspecified frequencies with match the pbus frequency (which is always set) + new chipyard.config.WithMemoryBusFrequency(100.0) ++ // Default 100 MHz mbus + new chipyard.config.WithPeripheryBusFrequency(100.0) ++ // Default 100 MHz pbus new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip) new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip) @@ -52,4 +56,3 @@ class AbstractConfig extends Config( new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts new chipyard.WithMulticlockCoherentBusTopology ++ // hierarchical buses including mbus+l2 new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system - diff --git a/generators/chipyard/src/main/scala/config/HeteroConfigs.scala b/generators/chipyard/src/main/scala/config/HeteroConfigs.scala index 862ee64385..28cdc4cb20 100644 --- a/generators/chipyard/src/main/scala/config/HeteroConfigs.scala +++ b/generators/chipyard/src/main/scala/config/HeteroConfigs.scala @@ -20,23 +20,35 @@ class HwachaLargeBoomAndHwachaRocketConfig extends Config( new chipyard.config.AbstractConfig) // DOC include end: BoomAndRocketWithHwacha -// DOC include start: DualBoomAndRocketOneHwacha class LargeBoomAndHwachaRocketConfig extends Config( new chipyard.config.WithMultiRoCC ++ // support heterogeneous rocc - new chipyard.config.WithMultiRoCCHwacha(1) ++ // put hwacha on hart-1 (rocket) + new chipyard.config.WithMultiRoCCHwacha(0) ++ // put hwacha on hart-0 (rocket) new hwacha.DefaultHwachaConfig ++ // set default hwacha config keys new boom.common.WithNLargeBooms(1) ++ // add 1 boom core new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket core new chipyard.config.AbstractConfig) -// DOC include end: DualBoomAndRocketOneHwacha +// DOC include start: DualBoomAndRocketOneHwacha +class DualLargeBoomAndHwachaRocketConfig extends Config( + new chipyard.config.WithMultiRoCC ++ // support heterogeneous rocc + new chipyard.config.WithMultiRoCCHwacha(0) ++ // put hwacha on hart-0 (rocket) + new hwacha.DefaultHwachaConfig ++ // set default hwacha config keys + new boom.common.WithNLargeBooms(2) ++ // add 2 boom cores + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket core + new chipyard.config.AbstractConfig) +// DOC include end: DualBoomAndRocketOneHwacha -// DOC include start: DualBoomAndRocket class DualLargeBoomAndDualRocketConfig extends Config( new boom.common.WithNLargeBooms(2) ++ // add 2 boom cores new freechips.rocketchip.subsystem.WithNBigCores(2) ++ // add 2 rocket cores new chipyard.config.AbstractConfig) -// DOC include end: DualBoomAndRocket + +// DOC include start: DualBoomAndSingleRocket +class DualLargeBoomAndSingleRocketConfig extends Config( + new boom.common.WithNLargeBooms(2) ++ // add 2 boom cores + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // add 1 rocket core + new chipyard.config.AbstractConfig) +// DOC include end: DualBoomAndSingleRocket class LargeBoomAndRocketWithControlCoreConfig extends Config( new freechips.rocketchip.subsystem.WithNSmallCores(1) ++ // Add a small "control" core diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index 308ebc39cf..962578387c 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -34,6 +34,12 @@ class GemminiRocketConfig extends Config( new chipyard.config.AbstractConfig) // DOC include end: GemminiRocketConfig +class FPGemminiRocketConfig extends Config( + new gemmini.GemminiFP32DefaultConfig ++ // use FP32Gemmini systolic array GEMM accelerator + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new chipyard.config.AbstractConfig) + + // DOC include start: DmiRocket class dmiRocketConfig extends Config( new chipyard.harness.WithSerialAdapterTiedOff ++ // don't attach an external SimSerial @@ -201,8 +207,36 @@ class MulticlockRocketConfig extends Config( new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Add Async crossing between serial and MBUS. Its master-side is tied to the FBUS new chipyard.config.AbstractConfig) +class TestChipMulticlockRocketConfig extends Config( + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ + new chipyard.config.WithTestChipBusFreqs ++ + new chipyard.config.AbstractConfig) + class LBWIFRocketConfig extends Config( new testchipip.WithSerialTLMem(isMainMemory=true) ++ // set lbwif memory base to DRAM_BASE, use as main memory new freechips.rocketchip.subsystem.WithNoMemPort ++ // remove AXI4 backing memory new freechips.rocketchip.subsystem.WithNBigCores(1) ++ new chipyard.config.AbstractConfig) + +// DOC include start: MulticlockAXIOverSerialConfig +class MulticlockAXIOverSerialConfig extends Config( + new chipyard.config.WithSystemBusFrequencyAsDefault ++ + new chipyard.config.WithSystemBusFrequency(250) ++ + new chipyard.config.WithPeripheryBusFrequency(250) ++ + new chipyard.config.WithMemoryBusFrequency(250) ++ + new chipyard.config.WithFrontBusFrequency(50) ++ + new chipyard.config.WithTileFrequency(500, Some(1)) ++ + new chipyard.config.WithTileFrequency(250, Some(0)) ++ + + new chipyard.config.WithFbusToSbusCrossingType(AsynchronousCrossing()) ++ + new testchipip.WithAsynchronousSerialSlaveCrossing ++ + new freechips.rocketchip.subsystem.WithAsynchronousRocketTiles( + AsynchronousCrossing().depth, + AsynchronousCrossing().sourceSync) ++ + + new chipyard.harness.WithSimAXIMemOverSerialTL ++ // add SimDRAM DRAM model for axi4 backing memory over the SerDes link, if axi4 mem is enabled + new chipyard.config.WithSerialTLBackingMemory ++ // remove axi4 mem port in favor of SerialTL memory + + new freechips.rocketchip.subsystem.WithNBigCores(2) ++ + new chipyard.config.AbstractConfig) +// DOC include end: MulticlockAXIOverSerialConfig diff --git a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala index f9980bf671..3f9e27d138 100644 --- a/generators/chipyard/src/main/scala/config/TracegenConfigs.scala +++ b/generators/chipyard/src/main/scala/config/TracegenConfigs.scala @@ -11,6 +11,8 @@ class AbstractTraceGenConfig extends Config( new chipyard.config.WithTracegenSystem ++ new chipyard.config.WithNoSubsystemDrivenClocks ++ new chipyard.config.WithPeripheryBusFrequencyAsDefault ++ + new chipyard.config.WithMemoryBusFrequency(100.0) ++ + new chipyard.config.WithPeripheryBusFrequency(100.0) ++ new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ new freechips.rocketchip.groundtest.GroundTestBaseConfig) diff --git a/generators/chipyard/src/test/scala/clocking/SimplePllConfigurationSpec.scala b/generators/chipyard/src/test/scala/clocking/SimplePllConfigurationSpec.scala index 0abe7c5092..d80aafc160 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/BridgeBinders.scala b/generators/firechip/src/main/scala/BridgeBinders.scala index cdb026e10a..bf1ff6805d 100644 --- a/generators/firechip/src/main/scala/BridgeBinders.scala +++ b/generators/firechip/src/main/scala/BridgeBinders.scala @@ -12,6 +12,8 @@ import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebugModuleImp} import freechips.rocketchip.amba.axi4.{AXI4Bundle} import freechips.rocketchip.subsystem._ import freechips.rocketchip.tile.{RocketTile} +import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters} +import freechips.rocketchip.util.{ResetCatchAndSync} import sifive.blocks.devices.uart._ import testchipip._ @@ -70,8 +72,11 @@ class WithSerialBridge extends OverrideHarnessBinder({ (system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedIO[SerialIO]]) => { ports.map { port => implicit val p = GetSystemParameters(system) - val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, port, th.harnessReset) - SerialBridge(port.clock, ram.module.io.tsi_ser, p(ExtMem).map(_ => MainMemoryConsts.globalName)) + val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) + val ram = withClockAndReset(th.buildtopClock, th.buildtopReset) { + SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset) + } + SerialBridge(th.buildtopClock, ram.module.io.tsi_ser, p(ExtMem).map(_ => MainMemoryConsts.globalName)) } Nil } @@ -98,7 +103,56 @@ class WithUARTBridge extends OverrideHarnessBinder({ class WithBlockDeviceBridge extends OverrideHarnessBinder({ (system: CanHavePeripheryBlockDevice, th: FireSim, ports: Seq[ClockedIO[BlockDeviceIO]]) => { implicit val p: Parameters = GetSystemParameters(system) - ports.map { b => BlockDevBridge(b.clock, b.bits, th.harnessReset.toBool) } + ports.map { b => BlockDevBridge(b.clock, b.bits, th.buildtopReset.asBool) } + Nil + } +}) + +class WithAXIOverSerialTLCombinedBridges extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedIO[SerialIO]]) => { + implicit val p = GetSystemParameters(system) + + p(SerialTLKey).map({ sVal => + require(sVal.axiMemOverSerialTLParams.isDefined) + val axiDomainParams = sVal.axiMemOverSerialTLParams.get + require(sVal.isMemoryDevice) + + val memFreq = axiDomainParams.getMemFrequency(system.asInstanceOf[HasTileLinkLocations]) + + ports.map({ port => + val axiClock = p(ClockBridgeInstantiatorKey).requestClock("mem_over_serial_tl_clock", memFreq) + val axiClockBundle = Wire(new ClockBundle(ClockBundleParameters())) + axiClockBundle.clock := axiClock + axiClockBundle.reset := ResetCatchAndSync(axiClock, th.buildtopReset.asBool) + + val serial_bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) + + val harnessMultiClockAXIRAM = withClockAndReset(th.buildtopClock, th.buildtopReset) { + SerialAdapter.connectHarnessMultiClockAXIRAM( + system.serdesser.get, + serial_bits, + axiClockBundle, + th.buildtopReset) + } + SerialBridge(th.buildtopClock, harnessMultiClockAXIRAM.module.io.tsi_ser, Some(MainMemoryConsts.globalName)) + + // connect SimAxiMem + (harnessMultiClockAXIRAM.mem_axi4 zip harnessMultiClockAXIRAM.memNode.edges.in).map { case (axi4, edge) => + val nastiKey = NastiParameters(axi4.bits.r.bits.data.getWidth, + axi4.bits.ar.bits.addr.getWidth, + axi4.bits.ar.bits.id.getWidth) + system match { + case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, axi4.reset.asBool, + CompleteConfig(p(firesim.configs.MemModelKey), + nastiKey, + Some(AXI4EdgeSummary(edge)), + Some(MainMemoryConsts.globalName))) + case _ => throw new Exception("Attempting to attach FASED Bridge to misconfigured design") + } + } + }) + }) + Nil } }) @@ -138,7 +192,7 @@ class WithDromajoBridge extends ComposeHarnessBinder({ class WithTraceGenBridge extends OverrideHarnessBinder({ (system: TraceGenSystemModuleImp, th: FireSim, ports: Seq[Bool]) => - ports.map { p => GroundTestBridge(th.harnessClock, p)(system.p) }; Nil + ports.map { p => GroundTestBridge(th.buildtopClock, p)(system.p) }; Nil }) class WithFireSimMultiCycleRegfile extends ComposeIOBinder({ @@ -170,6 +224,7 @@ class WithFireSimFAME5 extends ComposeIOBinder({ annotate(EnableModelMultiThreadingAnnotation(b.module)) case r: RocketTile => annotate(EnableModelMultiThreadingAnnotation(r.module)) + case _ => Nil } (Nil, Nil) } diff --git a/generators/firechip/src/main/scala/FireSim.scala b/generators/firechip/src/main/scala/FireSim.scala index ff76597094..79242d2e6d 100644 --- a/generators/firechip/src/main/scala/FireSim.scala +++ b/generators/firechip/src/main/scala/FireSim.scala @@ -2,6 +2,8 @@ package firesim.firesim +import scala.collection.mutable.{LinkedHashMap} + import chisel3._ import chisel3.experimental.{IO} @@ -35,47 +37,129 @@ 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 - * the harness and reused across all supernode instances. This class attempts to + * the harness and reused across all supernode instances. This class attempts to * memoize its instantiation such that it can be referenced from within a ClockScheme function. */ class ClockBridgeInstantiator { - private var _clockRecord: Option[RecordMap[Clock]] = None + private val _harnessClockMap: LinkedHashMap[String, (Double, Clock)] = LinkedHashMap.empty - def getClockRecord: RecordMap[Clock] = _clockRecord.get + // Assumes that the supernode implementation results in duplicated clocks + // (i.e. only 1 set of clocks is generated for all BuildTop designs) + private var _buildTopClockParams: Option[BuildTopClockParameters] = None + private val _buildTopClockMap: LinkedHashMap[String, (RationalClock, Clock)] = LinkedHashMap.empty + private var _buildTopClockRecord: Option[RecordMap[Clock]] = None - def getClockRecordOrInstantiate(allClocks: Seq[RationalClock], baseClockName: String): RecordMap[Clock] = { - if (_clockRecord.isEmpty) { - require(allClocks.exists(_.name == baseClockName), - s"Provided base-clock name, ${baseClockName}, does not match a defined clock. Available clocks:\n " + - allClocks.map(_.name).mkString("\n ")) + /** + * Request a clock at a particular frequency + * + * @param name An identifier for the associated clock domain + * + * @param freqRequested Freq. for the domain in Hz + */ + def requestClock(name: String, freqRequested: Double): Clock = { + val clkWire = Wire(new Clock) + _harnessClockMap(name) = (freqRequested, clkWire) + clkWire + } - val baseClock = allClocks.find(_.name == baseClockName).get - val simplified = allClocks.map { c => - c.copy(multiplier = c.multiplier * baseClock.divisor, divisor = c.divisor * baseClock.multiplier) - .simplify - } + /** + * Get a RecordMap of clocks for a set of input RationalClocks. Used to drive + * the design elaborated by buildtop + * + * @param clockMapParameters Defines the set of required 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) - /** - * Removes clocks that have the same frequency before instantiating the - * clock bridge to avoid unnecessary BUFGCE use. - */ - val distinct = simplified.foldLeft(Seq(RationalClock(baseClockName, 1, 1))) { case (list, candidate) => - if (list.exists { clock => clock.equalFrequency(candidate) }) list else list :+ candidate + for (clock <- clockMapParameters.allClocks) { + val clockWire = Wire(new Clock) + _buildTopClockMap(clock.name) = (clock, clockWire) + clockRecord(clock.name).get := clockWire } + } - val clockBridge = Module(new RationalClockBridge(distinct)) - val cbVecTuples = distinct.zip(clockBridge.io.clocks) - val outputWire = Wire(RecordMap(simplified.map { c => (c.name, Clock()) }:_*)) - for (parameter <- simplified) { - val (_, cbClockField) = cbVecTuples.find(_._1.equalFrequency(parameter)).get - outputWire(parameter.name).get := cbClockField - } - _clockRecord = Some(outputWire) + _buildTopClockRecord.get + } + + /** + * Connect all clocks requested to ClockBridge + */ + def instantiateFireSimClockBridge: Unit = { + 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 == refRatClockName).get._2._1 + val simpleRatClocks = _buildTopClockMap.map { t => + val ratClock = t._2._1 + ratClock.copy( + multiplier = ratClock.multiplier * refRatClock.divisor, + divisor = ratClock.divisor * refRatClock.multiplier).simplify + } + + // Determine all the clock dividers (harness + rational clocks) + // Note: Requires that the BuildTop reference frequency is requested with proper freq. + 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 + val allSinkParams = harSinkParams :+ refRatSinkParams + + // Use PLL config to determine overall div's + val pllConfig = new SimplePllConfiguration("firesimOverallClockBridge", allSinkParams) + pllConfig.emitSummaries + + // Adjust all BuildTop RationalClocks with the div determined by the PLL + val refRatDiv = pllConfig.sinkDividerMap(refRatSinkParams) + val adjRefRatClocks = simpleRatClocks.map { clock => + clock.copy(divisor = clock.divisor * refRatDiv).simplify + } + + // Convert harness clocks to RationalClocks + val harRatClocks = harSinkParams.map { case ClockSinkParameters(_, _, _, _, clkParamsOpt, nameOpt) => + RationalClock(nameOpt.get, 1, pllConfig.referenceFreqMHz.toInt / clkParamsOpt.get.freqMHz.toInt) + } + + val allAdjRatClks = adjRefRatClocks ++ harRatClocks + + // Removes clocks that have the same frequency before instantiating the + // clock bridge to avoid unnecessary BUFGCE use. + val allDistinctRatClocks = allAdjRatClks.foldLeft(Seq(RationalClock(pllConfig.referenceSinkParams.name.get, 1, 1))) { + case (list, candidate) => if (list.exists { clock => clock.equalFrequency(candidate) }) list else list :+ candidate + } + + val clockBridge = Module(new RationalClockBridge(allDistinctRatClocks)) + val cbVecTuples = allDistinctRatClocks.zip(clockBridge.io.clocks) + + // 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 } + _harnessClockMap.get(clock.name).map { case (_, clk) => clk := cbClockField } } - getClockRecord } } @@ -117,29 +201,38 @@ class WithFireSimSimpleClocks extends Config((site, here, up) => { clockBundle.reset := reset } - val pllConfig = new SimplePllConfiguration("FireSim RationalClockBridge", clockGroupEdge.sink.members) + val pllConfig = new SimplePllConfiguration("firesimBuildTopClockGenerator", clockGroupEdge.sink.members) pllConfig.emitSummaries val rationalClockSpecs = for ((sinkP, division) <- pllConfig.sinkDividerMap) yield { RationalClock(sinkP.name.get, 1, division) } chiptop.harnessFunctions += ((th: HasHarnessSignalReferences) => { - reset := th.harnessReset + reset := th.buildtopReset input_clocks := p(ClockBridgeInstantiatorKey) - .getClockRecordOrInstantiate(rationalClockSpecs.toSeq, p(FireSimBaseClockNameKey)) + .requestClockRecordMap(BuildTopClockParameters( + rationalClockSpecs.toSeq, + p(FireSimBaseClockNameKey), + pllConfig.referenceFreqMHz * (1000 * 1000))) Nil }) + + // return the reference frequency + pllConfig.referenceFreqMHz } } }) class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSignalReferences { freechips.rocketchip.util.property.cover.setPropLib(new midas.passes.FireSimPropertyLibrary()) - val harnessClock = Wire(Clock()) - val harnessReset = WireInit(false.B) - val peekPokeBridge = PeekPokeBridge(harnessClock, harnessReset) + + val buildtopClock = Wire(Clock()) + val buildtopReset = WireInit(false.B) + val peekPokeBridge = PeekPokeBridge(buildtopClock, buildtopReset) def dutReset = { require(false, "dutReset should not be used in Firesim"); false.B } def success = { require(false, "success should not be used in Firesim"); false.B } + var btFreqMHz: Option[Double] = None + // Instantiate multiple instances of the DUT to implement supernode for (i <- 0 until p(NumNodes)) { // It's not a RC bump without some hacks... @@ -151,6 +244,12 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSigna case AsyncClockGroupsKey => p(AsyncClockGroupsKey).copy }))) val module = Module(lazyModule.module) + + btFreqMHz = Some(lazyModule match { + case d: HasReferenceClockFreq => d.refClockFreqMHz + case _ => p(DefaultClockFrequencyKey) + }) + lazyModule match { case d: HasTestHarnessFunctions => require(d.harnessFunctions.size == 1, "There should only be 1 harness function to connect clock+reset") d.harnessFunctions.foreach(_(this)) @@ -160,5 +259,8 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessSigna } NodeIdx.increment() } - harnessClock := p(ClockBridgeInstantiatorKey).getClockRecord("implicit_clock").get + + buildtopClock := p(ClockBridgeInstantiatorKey).requestClock("buildtop_reference_clock", btFreqMHz.get * (1000 * 1000)) + + p(ClockBridgeInstantiatorKey).instantiateFireSimClockBridge } diff --git a/generators/firechip/src/main/scala/TargetConfigs.scala b/generators/firechip/src/main/scala/TargetConfigs.scala index ece2546bd2..691ef15dda 100644 --- a/generators/firechip/src/main/scala/TargetConfigs.scala +++ b/generators/firechip/src/main/scala/TargetConfigs.scala @@ -12,7 +12,7 @@ import freechips.rocketchip.rocket.DCacheParams import freechips.rocketchip.subsystem._ import freechips.rocketchip.devices.tilelink.{BootROMLocated, BootROMParams} import freechips.rocketchip.devices.debug.{DebugModuleParams, DebugModuleKey} -import freechips.rocketchip.diplomacy.LazyModule +import freechips.rocketchip.diplomacy.{LazyModule, AsynchronousCrossing} import testchipip.{BlockDeviceKey, BlockDeviceConfig, TracePortKey, TracePortParams} import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams} import scala.math.{min, max} @@ -50,6 +50,7 @@ class WithScalaTestFeatures extends Config((site, here, up) => { // FASED Config Aliases. This to enable config generation via "_" concatenation // which requires that all config classes be defined in the same package +class DDR3FCFS extends FCFS16GBQuadRank class DDR3FRFCFS extends FRFCFS16GBQuadRank class DDR3FRFCFSLLC4MB extends FRFCFS16GBQuadRankLLC4MB @@ -59,28 +60,14 @@ class WithNIC extends icenet.WithIceNIC(inBufFlits = 8192, ctrlQueueDepth = 64) class WithNVDLALarge extends nvidia.blocks.dla.WithNVDLA("large") class WithNVDLASmall extends nvidia.blocks.dla.WithNVDLA("small") - -// Tweaks that are generally applied to all firesim configs -class WithFireSimConfigTweaks extends Config( +// Non-frequency tweaks that are generally applied to all firesim configs +class WithFireSimDesignTweaks extends Config( // Required: Bake in the default FASED memory model new WithDefaultMemModel ++ // Required*: Uses FireSim ClockBridge and PeekPokeBridge to drive the system with a single clock/reset new WithFireSimSimpleClocks ++ // Required*: When using FireSim-as-top to provide a correct path to the target bootrom source new WithBootROM ++ - // Optional: This sets the default frequency for all buses in the system to 3.2 GHz - // (since unspecified bus frequencies will use the pbus frequency) - // This frequency selection matches FireSim's legacy selection and is required - // to support 200Gb NIC performance. You may select a smaller value. - new chipyard.config.WithPeripheryBusFrequency(3200.0) ++ - // Optional: These three configs put the DRAM memory system in it's own clock domian. - // Removing the first config will result in the FASED timing model running - // at the pbus freq (above, 3.2 GHz), which is outside the range of valid DDR3 speedgrades. - // 1 GHz matches the FASED default, using some other frequency will require - // runnings the FASED runtime configuration generator to generate faithful DDR3 timing values. - new chipyard.config.WithMemoryBusFrequency(1000.0) ++ - new chipyard.config.WithAsynchrousMemoryBusCrossing ++ - new testchipip.WithAsynchronousSerialSlaveCrossing ++ // Required: Existing FAME-1 transform cannot handle black-box clock gates new WithoutClockGating ++ // Required*: Removes thousands of assertions that would be synthesized (* pending PriorityMux bugfix) @@ -89,18 +76,56 @@ class WithFireSimConfigTweaks extends Config( new chipyard.config.WithTraceIO ++ // Optional: Request 16 GiB of target-DRAM by default (can safely request up to 32 GiB on F1) new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 16L) ++ - // Required: Adds IO to attach SerialBridge. The SerialBridges is responsible - // for signalling simulation termination under simulation success. This fragment can - // be removed if you supply an auxiliary bridge that signals simulation termination - new testchipip.WithDefaultSerialTL ++ // Optional: Removing this will require using an initramfs under linux new testchipip.WithBlockDevice ++ - // Optional: Set a UART baudrate (this selection matches FireSim's historical value) + // Required*: Scale default baud rate with periphery bus frequency new chipyard.config.WithUART(BigInt(3686400L)) ++ // Required: Do not support debug module w. JTAG until FIRRTL stops emitting @(posedge ~clock) new chipyard.config.WithNoDebug ) +// Tweaks to modify target clock frequencies / crossings to legacy firesim defaults +class WithFireSimHighPerfClocking extends Config( + // Optional: This sets the default frequency for all buses in the system to 3.2 GHz + // (since unspecified bus frequencies will use the pbus frequency) + // This frequency selection matches FireSim's legacy selection and is required + // to support 200Gb NIC performance. You may select a smaller value. + new chipyard.config.WithPeripheryBusFrequency(3200.0) ++ + // Optional: These three configs put the DRAM memory system in it's own clock domain. + // Removing the first config will result in the FASED timing model running + // at the pbus freq (above, 3.2 GHz), which is outside the range of valid DDR3 speedgrades. + // 1 GHz matches the FASED default, using some other frequency will require + // runnings the FASED runtime configuration generator to generate faithful DDR3 timing values. + new chipyard.config.WithMemoryBusFrequency(1000.0) ++ + new chipyard.config.WithAsynchrousMemoryBusCrossing ++ + new testchipip.WithAsynchronousSerialSlaveCrossing +) + +// Tweaks that are generally applied to all firesim configs setting a single clock domain at 1000 MHz +class WithFireSimConfigTweaks extends Config( + // 1 GHz matches the FASED default (DRAM modeli realistically configured for that frequency) + // Using some other frequency will require runnings the FASED runtime configuration generator + // to generate faithful DDR3 timing values. + new chipyard.config.WithSystemBusFrequency(1000.0) ++ + new chipyard.config.WithSystemBusFrequencyAsDefault ++ // All unspecified clock frequencies, notably the implicit clock, will use the sbus freq (1000 MHz) + // Explicitly set PBUS + MBUS to 1000 MHz, since they will be driven to 100 MHz by default because of assignments in the Chisel + new chipyard.config.WithPeripheryBusFrequency(1000.0) ++ + new chipyard.config.WithMemoryBusFrequency(1000.0) ++ + new WithFireSimDesignTweaks +) + +// Tweak more representative of testchip configs +class WithFireSimTestChipConfigTweaks extends Config( + new chipyard.config.WithTestChipBusFreqs ++ + new WithFireSimDesignTweaks +) + +// Tweaks for legacy FireSim configs. +class WithFireSimHighPerfConfigTweaks extends Config( + new WithFireSimHighPerfClocking ++ + new WithFireSimDesignTweaks +) + /******************************************************************************* * Full TARGET_CONFIG configurations. These set parameters of the target being * simulated. @@ -201,10 +226,14 @@ class FireSimCVA6Config extends Config( //********************************************************************************** //* Multiclock Configurations //*********************************************************************************/ -class FireSimMulticlockRocketConfig extends Config( - new chipyard.config.WithTileFrequency(6400.0) ++ //lol - new freechips.rocketchip.subsystem.WithRationalRocketTiles ++ // Add rational crossings between RocketTile and uncore - new FireSimRocketConfig) +class FireSimMulticlockAXIOverSerialConfig extends Config( + new WithAXIOverSerialTLCombinedBridges ++ // use combined bridge to connect to axi mem over serial + new WithDefaultFireSimBridges ++ + new testchipip.WithBlockDevice(false) ++ // disable blockdev + new WithDefaultMemModel ++ + new WithFireSimDesignTweaks ++ // don't inherit firesim clocking + new chipyard.MulticlockAXIOverSerialConfig +) //********************************************************************************** // System with 16 LargeBOOMs that can be simulated with Golden Gate optimizations @@ -217,3 +246,4 @@ class FireSim16LargeBoomConfig extends Config( new WithFireSimConfigTweaks ++ new boom.common.WithNLargeBooms(16) ++ new chipyard.config.AbstractConfig) + diff --git a/generators/firechip/src/test/scala/ScalaTestSuite.scala b/generators/firechip/src/test/scala/ScalaTestSuite.scala index 64b217b8f3..397f23d463 100644 --- a/generators/firechip/src/test/scala/ScalaTestSuite.scala +++ b/generators/firechip/src/test/scala/ScalaTestSuite.scala @@ -107,11 +107,6 @@ abstract class FireSimTestSuite( class RocketF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimQuadRocketConfig", "WithSynthAsserts_BaseF1Config") class BoomF1Tests extends FireSimTestSuite("FireSim", "DDR3FRFCFSLLC4MB_FireSimLargeBoomConfig", "BaseF1Config") class RocketNICF1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimRocketConfig", "BaseF1Config") -// Multiclock tests -class RocketMulticlockF1Tests extends FireSimTestSuite( - "FireSim", - "FireSimMulticlockRocketConfig", - "WithSynthAsserts_BaseF1Config") class CVA6F1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_FireSimCVA6Config", "BaseF1Config") @@ -119,5 +114,4 @@ class CVA6F1Tests extends FireSimTestSuite("FireSim", "WithNIC_DDR3FRFCFSLLC4MB_ class CITests extends Suites( new RocketF1Tests, new BoomF1Tests, - new RocketNICF1Tests, - new RocketMulticlockF1Tests) + new RocketNICF1Tests) diff --git a/generators/gemmini b/generators/gemmini index e6e14f7117..7ac61db64f 160000 --- a/generators/gemmini +++ b/generators/gemmini @@ -1 +1 @@ -Subproject commit e6e14f711760b976d8eb00c32d0fe2423aeda211 +Subproject commit 7ac61db64fecbc8918b3039d738513b4a03337ca diff --git a/generators/sha3 b/generators/sha3 index 74e41f5792..63eda8268c 160000 --- a/generators/sha3 +++ b/generators/sha3 @@ -1 +1 @@ -Subproject commit 74e41f579213549501ccf292d101f9db73ee2347 +Subproject commit 63eda8268c16c502cada9944ae41b584e6e32789 diff --git a/generators/testchipip b/generators/testchipip index 6572beb03b..0743c5a941 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 6572beb03bc6eb0575269eaf4cc960b72b3ddef3 +Subproject commit 0743c5a9410af713fb7a1c0025d6331dfedec328 diff --git a/generators/utilities/src/main/resources/bootrom b/generators/utilities/src/main/resources/bootrom deleted file mode 120000 index fb0b1375ae..0000000000 --- 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 fa157a3652..0000000000 --- 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 7de0a9382f..dbae93bcfd 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 92cd24dc0a..19fa524e44 100755 --- a/scripts/build-toolchains.sh +++ b/scripts/build-toolchains.sh @@ -6,7 +6,9 @@ set -e set -o pipefail -DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +# If BASH_SOURCE is undefined, we may be running under zsh, in that case +# provide a zsh-compatible alternative +DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]:-${(%):-%x}}")")" CHIPYARD_DIR="$(dirname "$DIR")" usage() { @@ -18,10 +20,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 " --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" } @@ -36,7 +40,9 @@ die() { TOOLCHAIN="riscv-tools" EC2FASTINSTALL="false" IGNOREQEMU="" +CLEANAFTERINSTALL="" RISCV="" +ARCH="" # getopts does not support long options, and is inflexible while [ "$1" != "" ]; @@ -48,8 +54,12 @@ do shift RISCV=$(realpath $1) ;; --ignore-qemu ) - shift IGNOREQEMU="true" ;; + -a | --arch ) + shift + ARCH=$1 ;; + --clean-after-install ) + CLEANAFTERINSTALL="true" ;; riscv-tools | esp-tools) TOOLCHAIN=$1 ;; ec2fast ) @@ -66,6 +76,15 @@ if [ -z "$RISCV" ] ; then RISCV="$(pwd)/$INSTALL_DIR" fi +if [ -z "$ARCH" ] ; then + XLEN=64 +elif [[ "$ARCH" =~ ^rv(32|64)((i?m?a?f?d?|g?)c?)$ ]]; then + XLEN=${BASH_REMATCH[1]} +else + error "invalid arch $ARCH" + usage 1 +fi + echo "Installing toolchain to $RISCV" # install risc-v tools @@ -119,7 +138,7 @@ else esac module_prepare riscv-gnu-toolchain qemu - module_build riscv-gnu-toolchain --prefix="${RISCV}" --with-cmodel=medany + module_build riscv-gnu-toolchain --prefix="${RISCV}" --with-cmodel=medany ${ARCH:+--with-arch=${ARCH}} echo '==> Building GNU/Linux toolchain' module_make riscv-gnu-toolchain linux fi @@ -130,15 +149,34 @@ echo '==> Installing libfesvr static library' module_make riscv-isa-sim libfesvr.a cp -p "${SRCDIR}/riscv-isa-sim/build/libfesvr.a" "${RISCV}/lib/" -CC= CXX= module_all riscv-pk --prefix="${RISCV}" --host=riscv64-unknown-elf -module_all riscv-tests --prefix="${RISCV}/riscv64-unknown-elf" +CC= CXX= module_all riscv-pk --prefix="${RISCV}" --host=riscv${XLEN}-unknown-elf +module_all riscv-tests --prefix="${RISCV}/riscv${XLEN}-unknown-elf" --with-xlen=${XLEN} # Common tools (not in any particular toolchain dir) -CC= CXX= SRCDIR="$(pwd)/toolchains" module_all libgloss --prefix="${RISCV}/riscv64-unknown-elf" --host=riscv64-unknown-elf +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=riscv64-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 892b274d08..1af11aeec1 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 89e8644c36..8c7ac3a0ab 100755 --- a/scripts/centos-req.sh +++ b/scripts/centos-req.sh @@ -4,23 +4,30 @@ 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 # install DTC sudo yum install -y dtc +sudo yum install -y python # install verilator 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 new file mode 100755 index 0000000000..457656e81e --- /dev/null +++ b/scripts/entrypoint.sh @@ -0,0 +1,8 @@ +#!/bin/bash + +# 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 + +. /root/chipyard/env.sh + +exec "$@" diff --git a/scripts/init-submodules-no-riscv-tools-nolog.sh b/scripts/init-submodules-no-riscv-tools-nolog.sh index 0039d9df15..2d2e920cef 100755 --- a/scripts/init-submodules-no-riscv-tools-nolog.sh +++ b/scripts/init-submodules-no-riscv-tools-nolog.sh @@ -17,7 +17,9 @@ if [ "$MINGIT" != "$(echo -e "$MINGIT\n$MYGIT" | sort -V | head -n1)" ]; then false fi -DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" +# If BASH_SOURCE is undefined we may be running under zsh, in that case +# provide a zsh-compatible alternative +DIR="$(dirname "$(readlink -f "${BASH_SOURCE[0]:-${(%):-%x}}")")" CHIPYARD_DIR="$(dirname "$DIR")" cd "$CHIPYARD_DIR" diff --git a/scripts/tutorial-patches/build.sbt.patch b/scripts/tutorial-patches/build.sbt.patch index 62cecb8df4..0e55dde41c 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`, + dsptools, `rocket-dsp-utils`, 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 3bc22c7395..ff5fe3ad88 100755 --- a/scripts/ubuntu-req.sh +++ b/scripts/ubuntu-req.sh @@ -2,25 +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 766dd0d31e..7c6c580d6e 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/firesim b/sims/firesim index 72a52523e1..b611551ca5 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 72a52523e18443d9ef9a1e2664cbc71a45fc0c57 +Subproject commit b611551ca5ea391513584dc2cde3d82717309125 diff --git a/sims/vcs/Makefile b/sims/vcs/Makefile index 2c44ae6e54..e364830be0 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 ######################################################################################### @@ -66,7 +81,7 @@ $(sim_debug): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib) $(EXTRA_SIM_REQS) ######################################################################################### .PRECIOUS: $(output_dir)/%.vpd %.vpd $(output_dir)/%.vpd: $(output_dir)/% $(sim_debug) - (set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $< >(spike-dasm > $<.out) | tee $<.log) + (set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $< >(spike-dasm > $<.out) | tee $<.log) ######################################################################################### # general cleanup rules diff --git a/sims/verilator/Makefile b/sims/verilator/Makefile index 2b250ee964..a1186acc74 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 aa8e6aa871..daf1040c0f 160000 --- a/software/firemarshal +++ b/software/firemarshal @@ -1 +1 @@ -Subproject commit aa8e6aa8714d46b74917ebaa91333f5727e34599 +Subproject commit daf1040c0f0ec449734cd183be876880357644fc diff --git a/software/spec2017 b/software/spec2017 index 8f2812bebc..83e3311047 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 f8b3641b27..6a3d2744d2 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/toolchains/esp-tools/riscv-isa-sim b/toolchains/esp-tools/riscv-isa-sim index fa94e84d4f..467da4f613 160000 --- a/toolchains/esp-tools/riscv-isa-sim +++ b/toolchains/esp-tools/riscv-isa-sim @@ -1 +1 @@ -Subproject commit fa94e84d4ff3e23ba909a63376b294e444234752 +Subproject commit 467da4f613e2a447af35e69ee4f14e5adc94664f diff --git a/toolchains/esp-tools/riscv-pk b/toolchains/esp-tools/riscv-pk index a3e4ac61d2..e8e6b3aaee 160000 --- a/toolchains/esp-tools/riscv-pk +++ b/toolchains/esp-tools/riscv-pk @@ -1 +1 @@ -Subproject commit a3e4ac61d2b1ff37a22b9193b85d3b94273e80cb +Subproject commit e8e6b3aaee44d43b48164fbd377864c3a682dbd3 diff --git a/toolchains/esp-tools/riscv-tests b/toolchains/esp-tools/riscv-tests index e116930c7d..7c3dfd3205 160000 --- a/toolchains/esp-tools/riscv-tests +++ b/toolchains/esp-tools/riscv-tests @@ -1 +1 @@ -Subproject commit e116930c7d4a30fc2a1378417089a089e9e4cad0 +Subproject commit 7c3dfd3205fa90104db06346e797a8eeea149207 diff --git a/toolchains/riscv-tools/riscv-isa-sim b/toolchains/riscv-tools/riscv-isa-sim index acd953afd2..bf4b1e09ed 160000 --- a/toolchains/riscv-tools/riscv-isa-sim +++ b/toolchains/riscv-tools/riscv-isa-sim @@ -1 +1 @@ -Subproject commit acd953afd2f52d64e2264c2c7c713dc0ad614406 +Subproject commit bf4b1e09ed8e7a11ecff9891b12ce5d7f3375722 diff --git a/toolchains/riscv-tools/riscv-pk b/toolchains/riscv-tools/riscv-pk index a3e4ac61d2..e8e6b3aaee 160000 --- a/toolchains/riscv-tools/riscv-pk +++ b/toolchains/riscv-tools/riscv-pk @@ -1 +1 @@ -Subproject commit a3e4ac61d2b1ff37a22b9193b85d3b94273e80cb +Subproject commit e8e6b3aaee44d43b48164fbd377864c3a682dbd3 diff --git a/toolchains/riscv-tools/riscv-tests b/toolchains/riscv-tools/riscv-tests index 19bfdab48c..1ce128fa78 160000 --- a/toolchains/riscv-tools/riscv-tests +++ b/toolchains/riscv-tools/riscv-tests @@ -1 +1 @@ -Subproject commit 19bfdab48c2a6da4a2c67d5779757da7b073811d +Subproject commit 1ce128fa78c24bb0ed399c647e7139322b5353a7 diff --git a/tools/api-config-chipsalliance b/tools/api-config-chipsalliance new file mode 160000 index 0000000000..fd8df1105a --- /dev/null +++ b/tools/api-config-chipsalliance @@ -0,0 +1 @@ +Subproject commit fd8df1105a92065425cd353b6855777e35bd79b4 diff --git a/tools/barstools b/tools/barstools index 689ebdc06e..a3711c4e19 160000 --- a/tools/barstools +++ b/tools/barstools @@ -1 +1 @@ -Subproject commit 689ebdc06e29028861f3282d9af6f2304541c9db +Subproject commit a3711c4e19911b57b21bdcf8d459d19795f3201d diff --git a/tools/rocket-dsp-utils b/tools/rocket-dsp-utils new file mode 160000 index 0000000000..355bf9f203 --- /dev/null +++ b/tools/rocket-dsp-utils @@ -0,0 +1 @@ +Subproject commit 355bf9f2038c68f4d44650f66d1516d171bfb224 diff --git a/variables.mk b/variables.mk index 88ba73ee21..5d136e801a 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 @@ -146,13 +153,16 @@ sim_common_files ?= $(build_dir)/sim_files.common.f # java arguments used in sbt ######################################################################################### JAVA_HEAP_SIZE ?= 8G -JAVA_OPTS ?= -Xmx$(JAVA_HEAP_SIZE) -Xss8M -XX:MaxPermSize=256M +JAVA_OPTS ?= -Xmx$(JAVA_HEAP_SIZE) -Xss8M -XX:MaxPermSize=256M -Djava.io.tmpdir=$(base_dir)/.java_tmp ######################################################################################### # 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/Makefile b/vlsi/Makefile index 182f7a950d..6ff0e735ff 100644 --- a/vlsi/Makefile +++ b/vlsi/Makefile @@ -26,33 +26,33 @@ SMEMS_COMP ?= $(tech_dir)/sram-compiler.json SMEMS_CACHE ?= $(tech_dir)/sram-cache.json SMEMS_HAMMER ?= $(build_dir)/$(long_name).mems.hammer.json -ifeq ($(tech_name),asap7) - MACROCOMPILER_MODE ?= --mode synflops -else ifdef USE_SRAM_COMPILER +ifdef USE_SRAM_COMPILER MACROCOMPILER_MODE ?= -l $(SMEMS_COMP) --use-compiler -hir $(SMEMS_HAMMER) --mode strict else MACROCOMPILER_MODE ?= -l $(SMEMS_CACHE) -hir $(SMEMS_HAMMER) --mode strict endif ENV_YML ?= $(vlsi_dir)/env.yml -INPUT_CONFS ?= $(if $(filter $(tech_name),nangate45),\ +INPUT_CONFS ?= example-tools.yml \ + $(if $(filter $(tech_name),nangate45),\ example-nangate45.yml,\ example-asap7.yml) HAMMER_EXEC ?= ./example-vlsi VLSI_TOP ?= $(TOP) VLSI_HARNESS_DUT_NAME ?= chiptop -VLSI_OBJ_DIR ?= $(vlsi_dir)/build +# If overriding, this should be relative to $(vlsi_dir) +VLSI_OBJ_DIR ?= build ifneq ($(CUSTOM_VLOG),) - OBJ_DIR ?= $(VLSI_OBJ_DIR)/custom-$(VLSI_TOP) + OBJ_DIR ?= $(vlsi_dir)/$(VLSI_OBJ_DIR)/custom-$(VLSI_TOP) else - OBJ_DIR ?= $(VLSI_OBJ_DIR)/$(long_name)-$(VLSI_TOP) + OBJ_DIR ?= $(vlsi_dir)/$(VLSI_OBJ_DIR)/$(long_name)-$(VLSI_TOP) endif ######################################################################################### # general rules ######################################################################################### ALL_RTL = $(TOP_FILE) $(TOP_SMEMS_FILE) -extra_v_includes = $(build_dir)/EICG_wrapper.v $(vlsi_dir)/example.v +extra_v_includes = $(build_dir)/EICG_wrapper.v ifneq ($(CUSTOM_VLOG), ) VLSI_RTL = $(CUSTOM_VLOG) VLSI_BB = /dev/null @@ -100,6 +100,19 @@ $(SRAM_CONF): $(SRAM_GENERATOR_CONF) # simulation input configuration ######################################################################################### include $(base_dir)/vcs.mk + +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)))" >> $@;)) + SIM_CONF = $(OBJ_DIR)/sim-inputs.yml SIM_DEBUG_CONF = $(OBJ_DIR)/sim-debug-inputs.yml SIM_TIMING_CONF = $(OBJ_DIR)/sim-timing-inputs.yml @@ -149,6 +162,7 @@ endif $(SIM_DEBUG_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_common_files) mkdir -p $(dir $@) + mkdir -p $(output_dir) echo "sim.inputs:" > $@ echo " defines: ['DEBUG']" >> $@ echo " defines_meta: 'append'" >> $@ @@ -157,6 +171,9 @@ $(SIM_DEBUG_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_commo echo ' - "'$$x'"' >> $@; \ done echo " execution_flags_meta: 'append'" >> $@ + echo " saif.mode: 'time'" >> $@ + echo " saif.start_time: '0ns'" >> $@ + echo " saif.end_time: '`bc <<< $(timeout_cycles)*$(CLOCK_PERIOD)`ns'" >> $@ echo "sim.outputs.waveforms: ['$(sim_out_name).vpd']" >> $@ $(SIM_TIMING_CONF): $(VLSI_RTL) $(HARNESS_FILE) $(HARNESS_SMEMS_FILE) $(sim_common_files) @@ -192,7 +209,7 @@ endif SYN_CONF = $(OBJ_DIR)/inputs.yml GENERATED_CONFS = $(SYN_CONF) ifeq ($(CUSTOM_VLOG), ) - GENERATED_CONFS += $(if $(filter $(tech_name), asap7), , $(SRAM_CONF)) + GENERATED_CONFS += $(SRAM_CONF) endif $(SYN_CONF): $(VLSI_RTL) $(VLSI_BB) diff --git a/vlsi/example-asap7.yml b/vlsi/example-asap7.yml deleted file mode 100644 index c8e4a72b85..0000000000 --- a/vlsi/example-asap7.yml +++ /dev/null @@ -1,144 +0,0 @@ -# Technology Setup -# Technology used is ASAP7 -vlsi.core.technology: asap7 -# Specify dir with ASAP7 tarball -technology.asap7.tarball_dir: "" - -vlsi.core.max_threads: 12 - -# General Hammer Inputs - -# Hammer will auto-generate a CPF for simple power designs; see hammer/src/hammer-vlsi/defaults.yml for more info -vlsi.inputs.power_spec_mode: "auto" -vlsi.inputs.power_spec_type: "cpf" - -# Specify clock signals -vlsi.inputs.clocks: [ - {name: "clock", period: "1ns", uncertainty: "0.1ns"} -] - -# Generate Make include to aid in flow -vlsi.core.build_system: make - -# Power Straps -par.power_straps_mode: generate -par.generate_power_straps_method: by_tracks -par.blockage_spacing: 2.0 -par.generate_power_straps_options: - by_tracks: - strap_layers: - - M3 - - M4 - - M5 - - M6 - - M7 - - M8 - - M9 - pin_layers: - - M9 - track_width: 7 # minimum allowed for M2 & M3 - track_spacing: 0 - track_spacing_M3: 1 # to avoid M2 shorts at higher density - track_start: 10 - power_utilization: 0.05 - power_utilization_M8: 1.0 - power_utilization_M9: 1.0 - -# Placement Constraints -# For ASAP7, all numbers must be 4x larger than final GDS -vlsi.inputs.placement_constraints: - - path: "Sha3AccelwBB" - type: toplevel - x: 0 - y: 0 - width: 300 - height: 300 - margins: - left: 0 - right: 0 - top: 0 - bottom: 0 - - path: "Sha3AccelwBB/dco" - type: hardmacro - x: 108 - y: 108 - width: 128 - height: 128 - orientation: r0 - top_layer: M9 - - path: "Sha3AccelwBB/place_obs_bottom" - type: obstruction - obs_types: ["place"] - x: 0 - y: 0 - width: 300 - height: 1.08 # 1 core site tall, necessary to avoid shorts - -# Pin placement constraints -vlsi.inputs.pin_mode: generated -vlsi.inputs.pin.generate_mode: semi_auto -vlsi.inputs.pin.assignments: [ - {pins: "*", layers: ["M5", "M7"], side: "bottom"} -] - -# Paths to extra libraries -vlsi.technology.extra_libraries_meta: ["append", "deepsubst"] -vlsi.technology.extra_libraries: - - library: - nldm liberty file_deepsubst_meta: "local" - nldm liberty file: "extra_libraries/example/ExampleDCO_PVT_0P63V_100C.lib" - lef file_deepsubst_meta: "local" - lef file: "extra_libraries/example/ExampleDCO.lef" - gds file_deepsubst_meta: "local" - gds file: "extra_libraries/example/ExampleDCO.gds" - corner: - nmos: "slow" - pmos: "slow" - temperature: "100 C" - supplies: - VDD: "0.63 V" - GND: "0 V" - - library: - nldm liberty file_deepsubst_meta: "local" - nldm liberty file: "extra_libraries/example/ExampleDCO_PVT_0P77V_0C.lib" - lef file_deepsubst_meta: "local" - lef file: "extra_libraries/example/ExampleDCO.lef" - gds file_deepsubst_meta: "local" - gds file: "extra_libraries/example/ExampleDCO.gds" - corner: - nmos: "fast" - pmos: "fast" - temperature: "0 C" - supplies: - VDD: "0.77 V" - GND: "0 V" - -# Because the DCO is a dummy layout, we treat it as a physical-only cell -par.inputs.physical_only_cells_mode: append -par.inputs.physical_only_cells_list: - - ExampleDCO - -# SRAM Compiler compiler options -vlsi.core.sram_generator_tool: "sram_compiler" -# You should specify a location for the SRAM generator in the tech plugin -vlsi.core.sram_generator_tool_path: [] -vlsi.core.sram_generator_tool_path_meta: "append" - -# Tool options. Replace with your tool plugin of choice. -# Genus options -vlsi.core.synthesis_tool: "genus" -vlsi.core.synthesis_tool_path: ["hammer-cadence-plugins/synthesis"] -vlsi.core.synthesis_tool_path_meta: "append" -synthesis.genus.version: "1813" -# Innovus options -vlsi.core.par_tool: "innovus" -vlsi.core.par_tool_path: ["hammer-cadence-plugins/par"] -vlsi.core.par_tool_path_meta: "append" -par.innovus.version: "181" -par.innovus.design_flow_effort: "standard" -par.inputs.gds_merge: true -# Calibre options -vlsi.core.drc_tool: "calibre" -vlsi.core.drc_tool_path: ["hammer-mentor-plugins/drc"] -vlsi.core.lvs_tool: "calibre" -vlsi.core.lvs_tool_path: ["hammer-mentor-plugins/lvs"] diff --git a/vlsi/example-asap7yml b/vlsi/example-asap7yml new file mode 100644 index 0000000000..d8011a80b5 --- /dev/null +++ b/vlsi/example-asap7yml @@ -0,0 +1,121 @@ +# Technology Setup +# Technology used is ASAP7 +vlsi.core.technology: asap7 +# Specify dir with ASAP7 tarball +technology.asap7.tarball_dir: "" + +vlsi.core.max_threads: 12 + +# General Hammer Inputs + +# Hammer will auto-generate a CPF for simple power designs; see hammer/src/hammer-vlsi/defaults.yml for more info +vlsi.inputs.power_spec_mode: "auto" +vlsi.inputs.power_spec_type: "cpf" + +# Specify clock signals +vlsi.inputs.clocks: [ + {name: "clock", period: "1ns", uncertainty: "0.1ns"} +] + +# Generate Make include to aid in flow +vlsi.core.build_system: make + +# Power Straps +par.power_straps_mode: generate +par.generate_power_straps_method: by_tracks +par.blockage_spacing: 2.0 +par.generate_power_straps_options: + by_tracks: + strap_layers: + - M3 + - M4 + - M5 + - M6 + - M7 + - M8 + - M9 + pin_layers: + - M9 + track_width: 7 # minimum allowed for M2 & M3 + track_spacing: 0 + track_spacing_M3: 1 # to avoid M2 shorts at higher density + track_start: 10 + power_utilization: 0.2 + power_utilization_M8: 1.0 + power_utilization_M9: 1.0 + +# Placement Constraints +# For ASAP7, all numbers must be 4x larger than final GDS +vlsi.inputs.placement_constraints: + - path: "ChipTop" + type: toplevel + x: 0 + y: 0 + width: 800 + height: 500 + margins: + left: 0 + right: 0 + top: 0 + bottom: 0 + - path: "ChipTop/system/tile_prci_domain/tile_reset_domain/tile/dcache/data/data_arrays_0/data_arrays_0_ext/mem_0_0" + type: hardmacro + x: 550 + y: 25 + orientation: "r0" + top_layer: "M4" + master: "SRAM1RW4096x8" + - path: "ChipTop/system/tile_prci_domain/tile_reset_domain/tile/dcache/data/data_arrays_0/data_arrays_0_ext/mem_0_1" + type: hardmacro + x: 550 + y: 270 + orientation: "r0" + top_layer: "M4" + - path: "ChipTop/system/tile_prci_domain/tile_reset_domain/tile/dcache/data/data_arrays_0/data_arrays_0_ext/mem_0_2" + type: hardmacro + x: 675 + y: 25 + orientation: "r0" + top_layer: "M4" + master: "SRAM1RW4096x8" + - path: "ChipTop/system/tile_prci_domain/tile_reset_domain/tile/dcache/data/data_arrays_0/data_arrays_0_ext/mem_0_3" + type: hardmacro + x: 675 + y: 270 + orientation: "r0" + top_layer: "M4" + master: "SRAM1RW4096x8" + - path: "ChipTop/system/tile_prci_domain/tile_reset_domain/tile/frontend/icache/tag_array/tag_array_ext/mem_0_0" + type: hardmacro + x: 125 + y: 150 + orientation: "my" + top_layer: "M4" + master: "SRAM1RW64x21" + - path: "ChipTop/system/tile_prci_domain/tile_reset_domain/tile/frontend/icache/data_arrays_0/data_arrays_0_0_ext/mem_0_0" + type: hardmacro + x: 0 + y: 25 + orientation: "my" + top_layer: "M4" + master: "SRAM1RW1024x32" + - path: "ChipTop/system/tile_prci_domain/tile_reset_domain/tile/ptw/l2_tlb_ram/l2_tlb_ram_ext/mem_0_0" + type: hardmacro + x: 0 + y: 260 + orientation: "my" + top_layer: "M4" + master: "SRAM1RW1024x37" + +# Pin placement constraints +vlsi.inputs.pin_mode: generated +vlsi.inputs.pin.generate_mode: semi_auto +vlsi.inputs.pin.assignments: [ + {pins: "*", layers: ["M5", "M7"], side: "bottom"} +] + +# SRAM Compiler compiler options +vlsi.core.sram_generator_tool: "sram_compiler" +# You should specify a location for the SRAM generator in the tech plugin +vlsi.core.sram_generator_tool_path: ["hammer/src/hammer-vlsi/technology/asap7"] +vlsi.core.sram_generator_tool_path_meta: "append" diff --git a/vlsi/example-tools.yml b/vlsi/example-tools.yml index 338481ec5e..aad8afe52d 100644 --- a/vlsi/example-tools.yml +++ b/vlsi/example-tools.yml @@ -26,7 +26,7 @@ vlsi.core.lvs_tool_path: ["hammer-mentor-plugins/lvs"] vlsi.core.sim_tool: "vcs" vlsi.core.sim_tool_path: ["hammer-synopsys-plugins/sim"] sim.vcs.version: "P-2019.06-SP2-5" -# # Voltus options +# Voltus options vlsi.core.power_tool: "voltus" vlsi.core.power_tool_path: ["hammer-cadence-plugins/power"] vlsi.core.power_tool_path_meta: "append" diff --git a/vlsi/example.v b/vlsi/example.v deleted file mode 100644 index dbc7bec50b..0000000000 --- a/vlsi/example.v +++ /dev/null @@ -1,65 +0,0 @@ -// Sha3Accel w/ a blackbox (a dummy DCO) included inside - -module Sha3AccelwBB( // @[:example.TestHarness.Sha3RocketConfig.fir@135905.2] - input clock, // @[:example.TestHarness.Sha3RocketConfig.fir@135906.4] - input reset, // @[:example.TestHarness.Sha3RocketConfig.fir@135907.4] - output io_cmd_ready, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input io_cmd_valid, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input [6:0] io_cmd_bits_inst_funct, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input [63:0] io_cmd_bits_rs1, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input [63:0] io_cmd_bits_rs2, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input io_mem_req_ready, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - output io_mem_req_valid, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - output [39:0] io_mem_req_bits_addr, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - output [7:0] io_mem_req_bits_tag, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - output [4:0] io_mem_req_bits_cmd, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - output [63:0] io_mem_req_bits_data, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input io_mem_resp_valid, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input [7:0] io_mem_resp_bits_tag, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input [63:0] io_mem_resp_bits_data, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - output io_busy, // @[:example.TestHarness.Sha3RocketConfig.fir@135909.4] - input [13:0] col_sel_b, - input [15:0] row_sel_b, - input [7:0] code_regulator, - input dither, - input sleep_b, - output dco_clock -); - Sha3Accel sha3 ( - .clock(clock), - .reset(reset), - .io_cmd_ready(io_cmd_ready), - .io_cmd_valid(io_cmd_valid), - .io_cmd_bits_inst_funct(io_cmd_bits_inst_funct), - .io_cmd_bits_rs1(io_cmd_bits_rs1), - .io_cmd_bits_rs2(io_cmd_bits_rs2), - .io_mem_req_ready(io_mem_req_ready), - .io_mem_req_valid(io_mem_req_valid), - .io_mem_req_bits_addr(io_mem_req_bits_addr), - .io_mem_req_bits_tag(io_mem_req_bits_tag), - .io_mem_req_bits_cmd(io_mem_req_bits_cmd), - .io_mem_req_bits_data(io_mem_req_bits_data), - .io_mem_resp_valid(io_mem_resp_valid), - .io_mem_resp_bits_tag(io_mem_resp_bits_tag), - .io_mem_resp_bits_data(io_mem_resp_bits_data), - .io_busy(io_busy) - ); - ExampleDCO dco ( - .col_sel_b(col_sel_b), - .row_sel_b(row_sel_b), - .code_regulator(code_regulator), - .dither(dither), - .sleep_b(sleep_b), - .clock(dco_clock) - ); -endmodule - -module ExampleDCO ( - input [13:0] col_sel_b, - input [15:0] row_sel_b, - input [7:0] code_regulator, - input dither, - input sleep_b, - output clock -); -endmodule diff --git a/vlsi/extra_libraries/example/ExampleDCO.gds b/vlsi/extra_libraries/example/ExampleDCO.gds deleted file mode 100644 index 4864e115aa..0000000000 Binary files a/vlsi/extra_libraries/example/ExampleDCO.gds and /dev/null differ diff --git a/vlsi/extra_libraries/example/ExampleDCO.lef b/vlsi/extra_libraries/example/ExampleDCO.lef deleted file mode 100644 index 89e81a9d57..0000000000 --- a/vlsi/extra_libraries/example/ExampleDCO.lef +++ /dev/null @@ -1,377 +0,0 @@ -VERSION 5.6 ; -BUSBITCHARS "[]" ; -DIVIDERCHAR "/" ; - -MACRO ExampleDCO - CLASS BLOCK ; - ORIGIN 0 0 ; - FOREIGN ExampleDCO 0 0 ; - SIZE 123.936 BY 125.536 ; - SYMMETRY X Y ; - PIN VDD - DIRECTION INOUT ; - USE POWER ; - PORT - LAYER M5 ; - RECT 3.024 121.536 3.8 125.536 ; - END - END VDD - PIN VSS - DIRECTION INOUT ; - USE GROUND ; - PORT - LAYER M5 ; - RECT 1.728 121.536 2.5 125.536 ; - END - END VSS - PIN dither - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 0.384 1.2 0.768 ; - END - END dither - PIN row_sel_b[0] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 1.536 1.2 1.92 ; - END - END row_sel_b[0] - PIN row_sel_b[1] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 2.688 1.2 3.072 ; - END - END row_sel_b[1] - PIN row_sel_b[2] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 3.84 1.2 4.224 ; - END - END row_sel_b[2] - PIN row_sel_b[3] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 4.992 1.2 5.376 ; - END - END row_sel_b[3] - PIN row_sel_b[4] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 6.144 1.2 6.528 ; - END - END row_sel_b[4] - PIN row_sel_b[5] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 7.296 1.2 7.68 ; - END - END row_sel_b[5] - PIN row_sel_b[6] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 8.448 1.2 8.832 ; - END - END row_sel_b[6] - PIN row_sel_b[7] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 9.6 1.2 9.984 ; - END - END row_sel_b[7] - PIN row_sel_b[8] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 10.752 1.2 11.136 ; - END - END row_sel_b[8] - PIN row_sel_b[9] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 11.904 1.2 12.288 ; - END - END row_sel_b[9] - PIN row_sel_b[10] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 13.056 1.2 13.44 ; - END - END row_sel_b[10] - PIN row_sel_b[11] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 14.208 1.2 14.592 ; - END - END row_sel_b[11] - PIN row_sel_b[12] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 15.36 1.2 15.744 ; - END - END row_sel_b[12] - PIN row_sel_b[13] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 16.512 1.2 16.896 ; - END - END row_sel_b[13] - PIN row_sel_b[14] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 17.664 1.2 18.048 ; - END - END row_sel_b[14] - PIN row_sel_b[15] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 18.816 1.2 19.2 ; - END - END row_sel_b[15] - PIN col_sel_b[0] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 19.968 1.2 20.352 ; - END - END col_sel_b[0] - PIN col_sel_b[1] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 21.12 1.2 21.504 ; - END - END col_sel_b[1] - PIN col_sel_b[2] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 22.272 1.2 22.656 ; - END - END col_sel_b[2] - PIN col_sel_b[3] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 23.424 1.2 23.808 ; - END - END col_sel_b[3] - PIN col_sel_b[4] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 24.576 1.2 24.96 ; - END - END col_sel_b[4] - PIN col_sel_b[5] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 25.728 1.2 26.112 ; - END - END col_sel_b[5] - PIN col_sel_b[6] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 26.88 1.2 27.264 ; - END - END col_sel_b[6] - PIN col_sel_b[7] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 28.032 1.2 28.416 ; - END - END col_sel_b[7] - PIN col_sel_b[8] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 29.184 1.2 29.568 ; - END - END col_sel_b[8] - PIN col_sel_b[9] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 30.336 1.2 30.72 ; - END - END col_sel_b[9] - PIN col_sel_b[10] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 31.488 1.2 31.872 ; - END - END col_sel_b[10] - PIN col_sel_b[11] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 32.64 1.2 33.024 ; - END - END col_sel_b[11] - PIN col_sel_b[12] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 33.792 1.2 34.176 ; - END - END col_sel_b[12] - PIN col_sel_b[13] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 34.944 1.2 35.328 ; - END - END col_sel_b[13] - PIN code_regulator[0] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 36.096 1.2 36.48 ; - END - END code_regulator[0] - PIN code_regulator[1] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 37.248 1.2 37.632 ; - END - END code_regulator[1] - PIN code_regulator[2] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 38.4 1.2 38.784 ; - END - END code_regulator[2] - PIN code_regulator[3] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 39.552 1.2 39.936 ; - END - END code_regulator[3] - PIN code_regulator[4] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 40.704 1.2 41.088 ; - END - END code_regulator[4] - PIN code_regulator[5] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 41.856 1.2 42.24 ; - END - END code_regulator[5] - PIN code_regulator[6] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 43.008 1.2 43.392 ; - END - END code_regulator[6] - PIN code_regulator[7] - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 44.16 1.2 44.544 ; - END - END code_regulator[7] - PIN sleep_b - DIRECTION INPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 0.0 45.312 1.2 45.696 ; - END - END sleep_b - PIN clock - DIRECTION OUTPUT ; - USE SIGNAL ; - PORT - LAYER M4 ; - RECT 122.736 0.384 123.936 0.768 ; - END - END clock - OBS - LAYER M1 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M2 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M3 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M4 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M5 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M6 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M7 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M8 ; - RECT 1.2 0.0 122.736 121.536 ; - LAYER M9 ; - RECT 1.2 0.0 122.736 121.536 ; - END -END ExampleDCO - -END LIBRARY diff --git a/vlsi/extra_libraries/example/ExampleDCO_PVT_0P63V_100C.lib b/vlsi/extra_libraries/example/ExampleDCO_PVT_0P63V_100C.lib deleted file mode 100644 index 53d981eb76..0000000000 --- a/vlsi/extra_libraries/example/ExampleDCO_PVT_0P63V_100C.lib +++ /dev/null @@ -1,142 +0,0 @@ -library (ExampleDCO_PVT_0P63V_100C) { - technology (cmos); - date : "Mon Sep 2 16:01:59 2019"; - comment : "Generated by dotlibber.py"; - revision : 0; - delay_model : table_lookup; - simulation : true; - capacitive_load_unit (1,pf); - voltage_unit : "1V"; - current_unit : "1mA"; - time_unit : "1ns"; - pulling_resistance_unit : "1kohm"; - nom_process : 1; - nom_temperature : 100; - nom_voltage : 0.630000; - voltage_map(VDD, 0.630000); - voltage_map(VSS, 0.000000); - operating_conditions("PVT_0P63V_100C") { - process : 1; - temperature : 100; - voltage : 0.630000; - } - default_operating_conditions : PVT_0P63V_100C; - lu_table_template (constraint_template_3x3) { - variable_1 : related_pin_transition; - variable_2 : constrained_pin_transition; - index_1 ("0.0002, 0.0004, 0.0006"); - index_2 ("0.0002, 0.0004, 0.0006"); - } - lu_table_template (delay_template_8x8) { - variable_1 : input_net_transition; - variable_2 : total_output_net_capacitance; - index_1 ("0.0001, 0.0002, 0.0003, 0.0004, 0.0005, 0.0006, 0.0007, 0.0008"); - index_2 ("0.0011, 0.0022, 0.0033, 0.0044, 0.0055, 0.0066, 0.0077, 0.0088"); - } - - - type (bus_13_to_0) { - base_type : array ; - data_type : bit ; - bit_width : 14 ; - bit_from : 13 ; - bit_to : 0 ; - downto : true ; - } - - - type (bus_15_to_0) { - base_type : array ; - data_type : bit ; - bit_width : 16 ; - bit_from : 15 ; - bit_to : 0 ; - downto : true ; - } - - - type (bus_7_to_0) { - base_type : array ; - data_type : bit ; - bit_width : 8 ; - bit_from : 7 ; - bit_to : 0 ; - downto : true ; - } - cell (ExampleDCO) { - dont_use : true; - dont_touch : true; - is_macro_cell : true; - - pg_pin (VDD) { - pg_type : primary_power; - voltage_name : VDD; - } - - pg_pin (VSS) { - pg_type : primary_ground; - voltage_name : VSS; - } - - pin (clock) { - direction : output; - clock : true; - max_capacitance : 0.02; - related_power_pin : VDD; - related_ground_pin : VSS; - } - - bus ( col_sel_b ) { - bus_type : bus_13_to_0; - direction : input; - capacitance : 0.006; - max_transition : 0.04; - - pin ( col_sel_b[13:0] ) { - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - - bus ( row_sel_b ) { - bus_type : bus_15_to_0; - direction : input; - capacitance : 0.006; - max_transition : 0.04; - - pin ( row_sel_b[15:0] ) { - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - - bus ( code_regulator ) { - bus_type : bus_7_to_0; - direction : input; - capacitance : 0.006; - max_transition : 0.04; - - pin ( code_regulator[7:0] ) { - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - - pin (dither) { - direction : input; - capacitance : 0.006; - max_transition : 0.04; - related_power_pin : VDD; - related_ground_pin : VSS; - } - - pin (sleep_b) { - direction : input; - capacitance : 0.006; - max_transition : 0.04; - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - -} diff --git a/vlsi/extra_libraries/example/ExampleDCO_PVT_0P77V_0C.lib b/vlsi/extra_libraries/example/ExampleDCO_PVT_0P77V_0C.lib deleted file mode 100644 index 374b1899a9..0000000000 --- a/vlsi/extra_libraries/example/ExampleDCO_PVT_0P77V_0C.lib +++ /dev/null @@ -1,142 +0,0 @@ -library (ExampleDCO_PVT_0P77V_0C) { - technology (cmos); - date : "Mon Sep 2 16:01:59 2019"; - comment : "Generated by dotlibber.py"; - revision : 0; - delay_model : table_lookup; - simulation : true; - capacitive_load_unit (1,pf); - voltage_unit : "1V"; - current_unit : "1mA"; - time_unit : "1ns"; - pulling_resistance_unit : "1kohm"; - nom_process : 1; - nom_temperature : 0; - nom_voltage : 0.770000; - voltage_map(VDD, 0.770000); - voltage_map(VSS, 0.000000); - operating_conditions("PVT_0P77V_0C") { - process : 1; - temperature : 0; - voltage : 0.770000; - } - default_operating_conditions : PVT_0P77V_0C; - lu_table_template (constraint_template_3x3) { - variable_1 : related_pin_transition; - variable_2 : constrained_pin_transition; - index_1 ("0.0001, 0.0002, 0.0003"); - index_2 ("0.0001, 0.0002, 0.0003"); - } - lu_table_template (delay_template_8x8) { - variable_1 : input_net_transition; - variable_2 : total_output_net_capacitance; - index_1 ("0.0003, 0.0004, 0.0005, 0.0006, 0.0007, 0.0008, 0.0009, 0.001"); - index_2 ("0.0011, 0.0022, 0.0033, 0.0044, 0.0055, 0.0066, 0.0077, 0.0088"); - } - - - type (bus_13_to_0) { - base_type : array ; - data_type : bit ; - bit_width : 14 ; - bit_from : 13 ; - bit_to : 0 ; - downto : true ; - } - - - type (bus_15_to_0) { - base_type : array ; - data_type : bit ; - bit_width : 16 ; - bit_from : 15 ; - bit_to : 0 ; - downto : true ; - } - - - type (bus_7_to_0) { - base_type : array ; - data_type : bit ; - bit_width : 8 ; - bit_from : 7 ; - bit_to : 0 ; - downto : true ; - } - cell (ExampleDCO) { - dont_use : true; - dont_touch : true; - is_macro_cell : true; - - pg_pin (VDD) { - pg_type : primary_power; - voltage_name : VDD; - } - - pg_pin (VSS) { - pg_type : primary_ground; - voltage_name : VSS; - } - - pin (clock) { - direction : output; - clock : true; - max_capacitance : 0.02; - related_power_pin : VDD; - related_ground_pin : VSS; - } - - bus ( col_sel_b ) { - bus_type : bus_13_to_0; - direction : input; - capacitance : 0.006; - max_transition : 0.04; - - pin ( col_sel_b[13:0] ) { - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - - bus ( row_sel_b ) { - bus_type : bus_15_to_0; - direction : input; - capacitance : 0.006; - max_transition : 0.04; - - pin ( row_sel_b[15:0] ) { - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - - bus ( code_regulator ) { - bus_type : bus_7_to_0; - direction : input; - capacitance : 0.006; - max_transition : 0.04; - - pin ( code_regulator[7:0] ) { - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - - pin (dither) { - direction : input; - capacitance : 0.006; - max_transition : 0.04; - related_power_pin : VDD; - related_ground_pin : VSS; - } - - pin (sleep_b) { - direction : input; - capacitance : 0.006; - max_transition : 0.04; - related_power_pin : VDD; - related_ground_pin : VSS; - } - } - -} diff --git a/vlsi/hammer b/vlsi/hammer index 8fd1486499..353af21da3 160000 --- a/vlsi/hammer +++ b/vlsi/hammer @@ -1 +1 @@ -Subproject commit 8fd1486499b875d56f09b060f03a62775f0a6aa7 +Subproject commit 353af21da3fe6f0c2e054ac513b5db583031b962 diff --git a/vlsi/hammer-cadence-plugins b/vlsi/hammer-cadence-plugins index 3e5b046be1..191026ed35 160000 --- a/vlsi/hammer-cadence-plugins +++ b/vlsi/hammer-cadence-plugins @@ -1 +1 @@ -Subproject commit 3e5b046be13fb3fd4e00402acfbfd295a5da0a68 +Subproject commit 191026ed35fd86ba471d81a130f898db2928c7f4 diff --git a/vlsi/hammer-synopsys-plugins b/vlsi/hammer-synopsys-plugins index f8a7922220..5825e6dc4b 160000 --- a/vlsi/hammer-synopsys-plugins +++ b/vlsi/hammer-synopsys-plugins @@ -1 +1 @@ -Subproject commit f8a7922220c70b6905b37ab30bda6c791b594792 +Subproject commit 5825e6dc4b935e0c1ce3030dc7a94bd8d90ee5eb diff --git a/vlsi/power.mk b/vlsi/power.mk index 383da5f0dd..ce66606f0c 100644 --- a/vlsi/power.mk +++ b/vlsi/power.mk @@ -1,6 +1,10 @@ .PHONY: $(POWER_CONF) power-par: $(POWER_CONF) sim-par +power-par-$(VLSI_TOP): $(POWER_CONF) sim-par-$(VLSI_TOP) power-par: override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) +power-par-$(VLSI_TOP): override HAMMER_POWER_EXTRA_ARGS += -p $(POWER_CONF) redo-power-par: $(POWER_CONF) +redo-power-par-$(VLSI_TOP): $(POWER_CONF) redo-power-par: override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) -$(OBJ_DIR)/power-par-rundir/power-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_POWER_EXTRA_ARGS) +redo-power-par-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(POWER_CONF) +$(OBJ_DIR)/power-par-%/power-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_POWER_EXTRA_ARGS) diff --git a/vlsi/sim.mk b/vlsi/sim.mk index 6de46a9026..5bd02853a2 100644 --- a/vlsi/sim.mk +++ b/vlsi/sim.mk @@ -1,44 +1,85 @@ .PHONY: $(SIM_CONF) $(SIM_DEBUG_CONF) $(SIM_TIMING_CONF) # Update hammer top-level sim targets to include our generated sim configs redo-sim-rtl: $(SIM_CONF) +redo-sim-rtl-$(VLSI_TOP): $(SIM_CONF) redo-sim-rtl: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) +redo-sim-rtl-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) redo-sim-rtl: override HAMMER_SIM_RUN_DIR = sim-rtl-rundir +redo-sim-rtl-$(VLSI_TOP): override HAMMER_SIM_RUN_DIR = sim-rtl-$(VLSI_TOP) redo-sim-rtl-debug: $(SIM_DEBUG_CONF) redo-sim-rtl +redo-sim-rtl-debug-$(VLSI_TOP): $(SIM_DEBUG_CONF) redo-sim-rtl-$(VLSI_TOP) redo-sim-rtl-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) +redo-sim-rtl-debug-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) redo-sim-syn: $(SIM_CONF) +redo-sim-syn-$(VLSI_TOP): $(SIM_CONF) redo-sim-syn: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) +redo-sim-syn-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) redo-sim-syn: override HAMMER_SIM_RUN_DIR = sim-syn-rundir +redo-sim-syn-$(VLSI_TOP): override HAMMER_SIM_RUN_DIR = sim-syn-$(VLSI_TOP) redo-sim-syn-debug: $(SIM_DEBUG_CONF) redo-sim-syn +redo-sim-syn-debug-$(VLSI_TOP): $(SIM_DEBUG_CONF) redo-sim-syn-$(VLSI_TOP) redo-sim-syn-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) +redo-sim-syn-debug-$(VLSI_TOP): 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-$(VLSI_TOP): $(SIM_TIMING_CONF) redo-sim-syn-debug-$(VLSI_TOP) +redo-sim-syn-timing-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_TIMING_CONF) +redo-sim-syn-timing-debug-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(SIM_TIMING_CONF) redo-sim-par: $(SIM_CONF) +redo-sim-par-$(VLSI_TOP): $(SIM_CONF) redo-sim-par: override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) +redo-sim-par-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(SIM_CONF) redo-sim-par: override HAMMER_SIM_RUN_DIR = sim-par-rundir +redo-sim-par-$(VLSI_TOP): override HAMMER_SIM_RUN_DIR = sim-par-$(VLSI_TOP) redo-sim-par-debug: $(SIM_DEBUG_CONF) redo-sim-par +redo-sim-par-debug-$(VLSI_TOP): $(SIM_DEBUG_CONF) redo-sim-par-$(VLSI_TOP) redo-sim-par-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) +redo-sim-par-debug-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) redo-sim-par-timing-debug: $(SIM_TIMING_CONF) redo-sim-par-debug +redo-sim-par-timing-debug-$(VLSI_TOP): $(SIM_TIMING_CONF) redo-sim-par-debug-$(VLSI_TOP) redo-sim-par-timing-debug: override HAMMER_EXTRA_ARGS += -p $(SIM_TIMING_CONF) +redo-sim-par-timing-debug-$(VLSI_TOP): override HAMMER_EXTRA_ARGS += -p $(SIM_TIMING_CONF) sim-rtl: $(SIM_CONF) +sim-rtl-$(VLSI_TOP): $(SIM_CONF) sim-rtl: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF) +sim-rtl-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF) sim-rtl: override HAMMER_SIM_RUN_DIR = sim-rtl-rundir +sim-rtl-$(VLSI_TOP): override HAMMER_SIM_RUN_DIR = sim-rtl-$(VLSI_TOP) sim-rtl-debug: $(SIM_DEBUG_CONF) sim-rtl +sim-rtl-debug-$(VLSI_TOP): $(SIM_DEBUG_CONF) sim-rtl-$(VLSI_TOP) sim-rtl-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) -$(OBJ_DIR)/sim-rtl-rundir/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS) +sim-rtl-debug-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) sim-syn: $(SIM_CONF) +sim-syn-$(VLSI_TOP): $(SIM_CONF) sim-syn: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF) +sim-syn-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF) sim-syn: override HAMMER_SIM_RUN_DIR = sim-syn-rundir +sim-syn-$(VLSI_TOP): override HAMMER_SIM_RUN_DIR = sim-syn-$(VLSI_TOP) sim-syn-debug: $(SIM_DEBUG_CONF) sim-syn +sim-syn-debug-$(VLSI_TOP): $(SIM_DEBUG_CONF) sim-syn-$(VLSI_TOP) sim-syn-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) -$(OBJ_DIR)/sim-syn-rundir/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS) +sim-syn-debug-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) +sim-syn-timing-debug: $(SIM_TIMING_CONF) sim-syn-debug +sim-syn-timing-debug-$(VLSI_TOP): $(SIM_TIMING_CONF) sim-syn-debug-$(VLSI_TOP) +sim-syn-timing-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_TIMING_CONF) +sim-syn-timing-debug-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_TIMING_CONF) sim-par: $(SIM_CONF) +sim-par-$(VLSI_TOP): $(SIM_CONF) sim-par: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF) +sim-par-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_CONF) sim-par: override HAMMER_SIM_RUN_DIR = sim-par-rundir +sim-par-$(VLSI_TOP): override HAMMER_SIM_RUN_DIR = sim-par-$(VLSI_TOP) sim-par-debug: $(SIM_DEBUG_CONF) sim-par +sim-par-debug-$(VLSI_TOP): $(SIM_DEBUG_CONF) sim-par-$(VLSI_TOP) sim-par-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) +sim-par-debug-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_DEBUG_CONF) sim-par-timing-debug: $(SIM_TIMING_CONF) sim-par-debug +sim-par-timing-debug-$(VLSI_TOP): $(SIM_TIMING_CONF) sim-par-debug-$(VLSI_TOP) sim-par-timing-debug: override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_TIMING_CONF) -$(OBJ_DIR)/sim-par-rundir/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS) +sim-par-timing-debug-$(VLSI_TOP): override HAMMER_SIM_EXTRA_ARGS += -p $(SIM_TIMING_CONF) + +$(OBJ_DIR)/sim-%/sim-output-full.json: private override HAMMER_EXTRA_ARGS += $(HAMMER_SIM_EXTRA_ARGS)