1
0

Merge remote-tracking branch 'origin/master' into bump-submodules

This commit is contained in:
Henry Cook 2016-11-28 13:49:59 -08:00
commit 86065e5fb8
33 changed files with 416 additions and 289 deletions

View File

@ -35,6 +35,7 @@ env:
matrix: matrix:
- SUITE=RocketSuiteA - SUITE=RocketSuiteA
- SUITE=RocketSuiteB - SUITE=RocketSuiteB
- SUITE=RocketSuiteC
- SUITE=GroundtestSuiteA - SUITE=GroundtestSuiteA
- SUITE=GroundtestSuiteB - SUITE=GroundtestSuiteB
- SUITE=UnittestSuite - SUITE=UnittestSuite

View File

@ -43,24 +43,28 @@ endif
ifeq ($(SUITE),RocketSuiteA) ifeq ($(SUITE),RocketSuiteA)
PROJECT=rocketchip PROJECT=rocketchip
CONFIGS=DefaultConfig DefaultBufferlessConfig CONFIGS=DefaultConfig
endif endif
ifeq ($(SUITE),RocketSuiteB) ifeq ($(SUITE),RocketSuiteB)
PROJECT=rocketchip PROJECT=rocketchip
CONFIGS=DefaultBufferlessConfig
endif
ifeq ($(SUITE),RocketSuiteC)
PROJECT=rocketchip
CONFIGS=DefaultL2Config TinyConfig CONFIGS=DefaultL2Config TinyConfig
endif endif
ifeq ($(SUITE),GroundtestSuiteA) ifeq ($(SUITE),GroundtestSuiteA)
PROJECT=groundtest PROJECT=groundtest
CONFIGS=MemtestConfig MemtestBufferlessConfig MemtestStatelessConfig FancyMemtestConfig \ CONFIGS=MemtestConfig MemtestBufferlessConfig MemtestStatelessConfig FancyMemtestConfig
BroadcastRegressionTestConfig BufferlessRegressionTestConfig
endif endif
ifeq ($(SUITE),GroundtestSuiteB) ifeq ($(SUITE),GroundtestSuiteB)
PROJECT=groundtest PROJECT=groundtest
CONFIGS=CacheRegressionTestConfig \ CONFIGS=BroadcastRegressionTestConfig BufferlessRegressionTestConfig CacheRegressionTestConfig \
ComparatorConfig ComparatorBufferlessConfig ComparatorL2Config ComparatorStatelessConfig ComparatorConfig ComparatorBufferlessConfig ComparatorStatelessConfig
endif endif
ifeq ($(SUITE),UnittestSuite) ifeq ($(SUITE),UnittestSuite)

View File

@ -52,6 +52,8 @@ def main():
numFinished = numFinished + 1 numFinished = numFinished + 1
if numFinished == total: if numFinished == total:
break break
elif line[0:12] == "using random":
continue
else: else:
print line, print line,

View File

