Move example/utilities to generator directory

This commit is contained in:
Jerry Zhao
2019-05-10 15:29:28 -07:00
parent 17bc3bf60d
commit db8b8f50cf
10 changed files with 7 additions and 3 deletions

View File

@@ -0,0 +1,170 @@
package example
import chisel3._
import freechips.rocketchip.config.{Parameters, Config}
import freechips.rocketchip.subsystem.{WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32}
import freechips.rocketchip.diplomacy.{LazyModule, ValName}
import freechips.rocketchip.devices.tilelink.BootROMParams
import freechips.rocketchip.tile.XLen
import testchipip._
import sifive.blocks.devices.gpio._
/**
* TODO: Why do we need this?
*/
object ConfigValName {
implicit val valName = ValName("TestHarness")
}
import ConfigValName._
// -----------------------
// Common Parameter Mixins
// -----------------------
/**
* Class to specify where the BootRom file is (from `rebar` top)
*/
class WithBootROM extends Config((site, here, up) => {
case BootROMParams => BootROMParams(
contentFileName = s"./bootrom/bootrom.rv${site(XLen)}.img")
})
/**
* Class to add in GPIO
*/
class WithGPIO extends Config((site, here, up) => {
case PeripheryGPIOKey => List(
GPIOParams(address = 0x10012000, width = 4, includeIOF = false))
})
// ----------------------------------------
// Rocket Top Level System Parameter Mixins
// ----------------------------------------
/**
* Class to specify a "plain" top level rocket-chip system
*/
class WithNormalRocketTop extends Config((site, here, up) => {
case BuildRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
Module(LazyModule(new RocketTop()(p)).module)
}
})
/**
* Class to specify a top level rocket-chip system with PWM
*/
class WithPWMRocketTop extends Config((site, here, up) => {
case BuildRocketTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new RocketTopWithPWMTL()(p)).module)
})
/**
* Class to specify a top level rocket-chip system with a PWM AXI4
*/
class WithPWMAXI4RocketTop extends Config((site, here, up) => {
case BuildRocketTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new RocketTopWithPWMAXI4()(p)).module)
})
/**
* Class to specify a top level rocket-chip system with a block device
*/
class WithBlockDeviceModelRocketTop extends Config((site, here, up) => {
case BuildRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new RocketTopWithBlockDevice()(p)).module)
top.connectBlockDeviceModel()
top
}
})
/**
* Class to specify a top level rocket-chip system with a simulator block device
*/
class WithSimBlockDeviceRocketTop extends Config((site, here, up) => {
case BuildRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new RocketTopWithBlockDevice()(p)).module)
top.connectSimBlockDevice(clock, reset)
top
}
})
/**
* Class to specify a top level rocket-chip system with GPIO
*/
class WithGPIORocketTop extends Config((site, here, up) => {
case BuildRocketTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new RocketTopWithGPIO()(p)).module)
for (gpio <- top.gpio) {
for (pin <- gpio.pins) {
pin.i.ival := false.B
}
}
top
}
})
// --------------------------------------
// BOOM Top Level System Parameter Mixins
// --------------------------------------
/**
* Class to specify a "plain" top level BOOM system
*/
class WithNormalBoomTop extends Config((site, here, up) => {
case BuildBoomTop => (clock: Clock, reset: Bool, p: Parameters) => {
Module(LazyModule(new BoomTop()(p)).module)
}
})
/**
* Class to specify a top level BOOM system with PWM
*/
class WithPWMBoomTop extends Config((site, here, up) => {
case BuildBoomTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new BoomTopWithPWMTL()(p)).module)
})
/**
* Class to specify a top level BOOM system with a PWM AXI4
*/
class WithPWMAXI4BoomTop extends Config((site, here, up) => {
case BuildBoomTop => (clock: Clock, reset: Bool, p: Parameters) =>
Module(LazyModule(new BoomTopWithPWMAXI4()(p)).module)
})
/**
* Class to specify a top level BOOM system with a block device
*/
class WithBlockDeviceModelBoomTop extends Config((site, here, up) => {
case BuildBoomTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new BoomTopWithBlockDevice()(p)).module)
top.connectBlockDeviceModel()
top
}
})
/**
* Class to specify a top level BOOM system with a simulator block device
*/
class WithSimBlockDeviceBoomTop extends Config((site, here, up) => {
case BuildBoomTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new BoomTopWithBlockDevice()(p)).module)
top.connectSimBlockDevice(clock, reset)
top
}
})
/**
* Class to specify a top level BOOM system with GPIO
*/
class WithGPIOBoomTop extends Config((site, here, up) => {
case BuildBoomTop => (clock: Clock, reset: Bool, p: Parameters) => {
val top = Module(LazyModule(new BoomTopWithGPIO()(p)).module)
for (gpio <- top.gpio) {
for (pin <- gpio.pins) {
pin.i.ival := false.B
}
}
top
}
})

