Data Format
Calyx's fud
-based workflows specifies a JSON-based data format which can be used with software simulators.
External memories
First, a Calyx program must mark memories using the @external
attribute to tell the compiler that the memory is used as either an input or an ouput.
component main() {
cells {
@external ext = comb_mem_d1(...);
internal = comb_mem_d1(...);
}
}
In the above program, the memory ext
will be assumed to be an input-output memory by the compiler while internal
is considered to be an internal memory.
For all external memories, the compiler will generate code to read initial values and dump out final values.
The external attribute is recognized for all the std_mem
and seq_mem
primitives.
The @external
attribute can only be used on the top-level component.
When the
--synthesis
flag is passed to the compiler, this behavior is disabled and instead the memories are turned into ports on the top-level component.
The Data Format
The JSON-based data format allows us to provide inputs for a memory and specify how the values should be interpreted:
{
"mem": {
"data": [10],
"format": {
"numeric_type": "bitnum",
"is_signed": false,
"width": 32
}
}
}
The data
field represents the initial data for the memory and can use mutlidimensional arrays to describe it. For example, the following is the initial data for a two-dimensional (comb_mem_d2
) memory:
{
"data": [ [1, 2], [3, 4] ],
"format": {...}
}
The format
specifier tells fud
how to interpret the values in the data field. The original program specifies that all values should be treated as 32-bit, unsigned values.
In order to specify fixed-point values, we must specify both the total width and fraction widths:
"root": {
"data": [
0.0
],
"format": {
"numeric_type": "fixed_point",
"is_signed": false,
"width": 32,
"frac_width": 16
}
}
The format states that all values have a fractional width of 16-bits while the remainder is used for the integral part.
Note:
fud
requires that for each memory marked with the@external
attribute in the program.
Using fud
All software simulators supported by fud
, including Verilator and Icarus Verilog, as well as the Calyx interpreter can use this data format.
To pass a JSON file with initial values, use the -s verilog.data
flag:
# Use Icarus Verilog
fud e --to dat --through icarus-verilog <CALYX FILE> -s verilog.data <JSON>
# Use Verilator
fud e --to dat --through verilog <CALYX FILE> -s verilog.data <JSON>
# Use the Calyx Interpreter
fud e --to interpreter-out <CALYX FILE> -s verilog.data <JSON>
Generating Random Values
Often times, it can be useful to automatically generate random values for a large memory. The data-gen tool takes a Calyx program as an input and automatically generates random values for each memory marked with @external
in the above data format.