tilelink2: TLLegacy converts from legacy TileLink to TileLink2
This commit is contained in:
		
							
								
								
									
										107
									
								
								uncore/src/main/scala/tilelink2/Legacy.scala
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										107
									
								
								uncore/src/main/scala/tilelink2/Legacy.scala
									
									
									
									
									
										Normal file
									
								
							| @@ -0,0 +1,107 @@ | ||||
| // See LICENSE for license details. | ||||
|  | ||||
| package uncore.tilelink2 | ||||
|  | ||||
| import Chisel._ | ||||
| import cde.Parameters | ||||
| import uncore.tilelink._ | ||||
| import uncore.constants._ | ||||
|  | ||||
| class TLLegacy(implicit val p: Parameters) extends TLSimpleFactory with HasTileLinkParameters | ||||
| { | ||||
|   val outer_p = p | ||||
|   // TL legacy clients don't support anything fancy | ||||
|   val node = TLClientNode(TLClientParameters( | ||||
|     sourceId = IdRange(0, 1 << tlClientXactIdBits))) | ||||
|  | ||||
|   lazy val module = Module(new TLModule(this) with HasTileLinkParameters { | ||||
|     val p = outer_p | ||||
|     val io = new Bundle { | ||||
|       val legacy = new ClientUncachedTileLinkIO()(p).flip | ||||
|       val out = node.bundleOut | ||||
|     } | ||||
|  | ||||
|     // TL legacy is dumb. All managers must support it's accesses. | ||||
|     val edge = node.edgesOut(0) | ||||
|     require (edge.manager.beatBytes == tlDataBytes) | ||||
|     require (edge.manager.allSupportGet       .contains(TransferSizes(tlDataBytes))) | ||||
|     require (edge.manager.allSupportGet       .contains(TransferSizes(tlDataBeats * tlDataBytes))) | ||||
|     require (edge.manager.allSupportPutPartial.contains(TransferSizes(tlDataBytes))) | ||||
|     require (edge.manager.allSupportPutPartial.contains(TransferSizes(tlDataBeats * tlDataBytes))) | ||||
|     require (edge.manager.allSupportArithmetic.contains(TransferSizes(4, tlDataBytes))) | ||||
|     require (edge.manager.allSupportLogical   .contains(TransferSizes(4, tlDataBytes))) | ||||
|     require (edge.manager.allSupportHint) | ||||
|     // TL legacy will not generate PutFull, Acquire | ||||
|  | ||||
|     // Must be able to fit TL2 sink_id into TL legacy | ||||
|     require ((1 << tlManagerXactIdBits) >= edge.manager.endSinkId) | ||||
|  | ||||
|     val out = io.out(0) | ||||
|     out.a.valid := io.legacy.acquire.valid | ||||
|     out.d.ready := io.legacy.grant  .ready | ||||
|     io.legacy.acquire.ready := out.a.ready | ||||
|     io.legacy.grant  .valid := out.d.valid | ||||
|  | ||||
|     val source  = io.legacy.acquire.bits.client_xact_id | ||||
|     val data    = io.legacy.acquire.bits.data | ||||
|     val wmask   = io.legacy.acquire.bits.wmask() | ||||
|     val address = io.legacy.acquire.bits.full_addr() | ||||
|  | ||||
|     val beat  = UInt(log2Ceil(tlDataBytes)) | ||||
|     val block = UInt(log2Ceil(tlDataBytes*tlDataBeats)) | ||||
|  | ||||
|     out.a.bits := MuxLookup(io.legacy.acquire.bits.a_type, new TLBundleA(edge.bundle), Array( | ||||
|       Acquire.getType         -> edge.Get (source, address, beat) ._2, | ||||
|       Acquire.getBlockType    -> edge.Get (source, address, block)._2, | ||||
|       Acquire.putType         -> edge.Put (source, address, beat,  data, wmask)._2, | ||||
|       Acquire.putBlockType    -> edge.Put (source, address, block, data, wmask)._2, | ||||
|       Acquire.getPrefetchType -> edge.Hint(source, address, block, UInt(0))._2, | ||||
|       Acquire.putPrefetchType -> edge.Hint(source, address, block, UInt(1))._2, | ||||
|       Acquire.putAtomicType   -> MuxLookup(io.legacy.acquire.bits.op_code(), new TLBundleA(edge.bundle), Array( | ||||
|         MemoryOpConstants.M_XA_SWAP -> edge.Logical(source, address, beat, data, TLAtomics.SWAP)._2, | ||||
|         MemoryOpConstants.M_XA_XOR  -> edge.Logical(source, address, beat, data, TLAtomics.XOR) ._2, | ||||
|         MemoryOpConstants.M_XA_OR   -> edge.Logical(source, address, beat, data, TLAtomics.OR)  ._2, | ||||
|         MemoryOpConstants.M_XA_AND  -> edge.Logical(source, address, beat, data, TLAtomics.AND) ._2, | ||||
|         MemoryOpConstants.M_XA_ADD  -> edge.Arithmetic(source, address, beat, data, TLAtomics.ADD)._2, | ||||
|         MemoryOpConstants.M_XA_MIN  -> edge.Arithmetic(source, address, beat, data, TLAtomics.MIN)._2, | ||||
|         MemoryOpConstants.M_XA_MAX  -> edge.Arithmetic(source, address, beat, data, TLAtomics.MAX)._2, | ||||
|         MemoryOpConstants.M_XA_MINU -> edge.Arithmetic(source, address, beat, data, TLAtomics.MINU)._2, | ||||
|         MemoryOpConstants.M_XA_MAXU -> edge.Arithmetic(source, address, beat, data, TLAtomics.MAXU)._2)))) | ||||
|  | ||||
|     val beatMask  = UInt(tlDataBytes-1) | ||||
|     val blockMask = UInt(tlDataBytes*tlDataBeats-1) | ||||
|     val addressMask = MuxLookup(io.legacy.acquire.bits.a_type, beatMask, Array( | ||||
|       Acquire.getType         -> beatMask, | ||||
|       Acquire.getBlockType    -> blockMask, | ||||
|       Acquire.putType         -> beatMask, | ||||
|       Acquire.putBlockType    -> blockMask, | ||||
|       Acquire.getPrefetchType -> blockMask, | ||||
|       Acquire.putPrefetchType -> blockMask, | ||||
|       Acquire.putAtomicType   -> beatMask)) | ||||
|  | ||||
|     // Get rid of some unneeded muxes | ||||
|     out.a.bits.source  := source | ||||
|     out.a.bits.data    := data | ||||
|     out.a.bits.address := address & ~addressMask | ||||
|  | ||||
|     // TL legacy does not support bus errors | ||||
|     assert (!out.d.bits.error) | ||||
|  | ||||
|     // Recreate the beat address counter | ||||
|     val beatCounter = RegInit(UInt(0, width = tlBeatAddrBits)) | ||||
|     when (out.d.fire() && out.d.bits.hasData() && out.d.bits.size === block) { | ||||
|       beatCounter := beatCounter + UInt(1) | ||||
|     } | ||||
|  | ||||
|     val grant = io.legacy.grant.bits | ||||
|     grant.g_type := MuxLookup(out.d.bits.opcode, Grant.prefetchAckType, Array( | ||||
|       TLMessages.AccessAck     -> Grant.putAckType, | ||||
|       TLMessages.AccessAckData -> Mux(out.d.bits.size === beat, Grant.getDataBeatType, Grant.getDataBlockType), | ||||
|       TLMessages.HintAck       -> Grant.prefetchAckType)) | ||||
|     grant.is_builtin_type := Bool(true) | ||||
|     grant.client_xact_id  := out.d.bits.source | ||||
|     grant.manager_xact_id := out.d.bits.sink | ||||
|     grant.data            := out.d.bits.data | ||||
|     grant.addr_beat       := beatCounter | ||||
|   }) | ||||
| } | ||||
		Reference in New Issue
	
	Block a user