Merge remote-tracking branch 'origin/master' into debug_v013_pr
This commit is contained in:
commit
9de06f8c83
@ -155,7 +155,7 @@ done_processing:
|
||||
srand48(random_seed);
|
||||
|
||||
Verilated::randReset(2);
|
||||
VTestHarness *tile = new VTestHarness;
|
||||
TEST_HARNESS *tile = new TEST_HARNESS;
|
||||
|
||||
#if VM_TRACE
|
||||
Verilated::traceEverOn(true); // Verilator must compute traced signals
|
||||
|
@ -1,5 +1,5 @@
|
||||
#--------------------------------------------------------------------
|
||||
# Verilator Generation
|
||||
# Verilator Generation
|
||||
#--------------------------------------------------------------------
|
||||
firrtl = $(generated_dir)/$(long_name).fir
|
||||
firrtl_debug = $(generated_dir_debug)/$(long_name).fir
|
||||
@ -57,7 +57,7 @@ VERILATOR_FLAGS := --top-module $(MODEL) \
|
||||
--output-split 20000 \
|
||||
-Wno-STMTDLY --x-assign unique \
|
||||
-I$(base_dir)/vsrc \
|
||||
-O3 -CFLAGS "$(CXXFLAGS) -DVERILATOR -include $(base_dir)/csrc/verilator.h"
|
||||
-O3 -CFLAGS "$(CXXFLAGS) -DVERILATOR -DTEST_HARNESS=V$(MODEL) -include $(base_dir)/csrc/verilator.h"
|
||||
cppfiles = $(addprefix $(base_dir)/csrc/, $(addsuffix .cc, $(CXXSRCS)))
|
||||
headers = $(wildcard $(base_dir)/csrc/*.h)
|
||||
|
||||
|
2
firrtl
2
firrtl
@ -1 +1 @@
|
||||
Subproject commit 2376ff9849beafaf02b657b461c15a36d7b38fd4
|
||||
Subproject commit bda2bd363fbe66de9425bba12d96f5f9816a43ce
|
@ -1 +1 @@
|
||||
Subproject commit af8f5ee2fc951a4a0b030e4a8d82fc4b1a1571e2
|
||||
Subproject commit 4dbb81b31698ebaa6a3d548ae628a3c716c5df72
|
@ -66,7 +66,7 @@ trait CoreplexNetwork extends HasCoreplexParameters {
|
||||
Description("soc", Map(
|
||||
"#address-cells" -> width,
|
||||
"#size-cells" -> width,
|
||||
"compatible" -> (p(DTSModel) +: p(DTSCompat)).map(s => ResourceString(s + "-soc")),
|
||||
"compatible" -> ((p(DTSModel) +: p(DTSCompat)).map(s => ResourceString(s + "-soc")) :+ ResourceString("simple-bus")),
|
||||
"ranges" -> Nil))
|
||||
}
|
||||
}
|
||||
|
@ -8,6 +8,7 @@ import diplomacy._
|
||||
import rocket._
|
||||
import tile._
|
||||
import uncore.tilelink2._
|
||||
import util._
|
||||
|
||||
sealed trait ClockCrossing
|
||||
case object Synchronous extends ClockCrossing
|
||||
@ -21,12 +22,17 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
|
||||
val module: HasRocketTilesModule
|
||||
|
||||
private val crossing = p(RocketCrossing)
|
||||
private val configs = p(RocketTilesKey)
|
||||
val tileParams = p(RocketTilesKey)
|
||||
|
||||
// TODO: hack to fix deduplication; see PR https://github.com/ucb-bar/berkeley-hardfloat/pull/14
|
||||
hardfloat.consts
|
||||
// Handle interrupts to be routed directly into each tile
|
||||
val localIntNodes = tileParams map { t =>
|
||||
(t.core.nLocalInterrupts > 0).option(IntInputNode())
|
||||
}
|
||||
|
||||
val rocketWires: Seq[HasRocketTilesBundle => Unit] = configs.zipWithIndex.map { case (c, i) =>
|
||||
// Make a function for each tile that will wire it to coreplex devices and crossbars,
|
||||
// according to the specified type of clock crossing.
|
||||
val wiringTuple = localIntNodes.zip(tileParams).zipWithIndex
|
||||
val rocketWires: Seq[HasRocketTilesBundle => Unit] = wiringTuple.map { case ((lip, c), i) =>
|
||||
val pWithExtra = p.alterPartial {
|
||||
case TileKey => c
|
||||
case BuildRoCC => c.rocc
|
||||
@ -34,10 +40,11 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
|
||||
}
|
||||
|
||||
val intBar = LazyModule(new IntXbar)
|
||||
intBar.intnode := debug.intnode // Debug Interrupt
|
||||
intBar.intnode := clint.intnode // msip+mtip
|
||||
intBar.intnode := plic.intnode // meip
|
||||
intBar.intnode := debug.intnode // debug
|
||||
intBar.intnode := clint.intnode // msip+mtip
|
||||
intBar.intnode := plic.intnode // meip
|
||||
if (c.core.useVM) intBar.intnode := plic.intnode // seip
|
||||
lip.foreach { intBar.intnode := _ } // lip
|
||||
|
||||
crossing match {
|
||||
case Synchronous => {
|
||||
@ -97,6 +104,7 @@ trait HasRocketTiles extends CoreplexRISCVPlatform {
|
||||
|
||||
trait HasRocketTilesBundle extends CoreplexRISCVPlatformBundle {
|
||||
val outer: HasRocketTiles
|
||||
val local_interrupts = HeterogeneousBag(outer.localIntNodes.flatten.map(_.bundleIn))
|
||||
val tcrs = Vec(p(RocketTilesKey).size, new Bundle {
|
||||
val clock = Clock(INPUT)
|
||||
val reset = Bool(INPUT)
|
||||
|
@ -140,6 +140,8 @@ object CSR
|
||||
val firstHPM = 3
|
||||
val nCtr = 32
|
||||
val nHPM = nCtr - firstHPM
|
||||
|
||||
val maxPMPs = 16
|
||||
}
|
||||
|
||||
class PerfCounterIO(implicit p: Parameters) extends CoreBundle
|
||||
@ -418,10 +420,14 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
||||
|
||||
val pmpCfgPerCSR = xLen / new PMPConfig().getWidth
|
||||
def pmpCfgIndex(i: Int) = (xLen / 32) * (i / pmpCfgPerCSR)
|
||||
for (i <- 0 until reg_pmp.size by pmpCfgPerCSR)
|
||||
read_mapping += (CSRs.pmpcfg0 + pmpCfgIndex(i)) -> reg_pmp.map(_.cfg).slice(i, i + pmpCfgPerCSR).asUInt
|
||||
for ((pmp, i) <- reg_pmp zipWithIndex)
|
||||
read_mapping += (CSRs.pmpaddr0 + i) -> pmp.addr
|
||||
if (reg_pmp.nonEmpty) {
|
||||
require(reg_pmp.size <= CSR.maxPMPs)
|
||||
val read_pmp = reg_pmp.padTo(CSR.maxPMPs, 0.U.asTypeOf(new PMP))
|
||||
for (i <- 0 until read_pmp.size by pmpCfgPerCSR)
|
||||
read_mapping += (CSRs.pmpcfg0 + pmpCfgIndex(i)) -> read_pmp.map(_.cfg).slice(i, i + pmpCfgPerCSR).asUInt
|
||||
for ((pmp, i) <- read_pmp zipWithIndex)
|
||||
read_mapping += (CSRs.pmpaddr0 + i) -> pmp.addr
|
||||
}
|
||||
|
||||
for (i <- 0 until nCustomMrwCsrs) {
|
||||
val addr = 0xff0 + i
|
||||
@ -687,7 +693,7 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
||||
}
|
||||
if (reg_pmp.nonEmpty) for (((pmp, next), i) <- (reg_pmp zip (reg_pmp.tail :+ reg_pmp.last)) zipWithIndex) {
|
||||
require(xLen % pmp.cfg.getWidth == 0)
|
||||
when (decoded_addr(CSRs.pmpcfg0 + pmpCfgIndex(i)) && !pmp.locked) {
|
||||
when (decoded_addr(CSRs.pmpcfg0 + pmpCfgIndex(i)) && !pmp.cfgLocked) {
|
||||
pmp.cfg := new PMPConfig().fromBits(wdata >> ((i * pmp.cfg.getWidth) % xLen))
|
||||
}
|
||||
when (decoded_addr(CSRs.pmpaddr0 + i) && !pmp.addrLocked(next)) {
|
||||
@ -735,10 +741,11 @@ class CSRFile(perfEventSets: EventSets = new EventSets(Seq()))(implicit p: Param
|
||||
}
|
||||
for (bp <- reg_bp drop nBreakpoints)
|
||||
bp := new BP().fromBits(0)
|
||||
if (reg_pmp.nonEmpty) {
|
||||
for (pmp <- reg_pmp) {
|
||||
if (!usingUser) pmp.cfg.m := true
|
||||
when (reset) { pmp.cfg.p := 0 }
|
||||
for (pmp <- reg_pmp) {
|
||||
pmp.cfg.res := 0
|
||||
when (reset) {
|
||||
pmp.cfg.a := 0
|
||||
pmp.cfg.l := 0
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -180,6 +180,12 @@ class DCacheModule(outer: DCache) extends HellaCacheModule(outer) {
|
||||
io.cpu.s2_nack := s2_valid && !s2_valid_hit && !(s2_valid_uncached && tl_out.a.ready && !uncachedInFlight.asUInt.andR)
|
||||
when (io.cpu.s2_nack || (s2_valid_hit && s2_update_meta)) { s1_nack := true }
|
||||
|
||||
val s3_valid = Reg(next = s2_valid, init=Bool(false))
|
||||
val s3_uncached = Reg(next = s2_uncached, init=Bool(false))
|
||||
when (s2_valid_cached_miss) {
|
||||
assert( !(s3_valid && s3_uncached) )
|
||||
}
|
||||
|
||||
// exceptions
|
||||
val s1_storegen = new StoreGen(s1_req.typ, s1_req.addr, UInt(0), wordBytes)
|
||||
val no_xcpt = Bool(usingDataScratchpad) && s1_req.phys /* slave port */ && s1_hit_state.isValid()
|
||||
|
@ -9,9 +9,9 @@ import tile._
|
||||
import util._
|
||||
|
||||
class PMPConfig extends Bundle {
|
||||
val p = UInt(width = 2)
|
||||
val l = Bool()
|
||||
val res = UInt(width = 2)
|
||||
val a = UInt(width = 2)
|
||||
val m = Bool()
|
||||
val x = Bool()
|
||||
val w = Bool()
|
||||
val r = Bool()
|
||||
@ -32,8 +32,10 @@ class PMPReg(implicit p: Parameters) extends CoreBundle()(p) {
|
||||
val cfg = new PMPConfig
|
||||
val addr = UInt(width = paddrBits - PMP.lgAlign)
|
||||
|
||||
def locked = cfg.p(1)
|
||||
def addrLocked(next: PMPReg) = locked || next.locked && next.cfg.a(1)
|
||||
def napot = cfg.a(1)
|
||||
def torNotNAPOT = cfg.a(0)
|
||||
def cfgLocked = cfg.l
|
||||
def addrLocked(next: PMPReg) = cfgLocked || next.cfgLocked && next.cfg.a(1)
|
||||
}
|
||||
|
||||
class PMP(implicit p: Parameters) extends PMPReg {
|
||||
@ -99,7 +101,7 @@ class PMP(implicit p: Parameters) extends PMPReg {
|
||||
|
||||
// returns whether this PMP completely contains, or contains none of, a page
|
||||
def homogeneous(x: UInt, pgLevel: UInt, prev: PMP): Bool =
|
||||
!cfg.p(0) || Mux(cfg.a(1), rangeHomogeneous(x, pgLevel, prev), pow2Homogeneous(x, pgLevel))
|
||||
Mux(napot, pow2Homogeneous(x, pgLevel), !torNotNAPOT || rangeHomogeneous(x, pgLevel, prev))
|
||||
|
||||
// returns whether this matching PMP fully contains the access
|
||||
def aligned(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool = if (lgMaxSize <= lgAlign) true.B else {
|
||||
@ -108,12 +110,12 @@ class PMP(implicit p: Parameters) extends PMPReg {
|
||||
val straddlesUpperBound = ((x >> lgMaxSize) ^ (comparand >> lgMaxSize)) === 0 && (comparand(lgMaxSize-1, 0) & (x(lgMaxSize-1, 0) | lsbMask)) =/= 0
|
||||
val rangeAligned = !(straddlesLowerBound || straddlesUpperBound)
|
||||
val pow2Aligned = (lsbMask & ~mask(lgMaxSize-1, 0)) === 0
|
||||
Mux(cfg.a(1), rangeAligned, pow2Aligned)
|
||||
Mux(napot, pow2Aligned, rangeAligned)
|
||||
}
|
||||
|
||||
// returns whether this PMP matches at least one byte of the access
|
||||
def hit(x: UInt, lgSize: UInt, lgMaxSize: Int, prev: PMP): Bool =
|
||||
cfg.p(0) && Mux(cfg.a(1), rangeMatch(x, lgSize, lgMaxSize, prev), pow2Match(x, lgSize, lgMaxSize))
|
||||
Mux(napot, pow2Match(x, lgSize, lgMaxSize), torNotNAPOT && rangeMatch(x, lgSize, lgMaxSize, prev))
|
||||
}
|
||||
|
||||
class PMPHomogeneityChecker(pmps: Seq[PMP])(implicit p: Parameters) {
|
||||
@ -144,7 +146,7 @@ class PMPChecker(lgMaxSize: Int)(implicit p: Parameters) extends CoreModule()(p)
|
||||
|
||||
val res = (pmp0 /: (io.pmp zip (pmp0 +: io.pmp)).reverse) { case (prev, (pmp, prevPMP)) =>
|
||||
val hit = pmp.hit(io.addr, io.size, lgMaxSize, prevPMP)
|
||||
val ignore = default && !pmp.cfg.m
|
||||
val ignore = default && !pmp.cfg.l
|
||||
val aligned = pmp.aligned(io.addr, io.size, lgMaxSize, prevPMP)
|
||||
val cur = Wire(init = pmp)
|
||||
cur.cfg.r := (aligned && pmp.cfg.r) || ignore
|
||||
|
@ -79,6 +79,7 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
|
||||
val s1_kill = Reg(next = Bool(false))
|
||||
val resp_valid = Reg(next = Vec.fill(io.requestor.size)(Bool(false)))
|
||||
val ae = Reg(next = io.mem.xcpt.ae.ld)
|
||||
val resp_ae = Reg(Bool())
|
||||
|
||||
val r_req = Reg(new PTWReq)
|
||||
val r_req_dest = Reg(Bits())
|
||||
@ -99,7 +100,6 @@ class PTW(n: Int)(implicit edge: TLEdgeOut, p: Parameters) extends CoreModule()(
|
||||
}
|
||||
val traverse = pte.table() && !invalid_paddr && count < pgLevels-1
|
||||
val pte_addr = Cat(r_pte.ppn, vpn_idx) << log2Ceil(xLen/8)
|
||||
val resp_ae = Reg(next = ae || invalid_paddr)
|
||||
|
||||
when (arb.io.out.fire()) {
|
||||
r_req := arb.io.out.bits
|
||||
|
@ -61,6 +61,7 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
|
||||
val level = UInt(width = log2Ceil(pgLevels))
|
||||
val u = Bool()
|
||||
val g = Bool()
|
||||
val ae = Bool()
|
||||
val sw = Bool()
|
||||
val sx = Bool()
|
||||
val sr = Bool()
|
||||
@ -140,9 +141,13 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
|
||||
newEntry.c := cacheable
|
||||
newEntry.u := pte.u
|
||||
newEntry.g := pte.g
|
||||
newEntry.sr := pte.sr()
|
||||
newEntry.sw := pte.sw()
|
||||
newEntry.sx := pte.sx()
|
||||
// if an access exception occurs during PTW, pretend the page has full
|
||||
// permissions so that a page fault will not occur, but clear the
|
||||
// phyiscal memory permissions, so that an access exception will occur.
|
||||
newEntry.ae := io.ptw.resp.bits.ae
|
||||
newEntry.sr := pte.sr() || io.ptw.resp.bits.ae
|
||||
newEntry.sw := pte.sw() || io.ptw.resp.bits.ae
|
||||
newEntry.sx := pte.sx() || io.ptw.resp.bits.ae
|
||||
newEntry.pr := prot_r && !io.ptw.resp.bits.ae
|
||||
newEntry.pw := prot_w && !io.ptw.resp.bits.ae
|
||||
newEntry.px := prot_x && !io.ptw.resp.bits.ae
|
||||
@ -154,7 +159,7 @@ class TLB(lgMaxSize: Int, nEntries: Int)(implicit edge: TLEdgeOut, p: Parameters
|
||||
val plru = new PseudoLRU(normalEntries)
|
||||
val repl_waddr = Mux(!valid(normalEntries-1, 0).andR, PriorityEncoder(~valid(normalEntries-1, 0)), plru.replace)
|
||||
|
||||
val priv_ok = Mux(priv_s, ~Mux(io.ptw.status.sum, UInt(0), entries.map(_.u).asUInt), entries.map(_.u).asUInt)
|
||||
val priv_ok = entries.map(_.ae).asUInt | Mux(priv_s, ~Mux(io.ptw.status.sum, UInt(0), entries.map(_.u).asUInt), entries.map(_.u).asUInt)
|
||||
val r_array = Cat(true.B, priv_ok & (entries.map(_.sr).asUInt | Mux(io.ptw.status.mxr, entries.map(_.sx).asUInt, UInt(0))))
|
||||
val w_array = Cat(true.B, priv_ok & entries.map(_.sw).asUInt)
|
||||
val x_array = Cat(true.B, priv_ok & entries.map(_.sx).asUInt)
|
||||
|
@ -29,9 +29,10 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
|
||||
|
||||
nDCachePorts += 1 // core TODO dcachePorts += () => module.core.io.dmem ??
|
||||
|
||||
val device = new Device {
|
||||
def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
|
||||
def ofStr(x: String) = Seq(ResourceString(x))
|
||||
private def ofInt(x: Int) = Seq(ResourceInt(BigInt(x)))
|
||||
private def ofStr(x: String) = Seq(ResourceString(x))
|
||||
|
||||
val cpuDevice = new Device {
|
||||
def describe(resources: ResourceBindings): Description = {
|
||||
val block = p(CacheBlockBytes)
|
||||
val m = if (rocketParams.core.mulDiv.nonEmpty) "m" else ""
|
||||
@ -85,24 +86,28 @@ class RocketTile(val rocketParams: RocketTileParams, val hartid: Int)(implicit p
|
||||
"compatible" -> ofStr("riscv"),
|
||||
"status" -> ofStr("okay"),
|
||||
"clock-frequency" -> Seq(ResourceInt(rocketParams.core.bootFreqHz)),
|
||||
"riscv,isa" -> ofStr(isa),
|
||||
"interrupt-controller" -> Nil,
|
||||
"#interrupt-cells" -> ofInt(1))
|
||||
"riscv,isa" -> ofStr(isa))
|
||||
++ dcache ++ icache ++ nextlevel ++ mmu ++ itlb ++ dtlb)
|
||||
}
|
||||
}
|
||||
val intcDevice = new Device {
|
||||
def describe(resources: ResourceBindings): Description = {
|
||||
Description(s"cpus/cpu@${hartid}/interrupt-controller", Map(
|
||||
"compatible" -> ofStr("riscv,cpu-intc"),
|
||||
"interrupt-controller" -> Nil,
|
||||
"#interrupt-cells" -> ofInt(1)))
|
||||
}
|
||||
}
|
||||
|
||||
ResourceBinding {
|
||||
Resource(device, "reg").bind(ResourceInt(BigInt(hartid)))
|
||||
|
||||
// debug, msip, mtip, meip, seip offsets in CSRs
|
||||
val intMap = Seq(65535, 3, 7, 11, 9)
|
||||
Resource(cpuDevice, "reg").bind(ResourceInt(BigInt(hartid)))
|
||||
Resource(intcDevice, "reg").bind(ResourceInt(BigInt(hartid)))
|
||||
|
||||
intNode.edgesIn.flatMap(_.source.sources).map { case s =>
|
||||
for (i <- s.range.start until s.range.end) {
|
||||
intMap.lift(i).foreach { j =>
|
||||
csrIntMap.lift(i).foreach { j =>
|
||||
s.resources.foreach { r =>
|
||||
r.bind(device, ResourceInt(j))
|
||||
r.bind(intcDevice, ResourceInt(j))
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -122,7 +127,8 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
|
||||
require(outer.p(PAddrBits) >= outer.masterNode.edgesIn(0).bundle.addressBits)
|
||||
|
||||
val core = Module(p(BuildCore)(outer.p))
|
||||
core.io.hartid := io.hartid
|
||||
decodeCoreInterrupts(core.io.interrupts) // Decode the interrupt vector
|
||||
core.io.hartid := io.hartid // Pass through the hartid
|
||||
outer.frontend.module.io.cpu <> core.io.imem
|
||||
outer.frontend.module.io.resetVector := io.resetVector
|
||||
dcachePorts += core.io.dmem // TODO outer.dcachePorts += () => module.core.io.dmem ??
|
||||
@ -136,12 +142,6 @@ class RocketTileModule(outer: RocketTile) extends BaseTileModule(outer, () => ne
|
||||
core.io.rocc.interrupt := lr.module.io.core.interrupt
|
||||
}
|
||||
|
||||
// Decode the interrupt vector
|
||||
core.io.interrupts.debug := io.interrupts(0)(0)
|
||||
core.io.interrupts.msip := io.interrupts(0)(1)
|
||||
core.io.interrupts.mtip := io.interrupts(0)(2)
|
||||
core.io.interrupts.meip := io.interrupts(0)(3)
|
||||
core.io.interrupts.seip.foreach { _ := io.interrupts(0)(4) }
|
||||
|
||||
// TODO eliminate this redundancy
|
||||
val h = dcachePorts.size
|
||||
|
@ -35,7 +35,7 @@ trait HasTopLevelNetworks extends HasPeripheryParameters {
|
||||
|
||||
val socBus = LazyModule(new TLXbar) // Wide or unordered-access slave devices (TL-UH)
|
||||
val peripheryBus = LazyModule(new TLXbar) // Narrow and ordered-access slave devices (TL-UL)
|
||||
val intBus = LazyModule(new IntXbar) // Interrupts
|
||||
val intBus = LazyModule(new IntXbar) // Device and global external interrupts
|
||||
val fsb = LazyModule(new TLBuffer(BufferParams.none)) // Master devices talking to the frontside of the L2
|
||||
val bsb = LazyModule(new TLBuffer(BufferParams.none)) // Slave devices talking to the backside of the L2
|
||||
val mem = Seq.fill(nMemoryChannels) { LazyModule(new TLXbar) } // Ports out to DRAM
|
||||
|
@ -52,13 +52,11 @@ trait HasTileLinkMasterPort extends HasTileParameters {
|
||||
implicit val p: Parameters
|
||||
val module: HasTileLinkMasterPortModule
|
||||
val masterNode = TLOutputNode()
|
||||
val intNode = IntSinkNode(IntSinkPortSimple())
|
||||
}
|
||||
|
||||
trait HasTileLinkMasterPortBundle {
|
||||
val outer: HasTileLinkMasterPort
|
||||
val master = outer.masterNode.bundleOut
|
||||
val interrupts = outer.intNode.bundleIn
|
||||
}
|
||||
|
||||
trait HasTileLinkMasterPortModule {
|
||||
@ -67,15 +65,18 @@ trait HasTileLinkMasterPortModule {
|
||||
}
|
||||
|
||||
abstract class BaseTile(tileParams: TileParams)(implicit p: Parameters) extends BareTile
|
||||
with HasTileLinkMasterPort {
|
||||
with HasTileLinkMasterPort
|
||||
with HasExternalInterrupts {
|
||||
override lazy val module = new BaseTileModule(this, () => new BaseTileBundle(this))
|
||||
}
|
||||
|
||||
class BaseTileBundle[+L <: BaseTile](_outer: L) extends BareTileBundle(_outer)
|
||||
with HasTileLinkMasterPortBundle {
|
||||
with HasTileLinkMasterPortBundle
|
||||
with HasExternalInterruptsBundle {
|
||||
val hartid = UInt(INPUT, p(XLen))
|
||||
val resetVector = UInt(INPUT, p(XLen))
|
||||
}
|
||||
|
||||
class BaseTileModule[+L <: BaseTile, +B <: BaseTileBundle[L]](_outer: L, _io: () => B) extends BareTileModule(_outer, _io)
|
||||
with HasTileLinkMasterPortModule
|
||||
with HasExternalInterruptsModule
|
||||
|
@ -4,13 +4,53 @@ package tile
|
||||
|
||||
import Chisel._
|
||||
import config.Parameters
|
||||
import uncore.tilelink2.{IntSinkNode, IntSinkPortSimple}
|
||||
import util._
|
||||
|
||||
class TileInterrupts(implicit p: Parameters) extends CoreBundle()(p) {
|
||||
val lip = Vec(coreParams.nLocalInterrupts, Bool())
|
||||
val debug = Bool()
|
||||
val mtip = Bool()
|
||||
val msip = Bool()
|
||||
val meip = Bool()
|
||||
val seip = usingVM.option(Bool())
|
||||
val lip = Vec(coreParams.nLocalInterrupts, Bool())
|
||||
}
|
||||
|
||||
// Use diplomatic interrupts to external interrupts from the coreplex into the tile
|
||||
trait HasExternalInterrupts extends HasTileParameters {
|
||||
implicit val p: Parameters
|
||||
val module: HasExternalInterruptsModule
|
||||
|
||||
val intNode = IntSinkNode(IntSinkPortSimple())
|
||||
|
||||
// TODO: the order of the following two functions must match, and
|
||||
// also match the order which things are connected to the
|
||||
// per-tile crossbar in coreplex.HasRocketTiles
|
||||
|
||||
// debug, msip, mtip, meip, seip, lip offsets in CSRs
|
||||
def csrIntMap: List[Int] = {
|
||||
val nlips = tileParams.core.nLocalInterrupts
|
||||
List(65535, 3, 7, 11, 9) ++ List.tabulate(nlips)(_ + 16)
|
||||
}
|
||||
}
|
||||
|
||||
trait HasExternalInterruptsBundle {
|
||||
val outer: HasExternalInterrupts
|
||||
val interrupts = outer.intNode.bundleIn
|
||||
}
|
||||
|
||||
trait HasExternalInterruptsModule {
|
||||
val outer: HasExternalInterrupts
|
||||
val io: HasExternalInterruptsBundle
|
||||
|
||||
// go from flat diplomatic Interrupts to bundled TileInterrupts
|
||||
def decodeCoreInterrupts(core: TileInterrupts) {
|
||||
val core_ips = Seq(
|
||||
core.debug,
|
||||
core.msip,
|
||||
core.mtip,
|
||||
core.meip,
|
||||
core.seip.getOrElse(Wire(Bool()))) ++ core.lip
|
||||
core_ips.zip(io.interrupts(0)).foreach { case(c, i) => c := i }
|
||||
}
|
||||
}
|
||||
|
@ -25,6 +25,7 @@ $(generated_dir)/$(long_name).behav_srams.v : $(generated_dir)/$(long_name).conf
|
||||
#--------------------------------------------------------------------
|
||||
# Run
|
||||
#--------------------------------------------------------------------
|
||||
.PRECIOUS: $(output_dir)/%.vpd
|
||||
|
||||
$(output_dir)/%.run: $(output_dir)/% $(simv)
|
||||
cd $(sim_dir) && $(exec_simv) +max-cycles=$(timeout_cycles) $< 2> /dev/null 2> $@ && [ $$PIPESTATUS -eq 0 ]
|
||||
|
Loading…
Reference in New Issue
Block a user