Merge pull request #242 from ucb-bar/midas2-endpoint-rework

Golden Gate / Firesim Module-Based Endpoint System
This commit is contained in:
David Biancolin
2019-09-30 13:27:11 -04:00
committed by GitHub
7 changed files with 134 additions and 152 deletions

View File

@@ -0,0 +1,80 @@
//See LICENSE for license details.
package firesim.firesim
import chisel3._
import freechips.rocketchip.config.{Field, Config}
import freechips.rocketchip.diplomacy.{LazyModule}
import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp
import freechips.rocketchip.subsystem.{CanHaveMasterAXI4MemPortModuleImp}
import sifive.blocks.devices.uart.HasPeripheryUARTModuleImp
import testchipip.{HasPeripherySerialModuleImp, HasPeripheryBlockDeviceModuleImp}
import icenet.HasPeripheryIceNICModuleImpValidOnly
import junctions.{NastiKey, NastiParameters}
import midas.widgets.{IsEndpoint}
import midas.models.{FASEDEndpoint, FasedAXI4Edge}
import firesim.endpoints._
import firesim.configs.MemModelKey
import firesim.util.RegisterEndpointBinder
class WithTiedOffDebug extends RegisterEndpointBinder({ case target: HasPeripheryDebugModuleImp =>
target.debug.clockeddmi.foreach({ cdmi =>
cdmi.dmi.req.valid := false.B
cdmi.dmi.req.bits := DontCare
cdmi.dmi.resp.ready := false.B
cdmi.dmiClock := false.B.asClock
cdmi.dmiReset := false.B
})
Seq()
})
class WithSerialEndpoint extends RegisterEndpointBinder({
case target: HasPeripherySerialModuleImp => Seq(SerialEndpoint(target.serial)(target.p))
})
class WithNICEndpoint extends RegisterEndpointBinder({
case target: HasPeripheryIceNICModuleImpValidOnly => Seq(NICEndpoint(target.net)(target.p))
})
class WithUARTEndpoint extends RegisterEndpointBinder({
case target: HasPeripheryUARTModuleImp => target.uart.map(u => UARTEndpoint(u)(target.p))
})
class WithBlockDeviceEndpoint extends RegisterEndpointBinder({
case target: HasPeripheryBlockDeviceModuleImp => Seq(BlockDevEndpoint(target.bdev, target.reset.toBool)(target.p))
})
class WithFASEDEndpoint extends RegisterEndpointBinder({
case t: CanHaveMasterAXI4MemPortModuleImp =>
implicit val p = t.p
(t.mem_axi4 zip t.outer.memAXI4Node).flatMap({ case (io, node) =>
(io zip node.in).map({ case (axi4Bundle, (_, edge)) =>
val nastiKey = NastiParameters(axi4Bundle.r.bits.data.getWidth,
axi4Bundle.ar.bits.addr.getWidth,
axi4Bundle.ar.bits.id.getWidth)
val fasedP = p.alterPartial({
case NastiKey => nastiKey
case FasedAXI4Edge => Some(edge)
})
FASEDEndpoint(axi4Bundle, t.reset.toBool, p(MemModelKey)(fasedP))(fasedP)
})
}).toSeq
})
class WithTracerVEndpoint extends RegisterEndpointBinder({
case target: HasTraceIOImp => TracerVEndpoint(target.traceIO)(target.p)
})
// Shorthand to register all of the provided endpoints above
class WithDefaultFireSimEndpoints extends Config(
new WithTiedOffDebug ++
new WithSerialEndpoint ++
new WithNICEndpoint ++
new WithUARTEndpoint ++
new WithBlockDeviceEndpoint ++
new WithFASEDEndpoint ++
new WithTracerVEndpoint
)

View File

@@ -3,8 +3,6 @@ package firesim.firesim
import freechips.rocketchip.config.{Parameters, Config, Field}
import midas.{EndpointKey}
import midas.widgets.{EndpointMap}
import midas.models._
import firesim.endpoints._
@@ -19,40 +17,26 @@ import firesim.configs._
* reconstruct what is in a particular AGFI. These tags are also used to
* determine which driver to build.
*******************************************************************************/
class FireSimConfig extends Config(
new WithSerialWidget ++
new WithUARTWidget ++
new WithSimpleNICWidget ++
new WithBlockDevWidget ++
new WithDefaultMemModel ++
new WithTracerVWidget ++
new BasePlatformConfig)
class FireSimConfig extends Config(new BasePlatformConfig)
class FireSimClockDivConfig extends Config(
new WithDefaultMemModel(clockDivision = 2) ++
new FireSimConfig)
class FireSimDDR3Config extends Config(
new FCFS16GBQuadRank ++
new FireSimConfig)
class FireSimDDR3LLC4MBConfig extends Config(
new FCFS16GBQuadRankLLC4MB ++
new FireSimConfig)
class FireSimDDR3FRFCFSConfig extends Config(
new FRFCFS16GBQuadRank ++
new FireSimConfig)
class FireSimDDR3FRFCFSLLC4MBConfig extends Config(
new FRFCFS16GBQuadRankLLC4MB ++
new FireSimConfig)
class FireSimDDR3FRFCFSLLC4MB3ClockDivConfig extends Config(
new FRFCFS16GBQuadRankLLC4MB3Div ++
new FireSimConfig)
class Midas2Config extends Config(
new WithMultiCycleRamModels ++
new FireSimConfig)

