Merge remote-tracking branch 'origin/dev' into diplomatic-bridges
This commit is contained in:
@@ -145,6 +145,17 @@ jobs:
|
|||||||
name: Check that the tutorial-setup patches apply
|
name: Check that the tutorial-setup patches apply
|
||||||
command: |
|
command: |
|
||||||
scripts/tutorial-setup.sh
|
scripts/tutorial-setup.sh
|
||||||
|
documentation-check:
|
||||||
|
executor: main-env
|
||||||
|
steps:
|
||||||
|
- checkout
|
||||||
|
- run:
|
||||||
|
name: Check that documentation builds with no warnings/errors
|
||||||
|
command: |
|
||||||
|
sudo apt-get update -y
|
||||||
|
sudo apt-get install -y python3-pip
|
||||||
|
sudo pip3 install -r docs/requirements.txt
|
||||||
|
make -C docs html
|
||||||
|
|
||||||
install-riscv-toolchain:
|
install-riscv-toolchain:
|
||||||
executor: main-env
|
executor: main-env
|
||||||
@@ -357,6 +368,9 @@ workflows:
|
|||||||
# Attempt to apply the tutorial patches
|
# Attempt to apply the tutorial patches
|
||||||
- tutorial-setup-check
|
- tutorial-setup-check
|
||||||
|
|
||||||
|
# Check that documentation builds
|
||||||
|
- documentation-check
|
||||||
|
|
||||||
# Build extra tests
|
# Build extra tests
|
||||||
- build-extra-tests:
|
- build-extra-tests:
|
||||||
requires:
|
requires:
|
||||||
|
|||||||
@@ -10,7 +10,7 @@ To get started using Chipyard, see the documentation on the Chipyard documentati
|
|||||||
|
|
||||||
Chipyard is an open source framework for agile development of Chisel-based systems-on-chip.
|
Chipyard is an open source framework for agile development of Chisel-based systems-on-chip.
|
||||||
It will allow you to leverage the Chisel HDL, Rocket Chip SoC generator, and other [Berkeley][berkeley] projects to produce a [RISC-V][riscv] SoC with everything from MMIO-mapped peripherals to custom accelerators.
|
It will allow you to leverage the Chisel HDL, Rocket Chip SoC generator, and other [Berkeley][berkeley] projects to produce a [RISC-V][riscv] SoC with everything from MMIO-mapped peripherals to custom accelerators.
|
||||||
Chipyard contains processor cores ([Rocket][rocket-chip], [BOOM][boom], [Ariane][ariane]), accelerators ([Hwacha][hwacha]), memory systems, and additional peripherals and tooling to help create a full featured SoC.
|
Chipyard contains processor cores ([Rocket][rocket-chip], [BOOM][boom], [Ariane][ariane]), accelerators ([Hwacha][hwacha], [Gemmini][gemmini]), memory systems, and additional peripherals and tooling to help create a full featured SoC.
|
||||||
Chipyard supports multiple concurrent flows of agile hardware development, including software RTL simulation, FPGA-accelerated simulation ([FireSim][firesim]), automated VLSI flows ([Hammer][hammer]), and software workload generation for bare-metal and Linux-based systems ([FireMarshal][firemarshal]).
|
Chipyard supports multiple concurrent flows of agile hardware development, including software RTL simulation, FPGA-accelerated simulation ([FireSim][firesim]), automated VLSI flows ([Hammer][hammer]), and software workload generation for bare-metal and Linux-based systems ([FireMarshal][firemarshal]).
|
||||||
Chipyard is actively developed in the [Berkeley Architecture Research Group][ucb-bar] in the [Electrical Engineering and Computer Sciences Department][eecs] at the [University of California, Berkeley][berkeley].
|
Chipyard is actively developed in the [Berkeley Architecture Research Group][ucb-bar] in the [Electrical Engineering and Computer Sciences Department][eecs] at the [University of California, Berkeley][berkeley].
|
||||||
|
|
||||||
@@ -64,3 +64,4 @@ These publications cover many of the internal components used in Chipyard. Howev
|
|||||||
[boom]: https://github.com/ucb-bar/riscv-boom
|
[boom]: https://github.com/ucb-bar/riscv-boom
|
||||||
[firemarshal]: https://github.com/firesim/FireMarshal/
|
[firemarshal]: https://github.com/firesim/FireMarshal/
|
||||||
[ariane]: https://github.com/pulp-platform/ariane/
|
[ariane]: https://github.com/pulp-platform/ariane/
|
||||||
|
[gemmini]: https://github.com/ucb-bar/gemmini
|
||||||
|
|||||||
@@ -122,8 +122,12 @@ lazy val testchipip = (project in file("generators/testchipip"))
|
|||||||
.dependsOn(rocketchip, sifive_blocks)
|
.dependsOn(rocketchip, sifive_blocks)
|
||||||
.settings(commonSettings)
|
.settings(commonSettings)
|
||||||
|
|
||||||
|
lazy val iocell = (project in file("./tools/barstools/iocell/"))
|
||||||
|
.dependsOn(chisel)
|
||||||
|
.settings(commonSettings)
|
||||||
|
|
||||||
lazy val chipyard = conditionalDependsOn(project in file("generators/chipyard"))
|
lazy val chipyard = conditionalDependsOn(project in file("generators/chipyard"))
|
||||||
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities,
|
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, iocell,
|
||||||
sha3, // On separate line to allow for cleaner tutorial-setup patches
|
sha3, // On separate line to allow for cleaner tutorial-setup patches
|
||||||
gemmini, icenet, tracegen, ariane)
|
gemmini, icenet, tracegen, ariane)
|
||||||
.settings(commonSettings)
|
.settings(commonSettings)
|
||||||
|
|||||||
47
common.mk
47
common.mk
@@ -3,15 +3,26 @@
|
|||||||
#########################################################################################
|
#########################################################################################
|
||||||
SHELL=/bin/bash
|
SHELL=/bin/bash
|
||||||
|
|
||||||
|
#########################################################################################
|
||||||
|
# extra make variables/rules from subprojects
|
||||||
|
#
|
||||||
|
# EXTRA_GENERATOR_REQS - requirements needed for the main generator
|
||||||
|
# EXTRA_SIM_FLAGS - runtime simulation flags
|
||||||
|
# EXTRA_SIM_CC_FLAGS - cc flags for simulators
|
||||||
|
# EXTRA_SIM_SOURCES - simulation sources needed for simulator
|
||||||
|
# EXTRA_SIM_REQS - requirements to build the simulator
|
||||||
|
#########################################################################################
|
||||||
|
include $(base_dir)/generators/ariane/ariane.mk
|
||||||
|
include $(base_dir)/generators/tracegen/tracegen.mk
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# variables to get all *.scala files
|
# variables to get all *.scala files
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
lookup_srcs = $(shell find -L $(1)/ -name target -prune -o -iname "*.$(2)" -print 2> /dev/null)
|
lookup_srcs = $(shell find -L $(1)/ -name target -prune -o -iname "*.$(2)" -print 2> /dev/null)
|
||||||
|
|
||||||
SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim)
|
SOURCE_DIRS = $(addprefix $(base_dir)/,generators sims/firesim/sim tools/barstools/iocell)
|
||||||
SCALA_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),scala)
|
SCALA_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),scala)
|
||||||
VLOG_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),sv) $(call lookup_srcs,$(SOURCE_DIRS),v)
|
VLOG_SOURCES = $(call lookup_srcs,$(SOURCE_DIRS),sv) $(call lookup_srcs,$(SOURCE_DIRS),v)
|
||||||
ARIANE_VLOG_SOURCES = $(call lookup_srcs,$(base_dir)/generators/ariane,sv) $(call lookup_srcs,$(base_dir)/generators/ariane,v)
|
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# rocket and testchipip classes
|
# rocket and testchipip classes
|
||||||
@@ -45,7 +56,7 @@ $(FIRRTL_FILE) $(ANNO_FILE): generator_temp
|
|||||||
@echo "" > /dev/null
|
@echo "" > /dev/null
|
||||||
|
|
||||||
# AG: must re-elaborate if ariane sources have changed... otherwise just run firrtl compile
|
# AG: must re-elaborate if ariane sources have changed... otherwise just run firrtl compile
|
||||||
generator_temp: $(SCALA_SOURCES) $(ARIANE_VLOG_SOURCES) $(sim_files)
|
generator_temp: $(SCALA_SOURCES) $(sim_files) $(EXTRA_GENERATOR_REQS)
|
||||||
mkdir -p $(build_dir)
|
mkdir -p $(build_dir)
|
||||||
cd $(base_dir) && $(SBT) "project $(SBT_PROJECT)" "runMain $(GENERATOR_PACKAGE).Generator $(build_dir) $(MODEL_PACKAGE) $(MODEL) $(CONFIG_PACKAGE) $(CONFIG)"
|
cd $(base_dir) && $(SBT) "project $(SBT_PROJECT)" "runMain $(GENERATOR_PACKAGE).Generator $(build_dir) $(MODEL_PACKAGE) $(MODEL) $(CONFIG_PACKAGE) $(CONFIG)"
|
||||||
|
|
||||||
@@ -105,19 +116,19 @@ verilog: $(sim_vsrcs)
|
|||||||
#########################################################################################
|
#########################################################################################
|
||||||
.PHONY: run-binary run-binary-fast run-binary-debug run-fast
|
.PHONY: run-binary run-binary-fast run-binary-debug run-fast
|
||||||
run-binary: $(sim)
|
run-binary: $(sim)
|
||||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
|
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# helper rules to run simulator as fast as possible
|
# helper rules to run simulator as fast as possible
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
run-binary-fast: $(sim)
|
run-binary-fast: $(sim)
|
||||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $(BINARY) </dev/null | tee $(sim_out_name).log)
|
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(PERMISSIVE_OFF) $(BINARY) </dev/null | tee $(sim_out_name).log)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# helper rules to run simulator with as much debug info as possible
|
# helper rules to run simulator with as much debug info as possible
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
run-binary-debug: $(sim_debug)
|
run-binary-debug: $(sim_debug)
|
||||||
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) $(WAVEFORM_FLAG) $(PERMISSIVE_OFF) $(BINARY) </dev/null 2> >(spike-dasm > $(sim_out_name).out) | tee $(sim_out_name).log)
|
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(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
|
run-fast: run-asm-tests-fast run-bmark-tests-fast
|
||||||
|
|
||||||
@@ -129,10 +140,10 @@ $(output_dir)/%: $(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa/%
|
|||||||
ln -sf $< $@
|
ln -sf $< $@
|
||||||
|
|
||||||
$(output_dir)/%.run: $(output_dir)/% $(sim)
|
$(output_dir)/%.run: $(output_dir)/% $(sim)
|
||||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(PERMISSIVE_OFF) $< </dev/null | tee $<.log) && touch $@
|
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(PERMISSIVE_OFF) $< </dev/null | tee $<.log) && touch $@
|
||||||
|
|
||||||
$(output_dir)/%.out: $(output_dir)/% $(sim)
|
$(output_dir)/%.out: $(output_dir)/% $(sim)
|
||||||
(set -o pipefail && $(sim) $(PERMISSIVE_ON) +dramsim +max-cycles=$(timeout_cycles) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $@) | tee $<.log)
|
(set -o pipefail && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $@) | tee $<.log)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# include build/project specific makefrags made from the generator
|
# include build/project specific makefrags made from the generator
|
||||||
@@ -141,26 +152,6 @@ ifneq ($(filter run% %.run %.out %.vpd %.vcd,$(MAKECMDGOALS)),)
|
|||||||
-include $(build_dir)/$(long_name).d
|
-include $(build_dir)/$(long_name).d
|
||||||
endif
|
endif
|
||||||
|
|
||||||
#################################################
|
|
||||||
# Rules for running and checking tracegen tests #
|
|
||||||
#################################################
|
|
||||||
|
|
||||||
AXE_DIR=$(base_dir)/tools/axe/src
|
|
||||||
AXE=$(AXE_DIR)/axe
|
|
||||||
|
|
||||||
$(AXE): $(wildcard $(AXE_DIR)/*.[ch]) $(AXE_DIR)/make.sh
|
|
||||||
cd $(AXE_DIR) && ./make.sh
|
|
||||||
|
|
||||||
$(output_dir)/tracegen.out: $(sim)
|
|
||||||
mkdir -p $(output_dir) && $(sim) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) none </dev/null 2> $@
|
|
||||||
|
|
||||||
$(output_dir)/tracegen.result: $(output_dir)/tracegen.out $(AXE)
|
|
||||||
$(base_dir)/scripts/check-tracegen.sh $< > $@
|
|
||||||
|
|
||||||
tracegen: $(output_dir)/tracegen.result
|
|
||||||
|
|
||||||
.PHONY: tracegen
|
|
||||||
|
|
||||||
#######################################
|
#######################################
|
||||||
# Rules for building DRAMSim2 library #
|
# Rules for building DRAMSim2 library #
|
||||||
#######################################
|
#######################################
|
||||||
|
|||||||
@@ -2,17 +2,28 @@ Tops, Test-Harnesses, and the Test-Driver
|
|||||||
===========================================
|
===========================================
|
||||||
|
|
||||||
The three highest levels of hierarchy in a Chipyard
|
The three highest levels of hierarchy in a Chipyard
|
||||||
SoC are the Top (DUT), ``TestHarness``, and the ``TestDriver``.
|
SoC are the ``ChipTop`` (DUT), ``TestHarness``, and the ``TestDriver``.
|
||||||
The Top and ``TestHarness`` are both emitted by Chisel generators.
|
The ``ChipTop`` and ``TestHarness`` are both emitted by Chisel generators.
|
||||||
The ``TestDriver`` serves as our testbench, and is a Verilog
|
The ``TestDriver`` serves as our testbench, and is a Verilog
|
||||||
file in Rocket Chip.
|
file in Rocket Chip.
|
||||||
|
|
||||||
|
|
||||||
Top/DUT
|
ChipTop/DUT
|
||||||
-------------------------
|
-------------------------
|
||||||
|
|
||||||
The top-level module of a Rocket Chip SoC is composed via cake-pattern.
|
``ChipTop`` is the top-level module that instantiates the ``System`` submodule, usually an instance of the concrete class ``DigitalTop``.
|
||||||
Specifically, "Tops" extend a ``System``, which extends a ``Subsystem``, which extends a ``BaseSubsystem``.
|
The vast majority of the design resides in the ``System``.
|
||||||
|
Other components that exist inside the ``ChipTop`` layer are generally IO cells, clock receivers and multiplexers, reset synchronizers, and other analog IP that needs to exist outside of the ``System``.
|
||||||
|
The ``IOBinders`` are responsible for instantiating the IO cells and defining the test harness collateral that connects to the top-level ports.
|
||||||
|
Most of these types of devices can be instantiated using custom ``IOBinders``, so the provided ``ChipTop`` and ``ChipTopCaughtReset`` classes are sufficient.
|
||||||
|
However, if needed, the ``BaseChipTop`` abstract class can be extended for building more custom ``ChipTop`` designs.
|
||||||
|
|
||||||
|
|
||||||
|
System/DigitalTop
|
||||||
|
-------------------------
|
||||||
|
|
||||||
|
The system module of a Rocket Chip SoC is composed via cake-pattern.
|
||||||
|
Specifically, ``DigitalTop`` extends a ``System``, which extends a ``Subsystem``, which extends a ``BaseSubsystem``.
|
||||||
|
|
||||||
|
|
||||||
BaseSubsystem
|
BaseSubsystem
|
||||||
|
|||||||
@@ -77,10 +77,10 @@ It is used in the Rocket Chip SoC library and Chipyard framework in merging mult
|
|||||||
This example shows the Chipyard default top that composes multiple traits together into a fully-featured SoC with many optional components.
|
This example shows the Chipyard default top that composes multiple traits together into a fully-featured SoC with many optional components.
|
||||||
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/Top.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/DigitalTop.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: Top
|
:start-after: DOC include start: DigitalTop
|
||||||
:end-before: DOC include end: Top
|
:end-before: DOC include end: DigitalTop
|
||||||
|
|
||||||
|
|
||||||
There are two "cakes" or mixins here. One for the lazy module (ex. ``CanHavePeripherySerial``) and one for the lazy module
|
There are two "cakes" or mixins here. One for the lazy module (ex. ``CanHavePeripherySerial``) and one for the lazy module
|
||||||
@@ -88,8 +88,8 @@ implementation (ex. ``CanHavePeripherySerialModuleImp`` where ``Imp`` refers to
|
|||||||
all the logical connections between generators and exchanges configuration information among them, while the
|
all the logical connections between generators and exchanges configuration information among them, while the
|
||||||
lazy module implementation performs the actual Chisel RTL elaboration.
|
lazy module implementation performs the actual Chisel RTL elaboration.
|
||||||
|
|
||||||
In the ``Top`` example class, the "outer" ``Top`` instantiates the "inner"
|
In the ``DigitalTop`` example class, the "outer" ``DigitalTop`` instantiates the "inner"
|
||||||
``TopModule`` as a lazy module implementation. This delays immediate elaboration
|
``DigitalTopModule`` as a lazy module implementation. This delays immediate elaboration
|
||||||
of the module until all logical connections are determined and all configuration information is exchanged.
|
of the module until all logical connections are determined and all configuration information is exchanged.
|
||||||
The ``System`` outer base class, as well as the
|
The ``System`` outer base class, as well as the
|
||||||
``CanHavePeriphery<X>`` outer traits contain code to perform high-level logical
|
``CanHavePeriphery<X>`` outer traits contain code to perform high-level logical
|
||||||
@@ -102,8 +102,9 @@ For example, the ``CanHavePeripherySerialModuleImp`` trait optionally physically
|
|||||||
the ``SerialAdapter`` module, and instantiates queues.
|
the ``SerialAdapter`` module, and instantiates queues.
|
||||||
|
|
||||||
In the test harness, the SoC is elaborated with
|
In the test harness, the SoC is elaborated with
|
||||||
``val dut = Module(LazyModule(Top))``.
|
``val dut = p(BuildTop)(p)``.
|
||||||
After elaboration, the result will be a ``Top`` module, which contains a
|
|
||||||
|
After elaboration, the system submodule of ``ChipTop`` will be a ``DigitalTop`` module, which contains a
|
||||||
``SerialAdapter`` module (among others), if the config specified for that block to be instantiated.
|
``SerialAdapter`` module (among others), if the config specified for that block to be instantiated.
|
||||||
|
|
||||||
From a high level, classes which extend ``LazyModule`` *must* reference
|
From a high level, classes which extend ``LazyModule`` *must* reference
|
||||||
|
|||||||
@@ -15,10 +15,10 @@ that writes zeros to the memory at a configured address.
|
|||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/InitZero.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/InitZero.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/Top.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/DigitalTop.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: Top
|
:start-after: DOC include start: DigitalTop
|
||||||
:end-before: DOC include end: Top
|
:end-before: DOC include end: DigitalTop
|
||||||
|
|
||||||
We use ``TLHelper.makeClientNode`` to create a TileLink client node for us.
|
We use ``TLHelper.makeClientNode`` to create a TileLink client node for us.
|
||||||
We then connect the client node to the memory system through the front bus (fbus).
|
We then connect the client node to the memory system through the front bus (fbus).
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
IOBinders
|
IOBinders
|
||||||
=========
|
=========
|
||||||
|
|
||||||
In Chipyard we use a special ``Parameters`` key, ``IOBinders`` to determine what modules to bind to the IOs of a ``Top`` in the ``TestHarness``.
|
In Chipyard we use a special ``Parameters`` key, ``IOBinders`` to instantiate IO cells in the ``ChipTop`` layer and determine what modules to bind to the IOs of a ``ChipTop`` in the ``TestHarness``.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
@@ -9,11 +9,27 @@ In Chipyard we use a special ``Parameters`` key, ``IOBinders`` to determine what
|
|||||||
:end-before: DOC include end: IOBinders
|
:end-before: DOC include end: IOBinders
|
||||||
|
|
||||||
|
|
||||||
This special key solves the problem of duplicating test-harnesses for each different ``Top`` type.
|
This special key solves the problem of duplicating test-harnesses for each different ``System`` type.
|
||||||
|
You could just as well create a custom harness module that attaches IOs explicitly.
|
||||||
|
Instead, the ``IOBinders`` key provides a map from Scala traits to attachment behaviors.
|
||||||
|
Each ``IOBinder`` returns a tuple of three values: the list of ``ChipTop`` ports created by the ``IOBinder``, the list of all IO cell modules instantiated by the ``IOBinder``, and an optional function to be called inside the test harness.
|
||||||
|
This function is responsible for instantiating logic inside the ``TestHarness`` to appropriately drive the ``ChipTop`` IO ports created by the ``IOBinder``.
|
||||||
|
Conveniently, because the ``IOBinder`` is generating the port, it may also use the port inside this function, which prevents the ``BaseChipTop`` code from ever needing to access the port ``val``, thus having the ``IOBinder`` house all port specific code.
|
||||||
|
This scheme prevents the need to have two separate binder functions for each ``System`` trait.
|
||||||
|
When creating custom ``IOBinders`` it is important to use ``suggestName`` to name ports; otherwise Chisel will raise an exception trying to name the IOs.
|
||||||
|
The example ``IOBinders`` demonstrate this.
|
||||||
|
|
||||||
You could just as well create a custom harness module that attaches IOs explicitly. Instead, the IOBinders key provides a map from Scala traits to attachment behaviors.
|
As an example, the ``WithGPIOTiedOff`` IOBinder creates IO cells for the GPIO module(s) instantiated in the ``System``, then punches out new ``Analog`` ports for each one.
|
||||||
|
The test harness simply ties these off, but additional logic could be inserted to perform some kind of test in the ``TestHarness``.
|
||||||
|
|
||||||
For example, the ``WithSimAXIMemTiedOff`` IOBinder specifies that any ``Top`` which matches ``CanHaveMasterAXI4MemPortModuleImp`` will have a ``SimAXIMem`` connected.
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: WithGPIOTiedOff
|
||||||
|
:end-before: DOC include end: WithGPIOTiedOff
|
||||||
|
|
||||||
|
|
||||||
|
``IOBinders`` also do not need to create ports. Some ``IOBinders`` can simply insert circuitry inside the ``ChipTop`` layer.
|
||||||
|
For example, the ``WithSimAXIMemTiedOff`` IOBinder specifies that any ``System`` which matches ``CanHaveMasterAXI4MemPortModuleImp`` will have a ``SimAXIMem`` connected inside ``ChipTop``.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
|
|||||||
@@ -34,25 +34,25 @@ Accessing the value stored in the key is easy in Chisel, as long as the ``implic
|
|||||||
Traits
|
Traits
|
||||||
------
|
------
|
||||||
|
|
||||||
Typically, most custom blocks will need to modify the behavior of some pre-existing block. For example, the GCD widget needs the ``Top`` module to instantiate and connect the widget via Tilelink, generate a top-level ``gcd_busy`` port, and connect that to the module as well. Traits let us do this without modifying the existing code for the ``Top``, and enables compartmentalization of code for different custom blocks.
|
Typically, most custom blocks will need to modify the behavior of some pre-existing block. For example, the GCD widget needs the ``DigitalTop`` module to instantiate and connect the widget via Tilelink, generate a top-level ``gcd_busy`` port, and connect that to the module as well. Traits let us do this without modifying the existing code for the ``DigitalTop``, and enables compartmentalization of code for different custom blocks.
|
||||||
|
|
||||||
Top-level traits specify that the ``Top`` has been parameterized to read some custom key and optionally instantiate and connect a widget defined by that key. Traits **should not** mandate the instantiation of custom logic. In other words, traits should be written with ``CanHave`` semantics, where the default behavior when the key is unset is a no-op.
|
Top-level traits specify that the ``DigitalTop`` has been parameterized to read some custom key and optionally instantiate and connect a widget defined by that key. Traits **should not** mandate the instantiation of custom logic. In other words, traits should be written with ``CanHave`` semantics, where the default behavior when the key is unset is a no-op.
|
||||||
|
|
||||||
Top-level traits should be defined and documented in subprojects, alongside their corresponding keys. The traits should then be added to the ``Top`` being used by Chipyard.
|
Top-level traits should be defined and documented in subprojects, alongside their corresponding keys. The traits should then be added to the ``DigitalTop`` being used by Chipyard.
|
||||||
|
|
||||||
Below we see the traits for the GCD example. The Lazy trait connects the GCD module to the Diplomacy graph, while the Implementation trait causes the ``Top`` to instantiate an additional port and concretely connect it to the GCD module.
|
Below we see the traits for the GCD example. The Lazy trait connects the GCD module to the Diplomacy graph, while the Implementation trait causes the ``DigitalTop`` to instantiate an additional port and concretely connect it to the GCD module.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: GCD lazy trait
|
:start-after: DOC include start: GCD lazy trait
|
||||||
:end-before: DOC include end: GCD imp trait
|
:end-before: DOC include end: GCD imp trait
|
||||||
|
|
||||||
These traits are added to the default ``Top`` in Chipyard.
|
These traits are added to the default ``DigitalTop`` in Chipyard.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/Top.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/DigitalTop.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: Top
|
:start-after: DOC include start: DigitalTop
|
||||||
:end-before: DOC include end: Top
|
:end-before: DOC include end: DigitalTop
|
||||||
|
|
||||||
Config Fragments
|
Config Fragments
|
||||||
----------------
|
----------------
|
||||||
|
|||||||
@@ -87,21 +87,21 @@ For peripherals which instantiate a concrete module, or which need to be connect
|
|||||||
:start-after: DOC include start: GCD imp trait
|
:start-after: DOC include start: GCD imp trait
|
||||||
:end-before: DOC include end: GCD imp trait
|
:end-before: DOC include end: GCD imp trait
|
||||||
|
|
||||||
Constructing the Top and Config
|
Constructing the DigitalTop and Config
|
||||||
-------------------------------
|
--------------------------------------
|
||||||
|
|
||||||
Now we want to mix our traits into the system as a whole.
|
Now we want to mix our traits into the system as a whole.
|
||||||
This code is from ``generators/chipyard/src/main/scala/Top.scala``.
|
This code is from ``generators/chipyard/src/main/scala/DigitalTop.scala``.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/Top.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/DigitalTop.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: Top
|
:start-after: DOC include start: DigitalTop
|
||||||
:end-before: DOC include end: Top
|
:end-before: DOC include end: DigitalTop
|
||||||
|
|
||||||
Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system.
|
Just as we need separate traits for ``LazyModule`` and module implementation, we need two classes to build the system.
|
||||||
The ``Top`` class contains the set of traits which parameterize and define the ``Top``. Typically these traits will optionally add IOs or peripherals to the ``Top``.
|
The ``DigitalTop`` class contains the set of traits which parameterize and define the ``DigitalTop``. Typically these traits will optionally add IOs or peripherals to the ``DigitalTop``.
|
||||||
The ``Top`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``).
|
The ``DigitalTop`` class includes the pre-elaboration code and also a ``lazy val`` to produce the module implementation (hence ``LazyModule``).
|
||||||
The ``TopModule`` class is the actual RTL that gets synthesized.
|
The ``DigitalTopModule`` class is the actual RTL that gets synthesized.
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -38,6 +38,20 @@ Note that these configurations fully remove the L2 cache and mbus.
|
|||||||
This configuration fully removes the L2 cache and memory bus by setting the
|
This configuration fully removes the L2 cache and memory bus by setting the
|
||||||
number of channels and number of banks to 0.
|
number of channels and number of banks to 0.
|
||||||
|
|
||||||
|
The System Bus
|
||||||
|
--------------
|
||||||
|
|
||||||
|
The system bus is the TileLink network that sits between the tiles and the L2
|
||||||
|
agents and MMIO peripherals. Ordinarily, it is a fully-connected crossbar,
|
||||||
|
but TestChipIP provides a version that uses a ring network instead. This can
|
||||||
|
be useful when taping out larger systems. To use the ring network system
|
||||||
|
bus, simply add the ``WithRingSystemBus`` config fragment to your configuration.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/config/RocketConfigs.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: RingSystemBusRocket
|
||||||
|
:end-before: DOC include end: RingSystemBusRocket
|
||||||
|
|
||||||
The SiFive L2 Cache
|
The SiFive L2 Cache
|
||||||
-------------------
|
-------------------
|
||||||
|
|
||||||
|
|||||||
@@ -78,7 +78,7 @@ Configuration
|
|||||||
To add IceNIC to your design, add ``HasPeripheryIceNIC`` to your lazy module
|
To add IceNIC to your design, add ``HasPeripheryIceNIC`` to your lazy module
|
||||||
and ``HasPeripheryIceNICModuleImp`` to the module implementation. If you
|
and ``HasPeripheryIceNICModuleImp`` to the module implementation. If you
|
||||||
are confused about the distinction between lazy module and module
|
are confused about the distinction between lazy module and module
|
||||||
implementation, refer to :ref:`Cake Pattern`.
|
implementation, refer to :ref:`Cake Pattern / Mixin`.
|
||||||
|
|
||||||
Then add the ``WithIceNIC`` config fragment to your configuration. This will
|
Then add the ``WithIceNIC`` config fragment to your configuration. This will
|
||||||
define ``NICKey``, which IceNIC uses to determine its parameters. The config fragment
|
define ``NICKey``, which IceNIC uses to determine its parameters. The config fragment
|
||||||
|
|||||||
@@ -3,7 +3,8 @@ Test Chip IP
|
|||||||
|
|
||||||
Chipyard includes a Test Chip IP library which provides various hardware
|
Chipyard includes a Test Chip IP library which provides various hardware
|
||||||
widgets that may be useful when designing SoCs. This includes a :ref:`Serial Adapter`,
|
widgets that may be useful when designing SoCs. This includes a :ref:`Serial Adapter`,
|
||||||
:ref:`Block Device Controller`, :ref:`TileLink SERDES`, :ref:`TileLink Switcher`, and :ref:`UART Adapter`.
|
:ref:`Block Device Controller`, :ref:`TileLink SERDES`, :ref:`TileLink Switcher`,
|
||||||
|
:ref:`TileLink Ring Network`, and :ref:`UART Adapter`.
|
||||||
|
|
||||||
Serial Adapter
|
Serial Adapter
|
||||||
--------------
|
--------------
|
||||||
@@ -60,6 +61,19 @@ the select signal once TileLink messages have begun sending.
|
|||||||
For an example of how to use the switcher, take a look at the ``SwitcherTest``
|
For an example of how to use the switcher, take a look at the ``SwitcherTest``
|
||||||
unit test in the `Test Chip IP unit tests <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/Unittests.scala>`_.
|
unit test in the `Test Chip IP unit tests <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/Unittests.scala>`_.
|
||||||
|
|
||||||
|
TileLink Ring Network
|
||||||
|
---------------------
|
||||||
|
|
||||||
|
TestChipIP provides a TLRingNetwork generator that has a similar interface
|
||||||
|
to the TLXbar provided by RocketChip, but uses ring networks internally rather
|
||||||
|
than crossbars. This can be useful for chips with very wide TileLink networks
|
||||||
|
(many cores and L2 banks) that can sacrifice cross-section bandwidth to relieve
|
||||||
|
wire routing congestion. Documentation on how to use the ring network can be
|
||||||
|
found in :ref:`The System Bus`. The implementation itself can be found
|
||||||
|
`here <https://github.com/ucb-bar/testchipip/blob/master/src/main/scala/Ring.scala>`_,
|
||||||
|
and may serve as an example of how to implement your own TileLink network with
|
||||||
|
a different topology.
|
||||||
|
|
||||||
UART Adapter
|
UART Adapter
|
||||||
------------
|
------------
|
||||||
|
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#
|
#
|
||||||
|
|
||||||
# You can set these variables from the command line.
|
# You can set these variables from the command line.
|
||||||
SPHINXOPTS = -w warnings.txt
|
SPHINXOPTS = -w warnings.txt -n -W
|
||||||
SPHINXBUILD = python -msphinx
|
SPHINXBUILD = python3 -msphinx
|
||||||
SPHINXPROJ = Chipyard
|
SPHINXPROJ = Chipyard
|
||||||
SOURCEDIR = .
|
SOURCEDIR = .
|
||||||
BUILDDIR = _build
|
BUILDDIR = _build
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ transactions.
|
|||||||
- ``minSize: Int`` - Minimum size of transfers supported by all outward managers.
|
- ``minSize: Int`` - Minimum size of transfers supported by all outward managers.
|
||||||
- ``maxSize: Int`` - Maximum size of transfers supported after the Fragmenter is applied.
|
- ``maxSize: Int`` - Maximum size of transfers supported after the Fragmenter is applied.
|
||||||
- ``alwaysMin: Boolean`` - (optional) Fragment all requests down to minSize (else fragment to maximum supported by manager). (default: false)
|
- ``alwaysMin: Boolean`` - (optional) Fragment all requests down to minSize (else fragment to maximum supported by manager). (default: false)
|
||||||
- ``earlyAck: EarlyAck.T`` - (optional) Should a multibeat Put be acknowledged on the first beat or last beat?
|
- ``earlyAck: EarlyAck.T`` - (optional) Should a multibeat Put be acknowledged on the first beat or last beat?
|
||||||
Possible values (default: ``EarlyAck.None``):
|
Possible values (default: ``EarlyAck.None``):
|
||||||
|
|
||||||
- ``EarlyAck.AllPuts`` - always acknowledge on first beat.
|
- ``EarlyAck.AllPuts`` - always acknowledge on first beat.
|
||||||
@@ -270,7 +270,7 @@ the client to see a particular width.
|
|||||||
|
|
||||||
**Example Usage:**
|
**Example Usage:**
|
||||||
|
|
||||||
.. code-block::
|
.. code-block:: scala
|
||||||
|
|
||||||
// Assume the manager node sets beatBytes to 8
|
// Assume the manager node sets beatBytes to 8
|
||||||
// With WidthWidget, client sees beatBytes of 4
|
// With WidthWidget, client sees beatBytes of 4
|
||||||
@@ -398,11 +398,11 @@ package, not the ``freechips.rocketchip.tilelink`` package like the others.
|
|||||||
- ``size: Int`` - The size of the memory in bytes
|
- ``size: Int`` - The size of the memory in bytes
|
||||||
- ``contentsDelayed: => Seq[Byte]`` - A function which, when called generates
|
- ``contentsDelayed: => Seq[Byte]`` - A function which, when called generates
|
||||||
the byte contents of the ROM.
|
the byte contents of the ROM.
|
||||||
- ``executable: Boolean`` - (optional) Specify whether the CPU can fetch
|
- ``executable: Boolean`` - (optional) Specify whether the CPU can fetch
|
||||||
instructions from the ROM (default: ``true``).
|
instructions from the ROM (default: ``true``).
|
||||||
- ``beatBytes: Int`` - (optional) The width of the interface in bytes.
|
- ``beatBytes: Int`` - (optional) The width of the interface in bytes.
|
||||||
(default: 4).
|
(default: 4).
|
||||||
- ``resources: Seq[Resource]`` - (optional) Sequence of resources to add to
|
- ``resources: Seq[Resource]`` - (optional) Sequence of resources to add to
|
||||||
the device tree.
|
the device tree.
|
||||||
|
|
||||||
**Example Usage:**
|
**Example Usage:**
|
||||||
@@ -429,13 +429,13 @@ The TLRAM and AXI4RAM widgets provide read-write memories implemented as SRAMs.
|
|||||||
**Arguments:**
|
**Arguments:**
|
||||||
|
|
||||||
- ``address: AddressSet`` - The address range that this RAM will cover.
|
- ``address: AddressSet`` - The address range that this RAM will cover.
|
||||||
- ``cacheable: Boolean`` - (optional) Can the contents of this RAM be cached.
|
- ``cacheable: Boolean`` - (optional) Can the contents of this RAM be cached.
|
||||||
(default: ``true``)
|
(default: ``true``)
|
||||||
- ``executable: Boolean`` - (optional) Can the contents of this RAM be fetched
|
- ``executable: Boolean`` - (optional) Can the contents of this RAM be fetched
|
||||||
as instructions. (default: ``true``)
|
as instructions. (default: ``true``)
|
||||||
- ``beatBytes: Int`` - (optional) Width of the TL/AXI4 interface in bytes.
|
- ``beatBytes: Int`` - (optional) Width of the TL/AXI4 interface in bytes.
|
||||||
(default: 4)
|
(default: 4)
|
||||||
- ``atomics: Boolean`` - (optional, TileLink only) Does the RAM support
|
- ``atomics: Boolean`` - (optional, TileLink only) Does the RAM support
|
||||||
atomic operations? (default: ``false``)
|
atomic operations? (default: ``false``)
|
||||||
|
|
||||||
**Example Usage:**
|
**Example Usage:**
|
||||||
|
|||||||
@@ -131,5 +131,5 @@ This, unfortunately, breaks the process-agnostic RTL abstraction, so it is recom
|
|||||||
The simplest way to do this is to have a config fragment that when included updates instantiates the IO cells and connects them in the test harness.
|
The simplest way to do this is to have a config fragment that when included updates instantiates the IO cells and connects them in the test harness.
|
||||||
When simulating chip-specific designs, it is important to include the IO cells.
|
When simulating chip-specific designs, it is important to include the IO cells.
|
||||||
The IO cell behavioral models will often assert if they are connected incorrectly, which is a useful runtime check.
|
The IO cell behavioral models will often assert if they are connected incorrectly, which is a useful runtime check.
|
||||||
They also keep the IO interface at the chip and test harness boundary (see :ref:`Separating the top module from the test harness`) consistent after synthesis and place-and-route,
|
They also keep the IO interface at the chip and test harness boundary (see :ref:`Separating the Top module from the TestHarness module`) consistent after synthesis and place-and-route,
|
||||||
which allows the RTL simulation test harness to be reused.
|
which allows the RTL simulation test harness to be reused.
|
||||||
|
|||||||
@@ -45,8 +45,8 @@ It is possible to write this IR directly, or to generate it using simple python
|
|||||||
While we certainly look forward to having a more featureful toolkit, we have built many chips to date in this way.
|
While we certainly look forward to having a more featureful toolkit, we have built many chips to date in this way.
|
||||||
|
|
||||||
|
|
||||||
Running the VLSI flow
|
Running the VLSI tool flow
|
||||||
---------------------
|
--------------------------
|
||||||
|
|
||||||
For the full documentation on how to use the VLSI tool flow, see the `Hammer Documentation <https://hammer-vlsi.readthedocs.io/>`__.
|
For the full documentation on how to use the VLSI tool flow, see the `Hammer Documentation <https://hammer-vlsi.readthedocs.io/>`__.
|
||||||
For an example of how to use the VLSI in the context of Chipyard, see :ref:`ASAP7 Tutorial`.
|
For an example of how to use the VLSI in the context of Chipyard, see :ref:`ASAP7 Tutorial`.
|
||||||
|
|||||||
Submodule generators/ariane updated: 145b5ed106...e02436d2aa
102
generators/chipyard/src/main/scala/ChipTop.scala
Normal file
102
generators/chipyard/src/main/scala/ChipTop.scala
Normal file
@@ -0,0 +1,102 @@
|
|||||||
|
package chipyard
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
|
||||||
|
import scala.collection.mutable.{ArrayBuffer}
|
||||||
|
|
||||||
|
import freechips.rocketchip.config.{Parameters, Field}
|
||||||
|
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||||
|
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||||
|
import chipyard.config.ConfigValName._
|
||||||
|
import chipyard.iobinders.{IOBinders, TestHarnessFunction, IOBinderTuple}
|
||||||
|
|
||||||
|
import barstools.iocell.chisel._
|
||||||
|
|
||||||
|
case object BuildSystem extends Field[Parameters => RawModule]((p: Parameters) => Module(LazyModule(new DigitalTop()(p)).suggestName("system").module))
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The base class used for building chips. This constructor instantiates a module specified by the BuildSystem parameter,
|
||||||
|
* named "system", which is an instance of DigitalTop by default. The default clock and reset for "system" are set by two
|
||||||
|
* wires, "systemClock" and "systemReset", which are intended to be driven by traits mixed-in with this base class.
|
||||||
|
*/
|
||||||
|
abstract class BaseChipTop()(implicit val p: Parameters) extends RawModule with HasTestHarnessFunctions {
|
||||||
|
|
||||||
|
// A publicly accessible list of IO cells (useful for a floorplanning tool, for example)
|
||||||
|
val iocells = ArrayBuffer.empty[IOCell]
|
||||||
|
// A list of functions to call in the test harness
|
||||||
|
val harnessFunctions = ArrayBuffer.empty[TestHarnessFunction]
|
||||||
|
// The system clock
|
||||||
|
val systemClock = Wire(Input(Clock()))
|
||||||
|
// The system reset (synchronous to clock)
|
||||||
|
val systemReset = Wire(Input(Bool()))
|
||||||
|
|
||||||
|
// The system module specified by BuildSystem
|
||||||
|
val system = withClockAndReset(systemClock, systemReset) { p(BuildSystem)(p) }
|
||||||
|
|
||||||
|
// Call all of the IOBinders and provide them with a default clock and reset
|
||||||
|
withClockAndReset(systemClock, systemReset) {
|
||||||
|
val (_ports, _iocells, _harnessFunctions) = p(IOBinders).values.map(_(system)).flatten.unzip3
|
||||||
|
// We ignore _ports for now...
|
||||||
|
iocells ++= _iocells.flatten
|
||||||
|
harnessFunctions ++= _harnessFunctions.flatten
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A simple clock and reset implementation that punches out clock and reset ports with the same
|
||||||
|
* names as the implicit clock and reset for standard Module classes. Reset is synchronous to
|
||||||
|
* clock, which may not be a good idea to use for tapeouts.
|
||||||
|
*/
|
||||||
|
trait HasChipTopSimpleClockAndReset { this: BaseChipTop =>
|
||||||
|
|
||||||
|
val (clock, systemClockIO) = IOCell.generateIOFromSignal(systemClock, Some("iocell_clock"))
|
||||||
|
val (reset, systemResetIO) = IOCell.generateIOFromSignal(systemReset, Some("iocell_reset"))
|
||||||
|
|
||||||
|
iocells ++= systemClockIO
|
||||||
|
iocells ++= systemResetIO
|
||||||
|
|
||||||
|
// Add a TestHarnessFunction that connects clock and reset
|
||||||
|
harnessFunctions += { (th: TestHarness) => {
|
||||||
|
// Connect clock; it's not done implicitly with RawModule
|
||||||
|
clock := th.clock
|
||||||
|
// Connect reset; it's not done implicitly with RawModule
|
||||||
|
// Note that we need to use dutReset, not harnessReset
|
||||||
|
reset := th.dutReset
|
||||||
|
Nil
|
||||||
|
} }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Variant of HasChipTopSimpleClockAndReset that adds a reset synchronizer so that the top-level reset
|
||||||
|
* can be asynchronous with clock, which is useful for tapeout configs.
|
||||||
|
*/
|
||||||
|
trait HasChipTopSimpleClockAndCaughtReset { this: BaseChipTop =>
|
||||||
|
|
||||||
|
val asyncResetCore = Wire(Input(Bool()))
|
||||||
|
systemReset := ResetCatchAndSync(systemClock, asyncResetCore)
|
||||||
|
|
||||||
|
val (clock, systemClockIO) = IOCell.generateIOFromSignal(systemClock, Some("iocell_clock"))
|
||||||
|
val (areset, asyncResetIO) = IOCell.generateIOFromSignal(asyncResetCore, Some("iocell_areset"))
|
||||||
|
|
||||||
|
iocells ++= systemClockIO
|
||||||
|
iocells ++= asyncResetIO
|
||||||
|
|
||||||
|
// Add a TestHarnessFunction that connects clock and areset
|
||||||
|
harnessFunctions += { (th: TestHarness) => {
|
||||||
|
// Connect clock; it's not done implicitly with RawModule
|
||||||
|
clock := th.clock
|
||||||
|
// Connect reset; it's not done implicitly with RawModule
|
||||||
|
// Note that we need to use dutReset, not harnessReset
|
||||||
|
areset := th.dutReset
|
||||||
|
Nil
|
||||||
|
} }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
class ChipTop()(implicit p: Parameters) extends BaseChipTop()(p)
|
||||||
|
with HasChipTopSimpleClockAndReset
|
||||||
|
|
||||||
|
class ChipTopCaughtReset()(implicit p: Parameters) extends BaseChipTop()(p)
|
||||||
|
with HasChipTopSimpleClockAndCaughtReset
|
||||||
@@ -21,7 +21,7 @@ import hwacha.{Hwacha}
|
|||||||
import sifive.blocks.devices.gpio._
|
import sifive.blocks.devices.gpio._
|
||||||
import sifive.blocks.devices.uart._
|
import sifive.blocks.devices.uart._
|
||||||
|
|
||||||
import chipyard.{BuildTop}
|
import chipyard.{BuildTop, BuildSystem, ChipTopCaughtReset}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* TODO: Why do we need this?
|
* TODO: Why do we need this?
|
||||||
@@ -65,8 +65,8 @@ class WithL2TLBs(entries: Int) extends Config((site, here, up) => {
|
|||||||
))
|
))
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTracegenTop extends Config((site, here, up) => {
|
class WithTracegenSystem extends Config((site, here, up) => {
|
||||||
case BuildTop => (p: Parameters) => Module(LazyModule(new tracegen.TraceGenSystem()(p)).suggestName("Top").module)
|
case BuildSystem => (p: Parameters) => Module(LazyModule(new tracegen.TraceGenSystem()(p)).suggestName("Top").module)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
@@ -150,3 +150,13 @@ class WithControlCore extends Config((site, here, up) => {
|
|||||||
)
|
)
|
||||||
case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1)
|
case MaxHartIdBits => log2Up(up(RocketTilesKey, site).size + up(BoomTilesKey, site).size + 1)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Config fragment to use ChipTopCaughtReset as the top module, which adds a reset synchronizer to
|
||||||
|
* the top-level reset, allowing it to be asynchronous with the clock.
|
||||||
|
* NOTE: You must remember to set TOP=WithChipTopCaughtReset when building with this config
|
||||||
|
*/
|
||||||
|
class WithChipTopCaughtReset extends Config((site, here, up) => {
|
||||||
|
case BuildTop => (p: Parameters) => Module(new ChipTopCaughtReset()(p).suggestName("top"))
|
||||||
|
})
|
||||||
|
|||||||
@@ -11,8 +11,8 @@ import freechips.rocketchip.devices.tilelink._
|
|||||||
// BOOM and/or Rocket Top Level Systems
|
// BOOM and/or Rocket Top Level Systems
|
||||||
// ------------------------------------
|
// ------------------------------------
|
||||||
|
|
||||||
// DOC include start: Top
|
// DOC include start: DigitalTop
|
||||||
class Top(implicit p: Parameters) extends System
|
class DigitalTop(implicit p: Parameters) extends System
|
||||||
with testchipip.CanHaveTraceIO // Enables optionally adding trace IO
|
with testchipip.CanHaveTraceIO // Enables optionally adding trace IO
|
||||||
with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad
|
with testchipip.CanHaveBackingScratchpad // Enables optionally adding a backing scratchpad
|
||||||
with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device
|
with testchipip.CanHavePeripheryBlockDevice // Enables optionally adding the block device
|
||||||
@@ -23,10 +23,10 @@ class Top(implicit p: Parameters) extends System
|
|||||||
with chipyard.example.CanHavePeripheryInitZero // Enables optionally adding the initzero example widget
|
with chipyard.example.CanHavePeripheryInitZero // Enables optionally adding the initzero example widget
|
||||||
with chipyard.example.CanHavePeripheryGCD // Enables optionally adding the GCD example widget
|
with chipyard.example.CanHavePeripheryGCD // Enables optionally adding the GCD example widget
|
||||||
{
|
{
|
||||||
override lazy val module = new TopModule(this)
|
override lazy val module = new DigitalTopModule(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class TopModule[+L <: Top](l: L) extends SystemModule(l)
|
class DigitalTopModule[+L <: DigitalTop](l: L) extends SystemModule(l)
|
||||||
with testchipip.CanHaveTraceIOModuleImp
|
with testchipip.CanHaveTraceIOModuleImp
|
||||||
with testchipip.CanHavePeripheryBlockDeviceModuleImp
|
with testchipip.CanHavePeripheryBlockDeviceModuleImp
|
||||||
with testchipip.CanHavePeripherySerialModuleImp
|
with testchipip.CanHavePeripherySerialModuleImp
|
||||||
@@ -35,4 +35,4 @@ class TopModule[+L <: Top](l: L) extends SystemModule(l)
|
|||||||
with icenet.CanHavePeripheryIceNICModuleImp
|
with icenet.CanHavePeripheryIceNICModuleImp
|
||||||
with chipyard.example.CanHavePeripheryGCDModuleImp
|
with chipyard.example.CanHavePeripheryGCDModuleImp
|
||||||
with freechips.rocketchip.util.DontTouch
|
with freechips.rocketchip.util.DontTouch
|
||||||
// DOC include end: Top
|
// DOC include end: DigitalTop
|
||||||
@@ -1,19 +1,22 @@
|
|||||||
package chipyard.iobinders
|
package chipyard
|
||||||
|
package object iobinders {
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
|
import chisel3.experimental.{Analog, IO}
|
||||||
|
|
||||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||||
import freechips.rocketchip.devices.debug._
|
import freechips.rocketchip.devices.debug._
|
||||||
import freechips.rocketchip.subsystem._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.system._
|
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
|
||||||
import sifive.blocks.devices.gpio._
|
import sifive.blocks.devices.gpio._
|
||||||
import sifive.blocks.devices.uart._
|
import sifive.blocks.devices.uart._
|
||||||
|
|
||||||
|
import barstools.iocell.chisel._
|
||||||
|
|
||||||
import testchipip._
|
import testchipip._
|
||||||
import icenet._
|
import icenet.{CanHavePeripheryIceNICModuleImp, SimNetwork, NicLoopback, NICKey}
|
||||||
import tracegen.{HasTraceGenTilesModuleImp}
|
import tracegen.{HasTraceGenTilesModuleImp}
|
||||||
|
|
||||||
import scala.reflect.{ClassTag}
|
import scala.reflect.{ClassTag}
|
||||||
@@ -26,23 +29,32 @@ import scala.reflect.{ClassTag}
|
|||||||
// IO connection behavior for tops matching that trait. We use strings to enable
|
// IO connection behavior for tops matching that trait. We use strings to enable
|
||||||
// composition and overriding of IOBinders, much like how normal Keys in the config
|
// composition and overriding of IOBinders, much like how normal Keys in the config
|
||||||
// system are used/ At elaboration, the testharness traverses this set of functions,
|
// system are used/ At elaboration, the testharness traverses this set of functions,
|
||||||
// and functions which match the type of the Top are evaluated.
|
// and functions which match the type of the DigitalTop are evaluated.
|
||||||
|
|
||||||
// You can add your own binder by adding a new (key, fn) pair, typically by using
|
// You can add your own binder by adding a new (key, fn) pair, typically by using
|
||||||
// the OverrideIOBinder or ComposeIOBinder macros
|
// the OverrideIOBinder or ComposeIOBinder macros
|
||||||
|
|
||||||
|
|
||||||
// DOC include start: IOBinders
|
// DOC include start: IOBinders
|
||||||
case object IOBinders extends Field[Map[String, (Clock, Bool, Bool, Any) => Seq[Any]]](
|
// This type describes a function callable on the TestHarness instance. Its return type is unused.
|
||||||
Map[String, (Clock, Bool, Bool, Any) => Seq[Any]]().withDefaultValue((c: Clock, r: Bool, s: Bool, t: Any) => Nil)
|
type TestHarnessFunction = (chipyard.TestHarness) => Seq[Any]
|
||||||
|
// IOBinders will return a Seq of this tuple, which contains three fields:
|
||||||
|
// 1. A Seq containing all IO ports created by the IOBinder function
|
||||||
|
// 2. A Seq containing all IO cell modules created by the IOBinder function
|
||||||
|
// 3. An optional function to call inside the test harness (e.g. to connect the IOs)
|
||||||
|
type IOBinderTuple = (Seq[Data], Seq[IOCell], Option[TestHarnessFunction])
|
||||||
|
|
||||||
|
case object IOBinders extends Field[Map[String, (Any) => Seq[IOBinderTuple]]](
|
||||||
|
Map[String, (Any) => Seq[IOBinderTuple]]().withDefaultValue((Any) => Nil)
|
||||||
)
|
)
|
||||||
|
|
||||||
// This macro overrides previous matches on some Top mixin. This is useful for
|
// This macro overrides previous matches on some Top mixin. This is useful for
|
||||||
// binders which drive IO, since those typically cannot be composed
|
// binders which drive IO, since those typically cannot be composed
|
||||||
class OverrideIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
class OverrideIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
||||||
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
||||||
((clock: Clock, reset: Bool, success: Bool, t: Any) => {
|
((t: Any) => {
|
||||||
t match {
|
t match {
|
||||||
case top: T => fn(clock, reset, success, top)
|
case system: T => fn(system)
|
||||||
case _ => Nil
|
case _ => Nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -51,12 +63,12 @@ class OverrideIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit ta
|
|||||||
|
|
||||||
// This macro composes with previous matches on some Top mixin. This is useful for
|
// This macro composes with previous matches on some Top mixin. This is useful for
|
||||||
// annotation-like binders, since those can typically be composed
|
// annotation-like binders, since those can typically be composed
|
||||||
class ComposeIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
class ComposeIOBinder[T](fn: => (T) => Seq[IOBinderTuple])(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
||||||
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
case IOBinders => up(IOBinders, site) + (tag.runtimeClass.toString ->
|
||||||
((clock: Clock, reset: Bool, success: Bool, t: Any) => {
|
((t: Any) => {
|
||||||
t match {
|
t match {
|
||||||
case top: T => (up(IOBinders, site)(tag.runtimeClass.toString)(clock, reset, success, top)
|
case system: T => (up(IOBinders, site)(tag.runtimeClass.toString)(system)
|
||||||
++ fn(clock, reset, success, top))
|
++ fn(system))
|
||||||
case _ => Nil
|
case _ => Nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -65,74 +77,146 @@ class ComposeIOBinder[T](fn: => (Clock, Bool, Bool, T) => Seq[Any])(implicit tag
|
|||||||
|
|
||||||
// DOC include end: IOBinders
|
// DOC include end: IOBinders
|
||||||
|
|
||||||
|
object AddIOCells {
|
||||||
|
/**
|
||||||
|
* Add IO cells to a SiFive GPIO devices and name the IO ports.
|
||||||
|
* @param gpios A Seq of GPIO port bundles
|
||||||
|
* @param genFn A callable function to generate a DigitalGPIOCell module to use
|
||||||
|
* @return Returns a tuple of (a 2D Seq of Analog IOs corresponding to individual GPIO pins; a 2D Seq of IOCell module references)
|
||||||
|
*/
|
||||||
|
def gpio(gpios: Seq[GPIOPortIO], genFn: () => DigitalGPIOCell = IOCell.genericGPIO): (Seq[Seq[Analog]], Seq[Seq[IOCell]]) = {
|
||||||
|
gpios.zipWithIndex.map({ case (gpio, i) =>
|
||||||
|
gpio.pins.zipWithIndex.map({ case (pin, j) =>
|
||||||
|
val g = IO(Analog(1.W))
|
||||||
|
g.suggestName("gpio_${i}_${j}")
|
||||||
|
val iocell = genFn()
|
||||||
|
iocell.suggestName(s"iocell_gpio_${i}_${j}")
|
||||||
|
iocell.io.o := pin.o.oval
|
||||||
|
iocell.io.oe := pin.o.oe
|
||||||
|
iocell.io.ie := pin.o.ie
|
||||||
|
pin.i.ival := iocell.io.i
|
||||||
|
iocell.io.pad <> g
|
||||||
|
(g, iocell)
|
||||||
|
}).unzip
|
||||||
|
}).unzip
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add IO cells to a SiFive UART devices and name the IO ports.
|
||||||
|
* @param gpios A Seq of UART port bundles
|
||||||
|
* @return Returns a tuple of (A Seq of top-level UARTPortIO IOs; a 2D Seq of IOCell module references)
|
||||||
|
*/
|
||||||
|
def uart(uartPins: Seq[UARTPortIO]): (Seq[UARTPortIO], Seq[Seq[IOCell]]) = {
|
||||||
|
uartPins.zipWithIndex.map({ case (u, i) =>
|
||||||
|
val (port, ios) = IOCell.generateIOFromSignal(u, Some(s"iocell_uart_${i}"))
|
||||||
|
port.suggestName(s"uart_${i}")
|
||||||
|
(port, ios)
|
||||||
|
}).unzip
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add IO cells to a debug module and name the IO ports.
|
||||||
|
* @param gpios A PSDIO bundle
|
||||||
|
* @param debugOpt An optional DebugIO bundle
|
||||||
|
* @return Returns a tuple3 of (Top-level PSDIO IO; Optional top-level DebugIO IO; a list of IOCell module references)
|
||||||
|
*/
|
||||||
|
def debug(psd: PSDIO, debugOpt: Option[DebugIO]): (PSDIO, Option[DebugIO], Seq[IOCell]) = {
|
||||||
|
val (psdPort, psdIOs) = IOCell.generateIOFromSignal(psd, Some("iocell_psd"))
|
||||||
|
val optTuple = debugOpt.map(d => IOCell.generateIOFromSignal(d, Some("iocell_debug")))
|
||||||
|
val debugPortOpt: Option[DebugIO] = optTuple.map(_._1)
|
||||||
|
val debugIOs: Seq[IOCell] = optTuple.map(_._2).toSeq.flatten
|
||||||
|
debugPortOpt.foreach(_.suggestName("debug"))
|
||||||
|
psdPort.suggestName("psd")
|
||||||
|
(psdPort, debugPortOpt, psdIOs ++ debugIOs)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Add IO cells to a serial module and name the IO ports.
|
||||||
|
* @param serial A SerialIO bundle
|
||||||
|
* @return Returns a tuple of (Top-level SerialIO IO; a list of IOCell module references)
|
||||||
|
*/
|
||||||
|
def serial(serial: SerialIO): (SerialIO, Seq[IOCell]) = {
|
||||||
|
val (port, ios) = IOCell.generateIOFromSignal(serial, Some("iocell_serial"))
|
||||||
|
port.suggestName("serial")
|
||||||
|
(port, ios)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// DOC include start: WithGPIOTiedOff
|
||||||
class WithGPIOTiedOff extends OverrideIOBinder({
|
class WithGPIOTiedOff extends OverrideIOBinder({
|
||||||
(c, r, s, top: HasPeripheryGPIOModuleImp) => top.gpio.map(gpio => gpio.pins.map(p => p.i.ival := false.B)); Nil
|
(system: HasPeripheryGPIOModuleImp) => {
|
||||||
|
val (ports2d, ioCells2d) = AddIOCells.gpio(system.gpio)
|
||||||
|
val harnessFn = (th: chipyard.TestHarness) => { ports2d.flatten.foreach(_ <> AnalogConst(0)); Nil }
|
||||||
|
Seq((ports2d.flatten, ioCells2d.flatten, Some(harnessFn)))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
// DOC include end: WithGPIOTiedOff
|
||||||
|
|
||||||
|
class WithUARTAdapter extends OverrideIOBinder({
|
||||||
|
(system: HasPeripheryUARTModuleImp) => {
|
||||||
|
val (ports, ioCells2d) = AddIOCells.uart(system.uart)
|
||||||
|
val harnessFn = (th: chipyard.TestHarness) => { UARTAdapter.connect(ports)(system.p); Nil }
|
||||||
|
Seq((ports, ioCells2d.flatten, Some(harnessFn)))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimBlockDevice extends OverrideIOBinder({
|
class WithSimBlockDevice extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHavePeripheryBlockDeviceModuleImp) => top.connectSimBlockDevice(c, r); Nil
|
(system: CanHavePeripheryBlockDeviceModuleImp) => system.connectSimBlockDevice(system.clock, system.reset.asBool); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithBlockDeviceModel extends OverrideIOBinder({
|
class WithBlockDeviceModel extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHavePeripheryBlockDeviceModuleImp) => top.connectBlockDeviceModel(); Nil
|
(system: CanHavePeripheryBlockDeviceModuleImp) => system.connectBlockDeviceModel(); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithLoopbackNIC extends OverrideIOBinder({
|
class WithLoopbackNIC extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHavePeripheryIceNICModuleImp) => top.connectNicLoopback(); Nil
|
(system: CanHavePeripheryIceNICModuleImp) => system.connectNicLoopback(); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimNIC extends OverrideIOBinder({
|
class WithSimNIC extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHavePeripheryIceNICModuleImp) => top.connectSimNetwork(c, r); Nil
|
(system: CanHavePeripheryIceNICModuleImp) => system.connectSimNetwork(system.clock, system.reset.asBool); Nil
|
||||||
})
|
|
||||||
|
|
||||||
class WithUARTAdapter extends OverrideIOBinder({
|
|
||||||
(c, r, s, top: HasPeripheryUARTModuleImp) => {
|
|
||||||
val defaultBaudRate = 115200 // matches sifive-blocks uart baudrate
|
|
||||||
top.uart.zipWithIndex.foreach{ case (dut_io, i) =>
|
|
||||||
val uart_sim = Module(new UARTAdapter(i, defaultBaudRate)(top.p))
|
|
||||||
uart_sim.io.uart.txd := dut_io.txd
|
|
||||||
dut_io.rxd := uart_sim.io.uart.rxd
|
|
||||||
}
|
|
||||||
Nil
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
// DOC include start: WithSimAXIMem
|
// DOC include start: WithSimAXIMem
|
||||||
class WithSimAXIMem extends OverrideIOBinder({
|
class WithSimAXIMem extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHaveMasterAXI4MemPortModuleImp) => top.connectSimAXIMem(); Nil
|
(system: CanHaveMasterAXI4MemPortModuleImp) => system.connectSimAXIMem(); Nil
|
||||||
})
|
})
|
||||||
// DOC include end: WithSimAXIMem
|
// DOC include end: WithSimAXIMem
|
||||||
|
|
||||||
class WithBlackBoxSimMem extends OverrideIOBinder({
|
class WithBlackBoxSimMem extends OverrideIOBinder({
|
||||||
(clock, reset, _, top: CanHaveMasterAXI4MemPortModuleImp) => {
|
(system: CanHaveMasterAXI4MemPortModuleImp) => {
|
||||||
(top.mem_axi4 zip top.outer.memAXI4Node).foreach { case (io, node) =>
|
(system.mem_axi4 zip system.outer.memAXI4Node).foreach { case (io, node) =>
|
||||||
val memSize = top.p(ExtMem).get.master.size
|
val memSize = system.p(ExtMem).get.master.size
|
||||||
val lineSize = top.p(CacheBlockBytes)
|
val lineSize = system.p(CacheBlockBytes)
|
||||||
(io zip node.in).foreach { case (axi4, (_, edge)) =>
|
(io zip node.in).foreach { case (axi4, (_, edge)) =>
|
||||||
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle))
|
val mem = Module(new SimDRAM(memSize, lineSize, edge.bundle))
|
||||||
mem.io.axi <> axi4
|
mem.io.axi <> axi4
|
||||||
mem.io.clock := clock
|
mem.io.clock := system.clock
|
||||||
mem.io.reset := reset
|
mem.io.reset := system.reset
|
||||||
}
|
}
|
||||||
}; Nil
|
}; Nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimAXIMMIO extends OverrideIOBinder({
|
class WithSimAXIMMIO extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHaveMasterAXI4MMIOPortModuleImp) => top.connectSimAXIMMIO(); Nil
|
(system: CanHaveMasterAXI4MMIOPortModuleImp) => system.connectSimAXIMMIO(); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithDontTouchPorts extends OverrideIOBinder({
|
class WithDontTouchPorts extends OverrideIOBinder({
|
||||||
(c, r, s, top: DontTouch) => top.dontTouchPorts(); Nil
|
(system: DontTouch) => system.dontTouchPorts(); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTieOffInterrupts extends OverrideIOBinder({
|
class WithTieOffInterrupts extends OverrideIOBinder({
|
||||||
(c, r, s, top: HasExtInterruptsBundle) => top.tieOffInterrupts(); Nil
|
(system: HasExtInterruptsModuleImp) => {
|
||||||
|
val (port, ioCells) = IOCell.generateIOFromSignal(system.interrupts, Some("iocell_interrupts"))
|
||||||
|
port.suggestName("interrupts")
|
||||||
|
val harnessFn = (th: chipyard.TestHarness) => { port := 0.U; Nil }
|
||||||
|
Seq((Seq(port), ioCells, Some(harnessFn)))
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTieOffL2FBusAXI extends OverrideIOBinder({
|
class WithTieOffL2FBusAXI extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHaveSlaveAXI4PortModuleImp) => {
|
(system: CanHaveSlaveAXI4PortModuleImp) => {
|
||||||
top.l2_frontend_bus_axi4.foreach(axi => {
|
system.l2_frontend_bus_axi4.foreach(axi => {
|
||||||
axi.tieoff()
|
axi.tieoff()
|
||||||
experimental.DataMirror.directionOf(axi.ar.ready) match {
|
experimental.DataMirror.directionOf(axi.ar.ready) match {
|
||||||
case ActualDirection.Input =>
|
case ActualDirection.Input =>
|
||||||
@@ -142,6 +226,7 @@ class WithTieOffL2FBusAXI extends OverrideIOBinder({
|
|||||||
axi.aw.bits := DontCare
|
axi.aw.bits := DontCare
|
||||||
axi.ar.bits := DontCare
|
axi.ar.bits := DontCare
|
||||||
axi.w.bits := DontCare
|
axi.w.bits := DontCare
|
||||||
|
case _ => throw new Exception("Unknown AXI port direction")
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
Nil
|
Nil
|
||||||
@@ -149,38 +234,62 @@ class WithTieOffL2FBusAXI extends OverrideIOBinder({
|
|||||||
})
|
})
|
||||||
|
|
||||||
class WithTiedOffDebug extends OverrideIOBinder({
|
class WithTiedOffDebug extends OverrideIOBinder({
|
||||||
(c, r, s, top: HasPeripheryDebugModuleImp) => {
|
(system: HasPeripheryDebugModuleImp) => {
|
||||||
Debug.tieoffDebug(top.debug, top.psd)
|
val (psdPort, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.debug)
|
||||||
// tieoffDebug doesn't actually tie everything off :/
|
val harnessFn = (th: chipyard.TestHarness) => {
|
||||||
top.debug.foreach(_.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }))
|
Debug.tieoffDebug(debugPortOpt, psdPort)
|
||||||
Nil
|
// tieoffDebug doesn't actually tie everything off :/
|
||||||
|
debugPortOpt.foreach(_.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }))
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
Seq((Seq(psdPort) ++ debugPortOpt.toSeq, ioCells, Some(harnessFn)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimSerial extends OverrideIOBinder({
|
class WithSimDebug extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHavePeripherySerialModuleImp) => {
|
(system: HasPeripheryDebugModuleImp) => {
|
||||||
val ser_success = top.connectSimSerial()
|
val (psdPort, debugPortOpt, ioCells) = AddIOCells.debug(system.psd, system.debug)
|
||||||
when (ser_success) { s := true.B }
|
val harnessFn = (th: chipyard.TestHarness) => {
|
||||||
Nil
|
val dtm_success = Wire(Bool())
|
||||||
|
Debug.connectDebug(debugPortOpt, psdPort, th.clock, th.harnessReset, dtm_success)(system.p)
|
||||||
|
when (dtm_success) { th.success := true.B }
|
||||||
|
th.dutReset := th.harnessReset | debugPortOpt.map { debug => AsyncResetReg(debug.ndreset).asBool }.getOrElse(false.B)
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
Seq((Seq(psdPort) ++ debugPortOpt.toSeq, ioCells, Some(harnessFn)))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTiedOffSerial extends OverrideIOBinder({
|
class WithTiedOffSerial extends OverrideIOBinder({
|
||||||
(c, r, s, top: CanHavePeripherySerialModuleImp) => top.tieoffSerial(); Nil
|
(system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial =>
|
||||||
|
val (port, ioCells) = AddIOCells.serial(serial)
|
||||||
|
val harnessFn = (th: chipyard.TestHarness) => {
|
||||||
|
SerialAdapter.tieoff(port)
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
Seq((Seq(port), ioCells, Some(harnessFn)))
|
||||||
|
}).getOrElse(Nil)
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithSimSerial extends OverrideIOBinder({
|
||||||
|
(system: CanHavePeripherySerialModuleImp) => system.serial.map({ serial =>
|
||||||
|
val (port, ioCells) = AddIOCells.serial(serial)
|
||||||
|
val harnessFn = (th: chipyard.TestHarness) => {
|
||||||
|
val ser_success = SerialAdapter.connectSimSerial(port, th.clock, th.harnessReset)
|
||||||
|
when (ser_success) { th.success := true.B }
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
Seq((Seq(port), ioCells, Some(harnessFn)))
|
||||||
|
}).getOrElse(Nil)
|
||||||
|
})
|
||||||
|
|
||||||
class WithSimDebug extends OverrideIOBinder({
|
class WithTraceGenSuccessBinder extends OverrideIOBinder({
|
||||||
(c, r, s, top: HasPeripheryDebugModuleImp) => {
|
(system: HasTraceGenTilesModuleImp) => {
|
||||||
val dtm_success = Wire(Bool())
|
val (successPort, ioCells) = IOCell.generateIOFromSignal(system.success, Some("iocell_success"))
|
||||||
top.reset := r | top.debug.map { debug => AsyncResetReg(debug.ndreset) }.getOrElse(false.B)
|
successPort.suggestName("success")
|
||||||
Debug.connectDebug(top.debug, top.psd, c, r, dtm_success)(top.p)
|
val harnessFn = (th: chipyard.TestHarness) => { when (successPort) { th.success := true.B }; Nil }
|
||||||
when (dtm_success) { s := true.B }
|
Seq((Seq(successPort), ioCells, Some(harnessFn)))
|
||||||
Nil
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
}
|
||||||
class WithTraceGenSuccessBinder extends OverrideIOBinder({
|
|
||||||
(c, r, s, top: HasTraceGenTilesModuleImp) => when (top.success) { s := true.B }; Nil
|
|
||||||
})
|
|
||||||
|
|||||||
@@ -1,23 +1,21 @@
|
|||||||
package chipyard
|
package chipyard
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental._
|
|
||||||
|
|
||||||
import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxSourceHelper}
|
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||||
|
|
||||||
import freechips.rocketchip.diplomacy.LazyModule
|
|
||||||
import freechips.rocketchip.config.{Field, Parameters}
|
import freechips.rocketchip.config.{Field, Parameters}
|
||||||
import freechips.rocketchip.util.GeneratorApp
|
import chipyard.iobinders.{TestHarnessFunction}
|
||||||
import freechips.rocketchip.devices.debug.{Debug}
|
|
||||||
|
|
||||||
import chipyard.config.ConfigValName._
|
import chipyard.config.ConfigValName._
|
||||||
import chipyard.iobinders.{IOBinders}
|
|
||||||
|
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
// BOOM and/or Rocket Test Harness
|
// BOOM and/or Rocket Test Harness
|
||||||
// -------------------------------
|
// -------------------------------
|
||||||
|
|
||||||
case object BuildTop extends Field[Parameters => Any]((p: Parameters) => Module(LazyModule(new Top()(p)).suggestName("top").module))
|
case object BuildTop extends Field[Parameters => HasTestHarnessFunctions]((p: Parameters) => Module(new ChipTop()(p)))
|
||||||
|
|
||||||
|
trait HasTestHarnessFunctions {
|
||||||
|
val harnessFunctions: Seq[TestHarnessFunction]
|
||||||
|
}
|
||||||
|
|
||||||
class TestHarness(implicit val p: Parameters) extends Module {
|
class TestHarness(implicit val p: Parameters) extends Module {
|
||||||
val io = IO(new Bundle {
|
val io = IO(new Bundle {
|
||||||
@@ -26,5 +24,15 @@ class TestHarness(implicit val p: Parameters) extends Module {
|
|||||||
|
|
||||||
val dut = p(BuildTop)(p)
|
val dut = p(BuildTop)(p)
|
||||||
io.success := false.B
|
io.success := false.B
|
||||||
p(IOBinders).values.map(fn => fn(clock, reset.asBool, io.success, dut))
|
|
||||||
|
// dutReset can be overridden via a harnessFunction, but by default it is just reset
|
||||||
|
val dutReset = Wire(Bool())
|
||||||
|
dutReset := reset
|
||||||
|
|
||||||
|
dut.harnessFunctions.foreach(_(this))
|
||||||
|
|
||||||
|
def success = io.success
|
||||||
|
def harnessReset = this.reset.asBool
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -364,6 +364,7 @@ class ScratchpadRocketConfig extends Config(
|
|||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
// DOC include end: scratchpadrocket
|
// DOC include end: scratchpadrocket
|
||||||
|
|
||||||
|
// DOC include start: RingSystemBusRocket
|
||||||
class RingSystemBusRocketConfig extends Config(
|
class RingSystemBusRocketConfig extends Config(
|
||||||
new chipyard.iobinders.WithUARTAdapter ++
|
new chipyard.iobinders.WithUARTAdapter ++
|
||||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
new chipyard.iobinders.WithTieOffInterrupts ++
|
||||||
@@ -382,3 +383,4 @@ class RingSystemBusRocketConfig extends Config(
|
|||||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++
|
||||||
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
new freechips.rocketchip.subsystem.WithNBigCores(1) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
// DOC include end: RingSystemBusRocket
|
||||||
|
|||||||
@@ -6,21 +6,21 @@ import freechips.rocketchip.rocket.{DCacheParams}
|
|||||||
class TraceGenConfig extends Config(
|
class TraceGenConfig extends Config(
|
||||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||||
new chipyard.config.WithTracegenTop ++
|
new chipyard.config.WithTracegenSystem ++
|
||||||
new tracegen.WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++
|
new tracegen.WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 0, nSets = 16, nWays = 2) }) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class NonBlockingTraceGenConfig extends Config(
|
class NonBlockingTraceGenConfig extends Config(
|
||||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||||
new chipyard.config.WithTracegenTop ++
|
new chipyard.config.WithTracegenSystem ++
|
||||||
new tracegen.WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
|
new tracegen.WithTraceGen(List.fill(2) { DCacheParams(nMSHRs = 2, nSets = 16, nWays = 2) }) ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
|
|
||||||
class BoomTraceGenConfig extends Config(
|
class BoomTraceGenConfig extends Config(
|
||||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||||
new chipyard.config.WithTracegenTop ++
|
new chipyard.config.WithTracegenSystem ++
|
||||||
new tracegen.WithBoomTraceGen(List.fill(2) { DCacheParams(nMSHRs = 8, nSets = 16, nWays = 2) }) ++
|
new tracegen.WithBoomTraceGen(List.fill(2) { DCacheParams(nMSHRs = 8, nSets = 16, nWays = 2) }) ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
@@ -28,7 +28,7 @@ class BoomTraceGenConfig extends Config(
|
|||||||
class NonBlockingTraceGenL2Config extends Config(
|
class NonBlockingTraceGenL2Config extends Config(
|
||||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||||
new chipyard.config.WithTracegenTop ++
|
new chipyard.config.WithTracegenSystem ++
|
||||||
new tracegen.WithL2TraceGen(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++
|
new tracegen.WithL2TraceGen(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
new freechips.rocketchip.system.BaseConfig)
|
new freechips.rocketchip.system.BaseConfig)
|
||||||
@@ -36,7 +36,7 @@ class NonBlockingTraceGenL2Config extends Config(
|
|||||||
class NonBlockingTraceGenL2RingConfig extends Config(
|
class NonBlockingTraceGenL2RingConfig extends Config(
|
||||||
new chipyard.iobinders.WithBlackBoxSimMem ++
|
new chipyard.iobinders.WithBlackBoxSimMem ++
|
||||||
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
new chipyard.iobinders.WithTraceGenSuccessBinder ++
|
||||||
new chipyard.config.WithTracegenTop ++
|
new chipyard.config.WithTracegenSystem ++
|
||||||
new tracegen.WithL2TraceGen(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++
|
new tracegen.WithL2TraceGen(List.fill(2)(DCacheParams(nMSHRs = 2, nSets = 16, nWays = 4))) ++
|
||||||
new testchipip.WithRingSystemBus ++
|
new testchipip.WithRingSystemBus ++
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++
|
||||||
|
|||||||
@@ -7,10 +7,11 @@ import chisel3.experimental.annotate
|
|||||||
|
|
||||||
import freechips.rocketchip.config.{Field, Config, Parameters}
|
import freechips.rocketchip.config.{Field, Config, Parameters}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule}
|
import freechips.rocketchip.diplomacy.{LazyModule}
|
||||||
import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp
|
import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebugModuleImp}
|
||||||
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp}
|
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp, HasExtInterruptsModuleImp}
|
||||||
import freechips.rocketchip.tile.{RocketTile}
|
import freechips.rocketchip.tile.{RocketTile}
|
||||||
import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
|
import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
|
||||||
|
import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp}
|
||||||
|
|
||||||
import testchipip.{CanHavePeripherySerialModuleImp, CanHavePeripheryBlockDeviceModuleImp, CanHaveTraceIOModuleImp}
|
import testchipip.{CanHavePeripherySerialModuleImp, CanHavePeripheryBlockDeviceModuleImp, CanHaveTraceIOModuleImp}
|
||||||
import icenet.CanHavePeripheryIceNICModuleImp
|
import icenet.CanHavePeripheryIceNICModuleImp
|
||||||
@@ -30,75 +31,63 @@ import chipyard.HasChipyardTilesModuleImp
|
|||||||
|
|
||||||
object MainMemoryConsts {
|
object MainMemoryConsts {
|
||||||
val regionNamePrefix = "MainMemory"
|
val regionNamePrefix = "MainMemory"
|
||||||
def globalName(): String = s"${regionNamePrefix}_${NodeIdx()}"
|
def globalName = s"${regionNamePrefix}_${NodeIdx()}"
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithSerialBridge extends OverrideIOBinder({
|
class WithSerialBridge extends OverrideIOBinder({
|
||||||
(c, r, s, target: CanHavePeripherySerialModuleImp) =>
|
(system: CanHavePeripherySerialModuleImp) =>
|
||||||
target.serial.map(s => SerialBridge(target.clock, s, MainMemoryConsts.globalName)(target.p)).toSeq
|
system.serial.foreach(s => SerialBridge(system.clock, s, MainMemoryConsts.globalName)(system.p)); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithNICBridge extends OverrideIOBinder({
|
class WithNICBridge extends OverrideIOBinder({
|
||||||
(c, r, s, target: CanHavePeripheryIceNICModuleImp) =>
|
(system: CanHavePeripheryIceNICModuleImp) =>
|
||||||
target.net.map(n => NICBridge(target.clock, n)(target.p)).toSeq
|
system.net.foreach(n => NICBridge(system.clock, n)(system.p)); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithUARTBridge extends OverrideIOBinder({
|
class WithUARTBridge extends OverrideIOBinder({
|
||||||
(c, r, s, target: HasPeripheryUARTModuleImp) =>
|
(system: HasPeripheryUARTModuleImp) =>
|
||||||
target.uart.map(u => UARTBridge(target.clock, u)(target.p)).toSeq
|
system.uart.foreach(u => UARTBridge(system.clock, u)(system.p)); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithBlockDeviceBridge extends OverrideIOBinder({
|
class WithBlockDeviceBridge extends OverrideIOBinder({
|
||||||
(c, r, s, target: CanHavePeripheryBlockDeviceModuleImp) =>
|
(system: CanHavePeripheryBlockDeviceModuleImp) =>
|
||||||
target.bdev.map(b => BlockDevBridge(target.clock, b, target.reset.toBool)(target.p)).toSeq
|
system.bdev.foreach(b => BlockDevBridge(system.clock, b, system.reset.toBool)(system.p)); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
// Assign a unique name to each target memory space, consisting of one or more
|
|
||||||
// memory channels. In the multi-node case, serial widgets can then disambiguate
|
|
||||||
// each memory region using this string instead of relying on the assumption
|
|
||||||
// the target has a single memory channel.
|
|
||||||
object MemoryRegionNames {
|
|
||||||
var idx = -1
|
|
||||||
def getName(): String = {
|
|
||||||
idx += 1
|
|
||||||
s"memory_${idx}"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class WithFASEDBridge extends OverrideIOBinder ({
|
class WithFASEDBridge extends OverrideIOBinder({
|
||||||
(c, r, s, t: CanHaveMasterAXI4MemPortModuleImp) => {
|
(system: CanHaveMasterAXI4MemPortModuleImp) => {
|
||||||
implicit val p = t.p
|
implicit val p = system.p
|
||||||
(t.mem_axi4 zip t.outer.memAXI4Node).flatMap({ case (io, node) =>
|
(system.mem_axi4 zip system.outer.memAXI4Node).flatMap({ case (io, node) =>
|
||||||
(io zip node.in).map({ case (axi4Bundle, (_, edge)) =>
|
(io zip node.in).map({ case (axi4Bundle, (_, edge)) =>
|
||||||
val nastiKey = NastiParameters(axi4Bundle.r.bits.data.getWidth,
|
val nastiKey = NastiParameters(axi4Bundle.r.bits.data.getWidth,
|
||||||
axi4Bundle.ar.bits.addr.getWidth,
|
axi4Bundle.ar.bits.addr.getWidth,
|
||||||
axi4Bundle.ar.bits.id.getWidth)
|
axi4Bundle.ar.bits.id.getWidth)
|
||||||
FASEDBridge(t.clock, axi4Bundle, t.reset.toBool,
|
FASEDBridge(system.clock, axi4Bundle, system.reset.toBool,
|
||||||
CompleteConfig(p(firesim.configs.MemModelKey),
|
CompleteConfig(p(firesim.configs.MemModelKey),
|
||||||
nastiKey,
|
nastiKey,
|
||||||
Some(AXI4EdgeSummary(edge)),
|
Some(AXI4EdgeSummary(edge)),
|
||||||
Some(MainMemoryConsts.globalName)))
|
Some(MainMemoryConsts.globalName)))
|
||||||
})
|
})
|
||||||
}).toSeq
|
})
|
||||||
|
Nil
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTracerVBridge extends OverrideIOBinder({
|
class WithTracerVBridge extends OverrideIOBinder({
|
||||||
(c, r, s, target: CanHaveTraceIOModuleImp) => target.traceIO match {
|
(system: CanHaveTraceIOModuleImp) =>
|
||||||
case Some(t) => t.traces.map(tileTrace => TracerVBridge(tileTrace)(target.p))
|
system.traceIO.foreach(_.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p))); Nil
|
||||||
case None => Nil
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class WithTraceGenBridge extends OverrideIOBinder({
|
class WithTraceGenBridge extends OverrideIOBinder({
|
||||||
(c, r, s, target: HasTraceGenTilesModuleImp) =>
|
(system: HasTraceGenTilesModuleImp) =>
|
||||||
Seq(GroundTestBridge(target.clock, target.success)(target.p))
|
GroundTestBridge(system.clock, system.success)(system.p); Nil
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
|
class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
|
||||||
(c, r, s, target: HasChipyardTilesModuleImp) => {
|
(system: HasChipyardTilesModuleImp) => {
|
||||||
target.outer.tiles.map {
|
system.outer.tiles.map {
|
||||||
case r: RocketTile => {
|
case r: RocketTile => {
|
||||||
annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf))
|
annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf))
|
||||||
r.module.fpuOpt.foreach(fpu => annotate(MemModelAnnotation(fpu.fpuImpl.regfile)))
|
r.module.fpuOpt.foreach(fpu => annotate(MemModelAnnotation(fpu.fpuImpl.regfile)))
|
||||||
@@ -120,13 +109,31 @@ class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
|
|||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithTiedOffSystemGPIO extends OverrideIOBinder({
|
||||||
|
(system: HasPeripheryGPIOModuleImp) =>
|
||||||
|
system.gpio.foreach(_.pins.foreach(_.i.ival := false.B)); Nil
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithTiedOffSystemDebug extends OverrideIOBinder({
|
||||||
|
(system: HasPeripheryDebugModuleImp) => {
|
||||||
|
Debug.tieoffDebug(system.debug, system.psd)
|
||||||
|
// tieoffDebug doesn't actually tie everything off :/
|
||||||
|
system.debug.foreach(_.clockeddmi.foreach({ cdmi => cdmi.dmi.req.bits := DontCare }))
|
||||||
|
Nil
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithTiedOffSystemInterrupts extends OverrideIOBinder({
|
||||||
|
(system: HasExtInterruptsModuleImp) =>
|
||||||
|
system.interrupts := 0.U; Nil
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
// Shorthand to register all of the provided bridges above
|
// Shorthand to register all of the provided bridges above
|
||||||
class WithDefaultFireSimBridges extends Config(
|
class WithDefaultFireSimBridges extends Config(
|
||||||
new chipyard.iobinders.WithGPIOTiedOff ++
|
new WithTiedOffSystemGPIO ++
|
||||||
new chipyard.iobinders.WithTiedOffDebug ++
|
new WithTiedOffSystemDebug ++
|
||||||
new chipyard.iobinders.WithTieOffInterrupts ++
|
new WithTiedOffSystemInterrupts ++
|
||||||
new WithSerialBridge ++
|
new WithSerialBridge ++
|
||||||
new WithNICBridge ++
|
new WithNICBridge ++
|
||||||
new WithUARTBridge ++
|
new WithUARTBridge ++
|
||||||
|
|||||||
@@ -9,7 +9,7 @@ import freechips.rocketchip.diplomacy.{LazyModule}
|
|||||||
|
|
||||||
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge}
|
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge}
|
||||||
|
|
||||||
import chipyard.{BuildTop}
|
import chipyard.{BuildSystem}
|
||||||
import chipyard.iobinders.{IOBinders}
|
import chipyard.iobinders.{IOBinders}
|
||||||
|
|
||||||
// Determines the number of times to instantiate the DUT in the harness.
|
// Determines the number of times to instantiate the DUT in the harness.
|
||||||
@@ -34,14 +34,14 @@ class FireSim(implicit val p: Parameters) extends RawModule {
|
|||||||
val reset = WireInit(false.B)
|
val reset = WireInit(false.B)
|
||||||
withClockAndReset(clock, reset) {
|
withClockAndReset(clock, reset) {
|
||||||
// Instantiate multiple instances of the DUT to implement supernode
|
// Instantiate multiple instances of the DUT to implement supernode
|
||||||
val targets = Seq.fill(p(NumNodes))(p(BuildTop)(p))
|
val targets = Seq.fill(p(NumNodes))(p(BuildSystem)(p))
|
||||||
val peekPokeBridge = PeekPokeBridge(clock, reset)
|
val peekPokeBridge = PeekPokeBridge(clock, reset)
|
||||||
// A Seq of partial functions that will instantiate the right bridge only
|
// A Seq of partial functions that will instantiate the right bridge only
|
||||||
// if that Mixin trait is present in the target's class instance
|
// if that Mixin trait is present in the target's class instance
|
||||||
//
|
//
|
||||||
// Apply each partial function to each DUT instance
|
// Apply each partial function to each DUT instance
|
||||||
for (target <- targets) {
|
for ((target) <- targets) {
|
||||||
p(IOBinders).values.map(fn => fn(clock, reset.asBool, false.B, target))
|
p(IOBinders).values.map(_(target))
|
||||||
NodeIdx.increment()
|
NodeIdx.increment()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ import boom.common.{BoomTilesKey, BoomCrossingKey}
|
|||||||
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock}
|
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock}
|
||||||
import firesim.configs._
|
import firesim.configs._
|
||||||
|
|
||||||
import chipyard.{BuildTop, Top, TopModule}
|
import chipyard.{BuildSystem, DigitalTop, DigitalTopModule}
|
||||||
import chipyard.config.ConfigValName._
|
import chipyard.config.ConfigValName._
|
||||||
import chipyard.iobinders.{IOBinders}
|
import chipyard.iobinders.{IOBinders}
|
||||||
|
|
||||||
@@ -64,7 +64,7 @@ class WithSingleRationalTileDomain(multiplier: Int, divisor: Int) extends Config
|
|||||||
class HalfRateUncore extends WithSingleRationalTileDomain(2,1)
|
class HalfRateUncore extends WithSingleRationalTileDomain(2,1)
|
||||||
|
|
||||||
class WithFiresimMulticlockTop extends Config((site, here, up) => {
|
class WithFiresimMulticlockTop extends Config((site, here, up) => {
|
||||||
case BuildTop => (p: Parameters) => Module(LazyModule(new FiresimMulticlockTop()(p)).suggestName("Top").module)
|
case BuildSystem => (p: Parameters) => Module(LazyModule(new FiresimMulticlockTop()(p)).suggestName("system").module)
|
||||||
})
|
})
|
||||||
|
|
||||||
// Complete Config
|
// Complete Config
|
||||||
@@ -74,12 +74,12 @@ class FireSimQuadRocketMulticlockConfig extends Config(
|
|||||||
new FireSimQuadRocketConfig)
|
new FireSimQuadRocketConfig)
|
||||||
|
|
||||||
// Top Definition
|
// Top Definition
|
||||||
class FiresimMulticlockTop(implicit p: Parameters) extends chipyard.Top
|
class FiresimMulticlockTop(implicit p: Parameters) extends chipyard.DigitalTop
|
||||||
{
|
{
|
||||||
override lazy val module = new FiresimMulticlockTopModule(this)
|
override lazy val module = new FiresimMulticlockTopModule(this)
|
||||||
}
|
}
|
||||||
|
|
||||||
class FiresimMulticlockTopModule[+L <: Top](l: L) extends chipyard.TopModule(l) with HasFireSimClockingImp
|
class FiresimMulticlockTopModule[+L <: DigitalTop](l: L) extends chipyard.DigitalTopModule(l) with HasFireSimClockingImp
|
||||||
|
|
||||||
// Harness Definition
|
// Harness Definition
|
||||||
class FireSimMulticlockPOC(implicit val p: Parameters) extends RawModule {
|
class FireSimMulticlockPOC(implicit val p: Parameters) extends RawModule {
|
||||||
@@ -88,14 +88,14 @@ class FireSimMulticlockPOC(implicit val p: Parameters) extends RawModule {
|
|||||||
val reset = WireInit(false.B)
|
val reset = WireInit(false.B)
|
||||||
withClockAndReset(refClock, reset) {
|
withClockAndReset(refClock, reset) {
|
||||||
// Instantiate multiple instances of the DUT to implement supernode
|
// Instantiate multiple instances of the DUT to implement supernode
|
||||||
val targets = Seq.fill(p(NumNodes))(p(BuildTop)(p))
|
val targets = Seq.fill(p(NumNodes))(p(BuildSystem)(p))
|
||||||
val peekPokeBridge = PeekPokeBridge(refClock, reset)
|
val peekPokeBridge = PeekPokeBridge(refClock, reset)
|
||||||
// A Seq of partial functions that will instantiate the right bridge only
|
// A Seq of partial functions that will instantiate the right bridge only
|
||||||
// if that Mixin trait is present in the target's class instance
|
// if that Mixin trait is present in the target's class instance
|
||||||
//
|
//
|
||||||
// Apply each partial function to each DUT instance
|
// Apply each partial function to each DUT instance
|
||||||
for ((target) <- targets) {
|
for ((target) <- targets) {
|
||||||
p(IOBinders).values.map(fn => fn(refClock, reset.asBool, false.B, target))
|
p(IOBinders).values.map(_(target))
|
||||||
}
|
}
|
||||||
targets.collect({ case t: HasAdditionalClocks => t.clocks := clockBridge.io.clocks })
|
targets.collect({ case t: HasAdditionalClocks => t.clocks := clockBridge.io.clocks })
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ import testchipip.WithRingSystemBus
|
|||||||
|
|
||||||
import firesim.bridges._
|
import firesim.bridges._
|
||||||
import firesim.configs._
|
import firesim.configs._
|
||||||
import chipyard.{BuildTop}
|
|
||||||
import chipyard.config.ConfigValName._
|
import chipyard.config.ConfigValName._
|
||||||
|
|
||||||
class WithBootROM extends Config((site, here, up) => {
|
class WithBootROM extends Config((site, here, up) => {
|
||||||
|
|||||||
Submodule generators/icenet updated: f227228474...b1f957e6eb
Submodule generators/testchipip updated: 30d44252e8...d06d7c7dc2
18
generators/tracegen/tracegen.mk
Normal file
18
generators/tracegen/tracegen.mk
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
##############################################################
|
||||||
|
# extra variables/targets ingested by the chipyard make system
|
||||||
|
##############################################################
|
||||||
|
|
||||||
|
AXE_DIR=$(base_dir)/tools/axe/src
|
||||||
|
AXE=$(AXE_DIR)/axe
|
||||||
|
|
||||||
|
$(AXE): $(wildcard $(AXE_DIR)/*.[ch]) $(AXE_DIR)/make.sh
|
||||||
|
cd $(AXE_DIR) && ./make.sh
|
||||||
|
|
||||||
|
$(output_dir)/tracegen.out: $(sim)
|
||||||
|
mkdir -p $(output_dir) && $(sim) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(VERBOSE_FLAGS) $(PERMISSIVE_OFF) none </dev/null 2> $@
|
||||||
|
|
||||||
|
$(output_dir)/tracegen.result: $(output_dir)/tracegen.out $(AXE)
|
||||||
|
$(base_dir)/scripts/check-tracegen.sh $< > $@
|
||||||
|
|
||||||
|
.PHONY: tracegen
|
||||||
|
tracegen: $(output_dir)/tracegen.result
|
||||||
@@ -5,7 +5,7 @@ index a633066..3df8b74 100644
|
|||||||
@@ -124,7 +124,7 @@ lazy val testchipip = (project in file("generators/testchipip"))
|
@@ -124,7 +124,7 @@ lazy val testchipip = (project in file("generators/testchipip"))
|
||||||
|
|
||||||
lazy val chipyard = conditionalDependsOn(project in file("generators/chipyard"))
|
lazy val chipyard = conditionalDependsOn(project in file("generators/chipyard"))
|
||||||
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities,
|
.dependsOn(boom, hwacha, sifive_blocks, sifive_cache, utilities, iocell,
|
||||||
- sha3, // On separate line to allow for cleaner tutorial-setup patches
|
- sha3, // On separate line to allow for cleaner tutorial-setup patches
|
||||||
+// sha3, // On separate line to allow for cleaner tutorial-setup patches
|
+// sha3, // On separate line to allow for cleaner tutorial-setup patches
|
||||||
gemmini, icenet, tracegen, ariane)
|
gemmini, icenet, tracegen, ariane)
|
||||||
|
|||||||
Submodule sims/firesim updated: 998eeaea23...a4f0a18c0a
@@ -50,7 +50,8 @@ VCS_CC_OPTS = \
|
|||||||
-CC "-I$(dramsim_dir)" \
|
-CC "-I$(dramsim_dir)" \
|
||||||
-CC "-std=c++11" \
|
-CC "-std=c++11" \
|
||||||
$(dramsim_lib) \
|
$(dramsim_lib) \
|
||||||
$(RISCV)/lib/libfesvr.a
|
$(RISCV)/lib/libfesvr.a \
|
||||||
|
-CC "$(EXTRA_SIM_CC_FLAGS)"
|
||||||
|
|
||||||
VCS_NONCC_OPTS = \
|
VCS_NONCC_OPTS = \
|
||||||
+lint=all,noVCDE,noONGS,noUI \
|
+lint=all,noVCDE,noONGS,noUI \
|
||||||
@@ -80,16 +81,16 @@ VCS_DEFINES = \
|
|||||||
+define+RANDOMIZE_GARBAGE_ASSIGN \
|
+define+RANDOMIZE_GARBAGE_ASSIGN \
|
||||||
+define+RANDOMIZE_INVALID_ASSIGN
|
+define+RANDOMIZE_INVALID_ASSIGN
|
||||||
|
|
||||||
VCS_OPTS = -notice -line $(VCS_CC_OPTS) $(VCS_NONCC_OPTS) $(VCS_DEFINES)
|
VCS_OPTS = -notice -line $(VCS_CC_OPTS) $(VCS_NONCC_OPTS) $(VCS_DEFINES) $(EXTRA_SIM_SOURCES)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# vcs simulator rules
|
# vcs simulator rules
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
$(sim): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib)
|
$(sim): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib) $(EXTRA_SIM_REQS)
|
||||||
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \
|
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \
|
||||||
-debug_pp
|
-debug_pp
|
||||||
|
|
||||||
$(sim_debug): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib)
|
$(sim_debug): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib) $(EXTRA_SIM_REQS)
|
||||||
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \
|
rm -rf csrc && $(VCS) $(VCS_OPTS) -o $@ \
|
||||||
+define+DEBUG \
|
+define+DEBUG \
|
||||||
-debug_pp
|
-debug_pp
|
||||||
@@ -99,7 +100,7 @@ $(sim_debug): $(sim_vsrcs) $(sim_common_files) $(dramsim_lib)
|
|||||||
#########################################################################################
|
#########################################################################################
|
||||||
.PRECIOUS: $(output_dir)/%.vpd %.vpd
|
.PRECIOUS: $(output_dir)/%.vpd %.vpd
|
||||||
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
|
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
|
||||||
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(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) $(VERBOSE_FLAGS) +vcdplusfile=$@ $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# general cleanup rule
|
# general cleanup rule
|
||||||
|
|||||||
@@ -47,14 +47,25 @@ include $(base_dir)/common.mk
|
|||||||
#########################################################################################
|
#########################################################################################
|
||||||
VERILATOR := verilator --cc --exe
|
VERILATOR := verilator --cc --exe
|
||||||
|
|
||||||
CXXFLAGS := $(CXXFLAGS) -O1 -std=c++11 -I$(RISCV)/include -I$(dramsim_dir) -D__STDC_FORMAT_MACROS
|
CXXFLAGS := \
|
||||||
LDFLAGS := $(LDFLAGS) -L$(RISCV)/lib -Wl,-rpath,$(RISCV)/lib -L$(dramsim_dir) -Wl,-rpath,$(dramsim_dir) -L$(sim_dir) -lfesvr -lpthread -ldramsim
|
$(CXXFLAGS) -O1 -std=c++11 \
|
||||||
|
-I$(RISCV)/include \
|
||||||
|
-I$(dramsim_dir) \
|
||||||
|
-D__STDC_FORMAT_MACROS \
|
||||||
|
$(EXTRA_SIM_CC_FLAGS)
|
||||||
|
|
||||||
|
LDFLAGS := \
|
||||||
|
$(LDFLAGS) \
|
||||||
|
-L$(sim_dir) \
|
||||||
|
-lpthread
|
||||||
|
|
||||||
VERILATOR_CC_OPTS = \
|
VERILATOR_CC_OPTS = \
|
||||||
-O3 \
|
-O3 \
|
||||||
-CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(VLOG_MODEL) -DVERILATOR" \
|
-CFLAGS "$(CXXFLAGS) -DTEST_HARNESS=V$(VLOG_MODEL) -DVERILATOR" \
|
||||||
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(build_dir)/verilator.h" \
|
-CFLAGS "-I$(build_dir) -include $(build_dir)/$(long_name).plusArgs -include $(build_dir)/verilator.h" \
|
||||||
-LDFLAGS "$(LDFLAGS)"
|
-LDFLAGS "$(LDFLAGS)" \
|
||||||
|
$(RISCV)/lib/libfesvr.a \
|
||||||
|
$(dramsim_lib)
|
||||||
|
|
||||||
# default flags added for ariane
|
# default flags added for ariane
|
||||||
ARIANE_VERILATOR_FLAGS = \
|
ARIANE_VERILATOR_FLAGS = \
|
||||||
@@ -87,7 +98,7 @@ VERILATOR_DEFINES = \
|
|||||||
+define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \
|
+define+PRINTF_COND=\$$c\(\"verbose\",\"\&\&\"\,\"done_reset\"\) \
|
||||||
+define+STOP_COND=\$$c\(\"done_reset\"\)
|
+define+STOP_COND=\$$c\(\"done_reset\"\)
|
||||||
|
|
||||||
VERILATOR_OPTS = $(VERILATOR_CC_OPTS) $(VERILATOR_NONCC_OPTS) $(VERILATOR_DEFINES)
|
VERILATOR_OPTS = $(VERILATOR_CC_OPTS) $(VERILATOR_NONCC_OPTS) $(VERILATOR_DEFINES) $(EXTRA_SIM_SOURCES)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# verilator build paths and file names
|
# verilator build paths and file names
|
||||||
@@ -104,13 +115,13 @@ model_mk_debug = $(model_dir_debug)/V$(VLOG_MODEL).mk
|
|||||||
#########################################################################################
|
#########################################################################################
|
||||||
# build makefile fragment that builds the verilator sim rules
|
# build makefile fragment that builds the verilator sim rules
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
$(model_mk): $(sim_vsrcs) $(sim_common_files)
|
$(model_mk): $(sim_vsrcs) $(sim_common_files) $(EXTRA_SIM_REQS)
|
||||||
rm -rf $(build_dir)/$(long_name)
|
rm -rf $(build_dir)/$(long_name)
|
||||||
mkdir -p $(build_dir)/$(long_name)
|
mkdir -p $(build_dir)/$(long_name)
|
||||||
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim) -Mdir $(model_dir) -CFLAGS "-include $(model_header)"
|
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim) -Mdir $(model_dir) -CFLAGS "-include $(model_header)"
|
||||||
touch $@
|
touch $@
|
||||||
|
|
||||||
$(model_mk_debug): $(sim_vsrcs) $(sim_common_files)
|
$(model_mk_debug): $(sim_vsrcs) $(sim_common_files) $(EXTRA_SIM_REQS)
|
||||||
rm -rf $(build_dir)/$(long_name)
|
rm -rf $(build_dir)/$(long_name)
|
||||||
mkdir -p $(build_dir)/$(long_name).debug
|
mkdir -p $(build_dir)/$(long_name).debug
|
||||||
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim_debug) --trace -Mdir $(model_dir_debug) -CFLAGS "-include $(model_header_debug)"
|
$(VERILATOR) $(VERILATOR_OPTS) -o $(sim_debug) --trace -Mdir $(model_dir_debug) -CFLAGS "-include $(model_header_debug)"
|
||||||
@@ -132,7 +143,7 @@ $(sim_debug): $(model_mk_debug) $(dramsim_lib)
|
|||||||
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
|
$(output_dir)/%.vpd: $(output_dir)/% $(sim_debug)
|
||||||
rm -f $@.vcd && mkfifo $@.vcd
|
rm -f $@.vcd && mkfifo $@.vcd
|
||||||
vcd2vpd $@.vcd $@ > /dev/null &
|
vcd2vpd $@.vcd $@ > /dev/null &
|
||||||
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) +max-cycles=$(timeout_cycles) $(SIM_FLAGS) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
(set -o pipefail && $(sim_debug) $(PERMISSIVE_ON) $(SIM_FLAGS) $(EXTRA_SIM_FLAGS) $(VERBOSE_FLAGS) -v$@.vcd $(PERMISSIVE_OFF) $< </dev/null 2> >(spike-dasm > $<.out) | tee $<.log)
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# general cleanup rule
|
# general cleanup rule
|
||||||
|
|||||||
Submodule software/spec2017 updated: b864313643...a4333f243c
Submodule tools/barstools updated: 63d74bc177...db6776367c
@@ -36,7 +36,7 @@ ifeq ($(SUB_PROJECT),chipyard)
|
|||||||
CONFIG_PACKAGE ?= $(SBT_PROJECT)
|
CONFIG_PACKAGE ?= $(SBT_PROJECT)
|
||||||
GENERATOR_PACKAGE ?= $(SBT_PROJECT)
|
GENERATOR_PACKAGE ?= $(SBT_PROJECT)
|
||||||
TB ?= TestDriver
|
TB ?= TestDriver
|
||||||
TOP ?= Top
|
TOP ?= ChipTop
|
||||||
endif
|
endif
|
||||||
# for Rocket-chip developers
|
# for Rocket-chip developers
|
||||||
ifeq ($(SUB_PROJECT),rocketchip)
|
ifeq ($(SUB_PROJECT),rocketchip)
|
||||||
@@ -143,7 +143,7 @@ output_dir=$(sim_dir)/output/$(long_name)
|
|||||||
# helper variables to run binaries
|
# helper variables to run binaries
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
BINARY ?=
|
BINARY ?=
|
||||||
SIM_FLAGS ?=
|
override SIM_FLAGS += +dramsim +max-cycles=$(timeout_cycles)
|
||||||
VERBOSE_FLAGS ?= +verbose
|
VERBOSE_FLAGS ?= +verbose
|
||||||
sim_out_name = $(subst $() $(),_,$(notdir $(basename $(BINARY))).$(long_name))
|
sim_out_name = $(subst $() $(),_,$(notdir $(basename $(BINARY))).$(long_name))
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user