From 08b14f5d4aa1efa5a9d8431d53b65252b72492fd Mon Sep 17 00:00:00 2001 From: Dolu1990 Date: Wed, 7 Feb 2024 19:00:42 +0100 Subject: [PATCH] Update tilelink_fabric doc --- .../Bus/tilelink/tilelink_fabric.rst | 30 ++++++++----------- 1 file changed, 13 insertions(+), 17 deletions(-) diff --git a/source/SpinalHDL/Libraries/Bus/tilelink/tilelink_fabric.rst b/source/SpinalHDL/Libraries/Bus/tilelink/tilelink_fabric.rst index 48c10179bc7..77036b1813d 100644 --- a/source/SpinalHDL/Libraries/Bus/tilelink/tilelink_fabric.rst +++ b/source/SpinalHDL/Libraries/Bus/tilelink/tilelink_fabric.rst @@ -35,10 +35,10 @@ Here is an example of a simple fictive SoC toplevel : .. code-block:: scala - val cpu = new CpuFiber() + val cpu = new CpuFiber(bytes = 0x200) val ram = new RamFiber() - ram.up at(0x10000, 0x200) of cpu.down // map the ram at [0x10000-0x101FF], the ram will infer its own size from it + ram.up at 0x10000 of cpu.down // map the ram at [0x10000-0x101FF], the ram will infer its own size from it val gpio = new GpioFiber() gpio.up at 0x20000 of cpu.down // map the gpio at [0x20000-0x20FFF], its range of 4KB being fixed internally @@ -49,8 +49,8 @@ You can also define intermediate nodes in the interconnect as following : val cpu = new CpuFiber() - val ram = new RamFiber() - ram.up at(0x10000, 0x200) of cpu.down + val ram = new RamFiber(bytes = 0x200) + ram.up at 0x10000 of cpu.down // Create a peripherals namespace to keep things clean val peripherals = new Area{ @@ -120,28 +120,25 @@ RamFiber is the integration layer of a regular tilelink Ram component. .. code-block:: scala - import spinal.lib.bus.tilelink - import spinal.core.fiber.Fiber - class RamFiber() extends Area { - val up = tilelink.fabric.Node.up() + class RamFiber(var bytes : BigInt) extends Area{ + val up = Node.up() + val thread = Fiber build new Area{ val thread = Fiber build new Area { // Here the supported parameters are function of what the master would like us to idealy support. // The tilelink.Ram support all addressWidth / dataWidth / burst length / get / put accesses // but doesn't support atomic / coherency. So we take what is proposed to use and restrict it to // all sorts of get / put request - up.m2s.supported load up.m2s.proposed.intersect(M2sTransfers.allGetPut) + up.m2s.supported load up.m2s.proposed.intersect(M2sTransfers.allGetPut).copy(addressWidth = log2Up(bytes)) up.s2m.none() - // Here we infer how many bytes our ram need to be, by looking at the memory mapping of the connected masters - val bytes = up.ups.map(e => e.mapping.value.highestBound - e.mapping.value.lowerBound + 1).max.toInt - // Then we finaly generate the regular hardware - val logic = new tilelink.Ram(up.bus.p.node, bytes) + val logic = new Ram(up.bus.p.node, bytes toInt) logic.io.up << up.bus } } + Example CpuFiber ---------------------- @@ -262,9 +259,9 @@ The getMemoryTransfers utility rely on a dedicated SpinalTag : trait MemoryConnection extends SpinalTag { def up : Nameable with SpinalTagReady // Side toward the masters of the system def down : Nameable with SpinalTagReady // Side toward the slaves of the system - def mapping : AddressMapping //Specify the memory mapping of the slave from the master address (before transformers are applied) def transformers : List[AddressTransformer] //List of alteration done to the address on this connection (ex offset, interleaving, ...) def sToM(downs : MemoryTransfers, args : MappedNode) : MemoryTransfers = downs //Convert the slave MemoryTransfers capabilities into the master ones + def sToM(down : AddressMapping) : AddressMapping = down //Convert the slave MemoryMapping capabilities into the master ones } That SpinalTag can be used applied to both ends of a given memory bus connection to keep this connection discoverable at elaboration time, creating a graph of MemoryConnection. One good thing about it is that is is bus agnostic, meaning it isn't tilelink specific. @@ -283,10 +280,9 @@ The width adapter is a simple example of bridge. // Populate the MemoryConnection graph new MemoryConnection { - override def up = up - override def down = down + override def up = WidthAdapterFiber.this.up + override def down = WidthAdapterFiber.this.down override def transformers = Nil - override def mapping = SizeMapping(0, BigInt(1) << WidthAdapterFiber.this.up.m2s.parameters.addressWidth) populate() }