View File

@@ -0,0 +1,113 @@
package example
import chisel3._
import freechips.rocketchip.config.{Config}
import freechips.rocketchip.subsystem.{WithRoccExample, WithNMemoryChannels, WithNBigCores, WithRV32, WithExtMemSize}
import testchipip._
// --------------
// Rocket Configs
// --------------
class BaseRocketConfig extends Config(
new WithBootROM ++
new freechips.rocketchip.system.DefaultConfig)
class DefaultRocketConfig extends Config(
new WithNormalRocketTop ++
new BaseRocketConfig)
class HwachaConfig extends Config(
new hwacha.DefaultHwachaConfig ++
new DefaultRocketConfig)
class RoccRocketConfig extends Config(
new WithRoccExample ++
new DefaultRocketConfig)
class PWMRocketConfig extends Config(
new WithPWMRocketTop ++
new BaseRocketConfig)
class PWMAXI4RocketConfig extends Config(
new WithPWMAXI4RocketTop ++
new BaseRocketConfig)
class SimBlockDeviceRocketConfig extends Config(
new WithBlockDevice ++
new WithSimBlockDeviceRocketTop ++
new BaseRocketConfig)
class BlockDeviceModelRocketConfig extends Config(
new WithBlockDevice ++
new WithBlockDeviceModelRocketTop ++
new BaseRocketConfig)
class DualCoreRocketConfig extends Config(
new WithNBigCores(2) ++
new DefaultRocketConfig)
class RV32RocketConfig extends Config(
new WithRV32 ++
new DefaultRocketConfig)
class GPIORocketConfig extends Config(
new WithGPIO ++
new WithGPIORocketTop ++
new BaseRocketConfig)
class GB1MemoryConfig extends Config(
new WithExtMemSize((1<<30) * 1L) ++
new DefaultRocketConfig)
// ------------
// BOOM Configs
// ------------
class BaseBoomConfig extends Config(
new WithBootROM ++
new boom.system.BoomConfig)
class DefaultBoomConfig extends Config(
new WithNormalBoomTop ++
new BaseBoomConfig)
class HwachaBoomConfig extends Config(
new hwacha.DefaultHwachaConfig ++
new DefaultBoomConfig)
class RoccBoomConfig extends Config(
new WithRoccExample ++
new DefaultBoomConfig)
class PWMBoomConfig extends Config(
new WithPWMBoomTop ++
new BaseBoomConfig)
class PWMAXI4BoomConfig extends Config(
new WithPWMAXI4BoomTop ++
new BaseBoomConfig)
class SimBlockDeviceBoomConfig extends Config(
new WithBlockDevice ++
new WithSimBlockDeviceBoomTop ++
new BaseBoomConfig)
class BlockDeviceModelBoomConfig extends Config(
new WithBlockDevice ++
new WithBlockDeviceModelBoomTop ++
new BaseBoomConfig)
class DualCoreBoomConfig extends Config(
// Core gets tacked onto existing list
new boom.system.WithNBoomCores(2) ++
new DefaultBoomConfig)
class RV32BoomConfig extends Config(
new WithBootROM ++
new boom.system.SmallRV32UnifiedBoomConfig)
class GPIOBoomConfig extends Config(
new WithGPIO ++
new WithGPIOBoomTop ++
new BaseBoomConfig)

View File