View File

@@ -12,12 +12,16 @@ import freechips.rocketchip.subsystem._
import freechips.rocketchip.devices.tilelink.BootROMParams
import freechips.rocketchip.devices.debug.DebugModuleParams
import boom.common.BoomTilesKey
import testchipip.{WithBlockDevice, BlockDeviceKey, BlockDeviceConfig}
import testchipip.{BlockDeviceKey, BlockDeviceConfig}
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
import scala.math.{min, max}
import tracegen.TraceGenKey
import icenet._
import firesim.endpoints._
import firesim.util.{WithNumNodes}
import firesim.configs.WithDefaultMemModel
class WithBootROM extends Config((site, here, up) => {
case BootROMParams => {
val chipyardBootROM = new File(s"./generators/testchipip/bootrom/bootrom.rv${site(XLen)}.img")
@@ -37,12 +41,14 @@ class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) =>
})
class WithUARTKey extends Config((site, here, up) => {
case PeripheryUARTKey => List(UARTParams(
case PeripheryUARTKey => List(UARTParams(
address = BigInt(0x54000000L),
nTxEntries = 256,
nRxEntries = 256))
})
class WithBlockDevice extends Config(new testchipip.WithBlockDevice)
class WithNICKey extends Config((site, here, up) => {
case NICKey => NICConfig(
inBufFlits = 8192,
@@ -101,6 +107,8 @@ class FireSimRocketChipConfig extends Config(
new WithRocketL2TLBs(1024) ++
new WithPerfCounters ++
new WithoutClockGating ++
new WithDefaultMemModel ++
new WithDefaultFireSimEndpoints ++
new freechips.rocketchip.system.DefaultConfig)
class WithNDuplicatedRocketCores(n: Int) extends Config((site, here, up) => {
@@ -140,8 +148,10 @@ class FireSimBoomConfig extends Config(
new WithBlockDevice ++
new WithBoomL2TLBs(1024) ++
new WithoutClockGating ++
new WithDefaultMemModel ++
new boom.common.WithLargeBooms ++
new boom.common.WithNBoomCores(1) ++
new WithDefaultFireSimEndpoints ++
new freechips.rocketchip.system.BaseConfig
)
@@ -165,9 +175,6 @@ class FireSimBoomQuadCoreConfig extends Config(
//**********************************************************************************
//* Supernode Configurations
//*********************************************************************************/
class WithNumNodes(n: Int) extends Config((pname, site, here) => {
case NumNodes => n
})
class SupernodeFireSimRocketChipConfig extends Config(
new WithNumNodes(4) ++

View File

@@ -1,6 +1,7 @@
package firesim.firesim
import chisel3._
import chisel3.util.Cat
import chisel3.experimental.annotate
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy._
@@ -12,62 +13,8 @@ import freechips.rocketchip.subsystem._
import freechips.rocketchip.rocket.TracedInstruction
import firesim.endpoints.{TraceOutputTop, DeclockedTracedInstruction}
import midas.models.AXI4BundleWithEdge
import midas.targetutils.{ExcludeInstanceAsserts, MemModelAnnotation}
/** Copied from RC and modified to change the IO type of the Imp to include the Diplomatic edges
* associated with each port. This drives FASED functional model sizing
*/
trait CanHaveFASEDOptimizedMasterAXI4MemPort { this: BaseSubsystem =>
val module: CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
val memAXI4Node = p(ExtMem).map { case MemoryPortParams(memPortParams, nMemoryChannels) =>
val portName = "axi4"
val device = new MemoryDevice
val memAXI4Node = AXI4SlaveNode(Seq.tabulate(nMemoryChannels) { channel =>
val base = AddressSet.misaligned(memPortParams.base, memPortParams.size)
val filter = AddressSet(channel * mbus.blockBytes, ~((nMemoryChannels-1) * mbus.blockBytes))
AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters(
address = base.flatMap(_.intersect(filter)),
resources = device.reg,
regionType = RegionType.UNCACHED, // cacheable
executable = true,
supportsWrite = TransferSizes(1, mbus.blockBytes),
supportsRead = TransferSizes(1, mbus.blockBytes),
interleavedId = Some(0))), // slave does not interleave read responses
beatBytes = memPortParams.beatBytes)
})
memAXI4Node := mbus.toDRAMController(Some(portName)) {
AXI4UserYanker() := AXI4IdIndexer(memPortParams.idBits) := TLToAXI4()
}
memAXI4Node
}
}
/** Actually generates the corresponding IO in the concrete Module */
trait CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp extends LazyModuleImp {
val outer: CanHaveFASEDOptimizedMasterAXI4MemPort
val mem_axi4 = outer.memAXI4Node.map(x => IO(HeterogeneousBag(AXI4BundleWithEdge.fromNode(x.in))))
(mem_axi4 zip outer.memAXI4Node) foreach { case (io, node) =>
(io zip node.in).foreach { case (io, (bundle, _)) => io <> bundle }
}
def connectSimAXIMem() {
(mem_axi4 zip outer.memAXI4Node).foreach { case (io, node) =>
(io zip node.in).foreach { case (io, (_, edge)) =>
val mem = LazyModule(new SimAXIMem(edge, size = p(ExtMem).get.master.size))
Module(mem.module).io.axi4.head <> io
}
}
}
}
/* Wires out tile trace ports to the top; and wraps them in a Bundle that the
* TracerV endpoint can match on.
*/
@@ -95,7 +42,7 @@ trait HasTraceIOImp extends LazyModuleImp {
// Enabled to test TracerV trace capture
if (p(PrintTracePort)) {
val traceprint = Wire(UInt(512.W))
traceprint := traceIO.asUInt
traceprint := Cat(traceIO.traces.map(_.asUInt))
printf("TRACEPORT: %x\n", traceprint)
}
}

View File

@@ -6,6 +6,7 @@ import freechips.rocketchip.subsystem._
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.tilelink._
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.devices.debug.HasPeripheryDebugModuleImp
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.util.{HeterogeneousBag}
import freechips.rocketchip.amba.axi4.AXI4Bundle
@@ -13,13 +14,19 @@ import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.diplomacy.LazyModule
import utilities.{Subsystem, SubsystemModuleImp}
import icenet._
import firesim.util.DefaultFireSimHarness
import testchipip._
import testchipip.SerialAdapter.SERIAL_IF_WIDTH
import tracegen.{HasTraceGenTiles, HasTraceGenTilesModuleImp}
import sifive.blocks.devices.uart._
import midas.models.AXI4BundleWithEdge
import java.io.File
object FireSimValName {
implicit val valName = ValName("FireSimHarness")
}
import FireSimValName._
/*******************************************************************************
* Top level DESIGN configurations. These describe the basic instantiations of
* the designs being simulated.
@@ -31,11 +38,10 @@ import java.io.File
* determine which driver to build.
*******************************************************************************/
class FireSim(implicit p: Parameters) extends Subsystem
class FireSimDUT(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with CanHaveMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryIceNIC
@@ -45,11 +51,10 @@ class FireSim(implicit p: Parameters) extends Subsystem
override lazy val module = new FireSimModuleImp(this)
}
class FireSimModuleImp[+L <: FireSim](l: L) extends SubsystemModuleImp(l)
class FireSimModuleImp[+L <: FireSimDUT](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryIceNICModuleImpValidOnly
@@ -57,12 +62,12 @@ class FireSimModuleImp[+L <: FireSim](l: L) extends SubsystemModuleImp(l)
with HasTraceIOImp
with CanHaveMultiCycleRegfileImp
class FireSim(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimDUT)
class FireSimNoNIC(implicit p: Parameters) extends Subsystem
class FireSimNoNICDUT(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with CanHaveMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryBlockDevice
@@ -71,11 +76,10 @@ class FireSimNoNIC(implicit p: Parameters) extends Subsystem
override lazy val module = new FireSimNoNICModuleImp(this)
}
class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends SubsystemModuleImp(l)
class FireSimNoNICModuleImp[+L <: FireSimNoNICDUT](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryBlockDeviceModuleImp
@@ -83,11 +87,12 @@ class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends SubsystemModuleImp
with CanHaveMultiCycleRegfileImp
class FireBoom(implicit p: Parameters) extends Subsystem
class FireSimNoNIC(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimNoNICDUT)
class FireBoomDUT(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with CanHaveMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryIceNIC
@@ -97,11 +102,10 @@ class FireBoom(implicit p: Parameters) extends Subsystem
override lazy val module = new FireBoomModuleImp(this)
}
class FireBoomModuleImp[+L <: FireBoom](l: L) extends SubsystemModuleImp(l)
class FireBoomModuleImp[+L <: FireBoomDUT](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryIceNICModuleImpValidOnly
@@ -110,11 +114,12 @@ class FireBoomModuleImp[+L <: FireBoom](l: L) extends SubsystemModuleImp(l)
with ExcludeInvalidBoomAssertions
with CanHaveMultiCycleRegfileImp
class FireBoomNoNIC(implicit p: Parameters) extends Subsystem
class FireBoom(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireBoomDUT)
class FireBoomNoNICDUT(implicit p: Parameters) extends Subsystem
with HasHierarchicalBusTopology
with CanHaveFASEDOptimizedMasterAXI4MemPort
with CanHaveMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial
with HasPeripheryUART
with HasPeripheryBlockDevice
@@ -123,11 +128,10 @@ class FireBoomNoNIC(implicit p: Parameters) extends Subsystem
override lazy val module = new FireBoomNoNICModuleImp(this)
}
class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends SubsystemModuleImp(l)
class FireBoomNoNICModuleImp[+L <: FireBoomNoNICDUT](l: L) extends SubsystemModuleImp(l)
with HasRTCModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with HasPeripheryUARTModuleImp
with HasPeripheryBlockDeviceModuleImp
@@ -135,58 +139,18 @@ class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends SubsystemModuleI
with ExcludeInvalidBoomAssertions
with CanHaveMultiCycleRegfileImp
case object NumNodes extends Field[Int]
class SupernodeIO(
nNodes: Int,
serialWidth: Int,
bagPrototype: HeterogeneousBag[AXI4BundleWithEdge])(implicit p: Parameters)
extends Bundle {
val serial = Vec(nNodes, new SerialIO(serialWidth))
val mem_axi = Vec(nNodes, bagPrototype.cloneType)
val bdev = Vec(nNodes, new BlockDeviceIO)
val net = Vec(nNodes, new NICIOvonly)
val uart = Vec(nNodes, new UARTPortIO)
override def cloneType = new SupernodeIO(nNodes, serialWidth, bagPrototype).asInstanceOf[this.type]
}
class FireSimSupernode(implicit p: Parameters) extends Module {
val nNodes = p(NumNodes)
val nodes = Seq.fill(nNodes) {
Module(LazyModule(new FireSim).module)
}
val io = IO(new SupernodeIO(nNodes, SERIAL_IF_WIDTH, nodes(0).mem_axi4.get))
io.mem_axi.zip(nodes.map(_.mem_axi4)).foreach {
case (out, mem_axi4) => out <> mem_axi4.get
}
io.serial <> nodes.map(_.serial)
io.bdev <> nodes.map(_.bdev)
io.net <> nodes.map(_.net)
io.uart <> nodes.map(_.uart(0))
nodes.foreach{ case n => {
n.debug.clockeddmi.get.dmi.req.valid := false.B
n.debug.clockeddmi.get.dmi.resp.ready := false.B
n.debug.clockeddmi.get.dmiClock := clock
n.debug.clockeddmi.get.dmiReset := reset.toBool
n.debug.clockeddmi.get.dmi.req.bits.data := DontCare
n.debug.clockeddmi.get.dmi.req.bits.addr := DontCare
n.debug.clockeddmi.get.dmi.req.bits.op := DontCare
} }
}
class FireBoomNoNIC(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireBoomNoNICDUT)
class FireSimTraceGen(implicit p: Parameters) extends BaseSubsystem
with HasHierarchicalBusTopology
with HasTraceGenTiles
with CanHaveFASEDOptimizedMasterAXI4MemPort {
with CanHaveMasterAXI4MemPort {
override lazy val module = new FireSimTraceGenModuleImp(this)
}
class FireSimTraceGenModuleImp(outer: FireSimTraceGen)
extends BaseSubsystemModuleImp(outer)
with HasTraceGenTilesModuleImp
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
class FireSimTraceGenModuleImp(outer: FireSimTraceGen) extends BaseSubsystemModuleImp(outer)
with HasTraceGenTilesModuleImp
with CanHaveMasterAXI4MemPortModuleImp
// Supernoded-ness comes from setting p(NumNodes) (see DefaultFiresimHarness) to something > 1
class FireSimSupernode(implicit p: Parameters) extends DefaultFireSimHarness(() => new FireSimDUT)

View File

@@ -112,7 +112,7 @@ abstract class FireSimTestSuite(
val resetLength = 51
val verilatedOutput = getLines(new File(outDir, s"/${verilatedLog}"))
val synthPrintOutput = getLines(new File(genDir, s"/TRACEFILE"), resetLength)
assert(verilatedOutput.size == synthPrintOutput.size, "Outputs differ in length")
assert(math.abs(verilatedOutput.size - synthPrintOutput.size) <= 1, "Outputs differ in length")
assert(verilatedOutput.nonEmpty)
for ( (vPrint, sPrint) <- verilatedOutput.zip(synthPrintOutput) ) {
assert(vPrint == sPrint)