Assignments
Assignments
There are multiple assignment operators:
Symbol |
Description |
---|---|
|
Standard assignment, equivalent to |
|
Equivalent to |
|
Automatic connection between 2 signals or two bundles of the same type. Direction is inferred by using signal direction (in/out). (Similar behavior to |
When muxing (for instance using when
, see When/Switch/Mux.), the last
valid standard assignment wins. Else, assigning twice to the same assignee
results in an assignment overlap (see Assignment overlap).
val a, b, c = UInt(4 bits)
a := 0
b := a
//a := 1 // assignment overlap with a := 0
c := a
var x = UInt(4 bits)
val y, z = UInt(4 bits)
x := 0
y := x // y read x with the value 0
x \= x + 1
z := x // z read x with the value 1
// Automatic connection between two UART interfaces.
uartCtrl.io.uart <> io.uart
It also supports Bundle assignment. Bundle multiple signals together using
()
to assign and assign to
val a, b, c = UInt(4 bits)
val d = UInt(12 bits)
val e = Bits(10 bits)
val f = SInt(2 bits)
val g = Bits()
(a, b, c) := B(0, 12 bits)
(a, b, c) := d.asBits
(a, b, c) := (e, f).asBits
g := (a, b, c, e, f).asBits
It is important to understand that in SpinalHDL, the nature of a signal (combinational/sequential) is defined in its declaration, not by the way it is assigned.
All datatype instances will define a combinational signal, while a datatype instance wrapped with Reg(...)
will define a sequential (registered) signal.
val a = UInt(4 bits) // Define a combinational signal
val b = Reg(UInt(4 bits)) // Define a registered signal
val c = Reg(UInt(4 bits)) init(0) // Define a registered signal which is set to 0 when a reset occurs
Width checking
SpinalHDL checks that the bit count of the left side and the right side of an assignment matches. There are multiple ways to adapt the width of a given BitVector (Bits
, UInt
, SInt
):
Resizing techniques |
Description |
---|---|
x := y.resized |
Assign x with a resized copy of y, resize value is automatically inferred to match x |
x := y.resize(newWidth) |
Assign x with a resized copy of y, size is manually calculated |
There is one case where Spinal automatically resizes a value:
Assignment |
Problem |
SpinalHDL action |
---|---|---|
myUIntOf_8bit := U(3) |
U(3) creates an UInt of 2 bits, which doesn’t match the left side (8 bits) |
Because U(3) is a “weak” bit count inferred signal, SpinalHDL resizes it automatically |
Combinatorial loops
SpinalHDL checks that there are no combinatorial loops (latches) in your design. If one is detected, it raises an error and SpinalHDL will print the path of the loop.