rocketchip: use TL2 and AXI4 for memory subsytem
This commit is contained in:
parent
9d77e34bee
commit
32fd11935c
@ -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
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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))
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
}
|
}
|
||||||
|
@ -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)
|
||||||
|
@ -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)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/////
|
/////
|
||||||
|
@ -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
|
||||||
|
@ -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):_*)
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user