# FloPoCo and MLIR: A Multi-Level Compilation Framework for Many Intents

Pierre Cochard, Louis Ledoux

<figure><img src="image_1.png" /></figure>

## ► To cite this version:

Pierre Cochard, Louis Ledoux. FloPoCo and MLIR: A Multi-Level Compilation Framework for Many Intents. Inria Lyon; INSA Lyon; CITI - Centre d'Innovation en Télécommunications et Intégration de services. 2025. hal-05412130

HAL Id: hal-05412130

https://hal.science/hal-05412130v1

Submitted on 11 Dec 2025

HAL is a multi-disciplinary open access archive for the deposit and dissemination of scientific research documents, whether they are published or not. The documents may come from teaching and research institutions in France or abroad, or from public or private research centers.

L'archive ouverte pluridisciplinaire HAL, est destinée au dépôt et à la diffusion de documents scientifiques de niveau recherche, publiés ou non, émanant des établissements d'enseignement et de recherche français ou étrangers, des laboratoires publics ou privés.

<figure><img src="image_2.png" /></figure>

Distributed under a Creative Commons Attribution 4.0 International License
<figure><img src="image_3.png" /></figure>
<figure><img src="image_4.png" /></figure>

<figure><img src="image_5.png" /></figure>

<figure><img src="image_6.png" /></figure>

# Table Of Content

① FloPoCo: the beautiful (but shaky) ivory tower

② MLIR: a hope for solid foundations

③ The Plan, the Done, the Missed, and the Yet-to-Do

④ Conclusions

⑤ Appendices (if any)
<figure><img src="image_7.png" /></figure>

<figure><img src="image_8.png" /></figure>

<figure><img src="image_9.png" /></figure>

# Motivations

## FloPoCo is multi-level

FloPoCo has its own quirks, let's complain about that.

## MLIR to the rescue

Maybe the savior that FloPoCo needs → Split FloPoCo intents into specialized dialects.

## Work status

* Definition of dialects.

* End-to-end compilation flow.

* Polynomial Approximations.

* Early results.
<figure><img src="image_10.png" /></figure>

<figure><img src="image_11.png" /></figure>

<figure><img src="image_12.png" /></figure>

# Motivations

## FloPoCo is multi-level

FloPoCo has its own quirks, let's complain about that.

## MLIR to the rescue

Maybe the savior that FloPoCo needs ⇒ Split FloPoCo **intents** into specialized **dialects**.

## Work status

* Definition of dialects.

* End-to-end compilation flow.

* Polynomial Approximations.

* Early results.
<figure><img src="image_13.png" /></figure>

<figure><img src="image_14.png" /></figure>

<figure><img src="image_15.png" /></figure>

# Motivations

## FloPoCo is multi-level

FloPoCo has its own quirks, let's complain about that.

## MLIR to the rescue

Maybe the savior that FloPoCo needs ⇒ Split FloPoCo **intents** into specialized **dialects**.

## Work status

1. Definition of dialects.

2. End-to-end compilation flow.

3. Polynomial Approximations.

4. Early results.
<figure><img src="image_16.png" /></figure>

<figure><img src="image_17.png" /></figure>

<figure><img src="image_18.png" /></figure>

<figure><img src="image_19.png" /></figure>

<figure><img src="image_20.png" /></figure>

<figure><img src="image_21.png" /></figure>

<figure><img src="image_22.png" /></figure>

# FloPoCo Limitations

* Large and complex codebase

* Academic papers

* Attic

* Many domains mixed:

* Image processing

* Computer vision

* Financial analysis

* Weak separation:

* Linear algebra

* Numerical analysis

* Target-agnostic... but also target-coupled?

* ASIC support? Pipelining?

* HDL generation = VHDL only → brittle

## Overall

A bit tangled... :)

<figure><img src="image_23.png" /><figcaption>FloPoCo ivory tower.</figcaption></figure>
<figure><img src="image_24.png" /></figure>

<figure><img src="image_25.png" /></figure>

<figure><img src="image_26.png" /></figure>

<figure><img src="image_27.png" /></figure>

<figure><img src="image_28.png" /></figure>

<figure><img src="image_29.png" /></figure>

<figure><img src="image_30.png" /></figure>

<figure><img src="image_31.png" /></figure>

# FloPoCo Limitations

* Large and complex codebase

* Academic papers

* Attic

* Many domains mixed:

* Multiplier heuristics

* Bitheap logic

* Polynomial approximation

* Weak separation:

* Target-agnostic... but also target-coupled?

* ASIC support? Pipelining?

* HDL generation = VHDL only → brittle

