AQFP buffer insertion and verification¶
Header: mockturtle/algorithms/aqfp/buffer_insertion.hpp
Technology assumptions¶
-
struct mockturtle::aqfp_assumptions¶
AQFP technology assumptions.
POs count toward the fanout sizes and always have to be branched. If PIs need to be balanced, then they must also need to be branched.
Public Members
-
bool branch_pis = {false}¶
Whether PIs need to be branched with splitters.
-
bool balance_pis = {false}¶
Whether PIs need to be path-balanced.
-
bool balance_pos = {true}¶
Whether POs need to be path-balanced.
-
uint32_t splitter_capacity = {3u}¶
The maximum number of fanouts each splitter (buffer) can have.
-
bool branch_pis = {false}¶
Buffer insertion algorithms¶
-
template<typename Ntk>
class mockturtle::buffer_insertion¶ Insert buffers and splitters for the AQFP technology.
In the AQFP technology, (1) logic gates can only have one fanout. If more than one fanout is needed, a splitter has to be inserted in between, which also takes one clocking phase (counted towards the network depth). (2) All fanins of a logic gate have to arrive at the same time (be at the same level). If one fanin path is shorter, buffers have to be inserted to balance it. Buffers and splitters are essentially the same component in this technology.
With a given level assignment to all gates in the network, the minimum number of buffers needed is determined. This class implements algorithms to count such “irredundant buffers” and to insert them to obtain a buffered network. Moreover, as buffer optimization is essentially a problem of obtaining a good level assignment, this class also implements algorithms to obtain an initial, legal assignment using scheduling algorithms and to further adjust and optimize it.
This class provides two easy-to-use top-level functions which wrap all the above steps together:
run
anddry_run
. In addition, the following interfaces are kept for more fine-grained usage:Query the current level assignment (
level
,depth
)Count irredundant buffers based on the current level assignment (
count_buffers
,num_buffers
)Optimize buffer count by scheduling (
schedule
,ASAP
,ALAP
) and by adjusting the level assignment with chunked movement (optimize
)Dump the resulting network into a network type which provides representation for buffers (
dump_buffered_network
)
Example
mig_network mig = ... buffer_insertion_params ps; ps.assume.branch_pis = true; ps.assume.balance_pis = false; ps.assume.balance_pos = true; ps.assume.splitter_capacity = 3u; ps.scheduling = buffer_insertion_params::ALAP; ps.optimization_effort = buffer_insertion_params::one_pass; buffer_insertion buffering( mig, ps ); buffered_mig_network buffered_mig; auto const num_buffers = buffering.run( buffered_mig ); std::cout << num_buffers << std::endl; assert( verify_aqfp_buffer( buffered_mig, ps.assume ) ); write_verilog( buffered_mig, "buffered.v" );
Required network functions:
foreach_node
foreach_gate
foreach_pi
foreach_po
foreach_fanin
is_pi
is_constant
get_node
fanout_size
size
set_visited
set_value
Public Functions
-
template<class BufNtk>
inline uint32_t run(BufNtk &bufntk, node_map<uint32_t, Ntk> *pLevels = nullptr)¶ Insert buffers and obtain a buffered network.
- Parameters
bufntk – An empty network of an appropriate buffered network type to to store the buffer-insertion result
pLevels – A pointer to a node map which will store the resulting level assignment
- Returns
The number of buffers in the resulting network
-
inline uint32_t dry_run(node_map<uint32_t, Ntk> *pLevels = nullptr)¶
Count the number of buffers without dumping the result into a buffered network.
This function saves some runtime for dumping the resulting network and allows users to experiment on the algorithms with new network types whose corresponding buffered_network are not implemented yet.
- Parameters
pLevels – A pointer to a node map which will store the resulting level assignment
- Returns
The number of buffers in the resulting network
-
inline uint32_t level(node const &n) const¶
Level of node
n
considering buffer/splitter insertion.
-
inline uint32_t depth() const¶
Network depth considering AQFP buffers/splitters.
Note that when neither PIs nor POs are balanced, there can be different schedulings for the same buffered network (i.e. having the same number of buffers), thus this number may be different from the depth obtained by dumping the buffered network and wrapping depth_view around it.
-
inline uint32_t num_buffers() const¶
The total number of buffers in the network under the current level assignment.
-
inline uint32_t num_buffers(node const &n) const¶
The number of buffers between
n
and all of its fanouts under the current level assignment.
-
inline void count_buffers()¶
Count the number of buffers needed at the fanout of each gate according to the current level assignment.
This function must be called after level (re-)assignment and before querying
num_buffers
.
-
inline void schedule()¶
Obtain the initial level assignment using the specified scheduling policy.
-
inline void ASAP()¶
ASAP scheduling.
-
inline void ALAP()¶
ALAP scheduling.
ALAP should follow right after ASAP (i.e., initialization) without other optimization in between.
-
template<class BufNtk>
inline void dump_buffered_network(BufNtk &bufntk) const¶ Dump buffered network.
After level assignment, (optimization), and buffer counting, this method can be called to dump the resulting buffered network.
-
inline void optimize()¶
Optimize with chunked movement using the specified optimization policy.
For more information, please refer to [1].
[1] Irredundant Buffer and Splitter Insertion and Scheduling-Based Optimization for AQFP Circuits. Siang-Yun Lee et. al. IWLS 2021.
Parameters¶
-
struct mockturtle::buffer_insertion_params¶
Parameters for (AQFP) buffer insertion.
Public Types
-
enum [anonymous]¶
The scheduling strategy to get the initial depth assignment.
provided
= An initial level assignment is given in the constructor, thus no scheduling is performed. It is the user’s responsibility to ensure that the provided assignment is legal.ASAP
= Classical As-Soon-As-Possible schedulingALAP
= ASAP (to obtain depth) followed by As-Late-As-Possible schedulingbetter
= ASAP followed by ALAP, then count buffers for both assignments and choose the better one
Values:
-
enumerator provided¶
-
enumerator ASAP¶
-
enumerator ALAP¶
-
enumerator better¶
-
enum [anonymous]¶
The level of optimization effort.
none
= No optimizationone_pass
= Try to form a chunk starting from each gate, once for all gatesuntil_sat
= Iterate over all gates until no more beneficial chunk movement can be foundoptimal
= Use an SMT solver to find the global optimal
Values:
-
enumerator none¶
-
enumerator one_pass¶
-
enumerator until_sat¶
-
enumerator optimal¶
Public Members
-
aqfp_assumptions assume¶
Technology assumptions.
-
enum mockturtle::buffer_insertion_params::[anonymous] scheduling = ASAP¶
The scheduling strategy to get the initial depth assignment.
provided
= An initial level assignment is given in the constructor, thus no scheduling is performed. It is the user’s responsibility to ensure that the provided assignment is legal.ASAP
= Classical As-Soon-As-Possible schedulingALAP
= ASAP (to obtain depth) followed by As-Late-As-Possible schedulingbetter
= ASAP followed by ALAP, then count buffers for both assignments and choose the better one
-
enum mockturtle::buffer_insertion_params::[anonymous] optimization_effort = none¶
The level of optimization effort.
none
= No optimizationone_pass
= Try to form a chunk starting from each gate, once for all gatesuntil_sat
= Iterate over all gates until no more beneficial chunk movement can be foundoptimal
= Use an SMT solver to find the global optimal
-
uint32_t max_chunk_size = {100u}¶
The maximum size of a chunk.
-
enum [anonymous]¶
Buffered network data structure¶
Header: mockturtle/networks/buffered.hpp
Two buffered network types are implemented: buffered_aig_network and buffered_mig_network. They inherit from aig_network and mig_network, respectively, and are supplemented with representations for buffers.
Verification of buffered networks¶
Header: mockturtle/algorithms/aqfp/buffer_verification.hpp
-
template<class Ntk>
bool mockturtle::verify_aqfp_buffer(Ntk const &ntk, aqfp_assumptions const &ps)¶ Verify a buffered network according to AQFP assumptions.
- Parameters
ntk – Buffered network
ps – AQFP constraints
- Returns
Whether
ntk
is path-balanced and properly-branched
-
template<class Ntk>
node_map<uint32_t, Ntk> mockturtle::schedule_buffered_network(Ntk const &ntk, aqfp_assumptions const &ps)¶ Find a reasonable level assignment for a buffered network.
- Parameters
ntk – Buffered network
ps – AQFP constraints
- Returns
Level assignment to all nodes
-
template<class Ntk>
bool mockturtle::verify_aqfp_buffer(Ntk const &ntk, aqfp_assumptions const &ps, node_map<uint32_t, Ntk> const &levels)¶ Verify a buffered network according to AQFP assumptions with provided level assignment.
- Parameters
ntk – Buffered network
ps – AQFP constraints
levels – Level assignment for all nodes
- Returns
Whether
ntk
is path-balanced and properly-branched
Simulation of buffered networks¶
Header: mockturtle/algorithms/simulation.hpp
-
template<uint32_t NumPIs, class Ntk>
std::vector<kitty::static_truth_table<NumPIs>> mockturtle::simulate_buffered(Ntk const &ntk)¶ Simulates a buffered network.
The implementation is only slightly different from
simulate
by replacingforeach_gate
withforeach_node
and checkingfanin_size
because buffers are not counted as gates but still need to be simulated.