Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add Baremetal IDE support #1534

Merged
merged 18 commits into from
Jan 7, 2024
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,9 @@
[submodule "software/nvdla-workload"]
path = software/nvdla-workload
url = https://github.com/ucb-bar/nvdla-workload.git
[submodule "software/baremetal-ide"]
path = software/baremetal-ide
url = https://github.com/ucb-bar/Baremetal-IDE.git
[submodule "tools/dromajo/dromajo-src"]
path = tools/dromajo/dromajo-src
url = https://github.com/riscv-boom/dromajo.git
Expand Down
110 changes: 109 additions & 1 deletion generators/chipyard/src/main/scala/config/ChipConfigs.scala
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,115 @@ class ChipLikeRocketConfig extends Config(
// Create the uncore clock group
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("implicit", "sbus", "mbus", "cbus", "system_bus", "fbus", "pbus"), Nil)) ++

new chipyard.config.AbstractConfig)
new chipyard.config.AbstractConfig
)

/**
* Chip Config generated by the GUI
*/
class ExampleChipConfig extends Config(
// ==================================
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can this be merged into ChipLikeRocketConfig?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Where is the ChipLikeRocketConfig defined...?

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actualy I forgot, hasn't been merged yet, after #1484 I change ChipLikeQuadRocket to ChipLikeRocket

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There should be only 1 basic ChipConfig ... this should be merged into ChipLikeRocketConfig above. Is there anything here that should not be merged into that?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The ExampleChipConfig is generated by the GUI interface. It lists every Config fragment in the chip explicitly within this class.

The idea is that this gives the user a clearer view of what components are included inside a chip, what Config fragment can be swapped with what else etc., and therefore can be used as a good teaching material for getting started tutorials (tutorials coming soon).

Listing Config fragments out in a single class also helps resolve the "what is overridden by what" problem. For example, for a tapeout chip, instead of overriding WithXXXPunchthrough with WithXXXIOBinder, the user will replace and switch between these two fragments for simulation vs. tapeout.

I'll try to merge this to the ChipLikeRocketConfig in future PR, but since this ExampleChipConfig is subject to user change (GUI will auto-generate the ChipConfigs.scala based on user configuration), and the scope can expand beyond using rocket cores, I suggest giving the class a more versatile name.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

At one point, AbstractConfig did not exist, and every single example config included every single relevant config fragment, as you describe. I fought for this model for quite some time, until it became untenable to maintain so many 50-line configs.

My perspective on "tapeout configs" is that they should be as explicit as possible, and will often require careful hand-edits/bespoke-configs. With that in mind, removing AbstractConfig from the ChipLike configs is a move I would support.

However, I'm not sure that using GUI-configs as "tapeout configs" is the right direction, given that the GUI will only be able to support a smaller design space than what the full system is capable of.

I'd also prefer to consolidate any "ChipLike" example config into the ChipLikeRocketConfig, as currently there is CI/regressions around that Config that test many features, including a regression that builds and tests the FPGA bringup harness.

A proposal based on the above points:

  • Expand ChipLikeRocketConfig to not override AbstractConfig.
  • Have GUI dump configs into a separate file. Since I expect users will often want to edit ChipConfigs.scala by hand, this also prevents edit conflicts. One idea... user specifies a name in the GUI... GUI dumps the file into configs/GUI_<user_config_name>.scala.
  • Make GUI flexible enough to support generating the exact same design (and exact same config text) as the ChipLikeRocketConfig.

// Set up TestHarness
// ==================================
// The HarnessBinders control generation of hardware in the TestHarness
new chipyard.harness.WithUARTAdapter ++ // add UART adapter to display UART on stdout, if uart is present
new chipyard.harness.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.WithSimDebug ++ // add SimJTAG or SimDTM adapters if debug module is enabled
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.WithSimAXIMMIO ++ // add SimAXIMem for axi4 mmio port, if enabled
new chipyard.harness.WithTieOffInterrupts ++ // tie-off interrupt ports, 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.WithClockAndResetFromHarness ++ // all Clock/Reset I/O in ChipTop should be driven by harnessClockInstantiator
new chipyard.harness.WithAbsoluteFreqHarnessClockInstantiator ++ // generate clocks in harness with unsynthesizable ClockSourceAtFreqMHz

// ==================================
// Set up I/O harness
// ==================================
// The IOBinders instantiate ChipTop IOs to match desired digital IOs
// 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 ++
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The "Punchthrough" IOBinders should not be included in any "Chip" configs, since they are not intended to be taped outl.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The idea is to make the default example a simulation-only setting. These Config fragments are directly extracted from chipyard.config.AbstractConfig.

new chipyard.iobinders.WithNICIOPunchthrough ++
new chipyard.iobinders.WithSerialTLIOCells ++
new chipyard.iobinders.WithDebugIOCells ++
new chipyard.iobinders.WithUARTIOCells ++
new chipyard.iobinders.WithGPIOCells ++
new chipyard.iobinders.WithSPIIOCells ++
new chipyard.iobinders.WithTraceIOPunchthrough ++
new chipyard.iobinders.WithExtInterruptIOCells ++
new chipyard.iobinders.WithCustomBootPin ++

// ==================================
// Set up Memory Devices
// ==================================
// External memory section
new testchipip.WithSerialTLClientIdBits(4) ++ // support up to 1 << 4 simultaneous requests from serialTL port
new testchipip.WithSerialTLWidth(32) ++ // fatten the serialTL interface to improve testing performance
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is wider than what we usually build (1-4 bits)

new testchipip.WithDefaultSerialTL ++ // use serialized tilelink port to external serialadapter/harnessRAM

new testchipip.WithMbusScratchpad(base = 0x08000000) ++ // use rocket l1 DCache scratchpad as base phys mem

// Peripheral section
new chipyard.config.WithUART(address = 0x10020000, baudrate = 115200) ++

// Core section
new chipyard.config.WithBootROM ++ // use default bootrom
new testchipip.WithCustomBootPin ++ // add a custom-boot-pin to support pin-driven boot address
new testchipip.WithBootAddrReg ++ // add a boot-addr-reg for configurable boot address // use default bootrom

// ==================================
// Set up tiles
// ==================================
// Debug settings
new chipyard.config.WithJTAGDTMKey(idcodeVersion = 2, partNum = 0x000, manufId = 0x489, debugIdleCycles = 5) ++
new freechips.rocketchip.subsystem.WithNBreakpoints(2) ++
new freechips.rocketchip.subsystem.WithNBreakpoints(2) ++
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Duplicate

new freechips.rocketchip.subsystem.WithJtagDTM ++ // set the debug module to expose a JTAG port

// Cache settings
new freechips.rocketchip.subsystem.WithL1ICacheSets(64) ++
new freechips.rocketchip.subsystem.WithL1ICacheWays(2) ++
new freechips.rocketchip.subsystem.WithL1DCacheSets(64) ++
new freechips.rocketchip.subsystem.WithL1DCacheWays(2) ++
new chipyard.config.WithL2TLBs(0) ++
new freechips.rocketchip.subsystem.WithInclusiveCache ++ // use Sifive L2 cache

// Memory settings
new chipyard.config.WithNPMPs(0) ++
new freechips.rocketchip.subsystem.WithNMemoryChannels(2) ++ // Default 2 memory channels
new freechips.rocketchip.subsystem.WithNoMMIOPort ++ // no top-level MMIO master port (overrides default set in rocketchip)
new freechips.rocketchip.subsystem.WithNoSlavePort ++ // no top-level MMIO slave port (overrides default set in rocketchip)
new freechips.rocketchip.subsystem.WithCoherentBusTopology ++ // hierarchical buses including sbus/mbus/pbus/fbus/cbus/l2

// Core settings
new freechips.rocketchip.subsystem.WithNExtTopInterrupts(0) ++ // no external interrupts
new freechips.rocketchip.subsystem.WithNSmallCores(1) ++

// ==================================
// Set up reset and clocking
// ==================================
new freechips.rocketchip.subsystem.WithDontDriveBusClocksFromSBus ++ // leave the bus clocks undriven by sbus
new freechips.rocketchip.subsystem.WithClockGateModel ++ // add default EICG_wrapper clock gate model
new chipyard.config.WithNoSubsystemDrivenClocks ++ // drive the subsystem diplomatic clocks from ChipTop instead of using implicit clocks
new chipyard.config.WithInheritBusFrequencyAssignments ++ // Unspecified clocks within a bus will receive the bus frequency if set
new chipyard.config.WithPeripheryBusFrequency(100.0) ++ // Default 500 MHz pbus
new chipyard.config.WithMemoryBusFrequency(100.0) ++ // Default 500 MHz mbus
new chipyard.clocking.WithPassthroughClockGenerator ++
new chipyard.clocking.WithClockGroupsCombinedByName(("uncore", Seq("sbus", "mbus", "pbus", "fbus", "cbus", "implicit"), Seq("tile"))) ++

// ==================================
// Base Settings
// ==================================
new freechips.rocketchip.subsystem.WithDTS("ucb-bar, chipyard", Nil) ++ // custom device name for DTS
new freechips.rocketchip.system.BaseConfig // "base" rocketchip system
)


// A simple config demonstrating a "bringup prototype" to bringup the ChipLikeRocketconfig
class ChipBringupHostConfig extends Config(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ import chipyard.{ExtTLMem}
* @param hang the power-on reset vector, i.e. the program counter will be set to this value on reset
* @param contentFileName the path to the BootROM image
*/
class WithBootROM(address: BigInt = 0x10000, size: Int = 0x10000, hang: BigInt = 0x10040) extends Config((site, here, up) => {
class WithBootROM(address: BigInt = 0x10000, size: Int = 0x10000, hang: BigInt = 0x10000) extends Config((site, here, up) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If this is changed, then we need to change the testchipip bootrom as well. Does this PR have a corresponding testchipip PR that changes that?

Also, what is the motivation for this change?

case BootROMLocated(x) => up(BootROMLocated(x), site)
.map(_.copy(
address = address,
Expand Down
1 change: 1 addition & 0 deletions software/baremetal-ide
Submodule baremetal-ide added at f48809
Loading