* ASIC support ? Pipelining ?

* HDL generation = VHDL only → brittle

## Overall

A bit tangled... :)

<figure><img src="image_32.png" /><figcaption>FloPoCo ivory tower.</figcaption></figure>
<figure><img src="image_33.png" /></figure>

<figure><img src="image_34.png" /></figure>

<figure><img src="image_35.png" /></figure>

<figure><img src="image_36.png" /></figure>

<figure><img src="image_37.png" /></figure>

<figure><img src="image_38.png" /></figure>

<figure><img src="image_39.png" /></figure>

# FloPoCo Limitations

* Large and complex codebase

* Academic papers

* Attic

* Many domains mixed:

* Multiplier heuristics

* Bitheap logic

* Polynomial approximation

* Weak separation:

* High-level math

* Low-level circuit details

* Target-agnostic... but also target-coupled?

* ASIC support? Pipelining?

* HDL generation = VHDL only → brittle

## Overall

A bit tangled... :)

<figure><img src="image_40.png" /><figcaption>FloPoCo ivory tower.</figcaption></figure>
<figure><img src="image_41.png" /></figure>

<figure><img src="image_42.png" /></figure>

<figure><img src="image_43.png" /></figure>

# FloPoCo Limitations

* Large and complex codebase

* Academic papers

* Attic

* Many domains mixed:

* Multiplier heuristics

* Bitheap logic

* Polynomial approximation

* Weak separation:

* High-level math

* Low-level circuit details

* Target-agnostic... but also target-coupled?

* ASIC support? Pipelining?

* HDL generation = VHDL only → brittle

## Overall

## A bit tangled... :)

<figure><img src="image_44.png" /></figure>
<figure><img src="image_45.png" /></figure>

<figure><img src="image_46.png" /></figure>

<figure><img src="image_47.png" /></figure>

<figure><img src="image_48.png" /></figure>

<figure><img src="image_49.png" /></figure>

<figure><img src="image_50.png" /></figure>

<figure><img src="image_51.png" /></figure>

# FloPoCo Limitations

* Large and complex codebase

* Academic papers

* Attic

* Many domains mixed:

* Multiplier heuristics

* Bitheap logic

* Polynomial approximation

* Weak separation:

* High-level math

* Low-level circuit details

* Target-agnostic... but also target-coupled?

* ASIC support ? Pipelining ?

* HDL generation = VHDL only → brittle

## Overall

A bit tangled... :)

<figure><img src="image_52.png" /><figcaption>FloPoCo ivory tower.</figcaption></figure>
<figure><img src="image_53.png" /></figure>

<figure><img src="image_54.png" /></figure>

<figure><img src="image_55.png" /></figure>

# FloPoCo Limitations

* Large and complex codebase

* Academic papers

* Attic

* Many domains mixed:

* Multiplier heuristics

* Bitheap logic

* Polynomial approximation

* Weak separation:

* High-level math

* Low-level circuit details

* Target-agnostic... but also target-coupled?

* ASIC support ? Pipelining ?

* HDL generation = VHDL only → **brittle**

## Overall

A bit tangled... :)

<figure><img src="image_56.png" /><figcaption>FloPoCo ivory tower.</figcaption></figure>
<figure><img src="image_57.png" /></figure>

# FloPoCo Limitations

* Large and complex codebase

* Academic papers

* Attic

* Many domains mixed:

* Multiplier heuristics

* Bitheap logic

* Polynomial approximation

* Weak separation:

* High-level math

* Low-level circuit details

* Target-agnostic... but also target-coupled?

* ASIC support ? Pipelining ?

* HDL generation = VHDL only → **brittle**

## Overall

A bit tangled... :)

<figure><img src="image_58.png" /></figure>

<figure><img src="image_59.png" /></figure>

<figure><img src="image_60.png" /></figure>
<figure><img src="image_61.png" /></figure>

<figure><img src="image_62.png" /></figure>

<figure><img src="image_63.png" /></figure>

# FloPoCo Limitations

## Gloubli-boulga

All these levels, intents, and representations ... ⇒ **Multi-Level Intermediate Representations**
<figure><img src="image_64.png" /></figure>

<figure><img src="image_65.png" /></figure>

<figure><img src="image_66.png" /></figure>

# Arithmetic Optimizations: Catch them all! (Motivations)

<figure><img src="image_67.png" /></figure>

Software and Hardware are intertwined and
multi-level.
<figure><img src="image_68.png" /></figure>

<figure><img src="image_69.png" /></figure>

<figure><img src="image_70.png" /></figure>

# Arithmetic Optimizations: Catch them all! (Motivations)

