# 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).

- Exceptional cases (zeroes, infinities and Not a Number or NaN) are encoded as separate bits in FloPoCo, instead of being encoded as special exponent values in IEEE-754. This saves quite a lot of decoding/encoding logic. The main drawback of this format is when results have to be stored in memory, where they consume two more bits. However, FPGA embedded memory can accomodate 36-bit data, so adding two bits to a 32-bit IEEE-754 format is harmless as long as data resides within the FPGA.

  As a side effect, the exponent can take two more values in FloPoCo than in IEEE-754 (one for very large numbers, one for very small ones).

- FloPoCo does not support subnormal numbers. If you think you need subnormal numbers, consider adding one bit to your exponent field instead: you will thus get all the subnormals, and many more. If you are still not convinced, maybe you are right: please get in touch with us.

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:

- FloPoCo's approach is to provide a fair estimate of the pipeline depth required to obtain a given frequency, and a sensible placement of registers.
- FloPoCo's pipelining effort is always tentative: You may not get the frequency you asked (sometimes you will even get a higher one). However, in such cases, increasing or decreasing the target frequency should also increase or decrease the obtained frequency. Note that you may do so on a per-operator basis, as in: `flopoco -frequency=200 FPAdder 11 52 -frequency=300 FPMultiplier 8 23`
- If the obtained frequency is higher than needed, reducing the `-frequency` option may save resources.
- The pipeline built by FloPoCo may depend on the target. When tuning it, we use the best possible speed grade for a given target family, for insance -12 for Virtex-4. If you want to target a FPGA with a lower speed grade, you may need to update `-frequency` accordingly.
- Better results will always be obtained by using retiming tools, which can work on a circuit netlist after technology mapping. The pipeline built by FloPoCo should help these retiming tools converge faster to a global optimal.

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.