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