<figure><img src="image_71.png" /></figure>

## What Compilers Already Do

* $x*1 \rightarrow x, x+0 \rightarrow x, x*0 \rightarrow 0,$
  $3*7 \rightarrow 21$

* $x*2 \rightarrow x \ll 1, x/8 \rightarrow x \gg 3$

* Div. / mult. by constants & powers of two $\rightarrow$ reciprocals, bitmasks

* Instruction selection
  Fused Multiply-Add (FMA)

Linked by compilers... Poor context window.
⇒ **Missing opportunities** 😊
<figure><img src="image_72.png" /></figure>

<figure><img src="image_73.png" /></figure>

<figure><img src="image_74.png" /></figure>

# Arithmetic Optimizations: Catch them all! (*Motivations*)

<figure><img src="image_75.png" /></figure>

Opportunities for dedicated Hardware Generation.

⇒ **Still missing opportunities** 😊

## Beyond Low-Level Rewrites

* High-Level Synthesis (HLS) [UDL+20]

* Arith. Expert / FloPoCo [DK24]

* Operator specialization
  ($x^2, x/3$)

* Operator fusion
  ($\frac{1}{\sqrt{x^2+y^2}}$, LZC+Shifter)

* Fine-grained hardware mapping
  (AMD LUT4, Intel DSP)
<figure><img src="image_76.png" /></figure>

<figure><img src="image_77.png" /></figure>

<figure><img src="image_78.png" /></figure>

# Arithmetic Optimizations: Catch them all! (*Motivations*)

<figure><img src="image_79.png" /></figure>

MLIR offers a larger view on the stack.
⇒ **Playground for many opportunities** 😊

## Multi-Level Intermediate Representation

* LLVM subproject

* Based on the concept of multi-IRs: *dialects*

* "Long chain of many domain-specific lowering compilation steps":
  * Arith, Math, Control-Flow (CF),
  * Tensors, Memory

* Multi-Level for Multi Intents

* Problem-to-Circuit: **R** functions
  Hardware evaluators.
<figure><img src="image_80.png" /></figure>

<figure><img src="image_81.png" /></figure>

<figure><img src="image_82.png" /></figure>

# Current Progress

Plan, Done, Missing, To Do

## 2.1 The plan

## 2.2 Contributions

## 2.3 Results
<figure><img src="image_83.png" /></figure>

<figure><img src="image_84.png" /></figure>

<figure><img src="image_85.png" /></figure>

# The Plan: Rebuild the Tower

* Separation of concerns

* Domain Specific Languages → Dialects

* VHDL generation → netlistS IRS ?
  (Netlists are also super multi level)

* Multi-Domain (level) End-to-end flow
  AI, Signal processing, linear algebra

Dream ©

FloPoCo-MLIR: From Problem to Silicon

<figure><img src="image_86.png" /><figcaption>FloPoCo ivory tower.</figcaption></figure>
<figure><img src="image_87.png" /></figure>

<figure><img src="image_88.png" /></figure>

<figure><img src="image_89.png" /></figure>

# The Plan: Rebuild the Tower

## Separation of concerns

* Higher levels → mathematical intents

* Lower levels → machine concerns

* → **Transformations / Lowering**

* Domain Specific Languages → Dialects

* VHDL generation → netlistS IRS ?
  (Netlists are also super multi level)

* Multi-Domain (level) End-to-end flow
  AI, Signal processing, linear algebra

<figure><img src="image_90.png" /></figure>

Dream ©

FloPoCo-MLIR: From Problem to Silicon

MLIR

FloPoCo ivory tower.
<figure><img src="image_91.png" /></figure>

<figure><img src="image_92.png" /></figure>

<figure><img src="image_93.png" /></figure>

# The Plan: Rebuild the Tower

## Separation of concerns

* Higher levels → mathematical intents

* Lower levels → machine concerns

* → **Transformations / Lowering**

## Domain Specific Languages → Dialects

* VHDL generation → netlistS IRS ?
  (Netlists are also super multi level)

* Multi-Domain (level) End-to-end flow
  AI, Signal processing, linear algebra

<figure><img src="image_94.png" /></figure>

Dream 😃

FloPoCo-MLIR: From Problem to Silicon

HW FixedPointArith

BitHeap

RealArith

MLIR

FloPoCo ivory tower.
<figure><img src="image_95.png" /></figure>

<figure><img src="image_96.png" /></figure>

<figure><img src="image_97.png" /></figure>

# The Plan: Rebuild the Tower

* Separation of concerns

* Higher levels → mathematical intents

* Lower levels → machine concerns

* → **Transformations / Lowering**