@@ -0,0 +1,138 @@
package example
import scala.collection.mutable.LinkedHashSet
import chisel3._
import chisel3.experimental._
import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxSourceHelper}
import freechips.rocketchip.subsystem.{RocketTilesKey}
import freechips.rocketchip.diplomacy.{LazyModule}
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.util.{GeneratorApp}
import freechips.rocketchip.tile.{XLen}
import freechips.rocketchip.system.{TestGeneration, RegressionTestSuite}
import boom.system.{BoomTilesKey, BoomTestSuites}
object Generator extends GeneratorApp {
val rv64RegrTestNames = LinkedHashSet(
"rv64ud-v-fcvt",
"rv64ud-p-fdiv",
"rv64ud-v-fadd",
"rv64uf-v-fadd",
"rv64um-v-mul",
"rv64mi-p-breakpoint",
"rv64uc-v-rvc",
"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 = LinkedHashSet(
"rv32mi-p-ma_addr",
"rv32mi-p-csr",
"rv32ui-p-sh",
"rv32ui-p-lh",
"rv32uc-p-rvc",
"rv32mi-p-sbreak",
"rv32ui-p-sll")
override def addTestSuites {
import freechips.rocketchip.system.DefaultTestSuites._
val xlen = params(XLen)
// TODO: for now only generate tests for the first rocket/boom tile in the subsystem
// TODO: support heterogenous systems?
// rocket specific tests
params(RocketTilesKey).headOption.map { tileParams =>
val coreParams = tileParams.core
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) {
if (tileParams.dcache.flatMap(_.scratch).isEmpty)
TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
else
TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
}
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
val (rvi, rvu) =
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))
}
// boom specific tests
params(BoomTilesKey).headOption.map { tileParams =>
val coreParams = tileParams.core
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 if (cfg.fLen >= 64) {
TestGeneration.addSuites(env.map(rv64ud))
TestGeneration.addSuites(env.map(rv64uf))
TestGeneration.addSuite(rv32udBenchmarks)
}
}
if (coreParams.useAtomics) {
if (tileParams.dcache.flatMap(_.scratch).isEmpty) {
TestGeneration.addSuites(env.map(if (xlen == 64) rv64ua else rv32ua))
} else {
TestGeneration.addSuites(env.map(if (xlen == 64) rv64uaSansLRSC else rv32uaSansLRSC))
}
}
if (coreParams.useCompressed) TestGeneration.addSuites(env.map(if (xlen == 64) rv64uc else rv32uc))
// Include our BOOM-specific overrides.
val (rvi, rvu) =
if (xlen == 64) ((if (vm) BoomTestSuites.rv64i else BoomTestSuites.rv64pi), rv64u)
else ((if (vm) rv32i else rv32pi), rv32u)
TestGeneration.addSuites(rvi.map(_("p")))
TestGeneration.addSuites(rvu.map(_("p")))
TestGeneration.addSuites((if (vm) List("v") else List()).flatMap(env => rvu.map(_(env))))
TestGeneration.addSuite(benchmarks)
rv64RegrTestNames -= "rv64mi-p-breakpoint" // TODO: breakpoints not implemented yet
TestGeneration.addSuite(new RegressionTestSuite(if (xlen == 64) rv64RegrTestNames else rv32RegrTestNames))
}
}
val longName = names.topModuleProject + "." + names.topModuleClass + "." + names.configs
generateFirrtl
generateAnno
generateTestSuiteMakefrags
generateArtefacts
}

View File

@@ -0,0 +1,126 @@
package example
import chisel3._
import chisel3.util._
import freechips.rocketchip.amba.axi4._
import freechips.rocketchip.subsystem.BaseSubsystem
import freechips.rocketchip.config.{Parameters, Field}
import freechips.rocketchip.diplomacy._
import freechips.rocketchip.regmapper.{HasRegMap, RegField}
import freechips.rocketchip.tilelink._
import freechips.rocketchip.util.UIntIsOneOf
case class PWMParams(address: BigInt, beatBytes: Int)
class PWMBase(w: Int) extends Module {
val io = IO(new Bundle {
val pwmout = Output(Bool())
val period = Input(UInt(w.W))
val duty = Input(UInt(w.W))
val enable = Input(Bool())
})
// The counter should count up until period is reached
val counter = Reg(UInt(w.W))
when (counter >= (io.period - 1.U)) {
counter := 0.U
} .otherwise {
counter := counter + 1.U
}
// If PWM is enabled, pwmout is high when counter < duty
// If PWM is not enabled, it will always be low
io.pwmout := io.enable && (counter < io.duty)
}
trait PWMBundle extends Bundle {
val pwmout = Output(Bool())
}
trait PWMModule extends HasRegMap {
val io: PWMBundle
implicit val p: Parameters
def params: PWMParams
// How many clock cycles in a PWM cycle?
val period = Reg(UInt(32.W))
// For how many cycles should the clock be high?
val duty = Reg(UInt(32.W))
// Is the PWM even running at all?
val enable = RegInit(false.B)
val base = Module(new PWMBase(32))
io.pwmout := base.io.pwmout
base.io.period := period
base.io.duty := duty
base.io.enable := enable
regmap(
0x00 -> Seq(
RegField(32, period)),
0x04 -> Seq(
RegField(32, duty)),
0x08 -> Seq(
RegField(1, enable)))
}
class PWMTL(c: PWMParams)(implicit p: Parameters)
extends TLRegisterRouter(
c.address, "pwm", Seq("ucbbar,pwm"),
beatBytes = c.beatBytes)(
new TLRegBundle(c, _) with PWMBundle)(
new TLRegModule(c, _, _) with PWMModule)
class PWMAXI4(c: PWMParams)(implicit p: Parameters)
extends AXI4RegisterRouter(c.address, beatBytes = c.beatBytes)(
new AXI4RegBundle(c, _) with PWMBundle)(
new AXI4RegModule(c, _, _) with PWMModule)
trait HasPeripheryPWMTL { this: BaseSubsystem =>
implicit val p: Parameters
private val address = 0x2000
private val portName = "pwm"
val pwm = LazyModule(new PWMTL(
PWMParams(address, pbus.beatBytes))(p))
pbus.toVariableWidthSlave(Some(portName)) { pwm.node }
}
trait HasPeripheryPWMTLModuleImp extends LazyModuleImp {
implicit val p: Parameters
val outer: HasPeripheryPWMTL
val pwmout = IO(Output(Bool()))
pwmout := outer.pwm.module.io.pwmout
}
trait HasPeripheryPWMAXI4 { this: BaseSubsystem =>
implicit val p: Parameters
private val address = 0x2000
private val portName = "pwm"
val pwm = LazyModule(new PWMAXI4(
PWMParams(address, pbus.beatBytes))(p))
pbus.toSlave(Some(portName)) {
pwm.node :=
AXI4Buffer () :=
TLToAXI4() :=
// toVariableWidthSlave doesn't use holdFirstDeny, which TLToAXI4() needs
TLFragmenter(pbus.beatBytes, pbus.blockBytes, holdFirstDeny = true)
}
}
trait HasPeripheryPWMAXI4ModuleImp extends LazyModuleImp {
implicit val p: Parameters
val outer: HasPeripheryPWMAXI4
val pwmout = IO(Output(Bool()))
pwmout := outer.pwm.module.io.pwmout
}

