WIP on new memory map
This commit is contained in:
		@@ -365,7 +365,6 @@ Top.DefaultVLSIConfig.conf file:
 | 
			
		||||
    Top.DefaultVLSIConfig.prm
 | 
			
		||||
    Top.DefaultVLSIConfig.v
 | 
			
		||||
    consts.DefaultVLSIConfig.vh
 | 
			
		||||
    memdessertMemDessert.DefaultVLSIConfig.v
 | 
			
		||||
    $ cat $ROCKETCHIP/vsim/generated-src/*.conf
 | 
			
		||||
    name MetadataArray_tag_arr depth 128 width 84 ports mwrite,read mask_gran 21
 | 
			
		||||
    name ICache_tag_array depth 128 width 38 ports mrw mask_gran 19
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								chisel3
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								chisel3
									
									
									
									
									
								
							 Submodule chisel3 updated: 19046381ae...6183533596
									
								
							@@ -111,7 +111,6 @@ int main(int argc, char** argv)
 | 
			
		||||
  // reset for one host_clk cycle to handle pipelined reset
 | 
			
		||||
  tile.Top__io_host_in_valid = LIT<1>(0);
 | 
			
		||||
  tile.Top__io_host_out_ready = LIT<1>(0);
 | 
			
		||||
  tile.Top__io_mem_backup_ctrl_en = LIT<1>(0);
 | 
			
		||||
  for (int i = 0; i < 3; i += tile.Top__io_host_clk_edge.to_bool())
 | 
			
		||||
  {
 | 
			
		||||
    tile.clock_lo(LIT<1>(1));
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								firrtl
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								firrtl
									
									
									
									
									
								
							 Submodule firrtl updated: ec32c852b5...54184c2a08
									
								
							@@ -8,9 +8,7 @@
 | 
			
		||||
sim_vsrcs = \
 | 
			
		||||
	$(generated_dir)/$(MODEL).$(CONFIG).v \
 | 
			
		||||
	$(generated_dir)/consts.$(CONFIG).vh \
 | 
			
		||||
	$(generated_dir)/memdessertMemDessert.$(CONFIG).v \
 | 
			
		||||
	$(base_dir)/vsrc/$(TB).v \
 | 
			
		||||
	$(base_dir)/vsrc/backup_mem.v \
 | 
			
		||||
 | 
			
		||||
# C sources
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
 Submodule junctions updated: cd3d2ca219...d9c4e92a21
									
								
							
							
								
								
									
										2
									
								
								rocket
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								rocket
									
									
									
									
									
								
							 Submodule rocket updated: bcc378aa71...43baccd10a
									
								
							@@ -25,24 +25,23 @@ class DefaultConfig extends Config (
 | 
			
		||||
    type PF = PartialFunction[Any,Any]
 | 
			
		||||
    def findBy(sname:Any):Any = here[PF](site[Any](sname))(pname)
 | 
			
		||||
    def genCsrAddrMap: AddrMap = {
 | 
			
		||||
      val deviceTree = AddrMapEntry("devicetree", None, MemSize(1 << 15, AddrMapConsts.R))
 | 
			
		||||
      val csrSize = (1 << 12) * (site(XLen) / 8)
 | 
			
		||||
      val csrs = (0 until site(NTiles)).map{ i => 
 | 
			
		||||
        AddrMapEntry(s"csr$i", None, MemSize(csrSize, AddrMapConsts.RW))
 | 
			
		||||
      }
 | 
			
		||||
      val scrSize = site(HtifKey).nSCR * (site(XLen) / 8)
 | 
			
		||||
      val scr = AddrMapEntry("scr", None, MemSize(scrSize, AddrMapConsts.RW))
 | 
			
		||||
      new AddrMap(deviceTree +: csrs :+ scr)
 | 
			
		||||
      val deviceTree = AddrMapEntry("devicetree", MemSize(1 << 15, AddrMapConsts.R))
 | 
			
		||||
      val rtc = AddrMapEntry("rtc", MemSize(1 << 12, AddrMapConsts.RW))
 | 
			
		||||
      new AddrMap(Seq(deviceTree, rtc))
 | 
			
		||||
    }
 | 
			
		||||
    def makeConfigString() = {
 | 
			
		||||
      val addrMap = new AddrHashMap(site(GlobalAddrMap))
 | 
			
		||||
      val xLen = site(XLen)
 | 
			
		||||
      val res = new StringBuilder
 | 
			
		||||
      val memSize = addrMap(s"mem").size
 | 
			
		||||
      val memSize = addrMap("mem").size
 | 
			
		||||
      val rtcAddr = addrMap("conf:rtc").start
 | 
			
		||||
      res append  "platform {\n"
 | 
			
		||||
      res append  "  vendor ucb;\n"
 | 
			
		||||
      res append  "  arch rocket;\n"
 | 
			
		||||
      res append  "};\n"
 | 
			
		||||
      res append  "rtc {\n"
 | 
			
		||||
      res append s"  addr 0x${rtcAddr.toString(16)};\n"
 | 
			
		||||
      res append  "};\n"
 | 
			
		||||
      res append  "ram {\n"
 | 
			
		||||
      res append  "  0 {\n"
 | 
			
		||||
      res append  "    addr 0;\n"
 | 
			
		||||
@@ -51,11 +50,11 @@ class DefaultConfig extends Config (
 | 
			
		||||
      res append  "};\n"
 | 
			
		||||
      res append  "core {\n"
 | 
			
		||||
      for (i <- 0 until site(NTiles)) {
 | 
			
		||||
        val csrAddr = addrMap(s"conf:csr$i").start
 | 
			
		||||
        val timecmpAddr = rtcAddr + 8*(i+1)
 | 
			
		||||
        res append s"  $i {\n"
 | 
			
		||||
        res append  "    0 {\n"
 | 
			
		||||
        res append s"      isa rv$xLen;\n"
 | 
			
		||||
        res append s"      addr 0x${csrAddr.toString(16)};\n"
 | 
			
		||||
        res append s"      timecmp 0x${timecmpAddr.toString(16)};\n"
 | 
			
		||||
        res append  "    };\n"
 | 
			
		||||
        res append  "  };\n"
 | 
			
		||||
      }
 | 
			
		||||
@@ -187,7 +186,7 @@ class DefaultConfig extends Config (
 | 
			
		||||
      case LNEndpoints => site(TLKey(site(TLId))).nManagers + site(TLKey(site(TLId))).nClients
 | 
			
		||||
      case LNHeaderBits => log2Ceil(site(TLKey(site(TLId))).nManagers) +
 | 
			
		||||
                             log2Up(site(TLKey(site(TLId))).nClients)
 | 
			
		||||
      case ExtraL1Clients => 2 // RTC and HTIF
 | 
			
		||||
      case ExtraL1Clients => 1 // HTIF // TODO not really a parameter
 | 
			
		||||
      case TLKey("L1toL2") => 
 | 
			
		||||
        TileLinkParameters(
 | 
			
		||||
          coherencePolicy = new MESICoherence(site(L2DirectoryRepresentation)),
 | 
			
		||||
@@ -201,9 +200,7 @@ class DefaultConfig extends Config (
 | 
			
		||||
              // L1 cache
 | 
			
		||||
              site(NMSHRs) + 1,
 | 
			
		||||
              // RoCC
 | 
			
		||||
              if (site(BuildRoCC).isEmpty) 1 else site(RoccMaxTaggedMemXacts),
 | 
			
		||||
              // RTC
 | 
			
		||||
              site(NTiles)),
 | 
			
		||||
              if (site(BuildRoCC).isEmpty) 1 else site(RoccMaxTaggedMemXacts)),
 | 
			
		||||
          maxClientsPerPort = if (site(BuildRoCC).isEmpty) 1 else 2,
 | 
			
		||||
          maxManagerXacts = site(NAcquireTransactors) + 2,
 | 
			
		||||
          dataBits = site(CacheBlockBytes)*8)
 | 
			
		||||
@@ -245,18 +242,15 @@ class DefaultConfig extends Config (
 | 
			
		||||
      case BankIdLSB => 0
 | 
			
		||||
      case CacheBlockBytes => Dump("CACHE_BLOCK_BYTES", 64)
 | 
			
		||||
      case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes))
 | 
			
		||||
      case UseBackupMemoryPort => false
 | 
			
		||||
      case UseHtifClockDiv => true
 | 
			
		||||
      case ConfigString => makeConfigString()
 | 
			
		||||
      case GlobalAddrMap => {
 | 
			
		||||
        val memsize = BigInt(1L << 30)
 | 
			
		||||
        Dump("MEM_SIZE", memsize)
 | 
			
		||||
        AddrMap(
 | 
			
		||||
          AddrMapEntry("mem", None, MemSize(memsize, AddrMapConsts.RWX, true)),
 | 
			
		||||
          AddrMapEntry("conf", None,
 | 
			
		||||
            MemSubmap(BigInt(1L << 30), genCsrAddrMap)),
 | 
			
		||||
          AddrMapEntry("devices", None,
 | 
			
		||||
            MemSubmap(BigInt(1L << 31), site(GlobalDeviceSet).getAddrMap)))
 | 
			
		||||
          AddrMapEntry("mem", MemSize(memsize, AddrMapConsts.RWX, true)),
 | 
			
		||||
          AddrMapEntry("conf", MemSubmap(BigInt(1L << 30), genCsrAddrMap)),
 | 
			
		||||
          AddrMapEntry("devices", MemSubmap(BigInt(1L << 31), site(GlobalDeviceSet).getAddrMap)))
 | 
			
		||||
      }
 | 
			
		||||
      case GlobalDeviceSet => {
 | 
			
		||||
        val devset = new DeviceSet
 | 
			
		||||
 
 | 
			
		||||
@@ -29,7 +29,7 @@ class DeviceSet {
 | 
			
		||||
    val entries = devices.map { case Device(name, size, _, readable, writeable) =>
 | 
			
		||||
      val prot = (if (readable) R else 0) | (if (writeable) W else 0)
 | 
			
		||||
      val realsize = roundup(size)
 | 
			
		||||
      new AddrMapEntry(name, None, new MemSize(realsize, prot))
 | 
			
		||||
      new AddrMapEntry(name, new MemSize(realsize, prot))
 | 
			
		||||
    }
 | 
			
		||||
    new AddrMap(entries)
 | 
			
		||||
  }
 | 
			
		||||
 
 | 
			
		||||
@@ -25,8 +25,6 @@ case object MemoryChannelMuxConfigs extends Field[List[Int]]
 | 
			
		||||
case object BankIdLSB extends Field[Int]
 | 
			
		||||
/** Number of outstanding memory requests */
 | 
			
		||||
