Skip to content

olo_fix_lin_approx_calc

Back to Entity List

Status Information

VHDL Source: olo_fix_lin_approx_calc
Bit-true Model: olo_fix_lin_approx

Description

This entity implements the calculation part of a piecewise linear approximation of an arbitrary function. The function is approximated by a table which contains the function value (offset) and the derivative of the function (gradient) for regularly spaced points. Between those points the function is approximated linearly.

The olo_fix_lin_approx_calc can calculate one approximation per clock cycle.

The table itself is not part of this entity. It is attached through the Tbl_Addr / Tbl_Data interface. Normally the table is not written by hand but generated from Python. The Python class olo_fix_lin_approx generates a wrapper entity that contains the table and instantiates olo_fix_lin_approx_calc - this is the normal way of using this entity.

Latency of this entity is 7 + TableLatency_g clock cycles (8 clock cycles for the default settings). The entity is fully pipelined, hence it accepts one input sample per clock cycle. As a result, back-pressure is not supported.

For details about the fixed-point number format used in Open Logic, refer to the fixed point principles.

Approximation Principle

The full range of InFmt_g is split into TableSize_g segments of equal width. For each segment, the table contains the value of the function at the center of the segment (offset, red) and the derivative of the function at the same point (gradient, blue).

principle

Generics

Name Type Default Description
InFmt_g string - Input data format
String representation of an en_cl_fix Format_t (e.g. "(1,1,15)")
OutFmt_g string - Output data format
String representation of an en_cl_fix Format_t (e.g. "(1,1,15)")
OffsFmt_g string - Format of the offset (function value) table entries
String representation of an en_cl_fix Format_t
GradFmt_g string - Format of the gradient (derivative) table entries
String representation of an en_cl_fix Format_t
TableSize_g positive - Number of entries in the table.
Must be a power of two and smaller than 2^width(InFmt_g)
TableLatency_g positive 1 Read latency of the table in clock cycles (range 1 to 3).
Increasing the value improves timing for slow ROMs, see Table Interface
Round_g string "NonSymPos_s" Rounding mode of the output stage
String representation of an en_cl_fix FixRound_t.
Saturate_g string "Sat_s" Saturation mode of the output stage
String representation of an en_cl_fix FixSaturate_t.

All generics except TableLatency_g, Round_g and Saturate_g are defined by the table content. They must not be modified without regenerating the table.

Interfaces

Control

Name In/Out Length Default Description
Clk in 1 - Clock
Rst in 1 - Reset input (high-active, synchronous to Clk)

Input Data

Name In/Out Length Default Description
In_Valid in 1 '1' AXI4-Stream handshaking signal for In_Data
In_Data in width(InFmt_g) - Input data
Format: InFmt_g

Output Data

Name In/Out Length Default Description
Out_Valid out 1 N/A AXI4-Stream handshaking signal for Out_Result
Out_Result out width(OutFmt_g) N/A Result data
Format: OutFmt_g

Table Interface

Name In/Out Length Default Description
Tbl_Addr out log2(TableSize_g) N/A Table read address
Tbl_Data in width(OffsFmt_g)+width(GradFmt_g) - Table read data.
The gradient is stored in the MSBs (format GradFmt_g), the offset in the LSBs (format OffsFmt_g).

The table must be a synchronous memory with a read latency of exactly TableLatency_g clock cycles (address registered, data available TableLatency_g clock cycles later). A read latency of one clock cycle corresponds to a ROM with registered address. Values of two or three add output registers to the ROM, which improves timing for (slow) ROMs at the cost of latency. Reads must not be gated - the table must deliver data for every address applied.

Details

Architecture

Below figure illustrates how the linear approximation is implemented.

arch

N-M is the number of address bits for the table. The figure shows TableLatency_g = 1. For higher values, the remainder path (lower branch) is delayed by the additional table read latency.

Table Details

The upper log2(TableSize_g) bits of In_Data are used as table index, the remaining lower bits are the position within the segment. The lower bits are unsigned and relative to the beginning of the segment. By inverting their MSB, they are converted into the signed offset relative to the center of the segment - which is exactly what the multiplication above requires.

For signed InFmt_g, negative input values wrap into the upper half of the table (the table index is simply the unsigned interpretation of the upper input bits). The code generator arranges the table content accordingly.

Precision

The multiplication and the addition are executed at full precision (no rounding, no saturation). This allows the adder to be implemented within a DSP slice. Rounding and saturation are applied in separate pipeline stages at the output, controlled by Round_g and Saturate_g.

The approximation error depends on the number of table entries and the formats chosen for the table. The Python class olo_fix_lin_approx provides an analyze() method that helps finding suitable settings.

Usage Example

Below example shows how a table is attached manually. Normally the wrapper entity generated by olo_fix_lin_approx is used instead.

signal Tbl_Addr : std_logic_vector(7 downto 0);
signal Tbl_Data : std_logic_vector(34 downto 0);
...
-- Table with one clock cycle read latency (matches the default TableLatency_g = 1)
p_table : process (Clk) is
begin
    if rising_edge(Clk) then
        Tbl_Data <= Table_c(to_integer(unsigned(Tbl_Addr)));
    end if;
end process;

i_approx : entity olo.olo_fix_lin_approx_calc
    generic map (
        InFmt_g     => "(0, 0, 16)",
        OutFmt_g    => "(1, 0, 16)",
        OffsFmt_g   => "(1, 0, 18)",
        GradFmt_g   => "(1, 3, 12)",
        TableSize_g => 256
    )
    port map (
        Clk        => Clk,
        Rst        => Rst,
        In_Valid   => In_Valid,
        In_Data    => In_Data,
        Out_Valid  => Out_Valid,
        Out_Result => Out_Result,
        Tbl_Addr   => Tbl_Addr,
        Tbl_Data   => Tbl_Data
    );