diff --git a/.github/actions/cleanup-conda/action.yml b/.github/actions/cleanup-conda/action.yml index b9aebb67..3b0fdf88 100644 --- a/.github/actions/cleanup-conda/action.yml +++ b/.github/actions/cleanup-conda/action.yml @@ -22,7 +22,7 @@ runs: echo "Skipping removal of $envname since it cannot be parsed into a date" else NUM_DIFF=$(( ( $(date +%s) - $(date --date="$ENV_DATE" +%s) )/(60*60*24) )) - if (( $NUM_DIFF > 7 )); then + if (( $NUM_DIFF > 2 )); then echo "Removing $envname since it is $NUM_DIFF days old." conda env remove -n $envname else diff --git a/common.mk b/common.mk index 7f2a1f50..c62743e0 100644 --- a/common.mk +++ b/common.mk @@ -182,6 +182,7 @@ endif if [ $(SFC_LEVEL) = low ]; then jq -s '[.[][]]' $(EXTRA_ANNO_FILE) $(SFC_EXTRA_ANNO_FILE) > $(FINAL_ANNO_FILE); fi if [ $(SFC_LEVEL) = none ]; then cat $(EXTRA_ANNO_FILE) > $(FINAL_ANNO_FILE); fi +$(SFC_MFC_TARGETS) &: private TMP_DIR := $(shell mktemp -d -t cy-XXXXXXXX) $(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(VLOG_SOURCES) $(SFC_LEVEL) $(EXTRA_FIRRTL_OPTIONS) rm -rf $(GEN_COLLATERAL_DIR) $(call run_scala_main,tapeout,barstools.tapeout.transforms.GenerateModelStageMain,\ @@ -196,9 +197,9 @@ $(SFC_MFC_TARGETS) &: $(FIRRTL_FILE) $(FINAL_ANNO_FILE) $(VLOG_SOURCES) $(SFC_LE -X $(SFC_LEVEL) \ $(EXTRA_FIRRTL_OPTIONS)) -mv $(SFC_FIRRTL_BASENAME).lo.fir $(SFC_FIRRTL_FILE) # Optionally change file type when SFC generates LowFIRRTL - @if [ $(SFC_LEVEL) = low ]; then cat $(SFC_ANNO_FILE) | jq 'del(.[] | select(.target | test("io.cpu"))?)' > /tmp/unnec-anno-deleted.sfc.anno.json; fi - @if [ $(SFC_LEVEL) = low ]; then cat /tmp/unnec-anno-deleted.sfc.anno.json | jq 'del(.[] | select(.class | test("SRAMAnnotation"))?)' > /tmp/unnec-anno-deleted2.sfc.anno.json; fi - @if [ $(SFC_LEVEL) = low ]; then cat /tmp/unnec-anno-deleted2.sfc.anno.json > $(SFC_ANNO_FILE) && rm /tmp/unnec-anno-deleted.sfc.anno.json && rm /tmp/unnec-anno-deleted2.sfc.anno.json; fi + @if [ $(SFC_LEVEL) = low ]; then cat $(SFC_ANNO_FILE) | jq 'del(.[] | select(.target | test("io.cpu"))?)' > $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json; fi + @if [ $(SFC_LEVEL) = low ]; then cat $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json | jq 'del(.[] | select(.class | test("SRAMAnnotation"))?)' > $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json; fi + @if [ $(SFC_LEVEL) = low ]; then cat $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json > $(SFC_ANNO_FILE) && rm $(TMP_DIR)/unnec-anno-deleted.sfc.anno.json && rm $(TMP_DIR)/unnec-anno-deleted2.sfc.anno.json; fi firtool \ --format=fir \ --dedup \ diff --git a/docs/Prototyping/Arty.rst b/docs/Prototyping/Arty.rst index 204eacec..15347cf8 100644 --- a/docs/Prototyping/Arty.rst +++ b/docs/Prototyping/Arty.rst @@ -1,8 +1,62 @@ Running a Design on Arty ======================== -Basic Arty Design ------------------ +Arty100T Instructions +---------------------- + +The default Xilinx Arty 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. +The interface for the ``uart_tsi`` program provides unique functionality that is useful for bringing up test chips. + +To build the design, run: + +.. code-block:: shell + + cd fpga/ + make SUB_PROJECT=arty100t + +To build the UART-based frontend server, run: + +.. code-block:: shell + + cd generators/testchipip/uart_tsi + make + +After programming the bitstream, and connecting the Arty'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 + +Run a design at a higher baud rate than default (For example, if ``CONFIG=UART921600RocketArty100TConfig`` were built): + +.. code-block:: shell + + ./uart_tsi +tty=/dev/ttyUSBX +baudrate=921600 dhrystone.riscv + + +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 `__. 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. diff --git a/docs/Simulation/Software-RTL-Simulation.rst b/docs/Simulation/Software-RTL-Simulation.rst index 5fd3ee75..d62f6f1c 100644 --- a/docs/Simulation/Software-RTL-Simulation.rst +++ b/docs/Simulation/Software-RTL-Simulation.rst @@ -188,6 +188,16 @@ An open-source vcd-capable waveform viewer is `GTKWave `__. + +The ``*.graphml`` file will be located in ``generated-src/<...>/``. Open the file in the graph viewer. +To get a clearer view of the SoC, switch to "hierarchical" view. For yEd, this would be done by selecting ``layout`` -> ``hierarchical``, and then choosing "Ok" without changing any settings. + .. _sw-sim-verilator-opts: Additional Verilator Options diff --git a/fpga/Makefile b/fpga/Makefile index e02dac54..7521b1ed 100644 --- a/fpga/Makefile +++ b/fpga/Makefile @@ -57,7 +57,6 @@ ifeq ($(SUB_PROJECT),bringup) BOARD ?= vcu118 FPGA_BRAND ?= xilinx endif - ifeq ($(SUB_PROJECT),arty) # TODO: Fix with Arty SBT_PROJECT ?= fpga_platforms @@ -72,6 +71,20 @@ ifeq ($(SUB_PROJECT),arty) BOARD ?= arty FPGA_BRAND ?= xilinx endif +ifeq ($(SUB_PROJECT),arty100t) + # TODO: Fix with Arty + SBT_PROJECT ?= fpga_platforms + MODEL ?= Arty100THarness + VLOG_MODEL ?= Arty100THarness + MODEL_PACKAGE ?= chipyard.fpga.arty100t + CONFIG ?= RocketArty100TConfig + CONFIG_PACKAGE ?= chipyard.fpga.arty100t + GENERATOR_PACKAGE ?= chipyard + TB ?= none # unused + TOP ?= ChipTop + BOARD ?= arty_a7_100 + FPGA_BRAND ?= xilinx +endif include $(base_dir)/variables.mk @@ -109,8 +122,7 @@ include $(base_dir)/common.mk # copy from other directory ######################################################################################### all_vsrcs := \ - $(base_dir)/generators/sifive-blocks/vsrc/SRLatch.v \ - $(fpga_dir)/common/vsrc/PowerOnResetFPGAOnly.v + $(base_dir)/generators/sifive-blocks/vsrc/SRLatch.v ######################################################################################### # vivado rules diff --git a/fpga/fpga-shells b/fpga/fpga-shells index 474ad191..b6cd1bb7 160000 --- a/fpga/fpga-shells +++ b/fpga/fpga-shells @@ -1 +1 @@ -Subproject commit 474ad19113b89ed5679695b269acdb011b9b871a +Subproject commit b6cd1bb7fe35bb7a44b6fe5a0d88d1293d7a3bc9 diff --git a/fpga/src/main/scala/arty/Configs.scala b/fpga/src/main/scala/arty/Configs.scala index 1c81f481..a88848d0 100644 --- a/fpga/src/main/scala/arty/Configs.scala +++ b/fpga/src/main/scala/arty/Configs.scala @@ -15,30 +15,20 @@ import testchipip.{SerialTLKey} import chipyard.{BuildSystem} -class WithDefaultPeripherals extends Config((site, here, up) => { - case PeripheryUARTKey => List( - UARTParams(address = 0x10013000)) - case DTSTimebase => BigInt(32768) - case JtagDTMKey => new JtagDTMConfig ( - idcodeVersion = 2, - idcodePartNum = 0x000, - idcodeManufId = 0x489, - debugIdleCycles = 5) - case SerialTLKey => None // remove serialized tl port -}) - // DOC include start: AbstractArty and Rocket class WithArtyTweaks extends Config( new WithArtyJTAGHarnessBinder ++ new WithArtyUARTHarnessBinder ++ new WithArtyResetHarnessBinder ++ new WithDebugResetPassthrough ++ - new WithDefaultPeripherals ++ - new freechips.rocketchip.subsystem.WithNBreakpoints(2) + + new chipyard.config.WithDTSTimebase(32768) ++ + new testchipip.WithNoSerialTL ) class TinyRocketArtyConfig extends Config( new WithArtyTweaks ++ + new freechips.rocketchip.subsystem.WithNBreakpoints(2) ++ new chipyard.TinyRocketConfig ) // DOC include end: AbstractArty and Rocket diff --git a/fpga/src/main/scala/arty100t/Configs.scala b/fpga/src/main/scala/arty100t/Configs.scala new file mode 100644 index 00000000..0930dbdb --- /dev/null +++ b/fpga/src/main/scala/arty100t/Configs.scala @@ -0,0 +1,59 @@ +// See LICENSE for license details. +package chipyard.fpga.arty100t + +import freechips.rocketchip.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) +}) + +class WithArty100TTweaks extends Config( + new WithArty100TUARTTSI ++ + new WithArty100TDDRTL ++ + new WithNoDesignKey ++ + 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(256) << 20) ++ // 256mb on ARTY + new freechips.rocketchip.subsystem.WithoutTLMonitors) + +class RocketArty100TConfig extends Config( + new WithArty100TTweaks ++ + new chipyard.config.WithMemoryBusFrequency(50.0) ++ + new chipyard.config.WithPeripheryBusFrequency(50.0) ++ // Match the sbus and pbus frequency + new chipyard.config.WithBroadcastManager ++ // no l2 + new chipyard.RocketConfig) + +class UART230400RocketArty100TConfig extends Config( + new WithArty100TUARTTSI(uartBaudRate = 230400) ++ + new RocketArty100TConfig) + +class UART460800RocketArty100TConfig extends Config( + new WithArty100TUARTTSI(uartBaudRate = 460800) ++ + new RocketArty100TConfig) + +class UART921600RocketArty100TConfig extends Config( + new WithArty100TUARTTSI(uartBaudRate = 921600) ++ + new RocketArty100TConfig) + + +class NoCoresArty100TConfig extends Config( + new WithArty100TTweaks ++ + new chipyard.config.WithMemoryBusFrequency(50.0) ++ + new chipyard.config.WithPeripheryBusFrequency(50.0) ++ // Match the sbus and pbus frequency + new chipyard.config.WithBroadcastManager ++ // no l2 + new chipyard.NoCoresConfig) diff --git a/fpga/src/main/scala/arty100t/Harness.scala b/fpga/src/main/scala/arty100t/Harness.scala new file mode 100644 index 00000000..5cc1e348 --- /dev/null +++ b/fpga/src/main/scala/arty100t/Harness.scala @@ -0,0 +1,92 @@ +package chipyard.fpga.arty100t + +import chisel3._ +import chisel3.util._ +import freechips.rocketchip.diplomacy._ +import freechips.rocketchip.config.{Parameters} +import freechips.rocketchip.tilelink.{TLClientNode, TLBlockDuringReset} + +import sifive.fpgashells.shell.xilinx._ +import sifive.fpgashells.shell._ +import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler} +import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly} + +import sifive.blocks.devices.uart._ + +import chipyard._ +import chipyard.harness.{ApplyHarnessBinders} +import chipyard.iobinders.{HasIOBinders} + +class Arty100THarness(override implicit val p: Parameters) extends Arty100TShell with HasHarnessSignalReferences +{ + def dp = designParameters + + val chiptop = LazyModule(p(BuildTop)(p)) + + val clockOverlay = dp(ClockInputOverlayKey).map(_.place(ClockInputDesignInput())).head + val harnessSysPLL = dp(PLLFactoryKey) + val harnessSysPLLNode = harnessSysPLL() + println(s"Arty100T FPGA Base Clock Freq: ${dp(DefaultClockFrequencyKey)} MHz") + val dutClock = ClockSinkNode(freqMHz = dp(DefaultClockFrequencyKey)) + val dutWrangler = LazyModule(new ResetWrangler()) + val dutGroup = ClockGroup() + dutClock := dutWrangler.node := dutGroup := 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)) + + val ddrOverlay = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRArtyPlacedOverlay] + val ddrInParams = chiptop match { case td: ChipTop => + td.lazySystem match { case lsys: CanHaveMasterTLMemPort => + lsys.memTLNode.edges.in(0) + } + } + val ddrClient = TLClientNode(Seq(ddrInParams.master)) + val ddrBlockDuringReset = LazyModule(new TLBlockDuringReset(4)) + ddrOverlay.overlayOutput.ddr := ddrBlockDuringReset.node := ddrClient + + val ledOverlays = dp(LEDOverlayKey).map(_.place(LEDDesignInput())) + val all_leds = ledOverlays.map(_.overlayOutput.led) + val status_leds = all_leds.take(3) + val other_leds = all_leds.drop(3) + + def buildtopClock = dutClock.in.head._1.clock + def buildtopReset = dutClock.in.head._1.reset + def success = { require(false, "Unused"); false.B } + + InModuleBody { + clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin + + val clk_100mhz = clockOverlay.overlayOutput.node.out.head._1.clock + + // Blink the status LEDs for sanity + withClock(clk_100mhz) { + 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) + + ddrOverlay.mig.module.clock := buildtopClock + ddrOverlay.mig.module.reset := buildtopReset + ddrBlockDuringReset.module.clock := buildtopClock + ddrBlockDuringReset.module.reset := buildtopReset || !ddrOverlay.mig.module.io.port.init_calib_complete + + other_leds(6) := ddrOverlay.mig.module.io.port.init_calib_complete + + chiptop match { case d: HasIOBinders => + ApplyHarnessBinders(this, d.lazySystem, d.portMap) + } + } + +} diff --git a/fpga/src/main/scala/arty100t/HarnessBinders.scala b/fpga/src/main/scala/arty100t/HarnessBinders.scala new file mode 100644 index 00000000..3d86f354 --- /dev/null +++ b/fpga/src/main/scala/arty100t/HarnessBinders.scala @@ -0,0 +1,61 @@ +package chipyard.fpga.arty100t + +import chisel3._ + +import freechips.rocketchip.devices.debug.{HasPeripheryDebug, HasPeripheryDebugModuleImp} +import freechips.rocketchip.jtag.{JTAGIO} +import freechips.rocketchip.subsystem.{PeripheryBusKey} +import freechips.rocketchip.tilelink.{TLBundle} +import freechips.rocketchip.util.{HeterogeneousBag} + +import sifive.blocks.devices.uart.{UARTPortIO, HasPeripheryUARTModuleImp, UARTParams} +import sifive.blocks.devices.jtag.{JTAGPins, JTAGPinsFromPort} +import sifive.blocks.devices.pinctrl.{BasePin} + +import sifive.fpgashells.ip.xilinx.{IBUFG, IOBUF, PULLUP, PowerOnResetFPGAOnly} + +import chipyard._ +import chipyard.harness._ +import chipyard.iobinders.JTAGChipIO + +import testchipip._ + +class WithArty100TUARTTSI(uartBaudRate: BigInt = 115200) extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + implicit val p = chipyard.iobinders.GetSystemParameters(system) + ports.map({ port => + val ath = th.asInstanceOf[Arty100THarness] + val freq = p(PeripheryBusKey).dtsFrequency.get + val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) + withClockAndReset(th.buildtopClock, th.buildtopReset) { + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset) + val uart_to_serial = Module(new UARTToSerial( + freq, UARTParams(0, initBaudRate=uartBaudRate))) + val serial_width_adapter = Module(new SerialWidthAdapter( + narrowW = 8, wideW = SerialAdapter.SERIAL_TSI_WIDTH)) + serial_width_adapter.io.narrow.flipConnect(uart_to_serial.io.serial) + + ram.module.io.tsi_ser.flipConnect(serial_width_adapter.io.wide) + + ath.io_uart_bb.bundle <> uart_to_serial.io.uart + ath.other_leds(1) := uart_to_serial.io.dropped + + ath.other_leds(9) := ram.module.io.adapter_state(0) + ath.other_leds(10) := ram.module.io.adapter_state(1) + ath.other_leds(11) := ram.module.io.adapter_state(2) + ath.other_leds(12) := ram.module.io.adapter_state(3) + } + }) + } +}) + +class WithArty100TDDRTL extends OverrideHarnessBinder({ + (system: CanHaveMasterTLMemPort, th: HasHarnessSignalReferences, ports: Seq[HeterogeneousBag[TLBundle]]) => { + require(ports.size == 1) + val artyTh = th.asInstanceOf[Arty100THarness] + val bundles = artyTh.ddrClient.out.map(_._1) + val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType))) + bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io } + ddrClientBundle <> ports.head + } +}) diff --git a/fpga/src/main/scala/vcu118/Configs.scala b/fpga/src/main/scala/vcu118/Configs.scala index 6c8cb3a6..85b6ee24 100644 --- a/fpga/src/main/scala/vcu118/Configs.scala +++ b/fpga/src/main/scala/vcu118/Configs.scala @@ -47,7 +47,6 @@ class WithVCU118Tweaks extends Config( // io binders new WithUARTIOPassthrough ++ new WithSPIIOPassthrough ++ - new WithTLIOPassthrough ++ // other configuration new WithDefaultPeripherals ++ new chipyard.config.WithTLBackingMemory ++ // use TL backing memory diff --git a/fpga/src/main/scala/vcu118/IOBinders.scala b/fpga/src/main/scala/vcu118/IOBinders.scala index a1f67bcd..279f9865 100644 --- a/fpga/src/main/scala/vcu118/IOBinders.scala +++ b/fpga/src/main/scala/vcu118/IOBinders.scala @@ -42,11 +42,3 @@ class WithSPIIOPassthrough extends OverrideLazyIOBinder({ } } }) - -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) - } -}) diff --git a/fpga/src/main/scala/vcu118/TestHarness.scala b/fpga/src/main/scala/vcu118/TestHarness.scala index 90ce51e0..9a3cc0d5 100644 --- a/fpga/src/main/scala/vcu118/TestHarness.scala +++ b/fpga/src/main/scala/vcu118/TestHarness.scala @@ -7,15 +7,15 @@ import freechips.rocketchip.diplomacy.{LazyModule, LazyRawModuleImp, BundleBridg import freechips.rocketchip.config.{Parameters} import freechips.rocketchip.tilelink.{TLClientNode} -import sifive.fpgashells.shell.xilinx.{VCU118ShellBasicOverlays, UARTVCU118ShellPlacer, SDIOVCU118ShellPlacer, JTAGDebugBScanVCU118ShellPlacer, JTAGDebugVCU118ShellPlacer, cJTAGDebugVCU118ShellPlacer, PCIeVCU118FMCShellPlacer, PCIeVCU118EdgeShellPlacer, VCU118ShellPMOD, ChipLinkVCU118PlacedOverlay} +import sifive.fpgashells.shell.xilinx._ import sifive.fpgashells.ip.xilinx.{IBUF, PowerOnResetFPGAOnly} -import sifive.fpgashells.shell.{ClockInputOverlayKey, ClockInputDesignInput, ClockInputShellInput, UARTOverlayKey, UARTDesignInput, UARTShellInput, SPIOverlayKey, SPIDesignInput, SPIShellInput, JTAGDebugOverlayKey, JTAGDebugShellInput, JTAGDebugBScanOverlayKey, JTAGDebugBScanShellInput, cJTAGDebugOverlayKey, cJTAGDebugShellInput, PCIeOverlayKey, PCIeDesignInput, PCIeShellInput, DDROverlayKey, DDRDesignInput, DDRShellInput} +import sifive.fpgashells.shell._ import sifive.fpgashells.clocks.{ClockGroup, ClockSinkNode, PLLFactoryKey, ResetWrangler} import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTPortIO} import sifive.blocks.devices.spi.{PeripherySPIKey, SPIPortIO} -import chipyard.{HasHarnessSignalReferences, BuildTop, ChipTop, ExtTLMem, CanHaveMasterTLMemPort, DefaultClockFrequencyKey} +import chipyard._ import chipyard.iobinders.{HasIOBinders} import chipyard.harness.{ApplyHarnessBinders} diff --git a/generators/chipyard/src/main/scala/HarnessBinders.scala b/generators/chipyard/src/main/scala/HarnessBinders.scala index a47b08e0..21dfe588 100644 --- a/generators/chipyard/src/main/scala/HarnessBinders.scala +++ b/generators/chipyard/src/main/scala/HarnessBinders.scala @@ -321,6 +321,27 @@ class WithSimSerial extends OverrideHarnessBinder({ } }) +class WithUARTSerial extends OverrideHarnessBinder({ + (system: CanHavePeripheryTLSerial, th: HasHarnessSignalReferences, ports: Seq[ClockedIO[SerialIO]]) => { + implicit val p = chipyard.iobinders.GetSystemParameters(system) + ports.map({ port => + val freq = p(PeripheryBusKey).dtsFrequency.get + val bits = SerialAdapter.asyncQueue(port, th.buildtopClock, th.buildtopReset) + withClockAndReset(th.buildtopClock, th.buildtopReset) { + val ram = SerialAdapter.connectHarnessRAM(system.serdesser.get, bits, th.buildtopReset) + val uart_to_serial = Module(new UARTToSerial(freq, UARTParams(0))) + val serial_width_adapter = Module(new SerialWidthAdapter( + 8, SerialAdapter.SERIAL_TSI_WIDTH)) + ram.module.io.tsi_ser.flipConnect(serial_width_adapter.io.wide) + UARTAdapter.connect(Seq(uart_to_serial.io.uart), uart_to_serial.div) + serial_width_adapter.io.narrow.flipConnect(uart_to_serial.io.serial) + th.success := false.B + } + }) + } +}) + + class WithTraceGenSuccess extends OverrideHarnessBinder({ (system: TraceGenSystemModuleImp, th: HasHarnessSignalReferences, ports: Seq[Bool]) => { ports.map { p => when (p) { th.success := true.B } } diff --git a/generators/chipyard/src/main/scala/IOBinders.scala b/generators/chipyard/src/main/scala/IOBinders.scala index efbe542d..71eef713 100644 --- a/generators/chipyard/src/main/scala/IOBinders.scala +++ b/generators/chipyard/src/main/scala/IOBinders.scala @@ -13,6 +13,7 @@ import freechips.rocketchip.amba.axi4.{AXI4Bundle, AXI4SlaveNode, AXI4MasterNode import freechips.rocketchip.util._ import freechips.rocketchip.prci._ import freechips.rocketchip.groundtest.{GroundTestSubsystemModuleImp, GroundTestSubsystem} +import freechips.rocketchip.tilelink.{TLBundle} import sifive.blocks.devices.gpio._ import sifive.blocks.devices.uart._ @@ -23,6 +24,7 @@ import barstools.iocell.chisel._ import testchipip._ import icenet.{CanHavePeripheryIceNIC, SimNetwork, NicLoopback, NICKey, NICIOvonly} +import chipyard.{CanHaveMasterTLMemPort} import chipyard.clocking.{HasChipyardPRCI, DividerOnlyClockGenerator} import scala.reflect.{ClassTag} @@ -381,6 +383,15 @@ class WithCustomBootPin extends OverrideIOBinder({ }).getOrElse((Nil, Nil)) }) +class WithTLMemPunchthrough 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) + } +}) + + class WithDontTouchPorts extends OverrideIOBinder({ (system: DontTouch) => system.dontTouchPorts(); (Nil, Nil) }) diff --git a/generators/chipyard/src/main/scala/Subsystem.scala b/generators/chipyard/src/main/scala/Subsystem.scala index 1ef19b39..34175d39 100644 --- a/generators/chipyard/src/main/scala/Subsystem.scala +++ b/generators/chipyard/src/main/scala/Subsystem.scala @@ -62,6 +62,9 @@ class ChipyardSubsystem(implicit p: Parameters) extends BaseSubsystem val intSink = IntSinkNode(IntSinkPortSimple()) intSink := intNexus :=* ibus.toPLIC + // avoids a bug when there are no interrupt sources + ibus.fromAsync := NullIntSource() + // Need to have at least 1 driver to the tile notification sinks tileHaltXbarNode := IntSourceNode(IntSourcePortSimple()) tileWFIXbarNode := IntSourceNode(IntSourcePortSimple()) diff --git a/generators/chipyard/src/main/scala/TestHarness.scala b/generators/chipyard/src/main/scala/TestHarness.scala index d8884410..240ae5cc 100644 --- a/generators/chipyard/src/main/scala/TestHarness.scala +++ b/generators/chipyard/src/main/scala/TestHarness.scala @@ -27,7 +27,6 @@ trait HasHarnessSignalReferences { def getRefClockFreq: Double = refClockFreq def buildtopClock: Clock def buildtopReset: Reset - def dutReset: Reset def success: Bool } @@ -91,7 +90,6 @@ class TestHarness(implicit val p: Parameters) extends Module with HasHarnessSign io.success := false.B - val dutReset = buildtopReset.asAsyncReset val success = io.success lazyDut match { case d: HasIOBinders => diff --git a/generators/chipyard/src/main/scala/config/AbstractConfig.scala b/generators/chipyard/src/main/scala/config/AbstractConfig.scala index 191954f6..b084845e 100644 --- a/generators/chipyard/src/main/scala/config/AbstractConfig.scala +++ b/generators/chipyard/src/main/scala/config/AbstractConfig.scala @@ -28,6 +28,7 @@ class AbstractConfig extends Config( // IOCells are generated for "Chip-like" IOs, while simulation-only IOs are directly punched through new chipyard.iobinders.WithAXI4MemPunchthrough ++ new chipyard.iobinders.WithAXI4MMIOPunchthrough ++ + new chipyard.iobinders.WithTLMemPunchthrough ++ new chipyard.iobinders.WithL2FBusAXI4Punchthrough ++ new chipyard.iobinders.WithBlockDeviceIOPunchthrough ++ new chipyard.iobinders.WithNICIOPunchthrough ++ diff --git a/generators/chipyard/src/main/scala/config/RocketConfigs.scala b/generators/chipyard/src/main/scala/config/RocketConfigs.scala index c6f5ca22..b6677cb1 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -21,6 +21,14 @@ class TinyRocketConfig extends Config( new freechips.rocketchip.subsystem.With1TinyCore ++ // single tiny rocket-core new chipyard.config.AbstractConfig) +class UARTTSIRocketConfig extends Config( + new chipyard.harness.WithUARTSerial ++ + new chipyard.config.WithNoUART ++ + new chipyard.config.WithMemoryBusFrequency(10) ++ + new chipyard.config.WithPeripheryBusFrequency(10) ++ + new freechips.rocketchip.subsystem.WithNBigCores(1) ++ // single rocket-core + new chipyard.config.AbstractConfig) + class SimAXIRocketConfig extends Config( new chipyard.harness.WithSimAXIMem ++ // drive the master AXI4 memory with a SimAXIMem, a 1-cycle magic memory, instead of default SimDRAM new freechips.rocketchip.subsystem.WithNBigCores(1) ++ diff --git a/generators/chipyard/src/main/scala/config/fragments/PeripheralFragments.scala b/generators/chipyard/src/main/scala/config/fragments/PeripheralFragments.scala index eec0d15d..ec9ff47c 100644 --- a/generators/chipyard/src/main/scala/config/fragments/PeripheralFragments.scala +++ b/generators/chipyard/src/main/scala/config/fragments/PeripheralFragments.scala @@ -37,6 +37,10 @@ class WithUART(baudrate: BigInt = 115200) extends Config((site, here, up) => { UARTParams(address = 0x54000000L, nTxEntries = 256, nRxEntries = 256, initBaudRate = baudrate)) }) +class WithNoUART extends Config((site, here, up) => { + case PeripheryUARTKey => Nil +}) + class WithUARTFIFOEntries(txEntries: Int, rxEntries: Int) extends Config((site, here, up) => { case PeripheryUARTKey => up(PeripheryUARTKey).map(_.copy(nTxEntries = txEntries, nRxEntries = rxEntries)) }) diff --git a/generators/chipyard/src/main/scala/config/fragments/SubsystemFragments.scala b/generators/chipyard/src/main/scala/config/fragments/SubsystemFragments.scala index 534259ab..c41e2716 100644 --- a/generators/chipyard/src/main/scala/config/fragments/SubsystemFragments.scala +++ b/generators/chipyard/src/main/scala/config/fragments/SubsystemFragments.scala @@ -2,6 +2,7 @@ package chipyard.config import freechips.rocketchip.config.{Config} import freechips.rocketchip.subsystem.{SystemBusKey, BankedL2Key, CoherenceManagerWrapper} +import freechips.rocketchip.diplomacy.{DTSTimebase} // Replaces the L2 with a broadcast manager for maintaining coherence class WithBroadcastManager extends Config((site, here, up) => { @@ -11,3 +12,7 @@ class WithBroadcastManager extends Config((site, here, up) => { class WithSystemBusWidth(bitWidth: Int) extends Config((site, here, up) => { case SystemBusKey => up(SystemBusKey, site).copy(beatBytes=bitWidth/8) }) + +class WithDTSTimebase(freqMHz: BigInt) extends Config((site, here, up) => { + case DTSTimebase => freqMHz +}) diff --git a/scripts/check-tracegen.sh b/scripts/check-tracegen.sh index e2974fb1..c30447ee 100755 --- a/scripts/check-tracegen.sh +++ b/scripts/check-tracegen.sh @@ -6,25 +6,26 @@ SCRIPT_DIR=$(dirname $0) AXE_DIR=$(realpath ${SCRIPT_DIR}/../tools/axe) ROCKET_DIR=$(realpath ${SCRIPT_DIR}/../generators/rocket-chip) +TMP_DIR=$(mktemp -d -t tracegen-XXXXXXXX) TO_AXE=${ROCKET_DIR}/scripts/toaxe.py -TO_AXE_PY3=/tmp/toaxe.py +TO_AXE_PY3=${TMP_DIR}/toaxe.py AXE=${AXE_DIR}/src/axe AXE_SHRINK=${AXE_DIR}/src/axe-shrink.py -AXE_SHRINK_PY3=/tmp/axe-shrink.py +AXE_SHRINK_PY3=${TMP_DIR}/axe-shrink.py # TODO: convert scripts to py3 in src -2to3 $TO_AXE -o /tmp -n -w +2to3 $TO_AXE -o ${TMP_DIR} -n -w sed -i '30d' $TO_AXE_PY3 # remove import sets -2to3 $AXE_SHRINK -o /tmp -n -w +2to3 $AXE_SHRINK -o ${TMP_DIR} -n -w PATH=$PATH:${AXE_DIR}/src -grep '.*:.*#.*@' $1 > /tmp/clean-trace.txt -python "$TO_AXE_PY3" /tmp/clean-trace.txt > /tmp/trace.axe -result=$("$AXE" check wmo /tmp/trace.axe) +grep '.*:.*#.*@' $1 > ${TMP_DIR}/clean-trace.txt +python "$TO_AXE_PY3" ${TMP_DIR}/clean-trace.txt > ${TMP_DIR}/trace.axe +result=$("$AXE" check wmo ${TMP_DIR}/trace.axe) if [ "$result" != OK ]; then - "$AXE_SHRINK_PY3" wmo /tmp/trace.axe + "$AXE_SHRINK_PY3" wmo ${TMP_DIR}/trace.axe else echo OK fi