# Upcoming ABC flow changes

**URL:** <https://yosyshq.discourse.group/t/upcoming-abc-flow-changes/133>\
**Category:** Developers\
**Created:** [March 30, 2026, 8:27am UTC](https://yosyshq.discourse.group/t/upcoming-abc-flow-changes/133 "2026-03-30T08:27:02Z")\
**Posts on this page:** 4\
**Page:** 1

<div class="post-metadata">

**Author:** ![lofty](https://avatars.discourse-cdn.com/v4/letter/l/f0a364/32.png) [@lofty](https://yosyshq.discourse.group/u/lofty)\
**Post date:** [March 30, 2026, 8:27am UTC](https://yosyshq.discourse.group/t/upcoming-abc-flow-changes/133/1 "2026-03-30T08:27:02Z")

</div>

Hello,

I have been working on some big changes on the interface to ABC in Yosys and wish to inform others about them.

Yosys presently has three different commands for running ABC: `abc`, `abc9` and `abc_new`.

`abc` is the original optimisation/technology mapping flow using ABC; it supports LUT and standard cell mapping, plus mapping to sum-of-products architectures (e.g. `synth_coolrunner2`). It’s robust and bug-free, but reliant on BLIF for communication to and from ABC, which is not very efficient.

`abc9` is the state of the art flow for FPGAs in Yosys, because it brings timing-driven mapping of LUTs and flops, as well as box support to describe fixed-function combinational logic (e.g. carry chains and hard multiplexers). It uses XAIGER to communicate with ABC because boxes are not supported in BLIF. It’s been the default LUT mapping flow for the past two and a half years for `synth_ice40`, `synth_ecp5` and `synth_gowin`.

`abc_new` attempts to bring the efficiency benefits of an XAIGER flow to a standard-cell mapping flow, while also supporting boxes to represent hand-optimised macro blocks. It has a lot of overlap with `abc9`, with a few improvements that could be ported back to it. Unfortunately, the developer working on this flow left the company while working on this, and the resulting code is poorly understood.

This situation is not ideal, so I would like to rework these into a less confusing flow.

The `abc9` pass is fairly mature and robust for LUT mapping, so I would like to rename it `abc_lut` (`abc_fpga` has also been suggested as a name), and remove LUT mapping functionality from the `abc` pass.

`abc_new` for standard-cell mapping is admittedly much less mature than `abc`, but I believe it to be a technologically superior base which would reduce resource usage on large designs. As such, I would like to rename it `abc_scl` (or `abc_asic`), develop it further and in the long term remove standard-cell mapping functionality from the `abc` pass.

This would leave the `abc` pass as existing solely for SOP mapping for `synth_coolrunner2`, which isn’t ideal and I’m unsure what to do there, but that can be solved later.

---

<div class="post-metadata">

**Author:** ![rocallahan](https://yyz2.discourse-cdn.com/free1/user_avatar/yosyshq.discourse.group/rocallahan/32/22_2.png) [@rocallahan](https://yosyshq.discourse.group/u/rocallahan)\
**Post date:** [April 19, 2026, 2:25am UTC](https://yosyshq.discourse.group/t/upcoming-abc-flow-changes/133/2 "2026-04-19T02:25:16Z")

</div>

I added support for parallel ABC runs to `abc` last year. This is a pretty huge speedup in some situations. Can we have that in `abc_new`?

---

<div class="post-metadata">

**Author:** ![lofty](https://avatars.discourse-cdn.com/v4/letter/l/f0a364/32.png) [@lofty](https://yosyshq.discourse.group/u/lofty)\
**Post date:** [April 20, 2026, 8:16am UTC](https://yosyshq.discourse.group/t/upcoming-abc-flow-changes/133/3 "2026-04-20T08:16:38Z")

</div>

Um, hmm; `abc9` and `abc_new` are both laid out as “scripts”, rather than the monolithic “blob” that is `abc`. The actual calls to ABC happen in `abc9_exe` for both passes, and both passes iterate over each selected module; I think they would have to be reworked a bit to enable this parallelism. Happy to discuss how to go about that.

---

<div class="post-metadata">

**Author:** ![widlarizer](https://avatars.discourse-cdn.com/v4/letter/w/bbce88/32.png) [@widlarizer](https://yosyshq.discourse.group/u/widlarizer)\
**Post date:** [April 21, 2026, 9:08am UTC](https://yosyshq.discourse.group/t/upcoming-abc-flow-changes/133/4 "2026-04-21T09:08:19Z")

</div>

Clock domain parallelism is a key feature we definitely don’t want to lose in this refactor. There was a good discussion about the changes in the original PR:

> <https://github.com/YosysHQ/yosys/pull/5266>
>
> \_What are the reasons/motivation for this change?\_
> 
> For large circuits \`AbcPas…s\` can run ABC hundreds or thousands of times, once per unique \`clkdomain\_t\`. Some of those ABC runs take a while. Running those ABCs in parallel is possible, because the cells assigned to each ABC run are disjoint. This PR improves the runtime of \`AbcPass\` on one of our large circuits by 5x (which translates into a 3x speedup of synthesis end-to-end).
> 
> \_Explain how this is achieved.\_
> 
> This builds on PR #5239.
> 
> Reading and writing RTLIL are not thread-safe for various reasons, and fixing that would be difficult. So for now we stick with reading and writing RTLIL on the main thread. We split up the per-clkdomain work into a "prepare" phase which builds the gate netlist and removes the corresponding cells from the module, a "run ABC" phase which actually runs ABC, and an "extract" phase which processes the results of an ABC run to create fresh cells in the module. Everything happens on the main thread other than the "run ABC" phases. For parallelism, we create a set of worker threads which pull work from a concurrent queue fed by the main thread.
> 
> To simplify things and also provide a small performance boost, the writing of \`lutdefs.txt\` and \`stdcells.genlib\` is factored out so it happens just once per pass instead of once per ABC run.
> 
> Writing thread-safe code in C++ is very scary, especially in a large existing project like Yosys not designed for multithreading. Fortunately the "run ABC" phase is not large and mostly self-contained so the risk of this PR may be acceptable.
> 
> One thread safety problem I had to tackle was logging. \`Yosys::log()\` is not thread-safe and making it thread-safe would be very invasive. The obvious approach of putting locks around everything would slow down the single-threaded case and not scale well for parallel threads, plus the desired behavior of some of the logging functions w.r.t. concurrent logging calls is not clear. So I've created a \`DeferredLogs\` class which exposes a \`log()\` function which simply captures the logs for a particular work item into a buffer. Eventually, back on the main thread, those deferred logs are printed via the standard \`log()\` function. If log timing is enabled then the timestamps are not meaningful; we can fix that by extending the logging API so callers can pass in previously captured timestamps, but I'd prefer to do that after my logging PR #5243 has been merged.
> 
> \_If applicable, please suggest to reviewers how they can test the change.\_
> 
> The existing Yosys test suite exercises this code fairly well. If we take this PR and especially if we carry on down the road of adding more parallelism, it would be good to run the Yosys test suite with TSAN regularly.

Script passes are just one possible way to build a decent level of abstraction and if that clashes with parallelization we’ll bake the parallel part of what is currently the script pass into a single pass. Passes are just functions that take a `Design*` and allow for taking a design snapshot conveniently. Having things split into lots of passes is great for allowing users to build super custom flows without touching C++. By the time people are sequencing abc-related passes themselves, they’re hopefully fine hacking at basic C++
