Signal
Signal is a collection of types that can be transferred through wires in HazardFlow HDL. We divide these types into two categories: scalar and compound.
The HazardFlow HDL reuse some data types from the Rust programming language.
Normally we can consider a data type implements Copy
trait in Rust as a signal type in the HazardFlow HDL.
NOTE: The
Copy
trait in Rust and the signal type in HazardFlow are not in a perfect 1:1 relationship. While the signal type in HazardFlow must implement Rust'sCopy
trait, there are some types like function pointers (e.g.,fn() -> i32
) that implement theCopy
trait but are not treated as signal types in HazardFlow.
For more information of the Rust data types, please refer to The Rust Programming Language Book.
Scalar Types
A scalar type represents a single value.
Boolean
We interpret the Boolean type the same as the bool
type in the Rust programming language. In HazardFlow HDL, we also interpret the Boolean value as 0
or 1
and can be sent through the wires when the value is True
or False
.
Unsigned Integer
In the HazardFlow HDL, we support arbitrary bit-width unsigned integers. We define it as U<N>
, where N
is the bit-width. We provide a handful of primitive functions for supporting unsigned integers' arithmetic operations, type conversion, and also ordering between different unsigned integers.
- Arithmetic operations
- Basic arithmetic operations
+
,-
,*
are supported, and logical right shift and logical left shift are supported. - Some of the arithmetic operations might lead to bit-width changes in the final result.
- Basic arithmetic operations
- Type conversion
- We support converting Rust
i32
,u32
,u8
,usize
,u128
, andbool
intoU<N>
. - We can convert
U<N>
intou32
,u8
, and alsobool
.
- We support converting Rust
- Ordering
- We provide ordering functions for developers to easily compare two unsigned integers.
Compound Types
Compound types can group multiple values into one type.
Enum
We interpret the enum
type in HazardFlow HDL the same as Rust, the pattern matching feature is supported. The enum
type gives you a way of saying a value is one of a possible set of values.
Example: HOption
Similar to the Option
type in Rust, the HOption
type in HazardFlow HDL is also an enum
type. We define HOption
type as:
#[derive(Debug, Clone, Copy, HEq)]
enum HOption<T: Copy> {
/// No value.
None,
/// Some value of type `T`.
Some(T),
}
We provide almost the same handy functions as Rust when we operate on the HOption
type.
For example, the map
function in the HOption
type applies a function f
on the inner type of HOption
if the value is Some(T)
else returns None
.
and_then
function often used to chain fallible operations that may return None
and it flattens the result, avoiding nested HOption
.
Tuple
The tuple type is the same as the tuple type in Rust, and as long as the types within a tuple are signals, then we can treat the tuple type as a signal type that can be sent through the wires too. For example, (U<32>, bool, HOption<U<8>>)
can be considered as a signal type.
Struct
Similar to the tuple type, if every field of a struct
is a signal type, we can consider the struct
as a signal type.
For example, the AXI stream can be constructued as follows:
#[derive(Debug, Clone, Copy)]
struct Axis {
data: U<512>, // TDATA signal
keep: U<64>, // TKEEP signal
last: bool, // TLAST signal
user: bool, // TUSER signal
}
Array
The Array
type is primitive in the HazardFlow HDL. We can define an N
size sequence of V
type data as Array<V, N>
. The Array
type comes with a handful of handy functions, including indexing, clipping an array, zipping two arrays together, etc.
Example: Unsigned Integer
In HazardFlow HDL, we represent unsigned integer as an Array
of bool
with bit-width N
. When bool
is true
, we interpret it as a bit with value 1
, false
as 0
.
type U<const N: usize> = Array<bool, N>;