State & Initialization
Semantically, every DFiant dataflow variable references a token stream (TS).
-
Unless stated otherwise, all dataflow variables are always consuming and always producing.
-
Previous token initialization:
-
The token history stream can be initialized.
-
Initialization does not mutate the dataflow variable.
-
Initialization has no effect on the TS. Only when using
prevthe initialization is placed on the TS reference. -
initreturns a reference to a new (initialized) dataflow variable, but maintains the mutability trait dataflow variable. -
Bubble tokens (?) :
-
Produced when a
previs called on a non-initialized dataflow variable. E.g.,Code Init Token Stream in : DFUInt[32]?2, 3, 1, 5, 9in.prev??, 2, 3, 1, 5, 9in.prev(2)??, ?, 2, 3, 1, 5, 9in.prev.prev??, ?, 2, 3, 1, 5, 9val in1 = in.init(1); in112, 3, 1, 5, 9in1.prev11, 2, 3, 1, 5, 9in1.prev(2)11, 1, 2, 3, 1, 5, 9in1.prev.init(8)81, 2, 3, 1, 5, 9val innew = DFUInt(32) := in1; innew?2, 3, 1, 5, 9val ins7 = in.init(7, ?); ins7(7, ?)2, 3, 1, 5, 9ins7.prev?7, 2, 3, 1, 5, 9val ins78 = in.init(7, 8, ?); ins78(7, 8, ?)2, 3, 1, 5, 9ins78.prev(8, ?)7, 2, 3, 1, 5, 9ins78.prev(2)?8, 7, 2, 3, 1, 5, 9in.init(7).prev.init(8, ?).prev?8, 7, 2, 3, 1, 5, 9 -
Bubbles are like any regular-value tokens in terms of consumption and production rules.
-
Bubbles are used to set phases between synchronized token streams by acting as a token place-holder within the stream queue.
-
Unless stated otherwise, any operation with a bubble token produces a bubble token (consuming the non-bubble token.). E.g.,
1 2 3
def foo(a : DFUInt(8)) = a + a.prev //'in' is token stream of: 2, 3, 1, 5, 9 //'foo(in)' returns: ?, 5, 4, 6, 14 -
prevmaintains Distributivity through basic operations e.g.:(a + b).prev≗a.prev + b.prev(timeless TS equality).Code Init Token Stream inL : DFUInt(32)?2, 3, 1, 5, 9inR : DFUInt(32)?4, 0, 2inL + inR?+?=?2, 3, 1, 5, 9+4, 0, 2=6, 3, 3inL + inR.prev?+?=?2, 3, 1, 5, 9+?, 4, 0, 2=?, 7, 1, 7inL.init(1) + inR.init(3).prev1+3=42, 3, 1, 5, 9+3, 4, 0, 2=5, 7, 1, 7inL.init(1, ?) + inR.init(3).prev(1, ?)+3=(4, ?)2, 3, 1, 5, 9+3, 4, 0, 2=5, 7, 1, 7inL.init(1) + inR.init(3, ?).prev1+?=?2, 3, 1, 5, 9+3, 4, 0, 2=5, 7, 1, 7inL.init(1).prev + inR.init(3).prev1+3=41, 2, 3, 1, 5, 9+3, 4, 0, 2=4, 6, 3, 3(inL.init(1) + inR.init(3)).prev1+3=4(2, 3, 1, 5, 9+4, 0, 2).prev =4, 6, 3, 3 -
Bubbles are typically treated differently at the edges of the dataflow paths, when bridging to the real-time world. E.g.: not committing bubbles to memory cells, or not raising ready flags.
-
Casting:
-
Parts of a bits vector can be bubbles while others normal values.
-
However, when casting to a number (e.g., DFUInt), the casting must check validity of all bits.