Fast Logic Solver
The Fast Logic Solver (FLS) is a runtime-configurable programmable logic module with I/O settings to accept and generate pulse trains and positive and negative logic.
The module consists of several submodules arranged in a data processing chain. A single HotRIO register tree instance is connected to all submodules for configuration purposes.
Input stage: parses the inputs based on the specified input logic and transforms them into standardized positive logic alarms, latching them if requested.
Data bus: vector of internal registers where processed inputs and LFB outputs are stored.
Logic function blocks (LFBs): lookup tables with 4-bit input and 1-bit output, with runtime-configurable equation and connections to the data bus.
Output stage: converts alarm signals from the data bus to the selected formats, chosen between positive/negative logic and several pulse train frequencies.
Debug block: generates timestamped debug packets to log the internal state of the FLS whenever one or more signals change.
Reference document
This component was originally developed targeting a Xilinx FPGA for use in the backplane of a NI cRIO chassis, and it was later adapted to Lattice ECP5UM-5G to be instantiated in HotRIO boards. The following document contains the design description for the original version of the FLS, detailing its functionalities and implementation details and providing block diagrams of the whole system and of its submodules:
Differences between original design and HotRIO version
While most FLS features are described in the document linked above, some aspects have been modified in the HotRIO version to accomodate for integration in the existing HotRIO framework.
The configuration interface has been converted from UART to SPI.
Configuration registers are generated based on the number of inputs, outputs and LFBs by the HotRIO register tree generation tool. The register map is unaffected by this change and still matches the table in the DDD.
The target clock frequency has been changed from 40 MHz to 125 MHz.
The input stage has been made insensitive to the duty cycle of pulse trains, while the pulse train frequency matching requirement has been made stricter.
An optional DataFeeder submodule can now be included when building the project, to generate signals on the FLS inputs through dedicated configuration registers for debug purposes.
Configuration interface changes
As in the original version, the configuration of the FLS is stored in registers that can be accessed through a register manager module connected to an external interface. This system, for the original implementation, is explained in sections 3.1 to 3.3 of the DDD.
The register map in sections 3.3.1 and 3.3.2 has been preserved, but the implementation of the system has changed. The configurable_register, registers_manager and mux_registers modules have been replaced with a HotRIO register tree instance containing equivalent items. This register tree is independent from any other register trees included in the HotRIO firmware design, and can be connected to the same SPI slave that services other register trees.
The documentation for the HotRIO register tree is available here:
HotRIO register tree documentation
The communication protocol described in section 3.2.1 of the DDD is no longer directly compatible with the FLS, but it can still be used by PLCs to communicate with the onboard microcontroller of the HotRIO board hosting the FLS; the microcontroller will translate commands and responses between the original protocol and the protocol described in this extract of the HotRIO register tree documentation:
For the microcontroller to access the configuration registers of the FLS, the UART interface described in section 2 of the DDD has also been removed and replaced with a HotRIO SPI slave interface. The corresponding spi_slave VHDL module is not included in the FLS design, as the interface may be shared with other functionalities. This module can be found in the hotrio-software Firmware library; it will need to be instantiated in the project alongside the FLS, as in the example provided in the FLS test.
Fast Logic Solver code generation
The amount of registers needed to configure the FLS, as specified in the table in section 3.3.1 of the DDD, is variable depending on the required number of inputs, outputs and logic function blocks. As the register tree is now generated by the “register_tree_gen.py” script from hotrio-software, the portlist of its instance changes depending on these three parameters. As such, no single VHDL module can represent all possible FLS instances, and the top level FLS component is not included among the sources of the FLS. Instead, the “fls_gen.py” script from hotrio-software should be used to generate it, providing the three values.
As an example, from the root folder of hotrio-software, the following command can be executed to generate a Fast Logic Solver with 20 inputs, 12 LFBs and 4 outputs:
python3 Firmware/Scripts/fls_gen.py -ni 20 -nl 12 -no 4
This script automatically calls register_tree_gen.py to generate the register tree, then includes an instance of the generated module into a template of the FLS top level architecture, producing the VHDL entity that will then be instantiated in the project.
Clock frequency increase
The intended clock frequency for the FLS has been increased from 40 MHz to 125 MHz to align with the frequency of HotRIO communication, allowing seamless connection of FLS inputs and outputs to bits from HotRIO packet payloads.
This does not result in different accepted and generated pulse train frequencies, as the counter thresholds used to obtain these frequencies have been adjusted according to the change of the system clock. The preserved frequency values are shown in Table 34 in the DDD, while the values in Table 36 have been replaced with the following new thresholds:
P_LEVEL_CNT_DELAY_FREQ_0 = 10
P_LEVEL_CNT_DELAY_FREQ_1 = 25
P_LEVEL_CNT_DELAY_FREQ_2 = 12500
P_LEVEL_CNT_DELAY_FREQ_3 = 12500000
Note that in the input stage these thresholds are combined with the user-selected counter_preload values to obtain the expected input frequencies. For the final frequencies to match those in Table 34 (2.5 MHz, 1 MHz, 1 kHz and 10 Hz), the counter preload values to be select for each threshold are respectively 5, 5, 10 and 10. Some of these differ from the preload values that resulted in the four frequencies in the original version.
Input stage changes
The input stage of the FLS has been modified both in concept and in implementation to support a wider range of pulse train input waveforms while also preventing false negatives, in which an alarm is not fired when a pulse train with different frequency than expected is connected to the input.
The following two changes have been applied to the input stage concept:
Alongside the maximum time waiting for an edge before firing the alarm, a minimum wait time has been added. This prevents signals with higher frequency than the expected input from being interpreted as a valid pulse train.
The timing of the falling edge of the input pulse train is no longer checked, allowing any duty cycle as long as the period of the waveform matches the expected value.
The minimum wait time is not configurable and depends on counter_preload, like the maximum wait time. The resulting time window in which the edge of the pulse train is accepted varies in width proportionally to the P_LEVEL_CNT_DELAY_FREQ constant for the chosen target frequency.
Data feeder module
In the HotRIO version of the FLS, an additional data_feeder module is available alongside the rest of the FLS components. By default, it is excluded by synthesis and does not contribute to the resource utilization of the FLS, but it can be enabled by appending the “-d” switch when calling fls_gen.py, before compilation.
When the data feeder is enabled, the datafeeder_o output of the FLS top module will be controlled by registers of addressses 0x00C6 to 0x00CF, that are not normally present in the FLS register map. This output can be connected to the input vector of the FLS to allow testing by setting the values of the inputs to the desired logic levels or pulse trains.
The data feeder should not be included to a design in which the number of inputs differs from 16.
Module instantiation
After generating the top level FLS module with fls_gen.py, its instance can be added to the project by connecting the following generics and ports.
Generics
Name |
Description |
Type |
Default |
|---|---|---|---|
CLOCK_FREQ |
Frequency of clk_i. Currently the default is the only supported value. |
|
125_000_000 |
Ports
Name |
Description |
Type |
|---|---|---|
clk_i |
System clock of the FPGA |
|
reset_i |
Active-high synchronous reset for the entire module |
|
spi_csn_sync_i |
Active-low SPI chip select synchronized with clk_i |
|
spi_rx_pulse_i |
1-cycle high pulse when spi_mosi_byte_i contains new valid data |
|
spi_mosi_byte_i |
Byte received by the SPI slave interface on the FPGA |
|
spi_miso_byte_o |
Byte to be sent by the SPI slave interface to the MCU |
|
spi_miso_sel_o |
High when this module needs to use MISO to send spi_miso_byte_o |
|
input_i |
Fast Logic Solver inputs |
|
pps_i |
1 Hz PPS signal to synchronize debug packet timestamps |
|
output_o |
Fast Logic Solver outputs |
|
init_state_o |
High when the FLS is in the INIT state, before the end of the initialization procedure |
|
ready_o |
High when the FLS is in the NORMAL_OP state, after initialization and configuration have finished |
|
debug_packet_o |
Latest produced debug packet. Will be overwritten whenever a new packet is ready |
|
debug_packet_valid_o |
1-cycle high pulse when debug_packet_o contains new valid data |
|
datafeeder_o |
If the FLS has been generated with the “-d” argument, connect this to input_i to control the inputs from the MCU |
|