* Domain Specific Languages → **Dialects**

* VHDL generation → netlist\S IRS ?
  (Netlists are also super multi level)

* Multi-Domain (level) End-to-end flow
  AI, Signal processing, linear algebra

<figure><img src="image_98.png" /><figcaption>FloPoCo ivory tower.</figcaption></figure>

Dream ©

FloPoCo-MLIR: From Problem to Silicon
<figure><img src="image_99.png" /></figure>

<figure><img src="image_100.png" /></figure>

<figure><img src="image_101.png" /></figure>

# The Plan: Rebuild the Tower

* Separation of concerns

* Higher levels → mathematical intents

* Lower levels → machine concerns

* → **Transformations / Lowering**

* Domain Specific Languages → **Dialects**

* VHDL generation → netlist\S IRS ?

*(Netlists are also super multi level)*

* Multi-Domain (level) End-to-end flow
* AI, Signal processing, linear algebra

Dream 😊

**FloPoCo-MLIR: From Problem to Silicon**

<figure><img src="image_102.png" /></figure>

Stable FloPoCo ivory tower with MLIR.
<figure><img src="image_103.png" /></figure>

<figure><img src="image_104.png" /></figure>

<figure><img src="image_105.png" /></figure>

The big picture

<figure><img src="image_106.png" /></figure>

☐ Internal Dialect ○ Internal Library ○ Language → Lowers to → Uses

☐ External Dialect ○ External Library ○ Benchmark → Missing Path
<figure><img src="image_107.png" /></figure>

<figure><img src="image_108.png" /></figure>

<figure><img src="image_109.png" /></figure>

The big picture

<figure><img src="image_110.png" /></figure>

☐ Internal Dialect ○ Internal Library ○ Language → Lowers to → Uses

☐ External Dialect ○ External Library ○ Benchmark → Missing Path
<figure><img src="image_111.png" /></figure>

<figure><img src="image_112.png" /></figure>

<figure><img src="image_113.png" /></figure>

# Contributed Dialects

## RealArith:

* operates on $\mathbb{R}$

* mnemonic: `r_arith`

* types: `r_expr`, `r_const`

* math ops:
  * `sin`, `cos`, `add`, `sub`, `mul`, `div`

* special ops: `machine_repr`

* no transformations yet

* lowers to `FixedPointArith`

## FixedPointArith:

* operates with fixed-points

* mnemonic: `fixedPt_arith`

* types: `fixedPt`, `fixedPt_val`

* arith ops: `add`, `mul`, `const`

* ops: `extract`, `rescale_2pow`, `extend`, `extract`, `get 固定点`, `get_int`

* no transformations yet

* lowers to `Arith`
<figure><img src="image_114.png" /></figure>

<figure><img src="image_115.png" /></figure>

<figure><img src="image_116.png" /></figure>

# Current Progress

Plan, Done, Missing, To Do

## 2.1 The plan

## 2.2 Contributions

## 2.3 Results
<figure><img src="image_117.png" /></figure>

<figure><img src="image_118.png" /></figure>

<figure><img src="image_119.png" /></figure>

# FloPoCo + Faust + MLIR: An end-to-end audio flow

Faust is an excellent candidate :)

* Signals

* R

* Intervals

* targets HW, machine number with DAC precision

## Ring Modulator

$$y(t) = \sin(2\pi ft) \cdot \sin(2\pi fm)$$

<figure><img src="image_120.png" /></figure>

-t

## Faust language

import("stdfaust.lib");

<figure><img src="image_121.png" /></figure>

sine(fc,t) = sin(ph) with {
    ph = t/48000.0*f*2.0*ma.PI;
};

ringmod不对称, 应为 `sine(fc,t) * sine(fm,t);`

process = ringmod(440.0, 33.0);

Ring modulation shape

## Faust Graph

<figure><img src="image_122.png" /></figure>

Internal Graph

Ring Modulation: 440/33.
<figure><img src="image_123.png" /></figure>

<figure><img src="image_124.png" /></figure>

<figure><img src="image_125.png" /></figure>

# FloPoCo + Faust + MLIR: Ring Modulator IR.

## Faust IR

