Implement NASTI-based Mem/IO interconnect
This commit is contained in:
		
							
								
								
									
										2
									
								
								chisel
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								chisel
									
									
									
									
									
								
							 Submodule chisel updated: 1f01401e9b...179f5c6a6f
									
								
							 Submodule hardfloat updated: 1136e89f0f...83b76aa258
									
								
							 Submodule junctions updated: f98a4d64e7...3ad77802d2
									
								
							
							
								
								
									
										2
									
								
								rocket
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								rocket
									
									
									
									
									
								
							 Submodule rocket updated: caa109c376...7a520740dc
									
								
							| @@ -35,15 +35,13 @@ class DefaultConfig extends ChiselConfig ( | |||||||
|       case MIFTagBits => Dump("MEM_TAG_BITS", |       case MIFTagBits => Dump("MEM_TAG_BITS", | ||||||
|                           log2Up(site(NAcquireTransactors)+2) + |                           log2Up(site(NAcquireTransactors)+2) + | ||||||
|                           log2Up(site(NBanksPerMemoryChannel)) + |                           log2Up(site(NBanksPerMemoryChannel)) + | ||||||
|                           log2Up(site(NMemoryChannels)) + /* TODO: Remove for multichannel Top */ |                           log2Up(site(NMemoryChannels))) | ||||||
|                           1) |  | ||||||
|       case MIFDataBits => Dump("MEM_DATA_BITS", 128) |       case MIFDataBits => Dump("MEM_DATA_BITS", 128) | ||||||
|       case MIFAddrBits => Dump("MEM_ADDR_BITS", site(PAddrBits) - site(CacheBlockOffsetBits)) |       case MIFAddrBits => Dump("MEM_ADDR_BITS", site(PAddrBits) - site(CacheBlockOffsetBits)) | ||||||
|       case MIFDataBeats => site(TLDataBits)*site(TLDataBeats)/site(MIFDataBits) |       case MIFDataBeats => site(TLDataBits)*site(TLDataBeats)/site(MIFDataBits) | ||||||
|       case NASTIDataBits => site(MIFDataBits) |       case NASTIDataBits => site(MIFDataBits) | ||||||
|       case NASTIAddrBits => site(MIFAddrBits) |       case NASTIAddrBits => site(PAddrBits) | ||||||
|       case NASTIIdBits => site(MIFTagBits) |       case NASTIIdBits => site(MIFTagBits) | ||||||
|       case UseNASTI => false |  | ||||||
|       //Params used by all caches |       //Params used by all caches | ||||||
|       case NSets => findBy(CacheName) |       case NSets => findBy(CacheName) | ||||||
|       case NWays => findBy(CacheName) |       case NWays => findBy(CacheName) | ||||||
| @@ -72,6 +70,7 @@ class DefaultConfig extends ChiselConfig ( | |||||||
|       case StoreDataQueueDepth => 17 |       case StoreDataQueueDepth => 17 | ||||||
|       case ReplayQueueDepth => 16 |       case ReplayQueueDepth => 16 | ||||||
|       case NMSHRs => Knob("L1D_MSHRS") |       case NMSHRs => Knob("L1D_MSHRS") | ||||||
|  |       case NIOMSHRs => 1 | ||||||
|       case LRSCCycles => 32  |       case LRSCCycles => 32  | ||||||
|       //L2 Memory System Params |       //L2 Memory System Params | ||||||
|       case NAcquireTransactors => 7 |       case NAcquireTransactors => 7 | ||||||
| @@ -119,6 +118,7 @@ class DefaultConfig extends ChiselConfig ( | |||||||
|       case TLNClients => site(TLNCachingClients) + site(TLNCachelessClients) |       case TLNClients => site(TLNCachingClients) + site(TLNCachelessClients) | ||||||
|       case TLDataBits => site(CacheBlockBytes)*8/site(TLDataBeats) |       case TLDataBits => site(CacheBlockBytes)*8/site(TLDataBeats) | ||||||
|       case TLDataBeats => 4 |       case TLDataBeats => 4 | ||||||
|  |       case TLWriteMaskBits => (site(TLDataBits) - 1) / 8 + 1 | ||||||
|       case TLNetworkIsOrderedP2P => false |       case TLNetworkIsOrderedP2P => false | ||||||
|       case TLNManagers => findBy(TLId) |       case TLNManagers => findBy(TLId) | ||||||
|       case TLNCachingClients => findBy(TLId) |       case TLNCachingClients => findBy(TLId) | ||||||
| @@ -133,7 +133,7 @@ class DefaultConfig extends ChiselConfig ( | |||||||
|         case TLNCachelessClients => site(NTiles) + 1 |         case TLNCachelessClients => site(NTiles) + 1 | ||||||
|         case TLCoherencePolicy => new MESICoherence(site(L2DirectoryRepresentation))  |         case TLCoherencePolicy => new MESICoherence(site(L2DirectoryRepresentation))  | ||||||
|         case TLMaxManagerXacts => site(NAcquireTransactors) + 2 |         case TLMaxManagerXacts => site(NAcquireTransactors) + 2 | ||||||
|         case TLMaxClientXacts => max(site(NMSHRs), |         case TLMaxClientXacts => max(site(NMSHRs) + site(NIOMSHRs), | ||||||
|                                      if(site(BuildRoCC).isEmpty) 1  |                                      if(site(BuildRoCC).isEmpty) 1  | ||||||
|                                        else site(RoCCMaxTaggedMemXacts)) |                                        else site(RoCCMaxTaggedMemXacts)) | ||||||
|         case TLMaxClientsPerPort => if(site(BuildRoCC).isEmpty) 1 else 3 |         case TLMaxClientsPerPort => if(site(BuildRoCC).isEmpty) 1 else 3 | ||||||
| @@ -155,6 +155,18 @@ class DefaultConfig extends ChiselConfig ( | |||||||
|       case CacheBlockBytes => 64 |       case CacheBlockBytes => 64 | ||||||
|       case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes)) |       case CacheBlockOffsetBits => log2Up(here(CacheBlockBytes)) | ||||||
|       case UseBackupMemoryPort => true |       case UseBackupMemoryPort => true | ||||||
|  |       case MMIOBase => BigInt(1 << 30) // 1 GB | ||||||
|  |       case ExternalIOStart => 2 * site(MMIOBase) | ||||||
|  |       case NASTIAddrMap => Seq( | ||||||
|  |         ("mem", None, MemSize(site(MMIOBase), AddrMap.RWX)), | ||||||
|  |         ("conf", None, Submap(site(ExternalIOStart) - site(MMIOBase), | ||||||
|  |           ("csr0", None, MemSize(1 << 15, AddrMap.RW)), | ||||||
|  |           ("scr", None, MemSize(site(HTIFNSCR) * 8, AddrMap.RW)))), | ||||||
|  |         ("io", Some(site(ExternalIOStart)), | ||||||
|  |           MemSize(2 * site(MMIOBase), AddrMap.RW))) | ||||||
|  |       case NASTIAddrHashMap => new AddrHashMap(site(NASTIAddrMap)) | ||||||
|  |       case NASTINMasters => site(TLNManagers) + 1 | ||||||
|  |       case NASTINSlaves => site(NASTIAddrHashMap).nEntries | ||||||
|   }}, |   }}, | ||||||
|   knobValues = { |   knobValues = { | ||||||
|     case "NTILES" => 1 |     case "NTILES" => 1 | ||||||
| @@ -254,3 +266,7 @@ class SmallConfig extends ChiselConfig ( | |||||||
| class DefaultFPGASmallConfig extends ChiselConfig(new SmallConfig ++ new DefaultFPGAConfig) | class DefaultFPGASmallConfig extends ChiselConfig(new SmallConfig ++ new DefaultFPGAConfig) | ||||||
|  |  | ||||||
| class ExampleSmallConfig extends ChiselConfig(new SmallConfig ++ new DefaultConfig) | class ExampleSmallConfig extends ChiselConfig(new SmallConfig ++ new DefaultConfig) | ||||||
|  |  | ||||||
|  | class MultibankConfig extends ChiselConfig(new With2Banks ++ new DefaultConfig) | ||||||
|  | class MultibankL2Config extends ChiselConfig( | ||||||
|  |   new With2Banks ++ new WithL2Cache ++ new DefaultConfig) | ||||||
|   | |||||||
| @@ -26,8 +26,8 @@ case object UseBackupMemoryPort extends Field[Boolean] | |||||||
| case object BuildL2CoherenceManager extends Field[() => CoherenceAgent] | case object BuildL2CoherenceManager extends Field[() => CoherenceAgent] | ||||||
| /** Function for building some kind of tile connected to a reset signal */ | /** Function for building some kind of tile connected to a reset signal */ | ||||||
| case object BuildTiles extends Field[Seq[(Bool) => Tile]] | case object BuildTiles extends Field[Seq[(Bool) => Tile]] | ||||||
| /** Which protocol to use to talk to memory/devices */ | /** Start address of the "io" region in the memory map */ | ||||||
| case object UseNASTI extends Field[Boolean] | case object ExternalIOStart extends Field[BigInt] | ||||||
|  |  | ||||||
| /** Utility trait for quick access to some relevant parameters */ | /** Utility trait for quick access to some relevant parameters */ | ||||||
| trait TopLevelParameters extends UsesParameters { | trait TopLevelParameters extends UsesParameters { | ||||||
| @@ -40,6 +40,7 @@ trait TopLevelParameters extends UsesParameters { | |||||||
|   val nMemReqs = params(NOutstandingMemReqsPerChannel) |   val nMemReqs = params(NOutstandingMemReqsPerChannel) | ||||||
|   val mifAddrBits = params(MIFAddrBits) |   val mifAddrBits = params(MIFAddrBits) | ||||||
|   val mifDataBeats = params(MIFDataBeats) |   val mifDataBeats = params(MIFDataBeats) | ||||||
|  |   val scrAddrBits = log2Up(params(HTIFNSCR)) | ||||||
|   require(lsb + log2Up(nBanks) < mifAddrBits) |   require(lsb + log2Up(nBanks) < mifAddrBits) | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -61,7 +62,8 @@ class TopIO extends BasicTopIO { | |||||||
| } | } | ||||||
|  |  | ||||||
| class MultiChannelTopIO extends BasicTopIO with TopLevelParameters { | class MultiChannelTopIO extends BasicTopIO with TopLevelParameters { | ||||||
|   val mem = Vec(new MemIO, nMemChannels) |   val mem = Vec(new NASTIMasterIO, nMemChannels) | ||||||
|  |   val mmio = new NASTIMasterIO | ||||||
| } | } | ||||||
|  |  | ||||||
| /** Top-level module for the chip */ | /** Top-level module for the chip */ | ||||||
| @@ -70,11 +72,19 @@ class Top extends Module with TopLevelParameters { | |||||||
|   val io = new TopIO |   val io = new TopIO | ||||||
|   if(!params(UseZscale)) { |   if(!params(UseZscale)) { | ||||||
|     val temp = Module(new MultiChannelTop) |     val temp = Module(new MultiChannelTop) | ||||||
|     val arb = Module(new MemIOArbiter(nMemChannels)) |     val arb = Module(new NASTIArbiter(nMemChannels)) | ||||||
|     arb.io.inner <> temp.io.mem |     val conv = Module(new MemIONASTISlaveIOConverter(params(CacheBlockOffsetBits))) | ||||||
|     io.mem <> arb.io.outer |     arb.io.master <> temp.io.mem | ||||||
|  |     conv.io.nasti <> arb.io.slave | ||||||
|  |     io.mem.req_cmd <> Queue(conv.io.mem.req_cmd) | ||||||
|  |     io.mem.req_data <> Queue(conv.io.mem.req_data, mifDataBeats) | ||||||
|  |     conv.io.mem.resp <> Queue(io.mem.resp, mifDataBeats) | ||||||
|     io.mem_backup_ctrl <> temp.io.mem_backup_ctrl |     io.mem_backup_ctrl <> temp.io.mem_backup_ctrl | ||||||
|     io.host <> temp.io.host |     io.host <> temp.io.host | ||||||
|  |  | ||||||
|  |     // tie off the mmio port | ||||||
|  |     val errslave = Module(new NASTIErrorSlave) | ||||||
|  |     errslave.io <> temp.io.mmio | ||||||
|   } else { |   } else { | ||||||
|     val temp = Module(new ZscaleTop) |     val temp = Module(new ZscaleTop) | ||||||
|     io.host <> temp.io.host |     io.host <> temp.io.host | ||||||
| @@ -93,8 +103,8 @@ class MultiChannelTop extends Module with TopLevelParameters { | |||||||
|     case ((hl, tile), i) => |     case ((hl, tile), i) => | ||||||
|       tile.io.host.id := UInt(i) |       tile.io.host.id := UInt(i) | ||||||
|       tile.io.host.reset := Reg(next=Reg(next=hl.reset)) |       tile.io.host.reset := Reg(next=Reg(next=hl.reset)) | ||||||
|       tile.io.host.pcr_req <> Queue(hl.pcr_req) |       tile.io.host.pcr.req <> Queue(hl.pcr.req) | ||||||
|       hl.pcr_rep <> Queue(tile.io.host.pcr_rep) |       hl.pcr.resp <> Queue(tile.io.host.pcr.resp) | ||||||
|       hl.ipi_req <> Queue(tile.io.host.ipi_req) |       hl.ipi_req <> Queue(tile.io.host.ipi_req) | ||||||
|       tile.io.host.ipi_rep <> Queue(hl.ipi_rep) |       tile.io.host.ipi_rep <> Queue(hl.ipi_rep) | ||||||
|       hl.debug_stats_pcr := tile.io.host.debug_stats_pcr |       hl.debug_stats_pcr := tile.io.host.debug_stats_pcr | ||||||
| @@ -105,6 +115,7 @@ class MultiChannelTop extends Module with TopLevelParameters { | |||||||
|   uncore.io.tiles_uncached <> tileList.map(_.io.uncached) |   uncore.io.tiles_uncached <> tileList.map(_.io.uncached) | ||||||
|   io.host <> uncore.io.host |   io.host <> uncore.io.host | ||||||
|   io.mem <> uncore.io.mem |   io.mem <> uncore.io.mem | ||||||
|  |   io.mmio <> uncore.io.mmio | ||||||
|   if(params(UseBackupMemoryPort)) { io.mem_backup_ctrl <> uncore.io.mem_backup_ctrl } |   if(params(UseBackupMemoryPort)) { io.mem_backup_ctrl <> uncore.io.mem_backup_ctrl } | ||||||
| } | } | ||||||
|  |  | ||||||
| @@ -116,11 +127,12 @@ class MultiChannelTop extends Module with TopLevelParameters { | |||||||
| class Uncore extends Module with TopLevelParameters { | class Uncore extends Module with TopLevelParameters { | ||||||
|   val io = new Bundle { |   val io = new Bundle { | ||||||
|     val host = new HostIO |     val host = new HostIO | ||||||
|     val mem = Vec(new MemIO, nMemChannels) |     val mem = Vec(new NASTIMasterIO, nMemChannels) | ||||||
|     val tiles_cached = Vec(new ClientTileLinkIO, nTiles).flip |     val tiles_cached = Vec(new ClientTileLinkIO, nTiles).flip | ||||||
|     val tiles_uncached = Vec(new ClientUncachedTileLinkIO, nTiles).flip |     val tiles_uncached = Vec(new ClientUncachedTileLinkIO, nTiles).flip | ||||||
|     val htif = Vec(new HTIFIO, nTiles).flip |     val htif = Vec(new HTIFIO, nTiles).flip | ||||||
|     val mem_backup_ctrl = new MemBackupCtrlIO |     val mem_backup_ctrl = new MemBackupCtrlIO | ||||||
|  |     val mmio = new NASTIMasterIO | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   val htif = Module(new HTIF(CSRs.mreset)) // One HTIF module per chip |   val htif = Module(new HTIF(CSRs.mreset)) // One HTIF module per chip | ||||||
| @@ -130,13 +142,36 @@ class Uncore extends Module with TopLevelParameters { | |||||||
|   outmemsys.io.tiles_uncached <> io.tiles_uncached |   outmemsys.io.tiles_uncached <> io.tiles_uncached | ||||||
|   outmemsys.io.tiles_cached <> io.tiles_cached |   outmemsys.io.tiles_cached <> io.tiles_cached | ||||||
|  |  | ||||||
|  |   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).ipi_req <> io.htif(i).ipi_req | ||||||
|  |     io.htif(i).ipi_rep <> htif.io.cpu(i).ipi_rep | ||||||
|  |     htif.io.cpu(i).debug_stats_pcr <> io.htif(i).debug_stats_pcr | ||||||
|  |  | ||||||
|  |     val pcr_arb = Module(new SMIArbiter(2, 64, 12)) | ||||||
|  |     pcr_arb.io.in(0) <> htif.io.cpu(i).pcr | ||||||
|  |     pcr_arb.io.in(1) <> outmemsys.io.pcr(i) | ||||||
|  |     io.htif(i).pcr <> pcr_arb.io.out | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   // Arbitrate SCR access between MMIO and HTIF | ||||||
|  |   val scrArb = Module(new SMIArbiter(2, 64, scrAddrBits)) | ||||||
|  |   val scrFile = Module(new SCRFile) | ||||||
|  |  | ||||||
|  |   scrArb.io.in(0) <> htif.io.scr | ||||||
|  |   scrArb.io.in(1) <> outmemsys.io.scr | ||||||
|  |   scrFile.io.smi <> scrArb.io.out | ||||||
|  |   // scrFile.io.scr <> (... your SCR connections ...) | ||||||
|  |  | ||||||
|   // Wire the htif to the memory port(s) and host interface |   // Wire the htif to the memory port(s) and host interface | ||||||
|   io.host.debug_stats_pcr := htif.io.host.debug_stats_pcr |   io.host.debug_stats_pcr := htif.io.host.debug_stats_pcr | ||||||
|   htif.io.cpu <> io.htif |  | ||||||
|   io.mem <> outmemsys.io.mem |   io.mem <> outmemsys.io.mem | ||||||
|  |   io.mmio <> outmemsys.io.mmio | ||||||
|   if(params(UseBackupMemoryPort)) { |   if(params(UseBackupMemoryPort)) { | ||||||
|     outmemsys.io.mem_backup_en := io.mem_backup_ctrl.en |     outmemsys.io.mem_backup_en := io.mem_backup_ctrl.en | ||||||
|     VLSIUtils.padOutHTIFWithDividedClock(htif.io, outmemsys.io.mem_backup, io.mem_backup_ctrl, io.host, htifW) |     VLSIUtils.padOutHTIFWithDividedClock(htif.io.host, scrFile.io.scr, | ||||||
|  |       outmemsys.io.mem_backup, io.mem_backup_ctrl, io.host, htifW) | ||||||
|   } else { |   } else { | ||||||
|     htif.io.host.out <> io.host.out |     htif.io.host.out <> io.host.out | ||||||
|     htif.io.host.in <> io.host.in |     htif.io.host.in <> io.host.in | ||||||
| @@ -152,9 +187,12 @@ class OuterMemorySystem extends Module with TopLevelParameters { | |||||||
|     val tiles_uncached = Vec(new ClientUncachedTileLinkIO, nTiles).flip |     val tiles_uncached = Vec(new ClientUncachedTileLinkIO, nTiles).flip | ||||||
|     val htif_uncached = (new ClientUncachedTileLinkIO).flip |     val htif_uncached = (new ClientUncachedTileLinkIO).flip | ||||||
|     val incoherent = Vec(Bool(), nTiles).asInput |     val incoherent = Vec(Bool(), nTiles).asInput | ||||||
|     val mem = Vec(new MemIO, nMemChannels) |     val mem = Vec(new NASTIMasterIO, nMemChannels) | ||||||
|     val mem_backup = new MemSerializedIO(htifW) |     val mem_backup = new MemSerializedIO(htifW) | ||||||
|     val mem_backup_en = Bool(INPUT) |     val mem_backup_en = Bool(INPUT) | ||||||
|  |     val pcr = Vec(new SMIIO(64, 12), nTiles) | ||||||
|  |     val scr = new SMIIO(64, scrAddrBits) | ||||||
|  |     val mmio = new NASTIMasterIO | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   // Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory |   // Create a simple L1toL2 NoC between the tiles+htif and the banks of outer memory | ||||||
| @@ -170,43 +208,59 @@ class OuterMemorySystem extends Module with TopLevelParameters { | |||||||
|     else new RocketChipTileLinkCrossbar(addrToBank, sharerToClientId, preBuffering, postBuffering)) |     else new RocketChipTileLinkCrossbar(addrToBank, sharerToClientId, preBuffering, postBuffering)) | ||||||
|  |  | ||||||
|   // Create point(s) of coherence serialization |   // Create point(s) of coherence serialization | ||||||
|   val managerEndpoints = List.fill(nMemChannels) { |   val nManagers = nMemChannels * nBanksPerMemChannel | ||||||
|                            List.fill(nBanksPerMemChannel) { |   val managerEndpoints = List.fill(nManagers) { params(BuildL2CoherenceManager)()} | ||||||
|                              params(BuildL2CoherenceManager)()}} |   managerEndpoints.foreach { _.incoherent := io.incoherent } | ||||||
|   managerEndpoints.flatten.foreach { _.incoherent := io.incoherent } |  | ||||||
|  |  | ||||||
|   // Wire the tiles and htif to the TileLink client ports of the L1toL2 network, |   // Wire the tiles and htif to the TileLink client ports of the L1toL2 network, | ||||||
|   // and coherence manager(s) to the other side |   // and coherence manager(s) to the other side | ||||||
|   l1tol2net.io.clients <> ordered_clients |   l1tol2net.io.clients <> ordered_clients | ||||||
|   l1tol2net.io.managers <> managerEndpoints.flatMap(_.map(_.innerTL)) |   l1tol2net.io.managers <> managerEndpoints.map(_.innerTL) | ||||||
|  |  | ||||||
|   // Create a converter between TileLinkIO and MemIO for each channel |   // Create a converter between TileLinkIO and MemIO for each channel | ||||||
|   val outerTLParams = params.alterPartial({ case TLId => "L2ToMC" }) |   val outerTLParams = params.alterPartial({ case TLId => "L2ToMC" }) | ||||||
|   val backendBuffering = TileLinkDepths(0,0,0,0,0) |   val backendBuffering = TileLinkDepths(0,0,0,0,0) | ||||||
|   val mem_channels = managerEndpoints.map { banks => |  | ||||||
|     if(!params(UseNASTI)) { |   val addrMap = params(NASTIAddrHashMap) | ||||||
|       val arb = Module(new RocketChipTileLinkArbiter(managerDepths = backendBuffering))(outerTLParams) |  | ||||||
|       val conv = Module(new MemPipeIOTileLinkIOConverter(nMemReqs))(outerTLParams) |   println("Generated Address Map") | ||||||
|       arb.io.clients <> banks.map(_.outerTL) |   for ((name, base, size, _) <- addrMap.sortedEntries) { | ||||||
|       arb.io.managers.head <> conv.io.tl |     println(f"\t$name%s $base%x - ${base + size - 1}%x") | ||||||
|       MemIOMemPipeIOConverter(conv.io.mem) |  | ||||||
|     } else { |  | ||||||
|       val arb = Module(new RocketChipTileLinkArbiter(managerDepths = backendBuffering))(outerTLParams) |  | ||||||
|       val conv1 = Module(new NASTIMasterIOTileLinkIOConverter)(outerTLParams) |  | ||||||
|       val conv2 = Module(new MemIONASTISlaveIOConverter(params(CacheBlockOffsetBits))) |  | ||||||
|       val conv3 = Module(new MemPipeIOMemIOConverter(nMemReqs)) |  | ||||||
|       arb.io.clients <> banks.map(_.outerTL) |  | ||||||
|       arb.io.managers.head <> conv1.io.tl |  | ||||||
|       conv2.io.nasti <> conv1.io.nasti |  | ||||||
|       conv3.io.cpu.req_cmd <> Queue(conv2.io.mem.req_cmd, 2) |  | ||||||
|       conv3.io.cpu.req_data <> Queue(conv2.io.mem.req_data, mifDataBeats) |  | ||||||
|       conv2.io.mem.resp <> conv3.io.cpu.resp |  | ||||||
|       MemIOMemPipeIOConverter(conv3.io.mem) |  | ||||||
|     } |  | ||||||
|   } |   } | ||||||
|  |  | ||||||
|  |   val interconnect = Module(new NASTITopInterconnect) | ||||||
|  |  | ||||||
|  |   for ((bank, i) <- managerEndpoints.zipWithIndex) { | ||||||
|  |     val unwrap = Module(new ClientTileLinkIOUnwrapper)(outerTLParams) | ||||||
|  |     val conv = Module(new NASTIMasterIOTileLinkIOConverter)(outerTLParams) | ||||||
|  |     unwrap.io.in <> bank.outerTL | ||||||
|  |     conv.io.tl <> unwrap.io.out | ||||||
|  |     interconnect.io.masters(i) <> conv.io.nasti | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   val rtc = Module(new RTC(CSRs.mtime)) | ||||||
|  |   interconnect.io.masters(nManagers) <> rtc.io | ||||||
|  |  | ||||||
|  |   for (i <- 0 until nTiles) { | ||||||
|  |     val csrName = s"conf:csr$i" | ||||||
|  |     val csrPort = addrMap(csrName).port | ||||||
|  |     val conv = Module(new SMIIONASTISlaveIOConverter(64, 12)) | ||||||
|  |     conv.io.nasti <> interconnect.io.slaves(csrPort) | ||||||
|  |     io.pcr(i) <> conv.io.smi | ||||||
|  |   } | ||||||
|  |  | ||||||
|  |   val conv = Module(new SMIIONASTISlaveIOConverter(64, scrAddrBits)) | ||||||
|  |   conv.io.nasti <> interconnect.io.slaves(addrMap("conf:scr").port) | ||||||
|  |   io.scr <> conv.io.smi | ||||||
|  |  | ||||||
|  |   io.mmio <> interconnect.io.slaves(addrMap("io").port) | ||||||
|  |  | ||||||
|  |   val mem_channels = interconnect.io.slaves.take(nMemChannels) | ||||||
|  |  | ||||||
|   // Create a SerDes for backup memory port |   // Create a SerDes for backup memory port | ||||||
|   if(params(UseBackupMemoryPort)) { |   if(params(UseBackupMemoryPort)) { | ||||||
|     VLSIUtils.doOuterMemorySystemSerdes(mem_channels, io.mem, io.mem_backup, io.mem_backup_en, nMemChannels, params(HTIFWidth)) |     VLSIUtils.doOuterMemorySystemSerdes( | ||||||
|  |       mem_channels, io.mem, io.mem_backup, io.mem_backup_en, | ||||||
|  |       nMemChannels, params(HTIFWidth), params(CacheBlockOffsetBits)) | ||||||
|   } else { io.mem <> mem_channels } |   } else { io.mem <> mem_channels } | ||||||
| } | } | ||||||
|   | |||||||
| @@ -15,52 +15,69 @@ class MemDessert extends Module { | |||||||
|  |  | ||||||
| object VLSIUtils { | object VLSIUtils { | ||||||
|   def doOuterMemorySystemSerdes( |   def doOuterMemorySystemSerdes( | ||||||
|       llcs: Seq[MemIO], |       llcs: Seq[NASTIMasterIO], | ||||||
|       mems: Seq[MemIO], |       mems: Seq[NASTIMasterIO], | ||||||
|       backup: MemSerializedIO, |       backup: MemSerializedIO, | ||||||
|       en: Bool, |       en: Bool, | ||||||
|       nMemChannels: Int, |       nMemChannels: Int, | ||||||
|       htifWidth: Int) { |       htifWidth: Int, | ||||||
|     val arb = Module(new MemIOArbiter(nMemChannels)) |       blockOffsetBits: Int) { | ||||||
|  |  | ||||||
|  |     val arb = Module(new NASTIArbiter(nMemChannels)) | ||||||
|  |     val conv = Module(new MemIONASTISlaveIOConverter(blockOffsetBits)) | ||||||
|     val mem_serdes = Module(new MemSerdes(htifWidth)) |     val mem_serdes = Module(new MemSerdes(htifWidth)) | ||||||
|     mem_serdes.io.wide <> arb.io.outer |  | ||||||
|  |     conv.io.nasti <> arb.io.slave | ||||||
|  |     mem_serdes.io.wide <> conv.io.mem | ||||||
|     backup <> mem_serdes.io.narrow |     backup <> mem_serdes.io.narrow | ||||||
|  |  | ||||||
|     llcs zip mems zip arb.io.inner foreach { case ((llc, mem), wide) => |     llcs zip mems zip arb.io.master foreach { case ((llc, mem), wide) => | ||||||
|       llc.req_cmd.ready := Mux(en, wide.req_cmd.ready, mem.req_cmd.ready) |       llc.ar.ready := Mux(en, wide.ar.ready, mem.ar.ready) | ||||||
|       mem.req_cmd.valid := llc.req_cmd.valid && !en |       mem.ar.valid := llc.ar.valid && !en | ||||||
|       mem.req_cmd.bits := llc.req_cmd.bits |       mem.ar.bits := llc.ar.bits | ||||||
|       wide.req_cmd.valid := llc.req_cmd.valid && en |       wide.ar.valid := llc.ar.valid && en | ||||||
|       wide.req_cmd.bits := llc.req_cmd.bits |       wide.ar.bits := llc.ar.bits | ||||||
|  |  | ||||||
|       llc.req_data.ready := Mux(en, wide.req_data.ready, mem.req_data.ready) |       llc.aw.ready := Mux(en, wide.aw.ready, mem.aw.ready) | ||||||
|       mem.req_data.valid := llc.req_data.valid && !en |       mem.aw.valid := llc.aw.valid && !en | ||||||
|       mem.req_data.bits := llc.req_data.bits |       mem.aw.bits := llc.aw.bits | ||||||
|       wide.req_data.valid := llc.req_data.valid && en |       wide.aw.valid := llc.aw.valid && en | ||||||
|       wide.req_data.bits := llc.req_data.bits |       wide.aw.bits := llc.aw.bits | ||||||
|  |  | ||||||
|       llc.resp.valid := Mux(en, wide.resp.valid, mem.resp.valid) |       llc.w.ready := Mux(en, wide.w.ready, mem.w.ready) | ||||||
|       llc.resp.bits := Mux(en, wide.resp.bits, mem.resp.bits) |       mem.w.valid := llc.w.valid && !en | ||||||
|       mem.resp.ready  := llc.resp.ready && !en |       mem.w.bits := llc.w.bits | ||||||
|       wide.resp.ready := llc.resp.ready && en |       wide.w.valid := llc.w.valid && en | ||||||
|  |       wide.w.bits := llc.w.bits | ||||||
|  |  | ||||||
|  |       llc.b.valid := Mux(en, wide.b.valid, mem.b.valid) | ||||||
|  |       llc.b.bits := Mux(en, wide.b.bits, mem.b.bits) | ||||||
|  |       mem.b.ready  := llc.b.ready && !en | ||||||
|  |       wide.b.ready := llc.b.ready && en | ||||||
|  |  | ||||||
|  |       llc.r.valid := Mux(en, wide.r.valid, mem.r.valid) | ||||||
|  |       llc.r.bits := Mux(en, wide.r.bits, mem.r.bits) | ||||||
|  |       mem.r.ready  := llc.r.ready && !en | ||||||
|  |       wide.r.ready := llc.r.ready && en | ||||||
|     } |     } | ||||||
|   } |   } | ||||||
|  |  | ||||||
|   def padOutHTIFWithDividedClock( |   def padOutHTIFWithDividedClock( | ||||||
|       htif: HTIFModuleIO, |       htif: HostIO, | ||||||
|  |       scr: SCRIO, | ||||||
|       child: MemSerializedIO,  |       child: MemSerializedIO,  | ||||||
|       parent: MemBackupCtrlIO, |       parent: MemBackupCtrlIO, | ||||||
|       host: HostIO, |       host: HostIO, | ||||||
|       htifW: Int) { |       htifW: Int) { | ||||||
|     val hio = Module((new SlowIO(512)) { Bits(width = htifW+1) }) |     val hio = Module((new SlowIO(512)) { Bits(width = htifW+1) }) | ||||||
|     hio.io.set_divisor.valid := htif.scr.wen && (htif.scr.waddr === UInt(63)) |     hio.io.set_divisor.valid := scr.wen && (scr.waddr === UInt(63)) | ||||||
|     hio.io.set_divisor.bits := htif.scr.wdata |     hio.io.set_divisor.bits := scr.wdata | ||||||
|     htif.scr.rdata(63) := hio.io.divisor |     scr.rdata(63) := hio.io.divisor | ||||||
|  |  | ||||||
|     hio.io.out_fast.valid := htif.host.out.valid || child.req.valid |     hio.io.out_fast.valid := htif.out.valid || child.req.valid | ||||||
|     hio.io.out_fast.bits := Cat(htif.host.out.valid, Mux(htif.host.out.valid, htif.host.out.bits, child.req.bits)) |     hio.io.out_fast.bits := Cat(htif.out.valid, Mux(htif.out.valid, htif.out.bits, child.req.bits)) | ||||||
|     htif.host.out.ready := hio.io.out_fast.ready |     htif.out.ready := hio.io.out_fast.ready | ||||||
|     child.req.ready := hio.io.out_fast.ready && !htif.host.out.valid |     child.req.ready := hio.io.out_fast.ready && !htif.out.valid | ||||||
|     host.out.valid := hio.io.out_slow.valid && hio.io.out_slow.bits(htifW) |     host.out.valid := hio.io.out_slow.valid && hio.io.out_slow.bits(htifW) | ||||||
|     host.out.bits := hio.io.out_slow.bits |     host.out.bits := hio.io.out_slow.bits | ||||||
|     parent.out_valid := hio.io.out_slow.valid && !hio.io.out_slow.bits(htifW) |     parent.out_valid := hio.io.out_slow.valid && !hio.io.out_slow.bits(htifW) | ||||||
| @@ -72,9 +89,9 @@ object VLSIUtils { | |||||||
|     host.in.ready := hio.io.in_slow.ready |     host.in.ready := hio.io.in_slow.ready | ||||||
|     child.resp.valid := hio.io.in_fast.valid && hio.io.in_fast.bits(htifW) |     child.resp.valid := hio.io.in_fast.valid && hio.io.in_fast.bits(htifW) | ||||||
|     child.resp.bits := hio.io.in_fast.bits |     child.resp.bits := hio.io.in_fast.bits | ||||||
|     htif.host.in.valid := hio.io.in_fast.valid && !hio.io.in_fast.bits(htifW) |     htif.in.valid := hio.io.in_fast.valid && !hio.io.in_fast.bits(htifW) | ||||||
|     htif.host.in.bits := hio.io.in_fast.bits |     htif.in.bits := hio.io.in_fast.bits | ||||||
|     hio.io.in_fast.ready := Mux(hio.io.in_fast.bits(htifW), Bool(true), htif.host.in.ready) |     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 := hio.io.clk_slow | ||||||
|     host.clk_edge := Reg(next=host.clk && !Reg(next=host.clk)) |     host.clk_edge := Reg(next=host.clk && !Reg(next=host.clk)) | ||||||
|   } |   } | ||||||
|   | |||||||
							
								
								
									
										2
									
								
								uncore
									
									
									
									
									
								
							
							
								
								
								
								
								
							
						
						
									
										2
									
								
								uncore
									
									
									
									
									
								
							 Submodule uncore updated: 5b76a91b2e...d6895713cf
									
								
							
		Reference in New Issue
	
	Block a user