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

View File

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

View File

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

View File

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

View File

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

View File

@ -3,7 +3,7 @@
package rocketchip
import Chisel._
import cde.{Parameters, Field}
import cde.{Parameters, Field, Dump}
import junctions._
import junctions.NastiConstants._
import diplomacy._
@ -153,47 +153,49 @@ trait PeripheryExtInterruptsModule {
/////
trait PeripheryMasterMem {
this: TopNetwork =>
trait PeripheryMasterAXI4Mem {
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 {
val outer: PeripheryMasterMem
val outer: PeripheryMasterAXI4Mem
} =>
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)
val mem_ahb = Vec(nMemAHBChannels, new HastiMasterIO)
val mem_tl = Vec(nMemTLChannels, new ClientUncachedTileLinkIO()(edgeMemParams))
val mem_axi4 = outer.mem_axi4.map(_.bundleOut).toList.headOption // !!! remove headOption when Seq supported
}
trait PeripheryMasterMemModule {
trait PeripheryMasterAXI4MemModule {
this: TopNetworkModule {
val outer: PeripheryMasterMem
val io: PeripheryMasterMemBundle
val outer: PeripheryMasterAXI4Mem
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
// 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_rst.isEmpty)
for (int <- dut.io.interrupts(0))
int := Bool(false)
if (dut.io.mem_axi.nonEmpty) {
if (dut.io.mem_axi4.nonEmpty) {
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))
require(memSize % dut.io.mem_axi4.size == 0)
for (axi <- dut.io.mem_axi4.map(_(0))) {
val mem = Module(new SimAXIMem(memSize / dut.io.mem_axi4.size))
mem.io.axi.ar <> axi.ar
mem.io.axi.aw <> axi.aw
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)
}).flatten.toList
val memBase = 0x80000000L
val memSize = p(ExtMemSize)
Dump("MEM_BASE", memBase)
val tl2 = AddrMapEntry("TL2", new AddrMap(uniquelyNamedTL2Devices, collapse = true))
val mem = AddrMapEntry("mem", MemRange(memBase, memSize, MemAttr(AddrMapProt.RWX, true)))
AddrMap((tl2 +: (p(NMemoryChannels) > 0).option(mem).toSeq):_*)
AddrMap(tl2)
}
}