@ -11,6 +11,7 @@ import uncore.coherence._
import uncore.agents._ import uncore.agents._
import uncore.devices._ import uncore.devices._
import uncore.converters._ import uncore.converters._
import uncore.util._
import rocket._ import rocket._
import util._ import util._
import util.ConfigUtils._ import util.ConfigUtils._
@ -108,7 +109,7 @@ class BaseCoreplexConfig extends Config (
case BroadcastConfig => BroadcastConfig() case BroadcastConfig => BroadcastConfig()
case BankedL2Config => BankedL2Config() case BankedL2Config => BankedL2Config()
case CacheBlockBytes => 64 case CacheBlockBytes => 64
case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes)) case CacheBlockOffsetBits => log2Up(site(CacheBlockBytes))
case EnableL2Logging => false case EnableL2Logging => false
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
} }
@ -123,39 +124,39 @@ class WithNCores(n: Int) extends Config(
class WithNBanksPerMemChannel(n: Int) extends Config( class WithNBanksPerMemChannel(n: Int) extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case BankedL2Config => up(BankedL2Config).copy(nBanksPerChannel = n) case BankedL2Config => up(BankedL2Config, site).copy(nBanksPerChannel = n)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
class WithNTrackersPerBank(n: Int) extends Config( class WithNTrackersPerBank(n: Int) extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case BroadcastConfig => up(BroadcastConfig).copy(nTrackers = n) case BroadcastConfig => up(BroadcastConfig, site).copy(nTrackers = n)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
// This is the number of sets **per way** // This is the number of sets **per way**
class WithL1ICacheSets(sets: Int) extends Config( class WithL1ICacheSets(sets: Int) extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case CacheName("L1I") => up(CacheName("L1I")).copy(nSets = sets) case CacheName("L1I") => up(CacheName("L1I"), site).copy(nSets = sets)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
// This is the number of sets **per way** // This is the number of sets **per way**
class WithL1DCacheSets(sets: Int) extends Config( class WithL1DCacheSets(sets: Int) extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = sets) case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = sets)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
class WithL1ICacheWays(ways: Int) extends Config( class WithL1ICacheWays(ways: Int) extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case CacheName("L1I") => up(CacheName("L1I")).copy(nWays = ways) case CacheName("L1I") => up(CacheName("L1I"), site).copy(nWays = ways)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
class WithL1DCacheWays(ways: Int) extends Config( class WithL1DCacheWays(ways: Int) extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case CacheName("L1D") => up(CacheName("L1D")).copy(nWays = ways) case CacheName("L1D") => up(CacheName("L1D"), site).copy(nWays = ways)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
@ -168,7 +169,7 @@ class WithCacheBlockBytes(linesize: Int) extends Config(
class WithDataScratchpad(n: Int) extends Config( class WithDataScratchpad(n: Int) extends Config(
(pname,site,here,up) => pname match { (pname,site,here,up) => pname match {
case DataScratchpadSize => n case DataScratchpadSize => n
case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = n / site(CacheBlockBytes)) case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = n / site(CacheBlockBytes))
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
@ -187,7 +188,7 @@ class WithL2Cache extends Config(
class WithBufferlessBroadcastHub extends Config( class WithBufferlessBroadcastHub extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case BroadcastConfig => up(BroadcastConfig).copy(bufferless = true) case BroadcastConfig => up(BroadcastConfig, site).copy(bufferless = true)
}) })
/** /**
@ -205,12 +206,12 @@ class WithBufferlessBroadcastHub extends Config(
class WithStatelessBridge extends Config( class WithStatelessBridge extends Config(
(pname,site,here,up) => pname match { (pname,site,here,up) => pname match {
/* !!! FIXME /* !!! FIXME
case BankedL2Config => up(BankedL2Config).copy(coherenceManager = { case (_, _) => case BankedL2Config => up(BankedL2Config, site).copy(coherenceManager = { case (_, _) =>
val pass = LazyModule(new TLBuffer(0)) val pass = LazyModule(new TLBuffer(0))
(pass.node, pass.node) (pass.node, pass.node)
}) })
*/ */
case DCacheKey => up(DCacheKey).copy(nMSHRs = 0) case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
@ -226,7 +227,7 @@ class WithL2Capacity(size_kb: Int) extends Config(
class WithNL2Ways(n: Int) extends Config( class WithNL2Ways(n: Int) extends Config(
(pname,site,here,up) => pname match { (pname,site,here,up) => pname match {
case CacheName("L2") => up(CacheName("L2")).copy(nWays = n) case CacheName("L2") => up(CacheName("L2"), site).copy(nWays = n)
}) })
class WithRV32 extends Config( class WithRV32 extends Config(
@ -238,7 +239,7 @@ class WithRV32 extends Config(
class WithBlockingL1 extends Config( class WithBlockingL1 extends Config(
(pname,site,here,up) => pname match { (pname,site,here,up) => pname match {
case DCacheKey => up(DCacheKey).copy(nMSHRs = 0) case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
@ -249,9 +250,9 @@ class WithSmallCores extends Config(
case UseVM => false case UseVM => false
case BtbKey => BtbParameters(nEntries = 0) case BtbKey => BtbParameters(nEntries = 0)
case NAcquireTransactors => 2 case NAcquireTransactors => 2
case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = 64, nWays = 1, nTLBEntries = 4) case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = 64, nWays = 1, nTLBEntries = 4)
case CacheName("L1I") => up(CacheName("L1I")).copy(nSets = 64, nWays = 1, nTLBEntries = 4) case CacheName("L1I") => up(CacheName("L1I"), site).copy(nSets = 64, nWays = 1, nTLBEntries = 4)
case DCacheKey => up(DCacheKey).copy(nMSHRs = 0) case DCacheKey => up(DCacheKey, site).copy(nMSHRs = 0)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })

View File

@ -29,7 +29,9 @@ trait CoreplexRISCVPlatform extends CoreplexNetwork {
lazy val configString = { lazy val configString = {
val managers = l1tol2.node.edgesIn(0).manager.managers val managers = l1tol2.node.edgesIn(0).manager.managers
rocketchip.GenerateConfigString(p, clint, plic, managers) // Use the existing config string if the user overrode it
ConfigStringOutput.contents.getOrElse(
rocketchip.GenerateConfigString(p, clint, plic, managers))
} }
} }

View File

@ -57,7 +57,7 @@ class AsyncRocketTile(tileId: Int)(implicit p: Parameters) extends LazyModule {
val uncached = uncachedOut.bundleOut val uncached = uncachedOut.bundleOut
val slave = slaveNode.map(_.bundleIn) val slave = slaveNode.map(_.bundleIn)
val hartid = UInt(INPUT, p(XLen)) val hartid = UInt(INPUT, p(XLen))
val interrupts = new TileInterrupts().asInput val interrupts = new TileInterrupts()(rocket.coreParams).asInput
val resetVector = UInt(INPUT, p(XLen)) val resetVector = UInt(INPUT, p(XLen))
} }
rocket.module.io.interrupts := ShiftRegister(io.interrupts, 3) rocket.module.io.interrupts := ShiftRegister(io.interrupts, 3)

View File

@ -3,7 +3,7 @@ package groundtest
import Chisel._ import Chisel._
import uncore.tilelink._ import uncore.tilelink._
import uncore.constants._ import uncore.constants._
import uncore.agents._ import uncore.util._
import util._ import util._
import config._ import config._

View File

@ -6,6 +6,7 @@ import diplomacy._
import uncore.tilelink._ import uncore.tilelink._
import uncore.coherence._ import uncore.coherence._
import uncore.agents._ import uncore.agents._
import uncore.util._
import uncore.devices.NTiles import uncore.devices.NTiles
import junctions._ import junctions._
import config._ import config._
@ -122,7 +123,7 @@ class WithAtomics extends Config(
class WithPrefetches extends Config( class WithPrefetches extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case ComparatorKey => up(ComparatorKey).copy(prefetches = true) case ComparatorKey => up(ComparatorKey, site).copy(prefetches = true)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
@ -201,6 +202,6 @@ class WithTraceGen extends Config(
}.flatten }.flatten
} }
case UseAtomics => true case UseAtomics => true
case CacheName("L1D") => up(CacheName("L1D")).copy(nSets = 16, nWays = 1) case CacheName("L1D") => up(CacheName("L1D"), site).copy(nSets = 16, nWays = 1)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })

View File

@ -6,9 +6,10 @@ import diplomacy._
import coreplex._ import coreplex._
import uncore.devices.NTiles import uncore.devices.NTiles
import uncore.tilelink2._ import uncore.tilelink2._
import rocket.TileId
import uncore.tilelink.TLId import uncore.tilelink.TLId
case object TileId extends Field[Int]
class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex { class GroundTestCoreplex(implicit p: Parameters) extends BaseCoreplex {
val tiles = List.tabulate(p(NTiles)) { i => val tiles = List.tabulate(p(NTiles)) { i =>
LazyModule(new GroundTestTile()(p.alterPartial({ LazyModule(new GroundTestTile()(p.alterPartial({

View File

@ -3,7 +3,7 @@ package groundtest
import Chisel._ import Chisel._
import uncore.tilelink._ import uncore.tilelink._
import uncore.constants._ import uncore.constants._
import uncore.agents._ import uncore.util._
import util._ import util._
import rocket._ import rocket._
import rocketchip._ import rocketchip._

View File

@ -3,7 +3,7 @@ package groundtest
import Chisel._ import Chisel._
import rocket._ import rocket._
import uncore.tilelink._ import uncore.tilelink._
import uncore.agents.CacheName import uncore.util.CacheName
import uncore.tilelink2._ import uncore.tilelink2._
import rocketchip.ExtMem import rocketchip.ExtMem
import diplomacy._ import diplomacy._

View File

@ -5,7 +5,6 @@ package rocket
import Chisel._ import Chisel._
import Chisel.ImplicitConversions._ import Chisel.ImplicitConversions._
import diplomacy._ import diplomacy._
import uncore.agents._
import uncore.constants._ import uncore.constants._
import uncore.tilelink2._ import uncore.tilelink2._
import uncore.util._ import uncore.util._
@ -252,7 +251,7 @@ class DCacheModule(outer: DCache)(implicit p: Parameters) extends HellaCacheModu
val a_source = PriorityEncoder(~uncachedInFlight.asUInt) val a_source = PriorityEncoder(~uncachedInFlight.asUInt)
val acquire_address = s2_req_block_addr val acquire_address = s2_req_block_addr
val access_address = s2_req.addr val access_address = s2_req.addr
val a_size = s2_req.typ val a_size = s2_req.typ(MT_SZ-2, 0)
val a_data = Fill(beatWords, pstore1_storegen.data) val a_data = Fill(beatWords, pstore1_storegen.data)
val acquire = if (edge.manager.anySupportAcquire) { val acquire = if (edge.manager.anySupportAcquire) {
edge.Acquire(a_source, acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb edge.Acquire(a_source, acquire_address, lgCacheBlockBytes, s2_grow_param)._2 // Cacheability checked by tlb

View File

@ -6,7 +6,7 @@ import Chisel._
import config.{Parameters, Field} import config.{Parameters, Field}
import diplomacy._ import diplomacy._
import uncore.tilelink2._ import uncore.tilelink2._
import uncore.agents._ import uncore.util._
import uncore.constants._ import uncore.constants._
import uncore.tilelink.{TLKey, TLId} import uncore.tilelink.{TLKey, TLId}
import util.ParameterizedBundle import util.ParameterizedBundle

View File

@ -5,7 +5,6 @@ package rocket
import Chisel._ import Chisel._
import Chisel.ImplicitConversions._ import Chisel.ImplicitConversions._
import diplomacy._ import diplomacy._
import uncore.agents._
import uncore.constants._ import uncore.constants._
import uncore.tilelink._ import uncore.tilelink._
import uncore.tilelink2._ import uncore.tilelink2._
@ -176,15 +175,18 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters)
val req_tag = req.addr >> untagBits val req_tag = req.addr >> untagBits
val req_block_addr = (req.addr >> blockOffBits) << blockOffBits val req_block_addr = (req.addr >> blockOffBits) << blockOffBits
val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits) val idx_match = req_idx === io.req_bits.addr(untagBits-1,blockOffBits)
val new_coh = Reg(init=ClientMetadata.onReset)
val (_, shrink_param, coh_on_clear) = req.old_meta.coh.onCacheControl(M_FLUSH)
val grow_param = new_coh.onAccess(req.cmd)._2
val coh_on_grant = new_coh.onGrant(req.cmd, io.mem_grant.bits.param)
// We only accept secondary misses if we haven't yet sent an Acquire to outer memory // We only accept secondary misses if we haven't yet sent an Acquire to outer memory
// or if the Acquire that was sent will obtain a Grant with sufficient permissions // or if the Acquire that was sent will obtain a Grant with sufficient permissions
// to let us replay this new request. I.e. we don't handle multiple outstanding // to let us replay this new request. I.e. we don't handle multiple outstanding
// Acquires on the same block for now. // Acquires on the same block for now.
val cmd_requires_second_acquire = val (cmd_requires_second_acquire, is_hit_again, _, dirtier_coh, dirtier_cmd) =
req.old_meta.coh.requiresAcquireOnSecondaryMiss(req.cmd, io.req_bits.cmd) new_coh.onSecondaryAccess(req.cmd, io.req_bits.cmd)
// Track whether or not a secondary acquire will cause the coherence state
// to go from clean to dirty.
val dirties_coh = Reg(Bool())
val states_before_refill = Seq(s_wb_req, s_wb_resp, s_meta_clear) val states_before_refill = Seq(s_wb_req, s_wb_resp, s_meta_clear)
val (_, _, refill_done, refill_address_inc) = edge.addr_inc(io.mem_grant) val (_, _, refill_done, refill_address_inc) = edge.addr_inc(io.mem_grant)
val sec_rdy = idx_match && val sec_rdy = idx_match &&
@ -197,19 +199,6 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters)
rpq.io.enq.bits := io.req_bits rpq.io.enq.bits := io.req_bits
rpq.io.deq.ready := (io.replay.ready && state === s_drain_rpq) || state === s_invalid rpq.io.deq.ready := (io.replay.ready && state === s_drain_rpq) || state === s_invalid
// TODO clean all this coh state business up
val new_coh_state = Reg(init=ClientMetadata.onReset)
val grow_param = Reg(init=UInt(0))
val coh_on_grant = Mux(dirties_coh,
ClientMetadata.maximum,
req.old_meta.coh.onGrant(req.cmd, io.mem_grant.bits.param))
val (is_hit, missed_param, coh_on_hit) = io.req_bits.old_meta.coh.onAccess(io.req_bits.cmd)
val (needs_wb, _, _) = io.req_bits.old_meta.coh.onCacheControl(M_FLUSH)
val (_, shrink_param, _) = req.old_meta.coh.onCacheControl(M_FLUSH)
val (hit_again, missed_again_param, _) = req.old_meta.coh.onCacheControl(io.req_bits.cmd)
val (_, _, clear_coh_state) = req.old_meta.coh.onCacheControl(M_FLUSH)
val (_, after_wb_param, _) = ClientMetadata.onReset.onAccess(req.cmd)
when (state === s_drain_rpq && !rpq.io.deq.valid) { when (state === s_drain_rpq && !rpq.io.deq.valid) {
state := s_invalid state := s_invalid
} }
@ -221,14 +210,13 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters)
state := s_meta_write_resp state := s_meta_write_resp
} }
when (state === s_refill_resp && refill_done) { when (state === s_refill_resp && refill_done) {
new_coh := coh_on_grant
state := s_meta_write_req state := s_meta_write_req
new_coh_state := coh_on_grant
} }
when (io.mem_acquire.fire()) { // s_refill_req when (io.mem_acquire.fire()) { // s_refill_req
state := s_refill_resp state := s_refill_resp
} }
when (state === s_meta_clear && io.meta_write.ready) { when (state === s_meta_clear && io.meta_write.ready) {
grow_param := after_wb_param
state := s_refill_req state := s_refill_req
} }
when (state === s_wb_resp && io.mem_grant.valid) { when (state === s_wb_resp && io.mem_grant.valid) {
@ -241,24 +229,26 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters)
//If we get a secondary miss that needs more permissions before we've sent //If we get a secondary miss that needs more permissions before we've sent
// out the primary miss's Acquire, we can upgrade the permissions we're // out the primary miss's Acquire, we can upgrade the permissions we're
// going to ask for in s_refill_req // going to ask for in s_refill_req
when(cmd_requires_second_acquire) { req.cmd := dirtier_cmd
req.cmd := io.req_bits.cmd when (is_hit_again) {
when(!hit_again) { grow_param := missed_again_param } new_coh := dirtier_coh
} }
dirties_coh := dirties_coh || isWrite(io.req_bits.cmd)
} }
when (io.req_pri_val && io.req_pri_rdy) { when (io.req_pri_val && io.req_pri_rdy) {
req := io.req_bits req := io.req_bits
dirties_coh := isWrite(io.req_bits.cmd) val old_coh = io.req_bits.old_meta.coh
val needs_wb = old_coh.onCacheControl(M_FLUSH)._1
val (is_hit, _, coh_on_hit) = old_coh.onAccess(io.req_bits.cmd)
when (io.req_bits.tag_match) { when (io.req_bits.tag_match) {
when (is_hit) { // set dirty bit when (is_hit) { // set dirty bit
new_coh := coh_on_hit
state := s_meta_write_req state := s_meta_write_req
new_coh_state := coh_on_hit
}.otherwise { // upgrade permissions }.otherwise { // upgrade permissions
new_coh := old_coh
state := s_refill_req state := s_refill_req
grow_param := missed_param
} }
}.otherwise { // writback if necessary and refill }.otherwise { // writback if necessary and refill
new_coh := ClientMetadata.onReset
state := Mux(needs_wb, s_wb_req, s_meta_clear) state := Mux(needs_wb, s_wb_req, s_meta_clear)
} }
} }
@ -285,7 +275,7 @@ class MSHR(id: Int, edge: TLEdgeOut)(implicit cfg: DCacheConfig, p: Parameters)
io.meta_write.valid := state.isOneOf(s_meta_write_req, s_meta_clear) io.meta_write.valid := state.isOneOf(s_meta_write_req, s_meta_clear)
io.meta_write.bits.idx := req_idx io.meta_write.bits.idx := req_idx
io.meta_write.bits.data.coh := Mux(state === s_meta_clear, clear_coh_state, new_coh_state) io.meta_write.bits.data.coh := Mux(state === s_meta_clear, coh_on_clear, new_coh)
io.meta_write.bits.data.tag := io.tag io.meta_write.bits.data.tag := io.tag
io.meta_write.bits.way_en := req.way_en io.meta_write.bits.way_en := req.way_en

View File

@ -6,7 +6,7 @@ import Chisel._
import config._ import config._
import util._ import util._
import Chisel.ImplicitConversions._ import Chisel.ImplicitConversions._
import uncore.agents.PseudoLRU import uncore.util.PseudoLRU
case object BtbKey extends Field[BtbParameters] case object BtbKey extends Field[BtbParameters]

View File

@ -3,7 +3,7 @@
package rocket package rocket
import Chisel._ import Chisel._
import uncore.agents._ import uncore.util.PseudoLRU
import uncore.constants._ import uncore.constants._
import util._ import util._
import Chisel.ImplicitConversions._ import Chisel.ImplicitConversions._

View File

@ -5,7 +5,7 @@ package rocket
import Chisel._ import Chisel._
import uncore.tilelink._ import uncore.tilelink._
import uncore.constants._ import uncore.constants._
import uncore.agents.CacheName import uncore.util.CacheName
import util._ import util._
import Chisel.ImplicitConversions._ import Chisel.ImplicitConversions._
import config._ import config._

View File

@ -4,7 +4,7 @@ package rocket
import Chisel._ import Chisel._
import uncore.devices._ import uncore.devices._
import uncore.agents.CacheName import uncore.util.CacheName
import uncore.constants._ import uncore.constants._
import uncore.tilelink2._ import uncore.tilelink2._
import util._ import util._

View File

@ -6,7 +6,7 @@ import Chisel._
import diplomacy._ import diplomacy._
import uncore.tilelink._ import uncore.tilelink._
import uncore.tilelink2._ import uncore.tilelink2._
import uncore.agents._ import uncore.util.{CacheName, CacheBlockBytes}
import uncore.converters._ import uncore.converters._
import uncore.devices._ import uncore.devices._
import util._ import util._
@ -14,7 +14,6 @@ import config._
import scala.collection.mutable.ListBuffer import scala.collection.mutable.ListBuffer
case object BuildRoCC extends Field[Seq[RoccParameters]] case object BuildRoCC extends Field[Seq[RoccParameters]]
case object TileId extends Field[Int]
case class RoccParameters( case class RoccParameters(
opcodes: OpcodeSet, opcodes: OpcodeSet,
@ -30,7 +29,6 @@ class RocketTile(tileId: Int)(implicit p: Parameters) extends LazyModule {
val dcacheParams = coreParams.alterPartial({ val dcacheParams = coreParams.alterPartial({
case CacheName => CacheName("L1D") case CacheName => CacheName("L1D")
case TLId => "L1toL2" case TLId => "L1toL2"
case TileId => tileId // TODO using this messes with Heirarchical P&R: change to io.hartid?
}) })
val icacheParams = coreParams.alterPartial({ val icacheParams = coreParams.alterPartial({
case CacheName => CacheName("L1I") case CacheName => CacheName("L1I")

View File

@ -8,8 +8,7 @@ import Chisel.ImplicitConversions._
import scala.math._ import scala.math._
import config._ import config._
import diplomacy._ import diplomacy._
import uncore.agents._ import uncore.util._
import uncore.coherence._
import uncore.tilelink2._ import uncore.tilelink2._
case object PgLevels extends Field[Int] case object PgLevels extends Field[Int]
@ -66,8 +65,10 @@ class TLB(implicit val p: Parameters) extends Module with HasTLBParameters {
val refill_ppn = io.ptw.resp.bits.pte.ppn(ppnBits-1, 0) val refill_ppn = io.ptw.resp.bits.pte.ppn(ppnBits-1, 0)
val do_refill = Bool(usingVM) && io.ptw.resp.valid val do_refill = Bool(usingVM) && io.ptw.resp.valid
val mpu_ppn = Mux(do_refill, refill_ppn, passthrough_ppn) val mpu_ppn = Mux(do_refill, refill_ppn, passthrough_ppn)
val mpu_physaddr = mpu_ppn << pgIdxBits
val legal_address = edge.manager.findSafe(mpu_physaddr).reduce(_||_)
def fastCheck(member: TLManagerParameters => Boolean) = def fastCheck(member: TLManagerParameters => Boolean) =
Mux1H(edge.manager.findFast(mpu_ppn << pgIdxBits), edge.manager.managers.map(m => Bool(member(m)))) legal_address && Mux1H(edge.manager.findFast(mpu_physaddr), edge.manager.managers.map(m => Bool(member(m))))
val prot_r = fastCheck(_.supportsGet) val prot_r = fastCheck(_.supportsGet)
val prot_w = fastCheck(_.supportsPutFull) val prot_w = fastCheck(_.supportsPutFull)
val prot_x = fastCheck(_.executable) val prot_x = fastCheck(_.executable)

View File

@ -28,8 +28,9 @@ class BasePlatformConfig extends Config(
case PeripheryBusArithmetic => true case PeripheryBusArithmetic => true
// Note that PLIC asserts that this is > 0. // Note that PLIC asserts that this is > 0.
case IncludeJtagDTM => false case IncludeJtagDTM => false
case ExtMem => AXIMasterConfig(0x80000000L, 0x10000000L, 8, 4) case ExtMem => MasterConfig(base=0x80000000L, size=0x10000000L, beatBytes=8, idBits=4)
case ExtBus => AXIMasterConfig(0x60000000L, 0x20000000L, 8, 4) case ExtBus => MasterConfig(base=0x60000000L, size=0x20000000L, beatBytes=8, idBits=4)
case ExtIn => SlaveConfig(beatBytes=8, idBits=8, sourceBits=2)
case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock case RTCPeriod => 100 // gives 10 MHz RTC assuming 1 GHz uncore clock
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
@ -56,14 +57,14 @@ class PLRUL2Config extends Config(new WithPLRU ++ new DefaultL2Config)
class WithNMemoryChannels(n: Int) extends Config( class WithNMemoryChannels(n: Int) extends Config(
(pname,site,here,up) => pname match { (pname,site,here,up) => pname match {
case BankedL2Config => up(BankedL2Config).copy(nMemoryChannels = n) case BankedL2Config => up(BankedL2Config, site).copy(nMemoryChannels = n)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
} }
) )
class WithExtMemSize(n: Long) extends Config( class WithExtMemSize(n: Long) extends Config(
(pname,site,here,up) => pname match { (pname,site,here,up) => pname match {
case ExtMem => up(ExtMem).copy(size = n) case ExtMem => up(ExtMem, site).copy(size = n)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
} }
) )
@ -94,7 +95,7 @@ class RoccExampleConfig extends Config(new WithRoccExample ++ new BaseConfig)
class WithEdgeDataBits(dataBits: Int) extends Config( class WithEdgeDataBits(dataBits: Int) extends Config(
(pname, site, here, up) => pname match { (pname, site, here, up) => pname match {
case ExtMem => up(ExtMem).copy(beatBytes = dataBits/8) case ExtMem => up(ExtMem, site).copy(beatBytes = dataBits/8)
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
}) })
@ -168,3 +169,9 @@ class WithNBreakpoints(hwbp: Int) extends Config (
case _ => throw new CDEMatchError case _ => throw new CDEMatchError
} }
) )
class WithRTCPeriod(nCycles: Int) extends Config(
(pname, site, here) => pname match {
case RTCPeriod => nCycles
case _ => throw new CDEMatchError
})

View File

@ -38,32 +38,25 @@ case object IncludeJtagDTM extends Field[Boolean]
* *
*/ */
class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters) class JtagDTMWithSync(implicit val p: Parameters) extends Module {
extends Module {
// io.DebugBusIO <-> Sync <-> DebugBusIO <-> UInt <-> DTM Black Box // io.DebugBusIO <-> Sync <-> DebugBusIO <-> UInt <-> DTM Black Box
val io = new Bundle { val io = new Bundle {
val jtag = new JTAGIO(true).flip val jtag = new JTAGIO(true).flip
val debug = new AsyncDebugBusIO val debug = new AsyncDebugBusIO
} }
val req_width = io.debug.req.mem(0).getWidth val req_width = io.debug.req.mem(0).getWidth
val resp_width = io.debug.resp.mem(0).getWidth val resp_width = io.debug.resp.mem(0).getWidth
val jtag_dtm = Module (new DebugTransportModuleJtag(req_width, resp_width)) val jtag_dtm = Module(new DebugTransportModuleJtag(req_width, resp_width))
jtag_dtm.io.jtag <> io.jtag jtag_dtm.io.jtag <> io.jtag
val dtm_req = Wire(new DecoupledIO(UInt(width = req_width)))
val dtm_resp = Wire(new DecoupledIO(UInt(width = resp_width)))
val io_debug_bus = Wire (new DebugBusIO) val io_debug_bus = Wire (new DebugBusIO)
io.debug <> ToAsyncDebugBus(io_debug_bus)
io.debug.req <> ToAsyncBundle(io_debug_bus.req) val dtm_req = jtag_dtm.io.dtm_req
io_debug_bus.resp <> FromAsyncBundle(io.debug.resp) val dtm_resp = jtag_dtm.io.dtm_resp
// Translate from straight 'bits' interface of the blackboxes // Translate from straight 'bits' interface of the blackboxes
// into the Resp/Req data structures. // into the Resp/Req data structures.
@ -74,20 +67,12 @@ class JtagDTMWithSync(depth: Int = 1, sync: Int = 3)(implicit val p: Parameters)
dtm_resp.valid := io_debug_bus.resp.valid dtm_resp.valid := io_debug_bus.resp.valid
dtm_resp.bits := io_debug_bus.resp.bits.asUInt dtm_resp.bits := io_debug_bus.resp.bits.asUInt
io_debug_bus.resp.ready := dtm_resp.ready io_debug_bus.resp.ready := dtm_resp.ready
dtm_req <> jtag_dtm.io.dtm_req
jtag_dtm.io.dtm_resp <> dtm_resp
} }
class DebugTransportModuleJtag(reqSize : Int, respSize : Int)(implicit val p: Parameters) extends BlackBox { class DebugTransportModuleJtag(reqSize : Int, respSize : Int)(implicit val p: Parameters) extends BlackBox {
val io = new Bundle { val io = new Bundle {
val jtag = new JTAGIO(true).flip() val jtag = new JTAGIO(true).flip()
val dtm_req = new DecoupledIO(UInt(width = reqSize)) val dtm_req = new DecoupledIO(UInt(width = reqSize))
val dtm_resp = new DecoupledIO(UInt(width = respSize)).flip() val dtm_resp = new DecoupledIO(UInt(width = respSize)).flip()
} }
} }

View File

@ -20,9 +20,11 @@ import scala.math.max
import coreplex._ import coreplex._
/** Specifies the size of external memory */ /** Specifies the size of external memory */
case class AXIMasterConfig(base: Long, size: Long, beatBytes: Int, idBits: Int) case class MasterConfig(base: Long, size: Long, beatBytes: Int, idBits: Int)
case object ExtMem extends Field[AXIMasterConfig] case object ExtMem extends Field[MasterConfig]
case object ExtBus extends Field[AXIMasterConfig] case object ExtBus extends Field[MasterConfig]
case class SlaveConfig(beatBytes: Int, idBits: Int, sourceBits: Int)
case object ExtIn extends Field[SlaveConfig]
/** Specifies the number of external interrupts */ /** Specifies the number of external interrupts */
case object NExtTopInterrupts extends Field[Int] case object NExtTopInterrupts extends Field[Int]
/** Source of RTC. First bundle is TopIO.extra, Second bundle is periphery.io.extra **/ /** Source of RTC. First bundle is TopIO.extra, Second bundle is periphery.io.extra **/
@ -70,6 +72,14 @@ trait PeripheryExtInterruptsModule {
///// /////
trait PeripheryNoMem extends TopNetwork {
private val channels = p(BankedL2Config).nMemoryChannels
require (channels == 0)
val mem = Seq()
}
/////
trait PeripheryMasterAXI4Mem { trait PeripheryMasterAXI4Mem {
this: TopNetwork => this: TopNetwork =>
val module: PeripheryMasterAXI4MemModule val module: PeripheryMasterAXI4MemModule
@ -155,14 +165,17 @@ trait PeripheryMasterAXI4MMIOModule {
// PeripherySlaveAXI4 is an example, make your own cake pattern like this one. // PeripherySlaveAXI4 is an example, make your own cake pattern like this one.
trait PeripherySlaveAXI4 extends L2Crossbar { trait PeripherySlaveAXI4 extends L2Crossbar {
private val axiIdBits = 8 private val config = p(ExtIn)
private val tlIdBits = 2 // at most 4 AXI requets inflight at a time
val l2_axi4 = AXI4BlindInputNode(AXI4MasterPortParameters( val l2_axi4 = AXI4BlindInputNode(AXI4MasterPortParameters(
masters = Seq(AXI4MasterParameters( masters = Seq(AXI4MasterParameters(
id = IdRange(0, 1 << axiIdBits))))) id = IdRange(0, 1 << config.idBits)))))
l2.node := TLSourceShrinker(1 << tlIdBits)(AXI4ToTL()(AXI4Fragmenter()(l2_axi4))) l2.node :=
TLSourceShrinker(1 << config.sourceBits)(
TLWidthWidget(config.beatBytes)(
AXI4ToTL()(
AXI4Fragmenter()(
l2_axi4))))
} }
trait PeripherySlaveAXI4Bundle extends L2CrossbarBundle { trait PeripherySlaveAXI4Bundle extends L2CrossbarBundle {
@ -178,6 +191,69 @@ trait PeripherySlaveAXI4Module extends L2CrossbarModule {
///// /////
// Add an external TL-UL slave
trait PeripheryMasterTLMMIO {
this: TopNetwork =>
private val config = p(ExtBus)
val mmio_tl = TLBlindOutputNode(TLManagerPortParameters(
managers = Seq(TLManagerParameters(
address = List(AddressSet(BigInt(config.base), config.size-1)),
executable = true,
supportsGet = TransferSizes(1, cacheBlockBytes),
supportsPutFull = TransferSizes(1, cacheBlockBytes),
supportsPutPartial = TransferSizes(1, cacheBlockBytes))),
beatBytes = config.beatBytes))
mmio_tl :=
TLSourceShrinker(config.idBits)(
TLWidthWidget(socBusConfig.beatBytes)(
socBus.node))
}
trait PeripheryMasterTLMMIOBundle {
this: TopNetworkBundle {
val outer: PeripheryMasterTLMMIO
} =>
val mmio_tl = outer.mmio_tl.bundleOut
}
trait PeripheryMasterTLMMIOModule {
this: TopNetworkModule {
val outer: PeripheryMasterTLMMIO
val io: PeripheryMasterTLMMIOBundle
} =>
// nothing to do
}
/////
// NOTE: this port is NOT allowed to issue Acquires
trait PeripherySlaveTL extends L2Crossbar {
private val config = p(ExtIn)
val l2_tl = TLBlindInputNode(TLClientPortParameters(
clients = Seq(TLClientParameters(
sourceId = IdRange(0, 1 << config.idBits)))))
l2.node :=
TLSourceShrinker(1 << config.sourceBits)(
TLWidthWidget(config.beatBytes)(
l2_tl))
}
trait PeripherySlaveTLBundle extends L2CrossbarBundle {
val outer: PeripherySlaveTL
val l2_tl = outer.l2_tl.bundleIn
}
trait PeripherySlaveTLModule extends L2CrossbarModule {
val outer: PeripherySlaveTL
val io: PeripherySlaveTLBundle
// nothing to do
}
/////
trait PeripheryBootROM { trait PeripheryBootROM {
this: TopNetwork => this: TopNetwork =>
val coreplex: CoreplexRISCVPlatform val coreplex: CoreplexRISCVPlatform

View File

@ -11,6 +11,8 @@ import util._
import junctions.JTAGIO import junctions.JTAGIO
import coreplex._ import coreplex._
/// Core with JTAG for debug only
trait PeripheryJTAG extends TopNetwork { trait PeripheryJTAG extends TopNetwork {
val module: PeripheryJTAGModule val module: PeripheryJTAGModule
val coreplex: CoreplexRISCVPlatform val coreplex: CoreplexRISCVPlatform
@ -34,6 +36,8 @@ trait PeripheryJTAGModule extends TopNetworkModule {
dtm.reset := io.jtag.TRST dtm.reset := io.jtag.TRST
} }
/// Core with DTM for debug only
trait PeripheryDTM extends TopNetwork { trait PeripheryDTM extends TopNetwork {
val module: PeripheryDTMModule val module: PeripheryDTMModule
val coreplex: CoreplexRISCVPlatform val coreplex: CoreplexRISCVPlatform
@ -52,6 +56,36 @@ trait PeripheryDTMModule extends TopNetworkModule {
outer.coreplex.module.io.debug <> ToAsyncDebugBus(io.debug) outer.coreplex.module.io.debug <> ToAsyncDebugBus(io.debug)
} }
/// Core with DTM or JTAG based on a parameter
trait PeripheryDebug extends TopNetwork {
val module: PeripheryDebugModule
val coreplex: CoreplexRISCVPlatform
}
trait PeripheryDebugBundle extends TopNetworkBundle {
val outer: PeripheryDebug
val debug = (!p(IncludeJtagDTM)).option(new DebugBusIO().flip)
val jtag = (p(IncludeJtagDTM)).option(new JTAGIO(true).flip)
}
trait PeripheryDebugModule extends TopNetworkModule {
val outer: PeripheryDebug
val io: PeripheryDebugBundle
io.debug.foreach { dbg => outer.coreplex.module.io.debug <> ToAsyncDebugBus(dbg) }
io.jtag.foreach { jtag =>
val dtm = Module (new JtagDTMWithSync)
dtm.clock := jtag.TCK
dtm.reset := jtag.TRST
dtm.io.jtag <> jtag
outer.coreplex.module.io.debug <> dtm.io.debug
}
}
/// Real-time clock is based on RTCPeriod relative to Top clock
trait PeripheryCounter extends TopNetwork { trait PeripheryCounter extends TopNetwork {
val module: PeripheryCounterModule val module: PeripheryCounterModule
val coreplex: CoreplexRISCVPlatform val coreplex: CoreplexRISCVPlatform
@ -75,6 +109,8 @@ trait PeripheryCounterModule extends TopNetworkModule {
} }
} }
/// Coreplex will power-on running at 0x1000 (BootROM)
trait HardwiredResetVector extends TopNetwork { trait HardwiredResetVector extends TopNetwork {
val module: HardwiredResetVectorModule val module: HardwiredResetVectorModule
val coreplex: CoreplexRISCVPlatform val coreplex: CoreplexRISCVPlatform

View File

@ -5,186 +5,14 @@ package uncore.agents
import Chisel._ import Chisel._
import scala.reflect.ClassTag import scala.reflect.ClassTag
import junctions.PAddrBits import junctions.PAddrBits
import util.ParameterizedBundle
import uncore.util.AMOALU
import uncore.coherence._ import uncore.coherence._
import uncore.tilelink._ import uncore.tilelink._
import uncore.constants._ import uncore.constants._
import uncore.util._ import uncore.util._
import util._ import util._
import config._ import config.{Parameters, Field}
case class CacheConfig(
nSets: Int,
nWays: Int,
rowBits: Int,
nTLBEntries: Int,
cacheIdBits: Int,
splitMetadata: Boolean)
case class CacheName(id: String) extends Field[CacheConfig]
case object CacheName extends Field[CacheName]
case object Replacer extends Field[() => ReplacementPolicy]
case object L2Replacer extends Field[() => SeqReplacementPolicy]
case object NPrimaryMisses extends Field[Int]
case object NSecondaryMisses extends Field[Int]
case object CacheBlockBytes extends Field[Int]
case object ECCCode extends Field[Option[Code]]
case object CacheId extends Field[Int] case object CacheId extends Field[Int]
trait HasCacheParameters {
implicit val p: Parameters
val cacheConfig = p(p(CacheName))
val nSets = cacheConfig.nSets
val blockOffBits = p(CacheBlockOffsetBits)
val cacheIdBits = cacheConfig.cacheIdBits
val idxBits = log2Up(cacheConfig.nSets)
val untagBits = blockOffBits + cacheIdBits + idxBits
val tagBits = p(PAddrBits) - untagBits
val nWays = cacheConfig.nWays
val wayBits = log2Up(nWays)
val isDM = nWays == 1
val rowBits = cacheConfig.rowBits
val rowBytes = rowBits/8
val rowOffBits = log2Up(rowBytes)
val code = p(ECCCode).getOrElse(new IdentityCode)
val hasSplitMetadata = cacheConfig.splitMetadata
}
abstract class CacheModule(implicit val p: Parameters) extends Module
with HasCacheParameters
abstract class CacheBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
with HasCacheParameters
abstract class ReplacementPolicy {
def way: UInt
def miss: Unit
def hit: Unit
}
class RandomReplacement(ways: Int) extends ReplacementPolicy {
private val replace = Wire(Bool())
replace := Bool(false)
val lfsr = LFSR16(replace)
def way = if(ways == 1) UInt(0) else lfsr(log2Up(ways)-1,0)
def miss = replace := Bool(true)
def hit = {}
}
abstract class SeqReplacementPolicy {
def access(set: UInt): Unit
def update(valid: Bool, hit: Bool, set: UInt, way: UInt): Unit
def way: UInt
}
class SeqRandom(n_ways: Int) extends SeqReplacementPolicy {
val logic = new RandomReplacement(n_ways)
def access(set: UInt) = { }
def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = {
when (valid && !hit) { logic.miss }
}
def way = logic.way
}
class PseudoLRU(n: Int)
{
require(isPow2(n))
val state_reg = Reg(Bits(width = n))
def access(way: UInt) {
state_reg := get_next_state(state_reg,way)
}
def get_next_state(state: UInt, way: UInt) = {
var next_state = state
var idx = UInt(1,1)
for (i <- log2Up(n)-1 to 0 by -1) {
val bit = way(i)
next_state = next_state.bitSet(idx, !bit)
idx = Cat(idx, bit)
}
next_state
}
def replace = get_replace_way(state_reg)
def get_replace_way(state: Bits) = {
var idx = UInt(1,1)
for (i <- 0 until log2Up(n))
idx = Cat(idx, state(idx))
idx(log2Up(n)-1,0)
}
}
class SeqPLRU(n_sets: Int, n_ways: Int) extends SeqReplacementPolicy {
val state = SeqMem(n_sets, Bits(width = n_ways-1))
val logic = new PseudoLRU(n_ways)
val current_state = Wire(Bits())
val plru_way = logic.get_replace_way(current_state)
val next_state = Wire(Bits())
def access(set: UInt) = {
current_state := Cat(state.read(set), Bits(0, width = 1))
}
def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = {
val update_way = Mux(hit, way, plru_way)
next_state := logic.get_next_state(current_state, update_way)
when (valid) { state.write(set, next_state(n_ways-1,1)) }
}
def way = plru_way
}
abstract class Metadata(implicit p: Parameters) extends CacheBundle()(p) {
val tag = Bits(width = tagBits)
}
class MetaReadReq(implicit p: Parameters) extends CacheBundle()(p) {
val idx = Bits(width = idxBits)
val way_en = Bits(width = nWays)
}
class MetaWriteReq[T <: Metadata](gen: T)(implicit p: Parameters) extends MetaReadReq()(p) {
val data = gen.cloneType
override def cloneType = new MetaWriteReq(gen)(p).asInstanceOf[this.type]
}
class MetadataArray[T <: Metadata](onReset: () => T)(implicit p: Parameters) extends CacheModule()(p) {
val rstVal = onReset()
val io = new Bundle {
val read = Decoupled(new MetaReadReq).flip
val write = Decoupled(new MetaWriteReq(rstVal)).flip
val resp = Vec(nWays, rstVal.cloneType).asOutput
}
val rst_cnt = Reg(init=UInt(0, log2Up(nSets+1)))
val rst = rst_cnt < UInt(nSets)
val waddr = Mux(rst, rst_cnt, io.write.bits.idx)
val wdata = Mux(rst, rstVal, io.write.bits.data).asUInt
val wmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.write.bits.way_en.asSInt).toBools
val rmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.read.bits.way_en.asSInt).toBools
when (rst) { rst_cnt := rst_cnt+UInt(1) }
val metabits = rstVal.getWidth
if (hasSplitMetadata) {
val tag_arrs = List.fill(nWays){ SeqMem(nSets, UInt(width = metabits)) }
val tag_readout = Wire(Vec(nWays,rstVal.cloneType))
(0 until nWays).foreach { (i) =>
when (rst || (io.write.valid && wmask(i))) {
tag_arrs(i).write(waddr, wdata)
}
io.resp(i) := rstVal.fromBits(tag_arrs(i).read(io.read.bits.idx, io.read.valid && rmask(i)))
}
} else {
val tag_arr = SeqMem(nSets, Vec(nWays, UInt(width = metabits)))
when (rst || io.write.valid) {
tag_arr.write(waddr, Vec.fill(nWays)(wdata), wmask)
}
io.resp := tag_arr.read(io.read.bits.idx, io.read.valid).map(rstVal.fromBits(_))
}
io.read.ready := !rst && !io.write.valid // so really this could be a 6T RAM
io.write.ready := !rst
}
case object L2DirectoryRepresentation extends Field[DirectoryRepresentation] case object L2DirectoryRepresentation extends Field[DirectoryRepresentation]
trait HasOuterCacheParameters extends HasCacheParameters with HasCoherenceAgentParameters { trait HasOuterCacheParameters extends HasCacheParameters with HasCoherenceAgentParameters {

View File

@ -53,3 +53,6 @@ case class AXI4InputNode() extends InputNode(AXI4Imp)
// Nodes used for external ports // Nodes used for external ports
case class AXI4BlindOutputNode(portParams: AXI4SlavePortParameters) extends BlindOutputNode(AXI4Imp)(portParams) case class AXI4BlindOutputNode(portParams: AXI4SlavePortParameters) extends BlindOutputNode(AXI4Imp)(portParams)
case class AXI4BlindInputNode(portParams: AXI4MasterPortParameters) extends BlindInputNode(AXI4Imp)(portParams) case class AXI4BlindInputNode(portParams: AXI4MasterPortParameters) extends BlindInputNode(AXI4Imp)(portParams)
case class AXI4InternalOutputNode(portParams: AXI4SlavePortParameters) extends InternalOutputNode(AXI4Imp)(portParams)
case class AXI4InternalInputNode(portParams: AXI4MasterPortParameters) extends InternalInputNode(AXI4Imp)(portParams)

View File

@ -88,12 +88,6 @@ class ClientMetadata extends Bundle {
Cat(wr, toT) -> Dirty)) Cat(wr, toT) -> Dirty))
} }
/** Does a secondary miss on the block require another Acquire message */
def requiresAcquireOnSecondaryMiss(first_cmd: UInt, second_cmd: UInt): Bool = {
import MemoryOpCategories._
isWriteIntent(second_cmd) && !isWriteIntent(first_cmd)
}
/** Does this cache have permissions on this block sufficient to perform op, /** Does this cache have permissions on this block sufficient to perform op,
* and what to do next (Acquire message param or updated metadata). */ * and what to do next (Acquire message param or updated metadata). */
def onAccess(cmd: UInt): (Bool, UInt, ClientMetadata) = { def onAccess(cmd: UInt): (Bool, UInt, ClientMetadata) = {
@ -101,6 +95,20 @@ class ClientMetadata extends Bundle {
(r._1, r._2, ClientMetadata(r._2)) (r._1, r._2, ClientMetadata(r._2))
} }
/** Does a secondary miss on the block require another Acquire message */
def onSecondaryAccess(first_cmd: UInt, second_cmd: UInt): (Bool, Bool, UInt, ClientMetadata, UInt) = {
import MemoryOpCategories._
val r1 = growStarter(first_cmd)
val r2 = growStarter(second_cmd)
val needs_second_acq = isWriteIntent(second_cmd) && !isWriteIntent(first_cmd)
val hit_again = r1._1 && r2._1
val dirties = categorize(second_cmd) === wr
val biggest_grow_param = Mux(dirties, r2._2, r1._2)
val dirtiest_state = ClientMetadata(biggest_grow_param)
val dirtiest_cmd = Mux(dirties, second_cmd, first_cmd)
(needs_second_acq, hit_again, biggest_grow_param, dirtiest_state, dirtiest_cmd)
}
/** Metadata change on a returned Grant */ /** Metadata change on a returned Grant */
def onGrant(cmd: UInt, param: UInt): ClientMetadata = ClientMetadata(growFinisher(cmd, param)) def onGrant(cmd: UInt, param: UInt): ClientMetadata = ClientMetadata(growFinisher(cmd, param))

View File

@ -126,6 +126,9 @@ case class TLInputNode() extends InputNode(TLImp)
case class TLBlindOutputNode(portParams: TLManagerPortParameters) extends BlindOutputNode(TLImp)(portParams) case class TLBlindOutputNode(portParams: TLManagerPortParameters) extends BlindOutputNode(TLImp)(portParams)
case class TLBlindInputNode(portParams: TLClientPortParameters) extends BlindInputNode(TLImp)(portParams) case class TLBlindInputNode(portParams: TLClientPortParameters) extends BlindInputNode(TLImp)(portParams)
case class TLInternalOutputNode(portParams: TLManagerPortParameters) extends InternalOutputNode(TLImp)(portParams)
case class TLInternalInputNode(portParams: TLClientPortParameters) extends InternalInputNode(TLImp)(portParams)
/** Synthesizeable unit tests */ /** Synthesizeable unit tests */
import unittest._ import unittest._

View File

@ -0,0 +1,180 @@
// See LICENSE for license details.
package uncore.util
import Chisel._
import config.{Parameters, Field}
import junctions.PAddrBits
import util.ParameterizedBundle
import uncore.constants._
case class CacheConfig(
nSets: Int,
nWays: Int,
rowBits: Int,
nTLBEntries: Int,
cacheIdBits: Int,
splitMetadata: Boolean)
case class CacheName(id: String) extends Field[CacheConfig]
case object CacheName extends Field[CacheName]
case object Replacer extends Field[() => ReplacementPolicy]
case object L2Replacer extends Field[() => SeqReplacementPolicy]
case object NPrimaryMisses extends Field[Int]
case object NSecondaryMisses extends Field[Int]
case object CacheBlockBytes extends Field[Int]
case object ECCCode extends Field[Option[Code]]
trait HasCacheParameters {
implicit val p: Parameters
val cacheConfig = p(p(CacheName))
val nSets = cacheConfig.nSets
val blockOffBits = log2Up(p(CacheBlockBytes))
val cacheIdBits = cacheConfig.cacheIdBits
val idxBits = log2Up(cacheConfig.nSets)
val untagBits = blockOffBits + cacheIdBits + idxBits
val tagBits = p(PAddrBits) - untagBits
val nWays = cacheConfig.nWays
val wayBits = log2Up(nWays)
val isDM = nWays == 1
val rowBits = cacheConfig.rowBits
val rowBytes = rowBits/8
val rowOffBits = log2Up(rowBytes)
val code = p(ECCCode).getOrElse(new IdentityCode)
val hasSplitMetadata = cacheConfig.splitMetadata
}
abstract class CacheModule(implicit val p: Parameters) extends Module
with HasCacheParameters
abstract class CacheBundle(implicit val p: Parameters) extends ParameterizedBundle()(p)
with HasCacheParameters
abstract class ReplacementPolicy {
def way: UInt
def miss: Unit
def hit: Unit
}
class RandomReplacement(ways: Int) extends ReplacementPolicy {
private val replace = Wire(Bool())
replace := Bool(false)
val lfsr = LFSR16(replace)
def way = if(ways == 1) UInt(0) else lfsr(log2Up(ways)-1,0)
def miss = replace := Bool(true)
def hit = {}
}
abstract class SeqReplacementPolicy {
def access(set: UInt): Unit
def update(valid: Bool, hit: Bool, set: UInt, way: UInt): Unit
def way: UInt
}
class SeqRandom(n_ways: Int) extends SeqReplacementPolicy {
val logic = new RandomReplacement(n_ways)
def access(set: UInt) = { }
def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = {
when (valid && !hit) { logic.miss }
}
def way = logic.way
}
class PseudoLRU(n: Int)
{
require(isPow2(n))
val state_reg = Reg(Bits(width = n))
def access(way: UInt) {
state_reg := get_next_state(state_reg,way)
}
def get_next_state(state: UInt, way: UInt) = {
var next_state = state
var idx = UInt(1,1)
for (i <- log2Up(n)-1 to 0 by -1) {
val bit = way(i)
next_state = next_state.bitSet(idx, !bit)
idx = Cat(idx, bit)
}
next_state
}
def replace = get_replace_way(state_reg)
def get_replace_way(state: Bits) = {
var idx = UInt(1,1)
for (i <- 0 until log2Up(n))
idx = Cat(idx, state(idx))
idx(log2Up(n)-1,0)
}
}
class SeqPLRU(n_sets: Int, n_ways: Int) extends SeqReplacementPolicy {
val state = SeqMem(n_sets, Bits(width = n_ways-1))
val logic = new PseudoLRU(n_ways)
val current_state = Wire(Bits())
val plru_way = logic.get_replace_way(current_state)
val next_state = Wire(Bits())
def access(set: UInt) = {
current_state := Cat(state.read(set), Bits(0, width = 1))
}
def update(valid: Bool, hit: Bool, set: UInt, way: UInt) = {
val update_way = Mux(hit, way, plru_way)
next_state := logic.get_next_state(current_state, update_way)
when (valid) { state.write(set, next_state(n_ways-1,1)) }
}
def way = plru_way
}
abstract class Metadata(implicit p: Parameters) extends CacheBundle()(p) {
val tag = Bits(width = tagBits)
}
class MetaReadReq(implicit p: Parameters) extends CacheBundle()(p) {
val idx = Bits(width = idxBits)
val way_en = Bits(width = nWays)
}
class MetaWriteReq[T <: Metadata](gen: T)(implicit p: Parameters) extends MetaReadReq()(p) {
val data = gen.cloneType
override def cloneType = new MetaWriteReq(gen)(p).asInstanceOf[this.type]
}
class MetadataArray[T <: Metadata](onReset: () => T)(implicit p: Parameters) extends CacheModule()(p) {
val rstVal = onReset()
val io = new Bundle {
val read = Decoupled(new MetaReadReq).flip
val write = Decoupled(new MetaWriteReq(rstVal)).flip
val resp = Vec(nWays, rstVal.cloneType).asOutput
}
val rst_cnt = Reg(init=UInt(0, log2Up(nSets+1)))
val rst = rst_cnt < UInt(nSets)
val waddr = Mux(rst, rst_cnt, io.write.bits.idx)
val wdata = Mux(rst, rstVal, io.write.bits.data).asUInt
val wmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.write.bits.way_en.asSInt).toBools
val rmask = Mux(rst || Bool(nWays == 1), SInt(-1), io.read.bits.way_en.asSInt).toBools
when (rst) { rst_cnt := rst_cnt+UInt(1) }
val metabits = rstVal.getWidth
if (hasSplitMetadata) {
val tag_arrs = List.fill(nWays){ SeqMem(nSets, UInt(width = metabits)) }
val tag_readout = Wire(Vec(nWays,rstVal.cloneType))
(0 until nWays).foreach { (i) =>
when (rst || (io.write.valid && wmask(i))) {
tag_arrs(i).write(waddr, wdata)
}
io.resp(i) := rstVal.fromBits(tag_arrs(i).read(io.read.bits.idx, io.read.valid && rmask(i)))
}
} else {
val tag_arr = SeqMem(nSets, Vec(nWays, UInt(width = metabits)))
when (rst || io.write.valid) {
tag_arr.write(waddr, Vec.fill(nWays)(wdata), wmask)
}
io.resp := tag_arr.read(io.read.bits.idx, io.read.valid).map(rstVal.fromBits(_))
}
io.read.ready := !rst && !io.write.valid // so really this could be a 6T RAM
io.write.ready := !rst
}

View File

@ -1,6 +1,6 @@
// See LICENSE for license details. // See LICENSE for license details.
package uncore.agents package uncore.util
import Chisel._ import Chisel._
import util._ import util._

View File

@ -9,8 +9,8 @@ final class AsyncBundle[T <: Data](val depth: Int, gen: T) extends Bundle
{ {
require (isPow2(depth)) require (isPow2(depth))
val mem = Vec(depth, gen) val mem = Vec(depth, gen)
val ridx = UInt(width = log2Up(depth)+1).flip val ridx = UInt(width = log2Ceil(depth)+1).flip
val widx = UInt(width = log2Up(depth)+1) val widx = UInt(width = log2Ceil(depth)+1)
val ridx_valid = Bool().flip val ridx_valid = Bool().flip
val widx_valid = Bool() val widx_valid = Bool()
val source_reset_n = Bool() val source_reset_n = Bool()

View File

@ -6,7 +6,8 @@ class CDEMatchError() extends Exception {
} }
abstract class View { abstract class View {
final def apply[T](pname: Field[T]): T = find(pname, this).asInstanceOf[T] final def apply[T](pname: Field[T]): T = apply(pname, this)
final def apply[T](pname: Field[T], site: View): T = find(pname, site).asInstanceOf[T]
protected[config] def find(pname: Any, site: View): Any protected[config] def find(pname: Any, site: View): Any
} }

View File

@ -12,9 +12,9 @@ $(generated_dir)/%.fir $(generated_dir)/%.prm $(generated_dir)/%.d: $(FIRRTL_JAR
mkdir -p $(dir $@) mkdir -p $(dir $@)
cd $(base_dir) && $(SBT) "run-main $(PROJECT).Generator $(generated_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)" cd $(base_dir) && $(SBT) "run-main $(PROJECT).Generator $(generated_dir) $(PROJECT) $(MODEL) $(CFG_PROJECT) $(CONFIG)"
$(generated_dir)/$(long_name).v $(generated_dir)/$(long_name).conf : $(firrtl) $(FIRRTL_JAR) $(generated_dir)/%.v $(generated_dir)/%.conf: $(generated_dir)/%.fir $(FIRRTL_JAR)
mkdir -p $(dir $@) mkdir -p $(dir $@)
$(FIRRTL) -i $< -o $(generated_dir)/$(long_name).v -X verilog --infer-rw $(MODEL) --repl-seq-mem -c:$(MODEL):-o:$(generated_dir)/$(long_name).conf $(FIRRTL) -i $< -o $(generated_dir)/$*.v -X verilog --infer-rw $(MODEL) --repl-seq-mem -c:$(MODEL):-o:$(generated_dir)/$*.conf
$(generated_dir)/$(long_name).behav_srams.v : $(generated_dir)/$(long_name).conf $(mem_gen) $(generated_dir)/$(long_name).behav_srams.v : $(generated_dir)/$(long_name).conf $(mem_gen)
cd $(generated_dir) && \ cd $(generated_dir) && \