diff --git a/.github/scripts/check-commit.sh b/.github/scripts/check-commit.sh index 11d12599..a9c0300b 100755 --- a/.github/scripts/check-commit.sh +++ b/.github/scripts/check-commit.sh @@ -88,7 +88,7 @@ dir="software" branches=("master" "dev") search -submodules=("DRAMSim2" "axe" "barstools" "chisel-testers" "dsptools" "rocket-dsp-utils" "torture") +submodules=("DRAMSim2" "axe" "barstools" "dsptools" "rocket-dsp-utils" "torture") dir="tools" branches=("master" "dev") search diff --git a/.github/scripts/defaults.sh b/.github/scripts/defaults.sh index fb83ad00..6013d7d4 100755 --- a/.github/scripts/defaults.sh +++ b/.github/scripts/defaults.sh @@ -14,9 +14,6 @@ REMOTE_CHIPYARD_DIR=$GITHUB_WORKSPACE REMOTE_SIM_DIR=$REMOTE_CHIPYARD_DIR/sims/verilator REMOTE_FIRESIM_DIR=$REMOTE_CHIPYARD_DIR/sims/firesim/sim REMOTE_FPGA_DIR=$REMOTE_CHIPYARD_DIR/fpga -REMOTE_JAVA_OPTS="-Xmx10G -Xss8M" -# Disable the supershell to greatly improve the readability of SBT output when captured by Circle CI -REMOTE_SBT_OPTS="-Dsbt.ivy.home=$REMOTE_WORK_DIR/.ivy2 -Dsbt.supershell=false -Dsbt.global.base=$REMOTE_WORK_DIR/.sbt -Dsbt.boot.directory=$REMOTE_WORK_DIR/.sbt/boot" # local variables (aka within the docker container) LOCAL_CHIPYARD_DIR=$GITHUB_WORKSPACE @@ -26,7 +23,8 @@ LOCAL_FIRESIM_DIR=$LOCAL_CHIPYARD_DIR/sims/firesim/sim # CI uses temp directories with very long names # explicitly force socket creation to use /tmp to avoid name length errors # https://github.com/sbt/sbt/pull/6887 -JAVA_TMP_DIR=$(mktemp -d -t ci-cy-XXXXXXXX) +REMOTE_JAVA_TMP_DIR=$(mktemp -d -t ci-cy-XXXXXXXX) +REMOTE_COURSIER_CACHE=$REMOTE_WORK_DIR/.coursier-cache # key value store to get the build groups declare -A grouping diff --git a/.github/scripts/remote-do-rtl-build.sh b/.github/scripts/remote-do-rtl-build.sh index b5755d01..445c1c31 100755 --- a/.github/scripts/remote-do-rtl-build.sh +++ b/.github/scripts/remote-do-rtl-build.sh @@ -52,6 +52,8 @@ read -a keys <<< ${grouping[$1]} # need to set the PATH to use the new verilator (with the new verilator root) for key in "${keys[@]}" do - export COURSIER_CACHE=$REMOTE_WORK_DIR/.coursier-cache - make -j$REMOTE_MAKE_NPROC -C $REMOTE_MAKE_DIR FIRRTL_LOGLEVEL=info JAVA_TMP_DIR=$JAVA_TMP_DIR SBT_OPTS="$REMOTE_SBT_OPTS" ${mapping[$key]} + export COURSIER_CACHE=$REMOTE_COURSIER_CACHE + export JVM_MEMORY=10G + export JAVA_TMP_DIR=$REMOTE_JAVA_TMP_DIR + make -j$REMOTE_MAKE_NPROC -C $REMOTE_MAKE_DIR FIRRTL_LOGLEVEL=info ${mapping[$key]} done diff --git a/.github/scripts/remote-run-firesim-scala-tests.sh b/.github/scripts/remote-run-firesim-scala-tests.sh index 960d1706..70a41e27 100755 --- a/.github/scripts/remote-run-firesim-scala-tests.sh +++ b/.github/scripts/remote-run-firesim-scala-tests.sh @@ -15,6 +15,7 @@ cd $REMOTE_CHIPYARD_DIR # Run Firesim Scala Tests export FIRESIM_ENV_SOURCED=1; -export COURSIER_CACHE=$REMOTE_WORK_DIR/.coursier-cache -JAVA_TOOL_OPTIONS="$REMOTE_JAVA_OPTS -Djava.io.tmpdir=$(mktemp -d -t cy-fsim-XXXXXXXX)" -make -C $REMOTE_FIRESIM_DIR JAVA_TOOL_OPTIONS="$JAVA_TOOL_OPTIONS" SBT_OPTS="$REMOTE_SBT_OPTS" TARGET_SBT_PROJECT="{file:$REMOTE_CHIPYARD_DIR}firechip" testOnly ${mapping[$1]} +export COURSIER_CACHE=$REMOTE_COURSIER_CACHE +export JVM_MEMORY=10G +export JAVA_TMP_DIR=$REMOTE_JAVA_TMP_DIR +make -C $REMOTE_FIRESIM_DIR TARGET_SBT_PROJECT="{file:$REMOTE_CHIPYARD_DIR}firechip" testOnly ${mapping[$1]} diff --git a/.github/workflows/chipyard-full-flow.yml b/.github/workflows/chipyard-full-flow.yml index 22382571..7fe09a23 100644 --- a/.github/workflows/chipyard-full-flow.yml +++ b/.github/workflows/chipyard-full-flow.yml @@ -78,9 +78,23 @@ jobs: run: | cd ${{ env.REMOTE_WORK_DIR }} eval "$(conda shell.bash hook)" + mkdir ${{ env.JAVA_TMP_DIR }} export MAKEFLAGS="-j32" ./build-setup.sh -f + run-cfg-finder: + name: run-cfg-finder + needs: [setup-repo] + runs-on: ferry + steps: + - name: Run config finder + run: | + cd ${{ env.REMOTE_WORK_DIR }} + eval "$(conda shell.bash hook)" + source env.sh + cd sims/verilator + make find-config-fragments + run-tutorial: name: run-tutorial needs: [setup-repo] diff --git a/.gitignore b/.gitignore index d3cf251d..9c73c6e1 100644 --- a/.gitignore +++ b/.gitignore @@ -24,3 +24,5 @@ first-clone-setup-fast-log project/.bloop/ project/metals.sbt project/project/ +.ivy2 +.sbt diff --git a/.gitmodules b/.gitmodules index 42d8e264..e6f3f772 100644 --- a/.gitmodules +++ b/.gitmodules @@ -31,9 +31,6 @@ [submodule "tools/dsptools"] path = tools/dsptools url = https://github.com/ucb-bar/dsptools.git -[submodule "tools/chisel-testers"] - path = tools/chisel-testers - url = https://github.com/freechipsproject/chisel-testers.git [submodule "generators/sha3"] path = generators/sha3 url = https://github.com/ucb-bar/sha3.git diff --git a/common.mk b/common.mk index 73d2d6c4..7f2a1f50 100644 --- a/common.mk +++ b/common.mk @@ -48,6 +48,7 @@ HELP_COMMANDS += \ " run-tests = run all assembly and benchmark tests" \ " launch-sbt = start sbt terminal" \ " {shutdown,start}-sbt-server = shutdown or start sbt server if using ENABLE_SBT_THIN_CLIENT" \ +" find-config-fragments = list all config. fragments and their locations (recursive up to CONFIG_FRAG_LEVELS=$(CONFIG_FRAG_LEVELS))" ######################################################################################### # include additional subproject make fragments @@ -387,8 +388,22 @@ start-sbt-server: check-thin-client cd $(base_dir) && $(SBT) "exit" ######################################################################################### -# print help text +# print help text (and other help) ######################################################################################### +# helper to add newlines (avoid bash argument too long) +define \n + + +endef + +CONFIG_FRAG_LEVELS ?= 3 +.PHONY: find-config-fragments +find-config-fragments: private IN_F := $(shell mktemp -d -t cy-XXXXXXXX)/scala_files.f +find-config-fragments: $(SCALA_SOURCES) + @$(foreach file,$(SCALA_SOURCES),echo $(file) >> $(IN_F)${\n}) + $(base_dir)/scripts/config-finder.py -l $(CONFIG_FRAG_LEVELS) $(IN_F) + @rm -rf $(dir $(IN_F)) + .PHONY: help help: @for line in $(HELP_LINES); do echo "$$line"; done diff --git a/docs/Customization/Keys-Traits-Configs.rst b/docs/Customization/Keys-Traits-Configs.rst index c92ad201..364f31cb 100644 --- a/docs/Customization/Keys-Traits-Configs.rst +++ b/docs/Customization/Keys-Traits-Configs.rst @@ -75,3 +75,9 @@ We can use this config fragment when composing our configs. .. note:: Readers who want more information on the configuration system may be interested in reading :ref:`cdes`. + +Chipyard Config Fragments +------------------------- + +For discoverability, users can run ``make find-config-fragments`` to see a list of config. fragments +(config. fragments that match "class NAME extends CONFIG\n" on a single line and a subset of their children) and their file path in a fully initialized Chipyard repository. 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/docs/Tools/Chisel-Testers.rst b/docs/Tools/Chisel-Testers.rst deleted file mode 100644 index 9570dd61..00000000 --- a/docs/Tools/Chisel-Testers.rst +++ /dev/null @@ -1,7 +0,0 @@ -Chisel Testers -============================== - -`Chisel Testers `__ is a library for writing tests for Chisel designs. -It provides a Scala API for interacting with a DUT. -It can use multiple backends, including things such as Treadle and Verilator. -See :ref:`Tools/Treadle:Treadle and FIRRTL Interpreter` and :ref:`sw-rtl-sim-intro` for more information on these simulation methods. diff --git a/docs/Tools/index.rst b/docs/Tools/index.rst index fecb2043..88161269 100644 --- a/docs/Tools/index.rst +++ b/docs/Tools/index.rst @@ -11,7 +11,6 @@ The following pages will introduce them, and how we can use them in order to gen Chisel FIRRTL Treadle - Chisel-Testers Dsptools Barstools Dromajo 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 c500888c..e8f72bfb 100644 --- a/generators/chipyard/src/main/scala/config/RocketConfigs.scala +++ b/generators/chipyard/src/main/scala/config/RocketConfigs.scala @@ -25,6 +25,14 @@ class RocketGPUConfig extends Config( new freechips.rocketchip.subsystem.WithNCustomSmallCores(2) ++ // multiple 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/generators/testchipip b/generators/testchipip index 6e8a6842..802d2b4a 160000 --- a/generators/testchipip +++ b/generators/testchipip @@ -1 +1 @@ -Subproject commit 6e8a68424216c9a02916af16a15850f40a534a22 +Subproject commit 802d2b4a4d45556b00db1159f4af1b9d40eca8f6 diff --git a/scripts/config-finder.py b/scripts/config-finder.py new file mode 100755 index 00000000..a7377939 --- /dev/null +++ b/scripts/config-finder.py @@ -0,0 +1,76 @@ +#!/usr/bin/env python3 + +import argparse +import subprocess +from collections import defaultdict +import re +from copy import deepcopy +import os + +cy_path = os.path.dirname(os.path.dirname(os.path.realpath(__file__))) + +# from https://gist.github.com/angstwad/bf22d1822c38a92ec0a9 +def deep_merge(a: dict, b: dict) -> dict: + """Merge two dicts and return a singular dict""" + result = deepcopy(a) + for bk, bv in b.items(): + av = result.get(bk) + if isinstance(av, dict) and isinstance(bv, dict): + result[bk] = deep_merge(av, bv) + else: + result[bk] = deepcopy(bv) + return result + +if __name__ == "__main__": + parser = argparse.ArgumentParser(description='Pretty print all configs given a filelist of scala files') + parser.add_argument('FILE', type=str, help='Filelist of scala files to search within') + parser.add_argument('-l', '--levels', default=0, type=int, help='Number of levels to recursively look for configs') + args = parser.parse_args() + + files = [] + with open(args.FILE, 'r') as f: + files = f.read().splitlines() + + cmd = ['grep', '-o', r"class \+.* \+extends \+Config"] + files + r = subprocess.run(cmd, check=True, capture_output=True) + + base_file_path_dict = defaultdict(list) + for l in r.stdout.decode("UTF-8").splitlines(): + match = re.match(r"^(.*):class +([a-zA-Z_$][a-zA-Z\d_$]*).* +extends", l) + if match: + base_file_path_dict[match.group(1)].append(match.group(2)) + + levels = [] + for level in range(args.levels): + if level == 0: + # use the base + dict_to_use = base_file_path_dict + else: + # use the level-1 dict + assert len(levels) > 0 + dict_to_use = levels[-1] + + file_path_dict = defaultdict(list) + + for configs in dict_to_use.values(): + for config in configs: + cmd = ['grep', '-o', r"class \+.* \+extends \+" + f"{config}"] + files + r = subprocess.run(cmd, capture_output=True) + + for l in r.stdout.decode("UTF-8").splitlines(): + match = re.match(r"^(.*):class +([a-zA-Z_$][a-zA-Z\d_$]*).* +extends", l) + if match: + file_path_dict[match.group(1)].append(match.group(2)) + + levels.append(file_path_dict) + + final_dict = base_file_path_dict + for dct in levels: + final_dict = deep_merge(final_dict, dct) + + print(f"Finding all one-line config. fragments (up to {args.levels} levels)\n") + for k, v in final_dict.items(): + print(f"{k.replace(cy_path, 'chipyard')}:") + for e in v: + print(f" {e}") + print("") diff --git a/sims/firesim b/sims/firesim index 9d3462ed..69e428f0 160000 --- a/sims/firesim +++ b/sims/firesim @@ -1 +1 @@ -Subproject commit 9d3462ed1357cc198be8485ae57635b9651999d5 +Subproject commit 69e428f01029dbdb21f23288f74bd37f0f759a60 diff --git a/tools/chisel-testers b/tools/chisel-testers deleted file mode 160000 index ce4e027e..00000000 --- a/tools/chisel-testers +++ /dev/null @@ -1 +0,0 @@ -Subproject commit ce4e027e5f3d871df59236b8471ea3e5be40130e diff --git a/variables.mk b/variables.mk index 3cbe0abd..84e6ed89 100644 --- a/variables.mk +++ b/variables.mk @@ -217,7 +217,7 @@ sim_common_files ?= $(build_dir)/sim_files.common.f ######################################################################################### JAVA_HEAP_SIZE ?= 8G JAVA_TMP_DIR ?= $(base_dir)/.java_tmp -export JAVA_TOOL_OPTIONS ?= -Xmx$(JAVA_HEAP_SIZE) -Xss8M -Djava.io.tmpdir=$(JAVA_TMP_DIR) +export JAVA_TOOL_OPTIONS ?= -Xmx$(JAVA_HEAP_SIZE) -Xss8M -Dsbt.supershell=false -Djava.io.tmpdir=$(JAVA_TMP_DIR) ######################################################################################### # default sbt launch command @@ -234,7 +234,8 @@ SBT_CLIENT_FLAG = --client endif # passes $(JAVA_TOOL_OPTIONS) from env to java -SBT_BIN ?= java -jar $(ROCKETCHIP_DIR)/sbt-launch.jar +export SBT_OPTS ?= -Dsbt.ivy.home=$(base_dir)/.ivy2 -Dsbt.global.base=$(base_dir)/.sbt -Dsbt.boot.directory=$(base_dir)/.sbt/boot/ +SBT_BIN ?= java -jar $(ROCKETCHIP_DIR)/sbt-launch.jar $(SBT_OPTS) SBT = $(SBT_BIN) $(SBT_CLIENT_FLAG) SBT_NON_THIN = $(subst $(SBT_CLIENT_FLAG),,$(SBT))