Import ml507 mig TL implementation stub
This commit is contained in:
		| @@ -0,0 +1,104 @@ | ||||
| // See LICENSE.SiFive for license details. | ||||
|  | ||||
| package sifive.fpgashells.devices.xilinx.xilinxml507mig | ||||
|  | ||||
| import Chisel._ | ||||
| import freechips.rocketchip.config.{Field, Parameters} | ||||
| import freechips.rocketchip.diplomacy._ | ||||
| import freechips.rocketchip.subsystem.BaseSubsystem | ||||
| import freechips.rocketchip.tilelink._ | ||||
| import freechips.rocketchip.util._ | ||||
|  | ||||
| case class MemoryML507Params( | ||||
|     address: Seq[AddressSet] | ||||
| ) | ||||
|  | ||||
| case object MemoryML507Key extends Field[MemoryML507Params] | ||||
|  | ||||
| trait HasMemoryML507 { this: BaseSubsystem => | ||||
|     val memory = LazyModule(new TLMemoryML507(p(MemoryML507Key))) | ||||
|  | ||||
|     // The Fragmenter will not fragment messages <= 32 bytes, so all | ||||
|     // slaves have to support this size. 64 byte specifies the maximum | ||||
|     // supported transfer size that the slave side of the fragmenter supports | ||||
|     // against the master (here the main memory bus). Specifying alwaysMin as | ||||
|     // true results in all messages being fragmented to the minimal size | ||||
|     // (32 byte). In TL1 terms, slaves | ||||
|     // correspond roughly to managers and masters to clients (confusingly…). | ||||
|     val fragmenter = TLFragmenter(32, 64, alwaysMin=true) | ||||
|  | ||||
|     // TODO: right TL/memory node chain? | ||||
|     memory.node := fragmenter := memBuses.head.toDRAMController(Some("ml507mig"))() | ||||
| } | ||||
|  | ||||
| class TLMemoryML507(c: MemoryML507Params)(implicit p: Parameters) extends LazyModule { | ||||
|     // Corresponds to MIG interface with 64 bit width and a burst length of 4 | ||||
|     val width = 256 | ||||
|     val beatBytes = width/8 // 32 byte (half a cache-line, fragmented) | ||||
|  | ||||
|     val device = new MemoryDevice | ||||
|     val node = TLManagerNode( | ||||
|         Seq(TLManagerPortParameters( | ||||
|             Seq(TLManagerParameters( | ||||
|                 address         = c.address, | ||||
|                 resources       = device.reg, | ||||
|                 regionType      = RegionType.UNCACHED, | ||||
|                 executable      = true, | ||||
|                 supportsGet     = TransferSizes(1, beatBytes), | ||||
|                 supportsPutFull = TransferSizes(1, beatBytes), | ||||
|                 fifoId          = Some(0) // in-order | ||||
|             )), | ||||
|             beatBytes = beatBytes | ||||
|         )) | ||||
|     ) | ||||
|     // We could possibly also support supportsPutPartial, as we need support | ||||
|     // for masks anyway because of the possibility of transfers smaller that | ||||
|     // the data width (size signal, see below). | ||||
|  | ||||
|     lazy val module = new LazyModuleImp(this) { | ||||
|         // in: TLBundle, edge: TLEdgeIn | ||||
|         val (in, edge) = node.in(0) | ||||
|  | ||||
|         // Due to the Fragmenter defined above, all messages are 32 bytes or | ||||
|         // smaller. The data signal of the TL channels is also 32 bytes, so | ||||
|         // all messages will be transfered in a single beat. | ||||
|         // Also, TL guarantees (see TL$4.6) that the payload of a data message | ||||
|         // is always aligned to the width of the beat, e.g. in case of a 32 | ||||
|         // byte data signal, data[7:0] will always have address 0x***00000 and | ||||
|         // data[255:247] address 0x***11111. It is also guaranteed that the | ||||
|         // mask bits always correctly reflect the active bytes inside the beat | ||||
|         // with respect to the size and address. | ||||
|         // So we can directly forward the mask, (relative) address and possibly | ||||
|         // data to the MIG interface. | ||||
|         // Put requests can be acknowledged as soon as they are latched into | ||||
|         // the write fifo of the MIG (possibly combinatorily). | ||||
|         // For read requests, we have to store the source id and size in a | ||||
|         // queue for later acknowledgment. | ||||
|         // We are ready if both the MIG and the response data queue are not | ||||
|         // full. | ||||
|  | ||||
|         // Widths of the A channel: | ||||
|         // addressBits: 32 | ||||
|         // dataBits:    256 | ||||
|         // sourceBits:  6 | ||||
|         // sinkBits:    1 | ||||
|         // sizeBits:    3 | ||||
|  | ||||
|         // source (from): in.a.bits.source | ||||
|         // adresse (to): edgeIn.address(in.a.bits) | ||||
|         // size: edgeIn.size(in.a.bits) | ||||
|         // isPut: edgeIn.hasData(in.a.bits) | ||||
|  | ||||
|         // bits kommt von Decoupled: ready, valid + bits | ||||
|  | ||||
|         println("a parameters: " + in.a.bits.params) | ||||
|  | ||||
|         in.a.ready := Bool(false) | ||||
|         in.d.valid := Bool(false) | ||||
|  | ||||
|         // Tie off unused channels | ||||
|         in.b.valid := Bool(false) | ||||
|         in.c.ready := Bool(true) | ||||
|         in.e.ready := Bool(true) | ||||
|     } | ||||
| } | ||||
		Reference in New Issue
	
	Block a user