```R
faust.graph @process inputs: 1, outputs: 1) {
  %0 = faust.PI
  %1 = faust.real(2.000000e+00 : f32)
  %2 = faust.real(3.300000e+01 : f32)
  %3 = faust.real(4.800000e+04 : f32)
  %4 = faust.input(0 : ui32)
  %5 = faust.div(%4 : !faust.real, %3 : !faust.rconst)
  %6 = faust.mul(%5 : !faust.real, %2 : !faust.rconst)
  %7 = faust.mul(%6 : !faust.real, %1 : !faust.rconst)
  %8 = faust.mul(%7 : !faust.real, %0 : !faust.rconst)
  %9 = faust.sin(%8 : !faust.real)
  %10 = faust.real(4.000000e+02 : f32)
  %11 = faust.mul(%5 : !faust.real, %10 : !faust.rconst)
  %12 = faust.mul(%11 : !faust.real, %1 : !faust.rconst)
  %13 = faust.mul(%12 : !faust.real, %0 : !faust.rconst)
  %14 = faust.sin(%13 : !faust.real)
  %15 = faust.mul(%14 : !faust.real, %9 : !faust.real)
  faust.output(%15 : !faust.real)
}
```

Step$_{i}$→ii: faust -lang=mlir ringmod-tfunc.dsp -o ringmod.mlir
<figure><img src="image_126.png" /></figure>

<figure><img src="image_127.png" /></figure>

<figure><img src="image_128.png" /></figure>

<figure><img src="image_129.png" /></figure>

<figure><img src="image_130.png" /></figure>

# FloPoCo + Faust + MLIR: From $\mathbb{R}$ to machine numbers

## Polynomial Approximation
(Horner Form, Sollya)

* A: fixedpt<4, -5, signed> → maps [-16, 16) to [-1, 1)

* B: fixedpt<0, -23, signed> → 12th-degree polynomial

<figure><img src="image_131.png" /></figure>

Polynomial Transformation

## RealArith IR

```c
func.func @process(%arg0: !fixedPt_arith fixedpt<4, -5, signed>) -> !fixedPt_arith fixedpt<0, -23, signed> {
    %0 = r_arith constant(4.400000e+02 : f32)
    %1 = r_arith pi
    %2 = r_arith constant(2.000000e+00 : f32)
    %3 = r_arith constant(3.300000e+01 : f32)
    %4 = r_arith constant(4.800000e+04 : f32)
    %5 = r_arith div(%arg0: !fixedPt_arith fixedpt<4, -5, signed>, %4: !r_arith r_const)
    %6 = r_arith mul(%5: !r_arith r_expr, %3: !r_arith r_const)
    %7 = r_arith mul(%6: !r_arith r_expr, %2: !r_arith r_const)
    %8 = r_arith mul(%7: !r_arith r_expr, %1: !r_arith r_const)
    %9 = r_arith sin(%8: !r_arith r_expr)
    %10 = r_arith mul(%5: !r_arith r_expr, %0: !r_arith r_const)
    %11 = r_arith mul(%10: !r_arith r_expr, %2: !r_arith r_const)
    %12 = r_arith mul(%11: !r_arith r_expr, %1: !r_arith r_const)
    %13 = r_arith sin(%12: !r_arith r_expr)
    %14 = r_arith mul(%13: !r_arith r_expr, %9: !r_arith r_expr)
    %15 = r_arith machine_repr of %14: !r_arith r_expr as !fixedPt_arith fixedpt<0, -23, signed>
    return %15: !fixedPt_arith fixedpt<0, -23, signed>
}
```

<figure><img src="image_132.png" /></figure>

<figure><img src="image_133.png" /></figure>

<figure><img src="image_134.png" /></figure>

Step$_{ii}$→$_{iii}$: faust-opt ringmod.mlr --cse --canonicalize
--faust-to-core='tfunc' -o ringmod_realarith.mlr
<figure><img src="image_135.png" /></figure>

<figure><img src="image_136.png" /></figure>

<figure><img src="image_137.png" /></figure>

<figure><img src="image_138.png" /></figure>

<figure><img src="image_139.png" /></figure>

# FloPoCo + Faust + MLIR: Fine-tuned fixed-point Horner architecture

## FixedPointArith IR

