WIP
This commit is contained in:
parent
bc54b24b85
commit
c0d4e848ba
|
@ -31,3 +31,9 @@
|
|||
[submodule "generators/hwacha"]
|
||||
path = generators/hwacha
|
||||
url = git@github.com:ucb-bar/hwacha.git
|
||||
[submodule "sims/firesim"]
|
||||
path = sims/firesim
|
||||
url = https://github.com/firesim/firesim.git
|
||||
[submodule "generators/icenet"]
|
||||
path = generators/icenet
|
||||
url = https://github.com/firesim/icenet.git
|
||||
|
|
84
build.sbt
84
build.sbt
|
@ -9,9 +9,9 @@ lazy val commonSettings = Seq(
|
|||
case _ => MergeStrategy.first}},
|
||||
scalacOptions ++= Seq("-deprecation","-unchecked","-Xsource:2.11"),
|
||||
libraryDependencies += "org.scalatest" %% "scalatest" % "3.0.5" % "test",
|
||||
libraryDependencies += "org.json4s" %% "json4s-native" % "3.6.1",
|
||||
libraryDependencies += "org.json4s" %% "json4s-jackson" % "3.6.1",
|
||||
libraryDependencies += "org.scala-lang" % "scala-reflect" % scalaVersion.value,
|
||||
libraryDependencies += "edu.berkeley.cs" %% "firrtl-interpreter" % "1.2-SNAPSHOT",
|
||||
//libraryDependencies += "edu.berkeley.cs" %% "firrtl-interpreter" % "1.2-SNAPSHOT",
|
||||
libraryDependencies += "com.github.scopt" %% "scopt" % "3.7.0",
|
||||
addCompilerPlugin("org.scalamacros" % "paradise" % "2.1.0" cross CrossVersion.full),
|
||||
resolvers ++= Seq(
|
||||
|
@ -19,18 +19,14 @@ lazy val commonSettings = Seq(
|
|||
Resolver.sonatypeRepo("releases"),
|
||||
Resolver.mavenLocal))
|
||||
|
||||
lazy val rebarFirrtl = (project in file("tools/firrtl"))
|
||||
.settings(commonSettings)
|
||||
val rocketChipDir = file("generators/rocket-chip")
|
||||
|
||||
lazy val rocketchip = RootProject(file("generators/rocket-chip"))
|
||||
|
||||
lazy val rebarrocketchip = project
|
||||
.dependsOn(rocketchip)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val testchipip = (project in file("generators/testchipip"))
|
||||
.dependsOn(rebarrocketchip)
|
||||
.settings(commonSettings)
|
||||
lazy val firesimAsLibrary = sys.env.get("FIRESIM_IS_TOP") == None
|
||||
lazy val firesimDir = if (firesimAsLibrary) {
|
||||
file("sims/firesim/sim/")
|
||||
} else {
|
||||
file("../../sim/")
|
||||
}
|
||||
|
||||
// Checks for -DROCKET_USE_MAVEN.
|
||||
// If it's there, use a maven dependency.
|
||||
|
@ -45,6 +41,42 @@ def conditionalDependsOn(prj: Project): Project = {
|
|||
}
|
||||
}
|
||||
|
||||
// Subproject definitions begin
|
||||
|
||||
// Biancolin: get to the bottom of these
|
||||
//lazy val rebarFirrtl = (project in file("tools/firrtl"))
|
||||
// .settings(commonSettings)
|
||||
// Overlaps with the dependency-injected version
|
||||
// lazy val rocketchip = RootProject(rocketChipDir)
|
||||
|
||||
// NB: FIRRTL dependency is unmanaged (and dropped in sim/lib)
|
||||
lazy val chisel = (project in rocketChipDir / "chisel3")
|
||||
|
||||
// Contains annotations & firrtl passes you may wish to use in rocket-chip without
|
||||
// introducing a circular dependency between RC and MIDAS
|
||||
lazy val midasTargetUtils = ProjectRef(firesimDir, "targetutils")
|
||||
|
||||
// Rocket-chip dependencies (subsumes making RC a RootProject)
|
||||
lazy val hardfloat = (project in rocketChipDir / "hardfloat")
|
||||
.settings(commonSettings).dependsOn(midasTargetUtils)
|
||||
|
||||
lazy val rocketMacros = (project in rocketChipDir / "macros")
|
||||
.settings(commonSettings)
|
||||
|
||||
// HACK: I'm strugging to override settings in rocket-chip's build.sbt (i want
|
||||
// the subproject to register a new library dependendency on midas's targetutils library)
|
||||
// So instead, avoid the existing build.sbt altogether and specify the project's root at src/
|
||||
lazy val rebarRocketchip = (project in rocketChipDir / "src")
|
||||
.settings(
|
||||
commonSettings,
|
||||
scalaSource in Compile := baseDirectory.value / "main" / "scala",
|
||||
resourceDirectory in Compile := baseDirectory.value / "main" / "resources")
|
||||
.dependsOn(chisel, hardfloat, rocketMacros)
|
||||
|
||||
lazy val testchipip = (project in file("generators/testchipip"))
|
||||
.dependsOn(rebarRocketchip)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val example = conditionalDependsOn(project in file("generators/example"))
|
||||
.dependsOn(boom, hwacha, sifive_blocks)
|
||||
.settings(commonSettings)
|
||||
|
@ -52,26 +84,38 @@ lazy val example = conditionalDependsOn(project in file("generators/example"))
|
|||
lazy val utilities = conditionalDependsOn(project in file("generators/utilities"))
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val hwacha = (project in file ("generators/hwacha"))
|
||||
.dependsOn(rebarrocketchip)
|
||||
lazy val icenet = (project in file("generators/icenet"))
|
||||
.dependsOn(rebarRocketchip, testchipip)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val hwacha = (project in file("generators/hwacha"))
|
||||
.dependsOn(rebarRocketchip)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val boom = (project in file("generators/boom"))
|
||||
.dependsOn(rebarrocketchip)
|
||||
.dependsOn(rebarRocketchip)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val tapeout = conditionalDependsOn(project in file("./tools/barstools/tapeout/"))
|
||||
.dependsOn(rebarFirrtl)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val mdf = (project in file("./tools/barstools/mdf/scalalib/"))
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val `barstools-macros` = (project in file("./tools/barstools/macros/"))
|
||||
.dependsOn(mdf, rebarrocketchip, rebarFirrtl)
|
||||
lazy val barstoolsMacros = (project in file("./tools/barstools/macros/"))
|
||||
.dependsOn(mdf, rebarRocketchip)
|
||||
.enablePlugins(sbtassembly.AssemblyPlugin)
|
||||
.settings(commonSettings)
|
||||
|
||||
lazy val sifive_blocks = (project in file("generators/sifive-blocks"))
|
||||
.dependsOn(rebarrocketchip)
|
||||
.dependsOn(rebarRocketchip)
|
||||
.settings(commonSettings)
|
||||
|
||||
// Library components of FireSim
|
||||
lazy val midas = ProjectRef(firesimDir, "midas")
|
||||
lazy val firesimLib = ProjectRef(firesimDir, "firesimLib")
|
||||
|
||||
lazy val firechip = (project in file("generators/firechip"))
|
||||
.dependsOn(boom, icenet, testchipip, sifive_blocks, midasTargetUtils, midas, firesimLib % "test->test;compile->compile")
|
||||
.settings(commonSettings)
|
||||
|
||||
|
|
12
common.mk
12
common.mk
|
@ -8,23 +8,25 @@ SHELL=/bin/bash
|
|||
#########################################################################################
|
||||
lookup_scala_srcs = $(shell find -L $(1)/ -iname "*.scala" 2> /dev/null)
|
||||
|
||||
PACKAGES=rocket-chip testchipip boom hwacha sifive-blocks example
|
||||
SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/generators/$(pkg)/src/main/scala))
|
||||
PACKAGES=$(addprefix generators/, rocket-chip testchipip boom hwacha sifive-blocks example) \
|
||||
$(addprefix sims/firesim/sim/, . firesim-lib midas midas/targetutils)
|
||||
SCALA_SOURCES=$(foreach pkg,$(PACKAGES),$(call lookup_scala_srcs,$(base_dir)/$(pkg)/src/main/scala))
|
||||
|
||||
#########################################################################################
|
||||
# rocket and testchipip classes
|
||||
#########################################################################################
|
||||
ROCKET_CLASSES ?= "$(ROCKETCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes:$(ROCKETCHIP_DIR)/chisel3/target/scala-$(SCALA_VERSION_MAJOR)/*"
|
||||
# NB: target/ lives under source ----V , due to how we're handling midas dependency injection
|
||||
ROCKET_CLASSES ?= "$(ROCKETCHIP_DIR)/src/target/scala-$(SCALA_VERSION_MAJOR)/classes:$(ROCKETCHIP_DIR)/chisel3/target/scala-$(SCALA_VERSION_MAJOR)/*"
|
||||
TESTCHIPIP_CLASSES ?= "$(TESTCHIP_DIR)/target/scala-$(SCALA_VERSION_MAJOR)/classes"
|
||||
|
||||
#########################################################################################
|
||||
# jar creation variables and rules
|
||||
#########################################################################################
|
||||
FIRRTL_JAR ?= $(ROCKETCHIP_DIR)/lib/firrtl.jar
|
||||
FIRRTL_JAR := $(base_dir)/lib/firrtl.jar
|
||||
|
||||
$(FIRRTL_JAR): $(call lookup_scala_srcs, $(REBAR_FIRRTL_DIR)/src/main/scala)
|
||||
$(MAKE) -C $(REBAR_FIRRTL_DIR) SBT="$(SBT)" root_dir=$(REBAR_FIRRTL_DIR) build-scala
|
||||
mkdir -p $(dir $@)
|
||||
mkdir -p $(@D)
|
||||
cp -p $(REBAR_FIRRTL_DIR)/utils/bin/firrtl.jar $@
|
||||
touch $@
|
||||
|
||||
|
|
|
@ -0,0 +1,124 @@
|
|||
//See LICENSE for license details.
|
||||
|
||||
package firesim.firesim
|
||||
|
||||
import java.io.{File}
|
||||
|
||||
import chisel3.experimental.RawModule
|
||||
import chisel3.internal.firrtl.{Circuit, Port}
|
||||
|
||||
import freechips.rocketchip.diplomacy.{ValName, AutoBundle}
|
||||
import freechips.rocketchip.devices.debug.DebugIO
|
||||
import freechips.rocketchip.util.{HasGeneratorUtilities, ParsedInputNames, ElaborationArtefacts}
|
||||
import freechips.rocketchip.system.DefaultTestSuites._
|
||||
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite}
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import freechips.rocketchip.subsystem.RocketTilesKey
|
||||
import freechips.rocketchip.tile.XLen
|
||||
|
||||
import boom.system.{BoomTilesKey, BoomTestSuites}
|
||||
|
||||
import firesim.util.{GeneratorArgs, HasTargetAgnosticUtilites, HasFireSimGeneratorUtilities}
|
||||
|
||||
trait HasTestSuites {
|
||||
val rv64RegrTestNames = collection.mutable.LinkedHashSet(
|
||||
"rv64ud-v-fcvt",
|
||||
"rv64ud-p-fdiv",
|
||||
"rv64ud-v-fadd",
|
||||
"rv64uf-v-fadd",
|
||||
"rv64um-v-mul",
|
||||
// "rv64mi-p-breakpoint", // Not implemented in BOOM
|
||||
// "rv64uc-v-rvc", // Not implemented in BOOM
|
||||
"rv64ud-v-structural",
|
||||
"rv64si-p-wfi",
|
||||
"rv64um-v-divw",
|
||||
"rv64ua-v-lrsc",
|
||||
"rv64ui-v-fence_i",
|
||||
"rv64ud-v-fcvt_w",
|
||||
"rv64uf-v-fmin",
|
||||
"rv64ui-v-sb",
|
||||
"rv64ua-v-amomax_d",
|
||||
"rv64ud-v-move",
|
||||
"rv64ud-v-fclass",
|
||||
"rv64ua-v-amoand_d",
|
||||
"rv64ua-v-amoxor_d",
|
||||
"rv64si-p-sbreak",
|
||||
"rv64ud-v-fmadd",
|
||||
"rv64uf-v-ldst",
|
||||
"rv64um-v-mulh",
|
||||
"rv64si-p-dirty")
|
||||
|
||||
val rv32RegrTestNames = collection.mutable.LinkedHashSet(
|
||||
"rv32mi-p-ma_addr",
|
||||
"rv32mi-p-csr",
|
||||
"rv32ui-p-sh",
|
||||
"rv32ui-p-lh",
|
||||
"rv32uc-p-rvc",
|
||||
"rv32mi-p-sbreak",
|
||||
"rv32ui-p-sll")
|
||||
|
||||
def addTestSuites(targetName: String, params: Parameters) {
|
||||
val coreParams =
|
||||
if (params(RocketTilesKey).nonEmpty) {
|
||||
params(RocketTilesKey).head.core
|
||||
} else {
|
||||
params(BoomTilesKey).head.core
|
||||
}
|
||||
val xlen = params(XLen)
|
||||
val vm = coreParams.useVM
|
||||
val env = if (vm) List("p","v") else List("p")
|
||||
coreParams.fpu foreach { case cfg =>
|
||||
if (xlen == 32) {
|
||||
TestGeneration.addSuites(env.map(rv32uf))
|
||||
if (cfg.fLen >= 64)
|
||||
TestGeneration.addSuites(env.map(rv32ud))
|
||||
} else {
|
||||
TestGeneration.addSuite(rv32udBenchmarks)
|
||||
TestGeneration.addSuites(env.map(rv64uf))
|
||||
if (cfg.fLen >= 64)
|
||||
TestGeneration.addSuites(env.map(rv64ud))
|
||||
}
|
||||
}
|
||||
if (coreParams.useAtomics) TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
|
||||
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
|
||||
val (rvi, rvu) =
|
||||
if (params(BoomTilesKey).nonEmpty) ((if (vm) BoomTestSuites.rv64i else BoomTestSuites.rv64pi), rv64u)
|
||||
else if (xlen == 64) ((if (vm) rv64i else rv64pi), rv64u)
|
||||
else ((if (vm) rv32i else rv32pi), rv32u)
|
||||
|
||||
TestGeneration.addSuites(rvi.map(_("p")))
|
||||
TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env))))
|
||||
TestGeneration.addSuite(benchmarks)
|
||||
TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames))
|
||||
TestGeneration.addSuite(FastBlockdevTests)
|
||||
TestGeneration.addSuite(SlowBlockdevTests)
|
||||
if (!targetName.contains("NoNIC"))
|
||||
TestGeneration.addSuite(NICLoopbackTests)
|
||||
}
|
||||
}
|
||||
|
||||
// Mixed into an App or into a TestSuite
|
||||
trait IsFireSimGeneratorLike extends HasFireSimGeneratorUtilities with HasTestSuites {
|
||||
/** Output software test Makefrags, which provide targets for integration testing. */
|
||||
def generateTestSuiteMakefrags {
|
||||
addTestSuites(names.topModuleClass, targetParams)
|
||||
writeOutputFile(s"$longName.d", TestGeneration.generateMakefrag) // Subsystem-specific test suites
|
||||
}
|
||||
|
||||
// Output miscellaneous files produced as a side-effect of elaboration
|
||||
def generateArtefacts {
|
||||
ElaborationArtefacts.files.foreach { case (extension, contents) =>
|
||||
writeOutputFile(s"${longName}.${extension}", contents ())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
object FireSimGenerator extends App with IsFireSimGeneratorLike {
|
||||
lazy val generatorArgs = GeneratorArgs(args)
|
||||
lazy val genDir = new File(names.targetDir)
|
||||
elaborateAndCompileWithMidas
|
||||
generateTestSuiteMakefrags
|
||||
generateHostVerilogHeader
|
||||
generateArtefacts
|
||||
generateTclEnvFile
|
||||
}
|
|
@ -0,0 +1,54 @@
|
|||
//See LICENSE for license details.
|
||||
package firesim.firesim
|
||||
|
||||
import freechips.rocketchip.config.{Parameters, Config, Field}
|
||||
|
||||
import midas.{EndpointKey}
|
||||
import midas.widgets.{EndpointMap}
|
||||
import midas.models._
|
||||
|
||||
import firesim.endpoints._
|
||||
import firesim.configs._
|
||||
|
||||
/*******************************************************************************
|
||||
* Full PLATFORM_CONFIG Configurations. These set simulator parameters.
|
||||
*
|
||||
* In general, if you're adding or removing features from any of these, you
|
||||
* should CREATE A NEW ONE, WITH A NEW NAME. This is because the manager
|
||||
* will store this name as part of the tags for the AGFI, so that later you can
|
||||
* 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 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)
|
||||
|
|
@ -0,0 +1,205 @@
|
|||
package firesim.firesim
|
||||
|
||||
import java.io.File
|
||||
|
||||
import chisel3.util.{log2Up}
|
||||
import freechips.rocketchip.config.{Parameters, Config}
|
||||
import freechips.rocketchip.tile._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.devices.tilelink.BootROMParams
|
||||
import freechips.rocketchip.devices.debug.DebugModuleParams
|
||||
import boom.system.BoomTilesKey
|
||||
import testchipip.{WithBlockDevice, BlockDeviceKey, BlockDeviceConfig}
|
||||
import sifive.blocks.devices.uart.{PeripheryUARTKey, UARTParams}
|
||||
import icenet._
|
||||
|
||||
class WithBootROM extends Config((site, here, up) => {
|
||||
case BootROMParams => {
|
||||
val rebarBootROM = new File(s"./generators/testchipip/bootrom/bootrom.rv${site(XLen)}.img")
|
||||
val firesimBootROM = new File(s"./target-rtl/testchipip/bootrom/bootrom.rv${site(XLen)}.img")
|
||||
|
||||
val bootROMPath = if (rebarBootROM.exists()) {
|
||||
rebarBootROM.getAbsolutePath()
|
||||
} else {
|
||||
firesimBootROM.getAbsolutePath()
|
||||
}
|
||||
BootROMParams(contentFileName = bootROMPath)
|
||||
}
|
||||
})
|
||||
|
||||
class WithPeripheryBusFrequency(freq: BigInt) extends Config((site, here, up) => {
|
||||
case PeripheryBusKey => up(PeripheryBusKey).copy(frequency=freq)
|
||||
})
|
||||
|
||||
class WithUARTKey extends Config((site, here, up) => {
|
||||
case PeripheryUARTKey => List(UARTParams(
|
||||
address = BigInt(0x54000000L),
|
||||
nTxEntries = 256,
|
||||
nRxEntries = 256))
|
||||
})
|
||||
|
||||
class WithNICKey extends Config((site, here, up) => {
|
||||
case NICKey => NICConfig(
|
||||
inBufFlits = 8192,
|
||||
ctrlQueueDepth = 64)
|
||||
})
|
||||
|
||||
class WithRocketL2TLBs(entries: Int) extends Config((site, here, up) => {
|
||||
case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy(
|
||||
core = tile.core.copy(
|
||||
nL2TLBEntries = entries
|
||||
)
|
||||
))
|
||||
})
|
||||
|
||||
class WithPerfCounters extends Config((site, here, up) => {
|
||||
case RocketTilesKey => up(RocketTilesKey) map (tile => tile.copy(
|
||||
core = tile.core.copy(nPerfCounters = 29)
|
||||
))
|
||||
})
|
||||
|
||||
class WithBoomL2TLBs(entries: Int) extends Config((site, here, up) => {
|
||||
case BoomTilesKey => up(BoomTilesKey) map (tile => tile.copy(
|
||||
core = tile.core.copy(nL2TLBEntries = entries)
|
||||
))
|
||||
})
|
||||
|
||||
// Disables clock-gating; doesn't play nice with our FAME-1 pass
|
||||
class WithoutClockGating extends Config((site, here, up) => {
|
||||
case DebugModuleParams => up(DebugModuleParams, site).copy(clockGate = false)
|
||||
})
|
||||
|
||||
// Testing configurations
|
||||
// This enables printfs used in testing
|
||||
class WithScalaTestFeatures extends Config((site, here, up) => {
|
||||
case PrintTracePort => true
|
||||
})
|
||||
|
||||
/*******************************************************************************
|
||||
* Full TARGET_CONFIG configurations. These set parameters of the target being
|
||||
* simulated.
|
||||
*
|
||||
* In general, if you're adding or removing features from any of these, you
|
||||
* should CREATE A NEW ONE, WITH A NEW NAME. This is because the manager
|
||||
* will store this name as part of the tags for the AGFI, so that later you can
|
||||
* reconstruct what is in a particular AGFI. These tags are also used to
|
||||
* determine which driver to build.
|
||||
*******************************************************************************/
|
||||
class FireSimRocketChipConfig extends Config(
|
||||
new WithBootROM ++
|
||||
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
|
||||
new WithExtMemSize(0x400000000L) ++ // 16GB
|
||||
new WithoutTLMonitors ++
|
||||
new WithUARTKey ++
|
||||
new WithNICKey ++
|
||||
new WithBlockDevice ++
|
||||
new WithRocketL2TLBs(1024) ++
|
||||
new WithPerfCounters ++
|
||||
new WithoutClockGating ++
|
||||
new freechips.rocketchip.system.DefaultConfig)
|
||||
|
||||
class WithNDuplicatedRocketCores(n: Int) extends Config((site, here, up) => {
|
||||
case RocketTilesKey => List.tabulate(n)(i => up(RocketTilesKey).head.copy(hartId = i))
|
||||
})
|
||||
|
||||
// single core config
|
||||
class FireSimRocketChipSingleCoreConfig extends Config(new FireSimRocketChipConfig)
|
||||
|
||||
// dual core config
|
||||
class FireSimRocketChipDualCoreConfig extends Config(
|
||||
new WithNDuplicatedRocketCores(2) ++
|
||||
new FireSimRocketChipSingleCoreConfig)
|
||||
|
||||
// quad core config
|
||||
class FireSimRocketChipQuadCoreConfig extends Config(
|
||||
new WithNDuplicatedRocketCores(4) ++
|
||||
new FireSimRocketChipSingleCoreConfig)
|
||||
|
||||
// hexa core config
|
||||
class FireSimRocketChipHexaCoreConfig extends Config(
|
||||
new WithNDuplicatedRocketCores(6) ++
|
||||
new FireSimRocketChipSingleCoreConfig)
|
||||
|
||||
// octa core config
|
||||
class FireSimRocketChipOctaCoreConfig extends Config(
|
||||
new WithNDuplicatedRocketCores(8) ++
|
||||
new FireSimRocketChipSingleCoreConfig)
|
||||
|
||||
class FireSimBoomConfig extends Config(
|
||||
new WithBootROM ++
|
||||
new WithPeripheryBusFrequency(BigInt(3200000000L)) ++
|
||||
new WithExtMemSize(0x400000000L) ++ // 16GB
|
||||
new WithoutTLMonitors ++
|
||||
new WithUARTKey ++
|
||||
new WithNICKey ++
|
||||
new WithBlockDevice ++
|
||||
new WithBoomL2TLBs(1024) ++
|
||||
new WithoutClockGating ++
|
||||
// Using a small config because it has 64-bit system bus, and compiles quickly
|
||||
new boom.system.SmallBoomConfig)
|
||||
|
||||
// A safer implementation than the one in BOOM in that it
|
||||
// duplicates whatever BOOMTileKey.head is present N times. This prevents
|
||||
// accidentally (and silently) blowing away configurations that may change the
|
||||
// tile in the "up" view
|
||||
class WithNDuplicatedBoomCores(n: Int) extends Config((site, here, up) => {
|
||||
case BoomTilesKey => List.tabulate(n)(i => up(BoomTilesKey).head.copy(hartId = i))
|
||||
case MaxHartIdBits => log2Up(site(BoomTilesKey).size)
|
||||
})
|
||||
|
||||
class FireSimBoomDualCoreConfig extends Config(
|
||||
new WithNDuplicatedBoomCores(2) ++
|
||||
new FireSimBoomConfig)
|
||||
|
||||
class FireSimBoomQuadCoreConfig extends Config(
|
||||
new WithNDuplicatedBoomCores(4) ++
|
||||
new FireSimBoomConfig)
|
||||
|
||||
//**********************************************************************************
|
||||
//* Supernode Configurations
|
||||
//*********************************************************************************/
|
||||
class WithNumNodes(n: Int) extends Config((pname, site, here) => {
|
||||
case NumNodes => n
|
||||
})
|
||||
|
||||
class SupernodeFireSimRocketChipConfig extends Config(
|
||||
new WithNumNodes(4) ++
|
||||
new WithExtMemSize(0x200000000L) ++ // 8GB
|
||||
new FireSimRocketChipConfig)
|
||||
|
||||
class SupernodeFireSimRocketChipSingleCoreConfig extends Config(
|
||||
new WithNumNodes(4) ++
|
||||
new WithExtMemSize(0x200000000L) ++ // 8GB
|
||||
new FireSimRocketChipSingleCoreConfig)
|
||||
|
||||
class SupernodeSixNodeFireSimRocketChipSingleCoreConfig extends Config(
|
||||
new WithNumNodes(6) ++
|
||||
new WithExtMemSize(0x40000000L) ++ // 1GB
|
||||
new FireSimRocketChipSingleCoreConfig)
|
||||
|
||||
class SupernodeEightNodeFireSimRocketChipSingleCoreConfig extends Config(
|
||||
new WithNumNodes(8) ++
|
||||
new WithExtMemSize(0x40000000L) ++ // 1GB
|
||||
new FireSimRocketChipSingleCoreConfig)
|
||||
|
||||
class SupernodeFireSimRocketChipDualCoreConfig extends Config(
|
||||
new WithNumNodes(4) ++
|
||||
new WithExtMemSize(0x200000000L) ++ // 8GB
|
||||
new FireSimRocketChipDualCoreConfig)
|
||||
|
||||
class SupernodeFireSimRocketChipQuadCoreConfig extends Config(
|
||||
new WithNumNodes(4) ++
|
||||
new WithExtMemSize(0x200000000L) ++ // 8GB
|
||||
new FireSimRocketChipQuadCoreConfig)
|
||||
|
||||
class SupernodeFireSimRocketChipHexaCoreConfig extends Config(
|
||||
new WithNumNodes(4) ++
|
||||
new WithExtMemSize(0x200000000L) ++ // 8GB
|
||||
new FireSimRocketChipHexaCoreConfig)
|
||||
|
||||
class SupernodeFireSimRocketChipOctaCoreConfig extends Config(
|
||||
new WithNumNodes(4) ++
|
||||
new WithExtMemSize(0x200000000L) ++ // 8GB
|
||||
new FireSimRocketChipOctaCoreConfig)
|
||||
|
|
@ -0,0 +1,45 @@
|
|||
//See LICENSE for license details.
|
||||
package firesim.firesim
|
||||
|
||||
import scala.collection.mutable.LinkedHashSet
|
||||
|
||||
import freechips.rocketchip.system.{TestGeneration, RocketTestSuite}
|
||||
|
||||
/* This imports tests from FireChip to test devices that aren't natively
|
||||
* tested by the riscv assembly tests.
|
||||
* Firesim's target-specific makefrag gives the recipes for building the
|
||||
* binaries.
|
||||
*/
|
||||
|
||||
class BlockdevTestSuite(prefix: String, val names: LinkedHashSet[String]) extends RocketTestSuite {
|
||||
val envName = ""
|
||||
// fc_test_dir is is defined in firesim's Makefrag
|
||||
val dir = "$(fc_test_dir)"
|
||||
val makeTargetName = prefix + "-blkdev-tests"
|
||||
def kind = "blockdev"
|
||||
// Blockdev tests need an image, which complicates this
|
||||
def additionalArgs = "+blkdev-in-mem0=128 +nic-loopback0"
|
||||
override def toString = s"$makeTargetName = \\\n" +
|
||||
// Make variable with the binaries of the suite
|
||||
names.map(n => s"\t$n.riscv").mkString(" \\\n") + "\n\n" +
|
||||
// Variables with binary specific arguments
|
||||
names.map(n => s"$n.riscv_ARGS=$additionalArgs").mkString(" \n") +
|
||||
postScript
|
||||
}
|
||||
|
||||
object FastBlockdevTests extends BlockdevTestSuite("fast", LinkedHashSet("blkdev"))
|
||||
object SlowBlockdevTests extends BlockdevTestSuite("slow", LinkedHashSet("big-blkdev"))
|
||||
|
||||
class NICTestSuite(prefix: String, val names: LinkedHashSet[String]) extends RocketTestSuite {
|
||||
val envName = ""
|
||||
val dir = "$(fc_test_dir)"
|
||||
val makeTargetName = prefix + "-nic-tests"
|
||||
def kind = "nic"
|
||||
def additionalArgs = "+netbw0=100 +linklatency0=6405 +netburst0=8 +slotid=0 +nic-loopback0"
|
||||
override def toString = s"$makeTargetName = \\\n" +
|
||||
names.map(n => s"\t$n.riscv").mkString(" \\\n") + "\n\n" +
|
||||
names.map(n => s"$n.riscv_ARGS=$additionalArgs").mkString(" \n") +
|
||||
postScript
|
||||
}
|
||||
|
||||
object NICLoopbackTests extends NICTestSuite("loopback", LinkedHashSet("nic-loopback"))
|
|
@ -0,0 +1,131 @@
|
|||
package firesim.firesim
|
||||
|
||||
import chisel3._
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.amba.axi4._
|
||||
import freechips.rocketchip.util._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.rocket.TracedInstruction
|
||||
import firesim.endpoints.{TraceOutputTop, DeclockedTracedInstruction}
|
||||
import boom.system.BoomSubsystem
|
||||
|
||||
import midas.models.AXI4BundleWithEdge
|
||||
import midas.targetutils.ExcludeInstanceAsserts
|
||||
|
||||
/** Ties together Subsystem buses in the same fashion done in the example top of Rocket Chip */
|
||||
trait HasDefaultBusConfiguration {
|
||||
this: BaseSubsystem =>
|
||||
// The sbus masters the cbus; here we convert TL-UH -> TL-UL
|
||||
sbus.crossToBus(cbus, NoCrossing)
|
||||
|
||||
// The cbus masters the pbus; which might be clocked slower
|
||||
cbus.crossToBus(pbus, SynchronousCrossing())
|
||||
|
||||
// The fbus masters the sbus; both are TL-UH or TL-C
|
||||
FlipRendering { implicit p =>
|
||||
sbus.crossFromBus(fbus, SynchronousCrossing())
|
||||
}
|
||||
|
||||
// The sbus masters the mbus; here we convert TL-C -> TL-UH
|
||||
private val BankedL2Params(nBanks, coherenceManager) = p(BankedL2Key)
|
||||
private val (in, out, halt) = coherenceManager(this)
|
||||
if (nBanks != 0) {
|
||||
sbus.coupleTo("coherence_manager") { in :*= _ }
|
||||
mbus.coupleFrom("coherence_manager") { _ :=* BankBinder(mbus.blockBytes * (nBanks-1)) :*= out }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/** 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.
|
||||
*/
|
||||
object PrintTracePort extends Field[Boolean](false)
|
||||
|
||||
trait HasTraceIO {
|
||||
this: HasTiles =>
|
||||
val module: HasTraceIOImp
|
||||
|
||||
// Bind all the trace nodes to a BB; we'll use this to generate the IO in the imp
|
||||
val traceNexus = BundleBridgeNexus[Vec[TracedInstruction]]
|
||||
val tileTraceNodes = tiles.map(tile => tile.traceNode)
|
||||
tileTraceNodes foreach { traceNexus := _ }
|
||||
}
|
||||
|
||||
trait HasTraceIOImp extends LazyModuleImp {
|
||||
val outer: HasTraceIO
|
||||
|
||||
val traceIO = IO(Output(new TraceOutputTop(
|
||||
DeclockedTracedInstruction.fromNode(outer.traceNexus.in))))
|
||||
(traceIO.traces zip outer.traceNexus.in).foreach({ case (port, (tileTrace, _)) =>
|
||||
port := DeclockedTracedInstruction.fromVec(tileTrace)
|
||||
})
|
||||
|
||||
// Enabled to test TracerV trace capture
|
||||
if (p(PrintTracePort)) {
|
||||
val traceprint = Wire(UInt(512.W))
|
||||
traceprint := traceIO.asUInt
|
||||
printf("TRACEPORT: %x\n", traceprint)
|
||||
}
|
||||
}
|
||||
|
||||
// Prevent MIDAS from synthesizing assertions in the dummy TLB included in BOOM
|
||||
trait ExcludeInvalidBoomAssertions extends LazyModuleImp {
|
||||
ExcludeInstanceAsserts(("NonBlockingDCache", "dtlb"))
|
||||
}
|
||||
|
|
@ -0,0 +1,176 @@
|
|||
package firesim.firesim
|
||||
|
||||
import chisel3._
|
||||
import freechips.rocketchip._
|
||||
import freechips.rocketchip.subsystem._
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.tilelink._
|
||||
import freechips.rocketchip.devices.tilelink._
|
||||
import freechips.rocketchip.config.Parameters
|
||||
import freechips.rocketchip.util.{HeterogeneousBag}
|
||||
import freechips.rocketchip.amba.axi4.AXI4Bundle
|
||||
import freechips.rocketchip.config.{Field, Parameters}
|
||||
import freechips.rocketchip.diplomacy.LazyModule
|
||||
import boom.system.{BoomSubsystem, BoomSubsystemModuleImp}
|
||||
import icenet._
|
||||
import testchipip._
|
||||
import testchipip.SerialAdapter.SERIAL_IF_WIDTH
|
||||
import sifive.blocks.devices.uart._
|
||||
import midas.models.AXI4BundleWithEdge
|
||||
import java.io.File
|
||||
|
||||
/*******************************************************************************
|
||||
* Top level DESIGN configurations. These describe the basic instantiations of
|
||||
* the designs being simulated.
|
||||
*
|
||||
* In general, if you're adding or removing features from any of these, you
|
||||
* should CREATE A NEW ONE, WITH A NEW NAME. This is because the manager
|
||||
* will store this name as part of the tags for the AGFI, so that later you can
|
||||
* reconstruct what is in a particular AGFI. These tags are also used to
|
||||
* determine which driver to build.
|
||||
*******************************************************************************/
|
||||
|
||||
class FireSim(implicit p: Parameters) extends RocketSubsystem
|
||||
with HasDefaultBusConfiguration
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPort
|
||||
with HasPeripheryBootROM
|
||||
with HasNoDebug
|
||||
with HasPeripherySerial
|
||||
with HasPeripheryUART
|
||||
with HasPeripheryIceNIC
|
||||
with HasPeripheryBlockDevice
|
||||
with HasTraceIO
|
||||
{
|
||||
override lazy val module = new FireSimModuleImp(this)
|
||||
}
|
||||
|
||||
class FireSimModuleImp[+L <: FireSim](l: L) extends RocketSubsystemModuleImp(l)
|
||||
with HasRTCModuleImp
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
|
||||
with HasPeripheryBootROMModuleImp
|
||||
with HasNoDebugModuleImp
|
||||
with HasPeripherySerialModuleImp
|
||||
with HasPeripheryUARTModuleImp
|
||||
with HasPeripheryIceNICModuleImpValidOnly
|
||||
with HasPeripheryBlockDeviceModuleImp
|
||||
with HasTraceIOImp
|
||||
|
||||
|
||||
class FireSimNoNIC(implicit p: Parameters) extends RocketSubsystem
|
||||
with HasDefaultBusConfiguration
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPort
|
||||
with HasPeripheryBootROM
|
||||
with HasNoDebug
|
||||
with HasPeripherySerial
|
||||
with HasPeripheryUART
|
||||
with HasPeripheryBlockDevice
|
||||
with HasTraceIO
|
||||
{
|
||||
override lazy val module = new FireSimNoNICModuleImp(this)
|
||||
}
|
||||
|
||||
class FireSimNoNICModuleImp[+L <: FireSimNoNIC](l: L) extends RocketSubsystemModuleImp(l)
|
||||
with HasRTCModuleImp
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
|
||||
with HasPeripheryBootROMModuleImp
|
||||
with HasNoDebugModuleImp
|
||||
with HasPeripherySerialModuleImp
|
||||
with HasPeripheryUARTModuleImp
|
||||
with HasPeripheryBlockDeviceModuleImp
|
||||
with HasTraceIOImp
|
||||
|
||||
|
||||
class FireBoom(implicit p: Parameters) extends BoomSubsystem
|
||||
with HasDefaultBusConfiguration
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPort
|
||||
with HasPeripheryBootROM
|
||||
with HasNoDebug
|
||||
with HasPeripherySerial
|
||||
with HasPeripheryUART
|
||||
with HasPeripheryIceNIC
|
||||
with HasPeripheryBlockDevice
|
||||
with HasTraceIO
|
||||
{
|
||||
override lazy val module = new FireBoomModuleImp(this)
|
||||
}
|
||||
|
||||
class FireBoomModuleImp[+L <: FireBoom](l: L) extends BoomSubsystemModuleImp(l)
|
||||
with HasRTCModuleImp
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
|
||||
with HasPeripheryBootROMModuleImp
|
||||
with HasNoDebugModuleImp
|
||||
with HasPeripherySerialModuleImp
|
||||
with HasPeripheryUARTModuleImp
|
||||
with HasPeripheryIceNICModuleImpValidOnly
|
||||
with HasPeripheryBlockDeviceModuleImp
|
||||
with HasTraceIOImp
|
||||
with ExcludeInvalidBoomAssertions
|
||||
|
||||
class FireBoomNoNIC(implicit p: Parameters) extends BoomSubsystem
|
||||
with HasDefaultBusConfiguration
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPort
|
||||
with HasPeripheryBootROM
|
||||
with HasNoDebug
|
||||
with HasPeripherySerial
|
||||
with HasPeripheryUART
|
||||
with HasPeripheryBlockDevice
|
||||
with HasTraceIO
|
||||
{
|
||||
override lazy val module = new FireBoomNoNICModuleImp(this)
|
||||
}
|
||||
|
||||
class FireBoomNoNICModuleImp[+L <: FireBoomNoNIC](l: L) extends BoomSubsystemModuleImp(l)
|
||||
with HasRTCModuleImp
|
||||
with CanHaveFASEDOptimizedMasterAXI4MemPortModuleImp
|
||||
with HasPeripheryBootROMModuleImp
|
||||
with HasNoDebugModuleImp
|
||||
with HasPeripherySerialModuleImp
|
||||
with HasPeripheryUARTModuleImp
|
||||
with HasPeripheryBlockDeviceModuleImp
|
||||
with HasTraceIOImp
|
||||
with ExcludeInvalidBoomAssertions
|
||||
|
||||
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
|
||||
} }
|
||||
}
|
||||
|
|
@ -0,0 +1,138 @@
|
|||
//See LICENSE for license details.
|
||||
package firesim.firesim
|
||||
|
||||
import java.io.File
|
||||
|
||||
import scala.concurrent.{Future, Await, ExecutionContext}
|
||||
import scala.sys.process.{stringSeqToProcess, ProcessLogger}
|
||||
import scala.io.Source
|
||||
|
||||
import freechips.rocketchip.diplomacy._
|
||||
import freechips.rocketchip.system.{RocketTestSuite, BenchmarkTestSuite}
|
||||
import freechips.rocketchip.system.TestGeneration._
|
||||
import freechips.rocketchip.system.DefaultTestSuites._
|
||||
|
||||
import firesim.util.GeneratorArgs
|
||||
|
||||
abstract class FireSimTestSuite(
|
||||
topModuleClass: String,
|
||||
targetConfigs: String,
|
||||
platformConfigs: String,
|
||||
N: Int = 8
|
||||
) extends firesim.midasexamples.TestSuiteCommon with HasFireSimGeneratorUtilities {
|
||||
import scala.concurrent.duration._
|
||||
import ExecutionContext.Implicits.global
|
||||
|
||||
lazy val generatorArgs = GeneratorArgs(
|
||||
midasFlowKind = "midas",
|
||||
targetDir = "generated-src",
|
||||
topModuleProject = "firesim.firesim",
|
||||
topModuleClass = topModuleClass,
|
||||
targetConfigProject = "firesim.firesim",
|
||||
targetConfigs = targetConfigs ++ "_WithScalaTestFeatures",
|
||||
platformConfigProject = "firesim.firesim",
|
||||
platformConfigs = platformConfigs)
|
||||
|
||||
// From HasFireSimGeneratorUtilities
|
||||
// For the firesim utilities to use the same directory as the test suite
|
||||
override lazy val testDir = genDir
|
||||
|
||||
// From TestSuiteCommon
|
||||
val targetTuple = generatorArgs.tupleName
|
||||
val commonMakeArgs = Seq(s"DESIGN=${generatorArgs.topModuleClass}",
|
||||
s"TARGET_CONFIG=${generatorArgs.targetConfigs}",
|
||||
s"PLATFORM_CONFIG=${generatorArgs.platformConfigs}")
|
||||
override lazy val platform = hostParams(midas.Platform)
|
||||
|
||||
def invokeMlSimulator(backend: String, name: String, debug: Boolean, additionalArgs: Seq[String] = Nil) = {
|
||||
make((Seq(s"${outDir.getAbsolutePath}/${name}.%s".format(if (debug) "vpd" else "out"),
|
||||
s"EMUL=${backend}")
|
||||
++ additionalArgs):_*)
|
||||
}
|
||||
|
||||
def runTest(backend: String, name: String, debug: Boolean, additionalArgs: Seq[String] = Nil) = {
|
||||
behavior of s"${name} running on ${backend} in MIDAS-level simulation"
|
||||
compileMlSimulator(backend, debug)
|
||||
if (isCmdAvailable(backend)) {
|
||||
it should s"pass" in {
|
||||
assert(invokeMlSimulator(backend, name, debug, additionalArgs) == 0)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
//def runReplay(backend: String, replayBackend: String, name: String) = {
|
||||
// val dir = (new File(outDir, backend)).getAbsolutePath
|
||||
// (Seq("make", s"replay-$replayBackend",
|
||||
// s"SAMPLE=${dir}/${name}.sample", s"output_dir=$dir") ++ makeArgs).!
|
||||
//}
|
||||
|
||||
def runSuite(backend: String, debug: Boolean = false)(suite: RocketTestSuite) {
|
||||
// compile emulators
|
||||
behavior of s"${suite.makeTargetName} running on $backend"
|
||||
if (isCmdAvailable(backend)) {
|
||||
val postfix = suite match {
|
||||
case _: BenchmarkTestSuite | _: BlockdevTestSuite | _: NICTestSuite => ".riscv"
|
||||
case _ => ""
|
||||
}
|
||||
val results = suite.names.toSeq sliding (N, N) map { t =>
|
||||
val subresults = t map (name =>
|
||||
Future(name -> invokeMlSimulator(backend, s"$name$postfix", debug)))
|
||||
Await result (Future sequence subresults, Duration.Inf)
|
||||
}
|
||||
results.flatten foreach { case (name, exitcode) =>
|
||||
it should s"pass $name" in { assert(exitcode == 0) }
|
||||
}
|
||||
//replayBackends foreach { replayBackend =>
|
||||
// if (platformParams(midas.EnableSnapshot) && isCmdAvailable("vcs")) {
|
||||
// assert((Seq("make", s"vcs-$replayBackend") ++ makeArgs).! == 0) // compile vcs
|
||||
// suite.names foreach { name =>
|
||||
// it should s"replay $name in $replayBackend" in {
|
||||
// assert(runReplay(backend, replayBackend, s"$name$postfix") == 0)
|
||||
// }
|
||||
// }
|
||||
// } else {
|
||||
// suite.names foreach { name =>
|
||||
// ignore should s"replay $name in $backend"
|
||||
// }
|
||||
// }
|
||||
//}
|
||||
} else {
|
||||
ignore should s"pass $backend"
|
||||
}
|
||||
}
|
||||
|
||||
// Checks the collected trace log matches the behavior of a chisel printf
|
||||
def diffTracelog(verilatedLog: String) {
|
||||
behavior of "captured instruction trace"
|
||||
it should s"match the chisel printf in ${verilatedLog}" in {
|
||||
def getLines(file: File, dropLines: Int = 0): Seq[String] = {
|
||||
val lines = Source.fromFile(file).getLines.toList
|
||||
lines.filter(_.startsWith("TRACEPORT")).drop(dropLines)
|
||||
}
|
||||
val resetLength = 50
|
||||
val verilatedOutput = getLines(new File(outDir, s"/${verilatedLog}"))
|
||||
val synthPrintOutput = getLines(new File(genDir, s"/TRACEFILE"), resetLength + 1)
|
||||
assert(verilatedOutput.size == synthPrintOutput.size, "Outputs differ in length")
|
||||
assert(verilatedOutput.nonEmpty)
|
||||
for ( (vPrint, sPrint) <- verilatedOutput.zip(synthPrintOutput) ) {
|
||||
assert(vPrint == sPrint)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
clean
|
||||
mkdirs
|
||||
elaborateAndCompileWithMidas
|
||||
generateTestSuiteMakefrags
|
||||
runTest("verilator", "rv64ui-p-simple", false, Seq(s"""EXTRA_SIM_ARGS=+trace-test-output0"""))
|
||||
diffTracelog("rv64ui-p-simple.out")
|
||||
runSuite("verilator")(benchmarks)
|
||||
runSuite("verilator")(FastBlockdevTests)
|
||||
}
|
||||
|
||||
class RocketF1Tests extends FireSimTestSuite("FireSimNoNIC", "FireSimRocketChipConfig", "FireSimConfig")
|
||||
class RocketF1ClockDivTests extends FireSimTestSuite("FireSimNoNIC", "FireSimRocketChipConfig", "FireSimClockDivConfig")
|
||||
class BoomF1Tests extends FireSimTestSuite("FireBoomNoNIC", "FireSimBoomConfig", "FireSimConfig")
|
||||
class RocketNICF1Tests extends FireSimTestSuite("FireSim", "FireSimRocketChipConfig", "FireSimConfig") {
|
||||
runSuite("verilator")(NICLoopbackTests)
|
||||
}
|
|
@ -0,0 +1 @@
|
|||
Subproject commit bba264d68d366180f6f9b55061ee9408425d8229
|
|
@ -0,0 +1 @@
|
|||
Subproject commit ccfd85aa287bd158b87ab9160cb599ec7534553b
|
|
@ -0,0 +1,79 @@
|
|||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
#include "mmio.h"
|
||||
#include "blkdev.h"
|
||||
|
||||
#define SECTOR_WORDS (BLKDEV_SECTOR_SIZE / sizeof(uint64_t))
|
||||
#define TEST_SECTORS 128
|
||||
|
||||
unsigned long sector_buf[SECTOR_WORDS];
|
||||
|
||||
void write_sector(unsigned int secnum)
|
||||
{
|
||||
int req_tag, resp_tag;
|
||||
|
||||
for (int i = 0; i < SECTOR_WORDS; i++)
|
||||
sector_buf[i] = (secnum << 6) | i;
|
||||
|
||||
while (reg_read8(BLKDEV_NREQUEST) == 0);
|
||||
req_tag = blkdev_send_request((unsigned long) sector_buf, secnum, 1, 1);
|
||||
while (reg_read8(BLKDEV_NCOMPLETE) == 0);
|
||||
resp_tag = reg_read8(BLKDEV_COMPLETE);
|
||||
|
||||
if (req_tag != resp_tag) {
|
||||
printf("Response tag %d does not match request tag %d\n",
|
||||
req_tag, resp_tag);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
|
||||
void check_sector(unsigned int secnum)
|
||||
{
|
||||
int req_tag, resp_tag;
|
||||
|
||||
while (reg_read8(BLKDEV_NREQUEST) == 0);
|
||||
req_tag = blkdev_send_request((unsigned long) sector_buf, secnum, 1, 0);
|
||||
while (reg_read8(BLKDEV_NCOMPLETE) == 0);
|
||||
resp_tag = reg_read8(BLKDEV_COMPLETE);
|
||||
|
||||
if (req_tag != resp_tag) {
|
||||
printf("Response tag %d does not match request tag %d\n",
|
||||
req_tag, resp_tag);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (int i = 0; i < SECTOR_WORDS; i++) {
|
||||
unsigned long expected = (secnum << 6) | i;
|
||||
unsigned long actual = sector_buf[i];
|
||||
if (actual != expected) {
|
||||
printf("Word %d in sector %x does not match expected\n",
|
||||
i, secnum);
|
||||
printf("Expected %lx, got %lx\n",
|
||||
expected, actual);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
unsigned int nsectors = blkdev_nsectors();
|
||||
unsigned int stride = nsectors / TEST_SECTORS;
|
||||
|
||||
printf("Writing %u of %u sectors\n", TEST_SECTORS, nsectors);
|
||||
|
||||
for (int i = 0; i < TEST_SECTORS; i++) {
|
||||
int sector = i * stride;
|
||||
write_sector(sector);
|
||||
}
|
||||
|
||||
printf("Checking sectors\n", nsectors);
|
||||
|
||||
for (int i = 0; i < TEST_SECTORS; i++) {
|
||||
int sector = i * stride;
|
||||
check_sector(sector);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -0,0 +1,98 @@
|
|||
#include "mmio.h"
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "nic.h"
|
||||
#include "encoding.h"
|
||||
|
||||
#define NPACKETS 10
|
||||
#define TEST_OFFSET 3
|
||||
#define TEST_LEN 356
|
||||
#define ARRAY_LEN 360
|
||||
#define NTRIALS 3
|
||||
|
||||
uint32_t src[NPACKETS][ARRAY_LEN];
|
||||
uint32_t dst[NPACKETS][ARRAY_LEN];
|
||||
uint64_t lengths[NPACKETS];
|
||||
|
||||
static inline void send_recv()
|
||||
{
|
||||
uint64_t send_packet, recv_addr;
|
||||
int ncomps, send_comps_left = NPACKETS, recv_comps_left = NPACKETS;
|
||||
int recv_idx = 0;
|
||||
|
||||
for (int i = 0; i < NPACKETS; i++) {
|
||||
uint64_t pkt_size = TEST_LEN * sizeof(uint32_t);
|
||||
uint64_t src_addr = (uint64_t) &src[i][TEST_OFFSET];
|
||||
send_packet = (pkt_size << 48) | src_addr;
|
||||
recv_addr = (uint64_t) dst[i];
|
||||
reg_write64(SIMPLENIC_SEND_REQ, send_packet);
|
||||
reg_write64(SIMPLENIC_RECV_REQ, recv_addr);
|
||||
}
|
||||
|
||||
while (send_comps_left > 0 || recv_comps_left > 0) {
|
||||
ncomps = nic_send_comp_avail();
|
||||
asm volatile ("fence");
|
||||
for (int i = 0; i < ncomps; i++)
|
||||
reg_read16(SIMPLENIC_SEND_COMP);
|
||||
send_comps_left -= ncomps;
|
||||
|
||||
ncomps = nic_recv_comp_avail();
|
||||
asm volatile ("fence");
|
||||
for (int i = 0; i < ncomps; i++) {
|
||||
lengths[recv_idx] = reg_read16(SIMPLENIC_RECV_COMP);
|
||||
recv_idx++;
|
||||
}
|
||||
recv_comps_left -= ncomps;
|
||||
}
|
||||
}
|
||||
|
||||
void run_test(void)
|
||||
{
|
||||
unsigned long start, end;
|
||||
int i, j;
|
||||
|
||||
memset(dst, 0, sizeof(dst));
|
||||
asm volatile ("fence");
|
||||
|
||||
start = rdcycle();
|
||||
send_recv();
|
||||
end = rdcycle();
|
||||
|
||||
printf("send/recv %lu cycles\n", end - start);
|
||||
|
||||
for (i = 0; i < NPACKETS; i++) {
|
||||
if (lengths[i] != TEST_LEN * sizeof(uint32_t)) {
|
||||
printf("recv got wrong # bytes\n");
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
for (j = 0; j < TEST_LEN; j++) {
|
||||
if (dst[i][j] != src[i][j + TEST_OFFSET]) {
|
||||
printf("Data mismatch @ %d, %d: %x != %x\n",
|
||||
i, j, dst[i][j], src[i][j + TEST_OFFSET]);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
int main(void)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
for (i = 0; i < NPACKETS; i++) {
|
||||
for (j = 0; j < ARRAY_LEN; j++)
|
||||
src[i][j] = i * ARRAY_LEN + j;
|
||||
}
|
||||
|
||||
for (i = 0; i < NTRIALS; i++) {
|
||||
printf("Trial %d\n", i);
|
||||
run_test();
|
||||
}
|
||||
|
||||
printf("All correct\n");
|
||||
|
||||
return 0;
|
||||
}
|
|
@ -8,22 +8,22 @@
|
|||
|
||||
static inline int nic_send_req_avail(void)
|
||||
{
|
||||
return reg_read16(SIMPLENIC_COUNTS) & 0xf;
|
||||
return reg_read32(SIMPLENIC_COUNTS) & 0xff;
|
||||
}
|
||||
|
||||
static inline int nic_recv_req_avail(void)
|
||||
{
|
||||
return (reg_read16(SIMPLENIC_COUNTS) >> 4) & 0xf;
|
||||
return (reg_read32(SIMPLENIC_COUNTS) >> 8) & 0xff;
|
||||
}
|
||||
|
||||
static inline int nic_send_comp_avail(void)
|
||||
{
|
||||
return (reg_read16(SIMPLENIC_COUNTS) >> 8) & 0xf;
|
||||
return (reg_read32(SIMPLENIC_COUNTS) >> 16) & 0xff;
|
||||
}
|
||||
|
||||
static inline int nic_recv_comp_avail(void)
|
||||
{
|
||||
return (reg_read16(SIMPLENIC_COUNTS) >> 12) & 0xf;
|
||||
return (reg_read32(SIMPLENIC_COUNTS) >> 24) & 0xff;
|
||||
}
|
||||
|
||||
static void nic_send(void *data, unsigned long len)
|
||||
|
|
|
@ -0,0 +1,254 @@
|
|||
#include "mmio.h"
|
||||
#include "nic.h"
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#define ETH_MAX_WORDS 190
|
||||
#define NET_IP_ALIGN 2
|
||||
#define ETH_HEADER_SIZE 14
|
||||
#define MAC_ADDR_SIZE 6
|
||||
#define IP_ADDR_SIZE 4
|
||||
|
||||
#define IPV4_ETHTYPE 0x0800
|
||||
#define ARP_ETHTYPE 0x0806
|
||||
#define ICMP_PROT 1
|
||||
#define ECHO_REPLY 0
|
||||
#define ECHO_REQUEST 8
|
||||
#define ARP_REQUEST 1
|
||||
#define ARP_REPLY 2
|
||||
#define HTYPE_ETH 1
|
||||
|
||||
static inline uint16_t ntohs(uint16_t nint)
|
||||
{
|
||||
return ((nint & 0xff) << 8) | ((nint >> 8) & 0xff);
|
||||
}
|
||||
|
||||
static inline uint16_t htons(uint16_t nint)
|
||||
{
|
||||
return ntohs(nint);
|
||||
}
|
||||
|
||||
struct eth_header {
|
||||
uint8_t padding[NET_IP_ALIGN];
|
||||
uint8_t dst_mac[MAC_ADDR_SIZE];
|
||||
uint8_t src_mac[MAC_ADDR_SIZE];
|
||||
uint16_t ethtype;
|
||||
};
|
||||
|
||||
struct arp_header {
|
||||
uint16_t htype;
|
||||
uint16_t ptype;
|
||||
uint8_t hlen;
|
||||
uint8_t plen;
|
||||
uint16_t oper;
|
||||
uint8_t sha[MAC_ADDR_SIZE];
|
||||
uint8_t spa[IP_ADDR_SIZE];
|
||||
uint8_t tha[MAC_ADDR_SIZE];
|
||||
uint8_t tpa[IP_ADDR_SIZE];
|
||||
};
|
||||
|
||||
struct ipv4_header {
|
||||
uint8_t ver_ihl;
|
||||
uint8_t dscp_ecn;
|
||||
uint16_t length;
|
||||
uint16_t ident;
|
||||
uint16_t flags_frag_off;
|
||||
uint8_t ttl;
|
||||
uint8_t prot;
|
||||
uint16_t cksum;
|
||||
uint32_t src_addr;
|
||||
uint32_t dst_addr;
|
||||
};
|
||||
|
||||
struct icmp_header {
|
||||
uint8_t type;
|
||||
uint8_t code;
|
||||
uint16_t cksum;
|
||||
uint32_t rest;
|
||||
};
|
||||
|
||||
static int checksum(uint16_t *data, int len)
|
||||
{
|
||||
int i;
|
||||
uint32_t sum = 0;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
sum += ntohs(data[i]);
|
||||
|
||||
while ((sum >> 16) != 0)
|
||||
sum = (sum & 0xffff) + (sum >> 16);
|
||||
|
||||
sum = ~sum & 0xffff;
|
||||
|
||||
return sum;
|
||||
}
|
||||
|
||||
#define ceil_div(n, d) (((n) - 1) / (d) + 1)
|
||||
|
||||
static int process_arp(void *buf, uint8_t *mac)
|
||||
{
|
||||
struct eth_header *eth = buf;
|
||||
struct arp_header *arp;
|
||||
size_t size = ETH_HEADER_SIZE + sizeof(*arp);
|
||||
uint8_t tmp_addr[IP_ADDR_SIZE];
|
||||
|
||||
// Verify arp packet
|
||||
arp = buf + sizeof(*eth);
|
||||
if (ntohs(arp->oper) != ARP_REQUEST) {
|
||||
printf("Wrong arp operation: %d\n", ntohs(arp->oper));
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ntohs(arp->htype) != HTYPE_ETH) {
|
||||
printf("Wrong ARP HTYPE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ntohs(arp->ptype) != IPV4_ETHTYPE) {
|
||||
printf("Wrong ARP PTYPE\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (arp->hlen != 6) {
|
||||
printf("Wrong ARP HLEN: %d\n", arp->hlen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (arp->plen != 4) {
|
||||
printf("Wrong ARP PLEN: %d\n", arp->plen);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Make the source the destination, and add our mac address
|
||||
memcpy(eth->dst_mac, eth->src_mac, MAC_ADDR_SIZE);
|
||||
memcpy(eth->src_mac, mac, MAC_ADDR_SIZE);
|
||||
|
||||
// create ARP reply
|
||||
arp->oper = htons(ARP_REPLY);
|
||||
|
||||
// Make tha the sha, and fill in sha with actual mac address
|
||||
memcpy(arp->tha, arp->sha, MAC_ADDR_SIZE);
|
||||
memcpy(arp->sha, mac, MAC_ADDR_SIZE);
|
||||
|
||||
// Swap spa and tpa in arp packet
|
||||
memcpy(tmp_addr, arp->tpa, IP_ADDR_SIZE);
|
||||
memcpy(arp->tpa, arp->spa, IP_ADDR_SIZE);
|
||||
memcpy(arp->spa, tmp_addr, IP_ADDR_SIZE);
|
||||
|
||||
size = ceil_div(size + NET_IP_ALIGN, 8) * 8;
|
||||
nic_send(buf, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
static int process_icmp(void *buf, uint8_t *mac)
|
||||
{
|
||||
struct eth_header *eth = buf;
|
||||
struct ipv4_header *ipv4;
|
||||
struct icmp_header *icmp;
|
||||
int ihl, icmp_size;
|
||||
ssize_t size;
|
||||
uint32_t tmp_addr;
|
||||
|
||||
// verify IPv4
|
||||
ipv4 = buf + sizeof(*eth);
|
||||
ihl = ipv4->ver_ihl & 0xf;
|
||||
|
||||
if (checksum((uint16_t *) ipv4, ihl << 1) != 0) {
|
||||
printf("Bad IP header checksum %04x\n", ipv4->cksum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ipv4->prot != ICMP_PROT) {
|
||||
printf("Wrong IP protocol %d\n", ipv4->prot);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// verify ICMP
|
||||
icmp = (buf + sizeof(*eth) + (ihl << 2));
|
||||
|
||||
if (icmp->type != ECHO_REQUEST) {
|
||||
printf("Wrong ICMP type %d\n", icmp->type);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (icmp->code != 0) {
|
||||
printf("Wrong ICMP code %d\n", icmp->code);
|
||||
return -1;
|
||||
}
|
||||
|
||||
icmp_size = ntohs(ipv4->length) - (ihl << 2);
|
||||
if (checksum((uint16_t *) icmp, icmp_size >> 1) != 0) {
|
||||
printf("Bad ICMP checksum %04x\n", icmp->cksum);
|
||||
return -1;
|
||||
}
|
||||
|
||||
// Set the destination and source MACs
|
||||
memcpy(eth->dst_mac, eth->src_mac, MAC_ADDR_SIZE);
|
||||
memcpy(eth->src_mac, mac, MAC_ADDR_SIZE);
|
||||
|
||||
// Swap the source and destination IP addresses
|
||||
tmp_addr = ipv4->dst_addr;
|
||||
ipv4->dst_addr = ipv4->src_addr;
|
||||
ipv4->src_addr = tmp_addr;
|
||||
|
||||
// compute the IPv4 header checksum
|
||||
ipv4->cksum = 0;
|
||||
ipv4->cksum = htons(checksum((uint16_t *) ipv4, ihl << 1));
|
||||
|
||||
// set the ICMP type to reply and compute checksum
|
||||
icmp->cksum = 0;
|
||||
icmp->type = ECHO_REPLY;
|
||||
icmp->cksum = htons(checksum((uint16_t *) icmp, icmp_size >> 1));
|
||||
size = ntohs(ipv4->length) + ETH_HEADER_SIZE;
|
||||
|
||||
size = ceil_div(size + NET_IP_ALIGN, 8) * 8;
|
||||
nic_send(buf, size);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int process_packet(void *buf, uint8_t *mac)
|
||||
{
|
||||
struct eth_header *eth;
|
||||
|
||||
// read the ICMP request
|
||||
nic_recv(buf);
|
||||
eth = buf;
|
||||
printf("Got packet: [ethtype=%04x]\n", ntohs(eth->ethtype));
|
||||
// Check ethernet type
|
||||
switch (ntohs(eth->ethtype)) {
|
||||
case IPV4_ETHTYPE:
|
||||
return process_icmp(buf, mac);
|
||||
case ARP_ETHTYPE:
|
||||
return process_arp(buf, mac);
|
||||
default:
|
||||
printf("Wrong ethtype %x\n", ntohs(eth->ethtype));
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
uint64_t buffer[ETH_MAX_WORDS];
|
||||
|
||||
int main(void)
|
||||
{
|
||||
uint64_t macaddr_long;
|
||||
uint8_t *macaddr;
|
||||
|
||||
macaddr_long = nic_macaddr();
|
||||
macaddr = (uint8_t *) &macaddr_long;
|
||||
|
||||
printf("macaddr - %02x", macaddr[0]);
|
||||
for (int i = 1; i < MAC_ADDR_SIZE; i++)
|
||||
printf(":%02x", macaddr[i]);
|
||||
printf("\n");
|
||||
|
||||
for (;;) {
|
||||
if (process_packet(buffer, macaddr))
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
12
variables.mk
12
variables.mk
|
@ -86,6 +86,18 @@ ifeq ($(SUB_PROJECT),hwacha)
|
|||
TB ?= TestDriver
|
||||
TOP ?= ExampleRocketSystem
|
||||
endif
|
||||
# Stand-in firechip variables
|
||||
ifeq ($(SUB_PROJECT),firechip)
|
||||
SBT_PROJECT ?= $(SUB_PROJECT)
|
||||
MODEL ?= TestHarness
|
||||
VLOG_MODEL ?= TestHarness
|
||||
MODEL_PACKAGE ?= firesim.firesim
|
||||
CONFIG ?= FireSimRocketChipConfig
|
||||
CONFIG_PACKAGE ?= firesim.firesim
|
||||
GENERATOR_PACKAGE ?= firesim.firesim
|
||||
TB ?= TestDriver
|
||||
TOP ?= ExampleRocketSystem
|
||||
endif
|
||||
|
||||
#########################################################################################
|
||||
# path to rocket-chip and testchipip
|
||||
|
|
Loading…
Reference in New Issue