1
0

Merge remote-tracking branch 'origin/master' into debug_v013_pr

This commit is contained in:
Megan Wachs 2017-03-30 08:01:11 -07:00
commit 9de06f8c83
16 changed files with 130 additions and 60 deletions

View File

@ -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

View File

@ -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

@ -1 +1 @@
Subproject commit 2376ff9849beafaf02b657b461c15a36d7b38fd4
Subproject commit bda2bd363fbe66de9425bba12d96f5f9816a43ce

@ -1 +1 @@
Subproject commit af8f5ee2fc951a4a0b030e4a8d82fc4b1a1571e2
Subproject commit 4dbb81b31698ebaa6a3d548ae628a3c716c5df72

View File

@ -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))
}
}

View File

@ -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)

View File

@ -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
}
}

View File

@ -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()

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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 }
}
}

View File

@ -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 ]