Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Tilelink doc update #1305 #242

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 13 additions & 17 deletions source/SpinalHDL/Libraries/Bus/tilelink/tilelink_fabric.rst
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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{
Expand Down Expand Up @@ -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
----------------------

Expand Down Expand Up @@ -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.
Expand All @@ -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()
}

Expand Down
Loading