CIRCT 23.0.0git
Loading...
Searching...
No Matches
TruthTable.h
Go to the documentation of this file.
1//===----------------------------------------------------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8//
9// This header file defines truth table utilities.
10//
11//===----------------------------------------------------------------------===//
12
13#ifndef CIRCT_SUPPORT_TRUTHTABLE_H
14#define CIRCT_SUPPORT_TRUTHTABLE_H
15
16#include "circt/Support/LLVM.h"
17#include "llvm/ADT/APInt.h"
18#include "llvm/ADT/ArrayRef.h"
19#include "llvm/ADT/SmallVector.h"
20#include "llvm/Support/raw_ostream.h"
21#include <array>
22#include <cstdint>
23
24namespace circt {
25
26/// Represents a boolean function as a truth table.
27///
28/// A truth table stores the output values for all possible input combinations
29/// of a boolean function. For a function with n inputs and m outputs, the
30/// truth table contains 2^n entries, each with m output bits.
31///
32/// Example: For a 2-input AND gate:
33/// - Input 00 -> Output 0
34/// - Input 01 -> Output 0
35/// - Input 10 -> Output 0
36/// - Input 11 -> Output 1
37/// This would be stored as the bit pattern 0001 in the truth table.
38///
39/// TODO: Rename this to MultiOutputTruthTable since for single-output functions
40/// we can just use llvm::APInt directly.
42 unsigned numInputs; ///< Number of inputs for this boolean function
43 unsigned numOutputs; ///< Number of outputs for this boolean function
44 llvm::APInt table; ///< Truth table data as a packed bit vector
45
46 /// Default constructor creates an empty truth table.
48
49 /// Constructor for a truth table with given dimensions and evaluation data.
51 const llvm::APInt &table)
53 assert(table.getBitWidth() == (1u << numInputs) * numOutputs &&
54 "Truth table size mismatch");
55 }
56
57 /// Constructor for a truth table with given dimensions, initialized to zero.
61
62 /// Get the output value for a given input combination.
63 llvm::APInt getOutput(const llvm::APInt &input) const;
64
65 /// Set the output value for a given input combination.
66 void setOutput(const llvm::APInt &input, const llvm::APInt &output);
67
68 /// Apply input permutation to create a new truth table.
69 /// This reorders the input variables according to the given permutation.
70 BinaryTruthTable applyPermutation(ArrayRef<unsigned> permutation) const;
71
72 /// Apply input negation to create a new truth table.
73 /// This negates selected input variables based on the mask.
74 BinaryTruthTable applyInputNegation(unsigned mask) const;
75
76 /// Apply output negation to create a new truth table.
77 /// This negates selected output variables based on the mask.
78 BinaryTruthTable applyOutputNegation(unsigned negation) const;
79
80 /// Check if this truth table is lexicographically smaller than another.
81 /// Used for canonical ordering of truth tables.
82 bool isLexicographicallySmaller(const BinaryTruthTable &other) const;
83
84 /// Equality comparison for truth tables.
85 bool operator==(const BinaryTruthTable &other) const;
86
87 /// Debug dump method for truth tables.
88 void dump(llvm::raw_ostream &os = llvm::errs()) const;
89};
90
91/// Represents the canonical form of a boolean function under NPN equivalence.
92///
93/// NPN (Negation-Permutation-Negation) equivalence considers two boolean
94/// functions equivalent if one can be obtained from the other by:
95/// 1. Negating some inputs (pre-negation)
96/// 2. Permuting the inputs
97/// 3. Negating some outputs (post-negation)
98///
99/// Example: The function ab+c is NPN equivalent to !a + b(!c) since we can
100/// transform the first function into the second by negating inputs 'a' and 'c',
101/// then reordering the inputs appropriately.
102///
103/// This canonical form is used to efficiently match cuts against library
104/// patterns, as functions in the same NPN class can be implemented by the
105/// same circuit with appropriate input/output inversions.
106struct NPNClass {
107 BinaryTruthTable truthTable; ///< Canonical truth table
108 llvm::SmallVector<unsigned> inputPermutation; ///< Input permutation applied
109 unsigned inputNegation = 0; ///< Input negation mask
110 unsigned outputNegation = 0; ///< Output negation mask
111
112 /// Default constructor creates an empty NPN class.
113 NPNClass() = default;
114
115 /// Constructor from a truth table.
117
118 NPNClass(const BinaryTruthTable &tt, llvm::SmallVector<unsigned> inputPerm,
119 unsigned inputNeg, unsigned outputNeg)
120 : truthTable(tt), inputPermutation(std::move(inputPerm)),
121 inputNegation(inputNeg), outputNegation(outputNeg) {}
122
123 /// Compute the canonical NPN form for a given truth table.
124 ///
125 /// This method exhaustively tries all possible input permutations and
126 /// negations to find the lexicographically smallest canonical form.
127 ///
128 /// FIXME: Currently we are using exact canonicalization which doesn't scale
129 /// well. For larger truth tables, semi-canonical forms should be used
130 /// instead.
132
133 /// Get input permutation from this NPN class to another equivalent NPN class.
134 ///
135 /// When two NPN classes are equivalent, they may have different input
136 /// permutations. This function computes a permutation that allows
137 /// transforming input indices from the target NPN class to input indices of
138 /// this NPN class.
139 ///
140 /// Returns a permutation vector where result[i] gives the input index in this
141 /// NPN class that corresponds to input i in the target NPN class.
142 ///
143 /// Example: If this has permutation [2,0,1] and target has [1,2,0],
144 /// the mapping allows connecting target inputs to this inputs correctly.
145 void getInputPermutation(const NPNClass &targetNPN,
146 llvm::SmallVectorImpl<unsigned> &permutation) const;
147
148 /// Equality comparison for NPN classes.
149 bool equivalentOtherThanPermutation(const NPNClass &other) const {
150 return truthTable == other.truthTable &&
151 inputNegation == other.inputNegation &&
153 }
154
155 bool isLexicographicallySmaller(const NPNClass &other) const {
156 if (truthTable.table != other.truthTable.table)
158 if (inputNegation != other.inputNegation)
159 return inputNegation < other.inputNegation;
160 return outputNegation < other.outputNegation;
161 }
162
163 /// Debug dump method for NPN classes.
164 void dump(llvm::raw_ostream &os = llvm::errs()) const;
165};
166
167/// Precomputed NPN canonicalization table for 4-input single-output functions.
168class NPNTable {
169public:
170 NPNTable();
171
172 /// Returns false if the given truth table shape is unsupported.
173 bool lookup(const BinaryTruthTable &tt, NPNClass &result) const;
174
175private:
176 struct Entry4 {
177 uint16_t representative = 0;
178 std::array<uint8_t, 4> inputPermutation = {};
179 uint8_t inputNegation = 0;
180 bool outputNegation = false;
181 };
182
183 std::array<Entry4, 1u << 16> entries4;
184};
185
186/// Collect all canonical 4-input single-output NPN representatives in
187/// ascending truth-table order.
189 llvm::SmallVectorImpl<uint16_t> &representatives);
190
191//===----------------------------------------------------------------------===//
192// Truth Table Utilities
193//===----------------------------------------------------------------------===//
194
195/// Create a mask for a variable in the truth table.
196///
197/// This function generates a bitmask that identifies which minterms have a
198/// particular value for a given variable in a truth table representation.
199///
200/// For positive=true: mask has 1s where var=1 in the truth table encoding
201/// For positive=false: mask has 1s where var=0 in the truth table encoding
202///
203/// For example, with 3 variables (a,b,c) where c is LSB:
204/// - createVarMask(3, 0, true) creates mask for c=1: 0b10101010
205/// - createVarMask(3, 1, true) creates mask for b=1: 0b11001100
206/// - createVarMask(3, 2, true) creates mask for a=1: 0b11110000
207///
208/// Parameters:
209/// numVars: Number of variables in the truth table
210/// var: Variable index (0 = LSB)
211/// positive: true for var=1 mask, false for var=0 mask
212///
213/// Returns: APInt mask with numBits = 2^numVars
214llvm::APInt createVarMask(unsigned numVars, unsigned varIndex, bool positive);
215
216namespace detail {
217/// Expand a truth table to a larger input space using the given input mapping.
218/// `inputMapping[i]` gives the destination input position for original input
219/// `i`.
220llvm::APInt expandTruthTableToInputSpace(const llvm::APInt &tt,
221 ArrayRef<unsigned> inputMapping,
222 unsigned numExpandedInputs);
223} // namespace detail
224
225/// Compute cofactor of a Boolean function for a given variable.
226///
227/// A cofactor of a function f with respect to variable x is the function
228/// obtained by fixing x to a constant value:
229/// - Negative cofactor f|x=0 : f with variable x set to 0
230/// - Positive cofactor f|x=1 : f with variable x set to 1
231///
232/// Cofactors are fundamental in Boolean function decomposition and the
233/// Shannon expansion: f = x'*f|x=0 + x*f|x=1
234///
235/// In truth table representation, cofactors are computed by selecting the
236/// subset of minterms where the variable has the specified value, then
237/// replicating that pattern across the full truth table width.
238///
239/// This function returns a pair of cofactors (negative, positive) for the
240/// specified variable index.
241std::pair<llvm::APInt, llvm::APInt>
242computeCofactors(const llvm::APInt &f, unsigned numVars, unsigned varIndex);
243
244//===----------------------------------------------------------------------===//
245// ISOP (Irredundant Sum-of-Products) Utilities
246//===----------------------------------------------------------------------===//
247
248/// Represents a product term (cube) in a sum-of-products expression.
249/// Each cube is a conjunction of literals (variables or their negations).
250/// Assumes number of variables is less than 64.
251struct Cube {
252 /// Bitmask indicating which variables appear in this cube
253 uint64_t mask = 0;
254 /// Bitmask indicating which variables are negated
255 uint64_t inverted = 0;
256
257 Cube() = default;
258
259 /// Get number of literals in this cube
260 unsigned size() const { return llvm::popcount(mask); }
261
262 /// Has literal for variable at index varIndex
263 inline bool hasLiteral(unsigned varIndex) const {
264 return mask & (1ULL << varIndex);
265 }
266
267 inline void setLiteral(unsigned varIndex, bool isInverted) {
268 uint64_t varMask = 1ULL << varIndex;
269 mask |= varMask;
270 if (isInverted)
271 inverted |= varMask;
272 }
273 inline void removeLiteral(unsigned varIndex) {
274 uint64_t varMask = 1ULL << varIndex;
275 mask &= ~varMask;
276 inverted &= ~varMask;
277 }
278
279 inline bool isLiteralInverted(unsigned varIndex) const {
280 return inverted & (1ULL << varIndex);
281 }
282};
283
284/// Represents a sum-of-products expression.
285struct SOPForm {
286 llvm::SmallVector<Cube> cubes;
287 unsigned numVars;
288
290
291 /// Compute the truth table represented by this SOP form
292 llvm::APInt computeTruthTable() const;
293
294#ifndef NDEBUG
295 /// Debug dump method for SOP forms
296 void dump(llvm::raw_ostream &os = llvm::errs()) const;
297#endif
298};
299
300/// Extract ISOP (Irredundant Sum-of-Products) from a truth table.
301///
302/// Computes an ISOP cover for a Boolean function using the Minato-Morreale
303/// algorithm. An ISOP is a sum-of-products where:
304/// 1. No cube can be removed without changing the function
305/// 2. The cubes are pairwise disjoint (no minterm is covered by multiple
306/// cubes)
307///
308/// Parameters:
309/// truthTable: Single-output truth table represented as APInt
310/// numVars: Number of variables (truthTable must have 2^numVars bits)
311///
312/// Returns: SOPForm representing the ISOP cover
313SOPForm extractISOP(const llvm::APInt &truthTable, unsigned numVars);
314
315} // namespace circt
316
317#endif // CIRCT_SUPPORT_TRUTHTABLE_H
assert(baseType &&"element must be base type")
Precomputed NPN canonicalization table for 4-input single-output functions.
Definition TruthTable.h:168
std::array< Entry4, 1u<< 16 > entries4
Definition TruthTable.h:183
bool lookup(const BinaryTruthTable &tt, NPNClass &result) const
Returns false if the given truth table shape is unsupported.
llvm::APInt expandTruthTableToInputSpace(const llvm::APInt &tt, ArrayRef< unsigned > inputMapping, unsigned numExpandedInputs)
Expand a truth table to a larger input space using the given input mapping.
The InstanceGraph op interface, see InstanceGraphInterface.td for more details.
SOPForm extractISOP(const llvm::APInt &truthTable, unsigned numVars)
Extract ISOP (Irredundant Sum-of-Products) from a truth table.
std::pair< llvm::APInt, llvm::APInt > computeCofactors(const llvm::APInt &f, unsigned numVars, unsigned varIndex)
Compute cofactor of a Boolean function for a given variable.
llvm::APInt createVarMask(unsigned numVars, unsigned varIndex, bool positive)
Create a mask for a variable in the truth table.
void collectCanonicalNPN4Representatives(llvm::SmallVectorImpl< uint16_t > &representatives)
Collect all canonical 4-input single-output NPN representatives in ascending truth-table order.
Represents a boolean function as a truth table.
Definition TruthTable.h:41
BinaryTruthTable()
Default constructor creates an empty truth table.
Definition TruthTable.h:47
BinaryTruthTable(unsigned numInputs, unsigned numOutputs)
Constructor for a truth table with given dimensions, initialized to zero.
Definition TruthTable.h:58
BinaryTruthTable applyOutputNegation(unsigned negation) const
Apply output negation to create a new truth table.
llvm::APInt table
Truth table data as a packed bit vector.
Definition TruthTable.h:44
BinaryTruthTable applyInputNegation(unsigned mask) const
Apply input negation to create a new truth table.
unsigned numInputs
Number of inputs for this boolean function.
Definition TruthTable.h:42
BinaryTruthTable(unsigned numInputs, unsigned numOutputs, const llvm::APInt &table)
Constructor for a truth table with given dimensions and evaluation data.
Definition TruthTable.h:50
void dump(llvm::raw_ostream &os=llvm::errs()) const
Debug dump method for truth tables.
bool isLexicographicallySmaller(const BinaryTruthTable &other) const
Check if this truth table is lexicographically smaller than another.
bool operator==(const BinaryTruthTable &other) const
Equality comparison for truth tables.
llvm::APInt getOutput(const llvm::APInt &input) const
Get the output value for a given input combination.
BinaryTruthTable applyPermutation(ArrayRef< unsigned > permutation) const
Apply input permutation to create a new truth table.
void setOutput(const llvm::APInt &input, const llvm::APInt &output)
Set the output value for a given input combination.
unsigned numOutputs
Number of outputs for this boolean function.
Definition TruthTable.h:43
Represents a product term (cube) in a sum-of-products expression.
Definition TruthTable.h:251
Cube()=default
bool hasLiteral(unsigned varIndex) const
Has literal for variable at index varIndex.
Definition TruthTable.h:263
unsigned size() const
Get number of literals in this cube.
Definition TruthTable.h:260
void removeLiteral(unsigned varIndex)
Definition TruthTable.h:273
uint64_t inverted
Bitmask indicating which variables are negated.
Definition TruthTable.h:255
bool isLiteralInverted(unsigned varIndex) const
Definition TruthTable.h:279
void setLiteral(unsigned varIndex, bool isInverted)
Definition TruthTable.h:267
uint64_t mask
Bitmask indicating which variables appear in this cube.
Definition TruthTable.h:253
Represents the canonical form of a boolean function under NPN equivalence.
Definition TruthTable.h:106
NPNClass(const BinaryTruthTable &tt)
Constructor from a truth table.
Definition TruthTable.h:116
unsigned outputNegation
Output negation mask.
Definition TruthTable.h:110
static NPNClass computeNPNCanonicalForm(const BinaryTruthTable &tt)
Compute the canonical NPN form for a given truth table.
void getInputPermutation(const NPNClass &targetNPN, llvm::SmallVectorImpl< unsigned > &permutation) const
Get input permutation from this NPN class to another equivalent NPN class.
BinaryTruthTable truthTable
Canonical truth table.
Definition TruthTable.h:107
void dump(llvm::raw_ostream &os=llvm::errs()) const
Debug dump method for NPN classes.
NPNClass()=default
Default constructor creates an empty NPN class.
bool equivalentOtherThanPermutation(const NPNClass &other) const
Equality comparison for NPN classes.
Definition TruthTable.h:149
llvm::SmallVector< unsigned > inputPermutation
Input permutation applied.
Definition TruthTable.h:108
unsigned inputNegation
Input negation mask.
Definition TruthTable.h:109
bool isLexicographicallySmaller(const NPNClass &other) const
Definition TruthTable.h:155
NPNClass(const BinaryTruthTable &tt, llvm::SmallVector< unsigned > inputPerm, unsigned inputNeg, unsigned outputNeg)
Definition TruthTable.h:118
std::array< uint8_t, 4 > inputPermutation
Definition TruthTable.h:178
Represents a sum-of-products expression.
Definition TruthTable.h:285
unsigned numVars
Definition TruthTable.h:287
void dump(llvm::raw_ostream &os=llvm::errs()) const
Debug dump method for SOP forms.
llvm::SmallVector< Cube > cubes
Definition TruthTable.h:286
llvm::APInt computeTruthTable() const
Compute the truth table represented by this SOP form.
SOPForm(unsigned numVars)
Definition TruthTable.h:289