Tydi-Chisel allows you to transfer simple to very complex nested variable length sequences between components over a stream bus in a structured way, using familiar Chisel concepts.
Tydi-Chisel is an implementation of Tydi interfaces and concepts in Chisel.
Tydi (Typed dataflow interface) is an open specification for streaming dataflow designs in digital circuits, allowing designers to express how composite and variable-length data structures are transferred over streams using clear, data-centric types.
Chisel (Constructing Hardware in a Scala Embedded Language) is a high-level open-source hardware description language (HDL).
With Tydi as data-streaming communication flow specification and Chisel as flexible implementation, an interface-driven design method can be followed.
Developing hardware is notoriously difficult. Many solutions exist to lighten the load of developing implementations for hardware components. Yet, a gap exists between the easy use of complex nested (sequence) data structures in software and trying to work with them in hardware.
Tydi aims to solve this issue by proposing an open standard for streams of arbitrary variable length data-structures. A data-structure is created by nesting Bits
, Group
, Union
and Stream
elements. See the following table for the meaning of the used terms.
Term | Type | Software equivalent | Chisel equivalent | Meaning |
---|---|---|---|---|
Null | Logical type | Null |
Bits(0) |
Empty data |
Bit | Logical type | Any primary datatype | Ground hardware type | Primary datatype of x bits |
Group | Logical type | Struct /dict /map |
Bundle |
Aggregate of several logic types |
Union | Logical type | Union |
Bundle with tag |
“pick one” of several logic types |
Stream | Logical type | Bus to transport sequence of instance | – | Specify how to transport logic type |
Streamlet | Hardware element | Interface |
Trait with IO defs |
IO specification of component |
Impl | Hardware element | Class with functionality |
Module |
Inner structure of component |
By being a super-set of ready-valid communication, like Chisel's DecoupledIO
, and the AXI-Stream standard, Tydi-interfaces stay close to existing streaming implementations.
See the work in publications for more details.
The following example provides an overview of the declaration of a nested Tydi data structure and its usage in streams.
In software, the declared data structure would look like
[
{
"time": 123456789,
"nested": {
"a": 5,
"b": true
},
"message": [
"Hello", "this", "is", "a", "string."
]
}
]
// Declaration of the data-structure
class Character extends BitsEl(8.W)
class NestedBundle extends Group {
val a: UInt = UInt(8.W)
val b: Bool = Bool()
}
class TimestampedMessageBundle extends Group {
val time: UInt = UInt(64.W)
val nested: NestedBundle = new NestedBundle
// Create a 2D sub-stream of character data with 3 data-lanes
val message = new PhysicalStreamDetailed(Character, n = 3, d = 2, c = 7)
}
// Declaration of the module
class TimestampedMessageModule extends TydiModule {
// Create Tydi logical stream object
val stream = PhysicalStreamDetailed(new TimestampedMessageBundle, 1, c = 7)
// Create and connect physical streams as IO
// following the Tydi standard with concatenated data bitvector
val tydi_port_top = stream.toPhysical
val tydi_port_child = stream.el.message.toPhysical
// → Assign values to logical stream group elements directly
stream.el.time := System.currentTimeMillis().U
stream.el.nested.a := 5.U
stream.el.nested.b := true.B
stream.el.message.data(0).value := 'H'.U
stream.el.message.data(1).value := 'e'.U
stream.el.message.data(2).value := 'l'.U
...
}
See the timestamped_message file for the full example. This file is just for showing the syntax of declaring and using Tydi-interfaces. It does not contain an implementation. For that, look at the pipeline examples. There you will also find advanced syntax for the creation of modules and chaining of submodules through their streams:
...
class PipelineExampleModule extends SimpleProcessorBase(new NumberGroup, new Stats) {
out := in.processWith(new NonNegativeFilter).processWith(new Reducer)
}
The code below shows a snippet from the pipeline example test code. It shows how to use the TydiStreamDriver to easily enqueue and dequeue data to sink and from source streams. Currently, this is only available for ChiselTest, and not ChiselSim.
// Import stuff
class PipelineExampleTest extends AnyFlatSpec with ChiselScalatestTester {
behavior of "PipelineExample"
class PipelineWrap extends TydiTestWrapper(new PipelineExampleModule, new NumberGroup, new Stats)
it should "process a sequence" in {
// Test code
test(new PipelineWrap) { c =>
// Initialize signals
c.in.initSource()
c.out.initSink()
// Generate list of random numbers
val nums = randomSeq(n = 50)
val stats = processSeq(nums) // Software impl.
// Test component
parallel({
for ((elem, i) <- nums.zipWithIndex) {
c.in.enqueueElNow(_.time -> i.U, _.value -> elem.S)
}
c.in.enqueueEmptyNow(last = Some(c.in.lastLit(0 -> 1.U)))
}, {
c.out.waitForValid()
// Utility for comprehensively printing stream state
println(c.out.printState(statsRenderer))
c.out.expectDequeue(_.min -> stats.min.U, _.max -> stats.max.U, _.sum -> stats.sum.U, _.average -> stats.average.U)
})
}
}
}
Look through the test examples for all functionality and syntax.
To get started with Tydi-Chisel, you can either run it in your local development environment, or use the Tydi-tools docker container.
For usage with sbt
or scala-cli
, the project package must first be built. Make sure you have git
, java
, and sbt
installed and available in your path.
git clone https://github.com/abs-tudelft/Tydi-Chisel.git
sbt publishLocal
After this, the library can be added to your project's dependencies in your build.sbt
like so.
libraryDependencies += "nl.tudelft" %% "tydi-chisel" % "0.1.0"
libraryDependencies += "nl.tudelft" %% "tydi-chisel-test" % "0.1.0" % Test
When using scala-cli
, use the following directive:
//> using dep "nl.tudelft::tydi-chisel::0.1.0"
Then, one can import the functionality, and start to write Tydi-Chisel code!
import nl.tudelft.tydi_chisel._
Look through the examples for inspiration for the functionality and syntax.
Concretely, this project contains:
- Expressing Tydi stream interfaces in Chisel
- Including nested stream support
- Being able to work with the detailed bundles inside your components
- Compliant with Tydi-standard for communication with components created outside of Chisel
- Simple stream connection
- Stream compatibility checks
- Helper functions for common signal use-cases
- A stream-processing component chaining syntax
- Testing utilities
chisel-test
driver for Tydi stream interfaces.
- Helper components
- A stream complexity converter that can convert any incoming stream to the lowest source complexity
- A multi-processor or interleaving component that splits a multi-lane stream into multiple single lane streams for easy processing, merging them again after.
- A Tydi-lang-2-Chisel transpiler
to convert Tydi interfaces described in Tydi-lang-2 to Chisel code utilizing the Tydi-Chisel library.- A reverse-transpiler to share your Tydi-Chisel code as Tydi-lang-2 code
- Projects
- Provide more worked out real-life examples
- Create interoperability with Fletcher
- Investigate adoption of other hardware description languages
- Library
- Better Union support
- Interoperability with other streaming standards
- Improved error handling and design rule checks
- Additional helper components
- Testing and debugging
- Change testing front-end to the new ChiselSim framework.
This can currently not happen yet as ChiselSim still lacks support forparallel
calls, which makes it hard to do asynchronous component testing. - Improved tooling for enqueueing and dequeueing of test data
- Stream protocol compliance verification tooling
- Enhanced support for TyWaves
- Provide more time-domain information
- Change testing front-end to the new ChiselSim framework.
- C. Cromjongh, Y. Tian, Z. Al-Ars and H. P. Hofstee
Enabling Collaborative and Interface-Driven Data-Streaming Accelerator Design with Tydi-Chisel
2023 IEEE Nordic Circuits and Systems Conference (NorCAS), 1 November 2023. DOI: 10.1109/NorCAS58970.2023.10305451.
Tydi and this library are licensed under the Apache-2.0 license. See LICENSE.
- Tydi-Lang-2
A tool for converting Tydi-lang code to ajson
representation of all logic types, streamlets, and implementations. - Tydi-Lang-2-Chisel
Consequtively converts thejson
tydi definitions to Chisel code utilising Tydi-Chisel. - TyWaves
A type based waveform viewer for Chisel and Tydi-Chisel, combining CIRCT debug output with the Surfer waveform viewer. - Tydi repository
Contains Tydi standard documentation and first implementation of a compiler.