Skip to content

abs-tudelft/Tydi-Chisel

Repository files navigation

Tydi-Chisel

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.

What is Tydi?

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.

Why Tidy?

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.

Example

Using Tydi data-structures and streams

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)
}

Testing a TydiModule

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.

Getting started

Acquire the lib

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

Use the lib

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.

Features

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

Future work

  • 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 for parallel 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

Publications

  • 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.

License

Tydi and this library are licensed under the Apache-2.0 license. See LICENSE.

Related Tools

  • Tydi-Lang-2
    A tool for converting Tydi-lang code to a json representation of all logic types, streamlets, and implementations.
  • Tydi-Lang-2-Chisel
    Consequtively converts the json 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.

About

No description, website, or topics provided.

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

 
 
 

Languages