### Size Encoding in Hardware Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Example demonstrating size encoding in hardware. ```scala val sizeField = 4.U(3.W) // Log2 of 16 bytes val beatsMinus1 = OH1.UIntToOH1(sizeField, parameter.sizeWidth) // 0xF (15 beats) val beats = beatsMinus1 + 1.U // 16 beats ``` -------------------------------- ### Configuration File Round-Trip Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Example demonstrating JSON serialization and deserialization of TileLink parameters. ```scala import upickle.default._ // Serialize to JSON val param = TLCrossBarParameter( arbitrationPolicy = TLArbiterPolicy.Priority, masters = Seq(/* ... */), slaves = Seq(/* ... */) ) val json = write(param) // String containing JSON // Deserialize from JSON val restored = read[TLCrossBarParameter](json) ``` -------------------------------- ### Parameterization Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/index.md Examples of creating parameter objects for different TileLink link configurations. ```Scala val tlul = TLLinkParameter(32, 4, 1, 32, 5, false) val tlc = TLLinkParameter(40, 8, 8, 128, 6, true) ``` -------------------------------- ### Valid Data Width Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example Scala code demonstrating a valid data width configuration for TileLink. ```Scala val dataWidth = 64 // 8 bytes, 8 byte-enables // Valid: 32 (4 bytes), 64 (8 bytes), 128 (16 bytes), etc. ``` -------------------------------- ### Parameterized Width Adaptation Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/architecture.md Example demonstrating parameterized width adaptation for TLLink. ```scala val smallLink = new TLLink(TLLinkParameter(32, 4, 1, 32, 4, false)) val bigLink = new TLLink(TLLinkParameter(40, 8, 8, 128, 6, true)) ``` -------------------------------- ### TLArbiterParameter Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLArbiter.md Example instantiation of TLArbiterParameter. ```Scala val arbiterParam = TLArbiterParameter( policy = TLArbiterPolicy.Priority, inputLinkParameters = Seq( TileLinkChannelAParameter(32, 4, 64, 5), TileLinkChannelAParameter(32, 4, 64, 5) ), outputLinkParameter = TileLinkChannelAParameter(32, 8, 64, 5) ) ``` -------------------------------- ### Minimal TL-UL Parameters Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example of TLLinkParameter for a Minimal TL-UL configuration. ```scala TLLinkParameter( addressWidth = 20, sourceWidth = 2, sinkWidth = 1, dataWidth = 32, sizeWidth = 3, hasBCEChannels = false ) ``` -------------------------------- ### compare Method Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Demonstrates sorting TLIdRange objects based on start and end positions. ```scala val r1 = TLIdRange(0, 16) val r2 = TLIdRange(0, 32) val r3 = TLIdRange(16, 32) val sorted = Seq(r3, r1, r2).sorted // Result: r1, r2, r3 (sorted by start, then end) ``` -------------------------------- ### Channel A Arbitration (Two Masters to One Slave) Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLArbiter.md Example demonstrating the setup of a TLArbiter with two masters and one slave, using a Priority arbitration policy. ```scala val master1 = Wire(DecoupledIO(new TLChannelA(master1Param))) val master2 = Wire(DecoupledIO(new TLChannelA(master2Param))) val slave = Wire(Flipped(DecoupledIO(new TLChannelA(slaveParam)))) val arbiter = Module(new TLArbiter( TLArbiterParameter( policy = TLArbiterPolicy.Priority, inputLinkParameters = Seq(master1Param, master2Param), outputLinkParameter = slaveParam ) )) arbiter.sources(0) <> master1 arbiter.sources(1) <> master2 slave <> arbiter.sink ``` -------------------------------- ### size Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example usage of the size method. ```scala val range = TLIdRange(10, 25) range.size // 15 ``` -------------------------------- ### Serialization/Deserialization Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Scala code demonstrating serialization and deserialization of TLLinkParameter using upickle. ```scala import upickle.default._ val param = TLLinkParameter(32, 4, 4, 64, 5, false) val json = write(param) val restored = read[TLLinkParameter](json) ``` -------------------------------- ### Four-Input Round-Robin Arbiter Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLArbiter.md Example demonstrating the setup of a TLArbiter with four inputs using a Round-Robin arbitration policy. ```scala val inputs = Seq( Wire(DecoupledIO(new TLChannelA(param))), Wire(DecoupledIO(new TLChannelA(param))), Wire(DecoupledIO(new TLChannelA(param))), Wire(DecoupledIO(new TLChannelA(param))) ) val output = Wire(Flipped(DecoupledIO(new TLChannelA(param)))) val arbiter = Module(new TLArbiter( TLArbiterParameter( policy = TLArbiterPolicy.RoundRobin, inputLinkParameters = Seq.fill(4)(param), outputLinkParameter = param ) )) arbiter.sources.zip(inputs).foreach { case (src, inp) => src <> inp } output <> arbiter.sink ``` -------------------------------- ### Memory Controller Backend Parameters Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example of TLLinkParameter for a Memory Controller Backend configuration. ```scala TLLinkParameter( addressWidth = 40, sourceWidth = 10, sinkWidth = 8, dataWidth = 256, sizeWidth = 6, hasBCEChannels = false ) ``` -------------------------------- ### UIntToOH1 Examples Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Convert unsigned integer to one-hot-1s encoding. ```scala val four = 4.U(3.W) val oh1 = OH1.UIntToOH1(four, 8) // 0b00001111 (four 1s) val size = 6.U(3.W) val sizes = OH1.UIntToOH1(size) // 0b0000111111 (six 1s) ``` -------------------------------- ### Server-Class with Coherence Parameters Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example of TLLinkParameter for a Server-Class with Coherence configuration. ```scala TLLinkParameter( addressWidth = 48, sourceWidth = 8, sinkWidth = 8, dataWidth = 128, sizeWidth = 6, hasBCEChannels = true ) ``` -------------------------------- ### range Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example usage of the range method. ```scala val tlRange = TLIdRange(5, 10) tlRange.range.toSeq // Vector(5, 6, 7, 8, 9) for (id <- tlRange.range) { println(s"ID: $id") } ``` -------------------------------- ### Standard Embedded CPU Parameters Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example of TLLinkParameter for a Standard Embedded CPU configuration. ```scala TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 1, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false ) ``` -------------------------------- ### isEmpty Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example usage of the isEmpty method. ```scala val empty = TLIdRange(10, 10) val full = TLIdRange(10, 20) empty.isEmpty // true full.isEmpty // false ``` -------------------------------- ### Typical Transaction for Channel D Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLChannel.md An example of a typical transaction on Channel D, showing the response to a channel A Get request. ```Scala Response to channel A Get (source=1, size=3): opcode = OpCode.AccessAckData source = 1.U // Match request sink = 5.U // Slave-chosen identifier data = 0x1234567890abcdef.U size = 3.U // Echo from request ``` -------------------------------- ### JSON Serialization Format Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example of TileLink parameters serialized to JSON format. ```json { "linkParameter": { "addressWidth": 32, "sourceWidth": 4, "sinkWidth": 4, "dataWidth": 64, "sizeWidth": 5, "hasBCEChannels": false }, "adVisibility": ["b00000011"], "bceVisibility": [], "srcIdRange": { "start": 0, "end": 16 } } ``` -------------------------------- ### Instantiating a Crossbar Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/index.md Example of how to instantiate a TLCrossBar module with master and slave link parameters. ```scala import org.chipsalliance.tilelink.xbar._ val masterParam = TLCrossBarMasterLinkParameter( linkParameter = TLLinkParameter(32, 4, 4, 64, 5, false), adVisibility = BitSet(0, 1), // Can access slaves 0 and 1 bceVisibility = BitSet(), srcIdRange = TLIdRange(0, 16) ) val slaveParam = TLCrossBarSlaveLinkParameter( linkParameter = TLLinkParameter(32, 8, 4, 64, 5, false), adVisibility = BitSet(0, 1), // Reachable from masters 0 and 1 bceVisibility = BitSet(), sinkIdRange = TLIdRange(0, 8), addressRange = BitSet(BitPat("b0000_????")) // 0x0000 - 0x0FFF ) val xbarParam = TLCrossBarParameter( arbitrationPolicy = TLArbiterPolicy.Priority, masters = Seq(masterParam), slaves = Seq(slaveParam) ) val xbar = Module(new TLCrossBar(xbarParam)) ``` -------------------------------- ### OH1ToOH Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Convert one-hot-1s encoding to one-hot encoding. ```scala val oh1_4 = 0b00001111.U // Represents 4 (four 1s) val oh = OH1.OH1ToOH(oh1_4) // 0b00010000 (single 1 at position 4) ``` -------------------------------- ### Best Practice: Use Type System for Channel Safety Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Scala example demonstrating how to use the type system to ensure channel safety for coherent operations. ```scala // Narrow type for coherent operations class CoherentController(param: TLLinkParameter) extends Module { require(param.hasBCEChannels) // Explicit requirement val tlLink = IO(new TLLink(param)) // Safe to use B, C, E channels } ``` -------------------------------- ### Simple Two-Master, Two-Slave Crossbar Configuration Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example configuration for a TileLink crossbar with two masters and two slaves, specifying their link parameters, visibility, and address ranges. ```Scala val master1 = TLCrossBarMasterLinkParameter( linkParameter = TLLinkParameter(32, 4, 4, 64, 5, false), adVisibility = BitSet(0, 1), // Access both slaves bceVisibility = BitSet(), srcIdRange = TLIdRange(0, 16) ) val master2 = TLCrossBarMasterLinkParameter( linkParameter = TLLinkParameter(32, 4, 4, 64, 5, false), adVisibility = BitSet(1), // Access only slave 1 bceVisibility = BitSet(), srcIdRange = TLIdRange(16, 32) ) val slave1 = TLCrossBarSlaveLinkParameter( linkParameter = TLLinkParameter(32, 8, 4, 64, 5, false), adVisibility = BitSet(0, 1), bceVisibility = BitSet(), sinkIdRange = TLIdRange(0, 8), addressRange = BitSet( BitPat("b0000_????_????_????_????_????_????_????") ) ) val slave2 = TLCrossBarSlaveLinkParameter( linkParameter = TLLinkParameter(32, 8, 4, 64, 5, false), adVisibility = BitSet(0, 1), bceVisibility = BitSet(), sinkIdRange = TLIdRange(8, 16), addressRange = BitSet( BitPat("b0001_????_????_????_????_????_????_????") ) ) val xbarConfig = TLCrossBarParameter( arbitrationPolicy = TLArbiterPolicy.Priority, masters = Seq(master1, master2), slaves = Seq(slave1, slave2) ) ``` -------------------------------- ### overlaps Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example usage of the overlaps method. ```scala val ranges = Seq( TLIdRange(0, 10), TLIdRange(15, 25), TLIdRange(20, 30) // Overlaps with previous ) val overlap = TLIdRange.overlaps(ranges) // Some((TLIdRange(15,25), TLIdRange(20,30))) ``` -------------------------------- ### Two-Input Priority Arbiter Configuration Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example configuration for a two-input priority arbiter, specifying the policy and link parameters for the CPU and DMA inputs, and the output. ```Scala val arbiterConfig = TLArbiterParameter( policy = TLArbiterPolicy.Priority, inputLinkParameters = Seq( TileLinkChannelAParameter(32, 4, 64, 5), // CPU (priority 0) TileLinkChannelAParameter(32, 4, 64, 5) // DMA (priority 1) ), outputLinkParameter = TileLinkChannelAParameter(32, 8, 64, 5) ) ``` -------------------------------- ### shift Method Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Demonstrates translating a TLIdRange by a fixed offset. ```scala val range = TLIdRange(0, 16) val shifted = range.shift(64) // TLIdRange(64, 80) ``` -------------------------------- ### Basic TL-UL Link (No Coherence) Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLLink.md Example of setting up and using a basic TL-UL link. ```scala val tlulParam = TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 1, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false ) val tlul = Module(new TLLink(tlulParam)) // Access only A and D channels tlul.a.valid := true.B tlul.a.bits.opcode := OpCode.Get tlul.a.bits.address := 0x1000.U tlul.a.bits.size := 3.U // 8 bytes val readData = tlul.d.bits.data val readValid = tlul.d.valid ``` -------------------------------- ### Trigger Example: Invalid TLLinkParameter Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Examples demonstrating how invalid TLLinkParameter values trigger AssertionError. ```scala // Fails: dataWidth not multiple of 8 val badParam = TLLinkParameter(32, 4, 4, 50, 5, false) // AssertionError: Width of data field must be multiples of 8 // Fails: dataWidth bytes not power-of-2 val badParam2 = TLLinkParameter(32, 4, 4, 96, 5, false) // AssertionError: Width of data field in bytes must be power of 2 // (96 bits = 12 bytes, not power of 2) ``` -------------------------------- ### Range Analysis Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example of analyzing and partitioning a TLIdRange. ```scala val sourceRange = TLIdRange(0, 64) // Check properties println(s"Range size: ${sourceRange.size}") println(s"Contains ID 32: ${sourceRange.contains(32)}") println(s"Contains ID 100: ${sourceRange.contains(100)}") // Partition val lower = TLIdRange(sourceRange.start, sourceRange.start + sourceRange.size/2) val upper = TLIdRange(lower.end, sourceRange.end) println(s"Lower: $lower, Upper: $upper") ``` -------------------------------- ### Best Practice: Defensive Optional Access Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Scala example showing how to safely access optional channels like channelBParameter by checking for their existence first. ```scala val tlLink = Module(new TLLink(tlParam)) // Always check before accessing optional channels tlLink.parameter.channelBParameter.foreach { bParam => when(tlLink.b.valid) { // Process probe } } ``` -------------------------------- ### Four-Input Round-Robin Arbiter Configuration Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Example configuration for a four-input round-robin arbiter, specifying the policy and link parameters for the inputs and the output. ```Scala val arbiterConfig = TLArbiterParameter( policy = TLArbiterPolicy.RoundRobin, inputLinkParameters = Seq.fill(4)( TileLinkChannelAParameter(32, 4, 64, 5) ), outputLinkParameter = TileLinkChannelAParameter(32, 16, 64, 5) ) ``` -------------------------------- ### Typical Usage of Channel C Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLChannel.md Examples demonstrating how Channel C is used for probe acknowledgments and voluntary releases. ```Scala In response to channel B probe: opcode = OpCode.ProbeAckData source = (matching B.source) data = (dirty cache line from L1) Or voluntary release: opcode = OpCode.ReleaseData address = 0x4000 source = 3.U ``` -------------------------------- ### TL-C Link with Coherence Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLLink.md Example of setting up and using a TL-C link with coherence channels. ```scala val tlcParam = TLLinkParameter( addressWidth = 40, sourceWidth = 8, sinkWidth = 8, dataWidth = 128, sizeWidth = 6, hasBCEChannels = true ) val tlc = Module(new TLLink(tlcParam)) // Full access to all five channels tlc.a.bits := /* ... */ tlc.b.bits := /* ... */ tlc.c.bits := /* ... */ tlc.d.bits := /* ... */ tlc.e.bits := /* ... */ ``` -------------------------------- ### Type Compatibility: Hardware Bundles Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLChannel.md Example of using channels within hardware bundles for synthesis and simulation. ```Scala val msg = Wire(new TLChannelA(param)) msg.opcode := OpCode.Get ``` -------------------------------- ### Creating a Simple TL-UL Link Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/index.md Example of creating a non-coherent TileLink link (TL-UL) and accessing its channels. ```Scala import org.chipsalliance.tilelink.bundle._ // Define link configuration val tlParam = TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 1, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false // Non-coherent ) // Create link bundle val tlLink = Module(new TLLink(tlParam)) // Access channels tlLink.a.valid := true.B tlLink.a.bits.opcode := OpCode.Get tlLink.a.bits.address := 0x1000.U tlLink.a.bits.size := 3.U // 8-byte read val readData = tlLink.d.bits.data val readValid = tlLink.d.valid ``` -------------------------------- ### OH1ToUInt Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Convert one-hot-1s encoded value to unsigned integer. ```scala val oh1 = 0b00000111.U // Three 1s in LSBs val result = OH1.OH1ToUInt(oh1) // 3.U ``` -------------------------------- ### Parameter Association Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLChannel.md Demonstrates how channels maintain a reference to their parameter object for width queries. ```Scala val channelA = Wire(new TLChannelA(param)) val addrWidth = channelA.parameter.addressWidth val sourceWidth = channelA.parameter.sourceWidth val dataWidth = channelA.parameter.dataWidth val sizeWidth = channelA.parameter.sizeWidth ``` -------------------------------- ### Type Compatibility: Pattern Matching Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLChannel.md Example of using channels in pattern matching for case analysis. ```Scala TLLink.hasData(x) match { case a: TLChannelA => // handle A case d: TLChannelD => // handle D } ``` -------------------------------- ### Best Practice: Validate Parameters Early Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Scala example of validating TLLinkParameter assumptions early in the mkController function. ```scala def mkController(tlParam: TLLinkParameter): Module = { // Validate assumptions up front require(tlParam.addressWidth >= 32, "Need at least 32-bit addresses") require(!tlParam.hasBCEChannels || tlParam.sinkWidth >= 3, "TL-C needs sink IDs") new Controller(tlParam) } ``` -------------------------------- ### Type Compatibility: DecoupledIO Wrapping Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLChannel.md Example of wrapping channels with DecoupledIO for flow control. ```Scala val decoupled = IO(DecoupledIO(new TLChannelA(param))) ``` -------------------------------- ### Dynamic Routing Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example of an IDRouter module that routes based on TLIdRange. ```scala class IDRouter(val ranges: Seq[TLIdRange]) extends Module { val id = IO(Input(UInt(8.W))) val destination = IO(Output(UInt(log2Ceil(ranges.size).W))) val matches = Wire(Vec(ranges.size, Bool())) ranges.zipWithIndex.foreach { case (range, idx) => matches(idx) := range.contains(id) } destination := OHToUInt(matches) } ``` -------------------------------- ### Two Masters, Two Slaves Configuration Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLCrossBar.md Example Scala code demonstrating the configuration of a TLCrossBar with two masters and two slaves, including link parameters and connections. ```Scala val masterA = TLCrossBarMasterLinkParameter( linkParameter = TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 4, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false ), adVisibility = BitSet(0, 1), // Can reach both slaves bceVisibility = BitSet(), srcIdRange = TLIdRange(0, 16) ) val masterB = TLCrossBarMasterLinkParameter( linkParameter = TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 4, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false ), adVisibility = BitSet(1), // Can reach only slave 1 bceVisibility = BitSet(), srcIdRange = TLIdRange(16, 32) ) val slaveA = TLCrossBarSlaveLinkParameter( linkParameter = TLLinkParameter( addressWidth = 32, sourceWidth = 8, sinkWidth = 4, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false ), adVisibility = BitSet(0, 1), bceVisibility = BitSet(), sinkIdRange = TLIdRange(0, 16), addressRange = BitSet( BitPat("b0000_????_????_????_????_????_????_????") // 0x0000_0000 - 0x0FFF_FFFF ) ) val slaveB = TLCrossBarSlaveLinkParameter( linkParameter = TLLinkParameter( addressWidth = 32, sourceWidth = 8, sinkWidth = 4, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false ), adVisibility = BitSet(0, 1), bceVisibility = BitSet(), sinkIdRange = TLIdRange(16, 32), addressRange = BitSet( BitPat("b0001_????_????_????_????_????_????_????") // 0x1000_0000 - 0x1FFF_FFFF ) ) val xbarParam = TLCrossBarParameter( arbitrationPolicy = TLArbiterPolicy.Priority, masters = Seq(masterA, masterB), slaves = Seq(slaveA, slaveB) ) val xbar = Module(new TLCrossBar(xbarParam)) // Connect master A to crossbar masterA_io.a <> xbar.masterLinksIO(0).a masterA_io.d <> xbar.masterLinksIO(0).d // Connect master B to crossbar masterB_io.a <> xbar.masterLinksIO(1).a masterB_io.d <> xbar.masterLinksIO(1).d // Connect slaves to crossbar xbar.slaveLinksIO(0).a <> slaveA_io.a xbar.slaveLinksIO(0).d <> slaveA_io.d xbar.slaveLinksIO(1).a <> slaveB_io.a xbar.slaveLinksIO(1).d <> slaveB_io.d ``` -------------------------------- ### Best Practice: Fail Fast with Informative Messages Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Scala example of a configureCrossbar function that fails fast with informative IllegalArgumentException for overlapping address ranges. ```scala def configureCrossbar(masters: Seq[TLCrossBarMasterLinkParameter], slaves: Seq[TLCrossBarSlaveLinkParameter]): TLCrossBarParameter = { require(masters.nonEmpty, "At least one master required") require(slaves.nonEmpty, "At least one slave required") val addressRanges = slaves.map(_.addressRange) TLIdRange.overlaps(addressRanges) match { case Some((r1, r2)) => throw new IllegalArgumentException( s"Address ranges must not overlap. Got $r1 and $r2") case None => () } TLCrossBarParameter( arbitrationPolicy = TLArbiterPolicy.Priority, masters = masters, slaves = slaves ) } ``` -------------------------------- ### Safe Channel Access Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLLink.md Example of safely accessing channels based on link parameters. ```scala val tlLink = Module(new TLLink(tlParam)) // Safe optional access without exceptions val hasB = tlLink.parameter.hasBCEChannels if (hasB) { tlLink.b.valid := true.B tlLink.b.bits.opcode := OpCode.ProbeBlock } ``` -------------------------------- ### Strategy 1: Check Configuration Before Access Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Safe access to TileLink channels by checking the configuration parameters before attempting access. ```scala val tlLink = Module(new TLLink(tlParam)) // Safe access with parameter check if (tlLink.parameter.hasBCEChannels) { tlLink.b.valid := true.B // Safe to access tlLink.c.bits := /* ... */ tlLink.e.bits := /* ... */ } ``` -------------------------------- ### TL-C Minimal Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md A minimal configuration for TL-C. ```scala val tlcMinimal = TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 4, dataWidth = 64, sizeWidth = 5, hasBCEChannels = true ) ``` -------------------------------- ### Building and Testing with Mill Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/index.md Commands for compiling, running tests, and generating output using the Mill build system. ```bash cd tilelink # Compile mill tilelink.compile # Run tests mill tests.elaborate # Elaborate test designs # Generate output mill tests.mfccompile.compile # Generate Verilog ``` -------------------------------- ### TLIdRange Validation Trigger Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Scala examples that trigger AssertionError exceptions for invalid TLIdRange values. ```scala // Fails: negative start val badRange = TLIdRange(-1, 10) // AssertionError: Ids cannot be negative, but got: -1 // Fails: end < start val badRange2 = TLIdRange(20, 10) // AssertionError: Id ranges cannot be negative ``` -------------------------------- ### TLCrossBarParameter Validation Trigger Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Scala example demonstrating how overlapping slave address ranges trigger an AssertionError in TLCrossBarParameter. ```scala val slave1 = TLCrossBarSlaveLinkParameter( /* ... */ addressRange = BitSet(BitPat("b0000_????")) // 0x0000 - 0x0FFF ) val slave2 = TLCrossBarSlaveLinkParameter( /* ... */ addressRange = BitSet(BitPat("b0000_????")) // Same range! ) // Fails: overlapping address ranges val xbar = TLCrossBarParameter( arbitrationPolicy = TLArbiterPolicy.Priority, masters = Seq(/* ... */), slaves = Seq(slave1, slave2) ) // AssertionError: Address ranges of different slaves cannot overlap: ... ``` -------------------------------- ### size Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Get the number of IDs in the range. ```scala def size: Int ``` -------------------------------- ### Strategy 3: Separate Modules for Different Variants Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Illustrates separating modules based on TileLink variants (coherent vs. non-coherent). ```scala // For TL-C links only class CoherentController(tlParam: TLLinkParameter) extends Module { require(tlParam.hasBCEChannels, "Controller requires TL-C coherence") val tlLink = IO(new TLLink(tlParam)) // Can safely use all channels } // For TL-UL links class SimpleController(tlParam: TLLinkParameter) extends Module { val tlLink = IO(new TLLink(tlParam)) tlLink.a.bits := /* ... */ // Only A and D guaranteed tlLink.d.bits := /* ... */ } ``` -------------------------------- ### range Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Get a Scala Range view of the interval. ```scala def range: Range ``` -------------------------------- ### TL-UL (Uncached, Lightweight) - 64-bit data Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Common configuration for TL-UL with 64-bit data. ```scala val tlul64 = TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 1, dataWidth = 64, sizeWidth = 5, hasBCEChannels = false ) ``` -------------------------------- ### Strategy 4: Parameterized Channel Access Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Implementing parameterized logic within a module to handle different TileLink channel configurations. ```scala class GenericController(tlParam: TLLinkParameter) extends Module { val tlLink = IO(new TLLink(tlParam)) // Parameterized logic if (tlParam.hasBCEChannels) { // Coherence-aware implementation tlLink.c.bits := /* ... */ } else { // Simple non-coherent implementation tlLink.a.bits := /* ... */ } } ``` -------------------------------- ### overlaps Method Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Shows how to check if two TLIdRange objects overlap. ```scala val r1 = TLIdRange(0, 16) val r2 = TLIdRange(15, 32) val r3 = TLIdRange(16, 32) r1.overlaps(r2) // true (both contain 15) r1.overlaps(r3) // false (adjacent but non-overlapping) ``` -------------------------------- ### Serialization Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example of serializing and deserializing TLIdRange instances to/from JSON using uPickle. ```scala import upickle.default._ val range = TLIdRange(16, 32) val json = write(range) // {"start": 16, "end": 32} val restored = read[TLIdRange](json) ``` -------------------------------- ### Hardware Generation Flow Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/architecture.md Steps involved in generating TileLink hardware, from Scala configuration to Verilog RTL. ```text TLLinkParameter (Scala config) ↓ TLLink class (elaborated with widths) ↓ Chisel RTL (hardware generated) ↓ TLChannelA/B/C/D/E bundles (sized fields) ↓ FIRRTL (intermediate representation) ↓ Verilog RTL or simulation ``` -------------------------------- ### ID Allocation in Crossbar Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Example of allocating source IDs to masters and validating no collisions. ```scala // Allocate source IDs to masters val masterSrcIds = Seq( TLIdRange(0, 16), // Master 0: 16 IDs TLIdRange(16, 32), // Master 1: 16 IDs TLIdRange(32, 48) // Master 2: 16 IDs ) // Validate no collisions TLIdRange.overlaps(masterSrcIds) match { case None => println("IDs allocated successfully") case Some((r1, r2)) => throw new IllegalArgumentException(s"Overlapping ranges: $r1 and $r2") } // Use in remapping val masterIndex = 1 val baseSourceId = masterSrcIds(masterIndex).start val remappedSource = incomingSourceId | baseSourceId.U ``` -------------------------------- ### TL-UL (Uncached, Lightweight) - 32-bit data Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Common configuration for TL-UL with 32-bit data. ```scala val tlul32 = TLLinkParameter( addressWidth = 32, sourceWidth = 4, sinkWidth = 1, dataWidth = 32, sizeWidth = 5, hasBCEChannels = false ) ``` -------------------------------- ### BitPat Serialization Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Serialization and deserialization logic for BitPat. ```scala implicit val bitPatSerializer: RW[chisel3.util.BitPat] = readwriter[String].bimap(_.rawString, s => chisel3.util.BitPat("b" ++ s)) ``` -------------------------------- ### Strategy 2: Use Optional Parameter Methods Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Using optional channel parameters to safely access channels that may not exist. ```scala val tlLink = Module(new TLLink(tlParam)) // Use optional channel parameters tlLink.parameter.channelBParameter.foreach { bParam => // Only execute if channel B exists val probeHandler = Wire(new TLChannelB(bParam)) probeHandler.opcode := OpCode.ProbeBlock } ``` -------------------------------- ### contains (Integer) Method Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Shows how to check if a TLIdRange contains a specific integer ID. ```scala val range = TLIdRange(10, 20) range.contains(15) // true range.contains(20) // false (exclusive end) range.contains(25) // false ``` -------------------------------- ### contains (Range) Method Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Demonstrates checking if one TLIdRange fully contains another. ```scala val parent = TLIdRange(0, 32) val child = TLIdRange(8, 16) val outside = TLIdRange(16, 48) parent.contains(child) // true parent.contains(outside) // false ``` -------------------------------- ### Minimal Transaction for Channel E Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLChannel.md An example of a minimal transaction on Channel E, acknowledging a channel D Grant. ```Scala Response to channel D Grant (sink=5): sink = 5.U // Match the grant response ``` -------------------------------- ### masterLinksIO Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLCrossBar.md Input ports for master devices. ```scala val masterLinksIO: Seq[TLLink] ``` -------------------------------- ### contains (UInt - Hardware) Method Example Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLIdRange.md Illustrates generating hardware to check if a UInt ID is within a TLIdRange. ```scala val range = TLIdRange(16, 32) val id = Wire(UInt(6.W)) val isInRange = range.contains(id) // Generates compare circuit when(isInRange) { // ID is in [16, 32) range } ``` -------------------------------- ### Handling Coherence Channels Safely Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/index.md Demonstrates safe access to coherence channels (B and C) in a TLLink, checking for their existence and handling data. ```scala val tlc = Module(new TLLink(tlcParam)) // Safe access to coherence channels if (tlc.parameter.hasBCEChannels) { // Only executed for TL-C links when(tlc.b.valid) { println("Received coherence probe") } tlc.c.bits := /* ... */ } // Or using optional parameters tlc.parameter.channelBParameter.foreach { _ => // Channel B exists tlc.b.ready := true.B } ``` -------------------------------- ### TLIdRange Case Class Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/types.md Represents a half-open range [start, end) for ID space allocation, extending Ordered[TLIdRange]. ```Scala case class TLIdRange(start: Int, end: Int) extends Ordered[TLIdRange] ``` -------------------------------- ### slaveLinksIO Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLCrossBar.md Output ports for slave devices. ```scala val slaveLinksIO: Seq[TLLink] ``` -------------------------------- ### Adding New Arbitration Policies Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/architecture.md Scala code snippets demonstrating how to add a new arbitration policy to TileLink. ```scala case object WeightedRoundRobin extends TLArbiterPolicy implicit val rw: RW[this.type] = macroRW ``` -------------------------------- ### BitSet Serialization Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Serialization and deserialization logic for BitSet. ```scala implicit val bitSetSerializer: RW[chisel3.util.experimental.BitSet] = readwriter[Seq[chisel3.util.BitPat]].bimap( _.terms.toSeq, chisel3.util.experimental.BitSet(_: _*) ) ``` -------------------------------- ### TLLinkParameter Case Class Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md The TLLinkParameter case class is the primary configuration object for a TileLink link. ```scala case class TLLinkParameter( addressWidth: Int, sourceWidth: Int, sinkWidth: Int, dataWidth: Int, sizeWidth: Int, hasBCEChannels: Boolean) ``` -------------------------------- ### TLCrossBarParameter Case Class Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Complete crossbar configuration combining arbitration policy and port parameters. ```scala case class TLCrossBarParameter( arbitrationPolicy: TLArbiterPolicy, masters: Seq[TLCrossBarMasterLinkParameter], slaves: Seq[TLCrossBarSlaveLinkParameter]) ``` -------------------------------- ### TLCrossBarMasterLinkParameter Case Class Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Master port configuration for TLCrossBarParameter. ```scala case class TLCrossBarMasterLinkParameter( linkParameter: TLLinkParameter, adVisibility: chisel3.util.experimental.BitSet, bceVisibility: chisel3.util.experimental.BitSet, srcIdRange: TLIdRange) ``` -------------------------------- ### TL-C (Cached, with coherence) - 128-bit data Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Common configuration for TL-C with 128-bit data. ```scala val tlc128 = TLLinkParameter( addressWidth = 40, sourceWidth = 8, sinkWidth = 8, dataWidth = 128, sizeWidth = 6, hasBCEChannels = true ) ``` -------------------------------- ### Configuration JSON Format Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md This JSON object defines the configuration for TileLink utilities, including arbitration policy, master configurations with link parameters and ID ranges, and slave configurations. ```json { "arbitrationPolicy": { "$type": "Priority" }, "masters": [ { "linkParameter": { "addressWidth": 32, "sourceWidth": 4, "sinkWidth": 4, "dataWidth": 64, "sizeWidth": 5, "hasBCEChannels": false }, "adVisibility": ["b???????"], "bceVisibility": [], "srcIdRange": { "start": 0, "end": 16 } } ], "slaves": [/* ... */] } ``` -------------------------------- ### Serializers Object Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/Utilities.md Configuration serialization support for JSON round-tripping of TileLink parameters. ```scala object Serializers { implicit val bitPatSerializer: RW[chisel3.util.BitPat] implicit val bitSetSerializer: RW[chisel3.util.experimental.BitSet] } ``` -------------------------------- ### Hardware Assertions in TLArbiter Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/errors.md Scala code for runtime hardware assertions in TLArbiter to ensure correct arbitration logic. ```scala // Never two winners assert(prefixOR.zip(winner).map { case (p, w) => !p || !w }.reduce { _ && _ }) // If any request, some source wins assert(!valids.reduce(_ || _) || winner.reduce(_ || _)) ``` -------------------------------- ### fanout Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/api-reference/TLCrossBar.md Distribute a single input channel to multiple output channels based on selection vector. ```scala private def fanout( input: DecoupledIO[TLChannel], select: Seq[Bool] ): Seq[DecoupledIO[TLChannel]] ``` -------------------------------- ### TileLinkChannelCParameter Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Channel C parameters derived from TLLinkParameter (if hasBCEChannels). ```scala TileLinkChannelCParameter( addressWidth: Int, sourceWidth: Int, dataWidth: Int, sizeWidth: Int ) ``` -------------------------------- ### TileLinkChannelAParameter Source: https://github.com/chipsalliance/tilelink/blob/master/_autodocs/configuration.md Channel A parameters derived from TLLinkParameter. ```scala TileLinkChannelAParameter( addressWidth: Int, sourceWidth: Int, dataWidth: Int, sizeWidth: Int ) ```