View File

@@ -0,0 +1,79 @@
package example
import chisel3._
import chisel3.experimental._
import firrtl.transforms.{BlackBoxResourceAnno, BlackBoxSourceHelper}
import freechips.rocketchip.diplomacy.LazyModule
import freechips.rocketchip.config.{Field, Parameters}
import freechips.rocketchip.util.GeneratorApp
// -------------------
// Rocket Test Harness
// -------------------
case object BuildRocketTop extends Field[(Clock, Bool, Parameters) => RocketTopModule[RocketTop]]
class RocketTestHarness(implicit val p: Parameters) extends Module {
val io = IO(new Bundle {
val success = Output(Bool())
})
// force Chisel to rename module
override def desiredName = "TestHarness"
val dut = p(BuildRocketTop)(clock, reset.toBool, p)
dut.debug := DontCare
dut.connectSimAXIMem()
dut.connectSimAXIMMIO()
dut.dontTouchPorts()
dut.tieOffInterrupts()
dut.l2_frontend_bus_axi4.foreach(axi => {
axi.tieoff()
experimental.DataMirror.directionOf(axi.ar.ready) match {
case core.ActualDirection.Input =>
axi.r.bits := DontCare
axi.b.bits := DontCare
case core.ActualDirection.Output =>
axi.aw.bits := DontCare
axi.ar.bits := DontCare
axi.w.bits := DontCare
}
})
io.success := dut.connectSimSerial()
}
// -----------------
// BOOM Test Harness
// -----------------
case object BuildBoomTop extends Field[(Clock, Bool, Parameters) => BoomTopModule[BoomTop]]
class BoomTestHarness(implicit val p: Parameters) extends Module {
val io = IO(new Bundle {
val success = Output(Bool())
})
// force Chisel to rename module
override def desiredName = "TestHarness"
val dut = p(BuildBoomTop)(clock, reset.toBool, p)
dut.debug := DontCare
dut.connectSimAXIMem()
dut.connectSimAXIMMIO()
dut.dontTouchPorts()
dut.tieOffInterrupts()
dut.l2_frontend_bus_axi4.foreach(axi => {
axi.tieoff()
experimental.DataMirror.directionOf(axi.ar.ready) match {
case core.ActualDirection.Input =>
axi.r.bits := DontCare
axi.b.bits := DontCare
case core.ActualDirection.Output =>
axi.aw.bits := DontCare
axi.ar.bits := DontCare
axi.w.bits := DontCare
}
})
io.success := dut.connectSimSerial()
}

View File

