1
0

rocketchip: use TL2 and AXI4 for memory subsytem

This commit is contained in:
Wesley W. Terpstra 2016-11-03 21:31:26 -07:00
parent 9d77e34bee
commit 32fd11935c
8 changed files with 59 additions and 64 deletions

View File

@ -165,7 +165,6 @@ trait CoreplexRISCVPlatformBundle {
val outer: CoreplexRISCVPlatform val outer: CoreplexRISCVPlatform
} => } =>
val mem = Vec(nMemChannels, new ClientUncachedTileLinkIO()(outerMemParams))
val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip val slave = Vec(nSlaves, new ClientUncachedTileLinkIO()(innerParams)).flip
val debug = new DebugBusIO().flip val debug = new DebugBusIO().flip
val rtcTick = Bool(INPUT) val rtcTick = Bool(INPUT)
@ -220,10 +219,7 @@ trait CoreplexRISCVPlatformModule {
// Cached ports are first in client list, making sharerToClientId just an indentity function // 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) // addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
def sharerToClientId(sharerId: UInt) = sharerId def sharerToClientId(sharerId: UInt) = sharerId
def addrToBank(addr: UInt): UInt = if (nBanks == 0) UInt(0) else { def addrToBank(addr: UInt): UInt = UInt(nBanks)
val isMemory = globalAddrMap.isInRegion("mem", addr << log2Up(p(CacheBlockBytes)))
Mux(isMemory, addr.extract(lsb + log2Ceil(nBanks) - 1, lsb), UInt(nBanks))
}
val l1tol2net = Module(new PortedTileLinkCrossbar(addrToBank, sharerToClientId)) val l1tol2net = Module(new PortedTileLinkCrossbar(addrToBank, sharerToClientId))
// Create point(s) of coherence serialization // Create point(s) of coherence serialization
@ -250,8 +246,6 @@ trait CoreplexRISCVPlatformModule {
val enqueued = TileLinkEnqueuer(bank.outerTL, backendBuffering) val enqueued = TileLinkEnqueuer(bank.outerTL, backendBuffering)
icPort <> TileLinkIOUnwrapper(enqueued) icPort <> TileLinkIOUnwrapper(enqueued)
} }
io.mem <> mem_ic.io.out
} }
// connect coreplex-internal interrupts to tiles // connect coreplex-internal interrupts to tiles
@ -271,16 +265,19 @@ trait CoreplexRISCVPlatformModule {
io.success := Bool(false) io.success := Bool(false)
} }
class BaseCoreplex(implicit p: Parameters) extends BareCoreplex abstract class BaseCoreplex(implicit p: Parameters) extends BareCoreplex
with CoreplexNetwork with CoreplexNetwork
with BankedL2CoherenceManagers
with CoreplexRISCVPlatform { with CoreplexRISCVPlatform {
override lazy val module = new BaseCoreplexModule(this, () => 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 CoreplexNetworkBundle
with BankedL2CoherenceManagersBundle
with CoreplexRISCVPlatformBundle with CoreplexRISCVPlatformBundle
class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](_outer: L, _io: () => B) extends BareCoreplexModule(_outer, _io) class BaseCoreplexModule[+L <: BaseCoreplex, +B <: BaseCoreplexBundle[L]](_outer: L, _io: () => B) extends BareCoreplexModule(_outer, _io)
with CoreplexNetworkModule with CoreplexNetworkModule
with BankedL2CoherenceManagersModule
with CoreplexRISCVPlatformModule with CoreplexRISCVPlatformModule

View File

@ -43,6 +43,7 @@ trait DirectConnectionModule {
} }
class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex class DefaultCoreplex(implicit p: Parameters) extends BaseCoreplex
with BroadcastL2
with DirectConnection { with DirectConnection {
override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this)) override lazy val module = new DefaultCoreplexModule(this, () => new DefaultCoreplexBundle(this))
} }
@ -112,6 +113,7 @@ trait AsyncConnectionModule {
} }
class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex class MultiClockCoreplex(implicit p: Parameters) extends BaseCoreplex
with BroadcastL2
with AsyncConnection { with AsyncConnection {
override lazy val module = new MultiClockCoreplexModule(this, () => new MultiClockCoreplexBundle(this)) override lazy val module = new MultiClockCoreplexModule(this, () => new MultiClockCoreplexBundle(this))
} }

View File

@ -5,6 +5,7 @@ import cde.{Parameters}
import coreplex._ import coreplex._
class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex
with BroadcastL2
with DirectConnection { with DirectConnection {
override lazy val module = new GroundTestCoreplexModule(this, () => new GroundTestCoreplexBundle(this)) override lazy val module = new GroundTestCoreplexModule(this, () => new GroundTestCoreplexBundle(this))
} }

View File

