You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Copy file name to clipboardExpand all lines: docs/user-guide/design-hierarchy/index.md
+7-8Lines changed: 7 additions & 8 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -172,6 +172,9 @@ Since this design is annotated with `@top`, it is a top-app design that generate
172
172
The `@top` annotation captures any [implicit/given](https://docs.scala-lang.org/scala3/book/ca-context-parameters.html#given-instances-implicit-definitions-in-scala-2){target="_blank"} options within its scope and provides them as defaults when no CLI arguments are specified.
Looking at the generated Verilog code, we can observe several key differences from the DFHDL source:
176
179
177
180
1.**Module Interface**: DFHDL's Scala-style port declarations (`<> IN/OUT`) are translated to traditional Verilog port declarations (`input wire`/`output logic`)
@@ -184,12 +187,12 @@ Looking at the generated Verilog code, we can observe several key differences fr
184
187
185
188
5.**Assignment Syntax**: DFHDL's `:=` assignments are translated to Verilog's `assign` statements
The generated VHDL code shows similar transformations from the DFHDL source:
194
197
195
198
1.**Entity Interface**: DFHDL's port declarations are translated to VHDL's `in`/`out` mode declarations with explicit signal types
@@ -201,10 +204,6 @@ The generated VHDL code shows similar transformations from the DFHDL source:
201
204
4.**Signal Types**: DFHDL's `Bits` type is translated to VHDL's `std_logic_vector` with appropriate widths
202
205
203
206
5.**Assignment Syntax**: While both DFHDL and VHDL use `:=`, the semantics differ - DFHDL represents high-level connections while VHDL represents signal assignments
@@ -240,7 +239,7 @@ The DFHDL design parameter block follows standard Scala syntax, accepting a comm
240
239
#### `LeftShiftBasic` example {#LeftShiftBasic}
241
240
/// admonition | Scala-parameterized top-app design example: a basic left shifter
242
241
type: example
243
-
The DFHDL code below implements a basic left shifter design named `LeftShiftBasic`. This design is similar to the earlier example of `LeftShift2` except here the design has the shift value as an input, and its input and output port widths are set according to the Scala parameter `width`.
242
+
The DFHDL code below implements a basic left shifter design named `LeftShiftBasic`. This design is similar to the earlier example of [`LeftShift2`][LeftShift2], except here the design has the shift value as an input, and its input and output port widths are set according to the Scala parameter `width`.
Copy file name to clipboardExpand all lines: docs/user-guide/type-system/index.md
+56-27Lines changed: 56 additions & 27 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -189,15 +189,12 @@ class Foo extends DFDesign:
189
189
190
190
/// details | Transitioning from Verilog
191
191
type: verilog
192
-
* Declaration Syntax: Port and variable declaration syntax is obviously very different
193
-
* Types:
194
-
* Scope
195
-
* The non-blocking assignment operator in DFHDL is `:==` instead of `<=` in Verilog.
192
+
TODO
196
193
///
197
194
198
195
/// details | Transitioning from VHDL
199
196
type: vhdl
200
-
* VHDL has
197
+
TODO
201
198
///
202
199
203
200
@@ -327,10 +324,7 @@ Ports can be grouped together in dedicated [interfaces][interfaces].
327
324
328
325
/// details | Transitioning from Verilog
329
326
type: verilog
330
-
* Declaration Syntax: Port and variable declaration syntax is obviously very different
331
-
* Types:
332
-
* Scope
333
-
* The non-blocking assignment operator in DFHDL is `:==` instead of `<=` in Verilog.
327
+
TODO
334
328
///
335
329
336
330
/// details | Transitioning from VHDL
@@ -451,37 +445,72 @@ class Foo extends DFDesign:
451
445
///
452
446
453
447
454
-
## DFHDL Value Mutation {#mutability}
448
+
## Bit-Accurate Operations and Type Inference
455
449
456
-
DFiant supports dataflow variables mutability via the `:=` operator. Do not confuse with Scala-level mutability which is enabled by using `#!scala var` instead of `#!scala val`. Each dataflow class has two variations: an immutable class, which inherits from `DFAny.Val` and a mutable class, which inherits from `DFAny.Var` and accepts `:=`. The difference between the types enforces an immutable right-hand-side (RHS), where required, and a mutable variable creation.
450
+
DFHDL provides bit-accurate operations and strong type inference for bit-level manipulations. Here are the key features:
457
451
458
-
Consider, for instance, the DFiant implementation of `g` in Table \ref`tbl:StateExDefImpl`: `a` is immutable because it is a RHS addition between the dataflow variable `i` and a literal value `5`. Contrarily, `c` is mutable, since it is a dataflow variable constructor (`.init` constructs a new initialized variable, while preserving the mutability trait).
452
+
### Bit Selection and Slicing
453
+
```scala
454
+
val b8 = Bits(8) <> VAR
455
+
// Most significant bits selection
456
+
val ms7 = b8(7, 1) // 7 MSBs
457
+
val ms1 = b8(7, 7) // MSB only
459
458
460
-
Fig. 1 demonstrates a dual class definition for every type (immutable and mutable). The naming convention helps to reason about the mutability. For example, `DFBits` and `DFBits.Var` are immutable and mutable classes, respectively. Constructing a new variable via `DFBits` (e.g, `#!scala val a = DFBits[5]`) returns the mutable `DFBits.Var[5]`. Usually, we either receive or return an immutable type, hence we do not require annotating a type with its mutable variation. In cases where we want to return a mutable type, we annotate it as an output port (see Section~\ref`sec:io_ports`).
459
+
// Least significant bits selection
460
+
val ls7 = b8(6, 0) // 7 LSBs
461
+
val ls1 = b8(0, 0) // LSB only
461
462
463
+
// Single bit access
464
+
val msbit = b8(7) // MSB
465
+
val lsbit = b8(0) // LSB
466
+
```
462
467
463
-
## Bit-Accurate Operations, Type Inference, and Data Structures
468
+
### Bit Operations
469
+
```scala
470
+
valb8=Bits(8) <>VAR
464
471
465
-
All DFiant's dataflow types are bit-accurate and structurally static, with their bit-width set upon construction (e.g., `DFBits[5]` is a 5-bit vector). Operations between dataflow variables produce a bit-accurate result with the proper type inference. For example, an addition between an unsigned 5-bit variable (`DFUInt[5]`) and a signed 10-bit variable (`DFSInt[10]`) produces an adder that can be implicitly converted to a 10-bit signed variable, if carry is not required, or an 11-bit signed variable by explicitly invoking `.wc` from the addition.
472
+
// Shift operations
473
+
valshifted_left= b8 <<2// Logical left shift
474
+
valshifted_right= b8 >>2// Logical right shift
466
475
467
-
DFiant also allows operations between dataflow types and their corresponding Scala numeric types, by treating the Scala numeric types as constants (e.g., addition between `DFSInt` and `Integer` variables). A constant in the dataflow graph is a node that can produce infinite tokens of the same value.
476
+
// Bit reduction operations
477
+
valor_reduced= b8.|// OR reduction
478
+
valand_reduced= b8.&// AND reduction
479
+
valxor_reduced= b8.^// XOR reduction
468
480
469
-
## Bit Aliasing and Casting
481
+
// Bit concatenation
482
+
valconcat= (b"100", b"1", b"0", b"11").toBits // Creates 8-bit value
483
+
```
470
484
471
-
Aliasing in DFiant enables referencing a part of a dataflow variable, by invoking `.bits(hiIdx, loIdx)`, which creates a bits vector alias that references the original variable at the given index parameters. Every change of a dataflow variable affects its alias and vice versa (similar to VHDL's signal aliasing). Since this function also casts the variable as `DFBits`, this feature is used as a raw-data cast between different dataflow types. Aliasing of an alias is also possible, while maintaining relative bits indexing. Aliasing preserves the mutability trait: an alias of an immutable value is immutable, while an alias of a mutable variable is mutable.
(b4M, b3M, u5L, b4L) := (u8, b8) // Automatically extracts appropriate bits for each variable
502
+
```
475
503
504
+
### Width Inference and Resizing
505
+
```scala
506
+
// Automatic width inference
507
+
valb3=Bits(3) <>VAR
508
+
valb8=Bits(8) <>VAR
476
509
477
-
1. Constructs a new 128-bit vector, `bits128`, and clears it.
478
-
2. Creates a new alias, `alias64`, which references the most significant 64 bits of `bits128`. Since `bits128` is a `DFBits` variable, there is no need to invoke `.bits()`, and we can apply the required indexes directly.
479
-
3. Creates a new alias, `alias32`, which references the least significant 32 bits of `alias64`, which reference bits 64 to 95 of `bits128`.
480
-
4. Constructs a new double precision floating point dataflow variable, `dbl`, and initialize its value as `1.0` (hexadecimal value of `0x3FF00...0`).
481
-
5. Modifies the least significant byte of `dbl`.
482
-
6. Sets the most significant bit of `bits128`.
483
-
7. Assigns `dbl` to the least significant 64 bits of `bits128` through casting. All the bits of `dbl` are selected because `.bits()` is invoked without index parameters.
484
-
8. Modifies a byte of `bits128`.
510
+
// Explicit resizing required when widths don't match
0 commit comments