Open mczyz-antmicro opened 5 months ago
Great writeup! I agree this is something we need. I think initially we could support this with annotations on a channel indicating that the channel is single-value and just use receives as normal.
A better longer term solution might be a first class construct ("wire" maybe?) which indicates a direct connection to a port. Such a value could be used directly within the proc. I have some ideas about the possible syntax and a related concept of a stateful block at the DSLX level which is basically an always_ff to enable expressing arbitrary RTL in a latency sensitive way.
Background
DSLX channels always infer a (valid,ready) handshake mechanism, based on the
send()
andrecv()
functions. Additional control is provided by conditional and non-blocking variants of these functions:send_if
,recv_if
,recv_if_non_blocking
Problem statement
There are digital designs that either can't be expressed with a (valid,ready) handshake, or become less than suboptimal.
Use case 1: Configuration
Use case 1 is motivated by an example of a bank of Control and Status Registers. CSRs can be read-only for some processes. From hardware point of view, information stored in CSRs should be read by the subordinate processes constantly to guarantee instant response to a configuration change.
Process A provides configuration for process B. In this example, term "configuration" refers to any data structure that is:
HDL
Module A:
Module B:
In module B it is enough to define configuration as input and the data structure becomes available for processing.
DSLX
In DSLX, however, attempts at expressing these hardware constructs would like this:
Process A:
Process B:
Observations
recv
in the blocking form.state
of the process, because otherwise it would only be available in ticks, when configuration changes. This creates further overhead, compared to HDL description.Use case 2: Interrupts
Use case when (valid,ready) handshake is not only not needed, but presumably incorrect, are interrupt signals.
Typically, the interrupt signal is a single wire signal, which does not rely on a handshake to send information. Any assertion of the signal should be interpreted by the hardware accordingly to the designers intent.
Currently:
Further comments about Single Value Channels
What is great about HDL descriptions is that when we connect 2 modules with ports is that data stored in the data bus is always readily available for both modules to use without any further overhead.
In order to express this mechanism in DSLX, we would have to create connections, which do not need to use send/recv pairs. This is suitable to describe a static configuration link, that is such that no flow control is associated with the link and changes to it may occur without any constraints. Ultimately, this leads us back to using the SingleValue Channels. Let's take a look at an example in C-frontend:
The resulting verilog module declaration:
Wires
r
,up
,down
,read
do not have associated valid/ready handshakes and are simply captured into registers:which later affect the state of the module, e.g.:
About DSLX overhead
Compared to HDL, the overhead in DSLX is that:
init
function,next
prototype andnext
return value, so adding 1 field to the state results in 3 updates to the code (Using structs does not reduce this number).Summary