[enhancement] Add latency-sensitive block construct to DSLX
- Dominant language
- C++
- Stars
- 1.9k
- Forks
- 283
- Avg merge
- 2d 10h
- Merged PRs (30d)
- 135
Description
### What's hard to do? (limit 100 words)
Expressing cycle-by-cycle latency-sensitive components is difficult in DSLX. It'd be good to have a mechanism for writing things at the RTL-level of abstraction. Many components can be built in a latency insenstive way, but invariably every design needs some latency-sensitive parts.
### Current best alternative workaround (limit 100 words)
There is no workaround.
### Your view of the "best case XLS enhancement" (limit 100 words)
XLS IR has a `block` construct which is an RTL-level representation. We need a syntax in DSLX which can lower directly to IR Blocks. This proposal mimics proc dslx syntax.
To express things at the RTL-level we need roughly need ports, registers, and combinational logic.
This syntax adds the following constructs:
* `block`: a container analogous to a proc which maps to a verilog module. It is guaranteed to iterate every cycle.
* `wire`: a latency-sensitive analog to a channel. It maps to directly to ports and connections between them. Wire inputs can be used directly in expressions. Wire outputs use `set` to indicate what value is presented on the output port each cycle.
* block state: analogous to proc state. This maps to registers.
Example syntax of a block which accumulates the value at input port `x` every cycle and presents the accumulated value on the output port `result` every cycle. The block has one 32-bit state element.
```
block accum {
x: wire in;
result: wire out;
init { u32:0 }
config(x: wire in, result: wire out) {
(x, result)
}
next(sum: u32) {
let next_sum = x + sum;
set(result, next_sum);
next_sum
}
}
```
Instantiations should also be supported. Possible syntax:
```
block accum_wrapper {
x: wire in;
a: wire out;
b: wire in;
result: wire out;
init { () }
config(x: wire in, result: wire out) {
let (a_accum_in, a_out) = wire;
let (b_in, b_out) = wire;
spawn accum(a_out, b_in);
(x, a_in, b_out, result)
}
next(st: ()) {
set(a, x + u32:1);
set(result, -2 * b);
()
}
}
```
TBD: Interrop with latency senstive components. Rough idea is channels can be composed/decomposed from wires to connect blocks and procs.
FYI @cdleary
Contributor guide
Assessment
This issue has not been assessed yet.