From d530ef7236a8482c5c43807d2e05b7e4cd4b64b3 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 24 Oct 2016 18:13:23 -0700 Subject: [PATCH 01/47] DebugModule: translate to TL2 with {32,64}-bit XLen width --- src/main/scala/uncore/devices/Debug.scala | 353 ++++++---------------- 1 file changed, 89 insertions(+), 264 deletions(-) diff --git a/src/main/scala/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index 9997f493..cae84406 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -4,8 +4,9 @@ package uncore.devices import Chisel._ import junctions._ -import uncore.tilelink._ import util._ +import regmapper._ +import uncore.tilelink2._ import cde.{Parameters, Config, Field} // ***************************************** @@ -15,6 +16,7 @@ import cde.{Parameters, Config, Field} object DbRegAddrs{ + def DMRAMBASE = UInt(0x0) def DMCONTROL = UInt(0x10) def DMINFO = UInt(0x11) @@ -69,7 +71,7 @@ object DsbBusConsts { // See $RISCV/riscv-tools/riscv-isa-sim/debug_rom/debug_rom.h/S // The code assumes 64 bytes of Debug RAM. - def defaultRomContents : Array[Byte] = Array( + def xlenAnyRomContents : Array[Byte] = Array( 0x6f, 0x00, 0xc0, 0x04, 0x6f, 0x00, 0xc0, 0x00, 0x13, 0x04, 0xf0, 0xff, 0x6f, 0x00, 0x80, 0x00, 0x13, 0x04, 0x00, 0x00, 0x0f, 0x00, 0xf0, 0x0f, 0xf3, 0x24, 0x00, 0xf1, 0x63, 0xc6, 0x04, 0x00, 0x83, 0x24, 0xc0, 0x43, @@ -121,10 +123,10 @@ object DsbBusConsts { object DsbRegAddrs{ - def CLEARDEBINT = UInt(0x100) - def SETHALTNOT = UInt(0x10C) - def SERINFO = UInt(0x110) - def SERBASE = UInt(0x114) + def CLEARDEBINT = 0x100 + def SETHALTNOT = 0x10C + def SERINFO = 0x110 + def SERBASE = 0x114 // For each serial, there are // 3 registers starting here: // SERSEND0 @@ -132,9 +134,11 @@ object DsbRegAddrs{ // SERSTATUS0 // ... // SERSTATUS7 - def SERTX_OFFSET = UInt(0) - def SERRX_OFFSET = UInt(4) - def SERSTAT_OFFSET = UInt(8) + def SERTX_OFFSET = 0 + def SERRX_OFFSET = 4 + def SERSTAT_OFFSET = 8 + def RAMBASE = 0x400 + def ROMBASE = 0x800 } @@ -302,6 +306,24 @@ class DebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p val resp = new DecoupledIO(new DebugBusResp).flip() } +trait HasDebugModuleParameters { + val params : Parameters + implicit val p = params + val cfg = p(DMKey) +} + +/** Debug Module I/O, with the exclusion of the RegisterRouter + * Access interface. + */ + +trait DebugModuleBundle extends Bundle with HasDebugModuleParameters { + val db = new DebugBusIO()(p).flip() + val debugInterrupts = Vec(cfg.nComponents, Bool()).asOutput + val ndreset = Bool(OUTPUT) + val fullreset = Bool(OUTPUT) +} + + // ***************************************** // The Module // @@ -313,7 +335,7 @@ class DebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p * DebugModule is a slave to two masters: * The Debug Bus -- implemented as a generic Decoupled IO with request * and response channels - * The System Bus -- implemented as Uncached Tile Link. + * The System Bus -- implemented as generic RegisterRouter * * DebugModule is responsible for holding registers, RAM, and ROM * to support debug interactions, as well as driving interrupts @@ -321,10 +343,9 @@ class DebugBusIO(implicit val p: cde.Parameters) extends ParameterizedBundle()(p * It is also responsible for some reset lines. */ -class DebugModule ()(implicit val p:cde.Parameters) - extends Module - with HasTileLinkParameters { - val cfg = p(DMKey) +trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap { + + val io: DebugModuleBundle //-------------------------------------------------------------- // Import constants for shorter variable names @@ -344,6 +365,7 @@ class DebugModule ()(implicit val p:cde.Parameters) require (cfg.hasBusMaster == false) require (cfg.nDebugRamBytes <= 64) require (cfg.authType == DebugModuleAuthType.None) + require((DbBusConsts.dbRamWordBits % 8) == 0) //-------------------------------------------------------------- // Private Classes (Register Fields) @@ -403,17 +425,6 @@ class DebugModule ()(implicit val p:cde.Parameters) } - //-------------------------------------------------------------- - // Module I/O - //-------------------------------------------------------------- - - val io = new Bundle { - val db = new DebugBusIO()(p).flip() - val debugInterrupts = Vec(cfg.nComponents, Bool()).asOutput - val tl = new ClientUncachedTileLinkIO().flip - val ndreset = Bool(OUTPUT) - val fullreset = Bool(OUTPUT) - } //-------------------------------------------------------------- // Register & Wire Declarations @@ -455,47 +466,21 @@ class DebugModule ()(implicit val p:cde.Parameters) // --- Debug RAM - // Since the access size from Debug Bus and System Bus may not be consistent, - // use the maximum to build the RAM, and then select as needed for the smaller - // size. + val ramDataWidth = DbBusConsts.dbRamWordBits + val ramDataBytes = ramDataWidth / 8; + val ramAddrWidth = log2Up(cfg.nDebugRamBytes / ramDataBytes) - val dbRamDataWidth = DbBusConsts.dbRamWordBits - val sbRamDataWidth = tlDataBits - val dbRamAddrWidth = log2Up((cfg.nDebugRamBytes * 8) / dbRamDataWidth) - val sbRamAddrWidth = log2Up((cfg.nDebugRamBytes * 8) / sbRamDataWidth) - val sbRamAddrOffset = log2Up(tlDataBits/8) + val ramMem = Reg(init = Vec.fill(cfg.nDebugRamBytes){UInt(0, width = 8)}) - val ramDataWidth = dbRamDataWidth max sbRamDataWidth - val ramAddrWidth = dbRamAddrWidth min sbRamAddrWidth - val ramMem = Mem(1 << ramAddrWidth , UInt(width=ramDataWidth)) - val ramAddr = Wire(UInt(width=ramAddrWidth)) - val ramRdData = Wire(UInt(width=ramDataWidth)) - val ramWrData = Wire(UInt(width=ramDataWidth)) - val ramWrMask = Wire(UInt(width=ramDataWidth)) - val ramWrEn = Wire(Bool()) - - val dbRamAddr = Wire(UInt(width=dbRamAddrWidth)) + val dbRamAddr = Wire(UInt(width=ramAddrWidth)) val dbRamAddrValid = Wire(Bool()) - val dbRamRdData = Wire (UInt(width=dbRamDataWidth)) - val dbRamWrData = Wire(UInt(width=dbRamDataWidth)) + val dbRamRdData = Wire (UInt(width=ramDataWidth)) + val dbRamWrData = Wire(UInt(width=ramDataWidth)) val dbRamWrEn = Wire(Bool()) val dbRamRdEn = Wire(Bool()) val dbRamWrEnFinal = Wire(Bool()) val dbRamRdEnFinal = Wire(Bool()) - val sbRamAddr = Wire(UInt(width=sbRamAddrWidth)) - val sbRamAddrValid = Wire(Bool()) - val sbRamRdData = Wire (UInt(width=sbRamDataWidth)) - val sbRamWrData = Wire(UInt(width=sbRamDataWidth)) - val sbRamWrEn = Wire(Bool()) - val sbRamRdEn = Wire(Bool()) - val sbRamWrEnFinal = Wire(Bool()) - val sbRamRdEnFinal = Wire(Bool()) - - - val sbRomRdData = Wire(UInt(width=tlDataBits)) - val sbRomAddrOffset = log2Up(tlDataBits/8) - // --- Debug Bus Accesses val dbRdEn = Wire(Bool()) @@ -513,16 +498,6 @@ class DebugModule ()(implicit val p:cde.Parameters) val rdCondWrFailure = Wire(Bool()) val dbWrNeeded = Wire(Bool()) - // --- System Bus Access - val sbAddr = Wire(UInt(width=sbAddrWidth)) - val sbRdData = Wire(UInt(width=tlDataBits)) - val sbWrData = Wire(UInt(width=tlDataBits)) - val sbWrMask = Wire(UInt(width=tlDataBits)) - val sbWrEn = Wire(Bool()) - val sbRdEn = Wire(Bool()) - - val stallFromDb = Wire(Bool()) - val stallFromSb = Wire(Bool()) //-------------------------------------------------------------- // Interrupt Registers //-------------------------------------------------------------- @@ -622,63 +597,32 @@ class DebugModule ()(implicit val p:cde.Parameters) HALTSUMRdData.acks := haltnotSummary //-------------------------------------------------------------- - // Debug RAM Access (Debug Bus & System Bus) + // Debug RAM Access (Debug Bus ... System Bus can override) //-------------------------------------------------------------- dbReq := io.db.req.bits // Debug Bus RAM Access // From Specification: Debug RAM is 0x00 - 0x0F // 0x40 - 0x6F Not Implemented - dbRamAddr := dbReq.addr( dbRamAddrWidth-1 , 0) + dbRamAddr := dbReq.addr( ramAddrWidth-1 , 0) dbRamWrData := dbReq.data dbRamAddrValid := Bool(true) - if (dbRamAddrWidth < 4){ - dbRamAddrValid := (dbReq.addr(3, dbRamAddrWidth) === UInt(0)) + if (ramAddrWidth < 4){ + dbRamAddrValid := (dbReq.addr(3, ramAddrWidth) === UInt(0)) } - sbRamAddr := sbAddr(sbRamAddrWidth + sbRamAddrOffset - 1, sbRamAddrOffset) - sbRamWrData := sbWrData - sbRamAddrValid := Bool(true) - // From Specification: Debug RAM is 0x400 - 0x4FF - if ((sbRamAddrWidth + sbRamAddrOffset) < 8){ - sbRamAddrValid := (sbAddr(7, sbRamAddrWidth + sbRamAddrOffset) === UInt(0)) + val dbRamRdDataFields = List.tabulate(cfg.nDebugRamBytes / ramDataBytes) { ii => + val slice = ramMem.slice(ii * ramDataBytes, (ii+1)*ramDataBytes) + slice.reduce[UInt]{ case (x: UInt, y: UInt) => Cat(y, x)} } - require (dbRamAddrWidth >= ramAddrWidth) // SB accesses less than 32 bits Not Implemented. - val dbRamWrMask = Wire(init=Vec.fill(1 << (dbRamAddrWidth - ramAddrWidth)){Fill(dbRamDataWidth, UInt(1, width=1))}) + dbRamRdData := dbRamRdDataFields(dbRamAddr) - if (dbRamDataWidth < ramDataWidth){ - - val dbRamSel = dbRamAddr(dbRamAddrWidth - ramAddrWidth - 1 , 0) - val rdDataWords = Vec.tabulate(1 << (dbRamAddrWidth - ramAddrWidth)){ ii => - ramRdData((ii+1)*dbRamDataWidth - 1 , ii*dbRamDataWidth)} - - dbRamWrMask := Vec.fill(1 << (dbRamAddrWidth - ramAddrWidth)){UInt(0, width = dbRamDataWidth)} - dbRamWrMask(dbRamSel) := Fill(dbRamDataWidth, UInt(1, width=1)) - dbRamRdData := rdDataWords(dbRamSel) - } else { - dbRamRdData := ramRdData + when (dbRamWrEnFinal) { + for (ii <- 0 until ramDataBytes) { + ramMem(dbRamAddr * UInt(ramDataBytes) + UInt(ii)) := dbRamWrData((8*(ii+1)-1), (8*ii)) + } } - - sbRamRdData := ramRdData - - ramWrMask := Mux(sbRamWrEn, sbWrMask, dbRamWrMask.asUInt) - - assert (!((dbRamWrEn | dbRamRdEn) & (sbRamRdEn | sbRamWrEn)), "Stall logic should have prevented concurrent SB/DB RAM Access") - - // Make copies of DB RAM data before writing. - val dbRamWrDataVec = Fill(1 << (dbRamAddrWidth - ramAddrWidth), dbRamWrData) - ramWrData := Mux(sbRamWrEn, - (ramWrMask & sbRamWrData ) | (~ramWrMask & ramRdData), - (ramWrMask & dbRamWrDataVec) | (~ramWrMask & ramRdData)) - - ramAddr := Mux(sbRamWrEn | sbRamRdEn, sbRamAddr, - dbRamAddr >> (dbRamAddrWidth - ramAddrWidth)) - - ramRdData := ramMem(ramAddr) - when (ramWrEn) { ramMem(ramAddr) := ramWrData } - - ramWrEn := sbRamWrEnFinal | dbRamWrEnFinal //-------------------------------------------------------------- // Debug Bus Access @@ -813,8 +757,8 @@ class DebugModule ()(implicit val p:cde.Parameters) // ----------------------------------------- // DB Access State Machine Decode (Combo) - io.db.req.ready := !stallFromSb && ((dbStateReg === s_DB_READY) || - (dbStateReg === s_DB_RESP && io.db.resp.fire())) + io.db.req.ready := (dbStateReg === s_DB_READY) || + (dbStateReg === s_DB_RESP && io.db.resp.fire()) io.db.resp.valid := (dbStateReg === s_DB_RESP) io.db.resp.bits := dbRespReg @@ -844,172 +788,37 @@ class DebugModule ()(implicit val p:cde.Parameters) // Debug ROM //-------------------------------------------------------------- - sbRomRdData := UInt(0) - if (cfg.hasDebugRom) { + val romRegFields = if (cfg.hasDebugRom) { // Inspired by ROMSlave val romContents = cfg.debugRomContents.get - val romByteWidth = tlDataBits / 8 + val romByteWidth = ramDataWidth / 8 val romRows = (romContents.size + romByteWidth - 1)/romByteWidth - val romMem = Vec.tabulate(romRows) { ii => + List.tabulate(romRows) { ii => { val slice = romContents.slice(ii*romByteWidth, (ii+1)*romByteWidth) - UInt(slice.foldRight(BigInt(0)) { case (x,y) => ((y << 8) + (x.toInt & 0xFF))}, width = romByteWidth*8) + val line = UInt(slice.foldRight(BigInt(0)) { case (x,y) => ((y << 8) + (x.toInt & 0xFF))}, width = romByteWidth*8) + RegField.r(ramDataWidth, line) } - - val sbRomRdAddr = Wire(UInt()) - - if (romRows == 1) { - sbRomRdAddr := UInt(0) - } else { - sbRomRdAddr := sbAddr(log2Up(romRows) + sbRomAddrOffset - 1, sbRomAddrOffset) } - sbRomRdData := romMem (sbRomRdAddr) + } else { + Seq(RegField(ramDataWidth)) } - + //-------------------------------------------------------------- // System Bus Access //-------------------------------------------------------------- - - // ----------------------------------------- - // SB Access Write Decoder - - sbRamWrEn := Bool(false) - sbRamWrEnFinal := Bool(false) - SETHALTNOTWrEn := Bool(false) - CLEARDEBINTWrEn := Bool(false) - - if (tlDataBits == 32) { - SETHALTNOTWrData := sbWrData - CLEARDEBINTWrData := sbWrData - when (sbAddr(11, 8) === UInt(4)){ // 0x400-0x4ff is Debug RAM - sbRamWrEn := sbWrEn - sbRamRdEn := sbRdEn - when (sbRamAddrValid) { - sbRamWrEnFinal := sbWrEn - sbRamRdEnFinal := sbRdEn - } - }.elsewhen (sbAddr === SETHALTNOT){ - SETHALTNOTWrEn := sbWrEn - }.elsewhen (sbAddr === CLEARDEBINT){ - CLEARDEBINTWrEn := sbWrEn - }.otherwise { - //Other registers/RAM are Not Implemented. - } - } else { - - // Pick out the correct word based on the address. - val sbWrDataWords = Vec.tabulate (tlDataBits / 32) {ii => sbWrData((ii+1)*32 - 1, ii*32)} - val sbWrMaskWords = Vec.tabulate (tlDataBits / 32) {ii => sbWrMask ((ii+1)*32 -1, ii*32)} - - val sbWrSelTop = log2Up(tlDataBits/8) - 1 - val sbWrSelBottom = 2 - - SETHALTNOTWrData := sbWrDataWords(SETHALTNOT(sbWrSelTop, sbWrSelBottom)) - CLEARDEBINTWrData := sbWrDataWords(CLEARDEBINT(sbWrSelTop, sbWrSelBottom)) - - when (sbAddr(11,8) === UInt(4)){ //0x400-0x4ff is Debug RAM - sbRamWrEn := sbWrEn - sbRamRdEn := sbRdEn - when (sbRamAddrValid){ - sbRamWrEnFinal := sbWrEn - sbRamRdEnFinal := sbRdEn - } - } - - SETHALTNOTWrEn := sbAddr(sbAddrWidth - 1, sbWrSelTop + 1) === SETHALTNOT(sbAddrWidth-1, sbWrSelTop + 1) && - (sbWrMaskWords(SETHALTNOT(sbWrSelTop, sbWrSelBottom))).orR && - sbWrEn - - CLEARDEBINTWrEn := sbAddr(sbAddrWidth - 1, sbWrSelTop + 1) === CLEARDEBINT(sbAddrWidth-1, sbWrSelTop + 1) && - (sbWrMaskWords(CLEARDEBINT(sbWrSelTop, sbWrSelBottom))).orR && - sbWrEn - + // Local reg mapper function : Notify when written, but give the value. + def wValue (n: Int, value: UInt, set: Bool) : RegField = { + RegField(n, value, RegWriteFn((valid, data) => {set := valid ; value := data; Bool(true)})) } - // ----------------------------------------- - // SB Access Read Mux - - sbRdData := UInt(0) - sbRamRdEn := Bool(false) - sbRamRdEnFinal := Bool(false) - - when (sbAddr(11, 8) === UInt(4)) { //0x400-0x4FF Debug RAM - sbRamRdEn := sbRdEn - when (sbRamAddrValid) { - sbRdData := sbRamRdData - sbRamRdEnFinal := sbRdEn - } - }.elsewhen (sbAddr(11,8).isOneOf(UInt(8), UInt(9))){ //0x800-0x9FF Debug ROM - if (cfg.hasDebugRom) { - sbRdData := sbRomRdData - } else { - sbRdData := UInt(0) - } - }. otherwise { - // All readable registers are Not Implemented. - sbRdData := UInt(0) - } - - // ----------------------------------------- - // SB Access State Machine -- based on BRAM Slave - - val sbAcqReg = Reg(io.tl.acquire.bits) - val sbAcqValidReg = Reg(init = Bool(false)) - - val (sbReg_get :: sbReg_getblk :: sbReg_put :: sbReg_putblk :: Nil) = Seq( - Acquire.getType, Acquire.getBlockType, Acquire.putType, Acquire.putBlockType - ).map(sbAcqReg.isBuiltInType _) - - val sbMultibeat = sbReg_getblk & sbAcqValidReg; - - val sbBeatInc1 = sbAcqReg.addr_beat + UInt(1) - - val sbLast = (sbAcqReg.addr_beat === UInt(tlDataBeats - 1)) - - sbAddr := sbAcqReg.full_addr() - sbRdEn := (sbAcqValidReg && (sbReg_get || sbReg_getblk)) - sbWrEn := (sbAcqValidReg && (sbReg_put || sbReg_putblk)) - sbWrData := sbAcqReg.data - sbWrMask := sbAcqReg.full_wmask() - - // ----------------------------------------- - // SB Access State Machine Update (Seq) - - when (io.tl.acquire.fire()){ - sbAcqReg := io.tl.acquire.bits - sbAcqValidReg := Bool(true) - } .elsewhen (io.tl.grant.fire()) { - when (sbMultibeat){ - sbAcqReg.addr_beat := sbBeatInc1 - when (sbLast) { - sbAcqValidReg := Bool(false) - } - } . otherwise { - sbAcqValidReg := Bool(false) - } - } - - - io.tl.grant.valid := sbAcqValidReg - io.tl.grant.bits := Grant( - is_builtin_type = Bool(true), - g_type = sbAcqReg.getBuiltInGrantType(), - client_xact_id = sbAcqReg.client_xact_id, - manager_xact_id = UInt(0), - addr_beat = sbAcqReg.addr_beat, - data = sbRdData + regmap( + CLEARDEBINT -> Seq(wValue(sbIdWidth, CLEARDEBINTWrData, CLEARDEBINTWrEn)), + SETHALTNOT -> Seq(wValue(sbIdWidth, SETHALTNOTWrData, SETHALTNOTWrEn)), + RAMBASE -> ramMem.map(x => RegField(8, x)), + ROMBASE -> romRegFields ) - stallFromDb := Bool(false) // SB always wins, and DB latches its read data so it is not necessary for SB to wait - - stallFromSb := sbRamRdEn || sbRamWrEn // pessimistically assume that DB/SB are going to conflict on the RAM, - // and SB doesn't latch its read data to it is necessary for DB hold - // off while SB is accessing the RAM and waiting to send its result. - - val sbStall = (sbMultibeat & !sbLast) || (io.tl.grant.valid && !io.tl.grant.ready) || stallFromDb - - io.tl.acquire.ready := !sbStall - //-------------------------------------------------------------- // Misc. Outputs //-------------------------------------------------------------- @@ -1019,6 +828,21 @@ class DebugModule ()(implicit val p:cde.Parameters) } +/** Create a concrete TL2 Slave for the DebugModule RegMapper interface. + * + */ + +class TLDebugModule(beatBytes: Int) (implicit p: Parameters) + extends TLRegisterRouter(0x0, beatBytes=beatBytes)( + new TLRegBundle(p, _ ) with DebugModuleBundle)( + new TLRegModule(p, _, _) with DebugModule) + + +/** Synchronizers for DebugBus + * + */ + + object AsyncDebugBusCrossing { // takes from_source from the 'from' clock domain to the 'to' clock domain def apply(from_clock: Clock, from_reset: Bool, from_source: DebugBusIO, to_clock: Clock, to_reset: Bool, depth: Int = 1, sync: Int = 3) = { @@ -1029,6 +853,7 @@ object AsyncDebugBusCrossing { } } + object AsyncDebugBusFrom { // OutsideClockDomain // takes from_source from the 'from' clock domain and puts it into your clock domain def apply(from_clock: Clock, from_reset: Bool, from_source: DebugBusIO, depth: Int = 1, sync: Int = 3): DebugBusIO = { From af924d8c5112b7f92f4f6bffce47dc661fa707b3 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Mon, 24 Oct 2016 19:01:32 -0700 Subject: [PATCH 02/47] DebugModule: Instantiate TL2 DebugModule in BaseCoreplex --- src/main/scala/coreplex/BaseCoreplex.scala | 19 ++++++++++++++----- 1 file changed, 14 insertions(+), 5 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 22d26ca1..a50a1ff0 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -48,7 +48,17 @@ case class CoreplexConfig( val plicKey = PLICConfig(nTiles, hasSupervisor, nExtInterrupts, nInterruptPriorities) } -abstract class BaseCoreplex(c: CoreplexConfig)(implicit p: Parameters) extends LazyModule +abstract class BaseCoreplex(c: CoreplexConfig)(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { + + val debugLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) + val debugModule = LazyModule(new TLDebugModule(p(XLen)/8)) + debugModule.node := + TLHintHandler()( + TLBuffer()( + TLFragmenter(p(XLen)/8, debugLegacy.tlDataBeats * debugLegacy.tlDataBytes)( + TLWidthWidget(debugLegacy.tlDataBytes)(debugLegacy.node)))) + +} abstract class BaseCoreplexBundle(val c: CoreplexConfig)(implicit val p: Parameters) extends Bundle with HasCoreplexParameters { val master = new Bundle { @@ -140,16 +150,15 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( plic.io.devices(i) <> gateway.io.plic } - val debugModule = Module(new DebugModule) - debugModule.io.tl <> cBus.port("cbus:debug") - debugModule.io.db <> io.debug + outer.debugLegacy.module.io.legacy <> cBus.port("cbus:debug") + outer.debugModule.module.io.db <> io.debug // connect coreplex-internal interrupts to tiles for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { tile.interrupts <> io.clint(i) tile.interrupts.meip := plic.io.harts(plic.cfg.context(i, 'M')) tile.interrupts.seip.foreach(_ := plic.io.harts(plic.cfg.context(i, 'S'))) - tile.interrupts.debug := debugModule.io.debugInterrupts(i) + tile.interrupts.debug := outer.debugModule.module.io.debugInterrupts(i) tile.hartid := UInt(i) tile.resetVector := io.resetVector } From 0dbda2f07d53f017442361e93315ca95157d4942 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 14:09:26 -0700 Subject: [PATCH 03/47] rocketchip: remove obsolete pDevices used during TL1=>2 migration --- src/main/scala/rocketchip/BaseTop.scala | 5 ++--- src/main/scala/rocketchip/Utils.scala | 13 +++---------- 2 files changed, 5 insertions(+), 13 deletions(-) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index a7d9836f..826a5405 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -27,7 +27,6 @@ abstract class BaseTop(q: Parameters) extends LazyModule { // the following variables will be refactored properly with TL2 val pInterrupts = new RangeManager val pBusMasters = new RangeManager - val pDevices = new ResourceManager[AddrMapEntry] TLImp.emitMonitors = q(TLEmitMonitors) @@ -44,10 +43,10 @@ abstract class BaseTop(q: Parameters) extends LazyModule { hasSupervisor = q(UseVM) ) - lazy val genGlobalAddrMap = GenerateGlobalAddrMap(q, pDevices.get, peripheryManagers) + lazy val genGlobalAddrMap = GenerateGlobalAddrMap(q, peripheryManagers) private val qWithMap = q.alterPartial({case GlobalAddrMap => genGlobalAddrMap}) - lazy val genConfigString = GenerateConfigString(qWithMap, c, pDevices.get, peripheryManagers) + lazy val genConfigString = GenerateConfigString(qWithMap, c, peripheryManagers) implicit val p = qWithMap.alterPartial({ case ConfigString => genConfigString case NCoreplexExtClients => pBusMasters.sum}) diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index 69a7d338..1bed6832 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -53,7 +53,7 @@ class GlobalVariable[T] { } object GenerateGlobalAddrMap { - def apply(p: Parameters, pDevicesEntries: Seq[AddrMapEntry], peripheryManagers: Seq[TLManagerParameters]) = { + def apply(p: Parameters, peripheryManagers: Seq[TLManagerParameters]) = { lazy val cBusIOAddrMap: AddrMap = { val entries = collection.mutable.ArrayBuffer[AddrMapEntry]() entries += AddrMapEntry("debug", MemSize(4096, MemAttr(AddrMapProt.RWX))) @@ -90,7 +90,7 @@ object GenerateGlobalAddrMap { }).flatten.toList lazy val tl2AddrMap = new AddrMap(uniquelyNamedTL2Devices, collapse = true) - lazy val pBusIOAddrMap = new AddrMap(AddrMapEntry("TL2", tl2AddrMap) +: (p(ExtMMIOPorts) ++ pDevicesEntries), collapse = true) + lazy val pBusIOAddrMap = new AddrMap(AddrMapEntry("TL2", tl2AddrMap) +: p(ExtMMIOPorts), collapse = true) val memBase = 0x80000000L val memSize = p(ExtMemSize) @@ -105,7 +105,7 @@ object GenerateGlobalAddrMap { } object GenerateConfigString { - def apply(p: Parameters, c: CoreplexConfig, pDevicesEntries: Seq[AddrMapEntry], peripheryManagers: Seq[TLManagerParameters]) = { + def apply(p: Parameters, c: CoreplexConfig, peripheryManagers: Seq[TLManagerParameters]) = { val addrMap = p(GlobalAddrMap) val plicAddr = addrMap("io:cbus:plic").start val clint = CoreplexLocalInterrupterConfig(0, addrMap("io:pbus:TL2:clint").start) @@ -160,13 +160,6 @@ object GenerateConfigString { res append " };\n" } res append "};\n" - pDevicesEntries foreach { entry => - val region = addrMap("io:pbus:" + entry.name) - res append s"${entry.name} {\n" - res append s" addr 0x${region.start.toString(16)};\n" - res append s" size 0x${region.size.toString(16)}; \n" - res append "}\n" - } peripheryManagers.foreach { manager => res append manager.dts } res append '\u0000' res.toString From 0ae45d0f247ae7abf83ff49519522f00a0aaa03a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 14:28:52 -0700 Subject: [PATCH 04/47] rocketchip: bundle (=> B) need not be delayed; Module is constructed later --- src/main/scala/coreplex/BaseCoreplex.scala | 2 +- src/main/scala/coreplex/Coreplex.scala | 4 ++-- src/main/scala/groundtest/Coreplex.scala | 2 +- src/main/scala/rocketchip/BaseTop.scala | 7 +++---- src/main/scala/rocketchip/ExampleTop.scala | 4 ++-- 5 files changed, 9 insertions(+), 10 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index a50a1ff0..63da5222 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -76,7 +76,7 @@ abstract class BaseCoreplexBundle(val c: CoreplexConfig)(implicit val p: Paramet } abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( - c: CoreplexConfig, l: L, b: => B)(implicit val p: Parameters) extends LazyModuleImp(l) with HasCoreplexParameters { + c: CoreplexConfig, l: L, b: B)(implicit val p: Parameters) extends LazyModuleImp(l) with HasCoreplexParameters { val outer: L = l val io: B = b diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index bbd39367..1e4fc37a 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -34,7 +34,7 @@ class DefaultCoreplex(c: CoreplexConfig)(implicit p: Parameters) extends BaseCor class DefaultCoreplexBundle(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplexBundle(c)(p) class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle]( - c: CoreplexConfig, l: L, b: => B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) + c: CoreplexConfig, l: L, b: B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) with DirectConnection ///// @@ -81,5 +81,5 @@ class MultiClockCoreplexBundle(c: CoreplexConfig)(implicit p: Parameters) extend with TileClockResetBundle class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle]( - c: CoreplexConfig, l: L, b: => B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) + c: CoreplexConfig, l: L, b: B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) with AsyncConnection diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index e4492e1c..35580996 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -11,6 +11,6 @@ class GroundTestCoreplex(c: CoreplexConfig)(implicit p: Parameters) extends Base class GroundTestCoreplexBundle(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplexBundle(c)(p) class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle]( - c: CoreplexConfig, l: L, b: => B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) with DirectConnection { + c: CoreplexConfig, l: L, b: B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) with DirectConnection { io.success := tiles.flatMap(_.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_) } diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 826a5405..756951ad 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -72,10 +72,9 @@ abstract class BaseTopBundle(val p: Parameters) extends Bundle { } abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle]( - val p: Parameters, l: L, b: => B) extends LazyModuleImp(l) { - val outer: L = l - val io: B = b - + val p: Parameters, + val outer: L, + val io: B) extends LazyModuleImp(outer) { val coreplex = p(BuildCoreplex)(outer.c, p) val coreplexIO = Wire(coreplex.io) diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index aef3dce9..35b0d74c 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -29,7 +29,7 @@ class ExampleTopBundle(p: Parameters) extends BaseTopBundle(p) with PeripheryMasterMMIOBundle with PeripherySlaveBundle -class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, l: L, b: => B) extends BaseTopModule(p, l, b) +class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, l: L, b: B) extends BaseTopModule(p, l, b) with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule @@ -49,5 +49,5 @@ class ExampleTopWithTestRAM(q: Parameters) extends ExampleTop(q) class ExampleTopWithTestRAMBundle(p: Parameters) extends ExampleTopBundle(p) with PeripheryTestRAMBundle -class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM, +B <: ExampleTopWithTestRAMBundle](p: Parameters, l: L, b: => B) extends ExampleTopModule(p, l, b) +class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM, +B <: ExampleTopWithTestRAMBundle](p: Parameters, l: L, b: B) extends ExampleTopModule(p, l, b) with PeripheryTestRAMModule From ec2d23b8b7b23272c55aa42d571772c08b440a68 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 14:38:14 -0700 Subject: [PATCH 05/47] rocketchip: Bundle-slices need access to the outer LazyModule We need this change in order for some ports to use parameters that result from LazyModule diplomacy. Now you can eat your cake too! --- src/main/scala/rocketchip/BaseTop.scala | 6 ++++-- src/main/scala/rocketchip/ExampleTop.scala | 12 ++++++------ 2 files changed, 10 insertions(+), 8 deletions(-) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 756951ad..3cec7521 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -67,11 +67,13 @@ abstract class BaseTop(q: Parameters) extends LazyModule { TopModule.contents = Some(this) } -abstract class BaseTopBundle(val p: Parameters) extends Bundle { +abstract class BaseTopBundle[+L <: BaseTop]( + val p: Parameters, + val outer: L) extends Bundle { val success = Bool(OUTPUT) } -abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle]( +abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]]( val p: Parameters, val outer: L, val io: B) extends LazyModuleImp(outer) { diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 35b0d74c..03a67412 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -17,10 +17,10 @@ class ExampleTop(q: Parameters) extends BaseTop(q) with PeripheryMasterMem with PeripheryMasterMMIO with PeripherySlave { - override lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p))) + override lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p, this))) } -class ExampleTopBundle(p: Parameters) extends BaseTopBundle(p) +class ExampleTopBundle[+L <: ExampleTop](p: Parameters, l: L) extends BaseTopBundle(p, l) with PeripheryBootROMBundle with PeripheryDebugBundle with PeripheryExtInterruptsBundle @@ -29,7 +29,7 @@ class ExampleTopBundle(p: Parameters) extends BaseTopBundle(p) with PeripheryMasterMMIOBundle with PeripherySlaveBundle -class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, l: L, b: B) extends BaseTopModule(p, l, b) +class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](p: Parameters, l: L, b: B) extends BaseTopModule(p, l, b) with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule @@ -43,11 +43,11 @@ class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle](p: Parameters, /** Example Top with TestRAM */ class ExampleTopWithTestRAM(q: Parameters) extends ExampleTop(q) with PeripheryTestRAM { - override lazy val module = Module(new ExampleTopWithTestRAMModule(p, this, new ExampleTopWithTestRAMBundle(p))) + override lazy val module = Module(new ExampleTopWithTestRAMModule(p, this, new ExampleTopWithTestRAMBundle(p, this))) } -class ExampleTopWithTestRAMBundle(p: Parameters) extends ExampleTopBundle(p) +class ExampleTopWithTestRAMBundle[+L <: ExampleTopWithTestRAM](p: Parameters, l: L) extends ExampleTopBundle(p, l) with PeripheryTestRAMBundle -class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM, +B <: ExampleTopWithTestRAMBundle](p: Parameters, l: L, b: B) extends ExampleTopModule(p, l, b) +class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM, +B <: ExampleTopWithTestRAMBundle[L]](p: Parameters, l: L, b: B) extends ExampleTopModule(p, l, b) with PeripheryTestRAMModule From 082f338432b2b479e50b8d648da5564a26403b6e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 17:42:00 -0700 Subject: [PATCH 06/47] diplomacy Nodes: remove useless indirection --- src/main/scala/diplomacy/Nodes.scala | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index db6b3513..6a218cc5 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -94,7 +94,7 @@ trait InwardNode[DI, UI, BI <: Data] extends BaseNode with InwardNodeHandle[DI, protected[diplomacy] lazy val iPorts = { iRealized = true; reqI(); accPI.result() } protected[diplomacy] val iParams: Seq[UI] - protected[diplomacy] def iConnect: Vec[BI] + val bundleIn: Vec[BI] } trait OutwardNodeHandle[DO, UO, BO <: Data] @@ -126,7 +126,7 @@ trait OutwardNode[DO, UO, BO <: Data] extends BaseNode with OutwardNodeHandle[DO protected[diplomacy] lazy val oPorts = { oRealized = true; reqO(); accPO.result() } protected[diplomacy] val oParams: Seq[DO] - protected[diplomacy] def oConnect: Vec[BO] + val bundleOut: Vec[BO] } class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( @@ -164,9 +164,6 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( lazy val bundleOut = outer.bundleO(edgesOut) lazy val bundleIn = inner.bundleI(edgesIn) - def oConnect = bundleOut - def iConnect = bundleIn - // connects the outward part of a node with the inward part of this node override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit sourceInfo: SourceInfo): Option[LazyModule] = { val x = this // x := y @@ -177,7 +174,7 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( val o = y.oPushed y.oPush(i, x) x.iPush(o, y) - val (out, binding) = inner.connect(y.oConnect(o), x.iConnect(i), x.edgesIn(i)) + val (out, binding) = inner.connect(y.bundleOut(o), x.bundleIn(i), x.edgesIn(i)) LazyModule.stack.head.bindings = binding :: LazyModule.stack.head.bindings out } @@ -195,14 +192,12 @@ class IdentityNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) class OutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) extends IdentityNode(imp) { - override def oConnect = bundleOut - override def iConnect = bundleOut + override lazy val bundleIn = bundleOut } class InputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) extends IdentityNode(imp) { - override def oConnect = bundleIn - override def iConnect = bundleIn + override lazy val bundleOut = bundleIn } class SourceNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: PO, num: Range.Inclusive = 1 to 1) From 0edcd3304a2b7b2f6ed281a7947cfd094ec0fcd6 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 17:47:32 -0700 Subject: [PATCH 07/47] diplomacy Nodes: leave flipping to the MixedNode implementation --- src/main/scala/diplomacy/Nodes.scala | 8 ++++++-- src/main/scala/uncore/axi4/Nodes.scala | 2 +- src/main/scala/uncore/tilelink2/IntNodes.scala | 2 +- src/main/scala/uncore/tilelink2/Nodes.scala | 4 ++-- 4 files changed, 10 insertions(+), 6 deletions(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 6a218cc5..949921b9 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -161,8 +161,12 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( lazy val edgesOut = (oPorts zip oParams).map { case ((i, n), o) => outer.edgeO(o, n.iParams(i)) } lazy val edgesIn = (iPorts zip iParams).map { case ((o, n), i) => inner.edgeI(n.oParams(o), i) } - lazy val bundleOut = outer.bundleO(edgesOut) - lazy val bundleIn = inner.bundleI(edgesIn) + val flip = false // needed for blind nodes + private def flipO(b: Vec[BO]) = if (flip) b.flip else b + private def flipI(b: Vec[BI]) = if (flip) b else b.flip + + lazy val bundleOut = flipO(outer.bundleO(edgesOut)) + lazy val bundleIn = flipI(inner.bundleI(edgesIn)) // connects the outward part of a node with the inward part of this node override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit sourceInfo: SourceInfo): Option[LazyModule] = { diff --git a/src/main/scala/uncore/axi4/Nodes.scala b/src/main/scala/uncore/axi4/Nodes.scala index 0613a70b..3417e8f0 100644 --- a/src/main/scala/uncore/axi4/Nodes.scala +++ b/src/main/scala/uncore/axi4/Nodes.scala @@ -16,7 +16,7 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters } def bundleI(ei: Seq[AXI4EdgeParameters]): Vec[AXI4Bundle] = { require (!ei.isEmpty) - Vec(ei.size, AXI4Bundle(ei.map(_.bundle).reduce(_.union(_)))).flip + Vec(ei.size, AXI4Bundle(ei.map(_.bundle).reduce(_.union(_)))) } def colour = "#00ccff" // bluish diff --git a/src/main/scala/uncore/tilelink2/IntNodes.scala b/src/main/scala/uncore/tilelink2/IntNodes.scala index 639d03ed..79fd4990 100644 --- a/src/main/scala/uncore/tilelink2/IntNodes.scala +++ b/src/main/scala/uncore/tilelink2/IntNodes.scala @@ -58,7 +58,7 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In } def bundleI(ei: Seq[IntEdge]): Vec[Vec[Bool]] = { require (!ei.isEmpty) - Vec(ei.size, Vec(ei.map(_.source.num).max, Bool())).flip + Vec(ei.size, Vec(ei.map(_.source.num).max, Bool())) } def colour = "#0000ff" // blue diff --git a/src/main/scala/uncore/tilelink2/Nodes.scala b/src/main/scala/uncore/tilelink2/Nodes.scala index 24668401..b395461b 100644 --- a/src/main/scala/uncore/tilelink2/Nodes.scala +++ b/src/main/scala/uncore/tilelink2/Nodes.scala @@ -17,7 +17,7 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL } def bundleI(ei: Seq[TLEdgeIn]): Vec[TLBundle] = { require (!ei.isEmpty) - Vec(ei.size, TLBundle(ei.map(_.bundle).reduce(_.union(_)))).flip + Vec(ei.size, TLBundle(ei.map(_.bundle).reduce(_.union(_)))) } var emitMonitors = true @@ -149,7 +149,7 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor } def bundleI(ei: Seq[TLAsyncEdgeParameters]): Vec[TLAsyncBundle] = { require (ei.size == 1) - Vec(ei.size, new TLAsyncBundle(ei(0).bundle)).flip + Vec(ei.size, new TLAsyncBundle(ei(0).bundle)) } def colour = "#ff0000" // red From 650f6fb23f1340e4770b63ad5c0c30ec4de60515 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 18:04:26 -0700 Subject: [PATCH 08/47] diplomacy: add BlindNodes for use as external ports --- src/main/scala/diplomacy/Nodes.scala | 16 ++++++++++++++++ src/main/scala/uncore/axi4/Nodes.scala | 13 +++++++++---- src/main/scala/uncore/tilelink2/Nodes.scala | 12 +++++++++--- 3 files changed, 34 insertions(+), 7 deletions(-) diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 949921b9..633ece07 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -208,12 +208,28 @@ class SourceNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: extends SimpleNode(imp)({case (n, Seq()) => Seq.fill(n)(po)}, {case (0, _) => Seq()}, num, 0 to 0) { require (num.end >= 1, s"${name} is a source which does not accept outputs${lazyModule.line}") + override lazy val bundleIn = { require(false, s"${name} has no bundleIn; try bundleOut?"); bundleOut } } class SinkNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: PI, num: Range.Inclusive = 1 to 1) extends SimpleNode(imp)({case (0, _) => Seq()}, {case (n, Seq()) => Seq.fill(n)(pi)}, 0 to 0, num) { require (num.end >= 1, s"${name} is a sink which does not accept inputs${lazyModule.line}") + override lazy val bundleOut = { require(false, s"${name} has no bundleOut; try bundleIn?"); bundleIn } +} + +class BlindOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: PI) + extends SimpleNode(imp)({case (0, _) => Seq()}, {case (n, Seq()) => Seq.fill(n)(pi)}, 0 to 0, 1 to 1) +{ + override val flip = true + override lazy val bundleOut = bundleIn +} + +class BlindInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: PO) + extends SimpleNode(imp)({case (n, Seq()) => Seq.fill(n)(po)}, {case (0, _) => Seq()}, 1 to 1, 0 to 0) +{ + override val flip = true + override lazy val bundleIn = bundleOut } class InteriorNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) diff --git a/src/main/scala/uncore/axi4/Nodes.scala b/src/main/scala/uncore/axi4/Nodes.scala index 3417e8f0..2c728e06 100644 --- a/src/main/scala/uncore/axi4/Nodes.scala +++ b/src/main/scala/uncore/axi4/Nodes.scala @@ -30,18 +30,23 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters pu.copy(slaves = pu.slaves.map { m => m.copy (nodePath = node +: m.nodePath) }) } +// Nodes implemented inside modules case class AXI4IdentityNode() extends IdentityNode(AXI4Imp) -case class AXI4OutputNode() extends OutputNode(AXI4Imp) -case class AXI4InputNode() extends InputNode(AXI4Imp) - case class AXI4MasterNode(portParams: AXI4MasterPortParameters, numPorts: Range.Inclusive = 1 to 1) extends SourceNode(AXI4Imp)(portParams, numPorts) case class AXI4SlaveNode(portParams: AXI4SlavePortParameters, numPorts: Range.Inclusive = 1 to 1) extends SinkNode(AXI4Imp)(portParams, numPorts) - case class AXI4AdapterNode( masterFn: Seq[AXI4MasterPortParameters] => AXI4MasterPortParameters, slaveFn: Seq[AXI4SlavePortParameters] => AXI4SlavePortParameters, numMasterPorts: Range.Inclusive = 1 to 1, numSlavePorts: Range.Inclusive = 1 to 1) extends InteriorNode(AXI4Imp)(masterFn, slaveFn, numMasterPorts, numSlavePorts) + +// Nodes passed from an inner module +case class AXI4OutputNode() extends OutputNode(AXI4Imp) +case class AXI4InputNode() extends InputNode(AXI4Imp) + +// Nodes used for external ports +case class AXI4BlindOutputNode(portParams: AXI4SlavePortParameters) extends BlindOutputNode(AXI4Imp)(portParams) +case class AXI4BlindInputNode(portParams: AXI4MasterPortParameters) extends BlindInputNode(AXI4Imp)(portParams) diff --git a/src/main/scala/uncore/tilelink2/Nodes.scala b/src/main/scala/uncore/tilelink2/Nodes.scala index b395461b..0941dc04 100644 --- a/src/main/scala/uncore/tilelink2/Nodes.scala +++ b/src/main/scala/uncore/tilelink2/Nodes.scala @@ -89,10 +89,8 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL } } +// Nodes implemented inside modules case class TLIdentityNode() extends IdentityNode(TLImp) -case class TLOutputNode() extends OutputNode(TLImp) -case class TLInputNode() extends InputNode(TLImp) - case class TLClientNode(portParams: TLClientPortParameters, numPorts: Range.Inclusive = 1 to 1) extends SourceNode(TLImp)(portParams, numPorts) case class TLManagerNode(portParams: TLManagerPortParameters, numPorts: Range.Inclusive = 1 to 1) @@ -117,6 +115,14 @@ case class TLAdapterNode( numManagerPorts: Range.Inclusive = 1 to 1) extends InteriorNode(TLImp)(clientFn, managerFn, numClientPorts, numManagerPorts) +// Nodes passed from an inner module +case class TLOutputNode() extends OutputNode(TLImp) +case class TLInputNode() extends InputNode(TLImp) + +// Nodes used for external ports +case class TLBlindOutputNode(portParams: TLManagerPortParameters) extends BlindOutputNode(TLImp)(portParams) +case class TLBlindInputNode(portParams: TLClientPortParameters) extends BlindInputNode(TLImp)(portParams) + /** Synthesizeable unit tests */ import unittest._ From 3df797fcab4caf1f581f33c4954aaa104b69defa Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 16:27:42 -0700 Subject: [PATCH 09/47] rocketchip: replace TL1 MMIO with an example of TL2 MMIO --- src/main/scala/rocketchip/Configs.scala | 16 ----- src/main/scala/rocketchip/ExampleTop.scala | 6 +- src/main/scala/rocketchip/Periphery.scala | 74 ++++++++------------- src/main/scala/rocketchip/TestHarness.scala | 4 -- src/main/scala/rocketchip/Utils.scala | 2 +- 5 files changed, 30 insertions(+), 72 deletions(-) diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index e253bfb5..c684b72b 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -48,11 +48,6 @@ class BasePlatformConfig extends Config( // Note that PLIC asserts that this is > 0. case AsyncDebugBus => false case IncludeJtagDTM => false - case AsyncMMIOChannels => false - case ExtMMIOPorts => Nil - case NExtMMIOAXIChannels => 0 - case NExtMMIOAHBChannels => 0 - case NExtMMIOTLChannels => 0 case AsyncBusChannels => false case NExtBusAXIChannels => 0 case HastiId => "Ext" @@ -110,17 +105,6 @@ class WithExtMemSize(n: Long) extends Config( case _ => throw new CDEMatchError } ) -class WithAHB extends Config( - (pname, site, here) => pname match { - case TMemoryChannels => BusType.AHB - case NExtMMIOAHBChannels => 1 - }) - -class WithTL extends Config( - (pname, site, here) => pname match { - case TMemoryChannels => BusType.TL - case NExtMMIOTLChannels => 1 - }) class WithScratchpads extends Config(new WithNMemoryChannels(0) ++ new WithDataScratchpad(16384)) diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 03a67412..2a191a0c 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -15,7 +15,7 @@ class ExampleTop(q: Parameters) extends BaseTop(q) with PeripheryExtInterrupts with PeripheryCoreplexLocalInterrupter with PeripheryMasterMem - with PeripheryMasterMMIO + with PeripheryMasterAXI4MMIO with PeripherySlave { override lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p, this))) } @@ -26,7 +26,7 @@ class ExampleTopBundle[+L <: ExampleTop](p: Parameters, l: L) extends BaseTopBun with PeripheryExtInterruptsBundle with PeripheryCoreplexLocalInterrupterBundle with PeripheryMasterMemBundle - with PeripheryMasterMMIOBundle + with PeripheryMasterAXI4MMIOBundle with PeripherySlaveBundle class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](p: Parameters, l: L, b: B) extends BaseTopModule(p, l, b) @@ -35,7 +35,7 @@ class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](p: Parameter with PeripheryExtInterruptsModule with PeripheryCoreplexLocalInterrupterModule with PeripheryMasterMemModule - with PeripheryMasterMMIOModule + with PeripheryMasterAXI4MMIOModule with PeripherySlaveModule with HardwiredResetVector with DirectConnection diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index d0db2c2a..cdb7a2f2 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -9,6 +9,7 @@ import junctions.NastiConstants._ import diplomacy._ import uncore.tilelink._ import uncore.tilelink2._ +import uncore.axi4._ import uncore.converters._ import uncore.devices._ import uncore.agents._ @@ -29,19 +30,12 @@ object BusType { /** Memory channel controls */ case object TMemoryChannels extends Field[BusType.EnumVal] -/** External MMIO controls */ -case object NExtMMIOAXIChannels extends Field[Int] -case object NExtMMIOAHBChannels extends Field[Int] -case object NExtMMIOTLChannels extends Field[Int] /** External Bus controls */ case object NExtBusAXIChannels extends Field[Int] /** Async configurations */ 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]] /** Specifies the size of external memory */ case object ExtMemSize extends Field[Long] /** Specifies the number of external interrupts */ @@ -204,55 +198,39 @@ trait PeripheryMasterMemModule extends HasPeripheryParameters { ///// -trait PeripheryMasterMMIO extends LazyModule { +// PeripheryMasterAXI4MMIO is an example, make your own cake pattern like this one. +trait PeripheryMasterAXI4MMIO extends BaseTop with HasPeripheryParameters { implicit val p: Parameters + + val mmio_axi4 = AXI4BlindOutputNode(AXI4SlavePortParameters( + slaves = Seq(AXI4SlaveParameters( + address = List(AddressSet(0x60000000L, 0x1fffffffL)), + executable = true, // Can we run programs on this memory? + supportsWrite = TransferSizes(1, 256), // The slave supports 1-256 byte transfers + supportsRead = TransferSizes(1, 256), + interleavedId = Some(0))), // slave does not interleave read responses + beatBytes = 8)) // 64-bit AXI interface + + mmio_axi4 := + // AXI4Fragmenter(lite=false, maxInFlight = 20)( // beef device up to support awlen = 0xff + TLToAXI4(idBits = 4)( // use idBits = 0 for AXI4-Lite + TLWidthWidget(socBusConfig.beatBytes)( // convert width before attaching to socBus + socBus.node)) } -trait PeripheryMasterMMIOBundle extends HasPeripheryParameters { +trait PeripheryMasterAXI4MMIOBundle extends HasPeripheryParameters { implicit val p: Parameters - val mmio_clk = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Clock(INPUT))) - val mmio_rst = p(AsyncMMIOChannels).option(Vec(p(NExtMMIOAXIChannels), Bool (INPUT))) - val mmio_axi = Vec(p(NExtMMIOAXIChannels), new NastiIO) - val mmio_ahb = Vec(p(NExtMMIOAHBChannels), new HastiMasterIO) - val mmio_tl = Vec(p(NExtMMIOTLChannels), new ClientUncachedTileLinkIO()(edgeMMIOParams)) + val outer: PeripheryMasterAXI4MMIO + + val mmio_axi = outer.mmio_axi4.bundleOut } -trait PeripheryMasterMMIOModule extends HasPeripheryParameters { +trait PeripheryMasterAXI4MMIOModule extends HasPeripheryParameters { implicit val p: Parameters - val outer: PeripheryMasterMMIO - val io: PeripheryMasterMMIOBundle - val pBus: TileLinkRecursiveInterconnect + val outer: PeripheryMasterAXI4MMIO + val io: PeripheryMasterAXI4MMIOBundle - val mmio_ports = p(ExtMMIOPorts) map { port => - TileLinkWidthAdapter(pBus.port(port.name), edgeMMIOParams) - } - - val mmio_axi_start = 0 - val mmio_axi_end = mmio_axi_start + p(NExtMMIOAXIChannels) - val mmio_ahb_start = mmio_axi_end - val mmio_ahb_end = mmio_ahb_start + p(NExtMMIOAHBChannels) - val mmio_tl_start = mmio_ahb_end - val mmio_tl_end = mmio_tl_start + p(NExtMMIOTLChannels) - require (mmio_tl_end == mmio_ports.size) - - for (i <- 0 until mmio_ports.size) { - if (mmio_axi_start <= i && i < mmio_axi_end) { - val idx = i-mmio_axi_start - val axi_sync = PeripheryUtils.convertTLtoAXI(mmio_ports(i)) - io.mmio_axi(idx) <> ( - if (!p(AsyncMMIOChannels)) axi_sync - else AsyncNastiTo(io.mmio_clk.get(idx), io.mmio_rst.get(idx), axi_sync) - ) - } else if (mmio_ahb_start <= i && i < mmio_ahb_end) { - val idx = i-mmio_ahb_start - io.mmio_ahb(idx) <> PeripheryUtils.convertTLtoAHB(mmio_ports(i), atomics = true) - } else if (mmio_tl_start <= i && i < mmio_tl_end) { - val idx = i-mmio_tl_start - io.mmio_tl(idx) <> TileLinkEnqueuer(mmio_ports(i), 2) - } else { - require(false, "Unconnected external MMIO port") - } - } + // nothing to do } ///// diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index f09c9b50..c4ba731e 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -25,10 +25,6 @@ class TestHarness(q: Parameters) extends Module { require(dut.io.mem_tl.isEmpty) require(dut.io.bus_clk.isEmpty) require(dut.io.bus_rst.isEmpty) - require(dut.io.mmio_clk.isEmpty) - require(dut.io.mmio_rst.isEmpty) - require(dut.io.mmio_ahb.isEmpty) - require(dut.io.mmio_tl.isEmpty) for (int <- dut.io.interrupts) int := Bool(false) diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index 1bed6832..7558297b 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -90,7 +90,7 @@ object GenerateGlobalAddrMap { }).flatten.toList lazy val tl2AddrMap = new AddrMap(uniquelyNamedTL2Devices, collapse = true) - lazy val pBusIOAddrMap = new AddrMap(AddrMapEntry("TL2", tl2AddrMap) +: p(ExtMMIOPorts), collapse = true) + lazy val pBusIOAddrMap = new AddrMap(Seq(AddrMapEntry("TL2", tl2AddrMap)), collapse = true) val memBase = 0x80000000L val memSize = p(ExtMemSize) From 10d084b9f3461b54bbed4396317d2628b6dc5764 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Wed, 26 Oct 2016 11:23:52 -0700 Subject: [PATCH 10/47] DebugModule: Use the power of RegisterRouter to simplify the DebugROM code. --- src/main/scala/uncore/devices/Debug.scala | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/src/main/scala/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index cae84406..e5cd0af6 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -789,20 +789,11 @@ trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap { //-------------------------------------------------------------- val romRegFields = if (cfg.hasDebugRom) { - // Inspired by ROMSlave - val romContents = cfg.debugRomContents.get - val romByteWidth = ramDataWidth / 8 - val romRows = (romContents.size + romByteWidth - 1)/romByteWidth - List.tabulate(romRows) { ii => { - val slice = romContents.slice(ii*romByteWidth, (ii+1)*romByteWidth) - val line = UInt(slice.foldRight(BigInt(0)) { case (x,y) => ((y << 8) + (x.toInt & 0xFF))}, width = romByteWidth*8) - RegField.r(ramDataWidth, line) - } - } + cfg.debugRomContents.get.map( x => RegField.r(8, UInt(x.toInt & 0xFF))) } else { - Seq(RegField(ramDataWidth)) + Seq(RegField(8)) } - + //-------------------------------------------------------------- // System Bus Access //-------------------------------------------------------------- From c3dacca39a7ae45239226fc883c12c59de4638d9 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Tue, 25 Oct 2016 18:18:06 -0700 Subject: [PATCH 11/47] rocketchip: remove pbus; TL2 has swallowed it completely --- src/main/scala/coreplex/BaseCoreplex.scala | 2 +- src/main/scala/groundtest/Configs.scala | 2 +- src/main/scala/groundtest/Regression.scala | 2 +- src/main/scala/rocketchip/BaseTop.scala | 6 +----- src/main/scala/rocketchip/Utils.scala | 7 +++---- 5 files changed, 7 insertions(+), 12 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 63da5222..3210ec36 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -167,7 +167,7 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( for ((t, m) <- (uncoreTileIOs.map(_.slave).flatten) zip (tileSlavePorts map (cBus port _))) t <> m - io.master.mmio <> cBus.port("pbus") + io.master.mmio <> cBus.port("TL2") } // Coreplex doesn't know when to stop running diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 7f5bc0eb..61dee763 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -121,7 +121,7 @@ class WithComparator extends Config( case BuildGroundTest => (p: Parameters) => Module(new ComparatorCore()(p)) case ComparatorKey => ComparatorParameters( - targets = Seq("mem", "io:pbus:TL2:testram").map(name => + targets = Seq("mem", "io:TL2:testram").map(name => site(GlobalAddrMap)(name).start.longValue), width = 8, operations = 1000, diff --git a/src/main/scala/groundtest/Regression.scala b/src/main/scala/groundtest/Regression.scala index cf0fefe7..093855fe 100644 --- a/src/main/scala/groundtest/Regression.scala +++ b/src/main/scala/groundtest/Regression.scala @@ -71,7 +71,7 @@ class IOGetAfterPutBlockRegression(implicit p: Parameters) extends Regression()( io.mem.grant.ready := Bool(true) io.cache.req.valid := !get_sent && started - io.cache.req.bits.addr := UInt(addrMap("io:pbus:TL2:bootrom").start) + io.cache.req.bits.addr := UInt(addrMap("io:TL2:bootrom").start) io.cache.req.bits.typ := MT_WU io.cache.req.bits.cmd := M_XRD io.cache.req.bits.tag := UInt(0) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 3cec7521..82f3b824 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -80,11 +80,7 @@ abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]]( val coreplex = p(BuildCoreplex)(outer.c, p) val coreplexIO = Wire(coreplex.io) - val pBus = - Module(new TileLinkRecursiveInterconnect(1, p(GlobalAddrMap).subMap("io:pbus"))( - p.alterPartial({ case TLId => "L2toMMIO" }))) - pBus.io.in.head <> coreplexIO.master.mmio - outer.legacy.module.io.legacy <> pBus.port("TL2") + outer.legacy.module.io.legacy <> coreplexIO.master.mmio println("Generated Address Map") for (entry <- p(GlobalAddrMap).flatten) { diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index 7558297b..c04b23e0 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -90,15 +90,14 @@ object GenerateGlobalAddrMap { }).flatten.toList lazy val tl2AddrMap = new AddrMap(uniquelyNamedTL2Devices, collapse = true) - lazy val pBusIOAddrMap = new AddrMap(Seq(AddrMapEntry("TL2", tl2AddrMap)), collapse = true) val memBase = 0x80000000L val memSize = p(ExtMemSize) Dump("MEM_BASE", memBase) val cBus = AddrMapEntry("cbus", cBusIOAddrMap) - val pBus = AddrMapEntry("pbus", pBusIOAddrMap) - val io = AddrMapEntry("io", AddrMap((cBus +: (!pBusIOAddrMap.isEmpty).option(pBus).toSeq):_*)) + val tlBus = AddrMapEntry("TL2", tl2AddrMap) + val io = AddrMapEntry("io", AddrMap(cBus, tlBus)) val mem = AddrMapEntry("mem", MemRange(memBase, memSize, MemAttr(AddrMapProt.RWX, true))) AddrMap((io +: (p(NMemoryChannels) > 0).option(mem).toSeq):_*) } @@ -108,7 +107,7 @@ object GenerateConfigString { def apply(p: Parameters, c: CoreplexConfig, peripheryManagers: Seq[TLManagerParameters]) = { val addrMap = p(GlobalAddrMap) val plicAddr = addrMap("io:cbus:plic").start - val clint = CoreplexLocalInterrupterConfig(0, addrMap("io:pbus:TL2:clint").start) + val clint = CoreplexLocalInterrupterConfig(0, addrMap("io:TL2:clint").start) val xLen = p(XLen) val res = new StringBuilder res append "plic {\n" From bddfa4d69bc18fced48f3e10bfc899e59ba21e63 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 26 Oct 2016 13:27:35 -0700 Subject: [PATCH 12/47] Debug: make address configurable --- src/main/scala/coreplex/BaseCoreplex.scala | 4 ++-- src/main/scala/uncore/devices/Debug.scala | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 3210ec36..b4e23b02 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -51,7 +51,7 @@ case class CoreplexConfig( abstract class BaseCoreplex(c: CoreplexConfig)(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { val debugLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) - val debugModule = LazyModule(new TLDebugModule(p(XLen)/8)) + val debugModule = LazyModule(new TLDebugModule()) debugModule.node := TLHintHandler()( TLBuffer()( @@ -121,7 +121,7 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( // and coherence manager(s) to the other side l1tol2net.io.clients_cached <> uncoreTileIOs.map(_.cached).flatten l1tol2net.io.clients_uncached <> uncoreTileIOs.map(_.uncached).flatten ++ io.slave - l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner + l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner // legacy goes here (not mmioManager) val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, c.nMemChannels)(outerMemParams)) diff --git a/src/main/scala/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index e5cd0af6..76641406 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -823,8 +823,8 @@ trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap { * */ -class TLDebugModule(beatBytes: Int) (implicit p: Parameters) - extends TLRegisterRouter(0x0, beatBytes=beatBytes)( +class TLDebugModule(address: BigInt = 0)(implicit p: Parameters) + extends TLRegisterRouter(address, beatBytes=p(rocket.XLen)/8)( new TLRegBundle(p, _ ) with DebugModuleBundle)( new TLRegModule(p, _, _) with DebugModule) From b99662796d27099ea412b07caa94061428f65b99 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 26 Oct 2016 13:52:23 -0700 Subject: [PATCH 13/47] PLIC: converted to TL2 --- src/main/scala/coreplex/BaseCoreplex.scala | 25 ++-- src/main/scala/uncore/devices/Plic.scala | 139 ++++++++------------- 2 files changed, 68 insertions(+), 96 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index b4e23b02..9dbf0080 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -51,13 +51,21 @@ case class CoreplexConfig( abstract class BaseCoreplex(c: CoreplexConfig)(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { val debugLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) - val debugModule = LazyModule(new TLDebugModule()) - debugModule.node := + val debug = LazyModule(new TLDebugModule()) + debug.node := TLHintHandler()( TLBuffer()( TLFragmenter(p(XLen)/8, debugLegacy.tlDataBeats * debugLegacy.tlDataBytes)( TLWidthWidget(debugLegacy.tlDataBytes)(debugLegacy.node)))) + val plicLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) + val plic = LazyModule(new TLPLIC(c.plicKey)) + plic.node := + TLHintHandler()( + TLBuffer()( + TLFragmenter(p(XLen)/8, plicLegacy.tlDataBeats * plicLegacy.tlDataBytes)( + TLWidthWidget(plicLegacy.tlDataBytes)(plicLegacy.node)))) + } abstract class BaseCoreplexBundle(val c: CoreplexConfig)(implicit val p: Parameters) extends Bundle with HasCoreplexParameters { @@ -142,23 +150,22 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( val cBus = Module(new TileLinkRecursiveInterconnect(1, ioAddrMap)) cBus.io.in.head <> mmio - val plic = Module(new PLIC(c.plicKey)) - plic.io.tl <> cBus.port("cbus:plic") + outer.plicLegacy.module.io.legacy <> cBus.port("cbus: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 + outer.plic.module.io.devices(i) <> gateway.io.plic } outer.debugLegacy.module.io.legacy <> cBus.port("cbus:debug") - outer.debugModule.module.io.db <> io.debug + outer.debug.module.io.db <> io.debug // connect coreplex-internal interrupts to tiles for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { tile.interrupts <> io.clint(i) - tile.interrupts.meip := plic.io.harts(plic.cfg.context(i, 'M')) - tile.interrupts.seip.foreach(_ := plic.io.harts(plic.cfg.context(i, 'S'))) - tile.interrupts.debug := outer.debugModule.module.io.debugInterrupts(i) + tile.interrupts.meip := outer.plic.module.io.harts(c.plicKey.context(i, 'M')) + tile.interrupts.seip.foreach(_ := outer.plic.module.io.harts(c.plicKey.context(i, 'S'))) + tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) tile.hartid := UInt(i) tile.resetVector := io.resetVector } diff --git a/src/main/scala/uncore/devices/Plic.scala b/src/main/scala/uncore/devices/Plic.scala index 8a180d99..0660fce6 100644 --- a/src/main/scala/uncore/devices/Plic.scala +++ b/src/main/scala/uncore/devices/Plic.scala @@ -6,7 +6,8 @@ import Chisel._ import Chisel.ImplicitConversions._ import junctions._ -import uncore.tilelink._ +import regmapper._ +import uncore.tilelink2._ import cde.Parameters class GatewayPLICIO extends Bundle { @@ -27,7 +28,7 @@ class LevelGateway extends Module { io.plic.valid := io.interrupt && !inFlight } -case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriorities: Int) { +case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriorities: Int, address: BigInt = 0xC000000) { def contextsPerHart = if (supervisor) 2 else 1 def nHarts = contextsPerHart * nHartsIn def context(i: Int, mode: Char) = mode match { @@ -41,6 +42,7 @@ case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriori def maxDevices = 1023 def maxHarts = 15872 + def priorityBase = 0x0 def pendingBase = 0x1000 def enableBase = 0x2000 def hartBase = 0x200000 @@ -56,15 +58,19 @@ case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriori require(nPriorities >= 0 && nPriorities <= nDevices) } -/** Platform-Level Interrupt Controller */ -class PLIC(val cfg: PLICConfig)(implicit val p: Parameters) extends Module - with HasTileLinkParameters - with HasAddrMapParameters { - val io = new Bundle { - val devices = Vec(cfg.nDevices, new GatewayPLICIO).flip - val harts = Vec(cfg.nHarts, Bool()).asOutput - val tl = new ClientUncachedTileLinkIO().flip - } +trait HasPLICParamters { + val params: (PLICConfig, Parameters) + val cfg = params._1 + implicit val p = params._2 +} + +trait PLICBundle extends Bundle with HasPLICParamters { + val devices = Vec(cfg.nDevices, new GatewayPLICIO).flip + val harts = Vec(cfg.nHarts, Bool()).asOutput +} + +trait PLICModule extends Module with HasRegMap with HasPLICParamters { + val io: PLICBundle val priority = if (cfg.nPriorities > 0) Reg(Vec(cfg.nDevices+1, UInt(width=log2Up(cfg.nPriorities+1)))) @@ -87,7 +93,7 @@ class PLIC(val cfg: PLICConfig)(implicit val p: Parameters) extends Module val lMax = findMax(x take half) val rMax = findMax(x drop half) val useLeft = lMax._1 >= rMax._1 - (Mux(useLeft, lMax._1, rMax._1), Mux(useLeft, lMax._2, UInt(half) + rMax._2)) + (Mux(useLeft, lMax._1, rMax._1), Mux(useLeft, lMax._2, UInt(half) | rMax._2)) } else (x.head, UInt(0)) } @@ -102,86 +108,45 @@ class PLIC(val cfg: PLICConfig)(implicit val p: Parameters) extends Module io.harts(hart) := Reg(next = maxPri) > Cat(UInt(1), threshold(hart)) } - val acq = Queue(io.tl.acquire, 1) - val read = acq.fire() && acq.bits.isBuiltInType(Acquire.getType) - val write = acq.fire() && acq.bits.isBuiltInType(Acquire.putType) - assert(!acq.fire() || read || write, "unsupported PLIC operation") - val addr = acq.bits.full_addr()(log2Up(cfg.size)-1,0) + def priorityRegField(x: UInt) = if (cfg.nPriorities > 0) RegField(32, x) else RegField.r(32, x) + val piorityRegFields = Seq(cfg.priorityBase -> priority.map(p => priorityRegField(p))) + val pendingRegFields = Seq(cfg.pendingBase -> pending .map(b => RegField.r(1, b))) - val claimant = - if (cfg.nHarts == 1) UInt(0) - else (addr - cfg.hartBase)(log2Up(cfg.hartOffset(cfg.nHarts))-1,log2Up(cfg.hartOffset(1))) - val hart = Wire(init = claimant) - val myMaxDev = maxDevs(claimant) - val myEnables = enables(hart) - val rdata = Wire(init = UInt(0, tlDataBits)) - val masked_wdata = (acq.bits.data & acq.bits.full_wmask()) | (rdata & ~acq.bits.full_wmask()) - - if (cfg.nDevices > 0) when (addr >= cfg.hartBase) { - val word = - if (tlDataBytes > cfg.claimOffset) UInt(0) - else addr(log2Up(cfg.claimOffset),log2Up(tlDataBytes)) - rdata := Cat(myMaxDev, UInt(0, 8*cfg.priorityBytes-threshold(0).getWidth), threshold(claimant)) >> (word * tlDataBits) - - when (read && addr(log2Ceil(cfg.claimOffset))) { - pending(myMaxDev) := false - } - when (write) { - when (if (tlDataBytes > cfg.claimOffset) acq.bits.wmask()(cfg.claimOffset) else addr(log2Ceil(cfg.claimOffset))) { - val dev = (acq.bits.data >> ((8 * cfg.claimOffset) % tlDataBits))(log2Up(pending.size)-1,0) - when (myEnables(dev)) { io.devices(dev-1).complete := true } - }.otherwise { - if (cfg.nPriorities > 0) threshold(claimant) := acq.bits.data - } - } - }.elsewhen (addr >= cfg.enableBase) { - val enableHart = - if (cfg.nHarts > 1) (addr - cfg.enableBase)(log2Up(cfg.enableOffset(cfg.nHarts))-1,log2Up(cfg.enableOffset(1))) - else UInt(0) - hart := enableHart - val word = - if (tlDataBits >= myEnables.size) UInt(0) - else addr(log2Ceil((myEnables.size-1)/tlDataBits+1) + tlByteAddrBits - 1, tlByteAddrBits) - for (i <- 0 until myEnables.size by tlDataBits) { - when (word === i/tlDataBits) { - rdata := Cat(myEnables.slice(i, i + tlDataBits).reverse) - for (j <- 0 until (tlDataBits min (myEnables.size - i))) { - when (write) { enables(enableHart)(i+j) := masked_wdata(j) } - } - } - } - }.elsewhen (addr >= cfg.pendingBase) { - val word = - if (tlDataBytes >= pending.size) UInt(0) - else addr(log2Up(pending.size)-1,log2Up(tlDataBytes)) - rdata := pending.asUInt >> (word * tlDataBits) - }.otherwise { - val regsPerBeat = tlDataBytes >> log2Up(cfg.priorityBytes) - val word = - if (regsPerBeat >= priority.size) UInt(0) - else addr(log2Up(priority.size*cfg.priorityBytes)-1,log2Up(tlDataBytes)) - for (i <- 0 until priority.size by regsPerBeat) { - when (word === i/regsPerBeat) { - rdata := Cat(priority.slice(i, i + regsPerBeat).map(p => Cat(UInt(0, 8*cfg.priorityBytes-p.getWidth), p)).reverse) - for (j <- 0 until (regsPerBeat min (priority.size - i))) { - if (cfg.nPriorities > 0) when (write) { priority(i+j) := masked_wdata >> (j * 8 * cfg.priorityBytes) } - } - } - } + val enableRegFields = enables.zipWithIndex.map { case (e, i) => + cfg.enableBase + cfg.enableOffset(i) -> e.map(b => RegField(1, b)) } + val hartRegFields = Seq.tabulate(cfg.nHarts) { i => + cfg.hartBase + cfg.hartOffset(i) -> Seq( + priorityRegField(threshold(i)), + RegField(32, + RegReadFn { valid => + when (valid) { + pending(maxDevs(i)) := Bool(false) + maxDevs(i) := UInt(0) // flush pipeline + } + (Bool(true), maxDevs(i)) + }, + RegWriteFn { (valid, data) => + when (valid && enables(i)(data)) { + io.devices(data - UInt(1)).complete := Bool(true) + } + Bool(true) + } + ) + ) + } + + regmap((piorityRegFields ++ pendingRegFields ++ enableRegFields ++ hartRegFields):_*) + priority(0) := 0 pending(0) := false for (e <- enables) e(0) := false - - io.tl.grant.valid := acq.valid - acq.ready := io.tl.grant.ready - io.tl.grant.bits := Grant( - is_builtin_type = Bool(true), - g_type = acq.bits.getBuiltInGrantType(), - client_xact_id = acq.bits.client_xact_id, - manager_xact_id = UInt(0), - addr_beat = UInt(0), - data = rdata) } + +/** Platform-Level Interrupt Controller */ +class TLPLIC(c: PLICConfig)(implicit val p: Parameters) + extends TLRegisterRouter(c.address, size = c.size, beatBytes = p(rocket.XLen)/8, undefZero = false)( + new TLRegBundle((c, p), _) with PLICBundle)( + new TLRegModule((c, p), _, _) with PLICModule) From 5090ff945bd808d7b317b693c0869e65c6f41713 Mon Sep 17 00:00:00 2001 From: Megan Wachs Date: Wed, 26 Oct 2016 18:03:07 -0700 Subject: [PATCH 14/47] DebugModule: Be more paranoid about addressing corner cases. --- src/main/scala/uncore/devices/Debug.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index 76641406..e4ca2516 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -480,6 +480,9 @@ trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap { val dbRamRdEn = Wire(Bool()) val dbRamWrEnFinal = Wire(Bool()) val dbRamRdEnFinal = Wire(Bool()) + require((cfg.nDebugRamBytes % ramDataBytes) == 0) + val dbRamDataOffset = log2Up(ramDataBytes) + // --- Debug Bus Accesses @@ -606,10 +609,7 @@ trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap { // 0x40 - 0x6F Not Implemented dbRamAddr := dbReq.addr( ramAddrWidth-1 , 0) dbRamWrData := dbReq.data - dbRamAddrValid := Bool(true) - if (ramAddrWidth < 4){ - dbRamAddrValid := (dbReq.addr(3, ramAddrWidth) === UInt(0)) - } + dbRamAddrValid := (dbReq.addr(3,0) <= UInt((cfg.nDebugRamBytes/ramDataBytes))) val dbRamRdDataFields = List.tabulate(cfg.nDebugRamBytes / ramDataBytes) { ii => val slice = ramMem.slice(ii * ramDataBytes, (ii+1)*ramDataBytes) @@ -620,7 +620,7 @@ trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap { when (dbRamWrEnFinal) { for (ii <- 0 until ramDataBytes) { - ramMem(dbRamAddr * UInt(ramDataBytes) + UInt(ii)) := dbRamWrData((8*(ii+1)-1), (8*ii)) + ramMem((dbRamAddr << UInt(dbRamDataOffset)) + UInt(ii)) := dbRamWrData((8*(ii+1)-1), (8*ii)) } } From f8a0829134b671d54f806cd426c1f7e6c442d469 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 26 Oct 2016 17:48:15 -0700 Subject: [PATCH 15/47] rocketchip: remove clint; it moves into coreplex --- src/main/scala/rocketchip/ExampleTop.scala | 3 --- src/main/scala/rocketchip/Periphery.scala | 28 ---------------------- src/main/scala/rocketchip/Utils.scala | 2 +- src/main/scala/uncore/devices/Prci.scala | 6 ++--- 4 files changed, 3 insertions(+), 36 deletions(-) diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 2a191a0c..922acb7b 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -13,7 +13,6 @@ class ExampleTop(q: Parameters) extends BaseTop(q) with PeripheryBootROM with PeripheryDebug with PeripheryExtInterrupts - with PeripheryCoreplexLocalInterrupter with PeripheryMasterMem with PeripheryMasterAXI4MMIO with PeripherySlave { @@ -24,7 +23,6 @@ class ExampleTopBundle[+L <: ExampleTop](p: Parameters, l: L) extends BaseTopBun with PeripheryBootROMBundle with PeripheryDebugBundle with PeripheryExtInterruptsBundle - with PeripheryCoreplexLocalInterrupterBundle with PeripheryMasterMemBundle with PeripheryMasterAXI4MMIOBundle with PeripherySlaveBundle @@ -33,7 +31,6 @@ class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](p: Parameter with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule - with PeripheryCoreplexLocalInterrupterModule with PeripheryMasterMemModule with PeripheryMasterAXI4MMIOModule with PeripherySlaveModule diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index cdb7a2f2..53b128e8 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -274,34 +274,6 @@ trait PeripherySlaveModule extends HasPeripheryParameters { ///// -trait PeripheryCoreplexLocalInterrupter extends LazyModule with HasPeripheryParameters { - implicit val p: Parameters - val peripheryBus: TLXbar - - // CoreplexLocalInterrupter must be at least 64b if XLen >= 64 - val beatBytes = max((outerMMIOParams(XLen) min 64) / 8, peripheryBusConfig.beatBytes) - val clintConfig = CoreplexLocalInterrupterConfig(beatBytes) - val clint = LazyModule(new CoreplexLocalInterrupter(clintConfig)(outerMMIOParams)) - // The periphery bus is 32-bit, so we may need to adapt its width to XLen - clint.node := TLFragmenter(beatBytes, cacheBlockBytes)(TLWidthWidget(peripheryBusConfig.beatBytes)(peripheryBus.node)) -} - -trait PeripheryCoreplexLocalInterrupterBundle { - implicit val p: Parameters -} - -trait PeripheryCoreplexLocalInterrupterModule extends HasPeripheryParameters { - implicit val p: Parameters - val outer: PeripheryCoreplexLocalInterrupter - val io: PeripheryCoreplexLocalInterrupterBundle - val coreplexIO: BaseCoreplexBundle - - outer.clint.module.io.rtcTick := Counter(p(RTCPeriod)).inc() - coreplexIO.clint <> outer.clint.module.io.tiles -} - -///// - trait PeripheryBootROM extends LazyModule with HasPeripheryParameters { implicit val p: Parameters val peripheryBus: TLXbar diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index c04b23e0..fb16cec4 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -107,7 +107,7 @@ object GenerateConfigString { def apply(p: Parameters, c: CoreplexConfig, peripheryManagers: Seq[TLManagerParameters]) = { val addrMap = p(GlobalAddrMap) val plicAddr = addrMap("io:cbus:plic").start - val clint = CoreplexLocalInterrupterConfig(0, addrMap("io:TL2:clint").start) + val clint = CoreplexLocalInterrupterConfig() val xLen = p(XLen) val res = new StringBuilder res append "plic {\n" diff --git a/src/main/scala/uncore/devices/Prci.scala b/src/main/scala/uncore/devices/Prci.scala index ab3ce91a..41217a69 100644 --- a/src/main/scala/uncore/devices/Prci.scala +++ b/src/main/scala/uncore/devices/Prci.scala @@ -20,7 +20,7 @@ class CoreplexLocalInterrupts extends Bundle { val msip = Bool() } -case class CoreplexLocalInterrupterConfig(beatBytes: Int, address: BigInt = 0x02000000) { +case class CoreplexLocalInterrupterConfig(address: BigInt = 0x02000000) { def msipOffset(hart: Int) = hart * msipBytes def msipAddress(hart: Int) = address + msipOffset(hart) def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes @@ -48,8 +48,6 @@ trait CoreplexLocalInterrupterModule extends Module with HasRegMap with MixCorep val timeWidth = 64 val regWidth = 32 - // demand atomic accesses for RV64 - require(c.beatBytes >= (p(rocket.XLen) min timeWidth)/8) val time = Seq.fill(timeWidth/regWidth)(Reg(init=UInt(0, width = regWidth))) when (io.rtcTick) { @@ -87,6 +85,6 @@ trait CoreplexLocalInterrupterModule extends Module with HasRegMap with MixCorep /** Power, Reset, Clock, Interrupt */ // Magic TL2 Incantation to create a TL2 Slave class CoreplexLocalInterrupter(c: CoreplexLocalInterrupterConfig)(implicit val p: Parameters) - extends TLRegisterRouter(c.address, 0, c.size, 0, c.beatBytes, false)( + extends TLRegisterRouter(c.address, size = c.size, beatBytes = p(rocket.XLen)/8, undefZero = false)( new TLRegBundle((c, p), _) with CoreplexLocalInterrupterBundle)( new TLRegModule((c, p), _, _) with CoreplexLocalInterrupterModule) From dddb50a94228676981c8b80273d969962ff4b7e3 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 26 Oct 2016 19:02:04 -0700 Subject: [PATCH 16/47] BuildTiles: convert to LazyTile --- src/main/scala/coreplex/BaseCoreplex.scala | 5 +- src/main/scala/coreplex/Configs.scala | 5 +- src/main/scala/coreplex/Coreplex.scala | 4 +- src/main/scala/groundtest/Configs.scala | 4 +- src/main/scala/groundtest/Tile.scala | 78 ++++---- src/main/scala/rocket/tile.scala | 197 +++++++++++---------- 6 files changed, 150 insertions(+), 143 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 9dbf0080..e02b0190 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -23,7 +23,7 @@ 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]] +case object BuildTiles extends Field[Seq[Parameters => LazyTile]] /** The file to read the BootROM contents from */ case object BootROMFile extends Field[String] @@ -49,6 +49,7 @@ case class CoreplexConfig( } abstract class BaseCoreplex(c: CoreplexConfig)(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { + val lazyTiles = p(BuildTiles) map { _(p) } val debugLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) val debug = LazyModule(new TLDebugModule()) @@ -89,7 +90,7 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( val io: B = b // Build a set of Tiles - val tiles = p(BuildTiles) map { _(reset, p) } + val tiles = outer.lazyTiles.map(_.module) val uncoreTileIOs = (tiles zipWithIndex) map { case (tile, i) => Wire(tile.io) } val nCachedPorts = tiles.map(tile => tile.io.cached.size).reduce(_ + _) diff --git a/src/main/scala/coreplex/Configs.scala b/src/main/scala/coreplex/Configs.scala index 4fea63f1..baff8e7b 100644 --- a/src/main/scala/coreplex/Configs.scala +++ b/src/main/scala/coreplex/Configs.scala @@ -4,6 +4,7 @@ package coreplex import Chisel._ import junctions._ +import diplomacy._ import uncore.tilelink._ import uncore.coherence._ import uncore.agents._ @@ -69,8 +70,8 @@ class BaseCoreplexConfig extends Config ( case NUncachedTileLinkPorts => 1 //Tile Constants case BuildTiles => { - List.tabulate(site(NTiles)){ i => (r: Bool, p: Parameters) => - Module(new RocketTile(resetSignal = r)(p.alterPartial({ + List.tabulate(site(NTiles)){ i => (p: Parameters) => + LazyModule(new RocketTile()(p.alterPartial({ case TileId => i case TLId => "L1toL2" case NUncachedTileLinkPorts => 1 + site(RoccNMemChannels) diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 1e4fc37a..4af784ee 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -9,7 +9,7 @@ import util._ import rocket._ trait DirectConnection { - val tiles: Seq[Tile] + val tiles: Seq[TileImp] val uncoreTileIOs: Seq[TileIO] val tlBuffering = TileLinkDepths(1,1,2,2,0) @@ -49,7 +49,7 @@ trait TileClockResetBundle { trait AsyncConnection { val io: TileClockResetBundle - val tiles: Seq[Tile] + val tiles: Seq[TileImp] val uncoreTileIOs: Seq[TileIO] (tiles, uncoreTileIOs, io.tcrs).zipped foreach { case (tile, uncore, tcr) => diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 61dee763..bf986429 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -95,8 +95,8 @@ class WithGroundTest extends Config( case BuildTiles => { (0 until site(NTiles)).map { i => val tileSettings = site(GroundTestKey)(i) - (r: Bool, p: Parameters) => { - Module(new GroundTestTile(resetSignal = r)(p.alterPartial({ + (p: Parameters) => { + LazyModule(new GroundTestTile()(p.alterPartial({ case TLId => "L1toL2" case TileId => i case NCachedTileLinkPorts => if(tileSettings.cached > 0) 1 else 0 diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 5a550fb3..63ac1f64 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -96,48 +96,46 @@ abstract class GroundTest(implicit val p: Parameters) extends Module val io = new GroundTestIO } -class GroundTestTile(resetSignal: Bool) - (implicit val p: Parameters) - extends Tile(resetSignal = resetSignal)(p) - with HasGroundTestParameters { - - override val io = new TileIO(bc) { - val success = Bool(OUTPUT) - } - - val test = p(BuildGroundTest)(dcacheParams) - - val ptwPorts = ListBuffer.empty ++= test.io.ptw - val memPorts = ListBuffer.empty ++= test.io.mem - - if (nCached > 0) { - val dcache_io = HellaCache(p(DCacheKey))(dcacheParams) - val dcacheArb = Module(new HellaCacheArbiter(nCached)(dcacheParams)) - - dcacheArb.io.requestor.zip(test.io.cache).foreach { - case (requestor, cache) => - val dcacheIF = Module(new SimpleHellaCacheIF()(dcacheParams)) - dcacheIF.io.requestor <> cache - requestor <> dcacheIF.io.cache +class GroundTestTile(implicit val p: Parameters) extends LazyTile with HasGroundTestParameters { + lazy val module = new TileImp(this) { + val io = new TileIO(bc) { + val success = Bool(OUTPUT) } - dcache_io.cpu <> dcacheArb.io.mem - io.cached.head <> dcache_io.mem - // SimpleHellaCacheIF leaves invalidate_lr dangling, so we wire it to false - dcache_io.cpu.invalidate_lr := Bool(false) + val test = p(BuildGroundTest)(dcacheParams) - ptwPorts += dcache_io.ptw + val ptwPorts = ListBuffer.empty ++= test.io.ptw + val memPorts = ListBuffer.empty ++= test.io.mem + + if (nCached > 0) { + val dcache_io = HellaCache(p(DCacheKey))(dcacheParams) + val dcacheArb = Module(new HellaCacheArbiter(nCached)(dcacheParams)) + + dcacheArb.io.requestor.zip(test.io.cache).foreach { + case (requestor, cache) => + val dcacheIF = Module(new SimpleHellaCacheIF()(dcacheParams)) + dcacheIF.io.requestor <> cache + requestor <> dcacheIF.io.cache + } + dcache_io.cpu <> dcacheArb.io.mem + io.cached.head <> dcache_io.mem + + // SimpleHellaCacheIF leaves invalidate_lr dangling, so we wire it to false + dcache_io.cpu.invalidate_lr := Bool(false) + + ptwPorts += dcache_io.ptw + } + + if (ptwPorts.size > 0) { + val ptw = Module(new DummyPTW(ptwPorts.size)) + ptw.io.requestors <> ptwPorts + } + + require(memPorts.size == io.uncached.size) + if (memPorts.size > 0) { + io.uncached <> memPorts + } + + io.success := test.io.status.finished } - - if (ptwPorts.size > 0) { - val ptw = Module(new DummyPTW(ptwPorts.size)) - ptw.io.requestors <> ptwPorts - } - - require(memPorts.size == io.uncached.size) - if (memPorts.size > 0) { - io.uncached <> memPorts - } - - io.success := test.io.status.finished } diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index 39dd5a35..5d30c1a1 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -3,7 +3,9 @@ package rocket import Chisel._ +import diplomacy._ import uncore.tilelink._ +import uncore.tilelink2._ import uncore.agents._ import uncore.converters._ import uncore.devices._ @@ -39,8 +41,7 @@ class TileIO(c: TileBundleConfig)(implicit p: Parameters) extends Bundle { override def cloneType = new TileIO(c).asInstanceOf[this.type] } -abstract class Tile(clockSignal: Clock = null, resetSignal: Bool = null) - (implicit p: Parameters) extends Module(Option(clockSignal), Option(resetSignal)) { +abstract class TileImp(l: LazyTile)(implicit p: Parameters) extends LazyModuleImp(l) { val nCachedTileLinkPorts = p(NCachedTileLinkPorts) val nUncachedTileLinkPorts = p(NUncachedTileLinkPorts) val dcacheParams = p.alterPartial({ case CacheName => "L1D" }) @@ -50,111 +51,117 @@ abstract class Tile(clockSignal: Clock = null, resetSignal: Bool = null) xLen = p(XLen), hasSlavePort = p(DataScratchpadSize) > 0) - val io = new TileIO(bc) + val io: TileIO } -class RocketTile(clockSignal: Clock = null, resetSignal: Bool = null) - (implicit p: Parameters) extends Tile(clockSignal, resetSignal)(p) { - val buildRocc = p(BuildRoCC) - val usingRocc = !buildRocc.isEmpty - val nRocc = buildRocc.size - val nFPUPorts = buildRocc.filter(_.useFPU).size +abstract class LazyTile(implicit p: Parameters) extends LazyModule { + val module: TileImp +} - val core = Module(new Rocket) - val icache = Module(new Frontend()(p.alterPartial({ case CacheName => "L1I" }))) - val dcache = HellaCache(p(DCacheKey))(dcacheParams) +class RocketTile(implicit p: Parameters) extends LazyTile { + lazy val module = new TileImp(this) { + val io = new TileIO(bc) + val buildRocc = p(BuildRoCC) + val usingRocc = !buildRocc.isEmpty + val nRocc = buildRocc.size + val nFPUPorts = buildRocc.filter(_.useFPU).size - val ptwPorts = collection.mutable.ArrayBuffer(icache.io.ptw, dcache.ptw) - val dcPorts = collection.mutable.ArrayBuffer(core.io.dmem) - val uncachedArbPorts = collection.mutable.ArrayBuffer(icache.io.mem) - val uncachedPorts = collection.mutable.ArrayBuffer[ClientUncachedTileLinkIO]() - val cachedPorts = collection.mutable.ArrayBuffer(dcache.mem) - core.io.interrupts := io.interrupts - core.io.hartid := io.hartid - icache.io.cpu <> core.io.imem - icache.io.resetVector := io.resetVector + val core = Module(new Rocket) + val icache = Module(new Frontend()(p.alterPartial({ case CacheName => "L1I" }))) + val dcache = HellaCache(p(DCacheKey))(dcacheParams) - val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg))) - fpuOpt.foreach(fpu => core.io.fpu <> fpu.io) + val ptwPorts = collection.mutable.ArrayBuffer(icache.io.ptw, dcache.ptw) + val dcPorts = collection.mutable.ArrayBuffer(core.io.dmem) + val uncachedArbPorts = collection.mutable.ArrayBuffer(icache.io.mem) + val uncachedPorts = collection.mutable.ArrayBuffer[ClientUncachedTileLinkIO]() + val cachedPorts = collection.mutable.ArrayBuffer(dcache.mem) + core.io.interrupts := io.interrupts + core.io.hartid := io.hartid + icache.io.cpu <> core.io.imem + icache.io.resetVector := io.resetVector - if (usingRocc) { - val respArb = Module(new RRArbiter(new RoCCResponse, nRocc)) - core.io.rocc.resp <> respArb.io.out + val fpuOpt = p(FPUKey).map(cfg => Module(new FPU(cfg))) + fpuOpt.foreach(fpu => core.io.fpu <> fpu.io) - val roccOpcodes = buildRocc.map(_.opcodes) - val cmdRouter = Module(new RoccCommandRouter(roccOpcodes)) - cmdRouter.io.in <> core.io.rocc.cmd + if (usingRocc) { + val respArb = Module(new RRArbiter(new RoCCResponse, nRocc)) + core.io.rocc.resp <> respArb.io.out - val roccs = buildRocc.zipWithIndex.map { case (accelParams, i) => - val rocc = accelParams.generator(p.alterPartial({ - case RoccNMemChannels => accelParams.nMemChannels - case RoccNPTWPorts => accelParams.nPTWPorts - })) - val dcIF = Module(new SimpleHellaCacheIF()(dcacheParams)) - rocc.io.cmd <> cmdRouter.io.out(i) - rocc.io.exception := core.io.rocc.exception - dcIF.io.requestor <> rocc.io.mem - dcPorts += dcIF.io.cache - uncachedArbPorts += rocc.io.autl - rocc + val roccOpcodes = buildRocc.map(_.opcodes) + val cmdRouter = Module(new RoccCommandRouter(roccOpcodes)) + cmdRouter.io.in <> core.io.rocc.cmd + + val roccs = buildRocc.zipWithIndex.map { case (accelParams, i) => + val rocc = accelParams.generator(p.alterPartial({ + case RoccNMemChannels => accelParams.nMemChannels + case RoccNPTWPorts => accelParams.nPTWPorts + })) + val dcIF = Module(new SimpleHellaCacheIF()(dcacheParams)) + rocc.io.cmd <> cmdRouter.io.out(i) + rocc.io.exception := core.io.rocc.exception + dcIF.io.requestor <> rocc.io.mem + dcPorts += dcIF.io.cache + uncachedArbPorts += rocc.io.autl + rocc + } + + if (nFPUPorts > 0) { + fpuOpt.foreach { fpu => + val fpArb = Module(new InOrderArbiter(new FPInput, new FPResult, nFPUPorts)) + val fp_roccs = roccs.zip(buildRocc) + .filter { case (_, params) => params.useFPU } + .map { case (rocc, _) => rocc.io } + fpArb.io.in_req <> fp_roccs.map(_.fpu_req) + fp_roccs.zip(fpArb.io.in_resp).foreach { + case (rocc, fpu_resp) => rocc.fpu_resp <> fpu_resp + } + fpu.io.cp_req <> fpArb.io.out_req + fpArb.io.out_resp <> fpu.io.cp_resp + } + } + + core.io.rocc.busy := cmdRouter.io.busy || roccs.map(_.io.busy).reduce(_ || _) + core.io.rocc.interrupt := roccs.map(_.io.interrupt).reduce(_ || _) + respArb.io.in <> roccs.map(rocc => Queue(rocc.io.resp)) + + ptwPorts ++= roccs.flatMap(_.io.ptw) + uncachedPorts ++= roccs.flatMap(_.io.utl) } - if (nFPUPorts > 0) { + val uncachedArb = Module(new ClientUncachedTileLinkIOArbiter(uncachedArbPorts.size)) + uncachedArb.io.in <> uncachedArbPorts + uncachedArb.io.out +=: uncachedPorts + + // Connect the caches and RoCC to the outer memory system + io.uncached <> uncachedPorts + io.cached <> cachedPorts + // TODO remove nCached/nUncachedTileLinkPorts parameters and these assertions + require(uncachedPorts.size == nUncachedTileLinkPorts) + require(cachedPorts.size == nCachedTileLinkPorts) + + if (p(UseVM)) { + val ptw = Module(new PTW(ptwPorts.size)(dcacheParams)) + ptw.io.requestor <> ptwPorts + ptw.io.mem +=: dcPorts + core.io.ptw <> ptw.io.dpath + } + + io.slave foreach { case slavePort => + val adapter = Module(new ScratchpadSlavePort()(dcacheParams)) + adapter.io.tl <> TileLinkFragmenter(slavePort) + adapter.io.dmem +=: dcPorts + } + + require(dcPorts.size == core.dcacheArbPorts) + val dcArb = Module(new HellaCacheArbiter(dcPorts.size)(dcacheParams)) + dcArb.io.requestor <> dcPorts + dcache.cpu <> dcArb.io.mem + + if (nFPUPorts == 0) { fpuOpt.foreach { fpu => - val fpArb = Module(new InOrderArbiter(new FPInput, new FPResult, nFPUPorts)) - val fp_roccs = roccs.zip(buildRocc) - .filter { case (_, params) => params.useFPU } - .map { case (rocc, _) => rocc.io } - fpArb.io.in_req <> fp_roccs.map(_.fpu_req) - fp_roccs.zip(fpArb.io.in_resp).foreach { - case (rocc, fpu_resp) => rocc.fpu_resp <> fpu_resp - } - fpu.io.cp_req <> fpArb.io.out_req - fpArb.io.out_resp <> fpu.io.cp_resp + fpu.io.cp_req.valid := Bool(false) + fpu.io.cp_resp.ready := Bool(false) } } - - core.io.rocc.busy := cmdRouter.io.busy || roccs.map(_.io.busy).reduce(_ || _) - core.io.rocc.interrupt := roccs.map(_.io.interrupt).reduce(_ || _) - respArb.io.in <> roccs.map(rocc => Queue(rocc.io.resp)) - - ptwPorts ++= roccs.flatMap(_.io.ptw) - uncachedPorts ++= roccs.flatMap(_.io.utl) - } - - val uncachedArb = Module(new ClientUncachedTileLinkIOArbiter(uncachedArbPorts.size)) - uncachedArb.io.in <> uncachedArbPorts - uncachedArb.io.out +=: uncachedPorts - - // Connect the caches and RoCC to the outer memory system - io.uncached <> uncachedPorts - io.cached <> cachedPorts - // TODO remove nCached/nUncachedTileLinkPorts parameters and these assertions - require(uncachedPorts.size == nUncachedTileLinkPorts) - require(cachedPorts.size == nCachedTileLinkPorts) - - if (p(UseVM)) { - val ptw = Module(new PTW(ptwPorts.size)(dcacheParams)) - ptw.io.requestor <> ptwPorts - ptw.io.mem +=: dcPorts - core.io.ptw <> ptw.io.dpath - } - - io.slave foreach { case slavePort => - val adapter = Module(new ScratchpadSlavePort()(dcacheParams)) - adapter.io.tl <> TileLinkFragmenter(slavePort) - adapter.io.dmem +=: dcPorts - } - - require(dcPorts.size == core.dcacheArbPorts) - val dcArb = Module(new HellaCacheArbiter(dcPorts.size)(dcacheParams)) - dcArb.io.requestor <> dcPorts - dcache.cpu <> dcArb.io.mem - - if (nFPUPorts == 0) { - fpuOpt.foreach { fpu => - fpu.io.cp_req.valid := Bool(false) - fpu.io.cp_resp.ready := Bool(false) - } } } From 11121b6f4c73d439ad9364c5a7a0c8c0ec1efc0e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 26 Oct 2016 19:54:47 -0700 Subject: [PATCH 17/47] rocket: convert scratchpad to TL2 --- src/main/scala/rocket/dcache.scala | 126 ++++++++++-------- src/main/scala/rocket/tile.scala | 31 +++-- src/main/scala/uncore/tilelink2/package.scala | 2 + 3 files changed, 88 insertions(+), 71 deletions(-) diff --git a/src/main/scala/rocket/dcache.scala b/src/main/scala/rocket/dcache.scala index 9bd89541..a10d4080 100644 --- a/src/main/scala/rocket/dcache.scala +++ b/src/main/scala/rocket/dcache.scala @@ -4,7 +4,9 @@ package rocket import Chisel._ import junctions._ +import diplomacy._ import uncore.tilelink._ +import uncore.tilelink2._ import uncore.agents._ import uncore.coherence._ import uncore.constants._ @@ -495,60 +497,74 @@ class DCache(implicit p: Parameters) extends L1HellaCacheModule()(p) { } } -class ScratchpadSlavePort(implicit p: Parameters) extends CoreModule()(p) { - val io = new Bundle { - val tl = new ClientUncachedTileLinkIO().flip - val dmem = new HellaCacheIO +class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { + val beatBytes = p(XLen)/8 + val node = TLManagerNode(TLManagerPortParameters( + Seq(TLManagerParameters( + address = List(AddressSet(0x80000000L, p(DataScratchpadSize))), + regionType = RegionType.UNCACHED, + executable = true, + supportsPutPartial = TransferSizes(1, beatBytes), + supportsPutFull = TransferSizes(1, beatBytes), + fifoId = Some(0))), // requests handled in FIFO order + beatBytes = beatBytes, + minLatency = 1)) + + lazy val module = new LazyModuleImp(this) with HasCoreParameters { + val io = new Bundle { + val tl_in = node.bundleIn + val dmem = new HellaCacheIO + } + + val tl_in = io.tl_in(0) + val edge = node.edgesIn(0) + val beatBytes = edge.manager.beatBytes + + require(coreDataBits == beatBytes*8) + require(usingDataScratchpad) + + val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4) + val state = Reg(init = s_ready) + when (io.dmem.resp.valid) { state := s_grant } + when (tl_in.d.fire()) { state := s_ready } + when (io.dmem.s2_nack) { state := s_replay } + when (io.dmem.req.fire()) { state := s_wait } + + val acq = Reg(tl_in.a.bits) + when (io.dmem.resp.valid) { acq.data := io.dmem.resp.bits.data } + when (tl_in.a.fire()) { acq := tl_in.a.bits } + + val isWrite = edge.hasData(acq) + val isRead = !isWrite + + def formCacheReq(acq: TLBundleA) = { + val req = Wire(new HellaCacheReq) + // treat all loads as full words, so bytes appear in correct lane + req.typ := Mux(isRead, log2Ceil(beatBytes), acq.size) + req.cmd := Mux(isRead, M_XRD, M_XWR) + req.addr := Mux(isRead, ~(~acq.address | (beatBytes-1)), acq.address) + req.tag := UInt(0) + req + } + + val ready = state === s_ready || tl_in.d.fire() + io.dmem.req.valid := (tl_in.a.valid && ready) || state === s_replay + tl_in.a.ready := io.dmem.req.ready && ready + io.dmem.req.bits := formCacheReq(Mux(state === s_replay, acq, tl_in.a.bits)) + // this blows. the TL data is already in the correct byte lane, but the D$ + // expects right-justified store data, so that it can steer the bytes. + io.dmem.s1_data := new LoadGen(acq.size, Bool(false), acq.address(log2Ceil(beatBytes)-1,0), acq.data, Bool(false), beatBytes).data + io.dmem.s1_kill := false + io.dmem.invalidate_lr := false + + // place AMO data in correct word lane + val minAMOBytes = 4 + val grantData = Mux(io.dmem.resp.valid, io.dmem.resp.bits.data, acq.data) + val alignedGrantData = Mux(acq.size <= log2Ceil(minAMOBytes), Fill(coreDataBytes/minAMOBytes, grantData(8*minAMOBytes-1, 0)), grantData) + + tl_in.d.valid := io.dmem.resp.valid || state === s_grant + tl_in.d.bits := Mux(isRead, + edge.AccessAck(acq, UInt(0), alignedGrantData), + edge.AccessAck(acq, UInt(0))) } - - val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4) - val state = Reg(init = s_ready) - when (io.dmem.resp.valid) { state := s_grant } - when (io.tl.grant.fire()) { state := s_ready } - when (io.dmem.s2_nack) { state := s_replay } - when (io.dmem.req.fire()) { state := s_wait } - - val acq = Reg(io.tl.acquire.bits) - when (io.dmem.resp.valid) { acq.data := io.dmem.resp.bits.data } - when (io.tl.acquire.fire()) { acq := io.tl.acquire.bits } - - val isRead = acq.isBuiltInType(Acquire.getType) - val isWrite = acq.isBuiltInType(Acquire.putType) - assert(state === s_ready || isRead || isWrite) - require(coreDataBits == acq.tlDataBits) - require(usingDataScratchpad) - - def formCacheReq(acq: Acquire) = { - val req = Wire(new HellaCacheReq) - // treat all loads as full words, so bytes appear in correct lane - req.typ := Mux(isRead, log2Ceil(acq.tlDataBytes), acq.op_size()) - req.cmd := acq.op_code() - req.addr := Mux(isRead, ~(~acq.full_addr() | (acq.tlDataBytes-1)), acq.full_addr()) - req.tag := UInt(0) - req - } - - val ready = state === s_ready || io.tl.grant.fire() - io.dmem.req.valid := (io.tl.acquire.valid && ready) || state === s_replay - io.tl.acquire.ready := io.dmem.req.ready && ready - io.dmem.req.bits := formCacheReq(Mux(state === s_replay, acq, io.tl.acquire.bits)) - // this blows. the TL data is already in the correct byte lane, but the D$ - // expects right-justified store data, so that it can steer the bytes. - io.dmem.s1_data := new LoadGen(acq.op_size(), Bool(false), acq.addr_byte(), acq.data, Bool(false), acq.tlDataBytes).data - io.dmem.s1_kill := false - io.dmem.invalidate_lr := false - - // place AMO data in correct word lane - val minAMOBytes = 4 - val grantData = Mux(io.dmem.resp.valid, io.dmem.resp.bits.data, acq.data) - val alignedGrantData = Mux(acq.op_size() <= log2Ceil(minAMOBytes), Fill(coreDataBytes/minAMOBytes, grantData(8*minAMOBytes-1, 0)), grantData) - - io.tl.grant.valid := io.dmem.resp.valid || state === s_grant - io.tl.grant.bits := Grant( - is_builtin_type = Bool(true), - g_type = acq.getBuiltInGrantType(), - client_xact_id = acq.client_xact_id, - manager_xact_id = UInt(0), - addr_beat = acq.addr_beat, - data = alignedGrantData) } diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index 5d30c1a1..f3c9d27b 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -27,40 +27,43 @@ case class RoccParameters( case class TileBundleConfig( nCachedTileLinkPorts: Int, nUncachedTileLinkPorts: Int, - xLen: Int, - hasSlavePort: Boolean) + xLen: Int) -class TileIO(c: TileBundleConfig)(implicit p: Parameters) extends Bundle { +class TileIO(c: TileBundleConfig, node: Option[TLInwardNode] = None)(implicit p: Parameters) extends Bundle { val cached = Vec(c.nCachedTileLinkPorts, new ClientTileLinkIO) val uncached = Vec(c.nUncachedTileLinkPorts, new ClientUncachedTileLinkIO) val hartid = UInt(INPUT, c.xLen) val interrupts = new TileInterrupts().asInput - val slave = c.hasSlavePort.option(new ClientUncachedTileLinkIO().flip) + val slave = node.map(_.inward.bundleIn) val resetVector = UInt(INPUT, c.xLen) override def cloneType = new TileIO(c).asInstanceOf[this.type] } abstract class TileImp(l: LazyTile)(implicit p: Parameters) extends LazyModuleImp(l) { + val io: TileIO +} + +abstract class LazyTile(implicit p: Parameters) extends LazyModule { val nCachedTileLinkPorts = p(NCachedTileLinkPorts) val nUncachedTileLinkPorts = p(NUncachedTileLinkPorts) val dcacheParams = p.alterPartial({ case CacheName => "L1D" }) val bc = TileBundleConfig( nCachedTileLinkPorts = nCachedTileLinkPorts, nUncachedTileLinkPorts = nUncachedTileLinkPorts, - xLen = p(XLen), - hasSlavePort = p(DataScratchpadSize) > 0) + xLen = p(XLen)) - val io: TileIO -} - -abstract class LazyTile(implicit p: Parameters) extends LazyModule { val module: TileImp } class RocketTile(implicit p: Parameters) extends LazyTile { + val slave = if (p(DataScratchpadSize) == 0) None else Some(TLOutputNode()) + val scratch = if (p(DataScratchpadSize) == 0) None else Some(LazyModule(new ScratchpadSlavePort()(dcacheParams))) + + (slave zip scratch) foreach { case (node, lm) => node := lm.node } + lazy val module = new TileImp(this) { - val io = new TileIO(bc) + val io = new TileIO(bc, slave) val buildRocc = p(BuildRoCC) val usingRocc = !buildRocc.isEmpty val nRocc = buildRocc.size @@ -146,11 +149,7 @@ class RocketTile(implicit p: Parameters) extends LazyTile { core.io.ptw <> ptw.io.dpath } - io.slave foreach { case slavePort => - val adapter = Module(new ScratchpadSlavePort()(dcacheParams)) - adapter.io.tl <> TileLinkFragmenter(slavePort) - adapter.io.dmem +=: dcPorts - } + scratch.foreach { lm => lm.module.io.dmem +=: dcPorts } require(dcPorts.size == core.dcacheArbPorts) val dcArb = Module(new HellaCacheArbiter(dcPorts.size)(dcacheParams)) diff --git a/src/main/scala/uncore/tilelink2/package.scala b/src/main/scala/uncore/tilelink2/package.scala index 55ff6b27..3fcd3fc5 100644 --- a/src/main/scala/uncore/tilelink2/package.scala +++ b/src/main/scala/uncore/tilelink2/package.scala @@ -5,9 +5,11 @@ import diplomacy._ package object tilelink2 { + type TLInwardNode = InwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] type TLOutwardNode = OutwardNodeHandle[TLClientPortParameters, TLManagerPortParameters, TLBundle] type TLAsyncOutwardNode = OutwardNodeHandle[TLAsyncClientPortParameters, TLAsyncManagerPortParameters, TLAsyncBundle] type IntOutwardNode = OutwardNodeHandle[IntSourcePortParameters, IntSinkPortParameters, Vec[Bool]] + def OH1ToOH(x: UInt) = (x << 1 | UInt(1)) & ~Cat(UInt(0, width=1), x) def OH1ToUInt(x: UInt) = OHToUInt(OH1ToOH(x)) def UIntToOH1(x: UInt, width: Int) = ~(SInt(-1, width=width).asUInt << x)(width-1, 0) From 89139a94923beb10b6e05b6568131d79d68ae5b8 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 13:09:11 -0700 Subject: [PATCH 18/47] Plic: split constants from variables used in config string --- src/main/scala/rocketchip/Utils.scala | 2 +- src/main/scala/uncore/devices/Plic.scala | 55 ++++++++++++++---------- 2 files changed, 33 insertions(+), 24 deletions(-) diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index fb16cec4..b4122cda 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -112,7 +112,7 @@ object GenerateConfigString { val res = new StringBuilder res append "plic {\n" res append s" priority 0x${plicAddr.toString(16)};\n" - res append s" pending 0x${(plicAddr + c.plicKey.pendingBase).toString(16)};\n" + res append s" pending 0x${(plicAddr + PLICConsts.pendingBase).toString(16)};\n" res append s" ndevs ${c.plicKey.nDevices};\n" res append "};\n" res append "rtc {\n" diff --git a/src/main/scala/uncore/devices/Plic.scala b/src/main/scala/uncore/devices/Plic.scala index 0660fce6..582d1131 100644 --- a/src/main/scala/uncore/devices/Plic.scala +++ b/src/main/scala/uncore/devices/Plic.scala @@ -28,30 +28,39 @@ class LevelGateway extends Module { io.plic.valid := io.interrupt && !inFlight } -case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriorities: Int, address: BigInt = 0xC000000) { - def contextsPerHart = if (supervisor) 2 else 1 - def nHarts = contextsPerHart * nHartsIn - def context(i: Int, mode: Char) = mode match { - case 'M' => i * contextsPerHart - case 'S' => require(supervisor); i * contextsPerHart + 1 - } - def claimAddr(i: Int, mode: Char) = hartBase + hartOffset(context(i, mode)) + claimOffset - def threshAddr(i: Int, mode: Char) = hartBase + hartOffset(context(i, mode)) - def enableAddr(i: Int, mode: Char) = enableBase + enableOffset(context(i, mode)) - def size = hartBase + hartOffset(maxHarts) - +object PLICConsts +{ def maxDevices = 1023 def maxHarts = 15872 def priorityBase = 0x0 def pendingBase = 0x1000 def enableBase = 0x2000 def hartBase = 0x200000 - require(hartBase >= enableBase + enableOffset(maxHarts)) + + def claimOffset = 4 + def priorityBytes = 4 def enableOffset(i: Int) = i * ((maxDevices+7)/8) def hartOffset(i: Int) = i * 0x1000 - def claimOffset = 4 - def priorityBytes = 4 + def enableBase(i: Int):Int = enableOffset(i) + enableBase + def hartBase(i: Int):Int = hartOffset(i) + hartBase + + def size = hartBase(maxHarts) + require(hartBase >= enableBase(maxHarts)) +} + +case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriorities: Int) { + import PLICConsts._ + + def contextsPerHart = if (supervisor) 2 else 1 + def nHarts = contextsPerHart * nHartsIn + def context(i: Int, mode: Char) = mode match { + case 'M' => i * contextsPerHart + case 'S' => require(supervisor); i * contextsPerHart + 1 + } + def claimAddr(i: Int, mode: Char) = hartBase(context(i, mode)) + claimOffset + def threshAddr(i: Int, mode: Char) = hartBase(context(i, mode)) + def enableAddr(i: Int, mode: Char) = enableBase(context(i, mode)) require(nDevices <= maxDevices) require(nHarts > 0 && nHarts <= maxHarts) @@ -59,8 +68,8 @@ case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriori } trait HasPLICParamters { - val params: (PLICConfig, Parameters) - val cfg = params._1 + val params: (() => PLICConfig, Parameters) + val cfg = params._1 () implicit val p = params._2 } @@ -109,15 +118,15 @@ trait PLICModule extends Module with HasRegMap with HasPLICParamters { } def priorityRegField(x: UInt) = if (cfg.nPriorities > 0) RegField(32, x) else RegField.r(32, x) - val piorityRegFields = Seq(cfg.priorityBase -> priority.map(p => priorityRegField(p))) - val pendingRegFields = Seq(cfg.pendingBase -> pending .map(b => RegField.r(1, b))) + val piorityRegFields = Seq(PLICConsts.priorityBase -> priority.map(p => priorityRegField(p))) + val pendingRegFields = Seq(PLICConsts.pendingBase -> pending .map(b => RegField.r(1, b))) val enableRegFields = enables.zipWithIndex.map { case (e, i) => - cfg.enableBase + cfg.enableOffset(i) -> e.map(b => RegField(1, b)) + PLICConsts.enableBase(i) -> e.map(b => RegField(1, b)) } val hartRegFields = Seq.tabulate(cfg.nHarts) { i => - cfg.hartBase + cfg.hartOffset(i) -> Seq( + PLICConsts.hartBase(i) -> Seq( priorityRegField(threshold(i)), RegField(32, RegReadFn { valid => @@ -146,7 +155,7 @@ trait PLICModule extends Module with HasRegMap with HasPLICParamters { } /** Platform-Level Interrupt Controller */ -class TLPLIC(c: PLICConfig)(implicit val p: Parameters) - extends TLRegisterRouter(c.address, size = c.size, beatBytes = p(rocket.XLen)/8, undefZero = false)( +class TLPLIC(c: () => PLICConfig, address: BigInt = 0xC000000)(implicit val p: Parameters) + extends TLRegisterRouter(address, size = PLICConsts.size, beatBytes = p(rocket.XLen)/8, undefZero = false)( new TLRegBundle((c, p), _) with PLICBundle)( new TLRegModule((c, p), _, _) with PLICModule) From 825c253a72e44952cf77e54cb0c8386b3566cfbf Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Wed, 26 Oct 2016 22:28:40 -0700 Subject: [PATCH 19/47] rocketchip: move TL2 and cake pattern into Coreplex --- src/main/scala/coreplex/BaseCoreplex.scala | 183 ++++++++++++-------- src/main/scala/coreplex/Coreplex.scala | 27 ++- src/main/scala/groundtest/Configs.scala | 4 +- src/main/scala/groundtest/Coreplex.scala | 10 +- src/main/scala/groundtest/Tile.scala | 1 + src/main/scala/rocket/dcache.scala | 4 +- src/main/scala/rocket/tile.scala | 1 + src/main/scala/rocketchip/BaseTop.scala | 62 +++---- src/main/scala/rocketchip/Configs.scala | 4 +- src/main/scala/rocketchip/ExampleTop.scala | 16 +- src/main/scala/rocketchip/Periphery.scala | 13 +- src/main/scala/rocketchip/TestHarness.scala | 4 +- src/main/scala/rocketchip/Utils.scala | 3 +- 13 files changed, 173 insertions(+), 159 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index e02b0190..12eff1c7 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -35,59 +35,53 @@ trait HasCoreplexParameters { lazy val outerMemParams = p.alterPartial({ case TLId => "L2toMC" }) lazy val outerMMIOParams = p.alterPartial({ case TLId => "L2toMMIO" }) lazy val globalAddrMap = p(rocketchip.GlobalAddrMap) + lazy val nTiles = p(uncore.devices.NTiles) + lazy val nExtInterrupts = p(rocketchip.NExtInterrupts) + lazy val nSlaves = p(rocketchip.NCoreplexExtClients) + lazy val nMemChannels = p(NMemoryChannels) + lazy val hasSupervisor = p(rocket.UseVM) + + lazy val nInterruptPriorities = if (nExtInterrupts <= 1) 0 else (nExtInterrupts min 7) + lazy val plicKey = PLICConfig(nTiles, hasSupervisor, nExtInterrupts, nInterruptPriorities) + lazy val clintKey = CoreplexLocalInterrupterConfig() } -case class CoreplexConfig( - nTiles: Int, - nExtInterrupts: Int, - nSlaves: Int, - nMemChannels: Int, - hasSupervisor: Boolean) -{ - val nInterruptPriorities = if (nExtInterrupts <= 1) 0 else (nExtInterrupts min 7) - val plicKey = PLICConfig(nTiles, hasSupervisor, nExtInterrupts, nInterruptPriorities) -} +case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters -abstract class BaseCoreplex(c: CoreplexConfig)(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { +abstract class BareCoreplex(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { + val l1tol2 = LazyModule(new TLXbar) + val mmio = TLOutputNode() val lazyTiles = p(BuildTiles) map { _(p) } + val legacy = LazyModule(new TLLegacy()(outerMMIOParams)) - val debugLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) - val debug = LazyModule(new TLDebugModule()) - debug.node := - TLHintHandler()( + mmio := TLBuffer()( - TLFragmenter(p(XLen)/8, debugLegacy.tlDataBeats * debugLegacy.tlDataBytes)( - TLWidthWidget(debugLegacy.tlDataBytes)(debugLegacy.node)))) - - val plicLegacy = LazyModule(new TLLegacy()(outerMMIOParams)) - val plic = LazyModule(new TLPLIC(c.plicKey)) - plic.node := - TLHintHandler()( - TLBuffer()( - TLFragmenter(p(XLen)/8, plicLegacy.tlDataBeats * plicLegacy.tlDataBytes)( - TLWidthWidget(plicLegacy.tlDataBytes)(plicLegacy.node)))) + TLWidthWidget(legacy.tlDataBytes)( + l1tol2.node)) + // Kill this once we move TL2 into rocket + l1tol2.node := + TLHintHandler()( + legacy.node) } -abstract class BaseCoreplexBundle(val c: CoreplexConfig)(implicit val p: Parameters) extends Bundle with HasCoreplexParameters { +abstract class BareCoreplexBundle[+L <: BareCoreplex](val outer: L) extends Bundle with HasCoreplexParameters { + implicit val p = outer.p + val master = new Bundle { - val mem = Vec(c.nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) - val mmio = new ClientUncachedTileLinkIO()(outerMMIOParams) + val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) + val mmio = outer.mmio.bundleOut } - val slave = Vec(c.nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip - val interrupts = Vec(c.nExtInterrupts, Bool()).asInput - val debug = new DebugBusIO()(p).flip - val clint = Vec(c.nTiles, new CoreplexLocalInterrupts).asInput + + val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip val resetVector = UInt(INPUT, p(XLen)) val success = Bool(OUTPUT) // used for testing - override def cloneType = this.getClass.getConstructors.head.newInstance(c, p).asInstanceOf[this.type] + override def cloneType = this.getClass.getConstructors.head.newInstance(outer).asInstanceOf[this.type] } -abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( - c: CoreplexConfig, l: L, b: B)(implicit val p: Parameters) extends LazyModuleImp(l) with HasCoreplexParameters { - val outer: L = l - val io: B = b +abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](val outer: L, val io: B) extends LazyModuleImp(outer) with HasCoreplexParameters { + implicit val p = outer.p // Build a set of Tiles val tiles = outer.lazyTiles.map(_.module) @@ -95,9 +89,8 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( val nCachedPorts = tiles.map(tile => tile.io.cached.size).reduce(_ + _) val nUncachedPorts = tiles.map(tile => tile.io.uncached.size).reduce(_ + _) - val nBanks = c.nMemChannels * nBanksPerMemChannel - - // Build an uncore backing the Tiles + val nBanks = nMemChannels * nBanksPerMemChannel + buildUncore(p.alterPartial({ case HastiId => "TL" case TLId => "L1toL2" @@ -105,7 +98,7 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( case NUncachedTileLinkPorts => nUncachedPorts })) - def buildUncore(implicit p: Parameters) = { + def buildUncore(implicit p: Parameters) { // 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) @@ -130,9 +123,10 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( // and coherence manager(s) to the other side l1tol2net.io.clients_cached <> uncoreTileIOs.map(_.cached).flatten l1tol2net.io.clients_uncached <> uncoreTileIOs.map(_.uncached).flatten ++ io.slave - l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner // legacy goes here (not mmioManager) + l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner + outer.legacy.module.io.legacy <> mmioManager.io.outer - val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, c.nMemChannels)(outerMemParams)) + val mem_ic = Module(new TileLinkMemoryInterconnect(nBanksPerMemChannel, nMemChannels)(outerMemParams)) val backendBuffering = TileLinkDepths(0,0,0,0,0) for ((bank, icPort) <- managerEndpoints zip mem_ic.io.in) { @@ -141,43 +135,80 @@ abstract class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle]( } io.master.mem <> mem_ic.io.out - - buildMMIONetwork(TileLinkEnqueuer(mmioManager.io.outer, 1))(outerMMIOParams) } - def buildMMIONetwork(mmio: ClientUncachedTileLinkIO)(implicit p: Parameters) = { - val ioAddrMap = globalAddrMap.subMap("io") - - val cBus = Module(new TileLinkRecursiveInterconnect(1, ioAddrMap)) - cBus.io.in.head <> mmio - - outer.plicLegacy.module.io.legacy <> cBus.port("cbus:plic") - for (i <- 0 until io.interrupts.size) { - val gateway = Module(new LevelGateway) - gateway.io.interrupt := io.interrupts(i) - outer.plic.module.io.devices(i) <> gateway.io.plic - } - - outer.debugLegacy.module.io.legacy <> cBus.port("cbus:debug") - outer.debug.module.io.db <> io.debug - - // connect coreplex-internal interrupts to tiles - for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { - tile.interrupts <> io.clint(i) - tile.interrupts.meip := outer.plic.module.io.harts(c.plicKey.context(i, 'M')) - tile.interrupts.seip.foreach(_ := outer.plic.module.io.harts(c.plicKey.context(i, 'S'))) - tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) - tile.hartid := UInt(i) - tile.resetVector := io.resetVector - } - - val tileSlavePorts = (0 until c.nTiles) map (i => s"cbus:dmem$i") filter (ioAddrMap contains _) - for ((t, m) <- (uncoreTileIOs.map(_.slave).flatten) zip (tileSlavePorts map (cBus port _))) - t <> m - - io.master.mmio <> cBus.port("TL2") + for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { + tile.hartid := UInt(i) + tile.resetVector := io.resetVector } // Coreplex doesn't know when to stop running io.success := Bool(false) } + +trait CoreplexPeripherals extends HasCoreplexParameters { + val module: CoreplexPeripheralsModule + val l1tol2: TLXbar + val legacy: TLLegacy + val lazyTiles: Seq[LazyTile] + + val cbus = LazyModule(new TLXbar) + val debug = LazyModule(new TLDebugModule()) + val plic = LazyModule(new TLPLIC(() => plicKey)) + val clint = LazyModule(new CoreplexLocalInterrupter(clintKey)) + + cbus.node := + TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata + TLWidthWidget(legacy.tlDataBytes)( + TLBuffer()( + l1tol2.node))) + + debug.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) + plic.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) + clint.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) + + lazyTiles.map(_.slave).flatten.foreach { scratch => + scratch := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) + } +} + +trait CoreplexPeripheralsBundle extends HasCoreplexParameters { + val outer: CoreplexPeripherals + + val debug = new DebugBusIO().flip + val interrupts = Vec(nExtInterrupts, Bool()).asInput +} + +trait CoreplexPeripheralsModule extends HasCoreplexParameters { + val outer: CoreplexPeripherals + val io: CoreplexPeripheralsBundle + val uncoreTileIOs: Seq[TileIO] + + for (i <- 0 until io.interrupts.size) { + val gateway = Module(new LevelGateway) + gateway.io.interrupt := io.interrupts(i) + outer.plic.module.io.devices(i) <> gateway.io.plic + } + + outer.debug.module.io.db <> io.debug + outer.clint.module.io.rtcTick := Counter(p(rocketchip.RTCPeriod)).inc() + + // connect coreplex-internal interrupts to tiles + for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { + tile.interrupts <> outer.clint.module.io.tiles(i) + tile.interrupts.meip := outer.plic.module.io.harts(plicKey.context(i, 'M')) + tile.interrupts.seip.foreach(_ := outer.plic.module.io.harts(plicKey.context(i, 'S'))) + tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) + } +} + +class BaseCoreplex(implicit p: Parameters) extends BareCoreplex + with CoreplexPeripherals { + override lazy val module = new BaseCoreplexModule(this, new BaseCoreplexBundle(this)) +} + +class BaseCoreplexBundle[+L <: BaseCoreplex](outer: L) extends BareCoreplexBundle(outer) + with CoreplexPeripheralsBundle + +class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](outer: L, io: B) extends BareCoreplexModule(outer, io) + with CoreplexPeripheralsModule diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 4af784ee..7a5a9b0c 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -18,7 +18,7 @@ trait DirectConnection { (tiles zip uncoreTileIOs) foreach { case (tile, uncore) => (uncore.cached zip tile.io.cached) foreach { case (u, t) => u <> TileLinkEnqueuer(t, tlBuffering) } (uncore.uncached zip tile.io.uncached) foreach { case (u, t) => u <> TileLinkEnqueuer(t, ultBuffering) } - tile.io.slave.foreach { _ <> TileLinkEnqueuer(uncore.slave.get, 1) } +// !!! tile.io.slave.foreach { _ <> TileLinkEnqueuer(uncore.slave.get, 1) } tile.io.interrupts <> uncore.interrupts @@ -27,21 +27,19 @@ trait DirectConnection { } } -class DefaultCoreplex(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplex(c)(p) { - override lazy val module = Module(new DefaultCoreplexModule(c, this, new DefaultCoreplexBundle(c)(p))(p)) +class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex { + override lazy val module = new DefaultCoreplexModule(this, new DefaultCoreplexBundle(this)) } -class DefaultCoreplexBundle(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplexBundle(c)(p) +class DefaultCoreplexBundle[+L <: DefaultCoreplex](outer: L) extends BaseCoreplexBundle(outer) -class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle]( - c: CoreplexConfig, l: L, b: B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) +class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) with DirectConnection ///// -trait TileClockResetBundle { - val c: CoreplexConfig - val tcrs = Vec(c.nTiles, new Bundle { +trait TileClockResetBundle extends HasCoreplexParameters { + val tcrs = Vec(nTiles, new Bundle { val clock = Clock(INPUT) val reset = Bool(INPUT) }) @@ -58,7 +56,7 @@ trait AsyncConnection { (uncore.cached zip tile.io.cached) foreach { case (u, t) => u <> AsyncTileLinkFrom(tcr.clock, tcr.reset, t) } (uncore.uncached zip tile.io.uncached) foreach { case (u, t) => u <> AsyncUTileLinkFrom(tcr.clock, tcr.reset, t) } - tile.io.slave.foreach { _ <> AsyncUTileLinkTo(tcr.clock, tcr.reset, uncore.slave.get)} +// !!! tile.io.slave.foreach { _ <> AsyncUTileLinkTo(tcr.clock, tcr.reset, uncore.slave.get)} val ti = tile.io.interrupts val ui = uncore.interrupts @@ -73,13 +71,12 @@ trait AsyncConnection { } } -class MultiClockCoreplex(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplex(c)(p) { - override lazy val module = Module(new MultiClockCoreplexModule(c, this, new MultiClockCoreplexBundle(c)(p))(p)) +class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex { + override lazy val module = new MultiClockCoreplexModule(this, new MultiClockCoreplexBundle(this)) } -class MultiClockCoreplexBundle(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplexBundle(c)(p) +class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](outer: L) extends BaseCoreplexBundle(outer) with TileClockResetBundle -class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle]( - c: CoreplexConfig, l: L, b: B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) +class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) with AsyncConnection diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index bf986429..e981774a 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -72,8 +72,6 @@ class Edge32BitMemtestConfig extends Config( /* Composable Configs to set individual parameters */ class WithGroundTest extends Config( (pname, site, here) => pname match { - case BuildCoreplex => - (c: CoreplexConfig, p: Parameters) => LazyModule(new GroundTestCoreplex(c)(p)).module case TLKey("L1toL2") => { val useMEI = site(NTiles) <= 1 && site(NCachedTileLinkPorts) <= 1 val dataBeats = (8 * site(CacheBlockBytes)) / site(XLen) @@ -106,7 +104,7 @@ class WithGroundTest extends Config( } } case BuildExampleTop => - (p: Parameters) => LazyModule(new ExampleTopWithTestRAM(p)) + (p: Parameters) => LazyModule(new ExampleTopWithTestRAM(new GroundTestCoreplex()(_))(p)) case FPUKey => None case UseAtomics => false case UseCompressed => false diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index 35580996..bd9c765f 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -4,13 +4,13 @@ import Chisel._ import cde.{Parameters} import coreplex._ -class GroundTestCoreplex(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplex(c)(p) { - override lazy val module = Module(new GroundTestCoreplexModule(c, this, new GroundTestCoreplexBundle(c)(p))(p)) +class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex { + override lazy val module = new GroundTestCoreplexModule(this, new GroundTestCoreplexBundle(this)) } -class GroundTestCoreplexBundle(c: CoreplexConfig)(implicit p: Parameters) extends BaseCoreplexBundle(c)(p) +class GroundTestCoreplexBundle[+L <: GroundTestCoreplex](outer: L) extends BaseCoreplexBundle(outer) -class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle]( - c: CoreplexConfig, l: L, b: B)(implicit p: Parameters) extends BaseCoreplexModule(c, l, b)(p) with DirectConnection { +class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) + with DirectConnection { io.success := tiles.flatMap(_.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_) } diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 63ac1f64..43b0390a 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -97,6 +97,7 @@ abstract class GroundTest(implicit val p: Parameters) extends Module } class GroundTestTile(implicit val p: Parameters) extends LazyTile with HasGroundTestParameters { + val slave = None lazy val module = new TileImp(this) { val io = new TileIO(bc) { val success = Bool(OUTPUT) diff --git a/src/main/scala/rocket/dcache.scala b/src/main/scala/rocket/dcache.scala index a10d4080..e0294bca 100644 --- a/src/main/scala/rocket/dcache.scala +++ b/src/main/scala/rocket/dcache.scala @@ -497,7 +497,7 @@ class DCache(implicit p: Parameters) extends L1HellaCacheModule()(p) { } } -class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { +class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with HasCoreParameters { val beatBytes = p(XLen)/8 val node = TLManagerNode(TLManagerPortParameters( Seq(TLManagerParameters( @@ -510,7 +510,7 @@ class ScratchpadSlavePort(implicit p: Parameters) extends LazyModule { beatBytes = beatBytes, minLatency = 1)) - lazy val module = new LazyModuleImp(this) with HasCoreParameters { + lazy val module = new LazyModuleImp(this) { val io = new Bundle { val tl_in = node.bundleIn val dmem = new HellaCacheIO diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index f3c9d27b..473a578c 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -54,6 +54,7 @@ abstract class LazyTile(implicit p: Parameters) extends LazyModule { xLen = p(XLen)) val module: TileImp + val slave: Option[TLOutputNode] } class RocketTile(implicit p: Parameters) extends LazyTile { diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 82f3b824..5bcc2df6 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -17,13 +17,12 @@ import coreplex._ case object GlobalAddrMap extends Field[AddrMap] case object ConfigString extends Field[String] case object NCoreplexExtClients extends Field[Int] +case object NExtInterrupts extends Field[Int] /** Enable or disable monitoring of Diplomatic buses */ case object TLEmitMonitors extends Field[Bool] -/** Function for building Coreplex */ -case object BuildCoreplex extends Field[(CoreplexConfig, Parameters) => BaseCoreplexModule[BaseCoreplex, BaseCoreplexBundle]] /** Base Top with no Periphery */ -abstract class BaseTop(q: Parameters) extends LazyModule { +abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit q: Parameters) extends LazyModule { // the following variables will be refactored properly with TL2 val pInterrupts = new RangeManager val pBusMasters = new RangeManager @@ -35,52 +34,39 @@ abstract class BaseTop(q: Parameters) extends LazyModule { val peripheryBus = LazyModule(new TLXbar) lazy val peripheryManagers = socBus.node.edgesIn(0).manager.managers - lazy val c = CoreplexConfig( - nTiles = q(NTiles), - nExtInterrupts = pInterrupts.sum, - nSlaves = pBusMasters.sum, - nMemChannels = q(NMemoryChannels), - hasSupervisor = q(UseVM) - ) + // Fill in the TL1 legacy parameters + val qWithSums = q.alterPartial { + case NCoreplexExtClients => pBusMasters.sum + case NExtInterrupts => pInterrupts.sum + } + val qWithMap = qWithSums.alterPartial { + case GlobalAddrMap => GenerateGlobalAddrMap(qWithSums, peripheryManagers) + } + implicit val p = qWithMap.alterPartial { + case ConfigString => GenerateConfigString(qWithMap, peripheryManagers) + } - lazy val genGlobalAddrMap = GenerateGlobalAddrMap(q, peripheryManagers) - private val qWithMap = q.alterPartial({case GlobalAddrMap => genGlobalAddrMap}) - - lazy val genConfigString = GenerateConfigString(qWithMap, c, peripheryManagers) - implicit val p = qWithMap.alterPartial({ - case ConfigString => genConfigString - case NCoreplexExtClients => pBusMasters.sum}) - - val legacy = LazyModule(new TLLegacy()(p.alterPartial({ case TLId => "L2toMMIO" }))) + val coreplex = LazyModule(buildCoreplex(p)) peripheryBus.node := - TLWidthWidget(p(SOCBusKey).beatBytes)( TLBuffer()( TLAtomicAutomata(arithmetic = p(PeripheryBusKey).arithAMO)( + TLWidthWidget(p(SOCBusKey).beatBytes)( socBus.node))) - socBus.node := - TLWidthWidget(legacy.tlDataBytes)( - TLHintHandler()( - legacy.node)) + socBus.node := coreplex.mmio TopModule.contents = Some(this) } -abstract class BaseTopBundle[+L <: BaseTop]( - val p: Parameters, - val outer: L) extends Bundle { +abstract class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](val outer: L) extends Bundle { + implicit val p = outer.p val success = Bool(OUTPUT) } -abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]]( - val p: Parameters, - val outer: L, - val io: B) extends LazyModuleImp(outer) { - val coreplex = p(BuildCoreplex)(outer.c, p) - val coreplexIO = Wire(coreplex.io) - - outer.legacy.module.io.legacy <> coreplexIO.master.mmio +abstract class BaseTopModule[+L <: BaseTop[BaseCoreplex], +B <: BaseTopBundle[L]](val outer: L, val io: B) extends LazyModuleImp(outer) { + implicit val p = outer.p + val coreplexIO = Wire(outer.coreplex.module.io) println("Generated Address Map") for (entry <- p(GlobalAddrMap).flatten) { @@ -106,8 +92,8 @@ abstract class BaseTopModule[+L <: BaseTop, +B <: BaseTopBundle[L]]( } trait DirectConnection { - val coreplexIO: BaseCoreplexBundle - val coreplex: BaseCoreplexModule[BaseCoreplex, BaseCoreplexBundle] + val coreplexIO: BaseCoreplexBundle[BaseCoreplex] + val outer: BaseTop[BaseCoreplex] - coreplexIO <> coreplex.io + coreplexIO <> outer.coreplex.module.io } diff --git a/src/main/scala/rocketchip/Configs.scala b/src/main/scala/rocketchip/Configs.scala index c684b72b..92643944 100644 --- a/src/main/scala/rocketchip/Configs.scala +++ b/src/main/scala/rocketchip/Configs.scala @@ -40,8 +40,6 @@ class BasePlatformConfig extends Config( site(TLKey("L2toMC")).copy(dataBeats = edgeDataBeats) case TLKey("MMIOtoEdge") => site(TLKey("L2toMMIO")).copy(dataBeats = edgeDataBeats) - case BuildCoreplex => - (c: CoreplexConfig, p: Parameters) => LazyModule(new DefaultCoreplex(c)(p)).module case NExtTopInterrupts => 2 case SOCBusKey => SOCBusConfig(beatBytes = site(TLKey("L2toMMIO")).dataBitsPerBeat/8) case PeripheryBusKey => PeripheryBusConfig(arithAMO = true, beatBytes = 4) @@ -65,7 +63,7 @@ class BasePlatformConfig extends Config( case ExtMemSize => Dump("MEM_SIZE", 0x10000000L) case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock case BuildExampleTop => - (p: Parameters) => LazyModule(new ExampleTop(p)) + (p: Parameters) => LazyModule(new ExampleTop(new DefaultCoreplex()(_))(p)) case SimMemLatency => 0 case _ => throw new CDEMatchError } diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 922acb7b..01088aa5 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -9,17 +9,17 @@ import coreplex._ import rocketchip._ /** Example Top with Periphery */ -class ExampleTop(q: Parameters) extends BaseTop(q) +class ExampleTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends BaseTop(buildCoreplex) with PeripheryBootROM with PeripheryDebug with PeripheryExtInterrupts with PeripheryMasterMem with PeripheryMasterAXI4MMIO with PeripherySlave { - override lazy val module = Module(new ExampleTopModule(p, this, new ExampleTopBundle(p, this))) + override lazy val module = new ExampleTopModule(this, new ExampleTopBundle(this)) } -class ExampleTopBundle[+L <: ExampleTop](p: Parameters, l: L) extends BaseTopBundle(p, l) +class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](outer: L) extends BaseTopBundle(outer) with PeripheryBootROMBundle with PeripheryDebugBundle with PeripheryExtInterruptsBundle @@ -27,7 +27,7 @@ class ExampleTopBundle[+L <: ExampleTop](p: Parameters, l: L) extends BaseTopBun with PeripheryMasterAXI4MMIOBundle with PeripherySlaveBundle -class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](p: Parameters, l: L, b: B) extends BaseTopModule(p, l, b) +class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L]](outer: L, io: B) extends BaseTopModule(outer, io) with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule @@ -38,13 +38,13 @@ class ExampleTopModule[+L <: ExampleTop, +B <: ExampleTopBundle[L]](p: Parameter with DirectConnection /** Example Top with TestRAM */ -class ExampleTopWithTestRAM(q: Parameters) extends ExampleTop(q) +class ExampleTopWithTestRAM[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(buildCoreplex) with PeripheryTestRAM { - override lazy val module = Module(new ExampleTopWithTestRAMModule(p, this, new ExampleTopWithTestRAMBundle(p, this))) + override lazy val module = new ExampleTopWithTestRAMModule(this, new ExampleTopWithTestRAMBundle(this)) } -class ExampleTopWithTestRAMBundle[+L <: ExampleTopWithTestRAM](p: Parameters, l: L) extends ExampleTopBundle(p, l) +class ExampleTopWithTestRAMBundle[+L <: ExampleTopWithTestRAM[BaseCoreplex]](outer: L) extends ExampleTopBundle(outer) with PeripheryTestRAMBundle -class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM, +B <: ExampleTopWithTestRAMBundle[L]](p: Parameters, l: L, b: B) extends ExampleTopModule(p, l, b) +class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM[BaseCoreplex], +B <: ExampleTopWithTestRAMBundle[L]](outer: L, io: B) extends ExampleTopModule(outer, io) with PeripheryTestRAMModule diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 53b128e8..f123168c 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -110,7 +110,7 @@ trait PeripheryDebugModule { implicit val p: Parameters val outer: PeripheryDebug val io: PeripheryDebugBundle - val coreplexIO: BaseCoreplexBundle + val coreplexIO: BaseCoreplexBundle[BaseCoreplex] if (p(IncludeJtagDTM)) { // JtagDTMWithSync is a wrapper which @@ -143,7 +143,7 @@ trait PeripheryExtInterruptsModule { implicit val p: Parameters val outer: PeripheryExtInterrupts val io: PeripheryExtInterruptsBundle - val coreplexIO: BaseCoreplexBundle + val coreplexIO: BaseCoreplexBundle[BaseCoreplex] { val r = outer.pInterrupts.range("ext") @@ -172,7 +172,7 @@ trait PeripheryMasterMemModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripheryMasterMem val io: PeripheryMasterMemBundle - val coreplexIO: BaseCoreplexBundle + val coreplexIO: BaseCoreplexBundle[BaseCoreplex] val edgeMem = coreplexIO.master.mem.map(TileLinkWidthAdapter(_, edgeMemParams)) @@ -199,8 +199,9 @@ trait PeripheryMasterMemModule extends HasPeripheryParameters { ///// // PeripheryMasterAXI4MMIO is an example, make your own cake pattern like this one. -trait PeripheryMasterAXI4MMIO extends BaseTop with HasPeripheryParameters { +trait PeripheryMasterAXI4MMIO extends HasPeripheryParameters { implicit val p: Parameters + val socBus: TLXbar val mmio_axi4 = AXI4BlindOutputNode(AXI4SlavePortParameters( slaves = Seq(AXI4SlaveParameters( @@ -253,7 +254,7 @@ trait PeripherySlaveModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripherySlave val io: PeripherySlaveBundle - val coreplexIO: BaseCoreplexBundle + val coreplexIO: BaseCoreplexBundle[BaseCoreplex] if (p(NExtBusAXIChannels) > 0) { val arb = Module(new NastiArbiter(p(NExtBusAXIChannels))) @@ -339,6 +340,6 @@ trait PeripheryTestBusMasterModule { ///// trait HardwiredResetVector { - val coreplexIO: BaseCoreplexBundle + val coreplexIO: BaseCoreplexBundle[BaseCoreplex] coreplexIO.resetVector := UInt(0x1000) // boot ROM } diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index c4ba731e..50eb45b6 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -8,14 +8,14 @@ import junctions._ import junctions.NastiConstants._ import util.LatencyPipe -case object BuildExampleTop extends Field[Parameters => ExampleTop] +case object BuildExampleTop extends Field[Parameters => ExampleTop[coreplex.BaseCoreplex]] case object SimMemLatency extends Field[Int] class TestHarness(q: Parameters) extends Module { val io = new Bundle { val success = Bool(OUTPUT) } - val dut = q(BuildExampleTop)(q).module + val dut = Module(q(BuildExampleTop)(q).module) implicit val p = dut.p // This test harness isn't especially flexible yet diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index b4122cda..c9c77771 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -104,7 +104,8 @@ object GenerateGlobalAddrMap { } object GenerateConfigString { - def apply(p: Parameters, c: CoreplexConfig, peripheryManagers: Seq[TLManagerParameters]) = { + def apply(p: Parameters, peripheryManagers: Seq[TLManagerParameters]) = { + val c = CoreplexParameters()(p) val addrMap = p(GlobalAddrMap) val plicAddr = addrMap("io:cbus:plic").start val clint = CoreplexLocalInterrupterConfig() From a73aa351ca1b6701c2e5865a9b50e85c449b2667 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 15:34:37 -0700 Subject: [PATCH 20/47] rocketchip: fix all clock crossings --- src/main/scala/coreplex/BaseCoreplex.scala | 16 ++----- src/main/scala/coreplex/Coreplex.scala | 53 +++++++++++++++++++--- src/main/scala/groundtest/Coreplex.scala | 5 +- src/main/scala/rocketchip/BaseTop.scala | 28 +++++++++--- src/main/scala/rocketchip/ExampleTop.scala | 5 +- src/main/scala/rocketchip/Periphery.scala | 23 +++++----- 6 files changed, 89 insertions(+), 41 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 12eff1c7..4f794a74 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -68,16 +68,11 @@ abstract class BareCoreplex(implicit val p: Parameters) extends LazyModule with abstract class BareCoreplexBundle[+L <: BareCoreplex](val outer: L) extends Bundle with HasCoreplexParameters { implicit val p = outer.p - val master = new Bundle { - val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) - val mmio = outer.mmio.bundleOut - } - + val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) + val mmio = outer.mmio.bundleOut val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip val resetVector = UInt(INPUT, p(XLen)) val success = Bool(OUTPUT) // used for testing - - override def cloneType = this.getClass.getConstructors.head.newInstance(outer).asInstanceOf[this.type] } abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](val outer: L, val io: B) extends LazyModuleImp(outer) with HasCoreplexParameters { @@ -134,7 +129,7 @@ abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L icPort <> TileLinkIOUnwrapper(enqueued) } - io.master.mem <> mem_ic.io.out + io.mem <> mem_ic.io.out } for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { @@ -150,7 +145,6 @@ trait CoreplexPeripherals extends HasCoreplexParameters { val module: CoreplexPeripheralsModule val l1tol2: TLXbar val legacy: TLLegacy - val lazyTiles: Seq[LazyTile] val cbus = LazyModule(new TLXbar) val debug = LazyModule(new TLDebugModule()) @@ -166,10 +160,6 @@ trait CoreplexPeripherals extends HasCoreplexParameters { debug.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) plic.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) clint.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) - - lazyTiles.map(_.slave).flatten.foreach { scratch => - scratch := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) - } } trait CoreplexPeripheralsBundle extends HasCoreplexParameters { diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 7a5a9b0c..6f98b144 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -3,12 +3,23 @@ package coreplex import Chisel._ import cde.{Parameters, Field} import junctions._ +import diplomacy._ import uncore.tilelink._ +import uncore.tilelink2._ import uncore.util._ import util._ import rocket._ trait DirectConnection { + implicit val p: Parameters + val lazyTiles: Seq[LazyTile] + val legacy: TLLegacy + val cbus: TLXbar + + lazyTiles.map(_.slave).flatten.foreach { scratch => scratch := cbus.node } +} + +trait DirectConnectionModule { val tiles: Seq[TileImp] val uncoreTileIOs: Seq[TileIO] @@ -18,7 +29,6 @@ trait DirectConnection { (tiles zip uncoreTileIOs) foreach { case (tile, uncore) => (uncore.cached zip tile.io.cached) foreach { case (u, t) => u <> TileLinkEnqueuer(t, tlBuffering) } (uncore.uncached zip tile.io.uncached) foreach { case (u, t) => u <> TileLinkEnqueuer(t, ultBuffering) } -// !!! tile.io.slave.foreach { _ <> TileLinkEnqueuer(uncore.slave.get, 1) } tile.io.interrupts <> uncore.interrupts @@ -27,18 +37,19 @@ trait DirectConnection { } } -class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex { +class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex + with DirectConnection { override lazy val module = new DefaultCoreplexModule(this, new DefaultCoreplexBundle(this)) } class DefaultCoreplexBundle[+L <: DefaultCoreplex](outer: L) extends BaseCoreplexBundle(outer) class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) - with DirectConnection + with DirectConnectionModule ///// -trait TileClockResetBundle extends HasCoreplexParameters { +trait TileClockResetBundle extends Bundle with HasCoreplexParameters { val tcrs = Vec(nTiles, new Bundle { val clock = Clock(INPUT) val reset = Bool(INPUT) @@ -46,9 +57,37 @@ trait TileClockResetBundle extends HasCoreplexParameters { } trait AsyncConnection { + implicit val p: Parameters + val lazyTiles: Seq[LazyTile] + val legacy: TLLegacy + val cbus: TLXbar + + val crossings = lazyTiles.map(_.slave).map(_.map { scratch => + val crossing = LazyModule(new TLAsyncCrossing) + crossing.node := cbus.node + val monitor = (scratch := crossing.node) + (crossing, monitor) + }) +} + +trait AsyncConnectionModule extends Module { val io: TileClockResetBundle val tiles: Seq[TileImp] val uncoreTileIOs: Seq[TileIO] + val outer: AsyncConnection + + (outer.crossings zip io.tcrs) foreach { case (slaves, tcr) => + slaves.foreach { case (crossing, monitor) => + crossing.module.io.in_clock := clock + crossing.module.io.in_reset := reset + crossing.module.io.out_clock := tcr.clock + crossing.module.io.out_reset := tcr.reset + monitor.foreach { m => + m.module.clock := tcr.clock + m.module.reset := tcr.reset + } + } + } (tiles, uncoreTileIOs, io.tcrs).zipped foreach { case (tile, uncore, tcr) => tile.clock := tcr.clock @@ -56,7 +95,6 @@ trait AsyncConnection { (uncore.cached zip tile.io.cached) foreach { case (u, t) => u <> AsyncTileLinkFrom(tcr.clock, tcr.reset, t) } (uncore.uncached zip tile.io.uncached) foreach { case (u, t) => u <> AsyncUTileLinkFrom(tcr.clock, tcr.reset, t) } -// !!! tile.io.slave.foreach { _ <> AsyncUTileLinkTo(tcr.clock, tcr.reset, uncore.slave.get)} val ti = tile.io.interrupts val ui = uncore.interrupts @@ -71,7 +109,8 @@ trait AsyncConnection { } } -class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex { +class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex + with AsyncConnection { override lazy val module = new MultiClockCoreplexModule(this, new MultiClockCoreplexBundle(this)) } @@ -79,4 +118,4 @@ class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](outer: L) extends BaseC with TileClockResetBundle class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) - with AsyncConnection + with AsyncConnectionModule diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index bd9c765f..59310230 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -4,13 +4,14 @@ import Chisel._ import cde.{Parameters} import coreplex._ -class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex { +class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex + with DirectConnection { override lazy val module = new GroundTestCoreplexModule(this, new GroundTestCoreplexBundle(this)) } class GroundTestCoreplexBundle[+L <: GroundTestCoreplex](outer: L) extends BaseCoreplexBundle(outer) class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) - with DirectConnection { + with DirectConnectionModule { io.success := tiles.flatMap(_.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_) } diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 5bcc2df6..10a2c1f1 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -54,8 +54,6 @@ abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(impli TLWidthWidget(p(SOCBusKey).beatBytes)( socBus.node))) - socBus.node := coreplex.mmio - TopModule.contents = Some(this) } @@ -66,7 +64,11 @@ abstract class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](val outer: L) extends abstract class BaseTopModule[+L <: BaseTop[BaseCoreplex], +B <: BaseTopBundle[L]](val outer: L, val io: B) extends LazyModuleImp(outer) { implicit val p = outer.p - val coreplexIO = Wire(outer.coreplex.module.io) + + val coreplexMem : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.mem) + val coreplexSlave : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.slave) + val coreplexDebug : DebugBusIO = Wire(outer.coreplex.module.io.debug) + val coreplexInterrupts : Vec[Bool] = Wire(outer.coreplex.module.io.interrupts) println("Generated Address Map") for (entry <- p(GlobalAddrMap).flatten) { @@ -88,12 +90,26 @@ abstract class BaseTopModule[+L <: BaseTop[BaseCoreplex], +B <: BaseTopBundle[L] println(p(ConfigString)) ConfigStringOutput.contents = Some(p(ConfigString)) - io.success := coreplexIO.success + io.success := outer.coreplex.module.io.success } trait DirectConnection { - val coreplexIO: BaseCoreplexBundle[BaseCoreplex] + val coreplex: BaseCoreplex + val socBus: TLXbar + + socBus.node := coreplex.mmio +} + +trait DirectConnectionModule { val outer: BaseTop[BaseCoreplex] - coreplexIO <> outer.coreplex.module.io + val coreplexMem : Vec[ClientUncachedTileLinkIO] + val coreplexSlave : Vec[ClientUncachedTileLinkIO] + val coreplexDebug : DebugBusIO + val coreplexInterrupts : Vec[Bool] + + coreplexMem <> outer.coreplex.module.io.mem + coreplexInterrupts <> outer.coreplex.module.io.interrupts + outer.coreplex.module.io.slave <> coreplexSlave + outer.coreplex.module.io.debug <> coreplexDebug } diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 01088aa5..f128b415 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -15,7 +15,8 @@ class ExampleTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: with PeripheryExtInterrupts with PeripheryMasterMem with PeripheryMasterAXI4MMIO - with PeripherySlave { + with PeripherySlave + with DirectConnection { override lazy val module = new ExampleTopModule(this, new ExampleTopBundle(this)) } @@ -35,7 +36,7 @@ class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L] with PeripheryMasterAXI4MMIOModule with PeripherySlaveModule with HardwiredResetVector - with DirectConnection + with DirectConnectionModule /** Example Top with TestRAM */ class ExampleTopWithTestRAM[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(buildCoreplex) diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index f123168c..5162bf0d 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -110,16 +110,16 @@ trait PeripheryDebugModule { implicit val p: Parameters val outer: PeripheryDebug val io: PeripheryDebugBundle - val coreplexIO: BaseCoreplexBundle[BaseCoreplex] + val coreplexDebug: DebugBusIO if (p(IncludeJtagDTM)) { // JtagDTMWithSync is a wrapper which // handles the synchronization as well. val dtm = Module (new JtagDTMWithSync()(p)) dtm.io.jtag <> io.jtag.get - coreplexIO.debug <> dtm.io.debug + coreplexDebug <> dtm.io.debug } else { - coreplexIO.debug <> + coreplexDebug <> (if (p(AsyncDebugBus)) AsyncDebugBusFrom(io.debug_clk.get, io.debug_rst.get, io.debug.get) else io.debug.get) } @@ -143,12 +143,12 @@ trait PeripheryExtInterruptsModule { implicit val p: Parameters val outer: PeripheryExtInterrupts val io: PeripheryExtInterruptsBundle - val coreplexIO: BaseCoreplexBundle[BaseCoreplex] + val coreplexInterrupts: Vec[Bool] { val r = outer.pInterrupts.range("ext") ((r._1 until r._2) zipWithIndex) foreach { case (c, i) => - coreplexIO.interrupts(c) := io.interrupts(i) + coreplexInterrupts(c) := io.interrupts(i) } } } @@ -172,9 +172,9 @@ trait PeripheryMasterMemModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripheryMasterMem val io: PeripheryMasterMemBundle - val coreplexIO: BaseCoreplexBundle[BaseCoreplex] + val coreplexMem: Vec[ClientUncachedTileLinkIO] - val edgeMem = coreplexIO.master.mem.map(TileLinkWidthAdapter(_, edgeMemParams)) + val edgeMem = coreplexMem.map(TileLinkWidthAdapter(_, edgeMemParams)) // Abuse the fact that zip takes the shorter of the two lists ((io.mem_axi zip edgeMem) zipWithIndex) foreach { case ((axi, mem), idx) => @@ -254,7 +254,7 @@ trait PeripherySlaveModule extends HasPeripheryParameters { implicit val p: Parameters val outer: PeripherySlave val io: PeripherySlaveBundle - val coreplexIO: BaseCoreplexBundle[BaseCoreplex] + val coreplexSlave: Vec[ClientUncachedTileLinkIO] if (p(NExtBusAXIChannels) > 0) { val arb = Module(new NastiArbiter(p(NExtBusAXIChannels))) @@ -269,7 +269,7 @@ trait PeripherySlaveModule extends HasPeripheryParameters { val (r_start, r_end) = outer.pBusMasters.range("ext") require(r_end - r_start == 1, "RangeManager should return 1 slot") - TileLinkWidthAdapter(coreplexIO.slave(r_start), conv.io.tl) + TileLinkWidthAdapter(coreplexSlave(r_start), conv.io.tl) } } @@ -340,6 +340,7 @@ trait PeripheryTestBusMasterModule { ///// trait HardwiredResetVector { - val coreplexIO: BaseCoreplexBundle[BaseCoreplex] - coreplexIO.resetVector := UInt(0x1000) // boot ROM + val outer: BaseTop[BaseCoreplex] + + outer.coreplex.module.io.resetVector := UInt(0x1000) // boot ROM } From b68bc449e70575ae4e7bf71770b0c9d104070c16 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 15:46:57 -0700 Subject: [PATCH 21/47] rocket: put a Fragmenter infront of the scratchpad --- src/main/scala/rocket/tile.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index 473a578c..931de47f 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -61,7 +61,7 @@ class RocketTile(implicit p: Parameters) extends LazyTile { val slave = if (p(DataScratchpadSize) == 0) None else Some(TLOutputNode()) val scratch = if (p(DataScratchpadSize) == 0) None else Some(LazyModule(new ScratchpadSlavePort()(dcacheParams))) - (slave zip scratch) foreach { case (node, lm) => node := lm.node } + (slave zip scratch) foreach { case (node, lm) => node := TLFragmenter(p(XLen)/8, p(RowBits)/8)(lm.node) } lazy val module = new TileImp(this) { val io = new TileIO(bc, slave) From 401fd378b420f53ad25aeaefc8a6a7d1ee34ac01 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 18:03:43 -0700 Subject: [PATCH 22/47] rocketchip: include devices from cbus in ConfigString --- src/main/scala/coreplex/BaseCoreplex.scala | 6 ++++++ src/main/scala/rocketchip/BaseTop.scala | 14 ++------------ src/main/scala/rocketchip/Utils.scala | 2 +- 3 files changed, 9 insertions(+), 13 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 4f794a74..dead46fe 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -78,6 +78,12 @@ abstract class BareCoreplexBundle[+L <: BareCoreplex](val outer: L) extends Bund abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](val outer: L, val io: B) extends LazyModuleImp(outer) with HasCoreplexParameters { implicit val p = outer.p + // Create and export the ConfigString + val managers = outer.l1tol2.node.edgesIn(0).manager.managers + val configString = rocketchip.GenerateConfigString(p, managers) + println(s"\nGenerated Configuration String\n${configString}") + ConfigStringOutput.contents = Some(configString) + // Build a set of Tiles val tiles = outer.lazyTiles.map(_.module) val uncoreTileIOs = (tiles zipWithIndex) map { case (tile, i) => Wire(tile.io) } diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 10a2c1f1..6b57835c 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -15,7 +15,6 @@ import coreplex._ // the following parameters will be refactored properly with TL2 case object GlobalAddrMap extends Field[AddrMap] -case object ConfigString extends Field[String] case object NCoreplexExtClients extends Field[Int] case object NExtInterrupts extends Field[Int] /** Enable or disable monitoring of Diplomatic buses */ @@ -35,15 +34,10 @@ abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(impli lazy val peripheryManagers = socBus.node.edgesIn(0).manager.managers // Fill in the TL1 legacy parameters - val qWithSums = q.alterPartial { + implicit val p = q.alterPartial { case NCoreplexExtClients => pBusMasters.sum case NExtInterrupts => pInterrupts.sum - } - val qWithMap = qWithSums.alterPartial { - case GlobalAddrMap => GenerateGlobalAddrMap(qWithSums, peripheryManagers) - } - implicit val p = qWithMap.alterPartial { - case ConfigString => GenerateConfigString(qWithMap, peripheryManagers) + case GlobalAddrMap => GenerateGlobalAddrMap(q, peripheryManagers) } val coreplex = LazyModule(buildCoreplex(p)) @@ -86,10 +80,6 @@ abstract class BaseTopModule[+L <: BaseTop[BaseCoreplex], +B <: BaseTopBundle[L] println("\nGenerated Interrupt Vector") outer.pInterrupts.print - println("\nGenerated Configuration String") - println(p(ConfigString)) - ConfigStringOutput.contents = Some(p(ConfigString)) - io.success := outer.coreplex.module.io.success } diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index c9c77771..33c59533 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -178,6 +178,6 @@ object GenerateBootROM { require(rom.getInt(12) == 0, "Config string address position should not be occupied by code") rom.putInt(12, configStringAddr) - rom.array() ++ (p(ConfigString).getBytes.toSeq) + rom.array() ++ (ConfigStringOutput.contents.get.getBytes.toSeq) } } From e9725aea2f58a270741eacf73ef6fa8d56878665 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 18:29:16 -0700 Subject: [PATCH 23/47] rocketchip: all of the address map now comes from TL2 --- src/main/scala/groundtest/Configs.scala | 2 +- src/main/scala/groundtest/Regression.scala | 2 +- src/main/scala/junctions/addrmap.scala | 7 +----- src/main/scala/rocket/dcache.scala | 2 +- src/main/scala/rocketchip/BaseTop.scala | 8 ++++--- src/main/scala/rocketchip/Utils.scala | 26 +++++----------------- 6 files changed, 14 insertions(+), 33 deletions(-) diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index e981774a..64ff77eb 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -119,7 +119,7 @@ class WithComparator extends Config( case BuildGroundTest => (p: Parameters) => Module(new ComparatorCore()(p)) case ComparatorKey => ComparatorParameters( - targets = Seq("mem", "io:TL2:testram").map(name => + targets = Seq("mem", "TL2:testram").map(name => site(GlobalAddrMap)(name).start.longValue), width = 8, operations = 1000, diff --git a/src/main/scala/groundtest/Regression.scala b/src/main/scala/groundtest/Regression.scala index 093855fe..3db5ad74 100644 --- a/src/main/scala/groundtest/Regression.scala +++ b/src/main/scala/groundtest/Regression.scala @@ -71,7 +71,7 @@ class IOGetAfterPutBlockRegression(implicit p: Parameters) extends Regression()( io.mem.grant.ready := Bool(true) io.cache.req.valid := !get_sent && started - io.cache.req.bits.addr := UInt(addrMap("io:TL2:bootrom").start) + io.cache.req.bits.addr := UInt(addrMap("TL2:bootrom").start) io.cache.req.bits.typ := MT_WU io.cache.req.bits.cmd := M_XRD io.cache.req.bits.tag := UInt(0) diff --git a/src/main/scala/junctions/addrmap.scala b/src/main/scala/junctions/addrmap.scala index 56158001..86fdd276 100644 --- a/src/main/scala/junctions/addrmap.scala +++ b/src/main/scala/junctions/addrmap.scala @@ -76,12 +76,7 @@ class AddrMap( var cacheable = true for (AddrMapEntry(name, r) <- entriesIn) { require (!mapping.contains(name)) - - if (r.start != 0) { - base = r.start - } else { - base = (base + r.size - 1) / r.size * r.size - } + base = r.start r match { case r: AddrMap => diff --git a/src/main/scala/rocket/dcache.scala b/src/main/scala/rocket/dcache.scala index e0294bca..4fccc725 100644 --- a/src/main/scala/rocket/dcache.scala +++ b/src/main/scala/rocket/dcache.scala @@ -127,7 +127,7 @@ class DCache(implicit p: Parameters) extends L1HellaCacheModule()(p) { require(nWays == 1) metaWriteArb.io.out.ready := true metaReadArb.io.out.ready := !metaWriteArb.io.out.valid - val inScratchpad = addrMap(s"io:cbus:dmem${tileId}").containsAddress(s1_paddr) + val inScratchpad = addrMap(s"TL2:dmem${tileId}").containsAddress(s1_paddr) val hitState = Mux(inScratchpad, ClientMetadata.onReset.onHit(M_XWR), ClientMetadata.onReset) (inScratchpad, hitState, L1Metadata(UInt(0), ClientMetadata.onReset)) } else { diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 6b57835c..9258b34b 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -31,16 +31,18 @@ abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(impli // Add a SoC and peripheral bus val socBus = LazyModule(new TLXbar) val peripheryBus = LazyModule(new TLXbar) - lazy val peripheryManagers = socBus.node.edgesIn(0).manager.managers // Fill in the TL1 legacy parameters implicit val p = q.alterPartial { case NCoreplexExtClients => pBusMasters.sum case NExtInterrupts => pInterrupts.sum - case GlobalAddrMap => GenerateGlobalAddrMap(q, peripheryManagers) + case GlobalAddrMap => legacyAddrMap } - val coreplex = LazyModule(buildCoreplex(p)) + val coreplex : C = LazyModule(buildCoreplex(p)) + + // Create the address map for legacy masters + lazy val legacyAddrMap = GenerateGlobalAddrMap(q, coreplex.l1tol2.node.edgesIn(0).manager.managers) peripheryBus.node := TLBuffer()( diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index 33c59533..f44cc105 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -54,19 +54,7 @@ class GlobalVariable[T] { object GenerateGlobalAddrMap { def apply(p: Parameters, peripheryManagers: Seq[TLManagerParameters]) = { - lazy val cBusIOAddrMap: AddrMap = { - val entries = collection.mutable.ArrayBuffer[AddrMapEntry]() - entries += AddrMapEntry("debug", MemSize(4096, MemAttr(AddrMapProt.RWX))) - entries += AddrMapEntry("plic", MemRange(0x0C000000, 0x4000000, MemAttr(AddrMapProt.RW))) - if (p(DataScratchpadSize) > 0) { // TODO heterogeneous tiles - require(p(NTiles) == 1) // TODO relax this - require(p(NMemoryChannels) == 0) // TODO allow both scratchpad & DRAM - entries += AddrMapEntry("dmem0", MemRange(0x80000000L, BigInt(p(DataScratchpadSize)), MemAttr(AddrMapProt.RWX))) - } - new AddrMap(entries) - } - - lazy val tl2Devices = peripheryManagers.map { manager => + val tl2Devices = peripheryManagers.map { manager => val cacheable = manager.regionType match { case RegionType.CACHED => true case RegionType.TRACKED => true @@ -84,22 +72,18 @@ object GenerateGlobalAddrMap { } }.flatten - lazy val uniquelyNamedTL2Devices = + val uniquelyNamedTL2Devices = tl2Devices.groupBy(_.name).values.map(_.zipWithIndex.map { case (e, i) => if (i == 0) e else e.copy(name = e.name + "_" + i) }).flatten.toList - lazy val tl2AddrMap = new AddrMap(uniquelyNamedTL2Devices, collapse = true) - val memBase = 0x80000000L val memSize = p(ExtMemSize) Dump("MEM_BASE", memBase) - val cBus = AddrMapEntry("cbus", cBusIOAddrMap) - val tlBus = AddrMapEntry("TL2", tl2AddrMap) - val io = AddrMapEntry("io", AddrMap(cBus, tlBus)) + val tl2 = AddrMapEntry("TL2", new AddrMap(uniquelyNamedTL2Devices, collapse = true)) val mem = AddrMapEntry("mem", MemRange(memBase, memSize, MemAttr(AddrMapProt.RWX, true))) - AddrMap((io +: (p(NMemoryChannels) > 0).option(mem).toSeq):_*) + AddrMap((tl2 +: (p(NMemoryChannels) > 0).option(mem).toSeq):_*) } } @@ -107,7 +91,7 @@ object GenerateConfigString { def apply(p: Parameters, peripheryManagers: Seq[TLManagerParameters]) = { val c = CoreplexParameters()(p) val addrMap = p(GlobalAddrMap) - val plicAddr = addrMap("io:cbus:plic").start + val plicAddr = addrMap("TL2:plic").start val clint = CoreplexLocalInterrupterConfig() val xLen = p(XLen) val res = new StringBuilder From 9a26cb7ec781edb2aa2319e0cdd1be72aad466ec Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 18:38:14 -0700 Subject: [PATCH 24/47] Debug: mark the debug device executable --- src/main/scala/uncore/axi4/RegisterRouter.scala | 15 ++++++++------- src/main/scala/uncore/devices/Debug.scala | 2 +- .../scala/uncore/tilelink2/RegisterRouter.scala | 15 ++++++++------- 3 files changed, 17 insertions(+), 15 deletions(-) diff --git a/src/main/scala/uncore/axi4/RegisterRouter.scala b/src/main/scala/uncore/axi4/RegisterRouter.scala index 97b598d5..9f408c9a 100644 --- a/src/main/scala/uncore/axi4/RegisterRouter.scala +++ b/src/main/scala/uncore/axi4/RegisterRouter.scala @@ -7,10 +7,11 @@ import diplomacy._ import regmapper._ import scala.math.{min,max} -class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true) +class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) extends AXI4SlaveNode(AXI4SlavePortParameters( Seq(AXI4SlaveParameters( address = Seq(address), + executable = executable, supportsWrite = TransferSizes(1, beatBytes), supportsRead = TransferSizes(1, beatBytes), interleavedId = Some(0))), @@ -69,16 +70,16 @@ class AXI4RegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int object AXI4RegisterNode { - def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true) = - new AXI4RegisterNode(address, concurrency, beatBytes, undefZero) + def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) = + new AXI4RegisterNode(address, concurrency, beatBytes, undefZero, executable) } // These convenience methods below combine to make it possible to create a AXI4 // register mapped device from a totally abstract register mapped device. -abstract class AXI4RegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean) extends LazyModule +abstract class AXI4RegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean) extends LazyModule { - val node = AXI4RegisterNode(address, concurrency, beatBytes, undefZero) + val node = AXI4RegisterNode(address, concurrency, beatBytes, undefZero, executable) val intnode = uncore.tilelink2.IntSourceNode(interrupts) } @@ -101,10 +102,10 @@ class AXI4RegModule[P, B <: AXI4RegBundleBase](val params: P, bundleBuilder: => } class AXI4RegisterRouter[B <: AXI4RegBundleBase, M <: LazyModuleImp] - (val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true) + (val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) (bundleBuilder: AXI4RegBundleArg => B) (moduleBuilder: (=> B, AXI4RegisterRouterBase) => M) - extends AXI4RegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero) + extends AXI4RegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable) { require (isPow2(size)) // require (size >= 4096) ... not absolutely required, but highly recommended diff --git a/src/main/scala/uncore/devices/Debug.scala b/src/main/scala/uncore/devices/Debug.scala index e4ca2516..3ee83e9a 100644 --- a/src/main/scala/uncore/devices/Debug.scala +++ b/src/main/scala/uncore/devices/Debug.scala @@ -824,7 +824,7 @@ trait DebugModule extends Module with HasDebugModuleParameters with HasRegMap { */ class TLDebugModule(address: BigInt = 0)(implicit p: Parameters) - extends TLRegisterRouter(address, beatBytes=p(rocket.XLen)/8)( + extends TLRegisterRouter(address, beatBytes=p(rocket.XLen)/8, executable=true)( new TLRegBundle(p, _ ) with DebugModuleBundle)( new TLRegModule(p, _, _) with DebugModule) diff --git a/src/main/scala/uncore/tilelink2/RegisterRouter.scala b/src/main/scala/uncore/tilelink2/RegisterRouter.scala index f8ab2fc3..d100917e 100644 --- a/src/main/scala/uncore/tilelink2/RegisterRouter.scala +++ b/src/main/scala/uncore/tilelink2/RegisterRouter.scala @@ -7,10 +7,11 @@ import diplomacy._ import regmapper._ import scala.math.{min,max} -class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true) +class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) extends TLManagerNode(TLManagerPortParameters( Seq(TLManagerParameters( address = Seq(address), + executable = executable, supportsGet = TransferSizes(1, beatBytes), supportsPutPartial = TransferSizes(1, beatBytes), supportsPutFull = TransferSizes(1, beatBytes), @@ -70,17 +71,17 @@ class TLRegisterNode(address: AddressSet, concurrency: Int = 0, beatBytes: Int = object TLRegisterNode { - def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true) = - new TLRegisterNode(address, concurrency, beatBytes, undefZero) + def apply(address: AddressSet, concurrency: Int = 0, beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) = + new TLRegisterNode(address, concurrency, beatBytes, undefZero, executable) } // These convenience methods below combine to make it possible to create a TL2 // register mapped device from a totally abstract register mapped device. // See GPIO.scala in this directory for an example -abstract class TLRegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean) extends LazyModule +abstract class TLRegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean) extends LazyModule { - val node = TLRegisterNode(address, concurrency, beatBytes, undefZero) + val node = TLRegisterNode(address, concurrency, beatBytes, undefZero, executable) val intnode = IntSourceNode(interrupts) } @@ -103,10 +104,10 @@ class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, r } class TLRegisterRouter[B <: TLRegBundleBase, M <: LazyModuleImp] - (val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true) + (val base: BigInt, val interrupts: Int = 0, val size: BigInt = 4096, val concurrency: Int = 0, val beatBytes: Int = 4, undefZero: Boolean = true, executable: Boolean = false) (bundleBuilder: TLRegBundleArg => B) (moduleBuilder: (=> B, TLRegisterRouterBase) => M) - extends TLRegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero) + extends TLRegisterRouterBase(AddressSet(base, size-1), interrupts, concurrency, beatBytes, undefZero, executable) { require (isPow2(size)) // require (size >= 4096) ... not absolutely required, but highly recommended From 545154c1c3a5644e8d57ae3230c54d3abd1b1bcb Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 19:55:40 -0700 Subject: [PATCH 25/47] groundtest: make it happy with TL2 addressing --- src/main/scala/groundtest/Tile.scala | 4 ++-- src/main/scala/rocket/tile.scala | 2 +- src/main/scala/uncore/tilelink2/Legacy.scala | 8 +++----- 3 files changed, 6 insertions(+), 8 deletions(-) diff --git a/src/main/scala/groundtest/Tile.scala b/src/main/scala/groundtest/Tile.scala index 43b0390a..f0973dc4 100644 --- a/src/main/scala/groundtest/Tile.scala +++ b/src/main/scala/groundtest/Tile.scala @@ -96,9 +96,9 @@ abstract class GroundTest(implicit val p: Parameters) extends Module val io = new GroundTestIO } -class GroundTestTile(implicit val p: Parameters) extends LazyTile with HasGroundTestParameters { +class GroundTestTile(implicit val p: Parameters) extends LazyTile { val slave = None - lazy val module = new TileImp(this) { + lazy val module = new TileImp(this) with HasGroundTestParameters { val io = new TileIO(bc) { val success = Bool(OUTPUT) } diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index 931de47f..c71848bb 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -40,7 +40,7 @@ class TileIO(c: TileBundleConfig, node: Option[TLInwardNode] = None)(implicit p: override def cloneType = new TileIO(c).asInstanceOf[this.type] } -abstract class TileImp(l: LazyTile)(implicit p: Parameters) extends LazyModuleImp(l) { +abstract class TileImp(l: LazyTile)(implicit val p: Parameters) extends LazyModuleImp(l) { val io: TileIO } diff --git a/src/main/scala/uncore/tilelink2/Legacy.scala b/src/main/scala/uncore/tilelink2/Legacy.scala index 252d77ea..3fa75774 100644 --- a/src/main/scala/uncore/tilelink2/Legacy.scala +++ b/src/main/scala/uncore/tilelink2/Legacy.scala @@ -38,11 +38,9 @@ class TLLegacy(implicit val p: Parameters) extends LazyModule with HasTileLinkPa require (m.supportsPutPartial.contains(TransferSizes(1, tlDataBytes))) require (m.supportsPutPartial.contains(TransferSizes(tlDataBeats * tlDataBytes))) } - // Any atomic support => must support 32-bit up to beat size of all types - if (m.supportsArithmetic || m.supportsLogical) { - require (m.supportsArithmetic.contains(TransferSizes(4, tlDataBytes))) - require (m.supportsLogical .contains(TransferSizes(4, tlDataBytes))) - } + // Any atomic support => must support 32-bit size + if (m.supportsArithmetic) { require (m.supportsArithmetic.contains(TransferSizes(4))) } + if (m.supportsLogical) { require (m.supportsLogical .contains(TransferSizes(4))) } // We straight-up require hints require (edge.manager.allSupportHint) } From d2e9fa8ec63fcc7991728037cc64404587a91714 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 21:35:16 -0700 Subject: [PATCH 26/47] Plic: remove path from ready to bits --- src/main/scala/uncore/devices/Plic.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/uncore/devices/Plic.scala b/src/main/scala/uncore/devices/Plic.scala index 582d1131..33c7a526 100644 --- a/src/main/scala/uncore/devices/Plic.scala +++ b/src/main/scala/uncore/devices/Plic.scala @@ -106,14 +106,14 @@ trait PLICModule extends Module with HasRegMap with HasPLICParamters { } else (x.head, UInt(0)) } - val maxDevs = Wire(Vec(cfg.nHarts, UInt(width = log2Up(pending.size)))) + val maxDevs = Reg(Vec(cfg.nHarts, UInt(width = log2Up(pending.size)))) for (hart <- 0 until cfg.nHarts) { val effectivePriority = for (((p, en), pri) <- (pending zip enables(hart) zip priority).tail) yield Cat(p && en, pri) val (maxPri, maxDev) = findMax((UInt(1) << priority(0).getWidth) +: effectivePriority) - maxDevs(hart) := Reg(next = maxDev) + maxDevs(hart) := maxDev io.harts(hart) := Reg(next = maxPri) > Cat(UInt(1), threshold(hart)) } From 0cc00e7616e030cf58c896f2786884521ec1ec08 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Thu, 27 Oct 2016 22:27:43 -0700 Subject: [PATCH 27/47] regressions: test scratchpad --- src/main/scala/groundtest/Configs.scala | 2 +- src/main/scala/rocket/dcache.scala | 11 ++++++++++- src/main/scala/rocket/tile.scala | 6 +++--- src/main/scala/uncore/axi4/Fragmenter.scala | 4 ++-- src/main/scala/uncore/devices/Plic.scala | 10 +++++----- 5 files changed, 21 insertions(+), 12 deletions(-) diff --git a/src/main/scala/groundtest/Configs.scala b/src/main/scala/groundtest/Configs.scala index 64ff77eb..5503e5a4 100644 --- a/src/main/scala/groundtest/Configs.scala +++ b/src/main/scala/groundtest/Configs.scala @@ -114,7 +114,7 @@ class WithGroundTest extends Config( class WithComparator extends Config( (pname, site, here) => pname match { case GroundTestKey => Seq.fill(site(NTiles)) { - GroundTestTileSettings(uncached = site(ComparatorKey).targets.size) + GroundTestTileSettings(uncached = 2) } case BuildGroundTest => (p: Parameters) => Module(new ComparatorCore()(p)) diff --git a/src/main/scala/rocket/dcache.scala b/src/main/scala/rocket/dcache.scala index 4fccc725..bef9e6d4 100644 --- a/src/main/scala/rocket/dcache.scala +++ b/src/main/scala/rocket/dcache.scala @@ -501,15 +501,19 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha val beatBytes = p(XLen)/8 val node = TLManagerNode(TLManagerPortParameters( Seq(TLManagerParameters( - address = List(AddressSet(0x80000000L, p(DataScratchpadSize))), + address = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), regionType = RegionType.UNCACHED, executable = true, supportsPutPartial = TransferSizes(1, beatBytes), supportsPutFull = TransferSizes(1, beatBytes), + supportsGet = TransferSizes(1, beatBytes), fifoId = Some(0))), // requests handled in FIFO order beatBytes = beatBytes, minLatency = 1)) + // Make sure this ends up with the same name as before + override def name = "dmem0" + lazy val module = new LazyModuleImp(this) { val io = new Bundle { val tl_in = node.bundleIn @@ -566,5 +570,10 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha tl_in.d.bits := Mux(isRead, edge.AccessAck(acq, UInt(0), alignedGrantData), edge.AccessAck(acq, UInt(0))) + + // Tie off unused channels + tl_in.b.valid := Bool(false) + tl_in.c.ready := Bool(true) + tl_in.e.ready := Bool(true) } } diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index c71848bb..b0391472 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -54,14 +54,14 @@ abstract class LazyTile(implicit p: Parameters) extends LazyModule { xLen = p(XLen)) val module: TileImp - val slave: Option[TLOutputNode] + val slave: Option[TLInputNode] } class RocketTile(implicit p: Parameters) extends LazyTile { - val slave = if (p(DataScratchpadSize) == 0) None else Some(TLOutputNode()) + val slave = if (p(DataScratchpadSize) == 0) None else Some(TLInputNode()) val scratch = if (p(DataScratchpadSize) == 0) None else Some(LazyModule(new ScratchpadSlavePort()(dcacheParams))) - (slave zip scratch) foreach { case (node, lm) => node := TLFragmenter(p(XLen)/8, p(RowBits)/8)(lm.node) } + (slave zip scratch) foreach { case (node, lm) => lm.node := TLFragmenter(p(XLen)/8, 256)(node) } lazy val module = new TileImp(this) { val io = new TileIO(bc, slave) diff --git a/src/main/scala/uncore/axi4/Fragmenter.scala b/src/main/scala/uncore/axi4/Fragmenter.scala index 939555cb..e933270f 100644 --- a/src/main/scala/uncore/axi4/Fragmenter.scala +++ b/src/main/scala/uncore/axi4/Fragmenter.scala @@ -10,7 +10,7 @@ import scala.math.{min,max} import uncore.tilelink2.{leftOR, rightOR, UIntToOH1, OH1ToOH} // lite: masters all use only one ID => reads will not be interleaved -class AXI4Fragmenter(lite: Boolean = false, maxInFlight: Int = 32, combinational: Boolean = true) extends LazyModule +class AXI4Fragmenter(lite: Boolean = false, maxInFlight: => Int = 32, combinational: Boolean = true) extends LazyModule { val maxBeats = 1 << AXI4Parameters.lenBits def expandTransfer(x: TransferSizes, beatBytes: Int, alignment: BigInt) = @@ -287,7 +287,7 @@ class AXI4FragmenterSideband(maxInFlight: Int, flow: Boolean = false) extends Mo object AXI4Fragmenter { // applied to the AXI4 source node; y.node := AXI4Fragmenter()(x.node) - def apply(lite: Boolean = false, maxInFlight: Int = 32, combinational: Boolean = true)(x: AXI4OutwardNode)(implicit sourceInfo: SourceInfo): AXI4OutwardNode = { + def apply(lite: Boolean = false, maxInFlight: => Int = 32, combinational: Boolean = true)(x: AXI4OutwardNode)(implicit sourceInfo: SourceInfo): AXI4OutwardNode = { val fragmenter = LazyModule(new AXI4Fragmenter(lite, maxInFlight, combinational)) fragmenter.node := x fragmenter.node diff --git a/src/main/scala/uncore/devices/Plic.scala b/src/main/scala/uncore/devices/Plic.scala index 33c7a526..dec058b0 100644 --- a/src/main/scala/uncore/devices/Plic.scala +++ b/src/main/scala/uncore/devices/Plic.scala @@ -67,18 +67,18 @@ case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriori require(nPriorities >= 0 && nPriorities <= nDevices) } -trait HasPLICParamters { +trait HasPLICParameters { val params: (() => PLICConfig, Parameters) val cfg = params._1 () implicit val p = params._2 } -trait PLICBundle extends Bundle with HasPLICParamters { +trait PLICBundle extends Bundle with HasPLICParameters { val devices = Vec(cfg.nDevices, new GatewayPLICIO).flip val harts = Vec(cfg.nHarts, Bool()).asOutput } -trait PLICModule extends Module with HasRegMap with HasPLICParamters { +trait PLICModule extends Module with HasRegMap with HasPLICParameters { val io: PLICBundle val priority = @@ -118,7 +118,7 @@ trait PLICModule extends Module with HasRegMap with HasPLICParamters { } def priorityRegField(x: UInt) = if (cfg.nPriorities > 0) RegField(32, x) else RegField.r(32, x) - val piorityRegFields = Seq(PLICConsts.priorityBase -> priority.map(p => priorityRegField(p))) + val priorityRegFields = Seq(PLICConsts.priorityBase -> priority.map(p => priorityRegField(p))) val pendingRegFields = Seq(PLICConsts.pendingBase -> pending .map(b => RegField.r(1, b))) val enableRegFields = enables.zipWithIndex.map { case (e, i) => @@ -146,7 +146,7 @@ trait PLICModule extends Module with HasRegMap with HasPLICParamters { ) } - regmap((piorityRegFields ++ pendingRegFields ++ enableRegFields ++ hartRegFields):_*) + regmap((priorityRegFields ++ pendingRegFields ++ enableRegFields ++ hartRegFields):_*) priority(0) := 0 pending(0) := false From 92ee4985216d02bd12e6544345720ff17f0a4104 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 12:13:01 -0700 Subject: [PATCH 28/47] rocket scratchpad: support atomics --- src/main/scala/rocket/dcache.scala | 48 +++++++++++++++++++----------- src/main/scala/rocket/tile.scala | 2 +- 2 files changed, 32 insertions(+), 18 deletions(-) diff --git a/src/main/scala/rocket/dcache.scala b/src/main/scala/rocket/dcache.scala index bef9e6d4..8e908dcd 100644 --- a/src/main/scala/rocket/dcache.scala +++ b/src/main/scala/rocket/dcache.scala @@ -498,17 +498,18 @@ class DCache(implicit p: Parameters) extends L1HellaCacheModule()(p) { } class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with HasCoreParameters { - val beatBytes = p(XLen)/8 val node = TLManagerNode(TLManagerPortParameters( Seq(TLManagerParameters( address = List(AddressSet(0x80000000L, BigInt(p(DataScratchpadSize)-1))), regionType = RegionType.UNCACHED, executable = true, - supportsPutPartial = TransferSizes(1, beatBytes), - supportsPutFull = TransferSizes(1, beatBytes), - supportsGet = TransferSizes(1, beatBytes), + supportsArithmetic = if (p(UseAtomics)) TransferSizes(1, coreDataBytes) else TransferSizes.none, + supportsLogical = if (p(UseAtomics)) TransferSizes(1, coreDataBytes) else TransferSizes.none, + supportsPutPartial = TransferSizes(1, coreDataBytes), + supportsPutFull = TransferSizes(1, coreDataBytes), + supportsGet = TransferSizes(1, coreDataBytes), fifoId = Some(0))), // requests handled in FIFO order - beatBytes = beatBytes, + beatBytes = coreDataBytes, minLatency = 1)) // Make sure this ends up with the same name as before @@ -522,9 +523,7 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha val tl_in = io.tl_in(0) val edge = node.edgesIn(0) - val beatBytes = edge.manager.beatBytes - require(coreDataBits == beatBytes*8) require(usingDataScratchpad) val s_ready :: s_wait :: s_replay :: s_grant :: Nil = Enum(UInt(), 4) @@ -538,15 +537,29 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha when (io.dmem.resp.valid) { acq.data := io.dmem.resp.bits.data } when (tl_in.a.fire()) { acq := tl_in.a.bits } - val isWrite = edge.hasData(acq) - val isRead = !isWrite + val isWrite = acq.opcode === TLMessages.PutFullData || acq.opcode === TLMessages.PutPartialData + val isRead = !edge.hasData(acq) def formCacheReq(acq: TLBundleA) = { val req = Wire(new HellaCacheReq) + req.cmd := MuxLookup(acq.opcode, Wire(M_XRD), Array( + TLMessages.PutFullData -> M_XWR, + TLMessages.PutPartialData -> M_XWR, + TLMessages.ArithmeticData -> MuxLookup(acq.param, Wire(M_XRD), Array( + TLAtomics.MIN -> M_XA_MIN, + TLAtomics.MAX -> M_XA_MAX, + TLAtomics.MINU -> M_XA_MINU, + TLAtomics.MAXU -> M_XA_MAXU, + TLAtomics.ADD -> M_XA_ADD)), + TLMessages.LogicalData -> MuxLookup(acq.param, Wire(M_XRD), Array( + TLAtomics.XOR -> M_XA_XOR, + TLAtomics.OR -> M_XA_OR, + TLAtomics.AND -> M_XA_AND, + TLAtomics.SWAP -> M_XA_SWAP)), + TLMessages.Get -> M_XRD)) // treat all loads as full words, so bytes appear in correct lane - req.typ := Mux(isRead, log2Ceil(beatBytes), acq.size) - req.cmd := Mux(isRead, M_XRD, M_XWR) - req.addr := Mux(isRead, ~(~acq.address | (beatBytes-1)), acq.address) + req.typ := Mux(isRead, log2Ceil(coreDataBytes), acq.size) + req.addr := Mux(isRead, ~(~acq.address | (coreDataBytes-1)), acq.address) req.tag := UInt(0) req } @@ -555,9 +568,9 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha io.dmem.req.valid := (tl_in.a.valid && ready) || state === s_replay tl_in.a.ready := io.dmem.req.ready && ready io.dmem.req.bits := formCacheReq(Mux(state === s_replay, acq, tl_in.a.bits)) - // this blows. the TL data is already in the correct byte lane, but the D$ + // the TL data is already in the correct byte lane, but the D$ // expects right-justified store data, so that it can steer the bytes. - io.dmem.s1_data := new LoadGen(acq.size, Bool(false), acq.address(log2Ceil(beatBytes)-1,0), acq.data, Bool(false), beatBytes).data + io.dmem.s1_data := new LoadGen(acq.size, Bool(false), acq.address(log2Ceil(coreDataBytes)-1,0), acq.data, Bool(false), coreDataBytes).data io.dmem.s1_kill := false io.dmem.invalidate_lr := false @@ -567,9 +580,10 @@ class ScratchpadSlavePort(implicit val p: Parameters) extends LazyModule with Ha val alignedGrantData = Mux(acq.size <= log2Ceil(minAMOBytes), Fill(coreDataBytes/minAMOBytes, grantData(8*minAMOBytes-1, 0)), grantData) tl_in.d.valid := io.dmem.resp.valid || state === s_grant - tl_in.d.bits := Mux(isRead, - edge.AccessAck(acq, UInt(0), alignedGrantData), - edge.AccessAck(acq, UInt(0))) + tl_in.d.bits := Mux(isWrite, + edge.AccessAck(acq, UInt(0)), + edge.AccessAck(acq, UInt(0), UInt(0))) + tl_in.d.bits.data := alignedGrantData // Tie off unused channels tl_in.b.valid := Bool(false) diff --git a/src/main/scala/rocket/tile.scala b/src/main/scala/rocket/tile.scala index b0391472..c497a98e 100644 --- a/src/main/scala/rocket/tile.scala +++ b/src/main/scala/rocket/tile.scala @@ -61,7 +61,7 @@ class RocketTile(implicit p: Parameters) extends LazyTile { val slave = if (p(DataScratchpadSize) == 0) None else Some(TLInputNode()) val scratch = if (p(DataScratchpadSize) == 0) None else Some(LazyModule(new ScratchpadSlavePort()(dcacheParams))) - (slave zip scratch) foreach { case (node, lm) => lm.node := TLFragmenter(p(XLen)/8, 256)(node) } + (slave zip scratch) foreach { case (node, lm) => lm.node := TLFragmenter(p(XLen)/8, p(CacheBlockBytes))(node) } lazy val module = new TileImp(this) { val io = new TileIO(bc, slave) From 015c3b862a4d778b1711d9dc41c66348cd30fa55 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 14:00:55 -0700 Subject: [PATCH 29/47] diplomacy: print out bus widths on edges in agent graph --- src/main/scala/diplomacy/LazyModule.scala | 10 +++++++--- src/main/scala/diplomacy/Nodes.scala | 10 ++++++---- src/main/scala/groundtest/Generator.scala | 1 + src/main/scala/uncore/axi4/Nodes.scala | 3 +++ src/main/scala/uncore/tilelink2/IntNodes.scala | 3 +++ src/main/scala/uncore/tilelink2/Nodes.scala | 6 ++++++ src/main/scala/unittest/Generator.scala | 1 + 7 files changed, 27 insertions(+), 7 deletions(-) diff --git a/src/main/scala/diplomacy/LazyModule.scala b/src/main/scala/diplomacy/LazyModule.scala index a8e2c10b..5de4877c 100644 --- a/src/main/scala/diplomacy/LazyModule.scala +++ b/src/main/scala/diplomacy/LazyModule.scala @@ -62,7 +62,7 @@ abstract class LazyModule private def nodesGraphML(buf: StringBuilder, pad: String) { buf ++= s"""${pad}\n""" - buf ++= s"""${pad} ${module.name}\n""" + buf ++= s"""${pad} ${module.instanceName}\n""" buf ++= s"""${pad} \n""" nodes.filter(!_.omitGraphML).foreach { n => buf ++= s"""${pad} \n""" @@ -72,11 +72,15 @@ abstract class LazyModule buf ++= s"""${pad}\n""" } private def edgesGraphML(buf: StringBuilder, pad: String) { - nodes.filter(!_.omitGraphML) foreach { n => n.outputs.filter(!_.omitGraphML).foreach { o => + nodes.filter(!_.omitGraphML) foreach { n => n.outputs.filter(!_._1.omitGraphML).foreach { case (o, l) => buf ++= pad buf ++= "\n""" + buf ++= s""" target=\"${o.lazyModule.index}::${o.index}\">""" + buf ++= s"""""" + buf ++= s"""""" + buf ++= s"""${l}""" + buf ++= s"""\n""" } } children.filter(!_.omitGraphML).foreach { c => c.edgesGraphML(buf, pad) } } diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 633ece07..88880a9f 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -20,6 +20,7 @@ trait InwardNodeImp[DI, UI, EI, BI <: Data] // optional methods to track node graph def mixI(pu: UI, node: InwardNode[DI, UI, BI]): UI = pu // insert node into parameters def getO(pu: UI): Option[BaseNode] = None // most-outward common node + def labelI(ei: EI) = "" } // DO = Downwards flowing Parameters generated by the outer side of the node @@ -34,6 +35,7 @@ trait OutwardNodeImp[DO, UO, EO, BO <: Data] // optional methods to track node graph def mixO(pd: DO, node: OutwardNode[DO, UO, BO]): DO = pd // insert node into parameters def getI(pd: DO): Option[BaseNode] = None // most-inward common node + def labelO(eo: EO) = "" } abstract class NodeImp[D, U, EO, EI, B <: Data] @@ -54,8 +56,8 @@ abstract class BaseNode protected[diplomacy] def gci: Option[BaseNode] // greatest common inner protected[diplomacy] def gco: Option[BaseNode] // greatest common outer - protected[diplomacy] def outputs: Seq[BaseNode] - protected[diplomacy] def inputs: Seq[BaseNode] + protected[diplomacy] def outputs: Seq[(BaseNode, String)] + protected[diplomacy] def inputs: Seq[(BaseNode, String)] protected[diplomacy] def colour: String } @@ -140,8 +142,8 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( { // meta-data for printing the node graph protected[diplomacy] def colour = inner.colour - protected[diplomacy] def outputs = oPorts.map(_._2) - protected[diplomacy] def inputs = iPorts.map(_._2) + protected[diplomacy] def outputs = oPorts.map(_._2) zip edgesOut.map(e => outer.labelO(e)) + protected[diplomacy] def inputs = iPorts.map(_._2) zip edgesIn .map(e => inner.labelI(e)) private def reqE(o: Int, i: Int) = require(i == o, s"${name} has ${i} inputs and ${o} outputs; they must match${lazyModule.line}") protected[diplomacy] lazy val oParams: Seq[DO] = { diff --git a/src/main/scala/groundtest/Generator.scala b/src/main/scala/groundtest/Generator.scala index f5c6bb27..62a1f38c 100644 --- a/src/main/scala/groundtest/Generator.scala +++ b/src/main/scala/groundtest/Generator.scala @@ -5,6 +5,7 @@ package groundtest object Generator extends util.GeneratorApp { val longName = names.topModuleProject + "." + names.configs generateFirrtl + generateGraphML generateTestSuiteMakefrags // TODO: Needed only for legacy make targets generateParameterDump // TODO: Needed only for legacy make targets } diff --git a/src/main/scala/uncore/axi4/Nodes.scala b/src/main/scala/uncore/axi4/Nodes.scala index 2c728e06..b8fb1efd 100644 --- a/src/main/scala/uncore/axi4/Nodes.scala +++ b/src/main/scala/uncore/axi4/Nodes.scala @@ -20,6 +20,9 @@ object AXI4Imp extends NodeImp[AXI4MasterPortParameters, AXI4SlavePortParameters } def colour = "#00ccff" // bluish + override def labelI(ei: AXI4EdgeParameters) = (ei.slave.beatBytes * 8).toString + override def labelO(eo: AXI4EdgeParameters) = (eo.slave.beatBytes * 8).toString + def connect(bo: => AXI4Bundle, bi: => AXI4Bundle, ei: => AXI4EdgeParameters)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { (None, () => { bi <> bo }) } diff --git a/src/main/scala/uncore/tilelink2/IntNodes.scala b/src/main/scala/uncore/tilelink2/IntNodes.scala index 79fd4990..0c6474e9 100644 --- a/src/main/scala/uncore/tilelink2/IntNodes.scala +++ b/src/main/scala/uncore/tilelink2/IntNodes.scala @@ -62,6 +62,9 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In } def colour = "#0000ff" // blue + override def labelI(ei: IntEdge) = ei.source.sources.map(_.range.size).sum.toString + override def labelO(eo: IntEdge) = eo.source.sources.map(_.range.size).sum.toString + def connect(bo: => Vec[Bool], bi: => Vec[Bool], ei: => IntEdge)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { (None, () => { // Cannot use bulk connect, because the widths could differ diff --git a/src/main/scala/uncore/tilelink2/Nodes.scala b/src/main/scala/uncore/tilelink2/Nodes.scala index 0941dc04..962517ba 100644 --- a/src/main/scala/uncore/tilelink2/Nodes.scala +++ b/src/main/scala/uncore/tilelink2/Nodes.scala @@ -25,6 +25,9 @@ object TLImp extends NodeImp[TLClientPortParameters, TLManagerPortParameters, TL var combinationalCheck = false def colour = "#000000" // black + override def labelI(ei: TLEdgeIn) = (ei.manager.beatBytes * 8).toString + override def labelO(eo: TLEdgeOut) = (eo.manager.beatBytes * 8).toString + def connect(bo: => TLBundle, bi: => TLBundle, ei: => TLEdgeIn)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { val monitor = if (emitMonitors) { Some(LazyModule(new TLMonitor(() => new TLBundleSnoop(bo.params), () => ei, sourceInfo))) @@ -159,6 +162,9 @@ object TLAsyncImp extends NodeImp[TLAsyncClientPortParameters, TLAsyncManagerPor } def colour = "#ff0000" // red + override def labelI(ei: TLAsyncEdgeParameters) = ei.manager.depth.toString + override def labelO(eo: TLAsyncEdgeParameters) = eo.manager.depth.toString + def connect(bo: => TLAsyncBundle, bi: => TLAsyncBundle, ei: => TLAsyncEdgeParameters)(implicit sourceInfo: SourceInfo): (Option[LazyModule], () => Unit) = { (None, () => { bi <> bo }) } diff --git a/src/main/scala/unittest/Generator.scala b/src/main/scala/unittest/Generator.scala index 95e114d1..36d64779 100644 --- a/src/main/scala/unittest/Generator.scala +++ b/src/main/scala/unittest/Generator.scala @@ -5,6 +5,7 @@ package unittest object Generator extends util.GeneratorApp { val longName = names.topModuleProject + "." + names.configs generateFirrtl + generateGraphML generateTestSuiteMakefrags // TODO: Needed only for legacy make targets generateParameterDump // TODO: Needed only for legacy make targets } From 72a7948ad271db9f5a988eb219cf7189a14b0810 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 15:05:49 -0700 Subject: [PATCH 30/47] rocketchip Periphery: move atomics before WidthWidget => 64-bit AMOs --- src/main/scala/rocketchip/BaseTop.scala | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 9258b34b..813a5af0 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -45,10 +45,9 @@ abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(impli lazy val legacyAddrMap = GenerateGlobalAddrMap(q, coreplex.l1tol2.node.edgesIn(0).manager.managers) peripheryBus.node := - TLBuffer()( - TLAtomicAutomata(arithmetic = p(PeripheryBusKey).arithAMO)( TLWidthWidget(p(SOCBusKey).beatBytes)( - socBus.node))) + TLAtomicAutomata(arithmetic = p(PeripheryBusKey).arithAMO)( + socBus.node)) TopModule.contents = Some(this) } From 043ed48c8c7a34a2a9bd5f552f901fe0942e70a3 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 15:07:35 -0700 Subject: [PATCH 31/47] tilelink2 HintHandler: delay answers to help TL1 legacy clients --- src/main/scala/uncore/tilelink2/HintHandler.scala | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/src/main/scala/uncore/tilelink2/HintHandler.scala b/src/main/scala/uncore/tilelink2/HintHandler.scala index 16d36a8e..3ba187e0 100644 --- a/src/main/scala/uncore/tilelink2/HintHandler.scala +++ b/src/main/scala/uncore/tilelink2/HintHandler.scala @@ -2,6 +2,7 @@ package uncore.tilelink2 +import scala.math.min import Chisel._ import chisel3.internal.sourceinfo.SourceInfo import diplomacy._ @@ -9,10 +10,9 @@ import diplomacy._ // Acks Hints for managers that don't support them or Acks all Hints if !passthrough class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = false, passthrough: Boolean = true) extends LazyModule { - // HintAcks can come back combinationally => minLatency=0 val node = TLAdapterNode( - clientFn = { case Seq(c) => if (!supportClients) c else c.copy(minLatency = 0, clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) }, - managerFn = { case Seq(m) => if (!supportManagers) m else m.copy(minLatency = 0, managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) }) + clientFn = { case Seq(c) => if (!supportClients) c else c.copy(minLatency = min(1, c.minLatency), clients = c.clients .map(_.copy(supportsHint = TransferSizes(1, c.maxTransfer)))) }, + managerFn = { case Seq(m) => if (!supportManagers) m else m.copy(minLatency = min(1, m.minLatency), managers = m.managers.map(_.copy(supportsHint = TransferSizes(1, m.maxTransfer)))) }) lazy val module = new LazyModuleImp(this) { val io = new Bundle { @@ -46,7 +46,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f hint.bits := edgeIn.HintAck(in.a.bits, edgeOut.manager.findIdStartFast(address)) out.a.bits := in.a.bits - TLArbiter(TLArbiter.lowestIndexFirst)(in.d, (edgeOut.numBeats1(out.d.bits), out.d), (UInt(0), hint)) + TLArbiter(TLArbiter.lowestIndexFirst)(in.d, (edgeOut.numBeats1(out.d.bits), out.d), (UInt(0), Queue(hint, 1))) } else { out.a.valid := in.a.valid in.a.ready := out.a.ready @@ -69,7 +69,7 @@ class TLHintHandler(supportManagers: Boolean = true, supportClients: Boolean = f hint.bits := edgeOut.HintAck(out.b.bits) in.b.bits := out.b.bits - TLArbiter(TLArbiter.lowestIndexFirst)(out.c, (edgeIn.numBeats1(in.c.bits), in.c), (UInt(0), hint)) + TLArbiter(TLArbiter.lowestIndexFirst)(out.c, (edgeIn.numBeats1(in.c.bits), in.c), (UInt(0), Queue(hint, 1))) } else if (bce) { in.b.valid := out.b.valid out.b.ready := in.b.ready From ac886026e69474cbf03eec7dad9c28b83f85bb60 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 16:47:20 -0700 Subject: [PATCH 32/47] rocketchip: reduce number of type parameters --- src/main/scala/coreplex/BaseCoreplex.scala | 7 ++++--- src/main/scala/coreplex/Coreplex.scala | 8 ++++---- src/main/scala/groundtest/Coreplex.scala | 4 ++-- src/main/scala/rocketchip/BaseTop.scala | 3 ++- src/main/scala/rocketchip/ExampleTop.scala | 8 ++++---- 5 files changed, 16 insertions(+), 14 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index dead46fe..c79db428 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -75,7 +75,8 @@ abstract class BareCoreplexBundle[+L <: BareCoreplex](val outer: L) extends Bund val success = Bool(OUTPUT) // used for testing } -abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](val outer: L, val io: B) extends LazyModuleImp(outer) with HasCoreplexParameters { +abstract class BareCoreplexModule[+B <: BareCoreplexBundle[BareCoreplex]](val io: B) extends LazyModuleImp(io.outer) with HasCoreplexParameters { + val outer = io.outer.asInstanceOf[io.outer.type] implicit val p = outer.p // Create and export the ConfigString @@ -200,11 +201,11 @@ trait CoreplexPeripheralsModule extends HasCoreplexParameters { class BaseCoreplex(implicit p: Parameters) extends BareCoreplex with CoreplexPeripherals { - override lazy val module = new BaseCoreplexModule(this, new BaseCoreplexBundle(this)) + override lazy val module = new BaseCoreplexModule(new BaseCoreplexBundle(this)) } class BaseCoreplexBundle[+L <: BaseCoreplex](outer: L) extends BareCoreplexBundle(outer) with CoreplexPeripheralsBundle -class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](outer: L, io: B) extends BareCoreplexModule(outer, io) +class BaseCoreplexModule[+B <: BaseCoreplexBundle[BaseCoreplex]](io: B) extends BareCoreplexModule(io) with CoreplexPeripheralsModule diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 6f98b144..062ce597 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -39,12 +39,12 @@ trait DirectConnectionModule { class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex with DirectConnection { - override lazy val module = new DefaultCoreplexModule(this, new DefaultCoreplexBundle(this)) + override lazy val module = new DefaultCoreplexModule(new DefaultCoreplexBundle(this)) } class DefaultCoreplexBundle[+L <: DefaultCoreplex](outer: L) extends BaseCoreplexBundle(outer) -class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) +class DefaultCoreplexModule[+B <: DefaultCoreplexBundle[DefaultCoreplex]](io: B) extends BaseCoreplexModule(io) with DirectConnectionModule ///// @@ -111,11 +111,11 @@ trait AsyncConnectionModule extends Module { class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex with AsyncConnection { - override lazy val module = new MultiClockCoreplexModule(this, new MultiClockCoreplexBundle(this)) + override lazy val module = new MultiClockCoreplexModule(new MultiClockCoreplexBundle(this)) } class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](outer: L) extends BaseCoreplexBundle(outer) with TileClockResetBundle -class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) +class MultiClockCoreplexModule[+B <: MultiClockCoreplexBundle[MultiClockCoreplex]](io: B) extends BaseCoreplexModule(io) with AsyncConnectionModule diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index 59310230..04cb2650 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -6,12 +6,12 @@ import coreplex._ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex with DirectConnection { - override lazy val module = new GroundTestCoreplexModule(this, new GroundTestCoreplexBundle(this)) + override lazy val module = new GroundTestCoreplexModule(new GroundTestCoreplexBundle(this)) } class GroundTestCoreplexBundle[+L <: GroundTestCoreplex](outer: L) extends BaseCoreplexBundle(outer) -class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](outer: L, io: B) extends BaseCoreplexModule(outer, io) +class GroundTestCoreplexModule[+B <: GroundTestCoreplexBundle[GroundTestCoreplex]](io: B) extends BaseCoreplexModule(io) with DirectConnectionModule { io.success := tiles.flatMap(_.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_) } diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 813a5af0..de2e8720 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -57,7 +57,8 @@ abstract class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](val outer: L) extends val success = Bool(OUTPUT) } -abstract class BaseTopModule[+L <: BaseTop[BaseCoreplex], +B <: BaseTopBundle[L]](val outer: L, val io: B) extends LazyModuleImp(outer) { +abstract class BaseTopModule[+B <: BaseTopBundle[BaseTop[BaseCoreplex]]](val io: B) extends LazyModuleImp(io.outer) { + val outer = io.outer.asInstanceOf[io.outer.type] implicit val p = outer.p val coreplexMem : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.mem) diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index f128b415..847781bf 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -17,7 +17,7 @@ class ExampleTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: with PeripheryMasterAXI4MMIO with PeripherySlave with DirectConnection { - override lazy val module = new ExampleTopModule(this, new ExampleTopBundle(this)) + override lazy val module = new ExampleTopModule(new ExampleTopBundle(this)) } class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](outer: L) extends BaseTopBundle(outer) @@ -28,7 +28,7 @@ class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](outer: L) extends BaseTop with PeripheryMasterAXI4MMIOBundle with PeripherySlaveBundle -class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L]](outer: L, io: B) extends BaseTopModule(outer, io) +class ExampleTopModule[+B <: ExampleTopBundle[ExampleTop[BaseCoreplex]]](io: B) extends BaseTopModule(io) with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule @@ -41,11 +41,11 @@ class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L] /** Example Top with TestRAM */ class ExampleTopWithTestRAM[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(buildCoreplex) with PeripheryTestRAM { - override lazy val module = new ExampleTopWithTestRAMModule(this, new ExampleTopWithTestRAMBundle(this)) + override lazy val module = new ExampleTopWithTestRAMModule(new ExampleTopWithTestRAMBundle(this)) } class ExampleTopWithTestRAMBundle[+L <: ExampleTopWithTestRAM[BaseCoreplex]](outer: L) extends ExampleTopBundle(outer) with PeripheryTestRAMBundle -class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM[BaseCoreplex], +B <: ExampleTopWithTestRAMBundle[L]](outer: L, io: B) extends ExampleTopModule(outer, io) +class ExampleTopWithTestRAMModule[+B <: ExampleTopWithTestRAMBundle[ExampleTopWithTestRAM[BaseCoreplex]]](io: B) extends ExampleTopModule(io) with PeripheryTestRAMModule From 6505431eacbf709b54fa61f83b04c62d9f4436fe Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 18:37:24 -0700 Subject: [PATCH 33/47] coreplex: use self-type constraints --- src/main/scala/coreplex/BaseCoreplex.scala | 140 +++++++++++---------- src/main/scala/coreplex/Coreplex.scala | 42 +++---- 2 files changed, 94 insertions(+), 88 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index c79db428..b37a0a79 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -48,36 +48,89 @@ trait HasCoreplexParameters { case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters -abstract class BareCoreplex(implicit val p: Parameters) extends LazyModule with HasCoreplexParameters { +abstract class BareCoreplex(implicit val p: Parameters) extends LazyModule +abstract class BareCoreplexBundle[+L <: BareCoreplex](val outer: L) extends Bundle +abstract class BareCoreplexModule[+B <: BareCoreplexBundle[BareCoreplex]](val io: B) extends LazyModuleImp(io.outer) { + val outer = io.outer.asInstanceOf[io.outer.type] +} + +trait CoreplexNetwork extends HasCoreplexParameters { + this: BareCoreplex => + val l1tol2 = LazyModule(new TLXbar) - val mmio = TLOutputNode() + val l1tol2_beatBytes = p(rocketchip.EdgeDataBits)/8 + val l1tol2_lineBytes = p(CacheBlockBytes) + + val cbus = LazyModule(new TLXbar) + val cbus_beatBytes = p(XLen)/8 + val cbus_lineBytes = l1tol2_lineBytes + + cbus.node := + TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata + TLWidthWidget(l1tol2_beatBytes)( + TLBuffer()( + l1tol2.node))) +} + +trait CoreplexNetworkBundle extends HasCoreplexParameters { + this: BareCoreplexBundle[BareCoreplex] => + implicit val p = outer.p +} + +trait CoreplexNetworkModule extends HasCoreplexParameters { + this: BareCoreplexModule[BareCoreplexBundle[BareCoreplex]] => + implicit val p = outer.p +} + +trait CoreplexRISCV { + this: CoreplexNetwork => + + // Build a set of Tiles val lazyTiles = p(BuildTiles) map { _(p) } val legacy = LazyModule(new TLLegacy()(outerMMIOParams)) - mmio := - TLBuffer()( - TLWidthWidget(legacy.tlDataBytes)( - l1tol2.node)) + val debug = LazyModule(new TLDebugModule()) + val plic = LazyModule(new TLPLIC(() => plicKey)) + val clint = LazyModule(new CoreplexLocalInterrupter(clintKey)) + val mmio = TLOutputNode() // Kill this once we move TL2 into rocket l1tol2.node := TLHintHandler()( legacy.node) + + debug.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) + plic.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) + clint.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) + + mmio := + TLBuffer()( + TLWidthWidget(l1tol2_beatBytes)( + l1tol2.node)) } -abstract class BareCoreplexBundle[+L <: BareCoreplex](val outer: L) extends Bundle with HasCoreplexParameters { - implicit val p = outer.p +trait CoreplexRISCVBundle { + this: CoreplexNetworkBundle { + val outer: CoreplexRISCV + } => - val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) val mmio = outer.mmio.bundleOut + val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip val resetVector = UInt(INPUT, p(XLen)) val success = Bool(OUTPUT) // used for testing + val debug = new DebugBusIO().flip + val interrupts = Vec(nExtInterrupts, Bool()).asInput } -abstract class BareCoreplexModule[+B <: BareCoreplexBundle[BareCoreplex]](val io: B) extends LazyModuleImp(io.outer) with HasCoreplexParameters { - val outer = io.outer.asInstanceOf[io.outer.type] - implicit val p = outer.p +trait CoreplexRISCVModule { + this: CoreplexNetworkModule { + val outer: CoreplexNetwork with CoreplexRISCV + val io: CoreplexRISCVBundle + } => + + val tiles = outer.lazyTiles.map(_.module) + val uncoreTileIOs = (tiles zipWithIndex) map { case (tile, i) => Wire(tile.io) } // Create and export the ConfigString val managers = outer.l1tol2.node.edgesIn(0).manager.managers @@ -85,14 +138,10 @@ abstract class BareCoreplexModule[+B <: BareCoreplexBundle[BareCoreplex]](val io println(s"\nGenerated Configuration String\n${configString}") ConfigStringOutput.contents = Some(configString) - // Build a set of Tiles - val tiles = outer.lazyTiles.map(_.module) - val uncoreTileIOs = (tiles zipWithIndex) map { case (tile, i) => Wire(tile.io) } - val nCachedPorts = tiles.map(tile => tile.io.cached.size).reduce(_ + _) val nUncachedPorts = tiles.map(tile => tile.io.uncached.size).reduce(_ + _) val nBanks = nMemChannels * nBanksPerMemChannel - + buildUncore(p.alterPartial({ case HastiId => "TL" case TLId => "L1toL2" @@ -139,48 +188,18 @@ abstract class BareCoreplexModule[+B <: BareCoreplexBundle[BareCoreplex]](val io io.mem <> mem_ic.io.out } + // connect coreplex-internal interrupts to tiles for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { tile.hartid := UInt(i) tile.resetVector := io.resetVector + tile.interrupts <> outer.clint.module.io.tiles(i) + tile.interrupts.meip := outer.plic.module.io.harts(plicKey.context(i, 'M')) + tile.interrupts.seip.foreach(_ := outer.plic.module.io.harts(plicKey.context(i, 'S'))) + tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) } // Coreplex doesn't know when to stop running io.success := Bool(false) -} - -trait CoreplexPeripherals extends HasCoreplexParameters { - val module: CoreplexPeripheralsModule - val l1tol2: TLXbar - val legacy: TLLegacy - - val cbus = LazyModule(new TLXbar) - val debug = LazyModule(new TLDebugModule()) - val plic = LazyModule(new TLPLIC(() => plicKey)) - val clint = LazyModule(new CoreplexLocalInterrupter(clintKey)) - - cbus.node := - TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata - TLWidthWidget(legacy.tlDataBytes)( - TLBuffer()( - l1tol2.node))) - - debug.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) - plic.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) - clint.node := TLFragmenter(p(XLen)/8, legacy.tlDataBeats * legacy.tlDataBytes)(cbus.node) -} - -trait CoreplexPeripheralsBundle extends HasCoreplexParameters { - val outer: CoreplexPeripherals - - val debug = new DebugBusIO().flip - val interrupts = Vec(nExtInterrupts, Bool()).asInput -} - -trait CoreplexPeripheralsModule extends HasCoreplexParameters { - val outer: CoreplexPeripherals - val io: CoreplexPeripheralsBundle - val uncoreTileIOs: Seq[TileIO] - for (i <- 0 until io.interrupts.size) { val gateway = Module(new LevelGateway) gateway.io.interrupt := io.interrupts(i) @@ -189,23 +208,18 @@ trait CoreplexPeripheralsModule extends HasCoreplexParameters { outer.debug.module.io.db <> io.debug outer.clint.module.io.rtcTick := Counter(p(rocketchip.RTCPeriod)).inc() - - // connect coreplex-internal interrupts to tiles - for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { - tile.interrupts <> outer.clint.module.io.tiles(i) - tile.interrupts.meip := outer.plic.module.io.harts(plicKey.context(i, 'M')) - tile.interrupts.seip.foreach(_ := outer.plic.module.io.harts(plicKey.context(i, 'S'))) - tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) - } } class BaseCoreplex(implicit p: Parameters) extends BareCoreplex - with CoreplexPeripherals { + with CoreplexNetwork + with CoreplexRISCV { override lazy val module = new BaseCoreplexModule(new BaseCoreplexBundle(this)) } class BaseCoreplexBundle[+L <: BaseCoreplex](outer: L) extends BareCoreplexBundle(outer) - with CoreplexPeripheralsBundle + with CoreplexNetworkBundle + with CoreplexRISCVBundle class BaseCoreplexModule[+B <: BaseCoreplexBundle[BaseCoreplex]](io: B) extends BareCoreplexModule(io) - with CoreplexPeripheralsModule + with CoreplexNetworkModule + with CoreplexRISCVModule diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 062ce597..d5bd9892 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -11,17 +11,12 @@ import util._ import rocket._ trait DirectConnection { - implicit val p: Parameters - val lazyTiles: Seq[LazyTile] - val legacy: TLLegacy - val cbus: TLXbar - + this: CoreplexNetwork with CoreplexRISCV => lazyTiles.map(_.slave).flatten.foreach { scratch => scratch := cbus.node } } trait DirectConnectionModule { - val tiles: Seq[TileImp] - val uncoreTileIOs: Seq[TileIO] + this: CoreplexNetworkModule with CoreplexRISCVModule => val tlBuffering = TileLinkDepths(1,1,2,2,0) val ultBuffering = UncachedTileLinkDepths(1,2) @@ -49,19 +44,8 @@ class DefaultCoreplexModule[+B <: DefaultCoreplexBundle[DefaultCoreplex]](io: B) ///// -trait TileClockResetBundle extends Bundle with HasCoreplexParameters { - val tcrs = Vec(nTiles, new Bundle { - val clock = Clock(INPUT) - val reset = Bool(INPUT) - }) -} - trait AsyncConnection { - implicit val p: Parameters - val lazyTiles: Seq[LazyTile] - val legacy: TLLegacy - val cbus: TLXbar - + this: CoreplexNetwork with CoreplexRISCV => val crossings = lazyTiles.map(_.slave).map(_.map { scratch => val crossing = LazyModule(new TLAsyncCrossing) crossing.node := cbus.node @@ -70,11 +54,19 @@ trait AsyncConnection { }) } -trait AsyncConnectionModule extends Module { - val io: TileClockResetBundle - val tiles: Seq[TileImp] - val uncoreTileIOs: Seq[TileIO] - val outer: AsyncConnection +trait AsyncConnectionBundle { + this: CoreplexNetworkBundle with CoreplexRISCVBundle => + val tcrs = Vec(nTiles, new Bundle { + val clock = Clock(INPUT) + val reset = Bool(INPUT) + }) +} + +trait AsyncConnectionModule { + this: Module with CoreplexNetworkModule with CoreplexRISCVModule { + val outer: AsyncConnection + val io: AsyncConnectionBundle + } => (outer.crossings zip io.tcrs) foreach { case (slaves, tcr) => slaves.foreach { case (crossing, monitor) => @@ -115,7 +107,7 @@ class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex } class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](outer: L) extends BaseCoreplexBundle(outer) - with TileClockResetBundle + with AsyncConnectionBundle class MultiClockCoreplexModule[+B <: MultiClockCoreplexBundle[MultiClockCoreplex]](io: B) extends BaseCoreplexModule(io) with AsyncConnectionModule From ba529c37167cadb19747a5bcd5d641021af1a8da Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 21:20:49 -0700 Subject: [PATCH 34/47] rocketchip: use TileLink2 interrupts --- src/main/scala/coreplex/BaseCoreplex.scala | 54 ++-- src/main/scala/diplomacy/Nodes.scala | 21 +- src/main/scala/rocketchip/BaseTop.scala | 14 +- src/main/scala/rocketchip/Periphery.scala | 25 +- src/main/scala/rocketchip/TestHarness.scala | 2 +- src/main/scala/rocketchip/Utils.scala | 33 +-- src/main/scala/uncore/devices/Plic.scala | 268 +++++++++++------- src/main/scala/uncore/devices/Prci.scala | 36 ++- .../scala/uncore/tilelink2/IntNodes.scala | 28 +- .../uncore/tilelink2/RegisterRouter.scala | 3 +- 10 files changed, 270 insertions(+), 214 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index b37a0a79..52482d1f 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -36,14 +36,9 @@ trait HasCoreplexParameters { lazy val outerMMIOParams = p.alterPartial({ case TLId => "L2toMMIO" }) lazy val globalAddrMap = p(rocketchip.GlobalAddrMap) lazy val nTiles = p(uncore.devices.NTiles) - lazy val nExtInterrupts = p(rocketchip.NExtInterrupts) lazy val nSlaves = p(rocketchip.NCoreplexExtClients) lazy val nMemChannels = p(NMemoryChannels) lazy val hasSupervisor = p(rocket.UseVM) - - lazy val nInterruptPriorities = if (nExtInterrupts <= 1) 0 else (nExtInterrupts min 7) - lazy val plicKey = PLICConfig(nTiles, hasSupervisor, nExtInterrupts, nInterruptPriorities) - lazy val clintKey = CoreplexLocalInterrupterConfig() } case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters @@ -55,7 +50,7 @@ abstract class BareCoreplexModule[+B <: BareCoreplexBundle[BareCoreplex]](val io } trait CoreplexNetwork extends HasCoreplexParameters { - this: BareCoreplex => + this: BareCoreplex => val l1tol2 = LazyModule(new TLXbar) val l1tol2_beatBytes = p(rocketchip.EdgeDataBits)/8 @@ -65,16 +60,29 @@ trait CoreplexNetwork extends HasCoreplexParameters { val cbus_beatBytes = p(XLen)/8 val cbus_lineBytes = l1tol2_lineBytes + val mmio = TLOutputNode() + val mmioInt = IntInputNode() + cbus.node := TLAtomicAutomata(arithmetic = true)( // disable once TLB uses TL2 metadata TLWidthWidget(l1tol2_beatBytes)( TLBuffer()( l1tol2.node))) + + mmio := + TLBuffer()( + TLWidthWidget(l1tol2_beatBytes)( + l1tol2.node)) } trait CoreplexNetworkBundle extends HasCoreplexParameters { - this: BareCoreplexBundle[BareCoreplex] => + this: { + val outer: CoreplexNetwork + } => + implicit val p = outer.p + val mmio = outer.mmio.bundleOut + val interrupts = outer.mmioInt.bundleIn } trait CoreplexNetworkModule extends HasCoreplexParameters { @@ -88,11 +96,11 @@ trait CoreplexRISCV { // Build a set of Tiles val lazyTiles = p(BuildTiles) map { _(p) } val legacy = LazyModule(new TLLegacy()(outerMMIOParams)) + val tileIntNode = IntInternalOutputNode() // this should be moved into the Tile... val debug = LazyModule(new TLDebugModule()) - val plic = LazyModule(new TLPLIC(() => plicKey)) - val clint = LazyModule(new CoreplexLocalInterrupter(clintKey)) - val mmio = TLOutputNode() + val plic = LazyModule(new TLPLIC(hasSupervisor, maxPriorities = 7)) + val clint = LazyModule(new CoreplexLocalInterrupter) // Kill this once we move TL2 into rocket l1tol2.node := @@ -103,10 +111,8 @@ trait CoreplexRISCV { plic.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) clint.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) - mmio := - TLBuffer()( - TLWidthWidget(l1tol2_beatBytes)( - l1tol2.node)) + plic.intnode := mmioInt + lazyTiles.foreach { _ => tileIntNode := plic.intnode } } trait CoreplexRISCVBundle { @@ -114,13 +120,11 @@ trait CoreplexRISCVBundle { val outer: CoreplexRISCV } => - val mmio = outer.mmio.bundleOut val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip val resetVector = UInt(INPUT, p(XLen)) val success = Bool(OUTPUT) // used for testing val debug = new DebugBusIO().flip - val interrupts = Vec(nExtInterrupts, Bool()).asInput } trait CoreplexRISCVModule { @@ -134,7 +138,7 @@ trait CoreplexRISCVModule { // Create and export the ConfigString val managers = outer.l1tol2.node.edgesIn(0).manager.managers - val configString = rocketchip.GenerateConfigString(p, managers) + val configString = rocketchip.GenerateConfigString(p, outer.clint, outer.plic, managers) println(s"\nGenerated Configuration String\n${configString}") ConfigStringOutput.contents = Some(configString) @@ -192,22 +196,16 @@ trait CoreplexRISCVModule { for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { tile.hartid := UInt(i) tile.resetVector := io.resetVector - tile.interrupts <> outer.clint.module.io.tiles(i) - tile.interrupts.meip := outer.plic.module.io.harts(plicKey.context(i, 'M')) - tile.interrupts.seip.foreach(_ := outer.plic.module.io.harts(plicKey.context(i, 'S'))) tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) - } - - // Coreplex doesn't know when to stop running - io.success := Bool(false) - for (i <- 0 until io.interrupts.size) { - val gateway = Module(new LevelGateway) - gateway.io.interrupt := io.interrupts(i) - outer.plic.module.io.devices(i) <> gateway.io.plic + tile.interrupts.meip := outer.tileIntNode.bundleOut(i)(0) + tile.interrupts.seip.foreach(_ := outer.tileIntNode.bundleOut(i)(1)) } outer.debug.module.io.db <> io.debug outer.clint.module.io.rtcTick := Counter(p(rocketchip.RTCPeriod)).inc() + + // Coreplex doesn't know when to stop running + io.success := Bool(false) } class BaseCoreplex(implicit p: Parameters) extends BareCoreplex diff --git a/src/main/scala/diplomacy/Nodes.scala b/src/main/scala/diplomacy/Nodes.scala index 88880a9f..83e0c80a 100644 --- a/src/main/scala/diplomacy/Nodes.scala +++ b/src/main/scala/diplomacy/Nodes.scala @@ -166,9 +166,12 @@ class MixedNode[DI, UI, EI, BI <: Data, DO, UO, EO, BO <: Data]( val flip = false // needed for blind nodes private def flipO(b: Vec[BO]) = if (flip) b.flip else b private def flipI(b: Vec[BI]) = if (flip) b else b.flip + val wire = false // needed if you want to grab access to from inside a module + private def wireO(b: Vec[BO]) = if (wire) Wire(b) else b + private def wireI(b: Vec[BI]) = if (wire) Wire(b) else b - lazy val bundleOut = flipO(outer.bundleO(edgesOut)) - lazy val bundleIn = flipI(inner.bundleI(edgesIn)) + lazy val bundleOut = wireO(flipO(outer.bundleO(edgesOut))) + lazy val bundleIn = wireI(flipI(inner.bundleI(edgesIn))) // connects the outward part of a node with the inward part of this node override def := (h: OutwardNodeHandle[DI, UI, BI])(implicit sourceInfo: SourceInfo): Option[LazyModule] = { @@ -234,6 +237,20 @@ class BlindInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) override lazy val bundleIn = bundleOut } +class InternalOutputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(pi: PI) + extends SimpleNode(imp)({case (0, _) => Seq()}, {case (n, Seq()) => Seq.fill(n)(pi)}, 0 to 0, 1 to 1) +{ + override val wire = true + override lazy val bundleOut = bundleIn +} + +class InternalInputNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B])(po: PO) + extends SimpleNode(imp)({case (n, Seq()) => Seq.fill(n)(po)}, {case (0, _) => Seq()}, 1 to 1, 0 to 0) +{ + override val wire = true + override lazy val bundleIn = bundleOut +} + class InteriorNode[PO, PI, EO, EI, B <: Data](imp: NodeImp[PO, PI, EO, EI, B]) (oFn: Seq[PO] => PO, iFn: Seq[PI] => PI, numPO: Range.Inclusive, numPI: Range.Inclusive) extends SimpleNode(imp)({case (n,s) => Seq.fill(n)(oFn(s))}, {case (n,s) => Seq.fill(n)(iFn(s))}, numPO, numPI) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index de2e8720..db22bff4 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -16,14 +16,12 @@ import coreplex._ // the following parameters will be refactored properly with TL2 case object GlobalAddrMap extends Field[AddrMap] case object NCoreplexExtClients extends Field[Int] -case object NExtInterrupts extends Field[Int] /** Enable or disable monitoring of Diplomatic buses */ case object TLEmitMonitors extends Field[Bool] /** Base Top with no Periphery */ abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit q: Parameters) extends LazyModule { // the following variables will be refactored properly with TL2 - val pInterrupts = new RangeManager val pBusMasters = new RangeManager TLImp.emitMonitors = q(TLEmitMonitors) @@ -31,11 +29,11 @@ abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(impli // Add a SoC and peripheral bus val socBus = LazyModule(new TLXbar) val peripheryBus = LazyModule(new TLXbar) + val intBus = LazyModule(new IntXbar) // Fill in the TL1 legacy parameters implicit val p = q.alterPartial { case NCoreplexExtClients => pBusMasters.sum - case NExtInterrupts => pInterrupts.sum case GlobalAddrMap => legacyAddrMap } @@ -64,7 +62,6 @@ abstract class BaseTopModule[+B <: BaseTopBundle[BaseTop[BaseCoreplex]]](val io: val coreplexMem : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.mem) val coreplexSlave : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.slave) val coreplexDebug : DebugBusIO = Wire(outer.coreplex.module.io.debug) - val coreplexInterrupts : Vec[Bool] = Wire(outer.coreplex.module.io.interrupts) println("Generated Address Map") for (entry <- p(GlobalAddrMap).flatten) { @@ -79,17 +76,16 @@ abstract class BaseTopModule[+B <: BaseTopBundle[BaseTop[BaseCoreplex]]](val io: println(f"\t$name%s $start%x - $end%x, $protStr$cacheable") } - println("\nGenerated Interrupt Vector") - outer.pInterrupts.print - io.success := outer.coreplex.module.io.success } trait DirectConnection { val coreplex: BaseCoreplex val socBus: TLXbar + val intBus: IntXbar socBus.node := coreplex.mmio + coreplex.mmioInt := intBus.intnode } trait DirectConnectionModule { @@ -98,10 +94,8 @@ trait DirectConnectionModule { val coreplexMem : Vec[ClientUncachedTileLinkIO] val coreplexSlave : Vec[ClientUncachedTileLinkIO] val coreplexDebug : DebugBusIO - val coreplexInterrupts : Vec[Bool] - coreplexMem <> outer.coreplex.module.io.mem - coreplexInterrupts <> outer.coreplex.module.io.interrupts + coreplexMem <> outer.coreplex.module.io.mem outer.coreplex.module.io.slave <> coreplexSlave outer.coreplex.module.io.debug <> coreplexDebug } diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 5162bf0d..8d3e02bc 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -129,28 +129,21 @@ trait PeripheryDebugModule { trait PeripheryExtInterrupts extends LazyModule { implicit val p: Parameters - val pInterrupts: RangeManager + val intBus: IntXbar - pInterrupts.add("ext", p(NExtTopInterrupts)) + val extInterrupts = IntBlindInputNode(p(NExtTopInterrupts)) + val extInterruptXing = LazyModule(new IntXing) + + intBus.intnode := extInterruptXing.intnode + extInterruptXing.intnode := extInterrupts } trait PeripheryExtInterruptsBundle { - implicit val p: Parameters - val interrupts = Vec(p(NExtTopInterrupts), Bool()).asInput + val outer: PeripheryExtInterrupts + val interrupts = outer.extInterrupts.bundleIn } trait PeripheryExtInterruptsModule { - implicit val p: Parameters - val outer: PeripheryExtInterrupts - val io: PeripheryExtInterruptsBundle - val coreplexInterrupts: Vec[Bool] - - { - val r = outer.pInterrupts.range("ext") - ((r._1 until r._2) zipWithIndex) foreach { case (c, i) => - coreplexInterrupts(c) := io.interrupts(i) - } - } } ///// @@ -220,9 +213,7 @@ trait PeripheryMasterAXI4MMIO extends HasPeripheryParameters { } trait PeripheryMasterAXI4MMIOBundle extends HasPeripheryParameters { - implicit val p: Parameters val outer: PeripheryMasterAXI4MMIO - val mmio_axi = outer.mmio_axi4.bundleOut } diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index 50eb45b6..400e6a93 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -26,7 +26,7 @@ class TestHarness(q: Parameters) extends Module { require(dut.io.bus_clk.isEmpty) require(dut.io.bus_rst.isEmpty) - for (int <- dut.io.interrupts) + for (int <- dut.io.interrupts(0)) int := Bool(false) if (dut.io.mem_axi.nonEmpty) { diff --git a/src/main/scala/rocketchip/Utils.scala b/src/main/scala/rocketchip/Utils.scala index f44cc105..d4839120 100644 --- a/src/main/scala/rocketchip/Utils.scala +++ b/src/main/scala/rocketchip/Utils.scala @@ -88,21 +88,12 @@ object GenerateGlobalAddrMap { } object GenerateConfigString { - def apply(p: Parameters, peripheryManagers: Seq[TLManagerParameters]) = { + def apply(p: Parameters, clint: CoreplexLocalInterrupter, plic: TLPLIC, peripheryManagers: Seq[TLManagerParameters]) = { val c = CoreplexParameters()(p) val addrMap = p(GlobalAddrMap) - val plicAddr = addrMap("TL2:plic").start - val clint = CoreplexLocalInterrupterConfig() - val xLen = p(XLen) val res = new StringBuilder - res append "plic {\n" - res append s" priority 0x${plicAddr.toString(16)};\n" - res append s" pending 0x${(plicAddr + PLICConsts.pendingBase).toString(16)};\n" - res append s" ndevs ${c.plicKey.nDevices};\n" - res append "};\n" - res append "rtc {\n" - res append s" addr 0x${clint.timeAddress.toString(16)};\n" - res append "};\n" + res append plic.module.globalConfigString + res append clint.module.globalConfigString if (addrMap contains "mem") { res append "ram {\n" res append " 0 {\n" @@ -124,22 +115,8 @@ object GenerateConfigString { res append s" $i {\n" res append " 0 {\n" res append s" isa $isa;\n" - res append s" timecmp 0x${clint.timecmpAddress(i).toString(16)};\n" - res append s" ipi 0x${clint.msipAddress(i).toString(16)};\n" - res append s" plic {\n" - res append s" m {\n" - res append s" ie 0x${(plicAddr + c.plicKey.enableAddr(i, 'M')).toString(16)};\n" - res append s" thresh 0x${(plicAddr + c.plicKey.threshAddr(i, 'M')).toString(16)};\n" - res append s" claim 0x${(plicAddr + c.plicKey.claimAddr(i, 'M')).toString(16)};\n" - res append s" };\n" - if (c.hasSupervisor) { - res append s" s {\n" - res append s" ie 0x${(plicAddr + c.plicKey.enableAddr(i, 'S')).toString(16)};\n" - res append s" thresh 0x${(plicAddr + c.plicKey.threshAddr(i, 'S')).toString(16)};\n" - res append s" claim 0x${(plicAddr + c.plicKey.claimAddr(i, 'S')).toString(16)};\n" - res append s" };\n" - } - res append " };\n" + res append clint.module.hartConfigStrings(i) + res append plic.module.hartConfigStrings(i) res append " };\n" res append " };\n" } diff --git a/src/main/scala/uncore/devices/Plic.scala b/src/main/scala/uncore/devices/Plic.scala index dec058b0..fa442b46 100644 --- a/src/main/scala/uncore/devices/Plic.scala +++ b/src/main/scala/uncore/devices/Plic.scala @@ -6,9 +6,11 @@ import Chisel._ import Chisel.ImplicitConversions._ import junctions._ +import diplomacy._ import regmapper._ import uncore.tilelink2._ import cde.Parameters +import scala.math.min class GatewayPLICIO extends Bundle { val valid = Bool(OUTPUT) @@ -49,113 +51,161 @@ object PLICConsts require(hartBase >= enableBase(maxHarts)) } -case class PLICConfig(nHartsIn: Int, supervisor: Boolean, nDevices: Int, nPriorities: Int) { - import PLICConsts._ - - def contextsPerHart = if (supervisor) 2 else 1 - def nHarts = contextsPerHart * nHartsIn - def context(i: Int, mode: Char) = mode match { - case 'M' => i * contextsPerHart - case 'S' => require(supervisor); i * contextsPerHart + 1 - } - def claimAddr(i: Int, mode: Char) = hartBase(context(i, mode)) + claimOffset - def threshAddr(i: Int, mode: Char) = hartBase(context(i, mode)) - def enableAddr(i: Int, mode: Char) = enableBase(context(i, mode)) - - require(nDevices <= maxDevices) - require(nHarts > 0 && nHarts <= maxHarts) - require(nPriorities >= 0 && nPriorities <= nDevices) -} - -trait HasPLICParameters { - val params: (() => PLICConfig, Parameters) - val cfg = params._1 () - implicit val p = params._2 -} - -trait PLICBundle extends Bundle with HasPLICParameters { - val devices = Vec(cfg.nDevices, new GatewayPLICIO).flip - val harts = Vec(cfg.nHarts, Bool()).asOutput -} - -trait PLICModule extends Module with HasRegMap with HasPLICParameters { - val io: PLICBundle - - val priority = - if (cfg.nPriorities > 0) Reg(Vec(cfg.nDevices+1, UInt(width=log2Up(cfg.nPriorities+1)))) - else Wire(init=Vec.fill(cfg.nDevices+1)(UInt(1))) - val threshold = - if (cfg.nPriorities > 0) Reg(Vec(cfg.nHarts, UInt(width = log2Up(cfg.nPriorities+1)))) - else Wire(init=Vec.fill(cfg.nHarts)(UInt(0))) - val pending = Reg(init=Vec.fill(cfg.nDevices+1){Bool(false)}) - val enables = Reg(Vec(cfg.nHarts, Vec(cfg.nDevices+1, Bool()))) - - for ((p, g) <- pending.tail zip io.devices) { - g.ready := !p - g.complete := false - when (g.valid) { p := true } - } - - def findMax(x: Seq[UInt]): (UInt, UInt) = { - if (x.length > 1) { - val half = 1 << (log2Ceil(x.length) - 1) - val lMax = findMax(x take half) - val rMax = findMax(x drop half) - val useLeft = lMax._1 >= rMax._1 - (Mux(useLeft, lMax._1, rMax._1), Mux(useLeft, lMax._2, UInt(half) | rMax._2)) - } else (x.head, UInt(0)) - } - - val maxDevs = Reg(Vec(cfg.nHarts, UInt(width = log2Up(pending.size)))) - for (hart <- 0 until cfg.nHarts) { - val effectivePriority = - for (((p, en), pri) <- (pending zip enables(hart) zip priority).tail) - yield Cat(p && en, pri) - val (maxPri, maxDev) = findMax((UInt(1) << priority(0).getWidth) +: effectivePriority) - - maxDevs(hart) := maxDev - io.harts(hart) := Reg(next = maxPri) > Cat(UInt(1), threshold(hart)) - } - - def priorityRegField(x: UInt) = if (cfg.nPriorities > 0) RegField(32, x) else RegField.r(32, x) - val priorityRegFields = Seq(PLICConsts.priorityBase -> priority.map(p => priorityRegField(p))) - val pendingRegFields = Seq(PLICConsts.pendingBase -> pending .map(b => RegField.r(1, b))) - - val enableRegFields = enables.zipWithIndex.map { case (e, i) => - PLICConsts.enableBase(i) -> e.map(b => RegField(1, b)) - } - - val hartRegFields = Seq.tabulate(cfg.nHarts) { i => - PLICConsts.hartBase(i) -> Seq( - priorityRegField(threshold(i)), - RegField(32, - RegReadFn { valid => - when (valid) { - pending(maxDevs(i)) := Bool(false) - maxDevs(i) := UInt(0) // flush pipeline - } - (Bool(true), maxDevs(i)) - }, - RegWriteFn { (valid, data) => - when (valid && enables(i)(data)) { - io.devices(data - UInt(1)).complete := Bool(true) - } - Bool(true) - } - ) - ) - } - - regmap((priorityRegFields ++ pendingRegFields ++ enableRegFields ++ hartRegFields):_*) - - priority(0) := 0 - pending(0) := false - for (e <- enables) - e(0) := false -} - /** Platform-Level Interrupt Controller */ -class TLPLIC(c: () => PLICConfig, address: BigInt = 0xC000000)(implicit val p: Parameters) - extends TLRegisterRouter(address, size = PLICConsts.size, beatBytes = p(rocket.XLen)/8, undefZero = false)( - new TLRegBundle((c, p), _) with PLICBundle)( - new TLRegModule((c, p), _, _) with PLICModule) +class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC000000)(implicit val p: Parameters) extends LazyModule +{ + val contextsPerHart = if (supervisor) 2 else 1 + require (maxPriorities >= 0) + + val node = TLRegisterNode( + address = AddressSet(address, PLICConsts.size-1), + beatBytes = p(rocket.XLen)/8, + undefZero = false) + + val intnode = IntAdapterNode( + numSourcePorts = 0 to 1024, + numSinkPorts = 0 to 1024, + sourceFn = { _ => IntSourcePortParameters(Seq(IntSourceParameters(contextsPerHart))) }, + sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }) + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val tl_in = node.bundleIn + val devices = intnode.bundleIn + val harts = intnode.bundleOut + } + + // Assign all the devices unique ranges + val sources = intnode.edgesIn.map(_.source) + val flatSources = (sources zip sources.map(_.num).scanLeft(0)(_+_).init).map { + case (s, o) => s.sources.map(z => z.copy(range = z.range.offset(o))) + }.flatten + // Compact the interrupt vector the same way + val interrupts = (intnode.edgesIn zip io.devices).map { case (e, i) => i.take(e.source.num) }.flatten + // This flattens the harts into an MSMSMSMSMS... or MMMMM.... sequence + val harts = io.harts.flatten + + println("\nInterrupt map:") + flatSources.foreach { s => + println(s" [${s.range.start}, ${s.range.end}) => ${s.name}") + } + + val nDevices = interrupts.size + val nPriorities = min(maxPriorities, nDevices) + val nHarts = harts.size + + require(nDevices <= PLICConsts.maxDevices) + require(nHarts > 0 && nHarts <= PLICConsts.maxHarts) + + def context(i: Int, mode: Char) = mode match { + case 'M' => i * contextsPerHart + case 'S' => require(supervisor); i * contextsPerHart + 1 + } + def claimAddr(i: Int, mode: Char) = address + PLICConsts.hartBase(context(i, mode)) + PLICConsts.claimOffset + def threshAddr(i: Int, mode: Char) = address + PLICConsts.hartBase(context(i, mode)) + def enableAddr(i: Int, mode: Char) = address + PLICConsts.enableBase(context(i, mode)) + + // Create the global PLIC config string + val globalConfigString = Seq( + s"plic {\n", + s" priority 0x${address.toString(16)};\n", + s" pending 0x${(address + PLICConsts.pendingBase).toString(16)};\n", + s" ndevs ${nDevices};\n", + s"};\n").mkString + + // Create the per-Hart config string + val hartConfigStrings = io.harts.zipWithIndex.map { case (_, i) => (Seq( + s" plic {\n", + s" m {\n", + s" ie 0x${enableAddr(i, 'M').toString(16)};\n", + s" thresh 0x${threshAddr(i, 'M').toString(16)};\n", + s" claim 0x${claimAddr(i, 'M').toString(16)};\n", + s" };\n") ++ (if (!supervisor) Seq() else Seq( + s" s {\n", + s" ie 0x${enableAddr(i, 'S').toString(16)};\n", + s" thresh 0x${threshAddr(i, 'S').toString(16)};\n", + s" claim 0x${claimAddr(i, 'S').toString(16)};\n", + s" };\n")) ++ Seq( + s" };\n")).mkString + } + + // For now, use LevelGateways for all TL2 interrupts + val gateways = Vec(interrupts.map { case i => + val gateway = Module(new LevelGateway) + gateway.io.interrupt := i + gateway.io.plic + }) + + val priority = + if (nPriorities > 0) Reg(Vec(nDevices+1, UInt(width=log2Up(nPriorities+1)))) + else Wire(init=Vec.fill(nDevices+1)(UInt(1))) + val threshold = + if (nPriorities > 0) Reg(Vec(nHarts, UInt(width = log2Up(nPriorities+1)))) + else Wire(init=Vec.fill(nHarts)(UInt(0))) + val pending = Reg(init=Vec.fill(nDevices+1){Bool(false)}) + val enables = Reg(Vec(nHarts, Vec(nDevices+1, Bool()))) + + for ((p, g) <- pending.tail zip gateways) { + g.ready := !p + g.complete := false + when (g.valid) { p := true } + } + + def findMax(x: Seq[UInt]): (UInt, UInt) = { + if (x.length > 1) { + val half = 1 << (log2Ceil(x.length) - 1) + val lMax = findMax(x take half) + val rMax = findMax(x drop half) + val useLeft = lMax._1 >= rMax._1 + (Mux(useLeft, lMax._1, rMax._1), Mux(useLeft, lMax._2, UInt(half) | rMax._2)) + } else (x.head, UInt(0)) + } + + val maxDevs = Reg(Vec(nHarts, UInt(width = log2Up(pending.size)))) + for (hart <- 0 until nHarts) { + val effectivePriority = + for (((p, en), pri) <- (pending zip enables(hart) zip priority).tail) + yield Cat(p && en, pri) + val (maxPri, maxDev) = findMax((UInt(1) << priority(0).getWidth) +: effectivePriority) + + maxDevs(hart) := maxDev + harts(hart) := Reg(next = maxPri) > Cat(UInt(1), threshold(hart)) + } + + def priorityRegField(x: UInt) = if (nPriorities > 0) RegField(32, x) else RegField.r(32, x) + val priorityRegFields = Seq(PLICConsts.priorityBase -> priority.map(p => priorityRegField(p))) + val pendingRegFields = Seq(PLICConsts.pendingBase -> pending .map(b => RegField.r(1, b))) + + val enableRegFields = enables.zipWithIndex.map { case (e, i) => + PLICConsts.enableBase(i) -> e.map(b => RegField(1, b)) + } + + val hartRegFields = Seq.tabulate(nHarts) { i => + PLICConsts.hartBase(i) -> Seq( + priorityRegField(threshold(i)), + RegField(32, + RegReadFn { valid => + when (valid) { + pending(maxDevs(i)) := Bool(false) + maxDevs(i) := UInt(0) // flush pipeline + } + (Bool(true), maxDevs(i)) + }, + RegWriteFn { (valid, data) => + when (valid && enables(i)(data)) { + gateways(data - UInt(1)).complete := Bool(true) + } + Bool(true) + } + ) + ) + } + + node.regmap((priorityRegFields ++ pendingRegFields ++ enableRegFields ++ hartRegFields):_*) + + priority(0) := 0 + pending(0) := false + for (e <- enables) + e(0) := false + } +} diff --git a/src/main/scala/uncore/devices/Prci.scala b/src/main/scala/uncore/devices/Prci.scala index 41217a69..604c89ab 100644 --- a/src/main/scala/uncore/devices/Prci.scala +++ b/src/main/scala/uncore/devices/Prci.scala @@ -6,6 +6,7 @@ import Chisel._ import junctions._ import junctions.NastiConstants._ import regmapper._ +import diplomacy._ import uncore.tilelink2._ import uncore.util._ import util._ @@ -20,22 +21,19 @@ class CoreplexLocalInterrupts extends Bundle { val msip = Bool() } -case class CoreplexLocalInterrupterConfig(address: BigInt = 0x02000000) { +object ClintConsts +{ def msipOffset(hart: Int) = hart * msipBytes - def msipAddress(hart: Int) = address + msipOffset(hart) def timecmpOffset(hart: Int) = 0x4000 + hart * timecmpBytes - def timecmpAddress(hart: Int) = address + timecmpOffset(hart) def timeOffset = 0xbff8 - def timeAddress = address + timeOffset def msipBytes = 4 def timecmpBytes = 8 def size = 0x10000 } trait MixCoreplexLocalInterrupterParameters { - val params: (CoreplexLocalInterrupterConfig, Parameters) - val c = params._1 - implicit val p = params._2 + val params: Parameters + implicit val p = params } trait CoreplexLocalInterrupterBundle extends Bundle with MixCoreplexLocalInterrupterParameters { @@ -45,6 +43,7 @@ trait CoreplexLocalInterrupterBundle extends Bundle with MixCoreplexLocalInterru trait CoreplexLocalInterrupterModule extends Module with HasRegMap with MixCoreplexLocalInterrupterParameters { val io: CoreplexLocalInterrupterBundle + val address: AddressSet val timeWidth = 64 val regWidth = 32 @@ -64,6 +63,15 @@ trait CoreplexLocalInterrupterModule extends Module with HasRegMap with MixCorep tile.mtip := time.asUInt >= timecmp(i).asUInt } + val globalConfigString = Seq( + s"rtc {\n", + s" addr 0x${(address.base + ClintConsts.timeOffset).toString(16)};\n", + s"};\n").mkString + val hartConfigStrings = (0 until p(NTiles)).map { i => Seq( + s" timecmp 0x${(address.base + ClintConsts.timecmpOffset(i)).toString(16)};\n", + s" ipi 0x${(address.base + ClintConsts.msipOffset(i)).toString(16)};\n").mkString + } + /* 0000 msip hart 0 * 0004 msip hart 1 * 4000 mtimecmp hart 0 lo @@ -75,16 +83,16 @@ trait CoreplexLocalInterrupterModule extends Module with HasRegMap with MixCorep */ regmap( - 0 -> makeRegFields(ipi), - c.timecmpOffset(0) -> makeRegFields(timecmp.flatten), - c.timeOffset -> makeRegFields(time)) + 0 -> makeRegFields(ipi), + ClintConsts.timecmpOffset(0) -> makeRegFields(timecmp.flatten), + ClintConsts.timeOffset -> makeRegFields(time)) def makeRegFields(s: Seq[UInt]) = s.map(r => RegField(regWidth, r)) } /** Power, Reset, Clock, Interrupt */ // Magic TL2 Incantation to create a TL2 Slave -class CoreplexLocalInterrupter(c: CoreplexLocalInterrupterConfig)(implicit val p: Parameters) - extends TLRegisterRouter(c.address, size = c.size, beatBytes = p(rocket.XLen)/8, undefZero = false)( - new TLRegBundle((c, p), _) with CoreplexLocalInterrupterBundle)( - new TLRegModule((c, p), _, _) with CoreplexLocalInterrupterModule) +class CoreplexLocalInterrupter(address: BigInt = 0x02000000)(implicit val p: Parameters) + extends TLRegisterRouter(address, size = ClintConsts.size, beatBytes = p(rocket.XLen)/8, undefZero = false)( + new TLRegBundle(p, _) with CoreplexLocalInterrupterBundle)( + new TLRegModule(p, _, _) with CoreplexLocalInterrupterModule) diff --git a/src/main/scala/uncore/tilelink2/IntNodes.scala b/src/main/scala/uncore/tilelink2/IntNodes.scala index 0c6474e9..d98e93e7 100644 --- a/src/main/scala/uncore/tilelink2/IntNodes.scala +++ b/src/main/scala/uncore/tilelink2/IntNodes.scala @@ -79,9 +79,6 @@ object IntImp extends NodeImp[IntSourcePortParameters, IntSinkPortParameters, In } case class IntIdentityNode() extends IdentityNode(IntImp) -case class IntOutputNode() extends OutputNode(IntImp) -case class IntInputNode() extends InputNode(IntImp) - case class IntSourceNode(num: Int) extends SourceNode(IntImp)( IntSourcePortParameters(Seq(IntSourceParameters(num))), (if (num == 0) 0 else 1) to 1) case class IntSinkNode() extends SinkNode(IntImp)( @@ -94,11 +91,20 @@ case class IntAdapterNode( numSinkPorts: Range.Inclusive = 1 to 1) extends InteriorNode(IntImp)(sourceFn, sinkFn, numSourcePorts, numSinkPorts) +case class IntOutputNode() extends OutputNode(IntImp) +case class IntInputNode() extends InputNode(IntImp) + +case class IntBlindOutputNode() extends BlindOutputNode(IntImp)(IntSinkPortParameters(Seq(IntSinkParameters()))) +case class IntBlindInputNode(num: Int) extends BlindInputNode(IntImp)(IntSourcePortParameters(Seq(IntSourceParameters(num)))) + +case class IntInternalOutputNode() extends InternalOutputNode(IntImp)(IntSinkPortParameters(Seq(IntSinkParameters()))) +case class IntInternalInputNode(num: Int) extends InternalInputNode(IntImp)(IntSourcePortParameters(Seq(IntSourceParameters(num)))) + class IntXbar extends LazyModule { val intnode = IntAdapterNode( numSourcePorts = 1 to 1, // does it make sense to have more than one interrupt sink? - numSinkPorts = 1 to 128, + numSinkPorts = 0 to 128, sinkFn = { _ => IntSinkPortParameters(Seq(IntSinkParameters())) }, sourceFn = { seq => IntSourcePortParameters((seq zip seq.map(_.num).scanLeft(0)(_+_).init).map { @@ -116,3 +122,17 @@ class IntXbar extends LazyModule io.out.foreach { _ := cat } } } + +class IntXing extends LazyModule +{ + val intnode = IntIdentityNode() + + lazy val module = new LazyModuleImp(this) { + val io = new Bundle { + val in = intnode.bundleIn + val out = intnode.bundleOut + } + + io.out := RegNext(RegNext(RegNext(io.in))) + } +} diff --git a/src/main/scala/uncore/tilelink2/RegisterRouter.scala b/src/main/scala/uncore/tilelink2/RegisterRouter.scala index d100917e..3004ea1f 100644 --- a/src/main/scala/uncore/tilelink2/RegisterRouter.scala +++ b/src/main/scala/uncore/tilelink2/RegisterRouter.scala @@ -79,7 +79,7 @@ object TLRegisterNode // register mapped device from a totally abstract register mapped device. // See GPIO.scala in this directory for an example -abstract class TLRegisterRouterBase(address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean) extends LazyModule +abstract class TLRegisterRouterBase(val address: AddressSet, interrupts: Int, concurrency: Int, beatBytes: Int, undefZero: Boolean, executable: Boolean) extends LazyModule { val node = TLRegisterNode(address, concurrency, beatBytes, undefZero, executable) val intnode = IntSourceNode(interrupts) @@ -100,6 +100,7 @@ class TLRegModule[P, B <: TLRegBundleBase](val params: P, bundleBuilder: => B, r { val io = bundleBuilder val interrupts = if (io.interrupts.isEmpty) Vec(0, Bool()) else io.interrupts(0) + val address = router.address def regmap(mapping: RegField.Map*) = router.node.regmap(mapping:_*) } From 841a31479a15e2603444b97be3c7d23089e8e415 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 21:34:04 -0700 Subject: [PATCH 35/47] coreplex: fix TinyConfig --- src/main/scala/coreplex/BaseCoreplex.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 52482d1f..63cbec7a 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -53,7 +53,7 @@ trait CoreplexNetwork extends HasCoreplexParameters { this: BareCoreplex => val l1tol2 = LazyModule(new TLXbar) - val l1tol2_beatBytes = p(rocketchip.EdgeDataBits)/8 + val l1tol2_beatBytes = p(TLKey("L2toMMIO")).dataBitsPerBeat/8 val l1tol2_lineBytes = p(CacheBlockBytes) val cbus = LazyModule(new TLXbar) From d51b0b5c02f481368d5b18f3fa611267f890025f Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 21:56:11 -0700 Subject: [PATCH 36/47] rocketchip: use self-type --- src/main/scala/coreplex/BaseCoreplex.scala | 13 +++ src/main/scala/rocketchip/BaseTop.scala | 92 +++++++++++----------- 2 files changed, 60 insertions(+), 45 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 63cbec7a..ee00d10f 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -136,6 +136,19 @@ trait CoreplexRISCVModule { val tiles = outer.lazyTiles.map(_.module) val uncoreTileIOs = (tiles zipWithIndex) map { case (tile, i) => Wire(tile.io) } + println("\nGenerated Address Map") + for (entry <- p(rocketchip.GlobalAddrMap).flatten) { + val name = entry.name + val start = entry.region.start + val end = entry.region.start + entry.region.size - 1 + val prot = entry.region.attr.prot + val protStr = (if ((prot & AddrMapProt.R) > 0) "R" else "") + + (if ((prot & AddrMapProt.W) > 0) "W" else "") + + (if ((prot & AddrMapProt.X) > 0) "X" else "") + val cacheable = if (entry.region.attr.cacheable) " [C]" else "" + println(f"\t$name%s $start%x - $end%x, $protStr$cacheable") + } + // Create and export the ConfigString val managers = outer.l1tol2.node.edgesIn(0).manager.managers val configString = rocketchip.GenerateConfigString(p, outer.clint, outer.plic, managers) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index db22bff4..3632faee 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -19,81 +19,83 @@ case object NCoreplexExtClients extends Field[Int] /** Enable or disable monitoring of Diplomatic buses */ case object TLEmitMonitors extends Field[Bool] -/** Base Top with no Periphery */ -abstract class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit q: Parameters) extends LazyModule { - // the following variables will be refactored properly with TL2 +abstract class BareTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit val q: Parameters) extends LazyModule { + // Fill in the TL1 legacy parameters; remove these once rocket/groundtest/unittest are TL2 val pBusMasters = new RangeManager + lazy val legacyAddrMap = GenerateGlobalAddrMap(q, coreplex.l1tol2.node.edgesIn(0).manager.managers) + val coreplex : C = LazyModule(buildCoreplex(q.alterPartial { + case NCoreplexExtClients => pBusMasters.sum + case GlobalAddrMap => legacyAddrMap + })) - TLImp.emitMonitors = q(TLEmitMonitors) + TopModule.contents = Some(this) +} + +abstract class BareTopBundle[+L <: BareTop[BaseCoreplex]](val outer: L) extends Bundle +abstract class BareTopModule[+B <: BareTopBundle[BareTop[BaseCoreplex]]](val io: B) extends LazyModuleImp(io.outer) { + val outer = io.outer.asInstanceOf[io.outer.type] +} + +/** Base Top with no Periphery */ +trait TopNetwork { + this: BareTop[BaseCoreplex] => + implicit val p = q + TLImp.emitMonitors = p(TLEmitMonitors) // Add a SoC and peripheral bus val socBus = LazyModule(new TLXbar) val peripheryBus = LazyModule(new TLXbar) val intBus = LazyModule(new IntXbar) - // Fill in the TL1 legacy parameters - implicit val p = q.alterPartial { - case NCoreplexExtClients => pBusMasters.sum - case GlobalAddrMap => legacyAddrMap - } - - val coreplex : C = LazyModule(buildCoreplex(p)) - - // Create the address map for legacy masters - lazy val legacyAddrMap = GenerateGlobalAddrMap(q, coreplex.l1tol2.node.edgesIn(0).manager.managers) - peripheryBus.node := TLWidthWidget(p(SOCBusKey).beatBytes)( TLAtomicAutomata(arithmetic = p(PeripheryBusKey).arithAMO)( socBus.node)) - - TopModule.contents = Some(this) } -abstract class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](val outer: L) extends Bundle { - implicit val p = outer.p +trait TopNetworkBundle { + this: BareTopBundle[BareTop[BaseCoreplex]] => + implicit val p = outer.q val success = Bool(OUTPUT) } -abstract class BaseTopModule[+B <: BaseTopBundle[BaseTop[BaseCoreplex]]](val io: B) extends LazyModuleImp(io.outer) { - val outer = io.outer.asInstanceOf[io.outer.type] +trait TopNetworkModule { + this: { + val outer: BareTop[BaseCoreplex] with TopNetwork + val io: TopNetworkBundle + } => implicit val p = outer.p - val coreplexMem : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.mem) - val coreplexSlave : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.slave) - val coreplexDebug : DebugBusIO = Wire(outer.coreplex.module.io.debug) - - 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 - val prot = entry.region.attr.prot - val protStr = (if ((prot & AddrMapProt.R) > 0) "R" else "") + - (if ((prot & AddrMapProt.W) > 0) "W" else "") + - (if ((prot & AddrMapProt.X) > 0) "X" else "") - val cacheable = if (entry.region.attr.cacheable) " [C]" else "" - println(f"\t$name%s $start%x - $end%x, $protStr$cacheable") - } + val coreplexMem : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.mem) + val coreplexSlave: Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.slave) + val coreplexDebug: DebugBusIO = Wire(outer.coreplex.module.io.debug) io.success := outer.coreplex.module.io.success } +/** Base Top with no Periphery */ +class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends BareTop(buildCoreplex) + with TopNetwork { + override lazy val module = new BaseTopModule(new BaseTopBundle(this)) +} + +class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](outer: L) extends BareTopBundle(outer) + with TopNetworkBundle + +class BaseTopModule[+B <: BaseTopBundle[BaseTop[BaseCoreplex]]](io: B) extends BareTopModule(io) + with TopNetworkModule + trait DirectConnection { - val coreplex: BaseCoreplex - val socBus: TLXbar - val intBus: IntXbar + this: BareTop[BaseCoreplex] with TopNetwork => socBus.node := coreplex.mmio coreplex.mmioInt := intBus.intnode } trait DirectConnectionModule { - val outer: BaseTop[BaseCoreplex] - - val coreplexMem : Vec[ClientUncachedTileLinkIO] - val coreplexSlave : Vec[ClientUncachedTileLinkIO] - val coreplexDebug : DebugBusIO + this: TopNetworkModule { + val outer: BaseTop[BaseCoreplex] + } => coreplexMem <> outer.coreplex.module.io.mem outer.coreplex.module.io.slave <> coreplexSlave From 5bca13ebdb692a87055b994455dbf726e7519691 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 22:30:13 -0700 Subject: [PATCH 37/47] rocketchip: use self-type constraints --- src/main/scala/rocketchip/BaseTop.scala | 6 +- src/main/scala/rocketchip/Periphery.scala | 165 ++++++++++++---------- 2 files changed, 93 insertions(+), 78 deletions(-) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index 3632faee..a560ad6c 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -37,7 +37,7 @@ abstract class BareTopModule[+B <: BareTopBundle[BareTop[BaseCoreplex]]](val io: } /** Base Top with no Periphery */ -trait TopNetwork { +trait TopNetwork extends HasPeripheryParameters { this: BareTop[BaseCoreplex] => implicit val p = q TLImp.emitMonitors = p(TLEmitMonitors) @@ -53,13 +53,13 @@ trait TopNetwork { socBus.node)) } -trait TopNetworkBundle { +trait TopNetworkBundle extends HasPeripheryParameters { this: BareTopBundle[BareTop[BaseCoreplex]] => implicit val p = outer.q val success = Bool(OUTPUT) } -trait TopNetworkModule { +trait TopNetworkModule extends HasPeripheryParameters { this: { val outer: BareTop[BaseCoreplex] with TopNetwork val io: TopNetworkBundle diff --git a/src/main/scala/rocketchip/Periphery.scala b/src/main/scala/rocketchip/Periphery.scala index 8d3e02bc..0b6783d8 100644 --- a/src/main/scala/rocketchip/Periphery.scala +++ b/src/main/scala/rocketchip/Periphery.scala @@ -83,10 +83,8 @@ trait HasPeripheryParameters { lazy val nMemAXIChannels = if (tMemChannels == BusType.AXI) nMemChannels else 0 lazy val nMemAHBChannels = if (tMemChannels == BusType.AHB) nMemChannels else 0 lazy val nMemTLChannels = if (tMemChannels == BusType.TL) nMemChannels else 0 - lazy val outerMMIOParams = p.alterPartial({ case TLId => "L2toMMIO" }) lazy val edgeSlaveParams = p.alterPartial({ case TLId => "EdgetoSlave" }) lazy val edgeMemParams = p.alterPartial({ case TLId => "MCtoEdge" }) - lazy val edgeMMIOParams = p.alterPartial({ case TLId => "MMIOtoEdge" }) lazy val peripheryBusConfig = p(PeripheryBusKey) lazy val socBusConfig = p(SOCBusKey) lazy val cacheBlockBytes = p(CacheBlockBytes) @@ -94,12 +92,14 @@ trait HasPeripheryParameters { ///// -trait PeripheryDebug extends LazyModule { - implicit val p: Parameters +trait PeripheryDebug { + this: TopNetwork => } trait PeripheryDebugBundle { - implicit val p: Parameters + this: TopNetworkBundle { + val outer: PeripheryDebug + } => val debug_clk = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Clock(INPUT)) val debug_rst = (p(AsyncDebugBus) && !p(IncludeJtagDTM)).option(Bool(INPUT)) val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO()(p).flip) @@ -107,10 +107,10 @@ trait PeripheryDebugBundle { } trait PeripheryDebugModule { - implicit val p: Parameters - val outer: PeripheryDebug - val io: PeripheryDebugBundle - val coreplexDebug: DebugBusIO + this: TopNetworkModule { + val outer: PeripheryDebug + val io: PeripheryDebugBundle + } => if (p(IncludeJtagDTM)) { // JtagDTMWithSync is a wrapper which @@ -127,9 +127,8 @@ trait PeripheryDebugModule { ///// -trait PeripheryExtInterrupts extends LazyModule { - implicit val p: Parameters - val intBus: IntXbar +trait PeripheryExtInterrupts { + this: TopNetwork => val extInterrupts = IntBlindInputNode(p(NExtTopInterrupts)) val extInterruptXing = LazyModule(new IntXing) @@ -139,21 +138,29 @@ trait PeripheryExtInterrupts extends LazyModule { } trait PeripheryExtInterruptsBundle { - val outer: PeripheryExtInterrupts + this: TopNetworkBundle { + val outer: PeripheryExtInterrupts + } => val interrupts = outer.extInterrupts.bundleIn } trait PeripheryExtInterruptsModule { + this: TopNetworkModule { + val outer: PeripheryExtInterrupts + val io: PeripheryExtInterruptsBundle + } => } ///// -trait PeripheryMasterMem extends LazyModule { - implicit val p: Parameters +trait PeripheryMasterMem { + this: TopNetwork => } -trait PeripheryMasterMemBundle extends HasPeripheryParameters { - implicit val p: Parameters +trait PeripheryMasterMemBundle { + this: TopNetworkBundle { + val outer: PeripheryMasterMem + } => val mem_clk = p(AsyncMemChannels).option(Vec(nMemChannels, Clock(INPUT))) val mem_rst = p(AsyncMemChannels).option(Vec(nMemChannels, Bool (INPUT))) val mem_axi = Vec(nMemAXIChannels, new NastiIO) @@ -161,11 +168,11 @@ trait PeripheryMasterMemBundle extends HasPeripheryParameters { val mem_tl = Vec(nMemTLChannels, new ClientUncachedTileLinkIO()(edgeMemParams)) } -trait PeripheryMasterMemModule extends HasPeripheryParameters { - implicit val p: Parameters - val outer: PeripheryMasterMem - val io: PeripheryMasterMemBundle - val coreplexMem: Vec[ClientUncachedTileLinkIO] +trait PeripheryMasterMemModule { + this: TopNetworkModule { + val outer: PeripheryMasterMem + val io: PeripheryMasterMemBundle + } => val edgeMem = coreplexMem.map(TileLinkWidthAdapter(_, edgeMemParams)) @@ -192,9 +199,8 @@ trait PeripheryMasterMemModule extends HasPeripheryParameters { ///// // PeripheryMasterAXI4MMIO is an example, make your own cake pattern like this one. -trait PeripheryMasterAXI4MMIO extends HasPeripheryParameters { - implicit val p: Parameters - val socBus: TLXbar +trait PeripheryMasterAXI4MMIO { + this: TopNetwork => val mmio_axi4 = AXI4BlindOutputNode(AXI4SlavePortParameters( slaves = Seq(AXI4SlaveParameters( @@ -212,40 +218,45 @@ trait PeripheryMasterAXI4MMIO extends HasPeripheryParameters { socBus.node)) } -trait PeripheryMasterAXI4MMIOBundle extends HasPeripheryParameters { - val outer: PeripheryMasterAXI4MMIO +trait PeripheryMasterAXI4MMIOBundle { + this: TopNetworkBundle { + val outer: PeripheryMasterAXI4MMIO + } => val mmio_axi = outer.mmio_axi4.bundleOut } -trait PeripheryMasterAXI4MMIOModule extends HasPeripheryParameters { - implicit val p: Parameters - val outer: PeripheryMasterAXI4MMIO - val io: PeripheryMasterAXI4MMIOBundle - +trait PeripheryMasterAXI4MMIOModule { + this: TopNetworkModule { + val outer: PeripheryMasterAXI4MMIO + val io: PeripheryMasterAXI4MMIOBundle + } => // nothing to do } ///// -trait PeripherySlave extends LazyModule { - implicit val p: Parameters - val pBusMasters: RangeManager +trait PeripherySlave { + this: TopNetwork { + val pBusMasters: RangeManager + } => if (p(NExtBusAXIChannels) > 0) pBusMasters.add("ext", 1) // NExtBusAXIChannels are arbitrated into one TL port } -trait PeripherySlaveBundle extends HasPeripheryParameters { - implicit val p: Parameters +trait PeripherySlaveBundle { + this: TopNetworkBundle { + val outer: PeripherySlave + } => val bus_clk = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Clock(INPUT))) val bus_rst = p(AsyncBusChannels).option(Vec(p(NExtBusAXIChannels), Bool (INPUT))) val bus_axi = Vec(p(NExtBusAXIChannels), new NastiIO).flip } -trait PeripherySlaveModule extends HasPeripheryParameters { - implicit val p: Parameters - val outer: PeripherySlave - val io: PeripherySlaveBundle - val coreplexSlave: Vec[ClientUncachedTileLinkIO] +trait PeripherySlaveModule { + this: TopNetworkModule { + val outer: PeripherySlave { val pBusMasters: RangeManager } + val io: PeripherySlaveBundle + } => if (p(NExtBusAXIChannels) > 0) { val arb = Module(new NastiArbiter(p(NExtBusAXIChannels))) @@ -266,72 +277,76 @@ trait PeripherySlaveModule extends HasPeripheryParameters { ///// -trait PeripheryBootROM extends LazyModule with HasPeripheryParameters { - implicit val p: Parameters - val peripheryBus: TLXbar +trait PeripheryBootROM { + this: TopNetwork => - val address = 0x1000 - val size = 0x1000 - val bootrom = LazyModule(new TLROM(address, size, GenerateBootROM(p, address), true, peripheryBusConfig.beatBytes)) + val bootrom_address = 0x1000 + val bootrom_size = 0x1000 + val bootrom = LazyModule(new TLROM(bootrom_address, bootrom_size, GenerateBootROM(p, bootrom_address), true, peripheryBusConfig.beatBytes)) bootrom.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) } trait PeripheryBootROMBundle { - implicit val p: Parameters + this: TopNetworkBundle { + val outer: PeripheryBootROM + } => } -trait PeripheryBootROMModule extends HasPeripheryParameters { - implicit val p: Parameters - val outer: PeripheryBootROM - val io: PeripheryBootROMBundle +trait PeripheryBootROMModule { + this: TopNetworkModule { + val outer: PeripheryBootROM + val io: PeripheryBootROMBundle + } => } ///// -trait PeripheryTestRAM extends LazyModule with HasPeripheryParameters { - implicit val p: Parameters - val peripheryBus: TLXbar +trait PeripheryTestRAM { + this: TopNetwork => - val ramBase = 0x52000000 - val ramSize = 0x1000 - - val sram = LazyModule(new TLRAM(AddressSet(ramBase, ramSize-1), true, peripheryBusConfig.beatBytes) - { override def name = "testram" }) - sram.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) + val testram = LazyModule(new TLRAM(AddressSet(0x52000000, 0xfff), true, peripheryBusConfig.beatBytes)) + testram.node := TLFragmenter(peripheryBusConfig.beatBytes, cacheBlockBytes)(peripheryBus.node) } trait PeripheryTestRAMBundle { - implicit val p: Parameters + this: TopNetworkBundle { + val outer: PeripheryTestRAM + } => } -trait PeripheryTestRAMModule extends HasPeripheryParameters { - implicit val p: Parameters - val outer: PeripheryTestRAM +trait PeripheryTestRAMModule { + this: TopNetworkModule { + val outer: PeripheryTestRAM + val io: PeripheryTestRAMBundle + } => } ///// -trait PeripheryTestBusMaster extends LazyModule { - implicit val p: Parameters - val peripheryBus: TLXbar - +trait PeripheryTestBusMaster { + this: TopNetwork => val fuzzer = LazyModule(new TLFuzzer(5000)) peripheryBus.node := fuzzer.node } trait PeripheryTestBusMasterBundle { - implicit val p: Parameters + this: TopNetworkBundle { + val outer: PeripheryTestBusMaster + } => } trait PeripheryTestBusMasterModule { - implicit val p: Parameters - val outer: PeripheryTestBusMaster + this: TopNetworkModule { + val outer: PeripheryTestBusMaster + val io: PeripheryTestBusMasterBundle + } => } ///// trait HardwiredResetVector { - val outer: BaseTop[BaseCoreplex] - + this: TopNetworkModule { + val outer: BaseTop[BaseCoreplex] + } => outer.coreplex.module.io.resetVector := UInt(0x1000) // boot ROM } From 688e1bffdf7d1b2bebd0a198cef3bdc6c6759b23 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Fri, 28 Oct 2016 22:37:46 -0700 Subject: [PATCH 38/47] rocketchip: pull rtcTick out of the coreplex --- src/main/scala/coreplex/BaseCoreplex.scala | 5 +++-- src/main/scala/rocketchip/BaseTop.scala | 2 ++ 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index ee00d10f..af6abaf0 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -122,9 +122,10 @@ trait CoreplexRISCVBundle { val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip + val debug = new DebugBusIO().flip + val rtcTick = Bool(INPUT) val resetVector = UInt(INPUT, p(XLen)) val success = Bool(OUTPUT) // used for testing - val debug = new DebugBusIO().flip } trait CoreplexRISCVModule { @@ -215,7 +216,7 @@ trait CoreplexRISCVModule { } outer.debug.module.io.db <> io.debug - outer.clint.module.io.rtcTick := Counter(p(rocketchip.RTCPeriod)).inc() + outer.clint.module.io.rtcTick := io.rtcTick // Coreplex doesn't know when to stop running io.success := Bool(false) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index a560ad6c..a66276bc 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -69,8 +69,10 @@ trait TopNetworkModule extends HasPeripheryParameters { val coreplexMem : Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.mem) val coreplexSlave: Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.slave) val coreplexDebug: DebugBusIO = Wire(outer.coreplex.module.io.debug) + val coreplexRtc : Bool = Wire(outer.coreplex.module.io.rtcTick) io.success := outer.coreplex.module.io.success + coreplexRtc := Counter(p(rocketchip.RTCPeriod)).inc() } /** Base Top with no Periphery */ From 4de182247064c06d5cb66d47629ba81dd5dc013a Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 29 Oct 2016 00:25:58 -0700 Subject: [PATCH 39/47] rocketchip: avoid using the nearly defunct GlobalAddrMap --- src/main/scala/rocketchip/TestHarness.scala | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scala/rocketchip/TestHarness.scala b/src/main/scala/rocketchip/TestHarness.scala index 400e6a93..5d07d1cd 100644 --- a/src/main/scala/rocketchip/TestHarness.scala +++ b/src/main/scala/rocketchip/TestHarness.scala @@ -30,7 +30,7 @@ class TestHarness(q: Parameters) extends Module { int := Bool(false) if (dut.io.mem_axi.nonEmpty) { - val memSize = p(GlobalAddrMap)("mem").size + val memSize = p(ExtMemSize) require(memSize % dut.io.mem_axi.size == 0) for (axi <- dut.io.mem_axi) { val mem = Module(new SimAXIMem(memSize / dut.io.mem_axi.size)) From e97844f71e34b82e3f1d851cd4498c44b3efa43c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 29 Oct 2016 01:19:16 -0700 Subject: [PATCH 40/47] coreplex: make it possible to override the ConfigString --- src/main/scala/coreplex/BaseCoreplex.scala | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index af6abaf0..26e9b447 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -153,8 +153,11 @@ trait CoreplexRISCVModule { // Create and export the ConfigString val managers = outer.l1tol2.node.edgesIn(0).manager.managers val configString = rocketchip.GenerateConfigString(p, outer.clint, outer.plic, managers) - println(s"\nGenerated Configuration String\n${configString}") - ConfigStringOutput.contents = Some(configString) + // Allow something else to have override the config string + if (!ConfigStringOutput.contents.isDefined) { + ConfigStringOutput.contents = Some(configString) + } + println(s"\nGenerated Configuration String\n${ConfigStringOutput.contents.get}") val nCachedPorts = tiles.map(tile => tile.io.cached.size).reduce(_ + _) val nUncachedPorts = tiles.map(tile => tile.io.uncached.size).reduce(_ + _) From d52615c39e6b08ddbe419becdbfebbcf1ac67121 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 29 Oct 2016 01:30:11 -0700 Subject: [PATCH 41/47] coreplex: one IntNode per tile --- src/main/scala/coreplex/BaseCoreplex.scala | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 26e9b447..78f3f997 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -96,7 +96,7 @@ trait CoreplexRISCV { // Build a set of Tiles val lazyTiles = p(BuildTiles) map { _(p) } val legacy = LazyModule(new TLLegacy()(outerMMIOParams)) - val tileIntNode = IntInternalOutputNode() // this should be moved into the Tile... + val tileIntNodes = lazyTiles.map { _ => IntInternalOutputNode() } // this should be moved into the Tile... val debug = LazyModule(new TLDebugModule()) val plic = LazyModule(new TLPLIC(hasSupervisor, maxPriorities = 7)) @@ -112,7 +112,7 @@ trait CoreplexRISCV { clint.node := TLFragmenter(cbus_beatBytes, cbus_lineBytes)(cbus.node) plic.intnode := mmioInt - lazyTiles.foreach { _ => tileIntNode := plic.intnode } + tileIntNodes.foreach { _ := plic.intnode } } trait CoreplexRISCVBundle { @@ -214,8 +214,8 @@ trait CoreplexRISCVModule { tile.hartid := UInt(i) tile.resetVector := io.resetVector tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) - tile.interrupts.meip := outer.tileIntNode.bundleOut(i)(0) - tile.interrupts.seip.foreach(_ := outer.tileIntNode.bundleOut(i)(1)) + tile.interrupts.meip := outer.tileIntNodes(i).bundleOut(0)(0) + tile.interrupts.seip.foreach(_ := outer.tileIntNodes(i).bundleOut(0)(1)) } outer.debug.module.io.db <> io.debug From aabd17d935e72416591a60cf9a8751ceeff20d43 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 29 Oct 2016 03:30:49 -0700 Subject: [PATCH 42/47] rocketchip: must create bundles within Module scope 1. Bundles be created after base class Module constructor runs 2. Bundles must be created before Module(...) runs Solution: pass a bundle constructor to the cake base class Require the constructor to take a parameter so people don't use it by accident; they should get a type error. Consistently name all the cake arguments with an _io, _coreplex, _outer, so that they don't shadow the base class variables you should be using. --- src/main/scala/coreplex/BaseCoreplex.scala | 17 ++++++++++------- src/main/scala/coreplex/Coreplex.scala | 12 ++++++------ src/main/scala/groundtest/Coreplex.scala | 6 +++--- src/main/scala/rocketchip/BaseTop.scala | 22 +++++++++++++--------- src/main/scala/rocketchip/ExampleTop.scala | 16 ++++++++-------- 5 files changed, 40 insertions(+), 33 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 78f3f997..3392b020 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -44,9 +44,12 @@ trait HasCoreplexParameters { case class CoreplexParameters(implicit val p: Parameters) extends HasCoreplexParameters abstract class BareCoreplex(implicit val p: Parameters) extends LazyModule -abstract class BareCoreplexBundle[+L <: BareCoreplex](val outer: L) extends Bundle -abstract class BareCoreplexModule[+B <: BareCoreplexBundle[BareCoreplex]](val io: B) extends LazyModuleImp(io.outer) { - val outer = io.outer.asInstanceOf[io.outer.type] +abstract class BareCoreplexBundle[+L <: BareCoreplex](_outer: L) extends Bundle { + val outer = _outer +} +abstract class BareCoreplexModule[+L <: BareCoreplex, +B <: BareCoreplexBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) { + val outer = _outer + val io = _io () } trait CoreplexNetwork extends HasCoreplexParameters { @@ -86,7 +89,7 @@ trait CoreplexNetworkBundle extends HasCoreplexParameters { } trait CoreplexNetworkModule extends HasCoreplexParameters { - this: BareCoreplexModule[BareCoreplexBundle[BareCoreplex]] => + this: BareCoreplexModule[BareCoreplex, BareCoreplexBundle[BareCoreplex]] => implicit val p = outer.p } @@ -228,13 +231,13 @@ trait CoreplexRISCVModule { class BaseCoreplex(implicit p: Parameters) extends BareCoreplex with CoreplexNetwork with CoreplexRISCV { - override lazy val module = new BaseCoreplexModule(new BaseCoreplexBundle(this)) + override lazy val module = new BaseCoreplexModule(this, () => new BaseCoreplexBundle(this)) } -class BaseCoreplexBundle[+L <: BaseCoreplex](outer: L) extends BareCoreplexBundle(outer) +class BaseCoreplexBundle[+L <: BaseCoreplex](_outer: L) extends BareCoreplexBundle(_outer) with CoreplexNetworkBundle with CoreplexRISCVBundle -class BaseCoreplexModule[+B <: BaseCoreplexBundle[BaseCoreplex]](io: B) extends BareCoreplexModule(io) +class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](_outer: L, _io: () => B) extends BareCoreplexModule(_outer, _io) with CoreplexNetworkModule with CoreplexRISCVModule diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index d5bd9892..4a9e279a 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -34,12 +34,12 @@ trait DirectConnectionModule { class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex with DirectConnection { - override lazy val module = new DefaultCoreplexModule(new DefaultCoreplexBundle(this)) + override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this)) } -class DefaultCoreplexBundle[+L <: DefaultCoreplex](outer: L) extends BaseCoreplexBundle(outer) +class DefaultCoreplexBundle[+L <: DefaultCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) -class DefaultCoreplexModule[+B <: DefaultCoreplexBundle[DefaultCoreplex]](io: B) extends BaseCoreplexModule(io) +class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) with DirectConnectionModule ///// @@ -103,11 +103,11 @@ trait AsyncConnectionModule { class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex with AsyncConnection { - override lazy val module = new MultiClockCoreplexModule(new MultiClockCoreplexBundle(this)) + override lazy val module = new MultiClockCoreplexModule(this, () => new MultiClockCoreplexBundle(this)) } -class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](outer: L) extends BaseCoreplexBundle(outer) +class MultiClockCoreplexBundle[+L <: MultiClockCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) with AsyncConnectionBundle -class MultiClockCoreplexModule[+B <: MultiClockCoreplexBundle[MultiClockCoreplex]](io: B) extends BaseCoreplexModule(io) +class MultiClockCoreplexModule[+L <: MultiClockCoreplex, +B <: MultiClockCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) with AsyncConnectionModule diff --git a/src/main/scala/groundtest/Coreplex.scala b/src/main/scala/groundtest/Coreplex.scala index 04cb2650..738b02f8 100644 --- a/src/main/scala/groundtest/Coreplex.scala +++ b/src/main/scala/groundtest/Coreplex.scala @@ -6,12 +6,12 @@ import coreplex._ class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex with DirectConnection { - override lazy val module = new GroundTestCoreplexModule(new GroundTestCoreplexBundle(this)) + override lazy val module = new GroundTestCoreplexModule(this, () => new GroundTestCoreplexBundle(this)) } -class GroundTestCoreplexBundle[+L <: GroundTestCoreplex](outer: L) extends BaseCoreplexBundle(outer) +class GroundTestCoreplexBundle[+L <: GroundTestCoreplex](_outer: L) extends BaseCoreplexBundle(_outer) -class GroundTestCoreplexModule[+B <: GroundTestCoreplexBundle[GroundTestCoreplex]](io: B) extends BaseCoreplexModule(io) +class GroundTestCoreplexModule[+L <: GroundTestCoreplex, +B <: GroundTestCoreplexBundle[L]](_outer: L, _io: () => B) extends BaseCoreplexModule(_outer, _io) with DirectConnectionModule { io.success := tiles.flatMap(_.io.elements get "success").map(_.asInstanceOf[Bool]).reduce(_&&_) } diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index a66276bc..d17e95e4 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -19,11 +19,11 @@ case object NCoreplexExtClients extends Field[Int] /** Enable or disable monitoring of Diplomatic buses */ case object TLEmitMonitors extends Field[Bool] -abstract class BareTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit val q: Parameters) extends LazyModule { +abstract class BareTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit val q: Parameters) extends LazyModule { // Fill in the TL1 legacy parameters; remove these once rocket/groundtest/unittest are TL2 val pBusMasters = new RangeManager lazy val legacyAddrMap = GenerateGlobalAddrMap(q, coreplex.l1tol2.node.edgesIn(0).manager.managers) - val coreplex : C = LazyModule(buildCoreplex(q.alterPartial { + val coreplex : C = LazyModule(_coreplex(q.alterPartial { case NCoreplexExtClients => pBusMasters.sum case GlobalAddrMap => legacyAddrMap })) @@ -31,9 +31,13 @@ abstract class BareTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(impli TopModule.contents = Some(this) } -abstract class BareTopBundle[+L <: BareTop[BaseCoreplex]](val outer: L) extends Bundle -abstract class BareTopModule[+B <: BareTopBundle[BareTop[BaseCoreplex]]](val io: B) extends LazyModuleImp(io.outer) { - val outer = io.outer.asInstanceOf[io.outer.type] +abstract class BareTopBundle[+L <: BareTop[BaseCoreplex]](_outer: L) extends Bundle { + val outer = _outer +} + +abstract class BareTopModule[+L <: BareTop[BaseCoreplex], +B <: BareTopBundle[L]](_outer: L, _io: () => B) extends LazyModuleImp(_outer) { + val outer = _outer + val io = _io () } /** Base Top with no Periphery */ @@ -76,15 +80,15 @@ trait TopNetworkModule extends HasPeripheryParameters { } /** Base Top with no Periphery */ -class BaseTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends BareTop(buildCoreplex) +class BaseTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends BareTop(_coreplex) with TopNetwork { - override lazy val module = new BaseTopModule(new BaseTopBundle(this)) + override lazy val module = new BaseTopModule(this, () => new BaseTopBundle(this)) } -class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](outer: L) extends BareTopBundle(outer) +class BaseTopBundle[+L <: BaseTop[BaseCoreplex]](_outer: L) extends BareTopBundle(_outer) with TopNetworkBundle -class BaseTopModule[+B <: BaseTopBundle[BaseTop[BaseCoreplex]]](io: B) extends BareTopModule(io) +class BaseTopModule[+L <: BaseTop[BaseCoreplex], +B <: BaseTopBundle[L]](_outer: L, _io: () => B) extends BareTopModule(_outer, _io) with TopNetworkModule trait DirectConnection { diff --git a/src/main/scala/rocketchip/ExampleTop.scala b/src/main/scala/rocketchip/ExampleTop.scala index 847781bf..5b17b242 100644 --- a/src/main/scala/rocketchip/ExampleTop.scala +++ b/src/main/scala/rocketchip/ExampleTop.scala @@ -9,7 +9,7 @@ import coreplex._ import rocketchip._ /** Example Top with Periphery */ -class ExampleTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends BaseTop(buildCoreplex) +class ExampleTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends BaseTop(_coreplex) with PeripheryBootROM with PeripheryDebug with PeripheryExtInterrupts @@ -17,10 +17,10 @@ class ExampleTop[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: with PeripheryMasterAXI4MMIO with PeripherySlave with DirectConnection { - override lazy val module = new ExampleTopModule(new ExampleTopBundle(this)) + override lazy val module = new ExampleTopModule(this, () => new ExampleTopBundle(this)) } -class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](outer: L) extends BaseTopBundle(outer) +class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](_outer: L) extends BaseTopBundle(_outer) with PeripheryBootROMBundle with PeripheryDebugBundle with PeripheryExtInterruptsBundle @@ -28,7 +28,7 @@ class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](outer: L) extends BaseTop with PeripheryMasterAXI4MMIOBundle with PeripherySlaveBundle -class ExampleTopModule[+B <: ExampleTopBundle[ExampleTop[BaseCoreplex]]](io: B) extends BaseTopModule(io) +class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io) with PeripheryBootROMModule with PeripheryDebugModule with PeripheryExtInterruptsModule @@ -39,13 +39,13 @@ class ExampleTopModule[+B <: ExampleTopBundle[ExampleTop[BaseCoreplex]]](io: B) with DirectConnectionModule /** Example Top with TestRAM */ -class ExampleTopWithTestRAM[+C <: BaseCoreplex](buildCoreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(buildCoreplex) +class ExampleTopWithTestRAM[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(_coreplex) with PeripheryTestRAM { - override lazy val module = new ExampleTopWithTestRAMModule(new ExampleTopWithTestRAMBundle(this)) + override lazy val module = new ExampleTopWithTestRAMModule(this, () => new ExampleTopWithTestRAMBundle(this)) } -class ExampleTopWithTestRAMBundle[+L <: ExampleTopWithTestRAM[BaseCoreplex]](outer: L) extends ExampleTopBundle(outer) +class ExampleTopWithTestRAMBundle[+L <: ExampleTopWithTestRAM[BaseCoreplex]](_outer: L) extends ExampleTopBundle(_outer) with PeripheryTestRAMBundle -class ExampleTopWithTestRAMModule[+B <: ExampleTopWithTestRAMBundle[ExampleTopWithTestRAM[BaseCoreplex]]](io: B) extends ExampleTopModule(io) +class ExampleTopWithTestRAMModule[+L <: ExampleTopWithTestRAM[BaseCoreplex], +B <: ExampleTopWithTestRAMBundle[L]](_outer: L, _io: () => B) extends ExampleTopModule(_outer, _io) with PeripheryTestRAMModule From a12fea51e89582e9e06bbb8c24857c22f46aae4c Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 29 Oct 2016 12:39:04 -0700 Subject: [PATCH 43/47] Plic: skip reserved interrupt in interrupt map printout --- src/main/scala/uncore/devices/Plic.scala | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/main/scala/uncore/devices/Plic.scala b/src/main/scala/uncore/devices/Plic.scala index fa442b46..830cd88a 100644 --- a/src/main/scala/uncore/devices/Plic.scala +++ b/src/main/scala/uncore/devices/Plic.scala @@ -87,7 +87,8 @@ class TLPLIC(supervisor: Boolean, maxPriorities: Int, address: BigInt = 0xC00000 println("\nInterrupt map:") flatSources.foreach { s => - println(s" [${s.range.start}, ${s.range.end}) => ${s.name}") + // +1 because 0 is reserved, +1-1 because the range is half-open + println(s" [${s.range.start+1}, ${s.range.end}] => ${s.name}") } val nDevices = interrupts.size From 4a0b29850cf707d9ce4ab39f2bb940df3de33ac2 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 29 Oct 2016 12:39:37 -0700 Subject: [PATCH 44/47] coreplex: reattach clint interrupt --- src/main/scala/coreplex/BaseCoreplex.scala | 1 + 1 file changed, 1 insertion(+) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 3392b020..25d6a83c 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -216,6 +216,7 @@ trait CoreplexRISCVModule { for ((tile, i) <- (uncoreTileIOs zipWithIndex)) { tile.hartid := UInt(i) tile.resetVector := io.resetVector + tile.interrupts := outer.clint.module.io.tiles(i) tile.interrupts.debug := outer.debug.module.io.debugInterrupts(i) tile.interrupts.meip := outer.tileIntNodes(i).bundleOut(0)(0) tile.interrupts.seip.foreach(_ := outer.tileIntNodes(i).bundleOut(0)(1)) From f943c5d6efc87bbda14bb6a1aec6f2ebf1165064 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Sat, 29 Oct 2016 13:13:11 -0700 Subject: [PATCH 45/47] rocketchip: connect rtcTick to coreplex --- src/main/scala/rocketchip/BaseTop.scala | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/main/scala/rocketchip/BaseTop.scala b/src/main/scala/rocketchip/BaseTop.scala index d17e95e4..99a5521e 100644 --- a/src/main/scala/rocketchip/BaseTop.scala +++ b/src/main/scala/rocketchip/BaseTop.scala @@ -76,6 +76,8 @@ trait TopNetworkModule extends HasPeripheryParameters { val coreplexRtc : Bool = Wire(outer.coreplex.module.io.rtcTick) io.success := outer.coreplex.module.io.success + + outer.coreplex.module.io.rtcTick := coreplexRtc coreplexRtc := Counter(p(rocketchip.RTCPeriod)).inc() } From f83d1d0aaf01f490b7c9816e764abb1bc8d47e76 Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 31 Oct 2016 11:40:33 -0700 Subject: [PATCH 46/47] coreplex: rename trait CoreplexRISCVPlatform This makes it clear we are talking about the devices one expects in the platform, not the ISA. --- src/main/scala/coreplex/BaseCoreplex.scala | 18 +++++++++--------- src/main/scala/coreplex/Coreplex.scala | 10 +++++----- 2 files changed, 14 insertions(+), 14 deletions(-) diff --git a/src/main/scala/coreplex/BaseCoreplex.scala b/src/main/scala/coreplex/BaseCoreplex.scala index 25d6a83c..89b0cb99 100644 --- a/src/main/scala/coreplex/BaseCoreplex.scala +++ b/src/main/scala/coreplex/BaseCoreplex.scala @@ -93,7 +93,7 @@ trait CoreplexNetworkModule extends HasCoreplexParameters { implicit val p = outer.p } -trait CoreplexRISCV { +trait CoreplexRISCVPlatform { this: CoreplexNetwork => // Build a set of Tiles @@ -118,9 +118,9 @@ trait CoreplexRISCV { tileIntNodes.foreach { _ := plic.intnode } } -trait CoreplexRISCVBundle { +trait CoreplexRISCVPlatformBundle { this: CoreplexNetworkBundle { - val outer: CoreplexRISCV + val outer: CoreplexRISCVPlatform } => val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams)) @@ -131,10 +131,10 @@ trait CoreplexRISCVBundle { val success = Bool(OUTPUT) // used for testing } -trait CoreplexRISCVModule { +trait CoreplexRISCVPlatformModule { this: CoreplexNetworkModule { - val outer: CoreplexNetwork with CoreplexRISCV - val io: CoreplexRISCVBundle + val outer: CoreplexNetwork with CoreplexRISCVPlatform + val io: CoreplexRISCVPlatformBundle } => val tiles = outer.lazyTiles.map(_.module) @@ -231,14 +231,14 @@ trait CoreplexRISCVModule { class BaseCoreplex(implicit p: Parameters) extends BareCoreplex with CoreplexNetwork - with CoreplexRISCV { + with CoreplexRISCVPlatform { override lazy val module = new BaseCoreplexModule(this, () => new BaseCoreplexBundle(this)) } class BaseCoreplexBundle[+L <: BaseCoreplex](_outer: L) extends BareCoreplexBundle(_outer) with CoreplexNetworkBundle - with CoreplexRISCVBundle + with CoreplexRISCVPlatformBundle class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](_outer: L, _io: () => B) extends BareCoreplexModule(_outer, _io) with CoreplexNetworkModule - with CoreplexRISCVModule + with CoreplexRISCVPlatformModule diff --git a/src/main/scala/coreplex/Coreplex.scala b/src/main/scala/coreplex/Coreplex.scala index 4a9e279a..ad8952d2 100644 --- a/src/main/scala/coreplex/Coreplex.scala +++ b/src/main/scala/coreplex/Coreplex.scala @@ -11,12 +11,12 @@ import util._ import rocket._ trait DirectConnection { - this: CoreplexNetwork with CoreplexRISCV => + this: CoreplexNetwork with CoreplexRISCVPlatform => lazyTiles.map(_.slave).flatten.foreach { scratch => scratch := cbus.node } } trait DirectConnectionModule { - this: CoreplexNetworkModule with CoreplexRISCVModule => + this: CoreplexNetworkModule with CoreplexRISCVPlatformModule => val tlBuffering = TileLinkDepths(1,1,2,2,0) val ultBuffering = UncachedTileLinkDepths(1,2) @@ -45,7 +45,7 @@ class DefaultCoreplexModule[+L <: DefaultCoreplex, +B <: DefaultCoreplexBundle[L ///// trait AsyncConnection { - this: CoreplexNetwork with CoreplexRISCV => + this: CoreplexNetwork with CoreplexRISCVPlatform => val crossings = lazyTiles.map(_.slave).map(_.map { scratch => val crossing = LazyModule(new TLAsyncCrossing) crossing.node := cbus.node @@ -55,7 +55,7 @@ trait AsyncConnection { } trait AsyncConnectionBundle { - this: CoreplexNetworkBundle with CoreplexRISCVBundle => + this: CoreplexNetworkBundle with CoreplexRISCVPlatformBundle => val tcrs = Vec(nTiles, new Bundle { val clock = Clock(INPUT) val reset = Bool(INPUT) @@ -63,7 +63,7 @@ trait AsyncConnectionBundle { } trait AsyncConnectionModule { - this: Module with CoreplexNetworkModule with CoreplexRISCVModule { + this: Module with CoreplexNetworkModule with CoreplexRISCVPlatformModule { val outer: AsyncConnection val io: AsyncConnectionBundle } => From ed4224dde4d899982617dbcc3fd7ccd474f5bf9e Mon Sep 17 00:00:00 2001 From: "Wesley W. Terpstra" Date: Mon, 31 Oct 2016 15:17:10 -0700 Subject: [PATCH 47/47] tilelink2 AtomicAutomata: fix AccessAck on same cycle as PutFull If we send out the PutFull portion of an AMO, the slave is allowed to respond with AccessAck on the same cycle. In this case, we are still in the AMO state, but must still match the D response. --- src/main/scala/uncore/tilelink2/AtomicAutomata.scala | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/main/scala/uncore/tilelink2/AtomicAutomata.scala b/src/main/scala/uncore/tilelink2/AtomicAutomata.scala index 70bacae2..1a471334 100644 --- a/src/main/scala/uncore/tilelink2/AtomicAutomata.scala +++ b/src/main/scala/uncore/tilelink2/AtomicAutomata.scala @@ -94,7 +94,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc val cam_free = cam_s.map(_.state === FREE) val cam_amo = cam_s.map(_.state === AMO) val cam_abusy = cam_s.map(e => e.state === GET || e.state === AMO) // A is blocked - val cam_dmatch = cam_s.map(e => e.state === GET || e.state === ACK) // D should inspect these entries + val cam_dmatch = cam_s.map(e => e.state =/= FREE) // D should inspect these entries // Can the manager already handle this message? val a_size = edgeIn.size(in.a.bits) @@ -211,7 +211,7 @@ class TLAtomicAutomata(logical: Boolean = true, arithmetic: Boolean = true, conc val d_cam_sel_match = (d_cam_sel_raw zip cam_dmatch) map { case (a,b) => a&&b } val d_cam_data = Mux1H(d_cam_sel_match, cam_d.map(_.data)) val d_cam_sel_bypass = if (edgeOut.manager.minLatency > 0) Bool(false) else - out.d.bits.source === in.a.bits.source && in.a.valid && out.d.valid && !a_isSupported + out.d.bits.source === in.a.bits.source && in.a.valid && !a_isSupported val d_cam_sel = (a_cam_sel_free zip d_cam_sel_match) map { case (a,d) => Mux(d_cam_sel_bypass, a, d) } val d_cam_sel_any = d_cam_sel_bypass || d_cam_sel_match.reduce(_ || _) val d_ackd = out.d.bits.opcode === TLMessages.AccessAckData