FloPoCo user manual

Installation

To compile FloPoCo you need CMake (http://www.cmake.org/) which is included in mainstream Linux/Unix distributions, and is available for other operating systems, including Windows.

FloPoCo also depends on the MPFR library, available from http://www.mpfr.org and probably available in your favourite Linux/Unix distribution.

Optionally, you may want to link FloPoCo against Sollya. This enables more operators (HOTBM, CRFPConstMult). For this purpose, you must download, compile and install Sollya. FloPoCo is demonstrated to work with version 1.1 of Sollya and should work with future releases.

Compilation is a two-step process:

cmake .

make

The adventurous may get FloPoCo from its subversion repository.

Command-line interface

FloPoCo is a command-line tool. The general syntax is

flopoco <options> <operator specification list>

FloPoCo will generate a single VHDL file (named by default flopoco.vhdl) containing synthesisable descriptions of all the operators listed in <operator specification list>, plus possibly sub-operators instanciated by them. To use these operators in your design, just add this generated file to your project.

FloPoCo will also issue a report with useful information about the generated operators, such as the pipeline depth or expected working frequency.

Examples

./flopoco IntConstMult 16 12345

produces a file flopoco.vhdl containing a single operator for the integer multiplication of an input 16-bit number by the constant 12345. The VHDL entity is named after the operator specification, here IntConstMult_16_12345.

./flopoco IntConstMult 16 12345 IntConstMult 16 54321

produces a file flopoco.vhdl containing two VHDL entities and their architectures, for the two given constant multipliers.

./flopoco FPConstMult 8 23 8 23 0 -50 1768559438007110

produces a file flopoco.vhdl containing two VHDL entities, one for the specified constant floating-point multiplier by 1768559438007110x2-50, and the other one for a needed sub-component (an integer multiplier for the significand multiplication).

Options

Several transversal options are available and will typically change the operators occuring after them in the list. For instance -frequency=300 sets the target frequency. The -name=UserProvidedName option replaces the (ugly and parameter-dependent) name generated by FloPoCo for the next operator with a user-provided one. This allows in particular to change parameters while keeping the same entity name, so that these changes are transparent to the rest of the project. Options related to pipelining are reviewed below.

The -target option selects the target FPGA family. We try to optimize for the highest speed grade available for this family (see below for pipelining options).

Built-in help

To obtain a concise list of the available operators and options, simply type

./flopoco

In addition this help may be more in sync with the code than this file, especially if you are using a svn snapshot.

Helper programs

The FloPoCo distributions also includes useful programs for converting the binary string of a floating-point number to human-readable form (bin2fp) and back (fp2bin). The longacc2fp utility converts the fixed-point output of the LongAcc operator (see below) to human-readable form.

Floating-point format

The floating-point format used in FloPoCo is identical to the one used in FPLibrary. It is inspired from the IEEE-754 standard.

An FP number is a bit vector consisting of 4 fields. From left to right:

A 2-bit exception field
00 for zero, 01 for normal numbers, 10 for infinities, and 11 for NaN
A sign bit
0 for positive, 1 for negative
An exponent field on wE bits
It is biased as in IEEE-754. The smallest possible FP numbers have exponent field 00...00, the FP number 1.0 has the exponent field 011...11 and the largest possible FP numbers have exponent 11...11
A fraction field on wF bits
The actual significand has an implicit leading 1, so the fraction field ff...ff represents the significand 1.ff...ff

The format is therefore parameterized by to positive integers wE and wF which define the sizes of the exponent and fraction fields respectively.

The utilities fp2bin and bin2fp will allow you to get familiar with the format and set up test benches.

Difference between FloPoCo format and IEEE-754 format

There are two main differences between the format (wE=8, wF=23) and the IEEE-754 single precision format (the same holds for double).

Note that anyway, FloPoCo provides conversion operators from and to IEEE-754 formats (simple and double precision).

LNS format

Numbers in the Logarithm Number System used in FloPoCo have an encoding similar to the floating-point format, which is also the same as the one used in FPLibrary.

Its fields are:

A 2-bit exception field
Same encoding as floating-point: 00 for zero, 01 for the general case, 10 for infinities, and 11 for NaN
A sign bit
0 for positive, 1 for negative
The integral part of the exponent on wE bits
The fractional part of the exponent on wF bits
The fixed-point exponent is encoded in two's-complement.

Pipelining

An operator may be combinatorial, or pipelined. A combinatorial operator has pipeline depth 0. An operator of pipeline depth 1 is obtained by inserting one and only one register on any path from an input to an output. Hopefully, this divides the critical path delay by almost 2. An operator of pipeline depth 2 is obtained by inserting two register levels, etc.

It should be noted that, according to this definition, pipelined operators usually do not directly buffer neither their inputs nor their outputs. For instance, connecting the input of a 400MHz operator to the output of another 400MHz operator may well lead to a circuit working at 200MHz only. It is the responsibility of the user or calling program to insert one more level of registers between two FloPoCo operators. This convention may be felt as a burden to the user, but it is the most sensible choice. It makes it possible to assemble sub-component without inserting registers in many situations, thus reducing the latency of complex components. Besides, different application contexts may have different policies (registers on output, or registers on input).

Two command-line options control the pipelining of the FloPoCo operators that follow them.

-pipeline=[yes|no] (default yes)
-frequency=[frequency in MHz] (default 300)
Sets the target frequency. If the -pipeline option is set, then FloPoCo will try to pipeline the operator to the given frequency. It will report a warning if it fails -- or if frequency-directed pipelining is not yet implemented for this operator.
Requires the operators to be pipelined. If no, the operator will be combinatorial. If yes, registers may be inserted if needed to reach the target frequency.

The philosophy of FloPoCo's approach to pipelining is the following:

Note that not all operators support pipelining (utimately they all will). They are mentionned in the command-line help.

Available operators

Here is the list of operators that can be generated by FloPoCo. This list may not be fully up-to date... the code is the reference.

Useful building blocks for FP operators

LeftShifter wIn MaxShift
Left barrel shifter. It has two inputs, the data to shift and a shift value. The width of the latter is deduced from MaxShift, which is the maximum shift distance. This operator will be pipelined to match target frequency.
RightShifter wIn MaxShift
Same, but to the right.
LZOC wIn wOut
Leading Zero/One Counter.
LZOCShifterSticky wIn wOut computeSticky countType
Leading Zero/One Counter merged with a shifter. If computeSticky=0 the bits shifted out are discarded, if 1 they are ORed into a sticky bit. If countType=0, a leading zero counter is built, if 1 a leading one counter is built, if -1 the value to count is input from an extra input port.

Pipelined integer standard operators

IntAdder wIn
Integer adder. In modern VHDL, integer addition is expressed by a + and one usually needn't define an entity for it. However, this operator will be pipelined if the addition is too large to be performed at the target frequency.
IntNAdder wIn N
Multi-operand integer adder. (still experimental)
IntCompressorTree wIn N
Multi-operand integer adder using compressor trees. High quality operator at the expense of synthesis time.
IntMultiplier wInX wInY
Same for multiplication, although the frequency attainable will be limited by the DSP blocks available. wInX and wInY are the input widths of both operands. This is an unsigned operation.
IntSquarer wInX wInY
Same for squaring. For large multiplications on some FPGAs, it saves DSP blocks (your mileage may vary).
IntKaratsuba wIn
Multiplier that saves multiplications by trading them for additions. The TwoWaySplitting and ThreeWaySplitting Karatsuba-Ofman algorithms are implemented.

Classical floating-point operators

These operators are correctly rounded to the nearest, in a way compatible with IEEE-754, with the exception that subnormal numbers are flushed to zero.
FPMultiplier wE wF
A floating-point multiplier. The actual FloPoCo component supports different input and output sizes, but this is not available from the command line.
FPAdder wE wF
A floating-point adder.
FPDiv wE wF
A floating-point divider.
FPSqrt wE wF useDSP correctRounding
A floating-point square root. useDSP (0/1) is a boolean selecting between the classical digit-recurrence algorithm and a polynomial-based algorithm. The latter is currently only available for single precision (8,23). correctRounding (0/1) is a boolean selecting the rounding mode for the polynomial approach. If set to 0, the operator will be faithful (last-bit accurate, but not necessarily correctly rounded). This boolean is ignored if useDSP=0: the digit-recurrence algorithm always returns correctly rounded results.
FPSquarer wE wF
A floating-point squarer, using IntSquarer for the mantissa.

Long fixed-point accumulator, and derivatives

These operators are described in all the gory details in this article.
LongAcc wE_in wF_in MaxMSB_in LSB_acc MSB_acc
Long fixed-point accumulator. By tuning the MaxMSB_in, LSB_acc and MSB_acc parameters to a given application, it allows one to bring rounding error to a provably arbitrarily small level (and in some case to avoid any rounding), for a very small hardware cost compared to using a floating-point adder for accumulation.
DotProduct wE_in wF_X wF_Y MaxMSB_in LSB_acc MSB_acc
Dot product operator. It feeds a long accumulator with the unrounded result of a floating-point multiplier, thus removing rounding errors from the multiplication as well.
LongAcc2FP MaxMSB_in LSB_acc MSB_acc wE_out wF_out
Post-normalisation unit for LongAcc. It converts the output of a LongAcc or DotProduct (with the same parameters) into a floating-point number.

Constant multipliers

This family of operators is described in all the gory details in this article.

IntConstMult w c
integer constant multiplier: w is input size, c is the constant.
FPConstMult wE_in wF_in wE_out wF_out cst_sgn cst_exp cst_int_sig
floating-point constant multiplier. The constant is provided as sign, integral significand and integral exponent.

Floating-point elementary functions

FPExp wE wF
An exponential operator, where both inputs and outputs have wE bits exponent and wF bits significand. This operator implements the exponential function as described in this article.
FPLog wE wF TableInsize
A natural logarithm operator, where both inputs and outputs have wE bits exponent and wF bits significand. The third allows for performance tuning. In doubt, set it to 0, which will default to something sensible. Otherwise, it defines the input size of the tables used by the operator, and should be between 6 and 15. See this article (improved version in preparation).

Conversion operators

Fix2FP LSB MSB wE wF
Convert a 2's complement fixed-point number in the bit range MSB...LSB (both included) into floating-point. Example: Fix2FP 0 31 8 23 converts an input integer into a single-precision number.
InputIEEE wEI wFI wEO wFO
Conversion from IEEE-754 formats. Use InputIEEE 8 23 wEO wFO to convert from single-precision (or binary32) format, or InputIEEE 11 52 wEO wFO to convert from double-precision (or binary64) format. You may convert to a larger internal format or to a narrower one. Conversions are always correctly rounded.
OurputIEEE wEI wFI wEO wFO
Conversion to IEEE-754 formats. Not implemented yet. Do not hesitate to ask for it.
FP2FP wEI wFI wEO wFO
Conversion from a FloPoCo format to another one. Not implemented yet. Do not hesitate to ask for it.

Miscelanous floating-point operators

Collision wE wF
A collision operator. This is mostly a case study for a compound operator. It is described in this article.

HOTBM

This operator implements an arbitrary function using High-Order Table-Based Method, best described in this article.

HOTBM func wI wO degree
HOTBMFX func wE_in wF_in wE_out wF_out degree
HOTBMRange func wI wO degree xmin xmax scale
HOTBM implementation of a function. func is a sollya-like expression of the function, wI is the input width, wO is the output width and degree is the degree of the Remez polynomial. wE_in, wF_in, wE_out, wF_out are the width of the integral and fractional parts of the input and the output, respectively. [xmin, xmax] is the input domain of the function, and scale is a scaling factor to be applied to the output.

For HOTBM the input operand is interpreted as a positive fixed-point number, with the point before the leftmost bit. The function to be implemented is assumed to be well defined in [0;1[. The output is a fixed-point number, where the first bit is the sign and the point is placed right after it. Note that the output is in fact wO+1 bits wide.

Due to the fact that the expression of the function might contain characters which are treated specially by the shell, you should enclose it within quotes.

Example:
flopoco HOTBM "sin(x*Pi/2)" 16 16 3

The HOTBMFX version allows to select arbitrary fixed-point representations for the input and output. Negative values are allowed.

Example:
flopoco HOTBMFX "log2(1+2^(-x))" 2 8 -1 8 1

HOTBMRange uses HOTBM after mapping [xmin,xmax[ to [0,1[, then multiplies the output by the scaling factor scale.

Note that this launches an exploration process that typically takes a few minutes for 16 bits, and may take hours for 24 bits.

HOTBM uses a polynomial approximation. It works well for functions which are regular enough (in mathematical terms, they should be defined and n-times continuously differentiable on the domain).

LNS

These operators compute in the Logarithmic Number System. They are mostly useful for low-precisions systems performing few additions and many multiplications, divisions or square roots.

LNSAddSub wE wF
LNS addition operator. Both operands and the output have wE integral bits and wF fractional bits in their exponents.
LNSMul wE wF
LNS multiplication operator. Both operands and the output have wE integral bits and wF fractional bits in their exponents.
LNSDiv wE wF
LNS division operator. Both operands and the output have wE integral bits and wF fractional bits in their exponents.
LNSSqrt wE wF
LNS square root operator. Both input and output have wE integral bits and wF fractional bits in their exponents.

Test Benches

The TestBench operator will generate a test bench for the operator which precedes it in the command line (also called unit under test, UUT). Test cases are highly UUT specific. They include both standard tests and random tests. The single parameter of the TestBench specifies the number of random tests to generate. Random tests use a pseudo-random number generator initialised with the same seed, so that the test bench will be deterministic.

Example:
flopoco HOTBM "sin(x*Pi/2)" 16 16 3 TestBench 1000

Miscellanous

Wrapper
Produce a wrapper for the preceding operator: this operator simply adds registers before and after the preceding operator. It is useful in some cases to get synthesis results without having the operator optimised out, or to get critical path information including the delay of the first and last stages connected to registers, not to I/O.