```c
func func @process(%arg0: !fixedPt_arith fixedpt<4, -5, signed>) !> fixedPt_arith fixedpt
<23, 0, signed> {
    %0 = fixedPt_arith const <2 %ci fixedPt_arith fixedpt<0, -2, signed>>
    %1 = fixedPt_arith const <4170, !fixedPt_arith fixedpt<11, -2, signed>>
    %2 = fixedPt_arith const <2132970, !fixedPt_arith fixedpt<20, -2, signed>>
    %3 = fixedPt_arith const <1183, !fixedPt_arith fixedpt<9, -2, signed>>
    %4 = fixedPt_arith const <-303000, !fixedPt_arith fixedpt<17, -2, signed>>
    %5 = fixedPt_arith const <-70, !fixedPt_arith fixedpt<5, -2, signed>>
    %6 = fixedPt_arith const <13004, !fixedPt_arith fixedpt<12, -2, signed>>
    %7 = fixedPt_arith const <-3, !fixedPt_arith fixedpt<0, -2, signed>>
    %8 = fixedPt_arith const <-261, !fixedPt_arith fixedpt<7, -2, signed>>
    %9 = fixedPt_arith rescale_p2ow %arg0: <4, -5, signed> shift by -4
    %10 = fixedPt_arith mul %8: <7, -2, signed>, %9: <0, -9, signed>
    %11 = fixedPt_arith extract <8, -4, signed> from %10: <8, -11, signed>
    %12 = fixedPt_arith.add %11: <8, -4, signed>, %7: <0, -2, signed> -> <7, -4, signed>
}

// Intermediate Horner stages
// ...
%31 = fixedPt_arith.mul %30: <19, -4, signed>, %9: <0, -9, signed>
%32 = fixedPt_arith.extract <20, -4, signed> from %31: <20, -13, signed>
%33 = fixedPt_arith.add %32: <20, -4, signed>, %0: <0, -2, signed> -> <20, -4, signed>
%34 = fixedPt_arith.extend %33: <20, -4, signed> to <23, -4, signed>
%35 = fixedPt_arith.extract <23, 0, signed> from %34: <23, -4, signed>
return %35 !fixedPt_arith fixedpt<23, 0, signed>
}
```

## Fixed-Point Horner Evaluator

* $c_i$: fixed-point coefficients

* $\bar{y}_i$: truncated input reused

* $s_i$: adder output sizes

* Final stage: rounding

<figure><img src="image_140.png" /><figcaption>Generated Architecture</figcaption></figure>

Step$_{iii}$→$_{iv}$: flopoco-opt ringmod_realarith.mlir
--realarith-to-fixedPt_arith -o ringmod fixedpt.mlir
<figure><img src="image_141.png" /></figure>

<figure><img src="image_142.png" /></figure>

<figure><img src="image_143.png" /></figure>

# Multi-Optimized Intermediate Representation to HDL

* leave MLIR world

* FixedPointArith → Arith+CF

* Target: CIRCT<fnref n="1" /> and Dynamic<fnref n="2" />

* Yield SV/VHDL 😊

<figure><img src="image_144.png" /></figure>

<footnote n="1">¹CIRCT: https://circt.llvm.org/</footnote>

<footnote n="2">²Dynamic: https://dynamatic.epfl.ch/</footnote>
<figure><img src="image_145.png" /></figure>

<figure><img src="image_146.png" /></figure>

<figure><img src="image_147.png" /></figure>

<figure><img src="image_148.png" /></figure>

# Multi-Optimized Intermediate Representation to HDL

1. SCF(switch, case, yield) + FixedPointArith → SCF(switch, case, yield) + Arith

flopoco-opt real_arith.mlir

- realarith-to-fixedPt_arith="approximation-method=uniform_

piecewise_polynomial_degree=4" -symbol-dce -canonicalize -cse

- o 1 fixed Pt arith uniform piecewise 8 bout deg 8.mlir

2. SCF(switch, case, yield) + Arith → SCF(if) + Arith

flopoco-opt 1 fixed Pt arith uniform piecewise 24 bout deg 9.mlir

- fixedPt_arith-to-arith -o

2_arithUniform piecewise_24boutDeg 9.mlir

3. SCF(if) + Arith → CF + Arith

cirmc-opt 2_arith uniform piecewise 24 bout deg 9.mlir -switch-to-if

- o 3_arith_switch_to_if uniform piecewise 24 bout deg 9.mlir

4. CF + Arith (final)

mlir-opt 3_arith_switch_to_if uniform piecewise 24 bout deg 9.mlir

- convert-scf-to-cf -o 4_out.mlir
<figure><img src="image_149.png" /></figure>

<figure><img src="image_150.png" /></figure>

<figure><img src="image_151.png" /></figure>

# Multi-Optimized Intermediate Representation to HDL

1. SCF(switch, case, yield) + FixedPointArith → SCF(switch, case, yield) + Arith

```
flopoco-opt real_arith.mlir
-reaarithmetic-to-fixedPtArith="approximation-method=uniform_
piecewise_polynomial_degree=4" -symbol-dce -canonicalize -cse
-o 1 fixed Pt Arith uniform piecewise 8 bout deg 8.mlir
```

2. SCF(switch, case, yield) + Arith → SCF(if) + Arith

```
flopoco-opt 1 fixed Pt Arith uniform piecewise 24 bout deg 9.mlir
-fixed Pt Arith-to-Arith -o
2 Arith uniform piecewise 24 bout deg 9.mlir
```