case object NOutstandingMemReqsPerChannel extends Field[Int]
 | 
			
		||||
/** Whether to use the slow backup memory port [VLSI] */
 | 
			
		||||
case object UseBackupMemoryPort extends Field[Boolean]
 | 
			
		||||
/** Whether to divide HTIF clock */
 | 
			
		||||
case object UseHtifClockDiv extends Field[Boolean]
 | 
			
		||||
/** Function for building some kind of coherence manager agent */
 | 
			
		||||
@@ -78,7 +76,6 @@ class MemBackupCtrlIO extends Bundle {
 | 
			
		||||
class BasicTopIO(implicit val p: Parameters) extends ParameterizedBundle()(p)
 | 
			
		||||
    with HasTopLevelParameters {
 | 
			
		||||
  val host = new HostIO(htifW)
 | 
			
		||||
  val mem_backup_ctrl = new MemBackupCtrlIO
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
class TopIO(implicit p: Parameters) extends BasicTopIO()(p) {
 | 
			
		||||
@@ -95,6 +92,11 @@ object TopUtils {
 | 
			
		||||
    inner.r  <> Queue(outer.r, mifDataBeats)
 | 
			
		||||
    inner.b  <> Queue(outer.b)
 | 
			
		||||
  }
 | 
			
		||||
  def connectTilelinkNasti(nasti: NastiIO, tl: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
 | 
			
		||||
    val conv = Module(new NastiIOTileLinkIOConverter())
 | 
			
		||||
    conv.io.tl <> tl
 | 
			
		||||
    TopUtils.connectNasti(nasti, conv.io.nasti)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/** Top-level module for the chip */
 | 
			
		||||
@@ -111,19 +113,17 @@ class Top(topParams: Parameters) extends Module with HasTopLevelParameters {
 | 
			
		||||
  // Connect each tile to the HTIF
 | 
			
		||||
  uncore.io.htif.zip(tileList).zipWithIndex.foreach {
 | 
			
		||||
    case ((hl, tile), i) =>
 | 
			
		||||
      tile.io.host.timerIRQ := uncore.io.timerIRQs(i)
 | 
			
		||||
      tile.io.host.id := UInt(i)
 | 
			
		||||
      tile.io.host.reset := Reg(next=Reg(next=hl.reset))
 | 
			
		||||
      tile.io.host.csr.req <> Queue(hl.csr.req)
 | 
			
		||||
      hl.csr.resp <> Queue(tile.io.host.csr.resp)
 | 
			
		||||
      hl.debug_stats_csr := tile.io.host.debug_stats_csr
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Connect the uncore to the tile memory ports, HostIO and MemIO
 | 
			
		||||
  uncore.io.tiles_cached <> tileList.map(_.io.cached).flatten
 | 
			
		||||
  uncore.io.tiles_uncached <> tileList.map(_.io.uncached).flatten
 | 
			
		||||
  io.host <> uncore.io.host
 | 
			
		||||
  if (p(UseBackupMemoryPort)) { io.mem_backup_ctrl <> uncore.io.mem_backup_ctrl }
 | 
			
		||||
  else { uncore.io.mem_backup_ctrl.en := Bool(false) }
 | 
			
		||||
 | 
			
		||||
  io.mem.zip(uncore.io.mem).foreach { case (outer, inner) =>
 | 
			
		||||
    TopUtils.connectNasti(outer, inner)
 | 
			
		||||
@@ -146,7 +146,7 @@ class Uncore(implicit val p: Parameters) extends Module
 | 
			
		||||
    val tiles_cached = Vec(nCachedTilePorts, new ClientTileLinkIO).flip
 | 
			
		||||
    val tiles_uncached = Vec(nUncachedTilePorts, new ClientUncachedTileLinkIO).flip
 | 
			
		||||
    val htif = Vec(nTiles, new HtifIO).flip
 | 
			
		||||
    val mem_backup_ctrl = new MemBackupCtrlIO
 | 
			
		||||
    val timerIRQs = Vec(nTiles, Bool()).asOutput
 | 
			
		||||
    val mmio = new NastiIO
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
@@ -160,25 +160,20 @@ class Uncore(implicit val p: Parameters) extends Module
 | 
			
		||||
  for (i <- 0 until nTiles) {
 | 
			
		||||
    io.htif(i).reset := htif.io.cpu(i).reset
 | 
			
		||||
    io.htif(i).id := htif.io.cpu(i).id
 | 
			
		||||
    htif.io.cpu(i).debug_stats_csr <> io.htif(i).debug_stats_csr
 | 
			
		||||
 | 
			
		||||
    val csr_arb = Module(new SmiArbiter(2, xLen, csrAddrBits))
 | 
			
		||||
    csr_arb.io.in(0) <> htif.io.cpu(i).csr
 | 
			
		||||
    csr_arb.io.in(1) <> outmemsys.io.csr(i)
 | 
			
		||||
    io.htif(i).csr <> csr_arb.io.out
 | 
			
		||||
    io.htif(i).csr <> htif.io.cpu(i).csr
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Arbitrate SCR access between MMIO and HTIF
 | 
			
		||||
  val addrHashMap = new AddrHashMap(p(GlobalAddrMap))
 | 
			
		||||
  val scrFile = Module(new SCRFile("UNCORE_SCR",addrHashMap("conf:scr").start))
 | 
			
		||||
  val scrArb = Module(new SmiArbiter(2, scrDataBits, scrAddrBits))
 | 
			
		||||
  scrArb.io.in(0) <> htif.io.scr
 | 
			
		||||
  scrArb.io.in(1) <> outmemsys.io.scr
 | 
			
		||||
  scrFile.io.smi <> scrArb.io.out
 | 
			
		||||
  val addrMap = p(GlobalAddrMap)
 | 
			
		||||
  val addrHashMap = new AddrHashMap(addrMap)
 | 
			
		||||
  val memSize = addrHashMap("mem").size
 | 
			
		||||
  val scrFile = Module(new SCRFile("UNCORE_SCR", 0))
 | 
			
		||||
  scrFile.io.smi <> htif.io.scr
 | 
			
		||||
  scrFile.io.scr.attach(Wire(init = UInt(nTiles)), "N_CORES")
 | 
			
		||||
  scrFile.io.scr.attach(Wire(init = UInt(addrHashMap("mem").size >> 20)), "MMIO_BASE")
 | 
			
		||||
  scrFile.io.scr.attach(Wire(init = UInt(memSize >> 20)), "MMIO_BASE")
 | 
			
		||||
  // scrFile.io.scr <> (... your SCR connections ...)
 | 
			
		||||
 | 
			
		||||
  buildMMIONetwork(p.alterPartial({case TLId => "MMIO_Outermost"}))
 | 
			
		||||
 | 
			
		||||
  // Configures the enabled memory channels.  This can't be changed while the
 | 
			
		||||
  // chip is actively using memory, as it both drops Nasti messages and garbles
 | 
			
		||||
  // all of memory.
 | 
			
		||||
@@ -187,19 +182,40 @@ class Uncore(implicit val p: Parameters) extends Module
 | 
			
		||||
    "MEMORY_CHANNEL_MUX_SELECT")
 | 
			
		||||
  outmemsys.io.memory_channel_mux_select := memory_channel_mux_select
 | 
			
		||||
 | 
			
		||||
  val deviceTree = Module(new NastiROM(p(ConfigString).toSeq))
 | 
			
		||||
  deviceTree.io <> outmemsys.io.deviceTree
 | 
			
		||||
 | 
			
		||||
  // Wire the htif to the memory port(s) and host interface
 | 
			
		||||
  io.host.debug_stats_csr := htif.io.host.debug_stats_csr
 | 
			
		||||
  io.mem <> outmemsys.io.mem
 | 
			
		||||
  if(p(UseHtifClockDiv)) {
 | 
			
		||||
    outmemsys.io.mem_backup_en := io.mem_backup_ctrl.en
 | 
			
		||||
    VLSIUtils.padOutHTIFWithDividedClock(htif.io.host, scrFile.io.scr,
 | 
			
		||||
      outmemsys.io.mem_backup, io.mem_backup_ctrl, io.host, htifW)
 | 
			
		||||
    VLSIUtils.padOutHTIFWithDividedClock(htif.io.host, scrFile.io.scr, io.host, htifW)
 | 
			
		||||
  } else {
 | 
			
		||||
    io.host.out <> htif.io.host.out
 | 
			
		||||
    htif.io.host.in <> io.host.in
 | 
			
		||||
    io.host <> htif.io.host
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def buildMMIONetwork(implicit p: Parameters) = {
 | 
			
		||||
    val mmioNarrower = Module(new TileLinkIONarrower("L2toMMIO", "MMIO_Outermost"))
 | 
			
		||||
    val mmioNetwork = Module(new TileLinkRecursiveInterconnect(1, addrMap.tail, memSize))
 | 
			
		||||
 | 
			
		||||
    mmioNarrower.io.in <> outmemsys.io.mmio
 | 
			
		||||
    mmioNetwork.io.in.head <> mmioNarrower.io.out
 | 
			
		||||
 | 
			
		||||
    if (p(UseStreamLoopback)) {
 | 
			
		||||
      val lo_width = p(StreamLoopbackWidth)
 | 
			
		||||
      val lo_size = p(StreamLoopbackSize)
 | 
			
		||||
      val lo_conv = Module(new NastiIOStreamIOConverter(lo_width))
 | 
			
		||||
      val lo_port = addrHashMap("devices:loopback").port - 1
 | 
			
		||||
      TopUtils.connectTilelinkNasti(lo_conv.io.nasti, mmioNetwork.io.out(lo_port))
 | 
			
		||||
      lo_conv.io.stream.in <> Queue(lo_conv.io.stream.out, lo_size)
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    val rtc = Module(new RTC(p(NTiles)))
 | 
			
		||||
    val rtcAddr = addrHashMap("conf:rtc")
 | 
			
		||||
    val rtcPort = rtcAddr.port - 1
 | 
			
		||||
    require(rtc.size <= rtcAddr.size)
 | 
			
		||||
    rtc.io.tl <> mmioNetwork.io.out(rtcPort)
 | 
			
		||||
    io.timerIRQs := rtc.io.irqs
 | 
			
		||||
 | 
			
		||||
    val deviceTree = Module(new ROMSlave(p(ConfigString).toSeq))
 | 
			
		||||
    val dtPort = addrHashMap("conf:devicetree").port - 1
 | 
			
		||||
    deviceTree.io <> mmioNetwork.io.out(dtPort)
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -213,25 +229,18 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
 | 
			
		||||
    val htif_uncached = (new ClientUncachedTileLinkIO).flip
 | 
			
		||||
    val incoherent = Vec(nTiles, Bool()).asInput
 | 
			
		||||
    val mem = Vec(nMemChannels, new NastiIO)
 | 
			
		||||
    val mem_backup = new MemSerializedIO(htifW)
 | 
			
		||||
    val mem_backup_en = Bool(INPUT)
 | 
			
		||||
    val memory_channel_mux_select = UInt(INPUT, log2Up(memoryChannelMuxConfigs.size))
 | 
			
		||||
    val csr = Vec(nTiles, new SmiIO(xLen, csrAddrBits))
 | 
			
		||||
    val scr = new SmiIO(xLen, scrAddrBits)
 | 
			
		||||
    val deviceTree = new NastiIO
 | 
			
		||||
    val mmio = new ClientUncachedTileLinkIO()(p.alterPartial({case TLId => "L2toMMIO"}))
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val addrMap = p(GlobalAddrMap)
 | 
			
		||||
  val addrHashMap = new AddrHashMap(addrMap)
 | 
			
		||||
  val memSize = addrHashMap("mem").size
 | 
			
		||||
  val addrHashMap = new AddrHashMap(p(GlobalAddrMap))
 | 
			
		||||
 | 
			
		||||
  // Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory
 | 
			
		||||
  // Cached ports are first in client list, making sharerToClientId just an indentity function
 | 
			
		||||
  // addrToBank is sed to hash physical addresses (of cache blocks) to banks (and thereby memory channels)
 | 
			
		||||
  def sharerToClientId(sharerId: UInt) = sharerId
 | 
			
		||||
  def addrToBank(addr: Bits): UInt = {
 | 
			
		||||
    val isMemory = addrHashMap.isInRegion("mem",
 | 
			
		||||
      addr.toUInt << log2Up(p(CacheBlockBytes)))
 | 
			
		||||
  def addrToBank(addr: UInt): UInt = {
 | 
			
		||||
    val isMemory = addrHashMap.isInRegion("mem", addr << log2Up(p(CacheBlockBytes)))
 | 
			
		||||
    Mux(isMemory,
 | 
			
		||||
      if (nBanks > 1) addr(lsb + log2Up(nBanks) - 1, lsb) else UInt(0),
 | 
			
		||||
      UInt(nBanks))
 | 
			
		||||
@@ -248,13 +257,12 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
 | 
			
		||||
    case InnerTLId => "L1toL2"
 | 
			
		||||
    case OuterTLId => "L2toMMIO"
 | 
			
		||||
  })))
 | 
			
		||||
 | 
			
		||||
  val rtc = Module(new RTC(CSRs.mtime))
 | 
			
		||||
  io.mmio <> mmioManager.io.outer
 | 
			
		||||
 | 
			
		||||
  // Wire the tiles and htif to the TileLink client ports of the L1toL2 network,
 | 
			
		||||
  // and coherence manager(s) to the other side
 | 
			
		||||
  l1tol2net.io.clients_cached <> io.tiles_cached
 | 
			
		||||
  l1tol2net.io.clients_uncached <> io.tiles_uncached ++ Seq(rtc.io, io.htif_uncached)
 | 
			
		||||
  l1tol2net.io.clients_uncached <> io.tiles_uncached ++ Seq(io.htif_uncached)
 | 
			
		||||
  l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) :+ mmioManager.io.inner
 | 
			
		||||
 | 
			
		||||
  // Create a converter between TileLinkIO and MemIO for each channel
 | 
			
		||||
@@ -262,7 +270,6 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
 | 
			
		||||
  val outermostTLParams = p.alterPartial({case TLId => "Outermost"})
 | 
			
		||||
  val backendBuffering = TileLinkDepths(0,0,0,0,0)
 | 
			
		||||
 | 
			
		||||
 | 
			
		||||
  // TODO: the code to print this stuff should live somewhere else
 | 
			
		||||
  println("Generated Address Map")
 | 
			
		||||
  for ((name, base, size, _, _) <- addrHashMap.sortedEntries) {
 | 
			
		||||
@@ -295,67 +302,6 @@ class OuterMemorySystem(implicit val p: Parameters) extends Module with HasTopLe
 | 
			
		||||
    mem_ic.io.in(i) <> narrow.io.out
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val mmioOutermostTLParams = p.alterPartial({case TLId => "MMIO_Outermost"})
 | 
			
		||||
 | 
			
		||||
  val mmio_narrow = Module(new TileLinkIONarrower("L2toMMIO", "MMIO_Outermost"))
 | 
			
		||||
  val mmio_net = Module(new TileLinkRecursiveInterconnect(
 | 
			
		||||
    1, addrHashMap.nEntries - 1, addrMap.tail, memSize)(mmioOutermostTLParams))
 | 
			
		||||
 | 
			
		||||
  //val mmio_conv = Module(new NastiIOTileLinkIOConverter()(outermostTLParams))
 | 
			
		||||
  mmio_narrow.io.in <> mmioManager.io.outer
 | 
			
		||||
  mmio_net.io.in.head <> mmio_narrow.io.out
 | 
			
		||||
 | 
			
		||||
  def connectTilelinkNasti(nasti: NastiIO, tl: ClientUncachedTileLinkIO)(implicit p: Parameters) = {
 | 
			
		||||
    val conv = Module(new NastiIOTileLinkIOConverter())
 | 
			
		||||
    conv.io.tl <> tl
 | 
			
		||||
    TopUtils.connectNasti(nasti, conv.io.nasti)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  for (i <- 0 until nTiles) {
 | 
			
		||||
    val csrName = s"conf:csr$i"
 | 
			
		||||
    val csrPort = addrHashMap(csrName).port - 1
 | 
			
		||||
    val conv = Module(new SmiIONastiIOConverter(xLen, csrAddrBits))
 | 
			
		||||
    connectTilelinkNasti(conv.io.nasti, mmio_net.io.out(csrPort))(mmioOutermostTLParams)
 | 
			
		||||
    io.csr(i) <> conv.io.smi
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val scrPort = addrHashMap("conf:scr").port - 1
 | 
			
		||||
  val scr_conv = Module(new SmiIONastiIOConverter(scrDataBits, scrAddrBits))
 | 
			
		||||
  connectTilelinkNasti(scr_conv.io.nasti, mmio_net.io.out(scrPort))(mmioOutermostTLParams)
 | 
			
		||||
  io.scr <> scr_conv.io.smi
 | 
			
		||||
 | 
			
		||||
  if (p(UseStreamLoopback)) {
 | 
			
		||||
    val lo_width = p(StreamLoopbackWidth)
 | 
			
		||||
    val lo_size = p(StreamLoopbackSize)
 | 
			
		||||
    val lo_conv = Module(new NastiIOStreamIOConverter(lo_width))
 | 
			
		||||
    val lo_port = addrHashMap("devices:loopback").port - 1
 | 
			
		||||
    connectTilelinkNasti(lo_conv.io.nasti, mmio_net.io.out(lo_port))(mmioOutermostTLParams)
 | 
			
		||||
    lo_conv.io.stream.in <> Queue(lo_conv.io.stream.out, lo_size)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  val dtPort = addrHashMap("conf:devicetree").port - 1
 | 
			
		||||
  connectTilelinkNasti(io.deviceTree, mmio_net.io.out(dtPort))(mmioOutermostTLParams)
 | 
			
		||||
 | 
			
		||||
  val mem_channels = Wire(Vec(nMemChannels, new NastiIO))
 | 
			
		||||
 | 
			
		||||
  mem_channels.zip(mem_ic.io.out).foreach { case (ch, out) =>
 | 
			
		||||
    connectTilelinkNasti(ch, out)(outermostTLParams)
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Create a SerDes for backup memory port
 | 
			
		||||
  if(p(UseBackupMemoryPort)) {
 | 
			
		||||
    VLSIUtils.doOuterMemorySystemSerdes(
 | 
			
		||||
      mem_channels, io.mem, io.mem_backup, io.mem_backup_en,
 | 
			
		||||
      1, htifW, p(CacheBlockOffsetBits))
 | 
			
		||||
    for (i <- 1 until nMemChannels) { io.mem(i) <> mem_channels(i) }
 | 
			
		||||
    val mem_request = mem_channels.map(io => io.ar.valid || io.aw.valid).reduce(_ || _)
 | 
			
		||||
    val config_nchannels = Vec(channelConfigs.map(i => UInt(i)))(io.memory_channel_mux_select)
 | 
			
		||||
    assert(!mem_request || !io.mem_backup_en || config_nchannels === UInt(1),
 | 
			
		||||
           "Backup memory port only works when 1 memory channel is enabled")
 | 
			
		||||
    require(channelConfigs.sortWith(_ < _)(0) == 1,
 | 
			
		||||
                  "Backup memory port requires a single memory port mux config")
 | 
			
		||||
  } else {
 | 
			
		||||
    io.mem <> mem_channels
 | 
			
		||||
    io.mem_backup.req.valid := Bool(false)
 | 
			
		||||
  }
 | 
			
		||||
  for ((nasti, tl) <- io.mem zip mem_ic.io.out)
 | 
			
		||||
    TopUtils.connectTilelinkNasti(nasti, tl)(outermostTLParams)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -22,7 +22,6 @@ object TestBenchGeneration extends FileSystemUtilities {
 | 
			
		||||
  wire [`HTIF_WIDTH-1:0] htif_in_bits;
 | 
			
		||||
  wire htif_in_ready, htif_out_valid;
 | 
			
		||||
  wire [`HTIF_WIDTH-1:0] htif_out_bits;
 | 
			
		||||
  wire htif_out_stats;
 | 
			
		||||
 | 
			
		||||
  wire mem_bk_in_valid;
 | 
			
		||||
  wire mem_bk_out_valid;
 | 
			
		||||
@@ -73,12 +72,6 @@ object TestBenchGeneration extends FileSystemUtilities {
 | 
			
		||||
  wire htif_out_valid_delay;
 | 
			
		||||
  wire htif_out_ready_delay;
 | 
			
		||||
  wire [`HTIF_WIDTH-1:0] htif_out_bits_delay;
 | 
			
		||||
  
 | 
			
		||||
  wire htif_out_stats_delay;
 | 
			
		||||
 | 
			
		||||
  wire mem_bk_out_ready_delay;
 | 
			
		||||
  wire mem_bk_in_valid_delay;
 | 
			
		||||
  wire mem_bk_out_valid_delay;
 | 
			
		||||
 | 
			
		||||
  assign #0.1 htif_in_valid_delay = htif_in_valid;
 | 
			
		||||
  assign #0.1 htif_in_ready = htif_in_ready_delay;
 | 
			
		||||
@@ -87,12 +80,6 @@ object TestBenchGeneration extends FileSystemUtilities {
 | 
			
		||||
  assign #0.1 htif_out_valid = htif_out_valid_delay;
 | 
			
		||||
  assign #0.1 htif_out_ready_delay = htif_out_ready;
 | 
			
		||||
  assign #0.1 htif_out_bits = htif_out_bits_delay;
 | 
			
		||||
  
 | 
			
		||||
  assign #0.1 htif_out_stats = htif_out_stats_delay;
 | 
			
		||||
 | 
			
		||||
  assign #0.1 mem_bk_out_ready_delay = mem_bk_out_ready;
 | 
			
		||||
  assign #0.1 mem_bk_in_valid_delay = mem_bk_in_valid;
 | 
			
		||||
  assign #0.1 mem_bk_out_valid = mem_bk_out_valid_delay;
 | 
			
		||||
"""
 | 
			
		||||
 | 
			
		||||
    val nasti_delays = (0 until nMemChannel) map { i => s"""
 | 
			
		||||
@@ -216,8 +203,6 @@ object TestBenchGeneration extends FileSystemUtilities {
 | 
			
		||||
 | 
			
		||||
    val instantiation = s"""
 | 
			
		||||
`ifdef FPGA
 | 
			
		||||
  assign mem_bk_out_valid_delay = 1'b0;
 | 
			
		||||
  assign htif_out_stats_delay = 1'b0;
 | 
			
		||||
  assign htif_clk = clk;
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
@@ -231,25 +216,9 @@ object TestBenchGeneration extends FileSystemUtilities {
 | 
			
		||||
`ifndef FPGA
 | 
			
		||||
    .io_host_clk(htif_clk),
 | 
			
		||||
    .io_host_clk_edge(),
 | 
			
		||||
    .io_host_debug_stats_csr(htif_out_stats_delay),
 | 
			
		||||
 | 
			
		||||
`ifdef MEM_BACKUP_EN
 | 
			
		||||
    .io_mem_backup_ctrl_en(1'b1),
 | 
			
		||||
`else
 | 
			
		||||
    .io_mem_backup_ctrl_en(1'b0),
 | 
			
		||||
`endif // MEM_BACKUP_EN
 | 
			
		||||
    .io_mem_backup_ctrl_in_valid(mem_bk_in_valid_delay),
 | 
			
		||||
    .io_mem_backup_ctrl_out_ready(mem_bk_out_ready_delay),
 | 
			
		||||
    .io_mem_backup_ctrl_out_valid(mem_bk_out_valid_delay),
 | 
			
		||||
`else
 | 
			
		||||
    .io_host_clk (),
 | 
			
		||||
    .io_host_clk_edge (),
 | 
			
		||||
    .io_host_debug_stats_csr (),
 | 
			
		||||
 | 
			
		||||
    .io_mem_backup_ctrl_en (1'b0),
 | 
			
		||||
    .io_mem_backup_ctrl_in_valid (1'b0),
 | 
			
		||||
    .io_mem_backup_ctrl_out_ready (1'b0),
 | 
			
		||||
    .io_mem_backup_ctrl_out_valid (),
 | 
			
		||||
`endif // FPGA
 | 
			
		||||
 | 
			
		||||
    .io_host_in_valid(htif_in_valid_delay),
 | 
			
		||||
 
 | 
			
		||||
@@ -7,14 +7,6 @@ import cde.Parameters
 | 
			
		||||
import junctions._
 | 
			
		||||
import uncore._
 | 
			
		||||
 | 
			
		||||
class MemDessert(topParams: Parameters) extends Module {
 | 
			
		||||
  implicit val p = topParams
 | 
			
		||||
  val io = new MemDesserIO(p(HtifKey).width)
 | 
			
		||||
  val x = Module(new MemDesser(p(HtifKey).width))
 | 
			
		||||
  x.io.narrow <> io.narrow
 | 
			
		||||
  io.wide <> x.io.wide
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
object VLSIUtils {
 | 
			
		||||
  def doOuterMemorySystemSerdes(
 | 
			
		||||
      llcs: Seq[NastiIO],
 | 
			
		||||
@@ -65,6 +57,30 @@ object VLSIUtils {
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  private def makeHTIFClockDivider(scr: SCRIO, host: HostIO, htifW: Int) = {
 | 
			
		||||
    val hio = Module((new SlowIO(512)) { Bits(width = htifW) })
 | 
			
		||||
    hio.io.set_divisor.valid := scr.wen && (scr.waddr === UInt(63))
 | 
			
		||||
    hio.io.set_divisor.bits := scr.wdata
 | 
			
		||||
    scr.rdata(63) := hio.io.divisor
 | 
			
		||||
    scr.allocate(63, "HTIF_IO_CLOCK_DIVISOR")
 | 
			
		||||
    host.clk := hio.io.clk_slow
 | 
			
		||||
    host.clk_edge := Reg(next=host.clk && !Reg(next=host.clk))
 | 
			
		||||
    hio
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def padOutHTIFWithDividedClock(
 | 
			
		||||
      htif: HostIO,
 | 
			
		||||
      scr: SCRIO,
 | 
			
		||||
      host: HostIO,
 | 
			
		||||
      htifW: Int) {
 | 
			
		||||
    val hio = makeHTIFClockDivider(scr, host, htifW)
 | 
			
		||||
 | 
			
		||||
    hio.io.out_fast <> htif.out
 | 
			
		||||
    host.out <> hio.io.out_slow
 | 
			
		||||
    hio.io.in_slow <> host.in
 | 
			
		||||
    htif.in <> hio.io.in_fast
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  def padOutHTIFWithDividedClock(
 | 
			
		||||
      htif: HostIO,
 | 
			
		||||
      scr: SCRIO,
 | 
			
		||||
@@ -72,11 +88,7 @@ object VLSIUtils {
 | 
			
		||||
      parent: MemBackupCtrlIO,
 | 
			
		||||
      host: HostIO,
 | 
			
		||||
      htifW: Int) {
 | 
			
		||||
    val hio = Module((new SlowIO(512)) { Bits(width = htifW+1) })
 | 
			
		||||
    hio.io.set_divisor.valid := scr.wen && (scr.waddr === UInt(63))
 | 
			
		||||
    hio.io.set_divisor.bits := scr.wdata
 | 
			
		||||
    scr.rdata(63) := hio.io.divisor
 | 
			
		||||
    scr.allocate(63, "HTIF_IO_CLOCK_DIVISOR")
 | 
			
		||||
    val hio = makeHTIFClockDivider(scr, host, htifW+1)
 | 
			
		||||
 | 
			
		||||
    hio.io.out_fast.valid := htif.out.valid || child.req.valid
 | 
			
		||||
    hio.io.out_fast.bits := Cat(htif.out.valid, Mux(htif.out.valid, htif.out.bits, child.req.bits))
 | 
			
		||||
@@ -96,7 +108,5 @@ object VLSIUtils {
 | 
			
		||||
    htif.in.valid := hio.io.in_fast.valid && !hio.io.in_fast.bits(htifW)
 | 
			
		||||
    htif.in.bits := hio.io.in_fast.bits
 | 
			
		||||
    hio.io.in_fast.ready := Mux(hio.io.in_fast.bits(htifW), Bool(true), htif.in.ready)
 | 
			
		||||
    host.clk := hio.io.clk_slow
 | 
			
		||||
    host.clk_edge := Reg(next=host.clk && !Reg(next=host.clk))
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
							
								
								
									
										2
									
								
								uncore
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								uncore
									
									
									
									
									
								
							 Submodule uncore updated: 6aac33ff3e...291a0bbf58
									
								
							@@ -7,9 +7,7 @@
 | 
			
		||||
sim_vsrcs = \
 | 
			
		||||
	$(generated_dir)/$(MODEL).$(CONFIG).v \
 | 
			
		||||
	$(generated_dir)/consts.$(CONFIG).vh \
 | 
			
		||||
	$(generated_dir)/memdessertMemDessert.$(CONFIG).v \
 | 
			
		||||
	$(base_dir)/vsrc/$(TB).v \
 | 
			
		||||
	$(base_dir)/vsrc/backup_mem.v \
 | 
			
		||||
 | 
			
		||||
# C sources
 | 
			
		||||
 | 
			
		||||
 
 | 
			
		||||
@@ -10,9 +10,6 @@ $(generated_dir)/$(MODEL).$(CONFIG).v $(generated_dir)/$(MODEL).$(CONFIG).d $(ge
 | 
			
		||||
	  $(mem_gen) $(generated_dir)/$(MODEL).$(CONFIG).conf >> $(generated_dir)/$(MODEL).$(CONFIG).v; \
 | 
			
		||||
	fi
 | 
			
		||||
 | 
			
		||||
$(generated_dir)/memdessertMemDessert.$(CONFIG).v $(generated_dir)/memdessertMemDessert.$(CONFIG).d: $(base_dir)/$(src_path)/*.scala $(base_dir)/uncore/$(src_path)/*.scala
 | 
			
		||||
	cd $(base_dir) && mkdir -p $(generated_dir) && $(SBT) "run $(PROJECT) MemDessert $(CONFIG) --backend v --targetDir $(generated_dir) --W0W --moduleNamePrefix memdessert --configName $(CONFIG)"
 | 
			
		||||
 | 
			
		||||
else
 | 
			
		||||
 | 
			
		||||
FIRRTL ?= $(base_dir)/firrtl/utils/bin/firrtl
 | 
			
		||||
@@ -23,7 +20,6 @@ $(FIRRTL):
 | 
			
		||||
# If I don't mark these as .SECONDARY then make will delete these internal
 | 
			
		||||
# files.
 | 
			
		||||
.SECONDARY: $(generated_dir)/$(MODEL).$(CONFIG).fir
 | 
			
		||||
.SECONDARY: $(generated_dir)/MemDessert.$(CONFIG).fir
 | 
			
		||||
 | 
			
		||||
$(generated_dir)/%.$(CONFIG).fir: $(chisel_srcs)
 | 
			
		||||
	mkdir -p $(dir $@)
 | 
			
		||||
@@ -34,12 +30,6 @@ $(generated_dir)/%.v $(generated_dir)/%.prm: $(generated_dir)/%.fir $(FIRRTL)
 | 
			
		||||
	mkdir -p $(dir $@)
 | 
			
		||||
	$(FIRRTL) $(patsubst %,-i %,$(filter %.fir,$^)) -o $@ -X verilog
 | 
			
		||||
 | 
			
		||||
$(generated_dir)/memdessertMemDessert.$(CONFIG).v: $(generated_dir)/MemDessert.$(CONFIG).v
 | 
			
		||||
	cat $(filter %.v,$^) \
 | 
			
		||||
		| sed 's@MemDessert@memdessertMemDessert@g' \
 | 
			
		||||
		| sed 's@Queue@memdessetQueue@g' \
 | 
			
		||||
		> $@
 | 
			
		||||
 | 
			
		||||
endif
 | 
			
		||||
 | 
			
		||||
$(generated_dir)/consts.$(CONFIG).vh: $(generated_dir)/$(MODEL).$(CONFIG).prm
 | 
			
		||||
 
 | 
			
		||||
@@ -1,122 +0,0 @@
 | 
			
		||||
// See LICENSE for license details.
 | 
			
		||||
 | 
			
		||||
`define ceilLog2(x) ( \
 | 
			
		||||
(x) > 2**30 ? 31 : \
 | 
			
		||||
(x) > 2**29 ? 30 : \
 | 
			
		||||
(x) > 2**28 ? 29 : \
 | 
			
		||||
(x) > 2**27 ? 28 : \
 | 
			
		||||
(x) > 2**26 ? 27 : \
 | 
			
		||||
(x) > 2**25 ? 26 : \
 | 
			
		||||
(x) > 2**24 ? 25 : \
 | 
			
		||||
(x) > 2**23 ? 24 : \
 | 
			
		||||
(x) > 2**22 ? 23 : \
 | 
			
		||||
(x) > 2**21 ? 22 : \
 | 
			
		||||
(x) > 2**20 ? 21 : \
 | 
			
		||||
(x) > 2**19 ? 20 : \
 | 
			
		||||
(x) > 2**18 ? 19 : \
 | 
			
		||||
(x) > 2**17 ? 18 : \
 | 
			
		||||
(x) > 2**16 ? 17 : \
 | 
			
		||||
(x) > 2**15 ? 16 : \
 | 
			
		||||
(x) > 2**14 ? 15 : \
 | 
			
		||||
(x) > 2**13 ? 14 : \
 | 
			
		||||
(x) > 2**12 ? 13 : \
 | 
			
		||||
(x) > 2**11 ? 12 : \
 | 
			
		||||
(x) > 2**10 ? 11 : \
 | 
			
		||||
(x) > 2**9 ? 10 : \
 | 
			
		||||
(x) > 2**8 ? 9 : \
 | 
			
		||||
(x) > 2**7 ? 8 : \
 | 
			
		||||
(x) > 2**6 ? 7 : \
 | 
			
		||||
(x) > 2**5 ? 6 : \
 | 
			
		||||
(x) > 2**4 ? 5 : \
 | 
			
		||||
(x) > 2**3 ? 4 : \
 | 
			
		||||
(x) > 2**2 ? 3 : \
 | 
			
		||||
(x) > 2**1 ? 2 : \
 | 
			
		||||
(x) > 2**0 ? 1 : 0)
 | 
			
		||||
 | 
			
		||||
`ifdef MEM_BACKUP_EN
 | 
			
		||||
module BackupMemory
 | 
			
		||||
(
 | 
			
		||||
  input         clk,
 | 
			
		||||
  input         reset,
 | 
			
		||||
 | 
			
		||||
  input                       mem_req_valid,
 | 
			
		||||
  output                      mem_req_ready,
 | 
			
		||||
  input                       mem_req_rw,
 | 
			
		||||
  input [`MIF_ADDR_BITS-1:0]  mem_req_addr,
 | 
			
		||||
  input [`MIF_TAG_BITS-1:0]   mem_req_tag,
 | 
			
		||||
 | 
			
		||||
  input                       mem_req_data_valid,
 | 
			
		||||
  output                      mem_req_data_ready,
 | 
			
		||||
  input [`MIF_DATA_BITS-1:0]  mem_req_data_bits,
 | 
			
		||||
 | 
			
		||||
  output reg                  mem_resp_valid,
 | 
			
		||||
  output reg [`MIF_DATA_BITS-1:0] mem_resp_data,
 | 
			
		||||
  output reg [`MIF_TAG_BITS-1:0] mem_resp_tag
 | 
			
		||||
);
 | 
			
		||||
 | 
			
		||||
  localparam DATA_CYCLES = 8;
 | 
			
		||||
  localparam DEPTH = 2*1024*1024;
 | 
			
		||||
 | 
			
		||||
  reg [`ceilLog2(DATA_CYCLES)-1:0] cnt;
 | 
			
		||||
  reg [`MIF_TAG_BITS-1:0] tag;
 | 
			
		||||
  reg state_busy, state_rw;
 | 
			
		||||
  reg [`MIF_ADDR_BITS-1:0] addr;
 | 
			
		||||
 | 
			
		||||
  reg [127:0] ram [DEPTH-1:0];
 | 
			
		||||
  wire [`ceilLog2(DEPTH)-1:0] ram_addr = state_busy  ?         {addr[`ceilLog2(DEPTH/DATA_CYCLES)-1:0], cnt}
 | 
			
		||||
                                                     : {mem_req_addr[`ceilLog2(DEPTH/DATA_CYCLES)-1:0], cnt};
 | 
			
		||||
  wire do_read = mem_req_valid && mem_req_ready && !mem_req_rw || state_busy && !state_rw;
 | 
			
		||||
  wire do_write = mem_req_data_valid && mem_req_data_ready;
 | 
			
		||||
 | 
			
		||||
  initial
 | 
			
		||||
  begin : zero
 | 
			
		||||
    integer i;
 | 
			
		||||
    for (i = 0; i < DEPTH; i = i+1)
 | 
			
		||||
      ram[i] = 1'b0;
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  always @(posedge clk)
 | 
			
		||||
  begin
 | 
			
		||||
    if (reset)
 | 
			
		||||
      state_busy <= 1'b0;
 | 
			
		||||
    else if ((do_read || do_write) && cnt == DATA_CYCLES-1)
 | 
			
		||||
      state_busy <= 1'b0;
 | 
			
		||||
    else if (mem_req_valid && mem_req_ready)
 | 
			
		||||
      state_busy <= 1'b1;
 | 
			
		||||
 | 
			
		||||
    if (!state_busy && mem_req_valid)
 | 
			
		||||
    begin
 | 
			
		||||
      state_rw <= mem_req_rw;
 | 
			
		||||
      tag <= mem_req_tag;
 | 
			
		||||
      addr <= mem_req_addr;
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if (reset)
 | 
			
		||||
      cnt <= 1'b0;
 | 
			
		||||
    else if(do_read || do_write)
 | 
			
		||||
      cnt <= cnt + 1'b1;
 | 
			
		||||
 | 
			
		||||
    if (do_write)
 | 
			
		||||
      if (ram_addr[0] == 1'b0)
 | 
			
		||||
        ram[ram_addr/2][63:0] <= mem_req_data_bits;
 | 
			
		||||
      else
 | 
			
		||||
        ram[ram_addr/2][127:64] <= mem_req_data_bits;
 | 
			
		||||
    else
 | 
			
		||||
      if (ram_addr[0] == 1'b0)
 | 
			
		||||
        mem_resp_data <= ram[ram_addr/2][63:0];
 | 
			
		||||
      else
 | 
			
		||||
        mem_resp_data <= ram[ram_addr/2][127:64];
 | 
			
		||||
 | 
			
		||||
    if (reset)
 | 
			
		||||
      mem_resp_valid <= 1'b0;
 | 
			
		||||
    else
 | 
			
		||||
      mem_resp_valid <= do_read;
 | 
			
		||||
 | 
			
		||||
    mem_resp_tag <= state_busy ? tag : mem_req_tag;
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  assign mem_req_ready = !state_busy;
 | 
			
		||||
  assign mem_req_data_ready = state_busy && state_rw;
 | 
			
		||||
 | 
			
		||||
endmodule
 | 
			
		||||
`endif
 | 
			
		||||
@@ -75,8 +75,6 @@ module rocketTestHarness;
 | 
			
		||||
  reg [1023:0] loadmem = 0;
 | 
			
		||||
  reg [1023:0] vcdplusfile = 0;
 | 
			
		||||
  reg [1023:0] vcdfile = 0;
 | 
			
		||||
  reg          stats_active = 0;
 | 
			
		||||
  reg          stats_tracking = 0;
 | 
			
		||||
  reg          verbose = 0;
 | 
			
		||||
  wire         printf_cond = verbose && !reset;
 | 
			
		||||
  integer      stderr = 32'h80000002;
 | 
			
		||||
@@ -88,81 +86,11 @@ module rocketTestHarness;
 | 
			
		||||
    r_reset <= reset;
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  wire mem_bk_req_valid, mem_bk_req_rw, mem_bk_req_data_valid;
 | 
			
		||||
  wire [`MIF_TAG_BITS-1:0] mem_bk_req_tag;
 | 
			
		||||
  wire [`MIF_ADDR_BITS-1:0] mem_bk_req_addr;
 | 
			
		||||
  wire [`MIF_DATA_BITS-1:0] mem_bk_req_data_bits;
 | 
			
		||||
  wire mem_bk_req_ready, mem_bk_req_data_ready, mem_bk_resp_valid;
 | 
			
		||||
  wire [`MIF_TAG_BITS-1:0]  mem_bk_resp_tag;
 | 
			
		||||
  wire [`MIF_DATA_BITS-1:0] mem_bk_resp_data;
 | 
			
		||||
 | 
			
		||||
`ifdef MEM_BACKUP_EN
 | 
			
		||||
  memdessertMemDessert dessert
 | 
			
		||||
  (
 | 
			
		||||
    .clk(htif_clk),
 | 
			
		||||
    .reset(reset),
 | 
			
		||||
 | 
			
		||||
    .io_narrow_req_valid(mem_bk_out_valid),
 | 
			
		||||
    .io_narrow_req_ready(mem_bk_out_ready),
 | 
			
		||||
    .io_narrow_req_bits(htif_out_bits),
 | 
			
		||||
 | 
			
		||||
    .io_narrow_resp_valid(mem_bk_in_valid),
 | 
			
		||||
    .io_narrow_resp_bits(mem_in_bits),
 | 
			
		||||
 | 
			
		||||
    .io_wide_req_cmd_valid(mem_bk_req_valid),
 | 
			
		||||
    .io_wide_req_cmd_ready(mem_bk_req_ready),
 | 
			
		||||
    .io_wide_req_cmd_bits_rw(mem_bk_req_rw),
 | 
			
		||||
    .io_wide_req_cmd_bits_addr(mem_bk_req_addr),
 | 
			
		||||
    .io_wide_req_cmd_bits_tag(mem_bk_req_tag),
 | 
			
		||||
 | 
			
		||||
    .io_wide_req_data_valid(mem_bk_req_data_valid),
 | 
			
		||||
    .io_wide_req_data_ready(mem_bk_req_data_ready),
 | 
			
		||||
    .io_wide_req_data_bits_data(mem_bk_req_data_bits),
 | 
			
		||||
 | 
			
		||||
    .io_wide_resp_valid(mem_bk_resp_valid),
 | 
			
		||||
    .io_wide_resp_ready(),
 | 
			
		||||
    .io_wide_resp_bits_data(mem_bk_resp_data),
 | 
			
		||||
    .io_wide_resp_bits_tag(mem_bk_resp_tag)
 | 
			
		||||
  );
 | 
			
		||||
 | 
			
		||||
  BackupMemory mem
 | 
			
		||||
  (
 | 
			
		||||
    .clk(htif_clk),
 | 
			
		||||
    .reset(reset),
 | 
			
		||||
 | 
			
		||||
    .mem_req_valid(mem_bk_req_valid),
 | 
			
		||||
    .mem_req_ready(mem_bk_req_ready),
 | 
			
		||||
    .mem_req_rw(mem_bk_req_rw),
 | 
			
		||||
    .mem_req_addr(mem_bk_req_addr),
 | 
			
		||||
    .mem_req_tag(mem_bk_req_tag),
 | 
			
		||||
 | 
			
		||||
    .mem_req_data_valid(mem_bk_req_data_valid),
 | 
			
		||||
    .mem_req_data_ready(mem_bk_req_data_ready),
 | 
			
		||||
    .mem_req_data_bits(mem_bk_req_data_bits),
 | 
			
		||||
 | 
			
		||||
    .mem_resp_valid(mem_bk_resp_valid),
 | 
			
		||||
    .mem_resp_data(mem_bk_resp_data),
 | 
			
		||||
    .mem_resp_tag(mem_bk_resp_tag)
 | 
			
		||||
  );
 | 
			
		||||
`else
 | 
			
		||||
  // set dessert outputs to zero when !backupmem_en
 | 
			
		||||
  assign mem_bk_out_ready = 1'b0; 
 | 
			
		||||
  assign mem_bk_in_valid = 1'b0;
 | 
			
		||||
  assign mem_in_bits = {`HTIF_WIDTH {1'b0}};   
 | 
			
		||||
  assign mem_bk_req_valid = 1'b0;
 | 
			
		||||
  assign mem_bk_req_ready = 1'b0;
 | 
			
		||||
  assign mem_bk_req_addr = {`MIF_ADDR_BITS {1'b0}};
 | 
			
		||||
  assign mem_bk_req_rw = 1'b0;
 | 
			
		||||
  assign mem_bk_req_tag = {`MIF_TAG_BITS {1'b0}};
 | 
			
		||||
  assign mem_bk_req_data_valid = 1'b0;
 | 
			
		||||
  assign mem_bk_req_data_bits = 16'd0; 
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
  reg htif_in_valid_premux;
 | 
			
		||||
  reg [`HTIF_WIDTH-1:0] htif_in_bits_premux;
 | 
			
		||||
  assign htif_in_bits = mem_bk_in_valid ? mem_in_bits : htif_in_bits_premux;
 | 
			
		||||
  assign htif_in_valid = htif_in_valid_premux && !mem_bk_in_valid;
 | 
			
		||||
  wire htif_in_ready_premux = htif_in_ready && !mem_bk_in_valid;
 | 
			
		||||
  assign htif_in_bits = htif_in_bits_premux;
 | 
			
		||||
  assign htif_in_valid = htif_in_valid_premux;
 | 
			
		||||
  wire htif_in_ready_premux = htif_in_ready;
 | 
			
		||||
  reg [31:0] exit = 0;
 | 
			
		||||
 | 
			
		||||
  always @(posedge htif_clk)
 | 
			
		||||
@@ -191,40 +119,6 @@ module rocketTestHarness;
 | 
			
		||||
  //-----------------------------------------------
 | 
			
		||||
  // Start the simulation
 | 
			
		||||
 | 
			
		||||
  // Some helper functions for turning on, stopping, and finishing stat tracking
 | 
			
		||||
  task start_stats;
 | 
			
		||||
  begin
 | 
			
		||||
    if(!reset || !stats_active)
 | 
			
		||||
      begin
 | 
			
		||||
`ifdef DEBUG
 | 
			
		||||
      if(vcdplusfile)
 | 
			
		||||
      begin
 | 
			
		||||
        $vcdpluson(0);
 | 
			
		||||
        $vcdplusmemon(0);
 | 
			
		||||
      end
 | 
			
		||||
      if(vcdfile)
 | 
			
		||||
      begin
 | 
			
		||||
        $dumpon;
 | 
			
		||||
      end
 | 
			
		||||
`endif
 | 
			
		||||
      assign stats_tracking = 1;
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
  endtask
 | 
			
		||||
  task stop_stats;
 | 
			
		||||
  begin
 | 
			
		||||
`ifdef DEBUG
 | 
			
		||||
    $vcdplusoff; $dumpoff;
 | 
			
		||||
`endif
 | 
			
		||||
    assign stats_tracking = 0;
 | 
			
		||||
  end
 | 
			
		||||
  endtask
 | 
			
		||||
`ifdef DEBUG
 | 
			
		||||
`define VCDPLUSCLOSE $vcdplusclose; $dumpoff;
 | 
			
		||||
`else
 | 
			
		||||
`define VCDPLUSCLOSE
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
  // Read input arguments and initialize
 | 
			
		||||
  initial
 | 
			
		||||
  begin
 | 
			
		||||
@@ -236,27 +130,22 @@ module rocketTestHarness;
 | 
			
		||||
`endif
 | 
			
		||||
    verbose = $test$plusargs("verbose");
 | 
			
		||||
`ifdef DEBUG
 | 
			
		||||
    stats_active = $test$plusargs("stats");
 | 
			
		||||
    if ($value$plusargs("vcdplusfile=%s", vcdplusfile))
 | 
			
		||||
    begin
 | 
			
		||||
      $vcdplusfile(vcdplusfile);
 | 
			
		||||
      $vcdpluson(0);
 | 
			
		||||
      $vcdplusmemon(0);
 | 
			
		||||
    end
 | 
			
		||||
 | 
			
		||||
    if ($value$plusargs("vcdfile=%s", vcdfile))
 | 
			
		||||
    begin
 | 
			
		||||
      $dumpfile(vcdfile);
 | 
			
		||||
      $dumpvars(0, dut);
 | 
			
		||||
      $dumpon;
 | 
			
		||||
    end
 | 
			
		||||
    if (!stats_active)
 | 
			
		||||
    begin
 | 
			
		||||
      start_stats;
 | 
			
		||||
    end
 | 
			
		||||
    else
 | 
			
		||||
    begin
 | 
			
		||||
      if(vcdfile)
 | 
			
		||||
      begin
 | 
			
		||||
        $dumpoff;
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
`define VCDPLUSCLOSE $vcdplusclose; $dumpoff;
 | 
			
		||||
`else
 | 
			
		||||
`define VCDPLUSCLOSE
 | 
			
		||||
`endif
 | 
			
		||||
 | 
			
		||||
    // Strobe reset
 | 
			
		||||
@@ -286,32 +175,6 @@ module rocketTestHarness;
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  //-----------------------------------------------
 | 
			
		||||
  // Tracing code
 | 
			
		||||
 | 
			
		||||
  always @(posedge clk)
 | 
			
		||||
  begin
 | 
			
		||||
    if(stats_active)
 | 
			
		||||
    begin
 | 
			
		||||
      if(!stats_tracking && htif_out_stats)
 | 
			
		||||
      begin
 | 
			
		||||
        start_stats;
 | 
			
		||||
      end
 | 
			
		||||
      if(stats_tracking && !htif_out_stats)
 | 
			
		||||
      begin
 | 
			
		||||
        stop_stats;
 | 
			
		||||
      end
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  always @(posedge htif_clk)
 | 
			
		||||
  begin
 | 
			
		||||
    if (verbose && mem_bk_req_valid && mem_bk_req_ready)
 | 
			
		||||
    begin
 | 
			
		||||
      $fdisplay(stderr, "MB: rw=%d addr=%x", mem_bk_req_rw, {mem_bk_req_addr,6'd0});
 | 
			
		||||
    end
 | 
			
		||||
  end
 | 
			
		||||
 | 
			
		||||
  always @(posedge clk)
 | 
			
		||||
  begin
 | 
			
		||||
    trace_count = trace_count + 1;
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user