Merge remote-tracking branch 'origin/master' into bump-submodules
This commit is contained in:
		@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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,
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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))
 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
  })
 | 
					  })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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({
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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._
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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._
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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._
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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._
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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._
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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")
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 | 
					  })
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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()
 | 
				
			||||||
 | 
					 | 
				
			||||||
  }
 | 
					  }
 | 
				
			||||||
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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 {
 | 
				
			||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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._
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										180
									
								
								src/main/scala/uncore/util/Cache.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										180
									
								
								src/main/scala/uncore/util/Cache.scala
									
									
									
									
									
										Normal 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
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -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._
 | 
				
			||||||
@@ -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()
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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) && \
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user