3. SCF(if) + Arith → CF + Arith

```
circuit-opt 2 arithmetic uniform piecewise 24 bout deg 9.mlir -switch-to-if
-o 3 arithmetic switch to if uniform piecewise 24 bout deg 9.mlir
```

4. CF + Arith (final)

```
mlir-opt 3 arithmetic_switch_to_if uniform piecewise 24 bout deg 9.mlir
-convert-scf-to-cf -o 4_out.mlir
```
<figure><img src="image_152.png" /></figure>

<figure><img src="image_153.png" /></figure>

<figure><img src="image_154.png" /></figure>

<figure><img src="image_155.png" /></figure>

# Multi-Optimized Intermediate Representation to HDL

1. SCF(switch, case, yield) + FixedPointArith → SCF(switch, case, yield) + Arith

```
flopoco-opt real_arith.mlir
-reaarithmetic-to-fixedPtArith="approximation-method=uniform_
piecewise_polynomial_degree=4" -symbol-dce -canonicalize -cse
-o 1 fixed-pt-arithmetic-uniform_p piecewise_8 bout _deg 8.mlir
```

2. SCF(switch, case, yield) + Arith → SCF(if) + Arith

```
flopoco-opt 1 fixed-pt-arithmetic-uniform_p piecewise_24 bout _deg 9.mlir
-fixedPtArithmetic-to-Arithmetic -o
2_arithmetic-uniform_p piecewise_24 bout _deg 9.mlir
```

3. SCF(if) + Arith → CF + Arith

```
circuit-opt 2 arithmetic-uniform_p piecewise_24 bout _deg 9.mlir -switch-to-if
-o 3 arithmetic-switch-to-if-uniform_p piecewise_24 bout _deg 9.mlir
```

4. CF + Arith (final)

```
mlir-opt 3 arithmetic_switch_to_if-uniform_p piecewise_24 bout _deg 9.mlir
-convert-scf-to-cf -o 4 _out.mlir
```
<figure><img src="image_156.png" /></figure>

<figure><img src="image_157.png" /></figure>

<figure><img src="image_158.png" /></figure>

# Current Progress

Plan, Done, Missing, To Do

## 2.1 The plan

## 2.2 Contributions

## 2.3 Results
<figure><img src="image_159.png" /></figure>

<figure><img src="image_160.png" /></figure>

<figure><img src="image_161.png" /></figure>

# Different Polynomial Approximations

Approximations of $f(x) = \sin(2\pi \cdot 440x) \cdot \sin(2\pi \cdot 33x)$ on $[0, 1]$:

<figure><img src="image_162.png" /><figcaption>Two degree 16 polynomials.</figcaption></figure>

<figure><img src="image_163.png" /><figcaption>Thirty two degree 4 polynomials.</figcaption></figure>
<figure><img src="image_164.png" /></figure>

<figure><img src="image_165.png" /></figure>

<figure><img src="image_166.png" /></figure>

# Yielding Different Polynomial Fixed-Point Evaluator

<figure><img src="image_167.png" /></figure>

Tailored circuitry for a $\mathbb{R}$-function given domains and precision budget.
<figure><img src="image_168.png" /></figure>

<figure><img src="image_169.png" /></figure>

<figure><img src="image_170.png" /></figure>

# Hardware Tradeoffs

Resource usage across methods on xc7z020 FPGA.

<table><thead><tr><th rowspan="2">Method (output precision)</th><th rowspan="2">Poly. degree</th><th colspan="3">Hardware resources</th></tr><tr><th>LUT</th><th>FF</th><th>DSP</th></tr></thead><tbody><tr><td>faust-syfala (32 bits)</td><td>*</td><td>3,765</td><td>3,142</td><td>32</td></tr><tr><td>faust-mlir (32 bits)</td><td>*</td><td>14,638</td><td>8,226</td><td>27</td></tr><tr><td rowspan="4">Uniform Piecewise<br>Poly. Approx. (10 bits)</td><td>4</td><td>2,868</td><td>4,172</td><td>4</td></tr><tr><td>5</td><td>3,209</td><td>4,460</td><td>5</td></tr><tr><td>14</td><td>1,252</td><td>1,157</td><td>50</td></tr><tr><td>18</td><td>1,531</td><td>1,369</td><td>63</td></tr><tr><td rowspan="4">Uniform Piecewise<br>Poly. Approx. (24 bits)</td><td>3</td><td>127,441</td><td>209,121</td><td>5</td></tr><tr><td>4</td><td>32,042</td><td>56,004</td><td>8</td></tr><tr><td>5</td><td>17,608</td><td>30,399</td><td>11</td></tr><tr><td>6</td><td>9,712</td><td>16,489</td><td>15</td></tr><tr><td></td><td>8</td><td>4,965</td><td>7,886</td><td>24</td></tr><tr><td></td><td>9</td><td>5,228</td><td>8,229</td><td>27</td></tr></tbody></table>
<figure><img src="image_171.png" /></figure>