@ -55,6 +55,8 @@ trait TopNetwork extends HasPeripheryParameters {
TLWidthWidget(p(SOCBusKey).beatBytes)( TLWidthWidget(p(SOCBusKey).beatBytes)(
TLAtomicAutomata(arithmetic = p(PeripheryBusKey).arithAMO)( TLAtomicAutomata(arithmetic = p(PeripheryBusKey).arithAMO)(
socBus.node)) socBus.node))
var coreplexMem = Seq[TLOutwardNode]()
} }
trait TopNetworkBundle extends HasPeripheryParameters { trait TopNetworkBundle extends HasPeripheryParameters {
@ -70,7 +72,6 @@ trait TopNetworkModule extends HasPeripheryParameters {
} => } =>
implicit val p = outer.p 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 coreplexSlave: Vec[ClientUncachedTileLinkIO] = Wire(outer.coreplex.module.io.slave)
val coreplexDebug: DebugBusIO = Wire(outer.coreplex.module.io.debug) val coreplexDebug: DebugBusIO = Wire(outer.coreplex.module.io.debug)
val coreplexRtc : Bool = Wire(outer.coreplex.module.io.rtcTick) val coreplexRtc : Bool = Wire(outer.coreplex.module.io.rtcTick)
@ -98,6 +99,8 @@ trait DirectConnection {
socBus.node := coreplex.mmio socBus.node := coreplex.mmio
coreplex.mmioInt := intBus.intnode coreplex.mmioInt := intBus.intnode
coreplexMem = coreplex.mem
} }
trait DirectConnectionModule { trait DirectConnectionModule {
@ -105,7 +108,6 @@ trait DirectConnectionModule {
val outer: BaseTop[BaseCoreplex] val outer: BaseTop[BaseCoreplex]
} => } =>
coreplexMem <> outer.coreplex.module.io.mem
outer.coreplex.module.io.slave <> coreplexSlave outer.coreplex.module.io.slave <> coreplexSlave
outer.coreplex.module.io.debug <> coreplexDebug outer.coreplex.module.io.debug <> coreplexDebug
} }

View File

