Differences
This shows you the differences between two versions of the page.
| Both sides previous revisionPrevious revisionNext revision | Previous revision | ||
| language:langs:dflow [2023/02/11 17:04] – [Deterministic and non-deterministic merge] rajit | language:langs:dflow [2026/05/19 10:30] (current) – [Initial tokens] rajit | ||
|---|---|---|---|
| Line 16: | Line 16: | ||
| The dataflow language has the following primitives: | The dataflow language has the following primitives: | ||
| * Function: reads tokens on all of its inputs, computes some function of those inputs, and produces an output token in response; | * Function: reads tokens on all of its inputs, computes some function of those inputs, and produces an output token in response; | ||
| - | * Split: conditionally routes an input token to one of its outputs; | + | * Split (a.k.a. demux): conditionally routes an input token to one of its outputs; |
| - | * Controlled merge (a.k.a. | + | * Controlled merge (a.k.a. |
| - | * Deterministic merge: assumes | + | * Merge: this component waits for the arrival of an input token on any one of its inputs, and sends the arriving |
| - | * Non-deterministic merge: | + | * Deterministic merge: assumes input token arrivals are mutually exclusive |
| + | | ||
| * Initial tokens: these are specified directly in the syntax | * Initial tokens: these are specified directly in the syntax | ||
| - | * Copy: implicit, with the same channel is used for multiple inputs | + | * Copy (a.k.a. fork): implicit, with the same channel is used for multiple inputs |
| * Sources and sinks have short-hand syntax. | * Sources and sinks have short-hand syntax. | ||
| ===== Function ===== | ===== Function ===== | ||
| - | The syntax shown above corresponds to the // | + | The syntax shown in the first example |
| - | ===== Split ===== | + | By default, a function implicitly contains a buffer. However, functions can also have additional buffering on their output. The syntax used for this purpose is shown below. |
| + | <code act> | ||
| + | dataflow { | ||
| + | a + b -> [2] c | ||
| + | } | ||
| + | </ | ||
| + | In this example, one extra buffer stage is added to the output of '' | ||
| + | <code act> | ||
| + | dataflow { | ||
| + | a + b -> c1; | ||
| + | c1 -> c | ||
| + | } | ||
| + | </ | ||
| + | The '' | ||
| + | |||
| + | |||
| + | ===== Split or Demux ===== | ||
| The //split// dataflow element receives a control token and a data token, and uses the value of the control token to route the data token to one of the output channels. If the control token=0, the first channel is used; if it is 1, then the next channel is used; etc. The syntax for this is shown below: | The //split// dataflow element receives a control token and a data token, and uses the value of the control token to route the data token to one of the output channels. If the control token=0, the first channel is used; if it is 1, then the next channel is used; etc. The syntax for this is shown below: | ||
| Line 57: | Line 74: | ||
| <code act> | <code act> | ||
| dataflow { | dataflow { | ||
| - | {c = 0 ? 1 : 0} A -> X, Y | + | {c = 0 ? 0 : 1} A -> X, Y |
| } | } | ||
| </ | </ | ||
| Line 64: | Line 81: | ||
| < | < | ||
| dataflow { | dataflow { | ||
| - | c = 0 ? 1 : 0 -> ctrl; | + | c = 0 ? 0 : 1 -> ctrl; |
| {ctrl} A -> X, Y | {ctrl} A -> X, Y | ||
| } | } | ||
| </ | </ | ||
| - | ===== Controlled merge ===== | + | ===== Controlled merge or Mux ===== |
| The // | The // | ||
| Line 92: | Line 109: | ||
| } | } | ||
| </ | </ | ||
| - | The fact that '' | + | The fact that '' |
| In pipelined circuits, it is important to be able to introduce slack to optimize performance. The syntax for this is the following: | In pipelined circuits, it is important to be able to introduce slack to optimize performance. The syntax for this is the following: | ||
| Line 110: | Line 127: | ||
| } | } | ||
| </ | </ | ||
| - | This specifies that not only are there four pipeline stages, but the initial output produced on the '' | + | This specifies that not only are there four pipeline stages, but the initial output produced on the '' |
| The description so far is a complete set of dataflow primitives and can be used to [[https:// | The description so far is a complete set of dataflow primitives and can be used to [[https:// | ||
| Line 196: | Line 213: | ||
| </ | </ | ||
| + | Dataflow clusters are hints to the implementation that these dataflow elements should be grouped together---for example, by having a single control that is shared by all the elements of the cluster. | ||
| + | Finally, consider the following dataflow example: | ||
| + | <code act> | ||
| + | dataflow { | ||
| + | a + b -> c; // produce an output on channel c | ||
| + | d + e -> out // sum d and e and produce the output on out | ||
| + | } | ||
| + | </ | ||
| + | Furthermore, | ||
| + | When optimizing the dataflow block, one may decide to group the control for the two dataflow elements. However, doing so would result in deadlock, because the combined dataflow block would wait for inputs to arrive on '' | ||
| + | |||
| + | To simplify optimizations, | ||
| + | <code act> | ||
| + | dataflow { | ||
| + | order { | ||
| + | c < e // c must be produced before e is available | ||
| + | } | ||
| + | a + b -> c; | ||
| + | d + e -> out | ||
| + | } | ||
| + | </ | ||
| + | In general, the order block contains a semi-colon separated list of directives. Each directive is a list of comma-separated channels followed by ''<'' | ||
| + | |||
| + | ====== Syntactic replication ====== | ||
| + | |||
| + | The dataflow sub-language has support for syntactic replication for splits, merges, mixers, and arbiters. For a split, the output side can use syntactic replication; | ||
| + | For example, the following syntax is legal (assuming everything is of the right type): | ||
| + | <code act> | ||
| + | dataflow { | ||
| + | {ctrl} l -> (, i : 8 : out[i]) | ||
| + | } | ||
| + | </ | ||