@@ -0,0 +1,129 @@
package example
import chisel3._
import freechips.rocketchip.subsystem._
import freechips.rocketchip.system._
import freechips.rocketchip.config.Parameters
import freechips.rocketchip.devices.tilelink._
import freechips.rocketchip.util.DontTouch
import testchipip._
import sifive.blocks.devices.gpio._
// ------------------------
// Rocket Top Level Systems
// ------------------------
class RocketTop(implicit p: Parameters) extends ExampleRocketSystem
with CanHaveMasterAXI4MemPort
with HasPeripheryBootROM
with HasNoDebug
with HasPeripherySerial {
override lazy val module = new RocketTopModule(this)
}
class RocketTopModule[+L <: RocketTop](l: L) extends ExampleRocketSystemModuleImp(l)
with HasRTCModuleImp
with CanHaveMasterAXI4MemPortModuleImp
with HasPeripheryBootROMModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with DontTouch
//---------------------------------------------------------------------------------------------------------
class RocketTopWithPWMTL(implicit p: Parameters) extends RocketTop
with HasPeripheryPWMTL {
override lazy val module = new RocketTopWithPWMTLModule(this)
}
class RocketTopWithPWMTLModule(l: RocketTopWithPWMTL)
extends RocketTopModule(l) with HasPeripheryPWMTLModuleImp
//---------------------------------------------------------------------------------------------------------
class RocketTopWithPWMAXI4(implicit p: Parameters) extends RocketTop
with HasPeripheryPWMAXI4 {
override lazy val module = new RocketTopWithPWMAXI4Module(this)
}
class RocketTopWithPWMAXI4Module(l: RocketTopWithPWMAXI4)
extends RocketTopModule(l) with HasPeripheryPWMAXI4ModuleImp
//---------------------------------------------------------------------------------------------------------
class RocketTopWithBlockDevice(implicit p: Parameters) extends RocketTop
with HasPeripheryBlockDevice {
override lazy val module = new RocketTopWithBlockDeviceModule(this)
}
class RocketTopWithBlockDeviceModule(l: RocketTopWithBlockDevice)
extends RocketTopModule(l)
with HasPeripheryBlockDeviceModuleImp
//---------------------------------------------------------------------------------------------------------
class RocketTopWithGPIO(implicit p: Parameters) extends RocketTop
with HasPeripheryGPIO {
override lazy val module = new RocketTopWithGPIOModule(this)
}
class RocketTopWithGPIOModule(l: RocketTopWithGPIO)
extends RocketTopModule(l)
with HasPeripheryGPIOModuleImp
// ----------------------
// BOOM Top Level Systems
// ----------------------
class BoomTop(implicit p: Parameters) extends boom.system.ExampleBoomSystem
with HasNoDebug
with HasPeripherySerial {
override lazy val module = new BoomTopModule(this)
}
class BoomTopModule[+L <: BoomTop](l: L) extends boom.system.ExampleBoomSystemModule(l)
with HasRTCModuleImp
with HasNoDebugModuleImp
with HasPeripherySerialModuleImp
with DontTouch
//---------------------------------------------------------------------------------------------------------
class BoomTopWithPWMTL(implicit p: Parameters) extends BoomTop
with HasPeripheryPWMTL {
override lazy val module = new BoomTopWithPWMTLModule(this)
}
class BoomTopWithPWMTLModule(l: BoomTopWithPWMTL) extends BoomTopModule(l)
with HasPeripheryPWMTLModuleImp
//---------------------------------------------------------------------------------------------------------
class BoomTopWithPWMAXI4(implicit p: Parameters) extends BoomTop
with HasPeripheryPWMAXI4 {
override lazy val module = new BoomTopWithPWMAXI4Module(this)
}
class BoomTopWithPWMAXI4Module(l: BoomTopWithPWMAXI4) extends BoomTopModule(l)
with HasPeripheryPWMAXI4ModuleImp
//---------------------------------------------------------------------------------------------------------
class BoomTopWithBlockDevice(implicit p: Parameters) extends BoomTop
with HasPeripheryBlockDevice {
override lazy val module = new BoomTopWithBlockDeviceModule(this)
}
class BoomTopWithBlockDeviceModule(l: BoomTopWithBlockDevice) extends BoomTopModule(l)
with HasPeripheryBlockDeviceModuleImp
//---------------------------------------------------------------------------------------------------------
class BoomTopWithGPIO(implicit p: Parameters) extends BoomTop
with HasPeripheryGPIO {
override lazy val module = new BoomTopWithGPIOModule(this)
}
class BoomTopWithGPIOModule(l: BoomTopWithGPIO)
extends BoomTopModule(l)
with HasPeripheryGPIOModuleImp

View File

@@ -0,0 +1 @@
../../../../generators/rocket-chip/bootrom/

View File

