The PandABlocks-FPGA autogeneration framework reads block description files
(.block.ini, .timing.ini) and generates the VHDL wrappers, config entries,
and testbenches needed to build and verify each block.
Softblocks¶
Wrappers¶
The framework generates wrapper, config, description, VHDL entity, and
testbench files from the block description. The generated files tie together the
block’s signals (as defined in block.ini) with the surrounding PandABlocks
infrastructure.
Config_d entries¶
Config entries are generated by the Python module at
common/python/configs.py. Refer to that module’s source for the current
generation logic.
Test benches¶
A generic outline is common across the autogenerated testbenches. There are four main areas of required functionality:
Assigning input signals
Reading expected data
Assigning inputs to the unit under test (UUT) and reading the outputs
Comparing outputs against expected values
Required signals in the block¶
Python code extracts signals from the .block.ini file for each block and
produces register signals in the testbench for each signal, using the names from
the ini file. The field type of each signal determines:
the size of the register required for each signal
whether the signal is an input or an output
Each output signal requires a register (like the inputs) plus a wire signal
suffixed _UUT for connecting to the UUT, and an error register suffixed
_error. Integer signals are also declared for the file identifier, the
$fscanf return value, and the timestamp.
Read expected.csv¶
From the .timing.ini file a CSV is generated describing how the UUT should
behave under given inputs at different times. The first row contains signal
names; the first column is the timestamp. All other rows carry numeric data.
The testbench opens this file and reads it line by line, discarding the header
row. When the timestamp in the file matches the current simulation time, the
values are assigned to the corresponding registers. Signals are ordered as in
.block.ini, so iterating through them in order assigns data to the right
registers.
Assign signals¶
Input names in the entity match the testbench register names, so connecting
them is straightforward. Output registers hold expected values; the _UUT wire
signals carry the actual UUT outputs.
Compare output signals¶
To verify correct behaviour, each output value is compared to its expected
value. If they differ, the corresponding _error signal is set to 1 and an
error message is printed.