@ -10,13 +10,13 @@ import rocketchip._
/** Example Top with Periphery */ /** Example Top with Periphery */
class ExampleTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends BaseTop(_coreplex) class ExampleTop[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends BaseTop(_coreplex)
with DirectConnection
with PeripheryBootROM with PeripheryBootROM
with PeripheryDebug with PeripheryDebug
with PeripheryExtInterrupts with PeripheryExtInterrupts
with PeripheryMasterMem with PeripheryMasterAXI4Mem
with PeripheryMasterAXI4MMIO with PeripheryMasterAXI4MMIO
with PeripherySlave with PeripherySlave {
with DirectConnection {
override lazy val module = new ExampleTopModule(this, () => new ExampleTopBundle(this)) override lazy val module = new ExampleTopModule(this, () => new ExampleTopBundle(this))
} }
@ -24,19 +24,19 @@ class ExampleTopBundle[+L <: ExampleTop[BaseCoreplex]](_outer: L) extends BaseTo
with PeripheryBootROMBundle with PeripheryBootROMBundle
with PeripheryDebugBundle with PeripheryDebugBundle
with PeripheryExtInterruptsBundle with PeripheryExtInterruptsBundle
with PeripheryMasterMemBundle with PeripheryMasterAXI4MemBundle
with PeripheryMasterAXI4MMIOBundle with PeripheryMasterAXI4MMIOBundle
with PeripherySlaveBundle with PeripherySlaveBundle
class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io) class ExampleTopModule[+L <: ExampleTop[BaseCoreplex], +B <: ExampleTopBundle[L]](_outer: L, _io: () => B) extends BaseTopModule(_outer, _io)
with DirectConnectionModule
with PeripheryBootROMModule with PeripheryBootROMModule
with PeripheryDebugModule with PeripheryDebugModule
with PeripheryExtInterruptsModule with PeripheryExtInterruptsModule
with PeripheryMasterMemModule with PeripheryMasterAXI4MemModule
with PeripheryMasterAXI4MMIOModule with PeripheryMasterAXI4MMIOModule
with PeripherySlaveModule with PeripherySlaveModule
with HardwiredResetVector with HardwiredResetVector
with DirectConnectionModule
/** Example Top with TestRAM */ /** Example Top with TestRAM */
class ExampleTopWithTestRAM[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(_coreplex) class ExampleTopWithTestRAM[+C <: BaseCoreplex](_coreplex: Parameters => C)(implicit p: Parameters) extends ExampleTop(_coreplex)

View File

@ -3,7 +3,7 @@
package rocketchip package rocketchip
import Chisel._ import Chisel._
import cde.{Parameters, Field} import cde.{Parameters, Field, Dump}
import junctions._ import junctions._
import junctions.NastiConstants._ import junctions.NastiConstants._
import diplomacy._ import diplomacy._
@ -153,47 +153,49 @@ trait PeripheryExtInterruptsModule {
///// /////
trait PeripheryMasterMem { trait PeripheryMasterAXI4Mem {
this: TopNetwork => this: BaseTop[BaseCoreplex] with TopNetwork =>
val base = 0x80000000L
val size = p(ExtMemSize)
val channels = coreplexMem.size
Dump("MEM_BASE", base)
val mem_axi4 = coreplexMem.zipWithIndex.map { case (node, i) =>
val c_size = size/channels
val c_base = base + c_size*i
val axi4 = AXI4BlindOutputNode(AXI4SlavePortParameters(
slaves = Seq(AXI4SlaveParameters(
address = List(AddressSet(c_base, c_size-1)),
executable = true,
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
axi4 :=
// AXI4Fragmenter(lite=false, maxInFlight = 20)( // beef device up to support awlen = 0xff
TLToAXI4(idBits = 4)( // use idBits = 0 for AXI4-Lite
TLWidthWidget(coreplex.l1tol2_beatBytes)( // convert width before attaching to the l1tol2
node))
axi4
}
} }
trait PeripheryMasterMemBundle { trait PeripheryMasterAXI4MemBundle {
this: TopNetworkBundle { this: TopNetworkBundle {
val outer: PeripheryMasterMem val outer: PeripheryMasterAXI4Mem
} => } =>
val mem_clk = p(AsyncMemChannels).option(Vec(nMemChannels, Clock(INPUT))) val mem_axi4 = outer.mem_axi4.map(_.bundleOut).toList.headOption // !!! remove headOption when Seq supported
val mem_rst = p(AsyncMemChannels).option(Vec(nMemChannels, Bool (INPUT)))
val mem_axi = Vec(nMemAXIChannels, new NastiIO)
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
val mem_tl = Vec(nMemTLChannels, new ClientUncachedTileLinkIO()(edgeMemParams))
} }
trait PeripheryMasterMemModule { trait PeripheryMasterAXI4MemModule {
this: TopNetworkModule { this: TopNetworkModule {
val outer: PeripheryMasterMem val outer: PeripheryMasterAXI4Mem
val io: PeripheryMasterMemBundle val io: PeripheryMasterAXI4MemBundle
} => } =>
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) =>
val axi_sync = PeripheryUtils.convertTLtoAXI(mem)
axi_sync.ar.bits.cache := CACHE_NORMAL_NOCACHE_BUF
axi_sync.aw.bits.cache := CACHE_NORMAL_NOCACHE_BUF
axi <> (
if (!p(AsyncMemChannels)) axi_sync
else AsyncNastiTo(io.mem_clk.get(idx), io.mem_rst.get(idx), axi_sync)
)
}
(io.mem_ahb zip edgeMem) foreach { case (ahb, mem) =>
ahb <> PeripheryUtils.convertTLtoAHB(mem, atomics = false)
}
(io.mem_tl zip edgeMem) foreach { case (tl, mem) =>
tl <> TileLinkEnqueuer(mem, 2)
}
} }
///// /////

View File

@ -19,21 +19,17 @@ class TestHarness(q: Parameters) extends Module {
implicit val p = dut.p implicit val p = dut.p
// This test harness isn't especially flexible yet // This test harness isn't especially flexible yet
require(dut.io.mem_clk.isEmpty)
require(dut.io.mem_rst.isEmpty)
require(dut.io.mem_ahb.isEmpty)
require(dut.io.mem_tl.isEmpty)
require(dut.io.bus_clk.isEmpty) require(dut.io.bus_clk.isEmpty)
require(dut.io.bus_rst.isEmpty) require(dut.io.bus_rst.isEmpty)
for (int <- dut.io.interrupts(0)) for (int <- dut.io.interrupts(0))
int := Bool(false) int := Bool(false)
if (dut.io.mem_axi.nonEmpty) { if (dut.io.mem_axi4.nonEmpty) {
val memSize = p(ExtMemSize) val memSize = p(ExtMemSize)
require(memSize % dut.io.mem_axi.size == 0) require(memSize % dut.io.mem_axi4.size == 0)
for (axi <- dut.io.mem_axi) { for (axi <- dut.io.mem_axi4.map(_(0))) {
val mem = Module(new SimAXIMem(memSize / dut.io.mem_axi.size)) val mem = Module(new SimAXIMem(memSize / dut.io.mem_axi4.size))
mem.io.axi.ar <> axi.ar mem.io.axi.ar <> axi.ar
mem.io.axi.aw <> axi.aw mem.io.axi.aw <> axi.aw
mem.io.axi.w <> axi.w mem.io.axi.w <> axi.w

View File

@ -77,13 +77,8 @@ object GenerateGlobalAddrMap {
case (e, i) => if (i == 0) e else e.copy(name = e.name + "_" + i) case (e, i) => if (i == 0) e else e.copy(name = e.name + "_" + i)
}).flatten.toList }).flatten.toList
val memBase = 0x80000000L
val memSize = p(ExtMemSize)
Dump("MEM_BASE", memBase)
val tl2 = AddrMapEntry("TL2", new AddrMap(uniquelyNamedTL2Devices, collapse = true)) val tl2 = AddrMapEntry("TL2", new AddrMap(uniquelyNamedTL2Devices, collapse = true))
val mem = AddrMapEntry("mem", MemRange(memBase, memSize, MemAttr(AddrMapProt.RWX, true))) AddrMap(tl2)
AddrMap((tl2 +: (p(NMemoryChannels) > 0).option(mem).toSeq):_*)
} }
} }