@@ -0,0 +1,356 @@
// See LICENSE.SiFive for license details.
// See LICENSE.Berkeley for license details.
#include "verilated.h"
#if VM_TRACE
#include <memory>
#include "verilated_vcd_c.h"
#endif
#include <fesvr/dtm.h>
#include <fesvr/tsi.h>
#include "remote_bitbang.h"
#include <iostream>
#include <fcntl.h>
#include <signal.h>
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <getopt.h>
// For option parsing, which is split across this file, Verilog, and
// FESVR's HTIF, a few external files must be pulled in. The list of
// files and what they provide is enumerated:
//
// $RISCV/include/fesvr/htif.h:
// defines:
// - HTIF_USAGE_OPTIONS
// - HTIF_LONG_OPTIONS_OPTIND
// - HTIF_LONG_OPTIONS
// $(ROCKETCHIP_DIR)/generated-src(-debug)?/$(CONFIG).plusArgs:
// defines:
// - PLUSARG_USAGE_OPTIONS
// variables:
// - static const char * verilog_plusargs
extern tsi_t* tsi;
extern dtm_t* dtm;
extern remote_bitbang_t * jtag;
static uint64_t trace_count = 0;
bool verbose;
bool done_reset;
void handle_sigterm(int sig)
{
dtm->stop();
}
double sc_time_stamp()
{
return trace_count;
}
extern "C" int vpi_get_vlog_info(void* arg)
{
return 0;
}
static void usage(const char * program_name)
{
printf("Usage: %s [EMULATOR OPTION]... [VERILOG PLUSARG]... [HOST OPTION]... BINARY [TARGET OPTION]...\n",
program_name);
fputs("\
Run a BINARY on the Rocket Chip emulator.\n\
\n\
Mandatory arguments to long options are mandatory for short options too.\n\
\n\
EMULATOR OPTIONS\n\
-c, --cycle-count Print the cycle count before exiting\n\
+cycle-count\n\
-h, --help Display this help and exit\n\
-m, --max-cycles=CYCLES Kill the emulation after CYCLES\n\
+max-cycles=CYCLES\n\
-s, --seed=SEED Use random number seed SEED\n\
-r, --rbb-port=PORT Use PORT for remote bit bang (with OpenOCD and GDB) \n\
If not specified, a random port will be chosen\n\
automatically.\n\
-V, --verbose Enable all Chisel printfs (cycle-by-cycle info)\n\
+verbose\n\
", stdout);
#if VM_TRACE == 0
fputs("\
\n\
EMULATOR DEBUG OPTIONS (only supported in debug build -- try `make debug`)\n",
stdout);
#endif
fputs("\
-v, --vcd=FILE, Write vcd trace to FILE (or '-' for stdout)\n\
-x, --dump-start=CYCLE Start VCD tracing at CYCLE\n\
+dump-start\n\
", stdout);
fputs("\n" PLUSARG_USAGE_OPTIONS, stdout);
fputs("\n" HTIF_USAGE_OPTIONS, stdout);
printf("\n"
"EXAMPLES\n"
" - run a bare metal test:\n"
" %s $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n"
" - run a bare metal test showing cycle-by-cycle information:\n"
" %s +verbose $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add 2>&1 | spike-dasm\n"
#if VM_TRACE
" - run a bare metal test to generate a VCD waveform:\n"
" %s -v rv64ui-p-add.vcd $RISCV/riscv64-unknown-elf/share/riscv-tests/isa/rv64ui-p-add\n"
#endif
" - run an ELF (you wrote, called 'hello') using the proxy kernel:\n"
" %s pk hello\n",
program_name, program_name, program_name
#if VM_TRACE
, program_name
#endif
);
}
int main(int argc, char** argv)
{
unsigned random_seed = (unsigned)time(NULL) ^ (unsigned)getpid();
uint64_t max_cycles = -1;
int ret = 0;
bool print_cycles = false;
// Port numbers are 16 bit unsigned integers.
uint16_t rbb_port = 0;
#if VM_TRACE
FILE * vcdfile = NULL;
uint64_t start = 0;
#endif
char ** htif_argv = NULL;
int verilog_plusargs_legal = 1;
while (1) {
static struct option long_options[] = {
{"cycle-count", no_argument, 0, 'c' },
{"help", no_argument, 0, 'h' },
{"max-cycles", required_argument, 0, 'm' },
{"seed", required_argument, 0, 's' },
{"rbb-port", required_argument, 0, 'r' },
{"verbose", no_argument, 0, 'V' },
#if VM_TRACE
{"vcd", required_argument, 0, 'v' },
{"dump-start", required_argument, 0, 'x' },
#endif
HTIF_LONG_OPTIONS
};
int option_index = 0;
#if VM_TRACE
int c = getopt_long(argc, argv, "-chm:s:r:v:Vx:", long_options, &option_index);
#else
int c = getopt_long(argc, argv, "-chm:s:r:V", long_options, &option_index);
#endif
if (c == -1) break;
retry:
switch (c) {
// Process long and short EMULATOR options
case '?': usage(argv[0]); return 1;
case 'c': print_cycles = true; break;
case 'h': usage(argv[0]); return 0;
case 'm': max_cycles = atoll(optarg); break;
case 's': random_seed = atoi(optarg); break;
case 'r': rbb_port = atoi(optarg); break;
case 'V': verbose = true; break;
#if VM_TRACE
case 'v': {
vcdfile = strcmp(optarg, "-") == 0 ? stdout : fopen(optarg, "w");
if (!vcdfile) {
std::cerr << "Unable to open " << optarg << " for VCD write\n";
return 1;
}
break;
}
case 'x': start = atoll(optarg); break;
#endif
// Process legacy '+' EMULATOR arguments by replacing them with
// their getopt equivalents
case 1: {
std::string arg = optarg;
if (arg.substr(0, 1) != "+") {
optind--;
goto done_processing;
}
if (arg == "+verbose")
c = 'V';
else if (arg.substr(0, 12) == "+max-cycles=") {
c = 'm';
optarg = optarg+12;
}
#if VM_TRACE
else if (arg.substr(0, 12) == "+dump-start=") {
c = 'x';
optarg = optarg+12;
}
#endif
else if (arg.substr(0, 12) == "+cycle-count")
c = 'c';
// If we don't find a legacy '+' EMULATOR argument, it still could be
// a VERILOG_PLUSARG and not an error.
else if (verilog_plusargs_legal) {
const char ** plusarg = &verilog_plusargs[0];
int legal_verilog_plusarg = 0;
while (*plusarg && (legal_verilog_plusarg == 0)){
if (arg.substr(1, strlen(*plusarg)) == *plusarg) {
legal_verilog_plusarg = 1;
}
plusarg ++;
}
if (!legal_verilog_plusarg) {
verilog_plusargs_legal = 0;
} else {
c = 'P';
}
goto retry;
}
// If we STILL don't find a legacy '+' argument, it still could be
// an HTIF (HOST) argument and not an error. If this is the case, then
// we're done processing EMULATOR and VERILOG arguments.
else {
static struct option htif_long_options [] = { HTIF_LONG_OPTIONS };
struct option * htif_option = &htif_long_options[0];
while (htif_option->name) {
if (arg.substr(1, strlen(htif_option->name)) == htif_option->name) {
optind--;
goto done_processing;
}
htif_option++;
}
std::cerr << argv[0] << ": invalid plus-arg (Verilog or HTIF) \""
<< arg << "\"\n";
c = '?';
}
goto retry;
}
case 'P': break; // Nothing to do here, Verilog PlusArg
// Realize that we've hit HTIF (HOST) arguments or error out
default:
if (c >= HTIF_LONG_OPTIONS_OPTIND) {
optind--;
goto done_processing;
}
c = '?';
goto retry;
}
}
done_processing:
if (optind == argc) {
std::cerr << "No binary specified for emulator\n";
usage(argv[0]);
return 1;
}
int htif_argc = 1 + argc - optind;
htif_argv = (char **) malloc((htif_argc) * sizeof (char *));
htif_argv[0] = argv[0];
for (int i = 1; optind < argc;) htif_argv[i++] = argv[optind++];
if (verbose)
fprintf(stderr, "using random seed %u\n", random_seed);
srand(random_seed);
srand48(random_seed);
Verilated::randReset(2);
Verilated::commandArgs(argc, argv);
TEST_HARNESS *tile = new TEST_HARNESS;
#if VM_TRACE
Verilated::traceEverOn(true); // Verilator must compute traced signals
std::unique_ptr<VerilatedVcdFILE> vcdfd(new VerilatedVcdFILE(vcdfile));
std::unique_ptr<VerilatedVcdC> tfp(new VerilatedVcdC(vcdfd.get()));
if (vcdfile) {
tile->trace(tfp.get(), 99); // Trace 99 levels of hierarchy
tfp->open("");
}
#endif
jtag = new remote_bitbang_t(rbb_port);
dtm = new dtm_t(htif_argc, htif_argv);
tsi = new tsi_t(htif_argc, htif_argv);
signal(SIGTERM, handle_sigterm);
bool dump;
// reset for several cycles to handle pipelined reset
for (int i = 0; i < 10; i++) {
tile->reset = 1;
tile->clock = 0;
tile->eval();
#if VM_TRACE
dump = tfp && trace_count >= start;
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
#endif
tile->clock = 1;
tile->eval();
#if VM_TRACE
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
#endif
trace_count ++;
}
tile->reset = 0;
done_reset = true;
while (!dtm->done() && !jtag->done() && !tsi->done() &&
!tile->io_success && trace_count < max_cycles) {
tile->clock = 0;
tile->eval();
#if VM_TRACE
dump = tfp && trace_count >= start;
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2));
#endif
tile->clock = 1;
tile->eval();
#if VM_TRACE
if (dump)
tfp->dump(static_cast<vluint64_t>(trace_count * 2 + 1));
#endif
trace_count++;
}
#if VM_TRACE
if (tfp)
tfp->close();
if (vcdfile)
fclose(vcdfile);
#endif
if (dtm->exit_code())
{
fprintf(stderr, "*** FAILED *** via dtm (code = %d, seed %d) after %ld cycles\n", dtm->exit_code(), random_seed, trace_count);
ret = dtm->exit_code();
}
else if (tsi->exit_code())
{
fprintf(stderr, "*** FAILED *** (code = %d, seed %d) after %ld cycles\n", tsi->exit_code(), random_seed, trace_count);
ret = tsi->exit_code();
}
else if (jtag->exit_code())
{
fprintf(stderr, "*** FAILED *** via jtag (code = %d, seed %d) after %ld cycles\n", jtag->exit_code(), random_seed, trace_count);
ret = jtag->exit_code();
}
else if (trace_count == max_cycles)
{
fprintf(stderr, "*** FAILED *** via trace_count (timeout, seed %d) after %ld cycles\n", random_seed, trace_count);
ret = 2;
}
else if (verbose || print_cycles)
{
fprintf(stderr, "*** PASSED *** Completed after %ld cycles\n", trace_count);
}
if (dtm) delete dtm;
if (tsi) delete tsi;
if (jtag) delete jtag;
if (tile) delete tile;
if (htif_argv) free(htif_argv);
return ret;
}

