Merge branch 'main' of github.com:ucb-bar/chipyard into enable-sba
This commit is contained in:
2
.github/workflows/update-circt.yml
vendored
2
.github/workflows/update-circt.yml
vendored
@@ -16,7 +16,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Update CIRCT
|
- name: Update CIRCT
|
||||||
uses: circt/update-circt@v1.0.0
|
uses: circt/update-circt@v1
|
||||||
with:
|
with:
|
||||||
user: 'bartender'
|
user: 'bartender'
|
||||||
email: 'firesimchipyard@gmail.com'
|
email: 'firesimchipyard@gmail.com'
|
||||||
|
|||||||
6
.gitmodules
vendored
6
.gitmodules
vendored
@@ -1,10 +1,10 @@
|
|||||||
[submodule "rocket-chip"]
|
[submodule "generators/rocket-chip"]
|
||||||
path = generators/rocket-chip
|
path = generators/rocket-chip
|
||||||
url = https://github.com/chipsalliance/rocket-chip.git
|
url = https://github.com/chipsalliance/rocket-chip.git
|
||||||
[submodule "testchipip"]
|
[submodule "generators/testchipip"]
|
||||||
path = generators/testchipip
|
path = generators/testchipip
|
||||||
url = https://github.com/ucb-bar/testchipip.git
|
url = https://github.com/ucb-bar/testchipip.git
|
||||||
[submodule "barstools"]
|
[submodule "tools/barstools"]
|
||||||
path = tools/barstools
|
path = tools/barstools
|
||||||
url = https://github.com/ucb-bar/barstools.git
|
url = https://github.com/ucb-bar/barstools.git
|
||||||
[submodule "tools/torture"]
|
[submodule "tools/torture"]
|
||||||
|
|||||||
@@ -198,25 +198,3 @@ bringup design).
|
|||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: TetheredChipLikeRocketConfig
|
:start-after: DOC include start: TetheredChipLikeRocketConfig
|
||||||
:end-before: DOC include end: TetheredChipLikeRocketConfig
|
:end-before: DOC include end: TetheredChipLikeRocketConfig
|
||||||
|
|
||||||
Softcore-driven Bringup Setup of the Example Test Chip after Tapeout
|
|
||||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
Bringing up test chips with a FPGA softcore as described here is discouraged.
|
|
||||||
An alternative approach using the FPGA to "bridge" between a host computer and the test chip is the preferred approach.
|
|
||||||
|
|
||||||
Assuming this example test chip is taped out and now ready to be tested, we can communicate with the chip using this serial-link.
|
|
||||||
For example, a common test setup used at Berkeley to evaluate Chipyard-based test-chips includes an FPGA running a RISC-V soft-core that is able to speak to the DUT (over an FMC).
|
|
||||||
This RISC-V soft-core would serve as the host of the test that will run on the DUT.
|
|
||||||
This is done by the RISC-V soft-core running FESVR, sending TSI commands to a ``TSIToTileLink`` / ``TLSerdesser`` programmed on the FPGA.
|
|
||||||
Once the commands are converted to serialized TileLink, then they can be sent over some medium to the DUT
|
|
||||||
(like an FMC cable or a set of wires connecting FPGA outputs to the DUT board).
|
|
||||||
Similar to simulation, if the chip requests offchip memory, it can then send the transaction back over the serial-link.
|
|
||||||
Then the request can be serviced by the FPGA DRAM.
|
|
||||||
The following image shows this flow:
|
|
||||||
|
|
||||||
.. image:: ../_static/images/chip-bringup.png
|
|
||||||
|
|
||||||
In fact, this exact type of bringup setup is what the following section discusses:
|
|
||||||
:ref:_legacy-vcu118-bringup.
|
|
||||||
|
|||||||
@@ -74,6 +74,6 @@ mode, thus starting userspace execution.
|
|||||||
The easiest way to build a BBL image that boots Linux is to use the FireMarshal
|
The easiest way to build a BBL image that boots Linux is to use the FireMarshal
|
||||||
tool that lives in the `firesim-software <https://github.com/firesim/firesim-software>`_
|
tool that lives in the `firesim-software <https://github.com/firesim/firesim-software>`_
|
||||||
repository. Directions on how to use FireMarshal can be found in the
|
repository. Directions on how to use FireMarshal can be found in the
|
||||||
:fsim_doc:`FireSim documentation <Advanced-Usage/FireMarshal/index.html>`.
|
:fsim_doc:`FireSim documentation <Advanced-Usage/Workloads/FireMarshal.html>`.
|
||||||
Using FireMarshal, you can add custom kernel configurations and userspace software
|
Using FireMarshal, you can add custom kernel configurations and userspace software
|
||||||
to your workload.
|
to your workload.
|
||||||
|
|||||||
@@ -99,10 +99,16 @@ Instantiating the BlackBox and Defining MMIO
|
|||||||
|
|
||||||
Next, we must instantiate the blackbox. In order to take advantage of
|
Next, we must instantiate the blackbox. In order to take advantage of
|
||||||
diplomatic memory mapping on the system bus, we still have to
|
diplomatic memory mapping on the system bus, we still have to
|
||||||
integrate the peripheral at the Chisel level by mixing
|
integrate the peripheral at the Chisel level by instantiating a LazyModule wrapper
|
||||||
peripheral-specific traits into a ``TLRegisterRouter``. The ``params``
|
that instantiates a TileLink RegisterNode.
|
||||||
member and ``HasRegMap`` base trait should look familiar from the
|
|
||||||
previous memory-mapped GCD device example.
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD router
|
||||||
|
:end-before: DOC include end: GCD router
|
||||||
|
|
||||||
|
Within the LazyModule, the ``regmap`` function can be called to attach wires and
|
||||||
|
registers to the MMIO port.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
|
|||||||
@@ -3,14 +3,15 @@
|
|||||||
MMIO Peripherals
|
MMIO Peripherals
|
||||||
==================
|
==================
|
||||||
|
|
||||||
The easiest way to create a MMIO peripheral is to use the ``TLRegisterRouter`` or ``AXI4RegisterRouter`` widgets, which abstracts away the details of handling the interconnect protocols and provides a convenient interface for specifying memory-mapped registers. Since Chipyard and Rocket Chip SoCs primarily use Tilelink as the on-chip interconnect protocol, this section will primarily focus on designing Tilelink-based peripherals. However, see ``generators/chipyard/src/main/scala/example/GCD.scala`` for how an example AXI4 based peripheral is defined and connected to the Tilelink graph through converters.
|
The easiest way to create a MMIO peripheral is to follow the GCD TileLink MMIO example. Since Chipyard and Rocket Chip SoCs primarily use Tilelink as the on-chip interconnect protocol, this section will primarily focus on designing Tilelink-based peripherals. However, see ``generators/chipyard/src/main/scala/example/GCD.scala`` for how an example AXI4 based peripheral is defined and connected to the Tilelink graph through converters.
|
||||||
|
|
||||||
To create a RegisterRouter-based peripheral, you will need to specify a parameter case class for the configuration settings, a bundle trait with the extra top-level ports, and a module implementation containing the actual RTL.
|
To create a MMIO-mapped peripheral, you will need to specify a ``LazyModule`` wrapper containing the TileLink port as a Diplomacy Node, as well as an internal ``LazyModuleImp`` class that defines the MMIO's implementation and any non-TileLink I/O.
|
||||||
|
|
||||||
For this example, we will show how to connect a MMIO peripheral which computes the GCD.
|
For this example, we will show how to connect a MMIO peripheral which computes the GCD.
|
||||||
The full code can be found in ``generators/chipyard/src/main/scala/example/GCD.scala``.
|
The full code can be found in ``generators/chipyard/src/main/scala/example/GCD.scala``.
|
||||||
|
|
||||||
In this case we use a submodule ``GCDMMIOChiselModule`` to actually perform the GCD. The ``GCDModule`` class only creates the registers and hooks them up using ``regmap``.
|
In this case we use a submodule ``GCDMMIOChiselModule`` to actually perform the GCD. The ``GCDTL`` and ``GCDAXI4`` classes are the ``LazyModule`` classes which construct the TileLink or AXI4 ports, wrapping the inner ``GCDMMIOChiselModule``.
|
||||||
|
The ``node`` object is a Diplomacy node, which connects the peripheral to the Diplomacy interconnect graph.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
@@ -19,8 +20,9 @@ In this case we use a submodule ``GCDMMIOChiselModule`` to actually perform the
|
|||||||
|
|
||||||
.. 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 instance regmap
|
:start-after: DOC include start: GCD router
|
||||||
:end-before: DOC include end: GCD instance regmap
|
:end-before: DOC include end: GCD router
|
||||||
|
|
||||||
|
|
||||||
Advanced Features of RegField Entries
|
Advanced Features of RegField Entries
|
||||||
-------------------------------------
|
-------------------------------------
|
||||||
@@ -41,15 +43,31 @@ triggering the GCD algorithm when ``y`` is written. Therefore, the
|
|||||||
algorithm is set up by first writing ``x`` and then performing a
|
algorithm is set up by first writing ``x`` and then performing a
|
||||||
triggering write to ``y``. Polling can be used for status checks.
|
triggering write to ``y``. Polling can be used for status checks.
|
||||||
|
|
||||||
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
||||||
|
:language: scala
|
||||||
|
:start-after: DOC include start: GCD instance regmap
|
||||||
|
:end-before: DOC include end: GCD instance regmap
|
||||||
|
|
||||||
|
.. note::
|
||||||
|
In older versions of Chipyard and Rocket-Chip, a ``TLRegisterRouter`` abstrat
|
||||||
|
class was used to abstract away the construction of the ``TLRegisterNode`` and
|
||||||
|
``LazyModule`` classes necessary to construct MMIO peripherals. This was removed,
|
||||||
|
in favor of requiring users to explicitly construct the necessary classes.
|
||||||
|
|
||||||
|
This matches more closely how standard ``Modules`` and ``LazyModules`` are
|
||||||
|
constructed, making it clearer how a MMIO peripheral fits into the ``Module``
|
||||||
|
and ``LazyModule`` design patterns.
|
||||||
|
|
||||||
|
|
||||||
Connecting by TileLink
|
Connecting by TileLink
|
||||||
----------------------
|
----------------------
|
||||||
|
|
||||||
Once you have these classes, you can construct the final peripheral by extending the ``TLRegisterRouter`` and passing the proper arguments.
|
The key to connecting to the TileLink Diplomatic graph is the construction of the TileLink node for this peripheral.
|
||||||
The first set of arguments determines where the register router will be placed in the global address map and what information will be put in its device tree entry.
|
In this case, since the peripheral acts as a manager of some register-mapped address space, it uses the ``TLRegisterNode`` object.
|
||||||
The second set of arguments is the IO bundle constructor, which we create by extending ``TLRegBundle`` with our bundle trait.
|
The parameters to the ``TLRegisterNode`` object specify the size of the managed space, the base address, and the port width.
|
||||||
The final set of arguments is the module constructor, which we create by extends ``TLRegModule`` with our module trait.
|
|
||||||
Notice how we can create an analogous AXI4 version of our peripheral.
|
Within the register-mapped peripheral, the control registers can be mapped using the ``node.regmap`` function, as described above.
|
||||||
|
A similar procedure is followed for both AXI4 and TileLin peripherals.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/GCD.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
@@ -62,24 +80,18 @@ Top-level Traits
|
|||||||
----------------
|
----------------
|
||||||
|
|
||||||
After creating the module, we need to hook it up to our SoC.
|
After creating the module, we need to hook it up to our SoC.
|
||||||
Rocket Chip accomplishes this using the cake pattern.
|
The ``LazyModule`` abstract class containst the TileLink node representing the peripheral's I/O.
|
||||||
This basically involves placing code inside traits.
|
For a simple memory-mapped peripheral, connecting the peripheral's TileLink node must be connected to the relevant bu.
|
||||||
In the Rocket Chip cake, there are two kinds of traits: a ``LazyModule`` trait and a module implementation trait.
|
|
||||||
|
|
||||||
The ``LazyModule`` trait runs setup code that must execute before all the hardware gets elaborated.
|
|
||||||
For a simple memory-mapped peripheral, this just involves connecting the peripheral's TileLink node to the MMIO crossbar.
|
|
||||||
|
|
||||||
.. 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 lazy trait
|
:end-before: DOC include end: GCD lazy trait
|
||||||
|
|
||||||
Note that the ``GCDTL`` class we created from the register router is itself a ``LazyModule``.
|
|
||||||
Register routers have a TileLink node simply named "node", which we can hook up to the Rocket Chip bus.
|
|
||||||
This will automatically add address map and device tree entries for the peripheral.
|
|
||||||
Also observe how we have to place additional AXI4 buffers and converters for the AXI4 version of this peripheral.
|
Also observe how we have to place additional AXI4 buffers and converters for the AXI4 version of this peripheral.
|
||||||
|
|
||||||
Peripherals which expose I/O can use `InModuleBody` to punch their I/O to the `DigitalTop` module.
|
Peripherals which expose I/O can use `InModuleBody` to punch their I/O to the `DigitalTop` module.
|
||||||
|
In this example, the GCD module's ``gcd_busy`` signal is exposed as a I/O of DigitalTop.
|
||||||
|
|
||||||
Constructing the DigitalTop and Config
|
Constructing the DigitalTop and Config
|
||||||
--------------------------------------
|
--------------------------------------
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ The Hwacha project is developing a new vector architecture for future computer s
|
|||||||
The Hwacha project is inspired by traditional vector machines from the 70s and 80s, and lessons learned from our previous vector-thread architectures such as Scale and Maven
|
The Hwacha project is inspired by traditional vector machines from the 70s and 80s, and lessons learned from our previous vector-thread architectures such as Scale and Maven
|
||||||
The Hwacha project includes the Hwacha microarchitecture generator, as well as the ``XHwacha`` non-standard RISC-V extension. Hwacha does not implement the RISC-V standard vector extension proposal.
|
The Hwacha project includes the Hwacha microarchitecture generator, as well as the ``XHwacha`` non-standard RISC-V extension. Hwacha does not implement the RISC-V standard vector extension proposal.
|
||||||
|
|
||||||
For more information on the Hwacha project, please visit the `Hwacha website <http://hwacha.org/>`__.
|
For more information on the Hwacha project, please visit the `Hwacha website <https://bar.eecs.berkeley.edu/projects/hwacha.html>`__ or search for "Krste Asanovic Hwacha" on Google Scholar for publications.
|
||||||
|
|
||||||
To add the Hwacha vector unit to an SoC, you should add the ``hwacha.DefaultHwachaConfig`` config fragment to the SoC configurations. The Hwacha vector unit uses the RoCC port of a Rocket or BOOM `tile`, and by default connects to the memory system through the `System Bus` (i.e., directly to the L2 cache).
|
To add the Hwacha vector unit to an SoC, you should add the ``hwacha.DefaultHwachaConfig`` config fragment to the SoC configurations. The Hwacha vector unit uses the RoCC port of a Rocket or BOOM `tile`, and by default connects to the memory system through the `System Bus` (i.e., directly to the L2 cache).
|
||||||
|
|
||||||
|
|||||||
@@ -47,20 +47,6 @@ After the harness is created, the ``BundleBridgeSource``'s must be connected to
|
|||||||
This is done with harness binders and io binders (see ``fpga/src/main/scala/vcu118/HarnessBinders.scala`` and ``fpga/src/main/scala/vcu118/IOBinders.scala``).
|
This is done with harness binders and io binders (see ``fpga/src/main/scala/vcu118/HarnessBinders.scala`` and ``fpga/src/main/scala/vcu118/IOBinders.scala``).
|
||||||
For more information on harness binders and io binders, refer to :ref:`Customization/IOBinders:IOBinders and HarnessBinders`.
|
For more information on harness binders and io binders, refer to :ref:`Customization/IOBinders:IOBinders and HarnessBinders`.
|
||||||
|
|
||||||
(Legacy) Introduction to the Legacy Bringup Design
|
|
||||||
--------------------------------------------------
|
|
||||||
|
|
||||||
.. warning::
|
|
||||||
The bringup VCU118 design described here is designed for old versions of Chipyard SoCs, pre-1.9.1.
|
|
||||||
The key difference is that these designs rely on a clock generated on-chip to synchronize the slow serialized-TileLink interface.
|
|
||||||
After Chipyard 1.9.1, the FPGA host is expected to pass the clock to the chip, instead of the other way around.
|
|
||||||
A new bringup solution will be developed for post-1.9.1 Chipyard designs.
|
|
||||||
|
|
||||||
An example of a more complicated design used for Chipyard test chips can be viewed in ``fpga/src/main/scala/vcu118/bringup/``.
|
|
||||||
This example extends the default test harness and creates new ``Overlays`` to connect to a DUT (connected to the FMC port).
|
|
||||||
Extensions include another UART (connected over FMC), I2C (connected over FMC), miscellaneous GPIOS (can be connected to anything), and a TSI Host Widget.
|
|
||||||
The TSI Host Widget is used to interact with the DUT from the prototype over a SerDes link (sometimes called the Low BandWidth InterFace - LBWIF) and provide access to a channel of the FPGA's DRAM.
|
|
||||||
|
|
||||||
.. Note:: Remember that since whenever a new test harness is created (or the config changes, or the config packages changes, or...), you need to modify the make invocation.
|
.. Note:: Remember that since whenever a new test harness is created (or the config changes, or the config packages changes, or...), you need to modify the make invocation.
|
||||||
For example, ``make SUB_PROJECT=vcu118 CONFIG=MyNewVCU118Config CONFIG_PACKAGE=this.is.my.scala.package bitstream``.
|
For example, ``make SUB_PROJECT=vcu118 CONFIG=MyNewVCU118Config CONFIG_PACKAGE=this.is.my.scala.package bitstream``.
|
||||||
See :ref:`Prototyping/General:Generating a Bitstream` for information on the various make variables.
|
See :ref:`Prototyping/General:Generating a Bitstream` for information on the various make variables.
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ to handle TileLink requests, it is usually much easier to use a register node.
|
|||||||
This type of node provides a ``regmap`` method that allows you to specify
|
This type of node provides a ``regmap`` method that allows you to specify
|
||||||
control/status registers and automatically generates the logic to handle the
|
control/status registers and automatically generates the logic to handle the
|
||||||
TileLink protocol. More information about how to use register nodes can be
|
TileLink protocol. More information about how to use register nodes can be
|
||||||
found in :ref:`TileLink-Diplomacy-Reference/Register-Router:Register Router`.
|
found in :ref:`TileLink-Diplomacy-Reference/Register-Node:Register Node`.
|
||||||
|
|
||||||
Identity Node
|
Identity Node
|
||||||
-------------
|
-------------
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
Register Router
|
Register Node
|
||||||
===============
|
===============
|
||||||
|
|
||||||
Memory-mapped devices generally follow a common pattern. They expose a set
|
Memory-mapped devices generally follow a common pattern. They expose a set
|
||||||
@@ -10,10 +10,7 @@ While designers can manually instantiate a manager node and write the logic
|
|||||||
for exposing registers themselves, it's much easier to use RocketChip's
|
for exposing registers themselves, it's much easier to use RocketChip's
|
||||||
``regmap`` interface, which can generate most of the glue logic.
|
``regmap`` interface, which can generate most of the glue logic.
|
||||||
|
|
||||||
For TileLink devices, you can use the ``regmap`` interface by extending
|
For TileLink devices, you can use the ``regmap`` interface of the ``TLRegisterNode``.
|
||||||
the ``TLRegisterRouter`` class, as shown in :ref:`mmio-accelerators`,
|
|
||||||
or you can create a regular LazyModule and instantiate a ``TLRegisterNode``.
|
|
||||||
This section will focus on the second method.
|
|
||||||
|
|
||||||
Basic Usage
|
Basic Usage
|
||||||
-----------
|
-----------
|
||||||
@@ -32,7 +29,7 @@ The default value is 4 bytes. The ``concurrency`` argument is the size of the
|
|||||||
internal queue for TileLink requests. By default, this value is 0, which means
|
internal queue for TileLink requests. By default, this value is 0, which means
|
||||||
there will be no queue. This value must be greater than 0 if you wish to
|
there will be no queue. This value must be greater than 0 if you wish to
|
||||||
decoupled requests and responses for register accesses. This is discussed
|
decoupled requests and responses for register accesses. This is discussed
|
||||||
in :ref:`TileLink-Diplomacy-Reference/Register-Router:Using Functions`.
|
in :ref:`TileLink-Diplomacy-Reference/Register-Node:Using Functions`.
|
||||||
|
|
||||||
The main way to interact with the node is to call the ``regmap`` method, which
|
The main way to interact with the node is to call the ``regmap`` method, which
|
||||||
takes a sequence of pairs. The first element of the pair is an offset from the
|
takes a sequence of pairs. The first element of the pair is an offset from the
|
||||||
@@ -123,12 +120,12 @@ output for write.
|
|||||||
In order to use this variant, you need to set ``concurrency`` to a value
|
In order to use this variant, you need to set ``concurrency`` to a value
|
||||||
larger than 0.
|
larger than 0.
|
||||||
|
|
||||||
Register Routers for Other Protocols
|
Register Nodes for Other Protocols
|
||||||
------------------------------------
|
------------------------------------
|
||||||
|
|
||||||
One useful feature of the register router interface is that you can easily
|
One useful feature of the register node interface is that you can easily
|
||||||
change the protocol being used. For instance, in the first example in
|
change the protocol being used. For instance, in the first example in
|
||||||
:ref:`TileLink-Diplomacy-Reference/Register-Router:Basic Usage`, you could simply change the ``TLRegisterNode`` to
|
:ref:`TileLink-Diplomacy-Reference/Register-Node:Basic Usage`, you could simply change the ``TLRegisterNode`` to
|
||||||
and ``AXI4RegisterNode``.
|
and ``AXI4RegisterNode``.
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/RegisterNodeExample.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/example/RegisterNodeExample.scala
|
||||||
@@ -28,5 +28,5 @@ A detailed specification of the TileLink 1.7 protocol can be found on the
|
|||||||
NodeTypes
|
NodeTypes
|
||||||
Diplomacy-Connectors
|
Diplomacy-Connectors
|
||||||
EdgeFunctions
|
EdgeFunctions
|
||||||
Register-Router
|
Register-Node
|
||||||
Widgets
|
Widgets
|
||||||
|
|||||||
@@ -44,20 +44,6 @@ ifeq ($(SUB_PROJECT),vcu118)
|
|||||||
FPGA_BRAND ?= xilinx
|
FPGA_BRAND ?= xilinx
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifeq ($(SUB_PROJECT),bringup)
|
|
||||||
SBT_PROJECT ?= fpga_platforms
|
|
||||||
MODEL ?= BringupVCU118FPGATestHarness
|
|
||||||
VLOG_MODEL ?= BringupVCU118FPGATestHarness
|
|
||||||
MODEL_PACKAGE ?= chipyard.fpga.vcu118.bringup
|
|
||||||
CONFIG ?= RocketBringupConfig
|
|
||||||
CONFIG_PACKAGE ?= chipyard.fpga.vcu118.bringup
|
|
||||||
GENERATOR_PACKAGE ?= chipyard
|
|
||||||
TB ?= none # unused
|
|
||||||
TOP ?= ChipTop
|
|
||||||
BOARD ?= vcu118
|
|
||||||
FPGA_BRAND ?= xilinx
|
|
||||||
endif
|
|
||||||
|
|
||||||
ifeq ($(SUB_PROJECT),nexysvideo)
|
ifeq ($(SUB_PROJECT),nexysvideo)
|
||||||
SBT_PROJECT ?= fpga_platforms
|
SBT_PROJECT ?= fpga_platforms
|
||||||
MODEL ?= NexysVideoHarness
|
MODEL ?= NexysVideoHarness
|
||||||
|
|||||||
@@ -1,28 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118.bringup
|
|
||||||
|
|
||||||
import scala.collection.mutable.{LinkedHashMap}
|
|
||||||
|
|
||||||
object BringupGPIOs {
|
|
||||||
// map of the pin name (akin to die pin name) to (fpga package pin, IOSTANDARD, add pullup resistor?)
|
|
||||||
val pinMapping = LinkedHashMap(
|
|
||||||
// these connect to LEDs and switches on the VCU118 (and use 1.2V)
|
|
||||||
"led0" -> ("AT32", "LVCMOS12", false), // 0
|
|
||||||
"led1" -> ("AV34", "LVCMOS12", false), // 1
|
|
||||||
"led2" -> ("AY30", "LVCMOS12", false), // 2
|
|
||||||
"led3" -> ("BB32", "LVCMOS12", false), // 3
|
|
||||||
"led4" -> ("BF32", "LVCMOS12", false), // 4
|
|
||||||
"led5" -> ("AU37", "LVCMOS12", false), // 5
|
|
||||||
"led6" -> ("AV36", "LVCMOS12", false), // 6
|
|
||||||
"led7" -> ("BA37", "LVCMOS12", false), // 7
|
|
||||||
"sw0" -> ("B17", "LVCMOS12", false), // 8
|
|
||||||
"sw1" -> ("G16", "LVCMOS12", false), // 9
|
|
||||||
"sw2" -> ("J16", "LVCMOS12", false), // 10
|
|
||||||
"sw3" -> ("D21", "LVCMOS12", false) // 11
|
|
||||||
)
|
|
||||||
|
|
||||||
// return list of names (ordered)
|
|
||||||
def names: Seq[String] = pinMapping.keys.toSeq
|
|
||||||
|
|
||||||
// return number of GPIOs
|
|
||||||
def width: Int = pinMapping.size
|
|
||||||
}
|
|
||||||
@@ -1,97 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118.bringup
|
|
||||||
|
|
||||||
import math.min
|
|
||||||
|
|
||||||
import org.chipsalliance.cde.config.{Config, Parameters}
|
|
||||||
import freechips.rocketchip.diplomacy.{DTSModel, DTSTimebase, RegionType, AddressSet, ResourceBinding, Resource, ResourceAddress}
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.subsystem.{MasterPortParams}
|
|
||||||
|
|
||||||
import sifive.blocks.devices.gpio.{PeripheryGPIOKey, GPIOParams}
|
|
||||||
import sifive.blocks.devices.i2c.{PeripheryI2CKey, I2CParams}
|
|
||||||
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
|
||||||
|
|
||||||
import sifive.fpgashells.shell.{DesignKey}
|
|
||||||
import sifive.fpgashells.shell.xilinx.{VCU118ShellPMOD, VCU118DDRSize}
|
|
||||||
|
|
||||||
import testchipip.tsi.{PeripheryTSIHostKey, TSIHostParams, TSIHostSerdesParams}
|
|
||||||
|
|
||||||
import chipyard.{BuildSystem}
|
|
||||||
|
|
||||||
import chipyard.fpga.vcu118.{WithVCU118Tweaks, WithFPGAFrequency, VCU118DDR2Size}
|
|
||||||
import chipyard.iobinders.{WithGPIOPunchthrough}
|
|
||||||
|
|
||||||
class WithBringupPeripherals extends Config((site, here, up) => {
|
|
||||||
case PeripheryUARTKey => up(PeripheryUARTKey, site) ++ List(UARTParams(address = BigInt(0x64003000L)))
|
|
||||||
case PeripheryI2CKey => List(I2CParams(address = BigInt(0x64005000L)))
|
|
||||||
case PeripheryGPIOKey => {
|
|
||||||
if (BringupGPIOs.width > 0) {
|
|
||||||
require(BringupGPIOs.width <= 64) // currently only support 64 GPIOs (change addrs to get more)
|
|
||||||
val gpioAddrs = Seq(BigInt(0x64002000), BigInt(0x64007000))
|
|
||||||
val maxGPIOSupport = 32 // max gpios supported by SiFive driver (split by 32)
|
|
||||||
List.tabulate(((BringupGPIOs.width - 1)/maxGPIOSupport) + 1)(n => {
|
|
||||||
GPIOParams(address = gpioAddrs(n), width = min(BringupGPIOs.width - maxGPIOSupport*n, maxGPIOSupport))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
List.empty[GPIOParams]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case TSIClockMaxFrequencyKey => 100
|
|
||||||
case PeripheryTSIHostKey => List(
|
|
||||||
TSIHostParams(
|
|
||||||
offchipSerialIfWidth = 4,
|
|
||||||
mmioBaseAddress = BigInt(0x64006000),
|
|
||||||
mmioSourceId = 1 << 13, // manager source
|
|
||||||
serdesParams = TSIHostSerdesParams(
|
|
||||||
clientPortParams = TLMasterPortParameters.v1(
|
|
||||||
clients = Seq(TLMasterParameters.v1(
|
|
||||||
name = "tl-tsi-host-serdes",
|
|
||||||
sourceId = IdRange(0, (1 << 13))))),
|
|
||||||
managerPortParams = TLSlavePortParameters.v1(
|
|
||||||
managers = Seq(TLSlaveParameters.v1(
|
|
||||||
address = Seq(AddressSet(0, BigInt("FFFFFFFF", 16))), // access everything on chip
|
|
||||||
regionType = RegionType.UNCACHED,
|
|
||||||
executable = true,
|
|
||||||
supportsGet = TransferSizes(1, 64),
|
|
||||||
supportsPutFull = TransferSizes(1, 64),
|
|
||||||
supportsPutPartial = TransferSizes(1, 64),
|
|
||||||
supportsAcquireT = TransferSizes(1, 64),
|
|
||||||
supportsAcquireB = TransferSizes(1, 64),
|
|
||||||
supportsArithmetic = TransferSizes(1, 64),
|
|
||||||
supportsLogical = TransferSizes(1, 64))),
|
|
||||||
endSinkId = 1 << 6, // manager sink
|
|
||||||
beatBytes = 8)),
|
|
||||||
targetMasterPortParams = MasterPortParams(
|
|
||||||
base = BigInt("80000000", 16),
|
|
||||||
size = site(VCU118DDR2Size),
|
|
||||||
beatBytes = 8, // comes from test chip
|
|
||||||
idBits = 4) // comes from VCU118 idBits in XilinxVCU118MIG
|
|
||||||
))
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithBringupVCU118System extends Config((site, here, up) => {
|
|
||||||
case BuildSystem => (p: Parameters) => new BringupVCU118DigitalTop()(p) // use the VCU118-extended bringup digital top
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithBringupAdditions extends Config(
|
|
||||||
new WithBringupUART ++
|
|
||||||
new WithBringupI2C ++
|
|
||||||
new WithBringupGPIO ++
|
|
||||||
new WithBringupTSIHost ++
|
|
||||||
new WithTSITLIOPassthrough ++
|
|
||||||
new WithGPIOPunchthrough ++
|
|
||||||
new WithBringupPeripherals ++
|
|
||||||
new WithBringupVCU118System)
|
|
||||||
|
|
||||||
class RocketBringupConfig extends Config(
|
|
||||||
new WithBringupAdditions ++
|
|
||||||
new WithVCU118Tweaks ++
|
|
||||||
new chipyard.RocketConfig)
|
|
||||||
|
|
||||||
class BoomBringupConfig extends Config(
|
|
||||||
new WithFPGAFrequency(50) ++
|
|
||||||
new WithBringupAdditions ++
|
|
||||||
new WithVCU118Tweaks ++
|
|
||||||
new chipyard.MegaBoomConfig)
|
|
||||||
@@ -1,204 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118.bringup
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.experimental.{attach}
|
|
||||||
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import org.chipsalliance.cde.config.{Parameters, Field}
|
|
||||||
import freechips.rocketchip.tilelink.{TLInwardNode, TLAsyncCrossingSink}
|
|
||||||
|
|
||||||
import sifive.fpgashells.shell._
|
|
||||||
import sifive.fpgashells.ip.xilinx._
|
|
||||||
import sifive.fpgashells.shell.xilinx._
|
|
||||||
import sifive.fpgashells.clocks._
|
|
||||||
import sifive.fpgashells.devices.xilinx.xilinxvcu118mig.{XilinxVCU118MIGPads, XilinxVCU118MIGParams, XilinxVCU118MIG}
|
|
||||||
|
|
||||||
import testchipip.tsi.{TSIHostWidgetIO}
|
|
||||||
|
|
||||||
import chipyard.fpga.vcu118.{FMCPMap}
|
|
||||||
|
|
||||||
/* Connect the I2C to certain FMC pins */
|
|
||||||
class BringupI2CVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: I2CDesignInput, val shellInput: I2CShellInput)
|
|
||||||
extends I2CXilinxPlacedOverlay(name, designInput, shellInput)
|
|
||||||
{
|
|
||||||
shell { InModuleBody {
|
|
||||||
require(shellInput.index == 0) // only support 1 I2C <-> FMC connection
|
|
||||||
val i2cLocations = List(List(FMCPMap("K11"), FMCPMap("E2")))
|
|
||||||
val packagePinsWithPackageIOs = Seq((i2cLocations(shellInput.index)(0), IOPin(io.scl)),
|
|
||||||
(i2cLocations(shellInput.index)(1), IOPin(io.sda)))
|
|
||||||
|
|
||||||
packagePinsWithPackageIOs foreach { case (pin, io) => {
|
|
||||||
shell.xdc.addPackagePin(io, pin)
|
|
||||||
shell.xdc.addIOStandard(io, "LVCMOS18")
|
|
||||||
shell.xdc.addIOB(io)
|
|
||||||
} }
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
class BringupI2CVCU118ShellPlacer(val shell: VCU118ShellBasicOverlays, val shellInput: I2CShellInput)(implicit val valName: ValName)
|
|
||||||
extends I2CShellPlacer[VCU118ShellBasicOverlays]
|
|
||||||
{
|
|
||||||
def place(designInput: I2CDesignInput) = new BringupI2CVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect the UART to certain FMC pins */
|
|
||||||
class BringupUARTVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: UARTDesignInput, val shellInput: UARTShellInput)
|
|
||||||
extends UARTXilinxPlacedOverlay(name, designInput, shellInput, true)
|
|
||||||
{
|
|
||||||
shell { InModuleBody {
|
|
||||||
val packagePinsWithPackageIOs = Seq((FMCPMap("E9"), IOPin(io.ctsn.get)), // unused
|
|
||||||
(FMCPMap("E10"), IOPin(io.rtsn.get)), // unused
|
|
||||||
(FMCPMap("C15"), IOPin(io.rxd)),
|
|
||||||
(FMCPMap("C14"), IOPin(io.txd)))
|
|
||||||
|
|
||||||
packagePinsWithPackageIOs foreach { case (pin, io) => {
|
|
||||||
shell.xdc.addPackagePin(io, pin)
|
|
||||||
shell.xdc.addIOStandard(io, "LVCMOS18")
|
|
||||||
shell.xdc.addIOB(io)
|
|
||||||
} }
|
|
||||||
|
|
||||||
// add pullup on ctsn (ctsn is an input that is not used or driven)
|
|
||||||
packagePinsWithPackageIOs take 1 foreach { case (pin, io) => {
|
|
||||||
shell.xdc.addPullup(io)
|
|
||||||
} }
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
class BringupUARTVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: UARTShellInput)(implicit val valName: ValName)
|
|
||||||
extends UARTShellPlacer[VCU118ShellBasicOverlays] {
|
|
||||||
def place(designInput: UARTDesignInput) = new BringupUARTVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Connect GPIOs to FPGA I/Os */
|
|
||||||
abstract class GPIOXilinxPlacedOverlay(name: String, di: GPIODesignInput, si: GPIOShellInput)
|
|
||||||
extends GPIOPlacedOverlay(name, di, si)
|
|
||||||
{
|
|
||||||
def shell: XilinxShell
|
|
||||||
|
|
||||||
shell { InModuleBody {
|
|
||||||
(io.gpio zip tlgpioSink.bundle.pins).map { case (ioPin, sinkPin) =>
|
|
||||||
val iobuf = Module(new IOBUF)
|
|
||||||
iobuf.suggestName(s"gpio_iobuf")
|
|
||||||
attach(ioPin, iobuf.io.IO)
|
|
||||||
sinkPin.i.ival := iobuf.io.O
|
|
||||||
iobuf.io.T := !sinkPin.o.oe
|
|
||||||
iobuf.io.I := sinkPin.o.oval
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
class BringupGPIOVCU118PlacedOverlay(val shell: VCU118ShellBasicOverlays, name: String, val designInput: GPIODesignInput, val shellInput: GPIOShellInput, gpioNames: Seq[String])
|
|
||||||
extends GPIOXilinxPlacedOverlay(name, designInput, shellInput)
|
|
||||||
{
|
|
||||||
shell { InModuleBody {
|
|
||||||
require(gpioNames.length == io.gpio.length)
|
|
||||||
|
|
||||||
val packagePinsWithIOStdWithPackageIOs = (gpioNames zip io.gpio).map { case (name, io) =>
|
|
||||||
val (pin, iostd, pullupEnable) = BringupGPIOs.pinMapping(name)
|
|
||||||
(pin, iostd, pullupEnable, IOPin(io))
|
|
||||||
}
|
|
||||||
|
|
||||||
packagePinsWithIOStdWithPackageIOs foreach { case (pin, iostd, pullupEnable, io) => {
|
|
||||||
shell.xdc.addPackagePin(io, pin)
|
|
||||||
shell.xdc.addIOStandard(io, iostd)
|
|
||||||
if (iostd == "LVCMOS12") { shell.xdc.addDriveStrength(io, "8") }
|
|
||||||
if (pullupEnable) { shell.xdc.addPullup(io) }
|
|
||||||
} }
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
class BringupGPIOVCU118ShellPlacer(shell: VCU118ShellBasicOverlays, val shellInput: GPIOShellInput, gpioNames: Seq[String])(implicit val valName: ValName)
|
|
||||||
extends GPIOShellPlacer[VCU118ShellBasicOverlays] {
|
|
||||||
def place(designInput: GPIODesignInput) = new BringupGPIOVCU118PlacedOverlay(shell, valName.name, designInput, shellInput, gpioNames)
|
|
||||||
}
|
|
||||||
|
|
||||||
case class TSIHostShellInput()
|
|
||||||
case class TSIHostDesignInput(
|
|
||||||
serialIfWidth: Int,
|
|
||||||
node: BundleBridgeSource[TSIHostWidgetIO]
|
|
||||||
)(
|
|
||||||
implicit val p: Parameters)
|
|
||||||
case class TSIHostOverlayOutput()
|
|
||||||
trait TSIHostShellPlacer[Shell] extends ShellPlacer[TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]
|
|
||||||
|
|
||||||
case object TSIHostOverlayKey extends Field[Seq[DesignPlacer[TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]]](Nil)
|
|
||||||
|
|
||||||
abstract class TSIHostPlacedOverlay[IO <: Data](val name: String, val di: TSIHostDesignInput, val si: TSIHostShellInput)
|
|
||||||
extends IOPlacedOverlay[IO, TSIHostDesignInput, TSIHostShellInput, TSIHostOverlayOutput]
|
|
||||||
{
|
|
||||||
implicit val p = di.p
|
|
||||||
}
|
|
||||||
|
|
||||||
case object TSIHostVCU118DDRSize extends Field[BigInt](0x40000000L * 2) // 2GB
|
|
||||||
class TSIHostVCU118PlacedOverlay(val shell: BringupVCU118FPGATestHarness, name: String, val designInput: TSIHostDesignInput, val shellInput: TSIHostShellInput)
|
|
||||||
extends TSIHostPlacedOverlay[TSIHostWidgetIO](name, designInput, shellInput)
|
|
||||||
{
|
|
||||||
val tlTsiSerialSink = di.node.makeSink()
|
|
||||||
val tsiIoNode = BundleBridgeSource(() => new TSIHostWidgetIO(di.serialIfWidth))
|
|
||||||
val topTSIIONode = shell { tsiIoNode.makeSink() }
|
|
||||||
|
|
||||||
def overlayOutput = TSIHostOverlayOutput()
|
|
||||||
def ioFactory = new TSIHostWidgetIO(di.serialIfWidth)
|
|
||||||
|
|
||||||
InModuleBody {
|
|
||||||
// connect TSI serial
|
|
||||||
val tsiSourcePort = tsiIoNode.bundle
|
|
||||||
val tsiSinkPort = tlTsiSerialSink.bundle
|
|
||||||
tsiSinkPort.serial_clock := tsiSourcePort.serial_clock
|
|
||||||
tsiSourcePort.serial.out.bits := tsiSinkPort.serial.out.bits
|
|
||||||
tsiSourcePort.serial.out.valid := tsiSinkPort.serial.out.valid
|
|
||||||
tsiSinkPort.serial.out.ready := tsiSourcePort.serial.out.ready
|
|
||||||
tsiSinkPort.serial.in.bits := tsiSourcePort.serial.in.bits
|
|
||||||
tsiSinkPort.serial.in.valid := tsiSourcePort.serial.in.valid
|
|
||||||
tsiSourcePort.serial.in.ready := tsiSinkPort.serial.in.ready
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
case object TSIClockMaxFrequencyKey extends Field[Int](50) // in MHz
|
|
||||||
class BringupTSIHostVCU118PlacedOverlay(override val shell: BringupVCU118FPGATestHarness, override val name: String, override val designInput: TSIHostDesignInput, override val shellInput: TSIHostShellInput)
|
|
||||||
extends TSIHostVCU118PlacedOverlay(shell, name, designInput, shellInput)
|
|
||||||
{
|
|
||||||
// connect the TSI port
|
|
||||||
shell { InModuleBody {
|
|
||||||
// connect TSI signals
|
|
||||||
val tsiPort = topTSIIONode.bundle
|
|
||||||
io <> tsiPort
|
|
||||||
|
|
||||||
require(di.serialIfWidth == 4)
|
|
||||||
|
|
||||||
val clkIo = IOPin(io.serial_clock)
|
|
||||||
val packagePinsWithPackageIOs = Seq(
|
|
||||||
(FMCPMap("D8"), clkIo),
|
|
||||||
(FMCPMap("D17"), IOPin(io.serial.out.ready)),
|
|
||||||
(FMCPMap("D18"), IOPin(io.serial.out.valid)),
|
|
||||||
(FMCPMap("D11"), IOPin(io.serial.out.bits, 0)),
|
|
||||||
(FMCPMap("D12"), IOPin(io.serial.out.bits, 1)),
|
|
||||||
(FMCPMap("D14"), IOPin(io.serial.out.bits, 2)),
|
|
||||||
(FMCPMap("D15"), IOPin(io.serial.out.bits, 3)),
|
|
||||||
(FMCPMap("D26"), IOPin(io.serial.in.ready)),
|
|
||||||
(FMCPMap("D27"), IOPin(io.serial.in.valid)),
|
|
||||||
(FMCPMap("D20"), IOPin(io.serial.in.bits, 0)),
|
|
||||||
(FMCPMap("D21"), IOPin(io.serial.in.bits, 1)),
|
|
||||||
(FMCPMap("D23"), IOPin(io.serial.in.bits, 2)),
|
|
||||||
(FMCPMap("D24"), IOPin(io.serial.in.bits, 3)))
|
|
||||||
|
|
||||||
packagePinsWithPackageIOs foreach { case (pin, io) => {
|
|
||||||
shell.xdc.addPackagePin(io, pin)
|
|
||||||
shell.xdc.addIOStandard(io, "LVCMOS18")
|
|
||||||
} }
|
|
||||||
|
|
||||||
// Don't add an IOB to the clock
|
|
||||||
(packagePinsWithPackageIOs take 1) foreach { case (pin, io) => {
|
|
||||||
shell.xdc.addIOB(io)
|
|
||||||
} }
|
|
||||||
|
|
||||||
shell.sdc.addClock("TSI_CLK", clkIo, p(TSIClockMaxFrequencyKey))
|
|
||||||
shell.sdc.addGroup(pins = Seq(clkIo))
|
|
||||||
shell.xdc.clockDedicatedRouteFalse(clkIo)
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
|
|
||||||
class BringupTSIHostVCU118ShellPlacer(shell: BringupVCU118FPGATestHarness, val shellInput: TSIHostShellInput)(implicit val valName: ValName)
|
|
||||||
extends TSIHostShellPlacer[BringupVCU118FPGATestHarness] {
|
|
||||||
def place(designInput: TSIHostDesignInput) = new BringupTSIHostVCU118PlacedOverlay(shell, valName.name, designInput, shellInput)
|
|
||||||
}
|
|
||||||
@@ -1,26 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118.bringup
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
|
|
||||||
import freechips.rocketchip.subsystem._
|
|
||||||
import freechips.rocketchip.system._
|
|
||||||
import org.chipsalliance.cde.config.Parameters
|
|
||||||
import freechips.rocketchip.devices.tilelink._
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
|
|
||||||
import chipyard.{DigitalTop, DigitalTopModule}
|
|
||||||
|
|
||||||
// ------------------------------------
|
|
||||||
// Bringup VCU118 DigitalTop
|
|
||||||
// ------------------------------------
|
|
||||||
|
|
||||||
class BringupVCU118DigitalTop(implicit p: Parameters) extends DigitalTop
|
|
||||||
with sifive.blocks.devices.i2c.HasPeripheryI2C
|
|
||||||
with testchipip.tsi.HasPeripheryTSIHostWidget
|
|
||||||
{
|
|
||||||
override lazy val module = new BringupVCU118DigitalTopModule(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class BringupVCU118DigitalTopModule[+L <: BringupVCU118DigitalTop](l: L) extends DigitalTopModule(l)
|
|
||||||
with sifive.blocks.devices.i2c.HasPeripheryI2CModuleImp
|
|
||||||
@@ -1,51 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118.bringup
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.experimental.{Analog, IO, BaseModule}
|
|
||||||
|
|
||||||
import freechips.rocketchip.util.{HeterogeneousBag}
|
|
||||||
import freechips.rocketchip.tilelink.{TLBundle}
|
|
||||||
|
|
||||||
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp, UARTPortIO}
|
|
||||||
import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
|
|
||||||
import sifive.blocks.devices.i2c.{HasPeripheryI2CModuleImp, I2CPort}
|
|
||||||
import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp, GPIOPortIO}
|
|
||||||
|
|
||||||
import testchipip.tsi.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
|
||||||
|
|
||||||
import chipyard.harness._
|
|
||||||
import chipyard.iobinders._
|
|
||||||
|
|
||||||
/*** UART ***/
|
|
||||||
class WithBringupUART extends HarnessBinder({
|
|
||||||
case (th: BringupVCU118FPGATestHarnessImp, port: UARTPort, chipId: Int) => {
|
|
||||||
th.bringupOuter.io_fmc_uart_bb.bundle <> port.io
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/*** I2C ***/
|
|
||||||
class WithBringupI2C extends HarnessBinder({
|
|
||||||
case (th: BringupVCU118FPGATestHarnessImp, port: chipyard.iobinders.I2CPort, chipId: Int) => {
|
|
||||||
th.bringupOuter.io_i2c_bb.bundle <> port.io
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/*** GPIO ***/
|
|
||||||
class WithBringupGPIO extends HarnessBinder({
|
|
||||||
case (th: BringupVCU118FPGATestHarnessImp, port: GPIOPort, chipId: Int) => {
|
|
||||||
th.bringupOuter.io_gpio_bb(port.pinId).bundle <> port.io
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
/*** TSI Host Widget ***/
|
|
||||||
class WithBringupTSIHost extends HarnessBinder({
|
|
||||||
case (th: BringupVCU118FPGATestHarnessImp, port: TLMemPort, chipId: Int) => {
|
|
||||||
val tsiBundles = th.bringupOuter.tsiDdrClient.out.map(_._1)
|
|
||||||
val tsiDdrClientBundle = Wire(new HeterogeneousBag(tsiBundles.map(_.cloneType)))
|
|
||||||
tsiBundles.zip(tsiDdrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
|
||||||
tsiDdrClientBundle <> port.io
|
|
||||||
}
|
|
||||||
case (th: BringupVCU118FPGATestHarnessImp, port: TSIHostWidgetPort, chipId: Int) => {
|
|
||||||
th.bringupOuter.io_tsi_serial_bb.bundle <> port.io
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,30 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118.bringup
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.reflect.DataMirror
|
|
||||||
|
|
||||||
import freechips.rocketchip.util.{HeterogeneousBag}
|
|
||||||
import freechips.rocketchip.tilelink.{TLBundle}
|
|
||||||
|
|
||||||
import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp}
|
|
||||||
import sifive.blocks.devices.i2c.{HasPeripheryI2CModuleImp}
|
|
||||||
|
|
||||||
import testchipip.tsi.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
|
||||||
|
|
||||||
import chipyard.iobinders.{OverrideIOBinder, Port, TLMemPort}
|
|
||||||
|
|
||||||
case class TSIHostWidgetPort(val getIO: () => TSIHostWidgetIO)
|
|
||||||
extends Port[TSIHostWidgetIO]
|
|
||||||
|
|
||||||
class WithTSITLIOPassthrough extends OverrideIOBinder({
|
|
||||||
(system: HasPeripheryTSIHostWidget) => {
|
|
||||||
require(system.tsiTLMem.size == 1)
|
|
||||||
val io_tsi_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.tsiTLMem.head)).suggestName("tsi_tl_slave")
|
|
||||||
io_tsi_tl_mem_pins_temp <> system.tsiTLMem.head
|
|
||||||
|
|
||||||
require(system.tsiSerial.size == 1)
|
|
||||||
val io_tsi_serial_pins_temp = IO(DataMirror.internal.chiselTypeClone[TSIHostWidgetIO](system.tsiSerial.head)).suggestName("tsi_serial")
|
|
||||||
io_tsi_serial_pins_temp <> system.tsiSerial.head
|
|
||||||
(Seq(TLMemPort(() => io_tsi_tl_mem_pins_temp), TSIHostWidgetPort(() => io_tsi_serial_pins_temp)), Nil)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -1,99 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118.bringup
|
|
||||||
import chisel3._
|
|
||||||
|
|
||||||
import freechips.rocketchip.diplomacy._
|
|
||||||
import org.chipsalliance.cde.config._
|
|
||||||
import freechips.rocketchip.subsystem._
|
|
||||||
import freechips.rocketchip.tilelink._
|
|
||||||
import freechips.rocketchip.prci._
|
|
||||||
import sifive.fpgashells.shell.xilinx._
|
|
||||||
import sifive.fpgashells.ip.xilinx._
|
|
||||||
import sifive.fpgashells.shell._
|
|
||||||
import sifive.fpgashells.clocks._
|
|
||||||
|
|
||||||
import sifive.blocks.devices.uart._
|
|
||||||
import sifive.blocks.devices.spi._
|
|
||||||
import sifive.blocks.devices.i2c._
|
|
||||||
import sifive.blocks.devices.gpio._
|
|
||||||
|
|
||||||
import testchipip.tsi.{HasPeripheryTSIHostWidget, PeripheryTSIHostKey, TSIHostWidgetIO}
|
|
||||||
import testchipip.util.{TLSinkSetter}
|
|
||||||
|
|
||||||
import chipyard.fpga.vcu118.{VCU118FPGATestHarness, VCU118FPGATestHarnessImp, DDR2VCU118ShellPlacer, SysClock2VCU118ShellPlacer}
|
|
||||||
|
|
||||||
import chipyard.{ChipTop}
|
|
||||||
import chipyard.harness._
|
|
||||||
|
|
||||||
class BringupVCU118FPGATestHarness(override implicit val p: Parameters) extends VCU118FPGATestHarness {
|
|
||||||
|
|
||||||
/*** UART ***/
|
|
||||||
|
|
||||||
require(dp(PeripheryUARTKey).size == 2)
|
|
||||||
|
|
||||||
// 2nd UART goes to the FMC UART
|
|
||||||
|
|
||||||
val uart_fmc = Overlay(UARTOverlayKey, new BringupUARTVCU118ShellPlacer(this, UARTShellInput()))
|
|
||||||
|
|
||||||
val io_fmc_uart_bb = BundleBridgeSource(() => (new UARTPortIO(dp(PeripheryUARTKey).last)))
|
|
||||||
dp(UARTOverlayKey).last.place(UARTDesignInput(io_fmc_uart_bb))
|
|
||||||
|
|
||||||
/*** I2C ***/
|
|
||||||
|
|
||||||
val i2c = Overlay(I2COverlayKey, new BringupI2CVCU118ShellPlacer(this, I2CShellInput()))
|
|
||||||
|
|
||||||
val io_i2c_bb = BundleBridgeSource(() => (new I2CPort))
|
|
||||||
dp(I2COverlayKey).head.place(I2CDesignInput(io_i2c_bb))
|
|
||||||
|
|
||||||
/*** GPIO ***/
|
|
||||||
|
|
||||||
val gpio = Seq.tabulate(dp(PeripheryGPIOKey).size)(i => {
|
|
||||||
val maxGPIOSupport = 32 // max gpio per gpio chip
|
|
||||||
val names = BringupGPIOs.names.slice(maxGPIOSupport*i, maxGPIOSupport*(i+1))
|
|
||||||
Overlay(GPIOOverlayKey, new BringupGPIOVCU118ShellPlacer(this, GPIOShellInput(), names))
|
|
||||||
})
|
|
||||||
|
|
||||||
val io_gpio_bb = dp(PeripheryGPIOKey).map { p => BundleBridgeSource(() => (new GPIOPortIO(p))) }
|
|
||||||
(dp(GPIOOverlayKey) zip dp(PeripheryGPIOKey)).zipWithIndex.map { case ((placer, params), i) =>
|
|
||||||
placer.place(GPIODesignInput(params, io_gpio_bb(i)))
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** TSI Host Widget ***/
|
|
||||||
require(dp(PeripheryTSIHostKey).size == 1)
|
|
||||||
|
|
||||||
// use the 2nd system clock for the 2nd DDR
|
|
||||||
val sysClk2Node = dp(ClockInputOverlayKey).last.place(ClockInputDesignInput()).overlayOutput.node
|
|
||||||
|
|
||||||
val ddr2PLL = dp(PLLFactoryKey)()
|
|
||||||
ddr2PLL := sysClk2Node
|
|
||||||
|
|
||||||
val ddr2Clock = ClockSinkNode(freqMHz = dp(FPGAFrequencyKey))
|
|
||||||
val ddr2Wrangler = LazyModule(new ResetWrangler)
|
|
||||||
val ddr2Group = ClockGroup()
|
|
||||||
ddr2Clock := ddr2Wrangler.node := ddr2Group := ddr2PLL
|
|
||||||
|
|
||||||
val tsi_host = Overlay(TSIHostOverlayKey, new BringupTSIHostVCU118ShellPlacer(this, TSIHostShellInput()))
|
|
||||||
|
|
||||||
val ddr2Node = dp(DDROverlayKey).last.place(DDRDesignInput(dp(PeripheryTSIHostKey).head.targetMasterPortParams.base, ddr2Wrangler.node, ddr2PLL)).overlayOutput.ddr
|
|
||||||
|
|
||||||
val io_tsi_serial_bb = BundleBridgeSource(() => (new TSIHostWidgetIO(dp(PeripheryTSIHostKey).head.offchipSerialIfWidth)))
|
|
||||||
dp(TSIHostOverlayKey).head.place(TSIHostDesignInput(dp(PeripheryTSIHostKey).head.offchipSerialIfWidth, io_tsi_serial_bb))
|
|
||||||
|
|
||||||
// connect 1 mem. channel to the FPGA DDR
|
|
||||||
val tsiDdrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
|
|
||||||
name = "chip_ddr",
|
|
||||||
sourceId = IdRange(0, 64)
|
|
||||||
)))))
|
|
||||||
(ddr2Node
|
|
||||||
:= TLFragmenter(8,64,holdFirstDeny=true)
|
|
||||||
:= TLCacheCork()
|
|
||||||
:= TLAtomicAutomata(passthrough=false)
|
|
||||||
:= TLSinkSetter(64)
|
|
||||||
:= tsiDdrClient)
|
|
||||||
|
|
||||||
// module implementation
|
|
||||||
override lazy val module = new BringupVCU118FPGATestHarnessImp(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
class BringupVCU118FPGATestHarnessImp(_outer: BringupVCU118FPGATestHarness) extends VCU118FPGATestHarnessImp(_outer) {
|
|
||||||
lazy val bringupOuter = _outer
|
|
||||||
}
|
|
||||||
@@ -11,24 +11,31 @@ import org.chipsalliance.cde.config.{Config}
|
|||||||
// --------------
|
// --------------
|
||||||
|
|
||||||
class AbstractConfig extends Config(
|
class AbstractConfig extends Config(
|
||||||
|
// ================================================
|
||||||
|
// Set up TestHarness
|
||||||
|
// ================================================
|
||||||
// The HarnessBinders control generation of hardware in the TestHarness
|
// The HarnessBinders control generation of hardware in the TestHarness
|
||||||
new chipyard.harness.WithUARTAdapter ++ // add UART adapter to display UART on stdout, if uart is present
|
new chipyard.harness.WithUARTAdapter ++ /** add UART adapter to display UART on stdout, if uart is present */
|
||||||
new chipyard.harness.WithBlackBoxSimMem ++ // add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled
|
new chipyard.harness.WithBlackBoxSimMem ++ /** add SimDRAM DRAM model for axi4 backing memory, if axi4 mem is enabled */
|
||||||
new chipyard.harness.WithSimTSIOverSerialTL ++ // add external serial-adapter and RAM
|
new chipyard.harness.WithSimTSIOverSerialTL ++ /** add external serial-adapter and RAM */
|
||||||
new chipyard.harness.WithSimJTAGDebug ++ // add SimJTAG if JTAG for debug exposed
|
new chipyard.harness.WithSimJTAGDebug ++ /** add SimJTAG if JTAG for debug exposed */
|
||||||
new chipyard.harness.WithSimDMI ++ // add SimJTAG if DMI exposed
|
new chipyard.harness.WithSimDMI ++ /** add SimJTAG if DMI exposed */
|
||||||
new chipyard.harness.WithGPIOTiedOff ++ // tie-off chiptop GPIOs, if GPIOs are present
|
new chipyard.harness.WithGPIOTiedOff ++ /** tie-off chiptop GPIOs, if GPIOs are present */
|
||||||
new chipyard.harness.WithSimSPIFlashModel ++ // add simulated SPI flash memory, if SPI is enabled
|
new chipyard.harness.WithSimSPIFlashModel ++ /** add simulated SPI flash memory, if SPI is enabled */
|
||||||
new chipyard.harness.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled
|
new chipyard.harness.WithSimAXIMMIO ++ /** add SimAXIMem for axi4 mmio port, if enabled */
|
||||||
new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, if present
|
new chipyard.harness.WithTieOffInterrupts ++ /** tie-off interrupt ports, if present */
|
||||||
new chipyard.harness.WithTieOffL2FBusAXI ++ // tie-off external AXI4 master, if present
|
new chipyard.harness.WithTieOffL2FBusAXI ++ /** tie-off external AXI4 master, if present */
|
||||||
new chipyard.harness.WithCustomBootPinPlusArg ++ // drive custom-boot pin with a plusarg, if custom-boot-pin is present
|
new chipyard.harness.WithCustomBootPinPlusArg ++ /** drive custom-boot pin with a plusarg, if custom-boot-pin is present */
|
||||||
new chipyard.harness.WithDriveChipIdPin ++ // drive chip id pin from harness binder, if chip id pin is present
|
new chipyard.harness.WithDriveChipIdPin ++ /** drive chip id pin from harness binder, if chip id pin is present */
|
||||||
new chipyard.harness.WithSimUARTToUARTTSI ++ // connect a SimUART to the UART-TSI port
|
new chipyard.harness.WithSimUARTToUARTTSI ++ /** connect a SimUART to the UART-TSI port */
|
||||||
new chipyard.harness.WithClockFromHarness ++ // all Clock I/O in ChipTop should be driven by harnessClockInstantiator
|
new chipyard.harness.WithClockFromHarness ++ /** all Clock I/O in ChipTop should be driven by harnessClockInstantiator */
|
||||||
new chipyard.harness.WithResetFromHarness ++ // reset controlled by harness
|
new chipyard.harness.WithResetFromHarness ++ /** reset controlled by harness */
|
||||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz
|
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ /** generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz */
|
||||||
|
|
||||||
|
|
||||||
|
// ================================================
|
||||||
|
// Set up I/O cells + punch I/Os in ChipTop
|
||||||
|
// ================================================
|
||||||
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
|
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
|
||||||
// IOCells are generated for "Chip-like" IOs
|
// IOCells are generated for "Chip-like" IOs
|
||||||
new chipyard.iobinders.WithSerialTLIOCells ++
|
new chipyard.iobinders.WithSerialTLIOCells ++
|
||||||
@@ -53,43 +60,98 @@ class AbstractConfig extends Config(
|
|||||||
new chipyard.iobinders.WithUARTTSIPunchthrough ++
|
new chipyard.iobinders.WithUARTTSIPunchthrough ++
|
||||||
new chipyard.iobinders.WithNMITiedOff ++
|
new chipyard.iobinders.WithNMITiedOff ++
|
||||||
|
|
||||||
new chipyard.clocking.WithClockTapIOCells ++ // Default generate a clock tapio
|
|
||||||
new chipyard.clocking.WithPassthroughClockGenerator ++ // Default punch out IOs to the Harness
|
|
||||||
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", // Default merge all the bus clocks
|
|
||||||
Seq("sbus", "mbus", "pbus", "fbus", "cbus", "obus", "implicit", "clock_tap"), Seq("tile"))) ++
|
|
||||||
new chipyard.config.WithPeripheryBusFrequency(500.0) ++ // Default 500 MHz pbus
|
|
||||||
new chipyard.config.WithControlBusFrequency(500.0) ++ // Default 500 MHz cbus
|
|
||||||
new chipyard.config.WithMemoryBusFrequency(500.0) ++ // Default 500 MHz mbus
|
|
||||||
new chipyard.config.WithControlBusFrequency(500.0) ++ // Default 500 MHz cbus
|
|
||||||
new chipyard.config.WithSystemBusFrequency(500.0) ++ // Default 500 MHz sbus
|
|
||||||
new chipyard.config.WithFrontBusFrequency(500.0) ++ // Default 500 MHz fbus
|
|
||||||
new chipyard.config.WithOffchipBusFrequency(500.0) ++ // Default 500 MHz obus
|
|
||||||
|
|
||||||
new testchipip.boot.WithCustomBootPin ++ // add a custom-boot-pin to support pin-driven boot address
|
// ================================================
|
||||||
new testchipip.boot.WithBootAddrReg ++ // add a boot-addr-reg for configurable boot address
|
// Set up External Memory and IO Devices
|
||||||
new testchipip.serdes.WithSerialTL(Seq( // add a serial-tilelink interface
|
// ================================================
|
||||||
|
// External memory section
|
||||||
|
new testchipip.serdes.WithSerialTL(Seq( /** add a serial-tilelink interface */
|
||||||
testchipip.serdes.SerialTLParams(
|
testchipip.serdes.SerialTLParams(
|
||||||
client = Some(testchipip.serdes.SerialTLClientParams()), // serial-tilelink interface will master the FBUS, and support 4 idBits
|
client = Some(testchipip.serdes.SerialTLClientParams(idBits=4)), /** serial-tilelink interface will master the FBUS, and support 4 idBits */
|
||||||
phyParams = testchipip.serdes.ExternalSyncSerialParams(width=32) // serial-tilelink interface with 32 lanes
|
phyParams = testchipip.serdes.ExternalSyncSerialParams(width=32) /** serial-tilelink interface with 32 lanes */
|
||||||
)
|
)
|
||||||
)) ++
|
)) ++
|
||||||
new testchipip.soc.WithMbusScratchpad(base = 0x08000000, // add 64 KiB on-chip scratchpad
|
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ /** Default 1 AXI-4 memory channels */
|
||||||
|
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ /** no top-level MMIO master port (overrides default set in rocketchip) */
|
||||||
|
new freechips.rocketchip.subsystem.WithNoSlavePort ++ /** no top-level MMIO slave port (overrides default set in rocketchip) */
|
||||||
|
|
||||||
|
// MMIO device section
|
||||||
|
new chipyard.config.WithUART ++ /** add a UART */
|
||||||
|
|
||||||
|
|
||||||
|
// ================================================
|
||||||
|
// Set up Debug/Bringup/Testing Features
|
||||||
|
// ================================================
|
||||||
|
// JTAG
|
||||||
|
new freechips.rocketchip.subsystem.WithDebugSBA ++ /** enable the SBA (system-bus-access) feature of the debug module */
|
||||||
|
new chipyard.config.WithDebugModuleAbstractDataWords(8) ++ /** increase debug module data word capacity */
|
||||||
|
new freechips.rocketchip.subsystem.WithJtagDTM ++ /** set the debug module to expose a JTAG port */
|
||||||
|
|
||||||
|
// Boot Select Pins
|
||||||
|
new testchipip.boot.WithCustomBootPin ++ /** add a custom-boot-pin to support pin-driven boot address */
|
||||||
|
new testchipip.boot.WithBootAddrReg ++ /** add a boot-addr-reg for configurable boot address */
|
||||||
|
|
||||||
|
|
||||||
|
// ================================================
|
||||||
|
// Set up Interrupts
|
||||||
|
// ================================================
|
||||||
|
// CLINT and PLIC related settings goes here
|
||||||
|
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ /** no external interrupts */
|
||||||
|
|
||||||
|
|
||||||
|
// ================================================
|
||||||
|
// Set up Tiles
|
||||||
|
// ================================================
|
||||||
|
// tile-local settings goes here
|
||||||
|
|
||||||
|
|
||||||
|
// ================================================
|
||||||
|
// Set up Memory system
|
||||||
|
// ================================================
|
||||||
|
// On-chip memory section
|
||||||
|
new freechips.rocketchip.subsystem.WithDTS("ucb-bar,chipyard", Nil) ++ /** custom device name for DTS (embedded in BootROM) */
|
||||||
|
new chipyard.config.WithBootROM ++ /** use default bootrom */
|
||||||
|
new testchipip.soc.WithMbusScratchpad(base = 0x08000000, /** add 64 KiB on-chip scratchpad */
|
||||||
size = 64 * 1024) ++
|
size = 64 * 1024) ++
|
||||||
new chipyard.config.WithDebugModuleAbstractDataWords(8) ++ // increase debug module data capacity
|
|
||||||
new chipyard.config.WithBootROM ++ // use default bootrom
|
// Coherency settings
|
||||||
new chipyard.config.WithUART ++ // add a UART
|
new freechips.rocketchip.subsystem.WithInclusiveCache ++ /** use Sifive LLC cache as root of coherence */
|
||||||
new chipyard.config.WithL2TLBs(1024) ++ // use L2 TLBs
|
|
||||||
new chipyard.config.WithNoSubsystemClockIO ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks
|
// Bus/interconnect settings
|
||||||
new chipyard.config.WithInheritBusFrequencyAssignments ++ // Unspecified clocks within a bus will receive the bus frequency if set
|
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ /** hierarchical buses including sbus/mbus/pbus/fbus/cbus/l2 */
|
||||||
new freechips.rocketchip.subsystem.WithNMemoryChannels(1) ++ // Default 1 memory channels
|
|
||||||
new freechips.rocketchip.subsystem.WithClockGateModel ++ // add default EICG_wrapper clock gate model
|
|
||||||
new freechips.rocketchip.subsystem.WithDebugSBA ++ // enable the SBA (system-bus-access) feature of the debug module
|
// ================================================
|
||||||
new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port
|
// Set up power, reset and clocking
|
||||||
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
|
// ================================================
|
||||||
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip)
|
|
||||||
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache
|
// ChipTop clock IO/PLL/Divider/Mux settings
|
||||||
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts
|
new chipyard.clocking.WithClockTapIOCells ++ /** Default generate a clock tapio */
|
||||||
new freechips.rocketchip.subsystem.WithDontDriveBusClocksFromSBus ++ // leave the bus clocks undriven by sbus
|
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||||
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including sbus/mbus/pbus/fbus/cbus/l2
|
|
||||||
new freechips.rocketchip.subsystem.WithDTS("ucb-bar,chipyard", Nil) ++ // custom device name for DTS
|
// DigitalTop-internal clocking settings
|
||||||
new freechips.rocketchip.system.BaseConfig) // "base" rocketchip system
|
new freechips.rocketchip.subsystem.WithDontDriveBusClocksFromSBus ++ /** leave the bus clocks undriven by sbus */
|
||||||
|
new freechips.rocketchip.subsystem.WithClockGateModel ++ /** add default EICG_wrapper clock gate model */
|
||||||
|
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", /** create a "uncore" clock group tieing all the bus clocks together */
|
||||||
|
Seq("sbus", "mbus", "pbus", "fbus", "cbus", "obus", "implicit", "clock_tap"),
|
||||||
|
Seq("tile"))) ++
|
||||||
|
|
||||||
|
new chipyard.config.WithPeripheryBusFrequency(500.0) ++ /** Default 500 MHz pbus */
|
||||||
|
new chipyard.config.WithMemoryBusFrequency(500.0) ++ /** Default 500 MHz mbus */
|
||||||
|
new chipyard.config.WithControlBusFrequency(500.0) ++ /** Default 500 MHz cbus */
|
||||||
|
new chipyard.config.WithSystemBusFrequency(500.0) ++ /** Default 500 MHz sbus */
|
||||||
|
new chipyard.config.WithFrontBusFrequency(500.0) ++ /** Default 500 MHz fbus */
|
||||||
|
new chipyard.config.WithOffchipBusFrequency(500.0) ++ /** Default 500 MHz obus */
|
||||||
|
new chipyard.config.WithInheritBusFrequencyAssignments ++ /** Unspecified clocks within a bus will receive the bus frequency if set */
|
||||||
|
new chipyard.config.WithNoSubsystemClockIO ++ /** drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks */
|
||||||
|
|
||||||
|
// reset
|
||||||
|
|
||||||
|
// power
|
||||||
|
|
||||||
|
|
||||||
|
// ==================================
|
||||||
|
// Base Settings
|
||||||
|
// ==================================
|
||||||
|
new freechips.rocketchip.system.BaseConfig /** "base" rocketchip system */
|
||||||
|
)
|
||||||
|
|||||||
@@ -4,6 +4,7 @@ import chisel3._
|
|||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
import chisel3.experimental.{IntParam, BaseModule}
|
import chisel3.experimental.{IntParam, BaseModule}
|
||||||
import freechips.rocketchip.amba.axi4._
|
import freechips.rocketchip.amba.axi4._
|
||||||
|
import freechips.rocketchip.prci._
|
||||||
import freechips.rocketchip.subsystem.BaseSubsystem
|
import freechips.rocketchip.subsystem.BaseSubsystem
|
||||||
import org.chipsalliance.cde.config.{Parameters, Field, Config}
|
import org.chipsalliance.cde.config.{Parameters, Field, Config}
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
@@ -36,27 +37,24 @@ class GCDIO(val w: Int) extends Bundle {
|
|||||||
val busy = Output(Bool())
|
val busy = Output(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
trait GCDTopIO extends Bundle {
|
class GCDTopIO extends Bundle {
|
||||||
val gcd_busy = Output(Bool())
|
val gcd_busy = Output(Bool())
|
||||||
}
|
}
|
||||||
|
|
||||||
trait HasGCDIO extends BaseModule {
|
trait HasGCDTopIO {
|
||||||
val w: Int
|
def io: GCDTopIO
|
||||||
val io = IO(new GCDIO(w))
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// DOC include start: GCD blackbox
|
// DOC include start: GCD blackbox
|
||||||
class GCDMMIOBlackBox(val w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource
|
class GCDMMIOBlackBox(val w: Int) extends BlackBox(Map("WIDTH" -> IntParam(w))) with HasBlackBoxResource {
|
||||||
with HasGCDIO
|
val io = IO(new GCDIO(w))
|
||||||
{
|
|
||||||
addResource("/vsrc/GCDMMIOBlackBox.v")
|
addResource("/vsrc/GCDMMIOBlackBox.v")
|
||||||
}
|
}
|
||||||
// DOC include end: GCD blackbox
|
// DOC include end: GCD blackbox
|
||||||
|
|
||||||
// DOC include start: GCD chisel
|
// DOC include start: GCD chisel
|
||||||
class GCDMMIOChiselModule(val w: Int) extends Module
|
class GCDMMIOChiselModule(val w: Int) extends Module {
|
||||||
with HasGCDIO
|
val io = IO(new GCDIO(w))
|
||||||
{
|
|
||||||
val s_idle :: s_run :: s_done :: Nil = Enum(3)
|
val s_idle :: s_run :: s_done :: Nil = Enum(3)
|
||||||
|
|
||||||
val state = RegInit(s_idle)
|
val state = RegInit(s_idle)
|
||||||
@@ -90,70 +88,106 @@ class GCDMMIOChiselModule(val w: Int) extends Module
|
|||||||
}
|
}
|
||||||
// DOC include end: GCD chisel
|
// DOC include end: GCD chisel
|
||||||
|
|
||||||
// DOC include start: GCD instance regmap
|
|
||||||
|
|
||||||
trait GCDModule extends HasRegMap {
|
|
||||||
val io: GCDTopIO
|
|
||||||
|
|
||||||
implicit val p: Parameters
|
|
||||||
def params: GCDParams
|
|
||||||
val clock: Clock
|
|
||||||
val reset: Reset
|
|
||||||
|
|
||||||
|
|
||||||
// How many clock cycles in a PWM cycle?
|
|
||||||
val x = Reg(UInt(params.width.W))
|
|
||||||
val y = Wire(new DecoupledIO(UInt(params.width.W)))
|
|
||||||
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
|
|
||||||
val status = Wire(UInt(2.W))
|
|
||||||
|
|
||||||
val impl = if (params.useBlackBox) {
|
|
||||||
Module(new GCDMMIOBlackBox(params.width))
|
|
||||||
} else {
|
|
||||||
Module(new GCDMMIOChiselModule(params.width))
|
|
||||||
}
|
|
||||||
|
|
||||||
impl.io.clock := clock
|
|
||||||
impl.io.reset := reset.asBool
|
|
||||||
|
|
||||||
impl.io.x := x
|
|
||||||
impl.io.y := y.bits
|
|
||||||
impl.io.input_valid := y.valid
|
|
||||||
y.ready := impl.io.input_ready
|
|
||||||
|
|
||||||
gcd.bits := impl.io.gcd
|
|
||||||
gcd.valid := impl.io.output_valid
|
|
||||||
impl.io.output_ready := gcd.ready
|
|
||||||
|
|
||||||
status := Cat(impl.io.input_ready, impl.io.output_valid)
|
|
||||||
io.gcd_busy := impl.io.busy
|
|
||||||
|
|
||||||
regmap(
|
|
||||||
0x00 -> Seq(
|
|
||||||
RegField.r(2, status)), // a read-only register capturing current status
|
|
||||||
0x04 -> Seq(
|
|
||||||
RegField.w(params.width, x)), // a plain, write-only register
|
|
||||||
0x08 -> Seq(
|
|
||||||
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
|
||||||
0x0C -> Seq(
|
|
||||||
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
|
||||||
}
|
|
||||||
// DOC include end: GCD instance regmap
|
|
||||||
|
|
||||||
// DOC include start: GCD router
|
// DOC include start: GCD router
|
||||||
class GCDTL(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
|
class GCDTL(params: GCDParams, beatBytes: Int)(implicit p: Parameters) extends ClockSinkDomain(ClockSinkParameters())(p) {
|
||||||
extends TLRegisterRouter(
|
val device = new SimpleDevice("gcd", Seq("ucbbar,gcd"))
|
||||||
params.address, "gcd", Seq("ucbbar,gcd"),
|
val node = TLRegisterNode(Seq(AddressSet(params.address, 4096-1)), device, "reg/control", beatBytes=beatBytes)
|
||||||
beatBytes = beatBytes)(
|
|
||||||
new TLRegBundle(params, _) with GCDTopIO)(
|
|
||||||
new TLRegModule(params, _, _) with GCDModule)
|
|
||||||
|
|
||||||
class GCDAXI4(params: GCDParams, beatBytes: Int)(implicit p: Parameters)
|
override lazy val module = new GCDImpl
|
||||||
extends AXI4RegisterRouter(
|
class GCDImpl extends Impl with HasGCDTopIO {
|
||||||
params.address,
|
val io = IO(new GCDTopIO)
|
||||||
beatBytes=beatBytes)(
|
withClockAndReset(clock, reset) {
|
||||||
new AXI4RegBundle(params, _) with GCDTopIO)(
|
// How many clock cycles in a PWM cycle?
|
||||||
new AXI4RegModule(params, _, _) with GCDModule)
|
val x = Reg(UInt(params.width.W))
|
||||||
|
val y = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||||
|
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||||
|
val status = Wire(UInt(2.W))
|
||||||
|
|
||||||
|
val impl_io = if (params.useBlackBox) {
|
||||||
|
val impl = Module(new GCDMMIOBlackBox(params.width))
|
||||||
|
impl.io
|
||||||
|
} else {
|
||||||
|
val impl = Module(new GCDMMIOChiselModule(params.width))
|
||||||
|
impl.io
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_io.clock := clock
|
||||||
|
impl_io.reset := reset.asBool
|
||||||
|
|
||||||
|
impl_io.x := x
|
||||||
|
impl_io.y := y.bits
|
||||||
|
impl_io.input_valid := y.valid
|
||||||
|
y.ready := impl_io.input_ready
|
||||||
|
|
||||||
|
gcd.bits := impl_io.gcd
|
||||||
|
gcd.valid := impl_io.output_valid
|
||||||
|
impl_io.output_ready := gcd.ready
|
||||||
|
|
||||||
|
status := Cat(impl_io.input_ready, impl_io.output_valid)
|
||||||
|
io.gcd_busy := impl_io.busy
|
||||||
|
|
||||||
|
// DOC include start: GCD instance regmap
|
||||||
|
node.regmap(
|
||||||
|
0x00 -> Seq(
|
||||||
|
RegField.r(2, status)), // a read-only register capturing current status
|
||||||
|
0x04 -> Seq(
|
||||||
|
RegField.w(params.width, x)), // a plain, write-only register
|
||||||
|
0x08 -> Seq(
|
||||||
|
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
||||||
|
0x0C -> Seq(
|
||||||
|
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
||||||
|
// DOC include end: GCD instance regmap
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class GCDAXI4(params: GCDParams, beatBytes: Int)(implicit p: Parameters) extends ClockSinkDomain(ClockSinkParameters())(p) {
|
||||||
|
val node = AXI4RegisterNode(AddressSet(params.address, 4096-1), beatBytes=beatBytes)
|
||||||
|
override lazy val module = new GCDImpl
|
||||||
|
class GCDImpl extends Impl with HasGCDTopIO {
|
||||||
|
val io = IO(new GCDTopIO)
|
||||||
|
withClockAndReset(clock, reset) {
|
||||||
|
// How many clock cycles in a PWM cycle?
|
||||||
|
val x = Reg(UInt(params.width.W))
|
||||||
|
val y = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||||
|
val gcd = Wire(new DecoupledIO(UInt(params.width.W)))
|
||||||
|
val status = Wire(UInt(2.W))
|
||||||
|
|
||||||
|
val impl_io = if (params.useBlackBox) {
|
||||||
|
val impl = Module(new GCDMMIOBlackBox(params.width))
|
||||||
|
impl.io
|
||||||
|
} else {
|
||||||
|
val impl = Module(new GCDMMIOChiselModule(params.width))
|
||||||
|
impl.io
|
||||||
|
}
|
||||||
|
|
||||||
|
impl_io.clock := clock
|
||||||
|
impl_io.reset := reset.asBool
|
||||||
|
|
||||||
|
impl_io.x := x
|
||||||
|
impl_io.y := y.bits
|
||||||
|
impl_io.input_valid := y.valid
|
||||||
|
y.ready := impl_io.input_ready
|
||||||
|
|
||||||
|
gcd.bits := impl_io.gcd
|
||||||
|
gcd.valid := impl_io.output_valid
|
||||||
|
impl_io.output_ready := gcd.ready
|
||||||
|
|
||||||
|
status := Cat(impl_io.input_ready, impl_io.output_valid)
|
||||||
|
io.gcd_busy := impl_io.busy
|
||||||
|
|
||||||
|
node.regmap(
|
||||||
|
0x00 -> Seq(
|
||||||
|
RegField.r(2, status)), // a read-only register capturing current status
|
||||||
|
0x04 -> Seq(
|
||||||
|
RegField.w(params.width, x)), // a plain, write-only register
|
||||||
|
0x08 -> Seq(
|
||||||
|
RegField.w(params.width, y)), // write-only, y.valid is set on write
|
||||||
|
0x0C -> Seq(
|
||||||
|
RegField.r(params.width, gcd))) // read-only, gcd.ready is set on read
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
// DOC include end: GCD router
|
// DOC include end: GCD router
|
||||||
|
|
||||||
// DOC include start: GCD lazy trait
|
// DOC include start: GCD lazy trait
|
||||||
@@ -164,7 +198,8 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
|
|||||||
val gcd_busy = p(GCDKey) match {
|
val gcd_busy = p(GCDKey) match {
|
||||||
case Some(params) => {
|
case Some(params) => {
|
||||||
val gcd = if (params.useAXI4) {
|
val gcd = if (params.useAXI4) {
|
||||||
val gcd = pbus { LazyModule(new GCDAXI4(params, pbus.beatBytes)(p)) }
|
val gcd = LazyModule(new GCDAXI4(params, pbus.beatBytes)(p))
|
||||||
|
gcd.clockNode := pbus.fixedClockNode
|
||||||
pbus.coupleTo(portName) {
|
pbus.coupleTo(portName) {
|
||||||
gcd.node :=
|
gcd.node :=
|
||||||
AXI4Buffer () :=
|
AXI4Buffer () :=
|
||||||
@@ -174,18 +209,14 @@ trait CanHavePeripheryGCD { this: BaseSubsystem =>
|
|||||||
}
|
}
|
||||||
gcd
|
gcd
|
||||||
} else {
|
} else {
|
||||||
val gcd = pbus { LazyModule(new GCDTL(params, pbus.beatBytes)(p)) }
|
val gcd = LazyModule(new GCDTL(params, pbus.beatBytes)(p))
|
||||||
|
gcd.clockNode := pbus.fixedClockNode
|
||||||
pbus.coupleTo(portName) { gcd.node := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
|
pbus.coupleTo(portName) { gcd.node := TLFragmenter(pbus.beatBytes, pbus.blockBytes) := _ }
|
||||||
gcd
|
gcd
|
||||||
}
|
}
|
||||||
val pbus_io = pbus { InModuleBody {
|
|
||||||
val busy = IO(Output(Bool()))
|
|
||||||
busy := gcd.module.io.gcd_busy
|
|
||||||
busy
|
|
||||||
}}
|
|
||||||
val gcd_busy = InModuleBody {
|
val gcd_busy = InModuleBody {
|
||||||
val busy = IO(Output(Bool())).suggestName("gcd_busy")
|
val busy = IO(Output(Bool())).suggestName("gcd_busy")
|
||||||
busy := pbus_io
|
busy := gcd.module.io.gcd_busy
|
||||||
busy
|
busy
|
||||||
}
|
}
|
||||||
Some(gcd_busy)
|
Some(gcd_busy)
|
||||||
|
|||||||
@@ -360,3 +360,10 @@ class FireSimLeanGemminiRocketMMIOOnlyConfig extends Config(
|
|||||||
new WithDefaultMemModel ++
|
new WithDefaultMemModel ++
|
||||||
new WithFireSimConfigTweaks ++
|
new WithFireSimConfigTweaks ++
|
||||||
new chipyard.LeanGemminiRocketConfig)
|
new chipyard.LeanGemminiRocketConfig)
|
||||||
|
|
||||||
|
class FireSimLargeBoomCospikeConfig extends Config(
|
||||||
|
new firesim.firesim.WithCospikeBridge ++
|
||||||
|
new WithDefaultFireSimBridges ++
|
||||||
|
new WithDefaultMemModel ++
|
||||||
|
new WithFireSimConfigTweaks++
|
||||||
|
new chipyard.LargeBoomConfig)
|
||||||
|
|||||||
Submodule generators/icenet updated: d6a471f218...ab30e23e8e
Submodule generators/rocket-chip updated: 749a3eae96...8026b6bc9a
Submodule generators/rocket-chip-blocks updated: 212c7b070b...3dddfe9f5b
Submodule generators/testchipip updated: edacb214f0...003c9c1e81
@@ -69,6 +69,8 @@ cd "$RDIR"
|
|||||||
# path to temporarily exclude during the recursive update
|
# path to temporarily exclude during the recursive update
|
||||||
for name in \
|
for name in \
|
||||||
toolchains/*-tools/* \
|
toolchains/*-tools/* \
|
||||||
|
generators/cva6 \
|
||||||
|
generators/nvdla \
|
||||||
toolchains/libgloss \
|
toolchains/libgloss \
|
||||||
generators/sha3 \
|
generators/sha3 \
|
||||||
generators/gemmini \
|
generators/gemmini \
|
||||||
@@ -101,6 +103,20 @@ cd "$RDIR"
|
|||||||
# Non-recursive clone to exclude riscv-linux
|
# Non-recursive clone to exclude riscv-linux
|
||||||
git submodule update --init generators/sha3
|
git submodule update --init generators/sha3
|
||||||
|
|
||||||
|
# Non-recursive clone to exclude cva6 submods
|
||||||
|
git submodule update --init generators/cva6
|
||||||
|
git -C generators/cva6 submodule update --init src/main/resources/cva6/vsrc/cva6
|
||||||
|
git -C generators/cva6/src/main/resources/cva6/vsrc/cva6 submodule update --init src/axi
|
||||||
|
git -C generators/cva6/src/main/resources/cva6/vsrc/cva6 submodule update --init src/axi_riscv_atomics
|
||||||
|
git -C generators/cva6/src/main/resources/cva6/vsrc/cva6 submodule update --init src/common_cells
|
||||||
|
git -C generators/cva6/src/main/resources/cva6/vsrc/cva6 submodule update --init src/fpga-support
|
||||||
|
git -C generators/cva6/src/main/resources/cva6/vsrc/cva6 submodule update --init src/riscv-dbg
|
||||||
|
git -C generators/cva6/src/main/resources/cva6/vsrc/cva6 submodule update --init src/register_interface
|
||||||
|
git -C generators/cva6/src/main/resources/cva6/vsrc/cva6 submodule update --init --recursive src/fpu
|
||||||
|
# Non-recursive clone to exclude nvdla submods
|
||||||
|
git submodule update --init generators/nvdla
|
||||||
|
git -C generators/nvdla submodule update --init src/main/resources/hw
|
||||||
|
|
||||||
# Non-recursive clone to exclude gemmini-software
|
# Non-recursive clone to exclude gemmini-software
|
||||||
git submodule update --init generators/gemmini
|
git submodule update --init generators/gemmini
|
||||||
git -C generators/gemmini/ submodule update --init --recursive software/gemmini-rocc-tests
|
git -C generators/gemmini/ submodule update --init --recursive software/gemmini-rocc-tests
|
||||||
|
|||||||
Submodule tools/rocket-dsp-utils updated: 194455223a...272cee3c83
@@ -26,6 +26,7 @@ HELP_PROJECT_VARIABLES = \
|
|||||||
HELP_SIMULATION_VARIABLES = \
|
HELP_SIMULATION_VARIABLES = \
|
||||||
" BINARY = riscv elf binary that the simulator will run when using the run-binary* targets" \
|
" BINARY = riscv elf binary that the simulator will run when using the run-binary* targets" \
|
||||||
" BINARIES = list of riscv elf binary that the simulator will run when using the run-binaries* targets" \
|
" BINARIES = list of riscv elf binary that the simulator will run when using the run-binaries* targets" \
|
||||||
|
" BINARIES_DIR = directory of riscv elf binaries that the simulator will run when using the run-binaries* targets" \
|
||||||
" LOADMEM = riscv elf binary that should be loaded directly into simulated DRAM. LOADMEM=1 will load the BINARY elf" \
|
" LOADMEM = riscv elf binary that should be loaded directly into simulated DRAM. LOADMEM=1 will load the BINARY elf" \
|
||||||
" LOADARCH = path to a architectural checkpoint directory that should end in .loadarch/, for restoring from a checkpoint" \
|
" LOADARCH = path to a architectural checkpoint directory that should end in .loadarch/, for restoring from a checkpoint" \
|
||||||
" VERBOSE_FLAGS = flags used when doing verbose simulation [$(VERBOSE_FLAGS)]" \
|
" VERBOSE_FLAGS = flags used when doing verbose simulation [$(VERBOSE_FLAGS)]" \
|
||||||
@@ -288,6 +289,10 @@ override get_out_name = $(shell basename $(dir $(1)))
|
|||||||
override LOADMEM = 1
|
override LOADMEM = 1
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifneq ($(BINARIES_DIR),)
|
||||||
|
override BINARIES = $(shell find -L $(BINARIES_DIR) -type f -print 2> /dev/null)
|
||||||
|
endif
|
||||||
|
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
# build output directory for compilation
|
# build output directory for compilation
|
||||||
#########################################################################################
|
#########################################################################################
|
||||||
|
|||||||
@@ -100,8 +100,8 @@ $(SMEMS_HAMMER): $(TOP_SMEMS_FILE)
|
|||||||
|
|
||||||
$(SRAM_GENERATOR_CONF): $(SMEMS_HAMMER)
|
$(SRAM_GENERATOR_CONF): $(SMEMS_HAMMER)
|
||||||
mkdir -p $(dir $@)
|
mkdir -p $(dir $@)
|
||||||
echo "vlsi.inputs.sram_parameters: '$(SMEMS_HAMMER)'" >> $@
|
echo "vlsi.inputs.sram_parameters: '$(SMEMS_HAMMER)'" > $@
|
||||||
echo "vlsi.inputs.sram_parameters_meta: [\"transclude\", \"json2list\"]">> $@
|
echo "vlsi.inputs.sram_parameters_meta: [\"transclude\", \"json2list\"]" >> $@
|
||||||
|
|
||||||
$(SRAM_CONF): $(SRAM_GENERATOR_CONF)
|
$(SRAM_CONF): $(SRAM_GENERATOR_CONF)
|
||||||
cd $(vlsi_dir) && $(HAMMER_EXEC) -e $(ENV_YML) $(foreach x,$(INPUT_CONFS) $(SRAM_GENERATOR_CONF), -p $(x)) --obj_dir $(build_dir) sram_generator
|
cd $(vlsi_dir) && $(HAMMER_EXEC) -e $(ENV_YML) $(foreach x,$(INPUT_CONFS) $(SRAM_GENERATOR_CONF), -p $(x)) --obj_dir $(build_dir) sram_generator
|
||||||
|
|||||||
Reference in New Issue
Block a user