Merge pull request #773 from ucb-bar/dev
Chipyard 1.5 Release (Dev -> Master Tracking)
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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"]
|
||||
@@ -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 <PATH_NAME>:tag . # to build with tag (ex. 0.0.3)
|
||||
sudo docker login # login into the account to push to
|
||||
sudo docker push <PATH_NAME>: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 <PATH_NAME> `riscvboom/riscvboom-images`.
|
||||
Current up-to-date images are located in <PATH_NAME> `ucbbar/chipyard-image`
|
||||
@@ -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
|
||||
|
||||
6
.gitmodules
vendored
@@ -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
|
||||
|
||||
4
.java_tmp/.gitignore
vendored
Normal file
@@ -0,0 +1,4 @@
|
||||
# Ignore everything in this directory
|
||||
*
|
||||
# Except this file
|
||||
!.gitignore
|
||||
41
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
|
||||
|
||||
@@ -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
|
||||
|
||||
22
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)
|
||||
|
||||
|
||||
43
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) </dev/null 2> >(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) </dev/null | tee $(sim_out_name).log)
|
||||
|
||||
# run simulator with as much debug info as possible
|
||||
run-binary-debug: $(output_dir) $(sim_debug)
|
||||
run-binary-debug: $(output_dir) $(sim_debug) check-binary
|
||||
(set -o pipefail && $(NUMA_PREFIX) $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) $(WAVEFORM_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(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"
|
||||
|
||||
#########################################################################################
|
||||
|
||||
59
dockerfiles/Dockerfile
Normal file
@@ -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"]
|
||||
22
dockerfiles/README.md
Normal file
@@ -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=<COMMIT_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 <IMAGE_ID> <PATH_NAME>: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 <PATH_NAME>:tag # to push to repo with tag
|
||||
sudo docker run -it <IMAGE_ID> 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 <PATH_NAME> `riscvboom/riscvboom-images`.
|
||||
Current up-to-date images are located in <PATH_NAME> `ucbbar/chipyard-image`. NOTE: Less recent images in this path may not have toolchains initialized
|
||||
Current up-to-date CI images are located in <PATH_NAME> `ucbbar/chipyard-ci-image`.
|
||||
@@ -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
|
||||
make CONFIG=RocketConfig run-asm-tests
|
||||
|
||||
FireSim FPGA-accelerated simulations use TSI by default as well.
|
||||
|
||||
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
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Please refer to the following resources on how to debug with JTAG.
|
||||
Roughly the steps to debug with JTAG in simulation are as follows:
|
||||
|
||||
* https://github.com/chipsalliance/rocket-chip#-debugging-with-gdb
|
||||
* https://github.com/riscv/riscv-isa-sim#debugging-with-gdb
|
||||
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
|
||||
|
||||
3. `Follow the instructions here to connect to the simulation using OpenOCD + GDB. <https://github.com/chipsalliance/rocket-chip#4-launch-openocd>`__
|
||||
|
||||
.. 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 <https://github.com/chipsalliance/rocket-chip#-debugging-with-gdb>`__,
|
||||
`riscv-isa-sim GDB Docs <https://github.com/riscv/riscv-isa-sim#debugging-with-gdb>`__
|
||||
|
||||
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
|
||||
|
||||
In fact, this exact type of bringup setup is what the following section discusses:
|
||||
:ref:`Prototyping/VCU118:Introduction to the Bringup Design`.
|
||||
|
||||
38
docs/Advanced-Concepts/Harness-Clocks.rst
Normal file
@@ -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.
|
||||
@@ -14,4 +14,5 @@ They expect you to know about Chisel, Parameters, configs, etc.
|
||||
Debugging-BOOM
|
||||
Resources
|
||||
CDEs
|
||||
Harness-Clocks
|
||||
|
||||
|
||||
@@ -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:<TAG>
|
||||
|
||||
To run the Docker container in an interactive shell, run:
|
||||
|
||||
.. code-block:: shell
|
||||
|
||||
sudo docker run -it ucbbar/chipyard-image bash
|
||||
|
||||
What's Next?
|
||||
-------------------------------------------
|
||||
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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).
|
||||
|
||||
@@ -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 <https://github.com/ucb-bar/hammer/blob/8fd1486499b875d56f09b060f03a62775f0a6aa7/src/hammer-vlsi/technology/asap7/sram-cache-gen.py>`__.
|
||||
For information on writing ``.mdf`` files, look at `MDF on github <https://github.com/ucb-bar/plsi-mdf>`__ 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 <https://github.com/ucb-bar/plsi-mdf/blob/4be9b173647c77f990a542f4eb5f69af01d77316/macro_format.json>`_. A reference cache of SRAMs from the nangate45 technology library is `available here <https://github.com/ucb-bar/hammer/blob/8fd1486499b875d56f09b060f03a62775f0a6aa7/src/hammer-vlsi/technology/nangate45/sram-cache.json>`_.
|
||||
|
||||
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.
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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=<chipyard_config_name> tech_name=<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/<config-name>/syn-rundir``. The raw QoR data (area, timing, gate counts, etc.) will be found in ``build/<config-name>/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=<chipyard_config_name> tech_name=<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/<config-name>/par-rundir``. Specifically, the resulting GDSII file will be in that directory with the suffix ``*.gds``. and timing reports can be found in ``build/<config-name>/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=<chipyard_config_name> tech_name=<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"
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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 <http://asap.asu.edu/asap/>`__ 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 <http://asap.asu.edu/asap/>`__ 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 <https://github.com/The-OpenROAD-Project/asap7>`__ 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
|
||||
make buildfile CONFIG=TinyRocketConfig
|
||||
|
||||
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.
|
||||
|
||||
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 <https://github.com/ucb-bar/hammer/tree/master/src/hammer-vlsi/technology/asap7>`__.
|
||||
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-<syn/par>-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.
|
||||
|
||||
BIN
docs/_static/images/bringup-chipyard-config-communication.png
vendored
Normal file
|
After Width: | Height: | Size: 16 KiB |
BIN
docs/_static/images/chip-bringup-simulation.png
vendored
Normal file
|
After Width: | Height: | Size: 35 KiB |
BIN
docs/_static/images/chip-bringup.png
vendored
|
Before Width: | Height: | Size: 18 KiB After Width: | Height: | Size: 30 KiB |
BIN
docs/_static/images/chip-communication.png
vendored
|
Before Width: | Height: | Size: 104 KiB After Width: | Height: | Size: 83 KiB |
BIN
docs/_static/images/default-chipyard-config-communication.png
vendored
Normal file
|
After Width: | Height: | Size: 17 KiB |
@@ -2,3 +2,4 @@ Sphinx==1.8.5
|
||||
Pygments==2.7.4
|
||||
sphinx-autobuild
|
||||
sphinx_rtd_theme==0.2.5b1
|
||||
docutils==0.16
|
||||
|
||||
@@ -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
|
||||
#########################################################################################
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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 _ =>
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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) }
|
||||
} }
|
||||
} }
|
||||
}
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
})
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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))
|
||||
|
||||
val dutReset = reset.asAsyncReset
|
||||
buildtopClock := refClkBundle.clock
|
||||
buildtopReset := WireInit(refClkBundle.reset)
|
||||
val dutReset = refClkBundle.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)
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -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 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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -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)
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
for (clock <- clockMapParameters.allClocks) {
|
||||
val clockWire = Wire(new Clock)
|
||||
_buildTopClockMap(clock.name) = (clock, clockWire)
|
||||
clockRecord(clock.name).get := clockWire
|
||||
}
|
||||
|
||||
/**
|
||||
* 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
|
||||
}
|
||||
|
||||
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)
|
||||
}
|
||||
getClockRecord
|
||||
|
||||
_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 }
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
../../../../rocket-chip/bootrom
|
||||
@@ -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("<simulator-name>")
|
||||
.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("<target-directory>")
|
||||
.action((x, c) => c.copy(targetDir = x))
|
||||
.text("Target directory to put files")
|
||||
|
||||
opt[String]("dotFName")
|
||||
.abbr("df")
|
||||
.valueName("<dot-f filename>")
|
||||
.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
|
||||
}
|
||||
}
|
||||
@@ -1 +1 @@
|
||||
sbt.version=1.4.4
|
||||
sbt.version=1.4.9
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -49,6 +49,9 @@ module_make() ( # <submodule> <target..>
|
||||
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() ( # <submodule> [configure-arg..]
|
||||
@@ -81,6 +84,9 @@ module_build() ( # <submodule> [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
|
||||
)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
8
scripts/entrypoint.sh
Executable file
@@ -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 "$@"
|
||||
@@ -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"
|
||||
|
||||
@@ -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)
|
||||
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -21,3 +21,6 @@ SIM_LDFLAGS = \
|
||||
-lfesvr \
|
||||
-ldramsim \
|
||||
$(EXTRA_SIM_LDFLAGS)
|
||||
|
||||
SIM_FILE_REQS += \
|
||||
$(ROCKETCHIP_RSRCS_DIR)/vsrc/EICG_wrapper.v
|
||||
|
||||
@@ -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) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
||||
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(SEED_FLAG) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
||||
|
||||
#########################################################################################
|
||||
# general cleanup rules
|
||||
|
||||
@@ -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) \
|
||||
|
||||
@@ -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)
|
||||
{
|
||||
|
||||
1
tools/api-config-chipsalliance
Submodule
1
tools/rocket-dsp-utils
Submodule
21
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
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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"]
|
||||
121
vlsi/example-asap7yml
Normal file
@@ -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"
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
@@ -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
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@@ -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)
|
||||
|
||||