Merge branch 'main' into bump-barstools
This commit is contained in:
7
.github/scripts/defaults.sh
vendored
7
.github/scripts/defaults.sh
vendored
@@ -34,7 +34,7 @@ grouping["group-accels"]="chipyard-mempress chipyard-sha3 chipyard-hwacha chipya
|
|||||||
grouping["group-constellation"]="chipyard-constellation"
|
grouping["group-constellation"]="chipyard-constellation"
|
||||||
grouping["group-tracegen"]="tracegen tracegen-boom"
|
grouping["group-tracegen"]="tracegen tracegen-boom"
|
||||||
grouping["group-other"]="icenet testchipip constellation rocketchip-amba rocketchip-tlsimple rocketchip-tlwidth rocketchip-tlxbar"
|
grouping["group-other"]="icenet testchipip constellation rocketchip-amba rocketchip-tlsimple rocketchip-tlwidth rocketchip-tlxbar"
|
||||||
grouping["group-fpga"]="arty vcu118 vc707 arty100t"
|
grouping["group-fpga"]="arty arty100t nexysvideo vc707 vcu118"
|
||||||
|
|
||||||
# key value store to get the build strings
|
# key value store to get the build strings
|
||||||
declare -A mapping
|
declare -A mapping
|
||||||
@@ -79,6 +79,7 @@ mapping["rocketchip-tlwidth"]="SUB_PROJECT=rocketchip CONFIG=TLWidthUnitTestConf
|
|||||||
mapping["rocketchip-tlxbar"]="SUB_PROJECT=rocketchip CONFIG=TLXbarUnitTestConfig"
|
mapping["rocketchip-tlxbar"]="SUB_PROJECT=rocketchip CONFIG=TLXbarUnitTestConfig"
|
||||||
|
|
||||||
mapping["arty"]="SUB_PROJECT=arty verilog"
|
mapping["arty"]="SUB_PROJECT=arty verilog"
|
||||||
mapping["vcu118"]="SUB_PROJECT=vcu118 verilog"
|
|
||||||
mapping["vc707"]="SUB_PROJECT=vc707 verilog"
|
|
||||||
mapping["arty100t"]="SUB_PROJECT=arty100t verilog"
|
mapping["arty100t"]="SUB_PROJECT=arty100t verilog"
|
||||||
|
mapping["nexysvideo"]="SUB_PROJECT=nexysvideo verilog"
|
||||||
|
mapping["vc707"]="SUB_PROJECT=vc707 verilog"
|
||||||
|
mapping["vcu118"]="SUB_PROJECT=vcu118 verilog"
|
||||||
|
|||||||
@@ -13,7 +13,7 @@ The ``IOBinder`` functions are responsible for instantiating IO cells and IOPort
|
|||||||
For example, the ``WithUARTIOCells`` IOBinder will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleImp``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generated IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices.
|
For example, the ``WithUARTIOCells`` IOBinder will, for any ``System`` that might have UART ports (``HasPeripheryUARTModuleImp``, generate ports within the ``ChipTop`` (``ports``) as well as IOCells with the appropriate type and direction (``cells2d``). This function returns a the list of generated ports, and the list of generated IOCells. The list of generated ports is passed to the ``HarnessBinders`` such that they can be connected to ``TestHarness`` devices.
|
||||||
|
|
||||||
|
|
||||||
.. literalinclude:: ../../generators/chipyard/src/main/scala/IOBinders.scala
|
.. literalinclude:: ../../generators/chipyard/src/main/scala/iobinders/IOBinders.scala
|
||||||
:language: scala
|
:language: scala
|
||||||
:start-after: DOC include start: WithUARTIOCells
|
:start-after: DOC include start: WithUARTIOCells
|
||||||
:end-before: DOC include end: WithUARTIOCells
|
:end-before: DOC include end: WithUARTIOCells
|
||||||
|
|||||||
@@ -2,18 +2,18 @@ Running a Design on Arty
|
|||||||
========================
|
========================
|
||||||
|
|
||||||
Arty100T Instructions
|
Arty100T Instructions
|
||||||
----------------------
|
---------------------
|
||||||
|
|
||||||
The default Xilinx Arty 100T harness uses a TSI-over-UART adapter to bringup the FPGA.
|
The default Digilent Arty A7-100T harness uses a TSI-over-UART adapter to bringup the FPGA.
|
||||||
A user can connect to the Arty 100T target using a special ``uart_tsi`` program that opens a UART TTY.
|
A user can connect to the Arty A7-100T target using a special ``uart_tsi`` program that opens a UART TTY.
|
||||||
The interface for the ``uart_tsi`` program provides unique functionality that is useful for bringing up test chips.
|
The interface for the ``uart_tsi`` program provides unique functionality that is useful for bringing up test chips.
|
||||||
|
|
||||||
To build the design, run:
|
To build the design (Vivado should be added to the ``PATH``), run:
|
||||||
|
|
||||||
.. code-block:: shell
|
.. code-block:: shell
|
||||||
|
|
||||||
cd fpga/
|
cd fpga/
|
||||||
make SUB_PROJECT=arty100t
|
make SUB_PROJECT=arty100t bitstream
|
||||||
|
|
||||||
To build the UART-based frontend server, run:
|
To build the UART-based frontend server, run:
|
||||||
|
|
||||||
@@ -58,7 +58,7 @@ Run a design at a higher baud rate than default (For example, if ``CONFIG=UART92
|
|||||||
Arty35T Legacy Instructions
|
Arty35T Legacy Instructions
|
||||||
---------------------------
|
---------------------------
|
||||||
|
|
||||||
The default Xilinx Arty 35T harness is setup to have JTAG available over the board's PMOD pins, and UART available over its FTDI serial USB adapter. The pin mappings for JTAG signals are identical to those described in the `SiFive Freedom E310 Arty 35T Getting Started Guide <https://static.dev.sifive.com/SiFive-E310-arty-gettingstarted-v1.0.6.pdf>`__.
|
The default Digilent Arty A7-35T harness is setup to have JTAG available over the board's PMOD pins, and UART available over its FTDI serial USB adapter. The pin mappings for JTAG signals are identical to those described in the `SiFive Freedom E310 Arty 35T Getting Started Guide <https://static.dev.sifive.com/SiFive-E310-arty-gettingstarted-v1.0.6.pdf>`__.
|
||||||
The JTAG interface allows a user to connect to the core via OpenOCD, run bare-metal applications, and debug these applications with gdb. UART allows a user to communicate with the core over a USB connection and serial console running on a PC.
|
The JTAG interface allows a user to connect to the core via OpenOCD, run bare-metal applications, and debug these applications with gdb. UART allows a user to communicate with the core over a USB connection and serial console running on a PC.
|
||||||
To extend this design, a user may create their own Chipyard configuration and add the ``WithArtyTweaks`` located in ``fpga/src/main/scala/arty/Configs.scala``.
|
To extend this design, a user may create their own Chipyard configuration and add the ``WithArtyTweaks`` located in ``fpga/src/main/scala/arty/Configs.scala``.
|
||||||
Adding this config. fragment will enable and connect the JTAG and UART interfaces to your Chipyard design.
|
Adding this config. fragment will enable and connect the JTAG and UART interfaces to your Chipyard design.
|
||||||
@@ -68,13 +68,13 @@ Adding this config. fragment will enable and connect the JTAG and UART interface
|
|||||||
:start-after: DOC include start: AbstractArty and Rocket
|
:start-after: DOC include start: AbstractArty and Rocket
|
||||||
:end-before: DOC include end: AbstractArty and Rocket
|
:end-before: DOC include end: AbstractArty and Rocket
|
||||||
|
|
||||||
Future peripherals to be supported include the Arty 35T SPI Flash EEPROM, and I2C/PWM/SPI over the Arty 35T GPIO pins. These peripherals are available as part of sifive-blocks.
|
Future peripherals to be supported include the Arty A7-35T SPI Flash EEPROM, and I2C/PWM/SPI over the Arty A7-35T GPIO pins. These peripherals are available as part of sifive-blocks.
|
||||||
|
|
||||||
Brief Implementation Description and Guidance for Adding/Changing Xilinx Collateral
|
Brief Implementation Description and Guidance for Adding/Changing Xilinx Collateral
|
||||||
-----------------------------------------------------------------------------------
|
-----------------------------------------------------------------------------------
|
||||||
|
|
||||||
Like the VCU118, the basis for the Arty 35T design is the creation of a special test harness that connects the external IO (which exist as Xilinx IP blackboxes) to the Chipyard design.
|
Like the VCU118, the basis for the Arty A7-35T design is the creation of a special test harness that connects the external IO (which exist as Xilinx IP blackboxes) to the Chipyard design.
|
||||||
This is done with the ``ArtyTestHarness`` in the basic default Arty 35T target. However, unlike the ``VCU118TestHarness``, the ``ArtyTestHarness`` uses no ``Overlays``, and instead directly connects chip top IO to the ports of the external IO blackboxes, using functions such as ``IOBUF`` provided by ``fpga-shells``.
|
This is done with the ``ArtyTestHarness`` in the basic default Arty A7-35T target. However, unlike the ``VCU118TestHarness``, the ``ArtyTestHarness`` uses no ``Overlays``, and instead directly connects chip top IO to the ports of the external IO blackboxes, using functions such as ``IOBUF`` provided by ``fpga-shells``.
|
||||||
Unlike the VCU118 and other more complicated test harnesses, the Arty 35T Vivado collateral is not generated by ``Overlays``, but rather are a static collection of ``create_ip`` and ``set_properties`` statements located in the files within ``fpga/fpga-shells/xilinx/arty/tcl`` and ``fpga/fpga-shells/xilinx/arty/constraints``.
|
Unlike the VCU118 and other more complicated test harnesses, the Arty A7-35T Vivado collateral is not generated by ``Overlays``, but rather are a static collection of ``create_ip`` and ``set_properties`` statements located in the files within ``fpga/fpga-shells/xilinx/arty/tcl`` and ``fpga/fpga-shells/xilinx/arty/constraints``.
|
||||||
If the user wishes to re-map FPGA package pins to different harness-level IO, this may be changed within ``fpga/fpga-shells/xilinx/arty/constraints/arty-master.xdc``. The addition of new Xilinx IP blocks may be done in ``fpga-shells/xilinx/arty/tcl/ip.tcl``, mapped to harness-level IOs in ``arty-master.xdc``, and wired through from the test harness to the chip top using ``HarnessBinders`` and ``IOBinders``.
|
If the user wishes to re-map FPGA package pins to different harness-level IO, this may be changed within ``fpga/fpga-shells/xilinx/arty/constraints/arty-master.xdc``. The addition of new Xilinx IP blocks may be done in ``fpga-shells/xilinx/arty/tcl/ip.tcl``, mapped to harness-level IOs in ``arty-master.xdc``, and wired through from the test harness to the chip top using ``HarnessBinders`` and ``IOBinders``.
|
||||||
Examples of a simple ``IOBinder`` and ``HarnessBinder`` for routing signals (in this case the debug and JTAG resets) from the core to the test harness are the ``WithResetPassthrough`` and ``WithArtyResetHarnessBinder``.
|
Examples of a simple ``IOBinder`` and ``HarnessBinder`` for routing signals (in this case the debug and JTAG resets) from the core to the test harness are the ``WithResetPassthrough`` and ``WithArtyResetHarnessBinder``.
|
||||||
|
|||||||
@@ -2,7 +2,7 @@ General Setup and Usage
|
|||||||
==============================
|
==============================
|
||||||
|
|
||||||
Sources
|
Sources
|
||||||
---------------------------
|
-------
|
||||||
|
|
||||||
All FPGA prototyping-related collateral and sources are located in the ``fpga`` top-level Chipyard directory.
|
All FPGA prototyping-related collateral and sources are located in the ``fpga`` top-level Chipyard directory.
|
||||||
This includes the ``fpga-shells`` submodule and the ``src`` directory that hold both Scala, TCL and other collateral.
|
This includes the ``fpga-shells`` submodule and the ``src`` directory that hold both Scala, TCL and other collateral.
|
||||||
|
|||||||
49
docs/Prototyping/NexysVideo.rst
Normal file
49
docs/Prototyping/NexysVideo.rst
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
Running a Design on Nexys Video
|
||||||
|
===============================
|
||||||
|
|
||||||
|
Nexys Video Instructions
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
The default Digilent Nexys Video harness uses a TSI-over-UART adapter to bringup the FPGA.
|
||||||
|
A user can connect to the Nexys Video target using a special ``uart_tsi`` program that opens a UART TTY.
|
||||||
|
The interface for the ``uart_tsi`` program provides unique functionality that is useful for bringing up test chips.
|
||||||
|
|
||||||
|
To build the design (Vivado should be added to the ``PATH``), run:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
cd fpga/
|
||||||
|
make SUB_PROJECT=nexysvideo bitstream
|
||||||
|
|
||||||
|
To build the UART-based frontend server, run:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
cd generators/testchipip/uart_tsi
|
||||||
|
make
|
||||||
|
|
||||||
|
After programming the bitstream, and connecting the Nexys Video's UART to a host PC via the USB cable, the ``uart_tsi`` program can be run to interact with the target.
|
||||||
|
|
||||||
|
Running a program:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
./uart_tsi +tty=/dev/ttyUSBX dhrystone.riscv
|
||||||
|
|
||||||
|
Probe an address on the target system:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
./uart_tsi +tty=/dev/ttyUSBX +init_read=0x10040 none
|
||||||
|
|
||||||
|
Write some address before running a program:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
./uart_tsi +tty=/dev/ttyUSBX +init_write=0x80000000:0xdeadbeef none
|
||||||
|
|
||||||
|
Self-check that binary loading proceeded correctly:
|
||||||
|
|
||||||
|
.. code-block:: shell
|
||||||
|
|
||||||
|
./uart_tsi +tty=/dev/ttyUSBX +selfcheck dhrystone.riscv
|
||||||
@@ -2,10 +2,10 @@ Prototyping Flow
|
|||||||
================
|
================
|
||||||
|
|
||||||
Chipyard supports FPGA prototyping for local FPGAs supported by `fpga-shells <https://github.com/sifive/fpga-shells>`__.
|
Chipyard supports FPGA prototyping for local FPGAs supported by `fpga-shells <https://github.com/sifive/fpga-shells>`__.
|
||||||
This includes popular FPGAs such as the Xilinx VCU118 and the Xilinx Arty 35T board.
|
This includes popular FPGAs such as the Xilinx VCU118 and the Digilent Arty A7-35T/A7-100T board.
|
||||||
|
|
||||||
.. Note:: While ``fpga-shells`` provides harnesses for other FPGA development boards such as the Xilinx VC707 and some MicroSemi PolarFire, only harnesses for the Xilinx VCU118 and Xilinx Arty 35T boards are currently supported in Chipyard.
|
.. Note:: While ``fpga-shells`` provides harnesses for other FPGA development boards such as the Xilinx VC707 and some MicroSemi PolarFire, only harnesses for the Xilinx VCU118 and Digilent Arty A7-35T/A7-100T boards are currently supported in Chipyard.
|
||||||
However, the VCU118 and Arty 35T examples demonstrate how a user may implement support for other harnesses provided by fpga-shells.
|
However, the VCU118 and Arty A7-35T/A7-100T examples demonstrate how a user may implement support for other harnesses provided by fpga-shells.
|
||||||
|
|
||||||
.. toctree::
|
.. toctree::
|
||||||
:maxdepth: 2
|
:maxdepth: 2
|
||||||
@@ -14,3 +14,4 @@ This includes popular FPGAs such as the Xilinx VCU118 and the Xilinx Arty 35T bo
|
|||||||
General
|
General
|
||||||
VCU118
|
VCU118
|
||||||
Arty
|
Arty
|
||||||
|
NexysVideo
|
||||||
|
|||||||
@@ -57,6 +57,21 @@ ifeq ($(SUB_PROJECT),bringup)
|
|||||||
BOARD ?= vcu118
|
BOARD ?= vcu118
|
||||||
FPGA_BRAND ?= xilinx
|
FPGA_BRAND ?= xilinx
|
||||||
endif
|
endif
|
||||||
|
|
||||||
|
ifeq ($(SUB_PROJECT),nexysvideo)
|
||||||
|
SBT_PROJECT ?= fpga_platforms
|
||||||
|
MODEL ?= NexysVideoHarness
|
||||||
|
VLOG_MODEL ?= NexysVideoHarness
|
||||||
|
MODEL_PACKAGE ?= chipyard.fpga.nexysvideo
|
||||||
|
CONFIG ?= RocketNexysVideoConfig
|
||||||
|
CONFIG_PACKAGE ?= chipyard.fpga.nexysvideo
|
||||||
|
GENERATOR_PACKAGE ?= chipyard
|
||||||
|
TB ?= none # unused
|
||||||
|
TOP ?= ChipTop
|
||||||
|
BOARD ?= nexys_video
|
||||||
|
FPGA_BRAND ?= xilinx
|
||||||
|
endif
|
||||||
|
|
||||||
ifeq ($(SUB_PROJECT),arty)
|
ifeq ($(SUB_PROJECT),arty)
|
||||||
# TODO: Fix with Arty
|
# TODO: Fix with Arty
|
||||||
SBT_PROJECT ?= fpga_platforms
|
SBT_PROJECT ?= fpga_platforms
|
||||||
|
|||||||
Submodule fpga/fpga-shells updated: 7d0b79f855...2ce3e6f3df
@@ -17,7 +17,8 @@ import chipyard.{BuildSystem}
|
|||||||
|
|
||||||
// DOC include start: AbstractArty and Rocket
|
// DOC include start: AbstractArty and Rocket
|
||||||
class WithArtyTweaks extends Config(
|
class WithArtyTweaks extends Config(
|
||||||
new WithArtyResetHarnessBinder ++
|
new WithArtyDebugResetHarnessBinder ++
|
||||||
|
new WithArtyJTAGResetHarnessBinder ++
|
||||||
new WithArtyJTAGHarnessBinder ++
|
new WithArtyJTAGHarnessBinder ++
|
||||||
new WithArtyUARTHarnessBinder ++
|
new WithArtyUARTHarnessBinder ++
|
||||||
new WithDebugResetPassthrough ++
|
new WithDebugResetPassthrough ++
|
||||||
|
|||||||
@@ -11,33 +11,29 @@ import sifive.blocks.devices.pinctrl.{BasePin}
|
|||||||
|
|
||||||
import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}
|
import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}
|
||||||
|
|
||||||
import chipyard.harness.{ComposeHarnessBinder, OverrideHarnessBinder}
|
import chipyard.harness.{HarnessBinder}
|
||||||
import chipyard.iobinders.JTAGChipIO
|
import chipyard.iobinders._
|
||||||
|
|
||||||
class WithArtyResetHarnessBinder extends ComposeHarnessBinder({
|
class WithArtyDebugResetHarnessBinder extends HarnessBinder({
|
||||||
(system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => {
|
case (th: ArtyFPGATestHarness, port: DebugResetPort) => {
|
||||||
val resetPorts = ports.collect { case b: Bool => b }
|
th.dut_ndreset := port.io // Debug module reset
|
||||||
require(resetPorts.size == 2)
|
|
||||||
withClockAndReset(th.clock_32MHz, th.ck_rst) {
|
|
||||||
// Debug module reset
|
|
||||||
th.dut_ndreset := resetPorts(0)
|
|
||||||
|
|
||||||
// JTAG reset
|
|
||||||
resetPorts(1) := PowerOnResetFPGAOnly(th.clock_32MHz)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({
|
class WithArtyJTAGResetHarnessBinder extends HarnessBinder({
|
||||||
(system: HasPeripheryDebug, th: ArtyFPGATestHarness, ports: Seq[Data]) => {
|
case (th: ArtyFPGATestHarness, port: JTAGResetPort) => {
|
||||||
ports.map {
|
port.io := PowerOnResetFPGAOnly(th.clock_32MHz) // JTAG module reset
|
||||||
case j: JTAGChipIO => {
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithArtyJTAGHarnessBinder extends HarnessBinder({
|
||||||
|
case (th: ArtyFPGATestHarness, port: JTAGPort) => {
|
||||||
val jtag_wire = Wire(new JTAGIO)
|
val jtag_wire = Wire(new JTAGIO)
|
||||||
jtag_wire.TDO.data := j.TDO
|
jtag_wire.TDO.data := port.io.TDO
|
||||||
jtag_wire.TDO.driven := true.B
|
jtag_wire.TDO.driven := true.B
|
||||||
j.TCK := jtag_wire.TCK
|
port.io.TCK := jtag_wire.TCK
|
||||||
j.TMS := jtag_wire.TMS
|
port.io.TMS := jtag_wire.TMS
|
||||||
j.TDI := jtag_wire.TDI
|
port.io.TDI := jtag_wire.TDI
|
||||||
|
|
||||||
val io_jtag = Wire(new JTAGPins(() => new BasePin(), false)).suggestName("jtag")
|
val io_jtag = Wire(new JTAGPins(() => new BasePin(), false)).suggestName("jtag")
|
||||||
|
|
||||||
@@ -63,16 +59,13 @@ class WithArtyJTAGHarnessBinder extends OverrideHarnessBinder({
|
|||||||
io_jtag.TMS.i.po.map(_ := DontCare)
|
io_jtag.TMS.i.po.map(_ := DontCare)
|
||||||
io_jtag.TDO.i.po.map(_ := DontCare)
|
io_jtag.TDO.i.po.map(_ := DontCare)
|
||||||
}
|
}
|
||||||
case b: Bool =>
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithArtyUARTHarnessBinder extends OverrideHarnessBinder({
|
class WithArtyUARTHarnessBinder extends HarnessBinder({
|
||||||
(system: HasPeripheryUARTModuleImp, th: ArtyFPGATestHarness, ports: Seq[UARTPortIO]) => {
|
case (th: ArtyFPGATestHarness, port: UARTPort) => {
|
||||||
withClockAndReset(th.clock_32MHz, th.ck_rst) {
|
withClockAndReset(th.clock_32MHz, th.ck_rst) {
|
||||||
IOBUF(th.uart_rxd_out, ports.head.txd)
|
IOBUF(th.uart_rxd_out, port.io.txd)
|
||||||
ports.head.rxd := IOBUF(th.uart_txd_in)
|
port.io.rxd := IOBUF(th.uart_txd_in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -5,7 +5,7 @@ import chisel3.experimental.{IO}
|
|||||||
|
|
||||||
import freechips.rocketchip.devices.debug.{HasPeripheryDebug}
|
import freechips.rocketchip.devices.debug.{HasPeripheryDebug}
|
||||||
|
|
||||||
import chipyard.iobinders.{ComposeIOBinder}
|
import chipyard.iobinders.{ComposeIOBinder, DebugResetPort, JTAGResetPort}
|
||||||
|
|
||||||
class WithDebugResetPassthrough extends ComposeIOBinder({
|
class WithDebugResetPassthrough extends ComposeIOBinder({
|
||||||
(system: HasPeripheryDebug) => {
|
(system: HasPeripheryDebug) => {
|
||||||
@@ -18,6 +18,6 @@ class WithDebugResetPassthrough extends ComposeIOBinder({
|
|||||||
val io_sjtag_reset: Bool = IO(Input(Bool())).suggestName("sjtag_reset")
|
val io_sjtag_reset: Bool = IO(Input(Bool())).suggestName("sjtag_reset")
|
||||||
sjtag.reset := io_sjtag_reset
|
sjtag.reset := io_sjtag_reset
|
||||||
|
|
||||||
(Seq(io_ndreset, io_sjtag_reset), Nil)
|
(Seq(DebugResetPort(io_ndreset), JTAGResetPort(io_sjtag_reset)), Nil)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -16,33 +16,28 @@ import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly}
|
|||||||
|
|
||||||
import chipyard._
|
import chipyard._
|
||||||
import chipyard.harness._
|
import chipyard.harness._
|
||||||
import chipyard.iobinders.JTAGChipIO
|
import chipyard.iobinders._
|
||||||
|
|
||||||
import testchipip._
|
import testchipip._
|
||||||
|
|
||||||
class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarnessBinder({
|
class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends HarnessBinder({
|
||||||
(system: CanHavePeripheryUARTTSI, th: HasHarnessInstantiators, ports: Seq[UARTTSIIO]) => {
|
case (th: HasHarnessInstantiators, port: UARTTSIPort) => {
|
||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
|
||||||
require(ports.size <= 1)
|
|
||||||
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
|
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
|
||||||
ports.map({ port =>
|
ath.io_uart_bb.bundle <> port.io.uart
|
||||||
ath.io_uart_bb.bundle <> port.uart
|
ath.other_leds(1) := port.io.dropped
|
||||||
ath.other_leds(1) := port.dropped
|
ath.other_leds(9) := port.io.tsi2tl_state(0)
|
||||||
ath.other_leds(9) := port.tsi2tl_state(0)
|
ath.other_leds(10) := port.io.tsi2tl_state(1)
|
||||||
ath.other_leds(10) := port.tsi2tl_state(1)
|
ath.other_leds(11) := port.io.tsi2tl_state(2)
|
||||||
ath.other_leds(11) := port.tsi2tl_state(2)
|
ath.other_leds(12) := port.io.tsi2tl_state(3)
|
||||||
ath.other_leds(12) := port.tsi2tl_state(3)
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithArty100TDDRTL extends OverrideHarnessBinder({
|
class WithArty100TDDRTL extends HarnessBinder({
|
||||||
(system: CanHaveMasterTLMemPort, th: HasHarnessInstantiators, ports: Seq[HeterogeneousBag[TLBundle]]) => {
|
case (th: HasHarnessInstantiators, port: TLMemPort) => {
|
||||||
require(ports.size == 1)
|
|
||||||
val artyTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
|
val artyTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[Arty100THarness]
|
||||||
val bundles = artyTh.ddrClient.out.map(_._1)
|
val bundles = artyTh.ddrClient.out.map(_._1)
|
||||||
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
||||||
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
||||||
ddrClientBundle <> ports.head
|
ddrClientBundle <> port.io
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
72
fpga/src/main/scala/nexysvideo/Configs.scala
Normal file
72
fpga/src/main/scala/nexysvideo/Configs.scala
Normal file
@@ -0,0 +1,72 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
package chipyard.fpga.nexysvideo
|
||||||
|
|
||||||
|
import org.chipsalliance.cde.config._
|
||||||
|
import freechips.rocketchip.subsystem._
|
||||||
|
import freechips.rocketchip.devices.debug._
|
||||||
|
import freechips.rocketchip.devices.tilelink._
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import freechips.rocketchip.system._
|
||||||
|
import freechips.rocketchip.tile._
|
||||||
|
|
||||||
|
import sifive.blocks.devices.uart._
|
||||||
|
import sifive.fpgashells.shell.{DesignKey}
|
||||||
|
|
||||||
|
import testchipip.{SerialTLKey}
|
||||||
|
|
||||||
|
import chipyard.{BuildSystem}
|
||||||
|
|
||||||
|
// don't use FPGAShell's DesignKey
|
||||||
|
class WithNoDesignKey extends Config((site, here, up) => {
|
||||||
|
case DesignKey => (p: Parameters) => new SimpleLazyModule()(p)
|
||||||
|
})
|
||||||
|
|
||||||
|
// DOC include start: WithNexysVideoTweaks and Rocket
|
||||||
|
class WithNexysVideoTweaks extends Config(
|
||||||
|
new WithNexysVideoUARTTSI ++
|
||||||
|
new WithNexysVideoDDRTL ++
|
||||||
|
new WithNoDesignKey ++
|
||||||
|
new testchipip.WithUARTTSIClient ++
|
||||||
|
new chipyard.harness.WithSerialTLTiedOff ++
|
||||||
|
new chipyard.harness.WithHarnessBinderClockFreqMHz(50) ++
|
||||||
|
new chipyard.config.WithMemoryBusFrequency(50.0) ++
|
||||||
|
new chipyard.config.WithFrontBusFrequency(50.0) ++
|
||||||
|
new chipyard.config.WithSystemBusFrequency(50.0) ++
|
||||||
|
new chipyard.config.WithPeripheryBusFrequency(50.0) ++
|
||||||
|
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
|
||||||
|
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||||
|
new chipyard.config.WithNoDebug ++ // no jtag
|
||||||
|
new chipyard.config.WithNoUART ++ // use UART for the UART-TSI thing instad
|
||||||
|
new chipyard.config.WithTLBackingMemory ++ // FPGA-shells converts the AXI to TL for us
|
||||||
|
new freechips.rocketchip.subsystem.WithExtMemSize(BigInt(512) << 20) ++ // 512mb on Nexys Video
|
||||||
|
new freechips.rocketchip.subsystem.WithoutTLMonitors)
|
||||||
|
|
||||||
|
class RocketNexysVideoConfig extends Config(
|
||||||
|
new WithNexysVideoTweaks ++
|
||||||
|
new chipyard.config.WithBroadcastManager ++ // no l2
|
||||||
|
new chipyard.RocketConfig)
|
||||||
|
// DOC include end: WithNexysVideoTweaks and Rocket
|
||||||
|
|
||||||
|
// DOC include start: WithTinyNexysVideoTweaks and Rocket
|
||||||
|
class WithTinyNexysVideoTweaks extends Config(
|
||||||
|
new WithNexysVideoUARTTSI ++
|
||||||
|
new WithNoDesignKey ++
|
||||||
|
new sifive.fpgashells.shell.xilinx.WithNoNexysVideoShellDDR ++ // no DDR
|
||||||
|
new testchipip.WithUARTTSIClient ++
|
||||||
|
new chipyard.harness.WithSerialTLTiedOff ++
|
||||||
|
new chipyard.harness.WithHarnessBinderClockFreqMHz(50) ++
|
||||||
|
new chipyard.config.WithMemoryBusFrequency(50.0) ++
|
||||||
|
new chipyard.config.WithFrontBusFrequency(50.0) ++
|
||||||
|
new chipyard.config.WithSystemBusFrequency(50.0) ++
|
||||||
|
new chipyard.config.WithPeripheryBusFrequency(50.0) ++
|
||||||
|
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++
|
||||||
|
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||||
|
new chipyard.config.WithNoDebug ++ // no jtag
|
||||||
|
new chipyard.config.WithNoUART ++ // use UART for the UART-TSI thing instad
|
||||||
|
new freechips.rocketchip.subsystem.WithoutTLMonitors)
|
||||||
|
|
||||||
|
class TinyRocketNexysVideoConfig extends Config(
|
||||||
|
new WithTinyNexysVideoTweaks ++
|
||||||
|
new chipyard.config.WithBroadcastManager ++ // no l2
|
||||||
|
new chipyard.TinyRocketConfig)
|
||||||
|
// DOC include end: WithTinyNexysVideoTweaks and Rocket
|
||||||
92
fpga/src/main/scala/nexysvideo/Harness.scala
Normal file
92
fpga/src/main/scala/nexysvideo/Harness.scala
Normal file
@@ -0,0 +1,92 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
package chipyard.fpga.nexysvideo
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
import chisel3.util._
|
||||||
|
import freechips.rocketchip.diplomacy._
|
||||||
|
import org.chipsalliance.cde.config.{Parameters}
|
||||||
|
import freechips.rocketchip.tilelink._
|
||||||
|
import freechips.rocketchip.subsystem.{SystemBusKey}
|
||||||
|
|
||||||
|
import sifive.fpgashells.shell.xilinx._
|
||||||
|
import sifive.fpgashells.shell._
|
||||||
|
import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler}
|
||||||
|
|
||||||
|
import sifive.blocks.devices.uart._
|
||||||
|
|
||||||
|
import chipyard._
|
||||||
|
import chipyard.harness._
|
||||||
|
import chipyard.iobinders.{HasIOBinders}
|
||||||
|
|
||||||
|
class NexysVideoHarness(override implicit val p: Parameters) extends NexysVideoShell {
|
||||||
|
def dp = designParameters
|
||||||
|
|
||||||
|
val clockOverlay = dp(ClockInputOverlayKey).map(_.place(ClockInputDesignInput())).head
|
||||||
|
val harnessSysPLL = dp(PLLFactoryKey)
|
||||||
|
val harnessSysPLLNode = harnessSysPLL()
|
||||||
|
val dutFreqMHz = (dp(SystemBusKey).dtsFrequency.get / (1000 * 1000)).toInt
|
||||||
|
val dutClock = ClockSinkNode(freqMHz = dutFreqMHz)
|
||||||
|
println(s"NexysVideo FPGA Base Clock Freq: ${dutFreqMHz} MHz")
|
||||||
|
val dutWrangler = LazyModule(new ResetWrangler())
|
||||||
|
val dutGroup = ClockGroup()
|
||||||
|
dutClock := dutWrangler.node := dutGroup := harnessSysPLLNode
|
||||||
|
|
||||||
|
harnessSysPLLNode := clockOverlay.overlayOutput.node
|
||||||
|
|
||||||
|
val io_uart_bb = BundleBridgeSource(() => new UARTPortIO(dp(PeripheryUARTKey).headOption.getOrElse(UARTParams(0))))
|
||||||
|
val uartOverlay = dp(UARTOverlayKey).head.place(UARTDesignInput(io_uart_bb))
|
||||||
|
|
||||||
|
// Optional DDR
|
||||||
|
val ddrOverlay = if (p(NexysVideoShellDDR)) Some(dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRNexysVideoPlacedOverlay]) else None
|
||||||
|
val ddrClient = if (p(NexysVideoShellDDR)) Some(TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1(
|
||||||
|
name = "chip_ddr",
|
||||||
|
sourceId = IdRange(0, 1 << dp(ExtTLMem).get.master.idBits)
|
||||||
|
)))))) else None
|
||||||
|
val ddrBlockDuringReset = if (p(NexysVideoShellDDR)) Some(LazyModule(new TLBlockDuringReset(4))) else None
|
||||||
|
if (p(NexysVideoShellDDR)) { ddrOverlay.get.overlayOutput.ddr := ddrBlockDuringReset.get.node := ddrClient.get }
|
||||||
|
|
||||||
|
val ledOverlays = dp(LEDOverlayKey).map(_.place(LEDDesignInput()))
|
||||||
|
val all_leds = ledOverlays.map(_.overlayOutput.led)
|
||||||
|
val status_leds = all_leds.take(2)
|
||||||
|
val other_leds = all_leds.drop(2)
|
||||||
|
|
||||||
|
|
||||||
|
override lazy val module = new HarnessLikeImpl
|
||||||
|
|
||||||
|
class HarnessLikeImpl extends Impl with HasHarnessInstantiators {
|
||||||
|
all_leds.foreach(_ := DontCare)
|
||||||
|
clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin
|
||||||
|
|
||||||
|
val clk_100mhz = clockOverlay.overlayOutput.node.out.head._1.clock
|
||||||
|
|
||||||
|
// Blink the status LEDs for sanity
|
||||||
|
withClockAndReset(clk_100mhz, dutClock.in.head._1.reset) {
|
||||||
|
val period = (BigInt(100) << 20) / status_leds.size
|
||||||
|
val counter = RegInit(0.U(log2Ceil(period).W))
|
||||||
|
val on = RegInit(0.U(log2Ceil(status_leds.size).W))
|
||||||
|
status_leds.zipWithIndex.map { case (o,s) => o := on === s.U }
|
||||||
|
counter := Mux(counter === (period-1).U, 0.U, counter + 1.U)
|
||||||
|
when (counter === 0.U) {
|
||||||
|
on := Mux(on === (status_leds.size-1).U, 0.U, on + 1.U)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
other_leds(0) := resetPin
|
||||||
|
|
||||||
|
harnessSysPLL.plls.foreach(_._1.getReset.get := pllReset)
|
||||||
|
|
||||||
|
def referenceClockFreqMHz = dutFreqMHz
|
||||||
|
def referenceClock = dutClock.in.head._1.clock
|
||||||
|
def referenceReset = dutClock.in.head._1.reset
|
||||||
|
def success = { require(false, "Unused"); false.B }
|
||||||
|
|
||||||
|
if (p(NexysVideoShellDDR)) {
|
||||||
|
ddrOverlay.get.mig.module.clock := harnessBinderClock
|
||||||
|
ddrOverlay.get.mig.module.reset := harnessBinderReset
|
||||||
|
ddrBlockDuringReset.get.module.clock := harnessBinderClock
|
||||||
|
ddrBlockDuringReset.get.module.reset := harnessBinderReset.asBool || !ddrOverlay.get.mig.module.io.port.init_calib_complete
|
||||||
|
}
|
||||||
|
|
||||||
|
instantiateChipTops()
|
||||||
|
}
|
||||||
|
}
|
||||||
39
fpga/src/main/scala/nexysvideo/HarnessBinders.scala
Normal file
39
fpga/src/main/scala/nexysvideo/HarnessBinders.scala
Normal file
@@ -0,0 +1,39 @@
|
|||||||
|
// See LICENSE for license details.
|
||||||
|
package chipyard.fpga.nexysvideo
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
|
||||||
|
import freechips.rocketchip.subsystem.{PeripheryBusKey}
|
||||||
|
import freechips.rocketchip.tilelink.{TLBundle}
|
||||||
|
import freechips.rocketchip.util.{HeterogeneousBag}
|
||||||
|
import freechips.rocketchip.diplomacy.{LazyRawModuleImp}
|
||||||
|
|
||||||
|
import sifive.blocks.devices.uart.{UARTParams}
|
||||||
|
|
||||||
|
import chipyard._
|
||||||
|
import chipyard.harness._
|
||||||
|
|
||||||
|
import testchipip._
|
||||||
|
import chipyard.iobinders._
|
||||||
|
|
||||||
|
class WithNexysVideoUARTTSI(uartBaudRate: BigInt = 115200) extends HarnessBinder({
|
||||||
|
case (th: HasHarnessInstantiators, port: UARTTSIPort) => {
|
||||||
|
val nexysvideoth = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[NexysVideoHarness]
|
||||||
|
nexysvideoth.io_uart_bb.bundle <> port.io.uart
|
||||||
|
nexysvideoth.other_leds(1) := port.io.dropped
|
||||||
|
nexysvideoth.other_leds(2) := port.io.tsi2tl_state(0)
|
||||||
|
nexysvideoth.other_leds(3) := port.io.tsi2tl_state(1)
|
||||||
|
nexysvideoth.other_leds(4) := port.io.tsi2tl_state(2)
|
||||||
|
nexysvideoth.other_leds(5) := port.io.tsi2tl_state(3)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithNexysVideoDDRTL extends HarnessBinder({
|
||||||
|
case (th: HasHarnessInstantiators, port: TLMemPort) => {
|
||||||
|
val nexysTh = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[NexysVideoHarness]
|
||||||
|
val bundles = nexysTh.ddrClient.get.out.map(_._1)
|
||||||
|
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
||||||
|
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
||||||
|
ddrClientBundle <> port.io
|
||||||
|
}
|
||||||
|
})
|
||||||
@@ -53,10 +53,6 @@ class WithVC707Tweaks extends Config (
|
|||||||
new WithVC707UARTHarnessBinder ++
|
new WithVC707UARTHarnessBinder ++
|
||||||
new WithVC707SPISDCardHarnessBinder ++
|
new WithVC707SPISDCardHarnessBinder ++
|
||||||
new WithVC707DDRMemHarnessBinder ++
|
new WithVC707DDRMemHarnessBinder ++
|
||||||
// io binders
|
|
||||||
new WithUARTIOPassthrough ++
|
|
||||||
new WithSPIIOPassthrough ++
|
|
||||||
new WithTLIOPassthrough ++
|
|
||||||
// other configuration
|
// other configuration
|
||||||
new WithDefaultPeripherals ++
|
new WithDefaultPeripherals ++
|
||||||
new chipyard.config.WithTLBackingMemory ++ // use TL backing memory
|
new chipyard.config.WithTLBackingMemory ++ // use TL backing memory
|
||||||
|
|||||||
@@ -11,36 +11,29 @@ import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
|
|||||||
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{HasSystemXilinxVC707PCIeX1ModuleImp, XilinxVC707PCIeX1IO}
|
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{HasSystemXilinxVC707PCIeX1ModuleImp, XilinxVC707PCIeX1IO}
|
||||||
|
|
||||||
import chipyard.{CanHaveMasterTLMemPort}
|
import chipyard.{CanHaveMasterTLMemPort}
|
||||||
import chipyard.harness.{OverrideHarnessBinder}
|
import chipyard.harness.{HarnessBinder}
|
||||||
|
import chipyard.iobinders._
|
||||||
|
|
||||||
/*** UART ***/
|
/*** UART ***/
|
||||||
class WithVC707UARTHarnessBinder extends OverrideHarnessBinder({
|
class WithVC707UARTHarnessBinder extends HarnessBinder({
|
||||||
(system: HasPeripheryUARTModuleImp, th: BaseModule, ports: Seq[UARTPortIO]) => {
|
case (th: VC707FPGATestHarnessImp, port: UARTPort) => {
|
||||||
th match { case vc707th: VC707FPGATestHarnessImp => {
|
th.vc707Outer.io_uart_bb.bundle <> port.io
|
||||||
vc707th.vc707Outer.io_uart_bb.bundle <> ports.head
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*** SPI ***/
|
/*** SPI ***/
|
||||||
class WithVC707SPISDCardHarnessBinder extends OverrideHarnessBinder({
|
class WithVC707SPISDCardHarnessBinder extends HarnessBinder({
|
||||||
(system: HasPeripherySPI, th: BaseModule, ports: Seq[SPIPortIO]) => {
|
case (th: VC707FPGATestHarnessImp, port: SPIPort) => {
|
||||||
th match { case vc707th: VC707FPGATestHarnessImp => {
|
th.vc707Outer.io_spi_bb.bundle <> port.io
|
||||||
vc707th.vc707Outer.io_spi_bb.bundle <> ports.head
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*** Experimental DDR ***/
|
/*** Experimental DDR ***/
|
||||||
class WithVC707DDRMemHarnessBinder extends OverrideHarnessBinder({
|
class WithVC707DDRMemHarnessBinder extends HarnessBinder({
|
||||||
(system: CanHaveMasterTLMemPort, th: BaseModule, ports: Seq[HeterogeneousBag[TLBundle]]) => {
|
case (th: VC707FPGATestHarnessImp, port: TLMemPort) => {
|
||||||
th match { case vc707th: VC707FPGATestHarnessImp => {
|
val bundles = th.vc707Outer.ddrClient.out.map(_._1)
|
||||||
require(ports.size == 1)
|
|
||||||
|
|
||||||
val bundles = vc707th.vc707Outer.ddrClient.out.map(_._1)
|
|
||||||
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
||||||
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
||||||
ddrClientBundle <> ports.head
|
ddrClientBundle <> port.io
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,53 +0,0 @@
|
|||||||
package chipyard.fpga.vc707
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.experimental.{IO, DataMirror}
|
|
||||||
|
|
||||||
import freechips.rocketchip.diplomacy.{ResourceBinding, Resource, ResourceAddress, InModuleBody}
|
|
||||||
import freechips.rocketchip.subsystem.{BaseSubsystem}
|
|
||||||
import freechips.rocketchip.util.{HeterogeneousBag}
|
|
||||||
import freechips.rocketchip.tilelink.{TLBundle}
|
|
||||||
|
|
||||||
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp}
|
|
||||||
import sifive.blocks.devices.spi.{HasPeripherySPI, HasPeripherySPIModuleImp, MMCDevice}
|
|
||||||
import sifive.fpgashells.devices.xilinx.xilinxvc707pciex1.{HasSystemXilinxVC707PCIeX1ModuleImp}
|
|
||||||
|
|
||||||
import chipyard.{CanHaveMasterTLMemPort}
|
|
||||||
import chipyard.iobinders.{OverrideIOBinder, OverrideLazyIOBinder}
|
|
||||||
|
|
||||||
class WithUARTIOPassthrough extends OverrideIOBinder({
|
|
||||||
(system: HasPeripheryUARTModuleImp) => {
|
|
||||||
val io_uart_pins_temp = system.uart.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"uart_$i") }
|
|
||||||
(io_uart_pins_temp zip system.uart).map { case (io, sysio) =>
|
|
||||||
io <> sysio
|
|
||||||
}
|
|
||||||
(io_uart_pins_temp, Nil)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithSPIIOPassthrough extends OverrideLazyIOBinder({
|
|
||||||
(system: HasPeripherySPI) => {
|
|
||||||
// attach resource to 1st SPI
|
|
||||||
ResourceBinding {
|
|
||||||
Resource(new MMCDevice(system.tlSpiNodes.head.device, 1), "reg").bind(ResourceAddress(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
InModuleBody {
|
|
||||||
system.asInstanceOf[BaseSubsystem].module match { case system: HasPeripherySPIModuleImp => {
|
|
||||||
val io_spi_pins_temp = system.spi.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"spi_$i") }
|
|
||||||
(io_spi_pins_temp zip system.spi).map { case (io, sysio) =>
|
|
||||||
io <> sysio
|
|
||||||
}
|
|
||||||
(io_spi_pins_temp, Nil)
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithTLIOPassthrough extends OverrideIOBinder({
|
|
||||||
(system: CanHaveMasterTLMemPort) => {
|
|
||||||
val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave")
|
|
||||||
io_tl_mem_pins_temp <> system.mem_tl
|
|
||||||
(Seq(io_tl_mem_pins_temp), Nil)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -52,9 +52,6 @@ class WithVCU118Tweaks extends Config(
|
|||||||
new WithUART ++
|
new WithUART ++
|
||||||
new WithSPISDCard ++
|
new WithSPISDCard ++
|
||||||
new WithDDRMem ++
|
new WithDDRMem ++
|
||||||
// io binders
|
|
||||||
new WithUARTIOPassthrough ++
|
|
||||||
new WithSPIIOPassthrough ++
|
|
||||||
// other configuration
|
// other configuration
|
||||||
new WithDefaultPeripherals ++
|
new WithDefaultPeripherals ++
|
||||||
new chipyard.config.WithTLBackingMemory ++ // use TL backing memory
|
new chipyard.config.WithTLBackingMemory ++ // use TL backing memory
|
||||||
|
|||||||
@@ -11,35 +11,28 @@ import sifive.blocks.devices.spi.{HasPeripherySPI, SPIPortIO}
|
|||||||
|
|
||||||
import chipyard._
|
import chipyard._
|
||||||
import chipyard.harness._
|
import chipyard.harness._
|
||||||
|
import chipyard.iobinders._
|
||||||
|
|
||||||
/*** UART ***/
|
/*** UART ***/
|
||||||
class WithUART extends OverrideHarnessBinder({
|
class WithUART extends HarnessBinder({
|
||||||
(system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[UARTPortIO]) => {
|
case (th: VCU118FPGATestHarnessImp, port: UARTPort) => {
|
||||||
th match { case vcu118th: VCU118FPGATestHarnessImp => {
|
th.vcu118Outer.io_uart_bb.bundle <> port.io
|
||||||
vcu118th.vcu118Outer.io_uart_bb.bundle <> ports.head
|
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*** SPI ***/
|
/*** SPI ***/
|
||||||
class WithSPISDCard extends OverrideHarnessBinder({
|
class WithSPISDCard extends HarnessBinder({
|
||||||
(system: HasPeripherySPI, th: BaseModule with HasHarnessInstantiators, ports: Seq[SPIPortIO]) => {
|
case (th: VCU118FPGATestHarnessImp, port: SPIPort) => {
|
||||||
th match { case vcu118th: VCU118FPGATestHarnessImp => {
|
th.vcu118Outer.io_spi_bb.bundle <> port.io
|
||||||
vcu118th.vcu118Outer.io_spi_bb.bundle <> ports.head
|
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*** Experimental DDR ***/
|
/*** Experimental DDR ***/
|
||||||
class WithDDRMem extends OverrideHarnessBinder({
|
class WithDDRMem extends HarnessBinder({
|
||||||
(system: CanHaveMasterTLMemPort, th: BaseModule with HasHarnessInstantiators, ports: Seq[HeterogeneousBag[TLBundle]]) => {
|
case (th: VCU118FPGATestHarnessImp, port: TLMemPort) => {
|
||||||
th match { case vcu118th: VCU118FPGATestHarnessImp => {
|
val bundles = th.vcu118Outer.ddrClient.out.map(_._1)
|
||||||
require(ports.size == 1)
|
|
||||||
|
|
||||||
val bundles = vcu118th.vcu118Outer.ddrClient.out.map(_._1)
|
|
||||||
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType)))
|
||||||
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
||||||
ddrClientBundle <> ports.head
|
ddrClientBundle <> port.io
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -1,44 +0,0 @@
|
|||||||
package chipyard.fpga.vcu118
|
|
||||||
|
|
||||||
import chisel3._
|
|
||||||
import chisel3.experimental.{IO, DataMirror}
|
|
||||||
|
|
||||||
import freechips.rocketchip.diplomacy.{ResourceBinding, Resource, ResourceAddress, InModuleBody}
|
|
||||||
import freechips.rocketchip.subsystem.{BaseSubsystem}
|
|
||||||
import freechips.rocketchip.util.{HeterogeneousBag}
|
|
||||||
import freechips.rocketchip.tilelink.{TLBundle}
|
|
||||||
|
|
||||||
import sifive.blocks.devices.uart.{HasPeripheryUARTModuleImp}
|
|
||||||
import sifive.blocks.devices.spi.{HasPeripherySPI, HasPeripherySPIModuleImp, MMCDevice}
|
|
||||||
|
|
||||||
import chipyard.{CanHaveMasterTLMemPort}
|
|
||||||
import chipyard.iobinders.{OverrideIOBinder, OverrideLazyIOBinder}
|
|
||||||
|
|
||||||
class WithUARTIOPassthrough extends OverrideIOBinder({
|
|
||||||
(system: HasPeripheryUARTModuleImp) => {
|
|
||||||
val io_uart_pins_temp = system.uart.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"uart_$i") }
|
|
||||||
(io_uart_pins_temp zip system.uart).map { case (io, sysio) =>
|
|
||||||
io <> sysio
|
|
||||||
}
|
|
||||||
(io_uart_pins_temp, Nil)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithSPIIOPassthrough extends OverrideLazyIOBinder({
|
|
||||||
(system: HasPeripherySPI) => {
|
|
||||||
// attach resource to 1st SPI
|
|
||||||
ResourceBinding {
|
|
||||||
Resource(new MMCDevice(system.tlSpiNodes.head.device, 1), "reg").bind(ResourceAddress(0))
|
|
||||||
}
|
|
||||||
|
|
||||||
InModuleBody {
|
|
||||||
system.asInstanceOf[BaseSubsystem].module match { case system: HasPeripherySPIModuleImp => {
|
|
||||||
val io_spi_pins_temp = system.spi.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"spi_$i") }
|
|
||||||
(io_spi_pins_temp zip system.spi).map { case (io, sysio) =>
|
|
||||||
io <> sysio
|
|
||||||
}
|
|
||||||
(io_spi_pins_temp, Nil)
|
|
||||||
} }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
})
|
|
||||||
@@ -20,6 +20,7 @@ import testchipip.{PeripheryTSIHostKey, TSIHostParams, TSIHostSerdesParams}
|
|||||||
import chipyard.{BuildSystem}
|
import chipyard.{BuildSystem}
|
||||||
|
|
||||||
import chipyard.fpga.vcu118.{WithVCU118Tweaks, WithFPGAFrequency, VCU118DDR2Size}
|
import chipyard.fpga.vcu118.{WithVCU118Tweaks, WithFPGAFrequency, VCU118DDR2Size}
|
||||||
|
import chipyard.iobinders.{WithGPIOPunchthrough}
|
||||||
|
|
||||||
class WithBringupPeripherals extends Config((site, here, up) => {
|
class WithBringupPeripherals extends Config((site, here, up) => {
|
||||||
case PeripheryUARTKey => up(PeripheryUARTKey, site) ++ List(UARTParams(address = BigInt(0x64003000L)))
|
case PeripheryUARTKey => up(PeripheryUARTKey, site) ++ List(UARTParams(address = BigInt(0x64003000L)))
|
||||||
@@ -80,8 +81,7 @@ class WithBringupAdditions extends Config(
|
|||||||
new WithBringupGPIO ++
|
new WithBringupGPIO ++
|
||||||
new WithBringupTSIHost ++
|
new WithBringupTSIHost ++
|
||||||
new WithTSITLIOPassthrough ++
|
new WithTSITLIOPassthrough ++
|
||||||
new WithI2CIOPassthrough ++
|
new WithGPIOPunchthrough ++
|
||||||
new WithGPIOIOPassthrough ++
|
|
||||||
new WithBringupPeripherals ++
|
new WithBringupPeripherals ++
|
||||||
new WithBringupVCU118System)
|
new WithBringupVCU118System)
|
||||||
|
|
||||||
|
|||||||
@@ -14,56 +14,38 @@ import sifive.blocks.devices.gpio.{HasPeripheryGPIOModuleImp, GPIOPortIO}
|
|||||||
import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
||||||
|
|
||||||
import chipyard.harness._
|
import chipyard.harness._
|
||||||
|
import chipyard.iobinders._
|
||||||
|
|
||||||
/*** UART ***/
|
/*** UART ***/
|
||||||
class WithBringupUART extends ComposeHarnessBinder({
|
class WithBringupUART extends HarnessBinder({
|
||||||
(system: HasPeripheryUARTModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[UARTPortIO]) => {
|
case (th: BringupVCU118FPGATestHarnessImp, port: UARTPort) => {
|
||||||
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
|
th.bringupOuter.io_fmc_uart_bb.bundle <> port.io
|
||||||
require(ports.size == 2)
|
|
||||||
|
|
||||||
vcu118th.bringupOuter.io_fmc_uart_bb.bundle <> ports.last
|
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*** I2C ***/
|
/*** I2C ***/
|
||||||
class WithBringupI2C extends OverrideHarnessBinder({
|
class WithBringupI2C extends HarnessBinder({
|
||||||
(system: HasPeripheryI2CModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[I2CPort]) => {
|
case (th: BringupVCU118FPGATestHarnessImp, port: chipyard.iobinders.I2CPort) => {
|
||||||
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
|
th.bringupOuter.io_i2c_bb.bundle <> port.io
|
||||||
require(ports.size == 1)
|
|
||||||
|
|
||||||
vcu118th.bringupOuter.io_i2c_bb.bundle <> ports.head
|
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*** GPIO ***/
|
/*** GPIO ***/
|
||||||
class WithBringupGPIO extends OverrideHarnessBinder({
|
class WithBringupGPIO extends HarnessBinder({
|
||||||
(system: HasPeripheryGPIOModuleImp, th: BaseModule with HasHarnessInstantiators, ports: Seq[GPIOPortIO]) => {
|
case (th: BringupVCU118FPGATestHarnessImp, port: GPIOPort) => {
|
||||||
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
|
th.bringupOuter.io_gpio_bb(port.pinId).bundle <> port.io
|
||||||
(vcu118th.bringupOuter.io_gpio_bb zip ports).map { case (bb_io, dut_io) =>
|
|
||||||
bb_io.bundle <> dut_io
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
/*** TSI Host Widget ***/
|
/*** TSI Host Widget ***/
|
||||||
class WithBringupTSIHost extends OverrideHarnessBinder({
|
class WithBringupTSIHost extends HarnessBinder({
|
||||||
(system: HasPeripheryTSIHostWidget, th: BaseModule with HasHarnessInstantiators, ports: Seq[Data]) => {
|
case (th: BringupVCU118FPGATestHarnessImp, port: TLMemPort) => {
|
||||||
th match { case vcu118th: BringupVCU118FPGATestHarnessImp => {
|
val tsiBundles = th.bringupOuter.tsiDdrClient.out.map(_._1)
|
||||||
require(ports.size == 2) // 1st goes to the TL mem, 2nd goes to the serial link
|
|
||||||
|
|
||||||
ports.head match { case tlPort: HeterogeneousBag[TLBundle] =>
|
|
||||||
val tsiBundles = vcu118th.bringupOuter.tsiDdrClient.out.map(_._1)
|
|
||||||
val tsiDdrClientBundle = Wire(new HeterogeneousBag(tsiBundles.map(_.cloneType)))
|
val tsiDdrClientBundle = Wire(new HeterogeneousBag(tsiBundles.map(_.cloneType)))
|
||||||
tsiBundles.zip(tsiDdrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
tsiBundles.zip(tsiDdrClientBundle).foreach { case (bundle, io) => bundle <> io }
|
||||||
tsiDdrClientBundle <> tlPort
|
tsiDdrClientBundle <> port.io
|
||||||
}
|
}
|
||||||
|
case (th: BringupVCU118FPGATestHarnessImp, port: TSIHostWidgetPort) => {
|
||||||
ports.last match { case serialPort: TSIHostWidgetIO =>
|
th.bringupOuter.io_tsi_serial_bb.bundle <> port.io
|
||||||
vcu118th.bringupOuter.io_tsi_serial_bb.bundle <> serialPort
|
|
||||||
}
|
|
||||||
} }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -11,27 +11,10 @@ import sifive.blocks.devices.i2c.{HasPeripheryI2CModuleImp}
|
|||||||
|
|
||||||
import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
import testchipip.{HasPeripheryTSIHostWidget, TSIHostWidgetIO}
|
||||||
|
|
||||||
import chipyard.iobinders.{OverrideIOBinder}
|
import chipyard.iobinders.{OverrideIOBinder, Port, TLMemPort}
|
||||||
|
|
||||||
class WithGPIOIOPassthrough extends OverrideIOBinder({
|
case class TSIHostWidgetPort(val io: TSIHostWidgetIO)
|
||||||
(system: HasPeripheryGPIOModuleImp) => {
|
extends Port[TSIHostWidgetIO]
|
||||||
val io_gpio_pins_temp = system.gpio.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"gpio_$i") }
|
|
||||||
(io_gpio_pins_temp zip system.gpio).map { case (io, sysio) =>
|
|
||||||
io <> sysio
|
|
||||||
}
|
|
||||||
(io_gpio_pins_temp, Nil)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithI2CIOPassthrough extends OverrideIOBinder({
|
|
||||||
(system: HasPeripheryI2CModuleImp) => {
|
|
||||||
val io_i2c_pins_temp = system.i2c.zipWithIndex.map { case (dio, i) => IO(dio.cloneType).suggestName(s"i2c_$i") }
|
|
||||||
(io_i2c_pins_temp zip system.i2c).map { case (io, sysio) =>
|
|
||||||
io <> sysio
|
|
||||||
}
|
|
||||||
(io_i2c_pins_temp, Nil)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithTSITLIOPassthrough extends OverrideIOBinder({
|
class WithTSITLIOPassthrough extends OverrideIOBinder({
|
||||||
(system: HasPeripheryTSIHostWidget) => {
|
(system: HasPeripheryTSIHostWidget) => {
|
||||||
@@ -42,6 +25,6 @@ class WithTSITLIOPassthrough extends OverrideIOBinder({
|
|||||||
require(system.tsiSerial.size == 1)
|
require(system.tsiSerial.size == 1)
|
||||||
val io_tsi_serial_pins_temp = IO(DataMirror.internal.chiselTypeClone[TSIHostWidgetIO](system.tsiSerial.head)).suggestName("tsi_serial")
|
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
|
io_tsi_serial_pins_temp <> system.tsiSerial.head
|
||||||
(Seq(io_tsi_tl_mem_pins_temp, io_tsi_serial_pins_temp), Nil)
|
(Seq(TLMemPort(io_tsi_tl_mem_pins_temp), TSIHostWidgetPort(io_tsi_serial_pins_temp)), Nil)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -2,17 +2,13 @@ package chipyard.clocking
|
|||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
import chipyard.iobinders.{OverrideLazyIOBinder, GetSystemParameters, IOCellKey}
|
import chipyard.iobinders.{OverrideLazyIOBinder, GetSystemParameters, IOCellKey, ClockPort, ResetPort}
|
||||||
import freechips.rocketchip.prci._
|
import freechips.rocketchip.prci._
|
||||||
import freechips.rocketchip.diplomacy._
|
import freechips.rocketchip.diplomacy._
|
||||||
import freechips.rocketchip.subsystem._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.tilelink._
|
import freechips.rocketchip.tilelink._
|
||||||
import barstools.iocell.chisel._
|
import barstools.iocell.chisel._
|
||||||
|
|
||||||
class ClockWithFreq(val freqMHz: Double) extends Bundle {
|
|
||||||
val clock = Clock()
|
|
||||||
}
|
|
||||||
|
|
||||||
// This uses the FakePLL, which uses a ClockAtFreq Verilog blackbox to generate
|
// This uses the FakePLL, which uses a ClockAtFreq Verilog blackbox to generate
|
||||||
// the requested clocks. This also adds TileLink ClockDivider and ClockSelector
|
// the requested clocks. This also adds TileLink ClockDivider and ClockSelector
|
||||||
// blocks, which allow memory-mapped control of clock division, and clock muxing
|
// blocks, which allow memory-mapped control of clock division, and clock muxing
|
||||||
@@ -58,13 +54,13 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
|||||||
pllCtrlSink := pllCtrl.ctrlNode
|
pllCtrlSink := pllCtrl.ctrlNode
|
||||||
|
|
||||||
InModuleBody {
|
InModuleBody {
|
||||||
val clock_wire = Wire(Input(new ClockWithFreq(100)))
|
val clock_wire = Wire(Input(Clock()))
|
||||||
val reset_wire = Wire(Input(AsyncReset()))
|
val reset_wire = Wire(Input(AsyncReset()))
|
||||||
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
|
val (clock_io, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
|
||||||
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
|
val (reset_io, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
|
||||||
|
|
||||||
slowClockSource.out.unzip._1.map { o =>
|
slowClockSource.out.unzip._1.map { o =>
|
||||||
o.clock := clock_wire.clock
|
o.clock := clock_wire
|
||||||
o.reset := reset_wire
|
o.reset := reset_wire
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -79,7 +75,7 @@ class WithPLLSelectorDividerClockGenerator extends OverrideLazyIOBinder({
|
|||||||
o.reset := reset_wire
|
o.reset := reset_wire
|
||||||
}
|
}
|
||||||
|
|
||||||
(Seq(clock_io, reset_io), clockIOCell ++ resetIOCell)
|
(Seq(ClockPort(clock_io, 100), ResetPort(reset_io)), clockIOCell ++ resetIOCell)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
@@ -114,12 +110,12 @@ class WithPassthroughClockGenerator extends OverrideLazyIOBinder({
|
|||||||
require(m.take.isDefined, s"""Clock ${m.name.get} has no requested frequency
|
require(m.take.isDefined, s"""Clock ${m.name.get} has no requested frequency
|
||||||
|Clocks: ${edge.sink.members.map(_.name.get)}""".stripMargin)
|
|Clocks: ${edge.sink.members.map(_.name.get)}""".stripMargin)
|
||||||
val freq = m.take.get.freqMHz
|
val freq = m.take.get.freqMHz
|
||||||
val clock_io = IO(Input(new ClockWithFreq(freq))).suggestName(s"clock_${m.name.get}")
|
val clock_io = IO(Input(Clock())).suggestName(s"clock_${m.name.get}")
|
||||||
b.clock := clock_io.clock
|
b.clock := clock_io
|
||||||
b.reset := reset_io
|
b.reset := reset_io
|
||||||
clock_io
|
ClockPort(clock_io, freq)
|
||||||
}.toSeq
|
}.toSeq
|
||||||
((clock_ios :+ reset_io), Nil)
|
((clock_ios :+ ResetPort(reset_io)), Nil)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -51,7 +51,7 @@ object FrequencyUtils {
|
|||||||
require(!requestedOutputs.contains(0.0))
|
require(!requestedOutputs.contains(0.0))
|
||||||
val requestedFreqs = requestedOutputs.map(_.freqMHz)
|
val requestedFreqs = requestedOutputs.map(_.freqMHz)
|
||||||
val fastestFreq = requestedFreqs.max
|
val fastestFreq = requestedFreqs.max
|
||||||
require(fastestFreq <= maximumAllowableFreqMHz)
|
require(fastestFreq <= maximumAllowableFreqMHz, s"Fastest Freq $fastestFreq > Max Freq $maximumAllowableFreqMHz")
|
||||||
|
|
||||||
val candidateFreqs =
|
val candidateFreqs =
|
||||||
Seq.tabulate(Math.ceil(maximumAllowableFreqMHz / fastestFreq).toInt)(i => (i + 1) * fastestFreq)
|
Seq.tabulate(Math.ceil(maximumAllowableFreqMHz / fastestFreq).toInt)(i => (i + 1) * fastestFreq)
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ class AbstractConfig extends Config(
|
|||||||
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.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled
|
new chipyard.harness.WithSimJTAGDebug ++ // add SimJTAG if JTAG for debug 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
|
||||||
@@ -23,7 +24,8 @@ class AbstractConfig extends Config(
|
|||||||
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.WithSimUARTToUARTTSI ++ // connect a SimUART to the UART-TSI port
|
new chipyard.harness.WithSimUARTToUARTTSI ++ // connect a SimUART to the UART-TSI port
|
||||||
new chipyard.harness.WithClockAndResetFromHarness ++ // all Clock/Reset 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.WithAbsoluteFreqHarnessClockInstantiator ++ // generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz
|
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz
|
||||||
|
|
||||||
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
|
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
|
||||||
@@ -32,11 +34,13 @@ class AbstractConfig extends Config(
|
|||||||
new chipyard.iobinders.WithDebugIOCells ++
|
new chipyard.iobinders.WithDebugIOCells ++
|
||||||
new chipyard.iobinders.WithUARTIOCells ++
|
new chipyard.iobinders.WithUARTIOCells ++
|
||||||
new chipyard.iobinders.WithGPIOCells ++
|
new chipyard.iobinders.WithGPIOCells ++
|
||||||
new chipyard.iobinders.WithSPIIOCells ++
|
new chipyard.iobinders.WithSPIFlashIOCells ++
|
||||||
new chipyard.iobinders.WithExtInterruptIOCells ++
|
new chipyard.iobinders.WithExtInterruptIOCells ++
|
||||||
new chipyard.iobinders.WithCustomBootPin ++
|
new chipyard.iobinders.WithCustomBootPin ++
|
||||||
// The "punchthrough" IOBInders below don't generate IOCells, as these interfaces shouldn't really be mapped to ASIC IO
|
// The "punchthrough" IOBInders below don't generate IOCells, as these interfaces shouldn't really be mapped to ASIC IO
|
||||||
// Instead, they directly pass through the DigitalTop ports to ports in the ChipTop
|
// Instead, they directly pass through the DigitalTop ports to ports in the ChipTop
|
||||||
|
new chipyard.iobinders.WithI2CPunchthrough ++
|
||||||
|
new chipyard.iobinders.WithSPIIOPunchthrough ++
|
||||||
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
||||||
new chipyard.iobinders.WithAXI4MMIOPunchthrough ++
|
new chipyard.iobinders.WithAXI4MMIOPunchthrough ++
|
||||||
new chipyard.iobinders.WithTLMemPunchthrough ++
|
new chipyard.iobinders.WithTLMemPunchthrough ++
|
||||||
|
|||||||
@@ -7,7 +7,8 @@ class AbstractTraceGenConfig extends Config(
|
|||||||
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++
|
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++
|
||||||
new chipyard.harness.WithBlackBoxSimMem ++
|
new chipyard.harness.WithBlackBoxSimMem ++
|
||||||
new chipyard.harness.WithTraceGenSuccess ++
|
new chipyard.harness.WithTraceGenSuccess ++
|
||||||
new chipyard.harness.WithClockAndResetFromHarness ++
|
new chipyard.harness.WithClockFromHarness ++
|
||||||
|
new chipyard.harness.WithResetFromHarness ++
|
||||||
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
new chipyard.iobinders.WithAXI4MemPunchthrough ++
|
||||||
new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++
|
new chipyard.iobinders.WithTraceGenSuccessPunchthrough ++
|
||||||
new chipyard.clocking.WithPassthroughClockGenerator ++
|
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||||
|
|||||||
@@ -68,13 +68,13 @@ class FlatChipTop(implicit p: Parameters) extends LazyModule {
|
|||||||
l.reset := implicit_reset
|
l.reset := implicit_reset
|
||||||
}}
|
}}
|
||||||
|
|
||||||
val clock_wire = Wire(Input(new ClockWithFreq(80)))
|
val clock_wire = Wire(Input(Clock()))
|
||||||
val reset_wire = Wire(Input(AsyncReset()))
|
val reset_wire = Wire(Input(AsyncReset()))
|
||||||
val (clock_pad, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
|
val (clock_pad, clockIOCell) = IOCell.generateIOFromSignal(clock_wire, "clock", p(IOCellKey))
|
||||||
val (reset_pad, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
|
val (reset_pad, resetIOCell) = IOCell.generateIOFromSignal(reset_wire, "reset", p(IOCellKey))
|
||||||
|
|
||||||
slowClockSource.out.unzip._1.map { o =>
|
slowClockSource.out.unzip._1.map { o =>
|
||||||
o.clock := clock_wire.clock
|
o.clock := clock_wire
|
||||||
o.reset := reset_wire
|
o.reset := reset_wire
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ class FlatTestHarness(implicit val p: Parameters) extends Module {
|
|||||||
val clock_source = Module(new ClockSourceAtFreqFromPlusArg("slow_clk_freq_mhz"))
|
val clock_source = Module(new ClockSourceAtFreqFromPlusArg("slow_clk_freq_mhz"))
|
||||||
clock_source.io.power := true.B
|
clock_source.io.power := true.B
|
||||||
clock_source.io.gate := false.B
|
clock_source.io.gate := false.B
|
||||||
dut.clock_pad.clock := clock_source.io.clk
|
dut.clock_pad := clock_source.io.clk
|
||||||
|
|
||||||
// Reset
|
// Reset
|
||||||
dut.reset_pad := reset.asAsyncReset
|
dut.reset_pad := reset.asAsyncReset
|
||||||
|
|||||||
@@ -6,143 +6,111 @@ import chisel3.experimental.{Analog, BaseModule, DataMirror, Direction}
|
|||||||
|
|
||||||
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||||
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode, AXI4EdgeParameters}
|
|
||||||
import freechips.rocketchip.devices.debug._
|
|
||||||
import freechips.rocketchip.jtag.{JTAGIO}
|
|
||||||
import freechips.rocketchip.system.{SimAXIMem}
|
import freechips.rocketchip.system.{SimAXIMem}
|
||||||
import freechips.rocketchip.subsystem._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.util._
|
import freechips.rocketchip.util._
|
||||||
|
import freechips.rocketchip.jtag.{JTAGIO}
|
||||||
import sifive.blocks.devices.gpio._
|
import freechips.rocketchip.devices.debug.{SimJTAG}
|
||||||
import sifive.blocks.devices.uart._
|
|
||||||
import sifive.blocks.devices.spi._
|
|
||||||
|
|
||||||
import barstools.iocell.chisel._
|
import barstools.iocell.chisel._
|
||||||
|
|
||||||
import testchipip._
|
import testchipip._
|
||||||
|
import icenet.{NicLoopback, SimNetwork}
|
||||||
import chipyard._
|
import chipyard._
|
||||||
import chipyard.clocking.{HasChipyardPRCI, ClockWithFreq}
|
import chipyard.clocking.{HasChipyardPRCI}
|
||||||
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO}
|
import chipyard.iobinders._
|
||||||
|
|
||||||
import tracegen.{TraceGenSystemModuleImp}
|
case object HarnessBinders extends Field[HarnessBinderFunction]({case _ => })
|
||||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
|
||||||
|
|
||||||
import scala.reflect.{ClassTag}
|
|
||||||
|
|
||||||
case object HarnessBinders extends Field[HarnessBinderMap](HarnessBinderMapDefault)
|
|
||||||
|
|
||||||
object ApplyHarnessBinders {
|
object ApplyHarnessBinders {
|
||||||
def apply(th: HasHarnessInstantiators, sys: LazyModule, portMap: Map[String, Seq[Data]])(implicit p: Parameters): Unit = {
|
def apply(th: HasHarnessInstantiators, ports: Seq[Port[_]])(implicit p: Parameters): Unit = {
|
||||||
val pm = portMap.withDefaultValue(Nil)
|
ports.foreach(port => p(HarnessBinders)(th, port))
|
||||||
p(HarnessBinders).foreach { case (s, f) =>
|
|
||||||
f(sys, th, pm(s))
|
|
||||||
f(sys.module, th, pm(s))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// The ClassTags here are necessary to overcome issues arising from type erasure
|
class HarnessBinder[T <: HasHarnessInstantiators, S <: Port[_]](
|
||||||
class HarnessBinder[T, S <: HasHarnessInstantiators, U <: Data](composer: ((T, S, Seq[U]) => Unit) => (T, S, Seq[U]) => Unit)(implicit systemTag: ClassTag[T], harnessTag: ClassTag[S], portTag: ClassTag[U]) extends Config((site, here, up) => {
|
fn: => HarnessBinderFunction
|
||||||
case HarnessBinders => up(HarnessBinders, site) + (systemTag.runtimeClass.toString ->
|
) extends Config((site, here, up) => {
|
||||||
((t: Any, th: HasHarnessInstantiators, ports: Seq[Data]) => {
|
case HarnessBinders => fn orElse up(HarnessBinders)
|
||||||
val pts = ports.collect({case p: U => p})
|
|
||||||
require (pts.length == ports.length, s"Port type mismatch between IOBinder and HarnessBinder: ${portTag}")
|
|
||||||
val upfn = up(HarnessBinders, site)(systemTag.runtimeClass.toString)
|
|
||||||
(th, t) match {
|
|
||||||
case (th: S, system: T) => composer(upfn)(system, th, pts)
|
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
class OverrideHarnessBinder[T, S <: HasHarnessInstantiators, U <: Data](fn: => (T, S, Seq[U]) => Unit)
|
|
||||||
(implicit tag: ClassTag[T], thtag: ClassTag[S], ptag: ClassTag[U])
|
|
||||||
extends HarnessBinder[T, S, U]((upfn: (T, S, Seq[U]) => Unit) => fn)
|
|
||||||
|
|
||||||
class ComposeHarnessBinder[T, S <: HasHarnessInstantiators, U <: Data](fn: => (T, S, Seq[U]) => Unit)
|
|
||||||
(implicit tag: ClassTag[T], thtag: ClassTag[S], ptag: ClassTag[U])
|
|
||||||
extends HarnessBinder[T, S, U]((upfn: (T, S, Seq[U]) => Unit) => (t, th, p) => {
|
|
||||||
upfn(t, th, p)
|
|
||||||
fn(t, th, p)
|
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class WithGPIOTiedOff extends OverrideHarnessBinder({
|
class WithGPIOTiedOff extends HarnessBinder({
|
||||||
(system: HasPeripheryGPIOModuleImp, th: HasHarnessInstantiators, ports: Seq[Analog]) => {
|
case (th: HasHarnessInstantiators, port: GPIOPort) => {
|
||||||
ports.foreach { _ <> AnalogConst(0) }
|
port.io <> AnalogConst(0)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// DOC include start: WithUARTAdapter
|
// DOC include start: WithUARTAdapter
|
||||||
class WithUARTAdapter extends OverrideHarnessBinder({
|
class WithUARTAdapter extends HarnessBinder({
|
||||||
(system: HasPeripheryUARTModuleImp, th: HasHarnessInstantiators, ports: Seq[UARTPortIO]) => {
|
case (th: HasHarnessInstantiators, port: UARTPort) => {
|
||||||
UARTAdapter.connect(ports)(system.p)
|
val div = (th.getHarnessBinderClockFreqMHz.toDouble * 1000000 / port.io.c.initBaudRate.toDouble).toInt
|
||||||
|
val uart_sim = Module(new UARTAdapter(port.uartNo, div, false)).suggestName(s"uart_sim_uartno${port.uartNo}")
|
||||||
|
uart_sim.io.uart.txd := port.io.txd
|
||||||
|
port.io.rxd := uart_sim.io.uart.rxd
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// DOC include end: WithUARTAdapter
|
// DOC include end: WithUARTAdapter
|
||||||
|
|
||||||
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends OverrideHarnessBinder({
|
class WithSimSPIFlashModel(rdOnly: Boolean = true) extends HarnessBinder({
|
||||||
(system: HasPeripherySPIFlashModuleImp, th: HasHarnessInstantiators, ports: Seq[SPIChipIO]) => {
|
case (th: HasHarnessInstantiators, port: SPIFlashPort) => {
|
||||||
SimSPIFlashModel.connect(ports, th.harnessBinderReset, rdOnly)(system.p)
|
val spi_mem = Module(new SimSPIFlashModel(port.params.fSize, port.spiId, rdOnly)).suggestName(s"spi_mem${port.spiId}")
|
||||||
|
spi_mem.io.sck := port.io.sck
|
||||||
|
require(port.params.csWidth == 1, "I don't know what to do with your extra CS bits. Fix me please.")
|
||||||
|
spi_mem.io.cs(0) := port.io.cs(0)
|
||||||
|
spi_mem.io.dq.zip(port.io.dq).foreach { case (x, y) => x <> y }
|
||||||
|
spi_mem.io.reset := th.harnessBinderReset
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimBlockDevice extends OverrideHarnessBinder({
|
class WithSimBlockDevice extends HarnessBinder({
|
||||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessInstantiators, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
case (th: HasHarnessInstantiators, port: BlockDevicePort) => {
|
||||||
implicit val p: Parameters = GetSystemParameters(system)
|
val sim_blkdev = Module(new SimBlockDevice(port.params))
|
||||||
ports.map { b => SimBlockDevice.connect(b.clock, th.harnessBinderReset.asBool, Some(b.bits)) }
|
sim_blkdev.io.bdev <> port.io.bits
|
||||||
|
sim_blkdev.io.clock := port.io.clock
|
||||||
|
sim_blkdev.io.reset := th.harnessBinderReset
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithBlockDeviceModel extends OverrideHarnessBinder({
|
class WithBlockDeviceModel extends HarnessBinder({
|
||||||
(system: CanHavePeripheryBlockDevice, th: HasHarnessInstantiators, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
case (th: HasHarnessInstantiators, port: BlockDevicePort) => {
|
||||||
implicit val p: Parameters = GetSystemParameters(system)
|
val blkdev_model = Module(new BlockDeviceModel(16, port.params))
|
||||||
ports.map { b => BlockDeviceModel.connect(Some(b.bits)) }
|
blkdev_model.io <> port.io.bits
|
||||||
|
blkdev_model.clock := port.io.clock
|
||||||
|
blkdev_model.reset := th.harnessBinderReset
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithLoopbackNIC extends OverrideHarnessBinder({
|
class WithLoopbackNIC extends HarnessBinder({
|
||||||
(system: CanHavePeripheryIceNIC, th: HasHarnessInstantiators, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
case (th: HasHarnessInstantiators, port: NICPort) => {
|
||||||
implicit val p: Parameters = GetSystemParameters(system)
|
withClock(port.io.clock) { NicLoopback.connect(port.io.bits, port.params) }
|
||||||
ports.map { n =>
|
|
||||||
withClockAndReset(n.clock, th.harnessBinderReset.asBool) {
|
|
||||||
NicLoopback.connect(Some(n.bits), p(NICKey))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimNetwork extends OverrideHarnessBinder({
|
class WithSimNetwork extends HarnessBinder({
|
||||||
(system: CanHavePeripheryIceNIC, th: BaseModule with HasHarnessInstantiators, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
case (th: HasHarnessInstantiators, port: NICPort) => {
|
||||||
implicit val p: Parameters = GetSystemParameters(system)
|
withClock(port.io.clock) { SimNetwork.connect(Some(port.io.bits), port.io.clock, th.harnessBinderReset.asBool) }
|
||||||
ports.map { n => SimNetwork.connect(Some(n.bits), n.clock, th.harnessBinderReset.asBool) }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimAXIMem extends OverrideHarnessBinder({
|
class WithSimAXIMem extends HarnessBinder({
|
||||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessInstantiators, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
case (th: HasHarnessInstantiators, port: AXI4MemPort) => {
|
||||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
val mem = LazyModule(new SimAXIMem(port.edge, size=port.params.master.size)(Parameters.empty))
|
||||||
(ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
|
withClock(port.io.clock) { Module(mem.module) }
|
||||||
val mem = LazyModule(new SimAXIMem(edge, size=p(ExtMem).get.master.size)(p))
|
mem.io_axi4.head <> port.io
|
||||||
Module(mem.module).suggestName("mem")
|
|
||||||
mem.io_axi4.head <> port.bits
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithBlackBoxSimMem(additionalLatency: Int = 0) extends OverrideHarnessBinder({
|
class WithBlackBoxSimMem(additionalLatency: Int = 0) extends HarnessBinder({
|
||||||
(system: CanHaveMasterAXI4MemPort, th: HasHarnessInstantiators, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
case (th: HasHarnessInstantiators, port: AXI4MemPort) => {
|
||||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
|
||||||
(ports zip system.memAXI4Node.edges.in).map { case (port, edge) =>
|
|
||||||
// TODO FIX: This currently makes each SimDRAM contain the entire memory space
|
// TODO FIX: This currently makes each SimDRAM contain the entire memory space
|
||||||
val memSize = p(ExtMem).get.master.size
|
val memSize = port.params.master.size
|
||||||
val memBase = p(ExtMem).get.master.base
|
val memBase = port.params.master.base
|
||||||
val lineSize = p(CacheBlockBytes)
|
val lineSize = 64 // cache block size
|
||||||
val clockFreq = p(MemoryBusKey).dtsFrequency.get
|
val clockFreq = port.clockFreqMHz
|
||||||
val mem = Module(new SimDRAM(memSize, lineSize, clockFreq, memBase, edge.bundle)).suggestName("simdram")
|
val mem = Module(new SimDRAM(memSize, lineSize, clockFreq, memBase, port.edge.bundle)).suggestName("simdram")
|
||||||
mem.io.axi <> port.bits
|
|
||||||
|
mem.io.clock := port.io.clock
|
||||||
|
mem.io.reset := th.harnessBinderReset.asAsyncReset
|
||||||
|
mem.io.axi <> port.io.bits
|
||||||
// Bug in Chisel implementation. See https://github.com/chipsalliance/chisel3/pull/1781
|
// Bug in Chisel implementation. See https://github.com/chipsalliance/chisel3/pull/1781
|
||||||
def Decoupled[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = {
|
def Decoupled[T <: Data](irr: IrrevocableIO[T]): DecoupledIO[T] = {
|
||||||
require(DataMirror.directionOf(irr.bits) == Direction.Output, "Only safe to cast produced Irrevocable bits to Decoupled.")
|
require(DataMirror.directionOf(irr.bits) == Direction.Output, "Only safe to cast produced Irrevocable bits to Decoupled.")
|
||||||
@@ -153,212 +121,169 @@ class WithBlackBoxSimMem(additionalLatency: Int = 0) extends OverrideHarnessBind
|
|||||||
d
|
d
|
||||||
}
|
}
|
||||||
if (additionalLatency > 0) {
|
if (additionalLatency > 0) {
|
||||||
withClockAndReset (port.clock, port.reset) {
|
withClock (port.io.clock) {
|
||||||
mem.io.axi.aw <> (0 until additionalLatency).foldLeft(Decoupled(port.bits.aw))((t, _) => Queue(t, 1, pipe=true))
|
mem.io.axi.aw <> (0 until additionalLatency).foldLeft(Decoupled(port.io.bits.aw))((t, _) => Queue(t, 1, pipe=true))
|
||||||
mem.io.axi.w <> (0 until additionalLatency).foldLeft(Decoupled(port.bits.w ))((t, _) => Queue(t, 1, pipe=true))
|
mem.io.axi.w <> (0 until additionalLatency).foldLeft(Decoupled(port.io.bits.w ))((t, _) => Queue(t, 1, pipe=true))
|
||||||
port.bits.b <> (0 until additionalLatency).foldLeft(Decoupled(mem.io.axi.b))((t, _) => Queue(t, 1, pipe=true))
|
port.io.bits.b <> (0 until additionalLatency).foldLeft(Decoupled(mem.io.axi.b ))((t, _) => Queue(t, 1, pipe=true))
|
||||||
mem.io.axi.ar <> (0 until additionalLatency).foldLeft(Decoupled(port.bits.ar))((t, _) => Queue(t, 1, pipe=true))
|
mem.io.axi.ar <> (0 until additionalLatency).foldLeft(Decoupled(port.io.bits.ar))((t, _) => Queue(t, 1, pipe=true))
|
||||||
port.bits.r <> (0 until additionalLatency).foldLeft(Decoupled(mem.io.axi.r))((t, _) => Queue(t, 1, pipe=true))
|
port.io.bits.r <> (0 until additionalLatency).foldLeft(Decoupled(mem.io.axi.r ))((t, _) => Queue(t, 1, pipe=true))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
mem.io.clock := port.clock
|
|
||||||
mem.io.reset := port.reset
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimAXIMMIO extends OverrideHarnessBinder({
|
class WithSimAXIMMIO extends HarnessBinder({
|
||||||
(system: CanHaveMasterAXI4MMIOPort, th: HasHarnessInstantiators, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
case (th: HasHarnessInstantiators, port: AXI4MMIOPort) => {
|
||||||
val p: Parameters = chipyard.iobinders.GetSystemParameters(system)
|
val mmio_mem = LazyModule(new SimAXIMem(port.edge, size = port.params.size)(Parameters.empty))
|
||||||
(ports zip system.mmioAXI4Node.edges.in).map { case (port, edge) =>
|
withClock(port.io.clock) { Module(mmio_mem.module).suggestName("mmio_mem") }
|
||||||
val mmio_mem = LazyModule(new SimAXIMem(edge, size = p(ExtBus).get.size)(p))
|
mmio_mem.io_axi4.head <> port.io.bits
|
||||||
withClockAndReset(port.clock, port.reset) {
|
|
||||||
Module(mmio_mem.module).suggestName("mmio_mem")
|
|
||||||
}
|
|
||||||
mmio_mem.io_axi4.head <> port.bits
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTieOffInterrupts extends OverrideHarnessBinder({
|
class WithTieOffInterrupts extends HarnessBinder({
|
||||||
(system: HasExtInterruptsModuleImp, th: HasHarnessInstantiators, ports: Seq[UInt]) => {
|
case (th: HasHarnessInstantiators, port: ExtIntPort) => {
|
||||||
ports.foreach { _ := 0.U }
|
port.io := 0.U
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTieOffL2FBusAXI extends OverrideHarnessBinder({
|
class WithTieOffL2FBusAXI extends HarnessBinder({
|
||||||
(system: CanHaveSlaveAXI4Port, th: HasHarnessInstantiators, ports: Seq[ClockedIO[AXI4Bundle]]) => {
|
case (th: HasHarnessInstantiators, port: AXI4InPort) => {
|
||||||
ports.foreach({ p =>
|
port.io := DontCare
|
||||||
p.bits := DontCare
|
port.io.bits.aw.valid := false.B
|
||||||
p.bits.aw.valid := false.B
|
port.io.bits.w.valid := false.B
|
||||||
p.bits.w.valid := false.B
|
port.io.bits.b.ready := false.B
|
||||||
p.bits.b.ready := false.B
|
port.io.bits.ar.valid := false.B
|
||||||
p.bits.ar.valid := false.B
|
port.io.bits.r.ready := false.B
|
||||||
p.bits.r.ready := false.B
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimDebug extends OverrideHarnessBinder({
|
class WithSimJTAGDebug extends HarnessBinder({
|
||||||
(system: HasPeripheryDebug, th: HasHarnessInstantiators, ports: Seq[Data]) => {
|
case (th: HasHarnessInstantiators, port: JTAGPort) => {
|
||||||
implicit val p: Parameters = GetSystemParameters(system)
|
|
||||||
ports.map {
|
|
||||||
case d: ClockedDMIIO =>
|
|
||||||
val dtm_success = WireInit(false.B)
|
|
||||||
when (dtm_success) { th.success := true.B }
|
|
||||||
val dtm = Module(new TestchipSimDTM).connect(th.harnessBinderClock, th.harnessBinderReset.asBool, d, dtm_success)
|
|
||||||
case j: JTAGChipIO =>
|
|
||||||
val dtm_success = WireInit(false.B)
|
val dtm_success = WireInit(false.B)
|
||||||
when (dtm_success) { th.success := true.B }
|
when (dtm_success) { th.success := true.B }
|
||||||
val jtag_wire = Wire(new JTAGIO)
|
val jtag_wire = Wire(new JTAGIO)
|
||||||
jtag_wire.TDO.data := j.TDO
|
jtag_wire.TDO.data := port.io.TDO
|
||||||
jtag_wire.TDO.driven := true.B
|
jtag_wire.TDO.driven := true.B
|
||||||
j.TCK := jtag_wire.TCK
|
port.io.TCK := jtag_wire.TCK
|
||||||
j.TMS := jtag_wire.TMS
|
port.io.TMS := jtag_wire.TMS
|
||||||
j.TDI := jtag_wire.TDI
|
port.io.TDI := jtag_wire.TDI
|
||||||
val jtag = Module(new SimJTAG(tickDelay=3))
|
val jtag = Module(new SimJTAG(tickDelay=3))
|
||||||
jtag.connect(jtag_wire, th.harnessBinderClock, th.harnessBinderReset.asBool, ~(th.harnessBinderReset.asBool), dtm_success)
|
jtag.connect(jtag_wire, th.harnessBinderClock, th.harnessBinderReset.asBool, ~(th.harnessBinderReset.asBool), dtm_success)
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithSimDMI extends HarnessBinder({
|
||||||
|
case (th: HasHarnessInstantiators, port: DMIPort) => {
|
||||||
|
val dtm_success = WireInit(false.B)
|
||||||
|
when (dtm_success) { th.success := true.B }
|
||||||
|
val dtm = Module(new TestchipSimDTM()(Parameters.empty)).connect(th.harnessBinderClock, th.harnessBinderReset.asBool, port.io, dtm_success)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTiedOffDebug extends OverrideHarnessBinder({
|
class WithTiedOffJTAG extends HarnessBinder({
|
||||||
(system: HasPeripheryDebug, th: HasHarnessInstantiators, ports: Seq[Data]) => {
|
case (th: HasHarnessInstantiators, port: JTAGPort) => {
|
||||||
ports.map {
|
port.io.TCK := true.B.asClock
|
||||||
case j: JTAGChipIO =>
|
port.io.TMS := true.B
|
||||||
j.TCK := true.B.asClock
|
port.io.TDI := true.B
|
||||||
j.TMS := true.B
|
|
||||||
j.TDI := true.B
|
|
||||||
case d: ClockedDMIIO =>
|
|
||||||
d.dmi.req.valid := false.B
|
|
||||||
d.dmi.req.bits := DontCare
|
|
||||||
d.dmi.resp.ready := true.B
|
|
||||||
d.dmiClock := false.B.asClock
|
|
||||||
d.dmiReset := true.B
|
|
||||||
case a: ClockedAPBBundle =>
|
|
||||||
a.pready := false.B
|
|
||||||
a.pslverr := false.B
|
|
||||||
a.prdata := 0.U
|
|
||||||
a.pduser := DontCare
|
|
||||||
a.clock := false.B.asClock
|
|
||||||
a.reset := true.B.asAsyncReset
|
|
||||||
a.psel := false.B
|
|
||||||
a.penable := false.B
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithTiedOffDMI extends HarnessBinder({
|
||||||
class WithSerialTLTiedOff extends OverrideHarnessBinder({
|
case (th: HasHarnessInstantiators, port: DMIPort) => {
|
||||||
(system: CanHavePeripheryTLSerial, th: HasHarnessInstantiators, ports: Seq[ClockedIO[SerialIO]]) => {
|
port.io.dmi.req.valid := false.B
|
||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
port.io.dmi.req.bits := DontCare
|
||||||
ports.map({ port =>
|
port.io.dmi.resp.ready := true.B
|
||||||
val bits = port.bits
|
port.io.dmiClock := false.B.asClock
|
||||||
if (DataMirror.directionOf(port.clock) == Direction.Input) {
|
port.io.dmiReset := true.B
|
||||||
port.clock := false.B.asClock
|
|
||||||
}
|
|
||||||
port.bits.out.ready := false.B
|
|
||||||
port.bits.in.valid := false.B
|
|
||||||
port.bits.in.bits := DontCare
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimTSIOverSerialTL extends OverrideHarnessBinder({
|
class WithSerialTLTiedOff extends HarnessBinder({
|
||||||
(system: CanHavePeripheryTLSerial, th: HasHarnessInstantiators, ports: Seq[ClockedIO[SerialIO]]) => {
|
case (th: HasHarnessInstantiators, port: SerialTLPort) => {
|
||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
if (DataMirror.directionOf(port.io.clock) == Direction.Input) {
|
||||||
ports.map({ port =>
|
port.io.clock := false.B.asClock
|
||||||
val bits = port.bits
|
|
||||||
if (DataMirror.directionOf(port.clock) == Direction.Input) {
|
|
||||||
port.clock := th.harnessBinderClock
|
|
||||||
}
|
}
|
||||||
val ram = TSIHarness.connectRAM(system.serdesser.get, bits, th.harnessBinderReset)
|
port.io.bits.out.ready := false.B
|
||||||
val success = SimTSI.connect(Some(ram.module.io.tsi), th.harnessBinderClock, th.harnessBinderReset.asBool)
|
port.io.bits.in.valid := false.B
|
||||||
|
port.io.bits.in.bits := DontCare
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithSimTSIOverSerialTL extends HarnessBinder({
|
||||||
|
case (th: HasHarnessInstantiators, port: SerialTLPort) => {
|
||||||
|
val bits = port.io.bits
|
||||||
|
if (DataMirror.directionOf(port.io.clock) == Direction.Input) {
|
||||||
|
port.io.clock := th.harnessBinderClock
|
||||||
|
}
|
||||||
|
val ram = LazyModule(new SerialRAM(port.serdesser)(port.serdesser.p))
|
||||||
|
Module(ram.module)
|
||||||
|
ram.module.io.ser <> port.io.bits
|
||||||
|
val tsi = Module(new SimTSI)
|
||||||
|
tsi.io.clock := th.harnessBinderClock
|
||||||
|
tsi.io.reset := th.harnessBinderReset
|
||||||
|
tsi.io.tsi <> ram.module.io.tsi
|
||||||
|
val exit = tsi.io.exit
|
||||||
|
val success = exit === 1.U
|
||||||
|
val error = exit >= 2.U
|
||||||
|
assert(!error, "*** FAILED *** (exit code = %d)\n", exit >> 1.U)
|
||||||
when (success) { th.success := true.B }
|
when (success) { th.success := true.B }
|
||||||
})
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimUARTToUARTTSI extends OverrideHarnessBinder({
|
class WithSimUARTToUARTTSI extends HarnessBinder({
|
||||||
(system: CanHavePeripheryUARTTSI, th: HasHarnessInstantiators, ports: Seq[UARTTSIIO]) => {
|
case (th: HasHarnessInstantiators, port: UARTPort) => {
|
||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
UARTAdapter.connect(Seq(port.io),
|
||||||
require(ports.size <= 1)
|
baudrate=port.io.c.initBaudRate,
|
||||||
ports.map { port => {
|
|
||||||
UARTAdapter.connect(Seq(port.uart),
|
|
||||||
baudrate=port.uartParams.initBaudRate,
|
|
||||||
clockFrequency=th.getHarnessBinderClockFreqHz.toInt,
|
clockFrequency=th.getHarnessBinderClockFreqHz.toInt,
|
||||||
forcePty=true)
|
forcePty=true)
|
||||||
assert(!port.dropped)
|
|
||||||
}}
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSimTSIToUARTTSI extends OverrideHarnessBinder({
|
class WithSimTSIToUARTTSI extends HarnessBinder({
|
||||||
(system: CanHavePeripheryUARTTSI, th: HasHarnessInstantiators, ports: Seq[UARTTSIIO]) => {
|
case (th: HasHarnessInstantiators, port: UARTTSIPort) => {
|
||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
|
||||||
require(ports.size <= 1)
|
|
||||||
ports.map({ port =>
|
|
||||||
val freq = th.getHarnessBinderClockFreqHz.toInt
|
val freq = th.getHarnessBinderClockFreqHz.toInt
|
||||||
val uart_to_serial = Module(new UARTToSerial(freq, port.uartParams))
|
val uart_to_serial = Module(new UARTToSerial(freq, port.io.uart.c))
|
||||||
val serial_width_adapter = Module(new SerialWidthAdapter(8, TSI.WIDTH))
|
val serial_width_adapter = Module(new SerialWidthAdapter(8, TSI.WIDTH))
|
||||||
val success = SimTSI.connect(Some(TSIIO(serial_width_adapter.io.wide)), th.harnessBinderClock, th.harnessBinderReset)
|
val success = SimTSI.connect(Some(TSIIO(serial_width_adapter.io.wide)), th.harnessBinderClock, th.harnessBinderReset)
|
||||||
when (success) { th.success := true.B }
|
when (success) { th.success := true.B }
|
||||||
assert(!uart_to_serial.io.dropped)
|
assert(!uart_to_serial.io.dropped)
|
||||||
serial_width_adapter.io.narrow.flipConnect(uart_to_serial.io.serial)
|
serial_width_adapter.io.narrow.flipConnect(uart_to_serial.io.serial)
|
||||||
uart_to_serial.io.uart.rxd := port.uart.txd
|
uart_to_serial.io.uart.rxd := port.io.uart.txd
|
||||||
port.uart.rxd := uart_to_serial.io.uart.txd
|
port.io.uart.rxd := uart_to_serial.io.uart.txd
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithTraceGenSuccess extends HarnessBinder({
|
||||||
|
case (th: HasHarnessInstantiators, port: SuccessPort) => {
|
||||||
|
when (port.io) { th.success := true.B }
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithCospike extends HarnessBinder({
|
||||||
|
case (th: HasHarnessInstantiators, port: TracePort) => {
|
||||||
|
port.io.traces.zipWithIndex.map(t => SpikeCosim(t._1, t._2, port.cosimCfg))
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class WithTraceGenSuccess extends OverrideHarnessBinder({
|
class WithCustomBootPinPlusArg extends HarnessBinder({
|
||||||
(system: TraceGenSystemModuleImp, th: HasHarnessInstantiators, ports: Seq[Bool]) => {
|
case (th: HasHarnessInstantiators, port: CustomBootPort) => {
|
||||||
ports.map { p => when (p) { th.success := true.B } }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithCospike extends ComposeHarnessBinder({
|
|
||||||
(system: CanHaveTraceIOModuleImp, th: HasHarnessInstantiators, ports: Seq[TraceOutputTop]) => {
|
|
||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
|
||||||
val chipyardSystem = system.asInstanceOf[ChipyardSystemModule[_]].outer.asInstanceOf[ChipyardSystem]
|
|
||||||
val tiles = chipyardSystem.tiles
|
|
||||||
val cfg = SpikeCosimConfig(
|
|
||||||
isa = tiles.headOption.map(_.isaDTS).getOrElse(""),
|
|
||||||
vlen = tiles.headOption.map(_.tileParams.core.vLen).getOrElse(0),
|
|
||||||
priv = tiles.headOption.map(t => if (t.usingUser) "MSU" else if (t.usingSupervisor) "MS" else "M").getOrElse(""),
|
|
||||||
mem0_base = p(ExtMem).map(_.master.base).getOrElse(BigInt(0)),
|
|
||||||
mem0_size = p(ExtMem).map(_.master.size).getOrElse(BigInt(0)),
|
|
||||||
pmpregions = tiles.headOption.map(_.tileParams.core.nPMPs).getOrElse(0),
|
|
||||||
nharts = tiles.size,
|
|
||||||
bootrom = chipyardSystem.bootROM.map(_.module.contents.toArray.mkString(" ")).getOrElse(""),
|
|
||||||
has_dtm = p(ExportDebug).protocols.contains(DMI) // assume that exposing clockeddmi means we will connect SimDTM
|
|
||||||
)
|
|
||||||
ports.map { p => p.traces.zipWithIndex.map(t => SpikeCosim(t._1, t._2, cfg)) }
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
|
|
||||||
class WithCustomBootPinPlusArg extends OverrideHarnessBinder({
|
|
||||||
(system: CanHavePeripheryCustomBootPin, th: HasHarnessInstantiators, ports: Seq[Bool]) => {
|
|
||||||
val pin = PlusArg("custom_boot_pin", width=1)
|
val pin = PlusArg("custom_boot_pin", width=1)
|
||||||
ports.foreach(_ := pin)
|
port.io := pin
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithClockFromHarness extends HarnessBinder({
|
||||||
class WithClockAndResetFromHarness extends OverrideHarnessBinder({
|
case (th: HasHarnessInstantiators, port: ClockPort) => {
|
||||||
(system: HasChipyardPRCI, th: HasHarnessInstantiators, ports: Seq[Data]) => {
|
|
||||||
implicit val p = GetSystemParameters(system)
|
|
||||||
val clocks = ports.collect { case c: ClockWithFreq => c }
|
|
||||||
// DOC include start: HarnessClockInstantiatorEx
|
// DOC include start: HarnessClockInstantiatorEx
|
||||||
ports.map ({
|
port.io := th.harnessClockInstantiator.requestClockMHz(s"clock_${port.freqMHz}MHz", port.freqMHz)
|
||||||
case c: ClockWithFreq => {
|
|
||||||
val clock = th.harnessClockInstantiator.requestClockMHz(s"clock_${c.freqMHz.toInt}MHz", c.freqMHz)
|
|
||||||
c.clock := clock
|
|
||||||
}
|
|
||||||
case r: AsyncReset => r := th.referenceReset.asAsyncReset
|
|
||||||
})
|
|
||||||
// DOC include end: HarnessClockInstantiatorEx
|
// DOC include end: HarnessClockInstantiatorEx
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
class WithResetFromHarness extends HarnessBinder({
|
||||||
|
case (th: HasHarnessInstantiators, port: ResetPort) => {
|
||||||
|
port.io := th.referenceReset.asAsyncReset
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -63,7 +63,7 @@ trait HasHarnessInstantiators {
|
|||||||
|
|
||||||
val supportsMultiChip: Boolean = false
|
val supportsMultiChip: Boolean = false
|
||||||
|
|
||||||
private val chipParameters = p(MultiChipNChips) match {
|
val chipParameters = p(MultiChipNChips) match {
|
||||||
case Some(n) => (0 until n).map { i => p(MultiChipParameters(i)).alterPartial {
|
case Some(n) => (0 until n).map { i => p(MultiChipParameters(i)).alterPartial {
|
||||||
case TargetDirKey => p(TargetDirKey) // hacky fix
|
case TargetDirKey => p(TargetDirKey) // hacky fix
|
||||||
case MultiChipIdx => i
|
case MultiChipIdx => i
|
||||||
@@ -83,7 +83,7 @@ trait HasHarnessInstantiators {
|
|||||||
|
|
||||||
withClockAndReset (harnessBinderClock, harnessBinderReset) {
|
withClockAndReset (harnessBinderClock, harnessBinderReset) {
|
||||||
lazyDuts.zipWithIndex.foreach {
|
lazyDuts.zipWithIndex.foreach {
|
||||||
case (d: HasIOBinders, i: Int) => ApplyHarnessBinders(this, d.lazySystem, d.portMap)(chipParameters(i))
|
case (d: HasIOBinders, i: Int) => ApplyHarnessBinders(this, d.portMap.values.flatten.toSeq)(chipParameters(i))
|
||||||
case _ =>
|
case _ =>
|
||||||
}
|
}
|
||||||
ApplyMultiHarnessBinders(this, lazyDuts)
|
ApplyMultiHarnessBinders(this, lazyDuts)
|
||||||
|
|||||||
@@ -2,6 +2,7 @@ package chipyard.harness
|
|||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.util._
|
import chisel3.util._
|
||||||
|
import chisel3.experimental.{DataMirror, Direction}
|
||||||
|
|
||||||
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImpLike}
|
||||||
@@ -12,67 +13,58 @@ import freechips.rocketchip.util._
|
|||||||
import testchipip._
|
import testchipip._
|
||||||
|
|
||||||
import chipyard._
|
import chipyard._
|
||||||
import chipyard.clocking.{HasChipyardPRCI, ClockWithFreq}
|
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasIOBinders, Port, SerialTLPort}
|
||||||
import chipyard.iobinders.{GetSystemParameters, JTAGChipIO, HasIOBinders}
|
|
||||||
|
|
||||||
import scala.reflect.{ClassTag}
|
import scala.reflect.{ClassTag}
|
||||||
|
|
||||||
case class MultiHarnessBinders(c0: Int, c1: Int) extends Field[MultiHarnessBinderMap](MultiHarnessBinderMapDefault)
|
case class MultiHarnessBinders(chip0: Int, chip1: Int) extends Field[Seq[MultiHarnessBinderFunction]](Nil)
|
||||||
|
|
||||||
class MultiHarnessBinder[T0, T1, S <: HasHarnessInstantiators, U0 <: Data, U1 <: Data]
|
|
||||||
(chip0: Int, chip1: Int, fn: => (T0, T1, S, Seq[U0], Seq[U1]) => Unit)
|
|
||||||
(implicit tag0: ClassTag[T0], tag1: ClassTag[T1], thtag: ClassTag[S], ptag0: ClassTag[U0], ptag1: ClassTag[U1])
|
|
||||||
extends Config((site, here, up) => {
|
|
||||||
// Override any HarnessBinders for chip0/chip1
|
|
||||||
case MultiChipParameters(`chip0`) => new Config(
|
|
||||||
new OverrideHarnessBinder[T0, S, U0]((system: T0, th: S, ports: Seq[U0]) => Nil) ++
|
|
||||||
up(MultiChipParameters(chip0))
|
|
||||||
)
|
|
||||||
case MultiChipParameters(`chip1`) => new Config(
|
|
||||||
new OverrideHarnessBinder[T1, S, U1]((system: T1, th: S, ports: Seq[U1]) => Nil) ++
|
|
||||||
up(MultiChipParameters(chip1))
|
|
||||||
)
|
|
||||||
// Set the multiharnessbinder key
|
|
||||||
case MultiHarnessBinders(`chip0`, `chip1`) => up(MultiHarnessBinders(chip0, chip1)) +
|
|
||||||
((tag0.runtimeClass.toString, tag1.runtimeClass.toString) ->
|
|
||||||
((c0: Any, c1: Any, th: HasHarnessInstantiators, ports0: Seq[Data], ports1: Seq[Data]) => {
|
|
||||||
val pts0 = ports0.map(_.asInstanceOf[U0])
|
|
||||||
val pts1 = ports1.map(_.asInstanceOf[U1])
|
|
||||||
require(pts0.size == pts1.size)
|
|
||||||
(c0, c1, th) match {
|
|
||||||
case (c0: T0, c1: T1, th: S) => fn(c0, c1, th, pts0, pts1)
|
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
})
|
|
||||||
)
|
|
||||||
})
|
|
||||||
|
|
||||||
object ApplyMultiHarnessBinders {
|
object ApplyMultiHarnessBinders {
|
||||||
def apply(th: HasHarnessInstantiators, chips: Seq[LazyModule])(implicit p: Parameters): Unit = {
|
def apply(th: HasHarnessInstantiators, chips: Seq[LazyModule])(implicit p: Parameters): Unit = {
|
||||||
Seq.tabulate(chips.size, chips.size) { case (i, j) => if (i != j) {
|
Seq.tabulate(chips.size, chips.size) { case (i, j) => if (i != j) {
|
||||||
(chips(i), chips(j)) match {
|
(chips(i), chips(j)) match {
|
||||||
case (l0: HasIOBinders, l1: HasIOBinders) => p(MultiHarnessBinders(i, j)).foreach {
|
case (l0: HasIOBinders, l1: HasIOBinders) => p(MultiHarnessBinders(i, j)).foreach { f =>
|
||||||
case ((s0, s1), f) => {
|
f(l0.portMap.values.flatten.toSeq, l1.portMap.values.flatten.toSeq)
|
||||||
f(l0.lazySystem , l1.lazySystem , th, l0.portMap(s0), l1.portMap(s1))
|
|
||||||
f(l0.lazySystem.module, l1.lazySystem.module, th, l0.portMap(s0), l1.portMap(s1))
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
}}
|
}}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class WithMultiChipSerialTL(chip0: Int, chip1: Int) extends MultiHarnessBinder(chip0, chip1, (
|
class MultiHarnessBinder[T <: Port[_]](
|
||||||
(system0: CanHavePeripheryTLSerial, system1: CanHavePeripheryTLSerial,
|
chip0: Int, chip1: Int,
|
||||||
th: HasHarnessInstantiators,
|
chip0portFn: T => Boolean, chip1portFn: T => Boolean,
|
||||||
ports0: Seq[ClockedIO[SerialIO]], ports1: Seq[ClockedIO[SerialIO]]
|
connectFn: (T, T) => Unit
|
||||||
) => {
|
)(implicit tag: ClassTag[T]) extends Config((site, here, up) => {
|
||||||
require(ports0.size == ports1.size)
|
// Override any HarnessBinders for chip0/chip1
|
||||||
(ports0 zip ports1).map { case (l, r) =>
|
case MultiChipParameters(`chip0`) => new Config(
|
||||||
l.clock <> r.clock
|
new HarnessBinder({case (th, port: T) if chip0portFn(port) => }) ++ up(MultiChipParameters(chip0))
|
||||||
require(l.bits.w == r.bits.w)
|
)
|
||||||
l.bits.flipConnect(r.bits)
|
case MultiChipParameters(`chip1`) => new Config(
|
||||||
|
new HarnessBinder({case (th, port: T) if chip1portFn(port) => }) ++ up(MultiChipParameters(chip1))
|
||||||
|
)
|
||||||
|
// Set the multiharnessbinder key
|
||||||
|
case MultiHarnessBinders(`chip0`, `chip1`) => up(MultiHarnessBinders(chip0, chip1)) :+ {
|
||||||
|
((chip0Ports: Seq[Port[_]], chip1Ports: Seq[Port[_]]) => {
|
||||||
|
val chip0Port: Seq[T] = chip0Ports.collect { case (p: T) if chip0portFn(p) => p }
|
||||||
|
val chip1Port: Seq[T] = chip1Ports.collect { case (p: T) if chip1portFn(p) => p }
|
||||||
|
require(chip0Port.size == 1 && chip1Port.size == 1)
|
||||||
|
connectFn(chip0Port(0), chip1Port(0))
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
|
class WithMultiChipSerialTL(chip0: Int, chip1: Int, chip0portId: Int = 0, chip1portId: Int = 0) extends MultiHarnessBinder[SerialTLPort](
|
||||||
|
chip0, chip1,
|
||||||
|
(p0: SerialTLPort) => p0.portId == chip0portId,
|
||||||
|
(p1: SerialTLPort) => p1.portId == chip1portId,
|
||||||
|
(p0: SerialTLPort, p1: SerialTLPort) => {
|
||||||
|
(DataMirror.directionOf(p0.io.clock), DataMirror.directionOf(p1.io.clock)) match {
|
||||||
|
case (Direction.Input, Direction.Output) => p0.io.clock := p1.io.clock
|
||||||
|
case (Direction.Output, Direction.Input) => p1.io.clock := p0.io.clock
|
||||||
}
|
}
|
||||||
))
|
p0.io.bits.in <> p1.io.bits.out
|
||||||
|
p1.io.bits.in <> p0.io.bits.out
|
||||||
|
}
|
||||||
|
)
|
||||||
|
|||||||
@@ -5,13 +5,7 @@ import scala.collection.immutable.ListMap
|
|||||||
|
|
||||||
package object harness
|
package object harness
|
||||||
{
|
{
|
||||||
type HarnessBinderFunction = (Any, HasHarnessInstantiators, Seq[Data]) => Unit
|
import chipyard.iobinders.Port
|
||||||
type HarnessBinderMap = Map[String, HarnessBinderFunction]
|
type HarnessBinderFunction = PartialFunction[(HasHarnessInstantiators, Port[_]), Unit]
|
||||||
def HarnessBinderMapDefault: HarnessBinderMap = (new ListMap[String, HarnessBinderFunction])
|
type MultiHarnessBinderFunction = (Seq[Port[_]], Seq[Port[_]]) => Unit
|
||||||
.withDefaultValue((t: Any, th: HasHarnessInstantiators, d: Seq[Data]) => ())
|
|
||||||
|
|
||||||
type MultiHarnessBinderFunction = (Any, Any, HasHarnessInstantiators, Seq[Data], Seq[Data]) => Unit
|
|
||||||
type MultiHarnessBinderMap = Map[(String, String), MultiHarnessBinderFunction]
|
|
||||||
def MultiHarnessBinderMapDefault: MultiHarnessBinderMap = (new ListMap[(String, String), MultiHarnessBinderFunction])
|
|
||||||
.withDefaultValue((_: Any, _: Any, _: HasHarnessInstantiators, _: Seq[Data], _: Seq[Data]) => ())
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,18 +18,19 @@ import freechips.rocketchip.tilelink.{TLBundle}
|
|||||||
import sifive.blocks.devices.gpio._
|
import sifive.blocks.devices.gpio._
|
||||||
import sifive.blocks.devices.uart._
|
import sifive.blocks.devices.uart._
|
||||||
import sifive.blocks.devices.spi._
|
import sifive.blocks.devices.spi._
|
||||||
|
import sifive.blocks.devices.i2c._
|
||||||
import tracegen.{TraceGenSystemModuleImp}
|
import tracegen.{TraceGenSystemModuleImp}
|
||||||
|
|
||||||
import barstools.iocell.chisel._
|
import barstools.iocell.chisel._
|
||||||
|
|
||||||
import testchipip._
|
import testchipip._
|
||||||
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly}
|
||||||
import chipyard.{CanHaveMasterTLMemPort}
|
import chipyard.{CanHaveMasterTLMemPort, ChipyardSystem, ChipyardSystemModule}
|
||||||
|
|
||||||
import scala.reflect.{ClassTag}
|
import scala.reflect.{ClassTag}
|
||||||
|
|
||||||
object IOBinderTypes {
|
object IOBinderTypes {
|
||||||
type IOBinderTuple = (Seq[Data], Seq[IOCell])
|
type IOBinderTuple = (Seq[Port[_]], Seq[IOCell])
|
||||||
type IOBinderFunction = (Boolean, => Any) => ModuleValue[IOBinderTuple]
|
type IOBinderFunction = (Boolean, => Any) => ModuleValue[IOBinderTuple]
|
||||||
}
|
}
|
||||||
import IOBinderTypes._
|
import IOBinderTypes._
|
||||||
@@ -82,7 +83,7 @@ abstract trait HasIOBinders { this: LazyModule =>
|
|||||||
|
|
||||||
InModuleBody {
|
InModuleBody {
|
||||||
if (p(DontTouchIOBindersPorts)) {
|
if (p(DontTouchIOBindersPorts)) {
|
||||||
portMap.values.foreach(_.foreach(dontTouch(_)))
|
portMap.values.flatten.foreach { case (port: Port[Data]) => dontTouch(port.io) }
|
||||||
}
|
}
|
||||||
|
|
||||||
println("IOCells generated by IOBinders:")
|
println("IOCells generated by IOBinders:")
|
||||||
@@ -171,29 +172,72 @@ class WithGPIOCells extends OverrideIOBinder({
|
|||||||
iocell.io.ie := pin.o.ie
|
iocell.io.ie := pin.o.ie
|
||||||
pin.i.ival := iocell.io.i
|
pin.i.ival := iocell.io.i
|
||||||
iocell.io.pad <> g
|
iocell.io.pad <> g
|
||||||
(g, iocell)
|
(GPIOPort(g, i, j), iocell)
|
||||||
}).unzip
|
}).unzip
|
||||||
}).unzip
|
}).unzip
|
||||||
val ports: Seq[Analog] = ports2d.flatten
|
(ports2d.flatten, cells2d.flatten)
|
||||||
(ports, cells2d.flatten)
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithGPIOPunchthrough extends OverrideIOBinder({
|
||||||
|
(system: HasPeripheryGPIOModuleImp) => {
|
||||||
|
val ports = system.gpio.zipWithIndex.map { case (gpio, i) =>
|
||||||
|
val io_gpio = IO(gpio.cloneType).suggestName(s"gpio_$i")
|
||||||
|
io_gpio <> gpio
|
||||||
|
GPIOPinsPort(io_gpio, i)
|
||||||
|
}
|
||||||
|
(ports, Nil)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithI2CPunchthrough extends OverrideIOBinder({
|
||||||
|
(system: HasPeripheryI2CModuleImp) => {
|
||||||
|
val ports = system.i2c.zipWithIndex.map { case (i2c, i) =>
|
||||||
|
val io_i2c = IO(i2c.cloneType).suggestName(s"i2c_$i")
|
||||||
|
io_i2c <> i2c
|
||||||
|
I2CPort(i2c)
|
||||||
|
}
|
||||||
|
(ports, Nil)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
// DOC include start: WithUARTIOCells
|
// DOC include start: WithUARTIOCells
|
||||||
class WithUARTIOCells extends OverrideIOBinder({
|
class WithUARTIOCells extends OverrideIOBinder({
|
||||||
(system: HasPeripheryUARTModuleImp) => {
|
(system: HasPeripheryUARTModuleImp) => {
|
||||||
val (ports: Seq[UARTPortIO], cells2d) = system.uart.zipWithIndex.map({ case (u, i) =>
|
val (ports: Seq[UARTPort], cells2d) = system.uart.zipWithIndex.map({ case (u, i) =>
|
||||||
val (port, ios) = IOCell.generateIOFromSignal(u, s"uart_${i}", system.p(IOCellKey), abstractResetAsAsync = true)
|
val (port, ios) = IOCell.generateIOFromSignal(u, s"uart_${i}", system.p(IOCellKey), abstractResetAsAsync = true)
|
||||||
(port, ios)
|
val where = PBUS // TODO fix
|
||||||
|
val bus = system.outer.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(where)
|
||||||
|
val freqMHz = bus.dtsFrequency.get / 1000000
|
||||||
|
(UARTPort(port, i, freqMHz.toInt), ios)
|
||||||
}).unzip
|
}).unzip
|
||||||
(ports, cells2d.flatten)
|
(ports, cells2d.flatten)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
// DOC include end: WithUARTIOCells
|
// DOC include end: WithUARTIOCells
|
||||||
|
|
||||||
class WithSPIIOCells extends OverrideIOBinder({
|
class WithSPIIOPunchthrough extends OverrideLazyIOBinder({
|
||||||
|
(system: HasPeripherySPI) => {
|
||||||
|
// attach resource to 1st SPI
|
||||||
|
if (system.tlSpiNodes.size > 0) ResourceBinding {
|
||||||
|
Resource(new MMCDevice(system.tlSpiNodes.head.device, 1), "reg").bind(ResourceAddress(0))
|
||||||
|
}
|
||||||
|
InModuleBody {
|
||||||
|
val spi = system.asInstanceOf[BaseSubsystem].module.asInstanceOf[HasPeripherySPIBundle].spi
|
||||||
|
val ports = spi.zipWithIndex.map({ case (s, i) =>
|
||||||
|
val io_spi = IO(s.cloneType).suggestName(s"spi_$i")
|
||||||
|
io_spi <> s
|
||||||
|
SPIPort(io_spi)
|
||||||
|
})
|
||||||
|
(ports, Nil)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
|
||||||
|
class WithSPIFlashIOCells extends OverrideIOBinder({
|
||||||
(system: HasPeripherySPIFlashModuleImp) => {
|
(system: HasPeripherySPIFlashModuleImp) => {
|
||||||
val (ports: Seq[SPIChipIO], cells2d) = system.qspi.zipWithIndex.map({ case (s, i) =>
|
val (ports: Seq[SPIFlashPort], cells2d) = system.qspi.zipWithIndex.map({ case (s, i) =>
|
||||||
|
|
||||||
val name = s"spi_${i}"
|
val name = s"spi_${i}"
|
||||||
val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(name)
|
val port = IO(new SPIChipIO(s.c.csWidth)).suggestName(name)
|
||||||
val iocellBase = s"iocell_${name}"
|
val iocellBase = s"iocell_${name}"
|
||||||
@@ -213,7 +257,7 @@ class WithSPIIOCells extends OverrideIOBinder({
|
|||||||
iocell
|
iocell
|
||||||
}
|
}
|
||||||
|
|
||||||
(port, dqIOs ++ csIOs ++ sckIOs)
|
(SPIFlashPort(port, system.p(PeripherySPIFlashKey)(i), i), dqIOs ++ csIOs ++ sckIOs)
|
||||||
}).unzip
|
}).unzip
|
||||||
(ports, cells2d.flatten)
|
(ports, cells2d.flatten)
|
||||||
}
|
}
|
||||||
@@ -223,7 +267,7 @@ class WithExtInterruptIOCells extends OverrideIOBinder({
|
|||||||
(system: HasExtInterruptsModuleImp) => {
|
(system: HasExtInterruptsModuleImp) => {
|
||||||
if (system.outer.nExtInterrupts > 0) {
|
if (system.outer.nExtInterrupts > 0) {
|
||||||
val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey), abstractResetAsAsync = true)
|
val (port: UInt, cells) = IOCell.generateIOFromSignal(system.interrupts, "ext_interrupts", system.p(IOCellKey), abstractResetAsAsync = true)
|
||||||
(Seq(port), cells)
|
(Seq(ExtIntPort(port)), cells)
|
||||||
} else {
|
} else {
|
||||||
system.interrupts := DontCare // why do I have to drive this 0-wide wire???
|
system.interrupts := DontCare // why do I have to drive this 0-wide wire???
|
||||||
(Nil, Nil)
|
(Nil, Nil)
|
||||||
@@ -273,7 +317,8 @@ class WithDebugIOCells extends OverrideLazyIOBinder({
|
|||||||
|
|
||||||
// Add IOCells for the DMI/JTAG/APB ports
|
// Add IOCells for the DMI/JTAG/APB ports
|
||||||
val dmiTuple = debug.clockeddmi.map { d =>
|
val dmiTuple = debug.clockeddmi.map { d =>
|
||||||
IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = true)
|
val (port, cells) = IOCell.generateIOFromSignal(d, "dmi", p(IOCellKey), abstractResetAsAsync = true)
|
||||||
|
(DMIPort(port), cells)
|
||||||
}
|
}
|
||||||
|
|
||||||
val jtagTuple = debug.systemjtag.map { j =>
|
val jtagTuple = debug.systemjtag.map { j =>
|
||||||
@@ -282,14 +327,13 @@ class WithDebugIOCells extends OverrideLazyIOBinder({
|
|||||||
j.jtag.TMS := jtag_wire.TMS
|
j.jtag.TMS := jtag_wire.TMS
|
||||||
j.jtag.TDI := jtag_wire.TDI
|
j.jtag.TDI := jtag_wire.TDI
|
||||||
jtag_wire.TDO := j.jtag.TDO.data
|
jtag_wire.TDO := j.jtag.TDO.data
|
||||||
IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true)
|
val (port, cells) = IOCell.generateIOFromSignal(jtag_wire, "jtag", p(IOCellKey), abstractResetAsAsync = true)
|
||||||
|
(JTAGPort(port), cells)
|
||||||
}
|
}
|
||||||
|
|
||||||
val apbTuple = debug.apb.map { a =>
|
require(!debug.apb.isDefined)
|
||||||
IOCell.generateIOFromSignal(a, "apb", p(IOCellKey), abstractResetAsAsync = true)
|
|
||||||
}
|
|
||||||
|
|
||||||
val allTuples = (dmiTuple ++ jtagTuple ++ apbTuple).toSeq
|
val allTuples = (dmiTuple ++ jtagTuple).toSeq
|
||||||
(allTuples.map(_._1).toSeq, allTuples.flatMap(_._2).toSeq)
|
(allTuples.map(_._1).toSeq, allTuples.flatMap(_._2).toSeq)
|
||||||
}).getOrElse((Nil, Nil))
|
}).getOrElse((Nil, Nil))
|
||||||
}}}
|
}}}
|
||||||
@@ -297,20 +341,26 @@ class WithDebugIOCells extends OverrideLazyIOBinder({
|
|||||||
})
|
})
|
||||||
|
|
||||||
class WithSerialTLIOCells extends OverrideIOBinder({
|
class WithSerialTLIOCells extends OverrideIOBinder({
|
||||||
(system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s =>
|
(system: CanHavePeripheryTLSerial) => {
|
||||||
|
val (ports, cells) = system.serial_tl.zipWithIndex.map({ case (s, id) =>
|
||||||
val sys = system.asInstanceOf[BaseSubsystem]
|
val sys = system.asInstanceOf[BaseSubsystem]
|
||||||
val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey), abstractResetAsAsync = true)
|
val (port, cells) = IOCell.generateIOFromSignal(s.getWrappedValue, "serial_tl", sys.p(IOCellKey), abstractResetAsAsync = true)
|
||||||
(Seq(port), cells)
|
(SerialTLPort(port, sys.p(SerialTLKey).get, system.serdesser.get, id), cells)
|
||||||
}).getOrElse((Nil, Nil))
|
}).unzip
|
||||||
|
(ports.toSeq, cells.flatten.toSeq)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithSerialTLPunchthrough extends OverrideIOBinder({
|
class WithSerialTLPunchthrough extends OverrideIOBinder({
|
||||||
(system: CanHavePeripheryTLSerial) => system.serial_tl.map({ s =>
|
(system: CanHavePeripheryTLSerial) => {
|
||||||
|
val (ports, cells) = system.serial_tl.zipWithIndex.map({ case (s, id) =>
|
||||||
val sys = system.asInstanceOf[BaseSubsystem]
|
val sys = system.asInstanceOf[BaseSubsystem]
|
||||||
val port = IO(s.getWrappedValue.cloneType)
|
val port = IO(s.getWrappedValue.cloneType)
|
||||||
port <> s.getWrappedValue
|
port <> s.getWrappedValue
|
||||||
(Seq(port), Nil)
|
(SerialTLPort(port, sys.p(SerialTLKey).get, system.serdesser.get, id), Nil)
|
||||||
}).getOrElse((Nil, Nil))
|
}).unzip
|
||||||
|
(ports.toSeq, cells.flatten.toSeq)
|
||||||
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({
|
class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({
|
||||||
@@ -321,12 +371,11 @@ class WithAXI4MemPunchthrough extends OverrideLazyIOBinder({
|
|||||||
def clockBundle = clockSinkNode.get.in.head._1
|
def clockBundle = clockSinkNode.get.in.head._1
|
||||||
|
|
||||||
InModuleBody {
|
InModuleBody {
|
||||||
val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = system.mem_axi4.zipWithIndex.map({ case (m, i) =>
|
val ports: Seq[AXI4MemPort] = system.mem_axi4.zipWithIndex.map({ case (m, i) =>
|
||||||
val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}")
|
val port = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mem_${i}")
|
||||||
p.bits <> m
|
port.bits <> m
|
||||||
p.clock := clockBundle.clock
|
port.clock := clockBundle.clock
|
||||||
p.reset := clockBundle.reset
|
AXI4MemPort(port, p(ExtMem).get, system.memAXI4Node.edges.in(i), p(MemoryBusKey).dtsFrequency.get.toInt)
|
||||||
p
|
|
||||||
}).toSeq
|
}).toSeq
|
||||||
(ports, Nil)
|
(ports, Nil)
|
||||||
}
|
}
|
||||||
@@ -341,12 +390,11 @@ class WithAXI4MMIOPunchthrough extends OverrideLazyIOBinder({
|
|||||||
def clockBundle = clockSinkNode.get.in.head._1
|
def clockBundle = clockSinkNode.get.in.head._1
|
||||||
|
|
||||||
InModuleBody {
|
InModuleBody {
|
||||||
val ports: Seq[ClockedAndResetIO[AXI4Bundle]] = system.mmio_axi4.zipWithIndex.map({ case (m, i) =>
|
val ports: Seq[AXI4MMIOPort] = system.mmio_axi4.zipWithIndex.map({ case (m, i) =>
|
||||||
val p = IO(new ClockedAndResetIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}")
|
val port = IO(new ClockedIO(DataMirror.internal.chiselTypeClone[AXI4Bundle](m))).suggestName(s"axi4_mmio_${i}")
|
||||||
p.bits <> m
|
port.bits <> m
|
||||||
p.clock := clockBundle.clock
|
port.clock := clockBundle.clock
|
||||||
p.reset := clockBundle.reset
|
AXI4MMIOPort(port, p(ExtBus).get, system.mmioAXI4Node.edges.in(i))
|
||||||
p
|
|
||||||
}).toSeq
|
}).toSeq
|
||||||
(ports, Nil)
|
(ports, Nil)
|
||||||
}
|
}
|
||||||
@@ -361,11 +409,11 @@ class WithL2FBusAXI4Punchthrough extends OverrideLazyIOBinder({
|
|||||||
def clockBundle = clockSinkNode.get.in.head._1
|
def clockBundle = clockSinkNode.get.in.head._1
|
||||||
|
|
||||||
InModuleBody {
|
InModuleBody {
|
||||||
val ports: Seq[ClockedIO[AXI4Bundle]] = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) =>
|
val ports: Seq[AXI4InPort] = system.l2_frontend_bus_axi4.zipWithIndex.map({ case (m, i) =>
|
||||||
val p = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}")
|
val port = IO(new ClockedIO(Flipped(DataMirror.internal.chiselTypeClone[AXI4Bundle](m)))).suggestName(s"axi4_fbus_${i}")
|
||||||
m <> p.bits
|
m <> port.bits
|
||||||
p.clock := clockBundle.clock
|
port.clock := clockBundle.clock
|
||||||
p
|
AXI4InPort(port, p(ExtIn).get)
|
||||||
}).toSeq
|
}).toSeq
|
||||||
(ports, Nil)
|
(ports, Nil)
|
||||||
}
|
}
|
||||||
@@ -374,10 +422,12 @@ class WithL2FBusAXI4Punchthrough extends OverrideLazyIOBinder({
|
|||||||
|
|
||||||
class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({
|
class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({
|
||||||
(system: CanHavePeripheryBlockDevice) => {
|
(system: CanHavePeripheryBlockDevice) => {
|
||||||
val ports: Seq[ClockedIO[BlockDeviceIO]] = system.bdev.map({ bdev =>
|
val ports: Seq[BlockDevicePort] = system.bdev.map({ bdev =>
|
||||||
val p = IO(new ClockedIO(new BlockDeviceIO()(GetSystemParameters(system)))).suggestName("blockdev")
|
val p = GetSystemParameters(system)
|
||||||
p <> bdev
|
val bdParams = p(BlockDeviceKey).get
|
||||||
p
|
val port = IO(new ClockedIO(new BlockDeviceIO(bdParams))).suggestName("blockdev")
|
||||||
|
port <> bdev
|
||||||
|
BlockDevicePort(port, bdParams)
|
||||||
}).toSeq
|
}).toSeq
|
||||||
(ports, Nil)
|
(ports, Nil)
|
||||||
}
|
}
|
||||||
@@ -385,10 +435,11 @@ class WithBlockDeviceIOPunchthrough extends OverrideIOBinder({
|
|||||||
|
|
||||||
class WithNICIOPunchthrough extends OverrideIOBinder({
|
class WithNICIOPunchthrough extends OverrideIOBinder({
|
||||||
(system: CanHavePeripheryIceNIC) => {
|
(system: CanHavePeripheryIceNIC) => {
|
||||||
val ports: Seq[ClockedIO[NICIOvonly]] = system.icenicOpt.map({ n =>
|
val ports: Seq[NICPort] = system.icenicOpt.map({ n =>
|
||||||
val p = IO(new ClockedIO(new NICIOvonly)).suggestName("nic")
|
val p = GetSystemParameters(system)
|
||||||
p <> n
|
val port = IO(new ClockedIO(new NICIOvonly)).suggestName("nic")
|
||||||
p
|
port <> n
|
||||||
|
NICPort(port, p(NICKey).get)
|
||||||
}).toSeq
|
}).toSeq
|
||||||
(ports, Nil)
|
(ports, Nil)
|
||||||
}
|
}
|
||||||
@@ -398,16 +449,30 @@ class WithTraceGenSuccessPunchthrough extends OverrideIOBinder({
|
|||||||
(system: TraceGenSystemModuleImp) => {
|
(system: TraceGenSystemModuleImp) => {
|
||||||
val success: Bool = IO(Output(Bool())).suggestName("success")
|
val success: Bool = IO(Output(Bool())).suggestName("success")
|
||||||
success := system.success
|
success := system.success
|
||||||
(Seq(success), Nil)
|
(Seq(SuccessPort(success)), Nil)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTraceIOPunchthrough extends OverrideIOBinder({
|
class WithTraceIOPunchthrough extends OverrideIOBinder({
|
||||||
(system: CanHaveTraceIOModuleImp) => {
|
(system: CanHaveTraceIOModuleImp) => {
|
||||||
val ports: Option[TraceOutputTop] = system.traceIO.map { t =>
|
val ports: Option[TracePort] = system.traceIO.map { t =>
|
||||||
val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace")
|
val trace = IO(DataMirror.internal.chiselTypeClone[TraceOutputTop](t)).suggestName("trace")
|
||||||
trace <> t
|
trace <> t
|
||||||
trace
|
val p = GetSystemParameters(system)
|
||||||
|
val chipyardSystem = system.asInstanceOf[ChipyardSystemModule[_]].outer.asInstanceOf[ChipyardSystem]
|
||||||
|
val tiles = chipyardSystem.tiles
|
||||||
|
val cfg = SpikeCosimConfig(
|
||||||
|
isa = tiles.headOption.map(_.isaDTS).getOrElse(""),
|
||||||
|
vlen = tiles.headOption.map(_.tileParams.core.vLen).getOrElse(0),
|
||||||
|
priv = tiles.headOption.map(t => if (t.usingUser) "MSU" else if (t.usingSupervisor) "MS" else "M").getOrElse(""),
|
||||||
|
mem0_base = p(ExtMem).map(_.master.base).getOrElse(BigInt(0)),
|
||||||
|
mem0_size = p(ExtMem).map(_.master.size).getOrElse(BigInt(0)),
|
||||||
|
pmpregions = tiles.headOption.map(_.tileParams.core.nPMPs).getOrElse(0),
|
||||||
|
nharts = tiles.size,
|
||||||
|
bootrom = chipyardSystem.bootROM.map(_.module.contents.toArray.mkString(" ")).getOrElse(""),
|
||||||
|
has_dtm = p(ExportDebug).protocols.contains(DMI) // assume that exposing clockeddmi means we will connect SimDTM
|
||||||
|
)
|
||||||
|
TracePort(trace, cfg)
|
||||||
}
|
}
|
||||||
(ports.toSeq, Nil)
|
(ports.toSeq, Nil)
|
||||||
}
|
}
|
||||||
@@ -417,7 +482,7 @@ class WithCustomBootPin extends OverrideIOBinder({
|
|||||||
(system: CanHavePeripheryCustomBootPin) => system.custom_boot_pin.map({ p =>
|
(system: CanHavePeripheryCustomBootPin) => system.custom_boot_pin.map({ p =>
|
||||||
val sys = system.asInstanceOf[BaseSubsystem]
|
val sys = system.asInstanceOf[BaseSubsystem]
|
||||||
val (port, cells) = IOCell.generateIOFromSignal(p.getWrappedValue, "custom_boot", sys.p(IOCellKey), abstractResetAsAsync = true)
|
val (port, cells) = IOCell.generateIOFromSignal(p.getWrappedValue, "custom_boot", sys.p(IOCellKey), abstractResetAsAsync = true)
|
||||||
(Seq(port), cells)
|
(Seq(CustomBootPort(port)), cells)
|
||||||
}).getOrElse((Nil, Nil))
|
}).getOrElse((Nil, Nil))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -426,7 +491,7 @@ class WithUARTTSIPunchthrough extends OverrideIOBinder({
|
|||||||
val sys = system.asInstanceOf[BaseSubsystem]
|
val sys = system.asInstanceOf[BaseSubsystem]
|
||||||
val uart_tsi = IO(new UARTTSIIO(p.uartParams))
|
val uart_tsi = IO(new UARTTSIIO(p.uartParams))
|
||||||
uart_tsi <> p
|
uart_tsi <> p
|
||||||
(Seq(uart_tsi), Nil)
|
(Seq(UARTTSIPort(uart_tsi)), Nil)
|
||||||
}).getOrElse((Nil, Nil))
|
}).getOrElse((Nil, Nil))
|
||||||
})
|
})
|
||||||
|
|
||||||
@@ -434,7 +499,7 @@ class WithTLMemPunchthrough extends OverrideIOBinder({
|
|||||||
(system: CanHaveMasterTLMemPort) => {
|
(system: CanHaveMasterTLMemPort) => {
|
||||||
val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave")
|
val io_tl_mem_pins_temp = IO(DataMirror.internal.chiselTypeClone[HeterogeneousBag[TLBundle]](system.mem_tl)).suggestName("tl_slave")
|
||||||
io_tl_mem_pins_temp <> system.mem_tl
|
io_tl_mem_pins_temp <> system.mem_tl
|
||||||
(Seq(io_tl_mem_pins_temp), Nil)
|
(Seq(TLMemPort(io_tl_mem_pins_temp)), Nil)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
94
generators/chipyard/src/main/scala/iobinders/Ports.scala
Normal file
94
generators/chipyard/src/main/scala/iobinders/Ports.scala
Normal file
@@ -0,0 +1,94 @@
|
|||||||
|
package chipyard.iobinders
|
||||||
|
|
||||||
|
import chisel3._
|
||||||
|
import chisel3.experimental.{Analog}
|
||||||
|
import sifive.blocks.devices.uart.{UARTPortIO}
|
||||||
|
import sifive.blocks.devices.spi.{SPIFlashParams, SPIPortIO}
|
||||||
|
import sifive.blocks.devices.i2c.{I2CPort}
|
||||||
|
import sifive.blocks.devices.gpio.{GPIOPortIO}
|
||||||
|
import testchipip._
|
||||||
|
import icenet.{NICIOvonly, NICConfig}
|
||||||
|
import org.chipsalliance.cde.config.{Parameters}
|
||||||
|
import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4EdgeParameters}
|
||||||
|
import freechips.rocketchip.subsystem.{MemoryPortParams, MasterPortParams, SlavePortParams}
|
||||||
|
import freechips.rocketchip.devices.debug.{ClockedDMIIO}
|
||||||
|
import freechips.rocketchip.util.{HeterogeneousBag}
|
||||||
|
import freechips.rocketchip.tilelink.{TLBundle}
|
||||||
|
|
||||||
|
trait Port[T <: Data] {
|
||||||
|
val io: T
|
||||||
|
}
|
||||||
|
|
||||||
|
// These case classes are generated by IOBinders, and interpreted by HarnessBinders
|
||||||
|
case class GPIOPort (val io: Analog, val gpioId: Int, val pinId: Int)
|
||||||
|
extends Port[Analog]
|
||||||
|
|
||||||
|
case class GPIOPinsPort (val io: GPIOPortIO, val gpioId: Int)
|
||||||
|
extends Port[GPIOPortIO]
|
||||||
|
|
||||||
|
case class I2CPort (val io: sifive.blocks.devices.i2c.I2CPort)
|
||||||
|
extends Port[sifive.blocks.devices.i2c.I2CPort]
|
||||||
|
|
||||||
|
case class UARTPort (val io: UARTPortIO, val uartNo: Int, val freqMHz: Int)
|
||||||
|
extends Port[UARTPortIO]
|
||||||
|
|
||||||
|
case class SPIFlashPort (val io: SPIChipIO, val params: SPIFlashParams, val spiId: Int)
|
||||||
|
extends Port[SPIChipIO]
|
||||||
|
|
||||||
|
case class SPIPort (val io: SPIPortIO)
|
||||||
|
extends Port[SPIPortIO]
|
||||||
|
|
||||||
|
case class BlockDevicePort (val io: ClockedIO[BlockDeviceIO], val params: BlockDeviceConfig)
|
||||||
|
extends Port[ClockedIO[BlockDeviceIO]]
|
||||||
|
|
||||||
|
case class NICPort (val io: ClockedIO[NICIOvonly], val params: NICConfig)
|
||||||
|
extends Port[ClockedIO[NICIOvonly]]
|
||||||
|
|
||||||
|
case class AXI4MemPort (val io: ClockedIO[AXI4Bundle], val params: MemoryPortParams, val edge: AXI4EdgeParameters, val clockFreqMHz: Int)
|
||||||
|
extends Port[ClockedIO[AXI4Bundle]]
|
||||||
|
|
||||||
|
case class AXI4MMIOPort (val io: ClockedIO[AXI4Bundle], val params: MasterPortParams, val edge: AXI4EdgeParameters)
|
||||||
|
extends Port[ClockedIO[AXI4Bundle]]
|
||||||
|
|
||||||
|
case class AXI4InPort (val io: ClockedIO[AXI4Bundle], val params: SlavePortParams)
|
||||||
|
extends Port[ClockedIO[AXI4Bundle]]
|
||||||
|
|
||||||
|
case class ExtIntPort (val io: UInt)
|
||||||
|
extends Port[UInt]
|
||||||
|
|
||||||
|
case class DMIPort (val io: ClockedDMIIO)
|
||||||
|
extends Port[ClockedDMIIO]
|
||||||
|
|
||||||
|
case class JTAGPort (val io: JTAGChipIO)
|
||||||
|
extends Port[JTAGChipIO]
|
||||||
|
|
||||||
|
case class SerialTLPort (val io: ClockedIO[SerialIO], val params: SerialTLParams, val serdesser: TLSerdesser, val portId: Int)
|
||||||
|
extends Port[ClockedIO[SerialIO]]
|
||||||
|
|
||||||
|
case class UARTTSIPort (val io: UARTTSIIO)
|
||||||
|
extends Port[UARTTSIIO]
|
||||||
|
|
||||||
|
case class SuccessPort (val io: Bool)
|
||||||
|
extends Port[Bool]
|
||||||
|
|
||||||
|
case class TracePort (val io: TraceOutputTop, val cosimCfg: SpikeCosimConfig)
|
||||||
|
extends Port[TraceOutputTop]
|
||||||
|
|
||||||
|
case class CustomBootPort (val io: Bool)
|
||||||
|
extends Port[Bool]
|
||||||
|
|
||||||
|
case class ClockPort (val io: Clock, val freqMHz: Double)
|
||||||
|
extends Port[Clock]
|
||||||
|
|
||||||
|
case class ResetPort (val io: AsyncReset)
|
||||||
|
extends Port[Reset]
|
||||||
|
|
||||||
|
case class DebugResetPort (val io: Reset)
|
||||||
|
extends Port[Reset]
|
||||||
|
|
||||||
|
case class JTAGResetPort (val io: Reset)
|
||||||
|
extends Port[Reset]
|
||||||
|
|
||||||
|
case class TLMemPort (val io: HeterogeneousBag[TLBundle])
|
||||||
|
extends Port[HeterogeneousBag[TLBundle]]
|
||||||
|
|
||||||
@@ -3,7 +3,6 @@
|
|||||||
package firesim.firesim
|
package firesim.firesim
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental.annotate
|
|
||||||
import chisel3.experimental.{DataMirror, Direction}
|
import chisel3.experimental.{DataMirror, Direction}
|
||||||
import chisel3.util.experimental.BoringUtils
|
import chisel3.util.experimental.BoringUtils
|
||||||
|
|
||||||
@@ -12,7 +11,6 @@ import freechips.rocketchip.diplomacy.{LazyModule}
|
|||||||
import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebug, ExportDebug, DMI}
|
import freechips.rocketchip.devices.debug.{Debug, HasPeripheryDebug, ExportDebug, DMI}
|
||||||
import freechips.rocketchip.amba.axi4.{AXI4Bundle}
|
import freechips.rocketchip.amba.axi4.{AXI4Bundle}
|
||||||
import freechips.rocketchip.subsystem._
|
import freechips.rocketchip.subsystem._
|
||||||
import freechips.rocketchip.tile.{RocketTile}
|
|
||||||
import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters}
|
import freechips.rocketchip.prci.{ClockBundle, ClockBundleParameters}
|
||||||
import freechips.rocketchip.util.{ResetCatchAndSync}
|
import freechips.rocketchip.util.{ResetCatchAndSync}
|
||||||
import sifive.blocks.devices.uart._
|
import sifive.blocks.devices.uart._
|
||||||
@@ -22,21 +20,19 @@ import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvon
|
|||||||
|
|
||||||
import junctions.{NastiKey, NastiParameters}
|
import junctions.{NastiKey, NastiParameters}
|
||||||
import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig}
|
import midas.models.{FASEDBridge, AXI4EdgeSummary, CompleteConfig}
|
||||||
import midas.targetutils.{MemModelAnnotation, EnableModelMultiThreadingAnnotation}
|
|
||||||
import firesim.bridges._
|
import firesim.bridges._
|
||||||
import firesim.configs.MemModelKey
|
import firesim.configs.MemModelKey
|
||||||
import tracegen.{TraceGenSystemModuleImp}
|
import tracegen.{TraceGenSystemModuleImp}
|
||||||
import cva6.CVA6Tile
|
import cva6.CVA6Tile
|
||||||
|
|
||||||
import boom.common.{BoomTile}
|
|
||||||
import barstools.iocell.chisel._
|
import barstools.iocell.chisel._
|
||||||
import chipyard.iobinders.{IOBinders, OverrideIOBinder, ComposeIOBinder, GetSystemParameters, IOCellKey}
|
import chipyard.iobinders._
|
||||||
import chipyard._
|
import chipyard._
|
||||||
import chipyard.harness._
|
import chipyard.harness._
|
||||||
|
|
||||||
object MainMemoryConsts {
|
object MainMemoryConsts {
|
||||||
val regionNamePrefix = "MainMemory"
|
val regionNamePrefix = "MainMemory"
|
||||||
def globalName()(implicit p: Parameters) = s"${regionNamePrefix}_${p(MultiChipIdx)}"
|
def globalName(chipId: Int) = s"${regionNamePrefix}_$chipId"
|
||||||
}
|
}
|
||||||
|
|
||||||
trait Unsupported {
|
trait Unsupported {
|
||||||
@@ -69,130 +65,70 @@ class WithFireSimIOCellModels extends Config((site, here, up) => {
|
|||||||
case IOCellKey => FireSimIOCellParams()
|
case IOCellKey => FireSimIOCellParams()
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTSIBridgeAndHarnessRAMOverSerialTL extends OverrideHarnessBinder({
|
class WithTSIBridgeAndHarnessRAMOverSerialTL extends HarnessBinder({
|
||||||
(system: CanHavePeripheryTLSerial, th: FireSim, ports: Seq[ClockedIO[SerialIO]]) => {
|
case (th: FireSim, port: SerialTLPort) => {
|
||||||
ports.map { port =>
|
val bits = port.io.bits
|
||||||
implicit val p = GetSystemParameters(system)
|
port.io.clock := th.harnessBinderClock
|
||||||
val bits = port.bits
|
val ram = LazyModule(new SerialRAM(port.serdesser)(Parameters.empty))
|
||||||
port.clock := th.harnessBinderClock
|
Module(ram.module)
|
||||||
val ram = TSIHarness.connectRAM(system.serdesser.get, bits, th.harnessBinderReset)
|
ram.module.io.ser <> port.io.bits
|
||||||
TSIBridge(th.harnessBinderClock, ram.module.io.tsi, p(ExtMem).map(_ => MainMemoryConsts.globalName), th.harnessBinderReset.asBool)
|
|
||||||
}
|
// This assumes that:
|
||||||
Nil
|
// If ExtMem for the target is defined, then FASED bridge will be attached
|
||||||
|
// If FASED bridge is attached, loadmem widget is present
|
||||||
|
val hasMainMemory = th.chipParameters(th.p(MultiChipIdx))(ExtMem).isDefined
|
||||||
|
val mainMemoryName = Option.when(hasMainMemory)(MainMemoryConsts.globalName(th.p(MultiChipIdx)))
|
||||||
|
TSIBridge(th.harnessBinderClock, ram.module.io.tsi, mainMemoryName, th.harnessBinderReset.asBool)(th.p)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithNICBridge extends OverrideHarnessBinder({
|
class WithNICBridge extends HarnessBinder({
|
||||||
(system: CanHavePeripheryIceNIC, th: FireSim, ports: Seq[ClockedIO[NICIOvonly]]) => {
|
case (th: FireSim, port: NICPort) => {
|
||||||
val p: Parameters = GetSystemParameters(system)
|
NICBridge(port.io.clock, port.io.bits)(th.p)
|
||||||
ports.map { n => NICBridge(n.clock, n.bits)(p) }
|
|
||||||
Nil
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithUARTBridge extends OverrideHarnessBinder({
|
class WithUARTBridge extends HarnessBinder({
|
||||||
(system: HasPeripheryUARTModuleImp, th: FireSim, ports: Seq[UARTPortIO]) =>
|
case (th: FireSim, port: UARTPort) =>
|
||||||
val uartSyncClock = Wire(Clock())
|
val uartSyncClock = th.harnessClockInstantiator.requestClockMHz("uart_clock", port.freqMHz)
|
||||||
uartSyncClock := false.B.asClock
|
UARTBridge(uartSyncClock, port.io, th.harnessBinderReset.asBool, port.freqMHz)(th.p)
|
||||||
val pbusClockNode = system.outer.asInstanceOf[HasTileLinkLocations].locateTLBusWrapper(PBUS).fixedClockNode
|
|
||||||
val pbusClock = pbusClockNode.in.head._1.clock
|
|
||||||
BoringUtils.bore(pbusClock, Seq(uartSyncClock))
|
|
||||||
ports.map { p => UARTBridge(uartSyncClock, p, th.harnessBinderReset.asBool)(system.p) }; Nil
|
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithBlockDeviceBridge extends OverrideHarnessBinder({
|
class WithBlockDeviceBridge extends HarnessBinder({
|
||||||
(system: CanHavePeripheryBlockDevice, th: FireSim, ports: Seq[ClockedIO[BlockDeviceIO]]) => {
|
case (th: FireSim, port: BlockDevicePort) => {
|
||||||
implicit val p: Parameters = GetSystemParameters(system)
|
BlockDevBridge(port.io.clock, port.io.bits, th.harnessBinderReset.asBool)
|
||||||
ports.map { b => BlockDevBridge(b.clock, b.bits, th.harnessBinderReset.asBool) }
|
|
||||||
Nil
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|
||||||
class WithFASEDBridge extends OverrideHarnessBinder({
|
class WithFASEDBridge extends HarnessBinder({
|
||||||
(system: CanHaveMasterAXI4MemPort, th: FireSim, ports: Seq[ClockedAndResetIO[AXI4Bundle]]) => {
|
case (th: FireSim, port: AXI4MemPort) => {
|
||||||
implicit val p: Parameters = GetSystemParameters(system)
|
val nastiKey = NastiParameters(port.io.bits.r.bits.data.getWidth,
|
||||||
(ports zip system.memAXI4Node.edges.in).map { case (axi4, edge) =>
|
port.io.bits.ar.bits.addr.getWidth,
|
||||||
val nastiKey = NastiParameters(axi4.bits.r.bits.data.getWidth,
|
port.io.bits.ar.bits.id.getWidth)
|
||||||
axi4.bits.ar.bits.addr.getWidth,
|
FASEDBridge(port.io.clock, port.io.bits, th.harnessBinderReset.asBool,
|
||||||
axi4.bits.ar.bits.id.getWidth)
|
CompleteConfig(th.p(firesim.configs.MemModelKey),
|
||||||
system match {
|
|
||||||
case s: BaseSubsystem => FASEDBridge(axi4.clock, axi4.bits, axi4.reset.asBool,
|
|
||||||
CompleteConfig(p(firesim.configs.MemModelKey),
|
|
||||||
nastiKey,
|
nastiKey,
|
||||||
Some(AXI4EdgeSummary(edge)),
|
Some(AXI4EdgeSummary(port.edge)),
|
||||||
Some(MainMemoryConsts.globalName)))
|
Some(MainMemoryConsts.globalName(th.p(MultiChipIdx)))))(th.p)
|
||||||
case _ => throw new Exception("Attempting to attach FASED Bridge to misconfigured design")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Nil
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTracerVBridge extends ComposeHarnessBinder({
|
class WithTracerVBridge extends HarnessBinder({
|
||||||
(system: CanHaveTraceIOModuleImp, th: FireSim, ports: Seq[TraceOutputTop]) => {
|
case (th: FireSim, port: TracePort) => {
|
||||||
ports.map { p => p.traces.map(tileTrace => TracerVBridge(tileTrace)(system.p)) }
|
port.io.traces.map(tileTrace => TracerVBridge(tileTrace)(th.p))
|
||||||
Nil
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithCospikeBridge extends ComposeHarnessBinder({
|
class WithCospikeBridge extends HarnessBinder({
|
||||||
(system: CanHaveTraceIOModuleImp, th: FireSim, ports: Seq[TraceOutputTop]) => {
|
case (th: FireSim, port: TracePort) => {
|
||||||
implicit val p = chipyard.iobinders.GetSystemParameters(system)
|
port.io.traces.zipWithIndex.map(t => CospikeBridge(t._1, t._2, port.cosimCfg))
|
||||||
val chipyardSystem = system.asInstanceOf[ChipyardSystemModule[_]].outer.asInstanceOf[ChipyardSystem]
|
|
||||||
val tiles = chipyardSystem.tiles
|
|
||||||
val cfg = SpikeCosimConfig(
|
|
||||||
isa = tiles.headOption.map(_.isaDTS).getOrElse(""),
|
|
||||||
vlen = tiles.headOption.map(_.tileParams.core.vLen).getOrElse(0),
|
|
||||||
priv = tiles.headOption.map(t => if (t.usingUser) "MSU" else if (t.usingSupervisor) "MS" else "M").getOrElse(""),
|
|
||||||
mem0_base = p(ExtMem).map(_.master.base).getOrElse(BigInt(0)),
|
|
||||||
mem0_size = p(ExtMem).map(_.master.size).getOrElse(BigInt(0)),
|
|
||||||
pmpregions = tiles.headOption.map(_.tileParams.core.nPMPs).getOrElse(0),
|
|
||||||
nharts = tiles.size,
|
|
||||||
bootrom = chipyardSystem.bootROM.map(_.module.contents.toArray.mkString(" ")).getOrElse(""),
|
|
||||||
has_dtm = p(ExportDebug).protocols.contains(DMI) // assume that exposing clockeddmi means we will connect SimDTM
|
|
||||||
)
|
|
||||||
ports.map { p => p.traces.zipWithIndex.map(t => CospikeBridge(t._1, t._2, cfg)) }
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
class WithTraceGenBridge extends OverrideHarnessBinder({
|
class WithSuccessBridge extends HarnessBinder({
|
||||||
(system: TraceGenSystemModuleImp, th: FireSim, ports: Seq[Bool]) =>
|
case (th: FireSim, port: SuccessPort) => {
|
||||||
ports.map { p => GroundTestBridge(th.harnessBinderClock, p)(system.p) }; Nil
|
GroundTestBridge(th.harnessBinderClock, port.io)(th.p)
|
||||||
})
|
|
||||||
|
|
||||||
class WithFireSimMultiCycleRegfile extends ComposeIOBinder({
|
|
||||||
(system: HasTilesModuleImp) => {
|
|
||||||
system.outer.tiles.map {
|
|
||||||
case r: RocketTile => {
|
|
||||||
annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf))
|
|
||||||
r.module.fpuOpt.foreach(fpu => annotate(MemModelAnnotation(fpu.fpuImpl.regfile)))
|
|
||||||
}
|
|
||||||
case b: BoomTile => {
|
|
||||||
val core = b.module.core
|
|
||||||
core.iregfile match {
|
|
||||||
case irf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(irf.regfile))
|
|
||||||
}
|
|
||||||
if (core.fp_pipeline != null) core.fp_pipeline.fregfile match {
|
|
||||||
case frf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(frf.regfile))
|
|
||||||
}
|
|
||||||
}
|
|
||||||
case _ =>
|
|
||||||
}
|
|
||||||
(Nil, Nil)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
class WithFireSimFAME5 extends ComposeIOBinder({
|
|
||||||
(system: HasTilesModuleImp) => {
|
|
||||||
system.outer.tiles.map {
|
|
||||||
case b: BoomTile =>
|
|
||||||
annotate(EnableModelMultiThreadingAnnotation(b.module))
|
|
||||||
case r: RocketTile =>
|
|
||||||
annotate(EnableModelMultiThreadingAnnotation(r.module))
|
|
||||||
case _ => Nil
|
|
||||||
}
|
|
||||||
(Nil, Nil)
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
|||||||
@@ -5,21 +5,26 @@ package firesim.firesim
|
|||||||
import scala.collection.mutable.{LinkedHashMap}
|
import scala.collection.mutable.{LinkedHashMap}
|
||||||
|
|
||||||
import chisel3._
|
import chisel3._
|
||||||
import chisel3.experimental.{IO}
|
import chisel3.experimental.{IO, annotate}
|
||||||
|
|
||||||
import freechips.rocketchip.prci._
|
import freechips.rocketchip.prci._
|
||||||
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey}
|
import freechips.rocketchip.subsystem.{BaseSubsystem, SubsystemDriveAsyncClockGroupsKey, HasTiles}
|
||||||
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
import org.chipsalliance.cde.config.{Field, Config, Parameters}
|
||||||
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, InModuleBody, ValName}
|
import freechips.rocketchip.diplomacy.{LazyModule, LazyModuleImp, InModuleBody, ValName}
|
||||||
import freechips.rocketchip.util.{ResetCatchAndSync, RecordMap}
|
import freechips.rocketchip.util.{ResetCatchAndSync, RecordMap}
|
||||||
|
import freechips.rocketchip.tile.{RocketTile}
|
||||||
|
import boom.common.{BoomTile}
|
||||||
|
|
||||||
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock, ResetPulseBridge, ResetPulseBridgeParameters}
|
import midas.widgets.{Bridge, PeekPokeBridge, RationalClockBridge, RationalClock, ResetPulseBridge, ResetPulseBridgeParameters}
|
||||||
|
import midas.targetutils.{MemModelAnnotation, EnableModelMultiThreadingAnnotation}
|
||||||
import chipyard._
|
import chipyard._
|
||||||
import chipyard.harness._
|
import chipyard.harness._
|
||||||
import chipyard.iobinders._
|
import chipyard.iobinders._
|
||||||
import chipyard.clocking._
|
import chipyard.clocking._
|
||||||
|
|
||||||
|
case object FireSimMultiCycleRegFile extends Field[Boolean](false)
|
||||||
|
case object FireSimFAME5 extends Field[Boolean](false)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Under FireSim's current multiclock implementation there can be only a
|
* Under FireSim's current multiclock implementation there can be only a
|
||||||
* single clock bridge. This requires, therefore, that it be instantiated in
|
* single clock bridge. This requires, therefore, that it be instantiated in
|
||||||
@@ -85,11 +90,46 @@ class FireSim(implicit val p: Parameters) extends RawModule with HasHarnessInsta
|
|||||||
|
|
||||||
override val supportsMultiChip = true
|
override val supportsMultiChip = true
|
||||||
|
|
||||||
instantiateChipTops()
|
val chiptops = instantiateChipTops()
|
||||||
|
|
||||||
// Ensures FireSim-synthesized assertions and instrumentation is disabled
|
// Ensures FireSim-synthesized assertions and instrumentation is disabled
|
||||||
// while resetBridge.io.reset is asserted. This ensures assertions do not fire at
|
// while resetBridge.io.reset is asserted. This ensures assertions do not fire at
|
||||||
// time zero in the event their local reset is delayed (typically because it
|
// time zero in the event their local reset is delayed (typically because it
|
||||||
// has been pipelined)
|
// has been pipelined)
|
||||||
midas.targetutils.GlobalResetCondition(resetBridge.io.reset)
|
midas.targetutils.GlobalResetCondition(resetBridge.io.reset)
|
||||||
|
|
||||||
|
|
||||||
|
// FireSim multi-cycle regfile optimization
|
||||||
|
// FireSim ModelMultithreading
|
||||||
|
chiptops.foreach {
|
||||||
|
case c: ChipTop => c.lazySystem match {
|
||||||
|
case ls: HasTiles => {
|
||||||
|
if (p(FireSimMultiCycleRegFile)) ls.tiles.map {
|
||||||
|
case r: RocketTile => {
|
||||||
|
annotate(MemModelAnnotation(r.module.core.rocketImpl.rf.rf))
|
||||||
|
r.module.fpuOpt.foreach(fpu => annotate(MemModelAnnotation(fpu.fpuImpl.regfile)))
|
||||||
|
}
|
||||||
|
case b: BoomTile => {
|
||||||
|
val core = b.module.core
|
||||||
|
core.iregfile match {
|
||||||
|
case irf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(irf.regfile))
|
||||||
|
}
|
||||||
|
if (core.fp_pipeline != null) core.fp_pipeline.fregfile match {
|
||||||
|
case frf: boom.exu.RegisterFileSynthesizable => annotate(MemModelAnnotation(frf.regfile))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
if (p(FireSimFAME5)) ls.tiles.map {
|
||||||
|
case b: BoomTile =>
|
||||||
|
annotate(EnableModelMultiThreadingAnnotation(b.module))
|
||||||
|
case r: RocketTile =>
|
||||||
|
annotate(EnableModelMultiThreadingAnnotation(r.module))
|
||||||
|
case _ => Nil
|
||||||
|
}
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
|
case _ =>
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -55,6 +55,16 @@ class WithScalaTestFeatures extends Config((site, here, up) => {
|
|||||||
case TracePortKey => up(TracePortKey, site).map(_.copy(print = true))
|
case TracePortKey => up(TracePortKey, site).map(_.copy(print = true))
|
||||||
})
|
})
|
||||||
|
|
||||||
|
// Multi-cycle regfile for rocket+boom
|
||||||
|
class WithFireSimMultiCycleRegfile extends Config((site, here, up) => {
|
||||||
|
case FireSimMultiCycleRegFile => true
|
||||||
|
})
|
||||||
|
|
||||||
|
// Model multithreading optimization
|
||||||
|
class WithFireSimFAME5 extends Config((site, here, up) => {
|
||||||
|
case FireSimFAME5 => true
|
||||||
|
})
|
||||||
|
|
||||||
// FASED Config Aliases. This to enable config generation via "_" concatenation
|
// FASED Config Aliases. This to enable config generation via "_" concatenation
|
||||||
// which requires that all config classes be defined in the same package
|
// which requires that all config classes be defined in the same package
|
||||||
class DDR3FCFS extends FCFS16GBQuadRank
|
class DDR3FCFS extends FCFS16GBQuadRank
|
||||||
@@ -72,7 +82,8 @@ class WithMinimalFireSimDesignTweaks extends Config(
|
|||||||
// Required*: Punch all clocks to FireSim's harness clock instantiator
|
// Required*: Punch all clocks to FireSim's harness clock instantiator
|
||||||
new WithFireSimHarnessClockBridgeInstantiator ++
|
new WithFireSimHarnessClockBridgeInstantiator ++
|
||||||
new chipyard.harness.WithHarnessBinderClockFreqMHz(1000.0) ++
|
new chipyard.harness.WithHarnessBinderClockFreqMHz(1000.0) ++
|
||||||
new chipyard.harness.WithClockAndResetFromHarness ++
|
new chipyard.harness.WithClockFromHarness ++
|
||||||
|
new chipyard.harness.WithResetFromHarness ++
|
||||||
new chipyard.clocking.WithPassthroughClockGenerator ++
|
new chipyard.clocking.WithPassthroughClockGenerator ++
|
||||||
// Required*: When using FireSim-as-top to provide a correct path to the target bootrom source
|
// Required*: When using FireSim-as-top to provide a correct path to the target bootrom source
|
||||||
new WithBootROM ++
|
new WithBootROM ++
|
||||||
@@ -289,6 +300,7 @@ class FireSimLeanGemminiPrintfRocketConfig extends Config(
|
|||||||
//**********************************************************************************
|
//**********************************************************************************
|
||||||
class SupernodeFireSimRocketConfig extends Config(
|
class SupernodeFireSimRocketConfig extends Config(
|
||||||
new WithFireSimHarnessClockBridgeInstantiator ++
|
new WithFireSimHarnessClockBridgeInstantiator ++
|
||||||
|
new WithDefaultMemModel ++ // this is a global for all the multi-chip configs
|
||||||
new chipyard.harness.WithHomogeneousMultiChip(n=4, new Config(
|
new chipyard.harness.WithHomogeneousMultiChip(n=4, new Config(
|
||||||
new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 8L) ++ // 8GB DRAM per node
|
new freechips.rocketchip.subsystem.WithExtMemSize((1 << 30) * 8L) ++ // 8GB DRAM per node
|
||||||
new FireSimRocketConfig)))
|
new FireSimRocketConfig)))
|
||||||
|
|||||||
Submodule generators/icenet updated: 68b4c7f30f...18e88b5779
Submodule generators/testchipip updated: 177e307199...6436959d99
@@ -109,8 +109,31 @@ if [ $TOOLCHAIN_TYPE == "esp-tools" ]; then
|
|||||||
done
|
done
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|
||||||
|
#######################################
|
||||||
|
###### BEGIN STEP-BY-STEP SETUP #######
|
||||||
|
#######################################
|
||||||
|
|
||||||
|
# In order to run code on error, we must handle errors manually
|
||||||
|
set +e;
|
||||||
|
|
||||||
|
function begin_step
|
||||||
|
{
|
||||||
|
thisStepNum=$1;
|
||||||
|
thisStepDesc=$2;
|
||||||
|
echo " ========== BEGINNING STEP $thisStepNum: $thisStepDesc =========="
|
||||||
|
}
|
||||||
|
function exit_if_last_command_failed
|
||||||
|
{
|
||||||
|
local exitcode=$?;
|
||||||
|
if [ $exitcode -ne 0 ]; then
|
||||||
|
die "Build script failed with exit code $exitcode at step $thisStepNum: $thisStepDesc" $exitcode;
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
# setup and install conda environment
|
# setup and install conda environment
|
||||||
if run_step "1"; then
|
if run_step "1"; then
|
||||||
|
begin_step "1" "Conda environment setup"
|
||||||
# note: lock file must end in .conda-lock.yml - see https://github.com/conda-incubator/conda-lock/issues/154
|
# note: lock file must end in .conda-lock.yml - see https://github.com/conda-incubator/conda-lock/issues/154
|
||||||
CONDA_REQS=$CYDIR/conda-reqs
|
CONDA_REQS=$CYDIR/conda-reqs
|
||||||
CONDA_LOCK_REQS=$CONDA_REQS/conda-lock-reqs
|
CONDA_LOCK_REQS=$CONDA_REQS/conda-lock-reqs
|
||||||
@@ -120,13 +143,15 @@ if run_step "1"; then
|
|||||||
if [ "$USE_UNPINNED_DEPS" = true ]; then
|
if [ "$USE_UNPINNED_DEPS" = true ]; then
|
||||||
# auto-gen the lockfiles
|
# auto-gen the lockfiles
|
||||||
$CYDIR/scripts/generate-conda-lockfiles.sh
|
$CYDIR/scripts/generate-conda-lockfiles.sh
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# use conda-lock to create env
|
# use conda-lock to create env
|
||||||
conda-lock install --conda $(which conda) -p $CYDIR/.conda-env $LOCKFILE
|
conda-lock install --conda $(which conda) -p $CYDIR/.conda-env $LOCKFILE &&
|
||||||
|
|
||||||
source $CYDIR/.conda-env/etc/profile.d/conda.sh
|
source $CYDIR/.conda-env/etc/profile.d/conda.sh &&
|
||||||
conda activate $CYDIR/.conda-env
|
conda activate $CYDIR/.conda-env
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
if [ -z "$FORCE_FLAG" ]; then
|
if [ -z "$FORCE_FLAG" ]; then
|
||||||
@@ -138,11 +163,14 @@ fi
|
|||||||
|
|
||||||
# initialize all submodules (without the toolchain submodules)
|
# initialize all submodules (without the toolchain submodules)
|
||||||
if run_step "2"; then
|
if run_step "2"; then
|
||||||
|
begin_step "2" "Initializing Chipyard submodules"
|
||||||
$CYDIR/scripts/init-submodules-no-riscv-tools.sh $FORCE_FLAG
|
$CYDIR/scripts/init-submodules-no-riscv-tools.sh $FORCE_FLAG
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# build extra toolchain collateral (i.e. spike, pk, riscv-tests, libgloss)
|
# build extra toolchain collateral (i.e. spike, pk, riscv-tests, libgloss)
|
||||||
if run_step "3"; then
|
if run_step "3"; then
|
||||||
|
begin_step "3" "Building toolchain collateral"
|
||||||
if run_step "1"; then
|
if run_step "1"; then
|
||||||
PREFIX=$CONDA_PREFIX/$TOOLCHAIN_TYPE
|
PREFIX=$CONDA_PREFIX/$TOOLCHAIN_TYPE
|
||||||
else
|
else
|
||||||
@@ -153,57 +181,73 @@ if run_step "3"; then
|
|||||||
PREFIX=$RISCV
|
PREFIX=$RISCV
|
||||||
fi
|
fi
|
||||||
$CYDIR/scripts/build-toolchain-extra.sh $TOOLCHAIN_TYPE -p $PREFIX
|
$CYDIR/scripts/build-toolchain-extra.sh $TOOLCHAIN_TYPE -p $PREFIX
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# run ctags for code navigation
|
# run ctags for code navigation
|
||||||
if run_step "4"; then
|
if run_step "4"; then
|
||||||
|
begin_step "4" "Running ctags for code navigation"
|
||||||
$CYDIR/scripts/gen-tags.sh
|
$CYDIR/scripts/gen-tags.sh
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# precompile chipyard scala sources
|
# precompile chipyard scala sources
|
||||||
if run_step "5"; then
|
if run_step "5"; then
|
||||||
pushd $CYDIR/sims/verilator
|
begin_step "5" "Pre-compiling Chipyard Scala sources"
|
||||||
make launch-sbt SBT_COMMAND=";project chipyard; compile"
|
pushd $CYDIR/sims/verilator &&
|
||||||
make launch-sbt SBT_COMMAND=";project tapeout; compile"
|
make launch-sbt SBT_COMMAND=";project chipyard; compile" &&
|
||||||
|
make launch-sbt SBT_COMMAND=";project tapeout; compile" &&
|
||||||
popd
|
popd
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# setup firesim
|
# setup firesim
|
||||||
if run_step "6"; then
|
if run_step "6"; then
|
||||||
$CYDIR/scripts/firesim-setup.sh
|
begin_step "6" "Setting up FireSim"
|
||||||
|
$CYDIR/scripts/firesim-setup.sh &&
|
||||||
$CYDIR/sims/firesim/gen-tags.sh
|
$CYDIR/sims/firesim/gen-tags.sh
|
||||||
|
exit_if_last_command_failed
|
||||||
|
|
||||||
# precompile firesim scala sources
|
# precompile firesim scala sources
|
||||||
if run_step "7"; then
|
if run_step "7"; then
|
||||||
pushd $CYDIR/sims/firesim
|
begin_step "7" "Pre-compiling Firesim Scala sources"
|
||||||
|
pushd $CYDIR/sims/firesim &&
|
||||||
(
|
(
|
||||||
|
set -e # Subshells un-set "set -e" so it must be re enabled
|
||||||
echo $CYDIR
|
echo $CYDIR
|
||||||
source sourceme-manager.sh --skip-ssh-setup
|
source sourceme-manager.sh --skip-ssh-setup
|
||||||
pushd sim
|
pushd sim
|
||||||
make sbt SBT_COMMAND="project {file:$CYDIR}firechip; compile" TARGET_PROJECT=firesim
|
make sbt SBT_COMMAND="project {file:$CYDIR}firechip; compile" TARGET_PROJECT=firesim
|
||||||
popd
|
popd
|
||||||
)
|
)
|
||||||
|
exit_if_last_command_failed
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# setup firemarshal
|
# setup firemarshal
|
||||||
if run_step "8"; then
|
if run_step "8"; then
|
||||||
pushd $CYDIR/software/firemarshal
|
begin_step "8" "Setting up FireMarshal"
|
||||||
|
pushd $CYDIR/software/firemarshal &&
|
||||||
./init-submodules.sh
|
./init-submodules.sh
|
||||||
|
exit_if_last_command_failed
|
||||||
|
|
||||||
# precompile firemarshal buildroot sources
|
# precompile firemarshal buildroot sources
|
||||||
if run_step "9"; then
|
if run_step "9"; then
|
||||||
source $CYDIR/scripts/fix-open-files.sh
|
begin_step "9" "Pre-compiling FireMarshal buildroot sources"
|
||||||
./marshal $VERBOSE_FLAG build br-base.json
|
source $CYDIR/scripts/fix-open-files.sh &&
|
||||||
|
./marshal $VERBOSE_FLAG build br-base.json &&
|
||||||
./marshal $VERBOSE_FLAG clean br-base.json
|
./marshal $VERBOSE_FLAG clean br-base.json
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
popd
|
popd
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# do misc. cleanup for a "clean" git status
|
# do misc. cleanup for a "clean" git status
|
||||||
if run_step "10"; then
|
if run_step "10"; then
|
||||||
|
begin_step "10" "Cleaning up repository"
|
||||||
$CYDIR/scripts/repo-clean.sh
|
$CYDIR/scripts/repo-clean.sh
|
||||||
|
exit_if_last_command_failed
|
||||||
fi
|
fi
|
||||||
|
|
||||||
cat <<EOT >> env.sh
|
cat <<EOT >> env.sh
|
||||||
|
|||||||
Submodule sims/firesim updated: 08b565c8c6...73fe6a51b2
Submodule software/firemarshal updated: 8b8eea35f6...9782698343
Submodule tools/dsptools updated: 7bd039fb5f...8f43366395
Submodule tools/fixedpoint updated: 35dda166f5...36ce43c90c
Submodule tools/rocket-dsp-utils updated: 341e91985f...194455223a
Reference in New Issue
Block a user