View File

@@ -0,0 +1,119 @@
package utilities
import java.io.File
case class GenerateSimConfig(
targetDir: String = ".",
dotFName: String = "sim_files.f",
simulator: Simulator = VerilatorSimulator,
)
sealed trait Simulator
object VerilatorSimulator extends Simulator
object VCSSimulator extends Simulator
trait HasGenerateSimConfig {
val parser = new scopt.OptionParser[GenerateSimConfig]("GenerateSimFiles") {
head("GenerateSimFiles", "0.1")
opt[String]("simulator")
.abbr("sim")
.valueName("<simulator-name>")
.action((x, c) => x match {
case "verilator" => c.copy(simulator = VerilatorSimulator)
case "vcs" => c.copy(simulator = VCSSimulator)
case _ => throw new Exception(s"Unrecognized simulator $x")
})
.text("Name of simulator to generate files for (verilator, vcs)")
opt[String]("target-dir")
.abbr("td")
.valueName("<target-directory>")
.action((x, c) => c.copy(targetDir = x))
.text("Target director to put files")
opt[String]("dotFName")
.abbr("df")
.valueName("<dot-f filename>")
.action((x, c) => c.copy(dotFName = x))
.text("Name of generated dot-f file")
}
}
object GenerateSimFiles extends App with HasGenerateSimConfig {
def addOption(file: File, cfg: GenerateSimConfig): String = {
val fname = file.getCanonicalPath
// deal with header files
if (fname.takeRight(2) == ".h") {
cfg.simulator match {
// verilator needs to explicitly include verilator.h, so use the -FI option
case VerilatorSimulator => s"-FI ${fname}"
// vcs pulls headers in with +incdir, doesn't have anything like verilator.h
case VCSSimulator => ""
}
} else { // do nothing otherwise
fname
}
}
def writeDotF(lines: Seq[String], cfg: GenerateSimConfig): Unit = {
writeTextToFile(lines.mkString("\n"), new File(cfg.targetDir, cfg.dotFName))
}
// From FIRRTL
def safeFile[A](fileName: String)(code: => A) = try { code } catch {
case e@ (_: java.io.FileNotFoundException | _: NullPointerException) => throw new Exception(fileName, e)
case t: Throwable => throw t
}
// From FIRRTL
def writeResource(name: String, targetDir: String): File = {
val in = getClass.getResourceAsStream(name)
val p = java.nio.file.Paths.get(name)
val fname = p.getFileName().toString();
val f = new File(targetDir, fname)
val out = new java.io.FileOutputStream(f)
safeFile(name)(Iterator.continually(in.read).takeWhile(-1 != _).foreach(out.write))
out.close()
f
}
// From FIRRTL
def writeTextToFile(text: String, file: File) {
val out = new java.io.PrintWriter(file)
out.write(text)
out.close()
}
def resources(sim: Simulator): Seq[String] = Seq(
"/testchipip/csrc/SimSerial.cc",
"/csrc/SimDTM.cc",
"/csrc/SimJTAG.cc",
"/csrc/remote_bitbang.h",
"/csrc/remote_bitbang.cc",
"/vsrc/EICG_wrapper.v",
) ++ (sim match { // simulator specific files to include
case VerilatorSimulator => Seq(
"/project-template/csrc/emulator.cc",
"/csrc/verilator.h",
)
case VCSSimulator => Seq(
"/vsrc/TestDriver.v",
)
})
def writeBootrom(): Unit = {
firrtl.FileUtils.makeDirectory("./bootrom/")
writeResource("/testchipip/bootrom/bootrom.rv64.img", "./bootrom/")
writeResource("/testchipip/bootrom/bootrom.rv32.img", "./bootrom/")
writeResource("/bootrom/bootrom.img", "./bootrom/")
}
def writeFiles(cfg: GenerateSimConfig): Unit = {
writeBootrom()
firrtl.FileUtils.makeDirectory(cfg.targetDir)
val files = resources(cfg.simulator).map { writeResource(_, cfg.targetDir) }
writeDotF(files.map(addOption(_, cfg)), cfg)
}
parser.parse(args, GenerateSimConfig()) match {
case Some(cfg) => writeFiles(cfg)
case _ => // error message already shown
}
}