split coreplex off into separate package
This commit is contained in:
@ -4,27 +4,18 @@ package rocketchip
|
||||
|
||||
import Chisel._
|
||||
import junctions._
|
||||
import uncore.tilelink._
|
||||
import uncore.coherence._
|
||||
import rocket._
|
||||
import uncore.agents._
|
||||
import uncore.tilelink._
|
||||
import uncore.devices._
|
||||
import uncore.converters._
|
||||
import rocket._
|
||||
import rocket.Util._
|
||||
import groundtest._
|
||||
import coreplex._
|
||||
import scala.math.max
|
||||
import scala.collection.mutable.{LinkedHashSet, ListBuffer}
|
||||
import DefaultTestSuites._
|
||||
import cde.{Parameters, Config, Dump, Knob, CDEMatchError}
|
||||
|
||||
object ConfigUtils {
|
||||
def max_int(values: Int*): Int = {
|
||||
values.reduce((a, b) => max(a, b))
|
||||
}
|
||||
}
|
||||
import ConfigUtils._
|
||||
|
||||
class BaseConfig extends Config (
|
||||
class BasePlatformConfig extends Config (
|
||||
topDefinitions = { (pname,site,here) =>
|
||||
type PF = PartialFunction[Any,Any]
|
||||
def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname)
|
||||
@ -116,14 +107,6 @@ class BaseConfig extends Config (
|
||||
lazy val innerDataBeats = (8 * site(CacheBlockBytes)) / innerDataBits
|
||||
pname match {
|
||||
//Memory Parameters
|
||||
case PAddrBits => 32
|
||||
case PgIdxBits => 12
|
||||
case PgLevels => if (site(XLen) == 64) 3 /* Sv39 */ else 2 /* Sv32 */
|
||||
case PgLevelBits => site(PgIdxBits) - log2Up(site(XLen)/8)
|
||||
case VPNBits => site(PgLevels) * site(PgLevelBits)
|
||||
case PPNBits => site(PAddrBits) - site(PgIdxBits)
|
||||
case VAddrBits => site(VPNBits) + site(PgIdxBits)
|
||||
case ASIdBits => 7
|
||||
case MIFTagBits => Dump("MIF_TAG_BITS", 5)
|
||||
case MIFDataBits => Dump("MIF_DATA_BITS", 64)
|
||||
case MIFAddrBits => Dump("MIF_ADDR_BITS",
|
||||
@ -136,107 +119,9 @@ class BaseConfig extends Config (
|
||||
addrBits = Dump("MEM_ADDR_BITS", site(PAddrBits)),
|
||||
idBits = Dump("MEM_ID_BITS", site(MIFTagBits)))
|
||||
}
|
||||
//Params used by all caches
|
||||
case NSets => findBy(CacheName)
|
||||
case NWays => findBy(CacheName)
|
||||
case RowBits => findBy(CacheName)
|
||||
case NTLBEntries => findBy(CacheName)
|
||||
case CacheIdBits => findBy(CacheName)
|
||||
case SplitMetadata => findBy(CacheName)
|
||||
case "L1I" => {
|
||||
case NSets => Knob("L1I_SETS") //64
|
||||
case NWays => Knob("L1I_WAYS") //4
|
||||
case RowBits => site(TLKey("L1toL2")).dataBitsPerBeat
|
||||
case NTLBEntries => 8
|
||||
case CacheIdBits => 0
|
||||
case SplitMetadata => false
|
||||
}:PF
|
||||
case "L1D" => {
|
||||
case NSets => Knob("L1D_SETS") //64
|
||||
case NWays => Knob("L1D_WAYS") //4
|
||||
case RowBits => site(TLKey("L1toL2")).dataBitsPerBeat
|
||||
case NTLBEntries => 8
|
||||
case CacheIdBits => 0
|
||||
case SplitMetadata => false
|
||||
}:PF
|
||||
case ECCCode => None
|
||||
case Replacer => () => new RandomReplacement(site(NWays))
|
||||
case AmoAluOperandBits => site(XLen)
|
||||
//L1InstCache
|
||||
case BtbKey => BtbParameters()
|
||||
//L1DataCache
|
||||
case WordBits => site(XLen)
|
||||
case StoreDataQueueDepth => 17
|
||||
case ReplayQueueDepth => 16
|
||||
case NMSHRs => Knob("L1D_MSHRS")
|
||||
case LRSCCycles => 32
|
||||
//L2 Memory System Params
|
||||
case NAcquireTransactors => 7
|
||||
case L2StoreDataQueueDepth => 1
|
||||
case L2DirectoryRepresentation => new NullRepresentation(site(NTiles))
|
||||
case BuildL2CoherenceManager => (id: Int, p: Parameters) =>
|
||||
Module(new L2BroadcastHub()(p.alterPartial({
|
||||
case InnerTLId => "L1toL2"
|
||||
case OuterTLId => "L2toMC" })))
|
||||
case NCachedTileLinkPorts => 1
|
||||
case NUncachedTileLinkPorts => 1
|
||||
//Tile Constants
|
||||
case BuildTiles => {
|
||||
val (rvi, rvu) =
|
||||
if (site(XLen) == 64) ((if (site(UseVM)) rv64i else rv64pi), rv64u)
|
||||
else ((if (site(UseVM)) rv32i else rv32pi), rv32u)
|
||||
TestGeneration.addSuites(rvi.map(_("p")))
|
||||
TestGeneration.addSuites((if(site(UseVM)) List("v") else List()).flatMap(env => rvu.map(_(env))))
|
||||
TestGeneration.addSuite(if (site(UseVM)) benchmarks else emptyBmarks)
|
||||
List.fill(site(NTiles)){ (r: Bool, p: Parameters) =>
|
||||
Module(new RocketTile(resetSignal = r)(p.alterPartial({
|
||||
case TLId => "L1toL2"
|
||||
case NUncachedTileLinkPorts => 1 + site(RoccNMemChannels)
|
||||
})))
|
||||
}
|
||||
}
|
||||
case BuildRoCC => Nil
|
||||
case BuildCoreplex => (p: Parameters) => Module(new DefaultCoreplex(p))
|
||||
case RoccNMemChannels => site(BuildRoCC).map(_.nMemChannels).foldLeft(0)(_ + _)
|
||||
case RoccNPTWPorts => site(BuildRoCC).map(_.nPTWPorts).foldLeft(0)(_ + _)
|
||||
case RoccNCSRs => site(BuildRoCC).map(_.csrs.size).foldLeft(0)(_ + _)
|
||||
//Rocket Core Constants
|
||||
case FetchWidth => if (site(UseCompressed)) 2 else 1
|
||||
case RetireWidth => 1
|
||||
case UseVM => true
|
||||
case UseUser => true
|
||||
case UseDebug => true
|
||||
case AsyncDebugBus => false
|
||||
case NBreakpoints => 1
|
||||
case UsePerfCounters => true
|
||||
case FastLoadWord => true
|
||||
case FastLoadByte => false
|
||||
case MulUnroll => 8
|
||||
case DivEarlyOut => true
|
||||
case XLen => 64
|
||||
case UseFPU => {
|
||||
val env = if(site(UseVM)) List("p","v") else List("p")
|
||||
TestGeneration.addSuite(rv32udBenchmarks)
|
||||
if(site(FDivSqrt)) {
|
||||
TestGeneration.addSuites(env.map(rv64uf))
|
||||
TestGeneration.addSuites(env.map(rv64ud))
|
||||
} else {
|
||||
TestGeneration.addSuites(env.map(rv64ufNoDiv))
|
||||
TestGeneration.addSuites(env.map(rv64udNoDiv))
|
||||
}
|
||||
true
|
||||
}
|
||||
case UseAtomics => {
|
||||
val env = if(site(UseVM)) List("p","v") else List("p")
|
||||
TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64ua else rv32ua))
|
||||
true
|
||||
}
|
||||
case UseCompressed => {
|
||||
val env = if(site(UseVM)) List("p","v") else List("p")
|
||||
TestGeneration.addSuites(env.map(if (site(XLen) == 64) rv64uc else rv32uc))
|
||||
true
|
||||
}
|
||||
case NExtInterrupts => 2
|
||||
case AsyncDebugBus => false
|
||||
case AsyncMMIOChannels => false
|
||||
case ExtraDevices => Nil
|
||||
case ExtraTopPorts => (p: Parameters) => new Bundle
|
||||
@ -248,22 +133,9 @@ class BaseConfig extends Config (
|
||||
case AsyncBusChannels => false
|
||||
case NExtBusAXIChannels => 0
|
||||
case ExportBusPort => site(NExtBusAXIChannels) > 0
|
||||
case PLICKey => PLICConfig(site(NTiles), site(UseVM), site(NExtInterrupts), 0)
|
||||
case DMKey => new DefaultDebugModuleConfig(site(NTiles), site(XLen))
|
||||
case FDivSqrt => true
|
||||
case SFMALatency => 2
|
||||
case DFMALatency => 3
|
||||
case CoreInstBits => if (site(UseCompressed)) 16 else 32
|
||||
case CoreDataBits => site(XLen)
|
||||
case NCustomMRWCSRs => 0
|
||||
case ResetVector => BigInt(0x1000)
|
||||
case MtvecInit => BigInt(0x1010)
|
||||
case MtvecWritable => true
|
||||
//Uncore Paramters
|
||||
case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock
|
||||
case LNEndpoints => site(TLKey(site(TLId))).nManagers + site(TLKey(site(TLId))).nClients
|
||||
case LNHeaderBits => log2Ceil(site(TLKey(site(TLId))).nManagers) +
|
||||
log2Up(site(TLKey(site(TLId))).nClients)
|
||||
case ConnectExtraPorts =>
|
||||
(out: Bundle, in: Bundle, p: Parameters) => out <> in
|
||||
|
||||
case HastiId => "Ext"
|
||||
case HastiKey("TL") =>
|
||||
HastiParameters(
|
||||
@ -273,232 +145,21 @@ class BaseConfig extends Config (
|
||||
HastiParameters(
|
||||
addrBits = site(PAddrBits),
|
||||
dataBits = site(XLen))
|
||||
case TLKey("L1toL2") => {
|
||||
val useMEI = site(NTiles) <= 1 && site(NCachedTileLinkPorts) <= 1
|
||||
TileLinkParameters(
|
||||
coherencePolicy = (
|
||||
if (useMEI) new MEICoherence(site(L2DirectoryRepresentation))
|
||||
else new MESICoherence(site(L2DirectoryRepresentation))),
|
||||
nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1 /* MMIO */,
|
||||
nCachingClients = site(NCachedTileLinkPorts),
|
||||
nCachelessClients = site(NExtBusAXIChannels) + site(NUncachedTileLinkPorts),
|
||||
maxClientXacts = max_int(
|
||||
// L1 cache
|
||||
site(NMSHRs) + 1 /* IOMSHR */,
|
||||
// RoCC
|
||||
if (site(BuildRoCC).isEmpty) 1 else site(RoccMaxTaggedMemXacts)),
|
||||
maxClientsPerPort = if (site(BuildRoCC).isEmpty) 1 else 2,
|
||||
maxManagerXacts = site(NAcquireTransactors) + 2,
|
||||
dataBeats = innerDataBeats,
|
||||
dataBits = site(CacheBlockBytes)*8)
|
||||
}
|
||||
case TLKey("L2toMC") =>
|
||||
TileLinkParameters(
|
||||
coherencePolicy = new MEICoherence(
|
||||
new NullRepresentation(site(NBanksPerMemoryChannel))),
|
||||
nManagers = 1,
|
||||
nCachingClients = site(NBanksPerMemoryChannel),
|
||||
nCachelessClients = 0,
|
||||
maxClientXacts = 1,
|
||||
maxClientsPerPort = site(NAcquireTransactors) + 2,
|
||||
maxManagerXacts = 1,
|
||||
dataBeats = innerDataBeats,
|
||||
dataBits = site(CacheBlockBytes)*8)
|
||||
case TLKey("Outermost") => site(TLKey("L2toMC")).copy(
|
||||
maxClientXacts = site(NAcquireTransactors) + 2,
|
||||
maxClientsPerPort = site(NBanksPerMemoryChannel),
|
||||
dataBeats = site(MIFDataBeats))
|
||||
case TLKey("L2toMMIO") => {
|
||||
TileLinkParameters(
|
||||
coherencePolicy = new MICoherence(
|
||||
new NullRepresentation(site(NBanksPerMemoryChannel))),
|
||||
nManagers = globalAddrMap.subMap("io").numSlaves,
|
||||
nCachingClients = 0,
|
||||
nCachelessClients = 1,
|
||||
maxClientXacts = 4,
|
||||
maxClientsPerPort = 1,
|
||||
maxManagerXacts = 1,
|
||||
dataBeats = innerDataBeats,
|
||||
dataBits = site(CacheBlockBytes) * 8)
|
||||
}
|
||||
case BootROMFile => "./bootrom/bootrom.img"
|
||||
case TLKey("MMIO_Outermost") => site(TLKey("L2toMMIO")).copy(dataBeats = site(MIFDataBeats))
|
||||
case NTiles => Knob("NTILES")
|
||||
case AsyncMemChannels => false
|
||||
case NMemoryChannels => Dump("N_MEM_CHANNELS", 1)
|
||||
case TMemoryChannels => BusType.AXI
|
||||
case NBanksPerMemoryChannel => Knob("NBANKS_PER_MEM_CHANNEL")
|
||||
case NOutstandingMemReqsPerChannel => site(NBanksPerMemoryChannel)*(site(NAcquireTransactors)+2)
|
||||
case BankIdLSB => 0
|
||||
case CacheBlockBytes => Dump("CACHE_BLOCK_BYTES", 64)
|
||||
case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes))
|
||||
case ConfigString => makeConfigString()
|
||||
case GlobalAddrMap => globalAddrMap
|
||||
case EnableL2Logging => false
|
||||
case ExportGroundTestStatus => false
|
||||
case RegressionTestNames => 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")
|
||||
case _ => throw new CDEMatchError
|
||||
}},
|
||||
knobValues = {
|
||||
case "NTILES" => 1
|
||||
case "NBANKS_PER_MEM_CHANNEL" => 1
|
||||
case "L1D_MSHRS" => 2
|
||||
case "L1D_SETS" => 64
|
||||
case "L1D_WAYS" => 4
|
||||
case "L1I_SETS" => 64
|
||||
case "L1I_WAYS" => 4
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
}})
|
||||
|
||||
class BaseConfig extends Config(new BaseCoreplexConfig ++ new BasePlatformConfig)
|
||||
class DefaultConfig extends Config(new WithBlockingL1 ++ new BaseConfig)
|
||||
|
||||
class WithNCores(n: Int) extends Config(
|
||||
knobValues = { case"NTILES" => n; case _ => throw new CDEMatchError })
|
||||
|
||||
class WithNBanksPerMemChannel(n: Int) extends Config(
|
||||
knobValues = {
|
||||
case "NBANKS_PER_MEM_CHANNEL" => n;
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithNMemoryChannels(n: Int) extends Config(
|
||||
(pname,site,here) => pname match {
|
||||
case NMemoryChannels => Dump("N_MEM_CHANNELS", n)
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
|
||||
class WithL2Cache extends Config(
|
||||
(pname,site,here) => pname match {
|
||||
case "L2_CAPACITY_IN_KB" => Knob("L2_CAPACITY_IN_KB")
|
||||
case "L2Bank" => {
|
||||
case NSets => (((here[Int]("L2_CAPACITY_IN_KB")*1024) /
|
||||
site(CacheBlockBytes)) /
|
||||
(site(NBanksPerMemoryChannel)*site(NMemoryChannels))) /
|
||||
site(NWays)
|
||||
case NWays => Knob("L2_WAYS")
|
||||
case RowBits => site(TLKey(site(TLId))).dataBitsPerBeat
|
||||
case CacheIdBits => log2Ceil(site(NMemoryChannels) * site(NBanksPerMemoryChannel))
|
||||
case SplitMetadata => Knob("L2_SPLIT_METADATA")
|
||||
}: PartialFunction[Any,Any]
|
||||
case NAcquireTransactors => 2
|
||||
case NSecondaryMisses => 4
|
||||
case L2DirectoryRepresentation => new FullRepresentation(site(NTiles))
|
||||
case BuildL2CoherenceManager => (id: Int, p: Parameters) =>
|
||||
Module(new L2HellaCacheBank()(p.alterPartial({
|
||||
case CacheId => id
|
||||
case CacheName => "L2Bank"
|
||||
case InnerTLId => "L1toL2"
|
||||
case OuterTLId => "L2toMC"})))
|
||||
case L2Replacer => () => new SeqRandom(site(NWays))
|
||||
case _ => throw new CDEMatchError
|
||||
},
|
||||
knobValues = { case "L2_WAYS" => 8; case "L2_CAPACITY_IN_KB" => 2048; case "L2_SPLIT_METADATA" => false; case _ => throw new CDEMatchError }
|
||||
)
|
||||
|
||||
class WithBufferlessBroadcastHub extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case BuildL2CoherenceManager => (id: Int, p: Parameters) =>
|
||||
Module(new BufferlessBroadcastHub()(p.alterPartial({
|
||||
case InnerTLId => "L1toL2"
|
||||
case OuterTLId => "L2toMC" })))
|
||||
})
|
||||
|
||||
/**
|
||||
* WARNING!!! IGNORE AT YOUR OWN PERIL!!!
|
||||
*
|
||||
* There is a very restrictive set of conditions under which the stateless
|
||||
* bridge will function properly. There can only be a single tile. This tile
|
||||
* MUST use the blocking data cache (L1D_MSHRS == 0) and MUST NOT have an
|
||||
* uncached channel capable of writes (i.e. a RoCC accelerator).
|
||||
*
|
||||
* This is because the stateless bridge CANNOT generate probes, so if your
|
||||
* system depends on coherence between channels in any way,
|
||||
* DO NOT use this configuration.
|
||||
*/
|
||||
class WithStatelessBridge extends Config (
|
||||
topDefinitions = (pname, site, here) => pname match {
|
||||
case BuildL2CoherenceManager => (id: Int, p: Parameters) =>
|
||||
Module(new ManagerToClientStatelessBridge()(p.alterPartial({
|
||||
case InnerTLId => "L1toL2"
|
||||
case OuterTLId => "L2toMC" })))
|
||||
},
|
||||
knobValues = {
|
||||
case "L1D_MSHRS" => 0
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
|
||||
class WithPLRU extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case L2Replacer => () => new SeqPLRU(site(NSets), site(NWays))
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithL2Capacity(size_kb: Int) extends Config(
|
||||
knobValues = {
|
||||
case "L2_CAPACITY_IN_KB" => size_kb
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithNL2Ways(n: Int) extends Config(
|
||||
knobValues = {
|
||||
case "L2_WAYS" => n
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class DefaultL2Config extends Config(new WithL2Cache ++ new BaseConfig)
|
||||
class DefaultL2FPGAConfig extends Config(
|
||||
new WithL2Capacity(64) ++ new WithL2Cache ++ new DefaultFPGAConfig)
|
||||
|
||||
class DefaultBufferlessConfig extends Config(
|
||||
new WithBufferlessBroadcastHub ++ new BaseConfig)
|
||||
|
||||
class PLRUL2Config extends Config(new WithPLRU ++ new DefaultL2Config)
|
||||
|
||||
class WithRV32 extends Config(
|
||||
(pname,site,here) => pname match {
|
||||
case XLen => 32
|
||||
case UseVM => false
|
||||
case UseUser => false
|
||||
case UseAtomics => false
|
||||
case UseFPU => false
|
||||
case RegressionTestNames => LinkedHashSet(
|
||||
"rv32mi-p-ma_addr",
|
||||
"rv32mi-p-csr",
|
||||
"rv32ui-p-sh",
|
||||
"rv32ui-p-lh",
|
||||
"rv32mi-p-sbreak",
|
||||
"rv32ui-p-sll")
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
|
||||
class FPGAConfig extends Config (
|
||||
(pname,site,here) => pname match {
|
||||
case NAcquireTransactors => 4
|
||||
@ -507,9 +168,15 @@ class FPGAConfig extends Config (
|
||||
}
|
||||
)
|
||||
|
||||
class WithBlockingL1 extends Config (
|
||||
knobValues = {
|
||||
case "L1D_MSHRS" => 0
|
||||
class DefaultFPGAConfig extends Config(new FPGAConfig ++ new BaseConfig)
|
||||
class DefaultL2FPGAConfig extends Config(
|
||||
new WithL2Capacity(64) ++ new WithL2Cache ++ new DefaultFPGAConfig)
|
||||
|
||||
class PLRUL2Config extends Config(new WithPLRU ++ new DefaultL2Config)
|
||||
|
||||
class WithNMemoryChannels(n: Int) extends Config(
|
||||
(pname,site,here) => pname match {
|
||||
case NMemoryChannels => Dump("N_MEM_CHANNELS", n)
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
@ -526,30 +193,6 @@ class WithTL extends Config(
|
||||
case NExtMMIOTLChannels => 1
|
||||
})
|
||||
|
||||
class DefaultFPGAConfig extends Config(new FPGAConfig ++ new BaseConfig)
|
||||
|
||||
class WithSmallCores extends Config (
|
||||
topDefinitions = { (pname,site,here) => pname match {
|
||||
case UseFPU => false
|
||||
case MulUnroll => 1
|
||||
case DivEarlyOut => false
|
||||
case NTLBEntries => 4
|
||||
case BtbKey => BtbParameters(nEntries = 0)
|
||||
case StoreDataQueueDepth => 2
|
||||
case ReplayQueueDepth => 2
|
||||
case NAcquireTransactors => 2
|
||||
case _ => throw new CDEMatchError
|
||||
}},
|
||||
knobValues = {
|
||||
case "L1D_SETS" => 64
|
||||
case "L1D_WAYS" => 1
|
||||
case "L1I_SETS" => 64
|
||||
case "L1I_WAYS" => 1
|
||||
case "L1D_MSHRS" => 0
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
)
|
||||
|
||||
class DefaultFPGASmallConfig extends Config(new WithSmallCores ++ new DefaultFPGAConfig)
|
||||
class DefaultSmallConfig extends Config(new WithSmallCores ++ new BaseConfig)
|
||||
class DefaultRV32Config extends Config(new WithRV32 ++ new DefaultSmallConfig)
|
||||
@ -570,24 +213,6 @@ class DualChannelDualBankL2Config extends Config(
|
||||
new WithNMemoryChannels(2) ++ new WithNBanksPerMemChannel(2) ++
|
||||
new WithL2Cache ++ new BaseConfig)
|
||||
|
||||
class WithRoccExample extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case BuildRoCC => Seq(
|
||||
RoccParameters(
|
||||
opcodes = OpcodeSet.custom0,
|
||||
generator = (p: Parameters) => Module(new AccumulatorExample()(p))),
|
||||
RoccParameters(
|
||||
opcodes = OpcodeSet.custom1,
|
||||
generator = (p: Parameters) => Module(new TranslatorExample()(p)),
|
||||
nPTWPorts = 1),
|
||||
RoccParameters(
|
||||
opcodes = OpcodeSet.custom2,
|
||||
generator = (p: Parameters) => Module(new CharacterCountExample()(p))))
|
||||
|
||||
case RoccMaxTaggedMemXacts => 1
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class RoccExampleConfig extends Config(new WithRoccExample ++ new BaseConfig)
|
||||
|
||||
class WithMIFDataBits(n: Int) extends Config(
|
||||
@ -611,7 +236,6 @@ class OctoChannelBenchmarkConfig extends Config(new WithNMemoryChannels(8) ++ ne
|
||||
|
||||
class EightChannelConfig extends Config(new WithNMemoryChannels(8) ++ new BaseConfig)
|
||||
|
||||
class WithSplitL2Metadata extends Config(knobValues = { case "L2_SPLIT_METADATA" => true; case _ => throw new CDEMatchError })
|
||||
class SplitL2MetadataTestConfig extends Config(new WithSplitL2Metadata ++ new DefaultL2Config)
|
||||
|
||||
class DualCoreConfig extends Config(
|
||||
|
@ -1,276 +0,0 @@
|
||||
package rocketchip
|
||||
|
||||
import Chisel._
|
||||
import cde.{Parameters, Field}
|
||||
import junctions._
|
||||
import uncore.tilelink._
|
||||
import uncore.coherence._
|
||||
import uncore.agents._
|
||||
import uncore.devices._
|
||||
import uncore.util._
|
||||
import uncore.converters._
|
||||
import rocket._
|
||||
import rocket.Util._
|
||||
import java.nio.{ByteBuffer,ByteOrder}
|
||||
import java.nio.file.{Files, Paths}
|
||||
|
||||
/** Number of memory channels */
|
||||
case object NMemoryChannels extends Field[Int]
|
||||
/** Number of banks per memory channel */
|
||||
case object NBanksPerMemoryChannel extends Field[Int]
|
||||
/** Least significant bit of address used for bank partitioning */
|
||||
case object BankIdLSB extends Field[Int]
|
||||
/** Function for building some kind of coherence manager agent */
|
||||
case object BuildL2CoherenceManager extends Field[(Int, Parameters) => CoherenceAgent]
|
||||
/** Function for building some kind of tile connected to a reset signal */
|
||||
case object BuildTiles extends Field[Seq[(Bool, Parameters) => Tile]]
|
||||
/** A string describing on-chip devices, readable by target software */
|
||||
case object ConfigString extends Field[Array[Byte]]
|
||||
/** Number of external interrupt sources */
|
||||
case object NExtInterrupts extends Field[Int]
|
||||
/** Interrupt controller configuration */
|
||||
case object PLICKey extends Field[PLICConfig]
|
||||
/** Number of clock cycles per RTC tick */
|
||||
case object RTCPeriod extends Field[Int]
|
||||
/** The file to read the BootROM contents from */
|
||||
case object BootROMFile extends Field[String]
|
||||
/** Export an external MMIO slave port */
|
||||
case object ExportMMIOPort extends Field[Boolean]
|
||||
/** Expose an additional bus master port */
|
||||
case object ExportBusPort extends Field[Boolean]
|
||||
/** Function for building Coreplex */
|
||||
case object BuildCoreplex extends Field[Parameters => Coreplex]
|
||||
|
||||
trait HasCoreplexParameters {
|
||||
implicit val p: Parameters
|
||||
lazy val nTiles = p(NTiles)
|
||||
lazy val nCachedTilePorts = p(NCachedTileLinkPorts)
|
||||
lazy val nUncachedTilePorts = p(NUncachedTileLinkPorts)
|
||||
lazy val nMemChannels = p(NMemoryChannels)
|
||||
lazy val nBanksPerMemChannel = p(NBanksPerMemoryChannel)
|
||||
lazy val nBanks = nMemChannels*nBanksPerMemChannel
|
||||
lazy val lsb = p(BankIdLSB)
|
||||
lazy val outermostParams = p.alterPartial({ case TLId => "Outermost" })
|
||||
lazy val outermostMMIOParams = p.alterPartial({ case TLId => "MMIO_Outermost" })
|
||||
lazy val exportBus = p(ExportBusPort)
|
||||
lazy val exportMMIO = p(ExportMMIOPort)
|
||||
}
|
||||
|
||||
/** Wrapper around everything that isn't a Tile.
|
||||
*
|
||||
* Usually this is clocked and/or place-and-routed separately from the Tiles.
|
||||
*/
|
||||
class Uncore(implicit val p: Parameters) extends Module
|
||||
with HasCoreplexParameters {
|
||||
|
||||
val io = new Bundle {
|
||||
val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams))
|
||||
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
||||
val tiles_uncached = Vec(nUncachedTilePorts, new ClientUncachedTileLinkIO).flip
|
||||
val prci = Vec(nTiles, new PRCITileIO).asOutput
|
||||
val bus = if (exportBus) Some(new ClientUncachedTileLinkIO().flip) else None
|
||||
val mmio = if (exportMMIO) Some(new ClientUncachedTileLinkIO()(outermostMMIOParams)) else None
|
||||
val interrupts = Vec(p(NExtInterrupts), Bool()).asInput
|
||||
val debug = new DebugBusIO()(p).flip
|
||||
}
|
||||
|
||||
val outmemsys = if (nCachedTilePorts + nUncachedTilePorts > 0)
|
||||
Module(new DefaultOuterMemorySystem) // NoC, LLC and SerDes
|
||||
else Module(new DummyOuterMemorySystem)
|
||||
outmemsys.io.incoherent foreach (_ := false)
|
||||
outmemsys.io.tiles_uncached <> io.tiles_uncached
|
||||
outmemsys.io.tiles_cached <> io.tiles_cached
|
||||
if (exportBus) { outmemsys.io.bus.get <> io.bus.get }
|
||||
io.mem <> outmemsys.io.mem
|
||||
|
||||
buildMMIONetwork(p.alterPartial({case TLId => "L2toMMIO"}))
|
||||
|
||||
def makeBootROM()(implicit p: Parameters) = {
|
||||
val romdata = Files.readAllBytes(Paths.get(p(BootROMFile)))
|
||||
val rom = ByteBuffer.wrap(romdata)
|
||||
|
||||
rom.order(ByteOrder.LITTLE_ENDIAN)
|
||||
|
||||
// for now, have the reset vector jump straight to memory
|
||||
val resetToMemDist = p(GlobalAddrMap)("mem").start - p(ResetVector)
|
||||
require(resetToMemDist == (resetToMemDist.toInt >> 12 << 12))
|
||||
val configStringAddr = p(ResetVector).toInt + rom.capacity
|
||||
|
||||
require(rom.getInt(12) == 0,
|
||||
"Config string address position should not be occupied by code")
|
||||
rom.putInt(12, configStringAddr)
|
||||
rom.array() ++ p(ConfigString).toSeq
|
||||
}
|
||||
|
||||
def buildMMIONetwork(implicit p: Parameters) = {
|
||||
val ioAddrMap = p(GlobalAddrMap).subMap("io")
|
||||
|
||||
val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, ioAddrMap))
|
||||
mmioNetwork.io.in.head <> outmemsys.io.mmio
|
||||
|
||||
val plic = Module(new PLIC(p(PLICKey)))
|
||||
plic.io.tl <> mmioNetwork.port("int:plic")
|
||||
for (i <- 0 until io.interrupts.size) {
|
||||
val gateway = Module(new LevelGateway)
|
||||
gateway.io.interrupt := io.interrupts(i)
|
||||
plic.io.devices(i) <> gateway.io.plic
|
||||
}
|
||||
|
||||
val debugModule = Module(new DebugModule)
|
||||
debugModule.io.tl <> mmioNetwork.port("int:debug")
|
||||
debugModule.io.db <> io.debug
|
||||
|
||||
val prci = Module(new PRCI)
|
||||
prci.io.tl <> mmioNetwork.port("int:prci")
|
||||
io.prci := prci.io.tiles
|
||||
prci.io.rtcTick := Counter(p(RTCPeriod)).inc() // placeholder for real RTC
|
||||
|
||||
for (i <- 0 until nTiles) {
|
||||
prci.io.interrupts(i).meip := plic.io.harts(plic.cfg.context(i, 'M'))
|
||||
if (p(UseVM))
|
||||
prci.io.interrupts(i).seip := plic.io.harts(plic.cfg.context(i, 'S'))
|
||||
prci.io.interrupts(i).debug := debugModule.io.debugInterrupts(i)
|
||||
|
||||
io.prci(i).reset := reset
|
||||
}
|
||||
|
||||
val bootROM = Module(new ROMSlave(makeBootROM()))
|
||||
bootROM.io <> mmioNetwork.port("int:bootrom")
|
||||
|
||||
io.mmio.map { ext => ext <> mmioNetwork.port("ext") }
|
||||
}
|
||||
}
|
||||
|
||||
abstract class OuterMemorySystem(implicit val p: Parameters)
|
||||
extends Module with HasCoreplexParameters {
|
||||
val io = new Bundle {
|
||||
val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
|
||||
val tiles_uncached = Vec(nUncachedTilePorts, new ClientUncachedTileLinkIO).flip
|
||||
val bus = if (exportBus) Some(new ClientUncachedTileLinkIO().flip) else None
|
||||
val incoherent = Vec(nCachedTilePorts, Bool()).asInput
|
||||
val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams))
|
||||
val mmio = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => "L2toMMIO"}))
|
||||
}
|
||||
}
|
||||
|
||||
/** Use in place of OuterMemorySystem if there are no clients to connect. */
|
||||
class DummyOuterMemorySystem(implicit p: Parameters) extends OuterMemorySystem()(p) {
|
||||
require(nCachedTilePorts + nUncachedTilePorts == 0)
|
||||
require(io.bus.isEmpty)
|
||||
|
||||
io.mem.foreach { tl =>
|
||||
tl.acquire.valid := Bool(false)
|
||||
tl.grant.ready := Bool(false)
|
||||
}
|
||||
|
||||
io.mmio.acquire.valid := Bool(false)
|
||||
io.mmio.grant.ready := Bool(false)
|
||||
}
|
||||
|
||||
/** The whole outer memory hierarchy, including a NoC, some kind of coherence
|
||||
* manager agent, and a converter from TileLink to MemIO.
|
||||
*/
|
||||
class DefaultOuterMemorySystem(implicit p: Parameters) extends OuterMemorySystem()(p) {
|
||||
// Create a simple L1toL2 NoC between the tiles and the banks of outer memory
|
||||
// Cached ports are first in client list, making sharerToClientId just an indentity function
|
||||
// addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
|
||||
def sharerToClientId(sharerId: UInt) = sharerId
|
||||
def addrToBank(addr: UInt): UInt = {
|
||||
val isMemory = p(GlobalAddrMap).isInRegion("mem", addr << log2Up(p(CacheBlockBytes)))
|
||||
Mux(isMemory,
|
||||
if (nBanks > 1) addr(lsb + log2Up(nBanks) - 1, lsb) else UInt(0),
|
||||
UInt(nBanks))
|
||||
}
|
||||
val preBuffering = TileLinkDepths(1,1,2,2,0)
|
||||
val l1tol2net = Module(new PortedTileLinkCrossbar(addrToBank, sharerToClientId, preBuffering))
|
||||
|
||||
// Create point(s) of coherence serialization
|
||||
val managerEndpoints = List.tabulate(nBanks){id => p(BuildL2CoherenceManager)(id, p)}
|
||||
managerEndpoints.foreach { _.incoherent := io.incoherent }
|
||||
|
||||
val mmioManager = Module(new MMIOTileLinkManager()(p.alterPartial({
|
||||
case TLId => "L1toL2"
|
||||
case InnerTLId => "L1toL2"
|
||||
case OuterTLId => "L2toMMIO"
|
||||
})))
|
||||
io.mmio <> mmioManager.io.outer
|
||||
|
||||
// Wire the tiles to the TileLink client ports of the L1toL2 network,
|
||||
// and coherence manager(s) to the other side
|
||||
l1tol2net.io.clients_cached <> io.tiles_cached
|
||||
l1tol2net.io.clients_uncached <> io.tiles_uncached ++ io.bus
|
||||
l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
|
||||
|
||||
// Create a converter between TileLinkIO and MemIO for each channel
|
||||
val outerTLParams = p.alterPartial({ case TLId => "L2toMC" })
|
||||
val backendBuffering = TileLinkDepths(0,0,0,0,0)
|
||||
|
||||
// TODO: the code to print this stuff should live somewhere else
|
||||
println("Generated Address Map")
|
||||
for (entry <- p(GlobalAddrMap).flatten) {
|
||||
val name = entry.name
|
||||
val start = entry.region.start
|
||||
val end = entry.region.start + entry.region.size - 1
|
||||
println(f"\t$name%s $start%x - $end%x")
|
||||
}
|
||||
println("Generated Configuration String")
|
||||
println(new String(p(ConfigString)))
|
||||
|
||||
val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, nMemChannels)(outermostParams))
|
||||
|
||||
for ((bank, icPort) <- managerEndpoints zip mem_ic.io.in) {
|
||||
val unwrap = Module(new ClientTileLinkIOUnwrapper()(outerTLParams))
|
||||
unwrap.io.in <> ClientTileLinkEnqueuer(bank.outerTL, backendBuffering)(outerTLParams)
|
||||
TileLinkWidthAdapter(icPort, unwrap.io.out)
|
||||
}
|
||||
|
||||
io.mem <> mem_ic.io.out
|
||||
}
|
||||
|
||||
class CoreplexIO(implicit val p: Parameters) extends ParameterizedBundle()(p)
|
||||
with HasCoreplexParameters {
|
||||
val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outermostParams))
|
||||
val bus = if (p(ExportBusPort)) Some(new ClientUncachedTileLinkIO().flip) else None
|
||||
val mmio = if(p(ExportMMIOPort)) Some(new ClientUncachedTileLinkIO()(outermostMMIOParams)) else None
|
||||
val interrupts = Vec(p(NExtInterrupts), Bool()).asInput
|
||||
val debug = new DebugBusIO()(p).flip
|
||||
}
|
||||
|
||||
abstract class Coreplex(implicit val p: Parameters) extends Module
|
||||
with HasCoreplexParameters {
|
||||
val io = new CoreplexIO
|
||||
}
|
||||
|
||||
class DefaultCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
|
||||
// Build an Uncore and a set of Tiles
|
||||
val tileResets = Wire(Vec(nTiles, Bool()))
|
||||
val tileList = p(BuildTiles).zip(tileResets).map {
|
||||
case (tile, rst) => tile(rst, p)
|
||||
}
|
||||
val nCachedPorts = tileList.map(tile => tile.io.cached.size).reduce(_ + _)
|
||||
val nUncachedPorts = tileList.map(tile => tile.io.uncached.size).reduce(_ + _)
|
||||
|
||||
val innerTLParams = p.alterPartial({
|
||||
case HastiId => "TL"
|
||||
case TLId => "L1toL2"
|
||||
case NCachedTileLinkPorts => nCachedPorts
|
||||
case NUncachedTileLinkPorts => nUncachedPorts
|
||||
})
|
||||
|
||||
val uncore = Module(new Uncore()(innerTLParams))
|
||||
|
||||
(uncore.io.prci, tileResets, tileList).zipped.foreach {
|
||||
case (prci, rst, tile) =>
|
||||
rst := prci.reset
|
||||
tile.io.prci <> prci
|
||||
}
|
||||
|
||||
// Connect the uncore to the tile memory ports, HostIO and MemIO
|
||||
uncore.io.tiles_cached <> tileList.map(_.io.cached).flatten
|
||||
uncore.io.tiles_uncached <> tileList.map(_.io.uncached).flatten
|
||||
uncore.io.interrupts <> io.interrupts
|
||||
uncore.io.debug <> io.debug
|
||||
if (exportBus) { uncore.io.bus.get <> io.bus.get }
|
||||
if (exportMMIO) { io.mmio.get <> uncore.io.mmio.get }
|
||||
io.mem <> uncore.io.mem
|
||||
}
|
@ -1,64 +0,0 @@
|
||||
package rocketchip
|
||||
|
||||
import Chisel._
|
||||
import cde.{Parameters, Field}
|
||||
import groundtest._
|
||||
import uncore.tilelink._
|
||||
import uncore.agents._
|
||||
|
||||
case object ExportGroundTestStatus extends Field[Boolean]
|
||||
|
||||
class DirectGroundTestCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
|
||||
override val io = new CoreplexIO {
|
||||
// Need to export this for FPGA testing, but not for simulator
|
||||
val status = if (p(ExportGroundTestStatus)) Some(new GroundTestStatus) else None
|
||||
}
|
||||
|
||||
// Not using the debug
|
||||
io.debug.req.ready := Bool(false)
|
||||
io.debug.resp.valid := Bool(false)
|
||||
|
||||
require(!exportMMIO)
|
||||
require(!exportBus)
|
||||
require(nMemChannels == 1)
|
||||
require(nTiles == 1)
|
||||
|
||||
val test = p(BuildGroundTest)(outermostParams.alterPartial({
|
||||
case GroundTestId => 0
|
||||
case CacheName => "L1D"
|
||||
}))
|
||||
require(test.io.cache.size == 0)
|
||||
require(test.io.mem.size == nBanksPerMemChannel)
|
||||
require(test.io.ptw.size == 0)
|
||||
|
||||
when (test.io.status.finished) { stop() }
|
||||
|
||||
val mem_ic = Module(new TileLinkMemoryInterconnect(
|
||||
nBanksPerMemChannel, nMemChannels)(outermostParams))
|
||||
|
||||
mem_ic.io.in <> test.io.mem
|
||||
io.mem <> mem_ic.io.out
|
||||
|
||||
io.status.map { status =>
|
||||
val s_running :: s_finished :: s_errored :: s_timeout :: Nil = Enum(Bits(), 4)
|
||||
val state = Reg(init = s_running)
|
||||
val error_code = Reg(status.error.bits)
|
||||
val timeout_code = Reg(status.timeout.bits)
|
||||
when (state === s_running) {
|
||||
when (test.io.status.finished) { state := s_finished }
|
||||
when (test.io.status.error.valid) {
|
||||
state := s_errored
|
||||
error_code := test.io.status.error.bits
|
||||
}
|
||||
when (test.io.status.timeout.valid) {
|
||||
state := s_timeout
|
||||
timeout_code := test.io.status.timeout.bits
|
||||
}
|
||||
}
|
||||
status.finished := (state === s_finished)
|
||||
status.error.valid := (state === s_errored)
|
||||
status.error.bits := error_code
|
||||
status.timeout.valid := (state === s_timeout)
|
||||
status.timeout.bits := timeout_code
|
||||
}
|
||||
}
|
61
src/main/scala/Generator.scala
Normal file
61
src/main/scala/Generator.scala
Normal file
@ -0,0 +1,61 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package rocketchip
|
||||
|
||||
import Chisel._
|
||||
import scala.collection.mutable.{LinkedHashSet,LinkedHashMap}
|
||||
import cde.{Parameters, ParameterDump, Config, Field, CDEMatchError}
|
||||
import coreplex._
|
||||
|
||||
object TestGenerator extends App {
|
||||
val projectName = args(0)
|
||||
val topModuleName = args(1)
|
||||
val configClassName = args(2)
|
||||
|
||||
val aggregateConfigs = configClassName.split('_')
|
||||
|
||||
val finalConfig = aggregateConfigs.foldRight(new Config()) { case (currentConfigName, finalConfig) =>
|
||||
val currentConfig = try {
|
||||
Class.forName(s"$projectName.$currentConfigName").newInstance.asInstanceOf[Config]
|
||||
} catch {
|
||||
case e: java.lang.ClassNotFoundException =>
|
||||
throwException("Unable to find part \"" + currentConfigName +
|
||||
"\" of configClassName \"" + configClassName +
|
||||
"\", did you misspell it?", e)
|
||||
}
|
||||
currentConfig ++ finalConfig
|
||||
}
|
||||
val world = finalConfig.toInstance
|
||||
|
||||
val paramsFromConfig: Parameters = Parameters.root(world)
|
||||
|
||||
val gen = () =>
|
||||
Class.forName(s"$projectName.$topModuleName")
|
||||
.getConstructor(classOf[cde.Parameters])
|
||||
.newInstance(paramsFromConfig)
|
||||
.asInstanceOf[Module]
|
||||
|
||||
chiselMain.run(args.drop(3), gen)
|
||||
//Driver.elaborate(gen, configName = configClassName)
|
||||
|
||||
TestGeneration.addSuite(new RegressionTestSuite(paramsFromConfig(RegressionTestNames)))
|
||||
|
||||
TestGeneration.generateMakefrag(topModuleName, configClassName)
|
||||
TestBenchGeneration.generateVerilogFragment(
|
||||
topModuleName, configClassName, paramsFromConfig)
|
||||
TestBenchGeneration.generateCPPFragment(
|
||||
topModuleName, configClassName, paramsFromConfig)
|
||||
|
||||
val pdFile = TestGeneration.createOutputFile(s"$topModuleName.$configClassName.prm")
|
||||
pdFile.write(ParameterDump.getDump)
|
||||
pdFile.close
|
||||
val v = TestGeneration.createOutputFile(configClassName + ".knb")
|
||||
v.write(world.getKnobs)
|
||||
v.close
|
||||
val d = new java.io.FileOutputStream(Driver.targetDir + "/" + configClassName + ".cfg")
|
||||
d.write(paramsFromConfig(ConfigString))
|
||||
d.close
|
||||
val w = TestGeneration.createOutputFile(configClassName + ".cst")
|
||||
w.write(world.getConstraints)
|
||||
w.close
|
||||
}
|
@ -10,6 +10,7 @@ import uncore.devices._
|
||||
import uncore.util._
|
||||
import uncore.converters._
|
||||
import rocket._
|
||||
import coreplex._
|
||||
|
||||
/** Top-level parameters of RocketChip, values set in e.g. PublicConfigs.scala */
|
||||
|
||||
@ -24,8 +25,6 @@ object BusType {
|
||||
|
||||
/** Memory channel controls */
|
||||
case object TMemoryChannels extends Field[BusType.EnumVal]
|
||||
/** Number of outstanding memory requests */
|
||||
case object NOutstandingMemReqsPerChannel extends Field[Int]
|
||||
/** External MMIO controls */
|
||||
case object NExtMMIOAXIChannels extends Field[Int]
|
||||
case object NExtMMIOAHBChannels extends Field[Int]
|
||||
@ -37,9 +36,12 @@ case object AsyncBusChannels extends Field[Boolean]
|
||||
case object AsyncDebugBus extends Field[Boolean]
|
||||
case object AsyncMemChannels extends Field[Boolean]
|
||||
case object AsyncMMIOChannels extends Field[Boolean]
|
||||
|
||||
/** External address map settings */
|
||||
case object ExtMMIOPorts extends Field[Seq[AddrMapEntry]]
|
||||
/** Function for building Coreplex */
|
||||
case object BuildCoreplex extends Field[Parameters => Coreplex]
|
||||
/** Function for connecting coreplex extra ports to top-level extra ports */
|
||||
case object ConnectExtraPorts extends Field[(Bundle, Bundle, Parameters) => Unit]
|
||||
|
||||
/** Utility trait for quick access to some relevant parameters */
|
||||
trait HasTopLevelParameters {
|
||||
@ -162,6 +164,7 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
|
||||
else io.bus_axi)
|
||||
|
||||
io.extra <> periphery.io.extra
|
||||
p(ConnectExtraPorts)(io.extra, coreplex.io.extra, p)
|
||||
}
|
||||
|
||||
class Periphery(implicit val p: Parameters) extends Module
|
||||
|
@ -5,6 +5,7 @@ package rocketchip
|
||||
import Chisel._
|
||||
import cde.Parameters
|
||||
import uncore.devices.{DbBusConsts, DMKey}
|
||||
import coreplex._
|
||||
|
||||
object TestBenchGeneration {
|
||||
def generateVerilogFragment(
|
||||
|
@ -13,159 +13,9 @@ import junctions.unittests._
|
||||
import scala.collection.mutable.LinkedHashSet
|
||||
import cde.{Parameters, Config, Dump, Knob, CDEMatchError}
|
||||
import scala.math.max
|
||||
import coreplex._
|
||||
import ConfigUtils._
|
||||
|
||||
class WithGroundTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case TLKey("L1toL2") => {
|
||||
val useMEI = site(NTiles) <= 1 && site(NCachedTileLinkPorts) <= 1
|
||||
TileLinkParameters(
|
||||
coherencePolicy = (
|
||||
if (useMEI) new MEICoherence(site(L2DirectoryRepresentation))
|
||||
else new MESICoherence(site(L2DirectoryRepresentation))),
|
||||
nManagers = site(NBanksPerMemoryChannel)*site(NMemoryChannels) + 1,
|
||||
nCachingClients = site(NCachedTileLinkPorts),
|
||||
nCachelessClients = site(NUncachedTileLinkPorts),
|
||||
maxClientXacts = ((site(NMSHRs) + 1) +:
|
||||
site(GroundTestKey).map(_.maxXacts))
|
||||
.reduce(max(_, _)),
|
||||
maxClientsPerPort = 1,
|
||||
maxManagerXacts = site(NAcquireTransactors) + 2,
|
||||
dataBeats = 8,
|
||||
dataBits = site(CacheBlockBytes)*8)
|
||||
}
|
||||
case BuildTiles => {
|
||||
val groundtest = if (site(XLen) == 64)
|
||||
DefaultTestSuites.groundtest64
|
||||
else
|
||||
DefaultTestSuites.groundtest32
|
||||
TestGeneration.addSuite(groundtest("p"))
|
||||
TestGeneration.addSuite(DefaultTestSuites.emptyBmarks)
|
||||
(0 until site(NTiles)).map { i =>
|
||||
val tileSettings = site(GroundTestKey)(i)
|
||||
(r: Bool, p: Parameters) => {
|
||||
Module(new GroundTestTile(resetSignal = r)(p.alterPartial({
|
||||
case TLId => "L1toL2"
|
||||
case GroundTestId => i
|
||||
case NCachedTileLinkPorts => if(tileSettings.cached > 0) 1 else 0
|
||||
case NUncachedTileLinkPorts => tileSettings.uncached
|
||||
case RoccNCSRs => tileSettings.csrs
|
||||
})))
|
||||
}
|
||||
}
|
||||
}
|
||||
case UseFPU => false
|
||||
case UseAtomics => false
|
||||
case UseCompressed => false
|
||||
case RegressionTestNames => LinkedHashSet("rv64ui-p-simple")
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithComparator extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(uncached = site(ComparatorKey).targets.size)
|
||||
}
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new ComparatorCore()(p))
|
||||
case ComparatorKey => ComparatorParameters(
|
||||
targets = Seq("mem", "io:ext:testram").map(name =>
|
||||
site(GlobalAddrMap)(name).start.longValue),
|
||||
width = 8,
|
||||
operations = 1000,
|
||||
atomics = site(UseAtomics),
|
||||
prefetches = site("COMPARATOR_PREFETCHES"))
|
||||
case UseFPU => false
|
||||
case UseAtomics => false
|
||||
case "COMPARATOR_PREFETCHES" => false
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithAtomics extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case UseAtomics => true
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithPrefetches extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case "COMPARATOR_PREFETCHES" => true
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithMemtest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(1, 1)
|
||||
}
|
||||
case GeneratorKey => GeneratorParameters(
|
||||
maxRequests = 128,
|
||||
startAddress = site(GlobalAddrMap)("mem").start)
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new GeneratorTest()(p))
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithNGenerators(nUncached: Int, nCached: Int) extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(nUncached, nCached)
|
||||
}
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithCacheFillTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(uncached = 1)
|
||||
}
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new CacheFillTest()(p))
|
||||
case _ => throw new CDEMatchError
|
||||
},
|
||||
knobValues = {
|
||||
case "L2_WAYS" => 4
|
||||
case "L2_CAPACITY_IN_KB" => 4
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithBroadcastRegressionTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(1, 1, maxXacts = 3)
|
||||
}
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new RegressionTest()(p))
|
||||
case GroundTestRegressions =>
|
||||
(p: Parameters) => RegressionTests.broadcastRegressions(p)
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithCacheRegressionTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(1, 1, maxXacts = 5)
|
||||
}
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new RegressionTest()(p))
|
||||
case GroundTestRegressions =>
|
||||
(p: Parameters) => RegressionTests.cacheRegressions(p)
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithNastiConverterTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(uncached = 1)
|
||||
}
|
||||
case GeneratorKey => GeneratorParameters(
|
||||
maxRequests = 128,
|
||||
startAddress = site(GlobalAddrMap)("mem").start)
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new NastiConverterTest()(p))
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithUnitTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case BuildCoreplex => {
|
||||
@ -187,34 +37,6 @@ class WithUnitTest extends Config(
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithTraceGen extends Config(
|
||||
topDefinitions = (pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(uncached = 1, cached = 1)
|
||||
}
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new GroundTestTraceGenerator()(p))
|
||||
case GeneratorKey => GeneratorParameters(
|
||||
maxRequests = 256,
|
||||
startAddress = 0)
|
||||
case AddressBag => {
|
||||
val nSets = 32 // L2 NSets
|
||||
val nWays = 1
|
||||
val blockOffset = site(CacheBlockOffsetBits)
|
||||
val baseAddr = site(GlobalAddrMap)("mem").start
|
||||
val nBeats = site(MIFDataBeats)
|
||||
List.tabulate(4 * nWays) { i =>
|
||||
Seq.tabulate(nBeats) { j => (j * 8) + ((i * nSets) << blockOffset) }
|
||||
}.flatten.map(addr => baseAddr + BigInt(addr))
|
||||
}
|
||||
case UseAtomics => true
|
||||
case _ => throw new CDEMatchError
|
||||
},
|
||||
knobValues = {
|
||||
case "L1D_SETS" => 16
|
||||
case "L1D_WAYS" => 1
|
||||
})
|
||||
|
||||
class GroundTestConfig extends Config(new WithGroundTest ++ new BaseConfig)
|
||||
|
||||
class ComparatorConfig extends Config(
|
||||
@ -276,71 +98,25 @@ class MIF32BitComparatorConfig extends Config(
|
||||
class MIF32BitMemtestConfig extends Config(
|
||||
new WithMIFDataBits(32) ++ new MemtestConfig)
|
||||
|
||||
class WithPCIeMockupTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case NTiles => 2
|
||||
case GroundTestKey => Seq(
|
||||
GroundTestTileSettings(1, 1),
|
||||
GroundTestTileSettings(1))
|
||||
case GeneratorKey => GeneratorParameters(
|
||||
maxRequests = 128,
|
||||
startAddress = site(GlobalAddrMap)("mem").start)
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => {
|
||||
val id = p(GroundTestId)
|
||||
if (id == 0) Module(new GeneratorTest()(p))
|
||||
else Module(new NastiConverterTest()(p))
|
||||
}
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class PCIeMockupTestConfig extends Config(
|
||||
new WithPCIeMockupTest ++ new GroundTestConfig)
|
||||
|
||||
class WithDirectGroundTest extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case ExportGroundTestStatus => true
|
||||
case BuildCoreplex => (p: Parameters) => Module(new DirectGroundTestCoreplex(p))
|
||||
case ExtraCoreplexPorts => (p: Parameters) =>
|
||||
if (p(ExportGroundTestStatus)) new GroundTestStatus else new Bundle
|
||||
case ExtraTopPorts => (p: Parameters) =>
|
||||
if (p(ExportGroundTestStatus)) new GroundTestStatus else new Bundle
|
||||
case TLKey("Outermost") => site(TLKey("L2toMC")).copy(
|
||||
maxClientXacts = site(GroundTestKey)(0).maxXacts,
|
||||
maxClientsPerPort = site(NBanksPerMemoryChannel),
|
||||
dataBeats = site(MIFDataBeats))
|
||||
case MIFTagBits => Dump("MIF_TAG_BITS", 2)
|
||||
case NBanksPerMemoryChannel => site(GroundTestKey)(0).uncached
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class WithDirectMemtest extends Config(
|
||||
(pname, site, here) => {
|
||||
val nGens = 8
|
||||
pname match {
|
||||
case GroundTestKey => Seq(GroundTestTileSettings(uncached = nGens))
|
||||
case GeneratorKey => GeneratorParameters(
|
||||
maxRequests = 1024,
|
||||
startAddress = 0)
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new GeneratorTest()(p))
|
||||
case _ => throw new CDEMatchError
|
||||
}
|
||||
})
|
||||
|
||||
class WithDirectComparator extends Config(
|
||||
(pname, site, here) => pname match {
|
||||
case GroundTestKey => Seq.fill(site(NTiles)) {
|
||||
GroundTestTileSettings(uncached = site(ComparatorKey).targets.size)
|
||||
}
|
||||
case BuildGroundTest =>
|
||||
(p: Parameters) => Module(new ComparatorCore()(p))
|
||||
case ComparatorKey => ComparatorParameters(
|
||||
targets = Seq(0L, 0x100L),
|
||||
width = 8,
|
||||
operations = 1000,
|
||||
atomics = site(UseAtomics),
|
||||
prefetches = site("COMPARATOR_PREFETCHES"))
|
||||
case UseFPU => false
|
||||
case UseAtomics => false
|
||||
case "COMPARATOR_PREFETCHES" => false
|
||||
case _ => throw new CDEMatchError
|
||||
})
|
||||
|
||||
class DirectGroundTestConfig extends Config(
|
||||
new WithDirectGroundTest ++ new GroundTestConfig)
|
||||
class DirectMemtestConfig extends Config(
|
||||
|
@ -1,239 +0,0 @@
|
||||
// See LICENSE for license details.
|
||||
|
||||
package rocketchip
|
||||
|
||||
import Chisel._
|
||||
import scala.collection.mutable.{LinkedHashSet,LinkedHashMap}
|
||||
import cde.{Parameters, ParameterDump, Config, Field, CDEMatchError}
|
||||
|
||||
case object RegressionTestNames extends Field[LinkedHashSet[String]]
|
||||
|
||||
abstract class RocketTestSuite {
|
||||
val dir: String
|
||||
val makeTargetName: String
|
||||
val names: LinkedHashSet[String]
|
||||
val envName: String
|
||||
def postScript = s"""
|
||||
|
||||
$$(addprefix $$(output_dir)/, $$(addsuffix .hex, $$($makeTargetName))): $$(output_dir)/%.hex: $dir/%.hex
|
||||
\tmkdir -p $$(output_dir)
|
||||
\tln -fs $$< $$@
|
||||
|
||||
$$(addprefix $$(output_dir)/, $$($makeTargetName)): $$(output_dir)/%: $dir/%
|
||||
\tmkdir -p $$(output_dir)
|
||||
\tln -fs $$< $$@
|
||||
|
||||
run-$makeTargetName: $$(addprefix $$(output_dir)/, $$(addsuffix .out, $$($makeTargetName)))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$^ /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
|
||||
run-$makeTargetName-debug: $$(addprefix $$(output_dir)/, $$(addsuffix .vpd, $$($makeTargetName)))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$(patsubst %.vpd,%.out,$$^) /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
"""
|
||||
}
|
||||
|
||||
class AssemblyTestSuite(prefix: String, val names: LinkedHashSet[String])(val envName: String) extends RocketTestSuite {
|
||||
val dir = "$(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa"
|
||||
val makeTargetName = prefix + "-" + envName + "-asm-tests"
|
||||
override def toString = s"$makeTargetName = \\\n" + names.map(n => s"\t$prefix-$envName-$n").mkString(" \\\n") + postScript
|
||||
}
|
||||
|
||||
class BenchmarkTestSuite(makePrefix: String, val dir: String, val names: LinkedHashSet[String]) extends RocketTestSuite {
|
||||
val envName = ""
|
||||
val makeTargetName = makePrefix + "-bmark-tests"
|
||||
override def toString = s"$makeTargetName = \\\n" + names.map(n => s"\t$n.riscv").mkString(" \\\n") + postScript
|
||||
}
|
||||
|
||||
class RegressionTestSuite(val names: LinkedHashSet[String]) extends RocketTestSuite {
|
||||
val envName = ""
|
||||
val dir = "$(RISCV)/riscv64-unknown-elf/share/riscv-tests/isa"
|
||||
val makeTargetName = "regression-tests"
|
||||
override def toString = s"$makeTargetName = \\\n" + names.mkString(" \\\n")
|
||||
}
|
||||
|
||||
object TestGeneration {
|
||||
import scala.collection.mutable.HashMap
|
||||
val asmSuites = new LinkedHashMap[String,AssemblyTestSuite]()
|
||||
val bmarkSuites = new LinkedHashMap[String,BenchmarkTestSuite]()
|
||||
val regressionSuites = new LinkedHashMap[String,RegressionTestSuite]()
|
||||
|
||||
def addSuite(s: RocketTestSuite) {
|
||||
s match {
|
||||
case a: AssemblyTestSuite => asmSuites += (a.makeTargetName -> a)
|
||||
case b: BenchmarkTestSuite => bmarkSuites += (b.makeTargetName -> b)
|
||||
case r: RegressionTestSuite => regressionSuites += (r.makeTargetName -> r)
|
||||
}
|
||||
}
|
||||
|
||||
def addSuites(s: Seq[RocketTestSuite]) { s.foreach(addSuite) }
|
||||
|
||||
def generateMakefrag(topModuleName: String, configClassName: String) {
|
||||
def gen(kind: String, s: Seq[RocketTestSuite]) = {
|
||||
if(s.length > 0) {
|
||||
val envs = s.groupBy(_.envName)
|
||||
val targets = s.map(t => s"$$(${t.makeTargetName})").mkString(" ")
|
||||
s.map(_.toString).mkString("\n") +
|
||||
envs.filterKeys(_ != "").map( {
|
||||
case (env,envsuites) => {
|
||||
val suites = envsuites.map(t => s"$$(${t.makeTargetName})").mkString(" ")
|
||||
s"""
|
||||
run-$kind-$env-tests: $$(addprefix $$(output_dir)/, $$(addsuffix .out, $suites))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$^ /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
run-$kind-$env-tests-debug: $$(addprefix $$(output_dir)/, $$(addsuffix .vpd, $suites))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$(patsubst %.vpd,%.out,$$^) /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
run-$kind-$env-tests-fast: $$(addprefix $$(output_dir)/, $$(addsuffix .run, $suites))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$^ /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
"""} } ).mkString("\n") + s"""
|
||||
run-$kind-tests: $$(addprefix $$(output_dir)/, $$(addsuffix .out, $targets))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$^ /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
run-$kind-tests-debug: $$(addprefix $$(output_dir)/, $$(addsuffix .vpd, $targets))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$(patsubst %.vpd,%.out,$$^) /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
run-$kind-tests-fast: $$(addprefix $$(output_dir)/, $$(addsuffix .run, $targets))
|
||||
\t@echo; perl -ne 'print " [$$$$1] $$$$ARGV \\t$$$$2\\n" if( /\\*{3}(.{8})\\*{3}(.*)/ || /ASSERTION (FAILED)/i )' $$^ /dev/null | perl -ne 'if(/(.*)/){print "$$$$1\\n\\n"; exit(1) if eof()}'
|
||||
"""
|
||||
} else { "\n" }
|
||||
}
|
||||
|
||||
val f = createOutputFile(s"$topModuleName.$configClassName.d")
|
||||
f.write(
|
||||
List(
|
||||
gen("asm", asmSuites.values.toSeq),
|
||||
gen("bmark", bmarkSuites.values.toSeq),
|
||||
gen("regression", regressionSuites.values.toSeq)
|
||||
).mkString("\n"))
|
||||
f.close
|
||||
}
|
||||
|
||||
def createOutputFile(name: String) =
|
||||
new java.io.FileWriter(s"${Driver.targetDir}/$name")
|
||||
}
|
||||
|
||||
object DefaultTestSuites {
|
||||
val rv32uiNames = LinkedHashSet(
|
||||
"simple", "add", "addi", "and", "andi", "auipc", "beq", "bge", "bgeu", "blt", "bltu", "bne", "fence_i",
|
||||
"jal", "jalr", "lb", "lbu", "lh", "lhu", "lui", "lw", "or", "ori", "sb", "sh", "sw", "sll", "slli",
|
||||
"slt", "slti", "sra", "srai", "srl", "srli", "sub", "xor", "xori")
|
||||
val rv32ui = new AssemblyTestSuite("rv32ui", rv32uiNames)(_)
|
||||
|
||||
val rv32ucNames = LinkedHashSet("rvc")
|
||||
val rv32uc = new AssemblyTestSuite("rv32uc", rv32ucNames)(_)
|
||||
|
||||
val rv32umNames = LinkedHashSet("mul", "mulh", "mulhsu", "mulhu", "div", "divu", "rem", "remu")
|
||||
val rv32um = new AssemblyTestSuite("rv32um", rv32umNames)(_)
|
||||
|
||||
val rv32uaNames = LinkedHashSet("lrsc", "amoadd_w", "amoand_w", "amoor_w", "amoxor_w", "amoswap_w", "amomax_w", "amomaxu_w", "amomin_w", "amominu_w")
|
||||
val rv32ua = new AssemblyTestSuite("rv32ua", rv32uaNames)(_)
|
||||
|
||||
val rv32siNames = LinkedHashSet("csr", "ma_fetch", "scall", "sbreak", "wfi", "dirty")
|
||||
val rv32si = new AssemblyTestSuite("rv32si", rv32siNames)(_)
|
||||
|
||||
val rv32miNames = LinkedHashSet("csr", "mcsr", "illegal", "ma_addr", "ma_fetch", "sbreak", "scall")
|
||||
val rv32mi = new AssemblyTestSuite("rv32mi", rv32miNames)(_)
|
||||
|
||||
val rv32u = List(rv32ui, rv32um)
|
||||
val rv32i = List(rv32ui, rv32si, rv32mi)
|
||||
val rv32pi = List(rv32ui, rv32mi)
|
||||
|
||||
val rv64uiNames = LinkedHashSet("addw", "addiw", "ld", "lwu", "sd", "slliw", "sllw", "sltiu", "sltu", "sraiw", "sraw", "srliw", "srlw", "subw")
|
||||
val rv64ui = new AssemblyTestSuite("rv64ui", rv32uiNames ++ rv64uiNames)(_)
|
||||
|
||||
val rv64umNames = LinkedHashSet("divuw", "divw", "mulw", "remuw", "remw")
|
||||
val rv64um = new AssemblyTestSuite("rv64um", rv32umNames ++ rv64umNames)(_)
|
||||
|
||||
val rv64uaNames = rv32uaNames.map(_.replaceAll("_w","_d"))
|
||||
val rv64ua = new AssemblyTestSuite("rv64ua", rv32uaNames ++ rv64uaNames)(_)
|
||||
|
||||
val rv64ucNames = rv32ucNames
|
||||
val rv64uc = new AssemblyTestSuite("rv64uc", rv64ucNames)(_)
|
||||
|
||||
val rv64ufNames = LinkedHashSet("ldst", "move", "fsgnj", "fcmp", "fcvt", "fcvt_w", "fclass", "fadd", "fdiv", "fmin", "fmadd")
|
||||
val rv64uf = new AssemblyTestSuite("rv64uf", rv64ufNames)(_)
|
||||
val rv64ufNoDiv = new AssemblyTestSuite("rv64uf", rv64ufNames - "fdiv")(_)
|
||||
|
||||
val rv64udNames = rv64ufNames + "structural"
|
||||
val rv64ud = new AssemblyTestSuite("rv64ud", rv64udNames)(_)
|
||||
val rv64udNoDiv = new AssemblyTestSuite("rv64ud", rv64udNames - "fdiv")(_)
|
||||
|
||||
val rv64siNames = rv32siNames
|
||||
val rv64si = new AssemblyTestSuite("rv64si", rv64siNames)(_)
|
||||
|
||||
val rv64miNames = rv32miNames + "breakpoint"
|
||||
val rv64mi = new AssemblyTestSuite("rv64mi", rv64miNames)(_)
|
||||
|
||||
val groundtestNames = LinkedHashSet("simple")
|
||||
val groundtest64 = new AssemblyTestSuite("rv64ui", groundtestNames)(_)
|
||||
val groundtest32 = new AssemblyTestSuite("rv32ui", groundtestNames)(_)
|
||||
|
||||
// TODO: "rv64ui-pm-lrsc", "rv64mi-pm-ipi",
|
||||
|
||||
val rv64u = List(rv64ui, rv64um)
|
||||
val rv64i = List(rv64ui, rv64si, rv64mi)
|
||||
val rv64pi = List(rv64ui, rv64mi)
|
||||
|
||||
val benchmarks = new BenchmarkTestSuite("rvi", "$(RISCV)/riscv64-unknown-elf/share/riscv-tests/benchmarks", LinkedHashSet(
|
||||
"median", "multiply", "qsort", "towers", "vvadd", "dhrystone", "mt-matmul"))
|
||||
|
||||
val rv32udBenchmarks = new BenchmarkTestSuite("rvd", "$(RISCV)/riscv64-unknown-elf/share/riscv-tests/benchmarks", LinkedHashSet(
|
||||
"mm", "spmv", "mt-vvadd"))
|
||||
|
||||
val emptyBmarks = new BenchmarkTestSuite("empty",
|
||||
"$(RISCV)/riscv64-unknown-elf/share/riscv-tests/benchmarks", LinkedHashSet.empty)
|
||||
|
||||
val mtBmarks = new BenchmarkTestSuite("mt", "$(RISCV)/riscv64-unknown-elf/share/riscv-tests/mt",
|
||||
LinkedHashSet(((0 to 4).map("vvadd"+_) ++
|
||||
List("ad","ae","af","ag","ai","ak","al","am","an","ap","aq","ar","at","av","ay","az",
|
||||
"bb","bc","bf","bh","bj","bk","bm","bo","br","bs","ce","cf","cg","ci","ck","cl",
|
||||
"cm","cs","cv","cy","dc","df","dm","do","dr","ds","du","dv").map(_+"_matmul")): _*))
|
||||
}
|
||||
|
||||
object TestGenerator extends App {
|
||||
val projectName = args(0)
|
||||
val topModuleName = args(1)
|
||||
val configClassName = args(2)
|
||||
|
||||
val aggregateConfigs = configClassName.split('_')
|
||||
|
||||
val finalConfig = aggregateConfigs.foldRight(new Config()) { case (currentConfigName, finalConfig) =>
|
||||
val currentConfig = try {
|
||||
Class.forName(s"$projectName.$currentConfigName").newInstance.asInstanceOf[Config]
|
||||
} catch {
|
||||
case e: java.lang.ClassNotFoundException =>
|
||||
throwException("Unable to find part \"" + currentConfigName +
|
||||
"\" of configClassName \"" + configClassName +
|
||||
"\", did you misspell it?", e)
|
||||
}
|
||||
currentConfig ++ finalConfig
|
||||
}
|
||||
val world = finalConfig.toInstance
|
||||
|
||||
val paramsFromConfig: Parameters = Parameters.root(world)
|
||||
|
||||
val gen = () =>
|
||||
Class.forName(s"$projectName.$topModuleName")
|
||||
.getConstructor(classOf[cde.Parameters])
|
||||
.newInstance(paramsFromConfig)
|
||||
.asInstanceOf[Module]
|
||||
|
||||
chiselMain.run(args.drop(3), gen)
|
||||
//Driver.elaborate(gen, configName = configClassName)
|
||||
|
||||
TestGeneration.addSuite(new RegressionTestSuite(paramsFromConfig(RegressionTestNames)))
|
||||
|
||||
TestGeneration.generateMakefrag(topModuleName, configClassName)
|
||||
TestBenchGeneration.generateVerilogFragment(
|
||||
topModuleName, configClassName, paramsFromConfig)
|
||||
TestBenchGeneration.generateCPPFragment(
|
||||
topModuleName, configClassName, paramsFromConfig)
|
||||
|
||||
val pdFile = TestGeneration.createOutputFile(s"$topModuleName.$configClassName.prm")
|
||||
pdFile.write(ParameterDump.getDump)
|
||||
pdFile.close
|
||||
val v = TestGeneration.createOutputFile(configClassName + ".knb")
|
||||
v.write(world.getKnobs)
|
||||
v.close
|
||||
val d = new java.io.FileOutputStream(Driver.targetDir + "/" + configClassName + ".cfg")
|
||||
d.write(paramsFromConfig(ConfigString))
|
||||
d.close
|
||||
val w = TestGeneration.createOutputFile(configClassName + ".cst")
|
||||
w.write(world.getConstraints)
|
||||
w.close
|
||||
}
|
@ -1,20 +0,0 @@
|
||||
package rocketchip
|
||||
|
||||
import Chisel._
|
||||
import junctions.unittests.UnitTestSuite
|
||||
import rocket.Tile
|
||||
import uncore.tilelink.TLId
|
||||
import cde.Parameters
|
||||
|
||||
class UnitTestCoreplex(topParams: Parameters) extends Coreplex()(topParams) {
|
||||
require(!exportMMIO)
|
||||
require(!exportBus)
|
||||
require(nMemChannels == 0)
|
||||
|
||||
io.debug.req.ready := Bool(false)
|
||||
io.debug.resp.valid := Bool(false)
|
||||
|
||||
val l1params = p.alterPartial({ case TLId => "L1toL2" })
|
||||
val tests = Module(new UnitTestSuite()(l1params))
|
||||
when (tests.io.finished) { stop() }
|
||||
}
|
Reference in New Issue
Block a user