<figure><img src="image_172.png" /></figure>

<figure><img src="image_173.png" /></figure>

# Current Progress

## Conclusions

3.1 Key Takeaways

3.2 Future work

3.3 Addenda
<figure><img src="image_174.png" /></figure>

<figure><img src="image_175.png" /></figure>

<figure><img src="image_176.png" /></figure>

# Conclusions

## End-To-End compilation

Bridged highly abstracted language to circuit description in MLIR.

## Separation of Concerns

Created 2 MLIR dialects; RealArith and FixedPointArith. Different semantics, more arithmetic optimizations.

## Polynomial Approximations

Generation of fine-tuned fixed-point polynomial evaluator circuits.

## Work In Progress

Too hot to conclude, but... Playground is ready !
<figure><img src="image_177.png" /></figure>

<figure><img src="image_178.png" /></figure>

<figure><img src="image_179.png" /></figure>

<figure><img src="image_180.png" /></figure>

# Conclusions

## End-To-End compilation

Bridged highly abstracted language to circuit description in MLIR.

## Separation of Concerns

Created 2 MLIR dialects; **RealArith** and **FixedPointArith**. Different semantics, more arithmetic optimizations.

## Polynomial Approximations

Generation of fine-tuned fixed-point polynomial evaluator circuits.

## Work In Progress Results

Too hot to conclude, but... Playground is ready !
<figure><img src="image_181.png" /></figure>

<figure><img src="image_182.png" /></figure>

<figure><img src="image_183.png" /></figure>

<figure><img src="image_184.png" /></figure>

# Conclusions

## End-To-End compilation

Bridged highly abstracted language to circuit description in MLIR.

## Separation of Concerns

Created 2 MLIR dialects; **RealArith** and **FixedPointArith**. Different semantics, **more arithmetic optimizations**.

## Polynomial Approximations

Generation of fine-tuned fixed-point polynomial evaluator circuits.

## Work In Progress Results

Too hot to conclude, but... Playground is ready !
<figure><img src="image_185.png" /></figure>

<figure><img src="image_186.png" /></figure>

<figure><img src="image_187.png" /></figure>

<figure><img src="image_188.png" /></figure>

# Conclusions

## End-To-End compilation

Bridged highly abstracted language to circuit description in MLIR.

## Separation of Concerns

Created 2 MLIR dialects; **RealArith** and **FixedPointArith**. Different semantics, **more arithmetic optimizations**.

## Polynomial Approximations

Generation of fine-tuned fixed-point polynomial evaluator circuits.

## Work In Progress Results

Too hot to conclude, but... **Playground is ready !**
<figure><img src="image_189.png" /></figure>

<figure><img src="image_190.png" /></figure>

<figure><img src="image_191.png" /></figure>

# Future Work

* More polynomial schemes

* More benchmark / workloads

* More Optimizations, **lower levels !** (bitheap Dialect ?)

* Function analysis (e.g., parity, monotonicity)

* Interval tracking or propagation

* What other opportunities are we missing?

* Open the repositories and clarify licenses

* **Playground is ready !**
<figure><img src="image_192.png" /></figure>

<figure><img src="image_193.png" /></figure>

<figure><img src="image_194.png" /></figure>

Thank you

Q&A.
<figure><img src="image_195.png" /></figure>

<figure><img src="image_196.png" /></figure>

<figure><img src="image_197.png" /></figure>

# Dissemination

* Poster @ EuroLLVM 2025, Berlin, Germany

* Journal @ DSD 2025, Salerno, Italy

<figure><img src="image_198.png" /></figure>

Preprint available on HAL:

https://hal.science/hal-05063466
<figure><img src="image_199.png" /></figure>

<figure><img src="image_200.png" /></figure>

<figure><img src="image_201.png" /></figure>

# Appendix: CIRCT Framework Schematic

<figure><img src="image_202.png" /></figure>

Set of dialects and lowerings steps of theLLvm/CIRCT framework.
<figure><img src="image_203.png" /></figure>

<figure><img src="image_204.png" /></figure>

<figure><img src="image_205.png" /></figure>

The full flow

<figure><img src="image_206.png" /></figure>

Ringmod to Arith IR.