FPnew generates a floating-point unit from a list of formats
Parametric floating-point unit with support for standard RISC-V formats and operations as well as transprecision formats.
At a glance
- What is it?
- FPnew is a SystemVerilog floating-point unit whose formats are parameters rather than a fixed list, so the same RTL can be configured for single, double, quad or half precision, for custom transprecision widths, and for packed SIMD operation, with the divider chosen separately.
- Who is it for?
- FPnew fits a hardware team building a RISC-V core or an accelerator that needs a floating-point unit whose formats are decided by the application rather than by the standard, and that wants to generate several precision variants from one RTL source.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 39 days ago.
- What is it written in?
- Mainly SystemVerilog, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The format list is a parameter, not a fixed table
FPnew is described as a parametric floating-point unit with support for standard RISC-V formats and operations as well as transprecision formats, written in SystemVerilog. The parametric part is the interesting part, and it starts with the formats.
The design aims to be compliant with IEEE 754-2008 and supports any IEEE 754-2008 style binary floating-point format, including single, double, quad and half precision, that is binary32, binary64, binary128 and binary16. But those four are examples, not the limit. Formats can be defined with an arbitrary number of exponent and mantissa bits through parameters, and they are always symmetrically biased.
Two consequences follow. First, a team whose application needs, say, a narrow format with a wide exponent can describe it as parameters instead of writing a new unit. Second, multiple FP formats can be supported concurrently, and the number of formats is not limited. The configuration is a set of format descriptors, so a design can carry binary16, binary32 and binary64 in the same unit and convert between them.
Integer formats with an arbitrary number of bits can also be defined, as source or destination of conversions, which is what makes the format-to-integer conversion path useful for the fixed-point and integer-heavy parts of a modern core.
The README is explicit that this is aimed at RISC-V processors, but that the FPU or its sub-blocks can easily be used in other environments. For a reader, that is the practical summary: the RTL is written as reusable blocks rather than as a RISC-V-only unit.
Operations, multi-format FMA and packed SIMD variants
The operation set is broad, and two of the entries are unusual enough to deserve a separate look.
The standard set covers addition and subtraction, multiplication, fused multiply-add in four flavours named fmadd, fmsub, fnmadd and fnmsub, division, square root, minimum and maximum, comparisons, sign injection such as copy, abs, negate and copySign, conversions among all supported FP formats, conversions between FP formats and signed and unsigned integers and back, and classification.
The first unusual feature is multi-format FMA, which is optionally supported. That means the multiplication can happen in one format while the accumulation happens in another, which is exactly what an accumulation-heavy workload on mixed precision data needs, and it is the reason the design is described as transprecision rather than merely configurable.
The second is the packed SIMD option. Packed versions of all the operations can be generated for formats narrower than the FPU datapath width, and the README gives the example of supporting double precision operations and two simultaneous single precision operations at once. A core designer can therefore trade width for throughput without writing a second implementation.
One more configuration choice is worth noting because it affects the generated area. It is possible to generate only a subset of the operations, for example when divisions are not needed, which is a real decision in a small microcontroller-class core where a divider dominates the area budget.
Two divider implementations, and a known rounding gap
Division and square root are where the interesting engineering and the interesting caveats both live.
Two DivSqrt units are supported. One is the multi-format PULP DivSqrt unit, and the other is a 32-bit unit integrated from the T-Head OpenE906, which lives in the repository under vendor/opene906. The PulpDivsqrt parameter selects between them, with 1 selecting the former and 0 the latter. So a designer can trade multi-format capability for a smaller, self-contained 32-bit block.
The compliance note attached to division and square root is the part to read before trusting the results. Some compliance issues with IEEE 754-2008 are currently known to exist for the PULP DivSqrt unit, with rounding mismatches reported in GitHub issues, and the consequence is that results can be off by one ulp, with the inexact flag not being properly raised in those cases either.
That is a specific, bounded limitation rather than a vague caveat. An off-by-one-ulp error in a division is usually harmless, and the missing inexact flag is the more awkward of the two problems, because software that checks the flag to decide whether to round will behave differently from the specification. For a unit that feeds a compiler's floating-point emulation, or an implementation that must be bit-accurate against a reference, that is a blocker rather than a footnote.
The minimum and maximum operations carry a smaller note, indicating that the IEEE 754-201x minimumNumber and maximumNumber are being implemented.
Rounding modes and status flags come from the standard
Around the arithmetic, FPnew follows the specification closely, and this is the part of the design that a compiler engineer will check first.
All IEEE 754-2008 rounding modes are supported: roundTiesToEven, roundTiesToAway, roundTowardPositive, roundTowardNegative and roundTowardZero. The first two are the ones people care about most, since roundTiesToEven is the default in every architecture, and roundTiesToAway shows up in numerical code that wants a consistent direction.
All IEEE 754-2008 status flags are supported as well: invalid operation with the NV flag, division by zero with DZ, overflow with OF, underflow with UF and inexact with NX. The presence of the full set matters because the flags are what a compiler emits code to inspect, and a unit that omits one of them silently changes the behaviour of a correctly written program.
The rounding mode is an input to the unit, carried on the operation interface, so it can be changed per operation rather than only at configuration time. That is the behaviour a compliant implementation needs, and the fact that it is exposed on the interface rather than baked into a parameter is what makes the unit usable by a general purpose core.
Taken with the format parameters and the operation set, the picture is of a unit that takes its compliance obligations seriously and states precisely where it currently falls short.
Instantiating fpnew_top and the package discipline
The top-level module is called fpnew_top and can be instantiated directly in a design. The example in the README shows the shape of that instantiation:
// FPU instance
fpnew_top #(
.Features ( fpnew_pkg::RV64D ),
.Implementation ( fpnew_pkg::DEFAULT_NOREGS ),
.TagType ( logic )
) i_fpnew_top (
.clk_i,
.rst_ni,
.operands_i,Three parameters are visible in the fragment. Features selects the set of supported formats and operations, here RV64D, the RISC-V double precision extension. Implementation selects the pipeline variant, here DEFAULT_NOREGS, which is the version without registers. TagType sets the type of the tag signal used to track an operation through the pipeline.
The port list tells you the shape of the interface. Operands and results carry the data, rnd_mode_i takes the rounding mode, op_i and op_mod_i select the operation and its variant, src_fmt_i, dst_fmt_i and int_fmt_i select the formats, and vectorial_op_i with simd_mask_i control the packed path. There are handshake signals in both directions with in_valid, in_ready, out_valid and out_ready, plus a flush input and a busy output, and an early_valid output for a result that arrives before the full result.
The README also sets a coding convention that matters for a multi-module codebase. The package fpnew_pkg must be compiled ahead of any file that references its types, parameters or functions, and importing the whole of fpnew_pkg into your source files is discouraged. Instead, references should be explicitly scoped, written as fpnew_pkg::foo. That keeps namespace collisions out of a design that instantiates several format configurations at once.
Submodules, Bender and the branch layout
The build has external dependencies, and they are handled in a conventional way.
FPnew depends on lzc and rr_arb_tree from the common_cells repository at pulp-platform, and optionally on a divider and square-root unit from the fpu-div-sqrt-mvp repository. Both are included in the source directory as git submodules, and the README gives the command that loads them:
git submodule update --init --recursiveThe project also recommends Bender for dependency management in your own projects and says that FPnew comes with Bender support, which is confirmed by the Bender.yml file at the root of the repository. The other root files describe the IP for tooling purposes, with ips_list.yml and src_files.yml being the usual manifests for a hardware project that a build system reads.
The repository structure is conventional for an RTL project: HDL source in src, documentation in docs, a testbench directory, a util directory and the vendor directory holding the integrated third party design. More in-depth documentation on the FPnew configuration, interfaces and architecture is in docs/README.md, the contributing guidelines are in docs/CONTRIBUTING.md, and a changelog is kept at docs/CHANGELOG.md.
The branching model is stated as well. The repository loosely follows GitFlow, so master is considered stable and is used to publish releases, while develop contains features and bug fixes that have not yet been properly released. The project also tries to adhere to SemVer, as outlined in the changelog.
For a user, that means the default branch is not necessarily the branch you want. The default branch here is develop, and a design that needs stability should track master or a release tag instead.
SolderPad for the unit, Apache 2.0 for the borrowed divider
The licensing section is a two-part arrangement, and it is the part of the README that a hardware team should read closely.
FPnew itself is released under the SolderPad Hardware License, described as a permissive licence based on Apache 2.0, with the details in the LICENSE.solderpad file. The T-Head E906 DivSqrt unit that was integrated into FPnew, the one living in vendor/opene906, is released under the Apache License, Version 2.0, with the details in the LICENSE.apache file. The repository also carries a README.license.md explaining the arrangement.
Worth noting: the licence recorded for the repository as a whole is Apache-2.0, while the README describes the project as SolderPad with Apache 2.0 applying to the vendored unit. Both are permissive and both are hardware-friendly, but a company with a policy on licence forms should read the two files rather than the metadata field. This is a reading of the terms, not legal advice.
The project asks to be cited, and gives a specific publication: an article by Mach, Schuiki, Zaruba and Benini titled FPnew: An open-source multiformat floating-point unit architecture for energy-proportional transprecision computing, in IEEE Transactions on Very Large Scale Integration (VLSI) Systems. A CITATION.cff file at the root holds the same reference in machine-readable form.
The release history is the part that needs attention. The tagged releases are v0.8.1 on 2023-08-30, v0.8.0 on 2023-06-19 and v0.7.0 on 2023-03-20, and the last push to the repository was on 2026-09-14. So the project is still being worked on, but the published versions are three years old, and a team that wants a stable point should take master or a release tag rather than the tip of develop.
Editorial conclusion
FPnew fits a hardware team building a RISC-V core or an accelerator that needs a floating-point unit whose formats are decided by the application rather than by the standard, and that wants to generate several precision variants from one RTL source. It is the wrong choice for a team that only needs the RISC-V F and D extensions, where a simpler unit is less work, and it is the wrong choice if you cannot accept a division unit that is known to be off by one unit in the last place and to miss the inexact flag in those cases. Before adopting it, read the compliance note on the PULP DivSqrt unit and the rounding mode documentation, decide whether you need the multi-format FMA and packed SIMD options, and check the branch you depend on, since the default branch is develop and releases are published from master.
Frequently asked questions
What is FPnew and who is it for?
FPnew is a SystemVerilog parametric floating-point unit supporting standard RISC-V formats and operations as well as transprecision formats. It is aimed at RISC-V processors, although the unit or its sub-blocks can be used in other environments.
Which floating-point formats does FPnew support?
Any IEEE 754-2008 style binary format, including binary16, binary32, binary64 and binary128, plus formats defined with an arbitrary number of exponent and mantissa bits through parameters, which are always symmetrically biased. Multiple FP formats can be supported concurrently and the number is not limited.
Does FPnew have known IEEE 754 compliance issues?
Yes, for the PULP DivSqrt unit. The README states that rounding mismatches have been reported in GitHub issues, which can lead to results being off by one ulp, with the inexact flag not being properly raised in those cases.
How do I pull in the FPnew dependencies?
The lzc and rr_arb_tree cells from common_cells and the optional divider from fpu-div-sqrt-mvp are included as git submodules, so run git submodule update --init --recursive in the source directory. The project also ships Bender support through its Bender.yml file.
Which branch should I base a design on?
The repository follows GitFlow loosely: master is the stable branch used to publish releases, and develop holds unreleased features and bug fixes. The default branch is develop, so a design needing stability should track master or a release tag instead.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/openhwfoundation-cvfpu)