-
Notifications
You must be signed in to change notification settings - Fork 673
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #2136 from doihead/intel-fpgas
Add support for Intel/Altera FPGAs + Trenz Datastorm board
- Loading branch information
Showing
5 changed files
with
296 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Submodule fpga-shells
updated
20 files
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
// See LICENSE for license details. | ||
package chipyard.fpga.datastorm | ||
|
||
import org.chipsalliance.cde.config._ | ||
import freechips.rocketchip.subsystem._ | ||
import freechips.rocketchip.devices.debug._ | ||
import freechips.rocketchip.devices.tilelink._ | ||
import org.chipsalliance.diplomacy._ | ||
import org.chipsalliance.diplomacy.lazymodule._ | ||
import freechips.rocketchip.system._ | ||
import freechips.rocketchip.tile._ | ||
|
||
import sifive.blocks.devices.uart._ | ||
import sifive.fpgashells.shell.{DesignKey} | ||
|
||
import testchipip.serdes.{SerialTLKey} | ||
|
||
import chipyard.{BuildSystem} | ||
import testchipip.soc.WithNoScratchpads | ||
import sifive.blocks.devices.spi.SPIProtocol.width | ||
import chipyard.iobinders.WithGPIOPunchthrough | ||
|
||
// don't use FPGAShell's DesignKey | ||
class WithNoDesignKey extends Config((site, here, up) => { | ||
case DesignKey => (p: Parameters) => new SimpleLazyRawModule()(p) | ||
}) | ||
|
||
class WithDatastormTweaks(freqMHz: Double = 40) extends Config( | ||
new WithDatastormPMODUART ++ | ||
new WithDatastormUARTTSI ++ | ||
new WithDatastormDDRTL ++ | ||
new WithDatastormJTAG ++ | ||
new WithNoDesignKey ++ | ||
new testchipip.tsi.WithUARTTSIClient(initBaudRate = BigInt(921600)) ++ | ||
new chipyard.harness.WithSerialTLTiedOff ++ | ||
new chipyard.harness.WithHarnessBinderClockFreqMHz(freqMHz) ++ | ||
new chipyard.config.WithUniformBusFrequencies(freqMHz) ++ | ||
new chipyard.harness.WithAllClocksFromHarnessClockInstantiator ++ | ||
new chipyard.clocking.WithPassthroughClockGenerator ++ | ||
new chipyard.config.WithTLBackingMemory ++ // FPGA-shells converts the AXI to TL for us | ||
new freechips.rocketchip.subsystem.WithExtMemSize(BigInt(1) << 30) ++ // 1GB on Datastorm | ||
new freechips.rocketchip.subsystem.WithoutTLMonitors) | ||
|
||
class RocketDatastormConfig extends Config( | ||
new WithDatastormTweaks ++ | ||
new WithNoScratchpads ++ | ||
new testchipip.serdes.WithNoSerialTL ++ | ||
new chipyard.config.WithBroadcastManager ++ // no l2 | ||
new freechips.rocketchip.rocket.WithNBigCores(1) ++ // Use bigrocket instead of huge due to space constraints | ||
new chipyard.config.AbstractConfig) | ||
|
||
class NoCoresDatastormConfig extends Config( | ||
new WithDatastormTweaks ++ | ||
new chipyard.config.WithBroadcastManager ++ // no l2 | ||
new chipyard.NoCoresConfig) | ||
|
||
class BringupDatastormConfig extends Config( | ||
new WithDatastormSerialTLToFMC ++ | ||
new WithDatastormTweaks ++ | ||
new testchipip.serdes.WithSerialTLPHYParams(testchipip.serdes.InternalSyncSerialPhyParams(freqMHz=40)) ++ | ||
new chipyard.ChipBringupHostConfig) |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,83 @@ | ||
package chipyard.fpga.datastorm | ||
|
||
import chisel3._ | ||
import chisel3.util._ | ||
import freechips.rocketchip.diplomacy._ | ||
import org.chipsalliance.cde.config.{Parameters} | ||
import freechips.rocketchip.tilelink._ | ||
import freechips.rocketchip.prci._ | ||
import freechips.rocketchip.subsystem.{SystemBusKey} | ||
|
||
import sifive.fpgashells.shell.altera._ | ||
import sifive.fpgashells.shell._ | ||
import sifive.fpgashells.clocks._ | ||
|
||
import sifive.blocks.devices.uart._ | ||
|
||
import chipyard._ | ||
import chipyard.harness._ | ||
|
||
class DatastormHarness(override implicit val p: Parameters) extends DatastormShell { | ||
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"Datastorm FPGA Base Clock Freq: ${dutFreqMHz} MHz") | ||
val dutWrangler = LazyModule(new ResetWrangler()) | ||
val dutGroup = ClockGroup() | ||
dutClock := dutWrangler.node := dutGroup := harnessSysPLLNode | ||
|
||
harnessSysPLLNode := clockOverlay.overlayOutput.node | ||
|
||
val ddrOverlay = dp(DDROverlayKey).head.place(DDRDesignInput(dp(ExtTLMem).get.master.base, dutWrangler.node, harnessSysPLLNode)).asInstanceOf[DDRDatastormPlacedOverlay] | ||
val ddrClient = TLClientNode(Seq(TLMasterPortParameters.v1(Seq(TLMasterParameters.v1( | ||
name = "chip_ddr", | ||
sourceId = IdRange(0, 1 << dp(ExtTLMem).get.master.idBits) | ||
))))) | ||
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) | ||
|
||
override lazy val module = new HarnessLikeImpl | ||
|
||
class HarnessLikeImpl extends Impl with HasHarnessInstantiators { | ||
clockOverlay.overlayOutput.node.out(0)._1.reset := ~resetPin | ||
|
||
val clk_50mhz = clockOverlay.overlayOutput.node.out.head._1.clock | ||
|
||
// Blink the status LEDs for sanity | ||
withClockAndReset(clk_50mhz, dutClock.in.head._1.reset) { | ||
val period = (BigInt(50) << 20) | ||
val counter = RegInit(0.U(log2Ceil(period).W)) | ||
val on = RegInit(false.B) | ||
all_leds(0) := on | ||
counter := Mux(counter === (period-1).U, 0.U, counter + 1.U) | ||
when (counter === 0.U) { | ||
on := !on | ||
} | ||
} | ||
|
||
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 } | ||
|
||
childClock := harnessBinderClock | ||
childReset := harnessBinderReset | ||
|
||
ddrOverlay.mig.module.clock := harnessBinderClock | ||
ddrOverlay.mig.module.reset := harnessBinderReset | ||
ddrBlockDuringReset.module.clock := harnessBinderClock | ||
ddrBlockDuringReset.module.reset := harnessBinderReset.asBool || !ddrOverlay.mig.module.io.port.mem_status_local_cal_success | ||
|
||
all_leds(1) := ddrOverlay.mig.module.io.port.mem_status_local_cal_success | ||
instantiateChipTops() | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,125 @@ | ||
package chipyard.fpga.datastorm | ||
|
||
import chisel3._ | ||
|
||
import freechips.rocketchip.jtag.{JTAGIO} | ||
import freechips.rocketchip.subsystem.{PeripheryBusKey} | ||
import freechips.rocketchip.tilelink.{TLBundle} | ||
import freechips.rocketchip.diplomacy.{LazyRawModuleImp} | ||
import org.chipsalliance.diplomacy.nodes.{HeterogeneousBag} | ||
import sifive.blocks.devices.uart.{UARTPortIO, UARTParams} | ||
import sifive.blocks.devices.jtag.{JTAGPins, JTAGPinsFromPort} | ||
import sifive.blocks.devices.pinctrl.{BasePin} | ||
import sifive.fpgashells.shell._ | ||
import sifive.fpgashells.ip.altera._ | ||
import sifive.fpgashells.shell.altera._ | ||
import sifive.fpgashells.clocks._ | ||
import chipyard._ | ||
import chipyard.harness._ | ||
import chipyard.iobinders._ | ||
import testchipip.serdes._ | ||
|
||
class WithDatastormDDRTL extends HarnessBinder({ | ||
case (th: HasHarnessInstantiators, port: TLMemPort, chipId: Int) => { | ||
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[DatastormHarness] | ||
val bundles = ath.ddrClient.out.map(_._1) | ||
val ddrClientBundle = Wire(new HeterogeneousBag(bundles.map(_.cloneType))) | ||
bundles.zip(ddrClientBundle).foreach { case (bundle, io) => bundle <> io } | ||
ddrClientBundle <> port.io | ||
} | ||
}) | ||
|
||
class WithDatastormSerialTLToFMC extends HarnessBinder({ | ||
case (th: HasHarnessInstantiators, port: SerialTLPort, chipId: Int) => { | ||
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[DatastormHarness] | ||
val harnessIO = IO(chiselTypeOf(port.io)).suggestName("serial_tl") | ||
harnessIO <> port.io | ||
|
||
harnessIO match { | ||
case io: DecoupledPhitIO => { | ||
val clkIO = io match { | ||
case io: InternalSyncPhitIO => IOPin(io.clock_out) | ||
case io: ExternalSyncPhitIO => IOPin(io.clock_in) | ||
} | ||
val packagePinsWithPackageIOs = Seq( | ||
("PIN_C13", clkIO), | ||
("PIN_J12", IOPin(io.out.valid)), | ||
("PIN_K12", IOPin(io.out.ready)), | ||
("PIN_H12", IOPin(io.in.valid)), | ||
("PIN_H13", IOPin(io.in.ready)), | ||
("PIN_E9", IOPin(io.out.bits.phit, 0)), | ||
("PIN_D9", IOPin(io.out.bits.phit, 1)), | ||
("PIN_H14", IOPin(io.out.bits.phit, 2)), | ||
("PIN_G13", IOPin(io.out.bits.phit, 3)), | ||
("PIN_C12", IOPin(io.in.bits.phit, 0)), | ||
("PIN_B11", IOPin(io.in.bits.phit, 1)), | ||
("PIN_E8", IOPin(io.in.bits.phit, 2)), | ||
("PIN_D7", IOPin(io.in.bits.phit, 3)) | ||
) | ||
packagePinsWithPackageIOs foreach { case (pin, io) => { | ||
ath.io_tcl.addPackagePin(io, pin) | ||
ath.io_tcl.addIOStandard(io, "1.5 V") | ||
}} | ||
|
||
ath.sdc.addClock("ser_tl_clock", clkIO, 50) | ||
ath.sdc.addGroup(clocks = Seq("ser_tl_clock")) | ||
} | ||
} | ||
} | ||
}) | ||
|
||
class WithDatastormUARTTSI extends HarnessBinder({ | ||
case (th: HasHarnessInstantiators, port: UARTTSIPort, chipId: Int) => { | ||
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[DatastormHarness] | ||
val harnessIO = IO(new UARTPortIO(port.io.uartParams)).suggestName("uart_tsi") | ||
harnessIO <> port.io.uart | ||
val packagePinsWithPackageIOs = Seq( | ||
("PIN_AG10" , IOPin(harnessIO.rxd)), | ||
("PIN_AH9", IOPin(harnessIO.txd))) | ||
packagePinsWithPackageIOs foreach { case (pin, io) => { | ||
ath.io_tcl.addPackagePin(io, pin) | ||
ath.io_tcl.addIOStandard(io, "1.5 V") | ||
} } | ||
} | ||
}) | ||
|
||
// Maps the UART device to the on-board USB-UART | ||
class WithDatastormUART(rxdPin: String = "PIN_AG10", txdPin: String = "PIN_AH9") extends HarnessBinder({ | ||
case (th: HasHarnessInstantiators, port: UARTPort, chipId: Int) => { | ||
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[DatastormHarness] | ||
val harnessIO = IO(chiselTypeOf(port.io)).suggestName("uart") | ||
harnessIO <> port.io | ||
val packagePinsWithPackageIOs = Seq( | ||
(rxdPin, IOPin(harnessIO.rxd)), | ||
(txdPin, IOPin(harnessIO.txd))) | ||
packagePinsWithPackageIOs foreach { case (pin, io) => { | ||
ath.io_tcl.addPackagePin(io, pin) | ||
ath.io_tcl.addIOStandard(io, "3.3-V LVTTL") | ||
} } | ||
} | ||
}) | ||
|
||
// Maps the UART device to PMOD JD pins 3/7 | ||
class WithDatastormPMODUART extends WithDatastormUART("PIN_AB12", "PIN_AC12") | ||
|
||
class WithDatastormJTAG extends HarnessBinder({ | ||
case (th: HasHarnessInstantiators, port: JTAGPort, chipId: Int) => { | ||
val ath = th.asInstanceOf[LazyRawModuleImp].wrapper.asInstanceOf[DatastormHarness] | ||
val harnessIO = IO(chiselTypeOf(port.io)).suggestName("jtag") | ||
harnessIO <> port.io | ||
|
||
ath.sdc.addClock("JTCK", IOPin(harnessIO.TCK), 10) | ||
ath.sdc.addGroup(clocks = Seq("JTCK")) | ||
val packagePinsWithPackageIOs = Seq( | ||
("PIN_AD12", IOPin(harnessIO.TCK)), | ||
("PIN_AD10", IOPin(harnessIO.TMS)), | ||
("PIN_AC9", IOPin(harnessIO.TDI)), | ||
("PIN_AD9", IOPin(harnessIO.TDO)) | ||
) | ||
packagePinsWithPackageIOs foreach { case (pin, io) => { | ||
ath.io_tcl.addPackagePin(io, pin) | ||
ath.io_tcl.addIOStandard(io, "3.3-V LVTTL") | ||
// TODO Check if Cyclone V devices have integrated pullups ath.io_tcl.addPullup(io) | ||
} } | ||
} | ||
}) |