Compare commits

...

1075 Commits

Author SHA1 Message Date
Miodrag Milanovic a51bf4a7bb WASI fix 2026-08-18 11:37:14 +02:00
Miodrag Milanovic 89b0b366a2 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-08-18 08:18:49 +02:00
alanminko 5ea3464324
Merge pull request #535 from aiquoc/experiment-x-aware-equivalence-checking
Experiment x aware equivalence checking
2026-08-17 15:21:07 +09:00
Alan Mishchenko 324081b6a4 Update word-level data-structure 2026-08-16 23:13:47 -07:00
alanminko 371e53f93e
Merge pull request #545 from fxreichl/master
Fix a bug that can arise when reducing circuit depth.
2026-08-16 01:50:28 +09:00
alanminko 89bef47d8d
Merge pull request #543 from marcelwa/cec-verdict-const0
&cec -x/-y: is the AND-free check meant to be sufficient for equivalence?
2026-08-16 01:49:49 +09:00
alanminko fe862d3647
Merge pull request #541 from marcelwa/acd-local-extend-shift-ub
ACD: 64-bit shift by 64 or more in local_extend_to
2026-08-16 01:48:58 +09:00
alanminko 1d28820170
Merge pull request #540 from marcelwa/lpk-mux-split-support-guard
lutpack: assertion failure in Lpk_MuxSplit from an approximate cofactor support
2026-08-16 01:48:22 +09:00
alanminko 25b0e5399c
Merge pull request #539 from marcelwa/acd-uninit-bestperm
acd: uninitialised read of bestPerm in enumerate_iset_combinations
2026-08-16 01:47:52 +09:00
alanminko a954df2892
Merge pull request #538 from marcelwa/fraig-store-restore-pi-order
fraig_store: restore the PI order when the name comparison fails
2026-08-16 01:46:54 +09:00
Alan Mishchenko 094c1ca741 Fix windows build 2026-08-15 09:35:04 -07:00
Alan Mishchenko 12eb48b476 Add experimental word-level data-structure 2026-08-15 09:23:19 -07:00
Alan Mishchenko d389f88285 Remove obsolete ACB command interface 2026-08-15 09:18:47 -07:00
Franz Reichl ebd3e31a8d Fix a bug that can arise when reducing circuit depth. 2026-08-13 12:57:15 +02:00
Miodrag Milanovic 0bd9c3ea60 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-08-12 13:22:30 +02:00
Alan Mishchenko e4383a8d67 Remove BAC and CBA from Windows project 2026-08-11 20:30:25 -07:00
Alan Mishchenko e69c02c3f2 Remove legacy BAC and CBA packages 2026-08-11 20:15:35 -07:00
Marcel Walter d4e3670e21
&cec -x/-y, &icec: also require the swept miter outputs to be constant 0
The equivalence verdict in these three branches is taken from
Gia_ManAndNum(pNew) == 0 after Cec4_/Cec5_ManSimulateTest3. An AND-free GIA can
still have outputs that are constant 1 or CI literals, which are satisfiable, so
this reports "Networks are equivalent" for some non-equivalent pairs -- for
example `a & b` against `~(a & b)`, where the miter sweeps to constant 1.

Check the outputs as well: AND nodes remaining -> UNDECIDED as before; AND-free
with all outputs constant 0 -> equivalent as before; AND-free otherwise -> NOT
equivalent, which is decidable by inspection since such a miter is satisfiable.
2026-08-11 19:22:06 +02:00
Alan Mishchenko 6c51a92385 Adding an option t0 &cec against a truth table. 2026-08-08 17:29:15 -07:00
agentic-synthesis 5cbfa76dc3
lutpack: do not trust an approximate cofactor support in the MUX split
`lutpack` aborts on some networks with

  abc: src/opt/lpk/lpkAbcMux.c:192: Lpk_MuxSplit:
       Assertion `iVarVac < (int)p->nVars' failed.

Reproducer (a 24.7k-LUT `sqrt` netlist produced by `if -K 10 -Z 6`, ~10 s):

  read_blif sqrt-mapped.blif; lutpack

Lpk_MuxSplit() splits one component off a function and stores the new component
in a *vacant* fanin slot of the retained one:

  p->uSupp  = Kit_TruthSupport( Pol ? pTruth1 : pTruth0, p->nVars );
  p->uSupp |= (1 << Var);
  iVarVac   = Kit_WordFindFirstBit( ~p->uSupp );
  assert( iVarVac < (int)p->nVars );

A vacant slot is supposed to be guaranteed by Lpk_MuxAnalize(), which rejects a
candidate variable when

  nSuppSizeL = max(nSuppSize0 + 2*!Polarity, nSuppSize1 + 2*Polarity) > p->nVars

but it reads nSuppSize0/nSuppSize1 out of the *cached* p->puSupps[].  When those
came from Lpk_ComputeSupports() they are not exact: that routine builds two
BDDs of the function in opposite variable orders and stitches the two support
estimates together at the cofactoring variable, and the result can be a strict
subset of the true cofactor support.  Lpk_MuxAnalize() then admits a variable
whose split needs one slot more than the function has.

On the reproducer this happens for a 12-variable component at Var = 3,
Polarity = 1: the cached support of cofactor 1 is 0x3f7 (9 variables) while the
truth table's is 0xff7 (11).  The guard sees 9 + 2 = 11 <= 12 and accepts;
the split then produces uSupp = 0xff7 | (1 << 3) = 0xfff, which is full.

Instrumenting the same run shows the estimate differs from the exact support in
484 of 101970 cofactor supports, and is narrower in 352 of them, so this is not
a one-off.

Rather than change the support estimator or weaken the assertion -- which
documents a real invariant of Lpk_MuxSplit() -- re-derive the single support the
split depends on, once the candidate has been chosen, and decline the MUX
decomposition when it does not fit.  That is one cofactor and one support scan
per accepted candidate, not per candidate variable.  On the reproducer lutpack
then completes and yields the same result as recomputing every cached support
from the truth table (24694 -> 24635 nodes, 237 levels in both cases).
2026-08-08 10:21:19 +02:00
agentic-synthesis 0f5951ab2c
ACD: avoid a 64-bit shift by 64 or more in local_extend_to
ac_decomposition_impl::local_extend_to() replicates a truth table that really
depends on `real_num_vars` variables across the full `num_vars`-variable static
truth table.  For real_num_vars < 6 it does so by folding the first word:

    for ( auto i = real_num_vars; i < num_vars; ++i )
      mask |= ( mask << ( 1 << i ) );

Once i reaches 6 the shift distance is 1 << 6 == 64, which is at least the width
of the 64-bit operand, so the shift has undefined behaviour.  This is reached
whenever the cut being decomposed has more than six variables, i.e. in every
ordinary use of `if -K k -Z n` with k > 6; UBSan reports

  ac_decomposition.hpp: runtime error: shift exponent 64 is too large for
  64-bit type 'long unsigned int'

on, for example, `read adder.aig; strash; dch -f; if -K 11 -Z 6 -C 12`.

On x86 the shift is taken modulo 64 and the iteration happens to be a no-op, so
the observable behaviour today is correct, but that is not guaranteed by the
language and other targets shift in a saturating or unspecified way.

Variables 6 and above do not need the fold at all: the subsequent
std::fill() over the whole block array already replicates the word across every
block.  Clamp the loop to the variables that live inside one word.  No
behavioural change on x86.
2026-08-08 09:50:02 +02:00
Marcel Walter 4473e39efc
acd: seed bestPerm to avoid an uninitialised read in enumerate_iset_combinations
bestPerm is only written inside the 'cost < best_cost' branch. When no
combination beats the initial best_cost -- which happens for an infeasible
free-set size -- the array is never written, yet the tail of the function still
evaluates permutations[bestPerm[i]]. That reads uninitialised stack and then
uses the value to index permutations[], so it is an out-of-bounds read as well.

Upstream results are unaffected in practice because the caller discards the
permutation on that path, but it is undefined behaviour and it becomes a hard
segfault as soon as the stack layout changes -- adding two members to the
decomposer object was enough to trigger it reliably.

Seeding the identity permutation in the existing initialisation loop is
sufficient and costs nothing.
2026-08-08 08:43:10 +02:00
Marcel Walter 4d504f20ba
fraig_store: restore the PI order when the name comparison fails
Abc_NtkCompareSignals() sorts the PIs, POs and boxes of both networks by name
before comparing them. That is deliberate and is what lets fraig_store accept
two networks that use the same names in a different order.

When the names do not match, though, the comparison fails, Abc_NtkFraigStore()
resets the store and keeps the incoming network -- which by then has already
been sorted. The network that ends up in the store is a permutation of the one
the caller read in, and nothing reports it. The two lines printed on that path
say the store was reset; they do not say the interface changed.

Sorting is by name as a string, so numeric port names are where it shows up
worst: 1, 2, ..., 10 sort as 1, 10, 2, 3, ... With the EPFL cavlc benchmark and
its published reference netlist, whose ports are named "1".."10",

    read_aiger cavlc.aig; strash; fraig_store
    read_blif  cavlc_size.blif; strash; fraig_store
    fraig_restore; write_blif out.blif

gives an out.blif whose inputs are ordered 1, 10, 2, 3, ... instead of
1, 2, 3, ..., 10. It has the right number of inputs and outputs, it passes
Abc_NtkCheck(), and "cec -n out.blif cavlc.aig" reports a counterexample.

Save the three vectors before the comparison and put them back if it fails,
then rebuild vCis/vCos with Abc_NtkOrderCisCos(). The success path is
untouched, and so is every path where the names already agree -- those never
reach Abc_NtkCompareSignals(), since Abc_NodeCompareCiCo() has already
returned 1.
2026-08-07 20:54:11 +02:00
Alan Mishchenko 8e224cd794 Update mapped delay computation. 2026-08-01 15:27:17 -07:00
Miodrag Milanovic 2a9e9c2a00 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-07-30 16:59:55 +02:00
aiquoc 85770ba29d fix build windows 2026-07-29 13:46:44 +08:00
aiquoc 842a265d82 fix error build 2026-07-29 13:46:38 +08:00
aiquoc bd52945300 fix error build 2026-07-29 13:46:33 +08:00
aiquoc 2918589334 experiment X-aware equivalence checking 2026-07-29 13:46:16 +08:00
Alan Mishchenko e76768b9d3 Crtical path detection for AIGs. 2026-07-27 07:10:10 -07:00
alanminko 4e1b34d744
Merge pull request #534 from zxxr1113/scorr2-upstream
new command &scorr2 extended from &scorr
2026-07-27 22:56:46 +09:00
xiran 77cd6f4b04 new command &scorr2 extended from &scorr 2026-07-27 18:43:56 +08:00
Alan Mishchenko c1f9a942ca Add dumping truth tables in the PLA format. 2026-07-25 16:19:26 -07:00
Alan Mishchenko 57ad5cd47b Updating %ysoys to abstract modules/instances. 2026-07-25 16:19:26 -07:00
alanminko 3ed7e4179a
Merge pull request #530 from wjrforcyber/choice_fix
Fix(choices): On pSibls
2026-07-23 07:53:37 +09:00
JingrenWang c130edd5e8
Fix(choices): On pSibls
Signed-off-by: JingrenWang <wjrforcyber@163.com>
2026-07-03 14:47:40 +08:00
Miodrag Milanovic e026ed5380 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-07-02 11:29:04 +02:00
alanminko bcfdf59228
Merge pull request #523 from fxreichl/master
Improve support for -D 3 together with -X
2026-07-02 12:55:08 +07:00
alanminko a082d1ba3a
Merge pull request #524 from YosysHQ/upsteaming
Upsteaming Yosys changes
2026-07-02 12:54:37 +07:00
alanminko 523af52dd4
Merge pull request #525 from wjrforcyber/rand_fix
Fix(rand): UB on different platform
2026-07-02 12:54:21 +07:00
alanminko 0a297ad527
Merge pull request #529 from zxxr1113/scorr-i-pr3-upstream-merge
Add dynamic SRM and incremental simulation into &scorr -i ; Fix a bug of &scorr -i ;
2026-07-02 12:54:03 +07:00
xiran f8faf4379e add dynamic SRM and incremental simulation into -i 2026-07-02 12:45:29 +08:00
Alan Mishchenko a01df4b82c Adding function printout to &put. 2026-07-01 13:44:00 -07:00
JingrenWang f7c7cf0099
Fix(rand): UB on different platform
Signed-off-by: JingrenWang <wjrforcyber@163.com>
2026-07-01 16:23:45 +08:00
Alan Mishchenko b4ca3e7f52 Adding &put -i to preserve special LUT mapping. 2026-06-29 22:51:13 -07:00
Alan Mishchenko 79f1e0b41d Bug fixes. 2026-06-29 16:34:36 -07:00
Miodrag Milanovic a35f806b8c Change to ABC_NO_HISTORY so it is possible to change externally 2026-06-25 14:19:01 +02:00
Miodrag Milanovic 9794114a68 Change to ABC_NO_HISTORY so it is possible to change externally 2026-06-25 14:15:03 +02:00
Miodrag Milanovic b89ccd36bc Fix for case where ABC_USE_PTHREADS is not used 2026-06-25 13:24:00 +02:00
Miodrag Milanovic 0e32819325 Fix WASI and make prototype valid 2026-06-25 13:15:56 +02:00
Petter Reinholdtsen 5100825c51 Only use __int128 on architectures where it is present.
With GCC and Clang, look for the __SIZEOF_INT128__ define only defined
when __int128 is present before trying to use it.

This fixes build problem on all 32 bit Linux architectures.
2026-06-25 13:15:01 +02:00
Miodrag Milanovic 476b31cac5 Merge remote-tracking branch 'upstream' into yosys-experimental 2026-06-25 13:01:49 +02:00
Franz Reichl feaf7a773d Improve support for -D 3 together with -X and fix an issue in the construction of Gias. 2026-06-25 11:28:02 +02:00
alanminko 3ce53c361f
Merge pull request #519 from heshpdx/master
Fix strict aliasing violations
2026-06-25 02:53:37 +07:00
Mahesh Madhav 2eb8f38cd1 Fix build errors and spacing 2026-06-24 14:35:55 -04:00
Alan Mishchenko 7d253d7cb2 Do not support extension "e" (equiv classes of nodes). 2026-06-22 19:35:32 -07:00
alanminko 68bf7cba8e
Merge pull request #521 from fxreichl/master
Fix issue with constant replacements
2026-06-18 20:42:01 +07:00
Franz Reichl 70a92ee63f Fix issue with constant replacements 2026-06-18 14:45:45 +02:00
alanminko 29c59ab009
Merge pull request #508 from mshockwave/patch/fix-vec-int-nSize-reload
misc: Prevent Vec_IntRemove from loading nSize in every iteration
2026-06-16 22:44:11 +07:00
Mahesh Madhav cfd526afd0 Fix strict aliasing violations
The cast to char** is a violation of strict aliasing rules.
Compilers may generate incorrect code due to this issue.
Using memcpy to avoid the issue. Not expecting perf difference.
2026-06-16 15:33:12 +00:00
alanminko 4c08da846a
Merge pull request #511 from wjrforcyber/rd_inv
Feat(rd_inv): Simple inv redis framework.
2026-06-16 22:12:38 +07:00
alanminko d79133b567
Merge pull request #516 from flyingfoxyy/fix-satlut-k5-boundary
giaSatLut: fix &satlut expanding LUT size from K=5 to K=6
2026-06-16 22:11:36 +07:00
alanminko f1d6c364cf
Merge pull request #517 from YosysHQ/cmake_windows
Windows cleanup
2026-06-16 21:57:13 +07:00
Alan Mishchenko 334ae5d1b7 Update .gitingore 2026-06-16 07:53:07 -07:00
Alan Mishchenko 61e74a1033 Update high-effort synthesis. 2026-06-16 07:52:19 -07:00
Alan Mishchenko 2d835aabf0 Adding command "power" to eval static/dynamic power 2026-06-16 07:46:55 -07:00
Alan Mishchenko e00a2fe834 Adding support power info exraction from Liberty 2026-06-16 05:05:05 -07:00
Alan Mishchenko a4b7912895 Adding API to compute switching activity 2026-06-16 04:52:40 -07:00
Miodrag Milanovic 30c47da5c9 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-06-15 19:40:58 +02:00
alanminko 8783dcfd73
Merge pull request #513 from maliberty/update-zlib
Update zlib 1.2.5 to 1.3.2
2026-06-16 00:21:47 +07:00
alanminko f1ec6d32d8
Merge pull request #512 from maliberty/update-bzip2
Update bzip2 from version 1.0.5 to 1.0.8
2026-06-16 00:21:20 +07:00
Matt Liberty cd9d9fcc13 Fix namespace build of zlib gzguts.h on macOS
Move ABC_NAMESPACE_HEADER_START (and the abc_global.h include) before the
non-LFS prototype block so the bare gzFile references in gzopen64/gzseek64/
gztell64/gzoffset64 resolve to the namespaced type. Without this, building
with ABC_USE_NAMESPACE=xxx fails on platforms that compile this block (e.g.
macOS, which does not define _LARGEFILE64_SOURCE):

  gzguts.h: error: unknown type name 'gzFile'; did you mean 'xxx::gzFile'?

Restores the header ordering used in the previous zlib 1.2.5 sources.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
2026-06-15 17:12:13 +00:00
Miodrag Milanovic 1e130338f0 Make sure we detect these errors in future 2026-06-09 08:20:13 +02:00
Miodrag Milanovic 1e85fff18d Cleanup 2026-06-08 16:20:52 +02:00
Miodrag Milanovic 26ca14e4c6 Add missing includes for windows 2026-06-08 16:20:37 +02:00
Miodrag Milanovic d3d218eee2 Cleanup 2026-06-08 16:11:48 +02:00
Miodrag Milanovic b73fcb78ed Add missing includes for windows 2026-06-08 16:11:31 +02:00
Alan Mishchenko 304481b68a Simplify internal AIG reading when %yosys is used. 2026-06-08 18:05:22 +07:00
Miodrag Milanovic 3df13d9aad Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-06-08 12:54:10 +02:00
Alan Mishchenko 59896d6ec8 Another bug fix in delay propagation. 2026-06-08 17:45:17 +07:00
Alan Mishchenko 9749046cd6 Bug fix in required time propagation. 2026-06-08 17:05:54 +07:00
longfei 8149daf921 giaSatLut: fix &satlut expanding LUT size from K=5 to K=6
Sbl_CutIsFeasible only checked LutSize <= 4 before the final
return Count <= 6, allowing 6-input cuts when LutSize=5.
Add the missing LutSize <= 5 check after the 5th bit-strip.
2026-06-06 20:31:57 +08:00
Alan Mishchenko b7ee7a5f70 Fix a windows compile problem. 2026-06-05 16:15:34 +07:00
alanminko cd33ba563f
Merge pull request #514 from maliberty/fix-non-readline-prompt-pipe
mainUtils: match readline behavior when ABC_USE_READLINE is undefined
2026-06-05 16:14:23 +07:00
Matt Liberty 66f5d7c7a2 mainUtils: match readline behavior when ABC_USE_READLINE is undefined
The non-readline branch of Abc_UtilsGetUsersInput has three behavioral
gaps versus the readline branch that break callers driving abc as a
coprocess over a pipe (e.g. yosys's passes/techmap/abc.cc, which spawns
"abc -s" with piped stdin/stdout and uses read_until_abc_done to wait
for "abc NN> <command>" lines):

  1. The prompt is written with fprintf() and never flushed. On a pipe
     stdout is fully buffered, so the prompt never reaches the reader.
     The reader waits for the prompt, abc waits in fgets(), deadlock.

  2. There is no echo of the line read from stdin. readline() emits
     each character to its output stream; yosys's protocol depends on
     seeing "abc NN> source ...\n" in the output to advance state.
     Without an echo it waits forever.

  3. EOF on stdin is silently ignored: fgets() returns NULL but the
     function returns a stale Prompt buffer, causing a tight loop on
     pipe close. The readline branch exit(0)s on NULL.

Fix all three. Echo only when stdin is not a tty -- on a tty the kernel
already echoes typed characters during cooked input, so double-echo
would be visible to interactive users.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
2026-06-05 06:05:32 +00:00
Alan Mishchenko 21b2d8959a Add output name permutation in &cec. 2026-06-04 21:05:04 +07:00
Matt Liberty 749bc49826 Update zlib 1.2.5 to 1.3.2
Fixes many CVEs.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
2026-06-03 06:40:02 +00:00
Matt Liberty 0497d4708a Update bzip2 from version 1.0.5 to 1.0.8
Get the fixes for CVE-2010-0405 & CVE-2019-12900.  I have tried to
preserve the local modifications on top of the base library.

Signed-off-by: Matt Liberty <mliberty@precisioninno.com>
2026-06-02 21:29:57 +00:00
JingrenWang 7b0a6cbb58
Feat(rd_inv): Simple inv redis framework.
Signed-off-by: JingrenWang <wjrforcyber@163.com>
2026-06-01 16:23:38 +08:00
alanminko a917c1af9f
Merge pull request #509 from fxreichl/master
Add option for lut optimisation
2026-05-21 23:44:41 -07:00
Alan Mishchenko cd6e9b582b Modify default intermediate AIGER file name. 2026-05-21 23:41:12 -07:00
Franz Reichl 70c42b7292 Add option for lut optimisation 2026-05-21 11:58:13 +02:00
Min Hsu 9e02a87c1d misc: Prevent Vec_IntRemove from loading nSize in every iteration
This seemly benign loop
```
for ( i++; i < p->nSize; i++ )
  p->pArray[i-1] = p->pArray[i];
```

will actually load `p->nSize` in every loop iteration (rather than
memorizing the value) due to some unfortunate pointer aliasing properties
in C/C++. As Vec_IntRemove is quite ubiquitous, this extra memory load
actually causes visible performance impact and prevents further
optimizations on the loop.

This patch fixes this by factoring `p->nSize` out of the loop.
2026-05-19 14:17:09 -07:00
Alan Mishchenko f4d870e109 Updating interface of "twoexaxct". 2026-05-18 07:31:39 -07:00
Alan Mishchenko ffb0ff63fc Updating interface of %yosys to take multiple Verilog files. 2026-05-18 07:23:18 -07:00
Alan Mishchenko 07e38ef030 Imrpovements in "twoexact". 2026-05-17 18:51:49 -07:00
Alan Mishchenko 7bf1177d39 Add MM-based adder generation to &genadder. 2026-05-15 17:57:45 -07:00
Alan Mishchenko 26567123a7 Fix warnings. 2026-05-15 17:47:46 -07:00
alanminko 2827348459
Merge pull request #507 from Meneya/bmc3c
Added option -c to call CaDiCaL solver inside bmc3 engine (bmc3 -c)
2026-05-15 07:54:43 -07:00
Miodrag Milanovic 5d51a5e420 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-05-12 08:17:36 +02:00
Miodrag Milanovic 3d2af6345c Reapply "Fixing the required time problem."
This reverts commit 98967c9f3a.
2026-05-12 08:15:31 +02:00
Alan Mishchenko c61f1a04e9 Bug fix in handling ufar calls. 2026-05-11 19:27:06 -07:00
alanminko 9d410e8163
Merge pull request #506 from zxxr1113/incremental_scorr_clean
New feature: Add incremental refinement to &scorr command
2026-05-11 14:36:23 -07:00
xiran 97b15a29a0 Fix: fix the build bug in abclib.dsp by registering cecCorrIncr.c 2026-05-11 14:02:23 -07:00
Alan Mishchenko 8c9e66205e Bug fix in &sprove. 2026-05-11 13:49:26 -07:00
Alan Mishchenko 60b3991a0e Assume minimum required times when not given by the user. 2026-05-11 12:18:15 -07:00
Miodrag Milanovic 98967c9f3a Revert "Fixing the required time problem."
This reverts commit 6aaf0db1e1.
2026-05-11 14:35:23 +02:00
xiran d55ae1421c New feature: Add incremental refinement to &scorr command 2026-05-10 22:58:10 -07:00
Alan Mishchenko d54cbda229 Multi-output gate mapper. 2026-05-10 09:52:16 -07:00
Alan Mishchenko cf5da03652 Bug fix. 2026-05-09 19:13:42 -07:00
Alan Mishchenko f3157272ae Initial support of multi-output gates in sizing. 2026-05-08 16:03:24 -07:00
Alan Mishchenko eaa8496b42 Streamlining support for multi-output gates 2026-05-08 00:45:46 -07:00
Petter Reinholdtsen d217b35192 Only use __int128 on architectures where it is present.
With GCC and Clang, look for the __SIZEOF_INT128__ define only defined
when __int128 is present before trying to use it.

This fixes build problem on all 32 bit Linux architectures.
2026-05-05 13:04:37 +02:00
Alan Mishchenko fc4cfc0c35 Extending support for sequential AIGs. 2026-05-04 18:56:14 -07:00
alanminko 84b78d570c
Merge pull request #498 from petterreinholdtsen/mach-only-apple
Corrected #ifdef for mach based Apple builds in cadical_file.cpp.
2026-05-02 21:21:43 -07:00
alanminko 6d9c88d7e8
Merge pull request #499 from petterreinholdtsen/missing-path-max
Provide replacement value for PATH_MAX on platforms without it.
2026-05-02 21:20:38 -07:00
alanminko 298bcee98a
Merge pull request #505 from gigeresk/lutpack_assert_fix
Fix intermittent assert failures in lutpack functions
2026-05-02 21:20:01 -07:00
alanminko 5611ca0bbb
Merge pull request #503 from AdvaySingh1/ISSUE-479
Added fix for write_cnf adding extra clauses on direct PI-PO
2026-05-02 21:19:31 -07:00
alanminko 9ac97c7c4c
Merge pull request #502 from petterreinholdtsen/make-cppflags
Use CPPFLAGS alongside CFLAGS and CXXFLAGS during build.
2026-05-02 21:18:28 -07:00
alanminko ec4faae74a
Merge pull request #501 from petterreinholdtsen/writepla-assert-relaxed
Relaxed assert in Io_WritePla() to avoid failure with too shallow network.
2026-05-02 21:16:35 -07:00
Fred Tombs db8e5d9988 Apply same assert fix to l144 2026-05-02 16:15:00 -04:00
Alan Mishchenko ff00f67063 Updating verilog writer. 2026-05-02 08:22:59 -07:00
Fred Tombs 60e091d993 Replace failing assert in lutpack with non-failing version 2026-05-02 10:09:50 -04:00
Alan Mishchenko d07ce81c91 Bug fixes. 2026-04-30 23:38:51 -07:00
Alan Mishchenko 153d6b7f82 Fix out-of-bound bug in &glucose 2026-04-30 18:04:04 -07:00
Alan Mishchenko b413eb90de Fix windows build. 2026-04-25 22:41:26 -07:00
Alan Mishchenko b2a0cabf29 Updates to &sprove. 2026-04-25 22:32:27 -07:00
Alan Mishchenko c20832627f Extending &sprove interface 2026-04-25 17:45:55 -07:00
Alan Mishchenko 8e6b287674 Improving callbacks in &bmcG 2026-04-25 17:42:06 -07:00
Alan Mishchenko 1056de3239 High memory use fix in &scorr -Z 2026-04-24 18:57:29 -07:00
Advay Singh d74b33eba6 Added fix for write_cnf adding extra clauses on direct PI-PO 2026-04-23 13:09:26 -05:00
Petter Reinholdtsen 817d542c45 Use CPPFLAGS alongside CFLAGS and CXXFLAGS during build.
It is a convention inherited from GNU automake to use CPPFLAGS
for compiler flag intended for the preprocessor, while CFLAGS and
and CXXFLAGS provide flags intended for the C and C++ compiler.
Adjust build rules to include CPPFLAGS ensure any preprocessor
flags in build systems using this environment variable work out of
the box.

This allow Debian builds to pass on hardening flags without modifying
the build setup.

Patch from Ruben Undheim via Debian
2026-04-23 14:54:35 +02:00
Petter Reinholdtsen 2b9920e6a5 Relaxed assert in Io_WritePla() to avoid failure with too shallow network.
Otherwise the abc will refuse to output trivial functions(constant 1 or 0).

The issue was originally submitted to
<URL: https://bitbucket.org/alanmi/abc/issue/27/assertion-failure-in-write_pla-command >,
now available via
<URL: https://web.archive.org/web/20200621081236/https://bitbucket.org/alanmi/abc/issues/27/assertion-failure-in-write_pla-command >.
Sadly the example demonstrated the problem was not archived.

This issue was also reported as <URL: https://bugs.debian.org/780450 >.
2026-04-23 12:55:49 +02:00
Miodrag Milanovic 405511f850 Fix compile error in eSLIM when ABC_USE_PTHREADS is not used 2026-04-22 17:36:33 +02:00
Miodrag Milanovic ada8fb2e87 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-04-22 15:48:14 +02:00
Meneya 5096a78fbe Added option -c to call CaDiCaL solver inside bmc3 engine (bmc3 -c) 2026-04-20 14:53:32 +05:30
Petter Reinholdtsen 1ddb7a2352 Provide replacement value for PATH_MAX on platforms without it.
The buffer length is used in a static array returned from
Extra_FileNameGenericAppend(), used many places in the code, and a
more dynamic approach would require a huge refactoring.  There is no
guarantee that the 4096 value picked is large enough, but it matches
common values found on Linux.
2026-04-19 07:20:30 +02:00
Petter Reinholdtsen fa042e42ed Corrected #ifdef for mach based Apple builds in cadical_file.cpp.
Bring test in line with all other tests for mach based MacOS builds,
and ensure the code in question is not enabled with mach on GNU Hurd.
2026-04-18 10:25:11 +02:00
alanminko 8762d6c667
Merge pull request #496 from zxxr1113/fix-ssw-timing
fix timing inconsistency in calculating the "timeOther" in Ssw_ManPrintStats in sswMan.c
2026-04-14 10:02:22 -07:00
alanminko 2db6ae7848
Merge pull request #497 from fxreichl/master
Extend the eSLIM package
2026-04-14 10:01:59 -07:00
Franz Reichl 0f6ca59029 Extend the eSLIM package 2026-04-14 15:33:57 +02:00
xiran 6a52468604 fix timing inconsistency in calculating other time in Ssw_ManPrintStats in sswMan.c 2026-04-12 14:18:52 -07:00
Alan Mishchenko 8aa7e12dab Adding trace logging to &sprove. 2026-04-11 21:14:19 -07:00
Miodrag Milanovic 180a6adb68 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-04-08 13:28:16 +02:00
Alan Mishchenko 80c8a9a192 Bug fix in %blast. 2026-04-06 20:42:44 -07:00
Alan Mishchenko ca2a410095 Add log dump to %ufar. 2026-04-04 09:04:24 -07:00
Alan Mishchenko cd2998b5c7 Adding name-based input reordering in &cec. 2026-04-03 21:18:41 -07:00
Alan Mishchenko bef23270f8 Improvements to command "history". 2026-03-27 20:09:54 -07:00
Alan Mishchenko b8059c310a Add support for second Verilog files in %ysoys and &cec 2026-03-27 19:24:31 -07:00
Miodrag Milanovic de0ebae1c5 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-03-27 08:39:51 +01:00
Alan Mishchenko 6aaf0db1e1 Fixing the required time problem. 2026-03-25 10:03:26 -07:00
Alan Mishchenko 60e0303e3a Fix a mismatch in cut selection. 2026-03-24 20:16:09 -07:00
Alan Mishchenko 7a28b20d8e Fix windows build. 2026-03-23 17:44:06 -07:00
Alan Mishchenko 3881f2de37 Updated to &sprove. 2026-03-23 17:34:59 -07:00
Alan Mishchenko ceebb2d167 Updated to &sprove. 2026-03-23 14:55:27 -07:00
Alan Mishchenko 24917213df Updates to &if mapper. 2026-03-19 20:18:08 -07:00
Alan Mishchenko ca0fc3ed29 Adding support for Verilog dumping in "lutexact'. 2026-03-19 18:37:32 -07:00
Alan Mishchenko cf5aef3889 Fix compiler problems. 2026-03-10 22:26:43 -07:00
Alan Mishchenko fa5029da95 Updates to &if mapper. 2026-03-10 22:19:37 -07:00
Miodrag Milanovic b4a657e75b Fix WASI and make prototype valid 2026-03-09 13:02:54 +01:00
Miodrag Milanovic 55f552b454 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-03-09 11:32:02 +01:00
Alan Mishchenko 7ae0f4966a Adding gla to sprove. 2026-03-08 12:04:38 -07:00
Alan Mishchenko a745d5ec81 Adding profiling to %ufar. 2026-03-08 10:27:12 -07:00
Alan Mishchenko ba69519d73 Adding command for calling external solvers. 2026-03-08 10:26:27 -07:00
Alan Mishchenko c92cfab80b Adding new line at the end of AIGER files. 2026-03-08 10:25:15 -07:00
alanminko 7553ef9760
Merge pull request #471 from phyzhenli/master
Fix &synch2 crash with creating wrong mapping
2026-03-07 06:54:56 -08:00
alanminko d10a0d41a3
Merge pull request #488 from calewis/grow_faster
Avoid O(n^2) work on gzipped liberty data
2026-03-07 06:49:33 -08:00
Drew Lewis ee40e40d09 Have the buffer grow with a 2x factor to avoid O(n^2) work when reading big files.
Signed-off-by: Drew Lewis <cannada@google.com>
2026-03-02 22:22:27 +00:00
Miodrag Milanovic 8e401543d3 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-02-27 07:54:44 +01:00
Alan Mishchenko f3a17d343a Fixing assertion failure introduced by a recent PR. 2026-02-26 20:08:03 -08:00
Miodrag Milanovic 41c28e541a Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-02-26 09:17:07 +01:00
Alan Mishchenko 4e5c5e62af Compiler problem. 2026-02-25 20:18:28 -08:00
Alan Mishchenko c1937d12ac Improvements to &sprove. 2026-02-25 20:00:57 -08:00
Alan Mishchenko d5c1f2cfe1 Adding callbacks to "scorr" and "&scorr". 2026-02-25 20:00:28 -08:00
Alan Mishchenko ef54c1daea Updating interface of &cec. 2026-02-24 14:59:13 -08:00
alanminko ea6be8a51c
Merge pull request #486 from wjrforcyber/fix_windows_build
Refactor(Workflow): Windows build refactor
2026-02-24 06:45:00 -08:00
Jingren Wang 2b0e38c067
Merge branch 'berkeley-abc:master' into fix_windows_build 2026-02-24 08:44:41 +08:00
JingrenWang ce559b169e
Refactor(Workflow): Windows build refactor
Signed-off-by: JingrenWang <wjrforcyber@163.com>
2026-02-24 08:37:49 +08:00
alanminko e90839fcf1
Merge pull request #484 from wjrforcyber/fix_windows_build
Fix(Windows): Update to windows-2025
2026-02-23 15:51:54 -08:00
JingrenWang ec8b45add3
Fix(Windows): Update to windows-2025
Signed-off-by: JingrenWang <wjrforcyber@163.com>
2026-02-23 15:42:58 +08:00
alanminko 0433d6e327
Merge pull request #482 from jon-greene/fix-req-time-infinity
Fix required time handling for unconstrained POs, infinity arithmetic, and cosmetic problem in absDup.c
2026-02-21 20:51:08 -08:00
Jonathan Greene 3b5036a1e1 Fix required time handling for unconstrained POs, infinity arithmetic, and absDup cosmetic
- Tim_ManInitPoRequiredAll: only overwrite PO required times when ALL are
  unconstrained; preserve user-specified constraints
- Gia_ObjPropagateRequired: propagate infinity unchanged through LUTs
- Tim_ManGetCoRequired: guard against infinity minus delay arithmetic
- Gia_ManDelayTraceLut: handle infinite required times in slack computation;
  allow negative slack to report timing violations
- Tim_ManCreate: fix required-time loading to address actual POs via
  Tim_ManForEachPo instead of p->pCos[] (wrong for designs with boxes)
- Tim_ManGetArrTimes/Tim_ManGetReqTimes: fix loop-exit detection using
  boolean flag instead of comparing iterator index against PO/PI count
- Gia_ManPrintFlopClasses: use Gia_ManRegBoxNum instead of Gia_ManRegNum

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
2026-02-21 16:54:27 -08:00
alanminko 2c6089fff5
Merge pull request #481 from jon-greene/fix-req-time-with-boxes
Fix two bugs causing problems with &trace and boxes.
2026-02-21 07:54:20 -08:00
Jonathan Greene 771e70381c Fix two bugs causing problems with &trace and boxes. 2026-02-20 11:51:16 -08:00
alanminko 8a856ce23f
Merge pull request #480 from jon-greene/fix-tim-man-get-co-required
Fix backward required-time propagation through boxes
2026-02-19 17:20:22 -08:00
Jonathan Greene 71c24a4812 Fix backward required-time propagation through boxes 2026-02-19 13:24:41 -08:00
Alan Mishchenko c7ea67b7df Update command "history". 2026-02-18 12:19:32 -08:00
Alan Mishchenko 6c8b2cfa3b Compiler problem. 2026-02-18 12:19:04 -08:00
Alan Mishchenko 3dd086febe New command &divide, etc. 2026-02-18 10:02:42 -08:00
Alan Mishchenko 62d05a8832 Enable ccache in Makefile. 2026-02-18 10:01:16 -08:00
Alan Mishchenko 3cdb1c4c3b Dumping LUT-mapped networks in Vivado-readable Verilog. 2026-02-15 19:26:35 -08:00
Alan Mishchenko 8475386dfa Making %ufar preserve AIG name. 2026-02-13 09:52:37 -08:00
Alan Mishchenko 2726f0e470 Fixing compiler problem. 2026-02-13 07:12:50 -08:00
Alan Mishchenko 3285adaf32 Updating &sprove to run %ufar. 2026-02-13 07:04:50 -08:00
Miodrag Milanovic c18b835ef1 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-02-11 17:28:40 +01:00
Alan Mishchenko 90be4816ce Updating delay trace for LUT mapping. 2026-02-08 22:50:12 -08:00
Alan Mishchenko 6339de7296 Fix box flop issue. 2026-02-05 23:16:02 -08:00
Alan Mishchenko b60994e143 Bug fix. 2026-02-03 21:32:52 -08:00
Alan Mishchenko 8573cb98f6 Bug fix in %blast. 2026-02-03 11:52:21 -08:00
Alan Mishchenko ccafa23e40 Extending &funtrace. 2026-02-03 11:17:26 -08:00
Alan Mishchenko b50fd7a10a Adding support for not merging some flops after &scorr. 2026-02-02 17:12:15 -08:00
Miodrag Milanovic 734f64d5b9 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-02-02 11:22:23 +01:00
Alan Mishchenko 367b407fba Extending "lutexact" to get function from the current network. 2026-02-01 19:47:14 -08:00
Alan Mishchenko 5899aa5df1 Allow for backward compatibility (when nly PI/PO timing is given). 2026-02-01 19:24:35 -08:00
alanminko 70a12750c1
Merge pull request #475 from wjrforcyber/master
Fix(&put): Missing spec in cec
2026-02-01 07:55:20 -08:00
alanminko 5fd7c57407
Merge pull request #477 from YosysHQ/wasi_upstream
MINGW and WASI compile fixes (from YosysHQ fork)
2026-02-01 07:55:05 -08:00
Alan Mishchenko b6105230bf Transforming init1 states. 2026-01-30 17:29:15 +07:00
Miodrag Milanovic f2ae808236 MINGW proper pthread handling 2026-01-29 09:28:21 +01:00
Miodrag Milanovic 79010216cb MINGW proper pthread handling 2026-01-29 09:26:58 +01:00
Alan Mishchenko ade1882ffc Commenting out an assertion. 2026-01-29 11:33:37 +07:00
Alan Mishchenko 29656286cf New command &init1. 2026-01-28 18:39:21 +07:00
Miodrag Milanovic 6fcdfdbc5e WASI compile fixes 2026-01-28 09:52:01 +01:00
Miodrag Milanovic 9dcae29da3 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-01-28 09:37:06 +01:00
Alan Mishchenko 71e163571a Rename ID mapping switch in &verify. 2026-01-27 22:03:41 +07:00
Alan Mishchenko dd21791031 Extending &verify to handle combinational designs. 2026-01-27 21:52:26 +07:00
Alan Mishchenko d1157cae39 Updating the extension reading the arrival/required times. 2026-01-25 22:27:28 +07:00
JingrenWang 5f3a4fec83
Fix(&put): Missing spec in cec
Signed-off-by: JingrenWang <wjrforcyber@163.com>
2026-01-23 07:05:10 +08:00
alanminko 8e93af4589
Merge pull request #473 from wjrforcyber/master
Fix(Workflow): Bring windows build back to life
2026-01-20 17:18:33 -08:00
Alan Mishchenko cdcfb2febf Changing some default return values to make sure scripts do not abort. 2026-01-21 08:18:01 +07:00
Miodrag Milanovic 01ad37aada Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-01-19 12:06:50 +01:00
JingrenWang ad267aca8a
Fix(Workflow): Bring windows build back to life
Signed-off-by: JingrenWang <wjrforcyber@163.com>
2026-01-19 08:14:08 +08:00
Alan Mishchenko 57544eb9ca Add an option to unhash a mapped AIG after &satlut. 2026-01-18 09:30:48 +07:00
Alan Mishchenko 41e73dbd8b Bug fix in &satlut. 2026-01-17 17:34:52 +07:00
Alan Mishchenko 7f6aba463a Bug fix in &scorr. 2026-01-16 14:19:21 +07:00
phyzhenli c1ed182d38
Fix &synch2 crash with creating wrong mapping 2026-01-06 10:34:26 +08:00
Miodrag Milanovic 799ba63223 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2026-01-05 16:32:47 +01:00
alanminko c18b9a24de
Merge pull request #470 from MyskYko/btor
Btor
2026-01-04 14:22:14 -08:00
alanminko f833c265ce
Merge pull request #469 from MyskYko/cadical-rel-2.2.0
Update cadical VERSION
2026-01-04 14:21:54 -08:00
MyskYko db9275bfbc fix compilation errors 2026-01-04 13:37:42 -08:00
MyskYko 7721495458 add btor 2026-01-04 13:37:18 -08:00
Yukio Miyasaka 59bb87e28e
Update cadical VERSION
forgot to update version
2026-01-04 12:41:58 -08:00
Alan Mishchenko ab1e50bcd5 Updating print-out. 2026-01-04 09:35:32 -08:00
Alan Mishchenko 7bf910315b Changing interface of several commands. 2026-01-03 06:02:59 -08:00
Miodrag Milanovic ef74590ebd WASI fixes 2025-12-30 09:22:59 +01:00
Miodrag Milanovic 3b36aa1573 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-12-29 09:32:25 +01:00
Alan Mishchenko 91e806ffb6 Compiler fix. 2025-12-26 11:04:01 -08:00
Alan Mishchenko 1f13c88bfd Creating commands to match popular scripts. 2025-12-26 08:08:31 -08:00
Alan Mishchenko 291e0a2c83 Updating &write_ver. 2025-12-25 13:16:37 -08:00
Alan Mishchenko 8d3ba7bd7d Compiler problem. 2025-12-25 11:22:11 -08:00
Alan Mishchenko 0ff43a13cb Command "aigsim". 2025-12-25 11:13:38 -08:00
Alan Mishchenko 28cc76119c Fixing continues. 2025-12-24 22:45:37 -08:00
Alan Mishchenko 8b79876f17 Fixing continues. 2025-12-24 22:37:14 -08:00
Alan Mishchenko 8d42237589 Fixing continues. 2025-12-24 22:26:01 -08:00
Alan Mishchenko 99ca3e4428 Commenting out troublesome code. 2025-12-24 21:49:23 -08:00
Alan Mishchenko 95b8d57331 Updating declarations. 2025-12-24 21:34:38 -08:00
Alan Mishchenko 997619d33e Moving guards to proper places. 2025-12-24 21:08:18 -08:00
Alan Mishchenko 52741b9123 Adjusting guards to avoid compiler problems. 2025-12-24 21:02:20 -08:00
Alan Mishchenko 2accf61bcd Adding undefined procedure. 2025-12-24 20:49:55 -08:00
Alan Mishchenko d2c15a04db Commenting out conflicting declarations. 2025-12-24 20:38:07 -08:00
Alan Mishchenko 00cee5f2f5 Reordering includes. 2025-12-24 20:10:08 -08:00
Alan Mishchenko 645d8667c3 Fixing misplaced guard. 2025-12-24 19:59:20 -08:00
Alan Mishchenko a38d012563 Added proper guards to new files. 2025-12-24 19:47:46 -08:00
Alan Mishchenko 5cdded372a Command %ufar. 2025-12-24 19:06:29 -08:00
Alan Mishchenko 84fca2c3f0 Fixing misplaced declaration issue. 2025-12-24 17:52:20 -08:00
Alan Mishchenko 60f52cc082 Changes to "read_jsonc". 2025-12-24 17:45:00 -08:00
Alan Mishchenko 58023c97b7 Added counter-example printout to "&cec -t". 2025-12-24 15:57:57 -08:00
Alan Mishchenko c0ea0cf4d0 Printing counter-examples in "cec" and "&cec". 2025-12-24 15:36:42 -08:00
Alan Mishchenko 87395e54f5 Making sure "twoexact" works with functions up to 14 inputs. 2025-12-24 14:33:35 -08:00
Alan Mishchenko 6ff6a382df Extending %yosys to handle asynch and uninitilized flops. 2025-12-24 14:31:42 -08:00
Alan Mishchenko 050bab8314 Adding missing names in "undc". 2025-12-24 14:29:41 -08:00
Alan Mishchenko bd7fb12e18 Upgrading "lutexact -c" to be like "lutexact -k". 2025-12-24 13:37:06 -08:00
Alan Mishchenko 3d32b8b2ad Updating "lutexact -c" to fix the change in Cadical after upgrade. 2025-12-24 13:20:26 -08:00
Alan Mishchenko b822d47fcf Updating cofactoring procedure. 2025-12-24 13:12:10 -08:00
alanminko fd04a1c073
Merge pull request #465 from zeldin/flipvar5_fix
Fix memory corruption in &mfs.
2025-12-24 07:24:54 -08:00
alanminko f9e4430535
Merge pull request #464 from MyskYko/cadical-rel-2.2.0
update cadical to 2.2.0
2025-12-24 07:24:38 -08:00
alanminko c8d4592453
Merge pull request #463 from dinoruic/patch-2
Fix destructor rewireMiaig.h
2025-12-24 07:24:24 -08:00
alanminko e57bd52127
Merge pull request #462 from YosysHQ/upstreaming
Upstreaming YosysHQ changes
2025-12-24 07:24:07 -08:00
alanminko bc0f65cbfc
Merge pull request #460 from calewis/fix_ub
Make multiplications use unsigned to avoid UB on overflow
2025-12-24 07:23:49 -08:00
alanminko 7a4d8ec907
Merge pull request #458 from jfkey/bug/level-update
Fix assertion failure in `Abc_AigUpdateLevelR_int` during refactor/rewrite/resub
2025-12-24 07:23:19 -08:00
Marcus Comstedt c0e252846e Fix memory corruption in &mfs. 2025-12-24 10:31:08 +01:00
MyskYko a625ef2edc update cadical to 2.2.0 2025-12-23 23:37:45 -08:00
Dino e7c304d3d1
Fix destructor rewireMiaig.h
Pointers that are allocated with a C-style malloc should be deleted with free -- not with the C++-style delete.

Using delete here will trip up toolchains that enforce using free for memory allocated with malloc.
2025-12-23 16:14:38 -08:00
Miodrag Milanovic 35d19a9f33 WASI build fix for solver command 2025-12-22 12:32:43 +01:00
Miodrag Milanovic 9182a8048d WASI build fix for solver command 2025-12-22 12:31:08 +01:00
Miodrag Milanovic 6c34efdc2b Fixing revert/merge difference in code 2025-12-22 12:26:01 +01:00
Miodrag Milanovic 11732d3082 Fix WASI build 2025-12-22 12:02:13 +01:00
Martin Povišer 860b49dd80 Fix UB in `&mfs -r` print 2025-12-22 12:01:47 +01:00
Miodrag Milanovic c6966aa907 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-12-22 11:46:52 +01:00
Alan Mishchenko 64637b8395 Adding an option to &cec against a previous saved AIG. 2025-12-19 20:32:11 -08:00
Alan Mishchenko c327b83127 Command "solver". 2025-12-18 23:07:11 -08:00
Alan Mishchenko 99bde47c57 Adding callbacks to verification engines. 2025-12-18 21:54:22 -08:00
Alan Mishchenko 1e9cc528be Temporarily commenting out this line which causes BLIF reader to fail. 2025-12-18 16:41:25 -08:00
Drew Lewis 993f30ffae Make multiplications use unsigned to avoid UB on overflow
Signed-off-by: Drew Lewis <cannada@google.com>
2025-12-18 16:59:29 +00:00
Alan Mishchenko f8726e5e97 Fixing a compiler problem. 2025-12-17 15:06:20 -08:00
Alan Mishchenko 9a2cf907da Fix to the jsonc writer. 2025-12-17 15:05:12 -08:00
Alan Mishchenko 15abe445f4 Updates to the jsonc writer. 2025-12-15 17:15:46 -08:00
Alan Mishchenko ee04349aee Dumping symbol table when blasting by Yosys. 2025-12-14 23:06:33 -08:00
Alan Mishchenko a8a58c63ba Updateing "topoexact". 2025-12-14 22:54:25 -08:00
Alan Mishchenko 94d0b0dbbb Command "write_jsonc". 2025-12-12 20:35:42 -08:00
liujunfeng 85a0039b78 fix level update bug in rw rf and resub 2025-12-12 18:27:34 +08:00
Alan Mishchenko 362661f00d Command "genpop". 2025-12-10 14:12:22 -08:00
Miodrag Milanovic bd05a6454e Fix WASI build 2025-12-10 11:03:11 +01:00
Miodrag Milanovic b816c2d1bb Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-12-10 10:02:02 +01:00
Alan Mishchenko e67af0ad9e Command "netexact". 2025-12-07 17:51:22 -08:00
Alan Mishchenko 33001946f0 Accidental bug. 2025-12-05 21:14:01 -08:00
Alan Mishchenko eaa204829c Compiler warning. 2025-12-05 20:50:53 -08:00
Alan Mishchenko e58a28b73b Command "topoexact". 2025-12-05 20:44:46 -08:00
Miodrag Milanovic 49efc5bb45 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-12-05 14:00:53 +01:00
Miodrag Milanovic ef1a3d0f42 Revert "Merge pull request #30 from povik/&mfs-fixes"
This reverts commit ccc02c4400, reversing
changes made to 0cd90d0d2c.
2025-12-05 14:00:39 +01:00
Alan Mishchenko b7f8df0941 Command "andexact". 2025-12-03 13:39:13 -08:00
Alan Mishchenko 5e58e34f6c Extending "lutexact -k" to work with larger functions. 2025-11-30 19:51:05 -08:00
Alan Mishchenko c4b2b5c180 Adding extension "y" for obj ID mapping. 2025-11-29 17:30:23 -08:00
Alan Mishchenko 9b0786fe89 Experiments with multipliers. 2025-11-27 19:46:16 -08:00
alanminko 53edce3382
Merge pull request #447 from mmicko/mingw_wasi
Fix compilation for mingw and wasi (up streaming YosysHQ changes)
2025-11-27 08:28:01 -08:00
Alan Mishchenko b9074a754b Adding verbose mode to &permute. 2025-11-26 17:58:28 -08:00
Alan Mishchenko 7691e2ed3c Fixing a bug in &mfs when black boxes are present. 2025-11-26 17:57:16 -08:00
Miodrag Milanovic 131a50dd77 Merge commit 'ba852596b4a11e492e9682662a3e8d1a9be4d765' into yosys-experimental 2025-11-25 11:28:55 +01:00
Alan Mishchenko ee899284b8 Updating printing APIs. 2025-11-24 19:37:26 -08:00
Alan Mishchenko 7f64516f23 Fix to maintain correct order of boxes after "&mfs". 2025-11-24 08:01:26 -08:00
Alan Mishchenko ba852596b4 Adduing supporrt for dumping binary file with matches. 2025-11-23 15:05:46 -08:00
Alan Mishchenko 845de6f368 Adding binary cut dump. 2025-11-23 13:18:01 -08:00
Alan Mishchenko 6d2bedd609 Adding command "cuts". 2025-11-23 11:58:34 -08:00
Alan Mishchenko c956f02eb0 Debug features. 2025-11-23 11:57:59 -08:00
Alan Mishchenko 148f0e9cac Temporarily undoing recent changes to arrival/required times. 2025-11-23 10:55:51 -08:00
Alan Mishchenko fade76f70b Updating how history is recorded. 2025-11-21 20:07:49 -08:00
Alan Mishchenko 48d09e7f93 Fixing a corner case crash. 2025-11-21 19:49:48 -08:00
Alan Mishchenko bde60f2a20 Update to "lutexact". 2025-11-21 00:49:36 -08:00
Alan Mishchenko 4bba0356fb Dumping partial products as an AIG. 2025-11-20 22:57:16 -08:00
Alan Mishchenko d72b93c168 Updating how history is recorded. 2025-11-20 22:56:32 -08:00
Alan Mishchenko 6aaca6a1af Fixing timeout in kissat. 2025-11-20 22:54:05 -08:00
Alan Mishchenko 51c5ff3b81 Updated to "lutexact". 2025-11-20 13:35:47 -08:00
Alan Mishchenko 6490bd7da3 Improving print-outs. 2025-11-18 20:16:44 -08:00
Alan Mishchenko bb52782941 New command "print_npn". 2025-11-18 19:41:10 -08:00
Alan Mishchenko 8c27e4bc90 Adding permutation printout in "lutexact". 2025-11-18 18:10:31 -08:00
Alan Mishchenko 281204f938 Renaming "read_dsd" into "read_function". 2025-11-18 12:12:09 -08:00
Alan Mishchenko d8219265fc Updating LUT cascade generation to support flexible inputs. 2025-11-18 12:07:20 -08:00
Alan Mishchenko 309282601e Experiments with LUT mapping. 2025-11-17 21:37:51 -08:00
Alan Mishchenko b319f57dde Addressing platform-dependent computations in the CUDD package. 2025-11-17 16:39:13 -08:00
Alan Mishchenko 6f5c46632d Fixing another non-reproducibility issue. 2025-11-13 08:12:11 -08:00
Alan Mishchenko 6534475fa1 Fixing a non-reproducibility issue in "lutmin". 2025-11-13 07:50:10 -08:00
Alan Mishchenko b1c73c160c Fixing a valgrind warning. 2025-11-13 07:32:08 -08:00
Alan Mishchenko 5ade9e9dfb Adding command line option of &symfun. 2025-11-12 15:19:38 -08:00
Alan Mishchenko 28f4ad8281 New command &symfun. 2025-11-12 10:04:10 -08:00
Alan Mishchenko 9e90e6086d Updating .gitignore 2025-11-11 22:48:06 -08:00
Alan Mishchenko ec70146d5d Experiments with exact synthesis. 2025-11-11 22:47:23 -08:00
Alan Mishchenko 3bd528c0bf Experiments with exact synthesis. 2025-11-11 22:41:26 -08:00
Alan Mishchenko 38c2bec1ff Adding support for Kissat in "lutexact". 2025-11-11 14:17:48 -08:00
Alan Mishchenko 3d281a1907 Adding support for Cadical in "lutexact". 2025-11-11 13:24:02 -08:00
Alan Mishchenko 91d2f3d7e8 Changes to "lutexact". 2025-11-11 06:55:24 -08:00
Alan Mishchenko 169e288fc4 Reading the printout. 2025-11-10 22:00:07 -08:00
Alan Mishchenko 1b7912a247 Update to the equation solver. 2025-11-10 21:03:21 -08:00
Alan Mishchenko 677299a52f Updating print-outs. 2025-11-10 09:40:38 -08:00
Alan Mishchenko 0a650c18cf New command "&genlutcas". 2025-11-09 16:06:50 -08:00
Alan Mishchenko 6cab944535 New command %gen. 2025-11-09 11:28:25 -08:00
alanminko 3109172462
Merge pull request #443 from MyskYko/fix4
QBF using CaDiCaL
2025-11-06 12:46:13 -08:00
Alan Mishchenko cb971e07a3 Recent experiments. 2025-11-06 12:26:54 -08:00
Miodrag Milanovic 1c5ed1ce37 Revert "Extending support of CI/CO timing info."
This reverts commit aac6190208.
2025-11-06 09:53:28 +01:00
Miodrag Milanovic 7e961f4f3e Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-11-06 08:55:02 +01:00
alanminko 474e7fbec2
Merge pull request #450 from sterin/master
Reduce the amount of text printed when building `abc`.
2025-11-03 17:11:05 -08:00
Baruch Sterin f8981d48f5 Reduce the amount of text printed when building `abc`.
* introduce a user-defined function `abc_info` that only prints out text when ABC_MAKE_VERBOSE is set

* replace all calls to $(info ...) with calls to $(call abc_info, ...)

To show the output build with ABC_MAKE_VERBOSE. for example

```
make ABC_MAKE_VERBOSE=1 ...
```
2025-11-04 02:52:02 +02:00
Alan Mishchenko 8f06ce9112 Enabling runtime limit in "lutexact". 2025-11-02 19:08:59 -08:00
Alan Mishchenko f897673f68 Fixing compilier issues. 2025-11-01 23:33:25 -07:00
Alan Mishchenko 800c274cc2 Linear equetion solver. 2025-11-01 22:55:14 -07:00
Alan Mishchenko 5273eab9f7 Fixing compilation problem. 2025-11-01 11:14:37 -07:00
Alan Mishchenko aac6190208 Extending support of CI/CO timing info. 2025-11-01 11:07:30 -07:00
Alan Mishchenko f808e2c68b Experiments with LUT mapping. 2025-11-01 10:47:00 -07:00
Alan Mishchenko 7c6b779327 Supporting programmable cell libraries. 2025-11-01 01:23:30 -07:00
Alan Mishchenko a9d62d845d Experiments with LUT mapping. 2025-11-01 01:21:37 -07:00
Alan Mishchenko 6034f6621b Changes to cut dumping. 2025-10-30 22:14:18 -07:00
Alan Mishchenko 56a7c049ae Extending max support size in "lutexact". 2025-10-30 16:35:15 -07:00
Alan Mishchenko 18f6464ec7 Experiments with LUT mapping. 2025-10-24 16:57:55 -07:00
Alan Mishchenko 3a1efd48f7 Enabling multiple LUT libraries. 2025-10-24 11:46:55 -07:00
Alan Mishchenko 4c6b082463 Reusing switch "-j" in "if" and "&if". 2025-10-24 10:59:56 -07:00
Alan Mishchenko 6fb4f739b0 Suppress a warning about uninitialized variable. 2025-10-24 10:58:38 -07:00
Alan Mishchenko f39b84a4a1 Fixing compilation problem. 2025-10-22 11:24:18 -07:00
Alan Mishchenko 93f3791fbe Command "&dg" contributed by Jiun-Hao Chen from NTU. 2025-10-22 11:15:07 -07:00
Ethan Mahintorabi 1d7c05988f Adds unit testing framework to ABC
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2025-10-20 08:04:27 +02:00
Miodrag Milanovic a1f5e4541b Fix compilation for mingw and wasi 2025-10-20 07:38:00 +02:00
Miodrag Milanovic fa186342ba Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-10-13 10:47:14 +02:00
Alan Mishchenko 7fbcde9d22 Correcting performance degradation introduced by a bug fix in commit e824cca0c 2025-10-10 13:47:23 -07:00
Alan Mishchenko c8eac7595d Another bug fix. 2025-10-01 22:23:27 -07:00
Alan Mishchenko 9596162b4a Bug fix in the previous commit. 2025-09-30 22:18:30 -07:00
Alan Mishchenko 4c25599cce Exploring multiplier boundaries. 2025-09-30 15:49:14 -07:00
Alan Mishchenko 613fa4f5eb Enable saving choices in &deepsyn. 2025-09-30 15:48:45 -07:00
Alan Mishchenko b28e042afd Compiler warning. 2025-09-16 02:45:58 +07:00
Alan Mishchenko 08230e0c31 Adding choice computaiton to &stochsyn. 2025-09-16 02:33:08 +07:00
Alan Mishchenko 745376d505 Reconstruction of structural choices. 2025-09-16 00:59:49 +07:00
Miodrag Milanovic 8827bafb7f Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-09-03 17:27:47 +02:00
Alan Mishchenko 9478c17288 Adding the dump of non-decomposable functions in "lutcasdec". 2025-08-31 20:18:30 -07:00
Alan Mishchenko 5adfd0030d Silencing benign assertion failure (Issue #428) 2025-08-29 18:41:38 -07:00
alanminko 4dfa49774f
Merge pull request #438 from chenjunhao0315/master
rewire support timing-constraint
2025-08-29 10:55:59 -07:00
alanminko b84382b5db
Merge pull request #437 from povik/fix-fF-unit
Fix capacitance unit parsing
2025-08-29 10:55:40 -07:00
jiunhaochen 4f29be9046 rewire support timing-constraint 2025-08-27 00:56:43 +08:00
Martin Povišer 3455f423d0 Fix capacitance unit parsing
Fix the liberty parser to handle "capacitive_load_unit (1,fF)".
Previously this input would produce a corrupted internal representation
for the library as there would be an extra value written on line 944.
2025-08-26 12:05:05 +02:00
Alan Mishchenko 279217b73d Updating procedures to dump cut info. 2025-08-18 22:00:43 -07:00
Alan Mishchenko 0e4a080779 Enabling "if" to dump the cut and truth table info. 2025-08-16 16:32:29 -07:00
Alan Mishchenko 192c161f93 Enabled default memory blasting when using Yosys. 2025-08-16 16:20:56 -07:00
Alan Mishchenko c5ceff2bee Dumping a binary file with truth tables in "if". 2025-08-12 16:00:26 -07:00
Alan Mishchenko e29dcd9f32 Adding a way to dump sets of resub problems. 2025-08-11 22:44:46 -07:00
Alan Mishchenko e7d360811f Fixed combo loop in choice computation. 2025-08-10 11:04:20 -07:00
Alan Mishchenko 15151c58ed Updating &stochsyn with switch '-d' to support level-preserving AIG optimizations. 2025-08-09 18:10:32 -07:00
Alan Mishchenko 00910e36ff Fixing typos. 2025-08-09 17:00:02 -07:00
Alan Mishchenko a5715bc32d Updates to the prefix tree generation. 2025-08-09 16:43:55 -07:00
Alan Mishchenko 5e09cca964 Handing the case of signed comparators. 2025-08-09 14:46:45 -07:00
Alan Mishchenko 1a18c9a3d8 : lutexact 2025-08-07 12:35:03 -07:00
Alan Mishchenko fd74cb8e8a Refactored the code to return prefix tree as an array of GP-nodes. 2025-08-07 10:51:05 -07:00
Alan Mishchenko 260fa85161 Fixing a linker problem. 2025-08-06 07:38:27 -07:00
Alan Mishchenko c738ed6e86 Integrating prefix adder generation code by Martin Povišer 2025-08-05 22:50:06 -07:00
Miodrag Milanovic fa7fa163da Disable this code for now 2025-08-05 12:24:05 +02:00
Alan Mishchenko 0218e3e4cb New command for bound-set evaluation. 2025-08-03 20:10:26 -07:00
Alan Mishchenko aeef2c6692 Fixing compiler warning. 2025-08-02 08:58:01 -07:00
Alan Mishchenko 3aa8a4a639 New command to dump circuit structure into a file. 2025-08-02 08:53:22 -07:00
Alan Mishchenko c69e45916a Update &append to share primary inputs. 2025-08-01 14:29:45 -07:00
Miodrag Milanovic fcd8ac34d6 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-07-29 16:03:11 +02:00
Alan Mishchenko 052a365823 Undoing previous commit. 2025-07-28 22:58:24 -07:00
Alan Mishchenko 705a3da338 Saving box info for XAIG created usign %blast. 2025-07-28 22:52:27 -07:00
Alan Mishchenko 4ccacb1e5b Adding printout of don't-cares after mapping. 2025-07-21 10:22:43 -07:00
Alan Mishchenko ff56eed4b3 Allowing "lutexact" to take truth table from the current network. 2025-07-21 07:56:30 -07:00
Alan Mishchenko a511d753a6 Improvements to "lutcasdec". 2025-07-20 18:29:20 -07:00
Alan Mishchenko d0118d3917 Adding JSONC parser. 2025-07-14 10:34:24 -07:00
Alan Mishchenko c4c401b7a5 Fixing pointer-dependent behavior during BDD variable reordering. 2025-07-13 20:58:34 -07:00
Alan Mishchenko 990abc4349 Extending external AIG APIs. 2025-07-08 19:26:10 -07:00
Alan Mishchenko f1eebf78f4 Updating command "runscript". 2025-07-08 19:06:04 -07:00
alanminko 0dc5524b80
Merge pull request #425 from MyskYko/fix3
fix cadical
2025-07-07 03:44:24 -07:00
MyskYko 13205ccbb3 qbf with cadical 2025-06-21 01:29:26 -07:00
MyskYko 5e03f9fefa more APIs in cadical 2025-06-20 15:55:31 -07:00
MyskYko 6e130c15a3 fix setnvars 2025-06-20 15:28:27 -07:00
MyskYko 9ea1aaa3cf fix comments 2025-06-20 14:45:50 -07:00
MyskYko a5156f257e fix cadical 2025-06-20 13:40:04 -07:00
Alan Mishchenko beff7f1b34 Temporary fix of the compilation problem related to sorting objects by level in rewiring. 2025-06-19 14:32:10 +07:00
alanminko 83824878e3
Merge pull request #422 from MyskYko/fix
fix amap -m
2025-06-17 21:20:28 -07:00
alanminko da52efecdc
Merge pull request #423 from MyskYko/fix2
fix a bug when yosys constants are already declared
2025-06-17 21:19:55 -07:00
MyskYko e9845e534a fix a bug when yosys constants are already declared 2025-06-17 16:41:43 -07:00
MyskYko f443db4a24 fix amap -m 2025-06-16 10:27:33 -07:00
Alan Mishchenko 6463f11625 Fixing pointer-dependent behavior during BDD variable reordering. 2025-06-07 12:52:23 -07:00
alanminko 44f3265e8b
Merge pull request #397 from phyzhenli/patch-1
fix typo
2025-06-07 10:39:21 -07:00
alanminko afae379366
Merge pull request #419 from mikesinouye/multilib
Prevent merged scl filename size from growing unbounded.
2025-06-07 10:38:15 -07:00
alanminko 5cf5a8d9f5
Merge pull request #412 from tklam/feature/support_verilog_gate_name
Support primitive gates with names in Verilog netlist
2025-06-07 10:38:03 -07:00
alanminko d4358ec80c
Merge pull request #399 from wjrforcyber/gtest_refactor
Refactor(gtest): Remove duplicate libgtest.a
2025-06-07 10:37:53 -07:00
Mike Inouye a4064b8b73 Prevent merged scl filename size from growing unbounded, which limits upper bound of files loaded. 2025-05-30 18:14:47 +00:00
alanminko 0a55186553
Merge pull request #416 from chenjunhao0315/master
patch rewire with empty name
2025-05-25 22:27:43 -07:00
Alan Mishchenko 1f98c28011 Improved cascade printout in "lutcasdec". 2025-05-25 22:24:33 -07:00
Alan Mishchenko 301b46e3c1 Fixiing BLIF reader to read Yosys constants. 2025-05-25 18:45:59 -07:00
jiunhaochen 04161dfda8 patch rewire with empty name 2025-05-26 01:44:04 +08:00
Alan Mishchenko 0ae04514cd Work-around for a bug in "lutcasdec". 2025-05-22 23:56:40 -07:00
Alan Mishchenko 716314d835 Generating AIGs for adders. 2025-05-22 23:56:13 -07:00
Alan Mishchenko 32fe49b6d1 New commands for reading/writing mini-mapping for AIGs. 2025-05-21 21:57:51 -07:00
Alan Mishchenko e1a1994292 Extending "&cofs" to handle multi-output AIGs. 2025-05-21 21:30:58 -07:00
alanminko 0c155952bf
Merge pull request #415 from HAHHHD/master
add clause pushing with blocking
2025-05-20 16:37:20 -07:00
Alan Mishchenko 3bd7bac552 Improvements to "lutcasdec". 2025-05-20 16:17:43 -07:00
HAHHHD e20c484ee1 add clause pushing with blocking 2025-05-20 15:04:15 -07:00
Alan Mishchenko c5edc566ff Improvements to "lutcasdec". 2025-05-20 14:28:07 -07:00
Alan Mishchenko 29c8d3eacf Improvements to "lutcasdec". 2025-05-20 10:41:47 -07:00
Alan Mishchenko 9bb736acee Improvements to "lutcasdec". 2025-05-20 06:39:28 -07:00
Alan Mishchenko c398b06740 Experiments with decomposition. 2025-05-20 06:08:46 -07:00
Alan Mishchenko 240bf58f90 Updating "short_names" and BDD profiling. 2025-05-19 10:24:56 -07:00
Alan Mishchenko 916f70058e Updating script runner. 2025-05-18 14:05:50 -07:00
Alan Mishchenko 0b1d7c6d0f Supporting structural choices in rewiring. 2025-05-18 13:37:30 -07:00
Alan Mishchenko 5daa0c347e Small changes to "lutcasdec". 2025-05-16 17:23:32 -07:00
Alan Mishchenko 57966de4b4 Adding flag to skip two-output cells in "read_lib". 2025-05-14 17:01:48 -07:00
Alan Mishchenko d34821e768 Skipping cells with more than two outputs in "read_lib". 2025-05-14 14:17:05 -07:00
Alan Mishchenko 078debff4e Adding print-out of LUT mapping stats. 2025-05-13 22:49:55 -07:00
Alan Mishchenko d245305393 Improvements to "lutcasdec". 2025-05-13 19:21:56 -07:00
tklam 9545b79e0e support primitive gates with names in Verilog netlist 2025-05-12 10:20:13 -04:00
Alan Mishchenko c85f007f75 Convert buffers to .short lines in BLIF. 2025-05-09 18:16:37 -07:00
Alan Mishchenko 490bb92a8c Fixing the Yosys script used to read a mapped netlist. 2025-05-09 17:17:26 -07:00
Alan Mishchenko a42e6ecd23 Fixing a bug in "read_lib". 2025-05-09 17:13:40 -07:00
Alan Mishchenko 9dc7ade063 Adding a switch to read mapped Verilog using command %yosys. 2025-05-09 11:47:26 -07:00
Alan Mishchenko 71b60a9830 Updating &stochsyn. 2025-05-07 19:53:53 -07:00
Alan Mishchenko 4560597b31 Utility to duplicate inputs. 2025-05-07 16:53:51 -07:00
Alan Mishchenko 49d9252f90 Updating the way min col mult is reported in lutcasdec. 2025-05-05 09:03:41 -07:00
Alan Mishchenko 5e54ef3aff Adding printout of flops. 2025-05-03 18:15:11 -07:00
Alan Mishchenko f9e4d06806 Column multiplicity statistics 2025-05-02 08:18:12 -07:00
Alan Mishchenko 692b0c6908 Printout of column multiplicity statistics. 2025-05-02 08:13:20 -07:00
Alan Mishchenko 75adf123f6 Adding new feature to &nf. 2025-05-01 22:41:49 -07:00
Alan Mishchenko 1c2b935a77 Adding new feature to "lutexact". 2025-05-01 21:08:46 -07:00
Alan Mishchenko 391a767c16 Updating LUT cascade mapping. 2025-05-01 11:51:48 -07:00
Alan Mishchenko 6a031620fe Supporting random seed in "lutexact". 2025-04-30 12:10:22 -07:00
Alan Mishchenko 59bb4de39f Misc changes. 2025-04-30 10:47:12 -07:00
alanminko 5305d93037
Merge pull request #405 from MyskYko/rrr
update rrr
2025-04-25 06:48:30 +07:00
alanminko eaf974dec1
Merge pull request #406 from chenjunhao0315/master
rewire clean up
2025-04-19 00:15:32 +07:00
jiunhaochen b1734ac297 rewire clean up 2025-04-19 00:43:48 +08:00
MyskYko b1b1023285 update rrr 2025-04-17 11:01:39 -07:00
alanminko 5ea1240990
Merge pull request #404 from chenjunhao0315/master
rewire fix not mapped
2025-04-17 22:15:36 +07:00
jiunhaochen 0ab176d7c9 rewire fix genlib change 2025-04-17 16:14:49 +08:00
jiunhaochen 01bfd8fbad rewire fix not mapped 2025-04-17 12:39:24 +08:00
Alan Mishchenko 3a063c5901 Allowing more aggressive restructuring in "stochmap". 2025-04-16 16:58:04 -07:00
Alan Mishchenko 1626a337a1 Adding random seed to "lutcasdec". 2025-04-16 16:35:23 -07:00
alanminko b454511936
Merge pull request #403 from chenjunhao0315/master
rewire restructured even if the cost is not improved
2025-04-17 04:04:17 +07:00
jiunhaochen 6c37cc9ac3 rewire restructured even if the cost is not improved 2025-04-17 04:58:32 +08:00
Alan Mishchenko dcf9079507 Extending "stochmap" to work for AIGs. 2025-04-15 21:56:24 -07:00
Alan Mishchenko 47ac9f75ca New command "&andcare" to AND the miter with the careset. 2025-04-15 20:00:19 -07:00
Alan Mishchenko 1a1bdbe4c8 Another typo. 2025-04-10 07:03:19 -07:00
alanminko 1177cfabfb
Merge pull request #402 from chenjunhao0315/master
command rewire add external care
2025-04-10 21:02:10 +07:00
jiunhaochen 2179034f23 command rewire fix condition 2025-04-10 17:24:27 +08:00
jiunhaochen 43d12f6c31 command rewire add external careset 2025-04-10 16:57:13 +08:00
Chen jiun hao 08ccd6d0b9
Merge branch 'berkeley-abc:master' into master 2025-04-10 16:52:03 +08:00
Alan Mishchenko d271403514 Fixing a typo. 2025-04-09 21:23:44 -07:00
Alan Mishchenko c5fdfb3835 New command "runscript". 2025-04-09 18:16:24 -07:00
Alan Mishchenko 83150e6549 Enable overlapping partitions in "stochmap". 2025-04-09 08:46:38 -07:00
jiunhaochen 5700bff205 command rewire add external care 2025-04-09 19:27:32 +08:00
Miodrag Milanovic e55d316cc9 WASI build fix 2025-04-08 17:38:54 +02:00
Miodrag Milanovic 20416c1a7b mingw fixes 2025-04-08 14:23:55 +02:00
Miodrag Milanovic 1cdaaadf53 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-04-08 13:28:24 +02:00
Miodrag Milanovic 44a2996f7f Revert "Revert addition of CaDiCaL"
This reverts commit 5ecc7c333c.
2025-04-08 13:28:06 +02:00
alanminko 68c576cc56
Merge pull request #400 from MyskYko/rrr
update rrr
2025-04-07 11:34:13 +07:00
Alan Mishchenko 3846c193f2 Enable overlapping partitions in "stochmap". 2025-04-06 17:01:40 -07:00
MyskYko 27f2429d76 update rrr 2025-04-06 15:46:02 -07:00
Alan Mishchenko c0be439b45 Performance improvements. 2025-04-06 00:14:02 -07:00
Alan Mishchenko 1b6b553922 New commands for truth table file processing. 2025-04-05 22:40:24 -07:00
Alan Mishchenko 3f479dc84f Bug fixes in LUT cascade. 2025-04-05 22:39:59 -07:00
Alan Mishchenko 5c604949af Enable dumping of the resulting permutation of internal nodes in "permute". 2025-04-05 16:37:49 -07:00
JingrenWang 0b68f06172 Refactor(gtest): Remove duplicate libgtest.a
Close #398

Signed-off-by: JingrenWang <wjrforcyber@163.com>
2025-04-04 10:25:55 +08:00
phyzhenli 8db417597c
Update Makefile 2025-04-03 16:40:28 +08:00
Alan Mishchenko 96c28881a8 Bug fix in LUT cascade. 2025-04-01 19:03:17 -07:00
alanminko e3b96c784f
Merge pull request #396 from fxreichl/master
Extend logging for eSLIM
2025-04-01 20:35:49 +07:00
alanminko fa80e30eca
Merge pull request #386 from wjrforcyber/cmake_compilation_database
Refactor(cmake): Generate compilation database
2025-04-01 20:35:29 +07:00
alanminko a4d6775b7c
Merge pull request #384 from QiuYitai/master
Fix the null reference vulnerability
2025-04-01 20:35:09 +07:00
Franz Reichl 2c003f8865 Extend logging for eSLIM 2025-04-01 11:50:28 +02:00
Alan Mishchenko 29706ebede Bug with LUT cascade mapping. 2025-03-31 19:09:54 -07:00
Alan Mishchenko 80becaf2e2 Bug fix in LUT cascade decomposition. 2025-03-31 18:33:38 -07:00
Alan Mishchenko 9cdbb79338 Bug fix in handling concurrency in "stochmap". 2025-03-31 15:39:05 -07:00
Alan Mishchenko dc72d1e120 New command &store. 2025-03-31 15:24:15 -07:00
Alan Mishchenko 4656ae10e0 Updates to the GPC-based mapping. 2025-03-30 19:55:07 -07:00
Alan Mishchenko 6d6a5accb4 Experiments with LUT cascade mapping. 2025-03-30 18:20:55 -07:00
Alan Mishchenko 4ac014db41 Experiments with adder mapping. 2025-03-30 09:15:54 -07:00
Alan Mishchenko db2b52ca03 Bug fix. 2025-03-29 16:54:10 -07:00
Alan Mishchenko 2b5f102bdb Updating input file format in command "permute". 2025-03-29 15:48:07 -07:00
Alan Mishchenko bb11cc4c46 Experiments with adder-tree mapping. 2025-03-29 15:37:22 -07:00
Alan Mishchenko 2442720528 Adding counter generation to "symfun". 2025-03-29 11:11:13 -07:00
Alan Mishchenko 938ae9428b Extending interface of "permute". 2025-03-28 18:35:30 -07:00
Alan Mishchenko f5ac2d4bd3 Updates to LUT cascade decomposition. 2025-03-19 12:20:25 -07:00
Alan Mishchenko e320888191 Adding structural guidance. 2025-03-19 12:14:28 -07:00
alanminko da5f1e1579
Merge pull request #388 from fxreichl/master
Circuit minimization with exact synthesis and SAT-based local improvement
2025-03-19 19:50:37 +07:00
Franz Reichl 8ffca32372 Add command &eslim 2025-03-19 11:29:14 +01:00
Alan Mishchenko e7dd9151b1 Adding structural guidance. 2025-03-18 17:51:40 -07:00
Alan Mishchenko 2078b3945b Adding support for the random seed to the recent experiments. 2025-03-18 07:55:28 -07:00
Alan Mishchenko 30c952ed22 Remove structural choices after mapping. 2025-03-17 17:17:48 -07:00
Alan Mishchenko 59a7cc5c9c Removing intermediate files in exact synthesis. 2025-03-17 17:12:01 -07:00
Alan Mishchenko e20cbd6120 Updating command "cone" to extract a comma-separated list of outputs. 2025-03-17 16:10:22 -07:00
alanminko 80a43cce9e
Merge pull request #387 from chenjunhao0315/master
stochmap heuristic adjust, rewire support level constraint and different mapper
2025-03-17 10:09:15 +07:00
jiunhaochen e937e82cc6 rewire with &nf, &simap 2025-03-17 10:26:32 +08:00
jiunhaochen c63cf09660 rewire support level constraint 2025-03-17 10:26:32 +08:00
jiunhaochen 67d8095515 fix read_mm 2025-03-17 10:26:32 +08:00
jiunhaochen c3b76b1712 Patch rewire 2025-03-17 10:26:32 +08:00
Alan Mishchenko 0ebc9dbbae Experiments with exact synthesis. 2025-03-16 09:39:04 -07:00
Alan Mishchenko 839f3e18dd Experiments with mapping. 2025-03-14 20:24:08 -07:00
Alan Mishchenko aaba1b9a5f Experiments with mapping. 2025-03-13 20:59:17 -07:00
Alan Mishchenko d55735df2b Updates to the result reporting. 2025-03-13 11:57:53 -07:00
Alan Mishchenko 27fdbe0162 Updates to the mapping experiment. 2025-03-13 11:57:34 -07:00
Alan Mishchenko 2361a02c99 Fixing compilation problemj in some builds. 2025-03-12 20:53:02 -07:00
Alan Mishchenko feefa0f513 Supporting out of order signal names in AIGER reader. 2025-03-12 20:12:28 -07:00
Alan Mishchenko 5ef9c3c50b Experiment with mapping. 2025-03-12 20:11:33 -07:00
Miodrag Milanovic f2d68d590f Fix mingw compilation 2025-03-12 07:28:47 +01:00
wjrforcyber 504f604d2a
Refactor(cmake): Generate compilation database
Signed-off-by: wjrforcyber <wjrforcyber@163.com>
2025-03-12 14:27:47 +08:00
Martin Povišer 5ecc7c333c Revert addition of CaDiCaL
This reverts the upstream PR berkeley-abc/abc#382
2025-03-11 20:17:47 +01:00
Martin Povišer 43b9a4defe Merge remote-tracking branch 'upstream/master' into yosys-experimental 2025-03-11 19:28:00 +01:00
qiuweibin 02f3727d87 Fix the null reference vulnerability 2025-03-11 03:38:50 +00:00
Alan Mishchenko b09305204d Minor bug fixes. 2025-03-10 20:13:53 -07:00
Alan Mishchenko 2c45f9dce2 Adding conflict limit and timeout to &simap. 2025-03-10 17:54:30 -07:00
Alan Mishchenko 40ea8a7598 Enabling support for input/output names in mini mapping format. 2025-03-10 17:29:01 -07:00
Alan Mishchenko 9390a74c54 Changes to the file interface in "stochmap". 2025-03-10 14:40:28 -07:00
Alan Mishchenko bd9fb45808 Adding direct file interface for mapped networks. 2025-03-10 14:38:51 -07:00
Alan Mishchenko ecc27e80dc Adding support for the genlib library file name. 2025-03-10 14:37:29 -07:00
Alan Mishchenko 120f30a89e Removing file added accidentally. 2025-03-10 13:20:01 -07:00
Alan Mishchenko 9665696a94 Code refactoring to dump CNF files. 2025-03-10 13:17:04 -07:00
Alan Mishchenko 67fdd8d244 Random crash fix. 2025-03-10 13:06:14 -07:00
Alan Mishchenko 0e117760e2 Performance improvement. 2025-03-10 00:37:51 -07:00
Alan Mishchenko c62bf1b89c Updating cut level. 2025-03-10 00:08:35 -07:00
Alan Mishchenko 3dc77bbe1c Bug fix in "stochmap". 2025-03-09 23:52:03 -07:00
Alan Mishchenko 38ba7d78aa Experiment with mapping. 2025-03-09 15:42:25 -07:00
alanminko f058e15f87
Merge pull request #382 from MyskYko/cadical
CaDiCaL
2025-03-07 23:17:57 +07:00
alanminko 383c16b690
Merge pull request #380 from MyskYko/kissat
support debug mode
2025-03-07 23:17:44 +07:00
alanminko cab003b277
Merge pull request #383 from QiuYitai/master
Fix the NULL Pointer Dereference vulnerability in `Abc_NtkCecFraigPart`.
2025-03-07 23:17:19 +07:00
qiuweibin db4a3005e3 Fix the null reference vulnerability 2025-03-07 10:48:02 +00:00
MyskYko 14b451b52f patch 2025-03-07 00:25:11 -08:00
MyskYko f544165a88 cadical original 2025-03-05 21:25:31 -08:00
MyskYko 8fb9fc5d0f add version 2025-03-05 21:19:39 -08:00
MyskYko f168f2f286 support debug mode 2025-03-05 20:25:40 -08:00
alanminko fbd19056e7
Merge pull request #379 from MyskYko/rrr
update rrr
2025-03-06 09:00:36 +07:00
Alan Mishchenko 7364002c39 Updates to rewiring. 2025-03-05 17:47:12 -08:00
Alan Mishchenko f3ae349cf2 Bug fixing in "stockmap". 2025-03-05 17:46:39 -08:00
MyskYko 8005405ed7 update rrr 2025-03-05 14:44:12 -08:00
Alan Mishchenko 2126cb3ca1 Fixing a typo in Kissat integration. 2025-03-05 10:30:16 -08:00
Alan Mishchenko b9b8ff47e3 Adding programmable call to Kissat in command &kissat. 2025-03-05 08:26:28 -08:00
alanminko e7cd9a3b66
Merge pull request #378 from MyskYko/kissat
Kissat
2025-03-05 21:57:10 +07:00
MyskYko 3f6171127a add license 2025-03-05 04:21:18 -08:00
MyskYko 664d285fcb patch 2025-03-05 04:10:49 -08:00
MyskYko a7476c65d8 kissat original 2025-03-04 17:39:59 -08:00
Alan Mishchenko c25bf73466 Adding new external APIs. 2025-03-03 19:40:11 -08:00
Alan Mishchenko e462caed8f Adding new source files for the windows build. 2025-03-01 10:55:21 -08:00
alanminko 1b96863505
Merge pull request #375 from chenjunhao0315/master
Command rewire
2025-03-02 01:27:30 +07:00
alanminko adbeffc145
Merge pull request #374 from wjrforcyber/fix_lib_pointer
Fix(Pointer): Fix the wrong value passed to size
2025-03-02 01:27:01 +07:00
alanminko d0d1721bbe
Merge pull request #373 from wjrforcyber/fix_HMetis
Fix(write_hmetis): Remain the obj number when omitting POs explictly
2025-03-02 01:26:44 +07:00
jiunhaochen 083d3884dd Command rewire 2025-03-01 23:44:55 +08:00
wjrforcyber 5632bb8892
Fix(Pointer): Fix the wrong value passed to size
Signed-off-by: wjrforcyber <wjrforcyber@163.com>
2025-03-01 21:03:51 +08:00
Alan Mishchenko 75ef06017d LUT cascade mapping. 2025-02-27 13:40:11 -08:00
wjrforcyber 6046bbee4e
Update(EmptyLine): Remove empty line between data and comment
Due to the parsing issue here: https://github.com/kahypar/mt-kahypar/pull/205

Signed-off-by: wjrforcyber <wjrforcyber@163.com>
2025-02-27 16:42:29 +08:00
wjrforcyber e9c7059274
Fix(write_hmetis): Remain the obj number when omit POs explictly
Signed-off-by: wjrforcyber <wjrforcyber@163.com>
2025-02-26 21:36:48 +08:00
Alan Mishchenko 45c250fb5b New command &randsyn (fixing scalability issue). 2025-02-23 15:49:49 -08:00
Alan Mishchenko a9d959acbe Command "stochmap". 2025-02-23 15:47:28 -08:00
Alan Mishchenko c4a10c728e Suggested fix of an overflow in vectors (compiler error). 2025-02-23 15:47:00 -08:00
Alan Mishchenko 4f1b961d00 Suggested fix of an overflow in vectors. 2025-02-23 13:17:51 -08:00
Alan Mishchenko 9e35825e6b New command &randsyn. 2025-02-21 13:20:15 -08:00
Alan Mishchenko e5e1f76b21 Bug fix. 2025-02-14 14:41:01 -08:00
alanminko 0cbc9a851a
Merge pull request #368 from hriener/dau_fix
Increase buffer size to DAU_MAX_STR (=2000).
2025-02-15 05:30:48 +07:00
alanminko 57e504db7b
Merge pull request #362 from wjrforcyber/gz_lib_support
Feat(read_lib): Gz lib format support
2025-02-15 05:30:24 +07:00
alanminko ee8e0370d5
Merge pull request #361 from letsintegreat/power-aware
Fix switching bug
2025-02-15 05:29:55 +07:00
alanminko a2c6cb8fd4
Merge pull request #360 from wjrforcyber/fix_print_mffc
Fix(print_mffc): Missing condition when single output linked to CO
2025-02-15 05:29:37 +07:00
alanminko 4b6c35bd4d
Merge pull request #356 from wjrforcyber/choice_bug
Fix(&dch): choices bugs in &put
2025-02-15 05:29:14 +07:00
alanminko 8a96d02e33
Merge pull request #354 from wjrforcyber/write_hmetis
Feat(write_hmetis): Enable hMetis format
2025-02-15 05:28:50 +07:00
alanminko a2e4c153c9
Merge pull request #255 from phsauter/fix-scl-regression
Fix Segfault in scl
2025-02-15 05:28:25 +07:00
Heinz Riener 80eecea409 Increase buffer size to DAU_MAX_STR (=2000). 2025-02-14 15:49:17 +01:00
alanminko 7bd782382e
Merge pull request #367 from MyskYko/rrr
New implementation
2025-02-14 06:19:30 +07:00
MyskYko f51543457d change default parameter 2025-02-13 12:40:48 -08:00
Alan Mishchenko 775dee4de9 Fixing timing propagation bug in &nf with boxes. 2025-02-12 18:41:12 -08:00
MyskYko 20a57ef343 change dsp 2025-02-12 06:16:09 -08:00
MyskYko 23c632f113 compilation error 2025-02-12 06:16:09 -08:00
MyskYko b0153e0f57 fix template 2025-02-12 06:16:09 -08:00
MyskYko d1d861f703 fix template 2025-02-12 06:16:09 -08:00
MyskYko 6e3b38c7d3 add rrr 2025-02-12 06:16:02 -08:00
alanminko aa9630e169
Merge pull request #365 from QuantamHD/fix_nf_crash
nf: Fix assert( pDp->F < FLT_MAX ); in nf
2025-02-12 08:34:50 +07:00
alanminko c4f8e8e88b
Merge pull request #364 from QuantamHD/fix_mising_return
Fixes missing return in cec
2025-02-12 08:34:21 +07:00
Alan Mishchenko b7bf6c20b6 Improvements to LUT cascade mapping. 2025-02-11 17:32:19 -08:00
Ethan Mahintorabi 2227d6d4e7
nf: Fix assert( pDp->F < FLT_MAX ); in nf
This error was triggered by what appears to be a missing
saturating float check in Nf_ManCutMatchOne. When opened
in the debugger AreaF starts at FLT_MAX and in some cases
can be added to itself which results in +Inf. I noticed the
other if had a  saturating condidtion.

I took a flyer on it, and added it to the previous condition,
and it resolved the error. I think this is a good fix.

Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2025-02-11 22:04:24 +00:00
Ethan Mahintorabi 964170d8dc
Fixes missing return in cec
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2025-02-10 05:44:31 +00:00
Alan Mishchenko 8912d3aabe Adding command &write_truth equivalent to &write_truths. 2025-01-29 17:40:17 -08:00
Alan Mishchenko 3e86444510 Bug fix in reading truth tables. 2025-01-29 17:37:24 -08:00
wjrforcyber 303907ec0c
Update(read_lib): Remove redundant header 2025-01-21 15:58:31 +08:00
wjrforcyber adf9b4e7fb
Feat(read_lib): Support .gz file 2025-01-21 15:54:38 +08:00
Martin Povišer 8700bb58ee
Merge pull request #37 from YosysHQ/povik/fix-mfs-ub
Fix UB in `&mfs -r` print
2025-01-20 12:47:20 +01:00
Martin Povišer 013023f1bf
Fix UB in `&mfs -r` print 2025-01-20 12:45:53 +01:00
letsintegreat a75d0cb0ad
fix switching bug 2025-01-18 22:41:24 +05:30
wjrforcyber 910a66a372
Fix(print_mffc): Missing condition when single output linked to CO 2025-01-17 18:31:14 +08:00
wjrforcyber a03c126a13
Refactor(Redundant): Remove redundant code 2025-01-09 23:39:02 +08:00
wjrforcyber c1ac7d8153
Update(&ps): Revert two line since `cls` shows the same data 2025-01-09 23:04:00 +08:00
wjrforcyber 8c7c9d0ccf
Fix(&dch): choices bugs in &put 2025-01-09 22:21:32 +08:00
Alan Mishchenko d5e1a5d445 Bug fix in &gencex. 2025-01-02 00:33:22 +07:00
Alan Mishchenko 350dcd3ea4 Enabling shared variables in bound set evaluation. 2024-12-28 00:05:00 -08:00
wjrforcyber 71b3daf0f6
Merge remote-tracking branch 'upstream/master' into write_hmetis 2024-12-26 20:58:17 +08:00
Alan Mishchenko 73742a7ec2 Adding new file to windows makefile. 2024-12-26 01:10:02 -08:00
Alan Mishchenko b59b475d6a Compiler error. 2024-12-26 00:56:18 -08:00
Alan Mishchenko 7d247a08f7 Experiments with bound-set evaluation. 2024-12-26 00:37:37 -08:00
wjrforcyber 0dff4dbc4b
Feat(write_hmetis): Add weight on hyperedges and format 2024-12-26 13:54:55 +08:00
wjrforcyber 7a5a0ad8b3
Refactor(Compile): For MSVS build 2024-12-26 11:27:24 +08:00
wjrforcyber f7c5241dee
Merge branch 'master' into write_hmetis 2024-12-25 15:54:34 +08:00
wjrforcyber 47e4e23bc5
Fix(write_hmetis): Comments should be start with % 2024-12-25 15:43:50 +08:00
wjrforcyber 17652cfda6
Feat(write_hmetis): Write out hMetis file format 2024-12-25 15:37:36 +08:00
alanminko ef8230d9be
Merge pull request #353 from Carmine50/master
cec: Modifying algorithm for generating simulation vectors for SAT sweeping (SimGen) and adding new feature to specify the simulation vector of the PIs for SAT sweeping algorithm.
2024-12-24 11:36:05 -08:00
Carmine50 a74da1c50b [CEC][SAT Sweeping] Added new functionality in SAT sweeping function to use for simulation the PI vector present in vSimsPi data structure. 2024-12-24 14:54:59 +01:00
Carmine50 64e8bb02b9 [CEC][SimGen][Bits to Words] Changing the units of measure for random simulation from number bits to number words 2024-12-24 14:48:57 +01:00
Carmine50 5961231ed1 [CEC][SimGen][Clean codes] Disabling verbose. 2024-12-24 12:27:09 +01:00
Carmine50 7c6d1ffd2d [CEC][SimGen][Bugs] Fixing bugs and removing unused var. 2024-12-24 11:59:23 +01:00
Carmine50 37979dbd94 [CEC][SimGen][Clean codes] Removing commented SAT calls operations. 2024-12-24 11:50:47 +01:00
Carmine50 699c8c4c88 [CEC][SimGen][Clean codes] Removing commented SAT calls operations. 2024-12-24 11:50:11 +01:00
Carmine50 0ba2b7dae9 [CEC][SimGen][Clean codes] Removing unused parameters. 2024-12-24 11:49:17 +01:00
Carmine50 1a89f7ff63 [CEC][SimGen][CLI] Changed function name and help message. Added new option to specify file where to dump simulation vectors. Commented out too verbose information 2024-12-24 11:43:18 +01:00
Carmine50 463cf6a7df [CEC][SimGen][ABC Integration] Removed SAT solver calls and saving the simulation vectors in an internal data structure to pass to other functions. 2024-12-24 11:06:00 +01:00
Alan Mishchenko 14d46bfef8 Fixing big-endian problem if &fx and &deepsyn. 2024-12-23 20:26:00 -08:00
Alan Mishchenko 733fec328c Fixing big-endian problems in mfs2 and &mfs. 2024-12-23 20:04:21 -08:00
Alan Mishchenko cc894c5905 Deleting unused files. 2024-12-23 17:03:29 -08:00
Alan Mishchenko b81df1744f Removing unhelpful assertion. 2024-12-23 10:00:37 -08:00
Alan Mishchenko e21399f3bc Compiler warning. 2024-12-23 08:55:59 -08:00
alanminko 943bc0191c
Merge pull request #352 from wjrforcyber/conditional_jump
Fix(&if -x): Conditional jump or move depends on uninitialised value(s)
2024-12-23 08:52:54 -08:00
alanminko 01c6102ca7
Merge pull request #350 from wjrforcyber/put_bug_on_choice
Fix(&put): &put bug with choices
2024-12-23 08:52:29 -08:00
alanminko 733d2cd390
Merge pull request #348 from wjrforcyber/mem_leak
Refactor(MemLeak): MemLeak fix in orchestrate
2024-12-23 08:52:12 -08:00
wjrforcyber fdd66a8963
Fix(&if -x): Conditional jump or move depends on uninitialised value(s)
From Valgrind:
==44570== Conditional jump or move depends on uninitialised value(s)
==44570==    at 0x9DEBA1: Dau_DsdRemoveBraces (dauMerge.c:563)
==44570==    by 0x9D1F53: Dau_DsdDecompose (dauDsd.c:1926)
==44570==    by 0x835523: If_DsdManCompute (ifDsd.c:2073)
==44570==    by 0x84177C: If_ObjPerformMappingAnd (ifMap.c:315)
==44570==    by 0x843720: If_ManPerformMappingRound (ifMap.c:667)
==44570==    by 0x813A01: If_ManPerformMappingComb (ifCore.c:126)
==44570==    by 0x813C88: If_ManPerformMapping (ifCore.c:91)
==44570==    by 0xE5F147: Gia_ManPerformMappingInt (giaIf.c:2503)
==44570==    by 0xE60976: Gia_ManPerformMapping (giaIf.c:2566)
==44570==    by 0x543605: Abc_CommandAbc9If (abc.c:41910)
==44570==    by 0x654739: CmdCommandDispatch (cmdUtils.c:157)
==44570==    by 0x64E0F2: Cmd_CommandExecute (cmdApi.c:210)
2024-12-23 23:24:47 +08:00
Alan Mishchenko 42c2c54969 Fixing a big-endian issue in SOP manipulation and factoring. 2024-12-22 14:15:35 -08:00
Alan Mishchenko 207cfddaa8 Experiments with structural LUT cascade mapping. 2024-12-21 21:24:45 -08:00
alanminko df4d847bbf
Merge pull request #351 from Carmine50/master
cec: Adding new algorithm for generating simulation vectors for SAT sweeping (SimGen)
2024-12-21 15:02:29 -08:00
Carmine50 ef8c35f95d [CEC][SimGen][LUT mapping] Adding option to consider an already mapped circuit before executing SimGen 2024-12-21 20:22:02 +01:00
Carmine50 8a1c28bf0f [CEC][SimGen][LUT mapping] Adding option to consider an already mapped circuit before executing SimGen 2024-12-21 20:15:40 +01:00
Carmine50 f407156de6 [CEC][SimGen][Warnings] Re-adjusted code to remove unused variables and avoid warnings compilation 2024-12-21 16:19:47 +01:00
Carmine50 bd80d2e459 [CEC][SimGen][Warnings] Re-adjusted code to remove unused variables and avoid warnings compilation 2024-12-21 16:04:45 +01:00
Carmine50 a6de82377d [CEC][SimGen][Warnings] Re-adjusted code to remove unused variables and avoid warnings compilation 2024-12-21 15:57:47 +01:00
Carmine50 c104d9cb72 [CEC][SimGen][Warnings] Re-adjusted code to remove unused variables and avoid warnings compilation 2024-12-21 14:26:54 +01:00
Carmine50 b999084ade [CEC][SimGen][CLI] Removed option of nMaxStep since it was unused 2024-12-19 18:12:28 +01:00
Carmine50 30af6f9868 [CEC][SimGen][CLI] Change name of command for simgen 2024-12-19 17:25:45 +01:00
Carmine50 87a3cafa44 [CEC][SimGen][Main Algo] Added main algorithm of SimGen and all necessary utility functions 2024-12-19 14:23:19 +01:00
Carmine50 0ea9929e65 [CEC][SimGen][Man new data struct] Added new variables in Gia_Man to save truth tables, MFFC infos and luts rankings for simgen. Modified also the function type to extract MFFC info 2024-12-19 14:22:26 +01:00
Carmine50 91dcfae020 [CEC][SimGen][Experiment ID] Added experiment ID option to test different experiments with simgen 2024-12-18 19:56:12 +01:00
Carmine50 cbd4456805 [CEC][SimGen][Experiment ID] Added experiment ID option to test different experiments with simgen 2024-12-18 19:53:44 +01:00
Carmine50 070ae52a46 [CEC][SimGen][Custom Parameters] Added custom parameters for SimGen CEC algo 2024-12-18 19:36:50 +01:00
Carmine50 99648e132f [CEC][SimGen][CLI] Added command line function to call SimGen main function. 2024-12-18 18:43:38 +01:00
wjrforcyber a8c65f1343
Fix(&put): &put bug with choices
Related: #349
2024-12-17 14:05:58 +08:00
Alan Mishchenko 8ba3d9b91c Trying anothe resource limit in scorr. 2024-12-14 13:44:18 -08:00
Alan Mishchenko 6754da13f2 Compiler warning. 2024-12-08 00:19:54 -08:00
wjrforcyber 7391a297bb
Refactor(MemLeak): MemLeak fix in orchestrate 2024-12-06 18:13:32 +08:00
alanminko c315d9e149
Merge pull request #347 from QuantamHD/map_param
map: Add Mio_Library_t* parameter to Abc_NtkMap
2024-12-02 11:51:46 -08:00
Ethan Mahintorabi 01c9a65a47
map: Add Mio_Library_t* parameter to Abc_NtkMap
This lets users of the ABC API call map without relying on the static
Mio_Library_t* in Abc_FrameReadLibGen.
2024-12-02 06:55:42 +00:00
Alan Mishchenko 14168eb509 Updating command "rungen" to generate random functions. 2024-11-27 22:01:27 -08:00
Alan Mishchenko 1f3cf0aad9 Experiment with "scorr". 2024-11-17 15:44:32 -08:00
Alan Mishchenko 3aff0af0c5 Adding command for generating sorters. 2024-11-11 21:02:59 -08:00
Alan Mishchenko b5a76d8ba3 Compilation problem. 2024-11-10 19:30:24 -08:00
Alan Mishchenko f2e4ceb0e3 Update to "lutexact". 2024-11-10 19:12:40 -08:00
Alan Mishchenko aeb977286f Updates to LUT cascade synthesis. 2024-11-10 18:54:35 -08:00
Alan Mishchenko c787e32f86 Adding postiive minterm count for random functions generated by "lutexact". 2024-11-05 22:01:07 -08:00
Alan Mishchenko 091ff4e7a9 Adding generation of random functions to "lutexact" 2024-11-05 19:23:04 -08:00
Alan Mishchenko ecd948027e Fixing assertion failures in &put. 2024-10-23 14:49:57 +07:00
Alan Mishchenko cb2140dc0c Adding PI/PO name transfer after mapping+retiming. 2024-10-21 20:37:52 +07:00
alanminko 743f3a7bdd
Merge pull request #250 from wjrforcyber/typo
Refactor(Typo):Typo currently exists
2024-10-21 01:54:12 -07:00
alanminko 498ec539e6
Merge pull request #340 from aletempiac/acd_improvements
Performance improvements to ACD
2024-10-21 01:39:32 -07:00
alanminko a239dd8c0b
Merge pull request #328 from heshpdx/master
Perf improvement in satsolver
2024-10-21 01:38:40 -07:00
Alan Mishchenko f1773bd612 Procedure to detect node equivalences across two AIGs. 2024-10-21 15:15:08 +07:00
Alan Mishchenko 74e7c64662 Bug fix in &scorr 2024-10-21 13:16:29 +07:00
aletempiac baf4ddb16a Bug fix (just in the code; it does not affect the execution) 2024-10-15 19:04:49 +02:00
aletempiac d1f78b36cb Bug fix (just in the code; it does not affect the execution) 2024-10-15 19:00:45 +02:00
aletempiac 52c842b648 Cleaning code 2024-10-15 17:54:38 +02:00
aletempiac 46f2300b7b Performance improvements in ACD 2024-10-15 14:45:09 +02:00
Alan Mishchenko 707442e091 Bug fix in &scorr. 2024-10-08 10:01:29 +07:00
Alan Mishchenko cac8f99eaa Revert "Merge pull request #247 from QuantamHD/abc_unit_tests"
This reverts commit d91a2a049a, reversing
changes made to 475c8dad8e.

(cherry picked from commit 4222921d61)
2024-10-07 11:06:41 +02:00
Alan Mishchenko 2e3384390a Updating "lutexact" to run on symmetric functions. 2024-10-07 14:10:02 +07:00
Martin Povišer 745ea92718 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2024-10-03 16:12:07 +02:00
Alan Mishchenko af1de4fa9c Improved bit-blasting of some word-level operators. 2024-10-01 20:34:58 +07:00
Alan Mishchenko a78d358e1c Extending &funtrace to dump and load precomputed library. 2024-10-01 20:33:01 +07:00
Alan Mishchenko 6004b7b21e Adding API for inserting danginling flop. 2024-10-01 15:55:45 +07:00
Alan Mishchenko 4369321167 Bug fix. 2024-09-28 22:39:10 +02:00
alanminko 9539306436
Merge pull request #334 from mikesinouye/multilib
Increase buffer size in filename append utility to support more liberty files.
2024-09-22 20:48:15 -07:00
alanminko 3f7a30828f
Merge pull request #335 from MyskYko/fix_ttopt
ttopt bugfix
2024-09-22 20:47:59 -07:00
Yukio Miyasaka 35a8768c50 ttopt bugfix 2024-09-22 14:34:18 -07:00
Mike Inouye 8179c73e62 Try support for Windows again.
Signed-off-by: Mike Inouye <mikeinouye@google.com>
2024-09-18 23:46:28 +00:00
Mike Inouye 5bd52161cd Add #include <stdlib.h> for Windows build support.
Signed-off-by: Mike Inouye <mikeinouye@google.com>
2024-09-18 23:29:11 +00:00
Mike Inouye ee5acbbc01 Use <limits.h>'s PATH_MAX macro instead of fixed size.
Signed-off-by: Mike Inouye <mikeinouye@google.com>
2024-09-18 23:05:32 +00:00
Mike Inouye db735b632f Increase buffer size in filename append utility to support more liberty files.
Signed-off-by: Mike Inouye <mikeinouye@google.com>
2024-09-18 22:24:41 +00:00
alanminko db245f59bd
Merge pull request #333 from sterin/master
Resolve problems with GitHub Actions
2024-09-15 15:49:53 -07:00
Baruch Sterin 4c4e298fad GitHub Actions: updated cmake to use macos-latest instead of macos-11 2024-09-16 01:11:19 +03:00
Baruch Sterin 0a5057f8d3 github actions:
* upgrade upload-artifact action to v4 as v1 was deprectated long time
  go and now removed, and make sure artifact names are distinct as
  required by the new version.

* upgrade checkout action to v4 as v2 is deprecated
2024-09-15 01:14:51 +03:00
Alan Mishchenko 9c152b71e9 Trasferring equivalence in the special-case usage of &scorr. 2024-09-12 18:11:59 -07:00
Alan Mishchenko 0d10253bd0 Another way of writing primary outputs in Verilog. 2024-09-06 06:27:53 -07:00
Alan Mishchenko 3ddd46131c Updating "read_lib" to output all gates when gain-based modeling is used. 2024-09-05 17:53:13 -07:00
Alan Mishchenko 3de73f2756 Updating internal cut manager to prefer cuts with high fanin fanout counts. 2024-09-05 13:27:17 -07:00
Alan Mishchenko 03d92930fa Updating &funtrace to trace function of the primary outputs of the AIG. 2024-09-03 17:16:48 -07:00
Mahesh Madhav ad8f8a2aab Convert the other divide to a multiply 2024-09-03 04:48:07 +00:00
Mahesh Madhav cd711089d7 Perf improvement in satsolver
Switch one FP divide to an FP multiply (variable is constant).
Calculate ratio inside of verbosity clause, since that is where it is used.
2024-09-03 04:30:14 +00:00
alanminko 5d6a568c9e
Merge pull request #327 from YosysHQ/povik/aiger-cell-mapping
Save cell mapping as new 'M' AIGER extension
2024-08-28 13:23:17 -07:00
Martin Povišer 786a39a294 Make casts explicit 2024-08-28 22:09:34 +02:00
alanminko 9371696a7b
Merge pull request #326 from wjrforcyber/resub_markB
Refactor(Resub): Clear markA/B at the beginning
2024-08-28 12:05:40 -07:00
Martin Povišer cb294bbebc Save cell mapping as new 'M' AIGER extension 2024-08-28 16:21:10 +02:00
wjrforcyber 252afb1521
Refactor(Resub): Clear mark A/B 2024-08-28 16:51:33 +08:00
wjrforcyber bcf292fdeb
Refactor(Resub): Clear markB at the beginning 2024-08-28 15:41:09 +08:00
alanminko 64ed5b81a4
Merge pull request #323 from rocallahan/workflow-name
Rename Github Actions job to `build-posix-cmake`
2024-08-24 09:22:08 -07:00
alanminko 034492b0e2
Merge pull request #322 from rocallahan/unit-tests
Adds unit testing framework to ABC
2024-08-24 09:21:50 -07:00
Robert O'Callahan d93a12ebee Rename Github Actions job to `build-posix-cmake`
Clarify that it belongs to the `build-posix-cmake` workflow, not the
`build-posix` workflow.
2024-08-23 04:12:04 +00:00
Ethan Mahintorabi 49a489554b Adds unit testing framework to ABC
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2024-08-23 04:09:00 +00:00
Alan Mishchenko af77b80194 Regrouping recently added code. 2024-08-18 13:57:35 -07:00
Alan Mishchenko 5e35510e25 New APIs for AIG package. 2024-08-18 13:12:08 -07:00
Alan Mishchenko 03b786af99 Experiments with adder-based circuits. 2024-08-17 16:26:20 -07:00
Alan Mishchenko 732abf5b48 Compiler warnings. 2024-08-16 21:35:10 -07:00
Alan Mishchenko 2055b1b490 Adding an option to dump satisfying assignments into a BLIF file. 2024-08-14 14:41:35 -07:00
Alan Mishchenko c099e62032 Adding a switch to complement the primary outputs of an AIG. 2024-08-14 13:40:52 -07:00
Alan Mishchenko 1a62954eb8 Adding command to read ROM data. 2024-08-14 12:56:10 -07:00
Alan Mishchenko e2b7750d3b Experiments with bit-blasting. 2024-08-14 11:40:41 -07:00
Alan Mishchenko c2391686ea Adding BLIF dumping to "lutexact". 2024-08-13 20:03:18 -07:00
alanminko 324ceeaa08
Merge pull request #320 from YosysHQ/povik/revert-pdr
Revert recent PDR changes
2024-08-12 17:17:24 -07:00
Alan Mishchenko 81fcf8494e Updating "lutexact" to support single-rail LUT cascade. 2024-08-12 16:26:55 -07:00
Martin Povišer de8620d777 Revert "pdr -X to write CEXes immediately"
This reverts commit e62e8ac528.
2024-08-12 22:53:53 +02:00
Martin Povišer 39f6fbb052 Revert "Fix pdr timing output"
This reverts commit c8d64b8682.
2024-08-12 22:53:48 +02:00
Martin Povišer ec8419c84b Revert "Improved anytime pdr"
This reverts commit 5444cf281c.
2024-08-12 22:53:40 +02:00
Alan Mishchenko 807f6ddacf Experiments with detecting multipliers. 2024-08-10 19:24:00 -07:00
Alan Mishchenko e824cca0ca Fixing a serious bug in bit-blasting when multiplier argments have different bit-width. 2024-08-10 19:13:50 -07:00
Alan Mishchenko 71c4e23f97 Adding cut print-out in &funtrace. 2024-08-10 19:12:19 -07:00
Alan Mishchenko 35a1bbbdb4 Ongoing development related to Boolean decomposition. 2024-08-09 18:33:36 -07:00
Alan Mishchenko 4156a88dbb Extending &funtrace to trace functions found in an AIG. 2024-08-09 12:39:43 -07:00
alanminko 71b409b778
Merge pull request #319 from YosysHQ/povik/rm-buffering-asserts
Remove extra asserts in buffering code
2024-08-08 15:00:20 -07:00
alanminko 762a123edc
Merge pull request #318 from YosysHQ/povik/fix-atomic_store-call
Fix types in call to atomic_store_explicit
2024-08-08 15:00:05 -07:00
alanminko dce6e4899b
Merge pull request #317 from YosysHQ/povik/fix-transfer-timing
Handle edge case in Gia_ManTransferTiming
2024-08-08 14:59:49 -07:00
alanminko 0129b4c60a
Merge pull request #316 from YosysHQ/povik/yosyshq-commands
Pull command changes from YosysHQ fork
2024-08-08 14:59:31 -07:00
alanminko e6b36cb5da
Merge pull request #315 from YosysHQ/povik/yosyshq-build
Pull build-related changes from YosysHQ fork
2024-08-08 14:58:42 -07:00
Martin Povišer 2188bc7122 Merge branch 'povik/fix-atomic_store-call' into yosys-experimental 2024-08-08 17:31:10 +02:00
Martin Povišer 57f93e6627 Merge branch 'povik/fix-transfer-timing' into yosys-experimental 2024-08-08 17:28:12 +02:00
Alan Mishchenko 95f1837960 Ongoing development related to Boolean decomposition. 2024-08-07 10:07:39 -07:00
Martin Povišer 2d267786d7 Include `stdbool.h` for portability of atomic calls 2024-08-07 18:13:45 +02:00
Martin Povišer 2a8ea11ce0 Remove extra asserts in buffering code 2024-08-07 18:04:35 +02:00
Martin Povišer f0b070ef70 Fix types in call to atomic_store_explicit
Deals with the following compilation error:

  src/misc/util/utilPth.c:106:9: error: no matching function for call to 'atomic_store_explicit'
          atomic_store_explicit(&pThData->fWorking, 0, memory_order_release);
          ^~~~~~~~~~~~~~~~~~~~~
  ... /include/c++/v1/atomic:1911:1: note: candidate template ignored: deduced conflicting types for parameter '_Tp' ('bool' vs. 'int')
  atomic_store_explicit(volatile atomic<_Tp>* __o, _Tp __d, memory_order __m) _NOEXCEPT
  ^
2024-08-07 18:00:17 +02:00
Martin Povišer afbeccb79e Handle edge case in Gia_ManTransferTiming 2024-08-07 17:35:20 +02:00
Jannis Harder 5444cf281c Improved anytime pdr
(cherry picked from commit c832967200)
2024-08-07 15:46:44 +02:00
Jannis Harder c8d64b8682 Fix pdr timing output
(cherry picked from commit acbe1b1f03)
2024-08-07 15:46:44 +02:00
Jannis Harder e62e8ac528 pdr -X to write CEXes immediately
(cherry picked from commit f63471bdf5)
2024-08-07 15:46:44 +02:00
Miodrag Milanovic e334586ae4 Additional fix for large liberty files
(cherry picked from commit ab5b16ede2)
2024-08-07 15:46:43 +02:00
David A Roberts 3e65b25942 Apply patch to If_ObjPerformMappingChoice too
(cherry picked from commit accf50468a)
2024-08-07 15:46:43 +02:00
David A Roberts eef8c01340 Fix Assertion using &if: `pCutSet->nCuts > 0'
(cherry picked from commit 316eec6d3f)
2024-08-07 15:46:43 +02:00
Martin Povišer 1383c76464 Pull YosysHQ read_cex/write_cex changes
See

 - YosysHQ/abc#19
 - YosysHQ/abc#16
 - commit 6234e18d
 - YosysHQ/abc#14
 - YosysHQ/abc#12
 - YosysHQ/abc#11

Co-authored-by: Jannis Harder <me@jix.one>
Co-authored-by: Claire Xenia Wolf <claire@clairexen.net>
Co-authored-by: Miodrag Milanovic <mmicko@gmail.com>
2024-08-07 15:46:43 +02:00
Jade Lovelace 68c99247bd Fix archive reproducibility
The git archive export-subst option does not have consistent results
over time, since the abbreviated commit hash can get longer over time.

Instead, let's export the full commit hash.

This was found in an audit of source archive reproducibility in nixpkgs:

```
~ » expected=$(nix-store -r /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source)
actual=$(nix-prefetch-url --print-path --unpack --name source 896e5e7ded.tar.gz | tail -n1)
nix-shell -p diffoscope --run "diffoscope $expected $actual"
this path will be fetched (3.77 MiB download, 34.50 MiB unpacked):
  /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source
copying path '/nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source' from 'https://cache.nixos.org'...
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
--- /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source
+++ /nix/store/v7ms5ghibzi8pk71nzlhvsbn7a0rdpy7-source
│   --- /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source/.gitcommit
├── +++ /nix/store/v7ms5ghibzi8pk71nzlhvsbn7a0rdpy7-source/.gitcommit
│ @@ -1 +1 @@
│ -896e5e7de
│ +896e5e7ded
│ ├── stat {}
│ │ @@ -1,7 +1,7 @@
│ │
│ │ -  Size: 10        	Blocks: 1          IO Block: 512    regular file
│ │ +  Size: 11        	Blocks: 1          IO Block: 512    regular file
│ │  Device: 0,24	Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
│ │
│ │  Modify: 1970-01-01 00:00:01.000000000 +0000
```

(cherry picked from commit 04f50406fd)
2024-08-07 15:40:04 +02:00
Jannis Harder adbcb914b2 Add '-p' option to 'constr' to allow fully removing constraints
Invoking 'constr -r' converts constraints into POs but does not fully
remove them. Now 'constr -pr' can be used to completely remove them,
leaving the set of non-constraint POs unchanged.

(cherry picked from commit 8c923ad492)
2024-08-07 14:51:38 +02:00
Martin Povišer 57c3bd36f2 Patch to support WASI builds
Co-authored-by: whitequark <whitequark@whitequark.org>
2024-08-07 14:49:13 +02:00
Jannis Harder 6d52a1e449 fold: Option (-s) to make sequential cleanup optional
(cherry picked from commit 1bd088d027)
2024-08-07 14:47:00 +02:00
Mohamed A. Bamakhrama 15ec302095 Define S_IREAD|IWRITE macros using IRUSR|IWUSR
On platforms such as Android, legacy macros are no longer defined.
Hence, we define them in terms of the new POSIX macros if the new ones are defined. Otherwise, we throw an error.

Signed-off-by: Mohamed A. Bamakhrama <mohamed@alumni.tum.de>
Signed-off-by: Miodrag Milanovic <mmicko@gmail.com>
(cherry picked from commit e792072f8a)
2024-08-07 14:40:26 +02:00
Miodrag Milanovic 23435fc8bf Export version
(cherry picked from commit 4e89fc7ccb)
2024-08-07 14:34:42 +02:00
Sean Cross 10b9da7acb Makefile: break apart steps in `make clean`
The `make clean` target consists of a single `rm` call that passes every
generated file, object file, and dependency directory.  This results in
a command line that's around 53,800 characters long.

On Linux, the maximum length of a command line is 131,072 or 262,144
characters, however on Windows the limit is 32,768.

The 53,800 character command simply fails to run on Windows, which is a
problem when the first command that gets run is `make clean`.

Break this target into steps, first removing the output files, then the
object files, then any generated garbage, and then the object depedency
directories.

This fixes `make clean` (and as a result yosys) on Windows.

Signed-off-by: Sean Cross <sean@xobs.io>
(cherry picked from commit 11c4f998b2)
2024-08-07 14:34:16 +02:00
Roland Coeurjoly a692c0da48 Support out of tree builds
(cherry picked from commit 2c52e3f969)
2024-08-07 14:32:25 +02:00
Jason Thorpe f5f317d7d2 Skip -ldl on NetBSD; it does not exist. Skip -lrt on NetBSD; it is
not required.  Same treatment as FreeBSD.

(cherry picked from commit ecce27ce1d)
2024-08-07 14:31:59 +02:00
Josuah Demangeon fe0bb59baa do not include -lrt or -ldl on platform that do not support them
Some platforms were already listed, this includes OpenBSD to the list
and makes it easier to add more.

(cherry picked from commit b6c0b36c8a)
2024-08-07 14:31:48 +02:00
Martin Povišer bf64a92253 Merge remote-tracking branch 'upstream/master' into yosys-experimental 2024-08-07 12:57:53 +02:00
alanminko b23f998b81
Merge pull request #313 from rocallahan/no-exceptions
Instead of throwing C++ exceptions, just print an error message and a…
2024-08-06 11:58:26 -07:00
Alan Mishchenko 43adbc77e8 New command for LUT cascade decomposition. 2024-08-06 11:50:54 -07:00
Robert O'Callahan e0a9c29e5a Instead of throwing C++ exceptions, just print an error message and abort
Many C++ projects forbid the use of exceptions. These are not recoverable
errors anyway, so just abort.
2024-08-06 17:51:15 +00:00
Alan Mishchenko 1963422c10 Experiments with detecting multipliers. 2024-08-05 20:18:30 -07:00
Alan Mishchenko 037971d9c9 Migrating &stochsyn to generic concurrency interface. 2024-08-03 18:12:03 -07:00
Alan Mishchenko 43426f0a94 Updates to history printing. 2024-08-03 15:35:19 -07:00
Alan Mishchenko b25d9c482a Changing interface of &genrel. 2024-08-02 18:30:09 -07:00
Alan Mishchenko 7d88bf21e9 New command to detect presence of a function in the AIG. 2024-08-02 14:34:57 -07:00
alanminko 3286179c48
Merge pull request #307 from rocallahan/exor-defines
Using `#define` for short/common names like `BPI` and `DIFFERENT` can…
2024-08-01 19:24:51 -07:00
Alan Mishchenko 1ac5f6467b Compiler warning. 2024-08-01 19:23:38 -07:00
Alan Mishchenko 8f0cbbdf38 Compiler warning. 2024-08-01 18:36:32 -07:00
Alan Mishchenko 1954e2fcaa Updating DSD profiling procedures. 2024-08-01 18:36:20 -07:00
Robert O'Callahan ab858c5435 Replace `#define`s with enum constants and inline functions in `exor.h`
This avoids issues with short/common identifiers like `BPI`
and `DIFFERENT` colliding with identifiers used in other projects.
2024-08-02 01:07:40 +00:00
Robert O'Callahan 53c25250a4 Remove support for `int` sizes other than 32 bits
No viable platform uses anything other than 32 bits for `int`.
2024-08-02 01:07:40 +00:00
Alan Mishchenko 9f864ebe76 Trying to fix the compilation issue. 2024-07-31 22:25:01 -07:00
Alan Mishchenko c62bfec2fd Trying to fix the compilation issue. 2024-07-31 21:56:08 -07:00
Alan Mishchenko 3491773f2a Suggested changes to improve thread safety. 2024-07-31 19:05:37 -07:00
alanminko a06dde4cf0
Merge pull request #309 from coastalwhite/chore-popcount-intrinsics
chore: `__builtin_popcount` to replace BitCount8
2024-07-31 18:44:58 -07:00
alanminko 279a909a05
Merge pull request #310 from QuantamHD/ethan_fixing_things_2
Adds option to unmap network using a non static version of the library
2024-07-31 18:31:26 -07:00
Alan Mishchenko 35d67f6c90 The same problem in another place. 2024-07-31 18:03:38 -07:00
Alan Mishchenko 4f68f08a7b Compilation problem. 2024-07-31 17:44:19 -07:00
Alan Mishchenko 9062ed964c Experiments with circuit generators. 2024-07-31 17:39:11 -07:00
Alan Mishchenko 572b80b230 Updating windows makefile by removing unused package. 2024-07-31 17:36:46 -07:00
Ethan Mahintorabi 70563cd441
Adds option to unamap network using a non static version of the library
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2024-07-31 22:19:43 +00:00
Alan Mishchenko 2011cbced9 One more file to be committed. 2024-07-28 15:26:19 -07:00
Alan Mishchenko 96edf40d60 Allow for disabling variable ordering in "lutmin". 2024-07-28 15:25:22 -07:00
Alan Mishchenko 3e1979f3c6 Experimental features of &scorr. 2024-07-28 13:00:32 -07:00
Alan Mishchenko 93388c0d26 Experiments with DSD. 2024-07-27 14:48:02 -07:00
coastalwhite 849adb2fcb chore: add `__builtin_popcount` for MSVC 2024-07-26 21:48:53 +02:00
Alan Mishchenko b5f4afa73b Duplicating AIG after synthesis. 2024-07-26 09:10:39 -07:00
Alan Mishchenko f8a6432d75 Implementation of functional abstraction. 2024-07-24 20:23:07 -07:00
coastalwhite fe3b5bf5fe chore: `__builtin_popcount` to replace BitCount8
This replaces all occurrences of the `BitCount8` static array with the
`__builtin_popcount`. It is a rather simple and small PR.

Fixes #308.
2024-07-24 21:46:03 +02:00
alanminko 6262dcffa9
Merge pull request #303 from rocallahan/signed-lbool
Make `lbool` explicitly signed
2024-07-24 09:48:03 -07:00
Alan Mishchenko d036ba520e Updating usage messages of QBF commands. 2024-07-24 09:46:56 -07:00
Alan Mishchenko 5450779250 Improved SOP to BDD conversion. 2024-07-21 16:46:39 -07:00
Alan Mishchenko d7a623c151 New API for swicthing activity estimation. 2024-07-17 15:15:49 -07:00
Alan Mishchenko c7ac6be504 Updating parameters. 2024-07-12 07:28:20 -07:00
Alan Mishchenko ae2e3f90f7 Adding command &genmux. 2024-07-11 22:23:06 -07:00
Alan Mishchenko 13998baf97 Allowing the genlib reader to skip gates larger than the given size. 2024-07-10 12:59:10 -07:00
Emil J 28d955ca97
Merge pull request #35 from lf-/jade/fix-gitarchive
Fix archive reproducibility
2024-07-08 19:02:21 +02:00
Robert O'Callahan 6c6260465e Make `lbool` explicitly signed
This avoids issues due to some platforms making `char` signed and others
unsigned. For example, currently the result of promoting `(lbool)-1` to `int`
can differ on different platforms. See
50ffa10848/lib/bill/bill/sat/interface/abc_bsat2.hpp (L156)
for an example of that.
2024-06-28 01:07:10 +00:00
Jade Lovelace 04f50406fd Fix archive reproducibility
The git archive export-subst option does not have consistent results
over time, since the abbreviated commit hash can get longer over time.

Instead, let's export the full commit hash.

This was found in an audit of source archive reproducibility in nixpkgs:

```
~ » expected=$(nix-store -r /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source)
actual=$(nix-prefetch-url --print-path --unpack --name source 896e5e7ded.tar.gz | tail -n1)
nix-shell -p diffoscope --run "diffoscope $expected $actual"
this path will be fetched (3.77 MiB download, 34.50 MiB unpacked):
  /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source
copying path '/nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source' from 'https://cache.nixos.org'...
warning: you did not specify '--add-root'; the result might be removed by the garbage collector
--- /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source
+++ /nix/store/v7ms5ghibzi8pk71nzlhvsbn7a0rdpy7-source
│   --- /nix/store/4j9rj4m6akjskp0f7k923qff817k6hv5-source/.gitcommit
├── +++ /nix/store/v7ms5ghibzi8pk71nzlhvsbn7a0rdpy7-source/.gitcommit
│ @@ -1 +1 @@
│ -896e5e7de
│ +896e5e7ded
│ ├── stat {}
│ │ @@ -1,7 +1,7 @@
│ │
│ │ -  Size: 10        	Blocks: 1          IO Block: 512    regular file
│ │ +  Size: 11        	Blocks: 1          IO Block: 512    regular file
│ │  Device: 0,24	Access: (0444/-r--r--r--)  Uid: (    0/    root)   Gid: (    0/    root)
│ │
│ │  Modify: 1970-01-01 00:00:01.000000000 +0000
```
2024-06-27 13:41:10 -07:00
Alan Mishchenko 2d70debd07 Corner-case bug fix. 2024-06-18 23:01:03 +08:00
alanminko 7beda11621
Merge pull request #302 from mikesinouye/scl
Change Scl_Pair_t_ membes to long to enable larger liberty file loading.
2024-06-17 10:12:12 +02:00
Alan Mishchenko 24d420370a Adding switch "i" in "show" to display original AIG IDs of mapped nodes. 2024-06-16 17:49:39 +08:00
Mike Inouye a6bf51111f Change Scl_Pair_t_ member types to long to allow for large liberty file loading.
Signed-off-by: Mike Inouye <mikeinouye@google.com>
2024-06-13 23:12:45 +00:00
Alan Mishchenko 806a996b88 Updating the print-out after the bug fix. 2024-05-30 08:43:58 +02:00
Alan Mishchenko 17b1ec7655 Bug fix. 2024-05-29 22:05:40 +02:00
Alan Mishchenko fb4988bb13 New API to print internal nodes. 2024-05-28 22:23:07 +02:00
alanminko 1e58dc6b00
Merge pull request #299 from moonshotxx/test
Utility functions in aig/gia
2024-05-23 17:53:11 -07:00
Xiaoqing Xu 34c2ed73a2 up stream changes 2024-05-23 22:51:15 +00:00
Alan Mishchenko 161963a32b Merge branch 'master' of github.com:berkeley-abc/abc 2024-05-23 15:28:22 -07:00
alanminko 6e459faa0e
Merge pull request #289 from sirandreww/master
Fixed small issue with time stats for generalization in PDR
2024-05-23 15:25:40 -07:00
Alan Mishchenko 795fee8d57 Bug fix in &genrel. 2024-05-23 13:51:10 -07:00
Alan Mishchenko 23f351c7c6 Bug fix in word-level abstraction. 2024-05-23 07:47:30 -07:00
Alan Mishchenko 111867432c Compilation problem. 2024-05-21 10:26:01 -07:00
Alan Mishchenko 0cb945ebcd Enabling support of boxes in &nf. 2024-05-21 10:15:46 -07:00
Alan Mishchenko 8ec95e85c6 Bug fix. 2024-05-19 15:03:12 -07:00
Alan Mishchenko c64f927828 Various changes and bug fixes. 2024-05-19 14:47:18 -07:00
Alan Mishchenko 3616fd8fb5 New command "resub_unate" and various changes. 2024-05-17 02:56:33 -07:00
Alan Mishchenko 9a89447de4 Updating instructions for AIG construction. 2024-05-16 08:59:18 -07:00
Alan Mishchenko 3fd42912ad Suggested fix. 2024-05-16 06:24:18 -07:00
Alan Mishchenko 5fc62b881f Code to dump resub instances. 2024-05-15 22:21:22 -07:00
Alan Mishchenko d9a08eb44b New command &window to extract windows from an AIG. 2024-05-15 21:41:29 -07:00
Alan Mishchenko 2c02ae89a0 Updating the previous commit. 2024-05-15 09:41:14 -07:00
Alan Mishchenko c906dfb748 Upgrading "twoexact" to read relations in an updated format. 2024-05-15 09:33:57 -07:00
Alan Mishchenko 6ad6539c0f New command &genrel to generate relations for windows in the AIG. 2024-05-14 22:35:43 -07:00
Alan Mishchenko daf3313ce6 New aliases. 2024-05-13 23:31:50 -07:00
Alan Mishchenko 554da94ea6 New command &odc to study observability don't-cares. 2024-05-13 22:59:11 -07:00
Alan Mishchenko 66c7f67b96 New command "resub_core". 2024-05-13 21:31:28 -07:00
Alan Mishchenko f04f9c4353 Updating counter-example generation. 2024-05-08 23:45:14 -07:00
Alan Mishchenko c194c112ae New way to generate counter-examples. 2024-05-08 23:13:31 -07:00
Alan Mishchenko 3c56ccb8fb Add warning when trying to CEC AIGs with xor-gates. 2024-05-08 08:15:45 -07:00
William D. Jones 237d81397f Modify include guards in cmd.c so that Windows compilers don't compile Unix-only code. 2024-05-08 08:26:54 +02:00
alanminko ae92ea0214
Merge pull request #297 from aletempiac/yosys-flow
Integrating delay-driven LUT decomposition in &if
2024-05-07 06:43:53 -07:00
aletempiac d109372fb7 Adding delay-driven LUT decomposition to &if 2024-05-07 11:03:24 +02:00
Alan Mishchenko fb97997991 New command &putontop to create large AIGs. 2024-05-04 13:38:32 -07:00
alanminko 4865b58b19
Merge pull request #296 from QuantamHD/enable_actions_on_pull
Enables github actions on pull requests
2024-05-03 18:22:59 -07:00
alanminko 16ba7ed883
Merge pull request #295 from QuantamHD/revert_c++_downgrade
Reverts downgrade to c++11
2024-05-03 18:22:48 -07:00
alanminko 08301d00ed
Merge pull request #294 from QuantamHD/fix_wlc_blast
Fixes incorrect extern definition of Wlc_BlastMultiplier3
2024-05-03 18:22:33 -07:00
Ethan Mahintorabi 8afc83874f
add c++17 back to makefile for makefile only runs
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2024-05-04 01:13:09 +00:00
Ethan Mahintorabi 9ccb28ebc1
Enables github actions on pull requests
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2024-05-03 20:11:04 +00:00
Ethan Mahintorabi 0fc549d8b8
Reverts downgrade to c++11
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2024-05-03 05:24:02 +00:00
Ethan Mahintorabi 246337cdbe
Fixes incorrect extern definition of Wlc_BlastMultiplier3
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2024-05-03 01:55:31 +00:00
aletempiac 5708841672 Merge remote-tracking branch 'origin/master' into yosys-flow 2024-05-02 10:23:16 +02:00
aletempiac 714ab458b7 Adding deriving LUTs to if 2024-05-02 10:23:11 +02:00
aletempiac 39ed8b36d4 Cleaning code 2024-05-02 10:06:40 +02:00
alanminko 516c38bb44
Merge pull request #293 from QuantamHD/fix_duplicate_declaration
Fixes duplicate declaration of Abc_SclHasDelayInfo
2024-05-01 19:18:47 -07:00
Ethan Mahintorabi b7c7a6d98d
Fixes duplicate declaration of Abc_SclHasDelayInfo
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2024-05-02 02:15:59 +00:00
alanminko 848dc0da1b
Merge pull request #291 from cr1901/win-fix
Modify include guards in cmd.c so that Windows compilers don't compil…
2024-04-29 07:54:49 -07:00
William D. Jones 402c2579db Modify include guards in cmd.c so that Windows compilers don't compile Unix-only code. 2024-04-27 19:06:36 -04:00
Martin Povišer 03da96f12f Patch for lack of `system` on WASM 2024-04-23 13:49:12 +02:00
aletempiac 043a2ffcc6 Adding new XX decomposition to &if 2024-04-23 11:10:16 +02:00
Alan Mishchenko c14d5f3906 Dumping miter statistics. 2024-04-22 22:06:07 -04:00
alanminko 6699c07b92
Merge pull request #290 from YosysHQ/povik/fix-simrsb-decl
Fix prototype mismatch for `Gia_ManSimRsb`
2024-04-22 15:14:19 -04:00
Martin Povišer b502f00222 Fix prototype mismatch for `Gia_ManSimRsb` 2024-04-22 17:39:32 +02:00
Martin Povišer e6a3dc602c Fix prototype mismatch for `Gia_ManSimRsb` 2024-04-22 17:34:38 +02:00
Martin Povišer 208b48667f Merge branch 'master' of https://github.com/berkeley-abc/abc into yosys-experimental 2024-04-22 16:33:29 +02:00
Andrew Luka ac9cfc766a
Update pdrCore.c
Fixed issue with time stats for generalization in PDR
2024-04-21 10:55:52 +03:00
Roland Coeurjoly 2c52e3f969 Support out of tree builds 2024-04-18 04:49:09 +01:00
aletempiac 864f96b11e Adding decomposition of mapping into LUT structures before returning the result 2024-04-16 17:40:47 +02:00
alanminko 8a174ee865
Merge pull request #287 from gadfort/correct-prefix
ensure initial library writing also honors prefix
2024-04-16 06:22:46 -07:00
Peter Gadfort de060a26ad ensure initial library writing also honors prefix 2024-04-16 08:58:28 -04:00
Alan Mishchenko bc725b85de Bug fix in CNF generation for &glucose (three more places). 2024-04-15 20:29:38 -07:00
Alan Mishchenko 2d6b5c9adc Bug fix in CNF generation for &glucose. 2024-04-15 20:25:43 -07:00
Alan Mishchenko 99e0e37da6 Added switch -p in "read_lib" to skip writing cell prefix. 2024-04-14 09:51:00 -07:00
alanminko 682480e5e9
Merge pull request #285 from gadfort/add-lib-merging
add library merging flag to read_lib
2024-04-14 09:39:14 -07:00
Peter Gadfort 935c6a875d add missing flag to read_lib help 2024-04-12 13:49:44 -04:00
Peter Gadfort 1d90cafd54 add library merging flag to read_lib
Signed-off-by: Peter Gadfort <gadfort@zeroasic.com>
2024-04-12 13:27:58 -04:00
alanminko b10d000c7a
Merge pull request #284 from aletempiac/acd66
LUT structure mapping
2024-04-11 12:05:12 -07:00
aletempiac 045803dcb8 Merge remote-tracking branch 'origin/master' into acd66 2024-04-11 19:02:29 +02:00
aletempiac 0c905f873b Fixes 2024-04-11 19:01:05 +02:00
aletempiac 6052d10fde Adding new command if -U for 2-LUT decompositions under delay profile 2024-04-11 15:45:37 +02:00
aletempiac e8924e5534 Fixes and improvements 2024-04-11 15:44:52 +02:00
aletempiac 5b49724fcc removing acd666 2024-04-11 15:43:22 +02:00
Miodrag Milanović 1446b7549f
Merge pull request #29 from thorpej/dev/pkgsrc-patch-NetBSD-1
Fix building on NetBSD
2024-04-11 14:48:28 +02:00
N. Engelhardt 078afe9faa
Merge pull request #31 from davidar/fix-55
Fix Assertion using &if: `pCutSet->nCuts > 0'
2024-04-11 14:41:43 +02:00
N. Engelhardt ccc02c4400
Merge pull request #30 from povik/&mfs-fixes
Address some `&mfs` crashes
2024-04-11 14:41:24 +02:00
Alan Mishchenko ca78f5e6e5 Bug fix in the resub engine. 2024-04-11 05:05:52 -07:00
aletempiac 32bc1d4ab2 Cleaning and generalizing code 2024-04-11 11:31:28 +02:00
aletempiac 64fea5c4c2 Improving the performance and quality of acd66 2024-04-10 18:43:52 +02:00
aletempiac 6b5ebb3e76 Removing assertion when decomposing into LUTs smaller than 6 2024-04-10 18:42:52 +02:00
aletempiac 8f3447800c Support again decompositions into luts smaller than 6 2024-04-02 11:25:03 +02:00
David A Roberts accf50468a Apply patch to If_ObjPerformMappingChoice too 2024-04-01 10:03:10 +10:00
David A Roberts 316eec6d3f Fix Assertion using &if: `pCutSet->nCuts > 0' 2024-04-01 09:40:41 +10:00
Alan Mishchenko 6e1653426f Switch to randomly select one choice. 2024-03-28 16:22:06 +08:00
Alan Mishchenko a2cb5eb4e3 Adding command &pms to print miter status. 2024-03-25 23:39:03 +08:00
aletempiac 1f72ffce79 Improving ACD performance with bail-out conditions 2024-03-25 14:23:43 +01:00
Alan Mishchenko b0d2ff1c63 Exact synthesis using NAND-gates. 2024-03-24 00:10:08 +09:00
Martin Povišer 1107634fa6 &mfs: Make it no biggie when a network is all blackboxes, no whiteboxes 2024-03-22 22:47:40 +01:00
Martin Povišer d7fc8fe98f &mfs: Handle blackboxes robustly
When the network is being handed over to the "sfm" core, all blackboxes
are modeled by inserting new PIs, POs, and those being connected by
buffers to the nodes representing the CIs, COs. Make two changes:

 * Robustly deny the fake PIs from being considered when shopping for
   LUT fanin substitutions. Such reconnection occurring would trip up
   the code reintegrating the result.

 * Make sure the buffer connecting the fake-PO to the CO doesn't get
   rewritten as part of the `mfs` transformation, and extend this
   protection to any whitebox models.
2024-03-22 22:43:08 +01:00
Martin Povišer fda490235e &mfs: Fix issues with traversal when re-importing network
The former implementation of `Sfm_NtkDfs` was trying to serialize the
network while ordering all box inputs ahead of the box outputs. This is
sometimes impossible, leaving the result unordered, which led to crashes
in the `&mfs` code when it was reintegrating the result into the GIA
structure:

  ABC: Assertion failed: iLitNew >= 0 (src/aig/gia/giaMfs.c: Gia_ManInsertMfs: 388)

With a small change to `Gia_ManInsertMfs` which does the reintegration
we don't really need the ordering to see through boxes, ordering on the
paths between boxes is sufficient. Relaxing the ordering requirement, we
make `Sfm_NtkDfs` robust.
2024-03-22 22:01:45 +01:00
Martin Povišer b83985c25b Add `&mfs -r` for re-import testing 2024-03-22 21:42:12 +01:00
aletempiac 6aacf524aa Performance improvement and fixes 2024-03-22 19:19:35 +01:00
aletempiac 8a314db8dc Bug fix 2024-03-22 15:39:52 +01:00
Alan Mishchenko 783a5404a2 Fixing Windows makefile. 2024-03-19 09:57:52 +09:00
Alan Mishchenko 2c0943ff62 Fixiing compiler problem on Windows. 2024-03-19 09:34:20 +09:00
Alan Mishchenko 5d3d77fcfe Fixing Windows compiler problem. 2024-03-19 08:54:32 +09:00
Alan Mishchenko c32f36af08 Fixing c vs c++ header file issue. 2024-03-19 08:13:07 +09:00
Alan Mishchenko b31ab1960b Fixing compilation issues on Windows. 2024-03-18 21:30:46 +09:00
Alan Mishchenko c0989e93f0 Fixing Makefile on Windows. 2024-03-18 20:37:46 +09:00
Alan Mishchenko 914b3e980f FIxing Windows makefile. 2024-03-18 19:50:00 +09:00
alanminko 4f0d09261b
Merge pull request #283 from aletempiac/acd66
Boolean decomposition into LUT structures
2024-03-18 19:29:37 +09:00
aletempiac db72df7a63 Merge remote-tracking branch 'origin/master' into acd66 2024-03-18 10:08:48 +01:00
aletempiac 3737a69d8d Adding new ACD66 with support for multiple shared-set variables 2024-03-18 10:01:59 +01:00
Alan Mishchenko 210474b08c Bug fix in &gen_hie. 2024-03-18 07:49:35 +09:00
alanminko 3040b8ddd5
Merge pull request #282 from allen1236/master
&brecover with speculative reduction
2024-03-16 08:52:57 +09:00
Allen Ho b7884aaf2b clean up & add options for &brecover 2024-03-16 01:40:11 +08:00
Allen Ho 015dd2a367 use speculative in &brecover 2024-03-15 16:56:10 +08:00
Alan Mishchenko a16a0f1027 Writing Verilog for AIG using NAND gates. 2024-03-06 01:40:48 -08:00
alanminko 8bfd49880e
Merge pull request #280 from allen1236/master
added command &brecover and modified &str_eco
2024-03-03 20:29:46 -08:00
Allen Ho c607fc3101 restore 2024-03-04 11:20:27 +08:00
Allen Ho 524699d6ab restore .gitignore, Makefile, and abc.rc 2024-03-04 11:19:46 +08:00
Allen Ho d87b1cd543 fixed some warnings in bsat2 2024-03-04 10:16:14 +08:00
Allen Ho bfbec71211 &stc_eco and &brecover done 2024-03-04 09:36:35 +08:00
Allen Ho bcf04fadb6 &brecover done 2024-03-04 00:54:23 +08:00
Jason Thorpe ecce27ce1d Skip -ldl on NetBSD; it does not exist. Skip -lrt on NetBSD; it is
not required.  Same treatment as FreeBSD.
2024-03-03 08:02:41 -08:00
Alan Mishchenko a747f46292 More changes to compile with g++. 2024-03-02 17:21:05 -08:00
Alan Mishchenko eb24d29777 More changes. 2024-03-02 17:10:30 -08:00
Alan Mishchenko b73f1030a6 More changes. 2024-03-02 17:03:42 -08:00
Alan Mishchenko b627aa7cb5 More changes. 2024-03-02 16:57:00 -08:00
Alan Mishchenko ce44eda85a More changes. 2024-03-02 16:46:09 -08:00
Alan Mishchenko f6f542c873 More changes to compile with namespaces. 2024-03-02 16:38:16 -08:00
Alan Mishchenko 4de4605836 More changees to compile new code with namespaces. 2024-03-02 16:31:41 -08:00
Alan Mishchenko a1159d98df Fixing a compiler problem with namespaces. 2024-03-02 16:10:37 -08:00
alanminko 390a0e8ef3
Merge pull request #279 from allen1236/master
Sat-sweeping-based ECO (&str_eco)
2024-03-02 15:38:08 -08:00
Allen Ho 23654254e1 clean up 2024-03-03 03:06:13 +08:00
Allen Ho f5f4dca013 clean up 2024-03-02 21:08:10 +08:00
aletempiac cd407e2ba3 Activate use_first flag in acd_decompose 2024-03-01 10:05:30 +01:00
aletempiac 9bec2afd60 Removing -z flag to execute delay-driven ACD 2024-03-01 10:04:48 +01:00
Allen Ho 6f5656c188 shared EI/EO not handled yet 2024-03-01 16:05:41 +08:00
Alan Mishchenko 1fd79c8430 Fixing a bug in input/output name ordering. 2024-02-29 15:19:47 -08:00
aletempiac fa8a277765 Changing search space exploration of ACD to search for better implementation and prune unnecessary computations based on theoretical properties 2024-02-29 17:16:49 +01:00
aletempiac 48b5f3b399 ACD66 performance improvements by avoiding unnecessary computation 2024-02-29 17:15:29 +01:00
aletempiac 75abcd376b Adding bindings to use ACD66 instead of generic ACD 2024-02-28 09:51:32 +01:00
aletempiac 44a65c23ed Adding relaxation on the maximum free set constraint 2024-02-27 17:47:43 +01:00
aletempiac d3f140f1df Performance improvements 2024-02-27 17:36:24 +01:00
aletempiac f72000f5ae Adding ACD cascade 666, performance improvements 2024-02-21 18:25:48 +01:00
aletempiac eba56b088f Cleaning code and performance improvements 2024-02-21 17:13:29 +01:00
aletempiac 13fd0d55c7 Removing unnecessary structs 2024-02-21 09:47:16 +01:00
aletempiac 0cd548f1cb Performance improvements to ACD 2024-02-20 17:28:50 +01:00
aletempiac 0e471e3ff8 Performance improvements of ACD 66 2024-02-20 14:41:52 +01:00
aletempiac 7b74810047 Changing policy of finding ACD 66 decomposition (faster and 100 percent coverage) 2024-02-16 16:43:24 +01:00
aletempiac 17afd93c78 Extending ACD to work up to 11 variables 2024-02-08 15:36:09 +01:00
aletempiac 9eb32f0766 Changing compilation flag for c++11 2024-02-08 15:11:58 +01:00
aletempiac 3f80b202cd C++11 compatible code 2024-02-08 14:57:42 +01:00
aletempiac 2afaeac823 Adding hash table to reduce computations 2024-02-08 11:20:19 +01:00
aletempiac 2d9af6c9a4 Adding ACD for 66 LUT structure using a new method 2024-02-08 09:36:58 +01:00
Alan Mishchenko 52e0a10bf7 Fixing a compiler problem. 2024-02-05 20:49:36 -08:00
Alan Mishchenko e9a0bf6bf9 Adding reversing of simulation bits in &sim_read. 2024-02-05 20:32:11 -08:00
Alan Mishchenko d7ef3cc030 Bug fix in &fx. 2024-02-05 19:29:50 -08:00
Alan Mishchenko 62a22c7574 Bug fix in blasting multipliers with different argument bit-width. 2024-02-05 19:26:36 -08:00
Allen Ho c74144c6eb str_eco ver1 2024-02-01 07:25:46 +08:00
Alan Mishchenko 6d1d52deaa Adding an option to read the RTL elaboration library from the current directory. 2024-01-30 20:22:55 -08:00
Alan Mishchenko d6555f48dd Adding a switch to not write the timestamp in the AIGER file. 2024-01-26 07:31:20 -08:00
Alan Mishchenko 5fa9192412 Change how &stochsyn runs on a single core. 2024-01-18 18:34:50 -08:00
Alan Mishchenko 8da884de85 Switch to reverse the order of bits. 2024-01-18 18:23:11 -08:00
alanminko 922ee4f93d
Merge pull request #273 from sterin/master
Resolve build problems
2024-01-18 11:34:53 -08:00
Baruch Sterin 234af64a8c Workaround for C++17 compilation (on clang) 2024-01-18 09:58:18 -08:00
Baruch Sterin d140535d64 Adapt previous merge by @aletempiac to compile with ABC namespaces. 2024-01-17 15:04:31 -08:00
alanminko 9bdb8a7133
Merge pull request #272 from aletempiac/acd
LUT mapping with decomposition
2024-01-16 09:33:18 -08:00
aletempiac 5a00bbaa8f Cleaning Makefile 2024-01-16 18:13:30 +01:00
aletempiac d223898f3d Merge remote-tracking branch 'origin/master' into acd 2024-01-16 17:44:45 +01:00
aletempiac 67aab70cff Moving ACD package to if folder 2024-01-16 17:42:43 +01:00
Alan Mishchenko 5bc99574fc Eliminating dependency on "abc.rc" in "&deepsyn". 2024-01-12 22:54:44 -08:00
aletempiac 38e632a954 Consider buffers in matrix covering as free 2024-01-12 14:50:34 +01:00
Alan Mishchenko 8c7327b8df Recognizing interface of the module when writing Verilog. 2024-01-11 22:19:50 -08:00
Alan Mishchenko dc68fe27f9 Saving module interface. 2024-01-11 19:45:42 -08:00
aletempiac 7dcc10a254 Minor fixes 2024-01-10 15:18:39 +01:00
alanminko 7f0a319564
Merge pull request #269 from rmlarsen/speedup_scanning
Micro-optimizations to speed up the Liberty parser by ~1.67x.
2023-12-21 12:58:42 +09:00
Alan Mishchenko 5978ccdb52 Updating sleep command to wait for file. 2023-12-21 12:16:33 +09:00
Rasmus Munk Larsen 706112ebd8 Micro-optimizations to speed up the Liberty parser by ~1.67x.
Signed-off-by: Rasmus Munk Larsen <rmlarsen@google.com>
2023-12-19 16:13:52 -08:00
Alan Mishchenko 7fe92148cc New command to put computation to sleep. 2023-12-18 21:04:31 +09:00
Allen Ho 284b9d6a9c extended box report; 2023-12-10 21:30:46 +08:00
Alan Mishchenko 16a3c5fc30 Add copying names in &saveaig and &loadaig. 2023-12-09 21:53:48 +08:00
Allen Ho 9bb5333f62 extend bo 2023-12-07 19:07:52 +08:00
aletempiac b3d2419d9a Formatting, renaming, and cleaning code 2023-11-27 13:38:36 +01:00
aletempiac 6097fd4349 Code formatting 2023-11-24 14:24:20 +01:00
aletempiac 23cfcc1e1f Improving efficiency and removing useless code 2023-11-24 12:18:49 +01:00
aletempiac 43f4dccb4f run time improvements in computing the column multiplicity 2023-11-23 16:29:33 +01:00
Allen Ho a316847341 correct fanout count 2023-11-23 19:33:05 +08:00
aletempiac acdd08fd9b Performance improvements 2023-11-21 11:47:56 +01:00
aletempiac d10d450f38 Final implementation 2023-11-19 21:59:40 +01:00
aletempiac 219d6d86d6 Simplifying code 2023-11-19 19:33:19 +01:00
aletempiac 672fd1b629 removing not used methods 2023-11-19 18:53:54 +01:00
aletempiac f7a520b957 restructuring code 2023-11-19 18:51:50 +01:00
aletempiac 1d7dfd25c6 Improving ACD mapping 2023-11-17 16:58:17 +01:00
aletempiac 3d602e2f00 Adding sorting of columns in heuristic covering 2023-11-17 15:55:10 +01:00
aletempiac 1ca7a3a353 Remove symmetries in covering table 2023-11-17 15:49:29 +01:00
aletempiac b77bdeeb17 Enabling ACD for area 2023-11-16 19:21:29 +01:00
aletempiac 8aa57c5d54 Decisions on late arrival 2023-11-16 18:53:02 +01:00
aletempiac 548fd6afb2 New version of enumeration of combinations 2023-11-16 18:20:05 +01:00
aletempiac b32bbdfef3 Improving set covering using unitary cost 2023-11-16 15:33:19 +01:00
aletempiac dcc960beba Adding local search for covering 2023-11-15 21:57:29 +01:00
aletempiac c07080f818 Adding heuristic set covering solver 2023-11-15 21:32:34 +01:00
aletempiac 66cdd36d20 Runtime improvements in decomposition 2023-11-15 19:03:29 +01:00
aletempiac 1632dc0d4e First version of ACD 2023-11-15 18:38:00 +01:00
Alan Mishchenko 6ca7eab466 Prototype of integrating decomposition into "if". 2023-11-14 12:58:03 -08:00
Alan Mishchenko eb264c5d22 Suggested fixes. 2023-11-13 17:19:54 -08:00
WWFUG 67a2b97cf0 added -I options in &bmiter 2023-11-08 19:00:03 +08:00
Alan Mishchenko 04dba9eed9 Adding callback for wire caps during sizing. 2023-11-06 17:35:41 -08:00
Allen Ho 50010139ef why 2023-11-06 18:37:40 +08:00
Allen Ho ba64d6118b out-side box matching 2023-10-30 15:09:01 -07:00
Alan Mishchenko 5de12aa6b3 Experiments with SAT solving. 2023-10-23 11:30:44 -07:00
Alan Mishchenko 1bf21626c0 Bug fix. 2023-10-23 11:04:35 -07:00
Alan Mishchenko 76e8d21aaf Printout changes. 2023-10-23 10:48:43 -07:00
Alan Mishchenko 538ecb4515 Updating printouts. 2023-10-23 09:38:24 -07:00
Alan Mishchenko 01ad71b26f Experiments with verification. 2023-10-23 09:38:08 -07:00
Alan Mishchenko 8dbf8965fd Adding batch option to "scrgen". 2023-10-23 09:37:04 -07:00
Alan Mishchenko 652a0aaef7 Compiler warning. 2023-10-20 22:42:40 -07:00
Alan Mishchenko 72b423ba14 Experiments with SAT solving. 2023-10-20 20:53:43 -07:00
wjrforcyber c2fdb86a4d Refactor(Typo): Typo in ACD 2023-10-07 13:53:22 +08:00
wjrforcyber fb6a4722c2 Merge remote-tracking branch 'upstream/master' into typo 2023-10-07 13:50:29 +08:00
Alan Mishchenko 3c4c558656 Experiment with script generation. 2023-10-02 16:47:37 -07:00
Alan Mishchenko 65ccd3cc69 Enabled literal remapping. 2023-09-29 16:07:29 -07:00
Alan Mishchenko d971e3ecff Updating windows project file. 2023-09-28 07:17:42 -07:00
Alan Mishchenko cc636a0d83 Experiments with verification. 2023-09-28 06:40:57 -07:00
phsauter 6836863e55 Fix Segault in scl
Fixes a regression that was introduced in #232 by myself.
Reverts back to correct version introduced in #228.

This was likely introduced in a careless merge before creating PR #232.
2023-09-27 18:16:59 +02:00
wjrforcyber ecf6255985 Refactor(Typo):Missing a parameter fUseLutLib and use fSaveBest twice 2023-09-26 14:24:02 +08:00
Alan Mishchenko 0f11580fce Experiments with retiming. 2023-09-24 22:18:45 +08:00
wjrforcyber 3781c1df61 Refactor(Typo): Link is NOT FOUND page(not available), change to the book name 2023-09-24 19:31:37 +08:00
Alan Mishchenko 4d1618f600 Enable dumping Verilog with assign-statements. 2023-09-21 11:08:43 +08:00
Alan Mishchenko 73dac01c15 Warning regarding PathMatchSpec() on Windows. 2023-09-21 11:08:16 +08:00
Allen Ho 31ad17fa1a add abc9RecoverBoundary 2023-09-20 14:23:47 +08:00
Alan Mishchenko 7fd4b01fb3 Automatic script file generation. 2023-09-18 16:30:09 +08:00
Alan Mishchenko 09b0295c1a Adding aliases for some commands. 2023-09-18 16:27:54 +08:00
wjrforcyber eae19f7a62 Refactor(Typo): Typo in strash 2023-09-18 13:56:18 +08:00
wjrforcyber 05c897a753 Refactor(Typo): Typo in read_aiger 2023-09-17 19:34:56 +08:00
wjrforcyber e1db615384 Merge branch 'master' into typo 2023-09-17 13:28:57 +08:00
wjrforcyber 7ec8f17094 Refactor(Typo): Typo update in write_aiger message 2023-09-17 13:27:00 +08:00
Alan Mishchenko 9399faac48 Improvements to &gen_hie. 2023-09-17 12:40:33 +08:00
Alan Mishchenko da635a2995 Updating .gitignore. 2023-09-17 12:18:12 +08:00
Alan Mishchenko 2f5b81119b Experiments with retiming. 2023-09-17 12:17:27 +08:00
Alan Mishchenko 4222921d61 Revert "Merge pull request #247 from QuantamHD/abc_unit_tests"
This reverts commit d91a2a049a, reversing
changes made to 475c8dad8e.
2023-09-17 11:29:26 +08:00
wjrforcyber 6e1323caa2 Refactor(Typo): Typo update in bblif comment 2023-09-16 22:31:47 +08:00
wjrforcyber 136bae27d8 Refactor(Typo): Typo update in read_aiger comment 2023-09-16 19:43:03 +08:00
alanminko d91a2a049a
Merge pull request #247 from QuantamHD/abc_unit_tests
Adds unit testing framework to ABC
2023-09-16 15:41:56 +08:00
Alan Mishchenko 475c8dad8e Compiler problem. 2023-09-16 07:13:10 +08:00
alanminko 2800847a16
Merge pull request #249 from Yu-Maryland/master
AIG augmentation
2023-09-16 07:08:23 +08:00
Cunxi Yu 1261f71248
Merge branch 'berkeley-abc:master' into master 2023-09-15 13:25:27 -07:00
Alan Mishchenko 318d5cb54b Do not create spec outputs in the boundary miter. 2023-09-15 23:10:42 +08:00
Alan Mishchenko 57cc2bd089 Compiler problem. 2023-09-15 22:51:11 +08:00
Alan Mishchenko 09013f3a6e New command &gen_hie to generate hierarchical designs. 2023-09-15 22:44:31 +08:00
Ethan Mahintorabi 7d80ea5cf9
Adds unit testing framework to ABC
Signed-off-by: Ethan Mahintorabi <ethanmoon@google.com>
2023-09-13 18:24:01 +00:00
alanminko 79456fadde
Merge pull request #246 from wjrforcyber/typo
Refactor(Typo):Typo currently exists
2023-09-12 11:30:53 +07:00
wjrforcyber 3a53a950aa Refactor(Typo): Typo update on buffer 2023-09-12 11:57:18 +08:00
wjrforcyber 7fe7449685 Refactor(Typo):Typo update on dnsize 2023-09-12 10:40:59 +08:00
Cunxi Yu 3488a35472
Merge branch 'berkeley-abc:master' into master 2023-08-27 10:21:43 -07:00
CUNXI YU 855976c61d correct the naming of augmentation 2023-08-27 11:19:26 -06:00
CUNXI YU 0fe977a33c correct the naming of augmentation 2023-08-27 11:18:35 -06:00
Cunxi Yu 01f4eb9b43
Merge branch 'berkeley-abc:master' into master 2023-08-23 20:24:33 -06:00
lyj1201 0fab82384a add AIG random synthesis based RTL argumentation; command = aigarg 2023-08-14 12:04:33 -06:00
919 changed files with 247514 additions and 26304 deletions

View File

@ -1 +1 @@
$Format:%h$
$Format:%H$

63
.github/scripts/abcexe.vcxproj vendored Normal file
View File

@ -0,0 +1,63 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{6B6D7E0F-1234-4567-89AB-CDEF01234568}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>abcexe</RootNamespace>
<TargetName>abc</TargetName>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>Application</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>_TEST\</OutDir>
<IntDir>ReleaseExe\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;WINDOWS;NDEBUG;_CONSOLE;ABC_DLL=ABC_DLLEXPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ABC_USE_PTHREADS;ABC_USE_CUDD;HAVE_STRUCT_TIMESPEC;_WINSOCKAPI_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>src</AdditionalIncludeDirectories>
<AdditionalOptions>/Zc:strictStrings- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Link>
<SubSystem>Console</SubSystem>
<EnableCOMDATFolding>true</EnableCOMDATFolding>
<OptimizeReferences>true</OptimizeReferences>
<GenerateDebugInformation>true</GenerateDebugInformation>
<AdditionalDependencies>kernel32.lib;user32.lib;gdi32.lib;winspool.lib;comdlg32.lib;advapi32.lib;shell32.lib;ole32.lib;oleaut32.lib;uuid.lib;odbc32.lib;odbccp32.lib;lib\x86\pthreadVC2.lib;%(AdditionalDependencies)</AdditionalDependencies>
</Link>
</ItemDefinitionGroup>
<ItemGroup>
<ClCompile Include="src\base\main\main.c" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="abclib.vcxproj">
<Project>{6B6D7E0F-1234-4567-89AB-CDEF01234567}</Project>
</ProjectReference>
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

53
.github/scripts/abclib.vcxproj.template vendored Normal file
View File

@ -0,0 +1,53 @@
<?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Release|Win32">
<Configuration>Release</Configuration>
<Platform>Win32</Platform>
</ProjectConfiguration>
</ItemGroup>
<PropertyGroup Label="Globals">
<VCProjectVersion>17.0</VCProjectVersion>
<ProjectGuid>{6B6D7E0F-1234-4567-89AB-CDEF01234567}</ProjectGuid>
<Keyword>Win32Proj</Keyword>
<RootNamespace>abclib</RootNamespace>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.Default.props" />
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'" Label="Configuration">
<ConfigurationType>StaticLibrary</ConfigurationType>
<UseDebugLibraries>false</UseDebugLibraries>
<PlatformToolset>v143</PlatformToolset>
<WholeProgramOptimization>true</WholeProgramOptimization>
<CharacterSet>MultiByte</CharacterSet>
</PropertyGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.props" />
<ImportGroup Label="PropertySheets" Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<Import Project="$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props" Condition="exists('$(UserRootDir)\Microsoft.Cpp.$(Platform).user.props')" Label="LocalAppDataPlatform" />
</ImportGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<OutDir>lib\</OutDir>
<IntDir>ReleaseLib\</IntDir>
</PropertyGroup>
<ItemDefinitionGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<ClCompile>
<WarningLevel>Level3</WarningLevel>
<DisableSpecificWarnings>4146;4334;4996;4703;%(DisableSpecificWarnings)</DisableSpecificWarnings>
<TreatSpecificWarningsAsErrors>4013</TreatSpecificWarningsAsErrors>
<FunctionLevelLinking>true</FunctionLevelLinking>
<IntrinsicFunctions>true</IntrinsicFunctions>
<SDLCheck>true</SDLCheck>
<PreprocessorDefinitions>WIN32;WINDOWS;NDEBUG;_LIB;ABC_DLL=ABC_DLLEXPORT;_CRT_SECURE_NO_DEPRECATE;_CRT_NONSTDC_NO_WARNINGS;ABC_USE_PTHREADS;ABC_USE_CUDD;HAVE_STRUCT_TIMESPEC;_WINSOCKAPI_;%(PreprocessorDefinitions)</PreprocessorDefinitions>
<ConformanceMode>true</ConformanceMode>
<LanguageStandard>stdcpp17</LanguageStandard>
<AdditionalIncludeDirectories>src</AdditionalIncludeDirectories>
<AdditionalOptions>/Zc:strictStrings- %(AdditionalOptions)</AdditionalOptions>
</ClCompile>
<Lib>
<OutputFile>$(OutDir)abcr.lib</OutputFile>
</Lib>
</ItemDefinitionGroup>
<ItemGroup>
{{SOURCE_FILES}}
</ItemGroup>
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
</Project>

22
.github/scripts/abcspace.sln vendored Normal file
View File

@ -0,0 +1,22 @@
Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.0.31903.59
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abclib", "abclib.vcxproj", "{6B6D7E0F-1234-4567-89AB-CDEF01234567}"
EndProject
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "abcexe", "abcexe.vcxproj", "{6B6D7E0F-1234-4567-89AB-CDEF01234568}"
ProjectSection(ProjectDependencies) = postProject
{6B6D7E0F-1234-4567-89AB-CDEF01234567} = {6B6D7E0F-1234-4567-89AB-CDEF01234567}
EndProjectSection
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Release|Win32 = Release|Win32
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{6B6D7E0F-1234-4567-89AB-CDEF01234567}.Release|Win32.ActiveCfg = Release|Win32
{6B6D7E0F-1234-4567-89AB-CDEF01234567}.Release|Win32.Build.0 = Release|Win32
{6B6D7E0F-1234-4567-89AB-CDEF01234568}.Release|Win32.ActiveCfg = Release|Win32
{6B6D7E0F-1234-4567-89AB-CDEF01234568}.Release|Win32.Build.0 = Release|Win32
EndGlobalSection
EndGlobal

View File

@ -1,11 +1,15 @@
on: [push]
name: Build Posix CMake
on:
push:
pull_request:
jobs:
build-posix:
build-posix-cmake:
strategy:
matrix:
os: [macos-11, ubuntu-latest]
os: [macos-latest, ubuntu-latest]
use_namespace: [false, true]
runs-on: ${{ matrix.os }}
@ -18,7 +22,7 @@ jobs:
steps:
- name: Git Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: recursive
@ -40,6 +44,10 @@ jobs:
run: |
cmake --build build
- name: Run Unit Tests
run: |
ctest --output-on-failure
- name: Test Executable
run: |
./build/abc -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
@ -56,7 +64,7 @@ jobs:
cp build/abc build/libabc.a staging/
- name: Upload pacakge artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
with:
name: package
name: package-cmake-${{ matrix.os }}-${{ matrix.use_namespace }}
path: staging/

View File

@ -1,4 +1,8 @@
on: [push]
name: Build Posix
on:
push:
pull_request:
jobs:
@ -18,7 +22,7 @@ jobs:
steps:
- name: Git Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: recursive
@ -56,7 +60,7 @@ jobs:
cp abc libabc.a staging/
- name: Upload pacakge artifact
uses: actions/upload-artifact@v1
uses: actions/upload-artifact@v4
with:
name: package
name: package-posix-${{ matrix.os }}-${{ matrix.use_namespace }}
path: staging/

View File

@ -1,48 +1,78 @@
on: [push]
name: Build Windows
on:
push:
pull_request:
jobs:
build-windows:
runs-on: windows-2019
runs-on: windows-2025
steps:
- name: Git Checkout
uses: actions/checkout@v2
uses: actions/checkout@v4
with:
submodules: recursive
- name: Process project files to compile on Github Actions
run: |
sed -i 's#ABC_USE_PTHREADS\"#ABC_DONT_USE_PTHREADS\" /D \"_ALLOW_KEYWORD_MACROS=1\"#g' *.dsp
awk 'BEGIN { del=0; } /# Begin Group "uap"/ { del=1; } /# End Group/ { if( del > 0 ) {del=0; next;} } del==0 {print;} ' abclib.dsp > tmp.dsp
copy tmp.dsp abclib.dsp
del tmp.dsp
unix2dos *.dsp
- name: Prepare MSVC
uses: bus1/cabuild/action/msdevshell@v1
- name: Setup MSVC
uses: ilammy/msvc-dev-cmd@v1
with:
architecture: x86
arch: x86
- name: Upgrade project files to latest Visual Studio, ignoring upgrade errors, and build
- name: Copy project files from scripts
run: |
devenv abcspace.dsw /upgrade ; if (-not $? ) { cat UpgradeLog.htm }
msbuild abcspace.sln /m /nologo /p:Configuration=Release /p:PlatformTarget=x86
copy .github\scripts\abcspace.sln .
copy .github\scripts\abcexe.vcxproj .
- name: Generate abclib.vcxproj from dsp
shell: powershell
run: |
# Parse source files from abclib.dsp
$dspContent = Get-Content "abclib.dsp" -Raw
$sourceFiles = [regex]::Matches($dspContent, 'SOURCE=\.\\([^\r\n]+)') | ForEach-Object { $_.Groups[1].Value } | Sort-Object -Unique
Write-Host "Found $($sourceFiles.Count) source files"
# Build source file items
$sourceItems = ""
foreach ($src in $sourceFiles) {
if ($src -match '\.c$') {
$sourceItems += " <ClCompile Include=`"$src`" />`r`n"
} elseif ($src -match '\.(cpp|cc)$') {
$sourceItems += " <ClCompile Include=`"$src`" />`r`n"
} elseif ($src -match '\.h$') {
$sourceItems += " <ClInclude Include=`"$src`" />`r`n"
}
}
# Read template and replace placeholder
$template = Get-Content ".github\scripts\abclib.vcxproj.template" -Raw
$vcxproj = $template -replace '\{\{SOURCE_FILES\}\}', $sourceItems
Set-Content "abclib.vcxproj" $vcxproj -NoNewline
Write-Host "abclib.vcxproj generated successfully"
- name: Build
run: |
msbuild abcspace.sln /m /nologo /v:m /p:Configuration=Release /p:Platform=Win32 /p:UseMultiToolTask=true
if ($LASTEXITCODE -ne 0) { throw "Build failed with exit code $LASTEXITCODE" }
- name: Test Executable
run: |
_TEST\abc.exe -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
copy lib\x86\pthreadVC2.dll _TEST\
.\_TEST\abc.exe -c "r i10.aig; b; ps; b; rw -l; rw -lz; b; rw -lz; b; ps; cec"
if ($LASTEXITCODE -ne 0) { throw "Test failed with exit code $LASTEXITCODE" }
- name: Stage Executable
run: |
mkdir staging
copy _TEST/abc.exe staging/
copy UpgradeLog.htm staging/
mkdir staging
copy _TEST\abc.exe staging\
- name: Upload pacakge artifact
uses: actions/upload-artifact@v1
- name: Upload package artifact
uses: actions/upload-artifact@v4
with:
name: package
path: staging/
name: package-windows
path: staging/

7
.gitignore vendored
View File

@ -8,10 +8,13 @@ ReleaseExt/
_/
_TEST/
tools/
temp/
lib/abc*
lib/m114*
lib/bip*
docs/
.cache/
.vscode/
src/ext*
@ -30,13 +33,14 @@ src/aig/ddb/
*.plg
*.zip
*.DS_Store
abcspaceext.dsw
abcext.dsp
abcexe.vcproj*
abclib.vcproj*
abcspace.sln
/abcspace.sln
abcspace.suo
*.pyc
@ -61,3 +65,4 @@ tags
/cmake
/cscope
abc.history

View File

@ -1,8 +1,14 @@
cmake_minimum_required(VERSION 3.3.0)
cmake_minimum_required(VERSION 3.5.0)
include(CMakeParseArguments)
include(CheckCCompilerFlag)
include(CheckCXXCompilerFlag)
# Generate compilation database compile_commands.json
set(CMAKE_EXPORT_COMPILE_COMMANDS ON)
# Default c++ standard used unless otherwise specified in target_compile_features.
set(CMAKE_CXX_STANDARD 17 CACHE STRING "the C++ standard to use for this project")
set(CMAKE_CXX_STANDARD_REQUIRED ON)
function(addprefix var prefix)
foreach( s ${ARGN} )
@ -108,3 +114,17 @@ add_library(libabc-pic EXCLUDE_FROM_ALL ${ABC_SRC})
abc_properties(libabc-pic PUBLIC)
set_property(TARGET libabc-pic PROPERTY POSITION_INDEPENDENT_CODE ON)
set_property(TARGET libabc-pic PROPERTY OUTPUT_NAME abc-pic)
if(NOT DEFINED ABC_SKIP_TESTS)
enable_testing()
include(FetchContent)
FetchContent_Declare(
googletest
DOWNLOAD_EXTRACT_TIMESTAMP TRUE
# Specify the commit you depend on and update it regularly.
URL "https://github.com/google/googletest/archive/refs/tags/v1.14.0.zip"
)
FetchContent_MakeAvailable(googletest)
include(GoogleTest)
add_subdirectory(test)
endif()

View File

@ -4,13 +4,30 @@ CXX := g++
AR := ar
LD := $(CXX)
MSG_PREFIX ?=
ABCSRC = .
# Auto-enable ccache if available
CCACHE := $(shell command -v ccache 2>/dev/null)
ifneq ($(CCACHE),)
CC := $(CCACHE) $(CC)
CXX := $(CCACHE) $(CXX)
endif
$(info $(MSG_PREFIX)Using CC=$(CC))
$(info $(MSG_PREFIX)Using CXX=$(CXX))
$(info $(MSG_PREFIX)Using AR=$(AR))
$(info $(MSG_PREFIX)Using LD=$(LD))
MSG_PREFIX ?=
ABCSRC ?= .
VPATH = $(ABCSRC)
# whether to print build options, tools, and echo commands while building
ifdef ABC_MAKE_VERBOSE
VERBOSE=
abc_info = $(info $(1))
else
VERBOSE=@
abc_info =
endif
$(call abc_info,$(MSG_PREFIX)Using CC=$(CC))
$(call abc_info,$(MSG_PREFIX)Using CXX=$(CXX))
$(call abc_info,$(MSG_PREFIX)Using AR=$(AR))
$(call abc_info,$(MSG_PREFIX)Using LD=$(LD))
PROG := abc
OS := $(shell uname -s)
@ -18,16 +35,16 @@ OS := $(shell uname -s)
MODULES := \
$(wildcard src/ext*) \
src/base/abc src/base/abci src/base/cmd src/base/io src/base/main src/base/exor \
src/base/ver src/base/wlc src/base/wln src/base/acb src/base/bac src/base/cba src/base/pla src/base/test \
src/map/mapper src/map/mio src/map/super src/map/if \
src/map/amap src/map/cov src/map/scl src/map/mpm \
src/base/ver src/base/wlc src/base/wln src/base/sn src/base/acb src/base/pla src/base/test \
src/map/mapper src/map/mio src/map/super src/map/if src/map/if/acd \
src/map/amap src/map/cov src/map/scl src/map/mpm src/map/emap \
src/misc/extra src/misc/mvc src/misc/st src/misc/util src/misc/nm \
src/misc/vec src/misc/hash src/misc/tim src/misc/bzlib src/misc/zlib \
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse \
src/misc/mem src/misc/bar src/misc/bbl src/misc/parse src/misc/btor \
src/opt/cut src/opt/fxu src/opt/fxch src/opt/rwr src/opt/mfs src/opt/sim \
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt \
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd \
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 \
src/opt/ret src/opt/fret src/opt/res src/opt/lpk src/opt/nwk src/opt/rwt src/opt/rar \
src/opt/cgt src/opt/csw src/opt/dar src/opt/dau src/opt/dsc src/opt/sfm src/opt/sbd src/opt/eslim src/opt/ufar src/opt/untk src/opt/util \
src/sat/bsat src/sat/xsat src/sat/satoko src/sat/csat src/sat/msat src/sat/psat src/sat/cnf src/sat/bmc src/sat/glucose src/sat/glucose2 src/sat/kissat src/sat/cadical \
src/bool/bdc src/bool/deco src/bool/dec src/bool/kit src/bool/lucky \
src/bool/rsb src/bool/rpo \
src/proof/pdr src/proof/abs src/proof/live src/proof/ssc src/proof/int \
@ -41,7 +58,7 @@ default: $(PROG)
ARCHFLAGS_EXE ?= ./arch_flags
$(ARCHFLAGS_EXE) : arch_flags.c
$(CC) arch_flags.c -o $(ARCHFLAGS_EXE)
$(CC) $< -o $(ARCHFLAGS_EXE)
INCLUDES += -I$(ABCSRC)/src
@ -65,14 +82,14 @@ endif
ifdef ABC_USE_NAMESPACE
CFLAGS += -DABC_NAMESPACE=$(ABC_USE_NAMESPACE) -fpermissive -x c++
CC := $(CXX)
$(info $(MSG_PREFIX)Compiling in namespace $(ABC_NAMESPACE))
$(call abc_info,$(MSG_PREFIX)Compiling in namespace $(ABC_USE_NAMESPACE))
endif
# compile CUDD with ABC
ifndef ABC_USE_NO_CUDD
CFLAGS += -DABC_USE_CUDD=1
MODULES += src/bdd/cudd src/bdd/extrab src/bdd/dsd src/bdd/epd src/bdd/mtr src/bdd/reo src/bdd/cas src/bdd/bbr src/bdd/llb
$(info $(MSG_PREFIX)Compiling with CUDD)
$(call abc_info,$(MSG_PREFIX)Compiling with CUDD)
endif
ABC_READLINE_INCLUDES ?=
@ -86,28 +103,21 @@ ifndef ABC_USE_NO_READLINE
CFLAGS += -I/usr/local/include
LDFLAGS += -L/usr/local/lib
endif
$(info $(MSG_PREFIX)Using libreadline)
$(call abc_info,$(MSG_PREFIX)Using libreadline)
endif
# whether to compile with thread support
ifndef ABC_USE_NO_PTHREADS
CFLAGS += -DABC_USE_PTHREADS
LIBS += -lpthread
$(info $(MSG_PREFIX)Using pthreads)
$(call abc_info,$(MSG_PREFIX)Using pthreads)
endif
# whether to compile into position independent code
ifdef ABC_USE_PIC
CFLAGS += -fPIC
LIBS += -fPIC
$(info $(MSG_PREFIX)Compiling position independent code)
endif
# whether to echo commands while building
ifdef ABC_MAKE_VERBOSE
VERBOSE=
else
VERBOSE=@
$(call abc_info,$(MSG_PREFIX)Compiling position independent code)
endif
# Set -Wno-unused-bug-set-variable for GCC 4.6.0 and greater only
@ -119,16 +129,16 @@ GCC_VERSION=$(shell $(CC) -dumpversion)
GCC_MAJOR=$(word 1,$(subst .,$(space),$(GCC_VERSION)))
GCC_MINOR=$(word 2,$(subst .,$(space),$(GCC_VERSION)))
$(info $(MSG_PREFIX)Found GCC_VERSION $(GCC_VERSION))
$(call abc_info,$(MSG_PREFIX)Found GCC_VERSION $(GCC_VERSION))
ifeq ($(findstring $(GCC_MAJOR),0 1 2 3),)
ifeq ($(GCC_MAJOR),4)
$(info $(MSG_PREFIX)Found GCC_MAJOR==4)
$(call abc_info,$(MSG_PREFIX)Found GCC_MAJOR==4)
ifeq ($(findstring $(GCC_MINOR),0 1 2 3 4 5),)
$(info $(MSG_PREFIX)Found GCC_MINOR>=6)
$(call abc_info,$(MSG_PREFIX)Found GCC_MINOR>=6)
CFLAGS += -Wno-unused-but-set-variable
endif
else
$(info $(MSG_PREFIX)Found GCC_MAJOR>=5)
$(call abc_info,$(MSG_PREFIX)Found GCC_MAJOR>=5)
CFLAGS += -Wno-unused-but-set-variable
endif
endif
@ -137,21 +147,21 @@ endif
# LIBS := -ldl -lrt
LIBS += -lm
ifneq ($(OS), $(filter $(OS), FreeBSD OpenBSD))
ifneq ($(OS), $(filter $(OS), FreeBSD OpenBSD NetBSD))
LIBS += -ldl
endif
ifneq ($(OS), $(filter $(OS), FreeBSD OpenBSD Darwin))
ifneq ($(OS), $(filter $(OS), FreeBSD OpenBSD NetBSD Darwin))
LIBS += -lrt
endif
ifdef ABC_USE_LIBSTDCXX
LIBS += -lstdc++
$(info $(MSG_PREFIX)Using explicit -lstdc++)
$(call abc_info,$(MSG_PREFIX)Using explicit -lstdc++)
endif
$(info $(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
CXXFLAGS += $(CFLAGS)
$(call abc_info,$(MSG_PREFIX)Using CFLAGS=$(CFLAGS))
CXXFLAGS += $(CFLAGS) -std=c++17 -fno-exceptions
SRC :=
GARBAGE := core core.* *.stackdump ./tags $(PROG) arch_flags
@ -173,28 +183,34 @@ DEP := $(OBJ:.o=.d)
# implicit rules
%.o: %.c
@mkdir -p $(dir $@)
@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
$(VERBOSE)$(CC) -c $(OPTFLAGS) $(INCLUDES) $(CFLAGS) $< -o $@
$(VERBOSE)$(CC) -c $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< -o $@
%.o: %.cc
@mkdir -p $(dir $@)
@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< -o $@
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< -o $@
%.o: %.cpp
@mkdir -p $(dir $@)
@echo "$(MSG_PREFIX)\`\` Compiling:" $(LOCAL_PATH)/$<
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< -o $@
$(VERBOSE)$(CXX) -c $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< -o $@
%.d: %.c
@mkdir -p $(dir $@)
@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
$(VERBOSE)$(ABCSRC)/depends.sh "$(CC)" `dirname $*.c` $(OPTFLAGS) $(INCLUDES) $(CFLAGS) $< > $@
$(VERBOSE)$(ABCSRC)/depends.sh "$(CC)" `dirname $*.c` $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CFLAGS) $< > $@
%.d: %.cc
@mkdir -p $(dir $@)
@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cc` $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< > $@
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cc` $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< > $@
%.d: %.cpp
@mkdir -p $(dir $@)
@echo "$(MSG_PREFIX)\`\` Generating dependency:" $(LOCAL_PATH)/$<
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cpp` $(OPTFLAGS) $(INCLUDES) $(CXXFLAGS) $< > $@
$(VERBOSE)$(ABCSRC)/depends.sh "$(CXX)" `dirname $*.cpp` $(OPTFLAGS) $(INCLUDES) $(CPPFLAGS) $(CXXFLAGS) $< > $@
ifndef ABC_MAKE_NO_DEPS
-include $(DEP)
@ -210,6 +226,7 @@ clean:
$(VERBOSE)rm -rvf $(OBJ)
$(VERBOSE)rm -rvf $(GARBAGE)
$(VERBOSE)rm -rvf $(OBJ:.o=.d)
@if [ -n "$(CCACHE)" ]; then echo "$(MSG_PREFIX)ccache available: $(CCACHE)"; fi
tags:
etags `find . -type f -regex '.*\.\(c\|h\)'`

2
abc.rc
View File

@ -135,6 +135,8 @@ alias resyn2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; r
alias r2rs "b; rs -K 6; rw; rs -K 6 -N 2; rf; rs -K 8; b; rs -K 8 -N 2; rw; rs -K 10; rwz; rs -K 10 -N 2; b; rs -K 12; rfz; rs -K 12 -N 2; rwz; b"
alias compress2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
alias c2rs "b -l; rs -K 6 -l; rw -l; rs -K 6 -N 2 -l; rf -l; rs -K 8 -l; b -l; rs -K 8 -N 2 -l; rw -l; rs -K 10 -l; rwz -l; rs -K 10 -N 2 -l; b -l; rs -K 12 -l; rfz -l; rs -K 12 -N 2 -l; rwz -l; b -l"
alias &resyn2rs "&put; resyn2rs; &get"
alias &compress2rs "&put; compress2rs; &get"
# use this script to convert 1-valued and DC-valued flops for an AIG
alias fix_aig "logic; undc; strash; zero"

View File

@ -42,7 +42,7 @@ RSC=rc.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /GX /O2 /D "WIN32" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "WINDOWS" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /FR /YX /FD /c
# ADD CPP /nologo /MD /W3 /GX /O2 /I "src" /D "WIN32" /D "WINDOWS" /D "NDEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /D "HAVE_STRUCT_TIMESPEC" /D "_WINSOCKAPI_" /FR /YX /FD /c
# ADD BASE RSC /l 0x409 /d "NDEBUG"
# ADD RSC /l 0x409 /d "NDEBUG"
BSC32=bscmake.exe
@ -67,7 +67,7 @@ LINK32=link.exe
# PROP Ignore_Export_Lib 0
# PROP Target_Dir ""
# ADD BASE CPP /nologo /W3 /Gm /GX /ZI /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /FR /YX /FD /GZ /c
# ADD CPP /nologo /MDd /W3 /Gm /GX /ZI /Od /I "src" /D "WIN32" /D "WINDOWS" /D "_DEBUG" /D "_CONSOLE" /D "_MBCS" /D ABC_DLL=ABC_DLLEXPORT /D "_CRT_SECURE_NO_DEPRECATE" /D "ABC_USE_PTHREADS" /D "ABC_USE_CUDD" /D "HAVE_STRUCT_TIMESPEC" /D "_WINSOCKAPI_" /FR /YX /FD /GZ /c
# ADD BASE RSC /l 0x409 /d "_DEBUG"
# ADD RSC /l 0x409 /d "_DEBUG"
BSC32=bscmake.exe

1337
abclib.dsp

File diff suppressed because it is too large Load Diff

View File

@ -45,3 +45,27 @@ Using GIA Package in ABC
- For each object in the design annotated with the constructed AIG node (pNode), remember its AIG node ID by calling Gia_ObjId(pMan,pNode).
- Quit the AIG package using Gia_ManStop().
The above process should not produce memory leaks.
Using MiniAIG Package
- Add #include "miniaig.h".
- Start the AIG package using Mini_AigStart().
- Assign primary inputs using Mini_AigCreatePi().
- Assign flop outputs using Mini_AigCreatePi().
(It is important to create all PIs first, before creating flop outputs.)
(Flop control logic, if present, should be elaborated into AND gates. For example, to represent a flop enable, create the driver of enable signal, which can be a PI or an internal node, and then add logic for <flop_input_new> = MUX( <enable>, <flop_input>, <flop_output> ). The output of this logic feeds into the flop.
- Construct AIG in a topological order using Mini_AigAnd(), Mini_AigOr(), etc.
- If constant-0 or constant-1 functions are needed, use 0 or 1.
- Create primary outputs using Mini_AigCreatePo().
- Create flop inputs using Mini_AigCreatePo().
(It is important to create all POs first, before creating register inputs.)
- Set the number of flops by calling Mini_AigSetRegNum().
- The AIG may contain internal nodes without fanout and/or internal nodes fed by constants.
- Dump AIG in internal MiniAIG binary format using Mini_AigDump() and read it into ABC using "&read -m file.mini"
- Dump AIG in standard AIGER format (https://fmv.jku.at/aiger/index.html) using Mini_AigerWrite() and read it into ABC using "&read file.aig"
- For each object in the design represented using MiniAIG, it may be helpful to save the MiniAIG literal returned by Mini_AigAnd(), Mini_AigOr(), etc when constructing that object.
- Quit the AIG package using Mini_AigStop().
The above process should not produce memory leaks.

View File

@ -453,7 +453,7 @@ Aig_Obj_t * Aig_Miter( Aig_Man_t * p, Vec_Ptr_t * vPairs )
Aig_Obj_t * Aig_MiterTwo( Aig_Man_t * p, Vec_Ptr_t * vNodes1, Vec_Ptr_t * vNodes2 )
{
int i;
assert( vNodes1->nSize > 0 && vNodes1->nSize > 0 );
assert( vNodes1->nSize > 0 && vNodes2->nSize > 0 );
assert( vNodes1->nSize == vNodes2->nSize );
for ( i = 0; i < vNodes1->nSize; i++ )
vNodes1->pArray[i] = Aig_Not( Aig_Exor( p, (Aig_Obj_t *)vNodes1->pArray[i], (Aig_Obj_t *)vNodes2->pArray[i] ) );

View File

@ -344,7 +344,7 @@ void Aig_ManShow( Aig_Man_t * pMan, int fHaig, Vec_Ptr_t * vBold )
char FileNameDot[200];
FILE * pFile;
// create the file name
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName ? pMan->pName : (char *)"unknown", ".dot") );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
{

View File

@ -1169,8 +1169,13 @@ void Aig_ManRandomTest1()
***********************************************************************/
unsigned Aig_ManRandom( int fReset )
{
#ifdef _MSC_VER
static unsigned int m_z = NUMBER1;
static unsigned int m_w = NUMBER2;
#else
static __thread unsigned int m_z = NUMBER1;
static __thread unsigned int m_w = NUMBER2;
#endif
if ( fReset )
{
m_z = NUMBER1;

View File

@ -140,6 +140,7 @@ struct Gia_Man_t_
void * pSatlutWinman; // windowing for SAT-based mapping
Vec_Int_t * vPacking; // packing information
Vec_Int_t * vConfigs; // cell configurations
Vec_Str_t * vConfigs2; // cell configurations
char * pCellStr; // cell description
Vec_Int_t * vLutConfigs; // LUT configurations
Vec_Int_t * vEdgeDelay; // special edge information
@ -188,11 +189,13 @@ struct Gia_Man_t_
Vec_Int_t * vCoNumsOrig; // original CO names
Vec_Int_t * vIdsOrig; // original object IDs
Vec_Int_t * vIdsEquiv; // original object IDs proved equivalent
Vec_Int_t * vEquLitIds; // original object IDs proved equivalent
Vec_Int_t * vCofVars; // cofactoring variables
Vec_Vec_t * vClockDoms; // clock domains
Vec_Flt_t * vTiming; // arrival/required/slack
void * pManTime; // the timing manager
void * pLutLib; // LUT library
void * pCellLib; // cell library
word nHashHit; // hash table hit
word nHashMiss; // hash table miss
void * pData; // various user data
@ -241,6 +244,19 @@ struct Gia_Man_t_
Vec_Int_t vSuppVars; // used variables
Vec_Int_t vVarMap; // used variables
Gia_Dat_t * pUData;
// retiming data
Vec_Str_t * vStopsF;
Vec_Str_t * vStopsB;
// iteration with boxes
int iFirstNonPiId;
int iFirstPoId;
int iFirstAndObj;
int iFirstPoObj;
Vec_Str_t * vTTISOPs; // truth tables from ISOP computation
Vec_Int_t * vTTLut; // truth tables from ISOP computation
Vec_Int_t * vMFFCsInfo; // MFFC information
Vec_Int_t * vMFFCsLuts; // MFFCs for each lut
Vec_Ptr_t * vLutsRankings; // LUTs rankings of inputs
};
@ -257,6 +273,7 @@ struct Gps_Par_t_
int fSkipMap;
int fSlacks;
int fNoColor;
int fMapOutStats;
char * pDumpFile;
};
@ -359,6 +376,7 @@ struct Jf_Par_t_
int nCutNumMax;
int nProcNumMax;
int nLutSizeMux;
int nMaxMatches;
word Delay;
word Area;
word Edge;
@ -374,6 +392,7 @@ struct Jf_Par_t_
float Epsilon;
float * pTimesArr;
float * pTimesReq;
char * ZFile;
};
static inline unsigned Gia_ObjCutSign( unsigned ObjId ) { return (1 << (ObjId & 31)); }
@ -546,9 +565,11 @@ static inline int Gia_ObjFaninIdp( Gia_Man_t * p, Gia_Obj_t * pObj, int
static inline int Gia_ObjFaninLit0( Gia_Obj_t * pObj, int ObjId ) { return Abc_Var2Lit( Gia_ObjFaninId0(pObj, ObjId), Gia_ObjFaninC0(pObj) ); }
static inline int Gia_ObjFaninLit1( Gia_Obj_t * pObj, int ObjId ) { return Abc_Var2Lit( Gia_ObjFaninId1(pObj, ObjId), Gia_ObjFaninC1(pObj) ); }
static inline int Gia_ObjFaninLit2( Gia_Man_t * p, int ObjId ) { return (p->pMuxes && p->pMuxes[ObjId]) ? p->pMuxes[ObjId] : -1; }
static inline int Gia_ObjFaninLit( Gia_Obj_t * pObj, int ObjId, int n ){ return n ? Gia_ObjFaninLit1(pObj, ObjId) : Gia_ObjFaninLit0(pObj, ObjId);}
static inline int Gia_ObjFaninLit0p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Abc_Var2Lit( Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) ); }
static inline int Gia_ObjFaninLit1p( Gia_Man_t * p, Gia_Obj_t * pObj) { return Abc_Var2Lit( Gia_ObjFaninId1p(p, pObj), Gia_ObjFaninC1(pObj) ); }
static inline int Gia_ObjFaninLit2p( Gia_Man_t * p, Gia_Obj_t * pObj) { return (p->pMuxes && p->pMuxes[Gia_ObjId(p, pObj)]) ? p->pMuxes[Gia_ObjId(p, pObj)] : -1; }
static inline int Gia_ObjFaninLitp( Gia_Man_t * p, Gia_Obj_t * pObj, int n ){ return n ? Gia_ObjFaninLit1p(p, pObj) : Gia_ObjFaninLit0p(p, pObj);}
static inline void Gia_ObjFlipFaninC0( Gia_Obj_t * pObj ) { assert( Gia_ObjIsCo(pObj) ); pObj->fCompl0 ^= 1; }
static inline int Gia_ObjFaninNum( Gia_Man_t * p, Gia_Obj_t * pObj ) { if ( Gia_ObjIsMux(p, pObj) ) return 3; if ( Gia_ObjIsAnd(pObj) ) return 2; if ( Gia_ObjIsCo(pObj) ) return 1; return 0; }
static inline int Gia_ObjWhatFanin( Gia_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pFanin ) { if ( Gia_ObjFanin0(pObj) == pFanin ) return 0; if ( Gia_ObjFanin1(pObj) == pFanin ) return 1; if ( Gia_ObjFanin2(p, pObj) == pFanin ) return 2; assert(0); return -1; }
@ -1240,7 +1261,16 @@ static inline int Gia_ObjCellId( Gia_Man_t * p, int iLit ) { re
for ( i = 0; (i < Gia_ManRegNum(p)) && ((pObjRi) = Gia_ManCo(p, Gia_ManPoNum(p)+i)) && ((pObjRo) = Gia_ManCi(p, Gia_ManPiNum(p)+i)); i++ )
#define Gia_ManForEachRoToRiVec( vRoIds, p, pObj, i ) \
for ( i = 0; (i < Vec_IntSize(vRoIds)) && ((pObj) = Gia_ObjRoToRi(p, Gia_ManObj(p, Vec_IntEntry(vRoIds, i)))); i++ )
#define Gia_ManForEachObjWithBoxes( p, pObj, i ) \
for ( i = p->iFirstAndObj; (i < p->iFirstPoObj) && ((pObj) = Gia_ManObj(p, i)); i++ )
#define Gia_ManForEachObjReverseWithBoxes( p, pObj, i ) \
for ( i = p->iFirstPoObj - 1; (i >= p->iFirstAndObj) && ((pObj) = Gia_ManObj(p, i)); i-- )
#define Gia_ManForEachCiIdWithBoxes( p, Id, i ) \
for ( i = 0; (i < p->iFirstNonPiId) && ((Id) = Gia_ObjId(p, Gia_ManCi(p, i))); i++ )
#define Gia_ManForEachCoWithBoxes( p, pObj, i ) \
for ( i = p->iFirstPoId; (i < Vec_IntSize(p->vCos)) && ((pObj) = Gia_ManCo(p, i)); i++ )
////////////////////////////////////////////////////////////////////////
/// FUNCTION DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@ -1250,6 +1280,7 @@ extern int Gia_FileSize( char * pFileName );
extern Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSimple, int fSkipStrash, int fCheck );
extern Gia_Man_t * Gia_AigerRead( char * pFileName, int fGiaSimple, int fSkipStrash, int fCheck );
extern void Gia_AigerWrite( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine );
extern void Gia_AigerWriteS( Gia_Man_t * p, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine, int fSkipComment );
extern void Gia_DumpAiger( Gia_Man_t * p, char * pFilePrefix, int iFileNum, int nFileNumDigits );
extern Vec_Str_t * Gia_AigerWriteIntoMemoryStr( Gia_Man_t * p );
extern Vec_Str_t * Gia_AigerWriteIntoMemoryStrPart( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, int nRegs );
@ -1281,10 +1312,14 @@ extern void Cbs_ManStop( Cbs_Man_t * p );
extern int Cbs_ManSolve( Cbs_Man_t * p, Gia_Obj_t * pObj );
extern int Cbs_ManSolve2( Cbs_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
extern Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose );
extern Vec_Int_t * Cbs_ManSolveMiterNcOutVals( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals );
extern void Cbs_ManSyncCore( Cbs_Man_t * p );
extern Vec_Int_t * Cbs_ManSolveRoots( Cbs_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose );
extern void Cbs_ManSetConflictNum( Cbs_Man_t * p, int Num );
extern Vec_Int_t * Cbs_ReadModel( Cbs_Man_t * p );
/*=== giaCTas.c ============================================================*/
extern Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose );
extern Vec_Int_t * Tas_ManSolveMiterNcOutVals( Gia_Man_t * pGia, int nConfs, Vec_Str_t ** pvStatus, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals );
/*=== giaCof.c =============================================================*/
extern void Gia_ManPrintFanio( Gia_Man_t * pGia, int nNodes );
extern Gia_Man_t * Gia_ManDupCof( Gia_Man_t * p, int iVar );
@ -1331,7 +1366,7 @@ extern Gia_Man_t * Gia_ManDupZero( Gia_Man_t * p );
extern Gia_Man_t * Gia_ManDupPerm( Gia_Man_t * p, Vec_Int_t * vPiPerm );
extern Gia_Man_t * Gia_ManDupPermFlop( Gia_Man_t * p, Vec_Int_t * vFfPerm );
extern Gia_Man_t * Gia_ManDupPermFlopGap( Gia_Man_t * p, Vec_Int_t * vFfPerm );
extern void Gia_ManDupAppend( Gia_Man_t * p, Gia_Man_t * pTwo );
extern void Gia_ManDupAppend( Gia_Man_t * p, Gia_Man_t * pTwo, int fShareCis );
extern void Gia_ManDupAppendShare( Gia_Man_t * p, Gia_Man_t * pTwo );
extern Gia_Man_t * Gia_ManDupAppendNew( Gia_Man_t * pOne, Gia_Man_t * pTwo );
extern Gia_Man_t * Gia_ManDupAppendCones( Gia_Man_t * p, Gia_Man_t ** ppCones, int nCones, int fOnlyRegs );
@ -1386,6 +1421,12 @@ extern Gia_Man_t * Gia_ManDemiterToDual( Gia_Man_t * p );
extern int Gia_ManDemiterDual( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
extern int Gia_ManDemiterTwoWords( Gia_Man_t * p, Gia_Man_t ** pp0, Gia_Man_t ** pp1 );
extern void Gia_ManProdAdderGen( int nArgA, int nArgB, int Seed, int fSigned, int fCla );
typedef struct Gia_ChMan_t_ Gia_ChMan_t;
extern Gia_ChMan_t * Gia_ManDupChoicesStart( Gia_Man_t * pGia );
extern void Gia_ManDupChoicesAdd( Gia_ChMan_t * pMan, Gia_Man_t * pGia );
extern Gia_Man_t * Gia_ManDupChoicesFinish( Gia_ChMan_t * pMan );
extern Vec_Int_t * Gia_ManComputeMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vOuts );
extern Gia_Man_t * Gia_ManDupExtractMffc( Gia_Man_t * p, Vec_Int_t * vLits, Vec_Int_t * vAnds, Vec_Int_t * vCos );
/*=== giaEdge.c ==========================================================*/
extern void Gia_ManEdgeFromArray( Gia_Man_t * p, Vec_Int_t * vArray );
extern Vec_Int_t * Gia_ManEdgeToArray( Gia_Man_t * p );
@ -1411,6 +1452,7 @@ extern void Gia_ManEquivFixOutputPairs( Gia_Man_t * p );
extern int Gia_ManCheckTopoOrder( Gia_Man_t * p );
extern int * Gia_ManDeriveNexts( Gia_Man_t * p );
extern void Gia_ManDeriveReprs( Gia_Man_t * p );
extern void Gia_ManDeriveReprsFromSibls( Gia_Man_t *p );
extern int Gia_ManEquivCountLits( Gia_Man_t * p );
extern int Gia_ManEquivCountLitsAll( Gia_Man_t * p );
extern int Gia_ManEquivCountClasses( Gia_Man_t * p );
@ -1481,6 +1523,7 @@ extern int Gia_ManHashAndMulti( Gia_Man_t * p, Vec_Int_t * vLits
extern int Gia_ManHashAndMulti2( Gia_Man_t * p, Vec_Int_t * vLits );
extern int Gia_ManHashDualMiter( Gia_Man_t * p, Vec_Int_t * vOuts );
/*=== giaIf.c ===========================================================*/
extern void Gia_ManPrintOutputLutStats( Gia_Man_t * p );
extern void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile );
extern void Gia_ManPrintPackingStats( Gia_Man_t * p );
extern void Gia_ManPrintLutStats( Gia_Man_t * p );
@ -1527,7 +1570,8 @@ extern void Gia_ManPrintStatsMiter( Gia_Man_t * p, int fVerbose )
extern void Gia_ManSetRegNum( Gia_Man_t * p, int nRegs );
extern void Gia_ManReportImprovement( Gia_Man_t * p, Gia_Man_t * pNew );
extern void Gia_ManPrintNpnClasses( Gia_Man_t * p );
extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter );
extern void Gia_ManDumpVerilog( Gia_Man_t * p, char * pFileName, Vec_Int_t * vObjs, int fVerBufs, int fInter, int fInterComb, int fAssign, int fReverse );
extern void Gia_ManDumpVerilogNand( Gia_Man_t * p, char * pFileName );
/*=== giaMem.c ===========================================================*/
extern Gia_MmFixed_t * Gia_MmFixedStart( int nEntrySize, int nEntriesMax );
extern void Gia_MmFixedStop( Gia_MmFixed_t * p, int fVerbose );
@ -1668,6 +1712,7 @@ extern int Gia_SweeperRun( Gia_Man_t * p, Vec_Int_t * vProbeIds,
extern float Gia_ManEvaluateSwitching( Gia_Man_t * p );
extern float Gia_ManComputeSwitching( Gia_Man_t * p, int nFrames, int nPref, int fProbOne );
extern Vec_Int_t * Gia_ManComputeSwitchProbs( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne );
extern Vec_Int_t * Gia_ManComputeSwitchProbs2( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne, int nRandPiFactor );
extern Vec_Flt_t * Gia_ManPrintOutputProb( Gia_Man_t * p );
/*=== giaTim.c ===========================================================*/
extern int Gia_ManBoxNum( Gia_Man_t * p );
@ -1690,7 +1735,8 @@ extern void * Gia_ManUpdateTimMan2( Gia_Man_t * p, Vec_Int_t * vBox
extern Gia_Man_t * Gia_ManUpdateExtraAig( void * pTime, Gia_Man_t * pAig, Vec_Int_t * vBoxPres );
extern Gia_Man_t * Gia_ManUpdateExtraAig2( void * pTime, Gia_Man_t * pAig, Vec_Int_t * vBoxesLeft );
extern Gia_Man_t * Gia_ManDupCollapse( Gia_Man_t * p, Gia_Man_t * pBoxes, Vec_Int_t * vBoxPres, int fSeq );
extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fDumpFiles, int fVerbose, char * pFileSpec );
extern int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fNameMap, int fDumpFiles, int fVerbose, char * pFileSpec );
extern Vec_Int_t * Gia_ManDeriveBoxMapping( Gia_Man_t * pGia );
/*=== giaTruth.c ===========================================================*/
extern word Gia_LutComputeTruth6( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTruths );
extern word Gia_ObjComputeTruthTable6Lut( Gia_Man_t * p, int iObj, Vec_Wrd_t * vTemp );
@ -1709,6 +1755,7 @@ extern word Gia_ManRandomW( int fReset );
extern void Gia_ManRandomInfo( Vec_Ptr_t * vInfo, int iInputStart, int iWordStart, int iWordStop );
extern char * Gia_TimeStamp();
extern char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix );
extern Vec_Ptr_t * Gia_GetFakeNames( int nNames, int fCaps );
extern void Gia_ManIncrementTravId( Gia_Man_t * p );
extern void Gia_ManCleanMark01( Gia_Man_t * p );
extern void Gia_ManSetMark0( Gia_Man_t * p );
@ -1735,6 +1782,7 @@ extern Vec_Int_t * Gia_ManReverseLevel( Gia_Man_t * p );
extern Vec_Int_t * Gia_ManRequiredLevel( Gia_Man_t * p );
extern void Gia_ManCreateValueRefs( Gia_Man_t * p );
extern void Gia_ManCreateRefs( Gia_Man_t * p );
extern void Gia_ManCreateLitRefs( Gia_Man_t * p );
extern int * Gia_ManCreateMuxRefs( Gia_Man_t * p );
extern int Gia_ManCrossCut( Gia_Man_t * p, int fReverse );
extern Vec_Int_t * Gia_ManCollectPoIds( Gia_Man_t * p );
@ -1777,6 +1825,9 @@ extern Gia_Man_t * Gia_ManTtoptCare( Gia_Man_t * p, int nIns, int nOuts,
extern Gia_Man_t * Gia_ManTransductionBdd( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
extern Gia_Man_t * Gia_ManTransductionTt( Gia_Man_t * pGia, int nType, int fMspf, int nRandom, int nSortType, int nPiShuffle, int nParameter, int fLevel, Gia_Man_t * pExdc, int fNewLine, int nVerbose );
/*=== giaRrr.cpp ===========================================================*/
extern Gia_Man_t * Gia_ManRrr( Gia_Man_t *pGia, int iSeed, int nWords, int nTimeout, int nSchedulerVerbose, int nPartitionerVerbose, int nOptimizerVerbose, int nAnalyzerVerbose, int nSimulatorVerbose, int nSatSolverVerbose, int fUseBddCspf, int fUseBddMspf, int nConflictLimit, int nSortType, int nOptimizerFlow, int nSchedulerFlow, int nPartitionType, int nDistance, int nJobs, int nThreads, int nPartitionSize, int nPartitionSizeMin, int fDeterministic, int nParallelPartitions, int fOptOnInsert, int fGreedy );
/*=== giaCTas.c ===========================================================*/
typedef struct Tas_Man_t_ Tas_Man_t;
extern Tas_Man_t * Tas_ManAlloc( Gia_Man_t * pAig, int nBTLimit );
@ -1785,6 +1836,48 @@ extern Vec_Int_t * Tas_ReadModel( Tas_Man_t * p );
extern void Tas_ManSatPrintStats( Tas_Man_t * p );
extern int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 );
extern int Tas_ManSolveArray( Tas_Man_t * p, Vec_Ptr_t * vObjs );
extern void Tas_ManSetConflictNum( Tas_Man_t * p, int Num );
extern void Tas_ManSyncCore( Tas_Man_t * p );
extern Vec_Int_t * Tas_ManSolveRoots( Tas_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose );
/*=== giaDecGraph.c ===========================================================*/
extern Gia_Man_t* Gia_ManDecGraph( Gia_Man_t* p );
extern Gia_Man_t* Gia_ManDecGraphFromFile( char* pFileName );
/*=== giaBound.c ===========================================================*/
typedef struct Bnd_Man_t_ Bnd_Man_t;
extern Bnd_Man_t* Bnd_ManStart( Gia_Man_t *pSpec, Gia_Man_t *pImpl, int fVerbose );
extern void Bnd_ManStop();
// getter
extern int Bnd_ManGetNInternal();
extern int Bnd_ManGetNExtra();
//for fraig
extern void Bnd_ManMap( int iLit, int id, int spec );
extern void Bnd_ManMerge( int id1, int id2, int phaseDiff );
extern void Bnd_ManFinalizeMappings();
extern void Bnd_ManPrintMappings();
extern Gia_Man_t* Bnd_ManStackGias( Gia_Man_t *pSpec, Gia_Man_t *pImpl );
extern int Bnd_ManCheckCoMerged( Gia_Man_t *p );
// for eco
extern int Bnd_ManCheckBound( Gia_Man_t *p, int fVerbose );
extern void Bnd_ManFindBound( Gia_Man_t *p, Gia_Man_t *pImpl );
extern Gia_Man_t* Bnd_ManGenSpecOut( Gia_Man_t *p );
extern Gia_Man_t* Bnd_ManGenImplOut( Gia_Man_t *p );
extern Gia_Man_t* Bnd_ManGenPatched( Gia_Man_t *pOut, Gia_Man_t *pSpec, Gia_Man_t *pPatch );
extern Gia_Man_t* Bnd_ManGenPatched1( Gia_Man_t *pOut, Gia_Man_t *pSpec );
extern Gia_Man_t* Bnd_ManGenPatched2( Gia_Man_t *pImpl, Gia_Man_t *pPatch, int fSkiptStrash, int fVerbose );
extern void Bnd_ManSetEqOut( int eq );
extern void Bnd_ManSetEqRes( int eq );
extern void Bnd_ManPrintStats();
// util
extern Gia_Man_t* Bnd_ManCutBoundary( Gia_Man_t *p, Vec_Int_t* vEI, Vec_Int_t* vEO, Vec_Bit_t* vEI_phase, Vec_Bit_t* vEO_phase );
extern int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners );
ABC_NAMESPACE_HEADER_END
@ -1794,4 +1887,3 @@ ABC_NAMESPACE_HEADER_END
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -19,10 +19,12 @@
***********************************************************************/
#include "giaAig.h"
#include "aig/gia/gia.h"
#include "proof/fra/fra.h"
#include "proof/dch/dch.h"
#include "opt/dar/dar.h"
#include "opt/dau/dau.h"
#include <assert.h>
ABC_NAMESPACE_IMPL_START
@ -191,6 +193,8 @@ Gia_Man_t * Gia_ManFromAigChoices( Aig_Man_t * p )
Gia_ManSetRegNum( pNew, Aig_ManRegNum(p) );
//assert( Gia_ManObjNum(pNew) == Aig_ManObjNum(p) );
//Gia_ManCheckChoices( pNew );
if ( pNew->pSibls )
Gia_ManDeriveReprsFromSibls( pNew );
return pNew;
}

View File

@ -22,6 +22,7 @@
#include "gia.h"
#include "misc/tim/tim.h"
#include "base/main/main.h"
#include "map/if/if.h"
ABC_NAMESPACE_IMPL_START
@ -406,41 +407,38 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
if ( *pType == 'i' )
{
if ( vNamesIn == NULL )
vNamesIn = Vec_PtrAlloc( nInputs + nLatches );
if ( Vec_PtrSize(vNamesIn) != iTerm )
vNamesIn = Vec_PtrStart( nInputs );
if ( Vec_PtrSize(vNamesIn) <= iTerm )
{
fError = 1;
break;
}
Vec_PtrPush( vNamesIn, Abc_UtilStrsav(pName) );
Vec_PtrWriteEntry( vNamesIn, iTerm, Abc_UtilStrsav(pName) );
}
else if ( *pType == 'o' )
{
if ( vNamesOut == NULL )
vNamesOut = Vec_PtrAlloc( nOutputs + nLatches );
if ( Vec_PtrSize(vNamesOut) != iTerm )
vNamesOut = Vec_PtrStart( nOutputs );
if ( Vec_PtrSize(vNamesOut) <= iTerm )
{
fError = 1;
break;
}
Vec_PtrPush( vNamesOut, Abc_UtilStrsav(pName) );
Vec_PtrWriteEntry( vNamesOut, iTerm, Abc_UtilStrsav(pName) );
}
else if ( *pType == 'l' )
{
char Buffer[1000];
assert( strlen(pName) < 995 );
sprintf( Buffer, "%s_in", pName );
if ( vNamesRegIn == NULL )
vNamesRegIn = Vec_PtrAlloc( nLatches );
vNamesRegIn = Vec_PtrStart( nLatches );
if ( vNamesRegOut == NULL )
vNamesRegOut = Vec_PtrAlloc( nLatches );
if ( Vec_PtrSize(vNamesRegIn) != iTerm )
vNamesRegOut = Vec_PtrStart( nLatches );
if ( Vec_PtrSize(vNamesRegIn) <= iTerm )
{
fError = 1;
break;
}
Vec_PtrPush( vNamesRegIn, Abc_UtilStrsav(Buffer) );
Vec_PtrPush( vNamesRegOut, Abc_UtilStrsav(pName) );
Vec_PtrWriteEntry( vNamesRegIn, iTerm, Abc_UtilStrsavTwo(pName, (char *)"_in") );
Vec_PtrWriteEntry( vNamesRegOut, iTerm, Abc_UtilStrsav(pName) );
}
else if ( *pType == 'n' )
{
@ -648,6 +646,15 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
{
pCur++;
nInputs = Gia_AigerReadInt(pCur)/4; pCur += 4;
int nPiFf = Gia_ManPiNum(pNew) + Gia_ManRegNum(pNew);
if ( nInputs > nPiFf ) {
printf( "Warning: Timing info size (%d) exceeds PIs+FFs (%d). Using first %d values.\n", nInputs, nPiFf, nPiFf );
nInputs = nPiFf;
}
else if ( nInputs > Gia_ManPiNum(pNew) && nInputs < nPiFf ) {
printf( "Warning: Timing info size (%d) is between PIs (%d) and PIs+FFs (%d). Using first %d values.\n", nInputs, Gia_ManPiNum(pNew), nPiFf, Gia_ManPiNum(pNew) );
nInputs = Gia_ManPiNum(pNew);
}
pNew->vInArrs = Vec_FltStart( nInputs );
memcpy( Vec_FltArray(pNew->vInArrs), pCur, (size_t)4*nInputs ); pCur += 4*nInputs;
if ( fVerbose ) printf( "Finished reading extension \"i\".\n" );
@ -656,28 +663,50 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
{
pCur++;
nOutputs = Gia_AigerReadInt(pCur)/4; pCur += 4;
int nPoFf = Gia_ManPoNum(pNew) + Gia_ManRegNum(pNew);
if ( nOutputs > nPoFf ) {
printf( "Warning: Required time size (%d) exceeds POs+FFs (%d). Using first %d values.\n", nOutputs, nPoFf, nPoFf );
nOutputs = nPoFf;
}
else if ( nOutputs > Gia_ManPoNum(pNew) && nOutputs < nPoFf ) {
printf( "Warning: Required time size (%d) is between POs (%d) and POs+FFs (%d). Using first %d values.\n", nOutputs, Gia_ManPoNum(pNew), nPoFf, Gia_ManPoNum(pNew) );
nOutputs = Gia_ManPoNum(pNew);
}
pNew->vOutReqs = Vec_FltStart( nOutputs );
memcpy( Vec_FltArray(pNew->vOutReqs), pCur, (size_t)4*nOutputs ); pCur += 4*nOutputs;
// Convert -1.0 back to TIM_ETERNITY for internal use
{
float * pArr = Vec_FltArray(pNew->vOutReqs);
int i;
for ( i = 0; i < nOutputs; i++ )
if ( pArr[i] < 0 )
pArr[i] = TIM_ETERNITY;
}
if ( fVerbose ) printf( "Finished reading extension \"o\".\n" );
}
// read equivalence classes
else if ( *pCur == 'e' )
{
extern Gia_Rpr_t * Gia_AigerReadEquivClasses( unsigned char ** ppPos, int nSize );
pCur++;
pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
pNew->pReprs = Gia_AigerReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
pNew->pNexts = Gia_ManDeriveNexts( pNew );
assert( pCur == pCurTemp );
if ( fVerbose ) printf( "Finished reading extension \"e\".\n" );
}
//else if ( *pCur == 'e' )
//{
// extern Gia_Rpr_t * Gia_AigerReadEquivClasses( unsigned char ** ppPos, int nSize );
// pCur++;
// pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
// pNew->pReprs = Gia_AigerReadEquivClasses( &pCur, Gia_ManObjNum(pNew) );
// pNew->pNexts = Gia_ManDeriveNexts( pNew );
// assert( pCur == pCurTemp );
// if ( fVerbose ) printf( "Finished reading extension \"e\".\n" );
//}
// read flop classes
else if ( *pCur == 'f' )
{
int i, nRegs;
pCur++;
assert( Gia_AigerReadInt(pCur) == 4*Gia_ManRegNum(pNew) ); pCur += 4;
pNew->vFlopClasses = Vec_IntStart( Gia_ManRegNum(pNew) );
memcpy( Vec_IntArray(pNew->vFlopClasses), pCur, (size_t)4*Gia_ManRegNum(pNew) ); pCur += 4*Gia_ManRegNum(pNew);
pCurTemp = pCur + Gia_AigerReadInt(pCur) + 4; pCur += 4;
nRegs = Gia_AigerReadInt(pCur); pCur += 4;
//nRegs = (pCurTemp - pCur)/4;
pNew->vFlopClasses = Vec_IntAlloc( nRegs );
for ( i = 0; i < nRegs; i++ )
Vec_IntPush( pNew->vFlopClasses, Gia_AigerReadInt(pCur) ), pCur += 4;
assert( pCur == pCurTemp );
if ( fVerbose ) printf( "Finished reading extension \"f\".\n" );
}
// read gate classes
@ -800,6 +829,36 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
assert( pCur == pCurTemp );
if ( fVerbose ) printf( "Finished reading extension \"b\".\n" );
}
// read configuration data for extension "j"
else if ( *pCur == 'j' )
{
int nSize, Reserved, NumCellTypes, CellId, BytesPerInstance, TotalInstances;
pCur++;
nSize = Gia_AigerReadInt(pCur);
pCurTemp = pCur + nSize + 4; pCur += 4;
// Read reserved value (should be 0)
Reserved = Gia_AigerReadInt(pCur); pCur += 4;
assert( Reserved == 0 );
// Read number of cell types
NumCellTypes = Gia_AigerReadInt(pCur); pCur += 4;
// Skip cell type definitions (we know them already)
for ( i = 0; i < NumCellTypes; i++ )
{
CellId = Gia_AigerReadInt(pCur); pCur += 4;
// Skip function description string (null-terminated)
while ( *pCur++ != '\0' );
BytesPerInstance = Gia_AigerReadInt(pCur); pCur += 4;
}
// Read total number of instances
TotalInstances = Gia_AigerReadInt(pCur); pCur += 4;
// Create byte vector for instance data
pNew->vConfigs2 = Vec_StrAlloc( (int)(pCurTemp - pCur) );
// Read instance data as bytes
while ( pCur < pCurTemp )
Vec_StrPush( pNew->vConfigs2, *pCur++ );
assert( pCur == pCurTemp );
if ( fVerbose ) printf( "Finished reading extension \"j\".\n" );
}
// read choices
else if ( *pCur == 'q' )
{
@ -870,6 +929,25 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
printf( "Cannot read extension \"w\" because AIG is rehashed. Use \"&r -s <file.aig>\".\n" );
Vec_IntFree( vPairs );
}
// read object ID mapping
else if ( *pCur == 'y' )
{
pCur++;
int nInts = Gia_AigerReadInt(pCur)/4; pCur += 4;
if ( fSkipStrash ) {
pNew->vEquLitIds = Vec_IntStart( nInts );
memcpy( Vec_IntArray(pNew->vEquLitIds), pCur, (size_t)4*nInts );
if ( Vec_IntSize(pNew->vEquLitIds) != Gia_ManObjNum(pNew) ) {
printf( "Cannot read extension \"y\" because object count changed. Use \"&r -s <file.aig>\".\n" );
Vec_IntFreeP( &pNew->vEquLitIds );
}
else if ( fVerbose ) printf( "Finished reading extension \"y\".\n" );
}
else {
if ( fVerbose ) printf( "Cannot read extension \"y\" because AIG is rehashed. Use \"&r -s <file.aig>\".\n" );
}
pCur += 4*nInts;
}
else break;
}
}
@ -914,6 +992,106 @@ Gia_Man_t * Gia_AigerReadFromMemory( char * pContents, int nFileSize, int fGiaSi
pNew->pAigExtra = pAigExtra;
}
// Apply init state transformation for register boxes with init=1
if ( pNew->vRegInits && Vec_IntCountEntry(pNew->vRegInits, 1) > 0 )
{
extern void Gia_ManFlipInit1( Gia_Man_t * p, Vec_Int_t * vInit );
Tim_Man_t * pTimMan = (Tim_Man_t *)pNew->pManTime;
if ( pTimMan && Gia_ManRegBoxNum(pNew) > 0 )
{
// Handle register boxes: apply transformation to box inputs/outputs
Gia_Obj_t * pObj;
int i, curCo, curCi, nBoxIns, nBoxOuts;
int iRegBox = 0;
assert( Vec_IntSize(pNew->vRegInits) == Gia_ManRegBoxNum(pNew) );
// Step 1: Mark register box outputs with init state 1
curCi = Tim_ManPiNum(pTimMan);
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
{
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
// Check if this is a register box (1-input, 1-output)
if ( nBoxIns == 1 && nBoxOuts == 1 )
{
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
{
pObj = Gia_ManCi(pNew, curCi);
pObj->fMark0 = 1;
}
iRegBox++;
}
curCi += nBoxOuts;
}
// Step 2: Propagate complementation through AND gates
Gia_ManForEachAnd( pNew, pObj, i )
{
if ( Gia_ObjFanin0(pObj)->fMark0 )
pObj->fCompl0 ^= 1;
if ( Gia_ObjFanin1(pObj)->fMark0 )
pObj->fCompl1 ^= 1;
}
// Step 3: Complement CO fanins if needed
Gia_ManForEachCo( pNew, pObj, i )
{
if ( Gia_ObjFanin0(pObj)->fMark0 )
pObj->fCompl0 ^= 1;
}
// Step 4: Clear marks
curCi = Tim_ManPiNum(pTimMan);
iRegBox = 0;
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
{
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
if ( nBoxIns == 1 && nBoxOuts == 1 )
{
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
{
pObj = Gia_ManCi(pNew, curCi);
pObj->fMark0 = 0;
}
iRegBox++;
}
curCi += nBoxOuts;
}
// Step 5: Complement register box inputs with init state 1
curCo = Tim_ManPoNum(pTimMan);
iRegBox = 0;
for ( i = 0; i < Gia_ManBoxNum(pNew); i++ )
{
nBoxIns = Tim_ManBoxInputNum(pTimMan, i);
nBoxOuts = Tim_ManBoxOutputNum(pTimMan, i);
if ( nBoxIns == 1 && nBoxOuts == 1 )
{
if ( Vec_IntEntry(pNew->vRegInits, iRegBox) == 1 )
{
pObj = Gia_ManCo(pNew, curCo);
pObj->fCompl0 ^= 1;
}
iRegBox++;
}
curCo += nBoxIns;
}
// Clear all init states to 0 (transformation is now structural)
Vec_IntFill( pNew->vRegInits, Vec_IntSize(pNew->vRegInits), 0 );
}
else if ( Gia_ManRegNum(pNew) > 0 )
{
// Handle regular flops (no boxes)
Gia_ManFlipInit1( pNew, pNew->vRegInits );
// Clear all init states to 0 (transformation is now structural)
Vec_IntFill( pNew->vRegInits, Vec_IntSize(pNew->vRegInits), 0 );
}
}
if ( fHieOnly )
{
// Tim_ManPrint( (Tim_Man_t *)pNew->pManTime );
@ -1116,7 +1294,7 @@ Vec_Str_t * Gia_AigerWriteIntoMemoryStr( Gia_Man_t * p )
Gia_AigerWriteUnsigned( vBuffer, uLit - uLit1 );
Gia_AigerWriteUnsigned( vBuffer, uLit1 - uLit0 );
}
Vec_StrPrintStr( vBuffer, "c" );
Vec_StrPrintStr( vBuffer, "c\n" );
return vBuffer;
}
@ -1217,7 +1395,7 @@ Vec_Str_t * Gia_AigerWriteIntoMemoryStrPart( Gia_Man_t * p, Vec_Int_t * vCis, Ve
SeeAlso []
***********************************************************************/
void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine )
void Gia_AigerWriteS( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine, int fSkipComment )
{
int fVerbose = XAIG_VERBOSE;
FILE * pFile;
@ -1373,42 +1551,56 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
if ( p->pManTime )
{
float * pTimes;
pTimes = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime );
pTimes = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
if ( pTimes )
{
int nPis = Tim_ManPiNum((Tim_Man_t *)p->pManTime);
int nFlops = Gia_ManRegNum(p);
fprintf( pFile, "i" );
Gia_FileWriteBufferSize( pFile, 4*Tim_ManPiNum((Tim_Man_t *)p->pManTime) );
fwrite( pTimes, 1, 4*Tim_ManPiNum((Tim_Man_t *)p->pManTime), pFile );
Gia_FileWriteBufferSize( pFile, 4*(nPis + nFlops) );
fwrite( pTimes, 1, 4*(nPis + nFlops), pFile );
ABC_FREE( pTimes );
if ( fVerbose ) printf( "Finished writing extension \"i\".\n" );
if ( fVerbose ) printf( "Finished writing extension \"i\" (PIs+Flops).\n" );
}
pTimes = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime );
pTimes = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
if ( pTimes )
{
int nPos = Tim_ManPoNum((Tim_Man_t *)p->pManTime);
int nFlops = Gia_ManRegNum(p);
// Convert TIM_ETERNITY sentinel to -1.0 per XAIG spec
{
int i;
for ( i = 0; i < nPos + nFlops; i++ )
if ( pTimes[i] >= TIM_ETERNITY )
pTimes[i] = -1.0;
}
fprintf( pFile, "o" );
Gia_FileWriteBufferSize( pFile, 4*Tim_ManPoNum((Tim_Man_t *)p->pManTime) );
fwrite( pTimes, 1, 4*Tim_ManPoNum((Tim_Man_t *)p->pManTime), pFile );
Gia_FileWriteBufferSize( pFile, 4*(nPos + nFlops) );
fwrite( pTimes, 1, 4*(nPos + nFlops), pFile );
ABC_FREE( pTimes );
if ( fVerbose ) printf( "Finished writing extension \"o\".\n" );
if ( fVerbose ) printf( "Finished writing extension \"o\" (POs+Flops).\n" );
}
}
// write equivalences
if ( p->pReprs && p->pNexts )
{
extern Vec_Str_t * Gia_WriteEquivClasses( Gia_Man_t * p );
fprintf( pFile, "e" );
vStrExt = Gia_WriteEquivClasses( p );
Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
Vec_StrFree( vStrExt );
}
//if ( p->pReprs && p->pNexts )
//{
// extern Vec_Str_t * Gia_WriteEquivClasses( Gia_Man_t * p );
// fprintf( pFile, "e" );
// vStrExt = Gia_WriteEquivClasses( p );
// Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
// fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
// Vec_StrFree( vStrExt );
//}
// write flop classes
if ( p->vFlopClasses )
{
int i;
fprintf( pFile, "f" );
Gia_FileWriteBufferSize( pFile, 4*Gia_ManRegNum(p) );
assert( Vec_IntSize(p->vFlopClasses) == Gia_ManRegNum(p) );
fwrite( Vec_IntArray(p->vFlopClasses), 1, 4*Gia_ManRegNum(p), pFile );
Gia_FileWriteBufferSize( pFile, 4*(Vec_IntSize(p->vFlopClasses)+1) );
Gia_FileWriteBufferSize( pFile, Vec_IntSize(p->vFlopClasses) );
for ( i = 0; i < Vec_IntSize(p->vFlopClasses); i++ )
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vFlopClasses, i) );
if ( fVerbose ) printf( "Finished writing extension \"f\".\n" );
}
// write gate classes
if ( p->vGateClasses )
@ -1464,6 +1656,18 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
Vec_StrFree( vStrExt );
if ( fVerbose ) printf( "Finished writing extension \"m\".\n" );
}
// write cell mapping
if ( Gia_ManHasCellMapping(p) )
{
extern Vec_Str_t * Gia_AigerWriteCellMappingDoc( Gia_Man_t * p );
fprintf( pFile, "M" );
vStrExt = Gia_AigerWriteCellMappingDoc( p );
Gia_FileWriteBufferSize( pFile, Vec_StrSize(vStrExt) );
fwrite( Vec_StrArray(vStrExt), 1, Vec_StrSize(vStrExt), pFile );
Vec_StrFree( vStrExt );
if ( fVerbose ) printf( "Finished writing extension \"M\".\n" );
}
// write placement
if ( p->pPlacement )
{
@ -1480,6 +1684,7 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
Gia_FileWriteBufferSize( pFile, Vec_IntSize(p->vRegClasses) );
for ( i = 0; i < Vec_IntSize(p->vRegClasses); i++ )
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vRegClasses, i) );
if ( fVerbose ) printf( "Finished writing extension \"r\".\n" );
}
// write register inits
if ( p->vRegInits )
@ -1502,6 +1707,88 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
for ( i = 0; i < Vec_IntSize(p->vConfigs); i++ )
Gia_FileWriteBufferSize( pFile, Vec_IntEntry(p->vConfigs, i) );
}
// write configuration data for extension "j"
if ( p->vConfigs2 )
{
int nTotalSize, nInstances = 0;
If_LibCell_t * pLibCell = (If_LibCell_t *)Abc_FrameReadLibCell();
char *pCell0, *pCell1, *pCell2;
// Get formulas from cell library or use defaults
if ( pLibCell && pLibCell->nCellNum == 3 &&
pLibCell->pCellNames[0] && pLibCell->pCellNames[1] && pLibCell->pCellNames[2] )
{
pCell0 = pLibCell->pCellNames[0];
pCell1 = pLibCell->pCellNames[1];
pCell2 = pLibCell->pCellNames[2];
}
else
{
if ( !pLibCell )
Abc_Print( 0, "Warning: Cell library is not loaded. Using generic formulas.\n" );
else if ( pLibCell->nCellNum != 3 )
Abc_Print( 0, "Warning: Cell library has %d cells (expected exactly 3). Using generic formulas.\n", pLibCell->nCellNum );
else
Abc_Print( 0, "Warning: Cell library does not contain all required cells. Using generic formulas.\n" );
pCell0 = "Formula1";
pCell1 = "Formula2";
pCell2 = "Formula3";
}
// Count instances by scanning the byte data
for ( i = 0; i < Vec_StrSize(p->vConfigs2); )
{
unsigned char CellId = (unsigned char)Vec_StrEntry(p->vConfigs2, i);
if ( CellId == 0 )
i += 7; // 1 byte CellId + 4 bytes mapping + 2 bytes truth table
else if ( CellId == 1 )
i += 12; // 1 byte CellId + 7 bytes mapping + 4 bytes truth tables
else if ( CellId == 2 )
i += 14; // 1 byte CellId + 9 bytes mapping + 4 bytes truth tables
else
assert( 0 ); // Unknown cell type
nInstances++;
}
fprintf( pFile, "j" );
// Calculate total size
nTotalSize = 4; // Reserved value
nTotalSize += 4; // Number of cell types
// Cell type 0
nTotalSize += 4; // CellId
nTotalSize += strlen(pCell0) + 1; // Function description
nTotalSize += 4; // Bytes per instance
// Cell type 1
nTotalSize += 4; // CellId
nTotalSize += strlen(pCell1) + 1; // Function description
nTotalSize += 4; // Bytes per instance
// Cell type 2
nTotalSize += 4; // CellId
nTotalSize += strlen(pCell2) + 1; // Function description
nTotalSize += 4; // Bytes per instance
// Instance data
nTotalSize += 4; // Total instances count
nTotalSize += Vec_StrSize(p->vConfigs2); // Actual instance data
Gia_FileWriteBufferSize( pFile, nTotalSize );
// Write reserved value
Gia_FileWriteBufferSize( pFile, 0 );
// Write number of cell types
Gia_FileWriteBufferSize( pFile, 3 );
// Write cell type 0 (LUT4)
Gia_FileWriteBufferSize( pFile, 0 ); // CellId
fwrite( pCell0, 1, strlen(pCell0) + 1, pFile );
Gia_FileWriteBufferSize( pFile, 7 ); // 1 byte CellId + 4 bytes mapping + 2 bytes truth table
// Write cell type 1 (S44)
Gia_FileWriteBufferSize( pFile, 1 ); // CellId
fwrite( pCell1, 1, strlen(pCell1) + 1, pFile );
Gia_FileWriteBufferSize( pFile, 12 ); // 1 byte CellId + 7 bytes mapping + 4 bytes truth tables
// Write cell type 2 (9-input)
Gia_FileWriteBufferSize( pFile, 2 ); // CellId
fwrite( pCell2, 1, strlen(pCell2) + 1, pFile );
Gia_FileWriteBufferSize( pFile, 14 ); // 1 byte CellId + 9 bytes mapping + 4 bytes truth tables
// Write total instances
Gia_FileWriteBufferSize( pFile, nInstances );
// Write instance data as raw bytes
fwrite( Vec_StrArray(p->vConfigs2), 1, Vec_StrSize(p->vConfigs2), pFile );
}
// write choices
if ( Gia_ManHasChoices(p) )
{
@ -1546,6 +1833,15 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
assert( Vec_IntSize(p->vObjClasses) == Gia_ManObjNum(p) );
fwrite( Vec_IntArray(p->vObjClasses), 1, 4*Gia_ManObjNum(p), pFile );
}
// write object classes
if ( p->vEquLitIds )
{
fprintf( pFile, "y" );
Gia_FileWriteBufferSize( pFile, 4*Gia_ManObjNum(p) );
assert( Vec_IntSize(p->vEquLitIds) == Gia_ManObjNum(p) );
fwrite( Vec_IntArray(p->vEquLitIds), 1, 4*Gia_ManObjNum(p), pFile );
if ( fVerbose ) printf( "Finished writing extension \"y\".\n" );
}
// write name
if ( p->pName )
{
@ -1557,8 +1853,10 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
// write comments
if ( fWriteNewLine )
fprintf( pFile, "c\n" );
fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
if ( !fSkipComment ) {
fprintf( pFile, "\nThis file was produced by the GIA package in ABC on %s\n", Gia_TimeStamp() );
fprintf( pFile, "For information about AIGER format, refer to %s\n", "http://fmv.jku.at/aiger" );
}
fclose( pFile );
if ( p != pInit )
{
@ -1567,6 +1865,22 @@ void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int
}
}
/**Function*************************************************************
Synopsis [Writes the AIG in the binary AIGER format.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_AigerWrite( Gia_Man_t * pInit, char * pFileName, int fWriteSymbols, int fCompact, int fWriteNewLine )
{
Gia_AigerWriteS( pInit, pFileName, fWriteSymbols, fCompact, fWriteNewLine, 0 );
}
/**Function*************************************************************
Synopsis [Writes the AIG in the binary AIGER format.]
@ -1767,4 +2081,3 @@ int main( int argc, char ** argv )
ABC_NAMESPACE_IMPL_END

View File

@ -19,6 +19,9 @@
***********************************************************************/
#include "gia.h"
#include "misc/st/st.h"
#include "map/mio/mio.h"
#include "map/mio/mioInt.h"
ABC_NAMESPACE_IMPL_START
@ -288,6 +291,101 @@ Vec_Str_t * Gia_AigerWriteMappingDoc( Gia_Man_t * p )
return Vec_StrAllocArray( (char *)pBuffer, 4*nSize );
}
int Gia_AigerWriteCellMappingInstance( Gia_Man_t * p, unsigned char * pBuffer, int nSize2, int i )
{
int k, iFan;
if ( !Gia_ObjIsCellInv(p, i) ) {
Gia_AigerWriteInt( pBuffer + nSize2, Gia_ObjCellId(p, i) ); nSize2 += 4;
Gia_AigerWriteInt( pBuffer + nSize2, i ); nSize2 += 4;
Gia_CellForEachFanin( p, i, iFan, k )
{
Gia_AigerWriteInt( pBuffer + nSize2, iFan );
nSize2 += 4;
}
} else {
Gia_AigerWriteInt( pBuffer + nSize2, 3 ); nSize2 += 4;
Gia_AigerWriteInt( pBuffer + nSize2, i ); nSize2 += 4;
Gia_AigerWriteInt( pBuffer + nSize2, Abc_LitNot(i) ); nSize2 += 4;
}
return nSize2;
}
Vec_Str_t * Gia_AigerWriteCellMappingDoc( Gia_Man_t * p )
{
unsigned char * pBuffer;
int i, nCells = 0, nInstances = 0, nSize = 8, nSize2 = 0;
Mio_Cell2_t * pCells = Mio_CollectRootsNewDefault2( 6, &nCells, 0 );
assert( pCells );
for (int i = 0; i < nCells; i++)
{
Mio_Gate_t *pGate = (Mio_Gate_t *) pCells[i].pMioGate;
Mio_Pin_t *pPin;
nSize += strlen(Mio_GateReadName(pGate)) + 1;
nSize += strlen(Mio_GateReadOutName(pGate)) + 1 + 4;
Mio_GateForEachPin( pGate, pPin )
nSize += strlen(Mio_PinReadName(pPin)) + 1;
}
Gia_ManForEachCell( p, i )
{
assert ( !Gia_ObjIsCellBuf(p, i) ); // not implemented
nInstances++;
if ( Gia_ObjIsCellInv(p, i) )
nSize += 12;
else
nSize += Gia_ObjCellSize(p, i) * 4 + 8;
}
pBuffer = ABC_ALLOC( unsigned char, nSize );
Gia_AigerWriteInt( pBuffer + nSize2, nCells ); nSize2 += 4;
Gia_AigerWriteInt( pBuffer + nSize2, nInstances ); nSize2 += 4;
for (int i = 0; i < nCells; i++)
{
int nPins = 0;
Mio_Gate_t *pGate = (Mio_Gate_t *) pCells[i].pMioGate;
Mio_Pin_t *pPin;
strcpy((char *) pBuffer + nSize2, Mio_GateReadName(pGate));
nSize2 += strlen(Mio_GateReadName(pGate)) + 1;
strcpy((char *) pBuffer + nSize2, Mio_GateReadOutName(pGate));
nSize2 += strlen(Mio_GateReadOutName(pGate)) + 1;
Mio_GateForEachPin( pGate, pPin )
nPins++;
Gia_AigerWriteInt( pBuffer + nSize2, nPins ); nSize2 += 4;
Mio_GateForEachPin( pGate, pPin )
{
strcpy((char *) pBuffer + nSize2, Mio_PinReadName(pPin));
nSize2 += strlen(Mio_PinReadName(pPin)) + 1;
}
}
Gia_ManForEachCell( p, i )
{
if ( Gia_ObjIsCellBuf(p, i) )
continue;
if ( Gia_ObjIsCellInv(p, i) && !Abc_LitIsCompl(i) ) {
// swap the order so that the inverter is after the driver
// of the inverter's input
nSize2 = Gia_AigerWriteCellMappingInstance(p, pBuffer, nSize2, Abc_LitNot(i) );
nSize2 = Gia_AigerWriteCellMappingInstance(p, pBuffer, nSize2, i );
i += 1;
continue;
}
nSize2 = Gia_AigerWriteCellMappingInstance(p, pBuffer, nSize2, i );
}
assert( nSize2 == nSize );
ABC_FREE( pCells );
return Vec_StrAllocArray( (char *)pBuffer, nSize );
}
/**Function*************************************************************
Synopsis [Read/write packing information.]

1374
src/aig/gia/giaBound.c Normal file

File diff suppressed because it is too large Load Diff

580
src/aig/gia/giaBsFind.c Normal file
View File

@ -0,0 +1,580 @@
/**CFile****************************************************************
FileName [giaBsFind.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis []
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaBsFind.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
// Cost function: sum of squared differences between all pairs
int cost_sum_squares(int* subset, int K, void * pData) {
double cost = 0;
for (int i = 0; i < K - 1; i++) {
for (int j = i + 1; j < K; j++) {
int diff = subset[i] - subset[j];
cost += diff * diff;
}
}
// Normalize to be between 2 and 100
return (int)(2.0 + (cost / (K * K)) * 0.98);
}
// Compare function for qsort - for sorting individual subsets
int compare_ints(const void* a, const void* b) {
return *(int*)a - *(int*)b;
}
// Compare function for qsort - for sorting subsets by cost
// Subset format: [K, element1, element2, ..., elementK, cost]
int compare_subsets_by_cost(const void* a, const void* b) {
const int* subset_a = (const int*)a;
const int* subset_b = (const int*)b;
int K_a = subset_a[0];
int K_b = subset_b[0];
assert( K_a == K_b );
// Cost is at position K+1 (after K and K elements)
return subset_a[K_a + 1] - subset_b[K_b + 1];
}
// Generate a random subset of K numbers from 0 to N-1
// Format: [K, element1, element2, ..., elementK, cost]
void generate_random_subset(int* subset, int K, int N) {
subset[0] = K; // Store K in first position
int count = 0;
// First, generate K unique random numbers
while (count < K) {
int num = rand() % N;
// Check if number already exists in subset
int exists = 0;
for (int i = 0; i < count; i++) {
if (subset[i + 1] == num) {
exists = 1;
break;
}
}
if (!exists) {
subset[count + 1] = num;
count++;
}
}
// Then, sort the subset using bubble sort
for (int i = 1; i < K; i++) {
for (int j = 1; j < K - i + 1; j++) {
if (subset[j] > subset[j + 1]) {
int temp = subset[j];
subset[j] = subset[j + 1];
subset[j + 1] = temp;
}
}
}
}
// Create offspring from two parent subsets
// Uses pre-allocated arrays to avoid repeated memory allocation
void create_offspring(int* parent1, int* parent2, int* offspring, int K, int N,
int* in_offspring, int* in_parent1, int* in_parent2, int* candidates) {
int count = 0;
offspring[0] = K; // Store K in first position
// Mark which numbers are in each parent (skip first element which is K)
for (int i = 1; i <= K; i++) {
in_parent1[parent1[i]] = 1;
in_parent2[parent2[i]] = 1;
}
// First, add numbers that appear in both parents
for (int i = 0; i < N && count < K; i++) {
if (in_parent1[i] && in_parent2[i]) {
offspring[count + 1] = i;
count++;
in_offspring[i] = 1;
}
}
// Create array of numbers that appear in exactly one parent
int num_candidates = 0;
for (int i = 0; i < N; i++) {
if ((in_parent1[i] || in_parent2[i]) && !in_offspring[i]) {
candidates[num_candidates++] = i;
}
}
// Randomly add from candidates until we have K numbers
while (count < K && num_candidates > 0) {
int idx = rand() % num_candidates;
offspring[count + 1] = candidates[idx];
count++;
in_offspring[candidates[idx]] = 1;
// Remove selected candidate
candidates[idx] = candidates[--num_candidates];
}
// Sort the offspring elements (not including the first K value)
qsort(&offspring[1], K, sizeof(int), compare_ints);
// Clean up the intean arrays for next use - only clean used entries
for (int i = 1; i <= K; i++) {
in_parent1[parent1[i]] = 0;
in_parent2[parent2[i]] = 0;
}
for (int i = 1; i <= K; i++) {
in_offspring[offspring[i]] = 0;
}
}
// Count unique subsets in a sorted array of subsets
// Returns the number of unique subsets and prints the percentage
int count_unique_subsets(int* sorted_subsets, int num_subsets, int subset_size, const char* label) {
if (num_subsets == 0) return 0;
int unique_count = 1; // First subset is always unique
int K = sorted_subsets[0]; // Get K from first subset
// Compare each subset with the previous one
for (int i = 1; i < num_subsets; i++) {
int* current = &sorted_subsets[i * subset_size];
int* previous = &sorted_subsets[(i - 1) * subset_size];
// Compare all K elements (skip position 0 which has K, and K+1 which has cost)
int is_different = 0;
for (int j = 1; j <= K; j++) {
if (current[j] != previous[j]) {
is_different = 1;
break;
}
}
if (is_different) {
unique_count++;
}
}
double percentage = (unique_count * 100.0) / num_subsets;
printf("%s: %d unique subsets out of %d (%.1f%%)\n",
label, unique_count, num_subsets, percentage);
return unique_count;
}
// Main genetic algorithm
int genetic_subset_selection(int N, int K, int B, int L,
int verbose,
int (*cost_function)(int*, int, void *),
int** best_subsets_history,
int* iterations_used,
void * pUserData) {
int print_unique = 0;
int M = B * (B - 1) / 2;
int subset_size = K + 2; // K value + K elements + cost
// Allocate arrays
int* current_generation = (int*)malloc(M * subset_size * sizeof(int));
int* next_generation = (int*)malloc(M * subset_size * sizeof(int));
int* all_best_subsets = (int*)calloc(B * L * subset_size, sizeof(int));
// Pre-allocate reusable arrays for create_offspring
int* in_offspring = (int*)calloc(N, sizeof(int));
int* in_parent1 = (int*)calloc(N, sizeof(int));
int* in_parent2 = (int*)calloc(N, sizeof(int));
int* candidates = (int*)malloc(K * 2 * sizeof(int));
// Generate initial population
for (int i = 0; i < M; i++) {
int* subset = &current_generation[i * subset_size];
generate_random_subset(subset, K, N);
// Cost function uses elements starting at position 1
subset[K + 1] = cost_function(&subset[1], K, pUserData);
}
// Sort to get best B subsets
qsort(current_generation, M, subset_size * sizeof(int), compare_subsets_by_cost);
if ( print_unique ) count_unique_subsets(current_generation, M, subset_size, "Initial population");
int best_cost = current_generation[K + 1];
int generation = 0;
int total_best_count = 0;
// Main evolutionary loop
while (generation < L) {
// Store best B subsets from current generation
for (int i = 0; i < B && total_best_count < B * L; i++) {
memcpy(&all_best_subsets[total_best_count * subset_size],
&current_generation[i * subset_size],
subset_size * sizeof(int));
total_best_count++;
}
if ( verbose ) {
printf( "Iter %d\n", generation );
for (int i = 0; i < B; i++ ) {
printf( "Subset %2d : {", i );
for (int k = 0; k < K; k++ )
printf( " %2d", (&current_generation[i * subset_size])[k+1] );
printf( " } " );
printf( "Cost %2d\n", (&current_generation[i * subset_size])[K+1] );
}
}
// Create next generation from pairs of best B subsets
int offspring_idx = 0;
for (int i = 0; i < B; i++) {
for (int j = i + 1; j < B; j++) {
int* parent1 = &current_generation[i * subset_size];
int* parent2 = &current_generation[j * subset_size];
int* offspring = &next_generation[offspring_idx * subset_size];
create_offspring(parent1, parent2, offspring, K, N,
in_offspring, in_parent1, in_parent2, candidates);
offspring[K + 1] = cost_function(&offspring[1], K, pUserData);
offspring_idx++;
}
}
// Sort next generation
qsort(next_generation, M, subset_size * sizeof(int), compare_subsets_by_cost);
if ( print_unique ) count_unique_subsets(next_generation, M, subset_size, "Next generation");
generation++;
// Check for improvement
int new_best_cost = next_generation[K + 1];
if (new_best_cost >= best_cost) {
break; // No improvement
}
best_cost = new_best_cost;
// Swap generations
int* temp = current_generation;
current_generation = next_generation;
next_generation = temp;
}
// Sort all best subsets collected using qsort
qsort(all_best_subsets, total_best_count, subset_size * sizeof(int), compare_subsets_by_cost);
if ( print_unique ) count_unique_subsets(all_best_subsets, total_best_count, subset_size, "All best subsets");
if ( verbose ) {
printf( "Final best\n" );
for (int i = 0; i < B; i++ ) {
printf( "Subset %2d : {", i );
for (int k = 0; k < K; k++ )
printf( " %2d", (&all_best_subsets[i * subset_size])[k+1] );
printf( " } " );
printf( "Cost %2d\n", (&all_best_subsets[i * subset_size])[K+1] );
}
}
// Free pre-allocated arrays
free(in_offspring);
free(in_parent1);
free(in_parent2);
free(candidates);
// Return results
if (best_subsets_history != NULL) {
*best_subsets_history = all_best_subsets;
} else {
free(all_best_subsets);
}
if (iterations_used != NULL) {
*iterations_used = generation + 1;
}
free(current_generation);
free(next_generation);
return best_cost;
}
// Test bench
/*
int bs_find_test() {
srand(time(NULL));
// Test parameters
int N = 30; // Total numbers (0 to 29)
int K = 6; // Subset size
int B = 10; // Number of best subsets to keep
int L = 50; // Maximum iterations
printf("Genetic Algorithm for Subset Selection\n");
printf("======================================\n");
printf("Parameters:\n");
printf(" N (total numbers): %d\n", N);
printf(" K (subset size): %d\n", K);
printf(" B (best subsets): %d\n", B);
printf(" L (max iterations): %d\n", L);
printf("\n");
// Run the algorithm
int* best_subsets_history = NULL;
int iterations_used = 0;
int best_cost = genetic_subset_selection(N, K, B, L, 0,
cost_sum_squares,
&best_subsets_history,
&iterations_used);
printf("Best cost found: %d\n", best_cost);
printf("Iterations until convergence: %d\n\n", iterations_used);
// Display top 5 best subsets
printf("Top 5 best subsets:\n");
int subset_size = K + 2;
for (int i = 0; i < 5 && i < B * L; i++) {
int* subset = &best_subsets_history[i * subset_size];
if (subset[K + 1] == 0) break; // Check if cost is 0 (uninitialized)
printf("Subset %d: {", i + 1);
for (int j = 1; j <= K; j++) {
printf("%d", subset[j]);
if (j < K) printf(", ");
}
printf("} - Cost: %d\n", subset[K + 1]);
}
// Test with different parameters
printf("\n\nTesting with different parameters:\n");
printf("==================================\n");
// Test 1: Smaller problem
N = 20; K = 4; B = 6; L = 30;
free(best_subsets_history);
best_subsets_history = NULL;
iterations_used = 0;
best_cost = genetic_subset_selection(N, K, B, L, 0,
cost_sum_squares,
&best_subsets_history,
&iterations_used);
printf("\nTest 1 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L);
printf("Best cost: %d\n", best_cost);
printf("Iterations until convergence: %d\n", iterations_used);
printf("Best subset: {");
for (int j = 1; j <= K; j++) {
printf("%d", best_subsets_history[j]);
if (j < K) printf(", ");
}
printf("}\n");
// Test 2: Larger problem
N = 50; K = 8; B = 15; L = 100;
free(best_subsets_history);
best_subsets_history = NULL;
iterations_used = 0;
best_cost = genetic_subset_selection(N, K, B, L, 0,
cost_sum_squares,
&best_subsets_history,
&iterations_used);
printf("\nTest 2 - N=%d, K=%d, B=%d, L=%d\n", N, K, B, L);
printf("Best cost: %d\n", best_cost);
printf("Iterations until convergence: %d\n", iterations_used);
printf("Best subset: {");
for (int j = 1; j <= K; j++) {
printf("%d", best_subsets_history[j]);
if (j < K) printf(", ");
}
printf("}\n");
// Test 3: Test convergence speed with different B values
printf("\n\nConvergence Speed Analysis:\n");
printf("===========================\n");
N = 40; K = 7; L = 100;
for (int B_test = 5; B_test <= 20; B_test += 5) {
free(best_subsets_history);
best_subsets_history = NULL;
iterations_used = 0;
best_cost = genetic_subset_selection(N, K, B_test, L, 0,
cost_sum_squares,
&best_subsets_history,
&iterations_used);
printf("B=%2d: Best cost=%3d, Iterations=%3d\n",
B_test, best_cost, iterations_used);
}
free(best_subsets_history);
return 0;
}
*/
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Wrd_t * Gia_ManBsFindStart( Gia_Man_t * pGia, int nWords )
{
Vec_Wrd_t * vSims = Vec_WrdStartRandom( (Gia_ManCiNum(pGia) + 1) * nWords );
Vec_WrdFillExtra( vSims, Gia_ManObjNum(pGia) * nWords, 0 );
Abc_TtClear( Vec_WrdArray(vSims), nWords );
return vSims;
}
void Gia_ManBsFindNext( Gia_Man_t * pGia, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, int iMint )
{
Gia_Obj_t * pObj; int i;
word * pSims[2], * pSim;
Gia_ManForEachAnd( pGia, pObj, i ) {
pSim = Vec_WrdEntryP( vSims, i * nWords );
pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0(pObj, i) * nWords );
pSims[1] = Vec_WrdEntryP( vSims, Gia_ObjFaninId1(pObj, i) * nWords );
Abc_TtAndCompl( pSim, pSims[0], Gia_ObjFaninC0(pObj), pSims[1], Gia_ObjFaninC1(pObj), nWords );
}
Gia_ManForEachCo( pGia, pObj, i ) {
pSim = Vec_WrdEntryP( vSimsOuts, (iMint * Gia_ManCoNum(pGia) + i) * nWords );
pSims[0] = Vec_WrdEntryP( vSims, Gia_ObjFaninId0p(pGia, pObj) * nWords );
Abc_TtCopy( pSim, pSims[0], nWords, Gia_ObjFaninC0(pObj) );
}
}
int Gia_ManBsFindMyu( Gia_Man_t * p, int nWords, Vec_Wrd_t * vSims, Vec_Wrd_t * vSimsOuts, Vec_Int_t * vVarNums, Vec_Wrd_t * vTemp )
{
int nMints = 1 << Vec_IntSize(vVarNums);
int nWordsAll = Gia_ManCoNum(p) * nWords;
int nMyu = 0, pMyu[256], i, k, Var;
assert( nMints <= 256 );
assert( Vec_WrdSize(vTemp) == nWords * Vec_IntSize(vVarNums) );
assert( Vec_WrdSize(vSimsOuts) == nMints * nWordsAll );
Vec_IntForEachEntry( vVarNums, Var, i )
Abc_TtCopy( Vec_WrdEntryP(vTemp, i * nWords), Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, 0 );
for ( int m = 0; m < nMints; m++ ) {
Vec_IntForEachEntry( vVarNums, Var, i )
Abc_TtConst( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), nWords, (m >> i) & 1 );
Gia_ManBsFindNext( p, nWords, vSims, vSimsOuts, m );
}
Vec_IntForEachEntry( vVarNums, Var, i )
Abc_TtCopy( Vec_WrdEntryP(vSims, Gia_ManCiIdToId(p, Var) * nWords), Vec_WrdEntryP(vTemp, i * nWords), nWords, 0 );
for ( i = 0; i < nMints; i++ ) {
word * pSim = Vec_WrdEntryP(vSimsOuts, nWordsAll * i);
for ( k = 0; k < nMyu; k++ )
if ( Abc_TtEqual(pSim, Vec_WrdEntryP(vSimsOuts, nWordsAll * pMyu[k]), nWordsAll) )
break;
if ( k == nMyu )
pMyu[nMyu++] = i;
}
return nMyu;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
typedef struct BsFind_UserData_t_ {
Gia_Man_t * pGia;
int nWords;
Vec_Wrd_t * vSims;
Vec_Wrd_t * vSimsOuts;
Vec_Int_t * vVarNums;
Vec_Wrd_t * vTemp;
} BsFind_UserData_t;
BsFind_UserData_t * Gia_ManBsFindMyuFunctionStart( Gia_Man_t * pGia, int nWords, int nLutSize )
{
BsFind_UserData_t * p = ABC_CALLOC( BsFind_UserData_t, 1 );
p->pGia = pGia;
p->nWords = nWords;
p->vSims = Gia_ManBsFindStart( pGia, nWords );
p->vSimsOuts = Vec_WrdStart( (1 << nLutSize) * Gia_ManCoNum(pGia) * nWords );
p->vVarNums = Vec_IntAlloc( nLutSize );
p->vTemp = Vec_WrdStart( nLutSize * nWords );
return p;
}
int Gia_ManBsFindMyuFunction( int * subset, int K, void * pUserData )
{
BsFind_UserData_t * p = (BsFind_UserData_t *)pUserData;
Vec_IntClear( p->vVarNums );
for ( int i = 0; i < K; i++ )
Vec_IntPush( p->vVarNums, subset[i] );
return Gia_ManBsFindMyu( p->pGia, p->nWords, p->vSims, p->vSimsOuts, p->vVarNums, p->vTemp );
}
void Gia_ManBsFindMyuFunctionStop( BsFind_UserData_t * p )
{
Vec_WrdFree( p->vSims );
Vec_WrdFree( p->vSimsOuts );
Vec_WrdFree( p->vTemp );
Vec_IntFree( p->vVarNums );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManBsFindBest( Gia_Man_t * pGia, int nWords, int nLutSize, int nBest, int nIterMax, int fVerbose )
{
abctime clk = Abc_Clock();
Abc_Random(1);
BsFind_UserData_t * p = Gia_ManBsFindMyuFunctionStart( pGia, nWords, nLutSize );
int nIters = 0, Res = genetic_subset_selection( Gia_ManCiNum(pGia), nLutSize, nBest, nIterMax, fVerbose, Gia_ManBsFindMyuFunction, NULL, &nIters, (void *)p );
printf( "The best Myu %d was found after considering %d bound-sets in %d iterations. ", Res, nIters*nBest*(nBest-1)/2, nIters );
Abc_PrintTime( 1, "Time", Abc_Clock() - clk );
Gia_ManBsFindMyuFunctionStop( p );
return Res;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -64,6 +64,7 @@ struct Cbs_Man_t_
{
Cbs_Par_t Pars; // parameters
Gia_Man_t * pAig; // AIG manager
int nSyncedObjs; // pAig objects already prepped (Value/marks/refs) for resident reuse
Cbs_Que_t pProp; // propagation queue
Cbs_Que_t pJust; // justification queue
Cbs_Que_t pClauses; // clause queue
@ -71,6 +72,9 @@ struct Cbs_Man_t_
Vec_Int_t * vLevReas; // levels and decisions
Vec_Int_t * vModel; // satisfying assignment
Vec_Ptr_t * vTemp; // temporary storage
Vec_Int_t * vOutLits; // optional endpoint literals to sample before cancel
Vec_Int_t * vOutVals; // optional endpoint values by output
int iOutVal; // current output whose endpoints are sampled
// SAT calls statistics
int nSatUnsat; // the number of proofs
int nSatSat; // the number of failure
@ -256,6 +260,29 @@ static inline void Cbs_ManSaveModelAll( Cbs_Man_t * p, Vec_Int_t * vCex )
Vec_IntPush( vCex, Abc_Var2Lit(Gia_ObjId(p->pAig,pVar), !Cbs_VarValue(pVar)) );
}
static inline int Cbs_ManLitValue( Cbs_Man_t * p, int iLit )
{
Gia_Obj_t * pObj;
if ( iLit < 0 )
return -1;
if ( Abc_Lit2Var(iLit) == 0 )
return Abc_LitIsCompl(iLit);
pObj = Gia_ManObj( p->pAig, Abc_Lit2Var(iLit) );
if ( !Cbs_VarIsAssigned(pObj) )
return -1;
return Cbs_VarValue(pObj) ^ Abc_LitIsCompl(iLit);
}
static inline void Cbs_ManSaveOutVals( Cbs_Man_t * p, Vec_Int_t * vOutLits, Vec_Int_t * vOutVals, int Out )
{
if ( vOutLits == NULL || vOutVals == NULL )
return;
if ( 2*Out + 1 >= Vec_IntSize(vOutLits) )
return;
Vec_IntWriteEntry( vOutVals, 2*Out, Cbs_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out) ) );
Vec_IntWriteEntry( vOutVals, 2*Out + 1, Cbs_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out + 1) ) );
}
/**Function*************************************************************
Synopsis []
@ -954,7 +981,10 @@ int Cbs_ManSolve( Cbs_Man_t * p, Gia_Obj_t * pObj )
p->Pars.nBTThis = p->Pars.nJustThis = p->Pars.nBTThisNc = 0;
Cbs_ManAssign( p, pObj, 0, NULL, NULL );
if ( !Cbs_ManSolve_rec(p, 0) && !Cbs_ManCheckLimits(p) )
{
Cbs_ManSaveModel( p, p->vModel );
Cbs_ManSaveOutVals( p, p->vOutLits, p->vOutVals, p->iOutVal );
}
else
RetValue = 1;
Cbs_ManCancelUntil( p, 0 );
@ -1034,14 +1064,14 @@ void Cbs_ManSatPrintStats( Cbs_Man_t * p )
SeeAlso []
***********************************************************************/
Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose )
Vec_Int_t * Cbs_ManSolveMiterNcOutVals( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals )
{
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
Cbs_Man_t * p;
Vec_Int_t * vCex, * vVisit, * vCexStore;
Cbs_Man_t * p;
Vec_Int_t * vCex, * vVisit, * vCexStore, * vOutVals = NULL;
Vec_Str_t * vStatus;
Gia_Obj_t * pRoot;
Gia_Obj_t * pRoot;
int i, status;
abctime clk, clkTotal = Abc_Clock();
assert( Gia_ManRegNum(pAig) == 0 );
@ -1058,6 +1088,12 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
// create resulting data-structures
vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
vCexStore = Vec_IntAlloc( 10000 );
if ( pvOutVals )
{
*pvOutVals = NULL;
if ( vOutLits )
vOutVals = Vec_IntStartFull( 2 * Gia_ManPoNum(pAig) );
}
vVisit = Vec_IntAlloc( 100 );
vCex = Cbs_ReadModel( p );
// solve for each output
@ -1084,7 +1120,13 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
clk = Abc_Clock();
p->Pars.fUseHighest = 1;
p->Pars.fUseLowest = 0;
p->vOutLits = vOutLits;
p->vOutVals = vOutVals;
p->iOutVal = i;
status = Cbs_ManSolve( p, Gia_ObjChild0(pRoot) );
p->vOutLits = NULL;
p->vOutVals = NULL;
p->iOutVal = -1;
// printf( "\n" );
/*
if ( status == -1 )
@ -1126,6 +1168,10 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
Cbs_ManStop( p );
*pvStatus = vStatus;
if ( pvOutVals )
*pvOutVals = vOutVals;
else
Vec_IntFreeP( &vOutVals );
// printf( "Total number of cex literals = %d. (Ave = %d)\n",
// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
@ -1133,6 +1179,132 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
return vCexStore;
}
Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int f0Proved, int fVerbose )
{
return Cbs_ManSolveMiterNcOutVals( pAig, nConfs, pvStatus, f0Proved, fVerbose, NULL, NULL );
}
/**Function*************************************************************
Synopsis [Incrementally prepares newly appended objects of a persistent AIG.]
Description [The pAig of a resident manager is append-only across solve calls.
Cbs needs every unassigned object to carry Value=~0 and clean marks, and reads
Gia_ObjRefNum during branching. After a clean solve Cbs restores Value/marks
of the nodes it touched, and freshly appended nodes are zero-initialized, so we
only have to prep the suffix [nSyncedObjs, ObjNum): set Value=~0, clear marks,
grow pRefs and bump each new AND's fanin refs (= the global fanout counts that
Gia_ManCreateRefs would produce, computed incrementally). This replaces the
per-round O(|pAig|) refs/marks/value rebuild with O(newly appended).]
SideEffects [Allocates/grows pAig->pRefs (freed by Gia_ManStop).]
SeeAlso []
***********************************************************************/
void Cbs_ManSyncCore( Cbs_Man_t * p )
{
Gia_Man_t * pAig = p->pAig;
Gia_Obj_t * pObj;
int i, nObjs = Gia_ManObjNum( pAig );
assert( p->nSyncedObjs <= nObjs );
if ( p->nSyncedObjs == nObjs )
return;
pAig->pRefs = ABC_REALLOC( int, pAig->pRefs, nObjs );
memset( pAig->pRefs + p->nSyncedObjs, 0, sizeof(int) * (nObjs - p->nSyncedObjs) );
for ( i = p->nSyncedObjs; i < nObjs; i++ )
{
pObj = Gia_ManObj( pAig, i );
pObj->fMark0 = pObj->fMark1 = 0;
pObj->Value = ~0;
if ( Gia_ObjIsAnd(pObj) )
{
pAig->pRefs[Gia_ObjFaninId0(pObj, i)]++;
pAig->pRefs[Gia_ObjFaninId1(pObj, i)]++;
}
}
p->nSyncedObjs = nObjs;
}
/**Function*************************************************************
Synopsis [Solves a set of root literals directly on a persistent AIG.]
Description [Same prover as Cbs_ManSolveMiterNc, but each problem is a root
literal of p->pAig (no CO needed) instead of a CO of a freshly built view, and
the manager is resident: it is allocated once on the persistent COless pCore
and reused across rounds, only Cbs_ManSyncCore-ing the objects appended since
the last call - so neither the throwaway view (alloc + copy-all-CIs + cone
copy) nor the per-round whole-AIG prep is paid. Output index i corresponds to
vRootLits[i]; vCexStore / vStatus format matches Cbs_ManSolveMiterNc. CEX is
saved by CioId, which on pCore equals the view's CI numbering.]
SideEffects [Prepares newly appended objects via Cbs_ManSyncCore.]
SeeAlso []
***********************************************************************/
Vec_Int_t * Cbs_ManSolveRoots( Cbs_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose )
{
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
Gia_Man_t * pAig = p->pAig;
Vec_Int_t * vCex, * vCexStore;
Vec_Str_t * vStatus;
int i, iLit, status;
abctime clk, clkTotal = Abc_Clock();
assert( Gia_ManRegNum(pAig) == 0 );
Cbs_ManSyncCore( p ); // prep only objects appended since the last solve
vStatus = Vec_StrAlloc( Vec_IntSize(vRootLits) );
vCexStore = Vec_IntAlloc( 10000 );
vCex = Cbs_ReadModel( p );
Vec_IntForEachEntry( vRootLits, iLit, i )
{
Vec_IntClear( vCex );
if ( Abc_Lit2Var(iLit) == 0 ) // structural constant root
{
if ( Abc_LitIsCompl(iLit) ) // const 1: trivial counter-example
{
Cec_ManSatAddToStore( vCexStore, vCex, i );
Vec_StrPush( vStatus, 0 );
}
else // const 0: proved
Vec_StrPush( vStatus, 1 );
continue;
}
clk = Abc_Clock();
p->Pars.fUseHighest = 1;
p->Pars.fUseLowest = 0;
status = Cbs_ManSolve( p, Gia_ObjFromLit(pAig, iLit) );
Vec_StrPush( vStatus, (char)status );
if ( status == -1 )
{
p->nSatUndec++;
p->nConfUndec += p->Pars.nBTThis;
Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
p->timeSatUndec += Abc_Clock() - clk;
continue;
}
if ( status == 1 )
{
p->nSatUnsat++;
p->nConfUnsat += p->Pars.nBTThis;
p->timeSatUnsat += Abc_Clock() - clk;
continue;
}
p->nSatSat++;
p->nConfSat += p->Pars.nBTThis;
Cec_ManSatAddToStore( vCexStore, vCex, i );
p->timeSatSat += Abc_Clock() - clk;
}
p->nSatTotal = Vec_IntSize( vRootLits );
p->timeTotal = Abc_Clock() - clkTotal;
if ( fVerbose )
Cbs_ManSatPrintStats( p );
// manager is resident: caller (Cec_DynSrm) owns its lifetime
*pvStatus = vStatus;
return vCexStore;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
@ -1140,4 +1312,3 @@ Vec_Int_t * Cbs_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
ABC_NAMESPACE_IMPL_END

View File

@ -83,6 +83,7 @@ struct Tas_Man_t_
{
Tas_Par_t Pars; // parameters
Gia_Man_t * pAig; // AIG manager
int nSyncedObjs; // pAig objects already prepped (Value/marks/refs) for resident reuse
Tas_Que_t pProp; // propagation queue
Tas_Que_t pJust; // justification queue
Tas_Que_t pClauses; // clause queue
@ -90,6 +91,9 @@ struct Tas_Man_t_
Vec_Int_t * vLevReas; // levels and decisions
Vec_Int_t * vModel; // satisfying assignment
Vec_Ptr_t * vTemp; // temporary storage
Vec_Int_t * vOutLits; // optional endpoint literals to sample before cancel
Vec_Int_t * vOutVals; // optional endpoint values by output
int iOutVal; // current output whose endpoints are sampled
// watched clauses
Tas_Sto_t pStore; // storage for watched clauses
int * pWatches; // watched lists for each literal
@ -308,6 +312,29 @@ static inline void Tas_ManSaveModel( Tas_Man_t * p, Vec_Int_t * vCex )
}
}
static inline int Tas_ManLitValue( Tas_Man_t * p, int iLit )
{
Gia_Obj_t * pObj;
if ( iLit < 0 )
return -1;
if ( Abc_Lit2Var(iLit) == 0 )
return Abc_LitIsCompl(iLit);
pObj = Gia_ManObj( p->pAig, Abc_Lit2Var(iLit) );
if ( !Tas_VarIsAssigned(pObj) )
return -1;
return Tas_VarValue(pObj) ^ Abc_LitIsCompl(iLit);
}
static inline void Tas_ManSaveOutVals( Tas_Man_t * p, Vec_Int_t * vOutLits, Vec_Int_t * vOutVals, int Out )
{
if ( vOutLits == NULL || vOutVals == NULL )
return;
if ( 2*Out + 1 >= Vec_IntSize(vOutLits) )
return;
Vec_IntWriteEntry( vOutVals, 2*Out, Tas_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out) ) );
Vec_IntWriteEntry( vOutVals, 2*Out + 1, Tas_ManLitValue( p, Vec_IntEntry(vOutLits, 2*Out + 1) ) );
}
/**Function*************************************************************
Synopsis []
@ -1380,7 +1407,10 @@ int Tas_ManSolve( Tas_Man_t * p, Gia_Obj_t * pObj, Gia_Obj_t * pObj2 )
if ( pObj2 && !Tas_VarIsAssigned(Gia_Regular(pObj2)) )
Tas_ManAssign( p, pObj2, 0, NULL, NULL );
if ( !Tas_ManSolve_rec(p, 0) && !Tas_ManCheckLimits(p) )
{
Tas_ManSaveModel( p, p->vModel );
Tas_ManSaveOutVals( p, p->vOutLits, p->vOutVals, p->iOutVal );
}
else
RetValue = 1;
Tas_ManCancelUntil( p, 0 );
@ -1514,14 +1544,14 @@ void Tas_ManSatPrintStats( Tas_Man_t * p )
SeeAlso []
***********************************************************************/
Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
Vec_Int_t * Tas_ManSolveMiterNcOutVals( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose, Vec_Int_t * vOutLits, Vec_Int_t ** pvOutVals )
{
extern void Gia_ManCollectTest( Gia_Man_t * pAig );
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
Tas_Man_t * p;
Vec_Int_t * vCex, * vVisit, * vCexStore;
Tas_Man_t * p;
Vec_Int_t * vCex, * vVisit, * vCexStore, * vOutVals = NULL;
Vec_Str_t * vStatus;
Gia_Obj_t * pRoot;//, * pRootCopy;
Gia_Obj_t * pRoot;//, * pRootCopy;
// Gia_Man_t * pAigCopy = Gia_ManDup( pAig ), * pAigTemp;
int i, status;
@ -1540,6 +1570,12 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
// create resulting data-structures
vStatus = Vec_StrAlloc( Gia_ManPoNum(pAig) );
vCexStore = Vec_IntAlloc( 10000 );
if ( pvOutVals )
{
*pvOutVals = NULL;
if ( vOutLits )
vOutVals = Vec_IntStartFull( 2 * Gia_ManPoNum(pAig) );
}
vVisit = Vec_IntAlloc( 100 );
vCex = Tas_ReadModel( p );
// solve for each output
@ -1567,7 +1603,13 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
// p->Pars.fUseActive = 1;
p->Pars.fUseHighest = 1;
p->Pars.fUseLowest = 0;
p->vOutLits = vOutLits;
p->vOutVals = vOutVals;
p->iOutVal = i;
status = Tas_ManSolve( p, Gia_ObjChild0(pRoot), NULL );
p->vOutLits = NULL;
p->vOutVals = NULL;
p->iOutVal = -1;
// printf( "\n" );
/*
if ( status == -1 )
@ -1621,6 +1663,10 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
// printf( "RecCalls = %8d. RecClause = %8d. RecNonChro = %8d.\n", p->nRecCall, p->nRecClause, p->nRecNonChro );
Tas_ManStop( p );
*pvStatus = vStatus;
if ( pvOutVals )
*pvOutVals = vOutVals;
else
Vec_IntFreeP( &vOutVals );
// printf( "Total number of cex literals = %d. (Ave = %d)\n",
// Vec_IntSize(vCexStore)-2*p->nSatUndec-2*p->nSatSat,
@ -1628,6 +1674,11 @@ Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvSt
return vCexStore;
}
Vec_Int_t * Tas_ManSolveMiterNc( Gia_Man_t * pAig, int nConfs, Vec_Str_t ** pvStatus, int fVerbose )
{
return Tas_ManSolveMiterNcOutVals( pAig, nConfs, pvStatus, fVerbose, NULL, NULL );
}
/**Function*************************************************************
Synopsis [Packs patterns into array of simulation info.]
@ -1782,10 +1833,144 @@ void Tas_ManSolveMiterNc2( Gia_Man_t * pAig, int nConfs, Gia_Man_t * pAigOld, Ve
}
/**Function*************************************************************
Synopsis [Sets the conflict limit.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Tas_ManSetConflictNum( Tas_Man_t * p, int Num )
{
p->Pars.nBTLimit = Num;
}
/**Function*************************************************************
Synopsis [Syncs newly appended pAig objects for resident reuse.]
Description [Prepares objects appended since the last sync so the
persistent solver can reuse the same manager across rounds. Mirrors
Cbs_ManSyncCore but also resizes the TAS-specific watched-literal and
activity arrays.]
SideEffects []
SeeAlso []
***********************************************************************/
void Tas_ManSyncCore( Tas_Man_t * p )
{
Gia_Man_t * pAig = p->pAig;
Gia_Obj_t * pObj;
int i, nObjs = Gia_ManObjNum( pAig );
assert( p->nSyncedObjs <= nObjs );
if ( p->nSyncedObjs == nObjs )
return;
pAig->pRefs = ABC_REALLOC( int, pAig->pRefs, nObjs );
memset( pAig->pRefs + p->nSyncedObjs, 0, sizeof(int) * (nObjs - p->nSyncedObjs) );
p->pWatches = ABC_REALLOC( int, p->pWatches, 2 * nObjs );
memset( p->pWatches + 2 * p->nSyncedObjs, 0, sizeof(int) * 2 * (nObjs - p->nSyncedObjs) );
p->pActivity = ABC_REALLOC( float, p->pActivity, nObjs );
memset( p->pActivity + p->nSyncedObjs, 0, sizeof(float) * (nObjs - p->nSyncedObjs) );
for ( i = p->nSyncedObjs; i < nObjs; i++ )
{
pObj = Gia_ManObj( pAig, i );
pObj->fMark0 = pObj->fMark1 = 0;
pObj->Value = ~0;
pObj->fPhase = 0;
if ( Gia_ObjIsAnd(pObj) )
{
pAig->pRefs[Gia_ObjFaninId0(pObj, i)]++;
pAig->pRefs[Gia_ObjFaninId1(pObj, i)]++;
}
}
p->nSyncedObjs = nObjs;
}
/**Function*************************************************************
Synopsis [Solves a set of root literals directly on a persistent AIG.]
Description [Same prover as Tas_ManSolveMiterNc, but each problem is a root
literal of p->pAig (no CO needed) instead of a CO of a freshly built view, and
the manager is resident: it is allocated once on the persistent COless pCore
and reused across rounds, only Tas_ManSyncCore-ing the objects appended since
the last call. Output index i corresponds to vRootLits[i]; vCexStore / vStatus
format matches Tas_ManSolveMiterNc. CEX is saved by CioId, which on pCore
equals the view's CI numbering.]
SideEffects [Prepares newly appended objects via Tas_ManSyncCore.]
SeeAlso []
***********************************************************************/
Vec_Int_t * Tas_ManSolveRoots( Tas_Man_t * p, Vec_Int_t * vRootLits, Vec_Str_t ** pvStatus, int fVerbose )
{
extern void Cec_ManSatAddToStore( Vec_Int_t * vCexStore, Vec_Int_t * vCex, int Out );
Gia_Man_t * pAig = p->pAig;
Vec_Int_t * vCex, * vCexStore;
Vec_Str_t * vStatus;
int i, iLit, status;
abctime clk, clkTotal = Abc_Clock();
assert( Gia_ManRegNum(pAig) == 0 );
Tas_ManSyncCore( p ); // prep only objects appended since the last solve
vStatus = Vec_StrAlloc( Vec_IntSize(vRootLits) );
vCexStore = Vec_IntAlloc( 10000 );
vCex = Tas_ReadModel( p );
Vec_IntForEachEntry( vRootLits, iLit, i )
{
Vec_IntClear( vCex );
if ( Abc_Lit2Var(iLit) == 0 ) // structural constant root
{
if ( Abc_LitIsCompl(iLit) ) // const 1: trivial counter-example
{
Cec_ManSatAddToStore( vCexStore, vCex, i );
Vec_StrPush( vStatus, 0 );
}
else // const 0: proved
Vec_StrPush( vStatus, 1 );
continue;
}
clk = Abc_Clock();
p->Pars.fUseHighest = 1;
p->Pars.fUseLowest = 0;
status = Tas_ManSolve( p, Gia_ObjFromLit(pAig, iLit), NULL );
Vec_StrPush( vStatus, (char)status );
if ( status == -1 )
{
p->nSatUndec++;
p->nConfUndec += p->Pars.nBTThis;
Cec_ManSatAddToStore( vCexStore, NULL, i ); // timeout
p->timeSatUndec += Abc_Clock() - clk;
continue;
}
if ( status == 0 )
{
p->nSatSat++;
p->nConfSat += p->Pars.nBTThis;
Cec_ManSatAddToStore( vCexStore, vCex, i );
p->timeSatSat += Abc_Clock() - clk;
continue;
}
assert( status == 1 );
p->nSatUnsat++;
p->nConfUnsat += p->Pars.nBTThis;
p->timeSatUnsat += Abc_Clock() - clk;
}
p->nSatTotal += Vec_IntSize(vRootLits);
p->timeTotal += Abc_Clock() - clkTotal;
*pvStatus = vStatus;
return vCexStore;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -42,42 +42,6 @@ extern int Gia_ManFactorNode( Gia_Man_t * p, char * pSop, Vec_Int_t * vLeaves );
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Gia_GetFakeNames( int nNames )
{
Vec_Ptr_t * vNames;
char Buffer[5];
int i;
vNames = Vec_PtrAlloc( nNames );
for ( i = 0; i < nNames; i++ )
{
if ( nNames < 26 )
{
Buffer[0] = 'a' + i;
Buffer[1] = 0;
}
else
{
Buffer[0] = 'a' + i%26;
Buffer[1] = '0' + i/26;
Buffer[2] = 0;
}
Vec_PtrPush( vNames, Extra_UtilStrsav(Buffer) );
}
return vNames;
}
/**Function*************************************************************
Synopsis []
@ -378,11 +342,11 @@ Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
if ( fVerbose )
{
Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p) );
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p) );
Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p), 0 );
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p), 1 );
char ** ppNamesCi = (char **)Vec_PtrArray( vNamesCi );
char ** ppNamesCo = (char **)Vec_PtrArray( vNamesCo );
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1 );
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1, 0 );
Vec_PtrFreeFree( vNamesCi );
Vec_PtrFreeFree( vNamesCo );
}
@ -404,6 +368,145 @@ void Gia_ManCollapseTestTest( Gia_Man_t * p )
Gia_ManStop( pNew );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManPrintDsdOne( Dsd_Manager_t * pManDsd, int Output, int OffSet )
{
Vec_Str_t * vStr = Vec_StrAlloc( 100 );
Dsd_TreePrint4( vStr, pManDsd, Output );
for ( int i = 0; i < OffSet; i++ )
printf( " " );
printf( "Supp %2d nDsd %2d %s\n", Dsd_TreeSuppSize(pManDsd, Output), Dsd_TreeNonDsdMax(pManDsd, Output), Vec_StrArray(vStr) );
Vec_StrFree( vStr );
fflush( stdout );
}
void Gia_ManPrintDsd( Dsd_Manager_t * pManDsd, int Output, int nOutputs, int OffSet )
{
if ( Output == -1 )
{
for ( int i = 0; i < nOutputs; i++ )
Gia_ManPrintDsdOne( pManDsd, i, OffSet );
}
else
{
assert( Output >= 0 && Output < nOutputs );
Gia_ManPrintDsdOne( pManDsd, Output, OffSet );
}
}
void Gia_ManCheckDsd( Gia_Man_t * p, int OffSet, int fVerbose )
{
DdManager * dd;
Dsd_Manager_t * pManDsd;
Vec_Ptr_t * vFuncs;
dd = Cudd_Init( Gia_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
vFuncs = Gia_ManCollapse( p, dd, 10000, 0 );
Cudd_AutodynDisable( dd );
if ( vFuncs == NULL )
{
Extra_StopManager( dd );
return;
}
pManDsd = Dsd_ManagerStart( dd, Gia_ManCiNum(p), 0 );
if ( pManDsd == NULL )
{
Gia_ManCollapseDeref( dd, vFuncs );
Cudd_Quit( dd );
return;
}
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
if ( fVerbose )
{
Vec_Ptr_t * vNamesCi = Gia_GetFakeNames( Gia_ManCiNum(p), 0 );
Vec_Ptr_t * vNamesCo = Gia_GetFakeNames( Gia_ManCoNum(p), 1 );
char ** ppNamesCi = (char **)Vec_PtrArray( vNamesCi );
char ** ppNamesCo = (char **)Vec_PtrArray( vNamesCo );
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, 0, -1, OffSet );
Vec_PtrFreeFree( vNamesCi );
Vec_PtrFreeFree( vNamesCo );
}
else
Gia_ManPrintDsd( pManDsd, 0, Vec_PtrSize(vFuncs), 0 );
Dsd_ManagerStop( pManDsd );
Gia_ManCollapseDeref( dd, vFuncs );
Extra_StopManager( dd );
}
Vec_Ptr_t * Gia_ManRecurDsdCof( DdManager * dd, Vec_Ptr_t * vFuncs, int iVar )
{
Vec_Ptr_t * vNew = Vec_PtrAlloc( 2 * Vec_PtrSize(vFuncs) ); DdNode * bFunc; int i;
Vec_PtrForEachEntry( DdNode *, vFuncs, bFunc, i ) {
DdNode * bCof0 = Cudd_Cofactor( dd, bFunc, Cudd_Not(Cudd_bddIthVar(dd, iVar)) ); Cudd_Ref( bCof0 );
DdNode * bCof1 = Cudd_Cofactor( dd, bFunc, Cudd_bddIthVar(dd, iVar) ); Cudd_Ref( bCof1 );
Vec_PtrPush( vNew, bCof0 );
Vec_PtrPush( vNew, bCof1 );
}
return vNew;
}
void Gia_ManRecurDsd( Gia_Man_t * p, int fVerbose )
{
DdManager * dd;
Dsd_Manager_t * pManDsd;
Vec_Ptr_t * vFuncs, * vAux;
dd = Cudd_Init( Gia_ManCiNum(p), 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
Cudd_AutodynEnable( dd, CUDD_REORDER_SYMM_SIFT );
vFuncs = Gia_ManCollapse( p, dd, 10000, 0 );
Cudd_AutodynDisable( dd );
if ( vFuncs == NULL )
{
Extra_StopManager( dd );
return;
}
pManDsd = Dsd_ManagerStart( dd, Gia_ManCiNum(p), 0 );
if ( pManDsd == NULL )
{
Gia_ManCollapseDeref( dd, vFuncs );
Cudd_Quit( dd );
return;
}
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
printf( "Function:\n" );
Gia_ManPrintDsd( pManDsd, 0, Vec_PtrSize(vFuncs), 0 );
for ( int i = 0; i < 5 && Dsd_TreeNonDsdMax(pManDsd, -1) > 0; i++ )
{
int v, iBestV = -1, DsdMin = ABC_INFINITY, SuppMin = ABC_INFINITY;
for ( v = 0; v < Gia_ManCiNum(p); v++ )
{
Vec_Ptr_t * vTemp = Gia_ManRecurDsdCof( dd, vFuncs, v );
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vTemp), Vec_PtrSize(vTemp) );
int DsdCur = Dsd_TreeNonDsdMax( pManDsd, -1 );
int SuppCur = Dsd_TreeSuppSize( pManDsd, -1 );
if ( DsdMin > DsdCur || (DsdMin == DsdCur && SuppMin > SuppCur) )
DsdMin = DsdCur, SuppMin = SuppCur, iBestV = v;
Gia_ManCollapseDeref( dd, vTemp );
}
assert( iBestV >= 0 );
vFuncs = Gia_ManRecurDsdCof( dd, vAux = vFuncs, iBestV );
Gia_ManCollapseDeref( dd, vAux );
printf( "Cofactoring variable %c:\n", (int)(iBestV >= 26 ? 'A' - 26 : 'a') + iBestV );
Dsd_Decompose( pManDsd, (DdNode **)Vec_PtrArray(vFuncs), Vec_PtrSize(vFuncs) );
Gia_ManPrintDsd( pManDsd, -1, Vec_PtrSize(vFuncs), (i+1)*2 );
}
Dsd_ManagerStop( pManDsd );
Gia_ManCollapseDeref( dd, vFuncs );
Extra_StopManager( dd );
}
#else
Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
@ -411,6 +514,14 @@ Gia_Man_t * Gia_ManCollapseTest( Gia_Man_t * p, int fVerbose )
return NULL;
}
void Gia_ManCheckDsd( Gia_Man_t * p, int OffSet, int fVerbose )
{
}
void Gia_ManRecurDsd( Gia_Man_t * p, int fVerbose )
{
}
#endif
////////////////////////////////////////////////////////////////////////

View File

@ -993,6 +993,97 @@ Gia_Man_t * Gia_ManDupCofAll( Gia_Man_t * p, int nFanLim, int fVerbose )
return pNew;
}
/**Function*************************************************************
Synopsis [Print the matrix.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManDsdMatrix( Gia_Man_t * p, int iIn )
{
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, j;
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
assert( Gia_ManPoNum(p) == 1 );
assert( iIn >= 0 && iIn < Gia_ManPiNum(p) );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManHashAlloc( pNew );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
for ( i = 0; i < Gia_ManPiNum(p); i++ ) if ( i != iIn )
for ( j = i+1; j < Gia_ManPiNum(p); j++ ) if ( j != iIn )
{
int pRes[8], k, n;
int iLit0 = Gia_ManPi(p, iIn)->Value;
int iLit1 = Gia_ManPi(p, i)->Value;
int iLit2 = Gia_ManPi(p, j)->Value;
for ( k = 0; k < 8; k++ )
{
Gia_ManPi(p, iIn)->Value = k & 1;
Gia_ManPi(p, i)->Value = (k >> 1) & 1;
Gia_ManPi(p, j)->Value = (k >> 2) & 1;
Gia_ManForEachAnd( p, pObj, n )
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
pRes[k] = Gia_ObjFanin0Copy(Gia_ManPo(p, 0));
}
Gia_ManPi(p, iIn)->Value = iLit0;
Gia_ManPi(p, i)->Value = iLit1;
Gia_ManPi(p, j)->Value = iLit2;
for ( k = 0; k < 4; k++ )
pRes[k] = Gia_ManHashXor( pNew, pRes[2*k], pRes[2*k+1] );
Vec_IntPush( vRes, Gia_ManHashXor(pNew, Gia_ManHashAnd(pNew, pRes[0], pRes[3]), Gia_ManHashAnd(pNew, pRes[1], pRes[2])) );
}
Vec_IntForEachEntry( vRes, j, i )
Gia_ManAppendCo( pNew, j );
Vec_IntFree( vRes );
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
return pNew;
}
void Gia_ManPrintDsdMatrix( Gia_Man_t * p, int iIn )
{
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
Gia_Man_t * pNew = Gia_ManDsdMatrix( p, iIn ); int i, j, fFirst = 1, Count = 0;
Gia_Man_t * pSweep = Cec4_ManSimulateTest3( pNew, 0, 0 );
Gia_ManStop( pNew );
printf( "%4c : ", ' ' );
for ( j = 0; j < Gia_ManPiNum(p); j++ )
printf( "%4d", j );
printf( "\n" );
for ( i = 0; i < Gia_ManPiNum(p); i++, printf("\n"), fFirst = 1 )
for ( j = 0; j < Gia_ManPiNum(p); j++ )
{
if ( fFirst )
printf( "%4d : ", i ), fFirst = 0;
if ( i == iIn )
continue;
if ( j == iIn )
printf( "%4c", ' ' );
else
{
if ( j > i ) {
if ( Gia_ObjFaninLit0p(pSweep, Gia_ManPo(pSweep, Count++)) == 0 )
printf( "%4c", '.' );
else
printf( "%4c", '+' );
}
else
printf( "%4c", ' ' );
}
}
assert( Count == Gia_ManPoNum(pSweep) );
Gia_ManStop( pSweep );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -29,9 +29,9 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define GIA_MAX_CUTSIZE 8
#define GIA_MAX_CUTNUM 65
#define GIA_MAX_TT_WORDS ((GIA_MAX_CUTSIZE > 6) ? 1 << (GIA_MAX_CUTSIZE-6) : 1)
#define GIA_MAX_CUTSIZE 14
#define GIA_MAX_CUTNUM 257
#define GIA_MAX_TT_WORDS ((GIA_MAX_CUTSIZE > 6) ? 1 << (GIA_MAX_CUTSIZE-6) : 1)
#define GIA_CUT_NO_LEAF 0xF
@ -45,6 +45,7 @@ struct Gia_Cut_t_
unsigned nTreeLeaves : 28; // tree leaves
unsigned nLeaves : 4; // leaf count
int pLeaves[GIA_MAX_CUTSIZE]; // leaves
float CostF;
};
typedef struct Gia_Sto_t_ Gia_Sto_t;
@ -281,7 +282,7 @@ static inline int Gia_CutSetLastCutIsContained( Gia_Cut_t ** pCuts, int nCuts )
SeeAlso []
***********************************************************************/
static inline int Gia_CutCompare( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
static inline int Gia_CutCompare2( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
{
if ( pCut0->nTreeLeaves < pCut1->nTreeLeaves ) return -1;
if ( pCut0->nTreeLeaves > pCut1->nTreeLeaves ) return 1;
@ -289,6 +290,14 @@ static inline int Gia_CutCompare( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
return 0;
}
static inline int Gia_CutCompare( Gia_Cut_t * pCut0, Gia_Cut_t * pCut1 )
{
if ( pCut0->CostF > pCut1->CostF ) return -1;
if ( pCut0->CostF < pCut1->CostF ) return 1;
if ( pCut0->nLeaves < pCut1->nLeaves ) return -1;
if ( pCut0->nLeaves > pCut1->nLeaves ) return 1;
return 0;
}
static inline int Gia_CutSetLastCutContains( Gia_Cut_t ** pCuts, int nCuts )
{
int i, k, fChanges = 0;
@ -432,6 +441,13 @@ static inline int Gia_CutTreeLeaves( Gia_Sto_t * p, Gia_Cut_t * pCut )
Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] ) == 1;
return Cost;
}
static inline float Gia_CutGetCost( Gia_Sto_t * p, Gia_Cut_t * pCut )
{
int i, Cost = 0;
for ( i = 0; i < (int)pCut->nLeaves; i++ )
Cost += Vec_IntEntry( p->vRefs, pCut->pLeaves[i] );
return (float)Cost / Abc_MaxInt(1, pCut->nLeaves);
}
static inline int Gia_StoPrepareSet( Gia_Sto_t * p, int iObj, int Index )
{
Vec_Int_t * vThis = Vec_WecEntry( p->vCuts, iObj );
@ -445,6 +461,7 @@ static inline int Gia_StoPrepareSet( Gia_Sto_t * p, int iObj, int Index )
pCutTemp->iFunc = pCut[pCut[0]+1];
pCutTemp->Sign = Gia_CutGetSign( pCutTemp );
pCutTemp->nTreeLeaves = Gia_CutTreeLeaves( p, pCutTemp );
pCutTemp->CostF = Gia_CutGetCost( p, pCutTemp );
}
return pList[0];
}
@ -512,6 +529,7 @@ void Gia_StoMergeCuts( Gia_Sto_t * p, int iObj )
if ( p->fCutMin && Gia_CutComputeTruth(p, pCut0, pCut1, fComp0, fComp1, pCutsR[nCutsR], fIsXor) )
pCutsR[nCutsR]->Sign = Gia_CutGetSign(pCutsR[nCutsR]);
pCutsR[nCutsR]->nTreeLeaves = Gia_CutTreeLeaves( p, pCutsR[nCutsR] );
pCutsR[nCutsR]->CostF = Gia_CutGetCost( p, pCutsR[nCutsR] );
nCutsR = Gia_CutSetAddCut( pCutsR, nCutsR, nCutNum );
}
p->CutCount[3] += nCutsR;
@ -631,7 +649,7 @@ void Gia_StoComputeCuts( Gia_Man_t * pGia )
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
printf( "\n" );
printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
}
@ -672,7 +690,7 @@ Vec_Wec_t * Gia_ManSelectCuts( Vec_Wec_t * vCuts, int nCuts, int nCutSizeMin )
Vec_Wec_t * vCutsSel = Vec_WecStart( nCuts );
int i; srand( time(NULL) );
for ( i = 0; i < nCuts; i++ )
while ( !Gia_StoSelectOneCut(vCuts, (rand() | (rand() << 15)) % Vec_WecSize(vCuts), Vec_WecEntry(vCutsSel, i), nCutSizeMin) );
while ( !Gia_StoSelectOneCut(vCuts, (int)(((unsigned)rand() | ((unsigned)rand() << 15)) % Vec_WecSize(vCuts)), Vec_WecEntry(vCutsSel, i), nCutSizeMin) );
return vCutsSel;
}
Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
@ -706,7 +724,7 @@ Vec_Wec_t * Gia_ManExtractCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
printf( "\n" );
printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
}
@ -981,15 +999,571 @@ Vec_Wec_t * Gia_ManExploreCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
printf( "\n" );
printf( "The number of nodes with cut count over the limit (%d cuts) = %d nodes (out of %d). ",
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
}
vCutsSel = Gia_ManFilterCuts( pGia, p->vCuts, nCutSize0, nCuts0 );
Gia_ManConsiderCuts( pGia, vCutsSel );
//Gia_ManConsiderCuts( pGia, vCutsSel );
Gia_StoFree( p );
return vCutsSel;
}
void Gia_ManExploreCutsTest( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int fVerbose0 )
{
Vec_Wec_t * vCutSel = Gia_ManExploreCuts( pGia, nCutSize0, nCuts0, fVerbose0 );
Vec_WecPrint( vCutSel, 0 );
Vec_WecFree( vCutSel );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Sto_t * Gia_ManMatchCutsInt( Gia_Man_t * pGia, int nCutSize0, int nCutNum0, int fTruth0, int fVerbose0 )
{
int nCutSize = nCutSize0;
int nCutNum = nCutNum0;
int fCutMin = fTruth0;
int fTruthMin = fTruth0;
int fVerbose = fVerbose0;
Gia_Sto_t * p = Gia_StoAlloc( pGia, nCutSize, nCutNum, fCutMin, fTruthMin, fVerbose );
Gia_Obj_t * pObj; int i, iObj;
assert( nCutSize <= GIA_MAX_CUTSIZE );
assert( nCutNum < GIA_MAX_CUTNUM );
// prepare references
Gia_ManForEachObj( p->pGia, pObj, iObj )
Gia_StoRefObj( p, iObj );
// compute cuts
Gia_StoComputeCutsConst0( p, 0 );
Gia_ManForEachCiId( p->pGia, iObj, i )
Gia_StoComputeCutsCi( p, iObj );
Gia_ManForEachAnd( p->pGia, pObj, iObj )
Gia_StoComputeCutsNode( p, iObj );
if ( p->fVerbose )
{
printf( "Running cut computation with CutSize = %d CutNum = %d CutMin = %s TruthMin = %s\n",
p->nCutSize, p->nCutNum, p->fCutMin ? "yes":"no", p->fTruthMin ? "yes":"no" );
printf( "CutPair = %.0f ", p->CutCount[0] );
printf( "Merge = %.0f (%.2f %%) ", p->CutCount[1], 100.0*p->CutCount[1]/p->CutCount[0] );
printf( "Eval = %.0f (%.2f %%) ", p->CutCount[2], 100.0*p->CutCount[2]/p->CutCount[0] );
printf( "Cut = %.0f (%.2f %%) ", p->CutCount[3], 100.0*p->CutCount[3]/p->CutCount[0] );
printf( "Cut/Node = %.2f ", p->CutCount[3] / Gia_ManAndNum(p->pGia) );
printf( "\n" );
printf( "The number of nodes with maximum cut count (%d cuts) = %d nodes (out of %d). ",
p->nCutNum, p->nCutsOver, Gia_ManAndNum(pGia) );
Abc_PrintTime( 0, "Time", Abc_Clock() - p->clkStart );
}
return p;
}
int Gia_ManCountSelfCuts( Gia_Man_t * p, Gia_Sto_t * pSto )
{
Vec_Int_t * vLevel; int i, k, * pCut, nNodes = 0;
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
Gia_Obj_t * pObj = Gia_ManObj(p, i);
if ( !Gia_ObjIsAnd(pObj) )
continue;
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k )
nNodes += pCut[0] == 2 && pCut[1] == Gia_ObjFaninId0p(p, pObj) && pCut[2] == Gia_ObjFaninId1p(p, pObj);
}
return nNodes;
}
void Gia_ManEvalCutHashing( Gia_Man_t * p, Gia_Sto_t * pSto )
{
Hsh_VecMan_t * pHash = Hsh_VecManStart( 100000 );
Vec_Int_t vTemp = {0};
Vec_Int_t * vLevel; int i, k, * pCut, nBytes = 0, nCuts = 0;
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
Gia_Obj_t * pObj = Gia_ManObj(p, i);
if ( !Gia_ObjIsAnd(pObj) )
continue;
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
vTemp.nSize = vTemp.nCap = pCut[0];
vTemp.pArray = pCut+1;
Hsh_VecManAdd( pHash, &vTemp );
nBytes += 4*(pCut[0]+1);
nCuts++;
}
}
printf( "Total cuts = %d. Unique = %d. Memory = %.2f MB. With hashing = %.2f MB.\n",
nCuts, Hsh_VecSize(pHash), 1.0*nBytes/(1<<20), Hsh_VecManMemory(pHash)/(1<<20) );
Hsh_VecManStop( pHash );
}
void Gia_ManDumpCutsText( Gia_Man_t * p, Gia_Sto_t * pSto, FILE * pFile, int fVerbose, char * pFileName )
{
Vec_Int_t * vLevel; int i, k, c, * pCut, nCuts = 0, nNodes = 0;
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
if ( !Gia_ObjIsAnd(Gia_ManObj(p, i)) )
continue;
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
if ( pCut[0] == 1 )
continue;
fprintf( pFile, "%d ", i );
for ( c = 1; c <= pCut[0]; c++ )
fprintf( pFile, "%d ", pCut[c] );
fprintf( pFile, "1\n" );
nCuts++;
}
nNodes++;
}
Gia_Obj_t * pObj;
Gia_ManForEachCo( p, pObj, i )
fprintf( pFile, "%d %d 0\n", Gia_ObjId(p, pObj), Gia_ObjFaninId0p(p, pObj) );
if ( fVerbose )
printf( "Dumped %d cuts for %d nodes into text file \"%s\".\n", nCuts, nNodes, pFileName ? pFileName : "stdout" );
}
void Gia_ManDumpCutsPrint( Gia_Man_t * p, Vec_Int_t * vStore, int nCutSize, int nCutNum )
{
int o, f, c;
int nObjs = Gia_ManObjNum( p );
int * pStore = Vec_IntArray( vStore );
if ( nCutSize == 0 || nCutNum == 0 )
return;
for ( o = 0; o < nObjs; o++ ) {
Gia_Obj_t * pObj = Gia_ManObj( p, o );
int * pNodeStore;
if ( !Gia_ObjIsAnd(pObj) && !Gia_ObjIsCo(pObj) )
continue;
pNodeStore = pStore + o * nCutSize * nCutNum;
printf( "Node %d has %d cuts:\n", o, nCutNum );
for ( f = 0; f < nCutSize; f++ ) {
printf( "Fanin %d:", f );
for ( c = 0; c < nCutNum; c++ )
printf( " %4d", pNodeStore[f * nCutNum + c] );
printf( "\n" );
}
}
}
void Gia_ManDumpCutsBin( Gia_Man_t * p, Gia_Sto_t * pSto, FILE * pFile, int nCutSize, int nCutNum, int fVerbose, char * pFileName )
{
Vec_Int_t * vLevel; int i, k, c, * pCut, Num, RetValue, nCuts = 0, nNodes = 0;
Vec_Int_t * vStore = Vec_IntStart( Gia_ManObjNum(p) * nCutSize * nCutNum );
int * pStore = Vec_IntArray( vStore );
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
Gia_Obj_t * pObj = Gia_ManObj(p, i);
int CutIndex = 0;
int * pNodeStore;
if ( !Gia_ObjIsAnd(pObj) )
continue;
pNodeStore = pStore + i * nCutSize * nCutNum;
// flatten cuts as [object][leaf][cut], so each leaf spans nCutNum consecutive entries
// add the mandatory two-leaf cut composed of the current node's fanins
if ( nCutNum > 0 ) {
pNodeStore[CutIndex] = Gia_ObjFaninId0p( p, pObj );
pNodeStore[nCutNum + CutIndex] = Gia_ObjFaninId1p( p, pObj );
CutIndex++;
nCuts++;
}
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
if ( pCut[0] == 1 )
continue;
if ( CutIndex >= nCutNum )
break;
assert( pCut[0] <= nCutSize );
for ( c = 0; c < pCut[0]; c++ )
pNodeStore[c * nCutNum + CutIndex] = pCut[c+1];
CutIndex++;
nCuts++;
}
nNodes++;
}
// add unit cuts for primary outputs driven by arbitrary objects (const, PI, or internal node)
if ( nCutSize > 0 && nCutNum > 0 ) {
Gia_Obj_t * pObj;
Gia_ManForEachCo( p, pObj, i ) {
int ObjId = Gia_ObjId( p, pObj );
int * pNodeStore = pStore + ObjId * nCutSize * nCutNum;
pNodeStore[0] = Gia_ObjFaninId0p( p, pObj );
nCuts++;
}
}
// the number of dimension
Num = 3;
RetValue = fwrite( &Num, 4, 1, pFile );
assert( RetValue == 1 );
// the number of objects
Num = Gia_ManObjNum(p);
RetValue = fwrite( &Num, 4, 1, pFile );
assert( RetValue == 1 );
// the cut size
Num = nCutSize;
RetValue = fwrite( &Num, 4, 1, pFile );
assert( RetValue == 1 );
// the cut count
Num = nCutNum;
RetValue = fwrite( &Num, 4, 1, pFile );
assert( RetValue == 1 );
// the cuts themselves
RetValue = fwrite( Vec_IntArray(vStore), 4, Vec_IntSize(vStore), pFile );
assert( RetValue == Vec_IntSize(vStore) );
if ( fVerbose )
printf( "Dumped %d cuts for %d nodes into binary file \"%s\" (%.2f MB).\n", nCuts, nNodes, pFileName, Vec_IntMemory(vStore)/(1<<20) );
//Gia_ManDumpCutsPrint( p, vStore, nCutSize, nCutNum );
Vec_IntFree( vStore );
}
void Gia_ManComputeCutsCore( Gia_Man_t * pGia, int nCutSize, int nCutNum, int fTruth, int fVerbose, int fDumpText, int fDumpBin, char * pFileName )
{
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, fTruth, fVerbose );
if ( fDumpText ) {
FILE * pFile = pFileName ? fopen(pFileName, "wb") : stdout;
if ( !pFile ) return;
Gia_ManDumpCutsText( pGia, pSto, pFile, fVerbose, pFileName );
fclose( pFile );
}
else if ( fDumpBin ) {
FILE * pFile = pFileName ? fopen(pFileName, "wb") : NULL;
if ( !pFile ) return;
Gia_ManDumpCutsBin( pGia, pSto, pFile, nCutSize, nCutNum, fVerbose, pFileName );
fclose( pFile );
}
//printf( "The number of nodes with self-cuts = %d (out of %d).\n", Gia_ManCountSelfCuts(pGia, pSto), Gia_ManAndNum(pGia) );
//Gia_ManEvalCutHashing( pGia, pSto );
Gia_StoFree( pSto );
}
Vec_Wec_t * Gia_ManCompute54Cuts( Gia_Man_t * pGia, int fVerbose )
{
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( pGia, 5, 8, 0, fVerbose );
Vec_Wec_t * vRes = Vec_WecAlloc( 1000 );
Vec_Int_t * vLevel; int i, k, c, * pCut;
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) ) {
if ( !Gia_ObjIsAnd(Gia_ManObj(pGia, i)) )
continue;
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) {
if ( pCut[0] != 4 && pCut[0] != 5 )
continue;
Vec_Int_t * vCut = Vec_WecPushLevel( vRes );
for ( c = 1; c <= pCut[0]; c++ )
Vec_IntPush( vCut, pCut[c] );
Vec_IntPush( vCut, i );
}
}
Gia_StoFree( pSto );
return vRes;
}
void Gia_ManMatchCuts( Vec_Mem_t * vTtMem, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
{
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose );
Vec_Int_t * vLevel; int i, j, k, * pCut;
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
Vec_Wec_t * vCuts = Vec_WecAlloc( 100 );
abctime clkStart = Abc_Clock();
assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) );
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
{
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
{
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
if ( *pSpot == -1 )
continue;
Vec_IntPush( vNodes, i );
vLevel = Vec_WecPushLevel( vCuts );
Vec_IntPush( vLevel, i );
for ( j = 1; j <= pCut[0]; j++ )
Vec_IntPush( vLevel, pCut[j] );
break;
}
}
printf( "Nodes with matching cuts: " );
Vec_IntPrint( vNodes );
if ( Vec_WecSize(vCuts) > 32 )
Vec_WecShrink(vCuts, 32);
Vec_WecPrint( vCuts, 0 );
Vec_WecFree( vCuts );
Vec_IntFree( vNodes );
Gia_StoFree( p );
if ( fVerbose )
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
}
Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
{
Vec_Ptr_t * vRes = Vec_PtrAlloc( Vec_PtrSize(vTtMems) );
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose );
Vec_Int_t * vLevel, * vTemp; int i, k, c, * pCut;
abctime clkStart = Abc_Clock();
for ( i = 0; i < Vec_PtrSize(vTtMems); i++ )
Vec_PtrPush( vRes, Vec_WecAlloc(100) );
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
{
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
{
Vec_Mem_t * vTtMem; int m;
Vec_PtrForEachEntry( Vec_Mem_t *, vTtMems, vTtMem, m )
{
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
if ( *pSpot == -1 )
continue;
vTemp = Vec_WecPushLevel( (Vec_Wec_t *)Vec_PtrEntry(vRes, m) );
Vec_IntPush( vTemp, i );
for ( c = 1; c <= pCut[0]; c++ )
Vec_IntPush( vTemp, pCut[c] );
}
}
}
Gia_StoFree( p );
if ( fVerbose ) {
Vec_Wec_t * vCuts;
printf( "Detected nodes by type: " );
Vec_PtrForEachEntry( Vec_Wec_t *, vRes, vCuts, i )
printf( "Type%d = %d ", i, Vec_WecSize(vCuts) );
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
}
return vRes;
}
Vec_Ptr_t * Gia_ManMatchCutsMany( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, int nFuncs, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose )
{
Gia_Sto_t * p = Gia_ManMatchCutsInt( pGia, nCutSize, nCutNum, 1, fVerbose );
Vec_Int_t * vLevel; int i, j, k, * pCut;
abctime clkStart = Abc_Clock();
assert( Abc_Truth6WordNum(nCutSize) == Vec_MemEntrySize(vTtMem) );
Vec_Ptr_t * vRes = Vec_PtrAlloc( nFuncs );
for ( i = 0; i < nFuncs; i++ )
Vec_PtrPush( vRes, Vec_WecAlloc(10) );
Vec_WecForEachLevel( p->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
{
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] > 1 )
{
word * pTruth = Vec_MemReadEntry( p->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
assert( (pTruth[0] & 1) == 0 );
int * pSpot = Vec_MemHashLookup( vTtMem, pTruth );
if ( *pSpot == -1 )
continue;
int iFunc = vMap ? Vec_IntEntry( vMap, *pSpot ) : 0;
assert( iFunc < nFuncs );
Vec_Wec_t * vCuts = (Vec_Wec_t *)Vec_PtrEntry( vRes, iFunc );
vLevel = Vec_WecPushLevel( vCuts );
Vec_IntPush( vLevel, i );
for ( j = 1; j <= pCut[0]; j++ )
Vec_IntPush( vLevel, pCut[j] );
break;
}
}
Gia_StoFree( p );
if ( fVerbose )
Abc_PrintTime( 1, "Cut matching time", Abc_Clock() - clkStart );
return vRes;
}
/**Function*************************************************************
Synopsis [Function enumeration.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Wrd_t * Gia_ManCollectCutFuncs( Gia_Man_t * p, int nCutSize, int nCutNum, int fVerbose )
{
Gia_Sto_t * pSto = Gia_ManMatchCutsInt( p, nCutSize, nCutNum, 1, 0 );
Vec_Wrd_t * vFuncs = Vec_WrdAlloc( 1000 ); Vec_Int_t * vLevel; int i, k, * pCut;
Vec_WecForEachLevel( pSto->vCuts, vLevel, i ) if ( Vec_IntSize(vLevel) )
Sdb_ForEachCut( Vec_IntArray(vLevel), pCut, k ) if ( pCut[0] == nCutSize ) {
word * pTruth = Vec_MemReadEntry( pSto->vTtMem, Abc_Lit2Var(pCut[pCut[0]+1]) );
Vec_WrdPush( vFuncs, pTruth[0] );
}
Gia_StoFree( pSto );
if ( fVerbose )
printf( "Collected %d cut functions using the AIG with %d nodes.\n", Vec_WrdSize(vFuncs), Gia_ManAndNum(p) );
return vFuncs;
}
Vec_Int_t * Gia_ManCountNpnClasses( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, int nClasses, Vec_Wrd_t * vOrig )
{
assert( Vec_MemEntryNum(vTtMem) == Vec_IntSize(vMap) );
Vec_Int_t * vClassCounts = Vec_IntStart( nClasses ); int i; word Func;
Vec_WrdForEachEntry( vOrig, Func, i ) {
int * pSpot = Vec_MemHashLookup( vTtMem, &Func );
if ( *pSpot == -1 )
continue;
int iClass = Vec_IntEntry( vMap, *pSpot );
if ( iClass == -1 )
continue;
assert( iClass < Vec_IntSize(vClassCounts) );
Vec_IntAddToEntry( vClassCounts, iClass, 1 );
}
return vClassCounts;
}
Vec_Wrd_t * Gia_ManMatchFilterClasses( Vec_Mem_t * vTtMem, Vec_Int_t * vMap, Vec_Int_t * vClassCounts, int nNumFuncs, int fVerbose )
{
int * pPerm = Abc_MergeSortCost( Vec_IntArray(vClassCounts), Vec_IntSize(vClassCounts) );
Vec_Wrd_t * vBest = Vec_WrdAlloc( nNumFuncs ); int i, k, Entry;
Vec_Int_t * vMapNew = Vec_IntStartFull( Vec_IntSize(vMap) );
for ( i = Vec_IntSize(vClassCounts)-1; i >= 0; i-- ) {
word Best = ~(word)0;
Vec_IntForEachEntry( vMap, Entry, k ) {
if ( Entry != pPerm[i] )
continue;
if ( Best > Vec_MemReadEntry(vTtMem, k)[0] )
Best = Vec_MemReadEntry(vTtMem, k)[0];
Vec_IntWriteEntry( vMapNew, k, Vec_WrdSize(vBest) );
}
Vec_WrdPush( vBest, Best );
assert( ~Best );
if ( Vec_WrdSize(vBest) == nNumFuncs )
break;
}
ABC_SWAP( Vec_Int_t, *vMap, *vMapNew );
Vec_IntFree( vMapNew );
ABC_FREE( pPerm );
if ( fVerbose )
printf( "Isolated %d (out of %d) most frequently occuring classes.\n", Vec_WrdSize(vBest), Vec_IntSize(vClassCounts) );
return vBest;
}
void Gia_ManMatchProfileFunctions( Vec_Wrd_t * vBestReprs, Vec_Mem_t * vTtMem, Vec_Int_t * vMap, Vec_Wrd_t * vFuncs, int nCutSize )
{
int BarSize = 60;
extern void Dau_DsdPrintFromTruth( word * pTruth, int nVarsInit );
Vec_Int_t * vCounts = Gia_ManCountNpnClasses( vTtMem, vMap, Vec_WrdSize(vBestReprs), vFuncs );
word Repr; int c, i, MaxCount = Vec_IntFindMax( vCounts );
Vec_WrdForEachEntry( vBestReprs, Repr, c )
{
int nSymb = BarSize*Vec_IntEntry(vCounts, c)/Abc_MaxInt(MaxCount, 1);
printf( "Class%4d : ", c );
printf( "Count =%6d ", Vec_IntEntry(vCounts, c) );
for ( i = 0; i < nSymb; i++ )
printf( "*" );
for ( i = nSymb; i < BarSize+3; i++ )
printf( " " );
Dau_DsdPrintFromTruth( &Repr, nCutSize );
}
Vec_IntFree( vCounts );
}
void Gia_ManMatchCones( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutSize, int nCutNum, int nNumFuncs, int nNumCones, int fVerbose )
{
abctime clkStart = Abc_Clock();
extern void Dau_CanonicizeArray( Vec_Wrd_t * vFuncs, int nVars, int fVerbose );
extern Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int_t ** pvMap, int fVerbose );
Vec_Wrd_t * vFuncs = Gia_ManCollectCutFuncs( pSmall, nCutSize, nCutNum, fVerbose );
Vec_Wrd_t * vOrig = Vec_WrdDup( vFuncs );
Dau_CanonicizeArray( vFuncs, nCutSize, fVerbose );
Vec_Int_t * vMap = NULL; int n;
Vec_Mem_t * vTtMem = Dau_CollectNpnFunctionsArray( vFuncs, nCutSize, &vMap, fVerbose );
Vec_WrdFree( vFuncs );
Vec_Int_t * vClassCounts = Gia_ManCountNpnClasses( vTtMem, vMap, Vec_IntEntryLast(vMap)+1, vOrig );
Vec_Wrd_t * vBestReprs = Gia_ManMatchFilterClasses( vTtMem, vMap, vClassCounts, nNumFuncs, fVerbose );
assert( Vec_WrdSize(vBestReprs) == nNumFuncs );
Vec_IntFree( vClassCounts );
printf( "Frequency profile for %d most popular classes in the small AIG:\n", nNumFuncs );
Gia_ManMatchProfileFunctions( vBestReprs, vTtMem, vMap, vOrig, nCutSize );
Vec_WrdFree( vOrig );
Abc_Random( 1 );
for ( n = 0; n < nNumCones; n++ ) {
int nRand = Abc_Random( 0 ) % Gia_ManCoNum(pBig);
Gia_Man_t * pCone = Gia_ManDupCones( pBig, &nRand, 1, 1 );
Vec_Wrd_t * vCutFuncs = Gia_ManCollectCutFuncs( pCone, nCutSize, nCutNum, 0 );
printf( "ITER %d: Considering output cone %d with %d and-nodes. ", n+1, nRand, Gia_ManAndNum(pCone) );
printf( "Profiling %d functions of %d-cuts:\n", Vec_WrdSize(vCutFuncs), nCutSize );
Gia_ManMatchProfileFunctions( vBestReprs, vTtMem, vMap, vCutFuncs, nCutSize );
Vec_WrdFree( vCutFuncs );
Gia_ManStop( pCone );
}
Vec_WrdFree( vBestReprs );
Vec_IntFree( vMap );
Vec_MemHashFree( vTtMem );
Vec_MemFree( vTtMem );
Abc_PrintTime( 1, "Total computation time", Abc_Clock() - clkStart );
}
/**Function*************************************************************
Synopsis [Function enumeration.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManMatchConesMinimizeTts( Vec_Wrd_t * vSims, int nVarsMax )
{
int nVars = 0;
int nWordsMax = Abc_Truth6WordNum( nVarsMax ), nWords;
int i, k = 0, nTruths = Vec_WrdSize(vSims) / nWordsMax;
assert( nTruths * nWordsMax == Vec_WrdSize(vSims) );
// support-minimize and find the largest supp size
for ( i = 0; i < nTruths; i++ ) {
word * pTruth = Vec_WrdEntryP( vSims, i * nWordsMax );
int nVarsCur = Abc_TtMinBase( pTruth, NULL, nVarsMax, nVarsMax );
nVars = Abc_MaxInt( nVars, nVarsCur );
}
// remap truth tables
nWords = Abc_Truth6WordNum( nVars );
for ( i = 0; i < nTruths; i++ ) {
word * pTruth = Vec_WrdEntryP( vSims, i * nWordsMax );
word * pTruth2 = Vec_WrdEntryP( vSims, k * nWords );
if ( Abc_TtSupportSize(pTruth, nVars) < 3 )
continue;
memmove( pTruth2, pTruth, nWords * sizeof(word) );
k++;
if ( 0 ) {
extern void Extra_PrintHexadecimal( FILE * pFile, unsigned Sign[], int nVars );
printf( "Type%d : ", i );
Extra_PrintHexadecimal( stdout, (unsigned *)pTruth2, nVars );
printf( "\n" );
}
}
Vec_WrdShrink ( vSims, k * nWords );
return nVars;
}
void Gia_ManMatchConesOutputPrint( Vec_Ptr_t * p, int fVerbose )
{
Vec_Wec_t * vCuts; int i;
printf( "Nodes with matching cuts:\n" );
Vec_PtrForEachEntry( Vec_Wec_t *, p, vCuts, i ) {
if ( fVerbose ) {
printf( "Type %d:\n", i );
Vec_WecPrint( vCuts, 0 );
}
else
printf( "Type %d present in %d cuts\n", i, Vec_WecSize(vCuts) );
}
}
void Gia_ManMatchConesOutputFree( Vec_Ptr_t * p )
{
Vec_Wec_t * vCuts; int i;
Vec_PtrForEachEntry( Vec_Wec_t *, p, vCuts, i )
Vec_WecFree( vCuts );
Vec_PtrFree( p );
}
void Gia_ManMatchConesOutput( Gia_Man_t * pBig, Gia_Man_t * pSmall, int nCutNum, int fVerbose )
{
abctime clkStart = Abc_Clock();
extern Vec_Mem_t * Dau_CollectNpnFunctionsArray( Vec_Wrd_t * vFuncs, int nVars, Vec_Int_t ** pvMap, int fVerbose );
Vec_Wrd_t * vSimsPi = Vec_WrdStartTruthTables( Gia_ManCiNum(pSmall) );
Vec_Wrd_t * vSims = Gia_ManSimPatSimOut( pSmall, vSimsPi, 1 );
int nVars = Gia_ManMatchConesMinimizeTts( vSims, Gia_ManCiNum(pSmall) );
Vec_WrdFree( vSimsPi );
if ( nVars > 10 ) {
printf( "Some output functions have support size more than 10.\n" );
Vec_WrdFree( vSims );
return;
}
Vec_Int_t * vMap = NULL;
Vec_Mem_t * vTtMem = Dau_CollectNpnFunctionsArray( vSims, nVars, &vMap, fVerbose );
int nFuncs = Vec_WrdSize(vSims) / Abc_Truth6WordNum(nVars);
assert( Vec_WrdSize(vSims) == nFuncs * Abc_Truth6WordNum(nVars) );
Vec_WrdFree( vSims );
printf( "Using %d output functions with the support size between 3 and %d.\n", nFuncs, nVars );
Vec_Ptr_t * vRes = Gia_ManMatchCutsMany( vTtMem, vMap, nFuncs, pBig, nVars, nCutNum, fVerbose );
Vec_MemHashFree( vTtMem );
Vec_MemFree( vTtMem );
Vec_IntFree( vMap );
Gia_ManMatchConesOutputPrint( vRes, fVerbose );
Gia_ManMatchConesOutputFree( vRes );
Abc_PrintTime( 1, "Total computation time", Abc_Clock() - clkStart );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
@ -997,4 +1571,3 @@ Vec_Wec_t * Gia_ManExploreCuts( Gia_Man_t * pGia, int nCutSize0, int nCuts0, int
ABC_NAMESPACE_IMPL_END

2316
src/aig/gia/giaDecGraph.cpp Normal file

File diff suppressed because it is too large Load Diff

View File

@ -43,7 +43,7 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose, Vec_Ptr_t * vGias )
{
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
abctime clkStart = Abc_Clock();
@ -55,6 +55,7 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
Abc_Random(0);
for ( i = 0; i < IterMax; i++ )
{
char * pCompress2rs = "balance -l; resub -K 6 -l; rewrite -l; resub -K 6 -N 2 -l; refactor -l; resub -K 8 -l; balance -l; resub -K 8 -N 2 -l; rewrite -l; resub -K 10 -l; rewrite -z -l; resub -K 10 -N 2 -l; balance -l; resub -K 12 -l; refactor -z -l; resub -K 12 -N 2 -l; rewrite -z -l; balance -l";
unsigned Rand = Abc_Random(0);
int fDch = Rand & 1;
//int fCom = (Rand >> 1) & 3;
@ -62,16 +63,16 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
int fFx = (Rand >> 2) & 1;
int KLut = fUseTwo ? 2 + (i % 5) : 3 + (i % 4);
int fChange = 0;
char Command[1000];
char * pComp = NULL;
char Command[2000];
char pComp[1000];
if ( fCom == 3 )
pComp = "; &put; compress2rs; compress2rs; compress2rs; &get";
sprintf( pComp, "; &put; %s; %s; %s; &get", pCompress2rs, pCompress2rs, pCompress2rs );
else if ( fCom == 2 )
pComp = "; &put; compress2rs; compress2rs; &get";
sprintf( pComp, "; &put; %s; %s; &get", pCompress2rs, pCompress2rs );
else if ( fCom == 1 )
pComp = "; &put; compress2rs; &get";
sprintf( pComp, "; &put; %s; &get", pCompress2rs );
else if ( fCom == 0 )
pComp = "; &dc2";
sprintf( pComp, "; &dc2" );
sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
if ( Abc_FrameIsBatchMode() )
@ -99,6 +100,8 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
pNew = Gia_ManDup( pTemp );
fChange = 1;
iIterLast = i;
if ( vGias )
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
}
else if ( Gia_ManAndNum(pNew) + Gia_ManAndNum(pNew)/10 < Gia_ManAndNum(pTemp) )
{
@ -138,16 +141,19 @@ Gia_Man_t * Gia_ManDeepSynOne( int nNoImpr, int TimeOut, int nAnds, int Seed, in
nAndsMin, nAnds, i, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
return pNew;
}
Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose )
Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fChoices, int fVerbose )
{
Vec_Ptr_t * vGias = fChoices ? Vec_PtrAlloc(100) : NULL;
Gia_Man_t * pInit = Gia_ManDup(pGia);
Gia_Man_t * pBest = Gia_ManDup(pGia);
Gia_Man_t * pThis;
int i;
if ( vGias )
Vec_PtrPush( vGias, Gia_ManDup(pGia) );
for ( i = 0; i < nIters; i++ )
{
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) );
pThis = Gia_ManDeepSynOne( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose );
pThis = Gia_ManDeepSynOne( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose, vGias );
if ( Gia_ManAndNum(pBest) > Gia_ManAndNum(pThis) )
{
Gia_ManStop( pBest );
@ -158,6 +164,393 @@ Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeO
}
Gia_ManStop( pInit );
if ( vGias) {
if ( Vec_PtrSize(vGias) > 1 ) {
extern Gia_Man_t * Gia_ManCreateChoicesArray( Vec_Ptr_t * vGias, int fVerbose );
Gia_ManStopP( &pBest );
pBest = Gia_ManCreateChoicesArray( vGias, fVerbose );
}
// cleanup
Gia_Man_t * pTemp;
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
Gia_ManStop( pTemp );
Vec_PtrFree( vGias );
}
return pBest;
}
/**Function*************************************************************
Synopsis [Generating one AIG by applying a randomized script.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManRandSyn( Gia_Man_t * p, unsigned random_seed )
{
char * pCompress2rs = "balance -l; resub -K 6 -l; rewrite -l; resub -K 6 -N 2 -l; refactor -l; resub -K 8 -l; balance -l; resub -K 8 -N 2 -l; rewrite -l; resub -K 10 -l; rewrite -z -l; resub -K 10 -N 2 -l; balance -l; resub -K 12 -l; refactor -z -l; resub -K 12 -N 2 -l; rewrite -z -l; balance -l";
unsigned Rand = random_seed;
int fDch = Rand & 1;
//int fCom = (Rand >> 1) & 3;
int fCom = (Rand >> 1) & 1;
int fFx = (Rand >> 2) & 1;
int fUseTwo = 0;
int KLut = fUseTwo ? 2 + (Rand % 5) : 3 + (Rand % 4);
//int fChange = 0;
char Command[2000];
char pComp[1000];
if ( fCom == 3 )
sprintf( pComp, "; &put; %s; %s; %s; &get", pCompress2rs, pCompress2rs, pCompress2rs );
else if ( fCom == 2 )
sprintf( pComp, "; &put; %s; %s; &get", pCompress2rs, pCompress2rs );
else if ( fCom == 1 )
sprintf( pComp, "; &put; %s; &get", pCompress2rs );
else if ( fCom == 0 )
sprintf( pComp, "; &dc2" );
sprintf( Command, "&dch%s; &if -a -K %d; &mfs -e -W 20 -L 20%s%s",
fDch ? " -f" : "", KLut, fFx ? "; &fx; &st" : "", pComp );
Gia_Man_t * pOld = Abc_FrameGetGia(Abc_FrameGetGlobalFrame());
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(p) );
if ( Abc_FrameIsBatchMode() )
{
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
return NULL;
}
}
else
{
Abc_FrameSetBatchMode( 1 );
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
return NULL;
}
Abc_FrameSetBatchMode( 0 );
}
Gia_Man_t * pRes = Abc_FrameGetGia(Abc_FrameGetGlobalFrame());
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pOld );
return pRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static void Gia_ManDeepSynParetoUpdate( Vec_Ptr_t * vPareto, Gia_Man_t * pCand, int nLevels, int nAnds )
{
Gia_Man_t * pBest = (Gia_Man_t *)Vec_PtrGetEntry( vPareto, nLevels );
if ( pBest == NULL || Gia_ManAndNum(pBest) > nAnds )
{
if ( pBest )
Gia_ManStop( pBest );
Vec_PtrSetEntry( vPareto, nLevels, Gia_ManDup(pCand) );
}
}
static void Gia_ManDeepSynParetoPrint( Vec_Ptr_t * vPareto )
{
Gia_Man_t * pTemp;
int i, fFirst = 1;
printf( "Pareto points:" );
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
{
if ( pTemp == NULL )
continue;
printf( "%s%d:%d", fFirst ? " " : " ", i, Gia_ManAndNum(pTemp) );
fFirst = 0;
}
if ( fFirst )
printf( " none" );
printf( "\n" );
}
static void Gia_ManDeepSynParetoSave( Vec_Ptr_t * vPareto, char * pBase )
{
Gia_Man_t * pTemp;
char FileName[1000];
int i;
if ( pBase == NULL )
pBase = Extra_UtilStrsav( "gia" );
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
{
if ( pTemp == NULL )
continue;
sprintf( FileName, "%s_%d_%d.aig", pBase, i, Gia_ManAndNum(pTemp) );
Gia_AigerWrite( pTemp, FileName, 0, 0, 0 );
}
ABC_FREE( pBase );
}
Gia_Man_t * Gia_ManDeepSynOne2( int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fVerbose, Vec_Ptr_t * vGias, Vec_Ptr_t * vPareto )
{
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
abctime clkStart = Abc_Clock();
int s, i, k, IterMax = 100000, nLevelsMin = -1, nAndsMin = -1;
int nNoImprCount = 0;
Gia_Man_t * pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
Gia_Man_t * pNew = Gia_ManDup( pTemp );
(void)fUseTwo;
Abc_Random(1);
for ( s = 0; s < 10+Seed; s++ )
Abc_Random(0);
nLevelsMin = Gia_ManLevelNum(pNew);
nAndsMin = Gia_ManAndNum(pNew);
for ( i = 0; i < IterMax; )
{
unsigned Rand = Abc_Random(0);
int fDch = Rand & 1;
int fResyn = (Rand >> 1) % 3;
int fChange = 0;
char Command[2000];
char pResyn[200];
if ( fResyn == 0 )
sprintf( pResyn, "&resyn3" );
else if ( fResyn == 1 )
sprintf( pResyn, "&resyn3rs" );
else
sprintf( pResyn, "&resyn3; &resyn3rs" );
sprintf( Command, "&dch%s; &if -y -K 6; %s", fDch ? " -f" : "", pResyn );
if ( Abc_FrameIsBatchMode() )
{
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
return NULL;
}
}
else
{
Abc_FrameSetBatchMode( 1 );
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
return NULL;
}
Abc_FrameSetBatchMode( 0 );
}
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
{
int nLevelTemp = Gia_ManLevelNum(pTemp);
int nAndsTemp = Gia_ManAndNum(pTemp);
if ( vPareto )
Gia_ManDeepSynParetoUpdate( vPareto, pTemp, nLevelTemp, nAndsTemp );
if ( nLevelsMin > nLevelTemp || (nLevelsMin == nLevelTemp && nAndsMin > nAndsTemp) )
{
Gia_ManStop( pNew );
pNew = Gia_ManDup( pTemp );
nLevelsMin = nLevelTemp;
nAndsMin = nAndsTemp;
fChange = 1;
if ( vGias )
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
nNoImprCount = 0;
}
else
nNoImprCount++;
}
if ( fChange && fVerbose )
{
printf( "Iter %6d : ", i );
printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
printf( "Lev = %3d ", nLevelsMin );
printf( "And = %6d ", nAndsMin );
printf( "<== best : " );
printf( "%s", Command );
printf( "\n" );
}
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
{
if ( !Abc_FrameIsBatchMode() )
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
break;
}
i++;
if ( nNoImprCount > nNoImpr )
{
int nOuter = 1 + (Abc_Random(0) % 3);
int nKmax = nAnds ? nAnds : 6;
int nKmin = 3;
int nLuts[3];
if ( nKmax < nKmin )
nKmin = nKmax;
for ( k = 0; k < nOuter; k++ )
nLuts[k] = nKmin + (Abc_Random(0) % (nKmax - nKmin + 1));
if ( fVerbose )
{
printf( "Completed %d iterations without improvement. Trying %d outer iterations with ", nNoImpr, nOuter );
for ( k = 0; k < nOuter; k++ )
printf( "%sK=%d", k ? ", " : "", nLuts[k] );
printf( ". Time = %.2f sec\n", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
}
nNoImprCount = 0;
for ( k = 0; k < nOuter && i < IterMax; k++ )
{
int nLut = nLuts[k];
int fOuterChange = 0;
sprintf( Command, "&dch; &if -K %d -m; &mfs; &st", nLut );
if ( Abc_FrameIsBatchMode() )
{
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
return NULL;
}
}
else
{
Abc_FrameSetBatchMode( 1 );
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), Command) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", Command );
return NULL;
}
Abc_FrameSetBatchMode( 0 );
}
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
{
int nLevelTemp = Gia_ManLevelNum(pTemp);
int nAndsTemp = Gia_ManAndNum(pTemp);
if ( vPareto )
Gia_ManDeepSynParetoUpdate( vPareto, pTemp, nLevelTemp, nAndsTemp );
if ( nLevelsMin > nLevelTemp || (nLevelsMin == nLevelTemp && nAndsMin > nAndsTemp) )
{
Gia_ManStop( pNew );
pNew = Gia_ManDup( pTemp );
nLevelsMin = nLevelTemp;
nAndsMin = nAndsTemp;
fOuterChange = 1;
if ( vGias )
Vec_PtrPush( vGias, Gia_ManDup(pTemp) );
}
}
if ( fOuterChange && fVerbose )
{
printf( "Iter %6d : ", i );
printf( "Time %8.2f sec : ", (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
printf( "Lev = %3d ", nLevelsMin );
printf( "And = %6d ", nAndsMin );
printf( "<== best : " );
printf( "%s", Command );
printf( "\n" );
}
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
{
if ( !Abc_FrameIsBatchMode() )
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
return pNew;
}
i++;
}
}
}
if ( i == IterMax )
printf( "Iteration limit (%d iters) is reached after %.2f seconds.\n", IterMax, (float)1.0*(Abc_Clock() - clkStart)/CLOCKS_PER_SEC );
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManDeepSyn2( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeOut, int nAnds, int Seed, int fUseTwo, int fChoices, int fVerbose )
{
Vec_Ptr_t * vGias = fChoices ? Vec_PtrAlloc(100) : NULL;
Vec_Ptr_t * vPareto = fUseTwo ? Vec_PtrStart(100) : NULL;
char * pParetoBase = NULL;
Gia_Man_t * pInit;
Gia_Man_t * pBest;
Gia_Man_t * pThis;
int i, nBestLev, nBestAnd;
if ( !Abc_NtkRecIsRunning3() )
{
Abc_Print( -1, "Gia_ManDeepSyn2(): LMS library is not loaded.\n" );
Abc_Print( -1, "Download \"rec6Lib_final_filtered3_recanon.aig\" and run \"rec_start3 _/rec6Lib_final_filtered3_recanon.aig\".\n" );
if ( vGias )
Vec_PtrFree( vGias );
if ( vPareto )
Vec_PtrFree( vPareto );
return Gia_ManDup( pGia );
}
if ( vPareto )
{
if ( pGia->pSpec && pGia->pSpec[0] )
pParetoBase = Extra_FileNameGeneric( pGia->pSpec );
else if ( pGia->pName && pGia->pName[0] )
pParetoBase = Extra_FileNameGeneric( pGia->pName );
else
pParetoBase = Extra_UtilStrsav( "gia" );
}
pInit = Gia_ManDup(pGia);
pBest = Gia_ManDup(pGia);
nBestLev = Gia_ManLevelNum(pBest);
nBestAnd = Gia_ManAndNum(pBest);
if ( vPareto )
Gia_ManDeepSynParetoUpdate( vPareto, pGia, nBestLev, nBestAnd );
if ( vGias )
Vec_PtrPush( vGias, Gia_ManDup(pGia) );
for ( i = 0; i < nIters; i++ )
{
if ( fVerbose )
printf( "ITER %d (out of %d) running for %d seconds\n", i + 1, nIters, TimeOut );
int nThisLev, nThisAnd;
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(pInit) );
pThis = Gia_ManDeepSynOne2( nNoImpr, TimeOut, nAnds, Seed+i, fUseTwo, fVerbose, vGias, vPareto );
nThisLev = Gia_ManLevelNum(pThis);
nThisAnd = Gia_ManAndNum(pThis);
if ( nBestLev > nThisLev || (nBestLev == nThisLev && nBestAnd > nThisAnd) )
{
Gia_ManStop( pBest );
pBest = pThis;
nBestLev = nThisLev;
nBestAnd = nThisAnd;
}
else
Gia_ManStop( pThis );
if ( vPareto )
Gia_ManDeepSynParetoPrint( vPareto );
}
Gia_ManStop( pInit );
if ( vGias) {
if ( Vec_PtrSize(vGias) > 1 ) {
extern Gia_Man_t * Gia_ManCreateChoicesArray( Vec_Ptr_t * vGias, int fVerbose );
Gia_ManStopP( &pBest );
pBest = Gia_ManCreateChoicesArray( vGias, fVerbose );
}
// cleanup
Gia_Man_t * pTemp;
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
Gia_ManStop( pTemp );
Vec_PtrFree( vGias );
}
if ( vPareto )
{
Gia_ManDeepSynParetoSave( vPareto, pParetoBase );
Gia_Man_t * pTemp;
Vec_PtrForEachEntry( Gia_Man_t *, vPareto, pTemp, i )
if ( pTemp )
Gia_ManStop( pTemp );
Vec_PtrFree( vPareto );
}
return pBest;
}
@ -167,4 +560,3 @@ Gia_Man_t * Gia_ManDeepSyn( Gia_Man_t * pGia, int nIters, int nNoImpr, int TimeO
ABC_NAMESPACE_IMPL_END

File diff suppressed because it is too large Load Diff

View File

@ -310,6 +310,39 @@ void Gia_ManDeriveReprs( Gia_Man_t * p )
}
}
/**Function*************************************************************
Synopsis [Given pSibls, derives original representitives and nexts.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManDeriveReprsFromSibls( Gia_Man_t *p )
{
int i, iObj;
assert( !p->pReprs && p->pSibls );
p->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(p) );
for ( i = 0; i < Gia_ManObjNum(p); i++ )
Gia_ObjSetRepr( p, i, GIA_VOID );
for ( i = 0; i < Gia_ManObjNum(p); i++ )
{
if ( p->pSibls[i] == 0 )
continue;
if ( p->pReprs[i].iRepr != GIA_VOID )
continue;
for ( iObj = p->pSibls[i]; iObj; iObj = p->pSibls[iObj] )
p->pReprs[iObj].iRepr = i;
}
ABC_FREE( p->pNexts );
p->pNexts = Gia_ManDeriveNexts( p );
}
/**Function*************************************************************
Synopsis []
@ -715,6 +748,30 @@ Gia_Man_t * Gia_ManEquivReduce( Gia_Man_t * p, int fUseAll, int fDualOut, int fS
return pNew;
}
/**Function*************************************************************
Synopsis [Duplicates the AIG in the DFS order.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Obj_t * Gia_MakeRandomChoice( Gia_Man_t * p, int iRepr )
{
int iTemp, Rand, Count = 0;
Gia_ClassForEachObj( p, iRepr, iTemp )
Count++;
Rand = rand() % Count;
Count = 0;
Gia_ClassForEachObj( p, iRepr, iTemp )
if ( Count++ == Rand )
break;
return Gia_ManObj(p, iTemp);
}
/**Function*************************************************************
Synopsis [Duplicates the AIG in the DFS order.]
@ -735,7 +792,7 @@ void Gia_ManEquivReduce2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,
if ( fDiveIn && (pRepr = Gia_ManEquivRepr(p, pObj, 1, 0)) )
{
int iTemp, iRepr = Gia_ObjId(p, pRepr);
Gia_Obj_t * pRepr2 = Gia_ManObj( p, Vec_IntEntry(vMap, iRepr) );
Gia_Obj_t * pRepr2 = vMap ? Gia_ManObj( p, Vec_IntEntry(vMap, iRepr) ) : Gia_MakeRandomChoice(p, iRepr);
Gia_ManEquivReduce2_rec( pNew, p, pRepr2, vMap, 0 );
Gia_ClassForEachObj( p, iRepr, iTemp )
{
@ -751,12 +808,13 @@ void Gia_ManEquivReduce2_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj,
Gia_ManEquivReduce2_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, 1 );
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
}
Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p, int fRandom )
{
Vec_Int_t * vMap;
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
int i;
if ( fRandom ) srand(time(NULL));
if ( !p->pReprs && p->pSibls )
{
int * pMap = ABC_FALLOC( int, Gia_ManObjNum(p) );
@ -789,7 +847,7 @@ Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
break;
if ( i == Gia_ManObjNum(p) )
return Gia_ManDup( p );
vMap = Gia_ManChoiceMinLevel( p );
vMap = fRandom ? NULL : Gia_ManChoiceMinLevel( p );
Gia_ManSetPhase( p );
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
@ -805,7 +863,7 @@ Gia_Man_t * Gia_ManEquivReduce2( Gia_Man_t * p )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManHashStop( pNew );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
Vec_IntFree( vMap );
Vec_IntFreeP( &vMap );
return pNew;
}
@ -2707,6 +2765,58 @@ void Gia_ManTransferTest( Gia_Man_t * p )
Gia_ManStop( pNew );
}
/**Function*************************************************************
Synopsis [Transfer from new to old.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManTransferEquivs2( Gia_Man_t * p, Gia_Man_t * pOld )
{
Gia_Obj_t * pObj;
Vec_Int_t * vClass;
int i, k, iNode, iRepr;
assert( p->pReprs != NULL );
assert( p->pNexts != NULL );
assert( pOld->pReprs == NULL );
assert( pOld->pNexts == NULL );
// create map
Gia_ManFillValue( p );
Gia_ManForEachObj( pOld, pObj, i )
if ( ~pObj->Value )
Gia_ManObj(p, Abc_Lit2Var(pObj->Value))->Value = Abc_Var2Lit(i, 0);
// start representatives
pOld->pReprs = ABC_CALLOC( Gia_Rpr_t, Gia_ManObjNum(pOld) );
for ( i = 0; i < Gia_ManObjNum(pOld); i++ )
Gia_ObjSetRepr( pOld, i, GIA_VOID );
// iterate over constant candidates
Gia_ManForEachConst( p, i )
if ( ~Gia_ManObj(p, i)->Value )
Gia_ObjSetRepr( pOld, Abc_Lit2Var(Gia_ManObj(p, i)->Value), 0 );
// iterate over class candidates
vClass = Vec_IntAlloc( 100 );
Gia_ManForEachClass( p, i )
{
Vec_IntClear( vClass );
Gia_ClassForEachObj( p, i, k )
if ( (int)Gia_ManObj(p, k)->Value >= 0 )
Vec_IntPushUnique( vClass, Abc_Lit2Var(Gia_ManObj(p, k)->Value) );
if ( Vec_IntSize( vClass ) <= 1 )
continue;
assert( Vec_IntSize( vClass ) > 1 );
Vec_IntSort( vClass, 0 );
iRepr = Vec_IntEntry( vClass, 0 );
Vec_IntForEachEntryStart( vClass, iNode, k, 1 )
Gia_ObjSetRepr( pOld, iNode, iRepr );
}
Vec_IntFree( vClass );
pOld->pNexts = Gia_ManDeriveNexts( pOld );
}
/**Function*************************************************************

View File

@ -150,6 +150,13 @@ Vec_Wrd_t * Gia_ManComputeTruths( Gia_Man_t * p, int nCutSize, int nLutNum, int
// collect and sort fanins
vLeaves.nCap = vLeaves.nSize = Gia_ObjLutSize( p, i );
vLeaves.pArray = Gia_ObjLutFanins( p, i );
if( !Vec_IntCheckUniqueSmall(&vLeaves) )
{
Vec_IntUniqify(&vLeaves);
Vec_IntWriteEntry(p->vMapping, Vec_IntEntry(p->vMapping, i), vLeaves.nSize);
for ( k = 0; k < vLeaves.nSize; k++ )
Vec_IntWriteEntry(p->vMapping, Vec_IntEntry(p->vMapping, i) + 1 + k, vLeaves.pArray[k]);
}
assert( Vec_IntCheckUniqueSmall(&vLeaves) );
Vec_IntSelectSort( Vec_IntArray(&vLeaves), Vec_IntSize(&vLeaves) );
if ( !fReverse )
@ -210,7 +217,9 @@ Vec_Wec_t * Gia_ManFxRetrieve( Gia_Man_t * p, Vec_Str_t ** pvCompl, int fReverse
int nVars = Gia_ObjLutSize( p, i );
int * pVars = Gia_ObjLutFanins( p, i );
word * pTruth = Vec_WrdEntryP( vTruths, Counter++ * nWords );
Abc_TtFlipVar5( pTruth, nVars );
int Status = Kit_TruthIsop( (unsigned *)pTruth, nVars, vCover, 1 );
Abc_TtFlipVar5( pTruth, nVars );
if ( Vec_IntSize(vCover) == 0 || (Vec_IntSize(vCover) == 1 && Vec_IntEntry(vCover,0) == 0) )
{
Vec_StrWriteEntry( *pvCompl, pObj->Value, (char)(Vec_IntSize(vCover) == 0) );

View File

@ -924,10 +924,657 @@ void Gia_ManTestWordFile( Gia_Man_t * p, char * pFileName, char * pDumpFile, int
Abc_PrintTime( 1, "Total checking time", Abc_Clock() - clk );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManSumCount( char * p, Vec_Int_t * vDec, int b )
{
int i, Ent, Count = 0, Sum = 0;
for ( i = 0; p[i]; i++ ) {
Ent = (p[i] >= '0' && p[i] <= '9') ? p[i]-'0' : p[i]-'A'+10;
Count += Vec_IntEntry(vDec, Ent) + b * (1 << (Sum += Ent));
}
return Count + b * ((1 << Sum) - 1);
}
Vec_Str_t * Gia_ManSumEnum_rec( int Num )
{
if ( Num == 1 ) {
Vec_Str_t * vRes = Vec_StrAlloc(2);
Vec_StrPush( vRes, '1' );
Vec_StrPush( vRes, '\0' );
return vRes;
}
Vec_Str_t * vRes = Vec_StrAlloc( 16 );
for ( int i = 1; i < Num; i++ ) {
Vec_Str_t * vRes0 = Gia_ManSumEnum_rec(i);
Vec_Str_t * vRes1 = Gia_ManSumEnum_rec(Num-i);
for ( int c0 = 0; c0 < Vec_StrSize(vRes0); c0 += strlen(Vec_StrEntryP(vRes0,c0))+1 )
for ( int c1 = 0; c1 < Vec_StrSize(vRes1); c1 += strlen(Vec_StrEntryP(vRes1,c1))+1 )
Vec_StrPrintF( vRes, "%s%s%c", Vec_StrEntryP(vRes0,c0), Vec_StrEntryP(vRes1,c1), '\0' );
Vec_StrPrintF( vRes, "%c%c", Num < 10 ? '0'+Num : 'A'+Num-10, '\0' );
Vec_StrFree( vRes0 );
Vec_StrFree( vRes1 );
}
return vRes;
}
void Gia_ManSumEnum( int n, Vec_Int_t * vDec )
{
Vec_Str_t * vRes = Gia_ManSumEnum_rec( n );
for ( int b = 1; b <= 256; b <<= 1 ) {
int iBest = -1, CountCur, CountBest = ABC_INFINITY;
for ( int c0 = 0; c0 < Vec_StrSize(vRes); c0 += strlen(Vec_StrEntryP(vRes,c0))+1 ) {
CountCur = Gia_ManSumCount( Vec_StrEntryP(vRes,c0), vDec, b );
if ( CountBest > CountCur )
CountBest = CountCur, iBest = c0;
}
printf( " %8d", CountBest );
//printf( " %8s", Vec_StrEntryP(vRes,iBest) );
//printf( " %.3f", (float)CountBest/(3*b*((1<<n)-1)) );
}
// Vec_StrPrint( vRes, 0 );
Vec_StrFree( vRes );
}
Vec_Int_t * Gia_ManSumGenDec( int n )
{
Vec_Int_t * vDec = Vec_IntAlloc( n + 1 );
Vec_IntPush( vDec, 0 );
Vec_IntPush( vDec, 0 );
Vec_IntPush( vDec, 4 );
Vec_IntPush( vDec, 12 );
for ( int i = 4; i <= n; i++ ) {
int Ent0 = Vec_IntEntry( vDec, i / 2 );
int Ent1 = Vec_IntEntry( vDec, i - i / 2 );
assert( Vec_IntSize(vDec) == i );
Vec_IntPush( vDec, Ent0 + Ent1 + (1 << i / 2) * (1 << (i - i / 2)) );
}
return vDec;
}
void Gia_ManSumEnumTest()
{
Vec_Int_t * vDec = Gia_ManSumGenDec( 16 );
printf( " " );
for ( int b = 1; b <= 256; b <<= 1 )
printf( " %8d", b );
printf( "\n" );
for ( int i = 1; i <= 15; i++ ) {
printf( "%2d :", i );
Gia_ManSumEnum( i, vDec );
printf( "\n" );
}
Vec_IntFree( vDec );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManGenNeuronDumpVerilog( Vec_Wrd_t * vData, int nIBits, int nOBits )
{
FILE * pFile = fopen( "temp.v", "wb" );
if ( pFile == NULL ) {
printf( "Cannot open output file.\n" );
return;
}
fprintf( pFile, "module neuron_%d_%d_%d ( input [%d:0] i, output [%d:0] o );\n",
Vec_WrdSize(vData)-1, nIBits, nOBits, (Vec_WrdSize(vData)-1)*nIBits-1, nOBits-1 );
fprintf( pFile, "assign o = %d'h%lX", nOBits, Vec_WrdEntryLast(vData) );
word Data; int i;
Vec_WrdForEachEntryStop( vData, Data, i, Vec_WrdSize(vData)-1 )
fprintf( pFile, "\n + %d'h%lX * i[%d:%d]", nOBits, Data, nIBits*(i+1)-1, nIBits*i );
fprintf( pFile, ";\nendmodule\n\n" );
fclose( pFile );
printf( "Dumped the neuron specification into file \"temp.v\".\n" );
}
void Gia_ManGenNeuronAdder( Gia_Man_t * p, int nLits, int * pLitsA, int * pLitsB, int Carry, Vec_Int_t * vRes )
{
extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
int i, Res = -1;
Vec_IntClear( vRes );
for ( i = 0; i < nLits; i++ ) {
Wlc_BlastFullAdder( p, pLitsA[i], pLitsB[i], Carry, &Carry, &Res );
Vec_IntPush( vRes, Res );
}
}
void Gia_ManGenCompact( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1, Vec_Int_t * vIn2, Vec_Int_t * vOut0, Vec_Int_t * vOut1 )
{
extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
assert( Vec_IntSize(vIn0) == Vec_IntSize(vIn1) );
assert( Vec_IntSize(vIn0) == Vec_IntSize(vIn2) );
Vec_IntPush( vOut1, 0 );
int i, Lit0, Lit1, Lit2, Out0, Out1;
Vec_IntForEachEntryThree( vIn0, vIn1, vIn2, Lit0, Lit1, Lit2, i ) {
Wlc_BlastFullAdder( p, Lit0, Lit1, Lit2, &Out1, &Out0 );
Vec_IntPush( vOut0, Out0 );
Vec_IntPush( vOut1, Out1 );
}
Vec_IntPop( vOut1 );
assert( Vec_IntSize(vIn0) == Vec_IntSize(vOut0) );
assert( Vec_IntSize(vIn0) == Vec_IntSize(vOut1) );
}
Vec_Wec_t * Gia_ManGenNeuronCreateArgs( Vec_Wrd_t * vData, int nIBits, int nOBits )
{
word Data = Vec_WrdEntryLast(vData); int i, b, n, nLits = 2;
Vec_Wec_t * vArgs = Vec_WecAlloc( Vec_WrdSize(vData) * nIBits );
Vec_Int_t * vLev = Vec_WecPushLevel( vArgs );
Vec_IntFill( vLev, nOBits, 0 );
for ( b = 0; b < nOBits; b++ )
if ( (Data >> b) & 1 )
Vec_IntWriteEntry( vLev, b, 1 );
Vec_WrdForEachEntryStop( vData, Data, i, Vec_WrdSize(vData)-1 ) {
for ( n = 0; n < nIBits; n++, nLits += 2 ) {
Vec_Int_t * vLev = Vec_WecPushLevel( vArgs );
Vec_IntFill( vLev, nOBits, 0 );
for ( b = 0; b < nOBits; b++ )
if ( ((Data >> b) & 1) && b+n < nOBits )
Vec_IntWriteEntry( vLev, b+n, nLits );
}
}
return vArgs;
}
Vec_Wec_t * Gia_ManGenNeuronTransformArgs( Gia_Man_t * pNew, Vec_Wec_t * vArgs, int nLutSize, int nOBits )
{
int i, nParts = (Vec_WecSize(vArgs) + nLutSize - 2) / nLutSize;
while ( Vec_WecSize(vArgs) < nLutSize*nParts+1 )
Vec_IntFill( Vec_WecPushLevel(vArgs), nOBits, 0 );
assert( Vec_WecSize(vArgs) == nLutSize*nParts+1 );
Vec_Wec_t * vNew = Vec_WecAlloc( nParts );
Vec_Int_t * vRes = Vec_WecPushLevel( vNew ), * vArg;
Vec_IntAppend( vRes, Vec_WecEntry(vArgs, 0) );
Vec_WecForEachLevelStart( vArgs, vArg, i, 1 ) {
Gia_ManGenNeuronAdder( pNew, nOBits, Vec_IntArray(vArg), Vec_IntArray(vRes), 0, vRes );
if ( (i-1) % nLutSize == nLutSize-1 && i < Vec_WecSize(vArgs)-1 ) {
vRes = Vec_WecPushLevel( vNew );
Vec_IntFill( vRes, nOBits, 0 );
}
}
assert( Vec_WecSize(vNew) == nParts );
return vNew;
}
Vec_Wec_t * Gia_ManGenNeuronCompactArgs( Gia_Man_t * pNew, Vec_Wec_t * vArgs, int nLutSize, int nOBits )
{
int i, nParts = Vec_WecSize(vArgs) / 3;
Vec_Wec_t * vNew = Vec_WecAlloc( 2 * nParts + Vec_WecSize(vArgs) % 3 );
for ( i = 0; i < nParts; i++ ) {
Vec_Int_t * vIn0 = Vec_WecEntry(vArgs, 3*i+0);
Vec_Int_t * vIn1 = Vec_WecEntry(vArgs, 3*i+1);
Vec_Int_t * vIn2 = Vec_WecEntry(vArgs, 3*i+2);
Vec_Int_t * vOut0 = Vec_WecPushLevel(vNew);
Vec_Int_t * vOut1 = Vec_WecPushLevel(vNew);
Gia_ManGenCompact( pNew, vIn0, vIn1, vIn2, vOut0, vOut1 );
}
for ( i = 3*nParts; i < Vec_WecSize(vArgs); i++ )
Vec_IntAppend( Vec_WecPushLevel(vNew), Vec_WecEntry(vArgs, i) );
assert( Vec_WecSize(vNew) == 2 * nParts + Vec_WecSize(vArgs) % 3 );
return vNew;
}
Vec_Int_t * Gia_ManGenNeuronFinal( Gia_Man_t * pNew, Vec_Wec_t * vArgs, int nOBits )
{
Vec_Int_t * vRes = Vec_IntAlloc( nOBits ), * vArg; int i;
Vec_IntAppend( vRes, Vec_WecEntry(vArgs, 0) );
Vec_WecForEachLevelStart( vArgs, vArg, i, 1 )
Gia_ManGenNeuronAdder( pNew, nOBits, Vec_IntArray(vArg), Vec_IntArray(vRes), 0, vRes );
return vRes;
}
int Gia_ManGenNeuronBitWidth( Vec_Wrd_t * vData, int nIBits )
{
int i, InMask = (1<<nIBits)-1;
word Data, DataMax = Vec_WrdEntryLast(vData);
Vec_WrdForEachEntryStop( vData, Data, i, Vec_WrdSize(vData)-1 )
DataMax += InMask * Data;
return Abc_Base2LogW(DataMax);
}
Gia_Man_t * Gia_ManGenNeuron( char * pFileName, int nIBits, int nLutSize, int fDump, int fVerbose )
{
int nWords = -1;
Vec_Wrd_t * vData = Vec_WrdReadHex( pFileName, &nWords, 0 );
if ( vData == NULL )
return NULL;
assert( nWords == 1 );
assert( 0 < nIBits && nIBits < 32 );
int i, Lit, nOBits = Gia_ManGenNeuronBitWidth( vData, nIBits );
if ( fDump ) Gia_ManGenNeuronDumpVerilog( vData, nIBits, nOBits );
Gia_Man_t * pTemp, * pNew = Gia_ManStart( 10000 );
pNew->pName = Abc_UtilStrsav( "neuron" );
for ( i = 0; i < nIBits * (Vec_WrdSize(vData)-1); i++ )
Gia_ManAppendCi( pNew );
Gia_ManHashAlloc( pNew );
Vec_Wec_t * vTemp, * vArgs = Gia_ManGenNeuronCreateArgs( vData, nIBits, nOBits );
Vec_WrdFree( vData );
if ( nLutSize ) {
vArgs = Gia_ManGenNeuronTransformArgs( pNew, vTemp = vArgs, nLutSize, nOBits );
Vec_WecFree( vTemp );
while ( Vec_WecSize(vArgs) > 2 ) {
vArgs = Gia_ManGenNeuronCompactArgs( pNew, vTemp = vArgs, nLutSize, nOBits );
Vec_WecFree( vTemp );
}
}
Vec_Int_t * vRes = Gia_ManGenNeuronFinal( pNew, vArgs, nOBits );
Vec_IntForEachEntry( vRes, Lit, i )
Gia_ManAppendCo( pNew, Lit );
Vec_IntFree( vRes );
Vec_WecFree( vArgs );
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
return pNew;
}
/**Function*************************************************************
Synopsis [Generates minimum-node AIG for n-bit comparator (a > b).]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManDupGenComp( int nBits, int fInterleave, int fSigned )
{
Gia_Man_t * pNew, * pTemp; int i, iLit = 1, iLitXor = 0, iLitB = 0;
Vec_Int_t * vBitsA = Vec_IntAlloc( nBits + 1 );
Vec_Int_t * vBitsB = Vec_IntAlloc( nBits + 1 );
pNew = Gia_ManStart( 6*nBits+10 );
pNew->pName = Abc_UtilStrsav( "comp" );
Gia_ManHashAlloc( pNew );
if ( fInterleave ) {
for ( i = 0; i < nBits; i++ )
Vec_IntPush( vBitsA, Gia_ManAppendCi(pNew) ),
Vec_IntPush( vBitsB, Gia_ManAppendCi(pNew) );
}
else {
for ( i = 0; i < nBits; i++ )
Vec_IntPush( vBitsA, Gia_ManAppendCi(pNew) );
for ( i = 0; i < nBits; i++ )
Vec_IntPush( vBitsB, Gia_ManAppendCi(pNew) );
}
if ( fSigned ) {
iLitXor = Gia_ManHashXor( pNew, Vec_IntPop(vBitsA), (iLitB = Vec_IntPop(vBitsB)) );
nBits--;
}
Vec_IntPush( vBitsA, 0 );
Vec_IntPush( vBitsB, 0 );
for ( i = 0; i < nBits; i++ ) {
int iLitA0 = Vec_IntEntry(vBitsA, i);
int iLitA1 = Vec_IntEntry(vBitsA, i+1);
int iLitB0 = Vec_IntEntry(vBitsB, i);
int iLitB1 = Vec_IntEntry(vBitsB, i+1);
int iOrLit0;
if ( i == 0 )
iOrLit0 = Gia_ManHashOr(pNew, Abc_LitNotCond(iLitA0, !(i&1)), Abc_LitNotCond(iLitB0, i&1));
else
iOrLit0 = Gia_ManHashAnd(pNew, Abc_LitNotCond(iLitA0, !(i&1)), Abc_LitNotCond(iLitB0, i&1));
int iOrLit1 = Gia_ManHashAnd(pNew, Abc_LitNotCond(iLitA1, !(i&1)), Abc_LitNotCond(iLitB1, i&1));
int iOrLit = Gia_ManHashOr(pNew, iOrLit0, iOrLit1 );
iLit = Gia_ManHashOr(pNew, Abc_LitNot(iLit), iOrLit );
}
iLit = Abc_LitNotCond(iLit, nBits&1);
if ( fSigned )
iLit = Gia_ManHashMux(pNew, iLitXor, iLitB, iLit );
Gia_ManAppendCo( pNew, iLit );
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
Vec_IntFree( vBitsA );
Vec_IntFree( vBitsB );
return pNew;
}
/**Function*************************************************************
Synopsis [Generates optimized AIG for the decoder and the multiplexer.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_GenDecoder( Gia_Man_t * p, int * pLits, int nLits )
{
if ( nLits == 1 )
{
Vec_Int_t * vRes = Vec_IntAlloc( 2 );
Vec_IntPush( vRes, Abc_LitNot(pLits[0]) );
Vec_IntPush( vRes, pLits[0] );
return vRes;
}
assert( nLits > 1 );
int nPart1 = nLits / 2;
int nPart2 = nLits - nPart1;
Vec_Int_t * vRes1 = Gia_GenDecoder( p, pLits, nPart1 );
Vec_Int_t * vRes2 = Gia_GenDecoder( p, pLits+nPart1, nPart2 );
Vec_Int_t * vRes = Vec_IntAlloc( Vec_IntSize(vRes1) * Vec_IntSize(vRes2) );
int i, k, Lit1, Lit2;
Vec_IntForEachEntry( vRes2, Lit2, k )
Vec_IntForEachEntry( vRes1, Lit1, i )
Vec_IntPush( vRes, Gia_ManHashAnd(p, Lit1, Lit2) );
Vec_IntFree( vRes1 );
Vec_IntFree( vRes2 );
return vRes;
}
Gia_Man_t * Gia_ManGenMux( int nIns, char * pNums )
{
Vec_Int_t * vIns = Vec_IntAlloc( nIns );
Vec_Int_t * vData = Vec_IntAlloc( 1 << nIns );
Gia_Man_t * p = Gia_ManStart( 4*(1 << nIns) + nIns ), * pTemp;
int i, iStart = 0, nSize = 1 << nIns;
p->pName = Abc_UtilStrsav( "mux" );
for ( i = 0; i < nIns; i++ )
Vec_IntPush( vIns, Gia_ManAppendCi(p) );
for ( i = 0; i < nSize; i++ )
Vec_IntPush( vData, Gia_ManAppendCi(p) );
Gia_ManHashAlloc( p );
for ( i = (int)strlen(pNums)-1; i >= 0; i-- )
{
int k, b, nBits = (int)(pNums[i] - '0');
Vec_Int_t * vDec = Gia_GenDecoder( p, Vec_IntEntryP(vIns, iStart), nBits );
for ( k = 0; k < nSize; k++ )
Vec_IntWriteEntry( vData, k, Gia_ManHashAnd(p, Vec_IntEntry(vData, k), Vec_IntEntry(vDec, k%Vec_IntSize(vDec))) );
for ( b = 0; b < nBits; b++, nSize /= 2 )
for ( k = 0; k < nSize/2; k++ )
Vec_IntWriteEntry( vData, k, Gia_ManHashOr(p, Vec_IntEntry(vData, 2*k), Vec_IntEntry(vData, 2*k+1)) );
Vec_IntFree( vDec );
iStart += nBits;
}
assert( nSize == 1 );
Gia_ManAppendCo( p, Vec_IntEntry(vData, 0) );
Vec_IntFree( vIns );
Vec_IntFree( vData );
p = Gia_ManCleanup( pTemp = p );
Gia_ManStop( pTemp );
return p;
}
/**Function*************************************************************
Synopsis [Generates N-bit sorter using pair-wise sorting algorithm.]
Description [https://en.wikipedia.org/wiki/Pairwise_sorting_network]
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Gia_ManGenSorterOne( Gia_Man_t * p, int * pLits, int i, int k )
{
int Lit1 = Gia_ManAppendAnd( p, pLits[i], pLits[k] );
int Lit2 = Gia_ManAppendOr ( p, pLits[i], pLits[k] );
pLits[i] = Lit1;
pLits[k] = Lit2;
}
static inline void Gia_ManGenSorterConstrMerge( Gia_Man_t * p, int * pLits, int lo, int hi, int r )
{
int i, step = r * 2;
if ( step < hi - lo )
{
Gia_ManGenSorterConstrMerge( p, pLits, lo, hi-r, step );
Gia_ManGenSorterConstrMerge( p, pLits, lo+r, hi, step );
for ( i = lo+r; i < hi-r; i += step )
Gia_ManGenSorterOne( p, pLits, i, i+r );
}
}
static inline void Gia_ManGenSorterConstrRange( Gia_Man_t * p, int * pLits, int lo, int hi )
{
if ( hi - lo >= 1 )
{
int i, mid = lo + (hi - lo) / 2;
for ( i = lo; i <= mid; i++ )
Gia_ManGenSorterOne( p, pLits, i, i + (hi - lo + 1) / 2 );
Gia_ManGenSorterConstrRange( p, pLits, lo, mid );
Gia_ManGenSorterConstrRange( p, pLits, mid+1, hi );
Gia_ManGenSorterConstrMerge( p, pLits, lo, hi, 1 );
}
}
Gia_Man_t * Gia_ManGenSorter( int LogN )
{
int i, nVars = 1 << LogN;
int nVarsAlloc = nVars + 2 * (nVars * LogN * (LogN-1) / 4 + nVars - 1);
Vec_Int_t * vLits = Vec_IntAlloc( nVars );
Gia_Man_t * p = Gia_ManStart( 1 + 2*nVars + nVarsAlloc );
p->pName = Abc_UtilStrsav( "sorter" );
for ( i = 0; i < nVars; i++ )
Vec_IntPush( vLits, Gia_ManAppendCi(p) );
Gia_ManGenSorterConstrRange( p, Vec_IntArray(vLits), 0, nVars - 1 );
for ( i = 0; i < nVars; i++ )
Gia_ManAppendCo( p, Vec_IntEntry(vLits, i) );
Vec_IntFree( vLits );
return p;
}
/**Function*************************************************************
Synopsis [Generates brand-name adders.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManGenPrep( int nVars, int ** p )
{
int i, k;
for ( i = 0; i < nVars; i++ )
for ( k = 0; k < nVars; k++ )
p[i][k] = -1;
}
void Gia_ManGenSK( int nVars, int ** p )
{
int i, k, nBits = Abc_Base2Log(nVars);
for ( i = 0; i < nBits; i++ )
for ( k = 0; k < nVars; k++ )
if ( (k >> i) & 1 )
p[i+1][k] = ((1 << i) - 1) | ((k >> (i+1)) << (i+1));
}
void Gia_ManGenBK( int nVars, int ** p )
{
int i, k, nBits = Abc_Base2Log(nVars);
nVars = 1 << nBits;
for ( i = 1; i < nBits; i++ )
for ( k = (1 << i) - 1; k < nVars; k += (1 << i) )
p[i][k] = k - (1 << (i-1));
p[nBits][nVars-1] = (1<<(nBits-1))-1;
for ( i = 1; i < nBits; i++ )
for ( k = (1 << i) - 1; k < nVars-(1 << i); k += (1 << i) )
p[2*nBits-1-i][nVars-1-k+((1<<(i-1))-1)] = nVars-1-k+((1<<(i-1))-1) - (1 << (i-1));
}
void Gia_ManGenHC( int nVars, int ** p )
{
int i, k, nBits = Abc_Base2Log(nVars);
nVars = 1 << nBits;
for ( k = 1; k < nVars; k += 2 )
p[1][k] = k - 1;
for ( i = 2; i <= nBits; i++ )
for ( k = 1 + (1 << (i-1)); k < nVars; k += 2 )
p[i][k] = k - (1 << (i-1));
for ( k = 2; k < nVars; k += 2 )
p[nBits+1][k] = k - 1;
}
void Gia_ManGenRca( int nVars, int ** p )
{
int i;
for ( i = 1; i < nVars; i++ )
p[i][i] = i-1;
}
void Gia_ManGenPrint( int nVars, int ** p )
{
int i, k;
for ( i = nVars-1; i >= 0; i-- )
printf( "%2d ", i );
printf( "\n" );
for ( i = 0; i < nVars; i++ ) {
for ( k = nVars-1; k >= 0; k-- )
if ( p[i][k] >= 0 )
break;
for ( k = nVars-1; k >= 0; k-- )
if ( p[i][k] == -1 )
printf( " - " );
else
printf( "%2d ", p[i][k] );
printf("\n");
}
}
void Gia_ManGenPrefix( Gia_Man_t * pNew, int * p, int * g, int p2, int g2 )
{
*g = Gia_ManHashOr(pNew, *g, Gia_ManHashAnd(pNew, *p, g2));
*p = Gia_ManHashAnd(pNew, *p, p2);
}
static int Gia_ManGenAdderMaj( Gia_Man_t * p, int a, int b, int c )
{
int ab = Gia_ManHashAnd( p, a, b );
int ac = Gia_ManHashAnd( p, a, c );
int bc = Gia_ManHashAnd( p, b, c );
return Gia_ManHashOr( p, ab, Gia_ManHashOr( p, ac, bc ) );
}
static int Gia_ManGenAdderFloorPow2( int n )
{
int r = 1;
assert( n > 0 );
while ( r <= n / 2 )
r *= 2;
return r;
}
static void Gia_ManGenAdderMMRange( Gia_Man_t * p, int nVars, int * pLitsI, int * pM0, int * pM1, int i, int k )
{
int Index = i * nVars + k;
int nRange, nLeft, j;
assert( 0 <= i && i <= k && k < nVars );
if ( pM0[Index] >= 0 )
return;
if ( i == k )
{
pM0[Index] = pLitsI[2*i];
pM1[Index] = pLitsI[2*i+1];
return;
}
nRange = k - i + 1;
nLeft = Gia_ManGenAdderFloorPow2( nRange - 1 );
j = i + nLeft - 1;
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, i, j );
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, j+1, k );
pM0[Index] = Gia_ManGenAdderMaj( p, pM0[(j+1)*nVars+k], pM1[(j+1)*nVars+k], pM0[i*nVars+j] );
pM1[Index] = Gia_ManGenAdderMaj( p, pM0[(j+1)*nVars+k], pM1[(j+1)*nVars+k], pM1[i*nVars+j] );
}
static int Gia_ManGenAdderMMCarry( Gia_Man_t * p, int nVars, int * pLitsI, int * pM0, int * pM1, int * pCarries, int iCarry )
{
int nBase, iBeg;
assert( 0 <= iCarry && iCarry <= nVars );
if ( pCarries[iCarry] >= 0 )
return pCarries[iCarry];
nBase = Gia_ManGenAdderFloorPow2( iCarry );
iBeg = nBase - 1;
Gia_ManGenAdderMMRange( p, nVars, pLitsI, pM0, pM1, iBeg, iCarry-1 );
pCarries[iCarry] = Gia_ManGenAdderMaj( p, pM0[iBeg*nVars+iCarry-1], pM1[iBeg*nVars+iCarry-1], Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, iBeg ) );
return pCarries[iCarry];
}
Gia_Man_t * Gia_ManGenAdder( int nVars, int fSK, int fBK, int fHC, int fMM, int fCarries, int fVerbose )
{
extern void Wlc_BlastFullAdder( Gia_Man_t * pNew, int a, int b, int c, int * pc, int * ps );
int i, k, nBits = Abc_Base2Log(nVars), nVarsAlloc = (1 << nBits) + 2;
int ** pStore = fMM ? NULL : (int **)Extra_ArrayAlloc( nVarsAlloc, nVarsAlloc, 4 );
printf( "Generating %d-bit ", nVars );
if ( fMM )
printf("M/M ");
else
{
Gia_ManGenPrep( nVars+2, pStore );
if ( fSK )
Gia_ManGenSK( nVars, pStore ), printf("Sklansky ");
else if ( fBK )
Gia_ManGenBK( nVars, pStore ), printf("Brent-Kung ");
else if ( fHC )
Gia_ManGenHC( nVars, pStore ), printf("Huan-Carlsson ");
else
Gia_ManGenRca( nVars, pStore ), printf("ripple-carry ");
}
printf( "adder with%s carry-in and carry-out\n", fCarries ? "":"out" );
if ( fVerbose && !fMM ) Gia_ManGenPrint( nVars, pStore );
Gia_Man_t * p = Gia_ManStart( 1000 ), * pTemp;
p->pName = Abc_UtilStrsav( "adder" );
int * pLitsI = ABC_CALLOC( int, 2*nVars+10 );
for ( k = 0; k < nVars; k++ )
pLitsI[2*k] = Gia_ManAppendCi(p);
for ( k = 0; k < nVars; k++ )
pLitsI[2*k+1] = Gia_ManAppendCi(p);
int Carry = fCarries ? Gia_ManAppendCi(p) : 0;
Gia_ManHashStart( p );
if ( fMM )
{
int nPairs = nVars * nVars;
int * pM0 = ABC_ALLOC( int, nPairs );
int * pM1 = ABC_ALLOC( int, nPairs );
int * pCarries = ABC_ALLOC( int, nVars + 1 );
int * pProps = ABC_ALLOC( int, nVars );
for ( k = 0; k < nPairs; k++ )
pM0[k] = pM1[k] = -1;
for ( k = 0; k <= nVars; k++ )
pCarries[k] = -1;
pCarries[0] = Carry;
for ( k = 0; k < nVars; k++ )
pProps[k] = Gia_ManHashXor( p, pLitsI[2*k], pLitsI[2*k+1] );
if ( fCarries )
Gia_ManAppendCo( p, Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, nVars ) );
for ( k = 0; k < nVars; k++ )
Gia_ManAppendCo( p, Gia_ManHashXor( p, pProps[k], Gia_ManGenAdderMMCarry( p, nVars, pLitsI, pM0, pM1, pCarries, k ) ) );
ABC_FREE( pM0 );
ABC_FREE( pM1 );
ABC_FREE( pCarries );
ABC_FREE( pProps );
ABC_FREE( pLitsI );
p = Gia_ManCleanup( pTemp = p );
Gia_ManStop( pTemp );
return p;
}
for ( k = 0; k < nVars; k++ )
Wlc_BlastFullAdder( p, pLitsI[2*k], pLitsI[2*k+1], k ? 0 : Carry, &pLitsI[2*k+1], &pLitsI[2*k] );
int * pLits = ABC_CALLOC( int, 2*nVars+10 );
memcpy( pLits, pLitsI, sizeof(int)*2*nVars );
for ( i = 1; i < nVars; i++ )
for ( k = nVars - 1; k >= 1; k-- )
if ( pStore[i][k] >= 0 )
Gia_ManGenPrefix( p, &pLits[2*k], &pLits[2*k+1], pLits[2*pStore[i][k]], pLits[2*pStore[i][k]+1] );
if ( fCarries )
Gia_ManAppendCo( p, pLits[2*(k-1)+1] );
for ( k = 0; k < nVars; k++ )
Gia_ManAppendCo( p, k ? Gia_ManHashXor(p, pLitsI[2*k], pLits[2*(k-1)+1]) : pLitsI[2*k] );
ABC_FREE( pStore );
ABC_FREE( pLitsI );
ABC_FREE( pLits );
p = Gia_ManCleanup( pTemp = p );
Gia_ManStop( pTemp );
return p;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -470,6 +470,65 @@ int Gia_ManCountDupLut( Gia_Man_t * p )
return nCountDup + nCountPis;
}
void Gia_ManCollectLuts_rec( Gia_Man_t * p, int iObj, Vec_Int_t * vLuts )
{
if ( Gia_ObjIsTravIdCurrentId( p, iObj ) || !Gia_ObjIsAnd(Gia_ManObj(p, iObj)) )
return;
Gia_ObjSetTravIdCurrentId( p, iObj );
int k, iFan;
Gia_LutForEachFanin( p, iObj, iFan, k )
Gia_ManCollectLuts_rec( p, iFan, vLuts );
Vec_IntPush( vLuts, iObj );
}
int Gia_ManCountLutLevels( Gia_Man_t * p, Vec_Int_t * vLuts, Vec_Int_t * vLevel )
{
int i, iObj, k, iFan, LevelMax = 0;
Vec_IntForEachEntry( vLuts, iObj, i ) {
int Level = 0;
Gia_LutForEachFanin( p, iObj, iFan, k )
Level = Abc_MaxInt( Level, Vec_IntEntry(vLevel, iFan) );
Vec_IntWriteEntry( vLevel, iObj, Level+1 );
LevelMax = Abc_MaxInt( LevelMax, Level+1 );
}
Vec_IntForEachEntry( vLuts, iObj, i )
Vec_IntWriteEntry( vLevel, iObj, 0 );
return LevelMax;
}
void Gia_ManPrintOutputLutStats( Gia_Man_t * p )
{
int Limit = 100000;
int nLutSize = Gia_ManLutSizeMax(p);
Vec_Int_t * vLuts = Vec_IntAlloc( 1000 );
Vec_Int_t * vNodes = Vec_IntStart( Limit );
Vec_Int_t * vLevels = Vec_IntStart( Limit );
Vec_Int_t * vLevel = Vec_IntStart( Gia_ManObjNum(p) );
int i, DriverId, Value, nTotalLuts = 0;
Gia_ManForEachCoDriverId( p, DriverId, i ) {
Vec_IntClear( vLuts );
Gia_ManIncrementTravId(p);
Gia_ManCollectLuts_rec( p, DriverId, vLuts );
if ( Vec_IntSize(vLuts) < Limit )
Vec_IntAddToEntry( vNodes, Vec_IntSize(vLuts), 1 );
int Level = Gia_ManCountLutLevels( p, vLuts, vLevel );
if ( Level < Limit )
Vec_IntAddToEntry( vLevels, Level, 1 );
nTotalLuts += Vec_IntSize(vLuts);
}
printf( "Level count statistics for %d AIG outputs:\n", Gia_ManCoNum(p) );
Vec_IntForEachEntry( vLevels, Value, i )
if ( Value )
printf( " %2d level : Function count = %8d (%6.2f %%)\n", i, Value, 100.0*Value/Gia_ManCoNum(p) );
printf( "LUT count statistics for %d AIG outputs:\n", Gia_ManCoNum(p) );
Vec_IntForEachEntry( vNodes, Value, i )
if ( Value )
printf( " %2d LUT%d : Function count = %8d (%6.2f %%)\n", i, nLutSize, Value, 100.0*Value/Gia_ManCoNum(p) );
printf( "Sum total of LUT counts for all outputs = %d. Shared LUT count = %d.\n", nTotalLuts, Gia_ManLutNum(p) );
Vec_IntFree( vLuts );
Vec_IntFree( vNodes );
Vec_IntFree( vLevels );
Vec_IntFree( vLevel );
}
void Gia_ManPrintMappingStats( Gia_Man_t * p, char * pDumpFile )
{
int fDisable2Lut = 1;
@ -1116,6 +1175,111 @@ int Gia_ManFromIfLogicCreateLutSpecial( Gia_Man_t * pNew, word * pRes, Vec_Int_t
return iObjLit2;
}
/**Function*************************************************************
Synopsis [Write mapping for LUT with given fanins.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManFromIfLogicCreateLutSpecialJ( Gia_Man_t * pNew, word * pRes, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking )
{
word Truth;
int i, iObjLit1, iObjLit2, iObjLit3;
word z = If_CutPerformDeriveJ( NULL, (unsigned *)pRes, Vec_IntSize(vLeaves), Vec_IntSize(vLeaves), NULL, 1, 0 );
assert( z != 0 );
if ( ((z >> 63) & 1) == 0 )
{
// create first LUT
Vec_IntClear( vLeavesTemp );
for ( i = 0; i < 4; i++ )
{
int v = (int)((z >> (16+(i<<2))) & 7);
if ( v == 6 && Vec_IntSize(vLeaves) == 5 )
continue;
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v) );
}
Truth = (z & 0xffff);
Truth |= (Truth << 16);
Truth |= (Truth << 32);
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
// create second LUT
Vec_IntClear( vLeavesTemp );
for ( i = 0; i < 4; i++ )
{
int v = (int)((z >> (48+(i<<2))) & 7);
if ( v == 6 && Vec_IntSize(vLeaves) == 5 )
continue;
if ( v == 7 )
Vec_IntPush( vLeavesTemp, iObjLit1 );
else
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, v) );
}
Truth = ((z >> 32) & 0xffff);
Truth |= (Truth << 16);
Truth |= (Truth << 32);
iObjLit2 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
// write packing
Vec_IntPush( vPacking, 2 );
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit2) );
Vec_IntAddToEntry( vPacking, 0, 1 );
return iObjLit2;
}
else
{
int Pla2Var[9];
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
// create first data LUT
Vec_IntClear( vLeavesTemp );
for ( i = 0; i < 4; i++ )
{
if ( Pla2Var[i] != 9 )
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[i]) );
}
Truth = (z & 0xffff);
Truth |= (Truth << 16);
Truth |= (Truth << 32);
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
// create second data LUT
Vec_IntClear( vLeavesTemp );
for ( i = 4; i < 8; i++ )
{
if ( Pla2Var[i] != 9 )
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[i]) );
}
Truth = ((z >> 16) & 0xffff);
Truth |= (Truth << 16);
Truth |= (Truth << 32);
iObjLit2 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
// create MUX LUT (2-input MUX: select ? iObjLit2 : iObjLit1)
Vec_IntClear( vLeavesTemp );
Vec_IntPush( vLeavesTemp, iObjLit1 ); // data 0
Vec_IntPush( vLeavesTemp, iObjLit2 ); // data 1
if ( Pla2Var[8] != 9 )
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, Pla2Var[8]) ); // select
// MUX truth table: f = s ? d1 : d0 = ~s&d0 | s&d1 = 0xCACACACA for (d0,d1,s)
Truth = ABC_CONST(0xCACACACACACACACA);
iObjLit3 = Gia_ManFromIfLogicCreateLut( pNew, &Truth, vLeavesTemp, vCover, vMapping, vMapping2 );
// write packing - 3 LUTs packed together
Vec_IntPush( vPacking, 3 );
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit2) );
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit3) );
Vec_IntAddToEntry( vPacking, 0, 1 );
return iObjLit3;
}
}
/**Function*************************************************************
Synopsis [Write the node into a file.]
@ -1128,31 +1292,13 @@ int Gia_ManFromIfLogicCreateLutSpecial( Gia_Man_t * pNew, word * pRes, Vec_Int_t
***********************************************************************/
int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp,
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75, int fCheck44e )
word * pRes, char * pStr, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vPacking, int fCheck75 )
{
int nLeaves = Vec_IntSize(vLeaves);
int i, Length, nLutLeaf, nLutLeaf2, nLutRoot, iObjLit1, iObjLit2, iObjLit3;
// workaround for the special case
if ( fCheck75 )
pStr = "54";
// perform special case matching for 44
if ( fCheck44e )
{
if ( Vec_IntSize(vLeaves) <= 4 )
{
// create mapping
iObjLit1 = Gia_ManFromIfLogicCreateLut( pNew, pRes, vLeaves, vCover, vMapping, vMapping2 );
// write packing
if ( !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(iObjLit1))) && iObjLit1 > 1 )
{
Vec_IntPush( vPacking, 1 );
Vec_IntPush( vPacking, Abc_Lit2Var(iObjLit1) );
Vec_IntAddToEntry( vPacking, 0, 1 );
}
return iObjLit1;
}
return Gia_ManFromIfLogicCreateLutSpecial( pNew, pRes, vLeaves, vLeavesTemp, vCover, vMapping, vMapping2, vPacking );
}
if ( ((If_Man_t *)pIfMan)->pPars->fLut6Filter && Vec_IntSize(vLeaves) == 6 )
{
extern word If_Dec6Perform( word t, int fDerive );
@ -1308,12 +1454,25 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
{
if ( Length == 2 )
{
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
if ( ((If_Man_t *)pIfMan)->pPars->fEnableStructN )
{
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
return -1;
if ( !If_CluCheckXXExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
{
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
return -1;
}
}
else
{
if ( !If_CluCheckExt( NULL, pRes, nLeaves, nLutLeaf, nLutRoot, pLut0, pLut1, &Func0, &Func1 ) )
{
Extra_PrintHex( stdout, (unsigned *)pRes, nLeaves ); printf( " " );
Kit_DsdPrintFromTruth( (unsigned*)pRes, nLeaves ); printf( "\n" );
printf( "Node %d is not decomposable. Deriving LUT structures has failed.\n", iObj );
return -1;
}
}
}
else
@ -1411,6 +1570,90 @@ int Gia_ManFromIfLogicNode( void * pIfMan, Gia_Man_t * pNew, int iObj, Vec_Int_t
return iObjLit3;
}
/**Function*************************************************************
Synopsis [Implements delay-driven decomposition of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManFromIfLogicHop( Gia_Man_t * pNew, If_Man_t * pIfMan, If_Cut_t * pCutBest, Vec_Int_t * vLeaves, Vec_Int_t * vLeavesTemp, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2 )
{
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
unsigned char decompArray[92];
int val;
assert( pCutBest->nLeaves > pIfMan->pPars->nLutDecSize );
unsigned delayProfile = pCutBest->decDelay;
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
assert( val == 0 );
// convert the LUT-structure into a set of logic nodes in Gia_Man_t
unsigned char bytes_check = decompArray[0];
assert( bytes_check <= 92 );
int byte_p = 2;
unsigned char i, j, k, num_fanins, num_words, num_bytes;
int iObjLits[5];
int fanin;
word *tt;
for ( i = 0; i < decompArray[1]; ++i )
{
num_fanins = decompArray[byte_p++];
Vec_IntClear( vLeavesTemp );
for ( j = 0; j < num_fanins; ++j )
{
fanin = (int)decompArray[byte_p++];
if ( fanin < If_CutLeaveNum(pCutBest) )
{
Vec_IntPush( vLeavesTemp, Vec_IntEntry(vLeaves, fanin) );
}
else
{
Vec_IntPush( vLeavesTemp, iObjLits[fanin - If_CutLeaveNum(pCutBest)] );
}
}
/* extract the truth table */
tt = pIfMan->puTempW;
num_words = ( num_fanins <= 6 ) ? 1 : ( 1 << ( num_fanins - 6 ) );
num_bytes = ( num_fanins <= 3 ) ? 1 : ( 1 << ( Abc_MinInt( (int)num_fanins, 6 ) - 3 ) );
for ( j = 0; j < num_words; ++j )
{
tt[j] = 0;
for ( k = 0; k < num_bytes; ++k )
{
tt[j] |= ( (word)(decompArray[byte_p++]) ) << ( k << 3 );
}
}
/* extend truth table if size < 5 */
assert( num_fanins != 1 );
if ( num_fanins == 2 )
{
tt[0] |= tt[0] << 4;
}
while ( num_bytes < 4 )
{
tt[0] |= tt[0] << ( num_bytes << 3 );
num_bytes <<= 1;
}
iObjLits[i] = Gia_ManFromIfLogicCreateLut( pNew, tt, vLeavesTemp, vCover, vMapping, vMapping2 );
}
/* check correct read */
assert( byte_p == decompArray[0] );
return iObjLits[i-1];
}
/**Function*************************************************************
Synopsis [Recursively derives the local AIG for the cut.]
@ -1655,6 +1898,367 @@ void Gia_ManFromIfGetConfig( Vec_Int_t * vConfigs, If_Man_t * pIfMan, If_Cut_t *
Vec_StrPush( vConfigsStr, '\n' );
}
}
/**Function*************************************************************
Synopsis [Print configuration during encoding.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManConfigPrint( word Truth4, word z, int nLeaves )
{
static int Count = 0;
int i;
printf( "[%4d] Encoding (nLeaves=%d): ", Count++, nLeaves );
// Simple LUT4 case (Truth4 != 0, z == 0)
if ( z == 0 )
{
printf( "%04lX{", (unsigned long)(Truth4 & 0xFFFF) );
for ( i = 0; i < nLeaves && i < 4; i++ )
printf( "%c", 'a' + i );
printf( "} [Cell 0, LUT4]\n" );
return;
}
if ( ((z >> 63) & 1) == 0 )
{
// Extract truth tables
word Truth1 = z & 0xFFFF;
word Truth2 = (z >> 32) & 0xFFFF;
printf( "h=%04lX{", (unsigned long)Truth1 );
// First LUT4 inputs from bits 16-31
for ( i = 0; i < 4; i++ )
{
int v = (int)((z >> (16 + (i << 2))) & 7);
if ( v == 6 && nLeaves == 5 )
printf( "0" ); // Constant 0 for 5-input cuts
else if ( v == 7 )
printf( "?" ); // Internal connection (shouldn't appear in first LUT)
else if ( v <= 6 )
printf( "%c", 'a' + v );
else
printf( "?" );
}
printf( "} ");
printf( "i=%04lX{", (unsigned long)Truth2 );
// Second LUT4 inputs from bits 48-63
for ( i = 0; i < 4; i++ )
{
int v = (int)((z >> (48 + (i << 2))) & 7);
if ( v == 6 && nLeaves == 5 )
printf( "0" ); // Constant 0 for 5-input cuts
else if ( v == 7 )
printf( "h" ); // Output of first LUT
else if ( v <= 6 )
printf( "%c", 'a' + v );
else
printf( "?" );
}
printf( "} [Cell 1, S44]\n" );
}
else
{
int Pla2Var[9];
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
// Extract truth tables
word Truth1 = z & 0xFFFF;
word Truth2 = (z >> 16) & 0xFFFF;
printf( "j=%04lX{", (unsigned long)Truth1 );
// First LUT4 inputs
for ( i = 0; i < 4; i++ )
{
if ( Pla2Var[i] == 9 )
printf( "0" ); // Will be encoded as constant 0
else if ( Pla2Var[i] < 9 )
printf( "%c", 'a' + Pla2Var[i] );
else
printf( "?" );
}
printf( "} ");
printf( "k=%04lX{", (unsigned long)Truth2 );
// Second LUT4 inputs
for ( i = 4; i < 8; i++ )
{
if ( Pla2Var[i] == 9 )
printf( "0" ); // Will be encoded as constant 0
else if ( Pla2Var[i] < 9 )
printf( "%c", 'a' + Pla2Var[i] );
else
printf( "?" );
}
printf( "} ");
// final
printf( "l=<" );
if ( Pla2Var[8] == 9 )
printf( "0" ); // Will be encoded as constant 0
else if ( Pla2Var[8] < 9 )
printf( "%c", 'a' + Pla2Var[8] );
else
printf( "?" );
printf( "jk> [Cell 2, 9-input MUX]\n" );
}
}
/**Function*************************************************************
Synopsis [Print cell configuration data.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManConfigPrint2( unsigned char * pConfigData, int nLeaves )
{
unsigned char CellId = pConfigData[0];
int i;
static int Count = 0;
printf( "%6d : ", Count++ ); // Print instance number
printf( "[Cell %d with %d leaves] ", CellId, nLeaves );
if ( CellId == 0 )
{
assert( nLeaves <= 4 );
// Extract 16-bit truth table
word Truth = ((word)pConfigData[5] << 8) | pConfigData[6];
printf( "e=%04lX{", (unsigned long)Truth );
// Print as simple {abcd} since it's just a direct LUT4
for ( i = 0; i < nLeaves; i++ )
printf( "%c", 'a' + i );
for ( ; i < 4; i++ )
printf( "%c", '0' );
printf( "}\n" );
}
else if ( CellId == 1 )
{
// First LUT4
word Truth1 = ((word)pConfigData[8] << 8) | pConfigData[9];
printf( "h=%04lX{", (unsigned long)Truth1 );
for ( i = 0; i < 4; i++ )
{
int v = pConfigData[1+i];
if ( v == 0 )
printf( "0");
else if ( v == 1 )
printf( "1");
else if ( v >= 2 && v < 2 + nLeaves )
printf( "%c", 'a' + (v-2));
else
printf( "?");
}
printf( "};");
// Second LUT4
word Truth2 = ((word)pConfigData[10] << 8) | pConfigData[11];
printf( "i=%04lX{", (unsigned long)Truth2 );
for ( i = 4; i < 7; i++ )
{
int v = pConfigData[1+i];
if ( v == 0 )
printf( "0");
else if ( v == 1 )
printf( "1");
else if ( v >= 2 && v < 2 + nLeaves )
printf( "%c", 'a' + (v-2));
else if ( v == 9 )
printf( "h"); // Output of first LUT
else
printf( "?");
}
printf( "h}\n" );
}
else if ( CellId == 2 )
{
// First LUT4
word Truth1 = ((word)pConfigData[10] << 8) | pConfigData[11];
printf( "j=%04lX{", (unsigned long)Truth1 );
for ( i = 0; i < 4; i++ )
{
int v = pConfigData[1+i];
if ( v == 0 )
printf( "0");
else if ( v == 1 )
printf( "1");
else if ( v >= 2 && v < 2 + nLeaves )
printf( "%c", 'a' + (v-2));
else
printf( "?");
}
printf( "};");
// Second LUT4
word Truth2 = ((word)pConfigData[12] << 8) | pConfigData[13];
printf( "k=%04lX{", (unsigned long)Truth2 );
for ( i = 4; i < 8; i++ )
{
int v = pConfigData[1+i];
if ( v == 0 )
printf( "0");
else if ( v == 1 )
printf( "1");
else if ( v >= 2 && v < 2 + nLeaves )
printf( "%c", 'a' + (v-2));
else
printf( "?");
}
printf( "};");
// final node
printf( "l=<");
int v = pConfigData[1+8];
if ( v == 0 )
printf( "0");
else if ( v == 1 )
printf( "1");
else if ( v >= 2 && v < 2 + nLeaves )
printf( "%c", 'a' + (v-2));
else
printf( "?");
printf( "jk>\n" );
}
else
{
printf( "Unknown cell type %d!\n", CellId );
}
}
static inline word Gia_ManFromIfPermuteTruth4( word Truth, int nLeaves, word z )
{
word TruthNew = 0;
int i, k, x;
assert( nLeaves >= 1 && nLeaves <= 4 );
for ( i = 0; i < 16; i++ )
{
x = 0;
for ( k = 0; k < nLeaves; k++ )
{
int v = (int)((z >> (2 * k)) & 3);
x |= ((i >> k) & 1) << v;
}
TruthNew |= ((Truth >> x) & 1) << i;
}
return TruthNew;
}
/**Function*************************************************************
Synopsis [Derive configurations.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManFromIfGetConfig2( Vec_Str_t * vConfigs2, If_Man_t * pIfMan, word * pTruth, int nLeaves, int fDelay )
{
int i, CellId;
int startPos = Vec_StrSize(vConfigs2);
If_LibCell_t * pCellLib = pIfMan && pIfMan->pPars ? pIfMan->pPars->pCellLib : NULL;
assert( pCellLib != NULL );
// Determine cell type based on the number of leaves and configuration
if ( nLeaves <= 4 ) // 7 bytes = 1 byte CellId + 4 bytes mapping + 2 bytes truth table
{
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay );
int fHavePerm = (z != 0) && ((z & ABC_CONST(0x4000000000000000)) != 0);
word Truth = pTruth[0];
// Cell type 0: Simple LUT4
CellId = 0;
// Write CellId
Vec_StrPush( vConfigs2, (char)CellId );
// Write mapping
for ( i = 0; i < nLeaves; i++ )
{
int v = fHavePerm ? (int)((z >> (2 * i)) & 3) : i;
Vec_StrPush( vConfigs2, 2 + v );
}
for ( ; i < 4; i++ )
Vec_StrPush( vConfigs2, 0 );
// Write truth table (16 bits for LUT4)
if ( fHavePerm )
Truth = Gia_ManFromIfPermuteTruth4( Truth, nLeaves, z );
Vec_StrPush( vConfigs2, (char)((Truth >> 8) & 0xFF) );
Vec_StrPush( vConfigs2, (char)(Truth & 0xFF) );
assert( startPos + pCellLib->pCellRecordSizes[CellId] == Vec_StrSize(vConfigs2) );
//Gia_ManConfigPrint( Truth, 0, nLeaves );
}
else // 12 bytes = 1 byte CellId + 7 bytes mapping + 4 bytes truth tables
{
word z = If_CutPerformDeriveJ( pIfMan, (unsigned *)pTruth, nLeaves, nLeaves, NULL, 1, fDelay );
//Gia_ManConfigPrint( 0, z, nLeaves );
if ( ((z >> 63) & 1) == 0 )
{
CellId = 1;
Vec_StrPush( vConfigs2, (char)CellId );
// Write input mapping
for ( i = 0; i < 4; i++ )
{
int v = (int)((z >> (16 + (i << 2))) & 7);
if ( v == 6 && nLeaves == 5 )
Vec_StrPush( vConfigs2, 0 );
else
Vec_StrPush( vConfigs2, 2+v );
}
int iSpecial = -1;
for ( i = 0; i < 4; i++ )
{
int v = (int)((z >> (48 + (i << 2))) & 7);
if ( v == 6 && nLeaves == 5 )
Vec_StrPush( vConfigs2, 0 );
else if ( v != 7 )
Vec_StrPush( vConfigs2, 2+v );
else if ( v == 7 )
iSpecial = i;
}
// Transform the truth table
assert( iSpecial >= 0 );
word Truth = (z >> 32) & 0xFFFF;
Truth = Abc_Tt6Stretch( Truth, 4 );
for ( int v = iSpecial; v < 3; v++ )
Truth = Abc_Tt6SwapAdjacent( Truth, v );
// Write truth tables
word Truth1 = z & 0xFFFF;
//word Truth2 = (z >> 32) & 0xFFFF;
word Truth2 = Truth & 0xFFFF;
Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) );
Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) );
Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) );
Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) );
assert( startPos + pCellLib->pCellRecordSizes[CellId] == Vec_StrSize(vConfigs2) );
}
else // 14 bytes = 1 byte CellId + 9 bytes mapping + 4 bytes truth tables
{
CellId = 2;
int Pla2Var[9];
extern void If_PermUnpack( unsigned Value, int Pla2Var[9] );
If_PermUnpack( (unsigned)(z >> 32), Pla2Var );
// Write CellId
Vec_StrPush( vConfigs2, (char)CellId );
// Write input mapping
for ( i = 0; i < 9; i++ )
{
if ( Pla2Var[i] == 9 )
Vec_StrPush( vConfigs2, 0 );
else
Vec_StrPush( vConfigs2, Pla2Var[i] + 2 );
}
// Write truth tables for the two LUT4s only (MUX is structural, not a LUT)
word Truth1 = z & 0xFFFF;
word Truth2 = (z >> 16) & 0xFFFF;
Vec_StrPush( vConfigs2, (char)((Truth1 >> 8) & 0xFF) );
Vec_StrPush( vConfigs2, (char)(Truth1 & 0xFF) );
Vec_StrPush( vConfigs2, (char)((Truth2 >> 8) & 0xFF) );
Vec_StrPush( vConfigs2, (char)(Truth2 & 0xFF) );
assert( startPos + pCellLib->pCellRecordSizes[CellId] == Vec_StrSize(vConfigs2) );
}
}
if ( pIfMan->pPars->fVerboseTrace )
Gia_ManConfigPrint2( (unsigned char*)Vec_StrEntryP(vConfigs2, startPos), nLeaves );
}
int Gia_ManFromIfLogicFindCell( If_Man_t * pIfMan, Gia_Man_t * pNew, Gia_Man_t * pTemp, If_Cut_t * pCutBest, Ifn_Ntk_t * pNtkCell, int nLutMax, Vec_Int_t * vLeaves, Vec_Int_t * vLits, Vec_Int_t * vCover, Vec_Int_t * vMapping, Vec_Int_t * vMapping2, Vec_Int_t * vConfigs )
{
int iLit;
@ -1848,18 +2452,19 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
If_Cut_t * pCutBest;
If_Obj_t * pIfObj, * pIfLeaf;
Vec_Int_t * vMapping, * vMapping2, * vPacking = NULL, * vConfigs = NULL;
Vec_Str_t * vConfigs2 = NULL;
Vec_Int_t * vLeaves, * vLeaves2, * vCover, * vLits;
Vec_Str_t * vConfigsStr = NULL;
Ifn_Ntk_t * pNtkCell = NULL;
sat_solver * pSat = NULL;
int i, k, Entry;
assert( !pIfMan->pPars->fDeriveLuts || pIfMan->pPars->fTruth );
// if ( pIfMan->pPars->fEnableCheck07 )
// pIfMan->pPars->fDeriveLuts = 0;
//if ( pIfMan->pPars->fEnableCheck07 )
// pIfMan->pPars->fDeriveLuts = 0;
// start mapping and packing
vMapping = Vec_IntStart( If_ManObjNum(pIfMan) );
vMapping2 = Vec_IntStart( 1 );
if ( pIfMan->pPars->fDeriveLuts && (pIfMan->pPars->pLutStruct || pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u || pIfMan->pPars->fEnableCheck07) )
if ( pIfMan->pPars->fDeriveLuts && (pIfMan->pPars->pLutStruct || pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u) )
{
vPacking = Vec_IntAlloc( 1000 );
Vec_IntPush( vPacking, 0 );
@ -1875,6 +2480,8 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
if ( fWriteConfigs )
vConfigsStr = Vec_StrAlloc( 1000 );
}
if ( pIfMan->pPars->fEnableCheck07 )
vConfigs2 = Vec_StrAlloc( 1000 );
// create new manager
pNew = Gia_ManStart( If_ManObjNum(pIfMan) );
// iterate through nodes used in the mapping
@ -1894,7 +2501,7 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
if ( !pIfMan->pPars->fUseTtPerm && !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->fDelayOptLut && !pIfMan->pPars->fDsdBalance &&
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize &&
!pIfMan->pPars->fEnableCheck75 && !pIfMan->pPars->fEnableCheck75u && !pIfMan->pPars->fEnableCheck07 && !pIfMan->pPars->fUseDsdTune &&
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars && !pIfMan->pPars->fUseCheck1 && !pIfMan->pPars->fUseCheck2 )
!pIfMan->pPars->fUseCofVars && !pIfMan->pPars->fUseAndVars && !pIfMan->pPars->fUseCheck1 && !pIfMan->pPars->fUseCheck2 && !pIfMan->pPars->fUserLutDec )
If_CutRotatePins( pIfMan, pCutBest );
// collect leaves of the best cut
Vec_IntClear( vLeaves );
@ -1946,6 +2553,10 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
{
pIfObj->iCopy = Gia_ManFromIfLogicCofVars( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
}
else if ( pIfMan->pPars->fUserLutDec && (int)pCutBest->nLeaves > pIfMan->pPars->nLutDecSize )
{
pIfObj->iCopy = Gia_ManFromIfLogicHop( pNew, pIfMan, pCutBest, vLeaves, vLeaves2, vCover, vMapping, vMapping2 );
}
else if ( (pIfMan->pPars->fDeriveLuts && pIfMan->pPars->fTruth) || pIfMan->pPars->fUseDsd || pIfMan->pPars->fUseTtPerm || pIfMan->pPars->pFuncCell2 )
{
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
@ -1954,10 +2565,30 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
if ( If_CutLeafBit(pCutBest, k) )
Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k );
// perform decomposition of the cut
pIfObj->iCopy = Gia_ManFromIfLogicNode( pIfMan, pNew, i, vLeaves, vLeaves2, pTruth, pIfMan->pPars->pLutStruct, vCover, vMapping, vMapping2, vPacking, (pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u), pIfMan->pPars->fEnableCheck07 );
if ( pIfMan->pPars->fEnableCheck07 )
pIfObj->iCopy = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
else
pIfObj->iCopy = Gia_ManFromIfLogicNode( pIfMan, pNew, i, vLeaves, vLeaves2, pTruth, pIfMan->pPars->pLutStruct, vCover, vMapping, vMapping2, vPacking, (pIfMan->pPars->fEnableCheck75 || pIfMan->pPars->fEnableCheck75u) );
pIfObj->iCopy = Abc_LitNotCond( pIfObj->iCopy, pCutBest->fCompl );
if ( vConfigs && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 )
Gia_ManFromIfGetConfig( vConfigs, pIfMan, pCutBest, pIfObj->iCopy, vConfigsStr );
else if ( vConfigs2 && Vec_IntSize(vLeaves) > 1 && !Gia_ObjIsCi(Gia_ManObj(pNew, Abc_Lit2Var(pIfObj->iCopy))) && pIfObj->iCopy > 1 ) {
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
if ( Abc_LitIsCompl(pIfLeaf->iCopy) )
Abc_TtFlip( pTruth, Abc_TtWordNum(pCutBest->nLeaves), k );
if ( Abc_LitIsCompl(pIfObj->iCopy) ^ pCutBest->fCompl )
Abc_TtNot( pTruth, Abc_TtWordNum(pCutBest->nLeaves) );
if ( pIfMan->pPars->fDelayOptCell )
{
pIfMan->nCutLeavesCur = pCutBest->nLeaves;
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, k )
{
pIfMan->pCutLeavesCur[k] = pIfLeaf->Id;
pIfMan->pCutLeafArrCur[k] = If_ObjCutBest(pIfLeaf)->Delay;
}
}
Gia_ManFromIfGetConfig2( vConfigs2, pIfMan, pTruth, pCutBest->nLeaves, pIfMan->pPars->fDelayOptCell );
}
}
else
{
@ -2014,11 +2645,14 @@ Gia_Man_t * Gia_ManFromIfLogic( If_Man_t * pIfMan )
assert( pNew->vPacking == NULL );
assert( pNew->vConfigs == NULL );
assert( pNew->pCellStr == NULL );
assert( pNew->vConfigs2== NULL );
pNew->vMapping = vMapping;
pNew->vPacking = vPacking;
pNew->vConfigs = vConfigs;
pNew->pCellStr = vConfigs ? Abc_UtilStrsav( If_DsdManGetCellStr(pIfMan->pIfDsdMan) ) : NULL;
assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) );
pNew->vConfigs2= vConfigs2;
assert( !vConfigs || Vec_IntSize(vConfigs) == 2 + Vec_IntEntry(vConfigs, 0) * Vec_IntEntry(vConfigs, 1) );
// vConfigs2 is now a byte vector, no fixed size relationship
// verify that COs have mapping
{
Gia_Obj_t * pObj;
@ -2107,7 +2741,7 @@ void Gia_ManMappingVerify( Gia_Man_t * p )
continue;
if ( !Gia_ObjIsLut(p, Gia_ObjId(p, pFanin)) )
{
Abc_Print( -1, "Gia_ManMappingVerify: CO driver %d does not have mapping.\n", Gia_ObjId(p, pFanin) );
Abc_Print( -1, "Gia_ManMappingVerify: Buffer driver %d does not have mapping.\n", Gia_ObjId(p, pFanin) );
Result = 0;
continue;
}
@ -2209,6 +2843,8 @@ void Gia_ManTransferPacking( Gia_Man_t * p, Gia_Man_t * pGia )
}
void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
{
if ( p == pGia )
return;
if ( pGia->vCiArrs || pGia->vCoReqs || pGia->vCoArrs || pGia->vCoAttrs )
{
p->vCiArrs = pGia->vCiArrs; pGia->vCiArrs = NULL;
@ -2236,13 +2872,18 @@ void Gia_ManTransferTiming( Gia_Man_t * p, Gia_Man_t * pGia )
p->vConfigs = pGia->vConfigs; pGia->vConfigs = NULL;
p->pCellStr = pGia->pCellStr; pGia->pCellStr = NULL;
}
if ( pGia->pManTime == NULL || p == pGia )
if ( pGia->vConfigs2 )
{
p->vConfigs2 = pGia->vConfigs2; pGia->vConfigs2 = NULL;
}
if ( pGia->pManTime == NULL )
return;
p->pManTime = pGia->pManTime; pGia->pManTime = NULL;
p->pAigExtra = pGia->pAigExtra; pGia->pAigExtra = NULL;
p->vRegClasses = pGia->vRegClasses; pGia->vRegClasses = NULL;
p->vRegInits = pGia->vRegInits; pGia->vRegInits = NULL;
p->nAnd2Delay = pGia->nAnd2Delay; pGia->nAnd2Delay = 0;
p->pManTime = pGia->pManTime; pGia->pManTime = NULL;
p->pAigExtra = pGia->pAigExtra; pGia->pAigExtra = NULL;
p->vRegClasses = pGia->vRegClasses; pGia->vRegClasses = NULL;
p->vRegInits = pGia->vRegInits; pGia->vRegInits = NULL;
p->vFlopClasses = pGia->vFlopClasses; pGia->vFlopClasses = NULL;
p->nAnd2Delay = pGia->nAnd2Delay; pGia->nAnd2Delay = 0;
}
/**Function*************************************************************
@ -2359,8 +3000,33 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars )
pPars->pTimesReq[i] = EntryF;
}
*/
if ( p->pManTime && pPars->pTimesArr == NULL )
{
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
pPars->pTimesArr = ABC_CALLOC( float, Gia_ManCiNum(p) );
for ( i = 0; i < Gia_ManCiNum(p); i++ )
pPars->pTimesArr[i] = Tim_ManGetCiArrival( pManTime, i );
}
if ( p->pManTime && pPars->pTimesReq == NULL )
{
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
int fHasFiniteReq = 0;
for ( i = 0; i < Gia_ManCoNum(p); i++ )
if ( Tim_ManGetCoRequired( pManTime, i ) < TIM_ETERNITY )
{
fHasFiniteReq = 1;
break;
}
if ( fHasFiniteReq )
{
pPars->pTimesReq = ABC_CALLOC( float, Gia_ManCoNum(p) );
for ( i = 0; i < Gia_ManCoNum(p); i++ )
pPars->pTimesReq[i] = Tim_ManGetCoRequired( pManTime, i );
}
}
ABC_FREE( p->pCellStr );
Vec_IntFreeP( &p->vConfigs );
Vec_StrFreeP( &p->vConfigs2 );
// disable cut minimization when GIA strucure is needed
if ( !pPars->fDelayOpt && !pPars->fDelayOptLut && !pPars->fDsdBalance && !pPars->fUserRecLib && !pPars->fUserSesLib && !pPars->fDeriveLuts && !pPars->fUseDsd && !pPars->fUseTtPerm && !pPars->pFuncCell2 )
pPars->fCutMin = 0;
@ -2425,7 +3091,7 @@ Gia_Man_t * Gia_ManPerformMappingInt( Gia_Man_t * p, If_Par_t * pPars )
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
// print delay trace
if ( pPars->fVerboseTrace )
if ( pPars->fVerboseTrace && !pPars->fEnableCheck07 )
{
pNew->pLutLib = pPars->pLutLib;
Gia_ManDelayTraceLutPrint( pNew, 1 );
@ -2645,6 +3311,85 @@ Gia_Man_t * Gia_ManDupHashMapping( Gia_Man_t * p )
return pNew;
}
/**Function*************************************************************
Synopsis [Uniqifies AIG nodes within each mapped cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManDupCollectedCutNodes_rec( Gia_Man_t * p, int iLut, Vec_Int_t * vNodes )
{
if ( Gia_ObjUpdateTravIdCurrentId(p, iLut) )
return;
Gia_ManDupCollectedCutNodes_rec( p, Gia_ObjFaninId0p(p, Gia_ManObj(p, iLut)), vNodes );
Gia_ManDupCollectedCutNodes_rec( p, Gia_ObjFaninId1p(p, Gia_ManObj(p, iLut)), vNodes );
Vec_IntPush( vNodes, iLut );
}
void Gia_ManDupCollectedCutNodes( Gia_Man_t * p, int iLut, Vec_Int_t * vNodes )
{
Gia_ManIncrementTravId(p);
Vec_IntClear( vNodes );
int k, iFan;
Gia_LutForEachFanin( p, iLut, iFan, k )
Gia_ObjSetTravIdCurrentId(p, iFan);
assert( !Gia_ObjIsTravIdCurrentId(p, iLut) );
Gia_ManDupCollectedCutNodes_rec( p, iLut, vNodes );
assert( Gia_ObjIsTravIdCurrentId(p, iLut) );
}
Gia_Man_t * Gia_ManDupUnhashMapping( Gia_Man_t * p )
{
Gia_Man_t * pNew;
Vec_Int_t * vMapping;
Gia_Obj_t * pObj, * pFanin;
Vec_Int_t * vNodes = Vec_IntAlloc( 100 );
Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) );
int i, k, iTempLit;
assert( Gia_ManHasMapping(p) );
// copy the old manager with hashing
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
Gia_ManForEachLut( p, i )
{
Gia_ManDupCollectedCutNodes( p, i, vNodes );
Gia_ManForEachObjVec( vNodes, p, pObj, k )
Vec_IntWriteEntry( vMap, Gia_ObjId(p, pObj), pObj->Value );
Gia_ManForEachObjVec( vNodes, p, pObj, k )
pObj->Value = Gia_ManAppendAnd2( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
iTempLit = Gia_ManObj(p, i)->Value;
Gia_ManForEachObjVec( vNodes, p, pObj, k )
pObj->Value = Vec_IntEntry( vMap, Gia_ObjId(p, pObj) );
Gia_ManObj(p, i)->Value = iTempLit;
}
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(p) );
// recreate mapping
vMapping = Vec_IntAlloc( Vec_IntSize(p->vMapping) );
Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
Gia_ManForEachLut( p, i )
{
pObj = Gia_ManObj( p, i );
Vec_IntWriteEntry( vMapping, Abc_Lit2Var(pObj->Value), Vec_IntSize(vMapping) );
Vec_IntPush( vMapping, Gia_ObjLutSize(p, i) );
Gia_LutForEachFaninObj( p, i, pFanin, k )
Vec_IntPush( vMapping, Abc_Lit2Var(pFanin->Value) );
Vec_IntPush( vMapping, Abc_Lit2Var(pObj->Value) );
}
Vec_IntFree( vMap );
pNew->vMapping = vMapping;
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
@ -2652,4 +3397,3 @@ Gia_Man_t * Gia_ManDupHashMapping( Gia_Man_t * p )
ABC_NAMESPACE_IMPL_END

View File

@ -177,7 +177,7 @@ Vec_Wec_t * Gia_Iso4Gia( Gia_Man_t * p )
Vec_WecForEachLevel( vLevs, vLevel, l )
{
Gia_Obj_t * pObj; int i;
int RandC[2] = { (int)Abc_Random(0), (int)Abc_Random(0) };
unsigned RandC[2] = { Abc_Random(0), Abc_Random(0) };
if ( l == 0 )
{
Gia_ManForEachObjVec( vLevel, p, pObj, i )

View File

@ -29,7 +29,7 @@
#ifdef ABC_USE_PTHREADS
#ifdef _WIN32
#if defined(_WIN32) && !defined(__MINGW32__)
#include "../lib/pthread.h"
#else
#include <pthread.h>

View File

@ -1838,6 +1838,12 @@ static inline int Lf_ManDerivePart( Lf_Man_t * p, Gia_Man_t * pNew, Vec_Int_t *
}
pTruth = Lf_CutTruth( p, pCut );
iLit = Kit_TruthToGia( pNew, (unsigned *)pTruth, Vec_IntSize(vLeaves), vCover, vLeaves, 0 );
// do not create LUT in the simple case
if ( Abc_Lit2Var(iLit) == 0 )
return iLit;
Vec_IntForEachEntry( vLeaves, iTemp, k )
if ( Abc_Lit2Var(iLit) == Abc_Lit2Var(iTemp) )
return iLit;
// create mapping
Vec_IntSetEntry( vMapping, Abc_Lit2Var(iLit), Vec_IntSize(vMapping2) );
Vec_IntPush( vMapping2, Vec_IntSize(vLeaves) );
@ -2306,8 +2312,8 @@ Gia_Man_t * Gia_ManPerformLfMapping( Gia_Man_t * p, Jf_Par_t * pPars, int fNorma
Gia_ManTransferTiming( pNew, p );
p = pNew;
// set arrival and required times
pPars->pTimesArr = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime );
pPars->pTimesReq = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime );
pPars->pTimesArr = Tim_ManGetArrTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
pPars->pTimesReq = Tim_ManGetReqTimes( (Tim_Man_t *)p->pManTime, Gia_ManRegNum(p) );
}
else
p = Gia_ManDup( p );

304
src/aig/gia/giaLutCas.c Normal file
View File

@ -0,0 +1,304 @@
/**CFile****************************************************************
FileName [giaLutCas.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis [LUT cascade generator.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaLutCas.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
#ifdef _WIN32
#include <windows.h>
#endif
#include "sat/cnf/cnf.h"
#include "misc/util/utilTruth.h"
#include "sat/cadical/cadicalSolver.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManGenSymFun_rec( Gia_Man_t * p, word Str, int nChars, Vec_Ptr_t * vStrs, Vec_Wec_t * vLits, Vec_Int_t * vIns )
{
if ( Str == 0 ) return 0;
if ( Str == Abc_Tt6Mask(nChars) ) return 1;
assert( nChars > 1 );
Vec_Wrd_t * vStore = (Vec_Wrd_t *)Vec_PtrEntry(vStrs, nChars-1);
Vec_Int_t * vValue = Vec_WecEntry(vLits, nChars-1);
int Index;
if ( (Index = Vec_WrdFind(vStore, Str)) >= 0 )
return Vec_IntEntry(vValue, Index);
word Str0 = Str & ~Abc_Tt6MaskI(nChars-1);
word Str1 = Str >> 1;
int Lit0 = Gia_ManGenSymFun_rec( p, Str0, nChars-1, vStrs, vLits, vIns );
int Lit1 = Gia_ManGenSymFun_rec( p, Str1, nChars-1, vStrs, vLits, vIns );
int Lit = Gia_ManAppendMux2( p, Vec_IntEntry(vIns, nChars-2), Lit1, Lit0 );
Vec_WrdPush( vStore, Str );
Vec_WrdPush( vStore, ~Str & Abc_Tt6Mask(nChars) );
Vec_IntPush( vValue, Lit );
Vec_IntPush( vValue, Abc_LitNot(Lit) );
return Lit;
}
Gia_Man_t * Gia_ManGenSymFun( Vec_Wrd_t * vFuns, int nChars, int fVerbose )
{
assert( nChars <= 64 );
word Str; int i;
Vec_Ptr_t * vStrs = Vec_PtrAlloc(nChars);
for ( i = 0; i < nChars; i++ )
Vec_PtrPush( vStrs, Vec_WrdAlloc(0) );
Vec_Wec_t * vLits = Vec_WecStart(nChars);
Vec_Int_t * vOuts = Vec_IntAlloc(Vec_WrdSize(vFuns));
Gia_Man_t * pNew = Gia_ManStart( 10000 );
pNew->pName = Abc_UtilStrsav( "sym" );
Vec_Int_t * vIns = Vec_IntAlloc(nChars-1);
for ( i = 0; i < nChars-1; i++ )
Vec_IntPush(vIns, Gia_ManAppendCi(pNew));
Vec_WrdForEachEntry( vFuns, Str, i )
Vec_IntPush( vOuts, Gia_ManGenSymFun_rec(pNew, Str, nChars, vStrs, vLits, vIns ) );
Vec_WrdForEachEntry( vFuns, Str, i )
Gia_ManAppendCo(pNew, Vec_IntEntry(vOuts,i) );
for ( i = 0; i < nChars; i++ )
Vec_WrdFree( (Vec_Wrd_t *)Vec_PtrEntry(vStrs, i) );
Vec_PtrFree(vStrs);
Vec_WecFree(vLits);
Vec_IntFree(vOuts);
Vec_IntFree(vIns);
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline void Gia_LutCasSort( char * pStr, int iStart, int nChars )
{
int i, j;
for ( i = iStart; i < iStart + nChars - 1; i++ )
for ( j = i + 1; j < iStart + nChars; j++ )
if ( pStr[i] > pStr[j] )
ABC_SWAP( char, pStr[i], pStr[j] );
}
char * Gia_LutCasPerm( int nVars, int nLuts, int LutSize )
{
assert( nVars <= 26 && nLuts <= 100 );
int nStrLen = nLuts * LutSize;
char * pRes = ABC_CALLOC( char, nStrLen+1 );
int i, j, iVar, pPerm[26], nVarCount[100] = {0};
// create a random permutation
for ( i = 0; i < nVars; i++ )
pPerm[i] = i;
for ( i = nVars - 1; i > 0; i-- ) {
j = rand() % (i + 1);
ABC_SWAP( int, pPerm[i], pPerm[j] );
}
// assign the first variable
for ( i = 0; i < nLuts; i++ ) {
pRes[i * LutSize] = i ? '_' : 'a' + pPerm[0];
nVarCount[i] = 1;
}
// First pass: distribute each variable (starting from the second in permutation) to at least one LUT
for ( i = 1; i < nVars; i++ ) {
// Find a LUT with space that doesn't have this variable
int Tries = 0, iLut = rand() % nLuts;
while ( nVarCount[iLut] >= LutSize && Tries++ < nLuts )
iLut = (iLut + 1) % nLuts;
// the variables are unique - no need to check this
pRes[iLut * LutSize + nVarCount[iLut]] = 'a' + pPerm[i];
nVarCount[iLut]++;
}
// Second pass: fill remaining slots with random variables (cycling through permutation)
for ( i = 0; i < nLuts; i++ ) {
while ( nVarCount[i] < LutSize ) {
iVar = pPerm[rand() % nVars];
// Check this LUT already has this variable
for ( j = 0; j < nVarCount[i]; j++ )
if ( pRes[i * LutSize + j] == 'a' + iVar )
break;
if ( j == nVarCount[i] ) { // does not have
pRes[i * LutSize + nVarCount[i]] = 'a' + iVar;
nVarCount[i]++;
}
}
}
// Sort inputs within each LUT (skip '_' for non-first LUTs)
Gia_LutCasSort( pRes, 0, LutSize );
for ( i = 1; i < nLuts; i++ )
Gia_LutCasSort( pRes + i * LutSize, 1, LutSize-1 );
return pRes;
}
int Gia_ManGenLutCas_rec( Gia_Man_t * pNew, Vec_Int_t * vCtrls, int iCtrl, Vec_Int_t * vDatas, int Shift, int Offset )
{
if ( iCtrl-- == 0 )
return Vec_IntEntry( vDatas, Shift );
int iLit0 = Gia_ManGenLutCas_rec( pNew, vCtrls, iCtrl, vDatas, Shift, Offset );
int iLit1 = Gia_ManGenLutCas_rec( pNew, vCtrls, iCtrl, vDatas, Shift + (1<<iCtrl), Offset );
return Gia_ManAppendMux( pNew, Vec_IntEntry(vCtrls, iCtrl+Offset), iLit1, iLit0 );
}
int Gia_ManGenWire( Gia_Man_t * pNew, Vec_Int_t * vCtrls, Vec_Int_t * vParams2, int iParam2 )
{
int nVars = Vec_IntSize(vCtrls);
int nBits = Abc_Base2Log(nVars);
while ( Vec_IntSize(vCtrls) < (1 << nBits) )
Vec_IntPush( vCtrls, 0 );
int iRes = Gia_ManGenLutCas_rec( pNew, vParams2, nBits, vCtrls, 0, iParam2 );
Vec_IntShrink( vCtrls, nVars );
return iRes;
}
Gia_Man_t * Gia_ManGenLutCas( Gia_Man_t * p, char * pPermStr, int nVars, int nLuts, int LutSize, int Seed, int fVerbose )
{
if ( Seed )
srand(Seed);
else {
#ifdef _WIN32
unsigned int seed = (unsigned int)GetTickCount();
#else
struct timespec ts;
clock_gettime(CLOCK_REALTIME, &ts);
unsigned int seed = (unsigned int)(ts.tv_sec ^ ts.tv_nsec);
#endif
srand(seed);
}
int fOwnPerm = (pPermStr == NULL);
char * pPerm = fOwnPerm ? Gia_LutCasPerm( nVars, nLuts, LutSize ) : pPermStr;
int nParams = nLuts * (1 << LutSize);
// count how many variables are unassigned in the permutation
int nParams2 = 0;
for ( int v = 0; v < strlen(pPerm); v++ )
if ( pPerm[v] == '*' )
nParams2 += Abc_Base2Log(nVars);
if ( fVerbose )
printf( "Generating AIG with %d parameters (%d functional + %d structural) and %d inputs using fanin assignment \"%s\".\n",
nParams+nParams2, nParams, nParams2, nVars, pPerm );
Gia_Man_t * pNew = Gia_ManStart( nParams + nVars );
pNew->pName = Abc_UtilStrsav( pPerm );
Vec_Int_t * vDatas = Vec_IntAlloc( nParams );
Vec_Int_t * vWires = Vec_IntAlloc( nParams2 );
Vec_Int_t * vCtrls = Vec_IntAlloc( nVars );
for ( int i = 0; i < nParams; i++ )
Vec_IntPush( vDatas, Gia_ManAppendCi(pNew) );
for ( int i = 0; i < nParams2; i++ )
Vec_IntPush( vWires, Gia_ManAppendCi(pNew) );
for ( int i = 0; i < nVars; i++ )
Vec_IntPush( vCtrls, Gia_ManAppendCi(pNew) );
Vec_Int_t * vLits = Vec_IntStart( LutSize );
Vec_IntWriteEntry( vLits, 0, pPerm[0] == '*' ? Gia_ManGenWire(pNew, vCtrls, vWires, 0) : Vec_IntEntry(vCtrls, (int)(pPerm[0]-'a')) );
int iWireVars = pPerm[0] == '*' ? Abc_Base2Log(nVars) : 0;
char * pCur = pPerm;
for ( int i = 0; i < nLuts; i++ ) {
assert( i == 0 || *pCur == '_' );
pCur++;
for ( int k = 1; k < LutSize; k++ ) {
Vec_IntWriteEntry( vLits, k, *pCur == '*' ? Gia_ManGenWire(pNew, vCtrls, vWires, iWireVars) : Vec_IntEntry(vCtrls, (int)(*pCur - 'a')) );
iWireVars += *pCur++ == '*' ? Abc_Base2Log(nVars) : 0;
}
Vec_IntWriteEntry( vLits, 0, Gia_ManGenLutCas_rec(pNew, vLits, LutSize, vDatas, i * (1 << LutSize), 0) );
}
assert( iWireVars == nParams2 );
// if the AIG is given, create a miter
int iLit = Vec_IntEntry(vLits, 0);
if ( p ) {
assert( Gia_ManCiNum(p) == nVars );
assert( Gia_ManCoNum(p) == 1 );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_Obj_t * pObj; int i;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Vec_IntEntry(vCtrls, i);
Gia_ManForEachAnd( p, pObj, i )
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
iLit = Gia_ManAppendXor( pNew, iLit, Gia_ObjFanin0Copy(Gia_ManCo(p, 0)) );
iLit = Abc_LitNot(iLit);
}
Gia_ManAppendCo( pNew, iLit );
Vec_IntFree( vDatas );
Vec_IntFree( vCtrls );
Vec_IntFree( vWires );
Vec_IntFree( vLits );
if ( fOwnPerm )
ABC_FREE( pPerm );
return pNew;
}
/*
int Gia_ManGenLutCasSolve( int nVars, int nLuts, int LutSize, char * pTtStr, int fVerbose )
{
extern Gia_Man_t * Gia_QbfQuantifyAll( Gia_Man_t * p, int nPars, int fAndAll, int fOrAll );
assert( strlen(pTtStr) <= 1024 );
word pTruth[64] = {0};
int i, Id, nVars = Abc_TtReadHex( pTruth, pTtStr );
assert( nVars <= 12 );
int nParams = nLuts * (1 << LutSize);
Gia_Man_t * pCas = Gia_ManGenLutCas( NULL, NULL, nVars, nLuts, LutSize, 0, fVerbose );
Gia_Man_t * pCofs = Gia_QbfQuantifyAll( pCas, nParams, 0, 0 );
Gia_ManFree( pCas );
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCofs, 8, 0, 0, 0, 0 );
cadical_solver* pSat = cadical_solver_new(void);
cadical_solver_setnvars( pSat, pCnf->nVars );
// add output literals
assert( Gia_ManCoNum(pCofs) == (1 << nVars) );
Gia_ManForEachCoId( pCofs, Id, i ) {
int Lit = Abc_Var2Lit(pCnf->pVarNums[Id], Abc_TtGetBit(pTruth, i));
int status = cadical_solver_addclause( pSat, &Lit, &Lit+1 );
}
for ( i = 0; i < pCnf->nClauses; i++ )
if ( !cadical_solver_addclause( pSat, pCnf->pClauses[i], pCnf->pClauses[i+1] ) ) {
Cnf_DataFree( pCnf );
return 0;
}
Cnf_DataFree( pCnf );
Gia_ManFree( pCofs );
int status = cadical_solver_solve( pSat, NULL, NULL, 0, 0, 0, 0 );
for ( i = 0; i < nLuts; i++, printf(" ") )
for ( k = 0; k < (1 << LutSize); k++ ) {
int Value = cadical_solver_get_var_value(pSat, i*(1 << LutSize) + k);
printf( "%d", Value );
}
cadical_solver_delete( pSat );
return 1;
}
*/
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

File diff suppressed because it is too large Load Diff

View File

@ -290,15 +290,19 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
int nBoxes = Gia_ManBoxNum(p);
int nRealPis = nBoxes ? Tim_ManPiNum(pManTime) : Gia_ManPiNum(p);
int nRealPos = nBoxes ? Tim_ManPoNum(pManTime) : Gia_ManPoNum(p);
int i, k, Id, curCi, curCo, nBoxIns, nBoxOuts, iLitNew, iMfsId, iGroup, Fanin;
int i, k, curCi, curCo, nBoxIns, nBoxOuts, iLitNew, iMfsId, iGroup, Fanin, iBox;
int nMfsNodes;
word * pTruth, uTruthVar = ABC_CONST(0xAAAAAAAAAAAAAAAA);
Vec_Wec_t * vGroups = Vec_WecStart( nBoxes );
Vec_Int_t * vMfs2Gia, * vMfs2Old;
Vec_Int_t * vGroupMap;
Vec_Int_t * vMfsTopo, * vCover, * vBoxesLeft;
Vec_Int_t * vMfsTopo, * vCover, * vBoxesLeft, * vBoxKeep;
Vec_Int_t * vArray, * vLeaves;
Vec_Int_t * vMapping, * vMapping2;
Vec_Int_t * vCoDrivers;
Vec_Int_t * vPiBoxes = NULL;
Vec_Int_t * vBbCiMap = NULL;
Vec_Int_t * vBbOutLit = NULL;
int nBbIns = 0, nBbOuts = 0;
if ( pManTime ) Tim_ManBlackBoxIoNum( pManTime, &nBbIns, &nBbOuts );
nMfsNodes = 1 + Gia_ManCiNum(p) + Gia_ManLutNum(p) + Gia_ManCoNum(p) + nBbIns + nBbOuts;
@ -340,8 +344,40 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
assert( curCo == Gia_ManCoNum(p) );
// collect nodes in the given order
if ( nBbOuts > 0 )
{
int iBbOut = 0;
vPiBoxes = Vec_IntStartFull( nBbOuts + nRealPis );
vBbCiMap = Vec_IntStartFull( Gia_ManCiNum(p) );
vBbOutLit = Vec_IntStartFull( nBbOuts );
curCi = nRealPis;
curCo = 0;
for ( i = 0; i < nBoxes; i++ )
{
nBoxIns = Tim_ManBoxInputNum( pManTime, i );
nBoxOuts = Tim_ManBoxOutputNum( pManTime, i );
if ( Tim_ManBoxIsBlack(pManTime, i) )
for ( k = 0; k < nBoxOuts; k++ )
{
assert( iBbOut < nBbOuts );
Vec_IntWriteEntry( vPiBoxes, iBbOut, i );
Vec_IntWriteEntry( vBbCiMap, curCi + k, iBbOut );
iBbOut++;
}
curCo += nBoxIns;
curCi += nBoxOuts;
}
curCo += nRealPos;
assert( curCi == Gia_ManCiNum(p) );
assert( curCo == Gia_ManCoNum(p) );
assert( iBbOut == nBbOuts );
}
vBoxesLeft = Vec_IntAlloc( nBoxes );
vMfsTopo = Sfm_NtkDfs( pNtk, vGroups, vGroupMap, vBoxesLeft, fAllBoxes );
vMfsTopo = Sfm_NtkDfs( pNtk, vGroups, vGroupMap, vBoxesLeft, fAllBoxes, vPiBoxes );
Vec_IntUniqify( vBoxesLeft ); // reduce to sorted unique indices expected by the timing manager
vBoxKeep = Vec_IntStart( nBoxes );
Vec_IntForEachEntry( vBoxesLeft, iBox, i )
Vec_IntWriteEntry( vBoxKeep, iBox, 1 );
assert( Vec_IntSize(vBoxesLeft) <= nBoxes );
assert( Vec_IntSize(vMfsTopo) > 0 );
@ -360,13 +396,28 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
// map constant
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, 0), 0 );
// map primary inputs
Gia_ManForEachCiId( p, Id, i )
if ( i < nRealPis )
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, Id), Gia_ManAppendCi(pNew) );
// map primary inputs (real ones and preserved box outputs)
Gia_ManForEachCi( p, pObj, i )
{
int iCiId = Gia_ObjId( p, pObj );
int iBox = pManTime ? Tim_ManBoxForCi( pManTime, Gia_ObjCioId(pObj) ) : -1;
int iBbOut = vBbCiMap ? Vec_IntEntry(vBbCiMap, i) : -1;
if ( iBox >= 0 && !Vec_IntEntry(vBoxKeep, iBox) )
{
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, iCiId), -1 );
if ( iBbOut >= 0 && vBbOutLit )
Vec_IntWriteEntry( vBbOutLit, iBbOut, -1 );
continue;
}
iLitNew = Gia_ManAppendCi(pNew);
Vec_IntWriteEntry( vMfs2Gia, Gia_ObjCopyArray(p, iCiId), iLitNew );
if ( iBbOut >= 0 && vBbOutLit )
Vec_IntWriteEntry( vBbOutLit, iBbOut, iLitNew );
}
// map internal nodes
vLeaves = Vec_IntAlloc( 6 );
vCover = Vec_IntAlloc( 1 << 16 );
vCoDrivers = Vec_IntStartFull( Gia_ManCoNum(p) );
Vec_IntForEachEntry( vMfsTopo, iMfsId, i )
{
pTruth = Sfm_NodeReadTruth( pNtk, iMfsId );
@ -374,16 +425,21 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
vArray = Sfm_NodeReadFanins( pNtk, iMfsId ); // belongs to pNtk
if ( Vec_IntSize(vArray) == 1 && Vec_IntEntry(vArray,0) < nBbOuts ) // skip unreal inputs
{
// create CI for the output of black box
assert( Abc_LitIsCompl(iGroup) );
iLitNew = Gia_ManAppendCi( pNew );
assert( vBbOutLit != NULL );
iLitNew = Vec_IntEntry( vBbOutLit, Vec_IntEntry(vArray,0) );
assert( iLitNew >= 0 );
Vec_IntWriteEntry( vMfs2Gia, iMfsId, iLitNew );
continue;
}
Vec_IntClear( vLeaves );
Vec_IntForEachEntry( vArray, Fanin, k )
{
iLitNew = Vec_IntEntry( vMfs2Gia, Fanin ); assert( iLitNew >= 0 );
if ( Fanin < nBbOuts )
iLitNew = Vec_IntEntry( vBbOutLit, Fanin );
else
iLitNew = Vec_IntEntry( vMfs2Gia, Fanin );
assert( iLitNew >= 0 );
Vec_IntPush( vLeaves, iLitNew );
}
if ( iGroup == -1 ) // internal node
@ -395,7 +451,9 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
int nVarsNew;
Abc_TtSimplify( pTruth, Vec_IntArray(vLeaves), Vec_IntSize(vLeaves), &nVarsNew );
Vec_IntShrink( vLeaves, nVarsNew );
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
iLitNew = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
if ( MapSize < Vec_IntSize(vMapping2) )
{
assert( Vec_IntEntryLast(vMapping2) == Abc_Lit2Var(iLitNew) );
@ -403,38 +461,42 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
}
}
else
{
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
iLitNew = Gia_ManFromIfLogicCreateLut( pNew, pTruth, vLeaves, vCover, vMapping, vMapping2 );
Abc_TtFlipVar5( pTruth, Vec_IntSize(vLeaves) );
}
}
else if ( Abc_LitIsCompl(iGroup) ) // internal CI
else if ( Abc_LitIsCompl(iGroup) ) // internal CI (box output)
{
//Dau_DsdPrintFromTruth( pTruth, Vec_IntSize(vLeaves) );
iLitNew = Gia_ManAppendCi( pNew );
iLitNew = Vec_IntEntry( vMfs2Gia, iMfsId );
if ( iLitNew < 0 )
continue;
}
else // internal CO
{
int iObjOld = Vec_IntEntry( vMfs2Old, iMfsId );
int iCoIdx;
assert( iObjOld >= 0 );
assert( pTruth[0] == uTruthVar || pTruth[0] == ~uTruthVar );
iLitNew = Gia_ManAppendCo( pNew, Abc_LitNotCond(Vec_IntEntry(vLeaves, 0), pTruth[0] == ~uTruthVar) );
//printf("Group = %d. po = %d\n", iGroup>>1, iMfsId );
iLitNew = Abc_LitNotCond( Vec_IntEntry(vLeaves, 0), pTruth[0] == ~uTruthVar );
iCoIdx = Gia_ObjCioId( Gia_ManObj(p, iObjOld) );
Vec_IntWriteEntry( vCoDrivers, iCoIdx, iLitNew );
}
Vec_IntWriteEntry( vMfs2Gia, iMfsId, iLitNew );
}
Vec_IntFree( vCover );
Vec_IntFree( vLeaves );
// map primary outputs
// map primary outputs (internal box inputs followed by real POs)
Gia_ManForEachCo( p, pObj, i )
{
if ( i < Gia_ManCoNum(p) - nRealPos ) // internal COs
if ( i < Gia_ManCoNum(p) - nRealPos )
{
iMfsId = Gia_ObjCopyArray( p, Gia_ObjId(p, pObj) );
iGroup = Vec_IntEntry( vGroupMap, iMfsId );
if ( Vec_IntFind(vMfsTopo, iGroup) >= 0 )
{
iLitNew = Vec_IntEntry( vMfs2Gia, iMfsId );
if ( iLitNew < 0 )
continue;
assert( iLitNew >= 0 );
}
iLitNew = Vec_IntEntry( vCoDrivers, i );
if ( iLitNew == -1 )
continue;
Gia_ManAppendCo( pNew, iLitNew );
continue;
}
iLitNew = Vec_IntEntry( vMfs2Gia, Gia_ObjCopyArray(p, Gia_ObjFaninId0p(p, pObj)) );
@ -477,6 +539,11 @@ Gia_Man_t * Gia_ManInsertMfs( Gia_Man_t * p, Sfm_Ntk_t * pNtk, int fAllBoxes )
Vec_IntFree( vMfs2Gia );
Vec_IntFree( vMfs2Old );
Vec_IntFree( vBoxesLeft );
Vec_IntFree( vBoxKeep );
Vec_IntFree( vCoDrivers );
Vec_IntFreeP( &vPiBoxes );
Vec_IntFreeP( &vBbCiMap );
Vec_IntFreeP( &vBbOutLit );
return pNew;
}
@ -495,7 +562,7 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars )
{
Sfm_Ntk_t * pNtk;
Gia_Man_t * pNew;
int nFaninMax, nNodes;
int nFaninMax, nNodes = 0;
assert( Gia_ManRegNum(p) == 0 );
assert( p->vMapping != NULL );
if ( p->pManTime != NULL && p->pAigExtra == NULL )
@ -544,4 +611,3 @@ Gia_Man_t * Gia_ManPerformMfs( Gia_Man_t * p, Sfm_Par_t * pPars )
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -193,7 +193,7 @@ Gia_Man_t * Vec_WrdReadTest( char * pFileName )
void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO, int nIns, int nOuts )
{
int i, nSize, iLine, nLines, nWords;
char pLine[1000];
char pLine[2000];
Vec_Wrd_t * vSimI, * vSimO;
FILE * pFile = fopen( pFileName, "rb" );
if ( pFile == NULL )
@ -214,7 +214,7 @@ void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO
nWords = (nLines + 63)/64;
vSimI = Vec_WrdStart( nIns *nWords );
vSimO = Vec_WrdStart( nOuts*nWords );
for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
for ( iLine = 0; fgets( pLine, 2000, pFile ); iLine++ )
{
for ( i = 0; i < nIns; i++ )
if ( pLine[nIns-1-i] == '1' )
@ -233,7 +233,7 @@ void Vec_WrdReadText( char * pFileName, Vec_Wrd_t ** pvSimI, Vec_Wrd_t ** pvSimO
int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
{
int i, nSize, iLine, nLines, nWords, nIns;
char pLine[1000];
char pLine[2000];
Vec_Wrd_t * vSimI;
FILE * pFile = fopen( pFileName, "rb" );
if ( pFile == NULL )
@ -241,7 +241,7 @@ int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
printf( "Cannot open file \"%s\" for reading.\n", pFileName );
return 0;
}
if ( !fgets(pLine, 1000, pFile) || (nIns = strlen(pLine)-1) < 1 )
if ( !fgets(pLine, 2000, pFile) || (nIns = strlen(pLine)-1) < 1 )
{
printf( "Cannot find the number of inputs in file \"%s\".\n", pFileName );
fclose( pFile );
@ -259,7 +259,7 @@ int Vec_WrdReadText2( char * pFileName, Vec_Wrd_t ** pvSimI )
nLines = nSize / (nIns + 1);
nWords = (nLines + 63)/64;
vSimI = Vec_WrdStart( nIns *nWords );
for ( iLine = 0; fgets( pLine, 1000, pFile ); iLine++ )
for ( iLine = 0; fgets( pLine, 2000, pFile ); iLine++ )
{
for ( i = 0; i < nIns; i++ )
if ( pLine[nIns-1-i] == '1' )

View File

@ -555,6 +555,24 @@ char * Abc_FrameGiaOutputMiniLutAttr( Abc_Frame_t * pAbc, void * pMiniLut )
printf( "Current network in ABC framework is not defined.\n" );
return Gia_ManToMiniLutAttr( pGia, pMiniLut );
}
int * Abc_FrameGiaOutputMiniLutObj( Abc_Frame_t * pAbc )
{
int * pRes = NULL;
if ( pAbc == NULL )
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
pAbc->vMiniLutObjs = Gia_ManDeriveBoxMapping( Abc_FrameReadGia( pAbc ) );
if ( pAbc->vMiniLutObjs == NULL )
printf( "MiniLut objects are not defined.\n" );
pRes = Vec_IntReleaseArray( pAbc->vMiniLutObjs );
Vec_IntFreeP( &pAbc->vMiniLutObjs );
return pRes;
}
void Abc_FrameSetObjDelays( Abc_Frame_t * pAbc, int * pDelays, int nDelays )
{
Vec_IntFreeP( &pAbc->vObjDelays );
pAbc->vObjDelays = Vec_IntAllocArrayCopy( pDelays, nDelays );
}
/**Function*************************************************************
@ -724,6 +742,23 @@ int * Abc_FrameReadMiniLutSwitching( Abc_Frame_t * pAbc )
Vec_IntFree( vSwitching );
return pRes;
}
int * Abc_FrameReadMiniLutSwitching2( Abc_Frame_t * pAbc, int fRandPiFactor )
{
Vec_Int_t * vSwitching;
int i, iObj, * pRes = NULL;
if ( pAbc->pGiaMiniLut == NULL )
{
printf( "GIA derived from MiniLut is not available.\n" );
return NULL;
}
vSwitching = Gia_ManComputeSwitchProbs2( pAbc->pGiaMiniLut, 48, 16, 0, fRandPiFactor );
pRes = ABC_CALLOC( int, Vec_IntSize(pAbc->vCopyMiniLut) );
Vec_IntForEachEntry( pAbc->vCopyMiniLut, iObj, i )
if ( iObj >= 0 )
pRes[i] = (int)(10000*Vec_FltEntry( (Vec_Flt_t *)vSwitching, Abc_Lit2Var(iObj) ));
Vec_IntFree( vSwitching );
return pRes;
}
int * Abc_FrameReadMiniLutSwitchingPo( Abc_Frame_t * pAbc )
{
Vec_Int_t * vSwitching;
@ -1228,6 +1263,127 @@ void Gia_MiniAigGenerateFromFile()
Mini_AigStop( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Str_t * Gia_ManRetimableF( Gia_Man_t * p, int * pRst, int * pSet, int * pEna )
{
Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) );
Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) );
Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i;
char * pStops = Vec_StrArray(vStops);
assert( Gia_ManRegNum(p) > 0 );
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 0, pRst[i] );
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 1, pSet[i] );
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRo) + 2, pEna[i] );
}
Gia_ManForEachAnd( p, pObj, i ) {
int * pFan0 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId0(pObj, i) );
int * pFan1 = Vec_IntEntryP( vTemps, 3*Gia_ObjFaninId1(pObj, i) );
int * pNode = Vec_IntEntryP( vTemps, 3*i );
pStops[i] = (char)1;
if ( pFan0[0] != -1 && pFan0[0] == pFan1[0] && pFan0[1] == pFan1[1] && pFan0[2] == pFan1[2] )
pStops[i] = (char)0, pNode[0] = pFan0[0], pNode[1] = pFan0[1], pNode[2] = pFan0[2];
}
Vec_IntFree( vTemps );
return vStops;
}
Vec_Str_t * Gia_ManRetimableB( Gia_Man_t * p, int * pRst, int * pSet, int * pEna )
{
Vec_Str_t * vStops = Vec_StrStart( Gia_ManObjNum(p) );
Vec_Int_t * vTemps = Vec_IntStartFull( 3*Gia_ManObjNum(p) );
Gia_Obj_t * pObj, * pObjRi, * pObjRo; int i, n, iFanout;
char * pStops = Vec_StrArray(vStops);
assert( Gia_ManRegNum(p) > 0 );
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 0, pRst[i] );
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 1, pSet[i] );
Vec_IntWriteEntry( vTemps, 3*Gia_ObjId(p, pObjRi) + 2, pEna[i] );
}
Gia_ManStaticFanoutStart( p );
Gia_ManForEachAndReverse( p, pObj, i ) {
int * pFan0 = Vec_IntEntryP( vTemps, 3*Gia_ObjFanoutId(p, i, 0) );
int * pNode = Vec_IntEntryP( vTemps, 3*i );
pStops[i] = (char)1;
if ( pFan0[0] == -1 )
continue;
Gia_ObjForEachFanoutStaticId( p, i, iFanout, n ) {
int * pFan1 = Vec_IntEntryP( vTemps, 3*iFanout );
if ( pFan1[0] == -1 || pFan0[0] != pFan1[0] || pFan0[1] != pFan1[1] || pFan0[2] != pFan1[2] )
break;
}
if ( n < Gia_ObjFanoutNum(p, pObj) )
continue;
pStops[i] = (char)0, pNode[0] = pFan0[0], pNode[1] = pFan0[1], pNode[2] = pFan0[2];
}
Gia_ManStaticFanoutStop( p );
Vec_IntFree( vTemps );
Gia_ManForEachRiRo( p, pObjRi, pObjRo, i ) {
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pRst[i]))) ) pStops[Abc_Lit2Var(pRst[i])] = 1;
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pSet[i]))) ) pStops[Abc_Lit2Var(pSet[i])] = 1;
if ( Gia_ObjIsAnd(Gia_ManObj(p, Abc_Lit2Var(pEna[i]))) ) pStops[Abc_Lit2Var(pEna[i])] = 1;
}
return vStops;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_FrameRemapLits( int * pLits, int nLits, Vec_Int_t * vMap )
{
for ( int i = 0; i < nLits; i++ )
pLits[i] = Abc_Lit2LitL( Vec_IntArray(vMap), pLits[i] );
}
void Abc_FrameSetRetimingData( Abc_Frame_t * pAbc, int * pRst, int * pSet, int * pEna, int nRegs )
{
Gia_Man_t * pGia;
int * pRstNew = ABC_CALLOC( int, nRegs );
int * pSetNew = ABC_CALLOC( int, nRegs );
int * pEnaNew = ABC_CALLOC( int, nRegs );
if ( pAbc == NULL )
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
pGia = Abc_FrameReadGia( pAbc );
if ( pGia == NULL )
printf( "Current network in ABC framework is not defined.\n" );
else {
assert( nRegs == Gia_ManRegNum(pGia) );
memmove( pRstNew, pRst, sizeof(int)*nRegs );
memmove( pSetNew, pSet, sizeof(int)*nRegs );
memmove( pEnaNew, pEna, sizeof(int)*nRegs );
}
if ( pAbc->vCopyMiniAig == NULL )
printf( "Mapping of MiniAig nodes is not available.\n" );
else {
Abc_FrameRemapLits( pRstNew, nRegs, pAbc->vCopyMiniAig );
Abc_FrameRemapLits( pSetNew, nRegs, pAbc->vCopyMiniAig );
Abc_FrameRemapLits( pEnaNew, nRegs, pAbc->vCopyMiniAig );
}
assert( pGia->vStopsF == NULL );
assert( pGia->vStopsB == NULL );
pGia->vStopsF = Gia_ManRetimableF( pGia, pRstNew, pSetNew, pEnaNew );
pGia->vStopsB = Gia_ManRetimableB( pGia, pRstNew, pSetNew, pEnaNew );
ABC_FREE( pRstNew );
ABC_FREE( pSetNew );
ABC_FREE( pEnaNew );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

916
src/aig/gia/giaMulFind.c Normal file
View File

@ -0,0 +1,916 @@
/**CFile****************************************************************
FileName [giaMulFind.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Scalable AIG package.]
Synopsis [Multiplier detection.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaMulFind.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManMulFindXors2_rec( Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vXor )
{
if ( !Gia_ObjIsAnd(pObj) )
return;
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return;
Gia_ObjSetTravIdCurrent(p, pObj);
if ( !pObj->fMark0 )
{
if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj)
&& Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) >= 4
&& Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) >= 4 )
Vec_IntPushTwo( vXor, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninId1p(p, pObj) );
return;
}
Gia_Obj_t * pFan0, * pFan1;
int RetValue = Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1);
assert( RetValue );
Gia_ManMulFindXors2_rec( p, Gia_Regular(pFan0), vXor );
Gia_ManMulFindXors2_rec( p, Gia_Regular(pFan1), vXor );
}
Vec_Wec_t * Gia_ManMulFindXors2( Gia_Man_t * p )
{
Vec_Wec_t * vXors = Vec_WecAlloc( 100 );
Vec_Int_t * vTemp = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj, * pFan0, * pFan1; int i;
Gia_ManCreateRefs( p );
Gia_ManCleanMark01( p );
Gia_ManForEachAnd( p, pObj, i ) {
if ( !Gia_ObjRecognizeExor(pObj, &pFan0, &pFan1) )
continue;
Gia_Regular(pFan0)->fMark1 = 1;
Gia_Regular(pFan1)->fMark1 = 1;
pObj->fMark0 = 1;
}
Gia_ManForEachAnd( p, pObj, i ) {
if ( pObj->fMark0 && !pObj->fMark1 ) {
Gia_ManIncrementTravId( p );
Vec_IntClear( vTemp );
Gia_ManMulFindXors2_rec( p, pObj, vTemp );
if ( Vec_IntSize(vTemp) > 0 )
Vec_IntAppend( Vec_WecPushLevel(vXors), vTemp );
}
}
Vec_IntFree( vTemp );
return vXors;
}
int Gia_ManMulFindMaxSize( Vec_Wec_t * vXors, Vec_Int_t * vUsed )
{
Vec_Int_t * vLevel; int i, iBest = -1, nBestSize = 0;
Vec_WecForEachLevel( vXors, vLevel, i )
if ( !Vec_IntEntry(vUsed, i) && nBestSize < Vec_IntSize(vLevel) )
nBestSize = Vec_IntSize(vLevel), iBest = i;
return iBest;
}
int Gia_ManMulFindGetOverlap( Vec_Int_t * p1, Vec_Int_t * p2 )
{
int i, k, ObjI, ObjK, Counter = 0;
Vec_IntForEachEntry( p1, ObjI, i )
Vec_IntForEachEntry( p2, ObjK, k )
if ( ObjI == ObjK )
Counter++;
return Counter;
}
int Gia_ManMulFindGetOverlap2( Vec_Int_t * p1, Vec_Int_t * p2 )
{
int i, k, ObjI, ObjK, Counter = 0;
Vec_IntForEachEntryStart( p1, ObjI, i, 1 )
Vec_IntForEachEntry( p2, ObjK, k )
if ( ObjI == ObjK )
Counter++;
return Counter;
}
int Gia_ManMulFindMaxOverlap( Vec_Wec_t * vXors, Vec_Int_t * vUsed, Vec_Int_t * vFound )
{
Vec_Int_t * vLevel; int i, iBest = -1, nThisSize, nBestSize = 0;
Vec_WecForEachLevel( vXors, vLevel, i )
if ( !Vec_IntEntry(vUsed, i) && nBestSize < (nThisSize = Gia_ManMulFindGetOverlap(vFound, vLevel)) )
nBestSize = nThisSize, iBest = i;
return iBest;
}
Vec_Wec_t * Gia_ManMulFindSets( Gia_Man_t * p, Vec_Wec_t * vXors )
{
Vec_Wec_t * vSets = Vec_WecAlloc( 100 );
Vec_Int_t * vUsed = Vec_IntStart( Vec_WecSize(vXors) );
Vec_Int_t * vFound = Vec_IntAlloc( 100 ); int Item, k, Obj;
while ( (Item = Gia_ManMulFindMaxSize(vXors, vUsed)) != -1 ) {
Vec_Int_t * vTemp = Vec_WecEntry(vXors, Item);
Vec_Int_t * vNew = Vec_WecPushLevel( vSets );
Vec_IntPush( vNew, Item );
Vec_IntWriteEntry( vUsed, Item, 1 );
Vec_IntClear( vFound );
Vec_IntAppend( vFound, vTemp );
while ( (Item = Gia_ManMulFindMaxOverlap(vXors, vUsed, vFound)) != -1 ) {
Vec_IntPush( vNew, Item );
Vec_IntWriteEntry( vUsed, Item, 1 );
vTemp = Vec_WecEntry(vXors, Item);
Vec_IntForEachEntry( vTemp, Obj, k )
Vec_IntPushUnique( vFound, Obj );
}
}
Vec_IntFree( vUsed );
Vec_IntFree( vFound );
return vSets;
}
int Gia_ManMulFindOne( Gia_Man_t * p, Vec_Wec_t * vXors, Vec_Int_t * vSet, Vec_Int_t * vMap, Vec_Int_t * vA, Vec_Int_t * vB, int fVerbose )
{
Vec_Int_t * vObjs = Vec_IntAlloc( 100 ); int i, j, Obj, Obj1, Obj2;
Vec_IntForEachEntry( vSet, Obj, i )
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
Vec_IntForEachEntry( vObjs, Obj, i )
Vec_IntAddToEntry( vMap, Obj, 1 );
Vec_IntForEachEntry( vSet, Obj, i ) {
Vec_Int_t * vTemp = Vec_WecEntry(vXors, Obj); int k = 0;
Vec_IntForEachEntryDouble( vTemp, Obj1, Obj2, j )
if ( Vec_IntEntry(vMap, Obj1) > 1 || Vec_IntEntry(vMap, Obj2) > 1 )
Vec_IntWriteEntry(vTemp, k++, Obj1), Vec_IntWriteEntry(vTemp, k++, Obj2);
Vec_IntShrink( vTemp, k );
}
Vec_IntForEachEntry( vObjs, Obj, i )
Vec_IntWriteEntry( vMap, Obj, 0 );
Vec_IntClear( vObjs );
Vec_IntForEachEntry( vSet, Obj, i )
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
if ( Vec_IntSize(vObjs) == 0 ) {
Vec_IntFree(vObjs);
return 0;
}
Vec_IntClear( vA );
Vec_IntClear( vB );
Vec_IntPush( vA, Vec_IntPop(vObjs) );
Vec_IntPush( vB, Vec_IntPop(vObjs) );
while ( Vec_IntSize(vObjs) > 0 ) {
int k = 0;
Vec_IntForEachEntryDouble( vObjs, Obj1, Obj2, j ) {
if ( Vec_IntFind(vA, Obj1) >= 0 )
Vec_IntPushUnique(vB, Obj2);
else if ( Vec_IntFind(vA, Obj2) >= 0 )
Vec_IntPushUnique(vB, Obj1);
else if ( Vec_IntFind(vB, Obj1) >= 0 )
Vec_IntPushUnique(vA, Obj2);
else if ( Vec_IntFind(vB, Obj2) >= 0 )
Vec_IntPushUnique(vA, Obj1);
else {
Vec_IntWriteEntry(vObjs, k++, Obj1);
Vec_IntWriteEntry(vObjs, k++, Obj2);
}
}
Vec_IntShrink( vObjs, k );
}
Vec_IntSort( vA, 0 );
Vec_IntSort( vB, 0 );
Vec_IntClear( vObjs );
Vec_IntForEachEntry( vSet, Obj, i )
Vec_IntAppend( vObjs, Vec_WecEntry(vXors, Obj) );
Vec_IntForEachEntryDouble( vObjs, Obj1, Obj2, j )
if ( !((Vec_IntFind(vA, Obj1) >= 0 && Vec_IntFind(vB, Obj2) >= 0) ||
(Vec_IntFind(vA, Obj2) >= 0 && Vec_IntFind(vB, Obj1) >= 0)) ) {
if ( fVerbose )
printf( "Internal verification failed.\n" );
Vec_IntFree( vObjs );
Vec_IntClear( vA );
Vec_IntClear( vB );
return 0;
}
if ( fVerbose )
printf( "Generated system with %d+%d+%d=%d variables and %d equations.\n",
Vec_IntSize(vA),Vec_IntSize(vB),Vec_IntSize(vSet),
Vec_IntSize(vA)+Vec_IntSize(vB)+Vec_IntSize(vSet), Vec_IntSize(vObjs)/2 );
Vec_IntFree( vObjs );
return 1;
}
Vec_Wec_t * Gia_ManMulFindAInputs2( Gia_Man_t * p, int fVerbose )
{
Vec_Wec_t * vMuls = Vec_WecAlloc( 10 );
Vec_Wec_t * vXors = Gia_ManMulFindXors2( p );
Vec_Wec_t * vSets = Gia_ManMulFindSets( p, vXors );
Vec_Int_t * vMap = Vec_IntStart( Gia_ManObjNum(p) );
Vec_Int_t * vA = Vec_IntAlloc( 100 );
Vec_Int_t * vB = Vec_IntAlloc( 100 );
Vec_Int_t * vSet; int i;
Vec_WecForEachLevel( vSets, vSet, i )
{
if ( !Gia_ManMulFindOne(p, vXors, vSet, vMap, vA, vB, fVerbose) )
continue;
Vec_IntAppend( Vec_WecPushLevel(vMuls), vA );
Vec_IntAppend( Vec_WecPushLevel(vMuls), vB );
Vec_WecPushLevel(vMuls);
}
Vec_WecFree( vXors );
Vec_WecFree( vSets );
Vec_IntFree( vMap );
Vec_IntFree( vA );
Vec_IntFree( vB );
return vMuls;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManMulFindAddEntry1( Vec_Int_t * vPairs, int Obj )
{
int Entry, Sum, k;
Vec_IntForEachEntryDouble( vPairs, Entry, Sum, k )
if ( Obj == Entry ) {
Vec_IntAddToEntry( vPairs, k+1, 1 );
break;
}
if ( k == Vec_IntSize(vPairs) )
Vec_IntPushTwo( vPairs, Obj, 1 );
}
Vec_Int_t * Gia_ManMulFindCounts( Vec_Wec_t * vCuts4, Vec_Int_t * vSet )
{
Vec_Int_t * vCounts = Vec_IntAlloc( 10 );
int i, k, Obj, Item;
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
Vec_IntForEachEntryStart( vCut, Obj, k, 1 )
Gia_ManMulFindAddEntry1( vCounts, Obj );
}
return vCounts;
}
int Gia_ManMulFindNextEntry( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, int Entry )
{
int i, Item;
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
if ( Vec_IntSize(vCut) == 0 )
continue;
assert( Vec_IntSize(vCut) == 3 );
int RetValue = -1;
if ( Vec_IntEntry(vCut, 1) == Entry )
RetValue = Vec_IntEntry(vCut, 2);
if ( Vec_IntEntry(vCut, 2) == Entry )
RetValue = Vec_IntEntry(vCut, 1);
if ( RetValue == -1 )
continue;
Vec_IntClear( vCut );
return RetValue;
}
return -1;
}
void Gia_ManMulFindArg1( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, Vec_Int_t * vArg1 )
{
Vec_Int_t * vCounts = Gia_ManMulFindCounts( vCuts4, vSet );
int Entry = -1, Sum, k;
Vec_IntClear( vArg1 );
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
if ( Sum == 1 ) {
Vec_IntPush( vArg1, Entry );
break;
}
assert( Entry != -1 );
while ( (Entry = Gia_ManMulFindNextEntry(vCuts4, vSet, Entry)) != -1 )
Vec_IntPush( vArg1, Entry );
Vec_IntFree( vCounts );
}
int Gia_ManMulFindNextEntryCount( Vec_Int_t * vCounts, int Entry0 )
{
int Entry, Sum, k;
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
if ( Entry == Entry0 )
return Sum;
return -1;
}
int Gia_ManMulFindNextEntry2( Vec_Wec_t * vCuts4, Vec_Int_t * vSet, int Entry, Vec_Int_t * vCounts, int * pEntry0, int * pEntry1 )
{
int i, Item;
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
if ( Vec_IntSize(vCut) == 0 )
continue;
assert( Vec_IntSize(vCut) == 4 );
int Entry0, Entry1, iPlace = Vec_IntFind( vCut, Entry );
if ( iPlace == -1 )
continue;
if ( iPlace == 1 )
Entry0 = Vec_IntEntry(vCut, 2), Entry1 = Vec_IntEntry(vCut, 3);
else if ( iPlace == 2 )
Entry0 = Vec_IntEntry(vCut, 1), Entry1 = Vec_IntEntry(vCut, 3);
else if ( iPlace == 3 )
Entry0 = Vec_IntEntry(vCut, 1), Entry1 = Vec_IntEntry(vCut, 2);
else assert( 0 );
int Count0 = Gia_ManMulFindNextEntryCount(vCounts, Entry0);
int Count1 = Gia_ManMulFindNextEntryCount(vCounts, Entry1);
*pEntry0 = Count0 <= Count1 ? Entry0 : Entry1;
*pEntry1 = Count0 <= Count1 ? Entry1 : Entry0;
// remove entries
Vec_IntForEachEntry( vSet, Item, i ) {
Vec_Int_t * vCut = Vec_WecEntry(vCuts4, Item);
if ( Vec_IntSize(vCut) == 0 )
continue;
if ( Vec_IntFind( vCut, Entry ) >= 0 )
Vec_IntClear( vCut );
}
return 1;
}
return 0;
}
void Gia_ManMulFindArg2( Vec_Wec_t * vCuts5, Vec_Int_t * vSet, Vec_Int_t * vArg2, int Entry0, int Entry1 )
{
Vec_Int_t * vCounts = Gia_ManMulFindCounts( vCuts5, vSet );
int Entry, Sum, k, SumMin = ABC_INFINITY, SumMax = 0;
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k ) {
SumMin = Abc_MinInt( SumMin, Sum );
SumMax = Abc_MaxInt( SumMax, Sum );
}
Vec_IntClear( vArg2 );
Vec_IntForEachEntryDouble( vCounts, Entry, Sum, k )
if ( Entry == Entry0 || Entry == Entry1 ) {
Vec_IntPush( vArg2, Entry == Entry0 ? Entry1 : Entry0 );
Vec_IntPush( vArg2, Entry );
break;
}
Entry = Vec_IntEntry(vArg2, 1);
while ( Gia_ManMulFindNextEntry2(vCuts5, vSet, Entry, vCounts, &Entry0, &Entry1) )
Vec_IntPushTwo( vArg2, Entry0, Entry1 ), Entry = Entry1;
Vec_IntFree( vCounts );
}
void Gia_ManMulFindAddEntry( Vec_Int_t * vPairs, int Obj0, int Obj1 )
{
int Entry0, Entry1, Sum, k;
Vec_IntForEachEntryTriple( vPairs, Entry0, Entry1, Sum, k )
if ( Obj0 == Entry0 && Obj1 == Entry1 ) {
Vec_IntAddToEntry( vPairs, k+2, 1 );
break;
}
if ( k == Vec_IntSize(vPairs) )
Vec_IntPushThree( vPairs, Obj0, Obj1, 1 );
}
Vec_Wec_t * Gia_ManMulFindBInputs2( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
{
Vec_Wec_t * vRes = Vec_WecAlloc( 10 );
Vec_Int_t * vPairs = Vec_IntAlloc( 1000 );
Vec_Int_t * vSet = Vec_IntAlloc( 100 );
Vec_Int_t * vCut, * vArg1, * vArg2;
int i, j, k, n, Entry0, Entry1, Sum, Obj0, Obj1;
Vec_WecForEachLevel( vCuts4, vCut, i )
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
Vec_IntForEachEntryStart( vCut, Obj1, k, j+1 )
Gia_ManMulFindAddEntry( vPairs, Obj0, Obj1 );
Vec_IntForEachEntryTriple( vPairs, Entry0, Entry1, Sum, n ) {
if ( Sum < 3 )
continue;
Vec_IntClear( vSet );
Vec_WecForEachLevel( vCuts4, vCut, i )
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
Vec_IntForEachEntryStart( vCut, Obj1, k, j+1 )
if ( Obj0 == Entry0 && Obj1 == Entry1 ) {
Vec_IntPush( vSet, i );
Vec_IntDrop( vCut, k );
Vec_IntDrop( vCut, j );
j = k = Vec_IntSize(vCut);
}
vArg1 = Vec_WecPushLevel(vRes);
vArg2 = Vec_WecPushLevel(vRes);
Vec_WecPushLevel(vRes);
Gia_ManMulFindArg1( vCuts4, vSet, vArg1 );
// find overlapping with arg1 and remove nodes in arg1
Vec_IntClear( vSet );
Vec_WecForEachLevel( vCuts5, vCut, i )
if ( Gia_ManMulFindGetOverlap2(vCut, vArg1) ) {
k = 1;
Vec_IntForEachEntryStart( vCut, Obj0, j, 1 )
if ( Vec_IntFind(vArg1, Obj0) == -1 )
Vec_IntWriteEntry( vCut, k++, Obj0 );
Vec_IntShrink( vCut, k );
Vec_IntPush( vSet, i );
}
Gia_ManMulFindArg2( vCuts5, vSet, vArg2, Entry0, Entry1 );
}
Vec_IntFree( vSet );
Vec_IntFree( vPairs );
return vRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManMulFindOverlap( Vec_Int_t * p1, Vec_Int_t * p2 )
{
int i, k, ObjI, ObjK, Counter = 0;
Vec_IntForEachEntry( p1, ObjI, i )
Vec_IntForEachEntry( p2, ObjK, k )
if ( ObjI == ObjK )
Counter++;
return Counter;
}
void Gia_ManMulFindAssignGroup( Vec_Int_t * vTemp, int iGroup, Vec_Int_t * vMap )
{
int k, Obj;
Vec_IntForEachEntry( vTemp, Obj, k ) {
//assert( Vec_IntEntry(vMap, Obj) == -1 || Vec_IntEntry(vMap, Obj) == iGroup );
Vec_IntWriteEntry(vMap, Obj, iGroup);
}
Vec_IntPush( vTemp, iGroup );
}
Vec_Int_t * Gia_ManMulFindGroups( Vec_Wec_t * p, int nObjs, int fUseMap )
{
Vec_Int_t * vIndex = Vec_IntAlloc( 100 ), * vTemp;
Vec_Int_t * vMap = Vec_IntStartFull( nObjs ); int i, Counter, nGroups = 0;
Vec_Int_t * vUngrouped = Vec_IntStartNatural( Vec_WecSize(p) );
while ( Vec_IntSize(vUngrouped) ) {
int k, Obj, Item = Vec_IntPop(vUngrouped);
vTemp = Vec_WecEntry(p, Item);
Gia_ManMulFindAssignGroup( vTemp, nGroups, vMap );
int fChanges = 1;
while ( fChanges ) {
fChanges = 0;
Vec_IntForEachEntry( vUngrouped, Item, i ) {
vTemp = Vec_WecEntry(p, Item);
Counter = 0;
Vec_IntForEachEntry( vTemp, Obj, k )
if ( Vec_IntEntry(vMap, Obj) >= 0 )
Counter++;
if ( Counter < 1 )
continue;
Gia_ManMulFindAssignGroup( vTemp, nGroups, vMap );
Vec_IntDrop( vUngrouped, i-- );
fChanges = 1;
}
}
nGroups++;
}
Vec_IntFree( vUngrouped );
Vec_IntFree( vMap );
if ( fUseMap )
Vec_WecForEachLevel( p, vTemp, i )
Vec_IntPushTwo( vTemp, i, Vec_IntPop(vTemp) );
Vec_WecSortByLastInt( p, 0 );
Counter = 0;
Vec_IntPush( vIndex, 0 );
Vec_WecForEachLevel( p, vTemp, i )
if ( Vec_IntPop(vTemp) != Counter )
Vec_IntPush( vIndex, i ), Counter++;
Vec_IntPush( vIndex, Vec_WecSize(p) );
assert( Vec_WecSize(p) == 0 || Vec_IntSize(vIndex) == nGroups + 1 );
return vIndex;
}
Vec_Wec_t * Gia_ManMulFindXors( Gia_Man_t * p, Vec_Wec_t * vCuts3, int fVerbose )
{
Vec_Wec_t * vXors = Vec_WecAlloc( 10 );
Vec_Int_t * vIndex = Gia_ManMulFindGroups( vCuts3, Gia_ManObjNum(p), 0 );
Vec_Int_t * vAll = Vec_IntAlloc( 100 );
Vec_Bit_t * vSigs[2] = { Vec_BitStart(Gia_ManObjNum(p)), Vec_BitStart(Gia_ManObjNum(p)) };
Vec_Int_t * vTemp; int g, c, k, Obj, Start;
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
Vec_WecForEachLevelStartStop( vCuts3, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
Vec_IntForEachEntry( vTemp, Obj, k )
if ( !Vec_BitEntry(vSigs[k==0], Obj) ) {
Vec_BitWriteEntry( vSigs[k==0], Obj, 1 );
Vec_IntPush( vAll, Obj );
}
Vec_Int_t * vIns = Vec_WecPushLevel( vXors );
Vec_Int_t * vOuts = Vec_WecPushLevel( vXors );
Vec_IntForEachEntry( vAll, Obj, k ) {
if ( Vec_BitEntry(vSigs[0], Obj) && !Vec_BitEntry(vSigs[1], Obj) )
Vec_IntPush( vIns, Obj );
if ( !Vec_BitEntry(vSigs[0], Obj) && Vec_BitEntry(vSigs[1], Obj) )
Vec_IntPush( vOuts, Obj );
Vec_BitWriteEntry( vSigs[0], Obj, 0 );
Vec_BitWriteEntry( vSigs[1], Obj, 0 );
}
Vec_IntClear( vAll );
}
return vXors;
}
Vec_Int_t * Gia_ManFindMulDetectOrder( Vec_Wec_t * vAll, int iStart, int iStop )
{
Vec_Int_t * vOrder = Vec_IntAlloc( iStop - iStart );
Vec_Int_t * vUsed = Vec_IntStart( iStop ), * vTemp;
int i, nMatches = 0, iNext = -1;
Vec_WecForEachLevelStartStop( vAll, vTemp, i, iStart, iStop )
if ( Vec_IntSize(vTemp) == 2 )
nMatches++, iNext = i;
if ( nMatches == 1 ) {
while ( Vec_IntSize(vOrder) < iStop - iStart ) {
Vec_IntPush( vOrder, iNext );
Vec_IntWriteEntry( vUsed, iNext, 1 );
nMatches = 0;
Vec_WecForEachLevelStartStop( vAll, vTemp, i, iStart, iStop ) {
if ( Vec_IntEntry(vUsed, i) )
continue;
Vec_Int_t * vLast = Vec_WecEntry(vAll, Vec_IntEntryLast(vOrder));
if ( Gia_ManMulFindOverlap(vTemp, vLast) == Vec_IntSize(vLast) && Vec_IntSize(vTemp) == Vec_IntSize(vLast) + 2 )
nMatches++, iNext = i;
}
if ( nMatches != 1 )
break;
}
}
Vec_IntFree( vUsed );
if ( Vec_IntSize(vOrder) == 0 )
Vec_IntFreeP( &vOrder );
return vOrder;
}
Vec_Wec_t * Gia_ManMulFindAInputs( Gia_Man_t * p, Vec_Wec_t * vXors, int fVerbose )
{
Vec_Wec_t * vRes = Vec_WecAlloc( 10 );
Vec_Wec_t * vAll = Vec_WecAlloc( Vec_WecSize(vXors)/2 );
Gia_Obj_t * pObj; Vec_Int_t * vIns, * vOuts, * vTemp, * vIndex, * vOrder; int i, k, g, Start, Entry, Entry0, Entry1;
Gia_ManCreateRefs( p );
Vec_WecForEachLevelDouble( vXors, vIns, vOuts, i ) {
vTemp = Vec_WecPushLevel( vAll );
Gia_ManForEachObjVec( vIns, p, pObj, k )
if ( Gia_ObjIsAnd(pObj)
&& !Gia_ObjFaninC0(pObj) && Gia_ObjRefNum(p, Gia_ObjFanin0(pObj)) >= 4
&& !Gia_ObjFaninC1(pObj) && Gia_ObjRefNum(p, Gia_ObjFanin1(pObj)) >= 4 )
Vec_IntPushTwo( vTemp, Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninId1p(p, pObj) );
if ( Vec_IntSize(vTemp) == 0 )
Vec_WecShrink(vAll, Vec_WecSize(vAll)-1);
}
vIndex = Gia_ManMulFindGroups( vAll, Gia_ManObjNum(p), 0 );
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
vOrder = Gia_ManFindMulDetectOrder( vAll, Start, Vec_IntEntry(vIndex, g+1) );
if ( vOrder == NULL )
continue;
Vec_Int_t * vIn0 = Vec_WecPushLevel( vRes );
Vec_Int_t * vIn1 = Vec_WecPushLevel( vRes );
Vec_Int_t * vOut = Vec_WecPushLevel( vRes );
vTemp = Vec_WecEntry( vAll, Vec_IntEntry(vOrder, 0) );
assert( Vec_IntSize(vTemp) == 2 );
Vec_IntPush( vIn0, Vec_IntEntry(vTemp, 0) );
Vec_IntPush( vIn1, Vec_IntEntry(vTemp, 1) );
Vec_IntForEachEntryStart( vOrder, Entry, i, 1 ) {
vTemp = Vec_WecEntry( vAll, Entry );
Vec_IntForEachEntryDouble( vTemp, Entry0, Entry1, k ) {
if ( Vec_IntFind(vIn0, Entry0) >= 0 && Vec_IntFind(vIn1, Entry1) == -1 )
Vec_IntPush( vIn1, Entry1 );
else if ( Vec_IntFind(vIn0, Entry0) == -1 && Vec_IntFind(vIn1, Entry1) >= 0 )
Vec_IntPush( vIn0, Entry0 );
else
assert( (Vec_IntFind(vIn0, Entry0) >= 0 && Vec_IntFind(vIn1, Entry1) >= 0) ||
(Vec_IntFind(vIn0, Entry1) >= 0 && Vec_IntFind(vIn1, Entry0) >= 0) );
}
}
Vec_IntReverseOrder( vIn0 );
Vec_IntReverseOrder( vIn1 );
vOut = NULL;
}
Vec_IntFree( vIndex );
Vec_WecFree( vAll );
return vRes;
}
Vec_Wec_t * Gia_ManMulFindBInputs( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
{
Vec_Wec_t * vRes = Vec_WecAlloc( 10 ); Vec_Int_t * vTemp; int g, c, k, Obj, Start;
Vec_Int_t * vIndex = Gia_ManMulFindGroups( vCuts4, Gia_ManObjNum(p), 0 );
Vec_IntForEachEntryStop( vIndex, Start, g, Vec_IntSize(vIndex)-1 ) {
Vec_Int_t * vAll = Vec_IntAlloc ( 100 );
Vec_WecForEachLevelStartStop( vCuts4, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
Vec_IntPush( vAll, Obj );
Vec_IntUniqify( vAll );
int GroupSize = Vec_IntEntry(vIndex, g+1) - Start;
Vec_Int_t * vCnt = Vec_IntStart( Vec_IntSize(vAll) );
Vec_WecForEachLevelStartStop( vCuts4, vTemp, c, Start, Vec_IntEntry(vIndex, g+1) )
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
Vec_IntAddToEntry( vCnt, Vec_IntFind(vAll, Obj), 1 );
if ( Vec_IntCountEntry(vCnt, 1) != 2 || Vec_IntCountEntry(vCnt, 2) != GroupSize-1 || Vec_IntCountEntry(vCnt, GroupSize) != 2 ) {
printf( "Detection of group %d failed.\n", g );
continue;
}
Vec_Int_t * vIn1 = Vec_WecPushLevel( vRes );
Vec_Int_t * vIn2 = Vec_WecPushLevel( vRes );
Vec_Int_t * vOut = Vec_WecPushLevel( vRes );
Vec_IntForEachEntry( vAll, Obj, k )
if ( Vec_IntEntry(vCnt, k) <= 2 )
Vec_IntPush( vIn1, Obj );
else
Vec_IntPush( vIn2, Obj );
Vec_IntSort( vIn1, 0 );
Vec_IntSort( vIn2, 0 );
// TODO: check chain in[i] -> in[i+1]
Vec_WecForEachLevel( vCuts5, vTemp, c ) {
Vec_IntShift( vTemp, 1 );
if ( Gia_ManMulFindOverlap(vTemp, vIn1) >= 2 )
Vec_IntForEachEntryStart( vTemp, Obj, k, 1 )
if ( Vec_IntFind(vIn1, Obj) == -1 ) {
Vec_IntPushUnique(vIn2, Obj);
}
Vec_IntShift( vTemp, -1 );
}
Vec_IntSort( vIn2, 0 );
vOut = NULL;
}
Vec_IntFree( vIndex );
return vRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_ManMulFindTfo( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1, int fLits )
{
Vec_Int_t * vTfo = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj; int i, Obj;
Gia_ManIncrementTravId( p );
Vec_IntForEachEntry( vIn0, Obj, i )
Gia_ObjSetTravIdCurrentId( p, fLits ? Abc_Lit2Var(Obj) : Obj );
Vec_IntForEachEntry( vIn1, Obj, i )
Gia_ObjSetTravIdCurrentId( p, fLits ? Abc_Lit2Var(Obj) : Obj );
Gia_ManForEachAnd( p, pObj, i ) {
if ( Gia_ObjIsTravIdCurrentId(p, i) )
continue;
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) && Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vTfo, i );
}
return vTfo;
}
Vec_Wrd_t * Gia_ManMulFindSimCone( Gia_Man_t * p, Vec_Int_t * vIn0, Vec_Int_t * vIn1, Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, Vec_Int_t * vTfo, int fLits )
{
Vec_Wrd_t * vRes = Vec_WrdAlloc( Vec_IntSize(vTfo) );
Vec_Wrd_t * vSims = Vec_WrdStart( Gia_ManObjNum(p) );
Gia_Obj_t * pObj; int i, Obj;
Vec_IntForEachEntry( vIn0, Obj, i )
Vec_WrdWriteEntry( vSims, fLits ? Abc_Lit2Var(Obj) : Obj, (fLits && Abc_LitIsCompl(Obj)) ? ~Vec_WrdEntry(vSim0, i) : Vec_WrdEntry(vSim0, i) );
Vec_IntForEachEntry( vIn1, Obj, i )
Vec_WrdWriteEntry( vSims, fLits ? Abc_Lit2Var(Obj) : Obj, (fLits && Abc_LitIsCompl(Obj)) ? ~Vec_WrdEntry(vSim1, i) : Vec_WrdEntry(vSim1, i) );
Gia_ManForEachObjVec( vTfo, p, pObj, i ) {
word Sim0 = Vec_WrdEntry(vSims, Gia_ObjFaninId0p(p, pObj) );
word Sim1 = Vec_WrdEntry(vSims, Gia_ObjFaninId1p(p, pObj) );
Vec_WrdWriteEntry( vSims, Gia_ObjId(p, pObj), (Gia_ObjFaninC0(pObj) ? ~Sim0 : Sim0) & (Gia_ObjFaninC1(pObj) ? ~Sim1 : Sim1) );
}
Vec_IntForEachEntry( vTfo, Obj, i )
Vec_WrdPush( vRes, Vec_WrdEntry(vSims, Obj) );
Vec_WrdFree( vSims );
return vRes;
}
iword Gia_ManMulFindGetArg( Vec_Wrd_t * vSim, int i, int fSigned )
{
int w; iword Res = 0; word Word = 0;
Vec_WrdForEachEntry( vSim, Word, w )
if ( (Word >> i) & 1 )
Res |= ((iword)1 << w);
if ( fSigned && ((Word >> i) & 1) )
Res |= ~(iword)0 << Vec_WrdSize(vSim);
return Res;
}
void Gia_ManMulFindSetArg( Vec_Wrd_t * vSim, int i, iword iNum )
{
int w; word * pWords = Vec_WrdArray(vSim);
for ( w = 0; w < Vec_WrdSize(vSim); w++ )
if ( (iNum >> w) & 1 )
pWords[w] |= (word)1 << i;
}
Vec_Wrd_t * Gia_ManMulFindSim( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned )
{
assert( Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) <= 62 );
Vec_Wrd_t * vRes = Vec_WrdStart( Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) );
for ( int i = 0; i < 64; i++ )
{
iword a = Gia_ManMulFindGetArg( vSim0, i, fSigned );
iword b = Gia_ManMulFindGetArg( vSim1, i, fSigned );
Gia_ManMulFindSetArg( vRes, i, a * b );
}
return vRes;
}
Vec_Wrd_t * Gia_ManMulFindSim2( Vec_Wrd_t * vSim0, Vec_Wrd_t * vSim1, int fSigned )
{
extern word * product_many(word *pInfo1, int nBits1, word *pInfo2, int nBits2, int fSigned );
word * pRes = product_many( Vec_WrdArray(vSim0), Vec_WrdSize(vSim0), Vec_WrdArray(vSim1), Vec_WrdSize(vSim1), fSigned );
return Vec_WrdAllocArray( pRes, Vec_WrdSize(vSim0) + Vec_WrdSize(vSim1) );
}
int Gia_ManMulFindOutputs( Gia_Man_t * p, Vec_Wec_t * vTerms, int fLits, int fVerbose )
{
//abctime clkTotal = Abc_Clock();
int nDetected = 0;
Abc_Random(1);
for ( int m = 0; m < Vec_WecSize(vTerms)/3; m++ ) {
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
Vec_Wrd_t * vSim0 = Vec_WrdStartRandom( Vec_IntSize(vIn0) );
Vec_Wrd_t * vSim1 = Vec_WrdStartRandom( Vec_IntSize(vIn1) );
Vec_Wrd_t * vSimU = Gia_ManMulFindSim2( vSim0, vSim1, 0 );
Vec_Wrd_t * vSimS = Gia_ManMulFindSim2( vSim0, vSim1, 1 );
Vec_Int_t * vTfo = Gia_ManMulFindTfo( p, vIn0, vIn1, fLits );
Vec_Wrd_t * vSims = Gia_ManMulFindSimCone( p, vIn0, vIn1, vSim0, vSim1, vTfo, fLits );
Vec_Int_t * vOutU = Vec_IntAlloc( 100 );
Vec_Int_t * vOutS = Vec_IntAlloc( 100 );
word Word; int w, iPlace;
Vec_WrdForEachEntry( vSimU, Word, w ) {
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
Vec_IntPush( vOutU, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
Vec_IntPush( vOutU, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
else
Vec_IntPush( vOutU, -1 );
}
Vec_WrdForEachEntry( vSimS, Word, w ) {
if ( (iPlace = Vec_WrdFind(vSims, Word)) >= 0 )
Vec_IntPush( vOutS, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 0) );
else if ( (iPlace = Vec_WrdFind(vSims, ~Word)) >= 0 )
Vec_IntPush( vOutS, Abc_Var2Lit(Vec_IntEntry(vTfo, iPlace), 1) );
else
Vec_IntPush( vOutS, -1 );
}
assert( Vec_IntSize(vOut) == 0 );
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntSize(vOutU) ||
Vec_IntCountEntry(vOutS, -1) < Vec_IntSize(vOutS) )
{
if ( Vec_IntCountEntry(vOutU, -1) < Vec_IntCountEntry(vOutS, -1) ) {
Vec_IntAppend( vOut, vOutU ), Vec_IntPush(vOut, 0);
nDetected = Vec_IntSize(vOutU) - Vec_IntCountEntry(vOutU, -1);
}
else {
Vec_IntAppend( vOut, vOutS ), Vec_IntPush(vOut, 1);
nDetected = Vec_IntSize(vOutS) - Vec_IntCountEntry(vOutS, -1);
}
}
else
{
Vec_IntClear(vIn0);
Vec_IntClear(vIn1);
}
Vec_WrdFree( vSim0 );
Vec_WrdFree( vSim1 );
Vec_WrdFree( vSimU );
Vec_WrdFree( vSimS );
Vec_WrdFree( vSims );
Vec_IntFree( vTfo );
Vec_IntFree( vOutU );
Vec_IntFree( vOutS );
}
Vec_WecRemoveEmpty( vTerms );
//Abc_PrintTime( 1, "Output detection time", Abc_Clock() - clkTotal );
return nDetected;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Gia_ManMulFindCuts( Gia_Man_t * p, int nCutNum, int fVerbose )
{
extern Vec_Mem_t * Dau_CollectNpnFunctions( word * p, int nVars, int fVerbose );
extern Vec_Ptr_t * Gia_ManMatchCutsArray( Vec_Ptr_t * vTtMems, Gia_Man_t * pGia, int nCutSize, int nCutNum, int fVerbose );
word pTruths[3] = { ABC_CONST(0x6969696969696969), ABC_CONST(0x35C035C035C035C0), ABC_CONST(0xF335ACC0F335ACC0) };
Vec_Ptr_t * vTtMems = Vec_PtrAlloc( 3 ); Vec_Mem_t * vTtMem; int i;
for ( i = 0; i < 3; i++ )
Vec_PtrPush( vTtMems, Dau_CollectNpnFunctions( pTruths+i, i+3, fVerbose ) );
Vec_Ptr_t * vAll = Gia_ManMatchCutsArray( vTtMems, p, 5, nCutNum, fVerbose );
Vec_PtrForEachEntry( Vec_Mem_t *, vTtMems, vTtMem, i )
Vec_MemHashFree( vTtMem ), Vec_MemFree( vTtMem );
Vec_PtrFree( vTtMems );
return vAll;
}
Vec_Wec_t * Gia_ManMulFindA( Gia_Man_t * p, Vec_Wec_t * vCuts3, int fVerbose )
{
Vec_Wec_t * vXors = Gia_ManMulFindXors( p, vCuts3, fVerbose );
Vec_Wec_t * vTerms = Gia_ManMulFindAInputs2( p, fVerbose );
if ( Vec_WecSize(vTerms) )
Gia_ManMulFindOutputs( p, vTerms, 0, fVerbose );
Vec_WecFree( vXors );
return vTerms;
}
Vec_Wec_t * Gia_ManMulFindB( Gia_Man_t * p, Vec_Wec_t * vCuts4, Vec_Wec_t * vCuts5, int fVerbose )
{
Vec_Wec_t * vTerms = Vec_WecAlloc( 12 );
if ( Vec_WecSize(vCuts4) && Vec_WecSize(vCuts5) )
vTerms = Gia_ManMulFindBInputs2( p, vCuts4, vCuts5, fVerbose );
if ( Vec_WecSize(vTerms) )
Gia_ManMulFindOutputs( p, vTerms, 0, fVerbose );
return vTerms;
}
void Gia_ManMulFindPrintSet( Vec_Int_t * vSet, int fLit, int fSkipLast )
{
int i, Temp, Limit = Vec_IntSize(vSet) - fSkipLast;
printf( "{" );
if ( Vec_IntSize(vSet) > 16 ) {
Vec_IntForEachEntryStop( vSet, Temp, i, 4 ) {
if ( Temp == -1 )
printf( "n/a%s", i < Limit-1 ? " ":"" );
else
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
}
printf( "... " );
Vec_IntForEachEntryStartStop( vSet, Temp, i, Limit-4, Limit ) {
if ( Temp == -1 )
printf( "n/a%s", i < Limit-1 ? " ":"" );
else
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
}
}
else {
Vec_IntForEachEntryStop( vSet, Temp, i, Limit ) {
if ( Temp == -1 )
printf( "n/a%s", i < Limit-1 ? " ":"" );
else
printf( "%s%d%s", (fLit & Abc_LitIsCompl(Temp)) ? "~":"", fLit ? Abc_Lit2Var(Temp) : Temp, i < Limit-1 ? " ":"" );
}
}
printf( "}" );
}
void Gia_ManMulFindPrintOne( Vec_Wec_t * vTerms, int m, int fBooth, int fInputLits )
{
Vec_Int_t * vIn0 = Vec_WecEntry(vTerms, 3*m+0);
Vec_Int_t * vIn1 = Vec_WecEntry(vTerms, 3*m+1);
Vec_Int_t * vOut = Vec_WecEntry(vTerms, 3*m+2);
printf( "%sooth %s%ssigned %d x %d: ",
fBooth==1 ? "B" : "Non-b",
fBooth>=1 ? "radix-4 " : "",
Vec_IntEntryLast(vOut) ? "" : "un",
Vec_IntSize(vIn0), Vec_IntSize(vIn1) );
Gia_ManMulFindPrintSet( vIn0, fInputLits, 0 );
printf( " * " );
Gia_ManMulFindPrintSet( vIn1, fInputLits, 0 );
printf( " = " );
Gia_ManMulFindPrintSet( vOut, 1, 1 );
printf( "\n" );
}
void Gia_ManMulFind( Gia_Man_t * p, int nCutNum, int fVerbose )
{
Vec_Ptr_t * vAll = Gia_ManMulFindCuts( p, nCutNum, fVerbose ); int m;
Vec_Wec_t * vCuts3 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 0);
Vec_Wec_t * vCuts4 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 1);
Vec_Wec_t * vCuts5 = (Vec_Wec_t *)Vec_PtrEntry(vAll, 2);
Vec_Wec_t * vTermsB = Gia_ManMulFindB( p, vCuts4, vCuts5, fVerbose );
Vec_Wec_t * vTermsA = Gia_ManMulFindA( p, vCuts3, fVerbose );
printf( "Detected %d booth and %d non-booth multipliers.\n", Vec_WecSize(vTermsB)/3, Vec_WecSize(vTermsA)/3 );
for ( m = 0; m < Vec_WecSize(vTermsA)/3; m++ )
Gia_ManMulFindPrintOne( vTermsA, m, 0, 0 );
for ( m = 0; m < Vec_WecSize(vTermsB)/3; m++ )
Gia_ManMulFindPrintOne( vTermsB, m, 1, 0 );
Vec_WecFree( vTermsB );
Vec_WecFree( vTermsA );
Vec_WecFree( vCuts3 );
Vec_WecFree( vCuts4 );
Vec_WecFree( vCuts5 );
Vec_PtrFree( vAll );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -1,27 +1,32 @@
/**CFile****************************************************************
FileName [cba.c]
FileName [giaMulFind3.c]
SystemName [ABC: Logic synthesis and verification system.]
PackageName [Hierarchical word-level netlist.]
PackageName [Scalable AIG package.]
Synopsis []
Synopsis [Multiplier detection.]
Author [Alan Mishchenko]
Affiliation [UC Berkeley]
Date [Ver. 1.0. Started - July 21, 2015.]
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: cba.c,v 1.00 2014/11/29 00:00:00 alanmi Exp $]
Revision [$Id: giaMulFind3.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "cba.h"
#include <math.h>
#include "gia.h"
#include "misc/vec/vecHsh.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
@ -30,23 +35,14 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManMulFindNew( Gia_Man_t * p, int nABits, int nFanLim, int fLits, int fVerbose )
{
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -21,6 +21,7 @@
#ifndef ABC__aig__gia__giaNewBdd_h
#define ABC__aig__gia__giaNewBdd_h
#include <cstdlib>
#include <limits>
#include <vector>
#include <iostream>
@ -47,6 +48,11 @@ namespace NewBdd {
static inline uniq UniqHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
static inline cac CacHash(lit Arg0, lit Arg1) { return Arg0 + 4256249 * Arg1; }
static inline void fatal_error(const char* message) {
std::cerr << message << std::endl;
std::abort();
}
class Cache {
private:
cac nSize;
@ -62,10 +68,10 @@ namespace NewBdd {
public:
Cache(int nCacheSizeLog, int nCacheMaxLog, int nVerbose): nVerbose(nVerbose) {
if(nCacheMaxLog < nCacheSizeLog)
throw std::invalid_argument("nCacheMax must not be smaller than nCacheSize");
fatal_error("nCacheMax must not be smaller than nCacheSize");
nMax = (cac)1 << nCacheMaxLog;
if(!(nMax << 1))
throw std::length_error("Memout (nCacheMax) in init");
fatal_error("Memout (nCacheMax) in init");
nSize = (cac)1 << nCacheSizeLog;
if(nVerbose)
std::cout << "Allocating " << nSize << " cache entries" << std::endl;
@ -242,7 +248,7 @@ namespace NewBdd {
inline ref Ref(lit x) const { return vRefs[Lit2Bvar(x)]; }
inline double OneCount(lit x) const {
if(vOneCounts.empty())
throw std::logic_error("fCountOnes was not set");
fatal_error("fCountOnes was not set");
if(LitIsCompl(x))
return std::pow(2.0, nVars) - vOneCounts[Lit2Bvar(x)];
return vOneCounts[Lit2Bvar(x)];
@ -454,7 +460,7 @@ namespace NewBdd {
if(nGbc > 1)
fRemoved = Gbc();
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
throw std::length_error("Memout (node)");
fatal_error("Memout (node)");
} else
break;
}
@ -659,29 +665,29 @@ namespace NewBdd {
nVerbose = p.nVerbose;
// parameter sanity check
if(p.nObjsMaxLog < p.nObjsAllocLog)
throw std::invalid_argument("nObjsMax must not be smaller than nObjsAlloc");
fatal_error("nObjsMax must not be smaller than nObjsAlloc");
if(nVars_ >= (int)VarMax())
throw std::length_error("Memout (nVars) in init");
fatal_error("Memout (nVars) in init");
nVars = nVars_;
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
if(!nObjsMaxLit)
throw std::length_error("Memout (nObjsMax) in init");
fatal_error("Memout (nObjsMax) in init");
if(nObjsMaxLit > (lit)BvarMax())
nObjsMax = BvarMax();
else
nObjsMax = (bvar)nObjsMaxLit;
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
if(!nObjsAllocLit)
throw std::length_error("Memout (nObjsAlloc) in init");
fatal_error("Memout (nObjsAlloc) in init");
if(nObjsAllocLit > (lit)BvarMax())
nObjsAlloc = BvarMax();
else
nObjsAlloc = (bvar)nObjsAllocLit;
if(nObjsAlloc <= (bvar)nVars)
throw std::invalid_argument("nObjsAlloc must be larger than nVars");
fatal_error("nObjsAlloc must be larger than nVars");
uniq nUniqueSize = (uniq)1 << p.nUniqueSizeLog;
if(!nUniqueSize)
throw std::length_error("Memout (nUniqueSize) in init");
fatal_error("Memout (nUniqueSize) in init");
// allocation
if(nVerbose)
std::cout << "Allocating " << nObjsAlloc << " nodes and " << nVars << " x " << nUniqueSize << " unique table entries" << std::endl;
@ -703,7 +709,7 @@ namespace NewBdd {
}
if(p.fCountOnes) {
if(nVars > 1023)
throw std::length_error("nVars must be less than 1024 to count ones");
fatal_error("nVars must be less than 1024 to count ones");
vOneCounts.resize(nObjsAlloc);
}
// set up cache
@ -780,10 +786,34 @@ namespace NewBdd {
for(size_t i = 0; i < vLits.size(); i++)
IncRef(vLits[i]);
}
void RemoveRefIfUnused() {
if(!nGbc && nReo == BvarMax())
vRefs.clear();
}
void TurnOnReo(int nReo_ = 0, std::vector<lit> const *vLits = NULL) {
if(nReo_)
nReo = nReo_;
else
nReo = nObjs << 1;
if((lit)nReo > (lit)BvarMax())
nReo = BvarMax();
if(vRefs.empty()) {
if(vLits)
SetRef(*vLits);
else
vRefs.resize(nObjsAlloc);
}
}
void TurnOffReo() {
nReo = BvarMax();
if(!nGbc)
vRefs.clear();
}
var GetNumVars() const {
return nVars;
}
void GetOrdering(std::vector<int> &Var2Level_) {
Var2Level_.resize(nVars);
for(var v = 0; v < nVars; v++)
Var2Level_[v] = Var2Level[v];
}
bvar CountNodes() {
bvar count = 1;

View File

@ -21,6 +21,7 @@
#ifndef ABC__aig__gia__giaNewTt_h
#define ABC__aig__gia__giaNewTt_h
#include <cstdlib>
#include <limits>
#include <iomanip>
#include <iostream>
@ -41,6 +42,11 @@ namespace NewTt {
static inline ref RefMax() { return std::numeric_limits<ref>::max(); }
static inline size SizeMax() { return std::numeric_limits<size>::max(); }
static void fatal_error(const char* message) {
std::cerr << message << std::endl;
std::abort();
}
struct Param {
int nObjsAllocLog;
int nObjsMaxLog;
@ -48,6 +54,7 @@ namespace NewTt {
bool fCountOnes;
int nGbc;
int nReo; // dummy
std::vector<int> *pVar2Level; // dummy
Param() {
nObjsAllocLog = 15;
nObjsMaxLog = 20;
@ -181,35 +188,35 @@ namespace NewTt {
public:
Man(int nVars, Param p): nVars(nVars) {
if(p.nObjsMaxLog < p.nObjsAllocLog)
throw std::invalid_argument("nObjsMax must not be smaller than nObjsAlloc");
fatal_error("nObjsMax must not be smaller than nObjsAlloc");
if(nVars >= lww())
nSize = 1ull << (nVars - lww());
else
nSize = 1;
if(!nSize)
throw std::length_error("Memout (nVars) in init");
fatal_error("Memout (nVars) in init");
if(!(nSize << p.nObjsMaxLog))
throw std::length_error("Memout (nObjsMax) in init");
fatal_error("Memout (nObjsMax) in init");
lit nObjsMaxLit = (lit)1 << p.nObjsMaxLog;
if(!nObjsMaxLit)
throw std::length_error("Memout (nObjsMax) in init");
fatal_error("Memout (nObjsMax) in init");
if(nObjsMaxLit > (lit)BvarMax())
nObjsMax = BvarMax();
else
nObjsMax = (bvar)nObjsMaxLit;
lit nObjsAllocLit = (lit)1 << p.nObjsAllocLog;
if(!nObjsAllocLit)
throw std::length_error("Memout (nObjsAlloc) in init");
fatal_error("Memout (nObjsAlloc) in init");
if(nObjsAllocLit > (lit)BvarMax())
nObjsAlloc = BvarMax();
else
nObjsAlloc = (bvar)nObjsAllocLit;
if(nObjsAlloc <= (bvar)nVars)
throw std::invalid_argument("nObjsAlloc must be larger than nVars");
fatal_error("nObjsAlloc must be larger than nVars");
nTotalSize = nSize << p.nObjsAllocLog;
vVals.resize(nTotalSize);
if(p.fCountOnes && nVars > 63)
throw std::length_error("nVars must be less than 64 to count ones");
fatal_error("nVars must be less than 64 to count ones");
nObjs = 1;
for(int i = 0; i < 6 && i < nVars; i++) {
for(size j = 0; j < nSize; j++)
@ -238,7 +245,7 @@ namespace NewTt {
if(nGbc > 1)
fRemoved = Gbc();
if(!Resize() && !fRemoved && (nGbc != 1 || !Gbc()))
throw std::length_error("Memout (node)");
fatal_error("Memout (node)");
}
bvar zvar;
if(nObjs < nObjsAlloc)
@ -261,10 +268,14 @@ namespace NewTt {
for(size_t i = 0; i < vLits.size(); i++)
IncRef(vLits[i]);
}
void TurnOffReo() {
void RemoveRefIfUnused() {
if(!nGbc)
vRefs.clear();
}
void TurnOffReo() {}
int GetNumVars() const {
return nVars;
}
void PrintNode(lit x) const {
bvar a = Lit2Bvar(x);
word c = LitIsCompl(x)? one(): 0;

View File

@ -30,6 +30,12 @@
#include "opt/dau/dau.h"
#include "misc/util/utilNam.h"
#include "map/scl/sclCon.h"
#include "misc/tim/tim.h"
#ifdef _MSC_VER
# include <intrin.h>
# define __builtin_popcount __popcnt
#endif
ABC_NAMESPACE_IMPL_START
@ -82,6 +88,7 @@ struct Nf_Man_t_
{
// user data
Gia_Man_t * pGia; // derived manager
Tim_Man_t * pManTim; // timing manager
Jf_Par_t * pPars; // parameters
// matching
Vec_Mem_t * vTtMem; // truth tables
@ -223,7 +230,7 @@ void Nf_StoCreateGateAdd( Vec_Mem_t * vTtMem, Vec_Wec_t * vTt2Match, Mio_Cell2_t
if ( fPinQuick ) // reduce the number of matches agressively
{
Vec_IntForEachEntryDouble( vArray, GateId, Entry, i )
if ( GateId == (int)pCell->Id && Abc_TtBitCount8[Nf_Int2Cfg(Entry).Phase] == Abc_TtBitCount8[Mat.Phase] )
if ( GateId == (int)pCell->Id && __builtin_popcount( Nf_Int2Cfg(Entry).Phase & 0xff ) == __builtin_popcount( Mat.Phase & 0xff ) )
return;
}
else // reduce the number of matches less agressively
@ -379,6 +386,7 @@ Nf_Man_t * Nf_StoCreate( Gia_Man_t * pGia, Jf_Par_t * pPars )
p = ABC_CALLOC( Nf_Man_t, 1 );
p->clkStart = Abc_Clock();
p->pGia = pGia;
p->pManTim = (Tim_Man_t *)pGia->pManTime;
p->pPars = pPars;
p->pNfObjs = ABC_CALLOC( Nf_Obj_t, Gia_ManObjNum(pGia) );
p->iCur = 2;
@ -956,21 +964,42 @@ void Nf_ObjMergeOrder( Nf_Man_t * p, int iObj )
}
void Nf_ManComputeCuts( Nf_Man_t * p )
{
Gia_Obj_t * pObj; int i, iFanin;
Gia_ManForEachAnd( p->pGia, pObj, i )
Gia_Obj_t * pObj; int i, iFanin, arrTime;
float CutFlow = 0, CutFlowAve = 0; int fFirstCi = 0, nCutFlow = 0;
if ( p->pManTim )
Tim_ManIncrementTravId( p->pManTim );
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
if ( Gia_ObjIsBuf(pObj) )
{
iFanin = Gia_ObjFaninId0(pObj, i);
Nf_ObjSetCutFlow( p, i, Nf_ObjCutFlow(p, iFanin) );
Nf_ObjSetCutDelay( p, i, Nf_ObjCutDelay(p, iFanin) );
}
else
else if ( Gia_ObjIsAnd(pObj) )
Nf_ObjMergeOrder( p, i );
else if ( Gia_ObjIsCi(pObj) )
{
if ( fFirstCi ) {
CutFlowAve = CutFlow / nCutFlow;
CutFlow = 0;
nCutFlow = 0;
fFirstCi = 0;
}
arrTime = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
Nf_ObjSetCutFlow( p, i, CutFlowAve ); // approximation!
Nf_ObjSetCutDelay( p, i, arrTime );
}
else if ( Gia_ObjIsCo(pObj) )
{
iFanin = Gia_ObjFaninId0(pObj, i);
CutFlow += Nf_ObjCutFlow(p, iFanin);
arrTime = Nf_ObjCutDelay(p, iFanin);
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), arrTime );
nCutFlow++;
fFirstCi = 1;
}
}
/**Function*************************************************************
Synopsis []
@ -1143,7 +1172,10 @@ void Nf_ManCutMatchOne( Nf_Man_t * p, int iObj, int * pCut, int * pCutSet )
if ( ArrivalA + pC->iDelays[k] <= Required && Required != SCL_INFINITY )
{
Delay = Abc_MaxInt( Delay, ArrivalA + pC->iDelays[k] );
AreaF += pBestF[iFanin]->M[fComplF][1].F;
if ( AreaF >= (float)1e32 || pBestF[iFanin]->M[fComplF][1].F >= (float)1e32 )
AreaF = (float)1e32;
else
AreaF += pBestF[iFanin]->M[fComplF][1].F;
}
else
{
@ -1382,14 +1414,36 @@ void Nf_ManCutMatch( Nf_Man_t * p, int iObj )
}
*/
}
static inline Nf_Mat_t * Nf_ObjMatchBest( Nf_Man_t * p, int i, int c )
{
Nf_Mat_t * pD = Nf_ObjMatchD(p, i, c);
Nf_Mat_t * pA = Nf_ObjMatchA(p, i, c);
assert( pD->fBest != pA->fBest );
//assert( Nf_ObjMapRefNum(p, i, c) > 0 );
if ( pA->fBest )
return pA;
if ( pD->fBest )
return pD;
return NULL;
}
void Nf_ManComputeMapping( Nf_Man_t * p )
{
Gia_Obj_t * pObj; int i;
Gia_ManForEachAnd( p->pGia, pObj, i )
Gia_Obj_t * pObj; int i, arrTime;
if ( p->pManTim )
Tim_ManIncrementTravId( p->pManTim );
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
if ( Gia_ObjIsBuf(pObj) )
Nf_ObjPrepareBuf( p, pObj );
else
else if ( Gia_ObjIsAnd(pObj) )
Nf_ManCutMatch( p, i );
else if ( Gia_ObjIsCi(pObj) ) {
arrTime = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
Nf_ObjPrepareCi( p, i, arrTime );
}
else if ( Gia_ObjIsCo(pObj) ) {
arrTime = Nf_ObjMatchD( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj) )->D;
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), arrTime );
}
}
@ -1404,18 +1458,6 @@ void Nf_ManComputeMapping( Nf_Man_t * p )
SeeAlso []
***********************************************************************/
static inline Nf_Mat_t * Nf_ObjMatchBest( Nf_Man_t * p, int i, int c )
{
Nf_Mat_t * pD = Nf_ObjMatchD(p, i, c);
Nf_Mat_t * pA = Nf_ObjMatchA(p, i, c);
assert( pD->fBest != pA->fBest );
//assert( Nf_ObjMapRefNum(p, i, c) > 0 );
if ( pA->fBest )
return pA;
if ( pD->fBest )
return pD;
return NULL;
}
void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
{
Gia_Obj_t * pObj;
@ -1425,7 +1467,7 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
Vec_IntFill( &p->vRequired, nLits, SCL_INFINITY );
// compute delay
p->pPars->MapDelay = 0;
Gia_ManForEachCo( p->pGia, pObj, i )
Gia_ManForEachCoWithBoxes( p->pGia, pObj, i )
{
Required = Nf_ObjMatchD( p, Gia_ObjFaninId0p(p->pGia, pObj), Gia_ObjFaninC0(pObj) )->D;
p->pPars->MapDelay = Abc_MaxInt( p->pPars->MapDelay, Required );
@ -1445,7 +1487,9 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
}
//assert( p->pPars->MapDelayTarget == 0 );
// set required times
Gia_ManForEachCo( p->pGia, pObj, i )
if ( p->pManTim )
Tim_ManIncrementTravId( p->pManTim );
Gia_ManForEachCoWithBoxes( p->pGia, pObj, i )
{
iObj = Gia_ObjFaninId0p(p->pGia, pObj);
fCompl = Gia_ObjFaninC0(pObj);
@ -1470,6 +1514,13 @@ void Nf_ManSetOutputRequireds( Nf_Man_t * p, int fPropCompl )
Nf_ObjUpdateRequired( p, iObj, fCompl, Required );
if ( fPropCompl && iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
Nf_ObjUpdateRequired( p, iObj, !fCompl, Required - p->InvDelayI );
if ( p->pManTim == NULL )
continue;
if ( fPropCompl && iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
Tim_ManSetCoRequired( p->pManTim, Gia_ObjCioId(pObj), Required - p->InvDelayI );
else
Tim_ManSetCoRequired( p->pManTim, Gia_ObjCioId(pObj), Required );
//Nf_ObjMapRefInc( p, Gia_ObjFaninId0p(p->pGia, pObj), Gia_ObjFaninC0(pObj));
}
}
@ -1523,7 +1574,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
float * pFlowRefs = Vec_FltArray( &p->vFlowRefs );
int * pMapRefs = Vec_IntArray( &p->vMapRefs );
int nLits = 2*Gia_ManObjNum(p->pGia);
int i, c, Id, nRefs[2];
int i, c, Id, nRefs[2], reqTime;
Gia_Obj_t * pObj;
Nf_Mat_t * pD, * pA, * pM;
Nf_Mat_t * pDs[2], * pAs[2], * pMs[2];
@ -1541,7 +1592,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
p->nInvs = 0;
p->pPars->MapAreaF = 0;
p->pPars->Area = p->pPars->Edge = 0;
Gia_ManForEachAndReverse( p->pGia, pObj, i )
Gia_ManForEachObjReverseWithBoxes( p->pGia, pObj, i )
{
if ( Gia_ObjIsBuf(pObj) )
{
@ -1558,6 +1609,27 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
Nf_ObjMapRefInc( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj));
continue;
}
if ( Gia_ObjIsCi(pObj) )
{
if ( Nf_ObjMapRefNum(p, i, 1) )
{
Nf_ObjMapRefInc( p, i, 0 );
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
p->pPars->MapAreaF += p->InvAreaF;
p->pPars->Edge++;
p->pPars->Area++;
p->nInvs++;
}
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), Nf_ObjRequired(p, i, 0) );
continue;
}
if ( Gia_ObjIsCo(pObj) )
{
reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), reqTime );
Nf_ObjMapRefInc( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj));
continue;
}
// skip if this node is not used
for ( c = 0; c < 2; c++ )
nRefs[c] = Nf_ObjMapRefNum(p, i, c);
@ -1660,7 +1732,7 @@ int Nf_ManSetMapRefs( Nf_Man_t * p )
// - required times are propagated correctly
// - references are set correctly
}
Gia_ManForEachCiId( p->pGia, Id, i )
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
if ( Nf_ObjMapRefNum(p, Id, 1) )
{
Nf_ObjMapRefInc( p, Id, 0 );
@ -1860,7 +1932,9 @@ void Nf_ManResetMatches( Nf_Man_t * p, int Round )
Nf_Mat_t * pDc, * pAc, * pMfan, * pM[2];
int i, c, Arrival;
// go through matches in the topo order
Gia_ManForEachAnd( p->pGia, pObj, i )
if ( p->pManTim )
Tim_ManIncrementTravId( p->pManTim );
Gia_ManForEachObjWithBoxes( p->pGia, pObj, i )
{
if ( Gia_ObjIsBuf(pObj) )
{
@ -1877,6 +1951,18 @@ void Nf_ManResetMatches( Nf_Man_t * p, int Round )
}
continue;
}
if ( Gia_ObjIsCi(pObj) )
{
Arrival = Tim_ManGetCiArrival( p->pManTim, Gia_ObjCioId(pObj) );
Nf_ObjPrepareCi( p, i, Arrival );
continue;
}
if ( Gia_ObjIsCo(pObj) )
{
Arrival = Nf_ObjMatchD( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj) )->D;
Tim_ManSetCoArrival( p->pManTim, Gia_ObjCioId(pObj), Arrival );
continue;
}
// select the best match for each phase
for ( c = 0; c < 2; c++ )
{
@ -1949,19 +2035,40 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
Mio_Cell2_t * pCell;
Nf_Mat_t Mb, * pMb = &Mb, * pM;
word AreaBef, AreaAft, Gain = 0;
int i, c, iVar, Id, fCompl, k, * pCut;
int Required;
Nf_ManSetOutputRequireds( p, 1 );
int i, c, iVar, Id, fCompl, k, * pCut, Required;
Nf_ManResetMatches( p, p->Iter - p->pPars->nRounds );
Gia_ManForEachAndReverse( p->pGia, pObj, i )
Nf_ManSetOutputRequireds( p, 1 );
Gia_ManForEachObjReverseWithBoxes( p->pGia, pObj, i )
{
if ( Gia_ObjIsBuf(pObj) )
{
if ( Nf_ObjMapRefNum(p, i, 1) )
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
Nf_ObjUpdateRequired( p, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninC0(pObj), Nf_ObjRequired(p, i, 0) );
int reqTime = Nf_ObjRequired(p, i, 0);
int iObj = Gia_ObjFaninId0p(p->pGia, pObj);
int fCompl = Gia_ObjFaninC0(pObj);
Nf_ObjUpdateRequired( p, iObj, fCompl, reqTime );
if ( iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
Nf_ObjUpdateRequired( p, iObj, !fCompl, reqTime - p->InvDelayI );
continue;
}
if ( Gia_ObjIsCi(pObj) )
{
if ( Nf_ObjMapRefNum(p, i, 1) )
Nf_ObjUpdateRequired( p, i, 0, Nf_ObjRequired(p, i, 1) - p->InvDelayI );
Tim_ManSetCiRequired( p->pManTim, Gia_ObjCioId(pObj), Nf_ObjRequired(p, i, 0) );
continue;
}
if ( Gia_ObjIsCo(pObj) )
{
int reqTime = Tim_ManGetCoRequired( p->pManTim, Gia_ObjCioId(pObj) );
int iObj = Gia_ObjFaninId0p(p->pGia, pObj);
int fCompl = Gia_ObjFaninC0(pObj);
Nf_ObjUpdateRequired( p, iObj, fCompl, reqTime );
if ( iObj > 0 && Nf_ObjMatchBest(p, iObj, fCompl)->fCompl )
Nf_ObjUpdateRequired( p, iObj, !fCompl, reqTime - p->InvDelayI );
continue;
}
for ( c = 0; c < 2; c++ )
if ( Nf_ObjMapRefNum(p, i, c) )
{
@ -2012,7 +2119,7 @@ void Nf_ManComputeMappingEla( Nf_Man_t * p )
}
}
}
Gia_ManForEachCiId( p->pGia, Id, i )
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
if ( Nf_ObjMapRefNum(p, Id, 1) )
{
Required = Nf_ObjRequired( p, i, 1 );
@ -2054,6 +2161,240 @@ void Nf_ManFixPoDrivers( Nf_Man_t * p )
//printf( "Fixed %d PO drivers.\n", Count );
}
/**Function*************************************************************
Synopsis [Dump matches.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Nf_ManDumpMatches( Nf_Man_t * p )
{
FILE * pFile = fopen( p->pPars->ZFile, "wb" );
Gia_Obj_t * pObj; int n, iObj;
// output matches
Gia_ManForEachCi( p->pGia, pObj, n )
fprintf( pFile, "%d input %.2f\n", Abc_Var2Lit(Gia_ObjId(p->pGia, pObj), 0), 0.0 );
Gia_ManForEachAnd( p->pGia, pObj, iObj ) {
assert( !Gia_ObjIsBuf(pObj) );
for ( n = 0; n < 2; n++ ) {
int c, * pCut, * pCutSet = Nf_ObjCutSet( p, iObj );
Nf_SetForEachCut( pCutSet, pCut, c ) {
if ( Abc_Lit2Var(Nf_CutFunc(pCut)) >= Vec_WecSize(p->vTt2Match) )
continue;
assert( !Nf_CutIsTriv(pCut, iObj) );
assert( Nf_CutSize(pCut) <= p->pPars->nLutSize );
assert( Abc_Lit2Var(Nf_CutFunc(pCut)) < Vec_WecSize(p->vTt2Match) );
int iFuncLit = Nf_CutFunc(pCut);
int fComplExt = Abc_LitIsCompl(iFuncLit);
Vec_Int_t * v = Vec_WecEntry( p->vTt2Match, Abc_Lit2Var(iFuncLit) );
int j, k, Info, Offset, iFanin, fComplF;
Vec_IntForEachEntryDouble( v, Info, Offset, j ) {
Nf_Cfg_t Cfg = Nf_Int2Cfg(Offset);
int fCompl = Cfg.fCompl ^ fComplExt;
if ( fCompl != n )
continue;
Mio_Cell2_t*pC = Nf_ManCell( p, Info );
assert( Nf_CutSize(pCut) == (int)pC->nFanins );
fprintf( pFile, "%d ", Abc_Var2Lit(iObj, n) );
fprintf( pFile, "%s ", pC->pName );
fprintf( pFile, "%.2f", pC->AreaF );
Nf_CutForEachVarCompl( pCut, Cfg, iFanin, fComplF, k )
fprintf( pFile, " %d", Abc_Var2Lit(iFanin, fComplF) );
fprintf( pFile, "\n" );
}
}
}
}
Gia_ManForEachCo( p->pGia, pObj, n )
fprintf( pFile, "%d output %.2f %d\n", Abc_Var2Lit(Gia_ObjId(p->pGia, pObj), 0), 0.0, Gia_ObjFaninLit0p(p->pGia, pObj) );
// output levels
extern int Gia_ManChoiceLevel( Gia_Man_t * p );
int LevelMax = Gia_ManChoiceLevel( p->pGia );
Gia_ManForEachCiId( p->pGia, iObj, n )
fprintf( pFile, "L%d %d\n", Abc_Var2Lit(iObj, 0), 0 );
Gia_ManForEachAnd( p->pGia, pObj, iObj )
fprintf( pFile, "L%d %d\n", Abc_Var2Lit(iObj, 0), Gia_ObjLevelId(p->pGia, iObj) );
Gia_ManForEachCoId( p->pGia, iObj, n )
fprintf( pFile, "L%d %d\n", Abc_Var2Lit(iObj, 0), LevelMax+1 );
// output mapping
Gia_ManForEachCiId( p->pGia, iObj, n )
if ( Nf_ObjMapRefNum(p, iObj, 1) )
fprintf( pFile, "M%d %s %.2f %d\n", Abc_Var2Lit(iObj, 1), p->pCells[3].pName, p->pCells[3].AreaF, Abc_Var2Lit(iObj, 0) );
Gia_ManForEachAnd( p->pGia, pObj, iObj )
for ( n = 0; n < 2; n++ )
if ( Nf_ObjMapRefNum(p, iObj, n) ) {
Nf_Mat_t * pM = Nf_ObjMatchBest(p, iObj, n);
if ( pM->fCompl ) {
fprintf( pFile, "M%d %s %.2f %d\n", Abc_Var2Lit(iObj, n), p->pCells[3].pName, p->pCells[3].AreaF, Abc_Var2Lit(iObj, !n) );
continue;
}
int k, iVar, fCompl, * pCut = Nf_CutFromHandle( Nf_ObjCutSet(p, iObj), pM->CutH );
Mio_Cell2_t*pC = Nf_ManCell( p, pM->Gate );
fprintf( pFile, "M%d ", Abc_Var2Lit(iObj, n) );
fprintf( pFile, "%s ", pC->pName );
fprintf( pFile, "%.2f", pC->AreaF );
Nf_CutForEachVarCompl( pCut, pM->Cfg, iVar, fCompl, k )
fprintf( pFile, " %d", Abc_Var2Lit(iVar, fCompl) );
fprintf( pFile, "\n" );
}
fclose( pFile );
}
void Nf_ManDumpMatchesPrint( Gia_Man_t * pGia, Vec_Int_t * vStore, int nCutSize, int nMaxMatches )
{
int iObj, n, f, m;
int nObjs = Gia_ManObjNum( pGia );
int * pData;
if ( vStore == NULL || nCutSize == 0 || nMaxMatches == 0 )
return;
pData = Vec_IntArray( vStore );
for ( iObj = 0; iObj < nObjs; iObj++ )
{
Gia_Obj_t * pObj = Gia_ManObj( pGia, iObj );
int fPrint = 0;
if ( Gia_ObjIsAnd(pObj) && !Gia_ObjIsBuf(pObj) )
fPrint = 1;
else if ( Gia_ObjIsCo(pObj) )
fPrint = 1;
if ( !fPrint )
continue;
for ( n = 0; n < 2; n++ )
{
int * pNodeStore = pData + (2 * iObj + n) * nCutSize * nMaxMatches;
printf( "Node %d (%s) polarity %d has %d matches:\n", iObj, Gia_ObjIsCo(pObj) ? "CO" : "AND", n, nMaxMatches );
for ( f = 0; f < nCutSize; f++ )
{
printf( " Input %d:", f );
for ( m = 0; m < nMaxMatches; m++ )
printf( " %4d", pNodeStore[f * nMaxMatches + m] );
printf( "\n" );
}
}
}
}
void Nf_ManDumpMatchesBin( Nf_Man_t * p, int nMaxMatches )
{
const char * pNameNA = "n/a";
Gia_Obj_t * pObj;
Vec_Int_t * vStore;
int * pData;
int iObj, n, nMatches = 0;
int nCutSize = p->pPars->nLutSize;
int nObjs = Gia_ManObjNum(p->pGia);
char * pFileNameBin = NULL, * pFileNameGates = NULL;
FILE * pFileBin = NULL, * pFileGates = NULL;
if ( nMaxMatches <= 0 )
return;
if ( p->pPars->ZFile == NULL )
return;
assert( nCutSize > 0 && nCutSize <= NF_LEAF_MAX );
vStore = Vec_IntStart( 2 * nObjs * nCutSize * nMaxMatches );
pData = Vec_IntArray( vStore );
pFileNameBin = Abc_UtilStrsav( Extra_FileNameGenericAppend( p->pPars->ZFile, ".bin" ) );
pFileNameGates = Abc_UtilStrsav( Extra_FileNameGenericAppend( p->pPars->ZFile, ".gates" ) );
pFileBin = fopen( pFileNameBin, "wb" );
pFileGates = fopen( pFileNameGates, "wb" );
if ( pFileBin == NULL || pFileGates == NULL ) {
printf( "Cannot open match dump files \"%s\" and \"%s\".\n", pFileNameBin, pFileNameGates );
if ( pFileBin ) fclose( pFileBin );
if ( pFileGates ) fclose( pFileGates );
ABC_FREE( pFileNameBin );
ABC_FREE( pFileNameGates );
Vec_IntFree( vStore );
return;
}
for ( iObj = 0; iObj < nObjs; iObj++ ) {
pObj = Gia_ManObj( p->pGia, iObj );
assert( !Gia_ObjIsBuf(pObj) );
for ( n = 0; n < 2; n++ ) {
int Slot = 0;
int k;
int LitBuffer[NF_LEAF_MAX];
int * pNodeStore = pData + (2 * iObj + n) * nCutSize * nMaxMatches;
memset( pNodeStore, 0, sizeof(int) * nCutSize * nMaxMatches );
if ( Gia_ObjIsCo(pObj) && n == 0 && Slot < nMaxMatches ) {
pNodeStore[Slot] = Gia_ObjFaninLit0p( p->pGia, pObj );
fprintf( pFileGates, "%s %.2f\n", pNameNA, 0.0 );
Slot++;
nMatches++;
}
if ( Gia_ObjIsAnd(pObj) ) {
int c, * pCut, * pCutSet = Nf_ObjCutSet( p, iObj );
Nf_SetForEachCut( pCutSet, pCut, c )
{
int iFuncLit, fComplExt;
Vec_Int_t * vVec;
int j, Info, Offset;
if ( Slot == nMaxMatches )
break;
if ( Abc_Lit2Var(Nf_CutFunc(pCut)) >= Vec_WecSize(p->vTt2Match) )
continue;
if ( Nf_CutIsTriv(pCut, iObj) )
continue;
assert( Nf_CutSize(pCut) <= nCutSize );
iFuncLit = Nf_CutFunc(pCut);
fComplExt = Abc_LitIsCompl(iFuncLit);
vVec = Vec_WecEntry( p->vTt2Match, Abc_Lit2Var(iFuncLit) );
Vec_IntForEachEntryDouble( vVec, Info, Offset, j )
{
Nf_Cfg_t Cfg = Nf_Int2Cfg( Offset );
int fCompl = Cfg.fCompl ^ fComplExt;
Mio_Cell2_t * pCell = NULL;
const char * pGateName;
float Area = 0.0;
int iFanin, fComplF, nLitCount = 0;
if ( fCompl != n )
continue;
if ( Slot == nMaxMatches )
break;
if ( Info >= 0 )
pCell = Nf_ManCell( p, Info );
pGateName = (pCell && pCell->pName) ? pCell->pName : pNameNA;
Area = pCell ? pCell->AreaF : 0.0f;
Nf_CutForEachVarCompl( pCut, Cfg, iFanin, fComplF, k )
LitBuffer[nLitCount++] = Abc_Var2Lit( iFanin, fComplF );
for ( k = 0; k < nCutSize; k++ )
pNodeStore[k * nMaxMatches + Slot] = 0;
for ( k = 0; k < nLitCount; k++ )
pNodeStore[k * nMaxMatches + Slot] = LitBuffer[k];
fprintf( pFileGates, "%s %.2f\n", pGateName, Area );
Slot++;
nMatches++;
}
}
}
while ( Slot < nMaxMatches ) {
fprintf( pFileGates, "%s %.2f\n", pNameNA, 0.0 );
Slot++;
}
}
}
{
int Num = 3;
fwrite( &Num, 4, 1, pFileBin );
Num = 2 * nObjs;
fwrite( &Num, 4, 1, pFileBin );
Num = nCutSize;
fwrite( &Num, 4, 1, pFileBin );
Num = nMaxMatches;
fwrite( &Num, 4, 1, pFileBin );
}
fwrite( pData, 4, Vec_IntSize(vStore), pFileBin );
if ( p->pPars->fVerbose )
printf( "Dumped %d matches (limit %d) into binary file \"%s\" (%.2f MB).\n",
nMatches, nMaxMatches, pFileNameBin, Vec_IntMemory(vStore)/(1<<20) );
fclose( pFileBin );
fclose( pFileGates );
//Nf_ManDumpMatchesPrint( p->pGia, vStore, nCutSize, nMaxMatches );
Vec_IntFree( vStore );
ABC_FREE( pFileNameBin );
ABC_FREE( pFileNameGates );
}
/**Function*************************************************************
Synopsis [Deriving mapping.]
@ -2109,6 +2450,12 @@ Gia_Man_t * Nf_ManDeriveMapping( Nf_Man_t * p )
}
// assert( Vec_IntCap(vMapping) == 16 || Vec_IntSize(vMapping) == Vec_IntCap(vMapping) );
p->pGia->vCellMapping = vMapping;
if ( p->pPars->ZFile ) {
if ( p->pPars->nMaxMatches )
Nf_ManDumpMatchesBin( p, p->pPars->nMaxMatches );
else
Nf_ManDumpMatches( p );
}
return p->pGia;
}
void Nf_ManUpdateStats( Nf_Man_t * p )
@ -2360,16 +2707,21 @@ void Nf_ManSetDefaultPars( Jf_Par_t * pPars )
pPars->nCutNumMax = NF_CUT_MAX;
pPars->MapDelayTarget = 0;
}
Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
Gia_Man_t * Nf_ManPerformMappingInt( Gia_Man_t * pGia, Jf_Par_t * pPars )
{
Gia_Man_t * pNew = NULL, * pCls;
Nf_Man_t * p; int i, Id;
if ( Gia_ManHasChoices(pGia) )
pPars->fCoarsen = 0;
if ( Gia_ManHasChoices(pGia) || pGia->pManTime )
pPars->fCoarsen = 0;
pCls = pPars->fCoarsen ? Gia_ManDupMuxes(pGia, pPars->nCoarseLimit) : pGia;
p = Nf_StoCreate( pCls, pPars );
if ( p == NULL )
return NULL;
// if ( p->pManTim ) Tim_ManPrint( p->pManTim );
p->pGia->iFirstNonPiId = p->pManTim ? Tim_ManPiNum(p->pManTim) : Gia_ManCiNum(p->pGia);
p->pGia->iFirstPoId = p->pManTim ? Gia_ManCoNum(p->pGia) - Tim_ManPoNum(p->pManTim) : 0;
p->pGia->iFirstAndObj = 1 + p->pGia->iFirstNonPiId;
p->pGia->iFirstPoObj = Gia_ManObjNum(p->pGia) - Gia_ManCoNum(p->pGia) + p->pGia->iFirstPoId;
// if ( pPars->fVeryVerbose )
// Nf_StoPrint( p, pPars->fVeryVerbose );
if ( pPars->fVerbose && pPars->fCoarsen )
@ -2382,12 +2734,12 @@ Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
Nf_ManPrintQuit( p );
if ( Scl_ConIsRunning() )
{
Gia_ManForEachCiId( p->pGia, Id, i )
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
Nf_ObjPrepareCi( p, Id, Scl_ConGetInArr(i) );
}
else
{
Gia_ManForEachCiId( p->pGia, Id, i )
Gia_ManForEachCiIdWithBoxes( p->pGia, Id, i )
// Nf_ObjPrepareCi( p, Id, Scl_Flt2Int(p->pGia->vInArrs ? Abc_MaxFloat(0.0, Vec_FltEntry(p->pGia->vInArrs, i)) : 0.0) );
Nf_ObjPrepareCi( p, Id, Scl_Flt2Int(p->pGia->vInArrs ? Vec_FltEntry(p->pGia->vInArrs, i) : 0.0) );
}
@ -2418,10 +2770,162 @@ Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * pGia, Jf_Par_t * pPars )
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManCellMappingVerify_rec( Gia_Man_t * p, int iLit )
{
int iFanLit, k, Result = 1;
if ( Abc_LitIsCompl(iLit) && Gia_ObjIsTravIdCurrentId(p, Abc_Lit2Var(iLit)) )
return 1;
if ( !Abc_LitIsCompl(iLit) && Gia_ObjIsTravIdPreviousId(p, Abc_Lit2Var(iLit)) )
return 1;
if ( Abc_LitIsCompl(iLit) )
Gia_ObjSetTravIdCurrentId(p, Abc_Lit2Var(iLit));
else
Gia_ObjSetTravIdPreviousId(p, Abc_Lit2Var(iLit));
if ( !Gia_ObjIsAndNotBuf(Gia_ManObj(p, Abc_Lit2Var(iLit))) )
return 1;
if ( !Gia_ObjIsCell(p, iLit) )
{
Abc_Print( -1, "Gia_ManCellMappingVerify: Internal literal %d does not have mapping.\n", iLit );
return 0;
}
if ( Gia_ObjIsCellBuf(p, iLit) )
return Gia_ManCellMappingVerify_rec( p, Gia_ObjFaninLit0p(p, Gia_ManObj(p, Abc_Lit2Var(iLit))) );
if ( Gia_ObjIsCellInv(p, iLit) )
return Gia_ManCellMappingVerify_rec( p, Abc_LitNot(iLit) );
Gia_CellForEachFanin( p, iLit, iFanLit, k )
if ( Result )
Result &= Gia_ManCellMappingVerify_rec( p, iFanLit );
return Result;
}
void Gia_ManCellMappingVerify( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i, iLit, Result = 1;
assert( Gia_ManHasCellMapping(p) );
Gia_ManIncrementTravId( p );
Gia_ManIncrementTravId( p );
Gia_ManForEachBuf( p, pObj, i )
{
if ( !Gia_ObjIsAndNotBuf(Gia_ObjFanin0(pObj)) )
continue;
iLit = Gia_ObjFaninLit0p(p, pObj);
if ( !Gia_ObjIsCell(p, iLit) )
{
Abc_Print( -1, "Gia_ManCellMappingVerify: Buffer driver %d does not have mapping.\n", Gia_ObjFaninId0p(p, pObj) );
Result = 0;
continue;
}
Result &= Gia_ManCellMappingVerify_rec( p, iLit );
}
Gia_ManForEachCo( p, pObj, i )
{
if ( !Gia_ObjIsAndNotBuf(Gia_ObjFanin0(pObj)) )
continue;
iLit = Gia_ObjFaninLit0p(p, pObj);
if ( !Gia_ObjIsCell(p, iLit) )
{
Abc_Print( -1, "Gia_ManCellMappingVerify: CO driver %d does not have mapping.\n", Gia_ObjFaninId0p(p, pObj) );
Result = 0;
continue;
}
Result &= Gia_ManCellMappingVerify_rec( p, iLit );
}
// if ( Result )
// Abc_Print( 1, "Mapping verified correctly.\n" );
}
void Gia_ManTransferCellMapping( Gia_Man_t * p, Gia_Man_t * pGia )
{
int iLit, iLitNew, k, iFanLit, iPlace;
if ( !Gia_ManHasCellMapping(pGia) )
return;
Gia_ManCellMappingVerify( pGia );
Vec_IntFreeP( &p->vCellMapping );
p->vCellMapping = Vec_IntAlloc( 4 * Gia_ManObjNum(p) );
Vec_IntFill( p->vCellMapping, 2 * Gia_ManObjNum(p), 0 );
Gia_ManForEachCell( pGia, iLit )
{
Gia_Obj_t * pObj = Gia_ManObj(pGia, Abc_Lit2Var(iLit));
if ( Gia_ObjValue(pObj) == ~0 ) // handle dangling LUT
continue;
assert( !Abc_LitIsCompl( Gia_ObjValue(pObj) ) );
iLitNew = Abc_LitNotCond( Gia_ObjValue(pObj), Abc_LitIsCompl(iLit) );
if ( Gia_ObjIsCellInv(pGia, iLit) ) {
Vec_IntWriteEntry( p->vCellMapping, iLitNew, -1 );
continue;
}
if ( Gia_ObjIsCellBuf(pGia, iLit) ) {
Vec_IntWriteEntry( p->vCellMapping, iLitNew, -2 );
continue;
}
Vec_IntWriteEntry( p->vCellMapping, iLitNew, Vec_IntSize(p->vCellMapping) );
iPlace = Vec_IntSize( p->vCellMapping );
Vec_IntPush( p->vCellMapping, Gia_ObjCellSize(pGia, iLit) );
Gia_CellForEachFanin( pGia, iLit, iFanLit, k )
{
int iFanLitNew = Gia_ObjValue( Gia_ManObj(pGia, Abc_Lit2Var(iFanLit)) );
if ( iFanLitNew == ~0 ) // handle dangling LUT fanin
Vec_IntAddToEntry( p->vCellMapping, iPlace, -1 );
else
Vec_IntPush( p->vCellMapping, Abc_LitNotCond(iFanLitNew, Abc_LitIsCompl(iFanLit)) );
}
Vec_IntPush( p->vCellMapping, Gia_ObjCellId(pGia, iLit) );
}
Gia_ManCellMappingVerify( p );
}
Gia_Man_t * Nf_ManPerformMapping( Gia_Man_t * p, Jf_Par_t * pPars )
{
Gia_Man_t * pNew;
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t*)p->pManTime) && Gia_ManIsNormalized(p) )
{
pNew = Gia_ManDupUnnormalize( p );
if ( pNew == NULL )
return NULL;
Gia_ManTransferTiming( pNew, p );
p = pNew;
// mapping
pNew = Nf_ManPerformMappingInt( p, pPars );
if ( pNew != p )
{
Gia_ManTransferTiming( pNew, p );
Gia_ManStop( p );
}
// normalize
pNew = Gia_ManDupNormalize( p = pNew, 0 );
Gia_ManTransferCellMapping( pNew, p );
Gia_ManTransferTiming( pNew, p );
Gia_ManStop( p );
assert( Gia_ManIsNormalized(pNew) );
}
else
{
pNew = Nf_ManPerformMappingInt( p, pPars );
Gia_ManTransferTiming( pNew, p );
//Gia_ManCellMappingVerify( pNew );
// remove choices after mapping
ABC_FREE( pNew->pReprs );
ABC_FREE( pNew->pNexts );
}
//pNew->MappedDelay = (int)((If_Par_t *)pp)->FinalDelay;
//pNew->MappedArea = (int)((If_Par_t *)pp)->FinalArea;
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -184,13 +184,15 @@ static inline int Min_ManAppendCo( Min_Man_t * p, int iLit0 )
***********************************************************************/
void Min_ManFromGia_rec( Min_Man_t * pNew, Gia_Man_t * p, int iObj )
{
Gia_Obj_t * pObj = Gia_ManObj(p, iObj);
Gia_Obj_t * pObj = Gia_ManObj(p, iObj); int iLit0, iLit1;
if ( ~pObj->Value )
return;
assert( Gia_ObjIsAnd(pObj) );
Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId0(pObj, iObj) );
Min_ManFromGia_rec( pNew, p, Gia_ObjFaninId1(pObj, iObj) );
pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
iLit0 = Gia_ObjFanin0Copy(pObj);
iLit1 = Gia_ObjFanin1Copy(pObj);
pObj->Value = Min_ManAppendObj( pNew, Abc_MinInt(iLit0, iLit1), Abc_MaxInt(iLit0, iLit1) );
}
Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
{
@ -205,7 +207,7 @@ Min_Man_t * Min_ManFromGia( Gia_Man_t * p, Vec_Int_t * vOuts )
Gia_ManForEachAnd( p, pObj, i )
pObj->Value = Min_ManAppendObj( pNew, Gia_ObjFaninLit0(pObj, i), Gia_ObjFaninLit1(pObj, i) );
Gia_ManForEachCo( p, pObj, i )
pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFaninLit0p(p, pObj) );
pObj->Value = Min_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
}
else
{
@ -403,8 +405,10 @@ static inline char Min_LitIsImplied2( Min_Man_t * p, int iLit )
char Val1 = Min_LitValL(p, iLit1);
assert( Min_LitIsNode(p, iLit) ); // internal node
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
Val0 = Min_LitIsImplied1(p, iLit0);
Val1 = Min_LitValL(p, iLit1);
}
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
Val1 = Min_LitIsImplied1(p, iLit1);
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
@ -427,8 +431,10 @@ static inline char Min_LitIsImplied3( Min_Man_t * p, int iLit )
char Val1 = Min_LitValL(p, iLit1);
assert( Min_LitIsNode(p, iLit) ); // internal node
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
Val0 = Min_LitIsImplied2(p, iLit0);
Val1 = Min_LitValL(p, iLit1);
}
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
Val1 = Min_LitIsImplied2(p, iLit1);
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
@ -451,8 +457,10 @@ static inline char Min_LitIsImplied4( Min_Man_t * p, int iLit )
char Val1 = Min_LitValL(p, iLit1);
assert( Min_LitIsNode(p, iLit) ); // internal node
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
Val0 = Min_LitIsImplied3(p, iLit0);
Val1 = Min_LitValL(p, iLit1);
}
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
Val1 = Min_LitIsImplied3(p, iLit1);
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
@ -475,8 +483,10 @@ static inline char Min_LitIsImplied5( Min_Man_t * p, int iLit )
char Val1 = Min_LitValL(p, iLit1);
assert( Min_LitIsNode(p, iLit) ); // internal node
assert( Min_LitValL(p, iLit) == 2 ); // unassigned
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) )
if ( Val0 == 2 && Min_LitIsNode(p, iLit0) ) {
Val0 = Min_LitIsImplied4(p, iLit0);
Val1 = Min_LitValL(p, iLit1);
}
if ( Val1 == 2 && Min_LitIsNode(p, iLit1) )
Val1 = Min_LitIsImplied4(p, iLit1);
if ( Min_LitIsXor(iLit, iLit0, iLit1) )
@ -955,6 +965,12 @@ Vec_Wec_t * Min_ManComputeCexes( Gia_Man_t * p, Vec_Int_t * vOuts0, int nMaxTrie
if ( Vec_IntEntry(vStats[2], i) >= nMinCexes || Vec_IntEntry(vStats[1], i) > 10*Vec_IntEntry(vStats[2], i) )
continue;
{
assert( Gia_ObjIsCo(pObj) );
if ( Gia_ObjFaninId0p(p, pObj) == 0 ) {
if ( fVerbose )
printf( "Output %d is driven by constant %d.\n", Gia_ObjCioId(pObj), Gia_ObjFaninC0(pObj) );
continue;
}
abctime clk = Abc_Clock();
int iObj = Min_ManCo(pNew, i);
int Index = Gia_ObjCioId(pObj);
@ -1351,6 +1367,136 @@ void Min_ManTest2( Gia_Man_t * p )
Vec_WrdFreeP( &vSimsPi );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_GenerateCexesDumpBlif( char * pFileName, Gia_Man_t * p, Vec_Wec_t * vCexes )
{
extern Vec_Ptr_t * Gia_GetFakeNames( int nNames, int fCaps );
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL ) {
printf( "Cannot open output file name \"%s\".\n", pFileName );
return;
}
int fFakeIns = 0, fFakeOuts = 0;
if ( p->vNamesIn == NULL )
p->vNamesIn = Gia_GetFakeNames( Gia_ManCiNum(p), 0 ), fFakeIns = 1;
if ( p->vNamesOut == NULL )
p->vNamesOut = Gia_GetFakeNames( Gia_ManCoNum(p), 1 ), fFakeOuts = 1;
Gia_Obj_t * pObj, * pObj2;
char * pLine = ABC_CALLOC( char, Gia_ManCiNum(p)+3 );
int i, k, c, iLit, nOuts[2] = {0}, nCexes = Vec_WecSize(vCexes) / Gia_ManCoNum(p);
fprintf( pFile, "# Satisfying assignments for the primary outputs generated by ABC on %s\n", Gia_TimeStamp() );
fprintf( pFile, ".model %s\n", p->pName );
fprintf( pFile, ".inputs" );
Gia_ManForEachCi( p, pObj, i )
fprintf( pFile, " %s", Gia_ObjCiName(p, i) );
fprintf( pFile, "\n.outputs" );
Gia_ManForEachCo( p, pObj, i )
fprintf( pFile, " %s", Gia_ObjCoName(p, i) );
fprintf( pFile, "\n" );
Gia_ManForEachCo( p, pObj, i ) {
if ( Gia_ObjFaninLit0p(p, pObj) == 0 ) {
fprintf( pFile, ".names %s\n", Gia_ObjCoName(p, i) );
nOuts[0]++;
}
else if ( Gia_ObjFaninLit0p(p, pObj) == 1 ) {
fprintf( pFile, ".names %s\n 1\n", Gia_ObjCiName(p, i) );
nOuts[1]++;
}
else {
fprintf( pFile, ".names" );
Gia_ManForEachCi( p, pObj2, c )
fprintf( pFile, " %s", Gia_ObjCiName(p, c) );
fprintf( pFile, " %s\n", Gia_ObjCoName(p, i) );
for ( c = 0; c < nCexes; c++ ) {
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
memset(pLine, '-', Gia_ManCiNum(p) );
Vec_IntForEachEntry( vPat, iLit, k )
pLine[Abc_Lit2Var(iLit)-1] = '1' - Abc_LitIsCompl(iLit);
fprintf( pFile, "%s 1\n", pLine );
}
nOuts[1]++;
}
}
fprintf( pFile, ".end\n\n" );
fclose( pFile );
printf( "Information about %d sat, %d unsat, and %d undecided primary outputs was written into BLIF file \"%s\".\n",
nOuts[1], nOuts[0], Gia_ManCoNum(p)-nOuts[1]-nOuts[0], pFileName );
free( pLine );
if ( fFakeIns ) Vec_PtrFreeFree( p->vNamesIn ), p->vNamesIn = NULL;
if ( fFakeOuts ) Vec_PtrFreeFree( p->vNamesOut ), p->vNamesOut = NULL;
}
void Gia_GenerateCexesDumpFile( char * pFileName, Gia_Man_t * p, Vec_Wec_t * vCexes, int fShort )
{
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL ) {
printf( "Cannot open output file name \"%s\".\n", pFileName );
return;
}
Gia_Obj_t * pObj;
char * pLine = ABC_CALLOC( char, Gia_ManCiNum(p)+3 );
int i, k, c, iLit, nOuts[2] = {0}, nCexes = Vec_WecSize(vCexes) / Gia_ManCoNum(p);
Gia_ManForEachCo( p, pObj, i ) {
if ( Gia_ObjFaninLit0p(p, Gia_ManCo(p, i)) == 0 ) {
fprintf( pFile, "%d : unsat\n", i );
nOuts[0]++;
}
else if ( fShort ) {
for ( c = 0; c < nCexes; c++ ) {
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
fprintf( pFile, "%d :", i );
if ( Vec_IntSize(vPat) == 0 )
fprintf( pFile, " not available" );
else
Vec_IntForEachEntry( vPat, iLit, k )
fprintf( pFile, " %d", iLit );
fprintf( pFile, "\n" );
}
nOuts[1]++;
}
else {
for ( c = 0; c < nCexes; c++ ) {
Vec_Int_t * vPat = Vec_WecEntry( vCexes, i*nCexes+c );
memset(pLine, '-', Gia_ManCiNum(p) );
Vec_IntForEachEntry( vPat, iLit, k )
pLine[Abc_Lit2Var(iLit)-1] = '1' - Abc_LitIsCompl(iLit);
fprintf( pFile, "%d : %s\n", i, pLine );
}
nOuts[1]++;
}
}
printf( "Information about %d sat, %d unsat, and %d undecided primary outputs was written into file \"%s\".\n",
nOuts[1], nOuts[0], Gia_ManCoNum(p)-nOuts[1]-nOuts[0], pFileName );
fclose( pFile );
free( pLine );
}
void Gia_GenerateCexes( char * pFileName, Gia_Man_t * p, int nMaxTries, int nMinCexes, int fUseSim, int fUseSat, int fShort, int fBlif, int fVerbose, int fVeryVerbose )
{
unsigned Start = Abc_Random(1);
Vec_Int_t * vStats[3] = {0}; int i;
Vec_Wec_t * vCexes = Min_ManComputeCexes( p, NULL, nMaxTries, nMinCexes, vStats, fUseSim, fUseSat, fVerbose );
assert( Vec_WecSize(vCexes) == Gia_ManCoNum(p) * nMinCexes );
if ( fBlif )
Gia_GenerateCexesDumpBlif( pFileName, p, vCexes );
else
Gia_GenerateCexesDumpFile( pFileName, p, vCexes, fShort );
for ( i = 0; i < 3; i++ )
Vec_IntFreeP( &vStats[i] );
Vec_WecFree( vCexes );
Start = 0;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -23,7 +23,9 @@
#include "sat/bsat/satStore.h"
#include "misc/extra/extra.h"
#include "sat/glucose/AbcGlucose.h"
#include "sat/cadical/cadicalSolver.h"
#include "misc/util/utilTruth.h"
#include "base/io/ioResub.h"
ABC_NAMESPACE_IMPL_START
@ -44,6 +46,7 @@ struct Qbf_Man_t_
sat_solver * pSatVer; // verification instance
sat_solver * pSatSyn; // synthesis instance
bmcg_sat_solver*pSatSynG; // synthesis instance
cadical_solver* pSatSynC; // synthesis instance
Vec_Int_t * vValues; // variable values
Vec_Int_t * vParMap; // parameter mapping
Vec_Int_t * vLits; // literals for the SAT solver
@ -533,7 +536,7 @@ void Gia_QbfDumpFileInv( Gia_Man_t * pGia, int nPars )
SeeAlso []
***********************************************************************/
Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fGlucose, int fVerbose )
Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fGlucose, int fCadical, int fVerbose )
{
Qbf_Man_t * p;
Cnf_Dat_t * pCnf;
@ -550,11 +553,13 @@ Qbf_Man_t * Gia_QbfAlloc( Gia_Man_t * pGia, int nPars, int fGlucose, int fVerbos
p->pSatVer = (sat_solver *)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
p->pSatSyn = sat_solver_new();
p->pSatSynG = fGlucose ? bmcg_sat_solver_start() : NULL;
p->pSatSynC = fCadical ? cadical_solver_new() : NULL;
p->vValues = Vec_IntAlloc( Gia_ManPiNum(pGia) );
p->vParMap = Vec_IntStartFull( nPars );
p->vLits = Vec_IntAlloc( nPars );
sat_solver_setnvars( p->pSatSyn, nPars );
if ( p->pSatSynG ) bmcg_sat_solver_set_nvars( p->pSatSynG, nPars );
if ( p->pSatSynC ) cadical_solver_setnvars( p->pSatSynC, nPars );
Cnf_DataFree( pCnf );
return p;
}
@ -563,6 +568,7 @@ void Gia_QbfFree( Qbf_Man_t * p )
sat_solver_delete( p->pSatVer );
sat_solver_delete( p->pSatSyn );
if ( p->pSatSynG ) bmcg_sat_solver_stop( p->pSatSynG );
if ( p->pSatSynC ) cadical_solver_delete( p->pSatSynC );
Vec_IntFree( p->vLits );
Vec_IntFree( p->vValues );
Vec_IntFree( p->vParMap );
@ -748,6 +754,21 @@ int Gia_QbfAddCofactorG( Qbf_Man_t * p, Gia_Man_t * pCof )
Cnf_DataFree( pCnf );
return 1;
}
int Gia_QbfAddCofactorC( Qbf_Man_t * p, Gia_Man_t * pCof )
{
Cnf_Dat_t * pCnf = (Cnf_Dat_t *)Mf_ManGenerateCnf( pCof, 8, 0, 1, 0, 0 );
int i, iFirstVar = pCnf->nVars - Gia_ManPiNum(pCof); //-1
pCnf->pMan = NULL;
Cnf_SpecialDataLift( pCnf, cadical_solver_nvars(p->pSatSynC), iFirstVar, iFirstVar + Gia_ManPiNum(p->pGia) );
for ( i = 0; i < pCnf->nClauses; i++ )
if ( !cadical_solver_addclause( p->pSatSynC, pCnf->pClauses[i], pCnf->pClauses[i+1] ) )
{
Cnf_DataFree( pCnf );
return 0;
}
Cnf_DataFree( pCnf );
return 1;
}
/**Function*************************************************************
@ -765,16 +786,20 @@ void Gia_QbfOnePattern( Qbf_Man_t * p, Vec_Int_t * vValues )
int i;
Vec_IntClear( vValues );
for ( i = 0; i < p->nPars; i++ )
Vec_IntPush( vValues, p->pSatSynG ? bmcg_sat_solver_read_cex_varvalue(p->pSatSynG, i) : sat_solver_var_value(p->pSatSyn, i) );
Vec_IntPush( vValues, p->pSatSynC ? cadical_solver_get_var_value(p->pSatSynC, i) :
p->pSatSynG ? bmcg_sat_solver_read_cex_varvalue(p->pSatSynG, i) : sat_solver_var_value(p->pSatSyn, i) );
}
void Gia_QbfPrint( Qbf_Man_t * p, Vec_Int_t * vValues, int Iter )
{
printf( "%5d : ", Iter );
assert( Vec_IntSize(vValues) == p->nVars );
Vec_IntPrintBinary( vValues ); printf( " " );
printf( "Var =%7d ", p->pSatSynG ? bmcg_sat_solver_varnum(p->pSatSynG) : sat_solver_nvars(p->pSatSyn) );
printf( "Cla =%7d ", p->pSatSynG ? bmcg_sat_solver_clausenum(p->pSatSynG) : sat_solver_nclauses(p->pSatSyn) );
printf( "Conf =%9d ", p->pSatSynG ? bmcg_sat_solver_conflictnum(p->pSatSynG) : sat_solver_nconflicts(p->pSatSyn) );
printf( "Var =%7d ", p->pSatSynC ? cadical_solver_nvars(p->pSatSynC) :
p->pSatSynG ? bmcg_sat_solver_varnum(p->pSatSynG) : sat_solver_nvars(p->pSatSyn) );
printf( "Cla =%7d ", p->pSatSynC ? cadical_solver_nclauses(p->pSatSynC) :
p->pSatSynG ? bmcg_sat_solver_clausenum(p->pSatSynG) : sat_solver_nclauses(p->pSatSyn) );
printf( "Conf =%9d ", p->pSatSynC ? cadical_solver_nconflicts(p->pSatSynC) :
p->pSatSynG ? bmcg_sat_solver_conflictnum(p->pSatSynG) : sat_solver_nconflicts(p->pSatSyn) );
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
}
@ -868,9 +893,9 @@ void Gia_QbfLearnConstraint( Qbf_Man_t * p, Vec_Int_t * vValues )
SeeAlso []
***********************************************************************/
int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int nEncVars, int fGlucose, int fVerbose )
int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, int nTimeOut, int nEncVars, int fGlucose, int fCadical, int fSilent, int fVerbose )
{
Qbf_Man_t * p = Gia_QbfAlloc( pGia, nPars, fGlucose, fVerbose );
Qbf_Man_t * p = Gia_QbfAlloc( pGia, nPars, fGlucose, fCadical, fVerbose );
Gia_Man_t * pCof;
int i, status, RetValue = 0;
abctime clk;
@ -885,12 +910,15 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
// generate next constraint
assert( Vec_IntSize(p->vValues) == p->nVars );
pCof = Gia_QbfCofactor( pGia, nPars, p->vValues, p->vParMap );
status = p->pSatSynG ? Gia_QbfAddCofactorG( p, pCof ) : Gia_QbfAddCofactor( p, pCof );
status = p->pSatSynC ? Gia_QbfAddCofactorC( p, pCof ) :
p->pSatSynG ? Gia_QbfAddCofactorG( p, pCof ) : Gia_QbfAddCofactor( p, pCof );
Gia_ManStop( pCof );
if ( status == 0 ) { RetValue = 1; break; }
// synthesize next assignment
clk = Abc_Clock();
if ( p->pSatSynG )
if ( p->pSatSynC )
status = cadical_solver_solve( p->pSatSynC, NULL, NULL, 0, 0, 0, 0 );
else if ( p->pSatSynG )
status = bmcg_sat_solver_solve( p->pSatSynG, NULL, 0 );
else
status = sat_solver_solve( p->pSatSyn, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
@ -911,9 +939,18 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
if ( RetValue == 0 )
{
int nZeros = Vec_IntCountZero( p->vValues );
printf( "Parameters: " );
printf( "Parameters (%d): 0x", nPars );
assert( Vec_IntSize(p->vValues) == nPars );
Vec_IntPrintBinary( p->vValues );
//Vec_IntPrintBinary( p->vValues );
while ( Vec_IntSize(p->vValues) % 4 )
Vec_IntPush(p->vValues, 0);
for ( int i = Vec_IntSize(p->vValues)/4 - 1; i >= 0; i-- ) {
int Digit = Vec_IntEntry(p->vValues, 4*i+0);
Digit |= Vec_IntEntry(p->vValues, 4*i+1) << 1;
Digit |= Vec_IntEntry(p->vValues, 4*i+2) << 2;
Digit |= Vec_IntEntry(p->vValues, 4*i+3) << 3;
printf( "%x", Digit );
}
printf( " Statistics: 0=%d 1=%d\n", nZeros, Vec_IntSize(p->vValues) - nZeros );
if ( nEncVars )
{
@ -928,9 +965,9 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
printf( "The problem aborted after %d conflicts. ", nConfLimit );
else if ( RetValue == -1 && nIterLimit )
printf( "The problem aborted after %d iterations. ", nIterLimit );
else if ( RetValue == 1 )
else if ( RetValue == 1 && !fSilent )
printf( "The problem is UNSAT after %d iterations. ", i );
else
else if ( !fSilent )
printf( "The problem is SAT after %d iterations. ", i );
if ( fVerbose )
{
@ -939,12 +976,307 @@ int Gia_QbfSolve( Gia_Man_t * pGia, int nPars, int nIterLimit, int nConfLimit, i
Abc_PrintTime( 1, "Other", Abc_Clock() - p->clkStart - p->clkSat );
Abc_PrintTime( 1, "TOTAL", Abc_Clock() - p->clkStart );
}
else
else if ( !fSilent )
Abc_PrintTime( 1, "Time", Abc_Clock() - p->clkStart );
Gia_QbfFree( p );
return RetValue;
}
/**Function*************************************************************
Synopsis [Derive the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
sat_solver * Gia_ManGenSolver( Gia_Man_t * p, Vec_Int_t * vInsOuts, int nIns )
{
Gia_Obj_t * pObj; int i, nObjs = Gia_ManObjNum(p);
sat_solver * pSat = sat_solver_new();
sat_solver_setnvars( pSat, 2 * nObjs );
Gia_ManIncrementTravId(p);
Gia_ManForEachObjVecStart( vInsOuts, p, pObj, i, nIns )
Gia_ObjSetTravIdCurrent(p, pObj);
Gia_ManForEachAnd( p, pObj, i )
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
sat_solver_add_and( pSat, i, Gia_ObjFaninId0(pObj, i), Gia_ObjFaninId1(pObj, i), Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
Gia_ManForEachAnd( p, pObj, i )
sat_solver_add_and( pSat, nObjs+i, nObjs+Gia_ObjFaninId0(pObj, i), nObjs+Gia_ObjFaninId1(pObj, i), Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj), 0 );
Gia_ManForEachCi( p, pObj, i )
if ( !Gia_ObjIsTravIdCurrent(p, pObj) )
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), Gia_ObjId(p, pObj), 0 );
Gia_ManForEachCo( p, pObj, i )
if ( Gia_ObjFaninId0p(p, pObj) > 0 ) {
sat_solver_add_buffer( pSat, Gia_ObjId(p, pObj), Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), nObjs+Gia_ObjFaninId0p(p, pObj), Gia_ObjFaninC0(pObj) );
sat_solver_add_buffer( pSat, nObjs+Gia_ObjId(p, pObj), Gia_ObjId(p, pObj), 0 );
}
return pSat;
}
Vec_Int_t * Gia_ManGenCombs( Gia_Man_t * p, Vec_Int_t * vInsOuts, int nIns, int fVerbose )
{
int nTimeOut = 600, nConfLimit = 1000000;
int i, iSatVar, Iter, Mask, nSolutions = 0, RetValue = 0;
abctime clkStart = Abc_Clock();
sat_solver * pSat = Gia_ManGenSolver( p, vInsOuts, nIns );
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
for ( Iter = 0; Iter < 1000000; Iter++ )
{
int status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
if ( status == l_False ) { RetValue = 1; break; }
if ( status == l_Undef ) { RetValue = 0; break; }
nSolutions++;
// extract SAT assignment
Mask = 0;
Vec_IntClear( vLits );
Vec_IntForEachEntry( vInsOuts, iSatVar, i ) {
Vec_IntPush( vLits, Abc_Var2Lit(iSatVar, sat_solver_var_value(pSat, iSatVar)) );
if ( sat_solver_var_value(pSat, iSatVar) )
Mask |= 1 << (Vec_IntSize(vInsOuts)-1-i);
}
Vec_IntPush( vRes, Mask );
if ( fVerbose )
{
printf( "%5d : ", Iter );
Vec_IntForEachEntry( vInsOuts, iSatVar, i ) {
if ( i == nIns ) printf( " " );
printf( "%d", (Mask >> (Vec_IntSize(vInsOuts)-1-i)) & 1 );
}
printf( "\n" );
}
// add clause
if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ) )
{ RetValue = 1; break; }
if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = 0; break; }
}
Vec_IntSort( vRes, 0 );
Vec_IntFree( vLits );
sat_solver_delete( pSat );
if ( RetValue == 0 )
Vec_IntFreeP( &vRes );
if ( fVerbose )
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
return vRes;
}
void Gia_ManGenWriteRel( Vec_Int_t * vRes, int nIns, int nOuts, char * pFileName )
{
int i, k, Mask, nVars = nIns + nOuts;
Abc_RData_t * p2, * p = Abc_RDataStart( nIns, nOuts, Vec_IntSize(vRes) );
Vec_IntForEachEntry( vRes, Mask, i ) {
for ( k = 0; k < nVars; k++ )
if ( (Mask >> (nVars-1-k)) & 1 ) { // the bit is 1
if ( k < nIns )
Abc_RDataSetIn( p, k, i );
else
Abc_RDataSetOut( p, 2*(k-nIns)+1, i );
}
else { // the bit is zero
if ( k >= nIns )
Abc_RDataSetOut( p, 2*(k-nIns), i );
}
}
Abc_WritePla( p, pFileName, 0 );
p2 = Abc_RData2Rel( p );
Abc_WritePla( p2, Extra_FileNameGenericAppend(pFileName, "_rel.pla"), 1 );
Abc_RDataStop( p2 );
Abc_RDataStop( p );
}
void Gia_ManGenRel2( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, char * pFileName, int fVerbose )
{
Vec_Int_t * vRes = Gia_ManGenCombs( pGia, vInsOuts, nIns, fVerbose );
if ( vRes == NULL ) {
printf( "Enumerating solutions did not succeed.\n" );
return;
}
Gia_ManGenWriteRel( vRes, nIns, Vec_IntSize(vInsOuts)-nIns, pFileName );
Vec_IntFree( vRes );
}
/**Function*************************************************************
Synopsis [Derive the SAT solver.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_ManCollectNodeTfos( Gia_Man_t * p, int * pNodes, int nNodes )
{
Vec_Int_t * vTfo = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj; int i;
Gia_ManIncrementTravId( p );
for ( i = 0; i < nNodes; i++ )
Gia_ObjSetTravIdCurrentId( p, pNodes[i] );
Gia_ManForEachAnd( p, pObj, i ) {
if ( Gia_ObjIsTravIdCurrentId(p, i) )
continue;
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i)) || Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i)) )
Gia_ObjSetTravIdCurrentId( p, i ), Vec_IntPush( vTfo, i );
}
Gia_ManForEachCo( p, pObj, i )
if ( Gia_ObjIsTravIdCurrentId(p, Gia_ObjFaninId0p(p, pObj)) )
Vec_IntPush( vTfo, Gia_ObjId(p, pObj) );
return vTfo;
}
Vec_Int_t * Gia_ManCollectNodeTfis( Gia_Man_t * p, Vec_Int_t * vNodes )
{
Vec_Int_t * vTfi = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj; int i, Id;
Gia_ManIncrementTravId( p );
Gia_ManForEachObjVec( vNodes, p, pObj, i )
if ( Gia_ObjIsCo(pObj) )
Gia_ObjSetTravIdCurrentId( p, Gia_ObjFaninId0p(p, pObj) );
Gia_ManForEachAndReverse( p, pObj, i ) {
if ( !Gia_ObjIsTravIdCurrentId(p, i) )
continue;
Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId0(pObj, i));
Gia_ObjSetTravIdCurrentId(p, Gia_ObjFaninId1(pObj, i));
}
Gia_ManForEachCiId( p, Id, i )
if ( Gia_ObjIsTravIdCurrentId(p, Id) )
Vec_IntPush( vTfi, Id );
Gia_ManForEachAnd( p, pObj, i )
if ( Gia_ObjIsTravIdCurrentId(p, i) )
Vec_IntPush( vTfi, i );
return vTfi;
}
Gia_Man_t * Gia_ManGenRelMiter( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns )
{
Vec_Int_t * vTfo = Gia_ManCollectNodeTfos( pGia, Vec_IntEntryP(vInsOuts, nIns), Vec_IntSize(vInsOuts)-nIns );
Vec_Int_t * vTfi = Gia_ManCollectNodeTfis( pGia, vTfo );
Vec_Int_t * vInLits = Vec_IntAlloc( nIns );
Vec_Int_t * vOutLits = Vec_IntAlloc( Vec_IntSize(vInsOuts) - nIns );
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, iLit = 0;
Gia_ManFillValue( pGia );
pNew = Gia_ManStart( 1000 );
pNew->pName = Abc_UtilStrsav( pGia->pName );
Gia_ManHashAlloc( pNew );
Gia_ManForEachObjVec( vTfi, pGia, pObj, i )
if ( Gia_ObjIsCi(pObj) )
pObj->Value = Gia_ManAppendCi(pNew);
for ( i = 0; i < Vec_IntSize(vInsOuts)-nIns; i++ )
Vec_IntPush( vInLits, Gia_ManAppendCi(pNew) );
Gia_ManForEachObjVec( vTfi, pGia, pObj, i )
if ( Gia_ObjIsAnd(pObj) )
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
if ( Gia_ObjIsCo(pObj) )
pObj->Value = Gia_ObjFanin0Copy(pObj);
Gia_ManForEachObjVec( vInsOuts, pGia, pObj, i )
if ( i < nIns )
Vec_IntPush( vOutLits, pObj->Value );
else
pObj->Value = Vec_IntEntry( vInLits, i-nIns );
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
if ( Gia_ObjIsAnd(pObj) )
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
Gia_ManForEachObjVec( vTfo, pGia, pObj, i )
if ( Gia_ObjIsCo(pObj) )
iLit = Gia_ManHashOr( pNew, iLit, Gia_ManHashXor(pNew, Gia_ObjFanin0Copy(pObj), pObj->Value) );
Gia_ManAppendCo( pNew, iLit );
Vec_IntForEachEntry( vOutLits, iLit, i )
Gia_ManAppendCo( pNew, iLit );
Vec_IntFree( vTfo );
Vec_IntFree( vTfi );
Vec_IntFree( vInLits );
Vec_IntFree( vOutLits );
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
Gia_ManSetRegNum( pNew, Gia_ManRegNum(pGia) );
return pNew;
}
void Gia_ManPrintRelMinterm( int Mint, int nIns, int nVars )
{
for ( int i = 0; i < nVars; i++ )
printf( "%s%d", i == nIns ? " ":"", (Mint >> (nVars-1-i)) & 1 );
printf( "\n" );
}
Vec_Int_t * Gia_ManGenIoCombs( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, int fVerbose )
{
abctime clkStart = Abc_Clock();
int nTimeOut = 600, nConfLimit = 1000000;
int i, iNode, iSatVar, Iter, Mask, nSolutions = 0, RetValue = 0;
Gia_Man_t * pMiter = Gia_ManGenRelMiter( pGia, vInsOuts, nIns );
Cnf_Dat_t * pCnf = (Cnf_Dat_t*)Mf_ManGenerateCnf( pMiter, 8, 0, 0, 0, 0 );
sat_solver * pSat = (sat_solver*)Cnf_DataWriteIntoSolver( pCnf, 1, 0 );
int iLit = Abc_Var2Lit( 1, 0 ); // enumerating the care set (the miter output is 1)
int status = sat_solver_addclause( pSat, &iLit, &iLit + 1 ); assert( status );
Vec_Int_t * vSatVars = Vec_IntAlloc( Vec_IntSize(vInsOuts) );
Vec_IntForEachEntry( vInsOuts, iNode, i )
Vec_IntPush( vSatVars, i < nIns ? 2+i : pCnf->nVars-Vec_IntSize(vInsOuts)+i );
Vec_Int_t * vLits = Vec_IntAlloc( 100 );
Vec_Int_t * vRes = Vec_IntAlloc( 1000 );
for ( Iter = 0; Iter < 1000000; Iter++ )
{
int status = sat_solver_solve( pSat, NULL, NULL, (ABC_INT64_T)nConfLimit, 0, 0, 0 );
if ( status == l_False ) { RetValue = 1; break; }
if ( status == l_Undef ) { RetValue = 0; break; }
nSolutions++;
// extract SAT assignment
Mask = 0;
Vec_IntClear( vLits );
Vec_IntForEachEntry( vSatVars, iSatVar, i ) {
Vec_IntPush( vLits, Abc_Var2Lit(iSatVar, sat_solver_var_value(pSat, iSatVar)) );
if ( sat_solver_var_value(pSat, iSatVar) )
Mask |= 1 << (Vec_IntSize(vInsOuts)-1-i);
}
Vec_IntPush( vRes, Mask );
if ( 0 ) {
printf( "%5d : ", Iter );
Gia_ManPrintRelMinterm( Mask, nIns, Vec_IntSize(vSatVars) );
}
// add clause
if ( !sat_solver_addclause( pSat, Vec_IntArray(vLits), Vec_IntArray(vLits) + Vec_IntSize(vLits) ) )
{ RetValue = 1; break; }
if ( nTimeOut && (Abc_Clock() - clkStart)/CLOCKS_PER_SEC >= nTimeOut ) { RetValue = 0; break; }
}
// complement the set of input/output minterms
Vec_Int_t * vBits = Vec_IntStart( 1 << Vec_IntSize(vInsOuts) );
Vec_IntForEachEntry( vRes, Mask, i )
Vec_IntWriteEntry( vBits, Mask, 1 );
Vec_IntClear( vRes );
Vec_IntForEachEntry( vBits, Mask, i )
if ( !Mask )
Vec_IntPush( vRes, i );
Vec_IntFree( vBits );
// cleanup
Vec_IntFree( vLits );
sat_solver_delete( pSat );
Gia_ManStop( pMiter );
Cnf_DataFree( pCnf );
if ( RetValue == 0 )
Vec_IntFreeP( &vRes );
return vRes;
}
void Gia_ManGenRel( Gia_Man_t * pGia, Vec_Int_t * vInsOuts, int nIns, char * pFileName, int fVerbose )
{
abctime clkStart = Abc_Clock();
Vec_Int_t * vRes = Gia_ManGenIoCombs( pGia, vInsOuts, nIns, fVerbose );
if ( vRes == NULL ) {
printf( "Enumerating solutions did not succeed.\n" );
return;
}
Gia_ManGenWriteRel( vRes, nIns, Vec_IntSize(vInsOuts)-nIns, pFileName );
if ( fVerbose ) {
printf( "The resulting relation with %d input/output minterms is written into file \"%s\". ", Vec_IntSize(vRes), pFileName );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
if ( 0 ) {
int i, Mint;
Vec_IntForEachEntry( vRes, Mint, i )
Gia_ManPrintRelMinterm( Mint, nIns, Vec_IntSize(vInsOuts) );
}
}
Vec_IntFree( vRes );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -23,6 +23,7 @@
#include "misc/vec/vecQue.h"
#include "misc/vec/vecHsh.h"
#include "misc/util/utilTruth.h"
#include "base/io/ioResub.h"
ABC_NAMESPACE_IMPL_START
@ -67,7 +68,7 @@ int Gia_ObjCheckMffc_rec( Gia_Man_t * p,Gia_Obj_t * pObj, int Limit, Vec_Int_t *
return 0;
return 1;
}
static inline int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners )
int Gia_ObjCheckMffc( Gia_Man_t * p, Gia_Obj_t * pRoot, int Limit, Vec_Int_t * vNodes, Vec_Int_t * vLeaves, Vec_Int_t * vInners )
{
int RetValue, iObj, i;
Vec_IntClear( vNodes );
@ -2048,10 +2049,111 @@ Vec_Int_t * Gia_ManDeriveSubset( Gia_Man_t * p, Vec_Wrd_t * vFuncs, Vec_Int_t *
return vRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_ManResubFindUsed( Vec_Int_t * vRes, int nDivs, int nNodes, Vec_Int_t * vSupp )
{
int i, k, iLit, Counter = 1;
Vec_Int_t * vUsed = Vec_IntStartFull( nDivs );
Vec_Int_t * vRes2 = Vec_IntDup( vRes );
Vec_IntWriteEntry( vUsed, 0, 0 );
assert( Vec_IntSize(vRes) % 2 == 1 );
Vec_IntSort( vRes2, 0 );
Vec_IntForEachEntry( vRes2, iLit, k )
{
int iVar = Abc_Lit2Var(iLit);
if ( iVar > 0 && iVar < nDivs && Vec_IntEntry(vUsed, iVar) == -1 ) {
Vec_IntWriteEntry( vUsed, iVar, Counter++ );
Vec_IntPush( vSupp, iVar-2 );
}
}
Vec_IntFree( vRes2 );
for ( i = nDivs; i < nDivs + nNodes; i++ )
Vec_IntPush( vUsed, Counter++ );
return vUsed;
}
Vec_Int_t * Gia_ManResubRemapSolution( Vec_Int_t * vRes, Vec_Int_t * vUsed )
{
int i, iLit;
Vec_Int_t * vResNew = Vec_IntAlloc( Vec_IntSize(vRes) );
Vec_IntForEachEntry( vRes, iLit, i )
Vec_IntPush( vResNew, Abc_Lit2LitV(Vec_IntArray(vUsed), iLit) );
return vResNew;
}
void Gia_ManResubRecordSolution( char * pFileName, Vec_Int_t * vRes, int nDivs )
{
FILE * pFile = fopen( pFileName, "ab" );
if ( pFile == NULL ) {
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
return;
}
Vec_Int_t * vSupp = Vec_IntAlloc( 100 );
Vec_Int_t * vUsed = Gia_ManResubFindUsed( vRes, nDivs, Vec_IntSize(vRes)/2, vSupp );
Vec_Int_t * vResN = Gia_ManResubRemapSolution( vRes, vUsed );
int i, Temp;
fprintf( pFile, "\n.s" );
Vec_IntForEachEntry( vSupp, Temp, i )
fprintf( pFile, " %d", Temp );
fprintf( pFile, "\n.a" );
Vec_IntForEachEntry( vResN, Temp, i )
fprintf( pFile, " %d", Temp );
fprintf( pFile, "\n" );
fclose( pFile );
Vec_IntFree( vUsed );
Vec_IntFree( vSupp );
Vec_IntFree( vResN );
}
Gia_Man_t * Gia_ManResubUnateOne( char * pFileName, int nLimit, int nDivMax, int fWriteSol, int fVerbose )
{
Gia_Man_t * pNew = NULL;
Abc_RData_t * p = Abc_ReadPla( pFileName );
if ( p == NULL ) return NULL;
assert( p->nOuts == 1 );
Vec_Ptr_t * vDivs = Vec_PtrAlloc( 2+p->nIns );
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsOut, 0*p->nSimWords) );
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsOut, 1*p->nSimWords) );
int i, k, ArraySize, * pArray;
for ( i = 0; i < p->nIns; i++ )
Vec_PtrPush( vDivs, Vec_WrdEntryP(p->vSimsIn, i*p->nSimWords) );
Abc_ResubPrepareManager( p->nSimWords );
if ( fVerbose )
printf( "The problem has %d divisors and %d outputs.\n", p->nIns, p->nOuts );
ArraySize = Abc_ResubComputeFunction( (void **)Vec_PtrArray(vDivs), Vec_PtrSize(vDivs), p->nSimWords, nLimit, nDivMax, 0, 0, 1, fVerbose, &pArray );
for ( k = 0; k < ArraySize; k++ )
Vec_IntPush( vRes, pArray[k] );
if ( ArraySize ) {
//Vec_IntPrint( vRes );
Vec_Wec_t * vGates = Vec_WecStart(1);
Vec_IntAppend( Vec_WecEntry(vGates, 0), vRes );
pNew = Gia_ManConstructFromGates( vGates, Vec_PtrSize(vDivs) );
Vec_WecFree( vGates );
if ( fVerbose )
printf( "The solution has %d inputs and %d nodes.\n", Gia_ManCiNum(pNew), Gia_ManAndNum(pNew) );
}
if ( fWriteSol && ArraySize )
Gia_ManResubRecordSolution( pFileName, vRes, Vec_PtrSize(vDivs) );
Abc_ResubPrepareManager( 0 );
Vec_IntFree( vRes );
Vec_PtrFree( vDivs );
Abc_RDataStop( p );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -20,6 +20,7 @@
#include "gia.h"
#include "misc/util/utilTruth.h"
#include "base/io/ioResub.h"
ABC_NAMESPACE_IMPL_START
@ -45,6 +46,7 @@ struct Res6_Man_t_
Vec_Int_t vSol; // current solution
Vec_Int_t vSolBest; // best solution
Vec_Int_t vTempBest;// current best solution
Vec_Int_t vSupp; // support
};
extern void Dau_DsdPrintFromTruth2( word * pTruth, int nVarsInit );
@ -95,11 +97,47 @@ static inline void Res6_ManStop( Res6_Man_t * p )
Vec_IntErase( &p->vSol );
Vec_IntErase( &p->vSolBest );
Vec_IntErase( &p->vTempBest );
Vec_IntErase( &p->vSupp );
ABC_FREE( p->ppLits );
ABC_FREE( p->ppSets );
ABC_FREE( p );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Res6_Man_t * Res6_ManReadPla( char * pFileName )
{
int i, n;
Abc_RData_t * pData = Abc_ReadPla( pFileName ); assert( pData->nOuts == 1 );
Res6_Man_t * p = pData ? Res6_ManStart( 0, pData->nIns, pData->nOuts, pData->nPats ) : NULL;
if ( p == NULL ) return NULL;
assert( pData->nSimWords == p->nWords );
for ( i = 1; i < p->nDivs; i++ )
for ( n = 0; n < 2; n++ )
Abc_TtCopy( p->ppLits[2*i+n], Vec_WrdEntryP(pData->vSimsIn, (i-1)*pData->nSimWords), pData->nSimWords, n );
for ( i = 0; i < (1 << p->nOuts); i++ )
Abc_TtCopy( p->ppSets[i], Vec_WrdEntryP(pData->vSimsOut, i*pData->nSimWords), pData->nSimWords, 0 );
if ( pData->vDivs )
Vec_IntForEachEntry( pData->vDivs, n, i )
Vec_IntPush( &p->vSupp, 1+n );
if ( pData->vSol ) {
Vec_IntForEachEntry( pData->vSol, n, i )
Vec_IntPush( &p->vSol, n );
Vec_IntPush( &p->vSol, Vec_IntEntryLast(&p->vSol) );
}
Abc_RDataStop( pData );
return p;
}
/**Function*************************************************************
Synopsis []
@ -197,7 +235,7 @@ void Res6_ManWrite( char * pFileName, Res6_Man_t * p )
void Res6_ManPrintProblem( Res6_Man_t * p, int fVerbose )
{
int i, nInputs = (p->nIns && p->nIns < 6) ? p->nIns : 6;
printf( "Problem: In = %d Div = %d Out = %d Pattern = %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
printf( "Problem: In = %d Div = %d Out = %d Pat = %d\n", p->nIns, p->nDivs - p->nIns - 1, p->nOuts, p->nPats );
if ( !fVerbose )
return;
printf( "%02d : %s\n", 0, "const0" );
@ -426,6 +464,7 @@ void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose
{
Res6_Man_t * p = Res6_ManRead( pFileNameRes );
Vec_Int_t * vSol = Res6_ManReadSol( FileNameSol );
//Vec_IntPrint( vSol );
if ( p == NULL || vSol == NULL )
return;
if ( fVerbose )
@ -440,6 +479,80 @@ void Res6_ManResubCheck( char * pFileNameRes, char * pFileNameSol, int fVerbose
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Res6_FindBestEvalPla( Res6_Man_t * p, Vec_Int_t * vSol )
{
int i, n, iObj, iLit0, iLit1, iOffset = 2*(1+Vec_IntSize(&p->vSupp));
assert( Vec_IntSize(vSol) % 2 == 0 );
Vec_IntForEachEntry( &p->vSupp, iObj, i )
for ( n = 0; n < 2; n++ )
Abc_TtCopy( p->ppLits[2*(1+i)+n], p->ppLits[2*iObj+n], p->nWords, 0 );
Vec_IntForEachEntryDouble( vSol, iLit0, iLit1, i )
{
if ( iLit0 > iLit1 )
{
Abc_TtXor( p->ppLits[iOffset+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
Abc_TtXor( p->ppLits[iOffset+i+1], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 1 );
}
else
{
Abc_TtAnd( p->ppLits[iOffset+i+0], p->ppLits[iLit0], p->ppLits[iLit1], p->nWords, 0 );
Abc_TtOr ( p->ppLits[iOffset+i+1], p->ppLits[iLit0^1], p->ppLits[iLit1^1], p->nWords );
}
}
return Res6_FindGetCost( p, Vec_IntEntryLast(vSol) );
}
void Res6_ManResubVerifyPla( Res6_Man_t * p, Vec_Int_t * vSol )
{
int Cost = Res6_FindBestEvalPla( p, vSol );
if ( Cost == 0 )
printf( "Verification successful.\n" );
else
printf( "Verification FAILED with %d errors on %d patterns.\n", Cost, p->nPats );
}
void Res6_PrintSolutionPla( Vec_Int_t * vSol, int nSuppSize, int nDivs )
{
int iNode, nNodes = Vec_IntSize(vSol)/2-1;
assert( Vec_IntSize(vSol) % 2 == 0 );
printf( "Solution: In = %d Div = %d Node = %d Out = %d\n", nSuppSize, nDivs-1, nNodes, 1 );
for ( iNode = 0; iNode <= nNodes; iNode++ )
{
int * pLits = Vec_IntEntryP( vSol, 2*iNode );
printf( "x%-2d = ", 1+nSuppSize+iNode );
Res6_LitPrint( pLits[0], 1+nSuppSize );
if ( pLits[0] != pLits[1] )
{
printf( " %c ", pLits[0] < pLits[1] ? '&' : '^' );
Res6_LitPrint( pLits[1], 1+nSuppSize );
}
printf( "\n" );
}
}
void Res6_ManResubCheckPla( char * pFileName, int fVerbose )
{
Res6_Man_t * p = Res6_ManReadPla( pFileName );
if ( p == NULL ) return;
//Vec_IntPrint( &p->vSupp );
//Vec_IntPrint( &p->vSol );
if ( fVerbose )
Res6_ManPrintProblem( p, 0 );
if ( fVerbose )
Res6_PrintSolutionPla( &p->vSol, Vec_IntSize(&p->vSupp), p->nDivs );
//if ( fVerbose )
// Res6_PrintSuppSims( vSol, p->ppLits, p->nWords, p->nDivs );
Res6_ManResubVerifyPla( p, &p->vSol );
Res6_ManStop( p );
}
////////////////////////////////////////////////////////////////////////

42
src/aig/gia/giaRrr.cpp Normal file
View File

@ -0,0 +1,42 @@
#include "aig/gia/gia.h"
#include "opt/rrr/rrr.h"
#include "opt/rrr/rrrAbc.h"
ABC_NAMESPACE_IMPL_START
Gia_Man_t *Gia_ManRrr(Gia_Man_t *pGia, int iSeed, int nWords, int nTimeout, int nSchedulerVerbose, int nPartitionerVerbose, int nOptimizerVerbose, int nAnalyzerVerbose, int nSimulatorVerbose, int nSatSolverVerbose, int fUseBddCspf, int fUseBddMspf, int nConflictLimit, int nSortType, int nOptimizerFlow, int nSchedulerFlow, int nPartitionType, int nDistance, int nJobs, int nThreads, int nPartitionSize, int nPartitionSizeMin, int fDeterministic, int nParallelPartitions, int fOptOnInsert, int fGreedy) {
rrr::AndNetwork ntk;
ntk.Read(pGia, rrr::GiaReader<rrr::AndNetwork>);
rrr::Parameter Par;
Par.iSeed = iSeed;
Par.nWords = nWords;
Par.nTimeout = nTimeout;
Par.nSchedulerVerbose = nSchedulerVerbose;
Par.nPartitionerVerbose = nPartitionerVerbose;
Par.nOptimizerVerbose = nOptimizerVerbose;
Par.nAnalyzerVerbose = nAnalyzerVerbose;
Par.nSimulatorVerbose = nSimulatorVerbose;
Par.nSatSolverVerbose = nSatSolverVerbose;
Par.fUseBddCspf = fUseBddCspf;
Par.fUseBddMspf = fUseBddMspf;
Par.nConflictLimit = nConflictLimit;
Par.nSortType = nSortType;
Par.nOptimizerFlow = nOptimizerFlow;
Par.nSchedulerFlow = nSchedulerFlow;
Par.nPartitionType = nPartitionType;
Par.nDistance = nDistance;
Par.nJobs = nJobs;
Par.nThreads = nThreads;
Par.nPartitionSize = nPartitionSize;
Par.nPartitionSizeMin = nPartitionSizeMin;
Par.fDeterministic = fDeterministic;
Par.nParallelPartitions = nParallelPartitions;
Par.fOptOnInsert = fOptOnInsert;
Par.fGreedy = fGreedy;
rrr::Perform(&ntk, &Par);
Gia_Man_t *pNew = rrr::CreateGia(&ntk, false);
return pNew;
}
ABC_NAMESPACE_IMPL_END

View File

@ -20,11 +20,18 @@
#include "gia.h"
#include "misc/tim/tim.h"
#include "misc/util/utilTruth.h"
#include "sat/bsat/satStore.h"
#include "misc/util/utilNam.h"
#include "map/scl/sclCon.h"
#include "misc/vec/vecHsh.h"
#ifdef _MSC_VER
#define unlink _unlink
#else
#include <unistd.h>
#endif
ABC_NAMESPACE_IMPL_START
@ -632,7 +639,9 @@ static inline int Sbl_CutIsFeasible( word CutI1, word CutI2, word CutN1, word Cu
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
if ( LutSize <= 4 )
return Count <= 4;
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
if ( LutSize <= 5 )
return Count <= 5;
CutI1 &= CutI1-1; CutI2 &= CutI2-1; CutN1 &= CutN1-1; CutN2 &= CutN2-1; Count += (CutI1 != 0) + (CutI2 != 0) + (CutN1 != 0) + (CutN2 != 0);
return Count <= 6;
}
@ -1026,7 +1035,7 @@ int Sbl_ManTestSat( Sbl_Man_t * p, int iPivot )
StartSol = Vec_IntSize(p->vSolInit) + 1;
// StartSol = 30;
while ( fKeepTrying && StartSol-fKeepTrying > 0 )
while ( fKeepTrying && StartSol-fKeepTrying > 0 && StartSol-fKeepTrying < Vec_IntSize(p->vCardVars) )
{
int Count = 0, LitCount = 0;
int nConfBef, nConfAft;
@ -1216,6 +1225,864 @@ void Gia_ManLutSat( Gia_Man_t * pGia, int LutSize, int nNumber, int nImproves, i
Vec_IntFreeP( &pGia->vPacking );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_RunKadical( char * pFileNameIn, char * pFileNameOut, int Seed, int nBTLimit, int TimeOut, int fVerbose, int * pStatus )
{
extern Vec_Int_t * Exa4_ManParse( char *pFileName );
int fVerboseSolver = 0;
abctime clkTotal = Abc_Clock();
Vec_Int_t * vRes = NULL;
#ifdef _WIN32
char * pKadical = "kadical.exe";
#else
char * pKadical = "./kadical";
FILE * pFile = fopen( pKadical, "rb" );
if ( pFile == NULL )
pKadical += 2;
else
fclose( pFile );
#endif
char Command[1000], * pCommand = (char *)&Command;
if ( nBTLimit ) {
if ( TimeOut )
sprintf( pCommand, "%s --seed=%d -c %d -t %d %s %s > %s", pKadical, Seed, nBTLimit, TimeOut, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
else
sprintf( pCommand, "%s --seed=%d -c %d %s %s > %s", pKadical, Seed, nBTLimit, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
}
else {
if ( TimeOut )
sprintf( pCommand, "%s --seed=%d -t %d %s %s > %s", pKadical, Seed, TimeOut, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
else
sprintf( pCommand, "%s --seed=%d %s %s > %s", pKadical, Seed, fVerboseSolver ? "": "-q", pFileNameIn, pFileNameOut );
}
#ifdef __wasm
if ( 1 )
#else
if ( system( pCommand ) == -1 )
#endif
{
fprintf( stdout, "Command \"%s\" did not succeed.\n", pCommand );
return 0;
}
vRes = Exa4_ManParse( pFileNameOut );
if ( fVerbose )
{
if ( vRes )
printf( "The problem has a solution. " ), *pStatus = 0;
else if ( vRes == NULL && TimeOut == 0 )
printf( "The problem has no solution. " ), *pStatus = 1;
else if ( vRes == NULL )
printf( "The problem has no solution or reached a resource limit after %d sec. ", TimeOut ), *pStatus = -1;
Abc_PrintTime( 1, "SAT solver time", Abc_Clock() - clkTotal );
}
return vRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_SatVarReqPos( int i ) { return i*7+0; } // p
int Gia_SatVarReqNeg( int i ) { return i*7+1; } // n
int Gia_SatVarAckPos( int i ) { return i*7+2; } // P
int Gia_SatVarAckNeg( int i ) { return i*7+3; } // N
int Gia_SatVarInv ( int i ) { return i*7+4; } // i
int Gia_SatVarFan0 ( int i ) { return i*7+5; } // 0
int Gia_SatVarFan1 ( int i ) { return i*7+6; } // 1
int Gia_SatValReqPos( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+0); } // p
int Gia_SatValReqNeg( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+1); } // n
int Gia_SatValAckPos( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+2); } // P
int Gia_SatValAckNeg( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+3); } // N
int Gia_SatValInv ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+4); } // i
int Gia_SatValFan0 ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+5); } // 0
int Gia_SatValFan1 ( Vec_Int_t * p, int i ) { return Vec_IntEntry(p, i*7+6); } // 1
void Gia_SatDumpClause( Vec_Str_t * vStr, int * pLits, int nLits )
{
for ( int i = 0; i < nLits; i++ )
Vec_StrPrintF( vStr, "%d ", Abc_LitIsCompl(pLits[i]) ? -Abc_Lit2Var(pLits[i])-1 : Abc_Lit2Var(pLits[i])+1 );
Vec_StrPrintF( vStr, "0\n" );
}
void Gia_SatDumpLiteral( Vec_Str_t * vStr, int Lit )
{
Gia_SatDumpClause( vStr, &Lit, 1 );
}
void Gia_SatDumpKlause( Vec_Str_t * vStr, int nIns, int nAnds, int nBound )
{
int i, nVars = nIns + 7*nAnds;
Vec_StrPrintF( vStr, "k %d ", nVars - nBound );
// counting primary inputs: n
for ( i = 0; i < nIns; i++ )
Vec_StrPrintF( vStr, "-%d ", Gia_SatVarReqNeg(1+i)+1 );
// counting internal nodes: p, n, P, N, i, 0, 1
for ( i = 0; i < 7*nAnds; i++ )
Vec_StrPrintF( vStr, "-%d ", (1+nIns)*7+i+1 );
Vec_StrPrintF( vStr, "0\n" );
}
Vec_Str_t * Gia_ManSimpleCnf( Gia_Man_t * p, int nBound )
{
Vec_Str_t * vStr = Vec_StrAlloc( 10000 );
Gia_SatDumpKlause( vStr, Gia_ManCiNum(p), Gia_ManAndNum(p), nBound );
int i, n, m, Id, pLits[4]; Gia_Obj_t * pObj;
for ( n = 0; n < 7; n++ )
Gia_SatDumpLiteral( vStr, Abc_Var2Lit(n, 1) );
// acknowledge positive PI literals
Gia_ManForEachCiId( p, Id, i )
for ( n = 0; n < 7; n++ ) if ( n != 1 )
Gia_SatDumpLiteral( vStr, Abc_Var2Lit(Gia_SatVarReqPos(Id)+n, n>0) );
// require driving PO literals
Gia_ManForEachCo( p, pObj, i )
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId0p(p, pObj)) + Gia_ObjFaninC0(pObj), 0 ) );
// internal nodes
Gia_ManForEachAnd( p, pObj, i ) {
int fCompl[2] = { Gia_ObjFaninC0(pObj), Gia_ObjFaninC1(pObj) };
int iFans[2] = { Gia_ObjFaninId0(pObj, i), Gia_ObjFaninId1(pObj, i) };
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
// require inverter: p & !n & N -> i, n & !p & P -> i
for ( n = 0; n < 2; n++ ) {
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i)+n, 1 );
pLits[1] = Abc_Var2Lit( Gia_SatVarReqNeg(i)-n, 0 );
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i)-n, 1 );
pLits[3] = Abc_Var2Lit( Gia_SatVarInv (i), 0 );
Gia_SatDumpClause( vStr, pLits, 4 );
}
// exclusive acknowledge: !P + !N
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i), 1 );
pLits[1] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 1 );
Gia_SatDumpClause( vStr, pLits, 2 );
// required acknowledge: p -> P + N, n -> P + N
pLits[1] = Abc_Var2Lit( Gia_SatVarAckPos(i), 0 );
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 0 );
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
pLits[0] = Abc_Var2Lit( Gia_SatVarReqNeg(i), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
// forbid acknowledge: !p & !n -> !P, !p & !n -> !N
pLits[0] = Abc_Var2Lit( Gia_SatVarReqPos(i), 0 );
pLits[1] = Abc_Var2Lit( Gia_SatVarReqNeg(i), 0 );
pLits[2] = Abc_Var2Lit( Gia_SatVarAckPos(i), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
pLits[2] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
// when fanins can be used: !N & !P -> !0, !N & !P -> !1
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i), 0 );
pLits[1] = Abc_Var2Lit( Gia_SatVarAckNeg(i), 0 );
pLits[2] = Abc_Var2Lit( Gia_SatVarFan0(i), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
pLits[2] = Abc_Var2Lit( Gia_SatVarFan1(i), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
// when fanins are not used: 0 -> !N, 0 -> !P, 1 -> !N, 1 -> !P
for ( m = 0; m < 2; m++ )
for ( n = 0; n < 2; n++ ) {
pLits[0] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 );
pLits[1] = Abc_Var2Lit( Gia_SatVarReqPos(iFans[n])+m, 1 );
Gia_SatDumpClause( vStr, pLits, 2 );
}
// can only extend both when both complemented: !(C0 & C1) -> !0 + !1
pLits[0] = Abc_Var2Lit( Gia_SatVarFan0(i), 1 );
pLits[1] = Abc_Var2Lit( Gia_SatVarFan1(i), 1 );
if ( !fCompl[0] || !fCompl[1] )
Gia_SatDumpClause( vStr, pLits, 2 );
// if fanin is a primary input, cannot extend it (pi -> !0 or pi -> !1)
for ( n = 0; n < 2; n++ )
if ( Gia_ObjIsCi(pFans[n]) )
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 ) );
// propagating assignments when fanin is not used
// P & !0 -> C0 ? P0 : N0
// N & !0 -> C0 ? N0 : P0
// P & !1 -> C1 ? P1 : N1
// N & !1 -> C1 ? N1 : P1
for ( m = 0; m < 2; m++ )
for ( n = 0; n < 2; n++ ) {
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i)+m, 1 );
pLits[1] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 0 );
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(iFans[n]) + !(m ^ fCompl[n]), 0 );
Gia_SatDumpClause( vStr, pLits, 3 );
}
// propagating assignments when fanins are used
// P & 0 -> (C0 ^ C00) ? P00 : N00
// P & 0 -> (C0 ^ C01) ? P01 : N01
// N & 0 -> (C0 ^ C00) ? N00 : P00
// N & 0 -> (C0 ^ C01) ? N01 : P01
// P & 1 -> (C1 ^ C10) ? P10 : N10
// P & 1 -> (C1 ^ C11) ? P11 : N11
// N & 1 -> (C1 ^ C10) ? N10 : P10
// N & 1 -> (C1 ^ C11) ? N11 : P11
for ( m = 0; m < 2; m++ )
for ( n = 0; n < 2; n++ )
if ( Gia_ObjIsAnd(pFans[n]) ) {
pLits[0] = Abc_Var2Lit( Gia_SatVarAckPos(i)+m, 1 );
pLits[1] = Abc_Var2Lit( Gia_SatVarFan0(i)+n, 1 );
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId0p(p, pFans[n])) + !(m ^ fCompl[n] ^ Gia_ObjFaninC0(pFans[n])), 0 );
Gia_SatDumpClause( vStr, pLits, 3 );
pLits[2] = Abc_Var2Lit( Gia_SatVarReqPos(Gia_ObjFaninId1p(p, pFans[n])) + !(m ^ fCompl[n] ^ Gia_ObjFaninC1(pFans[n])), 0 );
Gia_SatDumpClause( vStr, pLits, 3 );
}
}
Vec_StrPush( vStr, '\0' );
return vStr;
}
typedef enum {
GIA_GATE_ZERO, // 0:
GIA_GATE_ONE, // 1:
GIA_GATE_BUF, // 2:
GIA_GATE_INV, // 3:
GIA_GATE_NAN2, // 4:
GIA_GATE_NOR2, // 5:
GIA_GATE_AOI21, // 6:
GIA_GATE_NAN3, // 7:
GIA_GATE_NOR3, // 8:
GIA_GATE_OAI21, // 9:
GIA_GATE_AOI22, // 10:
GIA_GATE_OAI22, // 11:
RTM_VAL_VOID // 12: unused value
} Gia_ManGate_t;
Vec_Int_t * Gia_ManDeriveSimpleMapping( Gia_Man_t * p, Vec_Int_t * vRes )
{
Vec_Int_t * vMapping = Vec_IntStart( 2*Gia_ManObjNum(p) );
int i, Id; Gia_Obj_t * pObj;
Gia_ManForEachCiId( p, Id, i )
if ( Gia_SatValReqNeg(vRes, Id) )
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(Id, 1), -1 );
Gia_ManForEachAnd( p, pObj, i )
{
if ( Gia_SatValAckPos(vRes, i) + Gia_SatValAckNeg(vRes, i) == 0 )
continue;
assert( Gia_SatValAckPos(vRes, i) != Gia_SatValAckNeg(vRes, i) );
if ( (Gia_SatValReqPos(vRes, i) && Gia_SatValReqNeg(vRes, i)) || Gia_SatValInv(vRes, i) )
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, Gia_SatValAckPos(vRes, i)), -1 );
int fComp = Gia_SatValAckNeg(vRes, i);
int fFan0 = Gia_SatValFan0(vRes, i);
int fFan1 = Gia_SatValFan1(vRes, i);
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, fComp), Vec_IntSize(vMapping) );
if ( fFan0 && fFan1 ) {
assert( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) );
Vec_IntPush( vMapping, 4 );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI22 : GIA_GATE_AOI22 );
} else if ( fFan0 ) {
Vec_IntPush( vMapping, 3 );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
if ( Gia_ObjFaninC0(pObj) )
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI21 : GIA_GATE_AOI21 );
else
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN3 : GIA_GATE_NOR3 );
} else if ( fFan1 ) {
Vec_IntPush( vMapping, 3 );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
if ( Gia_ObjFaninC1(pObj) )
Vec_IntPush( vMapping, fComp ? GIA_GATE_OAI21 : GIA_GATE_AOI21 );
else
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN3 : GIA_GATE_NOR3 );
} else {
Vec_IntPush( vMapping, 2 );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
Vec_IntPush( vMapping, fComp ? GIA_GATE_NAN2 : GIA_GATE_NOR2 );
}
}
return vMapping;
}
void Gia_ManSimplePrintMapping( Vec_Int_t * vRes, int nIns )
{
int i, k, nObjs = Vec_IntSize(vRes)/7, nSteps = Abc_Base10Log(nObjs);
int nCard = Vec_IntSum(vRes) - nIns; char NumStr[10];
printf( "Solution with cardinality %d:\n", nCard );
for ( k = 0; k < nSteps; k++ ) {
printf( " " );
for ( i = 0; i < nObjs; i++ ) {
sprintf( NumStr, "%02d", i );
printf( "%c", NumStr[k] );
}
printf( "\n" );
}
for ( k = 0; k < 7; k++ ) {
printf( "%c ", "pnPNi01"[k] );
for ( i = 0; i < nObjs; i++ )
if ( Vec_IntEntry( vRes, i*7+k ) == 0 )
printf( " " );
else
printf( "1" );
printf( "\n" );
}
}
int Gia_ManDumpCnf( char * pFileName, Vec_Str_t * vStr, int nVars )
{
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL ) { printf( "Cannot open input file \"%s\".\n", pFileName ); return 0; }
fprintf( pFile, "p knf %d %d\n%s\n", nVars, Vec_StrCountEntry(vStr, '\n'), Vec_StrArray(vStr) );
fclose( pFile );
return 1;
}
int Gia_ManDumpCnf2( Vec_Str_t * vStr, int nVars, int argc, char ** argv, abctime Time, int Status )
{
Vec_Str_t * vFileName = Vec_StrAlloc( 100 ); int c;
Vec_StrPrintF( vFileName, "%s", argv[0] + (argv[0][0] == '&') );
for ( c = 1; c < argc; c++ )
Vec_StrPrintF( vFileName, "_%s", argv[c] + (argv[c][0] == '-') );
Vec_StrPrintF( vFileName, ".cnf" );
Vec_StrPush( vFileName, '\0' );
FILE * pFile = fopen( Vec_StrArray(vFileName), "wb" );
if ( pFile == NULL ) { printf( "Cannot open output file \"%s\".\n", Vec_StrArray(vFileName) ); Vec_StrFree(vFileName); return 0; }
Vec_StrFree(vFileName);
fprintf( pFile, "c This file was generated by ABC command: \"" );
fprintf( pFile, "%s", argv[0] );
for ( c = 1; c < argc; c++ )
fprintf( pFile, " %s", argv[c] );
fprintf( pFile, "\" on %s\n", Gia_TimeStamp() );
fprintf( pFile, "c Cardinality CDCL (https://github.com/jreeves3/Cardinality-CDCL) found it to be " );
if ( Status == 1 )
fprintf( pFile, "UNSAT" );
if ( Status == 0 )
fprintf( pFile, "SAT" );
if ( Status == -1 )
fprintf( pFile, "UNDECIDED" );
fprintf( pFile, " in %.2f sec\n", 1.0*((double)(Time))/((double)CLOCKS_PER_SEC) );
fprintf( pFile, "p knf %d %d\n%s\n", nVars, Vec_StrCountEntry(vStr, '\n'), Vec_StrArray(vStr) );
fclose( pFile );
return 1;
}
int Gia_ManSimpleMapping( Gia_Man_t * p, int nBound, int Seed, int nBTLimit, int nTimeout, int fVerbose, int fKeepFile, int argc, char ** argv )
{
abctime clkStart = Abc_Clock();
srand(time(NULL));
int Status, Rand = ((((unsigned)rand()) << 12) ^ ((unsigned)rand())) & 0xFFFFFF;
char pFileNameI[32]; sprintf( pFileNameI, "_%06x_.cnf", Rand );
char pFileNameO[32]; sprintf( pFileNameO, "_%06x_.out", Rand );
if ( nBound == 0 )
nBound = 5 * Gia_ManAndNum(p);
Vec_Str_t * vStr = Gia_ManSimpleCnf( p, nBound/2 );
int nVars = 7*(Gia_ManObjNum(p)-Gia_ManCoNum(p));
if ( !Gia_ManDumpCnf(pFileNameI, vStr, nVars) ) {
Vec_StrFree( vStr );
return 0;
}
if ( fVerbose )
printf( "SAT variables = %d. SAT clauses = %d. Cardinality bound = %d. Conflict limit = %d. Timeout = %d.\n",
nVars, Vec_StrCountEntry(vStr, '\n'), nBound, nBTLimit, nTimeout );
Vec_Int_t * vRes = Gia_RunKadical( pFileNameI, pFileNameO, Seed, nBTLimit, nTimeout, fVerbose, &Status );
unlink( pFileNameI );
//unlink( pFileNameO );
if ( fKeepFile ) Gia_ManDumpCnf2( vStr, nVars, argc, argv, Abc_Clock() - clkStart, Status );
Vec_StrFree( vStr );
if ( vRes == NULL )
return 0;
Vec_IntFreeP( &p->vCellMapping );
assert( p->vCellMapping == NULL );
Vec_IntDrop( vRes, 0 );
if ( fVerbose ) Gia_ManSimplePrintMapping( vRes, Gia_ManCiNum(p) );
p->vCellMapping = Gia_ManDeriveSimpleMapping( p, vRes );
Vec_IntFree( vRes );
if ( fVerbose ) Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
return 1;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
#define KSAT_OBJS 24
#define KSAT_MINTS 64
#define KSAT_SPACE (4+3*KSAT_OBJS+3*KSAT_MINTS)
int Gia_KSatVarInv( int * pMap, int i ) { return pMap[i*KSAT_SPACE+0]; }
int Gia_KSatVarAnd( int * pMap, int i ) { return pMap[i*KSAT_SPACE+1]; }
int Gia_KSatVarEqu( int * pMap, int i ) { return pMap[i*KSAT_SPACE+2]; }
int Gia_KSatVarRef( int * pMap, int i ) { return pMap[i*KSAT_SPACE+3]; }
int Gia_KSatVarFan( int * pMap, int i, int f, int k ) { return pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k]; }
int Gia_KSatVarMin( int * pMap, int i, int m, int k ) { return pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k]; }
void Gia_KSatSetInv( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+0] ); pMap[i*KSAT_SPACE+0] = iVar; }
void Gia_KSatSetAnd( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+1] ); pMap[i*KSAT_SPACE+1] = iVar; }
void Gia_KSatSetEqu( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+2] ); pMap[i*KSAT_SPACE+2] = iVar; }
void Gia_KSatSetRef( int * pMap, int i, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+3] ); pMap[i*KSAT_SPACE+3] = iVar; }
void Gia_KSatSetFan( int * pMap, int i, int f, int k, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] ); pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] = iVar; }
void Gia_KSatSetMin( int * pMap, int i, int m, int k, int iVar ) { assert( -1 == pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] ); pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] = iVar; }
int Gia_KSatValInv( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+0] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+0] ); }
int Gia_KSatValAnd( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+1] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+1] ); }
int Gia_KSatValEqu( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+2] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+2] ); }
int Gia_KSatValRef( int * pMap, int i, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+3] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+3] ); }
int Gia_KSatValFan( int * pMap, int i, int f, int k, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+4+f*KSAT_OBJS+k] ); }
int Gia_KSatValMin( int * pMap, int i, int m, int k, Vec_Int_t * vRes ) { assert( -1 != pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] ); return Vec_IntEntry( vRes, pMap[i*KSAT_SPACE+4+3*KSAT_OBJS+3*m+k] ); }
int * Gia_KSatMapInit( int nIns, int nNodes, word Truth, int * pnVars )
{
assert( nIns + nNodes <= KSAT_OBJS );
assert( (1 << nIns) <= KSAT_MINTS );
int n, m, f, k, nVars = 2, * pMap = ABC_FALLOC( int, KSAT_OBJS*KSAT_SPACE );
for ( n = nIns; n < nIns+nNodes; n++ ) {
Gia_KSatSetInv(pMap, n, nVars++);
Gia_KSatSetAnd(pMap, n, nVars++);
Gia_KSatSetEqu(pMap, n, nVars++);
Gia_KSatSetRef(pMap, n, nVars++);
}
for ( n = nIns; n < nIns+nNodes; n++ ) {
for ( f = 0; f < 2; f++ )
for ( k = 0; k < n; k++ )
Gia_KSatSetFan(pMap, n, f, k, nVars++);
for ( k = n+1; k < nIns+nNodes; k++ )
Gia_KSatSetFan(pMap, n, 2, k, nVars++);
}
for ( m = 0; m < (1<<nIns); m++ ) {
for ( n = 0; n < nIns; n++ )
Gia_KSatSetMin(pMap, n, m, 0, (m >> n) & 1 );
Gia_KSatSetMin(pMap, nIns+nNodes-1, m, 0, (Truth >> m) & 1 );
for ( n = nIns; n < nIns+nNodes; n++ )
for ( k = 0; k < 3; k++ )
if ( k || n < nIns+nNodes-1 )
Gia_KSatSetMin(pMap, n, m, k, nVars++);
}
if ( pnVars ) *pnVars = nVars;
return pMap;
}
int Gia_KSatFindFan( int * pMap, int i, int f, Vec_Int_t * vRes )
{
assert( f < 2 );
for ( int k = 0; k < i; k++ )
if ( Gia_KSatValFan( pMap, i, f, k, vRes ) )
return k;
assert( 0 );
return -1;
}
Vec_Int_t * Gia_ManKSatGenLevels( char * pGuide, int nIns, int nNodes )
{
Vec_Int_t * vRes;
int i, k, Count = 0;
for ( i = 0; pGuide[i]; i++ )
Count += pGuide[i] - '0';
if ( Count != nNodes ) {
printf( "Guidance %s has %d nodes while the problem has %d nodes.\n", pGuide, Count, nNodes );
return NULL;
}
int FirstPrev = 0;
int FirstThis = nIns;
int FirstNext = FirstThis;
vRes = Vec_IntStartFull( 2*nIns );
for ( i = 0; pGuide[i]; i++ ) {
FirstNext += pGuide[i] - '0';
for ( k = FirstThis; k < FirstNext; k++ )
Vec_IntPushTwo( vRes, FirstPrev, FirstThis );
FirstPrev = FirstThis;
FirstThis = FirstNext;
}
assert( Vec_IntSize(vRes) == 2*(nIns + nNodes) );
Count = 0;
//int Start, Stop;
//Vec_IntForEachEntryDouble(vRes, Start, Stop, i)
// printf( "%2d : Start %2d Stop %2d\n", Count++, Start, Stop );
return vRes;
}
Vec_Str_t * Gia_ManKSatCnf( int * pMap, int nIns, int nNodes, int nBound, int fMultiLevel, char * pGuide )
{
Vec_Str_t * vStr = Vec_StrAlloc( 10000 );
Vec_Int_t * vRes = pGuide ? Gia_ManKSatGenLevels( pGuide, nIns, nNodes ) : NULL;
int i, j, m, n, f, c, a, Start, Stop, nLits = 0, pLits[256] = {0};
Gia_SatDumpLiteral( vStr, 1 );
Gia_SatDumpLiteral( vStr, 2 );
if ( vRes ) {
n = nIns;
Vec_IntForEachEntryDoubleStart( vRes, Start, Stop, i, 2*nIns ) {
for ( j = 0; j < Start; j++ )
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 ) );
for ( f = 0; f < 2; f++ )
for ( j = Stop; j < n; j++ )
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, j), 1 ) );
n++;
}
assert( n == nIns + nNodes );
}
// fanins are connected once
for ( n = nIns; n < nIns+nNodes; n++ )
for ( f = 0; f < 2; f++ ) {
nLits = 0;
for ( i = 0; i < n; i++ )
pLits[nLits++] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 0 );
Gia_SatDumpClause( vStr, pLits, nLits );
/*
for ( i = 0; i < n; i++ )
for ( j = 0; j < i; j++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, j), 1 );
Gia_SatDumpClause( vStr, pLits, 2 );
}
*/
Vec_StrPrintF( vStr, "k %d ", n-1 );
for ( i = 0; i < n; i++ )
pLits[i] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
Gia_SatDumpClause( vStr, pLits, n );
}
for ( n = nIns; n < nIns+nNodes; n++ ) {
// fanins are equal
for ( i = 0; i < n; i++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, i), 1 );
pLits[2] = Abc_Var2Lit( Gia_KSatVarEqu(pMap, n), 0 );
Gia_SatDumpClause( vStr, pLits, 3 );
}
for ( i = 0; i < n; i++ )
for ( j = i+1; j < n; j++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 );
pLits[2] = Abc_Var2Lit( Gia_KSatVarEqu(pMap, n), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
}
// if fanins are equal, inv is used
pLits[0] = Abc_Var2Lit( Gia_KSatVarEqu(pMap, n), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), 0 );
Gia_SatDumpClause( vStr, pLits, 2 );
// fanin ordering
for ( i = 0; i < n; i++ )
for ( j = 0; j < i; j++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 );
Gia_SatDumpClause( vStr, pLits, 2 );
}
}
for ( n = nIns; n < nIns+nNodes-1; n++ ) {
// there is a fanout to the node above
for ( i = n+1; i < nIns+nNodes; i++ ) {
for ( f = 0; f < 2; f++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, i, f, n), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 0 );
Gia_SatDumpClause( vStr, pLits, 2 );
}
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, i, 0, n), 0 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, i, 1, n), 0 );
pLits[2] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 1 );
Gia_SatDumpClause( vStr, pLits, 3 );
}
// there is at least one fanout, except the last one
nLits = 0;
for ( i = n+1; i < nIns+nNodes; i++ )
pLits[nLits++] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 0 );
assert( nLits > 0 );
Gia_SatDumpClause( vStr, pLits, nLits );
}
// there is more than one fanout, except the last one
for ( n = nIns; n < nIns+nNodes-1; n++ ) {
for ( i = n+1; i < nIns+nNodes; i++ )
for ( j = i+1; j < nIns+nNodes; j++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 2, j), 1 );
pLits[2] = Abc_Var2Lit( Gia_KSatVarRef(pMap, n), 0 );
Gia_SatDumpClause( vStr, pLits, 3 );
}
// if more than one fanout, inv is used
pLits[0] = Abc_Var2Lit( Gia_KSatVarRef(pMap, n), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), 0 );
Gia_SatDumpClause( vStr, pLits, 2 );
// if inv is not used, its fanins' invs are used
if ( !fMultiLevel ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), 0 );
for ( i = nIns; i < n; i++ )
for ( f = 0; f < 2; f++ ) {
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
pLits[2] = Abc_Var2Lit( Gia_KSatVarInv(pMap, i), 0 );
Gia_SatDumpClause( vStr, pLits, 3 );
}
}
}
// the last one always uses inverter
Gia_SatDumpLiteral( vStr, Abc_Var2Lit( Gia_KSatVarInv(pMap, nIns+nNodes-1), 0 ) );
/*
// for each minterm, for each pair of possible fanins, the node's output is determined using and/or and inv (4*N*N*M)
for ( m = 0; m < (1 << nIns); m++ )
for ( n = nIns; n < nIns+nNodes; n++ )
for ( c = 0; c < 2; c++ )
for ( a = 0; a < 2; a++ ) {
// implications: Fan(f) & Mint(m) & !And & !Inv -> Val1
for ( f = 0; f < 2; f++ )
for ( i = 0; i < n; i++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarMin(pMap, i, m, 0), !a );
pLits[2] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
pLits[3] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
pLits[4] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a^c );
Gia_SatDumpClause( vStr, pLits, 5 );
}
// large clauses: Fan(0) & Fan(1) & !Mint(m) & !Mint(m) & !And & !Inv -> Val0
for ( i = 0; i < n; i++ )
for ( j = i; j < n; j++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 0, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, 1, j), 1 );
pLits[2] = Abc_Var2Lit( Gia_KSatVarMin(pMap, i, m, 0), a );
pLits[3] = Abc_Var2Lit( Gia_KSatVarMin(pMap, j, m, 0), a );
pLits[4] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
pLits[5] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
pLits[6] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a==c );
Gia_SatDumpClause( vStr, pLits, 7 );
}
}
*/
// for each minterm, define a fanin variable and use it to get the node's output based on and/or and inv (4*N*N*M)
for ( m = 0; m < (1 << nIns); m++ )
for ( n = nIns; n < nIns+nNodes; n++ ) {
for ( i = 0; i < n; i++ )
for ( f = 0; f < 2; f++ )
for ( c = 0; c < 2; c++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarFan(pMap, n, f, i), 1 );
pLits[1] = Abc_Var2Lit( Gia_KSatVarMin(pMap, i, m, 0), c );
pLits[2] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 1+f), !c );
Gia_SatDumpClause( vStr, pLits, 3 );
}
for ( c = 0; c < 2; c++ )
for ( a = 0; a < 2; a++ ) {
// implications: Mint(m,f) & !And & !Inv -> Val1
for ( f = 0; f < 2; f++ ) {
pLits[0] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 1+f), !a );
pLits[1] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
pLits[2] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
pLits[3] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a^c );
Gia_SatDumpClause( vStr, pLits, 4 );
}
// large clauses: !Mint(m,0) & !Mint(m,1) & !And & !Inv -> Val0
pLits[0] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 1), a );
pLits[1] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 2), a );
pLits[2] = Abc_Var2Lit( Gia_KSatVarAnd(pMap, n), a );
pLits[3] = Abc_Var2Lit( Gia_KSatVarInv(pMap, n), c );
pLits[4] = Abc_Var2Lit( Gia_KSatVarMin(pMap, n, m, 0), a==c );
Gia_SatDumpClause( vStr, pLits, 5 );
}
}
// the number of nodes with duplicated fanins and without inv is maximized
if ( nBound && 2*nNodes > nBound ) {
Vec_StrPrintF( vStr, "k %d ", 2*nNodes-nBound );
nLits = 0;
for ( n = nIns; n < nIns+nNodes; n++ ) {
pLits[nLits++] = Abc_Var2Lit(Gia_KSatVarEqu(pMap, n), 0);
pLits[nLits++] = Abc_Var2Lit(Gia_KSatVarInv(pMap, n), 1);
}
Gia_SatDumpClause( vStr, pLits, nLits );
}
Vec_StrPush( vStr, '\0' );
Vec_IntFreeP( &vRes );
return vStr;
}
typedef enum {
GIA_GATE2_ZERO, // 0:
GIA_GATE2_ONE, // 1:
GIA_GATE2_BUF, // 2:
GIA_GATE2_INV, // 3:
GIA_GATE2_NAN2, // 4:
GIA_GATE2_NOR2, // 5:
GIA_GATE2_AOI21, // 6:
GIA_GATE2_NAN3, // 7:
GIA_GATE2_NOR3, // 8:
GIA_GATE2_OAI21, // 9:
GIA_GATE2_NOR4, // 10:
GIA_GATE2_AOI211, // 11:
GIA_GATE2_AOI22, // 12:
GIA_GATE2_NAN4, // 13:
GIA_GATE2_OAI211, // 14:
GIA_GATE2_OAI22, // 15:
GIA_GATE2_VOID // 16: unused value
} Gia_ManGate2_t;
Vec_Int_t * Gia_ManDeriveKSatMappingArray( Gia_Man_t * p, Vec_Int_t * vRes )
{
Vec_Int_t * vMapping = Vec_IntStart( 2*Gia_ManObjNum(p) );
int i, Id; Gia_Obj_t * pObj;
Gia_ManForEachCiId( p, Id, i )
if ( Vec_IntEntry(vRes, Id) )
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(Id, 1), -1 );
Gia_ManForEachAnd( p, pObj, i ) {
assert( Vec_IntEntry(vRes, i) > 0 );
if ( (Vec_IntEntry(vRes, i) & 2) == 0 ) {
assert( (Vec_IntEntry(vRes, i) & 1) == 0 );
continue;
}
Gia_Obj_t * pFans[2] = { Gia_ObjFanin0(pObj), Gia_ObjFanin1(pObj) };
int fComp = ((Vec_IntEntry(vRes, i) >> 2) & 1) != 0;
int fFan0 = ((Vec_IntEntry(vRes, Gia_ObjFaninId0(pObj, i)) >> 1) & 1) == 0 && Gia_ObjIsAnd(pFans[0]);
int fFan1 = ((Vec_IntEntry(vRes, Gia_ObjFaninId1(pObj, i)) >> 1) & 1) == 0 && Gia_ObjIsAnd(pFans[1]);
if ( Vec_IntEntry(vRes, i) & 1 )
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, !fComp), -1 );
Vec_IntWriteEntry( vMapping, Abc_Var2Lit(i, fComp), Vec_IntSize(vMapping) );
if ( fFan0 && fFan1 ) {
Vec_IntPush( vMapping, 4 );
if ( !Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) ) {
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
}
else {
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
}
if ( Gia_ObjFaninC0(pObj) && Gia_ObjFaninC1(pObj) )
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI22 : GIA_GATE2_AOI22 );
else if ( !Gia_ObjFaninC0(pObj) && !Gia_ObjFaninC1(pObj) )
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN4 : GIA_GATE2_NOR4 );
else
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI211 : GIA_GATE2_AOI211 );
} else if ( fFan0 ) {
Vec_IntPush( vMapping, 3 );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC0(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[0]), !(fComp ^ Gia_ObjFaninC0(pObj) ^ Gia_ObjFaninC1(pFans[0]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
if ( Gia_ObjFaninC0(pObj) )
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI21 : GIA_GATE2_AOI21 );
else
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN3 : GIA_GATE2_NOR3 );
} else if ( fFan1 ) {
Vec_IntPush( vMapping, 3 );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC0(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pFans[1]), !(fComp ^ Gia_ObjFaninC1(pObj) ^ Gia_ObjFaninC1(pFans[1]))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
if ( Gia_ObjFaninC1(pObj) )
Vec_IntPush( vMapping, fComp ? GIA_GATE2_OAI21 : GIA_GATE2_AOI21 );
else
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN3 : GIA_GATE2_NOR3 );
} else {
Vec_IntPush( vMapping, 2 );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId0p(p, pObj), !(fComp ^ Gia_ObjFaninC0(pObj))) );
Vec_IntPush( vMapping, Abc_Var2Lit(Gia_ObjFaninId1p(p, pObj), !(fComp ^ Gia_ObjFaninC1(pObj))) );
Vec_IntPush( vMapping, fComp ? GIA_GATE2_NAN2 : GIA_GATE2_NOR2 );
}
}
return vMapping;
}
Gia_Man_t * Gia_ManDeriveKSatMapping( Vec_Int_t * vRes, int * pMap, int nIns, int nNodes, int fVerbose )
{
Vec_Int_t * vGuide = Vec_IntStart( 1000 );
Gia_Man_t * pNew = Gia_ManStart( nIns + nNodes + 2 );
pNew->pName = Abc_UtilStrsav( "test" );
int i, nSave = 0, pCopy[256] = {0};
for ( i = 1; i <= nIns; i++ )
pCopy[i] = Gia_ManAppendCi( pNew );
for ( i = nIns; i < nIns+nNodes; i++ ) {
int iFan0 = Gia_KSatFindFan( pMap, i, 0, vRes );
int iFan1 = Gia_KSatFindFan( pMap, i, 1, vRes );
if ( iFan0 == iFan1 )
pCopy[i+1] = pCopy[iFan0+1];
else if ( Gia_KSatValAnd(pMap, i, vRes) )
pCopy[i+1] = Gia_ManAppendAnd( pNew, pCopy[iFan0+1], pCopy[iFan1+1] );
else
pCopy[i+1] = Gia_ManAppendOr( pNew, pCopy[iFan0+1], pCopy[iFan1+1] );
pCopy[i+1] = Abc_LitNotCond( pCopy[i+1], Gia_KSatValInv(pMap, i, vRes) );
if ( iFan0 == iFan1 )
*Vec_IntEntryP(vGuide, Abc_Lit2Var(pCopy[i+1])) ^= 1;
else if ( Gia_KSatValAnd(pMap, i, vRes) )
*Vec_IntEntryP(vGuide, Abc_Lit2Var(pCopy[i+1])) ^= 4 | (2*Gia_KSatValInv(pMap, i, vRes));
else
*Vec_IntEntryP(vGuide, Abc_Lit2Var(pCopy[i+1])) ^= 8 | (2*Gia_KSatValInv(pMap, i, vRes));
if ( fVerbose ) {
if ( i == nIns+nNodes-1 )
printf( " F = " );
else
printf( "%2d = ", i );
if ( iFan0 == iFan1 )
printf( "INV( %d )\n", iFan0 );
else if ( Gia_KSatValAnd(pMap, i, vRes) )
printf( "%sAND( %d, %d )\n", Gia_KSatValInv(pMap, i, vRes) ? "N":"", iFan0, iFan1 );
else
printf( "%sOR( %d, %d )\n", Gia_KSatValInv(pMap, i, vRes) ? "N":"", iFan0, iFan1 );
nSave += (iFan0 == iFan1) || !Gia_KSatValInv(pMap, i, vRes);
if ( i == nIns+nNodes-1 )
printf( "Solution cost = %d\n", 2*(2*nNodes - nSave) );
}
}
Gia_ManAppendCo( pNew, pCopy[nIns+nNodes] );
//pNew->vCellMapping = Gia_ManDeriveKSatMappingArray( pNew, vGuide );
Vec_IntFree( vGuide );
return pNew;
}
word Gia_ManGetTruth( Gia_Man_t * p )
{
Gia_Obj_t * pObj; int i, Id;
word pFuncs[256] = {0}, Const[2] = {0, ~(word)0};
assert( Gia_ManObjNum(p) <= 256 );
Gia_ManForEachCiId( p, Id, i )
pFuncs[Id] = s_Truths6[i];
Gia_ManForEachAnd( p, pObj, i )
pFuncs[i] = (Const[Gia_ObjFaninC0(pObj)] ^ pFuncs[Gia_ObjFaninId0(pObj, i)]) & (Const[Gia_ObjFaninC1(pObj)] ^ pFuncs[Gia_ObjFaninId1(pObj, i)]);
pObj = Gia_ManCo(p, 0);
return Const[Gia_ObjFaninC0(pObj)] ^ pFuncs[Gia_ObjFaninId0p(p, pObj)];
}
Gia_Man_t * Gia_ManKSatMapping( word Truth, int nIns, int nNodes, int nBound, int Seed, int fMultiLevel, int nBTLimit, int nTimeout, int fVerbose, int fKeepFile, int argc, char ** argv, char * pGuide )
{
abctime clkStart = Abc_Clock();
Gia_Man_t * pNew = NULL;
srand(time(NULL));
int Status, Rand = ((((unsigned)rand()) << 12) ^ ((unsigned)rand())) & 0xFFFFFF;
char pFileNameI[32]; sprintf( pFileNameI, "_%06x_.cnf", Rand );
char pFileNameO[32]; sprintf( pFileNameO, "_%06x_.out", Rand );
int nVars = 0, * pMap = Gia_KSatMapInit( nIns, nNodes, Truth, &nVars );
Vec_Str_t * vStr = Gia_ManKSatCnf( pMap, nIns, nNodes, nBound/2, fMultiLevel, pGuide );
if ( !Gia_ManDumpCnf(pFileNameI, vStr, nVars) ) {
Vec_StrFree( vStr );
return NULL;
}
if ( fVerbose )
printf( "Vars = %d. Nodes = %d. Cardinality bound = %d. SAT vars = %d. SAT clauses = %d. Conflict limit = %d. Timeout = %d.\n",
nIns, nNodes, nBound, nVars, Vec_StrCountEntry(vStr, '\n'), nBTLimit, nTimeout );
Vec_Int_t * vRes = Gia_RunKadical( pFileNameI, pFileNameO, Seed, nBTLimit, nTimeout, 1, &Status );
unlink( pFileNameI );
//unlink( pFileNameO );
if ( fKeepFile ) Gia_ManDumpCnf2( vStr, nVars, argc, argv, Abc_Clock() - clkStart, Status );
Vec_StrFree( vStr );
if ( vRes == NULL )
return 0;
Vec_IntDrop( vRes, 0 );
pNew = Gia_ManDeriveKSatMapping( vRes, pMap, nIns, nNodes, fVerbose );
printf( "Verification %s. ", Truth == Gia_ManGetTruth(pNew) ? "passed" : "failed" );
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
Vec_IntFree( vRes );
ABC_FREE( pMap );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -1129,7 +1129,7 @@ void Gia_ManShow( Gia_Man_t * pMan, Vec_Int_t * vBold, int fAdders, int fFadds,
char FileNameDot[200];
FILE * pFile;
Vec_Int_t * vXors = NULL, * vAdds = fAdders ? Ree_ManComputeCuts( pMan, &vXors, 0 ) : NULL;
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName, ".dot") );
sprintf( FileNameDot, "%s", Extra_FileNameGenericAppend(pMan->pName ? pMan->pName : (char *)"unknown", ".dot") );
// check that the file can be opened
if ( (pFile = fopen( FileNameDot, "w" )) == NULL )
{

View File

@ -490,13 +490,16 @@ int Gia_ManSifCheckIter( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, i
}
int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes, int nLutSize, int Period, int * pIters )
{
Gia_Obj_t * pObj; int i, Id, nSize = nLutSize+1;
Gia_Obj_t * pObj; int i, Id, Stop, nSize = nLutSize+1;
assert( Gia_ManRegNum(p) > 0 );
Gia_ManForEachCiId( p, Id, i )
Vec_IntWriteEntry( vCuts, Id*nSize, 1 );
Gia_ManForEachCiId( p, Id, i )
Vec_IntWriteEntry( vCuts, Id*nSize+1, Id << 8 );
Vec_IntFill( vTimes, Gia_ManObjNum(p), -Period );
if ( p->vStopsF )
Vec_StrForEachEntry( p->vStopsF, Stop, i )
if ( Stop ) Vec_IntWriteEntry( vTimes, i, 0 );
Vec_IntWriteEntry( vTimes, 0, 0 );
Gia_ManForEachPi( p, pObj, i )
Vec_IntWriteEntry( vTimes, Gia_ObjId(p, pObj), 0 );
@ -510,6 +513,10 @@ int Gia_ManSifCheckPeriod( Gia_Man_t * p, Vec_Int_t * vCuts, Vec_Int_t * vTimes,
Gia_ManForEachObj( p, pObj, i )
if ( Vec_IntEntry(vTimes, Gia_ObjId(p, pObj)) > 2*Period )
return 0;
if ( p->vStopsB )
Vec_StrForEachEntry( p->vStopsB, Stop, i )
if ( Stop && Vec_IntEntry(vTimes, i) > Period )
return 0;
}
return 0;
}
@ -638,6 +645,25 @@ Gia_Man_t * Gia_ManSifPerform( Gia_Man_t * p, int nLutSize, int fEvalOnly, int f
pNew = Gia_ManSifTransform( p, vCuts, vTimes, nLutSize, Upper, fVerbose );
Vec_IntFree( vCuts );
Vec_IntFree( vTimes );
//Gia_ManTransferTiming( pNew, p );
if ( p->vNamesIn ) {
char * pName; int i;
pNew->vNamesIn = p->vNamesIn; p->vNamesIn = NULL;
Vec_PtrForEachEntryStart( char *, pNew->vNamesIn, pName, i, Gia_ManPiNum(pNew) )
ABC_FREE( pName );
Vec_PtrShrink( pNew->vNamesIn, Gia_ManPiNum(pNew) );
for ( i = 0; i < Gia_ManRegNum(pNew); i++ )
Vec_PtrPush( pNew->vNamesIn, Abc_UtilStrsavNum("_fo", i) );
}
if ( p->vNamesOut ) {
char * pName; int i;
pNew->vNamesOut = p->vNamesOut; p->vNamesOut = NULL;
Vec_PtrForEachEntryStart( char *, pNew->vNamesOut, pName, i, Gia_ManPoNum(pNew) )
ABC_FREE( pName );
Vec_PtrShrink( pNew->vNamesOut, Gia_ManPoNum(pNew) );
for ( i = 0; i < Gia_ManRegNum(pNew); i++ )
Vec_PtrPush( pNew->vNamesOut, Abc_UtilStrsavNum("_fi", i) );
}
return pNew;
}

View File

@ -288,6 +288,21 @@ void Gia_ManSimPatWrite( char * pFileName, Vec_Wrd_t * vSimsIn, int nWords )
SeeAlso []
***********************************************************************/
Vec_Wrd_t * Gia_ManDeriveNodeFuncs( Gia_Man_t * p )
{
int nWords = Abc_Truth6WordNum( Gia_ManCiNum(p) );
Vec_Wrd_t * vSims = Vec_WrdStart( nWords * Gia_ManObjNum(p) );
Gia_Obj_t * pObj; int i;
Gia_ManForEachCi( p, pObj, i )
assert( Gia_ObjId(p, pObj) == i+1 );
Vec_Ptr_t * vTruths = Vec_PtrAllocTruthTables( Gia_ManCiNum(p) );
Gia_ManForEachCi( p, pObj, i )
Abc_TtCopy( Vec_WrdEntryP(vSims, nWords*(i+1)), (word *)Vec_PtrEntry(vTruths, i), nWords, 0 );
Vec_PtrFree( vTruths );
Gia_ManForEachAnd( p, pObj, i )
Gia_ManSimPatSimAnd( p, i, pObj, nWords, vSims );
return vSims;
}
word * Gia_ManDeriveFuncs( Gia_Man_t * p )
{
int nVars2 = (Gia_ManCiNum(p) + 6)/2;
@ -3199,7 +3214,7 @@ Vec_Int_t * Gia_ManRelDeriveSimple( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Int_t
void Gia_ManRelSolve( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Int_t * vIns, Vec_Int_t * vOuts, Vec_Int_t * vRel, Vec_Int_t * vDivs )
{
extern Mini_Aig_t * Exa4_ManGenTest( Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsOut, int nIns, int nDivs, int nOuts, int nNodes, int TimeOut, int fOnlyAnd, int fFancy, int fOrderNodes, int fUniqFans, int fVerbose );
extern Mini_Aig_t * Exa4_ManGenTest( Vec_Wrd_t * vSimsIn, Vec_Wrd_t * vSimsOut, int nIns, int nDivs, int nOuts, int nNodes, int TimeOut, int fOnlyAnd, int fFancy, int fOrderNodes, int fUniqFans, int fVerbose, int fCard, char * pGuide );
int i, m, iObj, Entry, iMint = 0, nMints = Vec_IntSize(vRel) - Vec_IntCountEntry(vRel, -1);
Vec_Wrd_t * vSimsIn = Vec_WrdStart( nMints );
@ -3232,7 +3247,7 @@ void Gia_ManRelSolve( Gia_Man_t * p, Vec_Wrd_t * vSims, Vec_Int_t * vIns, Vec_In
}
assert( iMint == nMints );
printf( "Created %d minterms.\n", iMint );
Exa4_ManGenTest( vSimsIn, vSimsOut, Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), 10, 0, 0, 0, 0, 0, 1 );
Exa4_ManGenTest( vSimsIn, vSimsOut, Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), 10, 0, 0, 0, 0, 0, 1, 0, NULL );
Vec_WrdFree( vSimsIn );
Vec_WrdFree( vSimsOut );
}
@ -3625,7 +3640,7 @@ Gia_Man_t * Gia_ManChangeTest3( Gia_Man_t * p )
{
extern void Exa6_WriteFile2( char * pFileName, int nVars, int nDivs, int nOuts, Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut );
extern void Exa_ManExactPrint( Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut, int nDivs, int nOuts );
extern Mini_Aig_t * Exa_ManExactSynthesis6Int( Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut, int nVars, int nDivs, int nOuts, int nNodes, int fOnlyAnd, int fVerbose );
extern Mini_Aig_t * Exa_ManExactSynthesis6Int( Vec_Wrd_t * vSimsDiv, Vec_Wrd_t * vSimsOut, int nVars, int nDivs, int nOuts, int nNodes, int fOnlyAnd, int fVerbose, char * pFileName );
extern Gia_Man_t * Gia_ManDupMini( Gia_Man_t * p, Vec_Int_t * vIns, Vec_Int_t * vDivs, Vec_Int_t * vOuts, Mini_Aig_t * pMini );
Gia_Man_t * pNew = NULL;
@ -3639,7 +3654,7 @@ Gia_Man_t * Gia_ManChangeTest3( Gia_Man_t * p )
Gia_ManRelCompute( p, vIns, vDivs, vOuts, &vSimsDiv, &vSimsOut );
Exa_ManExactPrint( vSimsDiv, vSimsOut, 1 + Vec_IntSize(vIns) + Vec_IntSize(vDivs), Vec_IntSize(vOuts) );
//Exa6_WriteFile2( "mul44_i%d_n%d_t%d_s%d.rel", Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), nNodes );
pMini = Exa_ManExactSynthesis6Int( vSimsDiv, vSimsOut, Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), nNodes, 1, 1 );
pMini = Exa_ManExactSynthesis6Int( vSimsDiv, vSimsOut, Vec_IntSize(vIns), Vec_IntSize(vDivs), Vec_IntSize(vOuts), nNodes, 1, 1, NULL );
if ( pMini )
{
pNew = Gia_ManDupMini( p, vIns, vDivs, vOuts, pMini );

View File

@ -20,6 +20,7 @@
#include "gia.h"
#include "map/if/if.h"
#include "misc/tim/tim.h"
ABC_NAMESPACE_IMPL_START
@ -32,6 +33,53 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static int Gia_ManConfig2GetBytePos( Gia_Man_t * p, int iObj, If_LibCell_t * pCellLib )
{
int iLut, bytePos = 0;
if ( p == NULL || p->vConfigs2 == NULL || pCellLib == NULL )
return -1;
Gia_ManForEachLut( p, iLut )
{
unsigned char CellId;
int nRecordSize;
if ( bytePos >= Vec_StrSize(p->vConfigs2) )
return -1;
if ( iLut == iObj )
return bytePos;
CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos );
if ( CellId >= IF_MAX_LUTSIZE )
return -1;
nRecordSize = pCellLib->pCellRecordSizes[CellId];
if ( nRecordSize <= 0 )
return -1;
bytePos += nRecordSize;
}
return -1;
}
int Gia_ManConfig2DerivePinDelays( Gia_Man_t * p, int iObj, If_LibCell_t * pCellLib, int * pPinDelay, int nLutSize )
{
int bytePos, i, nPins;
unsigned char CellId;
if ( pCellLib == NULL || pPinDelay == NULL || nLutSize < 1 || nLutSize > 32 )
return 0;
for ( i = 0; i < nLutSize; i++ )
pPinDelay[i] = 1;
bytePos = Gia_ManConfig2GetBytePos( p, iObj, pCellLib );
if ( bytePos < 0 || bytePos >= Vec_StrSize(p->vConfigs2) )
return 0;
CellId = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos );
if ( CellId >= pCellLib->nCellNum )
return 0;
nPins = Abc_MinInt( pCellLib->nCellInputs[CellId], 9 );
for ( i = 0; i < nPins; i++ )
{
int v = (unsigned char)Vec_StrEntry( p->vConfigs2, bytePos + 1 + i );
if ( v >= 2 && v < 2 + nLutSize )
pPinDelay[v - 2] = Abc_MaxInt( pPinDelay[v - 2], pCellLib->pCellPinDelays[CellId][i] );
}
return 1;
}
/**Function*************************************************************
Synopsis [Sorts the pins in the decreasing order of delays.]
@ -110,8 +158,9 @@ int Gia_LutWhereIsPin( Gia_Man_t * p, int iFanout, int iFanin, int * pPinPerm )
float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
{
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
Gia_Obj_t * pObj = Gia_ManObj( p, iObj );
int k, iFanin, pPinPerm[32];
int k, iFanin, pPinPerm[32], pPinDelay[32];
float pPinDelays[32];
float tArrival, * pDelays;
if ( Gia_ObjIsCi(pObj) )
@ -120,12 +169,54 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
return Gia_ObjTimeArrival(p, Gia_ObjFaninId0p(p, pObj) );
assert( Gia_ObjIsLut(p, iObj) );
tArrival = -TIM_ETERNITY;
if ( pLutLib == NULL )
if ( pLutLib == NULL && pCellLib == NULL )
{
Gia_LutForEachFanin( p, iObj, iFanin, k )
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 1.0 )
tArrival = Gia_ObjTimeArrival(p, iFanin) + 1.0;
}
else if ( pCellLib )
{
// Handle cell library delays (use integer delays directly)
int nLutSize = Gia_ObjLutSize(p, iObj);
int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize );
// Find matching cell (simple approach: use first cell with enough inputs)
int cellId = -1;
int i;
if ( !fHaveCfg2 )
for ( i = 0; i < pCellLib->nCellNum; i++ )
if ( pCellLib->nCellInputs[i] >= nLutSize )
{
cellId = i;
break;
}
if ( cellId >= 0 )
{
// Use cell delays as integers from the library
Gia_LutForEachFanin( p, iObj, iFanin, k )
{
float delay = (float)(pCellLib->pCellPinDelays[cellId][k]); // Integer delay from library
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + delay )
tArrival = Gia_ObjTimeArrival(p, iFanin) + delay;
}
}
else if ( fHaveCfg2 )
{
Gia_LutForEachFanin( p, iObj, iFanin, k )
{
float delay = (float)pPinDelay[k];
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + delay )
tArrival = Gia_ObjTimeArrival(p, iFanin) + delay;
}
}
else
{
// Fall back to default delay if no matching cell
Gia_LutForEachFanin( p, iObj, iFanin, k )
if ( tArrival < Gia_ObjTimeArrival(p, iFanin) + 100.0 )
tArrival = Gia_ObjTimeArrival(p, iFanin) + 100.0;
}
}
else if ( !pLutLib->fVarPinDelays )
{
pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
@ -170,18 +261,66 @@ float Gia_ObjComputeArrival( Gia_Man_t * p, int iObj, int fUseSorting )
float Gia_ObjPropagateRequired( Gia_Man_t * p, int iObj, int fUseSorting )
{
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
int k, iFanin, pPinPerm[32];
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
int k, iFanin, pPinPerm[32], pPinDelay[32];
float pPinDelays[32];
float tRequired = 0.0; // Suppress "might be used uninitialized"
float * pDelays;
assert( Gia_ObjIsLut(p, iObj) );
if ( pLutLib == NULL )
// Infinity propagates unchanged
if ( Gia_ObjTimeRequired( p, iObj ) >= TIM_ETERNITY )
return TIM_ETERNITY;
if ( pLutLib == NULL && pCellLib == NULL )
{
tRequired = Gia_ObjTimeRequired( p, iObj) - (float)1.0;
Gia_LutForEachFanin( p, iObj, iFanin, k )
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
}
else if ( pCellLib )
{
// Handle cell library delays (use integer delays directly)
int nLutSize = Gia_ObjLutSize(p, iObj);
int fHaveCfg2 = Gia_ManConfig2DerivePinDelays( p, iObj, pCellLib, pPinDelay, nLutSize );
// Find matching cell (simple approach: use first cell with enough inputs)
int cellId = -1;
int i;
if ( !fHaveCfg2 )
for ( i = 0; i < pCellLib->nCellNum; i++ )
if ( pCellLib->nCellInputs[i] >= nLutSize )
{
cellId = i;
break;
}
if ( cellId >= 0 )
{
// Use cell delays as integers from the library
Gia_LutForEachFanin( p, iObj, iFanin, k )
{
float delay = (float)(pCellLib->pCellPinDelays[cellId][k]); // Integer delay from library
tRequired = Gia_ObjTimeRequired( p, iObj) - delay;
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
}
}
else if ( fHaveCfg2 )
{
Gia_LutForEachFanin( p, iObj, iFanin, k )
{
tRequired = Gia_ObjTimeRequired( p, iObj ) - (float)pPinDelay[k];
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
}
}
else
{
// Fall back to default delay if no matching cell
tRequired = Gia_ObjTimeRequired( p, iObj) - 100.0;
Gia_LutForEachFanin( p, iObj, iFanin, k )
if ( Gia_ObjTimeRequired(p, iFanin) > tRequired )
Gia_ObjSetTimeRequired( p, iFanin, tRequired );
}
}
else if ( !pLutLib->fVarPinDelays )
{
pDelays = pLutLib->pLutDelays[Gia_ObjLutSize(p, iObj)];
@ -266,6 +405,32 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p )
Gia_ObjSetTimeArrival( p, i, tArrival );
}
// update levels of box output CIs to reflect box structure
// (Gia_ManLevelNum assigns level 0 to all CIs, but box output CIs
// need higher levels so that Gia_ManOrderReverse processes them
// before box input COs during the backward required-time pass)
if ( p->pManTime )
{
Tim_Man_t * pManTime = (Tim_Man_t *)p->pManTime;
int iBox, nBoxes = Tim_ManBoxNum( pManTime );
for ( iBox = 0; iBox < nBoxes; iBox++ )
{
int nIns = Tim_ManBoxInputNum( pManTime, iBox );
int nOuts = Tim_ManBoxOutputNum( pManTime, iBox );
int iCoFirst = Tim_ManBoxInputFirst( pManTime, iBox );
int iCiFirst = Tim_ManBoxOutputFirst( pManTime, iBox );
int j, maxLevel = 0;
for ( j = 0; j < nIns; j++ )
{
int coLevel = Gia_ObjLevel( p, Gia_ObjFanin0(Gia_ManCo(p, iCoFirst + j)) );
if ( coLevel > maxLevel )
maxLevel = coLevel;
}
for ( j = 0; j < nOuts; j++ )
Gia_ObjSetLevel( p, Gia_ManCi(p, iCiFirst + j), maxLevel + 1 );
}
}
// get the latest arrival times
tArrival = -TIM_ETERNITY;
Gia_ManForEachCo( p, pObj, i )
@ -314,9 +479,11 @@ float Gia_ManDelayTraceLut( Gia_Man_t * p )
}
// set slack for this object
tSlack = Gia_ObjTimeRequired(p, iObj) - Gia_ObjTimeArrival(p, iObj);
assert( tSlack + 0.01 > 0.0 );
Gia_ObjSetTimeSlack( p, iObj, tSlack < 0.0 ? 0.0 : tSlack );
if ( Gia_ObjTimeRequired(p, iObj) >= TIM_ETERNITY )
tSlack = TIM_ETERNITY;
else
tSlack = Gia_ObjTimeRequired(p, iObj) - Gia_ObjTimeArrival(p, iObj);
Gia_ObjSetTimeSlack( p, iObj, tSlack );
}
Vec_IntFree( vObjs );
return tArrival;
@ -441,20 +608,44 @@ int Gia_LutVerifyTiming( Gia_Man_t * p )
SeeAlso []
***********************************************************************/
float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
float Gia_ManDelayTraceLutPrintInt( Gia_Man_t * p, int fVerbose )
{
If_LibLut_t * pLutLib = (If_LibLut_t *)p->pLutLib;
If_LibCell_t * pCellLib = (If_LibCell_t *)p->pCellLib;
int i, Nodes, * pCounters;
float tArrival, tDelta, nSteps, Num;
// get the library
const char * pDelayModel;
// determine delay model
if ( pCellLib )
pDelayModel = "cell library";
else if ( pLutLib )
pDelayModel = "LUT library";
else
pDelayModel = "unit-delay";
// check library compatibility
if ( pLutLib && pLutLib->LutMax < Gia_ManLutSizeMax(p) )
{
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
printf( "The max LUT size (%d) is less than the max fanin count (%d).\n",
pLutLib->LutMax, Gia_ManLutSizeMax(p) );
return -ABC_INFINITY;
}
if ( pCellLib )
{
int nMaxInputs = 0;
for ( i = 0; i < pCellLib->nCellNum; i++ )
if ( pCellLib->nCellInputs[i] > nMaxInputs )
nMaxInputs = pCellLib->nCellInputs[i];
if ( nMaxInputs < Gia_ManLutSizeMax(p) )
{
printf( "The max cell inputs (%d) is less than the max fanin count (%d).\n",
nMaxInputs, Gia_ManLutSizeMax(p) );
return -ABC_INFINITY;
}
}
// decide how many steps
nSteps = pLutLib ? 20 : Gia_ManLutLevel(p, NULL);
nSteps = (pLutLib || pCellLib) ? 20 : Gia_ManLutLevel(p, NULL);
pCounters = ABC_ALLOC( int, nSteps + 1 );
memset( pCounters, 0, sizeof(int)*(nSteps + 1) );
// perform delay trace
@ -471,16 +662,19 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
assert( Num >=0 && Num <= nSteps );
pCounters[(int)Num]++;
}
// print the results
// print the results
if ( fVerbose )
{
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pLutLib? "LUT library" : "unit-delay" );
if ( pCellLib )
printf( "Max delay = %d. Delay trace using %s model:\n", (int)tArrival, pDelayModel );
else
printf( "Max delay = %6.2f. Delay trace using %s model:\n", tArrival, pDelayModel );
Nodes = 0;
for ( i = 0; i < nSteps; i++ )
{
Nodes += pCounters[i];
printf( "%3d %s : %5d (%6.2f %%)\n", pLutLib? 5*(i+1) : i+1,
pLutLib? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) );
printf( "%3d %s : %5d (%6.2f %%)\n", (pLutLib || pCellLib)? 5*(i+1) : i+1,
(pLutLib || pCellLib)? "%":"lev", Nodes, 100.0*Nodes/Gia_ManLutNum(p) );
}
}
ABC_FREE( pCounters );
@ -488,12 +682,61 @@ float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
return tArrival;
}
/**Function*************************************************************
Synopsis [Wrapper for delay trace that handles XIAGs with boxes.]
Description [For XIAGs with boxes, unnormalizes the AIG to ensure proper
topological order during delay computation, similar to how
Gia_ManPerformMapping handles it.]
SideEffects []
SeeAlso []
***********************************************************************/
float Gia_ManDelayTraceLutPrint( Gia_Man_t * p, int fVerbose )
{
float tArrival;
// Check if we have boxes and the AIG is normalized (like in Gia_ManPerformMapping)
if ( p->pManTime && Tim_ManBoxNum((Tim_Man_t*)p->pManTime) && Gia_ManIsNormalized(p) )
{
// For XIAGs with boxes, we need to unnormalize for proper topological order
Gia_Man_t * pTemp = Gia_ManDupUnnormalize( p );
if ( pTemp == NULL )
{
printf( "Failed to unnormalize AIG with boxes for delay trace.\n" );
return -1.0;
}
// Transfer timing and mapping information
Gia_ManTransferTiming( pTemp, p );
Gia_ManTransferMapping( pTemp, p );
// Transfer library pointers
pTemp->pLutLib = p->pLutLib;
pTemp->pCellLib = p->pCellLib;
// Perform delay trace on unnormalized AIG
tArrival = Gia_ManDelayTraceLutPrintInt( pTemp, fVerbose );
// Clean up temporary AIG
Gia_ManStop( pTemp );
}
else
{
// Normal case: no boxes or already unnormalized
tArrival = Gia_ManDelayTraceLutPrintInt( p, fVerbose );
}
return tArrival;
}
/**Function*************************************************************
Synopsis [Determines timing-critical edges of the node.]
Description []
SideEffects []
SeeAlso []
@ -803,4 +1046,3 @@ Gia_Man_t * Gia_ManSpeedup( Gia_Man_t * p, int Percentage, int Degree, int fVerb
ABC_NAMESPACE_IMPL_END

View File

@ -1,6 +1,6 @@
/**CFile****************************************************************
FileName [giaDeep.c]
FileName [giaStoch.c]
SystemName [ABC: Logic synthesis and verification system.]
@ -14,31 +14,23 @@
Date [Ver. 1.0. Started - June 20, 2005.]
Revision [$Id: giaDeep.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
Revision [$Id: giaStoch.c,v 1.00 2005/06/20 00:00:00 alanmi Exp $]
***********************************************************************/
#include "gia.h"
#include "aig/gia/giaAig.h"
#include "proof/dch/dch.h"
#include "base/main/main.h"
#include "base/cmd/cmd.h"
#ifdef _MSC_VER
#ifdef WIN32
#include <process.h>
#define unlink _unlink
#else
#include <unistd.h>
#endif
#ifdef ABC_USE_PTHREADS
#ifdef _WIN32
#include "../lib/pthread.h"
#else
#include <pthread.h>
#endif
#endif
ABC_NAMESPACE_IMPL_START
////////////////////////////////////////////////////////////////////////
@ -59,6 +51,66 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_StochProcessSingle( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
{
Gia_Man_t * pTemp, * pNew = Gia_ManDup( p );
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), Gia_ManDup(p) );
if ( Abc_FrameIsBatchMode() )
{
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
return NULL;
}
}
else
{
Abc_FrameSetBatchMode( 1 );
if ( Cmd_CommandExecute(Abc_FrameGetGlobalFrame(), pScript) )
{
Abc_Print( 1, "Something did not work out with the command \"%s\".\n", pScript );
return NULL;
}
Abc_FrameSetBatchMode( 0 );
}
pTemp = Abc_FrameReadGia(Abc_FrameGetGlobalFrame());
if ( Gia_ManAndNum(pNew) > Gia_ManAndNum(pTemp) )
{
Gia_ManStop( pNew );
pNew = Gia_ManDup( pTemp );
}
return pNew;
}
Vec_Int_t * Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int fVerbose )
{
Vec_Int_t * vGains = Vec_IntStartFull( Vec_PtrSize(vGias) );
Gia_Man_t * pGia, * pNew; int i;
Vec_Int_t * vRands = Vec_IntAlloc( Vec_PtrSize(vGias) );
Abc_Random(1);
for ( i = 0; i < Vec_PtrSize(vGias); i++ )
Vec_IntPush( vRands, Abc_Random(0) % 0x1000000 );
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
{
pNew = Gia_StochProcessSingle( pGia, pScript, Vec_IntEntry(vRands, i), TimeSecs );
Vec_IntWriteEntry( vGains, i, Gia_ManAndNum(pGia) - Gia_ManAndNum(pNew) );
Gia_ManStop( pGia );
Vec_PtrWriteEntry( vGias, i, pNew );
}
Vec_IntFree( vRands );
return vGains;
}
/**Function*************************************************************
Synopsis [Processing on many cores.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int TimeSecs )
{
@ -87,135 +139,71 @@ Gia_Man_t * Gia_StochProcessOne( Gia_Man_t * p, char * pScript, int Rand, int Ti
Gia_ManStopP( &pNew );
return Gia_ManDup(p);
}
void Gia_StochProcessArray( Vec_Ptr_t * vGias, char * pScript, int TimeSecs, int fVerbose )
{
Gia_Man_t * pGia, * pNew; int i;
Vec_Int_t * vRands = Vec_IntAlloc( Vec_PtrSize(vGias) );
Abc_Random(1);
for ( i = 0; i < Vec_PtrSize(vGias); i++ )
Vec_IntPush( vRands, Abc_Random(0) % 0x1000000 );
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i )
{
pNew = Gia_StochProcessOne( pGia, pScript, Vec_IntEntry(vRands, i), TimeSecs );
Gia_ManStop( pGia );
Vec_PtrWriteEntry( vGias, i, pNew );
}
Vec_IntFree( vRands );
}
/**Function*************************************************************
Synopsis [Processing on a many cores.]
Synopsis [Generic concurrent processing.]
Description []
Description [User-defined problem-specific data and the way to process it.]
SideEffects []
SeeAlso []
***********************************************************************/
#ifndef ABC_USE_PTHREADS
void Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose )
typedef struct StochSynData_t_
{
Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose );
}
#else // pthreads are used
#define PAR_THR_MAX 100
typedef struct Gia_StochThData_t_
{
Vec_Ptr_t * vGias;
Gia_Man_t * pIn;
Gia_Man_t * pOut;
char * pScript;
int Index;
int Rand;
int nTimeOut;
int fWorking;
} Gia_StochThData_t;
int TimeOut;
} StochSynData_t;
void * Gia_StochWorkerThread( void * pArg )
int Gia_StochProcess1( void * p )
{
Gia_StochThData_t * pThData = (Gia_StochThData_t *)pArg;
volatile int * pPlace = &pThData->fWorking;
Gia_Man_t * pGia, * pNew;
while ( 1 )
{
while ( *pPlace == 0 );
assert( pThData->fWorking );
if ( pThData->Index == -1 )
{
pthread_exit( NULL );
assert( 0 );
return NULL;
}
pGia = (Gia_Man_t *)Vec_PtrEntry( pThData->vGias, pThData->Index );
pNew = Gia_StochProcessOne( pGia, pThData->pScript, pThData->Rand, pThData->nTimeOut );
Gia_ManStop( pGia );
Vec_PtrWriteEntry( pThData->vGias, pThData->Index, pNew );
pThData->fWorking = 0;
}
assert( 0 );
return NULL;
StochSynData_t * pData = (StochSynData_t *)p;
assert( pData->pIn != NULL );
assert( pData->pOut == NULL );
pData->pOut = Gia_StochProcessOne( pData->pIn, pData->pScript, pData->Rand, pData->TimeOut );
return 1;
}
void Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose )
Vec_Int_t * Gia_StochProcess( Vec_Ptr_t * vGias, char * pScript, int nProcs, int TimeSecs, int fVerbose )
{
Gia_StochThData_t ThData[PAR_THR_MAX];
pthread_t WorkerThread[PAR_THR_MAX];
int i, k, status;
if ( fVerbose )
printf( "Running concurrent synthesis with %d processes.\n", nProcs );
fflush( stdout );
if ( nProcs < 2 )
if ( nProcs <= 2 ) {
if ( fVerbose )
printf( "Running non-concurrent synthesis.\n" ), fflush(stdout);
return Gia_StochProcessArray( vGias, pScript, TimeSecs, fVerbose );
// subtract manager thread
nProcs--;
assert( nProcs >= 1 && nProcs <= PAR_THR_MAX );
// start threads
}
Vec_Int_t * vGains = Vec_IntStartFull( Vec_PtrSize(vGias) );
StochSynData_t * pData = ABC_CALLOC( StochSynData_t, Vec_PtrSize(vGias) );
Vec_Ptr_t * vData = Vec_PtrAlloc( Vec_PtrSize(vGias) );
Gia_Man_t * pGia; int i;
Abc_Random(1);
for ( i = 0; i < nProcs; i++ )
{
ThData[i].vGias = vGias;
ThData[i].pScript = pScript;
ThData[i].Index = -1;
ThData[i].Rand = Abc_Random(0) % 0x1000000;
ThData[i].nTimeOut = TimeSecs;
ThData[i].fWorking = 0;
status = pthread_create( WorkerThread + i, NULL, Gia_StochWorkerThread, (void *)(ThData + i) ); assert( status == 0 );
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) {
pData[i].pIn = pGia;
pData[i].pOut = NULL;
pData[i].pScript = pScript;
pData[i].Rand = Abc_Random(0) % 0x1000000;
pData[i].TimeOut = TimeSecs;
Vec_PtrPush( vData, pData+i );
}
// look at the threads
for ( k = 0; k < Vec_PtrSize(vGias); k++ )
{
for ( i = 0; i < nProcs; i++ )
{
if ( ThData[i].fWorking )
continue;
ThData[i].Index = k;
ThData[i].fWorking = 1;
break;
}
if ( i == nProcs )
k--;
}
// wait till threads finish
for ( i = 0; i < nProcs; i++ )
if ( ThData[i].fWorking )
i = -1;
// stop threads
for ( i = 0; i < nProcs; i++ )
{
assert( !ThData[i].fWorking );
// stop
ThData[i].Index = -1;
ThData[i].fWorking = 1;
if ( fVerbose )
printf( "Running concurrent synthesis with %d processes.\n", nProcs ), fflush(stdout);
Util_ProcessThreads( Gia_StochProcess1, vData, nProcs, TimeSecs, fVerbose );
// replace old AIGs by new AIGs
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pGia, i ) {
Vec_IntWriteEntry( vGains, i, Gia_ManAndNum(pGia) - Gia_ManAndNum(pData[i].pOut) );
Gia_ManStop( pGia );
Vec_PtrWriteEntry( vGias, i, pData[i].pOut );
}
Vec_PtrFree( vData );
ABC_FREE( pData );
return vGains;
}
#endif // pthreads are used
/**Function*************************************************************
Synopsis []
@ -298,6 +286,455 @@ void Gia_ManStochSynthesis( Vec_Ptr_t * vAigs, char * pScript )
}
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManFilterPartitions( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins, Vec_Int_t * vGains, int fDelayOpt )
{
int RetValue = Vec_PtrSize(vvIns);
Vec_Ptr_t * vvInsNew = Vec_PtrAlloc( 10 );
Vec_Ptr_t * vvOutsNew = Vec_PtrAlloc( 10 );
Vec_Ptr_t * vvWinsNew = Vec_PtrAlloc( 10 );
Gia_ManIncrementTravId( p );
while ( 1 ) {
int i, Gain, iEntry = Vec_IntArgMax(vGains);
if ( iEntry == -1 || Vec_IntEntry(vGains, iEntry) < 0 )
break;
//printf( "Selecting partition %d with gain %d.\n", iEntry, Vec_IntEntry(vGains, iEntry) );
Vec_IntWriteEntry( vGains, iEntry, -1 );
Vec_PtrPush( vvInsNew, Vec_IntDup((Vec_Int_t *)Vec_PtrEntry(vvIns, iEntry)) );
Vec_PtrPush( vvOutsNew, Vec_IntDup((Vec_Int_t *)Vec_PtrEntry(vvOuts, iEntry)) );
Vec_PtrPush( vvWinsNew, Gia_ManDupDfs((Gia_Man_t *)Vec_PtrEntry(vWins, iEntry)) );
extern void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan, int fDelayOpt );
Gia_ManMarkTfiTfo( (Vec_Int_t *)Vec_PtrEntryLast(vvInsNew), p, fDelayOpt );
Vec_IntForEachEntry( vGains, Gain, i ) {
if ( Gain < 0 )
continue;
Vec_Int_t * vNodes = (Vec_Int_t *)Vec_PtrEntry(vvNodes, i);
Gia_Obj_t * pNode; int j;
Gia_ManForEachObjVec( vNodes, p, pNode, j )
if ( Gia_ObjIsTravIdCurrent(p, pNode) )
break;
if ( j < Vec_IntSize(vNodes) )
Vec_IntWriteEntry( vGains, i, -1 );
}
}
ABC_SWAP( Vec_Ptr_t, *vvInsNew, *vvIns );
ABC_SWAP( Vec_Ptr_t, *vvOutsNew, *vvOuts );
ABC_SWAP( Vec_Ptr_t, *vvWinsNew, *vWins );
Vec_PtrFreeFunc( vvInsNew, (void (*)(void *)) Vec_IntFree );
Vec_PtrFreeFunc( vvOutsNew, (void (*)(void *)) Vec_IntFree );
Vec_PtrFreeFunc( vvWinsNew, (void (*)(void *)) Gia_ManStop );
return RetValue;
}
/**Function*************************************************************
Synopsis [Partitioning.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ObjDfsMark_rec( Gia_Man_t * pGia, Gia_Obj_t * pObj )
{
assert( !pObj->fMark0 );
if ( Gia_ObjIsTravIdCurrent( pGia, pObj ) )
return;
Gia_ObjSetTravIdCurrent( pGia, pObj );
if ( Gia_ObjIsCi(pObj) )
return;
assert( Gia_ObjIsAnd(pObj) );
Gia_ObjDfsMark_rec( pGia, Gia_ObjFanin0(pObj) );
Gia_ObjDfsMark_rec( pGia, Gia_ObjFanin1(pObj) );
}
void Gia_ObjDfsMark2_rec( Gia_Man_t * pGia, Gia_Obj_t * pObj )
{
Gia_Obj_t * pFanout; int i;
assert( !pObj->fMark0 );
if ( Gia_ObjIsTravIdCurrent( pGia, pObj ) )
return;
Gia_ObjSetTravIdCurrent( pGia, pObj );
Gia_ObjForEachFanoutStatic( pGia, pObj, pFanout, i )
Gia_ObjDfsMark2_rec( pGia, pFanout );
}
Vec_Int_t * Gia_ManDeriveWinNodes( Gia_Man_t * pMan, Vec_Int_t * vIns, Vec_Wec_t * vStore )
{
Vec_Int_t * vLevel, * vNodes = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj, * pNext; int i, k, iLevel;
Vec_WecForEachLevel( vStore, vLevel, i )
Vec_IntClear( vLevel );
// mark the TFI cones of the inputs
Gia_ManIncrementTravId( pMan );
Gia_ManForEachObjVec( vIns, pMan, pObj, i )
Gia_ObjDfsMark_rec( pMan, pObj );
// add unrelated fanouts of the inputs to storage
Gia_ManForEachObjVec( vIns, pMan, pObj, i )
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
if ( Gia_ObjIsAnd(pNext) && !Gia_ObjIsTravIdCurrent(pMan, pNext) && !pNext->fMark0 ) {
pNext->fMark0 = 1;
Vec_WecPush( vStore, Gia_ObjLevel(pMan, pNext), Gia_ObjId(pMan, pNext) );
}
// mark the inputs
Gia_ManIncrementTravId( pMan );
Gia_ManForEachObjVec( vIns, pMan, pObj, i )
Gia_ObjSetTravIdCurrent(pMan, pObj);
// collect those fanouts that are completely supported by the inputs
Vec_WecForEachLevel( vStore, vLevel, iLevel )
Gia_ManForEachObjVec( vLevel, pMan, pObj, i ) {
assert( !Gia_ObjIsTravIdCurrent(pMan, pObj) );
assert( pObj->fMark0 );
pObj->fMark0 = 0;
if ( !Gia_ObjIsTravIdCurrent(pMan, Gia_ObjFanin0(pObj)) ||
!Gia_ObjIsTravIdCurrent(pMan, Gia_ObjFanin1(pObj)) )
continue;
Gia_ObjSetTravIdCurrent(pMan, pObj);
Vec_IntPush( vNodes, Gia_ObjId(pMan, pObj) );
assert( Gia_ObjIsAnd(pObj) );
// add fanouts of this node to storage
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
if ( Gia_ObjIsAnd(pNext) && !Gia_ObjIsTravIdCurrent(pMan, pNext) && !pNext->fMark0 ) {
pNext->fMark0 = 1;
assert( Gia_ObjLevel(pMan, pNext) > iLevel );
Vec_WecPush( vStore, Gia_ObjLevel(pMan, pNext), Gia_ObjId(pMan, pNext) );
}
}
Vec_IntSort( vNodes, 0 );
return vNodes;
}
Vec_Ptr_t * Gia_ManDeriveWinNodesAll( Gia_Man_t * pMan, Vec_Ptr_t * vvIns, Vec_Wec_t * vStore )
{
Vec_Int_t * vIns; int i;
Vec_Ptr_t * vvNodes = Vec_PtrAlloc( Vec_PtrSize(vvIns) );
Vec_PtrForEachEntry( Vec_Int_t *, vvIns, vIns, i )
Vec_PtrPush( vvNodes, Gia_ManDeriveWinNodes(pMan, vIns, vStore) );
return vvNodes;
}
Vec_Int_t * Gia_ManDeriveWinOuts( Gia_Man_t * pMan, Vec_Int_t * vNodes )
{
Vec_Int_t * vOuts = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj, * pNext; int i, k;
// mark the nodes in the window
Gia_ManIncrementTravId( pMan );
Gia_ManForEachObjVec( vNodes, pMan, pObj, i )
Gia_ObjSetTravIdCurrent(pMan, pObj);
// collect nodes that have unmarked fanouts
Gia_ManForEachObjVec( vNodes, pMan, pObj, i ) {
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
if ( !Gia_ObjIsTravIdCurrent(pMan, pNext) )
break;
if ( k < Gia_ObjFanoutNum(pMan, pObj) )
Vec_IntPush( vOuts, Gia_ObjId(pMan, pObj) );
}
if ( Vec_IntSize(vOuts) == 0 )
printf( "Window with %d internal nodes has no outputs (are these dangling nodes?).\n", Vec_IntSize(vNodes) );
return vOuts;
}
Vec_Ptr_t * Gia_ManDeriveWinOutsAll( Gia_Man_t * pMan, Vec_Ptr_t * vvNodes )
{
Vec_Int_t * vNodes; int i;
Vec_Ptr_t * vvOuts = Vec_PtrAlloc( Vec_PtrSize(vvNodes) );
Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i )
Vec_PtrPush( vvOuts, Gia_ManDeriveWinOuts(pMan, vNodes) );
return vvOuts;
}
void Gia_ManPermuteLevel( Gia_Man_t * pMan, int Level )
{
Gia_Obj_t * pObj, * pNext; int i, k;
Gia_ManForEachAnd( pMan, pObj, i ) {
int LevelMin = Gia_ObjLevel(pMan, pObj), LevelMax = Level + 1;
Gia_ObjForEachFanoutStatic( pMan, pObj, pNext, k )
if ( Gia_ObjIsAnd(pNext) )
LevelMax = Abc_MinInt( LevelMax, Gia_ObjLevel(pMan, pNext) );
if ( LevelMin == LevelMax ) continue;
assert( LevelMin < LevelMax );
// randomly set level between LevelMin and LevelMax-1
Gia_ObjSetLevel( pMan, pObj, LevelMin + (Abc_Random(0) % (LevelMax - LevelMin)) );
assert( Gia_ObjLevel(pMan, pObj) < LevelMax );
}
}
Vec_Int_t * Gia_ManCollectObjectsPointedTo( Gia_Man_t * pMan, int Level )
{
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
Gia_Obj_t * pObj, * pFanin; int i, n;
Gia_ManIncrementTravId( pMan );
Gia_ManForEachAnd( pMan, pObj, i ) {
if ( Gia_ObjLevel(pMan, pObj) <= Level )
continue;
for ( n = 0; n < 2; n++ ) {
Gia_Obj_t * pFanin = n ? Gia_ObjFanin1(pObj) : Gia_ObjFanin0(pObj);
if ( Gia_ObjLevel(pMan, pFanin) <= Level && !Gia_ObjIsTravIdCurrent(pMan, pFanin) ) {
Gia_ObjSetTravIdCurrent(pMan, pFanin);
Vec_IntPush( vRes, Gia_ObjId(pMan, pFanin) );
}
}
}
Gia_ManForEachCo( pMan, pObj, i ) {
pFanin = Gia_ObjFanin0(pObj);
if ( Gia_ObjLevel(pMan, pFanin) <= Level && !Gia_ObjIsTravIdCurrent(pMan, pFanin) && Gia_ObjIsAnd(pFanin) ) {
Gia_ObjSetTravIdCurrent(pMan, pFanin);
Vec_IntPush( vRes, Gia_ObjId(pMan, pFanin) );
}
}
Vec_IntSort( vRes, 0 );
return vRes;
}
Vec_Wec_t * Gia_ManCollectObjectsWithSuppLimit( Gia_Man_t * pMan, int Level, int nSuppMax )
{
Vec_Wec_t * vResSupps = NULL;
Vec_Int_t * vBelow = Gia_ManCollectObjectsPointedTo( pMan, Level );
Vec_Wec_t * vSupps = Vec_WecStart( Vec_IntSize(vBelow) );
Vec_Int_t * vSuppIds = Vec_IntStartFull( Gia_ManObjNum(pMan) );
Vec_Int_t * vTemp = Vec_IntAlloc(100);
Gia_Obj_t * pObj; int i, Count = 0;
Gia_ManForEachObjVec( vBelow, pMan, pObj, i ) {
Vec_IntWriteEntry( vSuppIds, Gia_ObjId(pMan, pObj), i );
Vec_IntPush( Vec_WecEntry(vSupps, i), Gia_ObjId(pMan, pObj) );
}
Gia_ManForEachAnd( pMan, pObj, i ) {
if ( Gia_ObjLevel(pMan, pObj) <= Level )
continue;
int iSuppId0 = Vec_IntEntry( vSuppIds, Gia_ObjFaninId0(pObj, i) );
int iSuppId1 = Vec_IntEntry( vSuppIds, Gia_ObjFaninId1(pObj, i) );
if ( iSuppId0 == -1 || iSuppId1 == -1 ) {
Count++;
continue;
}
Vec_IntClear( vTemp );
Vec_IntTwoMerge2( Vec_WecEntry(vSupps, iSuppId0), Vec_WecEntry(vSupps, iSuppId1), vTemp );
if ( Vec_IntSize(vTemp) > nSuppMax ) {
Count++;
continue;
}
Vec_IntWriteEntry( vSuppIds, i, Vec_WecSize(vSupps) );
Vec_IntAppend( Vec_WecPushLevel(vSupps), vTemp );
}
// remove those supported nodes that are in the TFI cones of others
Gia_ManIncrementTravId( pMan );
Gia_ManForEachAnd( pMan, pObj, i )
if ( Gia_ObjLevel(pMan, pObj) > Level && Vec_IntEntry(vSuppIds, i) >= 0 && !Gia_ObjIsTravIdCurrent(pMan, pObj) ) {
Gia_ObjDfsMark_rec(pMan, pObj);
Gia_ObjSetTravIdPrevious(pMan, pObj);
}
// create the result
vResSupps = Vec_WecAlloc( 100 );
Gia_ManForEachAnd( pMan, pObj, i )
if ( Gia_ObjLevel(pMan, pObj) > Level && Vec_IntEntry(vSuppIds, i) >= 0 && !Gia_ObjIsTravIdCurrent(pMan, pObj) ) {
Vec_Int_t * vSupp = Vec_WecEntry( vSupps, Vec_IntEntry(vSuppIds, i) );
if ( Vec_IntSize(vSupp) < 4 )
continue;
Vec_Int_t * vThis = Vec_WecPushLevel( vResSupps );
Vec_IntGrow( vThis, Vec_IntSize(vSupp) + 1 );
Vec_IntAppend( vThis, vSupp );
//Vec_IntPush( vThis, Gia_ObjId(pObj) );
}
//printf( "Inputs = %d. Nodes with %d-support = %d. Nodes with larger support = %d. Selected outputs = %d.\n",
// Vec_IntSize(vBelow), nSuppMax, Vec_WecSize(vSupps), Count, Vec_WecSize(vResSupps) );
Vec_WecFree( vSupps );
Vec_IntFree( vSuppIds );
Vec_IntFree( vBelow );
Vec_IntFree( vTemp );
return vResSupps;
}
// removes all supports that overlap with this one
void Gia_ManSelectRemove( Vec_Wec_t * vSupps, Vec_Int_t * vOne )
{
Vec_Int_t * vLevel; int i;
Vec_WecForEachLevel( vSupps, vLevel, i )
if ( Vec_IntTwoCountCommon(vLevel, vOne) > 0 )
Vec_IntClear( vLevel );
Vec_WecRemoveEmpty( vSupps );
}
// marks TFI/TFO of this one
void Gia_ManMarkTfiTfo( Vec_Int_t * vOne, Gia_Man_t * pMan, int fDelayOpt )
{
int i; Gia_Obj_t * pObj;
Gia_ManForEachObjVec( vOne, pMan, pObj, i ) {
if ( fDelayOpt ) {
Gia_ObjSetTravIdPrevious(pMan, pObj);
Gia_ObjDfsMark_rec( pMan, pObj );
}
Gia_ObjSetTravIdPrevious(pMan, pObj);
Gia_ObjDfsMark2_rec( pMan, pObj );
}
}
// removes all supports that overlap with the TFI/TFO cones of this one
void Gia_ManSelectRemove2( Vec_Wec_t * vSupps, Vec_Int_t * vOne, Gia_Man_t * pMan )
{
Vec_Int_t * vLevel; int i, k; Gia_Obj_t * pObj;
Gia_ManForEachObjVec( vOne, pMan, pObj, i ) {
Gia_ObjSetTravIdPrevious(pMan, pObj);
Gia_ObjDfsMark_rec( pMan, pObj );
Gia_ObjSetTravIdPrevious(pMan, pObj);
Gia_ObjDfsMark2_rec( pMan, pObj );
}
Vec_WecForEachLevel( vSupps, vLevel, i ) {
Gia_ManForEachObjVec( vLevel, pMan, pObj, k )
if ( Gia_ObjIsTravIdCurrent(pMan, pObj) )
break;
if ( k < Vec_IntSize(vLevel) )
Vec_IntClear( vLevel );
}
Vec_WecRemoveEmpty( vSupps );
}
// removes all supports that are contained in this one
void Gia_ManSelectRemove3( Vec_Wec_t * vSupps, Vec_Int_t * vOne )
{
Vec_Int_t * vLevel; int i;
Vec_WecForEachLevel( vSupps, vLevel, i )
if ( Vec_IntTwoCountCommon(vLevel, vOne) == Vec_IntSize(vLevel) )
Vec_IntClear( vLevel );
Vec_WecRemoveEmpty( vSupps );
}
Vec_Ptr_t * Gia_ManDeriveWinInsAll( Vec_Wec_t * vSupps, int nSuppMax, Gia_Man_t * pMan, int fOverlap )
{
Vec_Ptr_t * vRes = Vec_PtrAlloc( 100 );
Gia_ManIncrementTravId( pMan );
while ( Vec_WecSize(vSupps) > 0 ) {
int i, Item, iRand = Abc_Random(0) % Vec_WecSize(vSupps);
Vec_Int_t * vLevel, * vLevel2 = Vec_WecEntry( vSupps, iRand );
Vec_Int_t * vCopy = Vec_IntDup( vLevel2 );
if ( Vec_IntSize(vLevel2) == nSuppMax ) {
Vec_PtrPush( vRes, vCopy );
if ( fOverlap )
Gia_ManSelectRemove3( vSupps, vCopy );
else
Gia_ManSelectRemove2( vSupps, vCopy, pMan );
continue;
}
// find another support, which maximizes the union but does not exceed nSuppMax
int iBest = iRand, nUnion = Vec_IntSize(vCopy);
Vec_WecForEachLevel( vSupps, vLevel, i ) {
if ( i == iRand ) continue;
int nCommon = Vec_IntTwoCountCommon(vLevel, vCopy);
int nUnionCur = Vec_IntSize(vLevel) + Vec_IntSize(vCopy) - nCommon;
if ( nUnionCur <= nSuppMax && nUnion < nUnionCur ) {
nUnion = nUnionCur;
iBest = i;
}
}
vLevel = Vec_WecEntry( vSupps, iBest );
Vec_IntForEachEntry( vLevel, Item, i )
Vec_IntPushUniqueOrder( vCopy, Item );
Vec_PtrPush( vRes, vCopy );
if ( fOverlap )
Gia_ManSelectRemove3( vSupps, vCopy );
else
Gia_ManSelectRemove2( vSupps, vCopy, pMan );
}
return vRes;
}
Gia_Man_t * Gia_ManDupFromArrays( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, Vec_Int_t * vLevels[2], int nLevels )
{
Gia_Man_t * pNew;
Gia_Obj_t * pObj;
int i;
pNew = Gia_ManStart( 5000 );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachObjVec( vCis, p, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
Gia_ManForEachObjVec( vAnds, p, pObj, i )
pObj->Value = Gia_ManAppendAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
Gia_ManForEachObjVec( vCos, p, pObj, i )
pObj->Value = Gia_ManAppendCo( pNew, pObj->Value );
if ( vLevels[0] && vLevels[1] ) {
pNew->vCiArrs = Vec_IntAlloc( Gia_ManCiNum(pNew) );
Gia_ManForEachObjVec( vCis, p, pObj, i ) {
// Vec_IntPush( pNew->vCiArrs, Gia_ObjLevel(p, pObj) );
Vec_IntPush( pNew->vCiArrs, Vec_IntEntry(vLevels[0], Gia_ObjId(p, pObj)) );
}
pNew->vCoReqs = Vec_IntAlloc( Gia_ManCoNum(pNew) );
Gia_ManForEachObjVec( vCos, p, pObj, i ) {
// Vec_IntPush( pNew->vCoReqs, nLevels - Gia_ObjLevel(p, pObj) );
Vec_IntPush( pNew->vCoReqs, nLevels + 1 - Vec_IntEntry(vLevels[1], Gia_ObjId(p, pObj)) );
assert( Gia_ObjIsAnd(pObj) );
}
}
return pNew;
}
int Gia_ManLevelR( Gia_Man_t * pMan )
{
int i, LevelMax = Gia_ManLevelRNum( pMan );
Gia_Obj_t * pNode;
Gia_ManForEachObj( pMan, pNode, i )
Gia_ObjSetLevel( pMan, pNode, (int)(LevelMax - Gia_ObjLevel(pMan, pNode) + 1) );
Gia_ManForEachCi( pMan, pNode, i )
Gia_ObjSetLevel( pMan, pNode, 0 );
return LevelMax;
}
Vec_Ptr_t * Gia_ManDupWindows( Gia_Man_t * pMan, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvNodes, Vec_Ptr_t * vvOuts, int fDelayOpt )
{
// compute direct and reverse level
Vec_Int_t * vLevels[2] = {NULL};
if ( fDelayOpt ) {
int Levels[2];
Levels[0] = Gia_ManLevelNum( pMan );
ABC_SWAP( Vec_Int_t *, vLevels[0], pMan->vLevels );
Levels[1] = Gia_ManLevelRNum( pMan );
ABC_SWAP( Vec_Int_t *, vLevels[1], pMan->vLevels );
assert( (Levels[0] + 1) == Levels[1] );
}
Vec_Int_t * vNodes; int i;
Vec_Ptr_t * vWins = Vec_PtrAlloc( Vec_PtrSize(vvIns) );
assert( Vec_PtrSize(vvIns) == Vec_PtrSize(vvNodes) );
assert( Vec_PtrSize(vvOuts) == Vec_PtrSize(vvNodes) );
Gia_ManFillValue( pMan );
Gia_ManCleanMark01( pMan );
Vec_PtrForEachEntry( Vec_Int_t *, vvNodes, vNodes, i ) {
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
Gia_Man_t * pNew = Gia_ManDupFromArrays( pMan, vIns, vNodes, vOuts, vLevels, pMan->nLevels );
Vec_PtrPush( vWins, pNew );
}
Vec_IntFreeP( &vLevels[0] );
Vec_IntFreeP( &vLevels[1] );
return vWins;
}
Vec_Ptr_t * Gia_ManExtractPartitions( Gia_Man_t * pMan, int Iter, int nSuppMax, Vec_Ptr_t ** pvIns, Vec_Ptr_t ** pvOuts, Vec_Ptr_t ** pvNodes, int fOverlap, int fDelayOpt )
{
// if ( Gia_ManCiNum(pMan) <= nSuppMax ) {
// Vec_Ptr_t * vWins = Vec_PtrAlloc( 1 );
// Vec_PtrPush( vWins, Gia_ManDupDfs(pMan) );
// *pvIns = *pvOuts = *pvNodes = NULL;
// return vWins;
// }
// int iUseRevL = Iter % 3 == 0 ? 0 : Abc_Random(0) & 1;
int iUseRevL = Abc_Random(0) & 1;
int LevelMax = iUseRevL ? Gia_ManLevelR(pMan) : Gia_ManLevelNum(pMan);
// int LevelCut = Iter % 3 == 0 ? 0 : LevelMax > 8 ? 2 + (Abc_Random(0) % (LevelMax - 4)) : 0;
int LevelCut = LevelMax > 8 ? (Abc_Random(0) % (LevelMax - 4)) : 0;
//printf( "Using %s cut level %d (out of %d)\n", iUseRevL ? "reverse": "direct", LevelCut, LevelMax );
// Gia_ManPermuteLevel( pMan, LevelMax );
Vec_Wec_t * vStore = Vec_WecStart( LevelMax+1 );
Vec_Wec_t * vSupps = Gia_ManCollectObjectsWithSuppLimit( pMan, LevelCut, nSuppMax );
Vec_Ptr_t * vIns = Gia_ManDeriveWinInsAll( vSupps, nSuppMax, pMan, fOverlap );
Vec_Ptr_t * vNodes = Gia_ManDeriveWinNodesAll( pMan, vIns, vStore );
Vec_Ptr_t * vOuts = Gia_ManDeriveWinOutsAll( pMan, vNodes );
Vec_Ptr_t * vWins = Gia_ManDupWindows( pMan, vIns, vNodes, vOuts, fDelayOpt );
Vec_WecFree( vSupps );
Vec_WecFree( vStore );
*pvIns = vIns;
*pvOuts = vOuts;
*pvNodes = vNodes;
return vWins;
}
/**Function*************************************************************
Synopsis []
@ -334,7 +771,7 @@ void Gia_ManCollectNodes( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Ve
Vec_IntForEachEntry( vCos, iObj, i )
Gia_ManCollectNodes_rec( p, iObj, vAnds );
}
Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos )
Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vAnds, Vec_Int_t * vCos, Vec_Int_t * vLevels[2], int nLevels )
{
Vec_Int_t * vMapping; int i;
Gia_Man_t * pNew; Gia_Obj_t * pObj;
@ -349,8 +786,16 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA
Gia_ManForEachObjVec( vCos, p, pObj, i )
Gia_ManAppendCo( pNew, pObj->Value );
assert( Gia_ManCiNum(pNew) > 0 && Gia_ManCoNum(pNew) > 0 );
if ( !Gia_ManHasMapping(p) )
if ( !Gia_ManHasMapping(p) ) {
if ( vLevels[0] == NULL ) return pNew;
pNew->vCiArrs = Vec_IntAlloc( Gia_ManCiNum(pNew) );
Gia_ManForEachObjVec( vCis, p, pObj, i )
Vec_IntPush( pNew->vCiArrs, Gia_ObjLevel(p, pObj) );
pNew->vCoReqs = Vec_IntAlloc( Gia_ManCoNum(pNew) );
Gia_ManForEachObjVec( vCos, p, pObj, i )
Vec_IntPush( pNew->vCoReqs, nLevels - Gia_ObjLevel(p, pObj) );
return pNew;
}
vMapping = Vec_IntAlloc( 4*Gia_ManObjNum(pNew) );
Vec_IntFill( vMapping, Gia_ManObjNum(pNew), 0 );
Gia_ManForEachObjVec( vAnds, p, pObj, i )
@ -368,16 +813,29 @@ Gia_Man_t * Gia_ManDupDivideOne( Gia_Man_t * p, Vec_Int_t * vCis, Vec_Int_t * vA
pNew->vMapping = vMapping;
return pNew;
}
Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript, int nProcs, int TimeOut )
Vec_Ptr_t * Gia_ManDupDivide( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, char * pScript, int nProcs, int TimeOut, int fDelayOpt )
{
// compute direct and reverse level
Vec_Int_t * vLevels[2] = {NULL};
if ( fDelayOpt ) {
int Levels[2];
Levels[0] = Gia_ManLevelNum( p );
ABC_SWAP( Vec_Int_t *, vLevels[0], p->vLevels );
Levels[1] = Gia_ManLevelRNum( p );
ABC_SWAP( Vec_Int_t *, vLevels[1], p->vLevels );
// assert( Levels[0] == Levels[1] );
}
Vec_Ptr_t * vAigs = Vec_PtrAlloc( Vec_WecSize(vCis) ); int i;
for ( i = 0; i < Vec_WecSize(vCis); i++ )
{
Gia_ManCollectNodes( p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i) );
Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i)) );
Vec_PtrPush( vAigs, Gia_ManDupDivideOne(p, Vec_WecEntry(vCis, i), Vec_WecEntry(vAnds, i), Vec_WecEntry(vCos, i), vLevels, p->nLevels) );
}
//Gia_ManStochSynthesis( vAigs, pScript );
Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 );
Vec_Int_t * vGains = Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 );
Vec_IntFree( vGains );
Vec_IntFreeP( &vLevels[0] );
Vec_IntFreeP( &vLevels[1] );
return vAigs;
}
Gia_Man_t * Gia_ManDupStitch( Gia_Man_t * p, Vec_Wec_t * vCis, Vec_Wec_t * vAnds, Vec_Wec_t * vCos, Vec_Ptr_t * vAigs, int fHash )
@ -573,55 +1031,153 @@ Vec_Wec_t * Gia_ManStochOutputs( Gia_Man_t * p, Vec_Wec_t * vAnds )
SeeAlso []
***********************************************************************/
void Gia_ManStochSyn( int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs )
Gia_Man_t * Gia_ManCreateChoicesArray( Vec_Ptr_t * vGias, int fVerbose )
{
abctime clkStart = Abc_Clock();
// swap around the first and the last
//Gia_Man_t * pTemp = (Gia_Man_t *)Vec_PtrPop( vGias );
//Vec_PtrPush( vGias, Vec_PtrEntry(vGias,0) );
//Vec_PtrWriteEntry( vGias, 0, pTemp );
if ( fVerbose ) {
printf( "Choicing will be performed with %d AIGs:\n", Vec_PtrSize(vGias) );
Gia_Man_t * pTemp; int i;
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
Gia_ManPrintStats( pTemp, NULL );
}
Dch_Pars_t Pars, * pPars = &Pars;
Dch_ManSetDefaultParams( pPars );
// derive the miter
Gia_Man_t * pMiter = Gia_ManChoiceMiter( vGias );
Aig_Man_t * pAux, * pMan = Gia_ManToAigSkip( pMiter, Vec_PtrSize(vGias) );
Gia_ManStop( pMiter );
pMan = Dch_ComputeChoices( pAux = pMan, pPars );
Aig_ManStop( pAux );
// reconstruct the network
extern Vec_Ptr_t * Gia_ManOrderPios( Aig_Man_t * p, Gia_Man_t * pOrder );
Vec_Ptr_t * vPios = Gia_ManOrderPios( pMan, (Gia_Man_t *)Vec_PtrEntry(vGias,0) );
pMan = Aig_ManDupDfsGuided( pAux = pMan, vPios );
Aig_ManStop( pAux );
Vec_PtrFree( vPios );
// convert to GIA
Gia_Man_t * pChoices = Gia_ManFromAigChoices( pMan );
if ( fVerbose )
Abc_PrintTime( 0, "Choice computation time", Abc_Clock() - clkStart );
return pChoices;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManStochSyn( int nSuppMax, int nMaxSize, int nIters, int TimeOut, int Seed, int fVerbose, char * pScript, int nProcs, int fDelayOpt, int fChoices )
{
abctime nTimeToStop = TimeOut ? Abc_Clock() + TimeOut * CLOCKS_PER_SEC : 0;
abctime clkStart = Abc_Clock();
int fMapped = Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
int nLutEnd, nLutBeg = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
int i, nEnd, nBeg = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
Vec_Ptr_t * vGias = fChoices ? Vec_PtrAlloc( nIters ) : NULL;
Abc_Random(1);
for ( i = 0; i < 10+Seed; i++ )
Abc_Random(0);
if ( fVerbose )
printf( "Running %d iterations of script \"%s\".\n", nIters, pScript );
for ( i = 0; i < nIters; i++ )
{
abctime clk = Abc_Clock();
Gia_Man_t * pGia = Gia_ManDupWithMapping( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) );
Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF );
Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds );
Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds );
Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript, nProcs, TimeOut );
Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs );
int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew);
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
if ( fVerbose )
printf( "Iteration %3d : Using %3d partitions. Reducing %6d to %6d %s. ",
i, Vec_PtrSize(vAigs), fMapped ? Gia_ManLutNum(pGia) : Gia_ManAndNum(pGia),
fMapped ? Gia_ManLutNum(pNew) : Gia_ManAndNum(pNew),
fMapped ? "LUTs" : "ANDs" );
if ( fVerbose )
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
Gia_ManStop( pGia );
Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
Vec_WecFree( vAnds );
Vec_WecFree( vIns );
Vec_WecFree( vOuts );
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
if ( fVerbose ) {
printf( "Running %d iterations of the script \"%s\"", nIters, pScript );
if ( nProcs > 2 )
printf( " using %d concurrent threads.\n", nProcs-1 );
else
printf( " without concurrency.\n" );
fflush(stdout);
}
if ( !nSuppMax ) {
for ( i = 0; i < nIters; i++ )
{
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
break;
abctime clk = Abc_Clock();
Gia_Man_t * pGia = Gia_ManDupWithMapping( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) );
Vec_Wec_t * vAnds = Gia_ManStochNodes( pGia, nMaxSize, Abc_Random(0) & 0x7FFFFFFF );
Vec_Wec_t * vIns = Gia_ManStochInputs( pGia, vAnds );
Vec_Wec_t * vOuts = Gia_ManStochOutputs( pGia, vAnds );
Vec_Ptr_t * vAigs = Gia_ManDupDivide( pGia, vIns, vAnds, vOuts, pScript, nProcs, TimeOut, fDelayOpt );
Gia_Man_t * pNew = Gia_ManDupStitchMap( pGia, vIns, vAnds, vOuts, vAigs );
int fMapped = Gia_ManHasMapping(pGia) && Gia_ManHasMapping(pNew);
if ( vGias ) Vec_PtrPush( vGias, Gia_ManDup(pNew) );
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
if ( fVerbose )
printf( "Iteration %3d : Using %3d partitions. Reducing %6d to %6d %s. ",
i, Vec_PtrSize(vAigs), fMapped ? Gia_ManLutNum(pGia) : Gia_ManAndNum(pGia),
fMapped ? Gia_ManLutNum(pNew) : Gia_ManAndNum(pNew),
fMapped ? "LUTs" : "ANDs" );
if ( fVerbose )
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
Gia_ManStop( pGia );
Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
Vec_WecFree( vAnds );
Vec_WecFree( vIns );
Vec_WecFree( vOuts );
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
{
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
break;
}
}
}
else {
int fOverlap = 1;
Vec_Ptr_t * vIns = NULL, * vOuts = NULL, * vNodes = NULL;
for ( i = 0; i < nIters; i++ )
{
extern Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vAigs );
abctime clk = Abc_Clock();
Gia_Man_t * pGia = Gia_ManDup( Abc_FrameReadGia(Abc_FrameGetGlobalFrame()) ); Gia_ManStaticFanoutStart(pGia);
Vec_Ptr_t * vAigs = Gia_ManExtractPartitions( pGia, i, nSuppMax, &vIns, &vOuts, &vNodes, fOverlap, fDelayOpt );
Vec_Int_t * vGains = Gia_StochProcess( vAigs, pScript, nProcs, TimeOut, 0 );
int nPartsInit = fOverlap ? Gia_ManFilterPartitions( pGia, vIns, vNodes, vOuts, vAigs, vGains, fDelayOpt ) : Vec_PtrSize(vIns);
Gia_Man_t * pNew = Gia_ManDupInsertWindows( pGia, vIns, vOuts, vAigs ); Gia_ManStaticFanoutStop(pGia);
if ( vGias ) Vec_PtrPush( vGias, Gia_ManDup(pNew) );
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pNew );
if ( fVerbose )
printf( "Iteration %3d : Using %3d -> %3d partitions. Reducing node count from %6d to %6d. ",
i, nPartsInit, Vec_PtrSize(vAigs), Gia_ManAndNum(pGia), Gia_ManAndNum(pNew) );
if ( fVerbose )
Abc_PrintTime( 0, "Time", Abc_Clock() - clk );
// cleanup
Gia_ManStop( pGia );
Vec_PtrFreeFunc( vAigs, (void (*)(void *)) Gia_ManStop );
Vec_IntFreeP( &vGains );
if ( vIns ) Vec_PtrFreeFunc( vIns, (void (*)(void *)) Vec_IntFree );
if ( vOuts ) Vec_PtrFreeFunc( vOuts, (void (*)(void *)) Vec_IntFree );
if ( vNodes ) Vec_PtrFreeFunc( vNodes, (void (*)(void *)) Vec_IntFree );
if ( nTimeToStop && Abc_Clock() > nTimeToStop )
{
printf( "Runtime limit (%d sec) is reached after %d iterations.\n", TimeOut, i );
break;
}
}
}
fMapped &= Gia_ManHasMapping(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
nLutEnd = fMapped ? Gia_ManLutNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame())) : 0;
nEnd = Gia_ManAndNum(Abc_FrameReadGia(Abc_FrameGetGlobalFrame()));
if ( fVerbose )
printf( "Cumulatively reduced %d %s after %d iterations. ",
fMapped ? nLutBeg - nLutEnd : nBeg - nEnd, fMapped ? "LUTs" : "ANDs", nIters );
printf( "Cumulatively reduced %d %s (%.2f %%) after %d iterations. ",
fMapped ? nLutBeg - nLutEnd : nBeg - nEnd, fMapped ? "LUTs" : "nodes", 100.0*(nBeg - nEnd)/Abc_MaxInt(nBeg, 1), nIters );
if ( fVerbose )
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
if ( vGias ) {
Gia_Man_t * pChoices = Gia_ManCreateChoicesArray( vGias, fVerbose );
Abc_FrameUpdateGia( Abc_FrameGetGlobalFrame(), pChoices );
// cleanup
Gia_Man_t * pTemp;
Vec_PtrForEachEntry( Gia_Man_t *, vGias, pTemp, i )
Gia_ManStop( pTemp );
Vec_PtrFree( vGias );
}
}
////////////////////////////////////////////////////////////////////////

View File

@ -20,6 +20,7 @@
#include "aig/gia/gia.h"
#include "base/main/mainInt.h"
#include "base/io/ioResub.h"
#include "misc/util/utilTruth.h"
#include "misc/extra/extra.h"
#include "misc/vec/vecHsh.h"
@ -185,6 +186,50 @@ Supp_Man_t * Supp_ManCreate( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
Supp_ManInit( p );
return p;
}
int Supp_DeriveLines2( Supp_Man_t * p )
{
assert( Vec_WrdSize(p->vSims) % p->nWords == 0 );
int n, nDivWords = Abc_Bit6WordNum( Vec_WrdSize(p->vSims) / p->nWords );
for ( n = 0; n < 2; n++ )
{
p->vDivs[n] = Vec_WrdStart( 64*p->nWords*nDivWords );
p->vPats[n] = Vec_WrdStart( 64*p->nWords*nDivWords );
Abc_TtCopy( Vec_WrdArray(p->vDivs[n]), Vec_WrdArray(p->vSims), Vec_WrdSize(p->vSims), !n );
Extra_BitMatrixTransposeP( p->vDivs[n], p->nWords, p->vPats[n], nDivWords );
}
return nDivWords;
}
Supp_Man_t * Supp_ManCreate2( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vSims, Vec_Int_t * vWeights, int nWords, int nIters, int nRounds )
{
Supp_Man_t * p = ABC_CALLOC( Supp_Man_t, 1 );
assert( Vec_WrdSize(vSims)%nWords == 0 );
p->nIters = nIters;
p->nRounds = nRounds;
p->nWords = nWords;
p->vIsfs = vIsfs;
p->vCands = Vec_IntStartNatural( Vec_WrdSize(vSims)/nWords );
p->vWeights = NULL;
p->vSims = vSims;
p->vSimsC = NULL;
p->pGia = NULL;
// computed data
p->nDivWords = Supp_DeriveLines2( p );
p->vMatrix = Vec_PtrAlloc( 100 );
p->vMask = Vec_WrdAlloc( 100 );
p->vRowTemp = Vec_WrdStart( 64*p->nDivWords );
p->vCosts = Vec_IntStart( Vec_IntSize(p->vCands) );
p->pHash = Hsh_VecManStart( 1000 );
p->vSFuncs = Vec_WrdAlloc( 1000 );
p->vSStarts = Vec_IntAlloc( 1000 );
p->vSCount = Vec_IntAlloc( 1000 );
p->vSPairs = Vec_IntAlloc( 1000 );
p->vSolutions = Vec_WecStart( 16 );
p->vTemp = Vec_IntAlloc( 10 );
p->vTempSets = Vec_IntAlloc( 10 );
p->vTempPairs = Vec_IntAlloc( 10 );
Supp_ManInit( p );
return p;
}
void Supp_ManCleanMatrix( Supp_Man_t * p )
{
Vec_Wrd_t * vTemp; int i;
@ -214,6 +259,8 @@ void Supp_ManDelete( Supp_Man_t * p )
Vec_IntFreeP( &p->vTemp );
Vec_IntFreeP( &p->vTempSets );
Vec_IntFreeP( &p->vTempPairs );
if ( p->vSims == NULL )
Vec_IntFreeP( &p->vCands );
ABC_FREE( p );
}
int Supp_ManMemory( Supp_Man_t * p )
@ -572,6 +619,10 @@ int Supp_FindNextDiv( Supp_Man_t * p, int Pair )
iDiv1 = iDiv1 == -1 ? ABC_INFINITY : iDiv1;
iDiv2 = iDiv2 == -1 ? ABC_INFINITY : iDiv2;
iDiv = Abc_MinInt( iDiv1, iDiv2 );
// return -1 if the pair cannot be distinguished by any divisor
// in this case the original resub problem has no solution
if ( iDiv == ABC_INFINITY )
return -1;
assert( iDiv >= 0 && iDiv < Vec_IntSize(p->vCands) );
return iDiv;
}
@ -582,6 +633,8 @@ int Supp_ManRandomSolution( Supp_Man_t * p, int iSet, int fVerbose )
{
int Pair = Supp_ComputePair( p, iSet );
int iDiv = Supp_FindNextDiv( p, Pair );
if ( iDiv == -1 )
return -1;
iSet = Supp_ManSubsetAdd( p, iSet, iDiv, fVerbose );
if ( Supp_SetFuncNum(p, iSet) > 0 )
Vec_IntPush( p->vTempSets, iSet );
@ -765,6 +818,53 @@ void Supp_DeriveDumpSol( Vec_Int_t * vSet, Vec_Int_t * vRes, int nDivs )
printf( "Dumped solution info file \"%s\".\n", Buffer );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Supp_DeriveDumpProb2( Vec_Wrd_t * vIsfs, Vec_Wrd_t * vDivs, int nWords, Vec_Int_t * vSupp, Vec_Int_t * vRes )
{
char Buffer[100]; int i, k, Temp, nDivs = Vec_WrdSize(vDivs)/nWords;
int RetValue = sprintf( Buffer, "%02d.pla", s_Counter );
FILE * pFile = fopen( Buffer, "wb" );
if ( pFile == NULL )
printf( "Cannot open output file.\n" );
// fprintf( pFile, "resyn %d %d %d %d\n", 0, nDivs, 1, 64*nWords );
fprintf( pFile, ".i %d\n", nDivs );
fprintf( pFile, ".o %d\n", 1 );
fprintf( pFile, ".p %d\n", 64*nWords );
for ( i = 0; i < 64*nWords; i++ ) {
for ( k = 0; k < nDivs; k++ )
fprintf( pFile, "%d", Abc_TtGetBit(Vec_WrdEntryP(vDivs, k*nWords), i) );
// fprintf( pFile, " %d\n", Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 1*nWords), i) );
if ( Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 0*nWords), i) )
fprintf( pFile, " 0\n" );
else if ( Abc_TtGetBit(Vec_WrdEntryP(vIsfs, 1*nWords), i) )
fprintf( pFile, " 1\n" );
else
fprintf( pFile, " -\n" );
}
fprintf( pFile, ".e\n" );
fprintf( pFile, "\n.s" );
Vec_IntForEachEntryStart( vSupp, Temp, i, 2 )
fprintf( pFile, " %d", Temp );
fprintf( pFile, "\n.a" );
Vec_IntForEachEntry( vRes, Temp, i )
fprintf( pFile, " %d", Temp );
fprintf( pFile, "\n" );
fclose ( pFile );
RetValue = 0;
}
/**Function*************************************************************
Synopsis []
@ -804,6 +904,7 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe
}
if ( iSolBest > 0 && (CostBest >> 2) < 50 )
{
Vec_Int_t * vDivs2 = Vec_IntAlloc( 100 );
Vec_Int_t * vSet = Hsh_VecReadEntry( p->pHash, iSolBest ); int i, iObj;
vRes = Gia_ManDeriveSolutionOne( p->pGia, p->vSims, p->vIsfs, p->vCands, vSet, p->nWords, CostBest & 3 );
assert( !vRes || Vec_IntSize(vRes) == 2*(CostBest >> 2)+1 );
@ -811,13 +912,18 @@ Vec_Int_t * Supp_ManFindBestSolution( Supp_Man_t * p, Vec_Wec_t * vSols, int fVe
{
Vec_IntClear( *pvDivs );
Vec_IntPushTwo( *pvDivs, -1, -1 );
Vec_IntForEachEntry( vSet, iObj, i )
Vec_IntPushTwo( vDivs2, -1, -1 );
Vec_IntForEachEntry( vSet, iObj, i ) {
Vec_IntPush( *pvDivs, Vec_IntEntry(p->vCands, iObj) );
Vec_IntPush( vDivs2, iObj );
}
}
//Supp_DeriveDumpProbC( p->vIsfs, p->vDivsC, p->nWords );
//Supp_DeriveDumpProb( p->vIsfs, p->vDivs[1], p->nWords );
//Supp_DeriveDumpSol( vSet, vRes, Vec_WrdSize(p->vDivs[1])/p->nWords );
//s_Counter++;
//Supp_DeriveDumpProb2( p->vIsfs, p->vDivs[1], p->nWords, vDivs2, vRes );
Vec_IntFree( vDivs2 );
s_Counter++;
}
return vRes;
}
@ -864,7 +970,11 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
int i, r, iSet, iBest = -1;
abctime clk = Abc_Clock();
Vec_Int_t * vRes = NULL;
Supp_Man_t * p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
Supp_Man_t * p;
if ( vCands )
p = Supp_ManCreate( vIsfs, vCands, vWeights, vSims, vSimsC, nWords, pGia, nIters, nRounds );
else
p = Supp_ManCreate2( vIsfs, vSims, NULL, nWords, nIters, nRounds );
if ( Supp_SetFuncNum(p, 0) == 0 )
{
Supp_ManDelete( p );
@ -875,7 +985,7 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
return vRes;
}
if ( fVerbose )
printf( "\nUsing %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
printf( "Using %d divisors with %d words. Problem has %d functions and %d minterm pairs.\n",
Vec_IntSize(p->vCands), p->nWords, Supp_SetFuncNum(p, 0), Supp_SetPairNum(p, 0) );
//iBest = Supp_FindGivenOne( p );
if ( iBest == -1 )
@ -883,6 +993,10 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
{
Supp_ManAddPatternsFunc( p, i );
iSet = Supp_ManRandomSolution( p, 0, fVeryVerbose );
if ( iSet == -1 ) {
Supp_ManDelete( p );
return NULL;
}
for ( r = 0; r < p->nRounds; r++ )
{
if ( fVeryVerbose )
@ -898,6 +1012,10 @@ Vec_Int_t * Supp_ManCompute( Vec_Wrd_t * vIsfs, Vec_Int_t * vCands, Vec_Int_t *
iBest = iSet;
}
iSet = Supp_ManReconstruct( p, fVeryVerbose );
if ( iSet == -1 ) {
Supp_ManDelete( p );
return NULL;
}
}
if ( fVeryVerbose )
printf( "Matrix size %d.\n", Vec_PtrSize(p->vMatrix) );
@ -948,6 +1066,85 @@ void Supp_ManComputeTest( Gia_Man_t * p )
Vec_IntFree( vRes );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Supp_RecordSolution( char * pFileName, Vec_Int_t * vDivs, Vec_Int_t * vRes )
{
FILE * pFile = fopen( pFileName, "ab" );
if ( pFile == NULL ) {
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
return;
}
int i, Temp;
fprintf( pFile, "\n.s" );
Vec_IntForEachEntryStart( vDivs, Temp, i, 2 )
fprintf( pFile, " %d", Temp );
fprintf( pFile, "\n.a" );
Vec_IntForEachEntry( vRes, Temp, i )
fprintf( pFile, " %d", Temp-2 );
fprintf( pFile, "\n" );
fclose( pFile );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Supp_GenerateGia( Vec_Int_t * vRes, Vec_Int_t * vDivs )
{
int i, nAddOn = 2, nIns = Vec_IntSize(vDivs)-2;
int iLit0, iLit1, iTopLit = Vec_IntEntryLast(vRes);
assert( Vec_IntSize(vRes) > 0 );
assert( Vec_IntSize(vRes) % 2 == 1 );
Gia_Man_t * pNew = Gia_ManStart( 100 );
pNew->pName = Abc_UtilStrsav( "resub" );
for ( i = 0; i < nIns; i++ )
Gia_ManAppendCi(pNew);
Vec_IntForEachEntryDouble( vRes, iLit0, iLit1, i ) {
if ( iLit0 < iLit1 )
Gia_ManAppendAnd( pNew, iLit0-nAddOn, iLit1-nAddOn );
else if ( iLit0 > iLit1 )
Gia_ManAppendXor( pNew, iLit0-nAddOn, iLit1-nAddOn );
else assert( 0 );
}
Gia_ManAppendCo(pNew, iTopLit-nAddOn);
return pNew;
}
Gia_Man_t * Supp_ManSolveOne( char * pFileName, int nIters, int nRounds, int fWriteSol, int fVerbose )
{
//Abc_Random(1);
Abc_RData_t * p = Abc_ReadPla( pFileName );
if ( p == NULL ) return NULL;
assert( p->nOuts == 1 );
Vec_Int_t * vDivs = Vec_IntAlloc( 100 );
Vec_Int_t * vRes = Supp_ManCompute( p->vSimsOut, NULL, NULL, p->vSimsIn, NULL, p->nSimWords, NULL, &vDivs, nIters, nRounds, fVerbose );
if ( fVerbose && vDivs ) printf( "Divisors: " ), Vec_IntPrint( vDivs );
if ( fVerbose && vRes ) printf( "Solution: " ), Vec_IntPrint( vRes );
Gia_Man_t * pNew = vRes ? Supp_GenerateGia( vRes, vDivs ) : NULL;
if ( fWriteSol && vDivs && vRes )
Supp_RecordSolution( pFileName, vDivs, vRes );
Vec_IntFreeP( &vRes );
Vec_IntFreeP( &vDivs );
Abc_RDataStop( p );
return pNew;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -469,7 +469,266 @@ void Gia_ManCheckIntegrityWithBoxes( Gia_Man_t * p )
Synopsis [Computes representatives in terms of the original objects.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManFraigPrintDebugInfo( Gia_Man_t * p )
{
if ( p->vRegClasses )
printf( "Gia_ManFraigSelectReprs: vRegClasses with %d entries\n", Vec_IntSize(p->vRegClasses) );
if ( p->vFlopClasses )
printf( "Gia_ManFraigSelectReprs: vFlopClasses with %d entries\n", Vec_IntSize(p->vFlopClasses) );
// Debug: Show all CIs and their types
// In unnormalized AIG with boxes: flop outputs are the last nFlops CIs
printf( "Circuit has %d CIs (PiNum=%d, RegBoxNum=%d)\n",
Gia_ManCiNum(p), Gia_ManPiNum(p), Gia_ManRegBoxNum(p) );
int nTotalCis = Gia_ManCiNum(p);
int nFlops = Gia_ManRegBoxNum(p);
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
printf( " -> First %d CIs are PIs/box outputs, last %d CIs are flop outputs\n",
nFirstFlop, nFlops );
Gia_Obj_t * pCiObj;
int j;
Gia_ManForEachCi( p, pCiObj, j )
{
int CiId = Gia_ObjCioId(pCiObj);
const char* type = (CiId >= nFirstFlop) ? "FlopOut" : "PI/BoxOut";
int typeId = (CiId >= nFirstFlop) ? (CiId - nFirstFlop) : CiId;
printf( " CI obj %d: CiId=%d (%s %d)\n", Gia_ObjId(p, pCiObj), CiId, type, typeId );
}
}
/**Function*************************************************************
Synopsis [Mark box outputs that feed restricted flops.]
Description [This prevents box merging from indirectly eliminating restricted flops.]
SideEffects [Sets fMark1 on box output CIs.]
SeeAlso []
***********************************************************************/
void Gia_ManFraigMarkRestrictedBoxOutputs( Gia_Man_t * p, int fVerbose )
{
int i;
for ( i = 0; i < Gia_ManRegBoxNum(p); i++ )
{
int needsProtection = 0;
// Check if this flop has restrictions
if ( p->vRegClasses && i < Vec_IntSize(p->vRegClasses) )
{
if ( Vec_IntEntry(p->vRegClasses, i) == 0 ) // Domain 0 = not removeable
needsProtection = 1;
}
if ( p->vFlopClasses && i < Vec_IntSize(p->vFlopClasses) )
{
if ( Vec_IntEntry(p->vFlopClasses, i) == 0 ) // Class 0 = unmergeable
needsProtection = 1;
}
// If flop needs protection, mark the box output driving it
// For Test6: box output with CiId (i+1) feeds flop i
if ( needsProtection )
{
int targetCiId = i + 1; // Box output that feeds this flop
// Find and mark the CI with this CiId
Gia_Obj_t * pCi;
int j;
Gia_ManForEachCi( p, pCi, j )
{
if ( Gia_ObjCioId(pCi) == targetCiId )
{
pCi->fMark1 = 1; // Mark this box output as unmergeable
if ( fVerbose )
printf( "Marking box output (obj %d, CiId %d) for flop %d as unmergeable\n",
Gia_ObjId(p, pCi), targetCiId, i );
break;
}
}
}
}
}
/**Function*************************************************************
Synopsis [Print debug info about equivalence being processed.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManFraigPrintEquivInfo( Gia_Man_t * p, Gia_Obj_t * pObj, int i,
Gia_Obj_t * pReprObj, int * pClp2Gia,
int iLitClp, int iReprClp )
{
const char* typeStr = Gia_ObjIsCi(pObj) ? "CI" : (Gia_ObjIsAnd(pObj) ? "AND" : "OTHER");
printf( "Found equiv: obj %d (%s) repr %d - iLitClp=%d iReprClp=%d\n",
i, typeStr, pClp2Gia[iReprClp], iLitClp, iReprClp );
// Also show the representative's type
const char* reprTypeStr = Gia_ObjIsCi(pReprObj) ? "CI" : (Gia_ObjIsAnd(pReprObj) ? "AND" : "OTHER");
printf( " Representative obj %d is %s\n", pClp2Gia[iReprClp], reprTypeStr );
// If this is a CI, show more details
if ( Gia_ObjIsCi(pObj) )
{
// In unnormalized AIG with boxes, flop outputs are the last nFlops CIs
int CiId = Gia_ObjCioId(pObj);
int nTotalCis = Gia_ManCiNum(p); // Total CIs in unnormalized AIG
int nFlops = Gia_ManRegBoxNum(p);
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
printf( " -> obj %d: CiId=%d, TotalCIs=%d, nFlops=%d, FirstFlopCI=%d\n",
i, CiId, nTotalCis, nFlops, nFirstFlop );
if ( CiId >= nFirstFlop )
printf( " -> This is Flop output %d\n", CiId - nFirstFlop );
else
printf( " -> This is PI/BoxOut %d\n", CiId );
}
}
/**Function*************************************************************
Synopsis [Check flop and box output restrictions for merging.]
Description [Returns 1 if objects should be skipped, 0 if they can be merged.]
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManFraigCheckFlopRestrictions( Gia_Man_t * p, Gia_Obj_t * pObj, int i,
int * pClp2Gia, int iReprClp,
int fVerbose, int * pnSkipped )
{
// First check if either CI feeds restricted flops (marked with fMark1)
Gia_Obj_t * pReprObj = Gia_ManObj(p, pClp2Gia[iReprClp]);
if ( fVerbose && Gia_ObjIsCi(pObj) )
printf( " Checking obj %d: fMark1=%d\n", i, pObj->fMark1 );
if ( fVerbose && Gia_ObjIsCi(pReprObj) )
printf( " Checking repr %d: fMark1=%d\n", pClp2Gia[iReprClp], pReprObj->fMark1 );
if ( Gia_ObjIsCi(pObj) && pObj->fMark1 )
{
if ( fVerbose )
printf( " -> Skipping equiv: obj %d feeds restricted flop\n", i );
(*pnSkipped)++;
return 1;
}
if ( Gia_ObjIsCi(pReprObj) && pReprObj->fMark1 )
{
if ( fVerbose )
printf( " -> Skipping equiv: repr %d feeds restricted flop\n", pClp2Gia[iReprClp] );
(*pnSkipped)++;
return 1;
}
// Check vRegClasses and vFlopClasses restrictions if both are flops
// For flops to be mergeable, they must satisfy BOTH conditions:
// 1. vRegClasses: same non-zero clock domain (0 = not removeable/mergeable)
// 2. vFlopClasses: same non-zero merge class (0 = unmergeable)
if ( (p->vRegClasses || p->vFlopClasses) && Gia_ObjIsCi(pObj) )
{
// In unnormalized AIGs with boxes, flop outputs are the last nFlops CIs
// They are not marked with fMark0 (which marks CIs feeding flop inputs)
int iFlopCur = -1, iFlopRepr = -1;
int nTotalCis = Gia_ManCiNum(p); // Total CIs
int nFlops = Gia_ManRegBoxNum(p);
int nFirstFlop = nTotalCis - nFlops; // First flop CI index
// Get the CI ID of the current object
int CiIdCur = Gia_ObjCioId(pObj);
if ( fVerbose )
printf( " Checking CI: obj %d, CiId %d, nTotalCis=%d, nFlops=%d, FirstFlopCI=%d\n",
i, CiIdCur, nTotalCis, nFlops, nFirstFlop );
// Check if current object is a flop output (last nFlops CIs)
if ( CiIdCur >= nFirstFlop && CiIdCur < nTotalCis )
iFlopCur = CiIdCur - nFirstFlop;
// Check if representative is a flop output
int iRepr = pClp2Gia[iReprClp];
Gia_Obj_t * pRepr = Gia_ManObj(p, iRepr);
if ( Gia_ObjIsCi(pRepr) )
{
int CiIdRepr = Gia_ObjCioId(pRepr);
if ( CiIdRepr >= nFirstFlop && CiIdRepr < nTotalCis )
iFlopRepr = CiIdRepr - nFirstFlop;
}
// Apply merging restrictions
if ( iFlopCur >= 0 && iFlopRepr >= 0 )
{
if ( fVerbose )
printf( "Checking flop merge: flop %d and flop %d\n", iFlopCur, iFlopRepr );
// Check vRegClasses (clock domains) first
if ( p->vRegClasses )
{
assert( iFlopCur < Vec_IntSize(p->vRegClasses) );
assert( iFlopRepr < Vec_IntSize(p->vRegClasses) );
int DomainCur = Vec_IntEntry(p->vRegClasses, iFlopCur);
int DomainRepr = Vec_IntEntry(p->vRegClasses, iFlopRepr);
if ( fVerbose )
printf( " Clock domains: %d and %d\n", DomainCur, DomainRepr );
// Skip merging if either is in domain 0 or domains don't match
if ( DomainCur == 0 || DomainRepr == 0 || DomainCur != DomainRepr )
{
if ( fVerbose )
printf( " -> Skipping due to clock domain restriction\n" );
(*pnSkipped)++;
return 1; // Skip this merging
}
}
// Check vFlopClasses (merge classes) second
if ( p->vFlopClasses )
{
assert( iFlopCur < Vec_IntSize(p->vFlopClasses) );
assert( iFlopRepr < Vec_IntSize(p->vFlopClasses) );
int ClassCur = Vec_IntEntry(p->vFlopClasses, iFlopCur);
int ClassRepr = Vec_IntEntry(p->vFlopClasses, iFlopRepr);
if ( fVerbose )
printf( " Merge classes: %d and %d\n", ClassCur, ClassRepr );
// Skip merging if classes don't match or class is 0 (unmergeable)
if ( ClassCur == 0 || ClassRepr == 0 || ClassCur != ClassRepr )
{
if ( fVerbose )
printf( " -> Skipping due to merge class restriction\n" );
(*pnSkipped)++;
return 1; // Skip this merging
}
}
}
}
return 0; // OK to merge
}
/**Function*************************************************************
Synopsis [Select representatives for the collapsed AIG.]
Description []
SideEffects []
SeeAlso []
@ -483,8 +742,13 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
int * pReprs = ABC_FALLOC( int, Gia_ManObjNum(p) );
int * pClp2Gia = ABC_FALLOC( int, Gia_ManObjNum(pClp) );
int i, iLitClp, iLitClp2, iReprClp, fCompl;
int nConsts = 0, nReprs = 0;
int nConsts = 0, nReprs = 0, nSkipped = 0;
assert( pManTime != NULL );
// Debug: Check if vRegClasses and vFlopClasses are present
if ( fVerbose )
Gia_ManFraigPrintDebugInfo( p );
// count the number of equivalent objects
Gia_ManForEachObj1( pClp, pObj, i )
{
@ -513,6 +777,11 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
vCarryOuts = Gia_ManComputeCarryOuts( p );
Gia_ManForEachObjVec( vCarryOuts, p, pObj, i )
pObj->fMark0 = 1;
// Additionally, mark box outputs that feed restricted flops using fMark1
// This prevents box merging from indirectly eliminating restricted flops
if ( p->vRegClasses || p->vFlopClasses )
Gia_ManFraigMarkRestrictedBoxOutputs( p, fVerbose );
if ( fVerbose )
printf( "Fixed %d flop inputs and %d box/box connections (out of %d non-flop boxes).\n",
Gia_ManRegBoxNum(p), Vec_IntSize(vCarryOuts), Gia_ManNonRegBoxNum(p) );
@ -520,11 +789,23 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
// collect equivalent node info
pFlopTypes[0] = pFlopTypes[1] = pFlopTypes[2] = 0;
if ( fVerbose )
printf( "Checking flop equivalences in collapsed circuit:\n" );
Gia_ManForEachRo( pClp, pObj, i )
{
Gia_Obj_t * pRepr = Gia_ObjReprObj(pClp, i);
if ( pRepr && pRepr != pObj )
{
if ( fVerbose )
{
printf( " Flop %d (clp obj %d) has repr obj %d", i - Gia_ManPiNum(pClp),
i, Gia_ObjId(pClp, pRepr) );
if ( pRepr == Gia_ManConst0(pClp) )
printf( " (const 0)");
else if ( Gia_ObjIsRo(pClp, pRepr) )
printf( " (another flop: %d)", Gia_ObjCioId(pRepr) - (Gia_ManPiNum(pClp) - Gia_ManRegNum(pClp)) );
printf( "\n" );
}
if ( pRepr == Gia_ManConst0(pClp) )
pFlopTypes[0]++;
else if ( Gia_ObjIsRo(pClp, pRepr) )
@ -549,9 +830,21 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
if ( pClp2Gia[iReprClp] == -1 )
pClp2Gia[iReprClp] = i;
else
{
{
iLitClp2 = Gia_ObjValue( Gia_ManObj(p, pClp2Gia[iReprClp]) );
assert( Gia_ObjReprSelf(pClp, Abc_Lit2Var(iLitClp)) == Gia_ObjReprSelf(pClp, Abc_Lit2Var(iLitClp2)) );
// Debug: Show what's being merged
if ( fVerbose )
{
Gia_Obj_t * pReprObj = Gia_ManObj(p, pClp2Gia[iReprClp]);
Gia_ManFraigPrintEquivInfo( p, pObj, i, pReprObj, pClp2Gia, iLitClp, iReprClp );
}
// Check flop restrictions for merging
if ( Gia_ManFraigCheckFlopRestrictions( p, pObj, i, pClp2Gia, iReprClp, fVerbose, &nSkipped ) )
continue;
fCompl = Abc_LitIsCompl(iLitClp) ^ Abc_LitIsCompl(iLitClp2);
fCompl ^= Gia_ManObj(pClp, Abc_Lit2Var(iLitClp))->fPhase;
fCompl ^= Gia_ManObj(pClp, Abc_Lit2Var(iLitClp2))->fPhase;
@ -565,9 +858,16 @@ int * Gia_ManFraigSelectReprs( Gia_Man_t * p, Gia_Man_t * pClp, int fVerbose, in
}
ABC_FREE( pClp2Gia );
Gia_ManForEachCi( p, pObj, i )
{
pObj->fMark0 = 0;
pObj->fMark1 = 0; // Clean up the restricted flop marker
}
if ( fVerbose )
{
printf( "Found %d const objects and %d other objects.\n", nConsts, nReprs );
if ( (p->vRegClasses || p->vFlopClasses) && nSkipped > 0 )
printf( "Skipped %d flop mergings due to clock domain or merge class restrictions.\n", nSkipped );
}
return pReprs;
}
@ -737,12 +1037,21 @@ Gia_Man_t * Gia_ManSweepWithBoxesAndDomains( Gia_Man_t * p, void * pParsS, int f
***********************************************************************/
Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS, int fConst, int fEquiv, int fVerbose, int fVerbEquivs )
{
{
Gia_Man_t * pClp, * pNew, * pTemp;
int * pReprs, pFlopTypes[3] = {0};
int nFlopsNew, nFlops;
assert( Gia_ManRegNum(p) == 0 );
assert( p->pAigExtra != NULL );
// Debug: Check if vRegClasses and vFlopClasses are present
if ( fVerbose )
{
if ( p->vRegClasses )
printf( "Input has vRegClasses with %d entries\n", Vec_IntSize(p->vRegClasses) );
if ( p->vFlopClasses )
printf( "Input has vFlopClasses with %d entries\n", Vec_IntSize(p->vFlopClasses) );
}
// consider seq synthesis with multiple clock domains
if ( pParsC == NULL && Gia_ManClockDomainNum(p) > 1 )
return Gia_ManSweepWithBoxesAndDomains( p, pParsS, fConst, fEquiv, fVerbose, fVerbEquivs );
@ -751,7 +1060,7 @@ Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS,
if ( pNew == NULL )
return NULL;
Gia_ManTransferTiming( pNew, p );
nFlops = Vec_IntCountEntry(pNew->vRegClasses, 1);
nFlops = pNew->vRegClasses ? Vec_IntCountEntry(pNew->vRegClasses, 1) : 0;
// find global equivalences
pClp = Gia_ManDupCollapse( pNew, pNew->pAigExtra, NULL, pParsC ? 0 : 1 );
//Gia_DumpAiger( pClp, p->pSpec, 1, 1 );
@ -775,7 +1084,7 @@ Gia_Man_t * Gia_ManSweepWithBoxes( Gia_Man_t * p, void * pParsC, void * pParsS,
pNew = Gia_ManDupWithBoxes( pTemp = pNew, pParsC ? 0 : 1 );
Gia_ManStop( pTemp );
// report
nFlopsNew = Vec_IntCountEntry(pNew->vRegClasses, 1);
nFlopsNew = pNew->vRegClasses ? Vec_IntCountEntry(pNew->vRegClasses, 1) : 0;
pFlopTypes[2] = nFlops - nFlopsNew - (pFlopTypes[0] + pFlopTypes[1]);
if ( fVerbEquivs )
{

View File

@ -612,7 +612,7 @@ Vec_Int_t * Gia_ManSwiSimulate( Gia_Man_t * pAig, Gia_ParSwi_t * pPars )
else if ( pPars->fProbTrans )
{
Gia_ManForEachObj( pAig, pObj, i )
pSwitching[i] = Gia_ManSwiComputeProbOne( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
pSwitching[i] = Gia_ManSwiComputeSwitching( p->pData1[i], pPars->nWords*(pPars->nIters-pPars->nPref) );
}
else
{
@ -681,6 +681,33 @@ Vec_Int_t * Gia_ManComputeSwitchProbs( Gia_Man_t * pGia, int nFrames, int nPref,
// perform the computation of switching activity
return Gia_ManSwiSimulate( pGia, pPars );
}
Vec_Int_t * Gia_ManComputeSwitchProbs2( Gia_Man_t * pGia, int nFrames, int nPref, int fProbOne, int nRandPiFactor )
{
Gia_ParSwi_t Pars, * pPars = &Pars;
// set the default parameters
Gia_ManSetDefaultParamsSwi( pPars );
pPars->nRandPiFactor = nRandPiFactor;
// override some of the defaults
pPars->nIters = nFrames; // set number of total timeframes
if ( Abc_FrameReadFlag("seqsimframes") )
pPars->nIters = atoi( Abc_FrameReadFlag("seqsimframes") );
pPars->nPref = nPref; // set number of first timeframes to skip
// decide what should be computed
if ( fProbOne )
{
// if the user asked to compute propability of 1, we do not need transition information
pPars->fProbOne = 1; // enable computing probabiblity of being one
pPars->fProbTrans = 0; // disable computing transition probability
}
else
{
// if the user asked for transition propabability, we do not need to compute probability of 1
pPars->fProbOne = 0; // disable computing probabiblity of being one
pPars->fProbTrans = 1; // enable computing transition probability
}
// perform the computation of switching activity
return Gia_ManSwiSimulate( pGia, pPars );
}
Vec_Int_t * Saig_ManComputeSwitchProbs( Aig_Man_t * pAig, int nFrames, int nPref, int fProbOne )
{
Vec_Int_t * vSwitching, * vResult;

View File

@ -77,7 +77,8 @@ int Gia_ManClockDomainNum( Gia_Man_t * p )
if ( p->vRegClasses == NULL )
return 0;
nDoms = Vec_IntFindMax(p->vRegClasses);
assert( Vec_IntCountEntry(p->vRegClasses, 0) == 0 );
// Class 0 is now allowed - means unmergeable flops not in any clock domain
// assert( Vec_IntCountEntry(p->vRegClasses, 0) == 0 );
for ( i = 1; i <= nDoms; i++ )
if ( Vec_IntCountEntry(p->vRegClasses, i) > 0 )
Count++;
@ -372,8 +373,14 @@ Vec_Int_t * Gia_ManOrderWithBoxes( Gia_Man_t * p )
Synopsis [Duplicates AIG according to the timing manager.]
Description []
Description [Converts a normalized AIG to unnormalized form for box processing.
In normalized AIG: CIs are ordered as PIs + BoxOutputs + FlopOutputs
In unnormalized AIG: CIs are ordered as PIs + FlopOutputs only,
with BoxOutputs spread throughout the AIG in topological order.
This transformation allows proper timing-aware processing of boxes.
For sequential AIGs, flop count is preserved, with flop outputs
remaining as CIs and flop inputs as COs.]
SideEffects []
SeeAlso []
@ -952,7 +959,100 @@ Gia_Man_t * Gia_ManDupCollapse( Gia_Man_t * p, Gia_Man_t * pBoxes, Vec_Int_t * v
SeeAlso []
***********************************************************************/
int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fDumpFiles, int fVerbose, char * pFileSpec )
Vec_Int_t * Gia_ManVerifyFindNameMapping( Gia_Man_t * p, Gia_Man_t * p1, Gia_Man_t * p2, Vec_Int_t * vMap1, Vec_Int_t * vMap2 )
{
Vec_Int_t * vRes = Vec_IntStartFull(Vec_IntSize(vMap2));
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) );
int i, Entry, iRepr, fCompl, iLit;
Gia_Obj_t * pObj;
Gia_ManSetPhase( p1 );
Gia_ManSetPhase( p2 );
Vec_IntForEachEntry( vMap1, Entry, i )
{
if ( Entry == -1 )
continue;
pObj = Gia_ManObj( p1, Abc_Lit2Var(Entry) );
if ( ~pObj->Value == 0 )
continue;
fCompl = Abc_LitIsCompl(Entry) ^ pObj->fPhase;
iRepr = Gia_ObjReprSelf( p, Abc_Lit2Var(pObj->Value) );
Vec_IntWriteEntry( vMap, iRepr, Abc_Var2Lit( i, fCompl ) );
}
Vec_IntForEachEntry( vMap2, Entry, i )
{
if ( Entry == -1 )
continue;
pObj = Gia_ManObj( p2, Abc_Lit2Var(Entry) );
if ( ~pObj->Value == 0 )
continue;
fCompl = Abc_LitIsCompl(Entry) ^ pObj->fPhase;
iRepr = Gia_ObjReprSelf( p, Abc_Lit2Var(pObj->Value) );
if ( (iLit = Vec_IntEntry(vMap, iRepr)) == -1 )
continue;
Vec_IntWriteEntry( vRes, i, Abc_LitNotCond( iLit, fCompl ) );
}
Vec_IntFill( vMap, Gia_ManCoNum(p1), -1 );
Vec_IntForEachEntry( vMap1, Entry, i )
{
if ( Entry == -1 )
continue;
pObj = Gia_ManObj( p1, Abc_Lit2Var(Entry) );
if ( !Gia_ObjIsCo(pObj) )
continue;
Vec_IntWriteEntry( vMap, Gia_ObjCioId(pObj), i );
}
Vec_IntForEachEntry( vMap2, Entry, i )
{
if ( Entry == -1 )
continue;
pObj = Gia_ManObj( p2, Abc_Lit2Var(Entry) );
if ( !Gia_ObjIsCo(pObj) )
continue;
assert( Vec_IntEntry(vRes, i) == -1 );
Vec_IntWriteEntry( vRes, i, Abc_Var2Lit( Vec_IntEntry(vMap, Gia_ObjCioId(pObj)), 0 ) );
assert( Vec_IntEntry(vRes, i) != -1 );
}
Vec_IntFree( vMap );
return vRes;
}
void Gia_ManVerifyVerifyNameMapping( Gia_Man_t * p, Gia_Man_t * p1, Gia_Man_t * p2, Vec_Int_t * vMap1, Vec_Int_t * vMap2, Vec_Int_t * vMapRes )
{
int iImpl, iReprSpec, iReprImpl, nSize = Vec_IntSize(vMap2);
Gia_Obj_t * pObjSpec, * pObjImpl;
if ( vMapRes == NULL || p == NULL || p->pReprs == NULL )
return;
assert( Vec_IntSize(vMapRes) == nSize );
Gia_ManSetPhase( p1 );
Gia_ManSetPhase( p2 );
for ( iImpl = 0; iImpl < nSize; iImpl++ )
if ( Vec_IntEntry(vMapRes, iImpl) >= 0 )
{
int Entry = Vec_IntEntry( vMapRes, iImpl );
int iSpec = Abc_Lit2Var( Entry );
int fCompl = Abc_LitIsCompl( Entry );
int iLitSpec = Vec_IntEntry( vMap1, iSpec );
int iLitImpl = Vec_IntEntry( vMap2, iImpl );
pObjSpec = Gia_ManObj( p1, Abc_Lit2Var(iLitSpec) );
if ( Gia_ObjIsCo(pObjSpec) )
continue;
if ( ~pObjSpec->Value == 0 )
continue;
pObjImpl = Gia_ManObj( p2, Abc_Lit2Var(iLitImpl) );
if ( ~pObjImpl->Value == 0 )
continue;
iReprSpec = Gia_ObjReprSelf( p, Abc_Lit2Var(pObjSpec->Value) );
iReprImpl = Gia_ObjReprSelf( p, Abc_Lit2Var(pObjImpl->Value) );
if ( iReprSpec != iReprImpl )
printf( "Found functional mismatch for ImplId %d and SpecId %d.\n", iImpl, iSpec );
if ( (pObjImpl->fPhase ^ Abc_LitIsCompl(iLitImpl)) != (pObjSpec->fPhase ^ Abc_LitIsCompl(iLitSpec) ^ fCompl) )
printf( "Found phase mismatch for ImplId %d and SpecId %d.\n", iImpl, iSpec );
}
}
int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fSeq, int fObjIdMap, int fDumpFiles, int fVerbose, char * pFileSpec )
{
int Status = -1;
Gia_Man_t * pSpec, * pGia0, * pGia1, * pMiter;
@ -1029,6 +1129,16 @@ int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fS
// compute the miter
if ( fSeq )
{
extern Gia_Man_t * Gia_ManDupAddFlop( Gia_Man_t * p );
if ( Gia_ManRegNum(pGia0) == 0 ) {
pGia0 = Gia_ManDupAddFlop( pMiter = pGia0 );
Gia_ManStop( pMiter );
}
if ( Gia_ManRegNum(pGia1) == 0 ) {
pGia1 = Gia_ManDupAddFlop( pMiter = pGia1 );
Gia_ManStop( pMiter );
}
pMiter = Gia_ManMiter( pGia0, pGia1, 0, 0, 1, 0, fVerbose );
if ( pMiter )
{
@ -1052,12 +1162,30 @@ int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fS
{
Cec_ParCec_t ParsCec, * pPars = &ParsCec;
Cec_ManCecSetDefaultParams( pPars );
pPars->nBTLimit = nBTLimit;
pPars->TimeLimit = nTimeLim;
pPars->fVerbose = fVerbose;
pPars->nBTLimit = nBTLimit;
pPars->TimeLimit = nTimeLim;
pPars->fUseOrigIds = fObjIdMap;
pPars->fVerbose = fVerbose;
Status = Cec_ManVerify( pMiter, pPars );
if ( pPars->iOutFail >= 0 )
Abc_Print( 1, "Verification failed for at least one output (%d).\n", pPars->iOutFail );
if ( fObjIdMap ) {
Gia_Man_t * pReduced = Gia_ManOrigIdsReduce( pMiter, pMiter->vIdsEquiv );
Gia_ManStop( pReduced );
Gia_Obj_t * pObj; int i;
Vec_Int_t * vCopy0 = Vec_IntAlloc(Gia_ManObjNum(pSpec));
Gia_ManForEachObj( pSpec, pObj, i )
Vec_IntPush( vCopy0, pObj->Value );
Vec_Int_t * vCopy1 = Vec_IntAlloc(Gia_ManObjNum(pGia));
Gia_ManForEachObj( pGia, pObj, i )
Vec_IntPush( vCopy1, pObj->Value );
Vec_IntFreeP( &pGia->vEquLitIds );
pGia->vEquLitIds = Gia_ManVerifyFindNameMapping( pMiter, pGia0, pGia1, vCopy0, vCopy1 );
assert( Vec_IntSize(pGia->vEquLitIds) == Gia_ManObjNum(pGia) );
Gia_ManVerifyVerifyNameMapping( pMiter, pGia0, pGia1, vCopy0, vCopy1, pGia->vEquLitIds );
Vec_IntFree( vCopy0 );
Vec_IntFree( vCopy1 );
}
Gia_ManStop( pMiter );
}
}
@ -1067,10 +1195,30 @@ int Gia_ManVerifyWithBoxes( Gia_Man_t * pGia, int nBTLimit, int nTimeLim, int fS
return Status;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_ManDeriveBoxMapping( Gia_Man_t * pGia )
{
Tim_Man_t * pTim = (Tim_Man_t *)pGia->pManTime;
Vec_Int_t * vRes = Vec_IntAlloc( 100 );
int i, nBoxes = Tim_ManBoxNum( pTim );
for ( i = 0; i < nBoxes; i++ )
Vec_IntPush( vRes, Tim_ManBoxCopy(pTim, i) );
return vRes;
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -37,7 +37,7 @@
#ifdef ABC_USE_PTHREADS
#ifdef _WIN32
#if defined(_WIN32) && !defined(__MINGW32__)
#include "../lib/pthread.h"
#else
#include <pthread.h>
@ -423,6 +423,10 @@ Gia_Man_t * Gia_ManTranStoch( Gia_Man_t * pGia, int nRestarts, int nHops, int nS
if ( nVerbose )
printf( "best: %d\n", Gia_ManAndNum( pBest ) );
Vec_PtrFree( vpStarts );
ABC_FREE( pBest->pName );
ABC_FREE( pBest->pSpec );
pBest->pName = Abc_UtilStrsav( pGia->pName );
pBest->pSpec = Abc_UtilStrsav( pGia->pSpec );
return pBest;
}

View File

@ -22,6 +22,7 @@
#include "misc/vec/vecMem.h"
#include "misc/vec/vecWec.h"
#include "misc/util/utilTruth.h"
#include "bool/lucky/lucky.h"
#include "opt/dau/dau.h"
ABC_NAMESPACE_IMPL_START
@ -559,6 +560,11 @@ void Gia_ObjComputeTruthTableStart( Gia_Man_t * p, int nVarsMax )
p->vTtMemory = Vec_WrdStart( p->nTtWords * 64 );
p->vTtNums = Vec_IntAlloc( Gia_ManObjNum(p) + 1000 );
Vec_IntFill( p->vTtNums, Vec_IntCap(p->vTtNums), -ABC_INFINITY );
if ( nVarsMax >= 6 ) {
word * pTruth; int i;
Vec_PtrForEachEntry( word *, p->vTtInputs, pTruth, i )
Abc_TtFlipVar5( pTruth, nVarsMax );
}
}
void Gia_ObjComputeTruthTableStop( Gia_Man_t * p )
{
@ -804,10 +810,73 @@ Gia_Man_t * Gia_ManIsoNpnReduce( Gia_Man_t * p, Vec_Ptr_t ** pvPosEquivs, int fV
return pNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Gia_ManNodeFunctionProfile( Gia_Man_t * p, int nVars )
{
int fCanonicize = 1;
Gia_Obj_t * pObj;
Vec_Int_t * vLeaves = Vec_IntAlloc( 100 );
int nWords = Abc_Truth6WordNum( nVars );
Vec_Mem_t * pTtMem = Vec_MemAlloc( nWords, 12 ); // supports up to nVars words
Vec_MemHashAlloc( pTtMem, 1000 );
Vec_Int_t * vCounts = Vec_IntAlloc( 100 );
permInfo * pi = setPermInfoPtr( nVars );
word pAuxWord[DAU_MAX_WORD], pAuxWord1[DAU_MAX_WORD], Truth[DAU_MAX_WORD], * pTruth; int i;
assert( nVars <= 7 );
Gia_ObjComputeTruthTableStart( p, nVars );
Gia_ManForEachAnd( p, pObj, i ) {
if ( Gia_ManSuppSize(p, &i, 1) != nVars )
continue;
Gia_ManCollectCis( p, &i, 1, vLeaves );
assert( Vec_IntSize(vLeaves) == nVars );
pTruth = Gia_ObjComputeTruthTableCut( p, pObj, vLeaves );
if ( fCanonicize ) {
memcpy( Truth, pTruth, sizeof(word) * nWords );
simpleMinimal( Truth, pAuxWord, pAuxWord1, pi, nVars ); // NPN canonical form
}
else {
memcpy( Truth, pTruth, sizeof(word) * nWords );
}
{
int nEntries = Vec_MemEntryNum( pTtMem );
int Value = Vec_MemHashInsert( pTtMem, Truth );
if ( Vec_MemEntryNum( pTtMem ) == nEntries )
Vec_IntAddToEntry( vCounts, Value, 1 );
else
{
assert( Value == nEntries );
Vec_IntPush( vCounts, 1 );
}
}
}
for ( i = 0; i < Vec_MemEntryNum(pTtMem); i++ ) {
word * pCanon = Vec_MemReadEntry( pTtMem, i );
int Count = Vec_IntEntry( vCounts, i );
Abc_TtPrintHexRev( stdout, pCanon, nVars );
printf( " %d\n", Count );
}
Gia_ObjComputeTruthTableStop( p );
Vec_IntFree( vLeaves );
Vec_IntFree( vCounts );
Vec_MemHashFree( pTtMem );
Vec_MemFree( pTtMem );
freePermInfoPtr( pi );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -84,9 +84,11 @@ Gia_ManTer_t * Gia_ManTerCreate( Gia_Man_t * pAig )
p = ABC_CALLOC( Gia_ManTer_t, 1 );
p->pAig = Gia_ManFront( pAig );
p->nIters = 300;
p->pDataSim = ABC_ALLOC( unsigned, Abc_BitWordNum(2*p->pAig->nFront) );
p->pDataSimCis = ABC_ALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCiNum(p->pAig)) );
p->pDataSimCos = ABC_ALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCoNum(p->pAig)) );
// these buffers are accessed through XOR-based setters that read the current word first,
// so they must be zero-initialized to avoid touching undefined data on the first update
p->pDataSim = ABC_CALLOC( unsigned, Abc_BitWordNum(2*p->pAig->nFront) );
p->pDataSimCis = ABC_CALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCiNum(p->pAig)) );
p->pDataSimCos = ABC_CALLOC( unsigned, Abc_BitWordNum(2*Gia_ManCoNum(p->pAig)) );
// allocate storage for terminary states
p->nStateWords = Abc_BitWordNum( 2*Gia_ManRegNum(pAig) );
p->vStates = Vec_PtrAlloc( 1000 );
@ -754,4 +756,3 @@ Gia_Man_t * Gia_ManReduceConst( Gia_Man_t * pAig, int fVerbose )
ABC_NAMESPACE_IMPL_END

View File

@ -1176,6 +1176,17 @@ Gia_Man_t * Gia_ManTtoptCare( Gia_Man_t * p, int nIns, int nOuts, int nRounds, c
{
vSupp = Gia_ManCollectSuppNew( p, g, nOuts );
nInputs = Vec_IntSize( vSupp );
if ( nInputs == 0 )
{
for ( k = 0; k < nOuts; k++ )
{
pObj = Gia_ManCo( p, g+k );
pTruth = Gia_ObjComputeTruthTableCut( p, Gia_ObjFanin0(pObj), vSupp );
Gia_ManAppendCo( pNew, pTruth[0] & 1 );
}
Vec_IntFree( vSupp );
continue;
}
Ttopt::TruthTableLevelTSM tt( nInputs, nOuts );
for ( k = 0; k < nOuts; k++ )
{

View File

@ -48,8 +48,13 @@ ABC_NAMESPACE_IMPL_START
***********************************************************************/
unsigned Gia_ManRandom( int fReset )
{
#ifdef _MSC_VER
static unsigned int m_z = NUMBER1;
static unsigned int m_w = NUMBER2;
#else
static __thread unsigned int m_z = NUMBER1;
static __thread unsigned int m_w = NUMBER2;
#endif
if ( fReset )
{
m_z = NUMBER1;
@ -135,6 +140,42 @@ char * Gia_FileNameGenericAppend( char * pBase, char * pSuffix )
return Buffer;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Gia_GetFakeNames( int nNames, int fCaps )
{
Vec_Ptr_t * vNames;
char Buffer[5];
int i;
vNames = Vec_PtrAlloc( nNames );
for ( i = 0; i < nNames; i++ )
{
if ( nNames < 26 )
{
Buffer[0] = (fCaps ? 'A' : 'a') + i;
Buffer[1] = 0;
}
else
{
Buffer[0] = (fCaps ? 'A' : 'a') + i%26;
Buffer[1] = '0' + i/26;
Buffer[2] = 0;
}
Vec_PtrPush( vNames, Extra_UtilStrsav(Buffer) );
}
return vNames;
}
/**Function*************************************************************
Synopsis []
@ -755,6 +796,23 @@ void Gia_ManCreateRefs( Gia_Man_t * p )
Gia_ObjRefFanin0Inc( p, pObj );
}
}
void Gia_ManCreateLitRefs( Gia_Man_t * p )
{
Gia_Obj_t * pObj;
int i;
assert( p->pRefs == NULL );
p->pRefs = ABC_CALLOC( int, 2*Gia_ManObjNum(p) );
Gia_ManForEachObj( p, pObj, i )
{
if ( Gia_ObjIsAnd(pObj) )
{
p->pRefs[Gia_ObjFaninLit0(pObj, i)]++;
p->pRefs[Gia_ObjFaninLit1(pObj, i)]++;
}
else if ( Gia_ObjIsCo(pObj) )
p->pRefs[Gia_ObjFaninLit0(pObj, i)]++;
}
}
/**Function*************************************************************
@ -3161,10 +3219,780 @@ void Gia_ManPrintArray( Gia_Man_t * p )
printf( "};\n" );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_GetMValue( int i, int nIns, int Mint, unsigned Truth )
{
assert( i >= 0 && i < 16 );
if ( i < nIns )
return (Mint >> i) & 1;
if ( i == nIns )
{
if ( Mint < (1 << nIns) )
return (Truth >> Mint) & 1;
else
return ((Truth >> (Mint-(1 << nIns))) & 1) == 0;
}
else
return 1;
}
void Gia_ManTestProblem()
{
unsigned Truth = 0xFE;
int i, j, k, c, nIns = 3, nAux = 3;
int nTotal = nIns + 1 + nAux;
int nPairs = nTotal * (nTotal - 1) / 2;
int nMints = (1 << (nIns+1));
int M[64][100] = {{0}};
float Value[64] = {0};
float Solution[100] = {0};
assert( nMints <= 64 );
assert( nPairs <= 100 );
// 7 nodes: 3 inputs + 1 output + 3 aux
// 7*6/2 = 21 pairs
// 16 minterms
for ( k = 0; k < nMints; k++ )
{
for ( i = c = 0; i < nTotal; i++ )
for ( j = i+1; j < nTotal; j++ )
{
int iVal = Gia_GetMValue( i, nIns, k, Truth );
int jVal = Gia_GetMValue( j, nIns, k, Truth );
M[k][c++] = iVal == jVal ? 1 : -1;
}
Value[k] = k < (1 << nIns) ? -1 : 1;
assert( c == nPairs );
}
for ( k = 0; k < nMints; k++ )
{
for ( c = 0; c < nPairs; c++ )
printf( "%2d ", M[k][c] );
printf( "%3f\n", Value[k] );
}
// solve
float Delta = 0.02;
for ( i = 0; i < 100; i++ )
{
float Error = 0;
for ( k = 0; k < nMints; k++ )
Error += Value[k] > 0 ? Value[k] : -Value[k];
printf( "Round %3d : Error = %5f ", i, Error );
for ( c = 0; c < nPairs; c++ )
printf( "%2f ", Solution[c] );
printf( "\n" );
//if ( Error < 1 )
// Delta /= 10;
for ( c = 0; c < nPairs; c++ )
{
int Count = 0;
for ( k = 0; k < nMints; k++ )
if ( (M[k][c] > 0 && Value[k] > 0) || (M[k][c] < 0 && Value[k] < 0) )
Count++;
else
Count--;
if ( Count == 0 )
continue;
printf( "Count = %3d ", Count );
if ( Count > 0 )
{
printf( "Increasing %d by %f\n", c, Delta );
Solution[c] += Delta;
for ( k = 0; k < nMints; k++ )
if ( M[k][c] > 0 )
Value[k] -= Delta;
else
Value[k] -= Delta;
}
else
{
printf( "Reducing %d by %f\n", c, Delta );
Solution[c] -= Delta;
for ( k = 0; k < nMints; k++ )
if ( M[k][c] > 0 )
Value[k] += Delta;
else
Value[k] += Delta;
}
}
}
}
/**Function*************************************************************
Synopsis [Returns 1 if this window has a topo error (forward path from an output to an input).]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManWindowCheckTopoError_rec( Gia_Man_t * p, Gia_Obj_t * pObj )
{
if ( !Gia_ObjIsAnd(pObj) )
return 0;
if ( Gia_ObjIsTravIdPrevious(p, pObj) )
return 1; // there is an error
if ( Gia_ObjIsTravIdCurrent(p, pObj) )
return 0; // there is no error; visited this node before
Gia_ObjSetTravIdPrevious(p, pObj);
if ( Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin0(pObj)) || Gia_ManWindowCheckTopoError_rec(p, Gia_ObjFanin1(pObj)) )
return 1;
Gia_ObjSetTravIdCurrent(p, pObj);
return 0;
}
int Gia_ManWindowCheckTopoError( Gia_Man_t * p, Vec_Int_t * vIns, Vec_Int_t * vOuts )
{
Gia_Obj_t * pObj; int i, fError = 0;
// outputs should be internal nodes
Gia_ManForEachObjVec( vOuts, p, pObj, i )
assert(Gia_ObjIsAnd(pObj));
// mark outputs
Gia_ManIncrementTravId( p );
Gia_ManForEachObjVec( vOuts, p, pObj, i )
Gia_ObjSetTravIdCurrent(p, pObj);
// start from inputs and make sure we do not reach any of the outputs
Gia_ManIncrementTravId( p );
Gia_ManForEachObjVec( vIns, p, pObj, i )
fError |= Gia_ManWindowCheckTopoError_rec(p, pObj);
return fError;
}
/**Function*************************************************************
Synopsis [Updates the AIG after multiple windows have been optimized.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Gia_ManDupInsertWindows_rec( Gia_Man_t * pNew, Gia_Man_t * p, Gia_Obj_t * pObj, Vec_Int_t * vMap, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
{
if ( ~pObj->Value )
return pObj->Value;
assert( Gia_ObjIsAnd(pObj) );
if ( Vec_IntEntry(vMap, Gia_ObjId(p, pObj)) == -1 ) // this is a regular node
{
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin1(pObj), vMap, vvIns, vvOuts, vWins );
return pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
}
// this node is an output of a window
int iWin = Vec_IntEntry(vMap, Gia_ObjId(p, pObj));
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, iWin);
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, iWin);
Gia_Man_t * pWin = (Gia_Man_t *)Vec_PtrEntry(vWins, iWin);
// build transinvite fanins of window inputs
Gia_Obj_t * pNode; int i;
Gia_ManConst0(pWin)->Value = 0;
Gia_ManForEachObjVec( vIns, p, pNode, i )
Gia_ManPi(pWin, i)->Value = Gia_ManDupInsertWindows_rec( pNew, p, pNode, vMap, vvIns, vvOuts, vWins );
// add window nodes
Gia_ManForEachAnd( pWin, pNode, i )
pNode->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pNode), Gia_ObjFanin1Copy(pNode) );
// transfer to window outputs
Gia_ManForEachObjVec( vOuts, p, pNode, i )
pNode->Value = Gia_ObjFanin0Copy(Gia_ManPo(pWin, i));
assert( ~pObj->Value );
return pObj->Value;
}
Gia_Man_t * Gia_ManDupInsertWindows( Gia_Man_t * p, Vec_Ptr_t * vvIns, Vec_Ptr_t * vvOuts, Vec_Ptr_t * vWins )
{
// check consistency of input data
Gia_Man_t * pNew, * pTemp; Gia_Obj_t * pObj; int i, k, iNode;
Vec_PtrForEachEntry( Gia_Man_t *, vWins, pTemp, i ) {
Vec_Int_t * vIns = (Vec_Int_t *)Vec_PtrEntry(vvIns, i);
Vec_Int_t * vOuts = (Vec_Int_t *)Vec_PtrEntry(vvOuts, i);
assert( Vec_IntSize(vIns) == Gia_ManPiNum(pTemp) );
assert( Vec_IntSize(vOuts) == Gia_ManPoNum(pTemp) );
assert( !Gia_ManWindowCheckTopoError(p, vIns, vOuts) );
}
// create mapping of window outputs into window IDs
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(p) ), * vOuts;
Vec_PtrForEachEntry( Vec_Int_t *, vvOuts, vOuts, i )
Vec_IntForEachEntry( vOuts, iNode, k )
Vec_IntWriteEntry( vMap, iNode, i );
// create the resulting AIG by performing DFS from the POs of the original AIG
// it goes recursively through original nodes and windows until it reaches the PIs of the original AIG
pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSpec = Abc_UtilStrsav( p->pSpec );
Gia_ManHashAlloc( pNew );
Gia_ManFillValue( p );
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi(pNew);
Gia_ManForEachCo( p, pObj, i )
Gia_ManDupInsertWindows_rec( pNew, p, Gia_ObjFanin0(pObj), vMap, vvIns, vvOuts, vWins );
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
// cleanup and return
Vec_IntFree( vMap );
pNew = Gia_ManCleanup( pTemp = pNew );
Gia_ManStop( pTemp );
//Gia_ManPrint( pNew );
return pNew;
}
/**Function*************************************************************
Synopsis [Computing equivalent nodes across the two AIGs.]
Description [Assumes that both AIGs are structurally hashed without dandling nodes.]
SideEffects []
SeeAlso []
***********************************************************************/
Gia_Man_t * Gia_ManCreateDualOutputMiter( Gia_Man_t * p0, Gia_Man_t * p1 )
{
Gia_Man_t * pNew; Gia_Obj_t * pObj; int i;
assert( Gia_ManCiNum(p0) == Gia_ManCiNum(p1) );
assert( Gia_ManCoNum(p0) == Gia_ManCoNum(p1) );
// start the manager
pNew = Gia_ManStart( Gia_ManObjNum(p0) + Gia_ManObjNum(p1) );
pNew->pName = Abc_UtilStrsav( "miter" );
Gia_ManFillValue( p0 );
Gia_ManFillValue( p1 );
// map combinational inputs
Gia_ManConst0(p0)->Value = 0;
Gia_ManConst0(p1)->Value = 0;
Gia_ManForEachCi( p0, pObj, i )
Gia_ManCi(p1, i)->Value = pObj->Value = Gia_ManAppendCi( pNew );
// map internal nodes and outputs
Gia_ManHashAlloc( pNew );
Gia_ManForEachAnd( p0, pObj, i )
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
assert( Gia_ManAndNum(pNew) == Gia_ManAndNum(p0) ); // the input AIG p0 is structurally hashed
Gia_ManForEachAnd( p1, pObj, i )
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
// add the outputs
Gia_ManForEachCo( p0, pObj, i )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManForEachCo( p1, pObj, i )
pObj->Value = Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
printf( "The two AIGs have %d structurally equivalent nodes.\n", Gia_ManAndNum(p0) + Gia_ManAndNum(p1) - Gia_ManAndNum(pNew) );
// there should be no dangling nodes (otherwise, the second AIG may not be structurally hashed)
int nDangling = Gia_ManMarkDangling(pNew);
assert( nDangling == 0 );
Gia_ManCleanMark01(pNew);
return pNew;
}
Vec_Int_t * Gia_ManFindMutualEquivs( Gia_Man_t * p0, Gia_Man_t * p1, int nConflictLimit, int fVerbose )
{
Vec_Int_t * vPairs = Vec_IntAlloc( 100 );
// derive the miter
Gia_Man_t * pMiter = Gia_ManCreateDualOutputMiter( p0, p1 );
//Gia_ManPrintStats( pMiter, NULL );
//Gia_AigerWrite( pMiter, "out.aig", 0, 0, 0 );
// perform SAT sweeping
extern Gia_Man_t * Cec4_ManSimulateTest3( Gia_Man_t * p, int nBTLimit, int fVerbose );
Gia_Man_t * pNew = Cec4_ManSimulateTest3( pMiter, nConflictLimit, fVerbose );
Gia_ManStop( pNew );
// now, pMiter is annotated with the equiv class info
// here we collect AIG node pairs with the following properties:
// - the first node belongs to p0; the second node belongs to p1
// - both nodes are internal nodes of p0 and p1 (not primary inputs/outputs)
// - these nodes are combinationally equivalent (possibly up to the complement)
// - these nodes are "singleton" equivalences (no other nodes in p0 and p1 are equivalent to them)
// - these nodes are not structurally equivalent (that is, they have structurally different TFI logic cones)
// count the number of nodes in each equivalence class
Vec_Int_t * vCounts = Vec_IntStart( Gia_ManObjNum(pMiter) );
Gia_Obj_t * pObj; int i, k;
Gia_ManForEachClass( pMiter, i )
Gia_ClassForEachObj( pMiter, i, k )
Vec_IntAddToEntry( vCounts, i, 1 );
// map each miter node coming from p1 into the corresponding node in p1
Vec_Int_t * vMap = Vec_IntStartFull( Gia_ManObjNum(pMiter) );
int iStartP1 = 1 + Gia_ManPiNum(p0) + Gia_ManAndNum(p0);
Gia_ManForEachAnd( p1, pObj, i )
if ( Abc_Lit2Var(pObj->Value) >= iStartP1 ) // node from p1 (not from p0)
Vec_IntWriteEntry( vMap, Abc_Lit2Var(pObj->Value), i );
// go through functionally (not structurally!) equivalent nodes in the second AIG
// and collect those node pairs from p0 and p1 whose equivalence class contains exactly two nodes
for ( i = iStartP1; i < Gia_ManObjNum(pMiter) - Gia_ManCoNum(pMiter); i++ ) {
assert( Gia_ObjIsAnd(Gia_ManObj(pMiter, i)) );
int Repr = Gia_ObjRepr(pMiter, i);
if ( Repr == GIA_VOID || Repr >= iStartP1 || Vec_IntEntry(vCounts, Repr) != 2 )
continue;
assert( Repr < iStartP1 ); // node in p0
assert( Vec_IntEntry(vMap, i) > 0 ); // node in p1
Vec_IntPushTwo( vPairs, Repr, Vec_IntEntry(vMap, i) );
}
// cleanup
Vec_IntFree( vMap );
Vec_IntFree( vCounts );
Gia_ManStop( pMiter );
return vPairs;
}
void Gia_ManFindMutualEquivsTest()
{
Gia_Man_t * p0 = Gia_AigerRead( "p0.aig", 0, 0, 0 );
Gia_Man_t * p1 = Gia_AigerRead( "p1.aig", 0, 0, 0 );
Vec_Int_t * vPairs = Gia_ManFindMutualEquivs( p0, p1, 0, 0 );
printf( "Pair Aig0 node Aig1 node\n" );
int i, Obj0, Obj1;
Vec_IntForEachEntryDouble( vPairs, Obj0, Obj1, i )
printf( "%3d %6d %6d\n", i/2, Obj0, Obj1 );
Gia_ManStop( p0 );
Gia_ManStop( p1 );
Vec_IntFree( vPairs );
}
/**Function*************************************************************
Synopsis [Prints longest combinational paths between seq endpoints.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static char * Gia_ManPrintPathNameFallback( Gia_Man_t * p, int fCi, int iTerm, char * pBuffer )
{
if ( fCi )
{
if ( iTerm < Gia_ManPiNum(p) )
sprintf( pBuffer, "pi%d", iTerm );
else
sprintf( pBuffer, "ro%d", iTerm - Gia_ManPiNum(p) );
}
else
{
if ( iTerm < Gia_ManPoNum(p) )
sprintf( pBuffer, "po%d", iTerm );
else
sprintf( pBuffer, "ri%d", iTerm - Gia_ManPoNum(p) );
}
return pBuffer;
}
static int Gia_ManPrintPathNameBufferSize( Gia_Man_t * p )
{
Vec_Ptr_t * vNames;
char * pName;
int i, nSize = 64;
vNames = p->vNamesIn;
if ( vNames )
Vec_PtrForEachEntry( char *, vNames, pName, i )
if ( pName )
nSize = Abc_MaxInt( nSize, (int)strlen(pName) + 64 );
vNames = p->vNamesOut;
if ( vNames )
Vec_PtrForEachEntry( char *, vNames, pName, i )
if ( pName )
nSize = Abc_MaxInt( nSize, (int)strlen(pName) + 64 );
return nSize;
}
static void Gia_ManPrintPathCopyToken( char * pBuffer, char * pBeg, char * pEnd )
{
int nChars = pEnd ? (int)(pEnd - pBeg) : (int)strlen(pBeg);
memcpy( pBuffer, pBeg, nChars );
pBuffer[nChars] = 0;
}
static char * Gia_ManPrintPathName( Gia_Man_t * p, int fCi, int iTerm, char * pBuffer, int fFull, int fLeaf )
{
Vec_Ptr_t * vNames = fCi ? p->vNamesIn : p->vNamesOut;
char * pName = vNames && iTerm < Vec_PtrSize(vNames) ? (char *)Vec_PtrEntry(vNames, iTerm) : NULL;
char * pBeg, * pEnd, * pFirst, * pFirstEnd;
if ( pName == NULL )
return Gia_ManPrintPathNameFallback( p, fCi, iTerm, pBuffer );
if ( fFull )
return pName;
if ( fLeaf )
{
pBeg = strrchr( pName, ' ' );
return pBeg ? pBeg + 1 : pName;
}
pFirst = pName;
pFirstEnd = strchr( pFirst, ' ' );
for ( pBeg = pName; pBeg && *pBeg; pBeg = pEnd ? pEnd + 1 : NULL )
{
pEnd = strchr( pBeg, ' ' );
if ( strstr( pBeg, "reg_" ) && (pEnd == NULL || pEnd > strstr( pBeg, "reg_" )) )
{
Gia_ManPrintPathCopyToken( pBuffer, pBeg, pEnd );
return pBuffer;
}
}
Gia_ManPrintPathCopyToken( pBuffer, pFirst, pFirstEnd );
return pBuffer;
}
static char * Gia_ManPrintPathKind( Gia_Man_t * p, int fCi, int iTerm )
{
if ( fCi )
return iTerm < Gia_ManPiNum(p) ? (char *)"PI" : (char *)"RO";
return iTerm < Gia_ManPoNum(p) ? (char *)"PO" : (char *)"RI";
}
static int Gia_ManPrintPathTermIndex( Gia_Man_t * p, int fCi, int iTerm )
{
if ( fCi )
return iTerm < Gia_ManPiNum(p) ? iTerm : iTerm - Gia_ManPiNum(p);
return iTerm < Gia_ManPoNum(p) ? iTerm : iTerm - Gia_ManPoNum(p);
}
static int Gia_ManPrintPathParseBit( char * pName, char * pBase, int * pBit, char * pSuffix )
{
char * pLeft = strrchr( pName, '[' );
char * pRight = pLeft ? strchr( pLeft, ']' ) : NULL;
char * pTemp;
if ( pLeft == NULL || pRight == NULL )
return 0;
for ( pTemp = pLeft + 1; pTemp < pRight; pTemp++ )
if ( *pTemp < '0' || *pTemp > '9' )
return 0;
Gia_ManPrintPathCopyToken( pBase, pName, pLeft );
Gia_ManPrintPathCopyToken( pSuffix, pRight + 1, NULL );
*pBit = atoi( pLeft + 1 );
return 1;
}
static void Gia_ManPrintPathFormatTermRange( char * pBuffer, char * pKind, int iBeg, int iEnd )
{
if ( iBeg == iEnd )
sprintf( pBuffer, "%s[%d]", pKind, iBeg );
else
sprintf( pBuffer, "%s[%d..%d]", pKind, iBeg, iEnd );
}
static void Gia_ManPrintPathFormatNameRange( char * pBuffer, char * pNameBeg, char * pNameEnd, int nNameSize )
{
char * BaseBeg, * BaseEnd, * SuffixBeg, * SuffixEnd;
int BitBeg, BitEnd;
if ( !strcmp(pNameBeg, pNameEnd) )
{
sprintf( pBuffer, "%s", pNameBeg );
return;
}
BaseBeg = ABC_ALLOC( char, nNameSize );
BaseEnd = ABC_ALLOC( char, nNameSize );
SuffixBeg = ABC_ALLOC( char, nNameSize );
SuffixEnd = ABC_ALLOC( char, nNameSize );
if ( Gia_ManPrintPathParseBit(pNameBeg, BaseBeg, &BitBeg, SuffixBeg) &&
Gia_ManPrintPathParseBit(pNameEnd, BaseEnd, &BitEnd, SuffixEnd) &&
!strcmp(BaseBeg, BaseEnd) && !strcmp(SuffixBeg, SuffixEnd) )
sprintf( pBuffer, "%s[%d..%d]%s", BaseBeg, BitBeg, BitEnd, SuffixBeg );
else
sprintf( pBuffer, "%s..%s", pNameBeg, pNameEnd );
ABC_FREE( BaseBeg );
ABC_FREE( BaseEnd );
ABC_FREE( SuffixBeg );
ABC_FREE( SuffixEnd );
}
static int Gia_ManPrintPathCanGroup( Gia_Man_t * p, int Level0, int Source0, int Sink0, int Level1, int Source1, int Sink1, int nNameSize )
{
char * pStore, * Buffer0, * Buffer1, * Buffer2, * Buffer3, * Base0, * Base1, * Suffix0, * Suffix1;
int Bit0, Bit1;
int RetValue;
if ( Level0 != Level1 || Source0 != Source1 )
return 0;
if ( (Sink0 < Gia_ManPoNum(p)) != (Sink1 < Gia_ManPoNum(p)) )
return 0;
if ( Gia_ManPrintPathTermIndex(p, 0, Sink1) != Gia_ManPrintPathTermIndex(p, 0, Sink0) + 1 )
return 0;
pStore = ABC_ALLOC( char, 8 * nNameSize );
Buffer0 = pStore + 0 * nNameSize;
Buffer1 = pStore + 1 * nNameSize;
Buffer2 = pStore + 2 * nNameSize;
Buffer3 = pStore + 3 * nNameSize;
Base0 = pStore + 4 * nNameSize;
Base1 = pStore + 5 * nNameSize;
Suffix0 = pStore + 6 * nNameSize;
Suffix1 = pStore + 7 * nNameSize;
Gia_ManPrintPathName( p, 1, Source0, Buffer0, 0, 0 );
Gia_ManPrintPathName( p, 1, Source1, Buffer1, 0, 0 );
if ( strcmp(Buffer0, Buffer1) )
{
ABC_FREE( pStore );
return 0;
}
Gia_ManPrintPathName( p, 1, Source0, Buffer0, 0, 1 );
Gia_ManPrintPathName( p, 1, Source1, Buffer1, 0, 1 );
if ( strcmp(Buffer0, Buffer1) )
{
ABC_FREE( pStore );
return 0;
}
Gia_ManPrintPathName( p, 0, Sink0, Buffer2, 0, 0 );
Gia_ManPrintPathName( p, 0, Sink1, Buffer3, 0, 0 );
if ( !Gia_ManPrintPathParseBit(Buffer2, Base0, &Bit0, Suffix0) ||
!Gia_ManPrintPathParseBit(Buffer3, Base1, &Bit1, Suffix1) )
{
ABC_FREE( pStore );
return 0;
}
RetValue = !strcmp(Base0, Base1) && !strcmp(Suffix0, Suffix1) && Bit1 == Bit0 + 1;
ABC_FREE( pStore );
return RetValue;
}
static int Gia_ManPrintPathCandBetter( int Level0, int Source0, int Sink0, int Level1, int Source1, int Sink1 )
{
if ( Level0 != Level1 )
return Level0 > Level1;
if ( Source0 != Source1 )
return Source0 < Source1;
return Sink0 < Sink1;
}
static int Gia_ManPrintPathFaninBetter( int Level0, int Source0, int Level1, int Source1 )
{
if ( Source0 < 0 )
return 0;
if ( Source1 < 0 )
return 1;
if ( Level0 != Level1 )
return Level0 > Level1;
return Source0 < Source1;
}
static void Gia_ManPrintPathInsert( int * pLevels, int * pSources, int * pSinks, int * pDrivers, int * pnPaths, int nPathsMax, int Level, int Source, int Sink, int Driver )
{
int i, k, nPaths = *pnPaths;
if ( Source < 0 )
return;
for ( i = 0; i < nPaths; i++ )
if ( Gia_ManPrintPathCandBetter(Level, Source, Sink, pLevels[i], pSources[i], pSinks[i]) )
break;
if ( i == nPathsMax )
return;
if ( nPaths < nPathsMax )
nPaths++;
for ( k = nPaths - 1; k > i; k-- )
{
pLevels[k] = pLevels[k-1];
pSources[k] = pSources[k-1];
pSinks[k] = pSinks[k-1];
pDrivers[k] = pDrivers[k-1];
}
pLevels[i] = Level;
pSources[i] = Source;
pSinks[i] = Sink;
pDrivers[i] = Driver;
*pnPaths = nPaths;
}
static void Gia_ManPrintPathOne( Gia_Man_t * p, Vec_Int_t * vPreds, int Source, int Sink, int Driver, int nNameSize )
{
Vec_Int_t * vPath = Vec_IntAlloc( 100 );
char * pBuffer = ABC_ALLOC( char, 2 * nNameSize );
char * pBuffer0 = pBuffer;
char * pBuffer1 = pBuffer + nNameSize;
int i, Id;
for ( Id = Driver; Id > 0 && !Gia_ObjIsCi(Gia_ManObj(p, Id)); Id = Vec_IntEntry(vPreds, Id) )
{
Vec_IntPush( vPath, Id );
if ( Vec_IntEntry(vPreds, Id) < 0 )
break;
}
printf( " %s[%d] %s", Gia_ManPrintPathKind(p, 1, Source), Gia_ManPrintPathTermIndex(p, 1, Source), Gia_ManPrintPathName(p, 1, Source, pBuffer0, 1, 0) );
Vec_IntForEachEntryReverse( vPath, Id, i )
printf( " -> AND %d", Id );
printf( " -> %s[%d] %s\n", Gia_ManPrintPathKind(p, 0, Sink), Gia_ManPrintPathTermIndex(p, 0, Sink), Gia_ManPrintPathName(p, 0, Sink, pBuffer1, 1, 0) );
ABC_FREE( pBuffer );
Vec_IntFree( vPath );
}
void Gia_ManPrintPath( Gia_Man_t * p, int nPathsMax, int fVerbose, int fSummary )
{
Vec_Int_t * vLevels, * vSources, * vPreds;
Vec_Int_t * vGroupStarts, * vGroupEnds;
Gia_Obj_t * pObj;
int * pLevels, * pSources, * pSinks, * pDrivers;
int nGroupsMax = nPathsMax;
int nPathsAlloc, nNameSize, nLineSize, nSourceTermW, nSourceNameW, nSinkTermW;
int nPaths = 0, Counts[4] = {0}, MaxLevels[4] = {0};
int i, k, Id, FanId, Level, Source, Sink, Driver, Cost, LevelBest, SourceBest, FanBest, nGroups, iBeg, iEnd;
char * Buffer0, * Buffer1, * Buffer2, * Buffer3, * Buffer4, * Buffer5, * Buffer6, * Buffer7, * Buffer8, * Buffer9, * Buffer10;
if ( nPathsMax < 1 )
nPathsMax = 1;
nGroupsMax = nPathsMax;
nPathsAlloc = Abc_MinInt( Gia_ManCoNum(p), Abc_MaxInt(32 * nGroupsMax, nGroupsMax) );
nNameSize = Gia_ManPrintPathNameBufferSize( p );
nLineSize = 4 * nNameSize + 100;
Buffer0 = ABC_ALLOC( char, nNameSize );
Buffer1 = ABC_ALLOC( char, nNameSize );
Buffer2 = ABC_ALLOC( char, nNameSize );
Buffer3 = ABC_ALLOC( char, nNameSize );
Buffer4 = ABC_ALLOC( char, nNameSize );
Buffer5 = ABC_ALLOC( char, nNameSize );
Buffer6 = ABC_ALLOC( char, nNameSize );
Buffer7 = ABC_ALLOC( char, nLineSize );
Buffer8 = ABC_ALLOC( char, nLineSize );
Buffer9 = ABC_ALLOC( char, nLineSize );
Buffer10 = ABC_ALLOC( char, nLineSize );
vGroupStarts = Vec_IntAlloc( nGroupsMax );
vGroupEnds = Vec_IntAlloc( nGroupsMax );
vLevels = Vec_IntStart( Gia_ManObjNum(p) );
vSources = Vec_IntStartFull( Gia_ManObjNum(p) );
vPreds = Vec_IntStartFull( Gia_ManObjNum(p) );
Gia_ManForEachObj( p, pObj, i )
{
Id = Gia_ObjId( p, pObj );
if ( Gia_ObjIsCi(pObj) )
{
Vec_IntWriteEntry( vLevels, Id, 0 );
Vec_IntWriteEntry( vSources, Id, Gia_ObjCioId(pObj) );
continue;
}
if ( !Gia_ObjIsAnd(pObj) )
continue;
Cost = (!p->fGiaSimple && Gia_ObjIsBuf(pObj)) ? 0 : (Gia_ObjIsMux(p, pObj) || Gia_ObjIsXor(pObj) ? 2 : 1);
LevelBest = SourceBest = FanBest = -1;
for ( k = 0; k < Gia_ObjFaninNum(p, pObj); k++ )
{
FanId = k == 2 ? Gia_ObjFaninId2(p, Id) : Gia_ObjFaninId(pObj, Id, k);
Level = Vec_IntEntry( vLevels, FanId );
Source = Vec_IntEntry( vSources, FanId );
if ( Gia_ManPrintPathFaninBetter(Level, Source, LevelBest, SourceBest) )
LevelBest = Level, SourceBest = Source, FanBest = FanId;
}
Vec_IntWriteEntry( vLevels, Id, LevelBest + Cost );
Vec_IntWriteEntry( vSources, Id, SourceBest );
Vec_IntWriteEntry( vPreds, Id, FanBest );
}
pLevels = ABC_ALLOC( int, nPathsAlloc );
pSources = ABC_ALLOC( int, nPathsAlloc );
pSinks = ABC_ALLOC( int, nPathsAlloc );
pDrivers = ABC_ALLOC( int, nPathsAlloc );
Gia_ManForEachCo( p, pObj, i )
{
Driver = Gia_ObjFaninId0p( p, pObj );
Level = Vec_IntEntry( vLevels, Driver );
Source = Vec_IntEntry( vSources, Driver );
Sink = Gia_ObjCioId( pObj );
if ( Source >= 0 )
{
k = (Source >= Gia_ManPiNum(p) ? 2 : 0) + (Sink >= Gia_ManPoNum(p) ? 1 : 0);
Counts[k]++;
MaxLevels[k] = Abc_MaxInt( MaxLevels[k], Level );
}
Gia_ManPrintPathInsert( pLevels, pSources, pSinks, pDrivers, &nPaths, nPathsAlloc, Level, Source, Sink, Driver );
}
for ( i = 0, nGroups = 0; i < nPaths && nGroups < nGroupsMax; i = iEnd + 1, nGroups++ )
{
iBeg = iEnd = i;
while ( iEnd + 1 < nPaths && Gia_ManPrintPathCanGroup(p, pLevels[iEnd], pSources[iEnd], pSinks[iEnd], pLevels[iEnd+1], pSources[iEnd+1], pSinks[iEnd+1], nNameSize) )
iEnd++;
Vec_IntPush( vGroupStarts, iBeg );
Vec_IntPush( vGroupEnds, iEnd );
}
nSourceTermW = (int)strlen( "source" );
nSourceNameW = 0;
nSinkTermW = (int)strlen( "sink" );
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
{
char * pSourceName, * pSourceLeaf, * pSinkNameBeg, * pSinkNameEnd, * pSinkLeafBeg, * pSinkLeafEnd;
iEnd = Vec_IntEntry( vGroupEnds, i );
pSourceName = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer0, 0, 0);
pSourceLeaf = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer1, 0, 1);
pSinkNameBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer2, 0, 0);
pSinkNameEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer3, 0, 0);
pSinkLeafBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer4, 0, 1);
pSinkLeafEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer5, 0, 1);
Gia_ManPrintPathFormatTermRange( Buffer6, Gia_ManPrintPathKind(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]) );
sprintf( Buffer7, "%s", pSourceName );
if ( strcmp(pSourceName, pSourceLeaf) )
sprintf( Buffer7 + strlen(Buffer7), "->%s", pSourceLeaf );
Gia_ManPrintPathFormatTermRange( Buffer8, Gia_ManPrintPathKind(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iEnd]) );
Gia_ManPrintPathFormatNameRange( Buffer9, pSinkNameBeg, pSinkNameEnd, nNameSize );
if ( strcmp(pSinkLeafBeg, pSinkLeafEnd) )
Gia_ManPrintPathFormatNameRange( Buffer10, pSinkLeafBeg, pSinkLeafEnd, nNameSize );
else
sprintf( Buffer10, "%s", pSinkLeafBeg );
if ( strcmp(Buffer9, Buffer10) )
sprintf( Buffer9 + strlen(Buffer9), "<-%s", Buffer10 );
nSourceTermW = Abc_MaxInt( nSourceTermW, (int)strlen(Buffer6) );
nSourceNameW = Abc_MaxInt( nSourceNameW, (int)strlen(Buffer7) );
nSinkTermW = Abc_MaxInt( nSinkTermW, (int)strlen(Buffer8) );
}
printf( "Grouped critical combinational paths:\n" );
printf( " rank paths lev %-*s %-*s %-*s %s\n", nSourceTermW, "source", nSourceNameW, "", nSinkTermW, "sink", "" );
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
{
char * pSourceName, * pSourceLeaf, * pSinkNameBeg, * pSinkNameEnd, * pSinkLeafBeg, * pSinkLeafEnd;
iEnd = Vec_IntEntry( vGroupEnds, i );
pSourceName = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer0, 0, 0);
pSourceLeaf = Gia_ManPrintPathName(p, 1, pSources[iBeg], Buffer1, 0, 1);
pSinkNameBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer2, 0, 0);
pSinkNameEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer3, 0, 0);
pSinkLeafBeg = Gia_ManPrintPathName(p, 0, pSinks[iBeg], Buffer4, 0, 1);
pSinkLeafEnd = Gia_ManPrintPathName(p, 0, pSinks[iEnd], Buffer5, 0, 1);
Gia_ManPrintPathFormatTermRange( Buffer6, Gia_ManPrintPathKind(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]), Gia_ManPrintPathTermIndex(p, 1, pSources[iBeg]) );
sprintf( Buffer7, "%s", pSourceName );
if ( strcmp(pSourceName, pSourceLeaf) )
sprintf( Buffer7 + strlen(Buffer7), "->%s", pSourceLeaf );
Gia_ManPrintPathFormatTermRange( Buffer8, Gia_ManPrintPathKind(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iBeg]), Gia_ManPrintPathTermIndex(p, 0, pSinks[iEnd]) );
Gia_ManPrintPathFormatNameRange( Buffer9, pSinkNameBeg, pSinkNameEnd, nNameSize );
if ( strcmp(pSinkLeafBeg, pSinkLeafEnd) )
Gia_ManPrintPathFormatNameRange( Buffer10, pSinkLeafBeg, pSinkLeafEnd, nNameSize );
else
sprintf( Buffer10, "%s", pSinkLeafBeg );
if ( strcmp(Buffer9, Buffer10) )
sprintf( Buffer9 + strlen(Buffer9), "<-%s", Buffer10 );
if ( iBeg == iEnd )
sprintf( Buffer4, "%d", iBeg + 1 );
else
sprintf( Buffer4, "%d..%d", iBeg + 1, iEnd + 1 );
printf( "%5d %-7s %3d %-*s %-*s %-*s %s\n", i + 1, Buffer4, pLevels[iBeg], nSourceTermW, Buffer6, nSourceNameW, Buffer7, nSinkTermW, Buffer8, Buffer9 );
}
if ( fVerbose )
{
printf( "\nAIG paths:\n" );
Vec_IntForEachEntry( vGroupStarts, iBeg, i )
Gia_ManPrintPathOne( p, vPreds, pSources[iBeg], pSinks[iBeg], pDrivers[iBeg], nNameSize );
}
if ( fSummary )
{
printf( "\nEndpoint summary:\n" );
printf( " PI->PO : paths = %7d max levels = %6d\n", Counts[0], MaxLevels[0] );
printf( " PI->RI : paths = %7d max levels = %6d\n", Counts[1], MaxLevels[1] );
printf( " RO->PO : paths = %7d max levels = %6d\n", Counts[2], MaxLevels[2] );
printf( " RO->RI : paths = %7d max levels = %6d\n", Counts[3], MaxLevels[3] );
}
ABC_FREE( pLevels );
ABC_FREE( pSources );
ABC_FREE( pSinks );
ABC_FREE( pDrivers );
ABC_FREE( Buffer0 );
ABC_FREE( Buffer1 );
ABC_FREE( Buffer2 );
ABC_FREE( Buffer3 );
ABC_FREE( Buffer4 );
ABC_FREE( Buffer5 );
ABC_FREE( Buffer6 );
ABC_FREE( Buffer7 );
ABC_FREE( Buffer8 );
ABC_FREE( Buffer9 );
ABC_FREE( Buffer10 );
Vec_IntFree( vLevels );
Vec_IntFree( vSources );
Vec_IntFree( vPreds );
Vec_IntFreeP( &vGroupStarts );
Vec_IntFreeP( &vGroupEnds );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

View File

@ -6,6 +6,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaBalLut.c \
src/aig/gia/giaBalMap.c \
src/aig/gia/giaBidec.c \
src/aig/gia/giaBsFind.c \
src/aig/gia/giaCCof.c \
src/aig/gia/giaCex.c \
src/aig/gia/giaClp.c \
@ -49,6 +50,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaJf.c \
src/aig/gia/giaKf.c \
src/aig/gia/giaLf.c \
src/aig/gia/giaLutCas.c \
src/aig/gia/giaMf.c \
src/aig/gia/giaMan.c \
src/aig/gia/giaMem.c \
@ -56,6 +58,8 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaMini.c \
src/aig/gia/giaMinLut.c \
src/aig/gia/giaMinLut2.c \
src/aig/gia/giaMulFind.c \
src/aig/gia/giaMulFind3.c \
src/aig/gia/giaMuxes.c \
src/aig/gia/giaNf.c \
src/aig/gia/giaOf.c \
@ -72,6 +76,7 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaResub6.c \
src/aig/gia/giaRetime.c \
src/aig/gia/giaRex.c \
src/aig/gia/giaRrr.cpp \
src/aig/gia/giaSatEdge.c \
src/aig/gia/giaSatLE.c \
src/aig/gia/giaSatLut.c \
@ -109,4 +114,6 @@ SRC += src/aig/gia/giaAig.c \
src/aig/gia/giaTsim.c \
src/aig/gia/giaTtopt.cpp \
src/aig/gia/giaUnate.c \
src/aig/gia/giaUtil.c
src/aig/gia/giaUtil.c \
src/aig/gia/giaBound.c \
src/aig/gia/giaDecGraph.cpp

View File

@ -233,7 +233,7 @@ static inline Hop_Obj_t * Hop_ManFetchMemory( Hop_Man_t * p )
if ( p->pListFree == NULL )
Hop_ManAddMemory( p );
pTemp = p->pListFree;
p->pListFree = *((Hop_Obj_t **)pTemp);
memcpy(&p->pListFree, pTemp, sizeof(Hop_Obj_t *));
memset( pTemp, 0, sizeof(Hop_Obj_t) );
if ( p->vObjs )
{
@ -245,8 +245,8 @@ static inline Hop_Obj_t * Hop_ManFetchMemory( Hop_Man_t * p )
}
static inline void Hop_ManRecycleMemory( Hop_Man_t * p, Hop_Obj_t * pEntry )
{
pEntry->Type = AIG_NONE; // distinquishes dead node from live node
*((Hop_Obj_t **)pEntry) = p->pListFree;
pEntry->Type = AIG_NONE; // distinguishes dead node from live node
memcpy(pEntry, &p->pListFree, sizeof(Hop_Obj_t *));
p->pListFree = pEntry;
}

View File

@ -88,13 +88,15 @@ void Hop_ManStopMemory( Hop_Man_t * p )
***********************************************************************/
void Hop_ManAddMemory( Hop_Man_t * p )
{
char * pMemory;
char * pMemory = 0;
Hop_Obj_t * pEntry, * pNext;
int i, nBytes;
assert( sizeof(Hop_Obj_t) <= 64 );
assert( p->pListFree == NULL );
// assert( (Hop_ManObjNum(p) & IVY_PAGE_MASK) == 0 );
// allocate new memory page
nBytes = sizeof(Hop_Obj_t) * (1<<IVY_PAGE_SIZE) + 64;
pMemory = pMemory + 64 - (((int)(ABC_PTRUINT_T)pMemory) & 63);
pMemory = ABC_ALLOC( char, nBytes );
Vec_PtrPush( p->vChunks, pMemory );
// align memory at the 32-byte boundary
@ -102,13 +104,16 @@ void Hop_ManAddMemory( Hop_Man_t * p )
// remember the manager in the first entry
Vec_PtrPush( p->vPages, pMemory );
// break the memory down into nodes
p->pListFree = (Hop_Obj_t *)pMemory;
pEntry = (Hop_Obj_t *)pMemory;
p->pListFree = pEntry;
for ( i = 1; i <= IVY_PAGE_MASK; i++ )
{
*((char **)pMemory) = pMemory + sizeof(Hop_Obj_t);
pMemory += sizeof(Hop_Obj_t);
pNext = pEntry + 1;
memcpy( pEntry, &pNext, sizeof(Hop_Obj_t *) );
pEntry++;
}
*((char **)pMemory) = NULL;
pNext = NULL;
memcpy( pEntry, &pNext, sizeof(Hop_Obj_t *) );
}
////////////////////////////////////////////////////////////////////////

View File

@ -351,6 +351,20 @@ static int Mini_AigAndMulti( Mini_Aig_t * p, int * pLits, int nLits )
}
return pLits[0];
}
static int Mini_AigXorMulti( Mini_Aig_t * p, int * pLits, int nLits )
{
int i;
assert( nLits > 0 );
while ( nLits > 1 )
{
for ( i = 0; i < nLits/2; i++ )
pLits[i] = Mini_AigXor(p, pLits[2*i], pLits[2*i+1]);
if ( nLits & 1 )
pLits[i++] = pLits[nLits-1];
nLits = i;
}
return pLits[0];
}
static int Mini_AigMuxMulti( Mini_Aig_t * p, int * pCtrl, int nCtrl, int * pData, int nData )
{
int i, c;
@ -847,4 +861,3 @@ ABC_NAMESPACE_HEADER_END
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -219,7 +219,8 @@ static inline void Ndr_DataPushString( Ndr_Data_t * p, int ObjType, int Type, ch
{
//word Truth = (word)pFunc;
//Ndr_DataPushArray( p, Type, 2, (int *)&Truth );
Ndr_DataPushArray( p, Type, 2, (int *)&pFunc );
int nInts = (strlen(pFunc) + 1 + sizeof(int) - 1) / sizeof(int);
Ndr_DataPushArray( p, Type, nInts, (int *)&pFunc );
}
else
{

View File

@ -600,7 +600,7 @@ Aig_Man_t * Iso_ManTest888( Aig_Man_t * pAig1, int fVerbose )
Vec_Int_t * vMap;
pNtk = Abc_NtkFromAigPhase( pAig1 );
Abc_NtkPermute( pNtk, 1, 0, 1, NULL );
Abc_NtkPermute( pNtk, 1, 0, 1, NULL, NULL, NULL );
pAig2 = Abc_NtkToDar( pNtk, 0, 1 );
Abc_NtkDelete( pNtk );

View File

@ -142,6 +142,7 @@ struct Abc_Obj_t_ // 48/72 bytes (32-bits/64-bits)
unsigned Level : 20; // the level of the node
Vec_Int_t vFanins; // the array of fanins
Vec_Int_t vFanouts; // the array of fanouts
void * pDataComp;
union { void * pData; // the network specific data
int iData; }; // (SOP, BDD, gate, equiv class, etc)
union { void * pTemp; // temporary store for user's data
@ -214,6 +215,7 @@ struct Abc_Ntk_t_
Vec_Ptr_t * vAttrs; // managers of various node attributes (node functionality, global BDDs, etc)
Vec_Int_t * vNameIds; // name IDs
Vec_Int_t * vFins; // obj/type info
Vec_Int_t * vOrigNodeIds; // original node IDs
};
struct Abc_Des_t_
@ -619,6 +621,7 @@ extern ABC_DLL float Abc_NtkDelayTraceLut( Abc_Ntk_t * pNtk, int fU
/*=== abcDfs.c ==========================================================*/
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs( Abc_Ntk_t * pNtk, int fCollectAll );
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkDfsSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSup, int iVerbose);
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverse( Abc_Ntk_t * pNtk );
extern ABC_DLL Vec_Ptr_t * Abc_NtkDfsReverseNodes( Abc_Ntk_t * pNtk, Abc_Obj_t ** ppNodes, int nNodes );
@ -639,6 +642,7 @@ extern ABC_DLL Vec_Ptr_t * Abc_AigDfsMap( Abc_Ntk_t * pNtk );
extern ABC_DLL Vec_Vec_t * Abc_DfsLevelized( Abc_Obj_t * pNode, int fTfi );
extern ABC_DLL Vec_Vec_t * Abc_NtkLevelize( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkLevel( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkLevelR( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkLevelReverse( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkIsAcyclic( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkIsAcyclicWithBoxes( Abc_Ntk_t * pNtk );
@ -677,6 +681,7 @@ extern ABC_DLL void Abc_NtkLogicMakeDirectSops( Abc_Ntk_t * pNtk )
extern ABC_DLL int Abc_NtkSopToAig( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkAigToBdd( Abc_Ntk_t * pNtk );
extern ABC_DLL Gia_Man_t * Abc_NtkAigToGia( Abc_Ntk_t * p, int fGiaSimple );
extern ABC_DLL int Abc_NtkMapToSopUsingLibrary( Abc_Ntk_t * pNtk, void* library );
extern ABC_DLL int Abc_NtkMapToSop( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_NtkToSop( Abc_Ntk_t * pNtk, int fMode, int nCubeLimit );
extern ABC_DLL int Abc_NtkToBdd( Abc_Ntk_t * pNtk );
@ -752,6 +757,7 @@ extern ABC_DLL void Abc_NtkAddDummyPiNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkAddDummyBoxNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkShortNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkCharNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkCleanNames( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkStartNameIds( Abc_Ntk_t * p );
extern ABC_DLL void Abc_NtkTransferNameIds( Abc_Ntk_t * p, Abc_Ntk_t * pNew );
@ -789,7 +795,7 @@ extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSops );
extern ABC_DLL void Abc_NtkDelete( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkMakeComb( Abc_Ntk_t * pNtk, int fRemoveLatches );
extern ABC_DLL void Abc_NtkPermute( Abc_Ntk_t * pNtk, int fInputs, int fOutputs, int fFlops, char * pFlopPermFile );
extern ABC_DLL void Abc_NtkPermute( Abc_Ntk_t * pNtk, int fInputs, int fOutputs, int fFlops, char * pInPermFile, char * pOutPermFile, char * pFlopPermFile );
extern ABC_DLL void Abc_NtkUnpermute( Abc_Ntk_t * pNtk );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromSops( char * pName, Vec_Ptr_t * vSops );
extern ABC_DLL Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias, Gia_Man_t * pMulti );
@ -841,7 +847,7 @@ extern ABC_DLL void Abc_NtkPrintFanioNew( FILE * pFile, Abc_Ntk_t
extern ABC_DLL void Abc_NodePrintFanio( FILE * pFile, Abc_Obj_t * pNode );
extern ABC_DLL void Abc_NtkPrintFactor( FILE * pFile, Abc_Ntk_t * pNtk, int fUseRealNames );
extern ABC_DLL void Abc_NodePrintFactor( FILE * pFile, Abc_Obj_t * pNode, int fUseRealNames );
extern ABC_DLL void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fVerbose );
extern ABC_DLL void Abc_NtkPrintLevel( FILE * pFile, Abc_Ntk_t * pNtk, int fProfile, int fListNodes, int fOutputs, int fVerbose );
extern ABC_DLL void Abc_NodePrintLevel( FILE * pFile, Abc_Obj_t * pNode );
extern ABC_DLL void Abc_NtkPrintSkews( FILE * pFile, Abc_Ntk_t * pNtk, int fPrintAll );
extern ABC_DLL void Abc_ObjPrint( FILE * pFile, Abc_Obj_t * pObj );
@ -881,6 +887,8 @@ extern ABC_DLL int Abc_NodeRef_rec( Abc_Obj_t * pNode );
extern ABC_DLL int Abc_NtkRefactor( Abc_Ntk_t * pNtk, int nNodeSizeMax, int nMinSaved, int nConeSizeMax, int fUpdateLevel, int fUseZeros, int fUseDcs, int fVerbose );
/*=== abcRewrite.c ==========================================================*/
extern ABC_DLL int Abc_NtkRewrite( Abc_Ntk_t * pNtk, int fUpdateLevel, int fUseZeros, int fVerbose, int fVeryVerbose, int fPlaceEnable );
/*=== abcRmInverters.c ======================================================*/
extern ABC_DLL void Abc_NtkRmInverter(Abc_Ntk_t * pNtk, int iVerbose);
/*=== abcSat.c ==========================================================*/
extern ABC_DLL int Abc_NtkMiterSat( Abc_Ntk_t * pNtk, ABC_INT64_T nConfLimit, ABC_INT64_T nInsLimit, int fVerbose, ABC_INT64_T * pNumConfs, ABC_INT64_T * pNumInspects );
extern ABC_DLL void * Abc_NtkMiterSatCreate( Abc_Ntk_t * pNtk, int fAllPrimes );
@ -1042,7 +1050,7 @@ extern ABC_DLL Vec_Int_t * Abc_NtkFanoutCounts( Abc_Ntk_t * pNtk );
extern ABC_DLL Vec_Ptr_t * Abc_NtkCollectObjects( Abc_Ntk_t * pNtk );
extern ABC_DLL Vec_Int_t * Abc_NtkGetCiIds( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkReassignIds( Abc_Ntk_t * pNtk );
extern ABC_DLL int Abc_ObjPointerCompare( void ** pp1, void ** pp2 );
// extern ABC_DLL int Abc_ObjPointerCompare( void ** pp1, void ** pp2 );
extern ABC_DLL void Abc_NtkTransferCopy( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkInvertConstraints( Abc_Ntk_t * pNtk );
extern ABC_DLL void Abc_NtkPrintCiLevels( Abc_Ntk_t * pNtk );

View File

@ -90,10 +90,10 @@ struct Abc_Aig_t_
static unsigned Abc_HashKey2( Abc_Obj_t * p0, Abc_Obj_t * p1, int TableSize )
{
unsigned Key = 0;
Key ^= Abc_ObjRegular(p0)->Id * 7937;
Key ^= Abc_ObjRegular(p1)->Id * 2971;
Key ^= Abc_ObjIsComplement(p0) * 911;
Key ^= Abc_ObjIsComplement(p1) * 353;
Key ^= (unsigned)Abc_ObjRegular(p0)->Id * 7937;
Key ^= (unsigned)Abc_ObjRegular(p1)->Id * 2971;
Key ^= (unsigned)Abc_ObjIsComplement(p0) * 911;
Key ^= (unsigned)Abc_ObjIsComplement(p1) * 353;
return Key % TableSize;
}
@ -905,7 +905,7 @@ void Abc_AigReplace_int( Abc_Aig_t * pMan, Abc_Obj_t * pOld, Abc_Obj_t * pNew, i
{
Abc_ObjSetReverseLevel( pFanin1, Abc_ObjReverseLevel(pOld) );
assert( pFanin1->fMarkB == 0 );
if ( !Abc_ObjIsCi(pFanin1) )
if ( !Abc_ObjIsCi(pFanin1) && !Abc_AigNodeIsConst(pFanin1) )
{
pFanin1->fMarkB = 1;
Vec_VecPush( pMan->vLevelsR, Abc_ObjReverseLevel(pFanin1), pFanin1 );
@ -1139,7 +1139,7 @@ void Abc_AigUpdateLevelR_int( Abc_Aig_t * pMan )
// iterate through the fanins
Abc_ObjForEachFanin( pNode, pFanin, v )
{
if ( Abc_ObjIsCi(pFanin) )
if ( Abc_ObjIsCi(pFanin) || Abc_AigNodeIsConst(pFanin) )
continue;
// get the new reverse level of this fanin
LevelNew = 0;

View File

@ -19,6 +19,7 @@
***********************************************************************/
#include "abc.h"
#include "misc/vec/vecPtr.h"
#include "proof/cec/cec.h"
ABC_NAMESPACE_IMPL_START
@ -137,6 +138,101 @@ Vec_Ptr_t * Abc_NtkDfs2( Abc_Ntk_t * pNtk )
return vNodes;
}
/**Function*************************************************************
Synopsis [Collect support nodes bounded internal nodes.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkDfsSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vNodes, Vec_Ptr_t * vSup, int iVerbose)
{
Abc_Obj_t * pFanin;
int i;
assert( !Abc_ObjIsNet(pNode) );
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
Abc_NodeSetTravIdCurrent( pNode );
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsCo(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
return;
if( Vec_PtrFind(vSup, pNode) >= 0 )
{
if(iVerbose)
{
printf("Encountered vSup Node: %s\n", Abc_ObjName(pNode));
printf("Whose fanins are:\n");
printf(" Fanin0: %s", Abc_ObjName(Abc_ObjFanin0(pNode)));
printf(" %d on comp\n", pNode->fCompl0);
printf(" Fanin1: %s", Abc_ObjName(Abc_ObjFanin1(pNode)));
printf(" %d on comp\n", pNode->fCompl1);
}
return;
}
assert( Abc_ObjIsNode( pNode ) );
Abc_ObjForEachFanin( pNode, pFanin, i )
{
if(iVerbose)
{
printf(" Node %s Fanin %d: ", Abc_ObjName(pNode), i);
printf("%s", Abc_ObjName(pFanin));
printf(" %d on comp\n", i == 0 ? pNode->fCompl0 : pNode->fCompl1);
}
Abc_NtkDfsSup_rec( Abc_ObjFanin0Ntk(pFanin), vNodes, vSup, iVerbose);
}
Vec_PtrPush( vNodes, pNode );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkDfsInvSup_rec( Abc_Obj_t * pNode, Vec_Ptr_t * vSup, int * countFlip)
{
Abc_Obj_t * pFanin;
int i;
assert( !Abc_ObjIsNet(pNode) );
if ( Abc_NodeIsTravIdCurrent( pNode ) )
return;
Abc_NodeSetTravIdCurrent( pNode );
if ( Abc_ObjIsCi(pNode) || Abc_ObjIsCo(pNode) || (Abc_NtkIsStrash(pNode->pNtk) && Abc_AigNodeIsConst(pNode)) )
return;
if( Vec_PtrFind(vSup, pNode) >= 0 )
{
return;
}
assert( Abc_ObjIsNode( pNode ) || Abc_ObjIsBox( pNode ) );
Abc_ObjForEachFanin( pNode, pFanin, i )
{
if(Vec_PtrFind(vSup, pFanin) >= 0)
{
if(i == 0)
{
printf("Flipping edge on Node %s %d (Phase = %d)\n", Abc_ObjName(pNode), i, pFanin->fPhase );
pNode->fCompl0 ^= 1;
}
else if(i == 1)
{
printf("Flipping edge on Node %s %d (Phase = %d)\n", Abc_ObjName(pNode),i , pFanin->fPhase);
pNode->fCompl1 ^= 1;
}
*countFlip = *countFlip + 1;
}
Abc_NtkDfsInvSup_rec( Abc_ObjFanin0Ntk(pFanin), vSup, countFlip );
}
}
/**Function*************************************************************
Synopsis [Returns the DFS ordered array of logic nodes.]
@ -1514,6 +1610,14 @@ int Abc_NtkLevelReverse( Abc_Ntk_t * pNtk )
}
return LevelsMax;
}
int Abc_NtkLevelR( Abc_Ntk_t * pNtk )
{
int i, LevelMax = Abc_NtkLevelReverse( pNtk );
Abc_Obj_t * pNode;
Abc_NtkForEachObj( pNtk, pNode, i )
pNode->Level = (int)(LevelMax - pNode->Level + 1);
return LevelMax;
}
/**Function*************************************************************

View File

@ -33,7 +33,8 @@ ABC_NAMESPACE_IMPL_START
/// DECLARATIONS ///
////////////////////////////////////////////////////////////////////////
#define ABC_MAX_CUBES 100000
#define ABC_MAX_CUBES 1000000
#define ABC_MAX_CUBES2 10000
static Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop );
@ -42,11 +43,63 @@ static Hop_Obj_t * Abc_ConvertSopToAig( Hop_Man_t * pMan, char * pSop );
int Abc_ConvertZddToSop( DdManager * dd, DdNode * zCover, char * pSop, int nFanins, Vec_Str_t * vCube, int fPhase );
static DdNode * Abc_ConvertAigToBdd( DdManager * dd, Hop_Obj_t * pRoot);
extern int Abc_CountZddCubes( DdManager * dd, DdNode * zCover );
extern void Abc_NtkSortCubes( Abc_Ntk_t * pNtk, int fWeight );
////////////////////////////////////////////////////////////////////////
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
/**Function*************************************************************
Synopsis [Converts the node from SOP to BDD representation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_ConvertSopToBdd2Count( char * pSop, int nCubes, int nStep, int iVar, int pRes[3] )
{
int i;
for ( i = 0; i < nCubes; i++ )
if ( pSop[i*nStep+iVar] == '-' )
pRes[0]++, assert( pRes[1] == 0 && pRes[2] == 0 );
else if ( pSop[i*nStep+iVar] == '0' )
pRes[1]++, assert( pRes[2] == 0 );
else if ( pSop[i*nStep+iVar] == '1' )
pRes[2]++;
else assert( 0 );
}
DdNode * Abc_ConvertSopToBdd2_rec( DdManager * dd, char * pSop, DdNode ** pbVars, int nCubes, int nStep, int iVar )
{
DdNode * bRes[5] = {NULL};
int pRes[3] = {0}, i, Start = 0;
if ( nCubes == 0 )
return Cudd_ReadLogicZero(dd);
if ( iVar == nStep - 3 )
return Cudd_ReadOne(dd);
Abc_ConvertSopToBdd2Count( pSop, nCubes, nStep, iVar, pRes );
for ( i = 0; i < 3; Start += pRes[i++] )
bRes[i] = Abc_ConvertSopToBdd2_rec( dd, pSop + Start*nStep, pbVars, pRes[i], nStep, iVar+1 ), Cudd_Ref( bRes[i] );
bRes[3] = Cudd_bddIte( dd, pbVars[iVar], bRes[2], bRes[1] ); Cudd_Ref( bRes[3] );
Cudd_RecursiveDeref( dd, bRes[1] );
Cudd_RecursiveDeref( dd, bRes[2] );
bRes[4] = Cudd_bddOr( dd, bRes[0], bRes[3] ); Cudd_Ref( bRes[4] );
Cudd_RecursiveDeref( dd, bRes[3] );
Cudd_RecursiveDeref( dd, bRes[0] );
Cudd_Deref( bRes[4] );
return bRes[4];
}
DdNode * Abc_ConvertSopToBdd2( DdManager * dd, char * pSop, DdNode ** pbVars )
{
int nCubes = Abc_SopGetCubeNum(pSop);
int nStep = Abc_SopGetVarNum(pSop) + 3;
assert( pSop[nCubes*nStep] == '\0' );
return Abc_ConvertSopToBdd2_rec( dd, pSop, pbVars, nCubes, nStep, 0 );
}
/**Function*************************************************************
Synopsis [Converts the node from SOP to BDD representation.]
@ -74,6 +127,21 @@ DdNode * Abc_ConvertSopToBdd( DdManager * dd, char * pSop, DdNode ** pbVars )
bSum = Cudd_bddXor( dd, bTemp = bSum, pbVars? pbVars[v] : Cudd_bddIthVar(dd, v) ); Cudd_Ref( bSum );
Cudd_RecursiveDeref( dd, bTemp );
}
}
else if ( Abc_SopGetCubeNum(pSop) > ABC_MAX_CUBES2 )
{
Cudd_Deref( bSum );
if ( pbVars )
bSum = Abc_ConvertSopToBdd2( dd, pSop, pbVars );
else
{
DdNode ** pbVars = ABC_ALLOC( DdNode *, nVars );
for ( v = 0; v < nVars; v++ )
pbVars[v] = Cudd_bddIthVar( dd, v );
bSum = Abc_ConvertSopToBdd2( dd, pSop, pbVars );
ABC_FREE( pbVars );
}
Cudd_Ref( bSum );
}
else
{
@ -120,10 +188,16 @@ int Abc_NtkSopToBdd( Abc_Ntk_t * pNtk )
Abc_Obj_t * pNode;
DdManager * dd, * ddTemp = NULL;
Vec_Int_t * vFanins = NULL;
int nFaninsMax, i, k, iVar;
int nFaninsMax, i, k, iVar, nCubesMax = 0;
assert( Abc_NtkHasSop(pNtk) );
// check SOP sizes
Abc_NtkForEachNode( pNtk, pNode, i )
nCubesMax = Abc_MaxInt( nCubesMax, Abc_SopGetCubeNum((char *)pNode->pData) );
if ( nCubesMax > ABC_MAX_CUBES2 )
Abc_NtkSortCubes( pNtk, 0 );
// start the functionality manager
nFaninsMax = Abc_NtkGetFaninMax( pNtk );
if ( nFaninsMax == 0 )
@ -1108,7 +1182,7 @@ Abc_Obj_t * Abc_ConvertAigToAig( Abc_Ntk_t * pNtkAig, Abc_Obj_t * pObjOld )
/**Function*************************************************************
Synopsis [Unmaps the network.]
Synopsis [Unmaps the network with user provided Mio library.]
Description []
@ -1117,16 +1191,15 @@ Abc_Obj_t * Abc_ConvertAigToAig( Abc_Ntk_t * pNtkAig, Abc_Obj_t * pObjOld )
SeeAlso []
***********************************************************************/
int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
int Abc_NtkMapToSopUsingLibrary( Abc_Ntk_t * pNtk, void* library)
{
extern void * Abc_FrameReadLibGen();
Abc_Obj_t * pNode;
char * pSop;
int i;
assert( Abc_NtkHasMapping(pNtk) );
// update the functionality manager
assert( pNtk->pManFunc == Abc_FrameReadLibGen() );
assert( pNtk->pManFunc == (void*) library );
pNtk->pManFunc = Mem_FlexStart();
// update the nodes
Abc_NtkForEachNode( pNtk, pNode, i )
@ -1141,6 +1214,23 @@ int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
return 1;
}
/**Function*************************************************************
Synopsis [Unmaps the network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkMapToSop( Abc_Ntk_t * pNtk )
{
extern void * Abc_FrameReadLibGen();
return Abc_NtkMapToSopUsingLibrary(pNtk, Abc_FrameReadLibGen());
}
/**Function*************************************************************
Synopsis [Converts SOP functions into BLIF-MV functions.]

File diff suppressed because it is too large Load Diff

View File

@ -125,6 +125,12 @@ char * Abc_ObjNameDummy( char * pPrefix, int Num, int nDigits )
sprintf( Buffer, "%s%0*d", pPrefix, nDigits, Num );
return Buffer;
}
char * Abc_ObjNameChar( int Num, int fCap )
{
static char Buffer[2000];
sprintf( Buffer, "%c", (fCap ? 'A':'a') + Num );
return Buffer;
}
/**Function*************************************************************
@ -494,6 +500,12 @@ void Abc_NtkAddDummyPiNames( Abc_Ntk_t * pNtk )
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjAssignName( pObj, Abc_ObjNameDummy("pi", i, nDigits), NULL );
}
void Abc_NtkAddCharPiNames( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj; int i;
Abc_NtkForEachPi( pNtk, pObj, i )
Abc_ObjAssignName( pObj, Abc_ObjNameChar(i, 0), NULL );
}
/**Function*************************************************************
@ -514,6 +526,12 @@ void Abc_NtkAddDummyPoNames( Abc_Ntk_t * pNtk )
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_ObjAssignName( pObj, Abc_ObjNameDummy("po", i, nDigits), NULL );
}
void Abc_NtkAddCharPoNames( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj; int i;
Abc_NtkForEachPo( pNtk, pObj, i )
Abc_ObjAssignName( pObj, Abc_ObjNameChar(i, 1), NULL );
}
/**Function*************************************************************
@ -606,6 +624,14 @@ void Abc_NtkShortNames( Abc_Ntk_t * pNtk )
Abc_NtkAddDummyPoNames( pNtk );
Abc_NtkAddDummyBoxNames( pNtk );
}
void Abc_NtkCharNames( Abc_Ntk_t * pNtk )
{
Nm_ManFree( pNtk->pManName );
pNtk->pManName = Nm_ManCreate( Abc_NtkCiNum(pNtk) + Abc_NtkCoNum(pNtk) + Abc_NtkBoxNum(pNtk) );
Abc_NtkAddCharPiNames( pNtk );
Abc_NtkAddCharPoNames( pNtk );
Abc_NtkAddDummyBoxNames( pNtk );
}
void Abc_NtkCleanNames( Abc_Ntk_t * pNtk )
{
Abc_Obj_t * pObj; int i;

View File

@ -39,6 +39,86 @@ ABC_NAMESPACE_IMPL_START
/// FUNCTION DEFINITIONS ///
////////////////////////////////////////////////////////////////////////
static int Abc_NtkDupDfsSameFanins( Abc_Obj_t * pObj0, Abc_Obj_t * pObj1 )
{
Abc_Obj_t * pFanin0, * pFanin1;
int i;
if ( pObj0 == NULL || pObj1 == NULL || Abc_ObjFaninNum(pObj0) != Abc_ObjFaninNum(pObj1) )
return 0;
Abc_ObjForEachFanin( pObj0, pFanin0, i )
{
pFanin1 = Abc_ObjFanin( pObj1, i );
if ( pFanin0 != pFanin1 )
return 0;
}
return 1;
}
static Abc_Obj_t * Abc_NtkDupDfsFindTwin( Vec_Ptr_t * vNodes, Vec_Int_t * vSeen, Abc_Obj_t * pObj )
{
Mio_Gate_t * pGate = (Mio_Gate_t *)pObj->pData;
Abc_Obj_t * pObj2;
int i;
if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL )
return NULL;
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj2, i )
{
if ( pObj2 == pObj || Vec_IntEntry(vSeen, Abc_ObjId(pObj2)) )
continue;
if ( (Mio_Gate_t *)pObj2->pData != Mio_GateReadTwin(pGate) )
continue;
if ( Abc_NtkDupDfsSameFanins(pObj, pObj2) )
return pObj2;
}
return NULL;
}
static Vec_Ptr_t * Abc_NtkDupDfsOrderTwinNodes( Abc_Ntk_t * pNtk, Vec_Ptr_t * vNodes )
{
Vec_Int_t * vSeen;
Vec_Ptr_t * vRes;
Abc_Obj_t * pObj, * pTwin;
Mio_Gate_t * pGate, * pGateBase;
int i;
if ( !Abc_NtkHasMapping(pNtk) || pNtk->pManFunc == NULL )
return vNodes;
vSeen = Vec_IntStart( Abc_NtkObjNumMax(pNtk) );
vRes = Vec_PtrAlloc( Vec_PtrSize(vNodes) );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
{
if ( Vec_IntEntry(vSeen, Abc_ObjId(pObj)) )
continue;
pGate = (Mio_Gate_t *)pObj->pData;
if ( pGate == NULL || Mio_GateReadTwin(pGate) == NULL )
{
Vec_PtrPush( vRes, pObj );
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
continue;
}
pTwin = Abc_NtkDupDfsFindTwin( vNodes, vSeen, pObj );
if ( pTwin == NULL )
{
Vec_PtrPush( vRes, pObj );
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
continue;
}
pGateBase = Mio_LibraryReadGateByName( (Mio_Library_t *)pNtk->pManFunc, Mio_GateReadName(pGate), NULL );
if ( pGateBase == (Mio_Gate_t *)pTwin->pData )
{
Vec_PtrPush( vRes, pTwin );
Vec_PtrPush( vRes, pObj );
}
else
{
Vec_PtrPush( vRes, pObj );
Vec_PtrPush( vRes, pTwin );
}
Vec_IntWriteEntry( vSeen, Abc_ObjId(pObj), 1 );
Vec_IntWriteEntry( vSeen, Abc_ObjId(pTwin), 1 );
}
Vec_IntFree( vSeen );
Vec_PtrFree( vNodes );
return vRes;
}
/**Function*************************************************************
Synopsis [Creates a new Ntk.]
@ -96,6 +176,52 @@ Abc_Ntk_t * Abc_NtkAlloc( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan
pNtk->AndGateDelay = 0.0;
return pNtk;
}
Abc_Ntk_t * Abc_NtkAllocBdd( Abc_NtkType_t Type, Abc_NtkFunc_t Func, int fUseMemMan, int nVars )
{
Abc_Ntk_t * pNtk;
pNtk = ABC_ALLOC( Abc_Ntk_t, 1 );
memset( pNtk, 0, sizeof(Abc_Ntk_t) );
pNtk->ntkType = Type;
pNtk->ntkFunc = Func;
// start the object storage
pNtk->vObjs = Vec_PtrAlloc( 100 );
pNtk->vPios = Vec_PtrAlloc( 100 );
pNtk->vPis = Vec_PtrAlloc( 100 );
pNtk->vPos = Vec_PtrAlloc( 100 );
pNtk->vCis = Vec_PtrAlloc( 100 );
pNtk->vCos = Vec_PtrAlloc( 100 );
pNtk->vBoxes = Vec_PtrAlloc( 100 );
pNtk->vLtlProperties = Vec_PtrAlloc( 100 );
// start the memory managers
pNtk->pMmObj = fUseMemMan? Mem_FixedStart( sizeof(Abc_Obj_t) ) : NULL;
pNtk->pMmStep = fUseMemMan? Mem_StepStart( ABC_NUM_STEPS ) : NULL;
// get ready to assign the first Obj ID
pNtk->nTravIds = 1;
// start the functionality manager
if ( !Abc_NtkIsStrash(pNtk) )
Vec_PtrPush( pNtk->vObjs, NULL );
if ( Abc_NtkIsStrash(pNtk) )
pNtk->pManFunc = Abc_AigAlloc( pNtk );
else if ( Abc_NtkHasSop(pNtk) || Abc_NtkHasBlifMv(pNtk) )
pNtk->pManFunc = Mem_FlexStart();
#ifdef ABC_USE_CUDD
else if ( Abc_NtkHasBdd(pNtk) )
pNtk->pManFunc = Cudd_Init( nVars, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
#endif
else if ( Abc_NtkHasAig(pNtk) )
pNtk->pManFunc = Hop_ManStart();
else if ( Abc_NtkHasMapping(pNtk) )
pNtk->pManFunc = Abc_FrameReadLibGen();
else if ( !Abc_NtkHasBlackbox(pNtk) )
assert( 0 );
// name manager
pNtk->pManName = Nm_ManCreate( 200 );
// attribute manager
pNtk->vAttrs = Vec_PtrStart( VEC_ATTR_TOTAL_NUM );
// estimated AndGateDelay
pNtk->AndGateDelay = 0.0;
return pNtk;
}
/**Function*************************************************************
@ -118,7 +244,7 @@ Abc_Ntk_t * Abc_NtkStartFrom( Abc_Ntk_t * pNtk, Abc_NtkType_t Type, Abc_NtkFunc_
// decide whether to copy the names
fCopyNames = ( Type != ABC_NTK_NETLIST );
// start the network
pNtkNew = Abc_NtkAlloc( Type, Func, 1 );
pNtkNew = Func == ABC_FUNC_BDD ? Abc_NtkAllocBdd( Type, Func, 1, Abc_NtkCiNum(pNtk) ) : Abc_NtkAlloc( Type, Func, 1 );
pNtkNew->nConstrs = pNtk->nConstrs;
pNtkNew->nBarBufs = pNtk->nBarBufs;
// duplicate the name and the spec
@ -461,6 +587,15 @@ Abc_Ntk_t * Abc_NtkDup( Abc_Ntk_t * pNtk )
if ( !Abc_ObjIsBox(pObj) && !Abc_ObjIsBo(pObj) )
Abc_ObjForEachFanin( pObj, pFanin, k )
Abc_ObjAddFanin( pObj->pCopy, pFanin->pCopy );
// move object IDs
if ( pNtk->vOrigNodeIds )
{
pNtkNew->vOrigNodeIds = Vec_IntStartFull( Abc_NtkObjNumMax(pNtkNew) );
Abc_NtkForEachObj( pNtk, pObj, i )
if ( pObj->pCopy && Vec_IntEntry(pNtk->vOrigNodeIds, pObj->Id) > 0 )
Vec_IntWriteEntry( pNtkNew->vOrigNodeIds, pObj->pCopy->Id, Vec_IntEntry(pNtk->vOrigNodeIds, pObj->Id) );
}
}
// duplicate the EXDC Ntk
if ( pNtk->pExdc )
@ -493,6 +628,7 @@ Abc_Ntk_t * Abc_NtkDupDfs( Abc_Ntk_t * pNtk )
pNtkNew = Abc_NtkStartFrom( pNtk, pNtk->ntkType, pNtk->ntkFunc );
// copy the internal nodes
vNodes = Abc_NtkDfs( pNtk, 0 );
vNodes = Abc_NtkDupDfsOrderTwinNodes( pNtk, vNodes );
Vec_PtrForEachEntry( Abc_Obj_t *, vNodes, pObj, i )
Abc_NtkDupObj( pNtkNew, pObj, 0 );
Vec_PtrFree( vNodes );
@ -1335,10 +1471,11 @@ Abc_Ntk_t * Abc_NtkCreateWithNodes( Vec_Ptr_t * vSop )
Abc_NodeFreeNames( vNames );
// create the node, add PIs as fanins, set the function
Vec_PtrForEachEntry( char *, vSop, pSop, i )
{
{
pNode = Abc_NtkCreateNode( pNtkNew );
Abc_NtkForEachPi( pNtkNew, pFanin, k )
Abc_ObjAddFanin( pNode, pFanin );
if ( Abc_SopGetVarNum(pSop) > 0 )
Abc_NtkForEachPi( pNtkNew, pFanin, k )
Abc_ObjAddFanin( pNode, pFanin );
pNode->pData = Abc_SopRegister( (Mem_Flex_t *)pNtkNew->pManFunc, pSop );
// create the only PO
pNodePo = Abc_NtkCreatePo(pNtkNew);
@ -1483,6 +1620,7 @@ void Abc_NtkDelete( Abc_Ntk_t * pNtk )
Vec_IntFreeP( &pNtk->vObjPerm );
Vec_IntFreeP( &pNtk->vTopo );
Vec_IntFreeP( &pNtk->vFins );
Vec_IntFreeP( &pNtk->vOrigNodeIds );
ABC_FREE( pNtk );
}
@ -1507,6 +1645,24 @@ void Abc_NtkFixNonDrivenNets( Abc_Ntk_t * pNtk )
return;
// special case
pNet = Abc_NtkFindNet( pNtk, "$false" );
if ( pNet != NULL && !Abc_ObjFaninNum(pNet) )
{
pNode = Abc_NtkCreateNodeConst0( pNtk );
Abc_ObjAddFanin( pNet, pNode );
}
pNet = Abc_NtkFindNet( pNtk, "$undef" );
if ( pNet != NULL && !Abc_ObjFaninNum(pNet) )
{
pNode = Abc_NtkCreateNodeConst0( pNtk );
Abc_ObjAddFanin( pNet, pNode );
}
pNet = Abc_NtkFindNet( pNtk, "$true" );
if ( pNet != NULL && !Abc_ObjFaninNum(pNet) )
{
pNode = Abc_NtkCreateNodeConst1( pNtk );
Abc_ObjAddFanin( pNet, pNode );
}
pNet = Abc_NtkFindNet( pNtk, "[_c1_]" );
if ( pNet != NULL )
{
@ -1716,6 +1872,58 @@ void Abc_NtkMakeSeq( Abc_Ntk_t * pNtk, int nLatchesToAdd )
}
/**Function*************************************************************
Synopsis [Keeps POs in the array.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkSelectPos( Abc_Ntk_t * pNtkInit, Vec_Int_t * vPoIds )
{
Abc_Ntk_t * pNtk;
Vec_Ptr_t * vPosLeft;
Vec_Ptr_t * vCosLeft;
Abc_Obj_t * pNodePo;
int i, Index;
assert( !Abc_NtkIsNetlist(pNtkInit) );
assert( Abc_NtkHasOnlyLatchBoxes(pNtkInit) );
pNtk = Abc_NtkDup( pNtkInit );
if ( Abc_NtkPoNum(pNtk) == 1 )
return pNtk;
vPosLeft = Vec_PtrAlloc( Vec_IntSize(vPoIds) );
Vec_IntForEachEntry( vPoIds, Index, i ) {
Vec_PtrPush( vPosLeft, Abc_NtkPo(pNtk, Index) );
Vec_PtrWriteEntry( pNtk->vPos, Index, NULL );
}
// filter COs
vCosLeft = Vec_PtrDup( vPosLeft );
for ( i = Abc_NtkPoNum(pNtk); i < Abc_NtkCoNum(pNtk); i++ )
Vec_PtrPush( vCosLeft, Abc_NtkCo(pNtk, i) );
// remove remaiing POs
Abc_NtkForEachPo( pNtk, pNodePo, i )
if ( pNodePo )
Abc_NtkDeleteObjPo( pNodePo );
// update arrays
Vec_PtrFree( pNtk->vPos ); pNtk->vPos = vPosLeft;
Vec_PtrFree( pNtk->vCos ); pNtk->vCos = vCosLeft;
// clean the network
if ( Abc_NtkIsStrash(pNtk) ) {
Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc );
if ( Abc_NtkLatchNum(pNtk) ) printf( "Run sequential cleanup (\"scl\") to get rid of dangling logic.\n" );
}
else {
if ( Abc_NtkLatchNum(pNtk) ) printf( "Run sequential cleanup (\"st; scl\") to get rid of dangling logic.\n" );
}
if ( !Abc_NtkCheck( pNtk ) )
fprintf( stdout, "Abc_NtkMakeComb(): Network check has failed.\n" );
return pNtk;
}
/**Function*************************************************************
Synopsis [Removes all POs, except one.]
@ -1768,11 +1976,11 @@ Abc_Ntk_t * Abc_NtkMakeOnePo( Abc_Ntk_t * pNtkInit, int Output, int nRange )
if ( Abc_NtkIsStrash(pNtk) )
{
Abc_AigCleanup( (Abc_Aig_t *)pNtk->pManFunc );
printf( "Run sequential cleanup (\"scl\") to get rid of dangling logic.\n" );
if ( Abc_NtkLatchNum(pNtk) ) printf( "Run sequential cleanup (\"scl\") to get rid of dangling logic.\n" );
}
else
{
printf( "Run sequential cleanup (\"st; scl\") to get rid of dangling logic.\n" );
if ( Abc_NtkLatchNum(pNtk) ) printf( "Run sequential cleanup (\"st; scl\") to get rid of dangling logic.\n" );
}
if ( !Abc_NtkCheck( pNtk ) )
@ -1996,11 +2204,11 @@ void Abc_NtkRemovePo( Abc_Ntk_t * pNtk, int iOutput, int fRemoveConst0 )
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkReadFlopPerm( char * pFileName, int nFlops )
Vec_Int_t * Abc_NtkReadSignalPerm2( char * pFileName, int nSignals )
{
char Buffer[1000];
FILE * pFile;
Vec_Int_t * vFlops;
Vec_Int_t * vSignals;
int iFlop = -1;
pFile = fopen( pFileName, "rb" );
if ( pFile == NULL )
@ -2008,30 +2216,63 @@ Vec_Int_t * Abc_NtkReadFlopPerm( char * pFileName, int nFlops )
printf( "Cannot open input file \"%s\".\n", pFileName );
return NULL;
}
vFlops = Vec_IntAlloc( nFlops );
vSignals = Vec_IntAlloc( nSignals );
while ( fgets( Buffer, 1000, pFile ) != NULL )
{
if ( Buffer[0] == ' ' || Buffer[0] == '\r' || Buffer[0] == '\n' )
continue;
iFlop = atoi( Buffer );
if ( iFlop < 0 || iFlop >= nFlops )
if ( iFlop < 0 || iFlop >= nSignals )
{
printf( "Flop ID (%d) is out of range.\n", iFlop );
printf( "The zero-based signal ID (%d) is out of range.\n", iFlop );
fclose( pFile );
Vec_IntFree( vFlops );
Vec_IntFree( vSignals );
return NULL;
}
Vec_IntPush( vFlops, iFlop );
Vec_IntPush( vSignals, iFlop );
}
fclose( pFile );
if ( Vec_IntSize(vFlops) != nFlops )
if ( Vec_IntSize(vSignals) != nSignals )
{
printf( "The number of flops read in from file (%d) is different from the number of flops in the circuit (%d).\n", iFlop, nFlops );
Vec_IntFree( vFlops );
printf( "The number of indexes read in from file (%d) is different from the number of signals in the circuit (%d).\n", Vec_IntSize(vSignals), nSignals );
Vec_IntFree( vSignals );
return NULL;
}
return vFlops;
return vSignals;
}
Vec_Int_t * Abc_NtkReadSignalPerm( char * pFileName, int nSignals )
{
int Num = -1;
Vec_Int_t * vSignals;
FILE * pFile = fopen( pFileName, "rb" );
if ( pFile == NULL )
{
printf( "Cannot open input file \"%s\".\n", pFileName );
return NULL;
}
vSignals = Vec_IntAlloc( nSignals );
while ( fscanf( pFile, "%d", &Num ) == 1 )
{
if ( Num <= 0 || Num > nSignals )
{
printf( "The one-based signal ID (%d) is out of range (%d).\n", Num, nSignals );
fclose( pFile );
Vec_IntFree( vSignals );
return NULL;
}
Vec_IntPush( vSignals, Num-1 );
}
fclose( pFile );
if ( Vec_IntSize(vSignals) != nSignals )
{
printf( "The number of indexes read in from file (%d) is different from the number of signals in the circuit (%d).\n", Vec_IntSize(vSignals), nSignals );
Vec_IntFree( vSignals );
return NULL;
}
return vSignals;
}
/**Function*************************************************************
Synopsis []
@ -2043,61 +2284,98 @@ Vec_Int_t * Abc_NtkReadFlopPerm( char * pFileName, int nFlops )
SeeAlso []
***********************************************************************/
void Abc_NtkPermute( Abc_Ntk_t * pNtk, int fInputs, int fOutputs, int fFlops, char * pFlopPermFile )
void Abc_NtkPermute( Abc_Ntk_t * pNtk, int fInputs, int fOutputs, int fFlops, char * pInPermFile, char * pOutPermFile, char * pFlopPermFile )
{
Abc_Obj_t * pTemp;
Vec_Int_t * vInputs, * vOutputs, * vFlops, * vTemp;
int i, k, Entry;
// start permutation arrays
if ( pInPermFile )
{
vInputs = Abc_NtkReadSignalPerm( pInPermFile, Abc_NtkPiNum(pNtk) );
if ( vInputs == NULL )
return;
fInputs = 1;
}
else
vInputs = Vec_IntStartNatural( Abc_NtkPiNum(pNtk) );
if ( pOutPermFile )
{
vOutputs = Abc_NtkReadSignalPerm( pOutPermFile, Abc_NtkPoNum(pNtk) );
if ( vOutputs == NULL )
return;
fOutputs = 1;
}
else
vOutputs = Vec_IntStartNatural( Abc_NtkPoNum(pNtk) );
if ( pFlopPermFile )
{
vFlops = Abc_NtkReadFlopPerm( pFlopPermFile, Abc_NtkLatchNum(pNtk) );
vFlops = Abc_NtkReadSignalPerm( pFlopPermFile, Abc_NtkLatchNum(pNtk) );
if ( vFlops == NULL )
return;
fInputs = 0;
fOutputs = 0;
fFlops = 0;
fFlops = 1;
}
else
vFlops = Vec_IntStartNatural( Abc_NtkLatchNum(pNtk) );
vInputs = Vec_IntStartNatural( Abc_NtkPiNum(pNtk) );
vOutputs = Vec_IntStartNatural( Abc_NtkPoNum(pNtk) );
// permute inputs
Vec_Ptr_t * vCis = Vec_PtrDup(pNtk->vCis);
Vec_Ptr_t * vCos = Vec_PtrDup(pNtk->vCos);
Vec_Ptr_t * vFfs = Vec_PtrDup(pNtk->vBoxes);
if ( fInputs )
for ( i = 0; i < Abc_NtkPiNum(pNtk); i++ )
{
k = rand() % Abc_NtkPiNum(pNtk);
// swap indexes
Entry = Vec_IntEntry( vInputs, i );
Vec_IntWriteEntry( vInputs, i, Vec_IntEntry(vInputs, k) );
Vec_IntWriteEntry( vInputs, k, Entry );
// swap PIs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPis, i );
Vec_PtrWriteEntry( pNtk->vPis, i, Vec_PtrEntry(pNtk->vPis, k) );
Vec_PtrWriteEntry( pNtk->vPis, k, pTemp );
// swap CIs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, i );
Vec_PtrWriteEntry( pNtk->vCis, i, Vec_PtrEntry(pNtk->vCis, k) );
Vec_PtrWriteEntry( pNtk->vCis, k, pTemp );
if ( pInPermFile )
{
k = Vec_IntEntry( vInputs, i );
pTemp = (Abc_Obj_t *)Vec_PtrEntry( vCis, k );
Vec_PtrWriteEntry( pNtk->vPis, i, pTemp );
Vec_PtrWriteEntry( pNtk->vCis, i, pTemp );
}
else
{
k = rand() % Abc_NtkPiNum(pNtk);
// swap indexes
Entry = Vec_IntEntry( vInputs, i );
Vec_IntWriteEntry( vInputs, i, Vec_IntEntry(vInputs, k) );
Vec_IntWriteEntry( vInputs, k, Entry );
// swap PIs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPis, i );
Vec_PtrWriteEntry( pNtk->vPis, i, Vec_PtrEntry(pNtk->vPis, k) );
Vec_PtrWriteEntry( pNtk->vPis, k, pTemp );
// swap CIs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, i );
Vec_PtrWriteEntry( pNtk->vCis, i, Vec_PtrEntry(pNtk->vCis, k) );
Vec_PtrWriteEntry( pNtk->vCis, k, pTemp );
}
//printf( "Swapping PIs %d and %d.\n", i, k );
}
// permute outputs
if ( fOutputs )
for ( i = 0; i < Abc_NtkPoNum(pNtk); i++ )
{
k = rand() % Abc_NtkPoNum(pNtk);
// swap indexes
Entry = Vec_IntEntry( vOutputs, i );
Vec_IntWriteEntry( vOutputs, i, Vec_IntEntry(vOutputs, k) );
Vec_IntWriteEntry( vOutputs, k, Entry );
// swap POs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPos, i );
Vec_PtrWriteEntry( pNtk->vPos, i, Vec_PtrEntry(pNtk->vPos, k) );
Vec_PtrWriteEntry( pNtk->vPos, k, pTemp );
// swap COs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, i );
Vec_PtrWriteEntry( pNtk->vCos, i, Vec_PtrEntry(pNtk->vCos, k) );
Vec_PtrWriteEntry( pNtk->vCos, k, pTemp );
if ( pOutPermFile )
{
k = Vec_IntEntry( vOutputs, i );
pTemp = (Abc_Obj_t *)Vec_PtrEntry( vCos, k );
Vec_PtrWriteEntry( pNtk->vPos, i, pTemp );
Vec_PtrWriteEntry( pNtk->vCos, i, pTemp );
}
else
{
k = rand() % Abc_NtkPoNum(pNtk);
// swap indexes
Entry = Vec_IntEntry( vOutputs, i );
Vec_IntWriteEntry( vOutputs, i, Vec_IntEntry(vOutputs, k) );
Vec_IntWriteEntry( vOutputs, k, Entry );
// swap POs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vPos, i );
Vec_PtrWriteEntry( pNtk->vPos, i, Vec_PtrEntry(pNtk->vPos, k) );
Vec_PtrWriteEntry( pNtk->vPos, k, pTemp );
// swap COs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, i );
Vec_PtrWriteEntry( pNtk->vCos, i, Vec_PtrEntry(pNtk->vCos, k) );
Vec_PtrWriteEntry( pNtk->vCos, k, pTemp );
}
//printf( "Swapping POs %d and %d.\n", i, k );
}
// permute flops
@ -2105,26 +2383,42 @@ void Abc_NtkPermute( Abc_Ntk_t * pNtk, int fInputs, int fOutputs, int fFlops, ch
if ( fFlops )
for ( i = 0; i < Abc_NtkLatchNum(pNtk); i++ )
{
k = rand() % Abc_NtkLatchNum(pNtk);
// swap indexes
Entry = Vec_IntEntry( vFlops, i );
Vec_IntWriteEntry( vFlops, i, Vec_IntEntry(vFlops, k) );
Vec_IntWriteEntry( vFlops, k, Entry );
// swap flops
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vBoxes, i );
Vec_PtrWriteEntry( pNtk->vBoxes, i, Vec_PtrEntry(pNtk->vBoxes, k) );
Vec_PtrWriteEntry( pNtk->vBoxes, k, pTemp );
// swap CIs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+i );
Vec_PtrWriteEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+i, Vec_PtrEntry(pNtk->vCis, Abc_NtkPiNum(pNtk)+k) );
Vec_PtrWriteEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+k, pTemp );
// swap COs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+i );
Vec_PtrWriteEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+i, Vec_PtrEntry(pNtk->vCos, Abc_NtkPoNum(pNtk)+k) );
Vec_PtrWriteEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+k, pTemp );
if ( pFlopPermFile )
{
k = Vec_IntEntry( vFlops, i );
pTemp = (Abc_Obj_t *)Vec_PtrEntry( vFfs, k );
Vec_PtrWriteEntry( pNtk->vBoxes, i, pTemp );
pTemp = (Abc_Obj_t *)Vec_PtrEntry( vCis, Abc_NtkPiNum(pNtk)+k );
Vec_PtrWriteEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+i, pTemp );
pTemp = (Abc_Obj_t *)Vec_PtrEntry( vCos, Abc_NtkPoNum(pNtk)+k );
Vec_PtrWriteEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+i, pTemp );
}
else
{
k = rand() % Abc_NtkLatchNum(pNtk);
// swap indexes
Entry = Vec_IntEntry( vFlops, i );
Vec_IntWriteEntry( vFlops, i, Vec_IntEntry(vFlops, k) );
Vec_IntWriteEntry( vFlops, k, Entry );
// swap flops
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vBoxes, i );
Vec_PtrWriteEntry( pNtk->vBoxes, i, Vec_PtrEntry(pNtk->vBoxes, k) );
Vec_PtrWriteEntry( pNtk->vBoxes, k, pTemp );
// swap CIs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+i );
Vec_PtrWriteEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+i, Vec_PtrEntry(pNtk->vCis, Abc_NtkPiNum(pNtk)+k) );
Vec_PtrWriteEntry( pNtk->vCis, Abc_NtkPiNum(pNtk)+k, pTemp );
// swap COs
pTemp = (Abc_Obj_t *)Vec_PtrEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+i );
Vec_PtrWriteEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+i, Vec_PtrEntry(pNtk->vCos, Abc_NtkPoNum(pNtk)+k) );
Vec_PtrWriteEntry( pNtk->vCos, Abc_NtkPoNum(pNtk)+k, pTemp );
}
//printf( "Swapping flops %d and %d.\n", i, k );
}
Vec_PtrFree(vCis);
Vec_PtrFree(vCos);
Vec_PtrFree(vFfs);
// invert arrays
vInputs = Vec_IntInvert( vTemp = vInputs, -1 );
Vec_IntFree( vTemp );
@ -2408,4 +2702,3 @@ Abc_Ntk_t * Abc_NtkCreateFromGias( char * pName, Vec_Ptr_t * vGias, Gia_Man_t *
ABC_NAMESPACE_IMPL_END

View File

@ -241,7 +241,7 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax )
// add the root node to the cone (for visualization)
Vec_PtrPush( vCutSmall, pNode );
// write the DOT file
Io_WriteDotNtk( pNode->pNtk, vInside, vCutSmall, FileNameDot, 0, 0 );
Io_WriteDotNtk( pNode->pNtk, vInside, vCutSmall, FileNameDot, 0, 0, 0 );
// stop the cut computation manager
Abc_NtkManCutStop( p );
@ -260,7 +260,7 @@ void Abc_NodeShowCut( Abc_Obj_t * pNode, int nNodeSizeMax, int nConeSizeMax )
SeeAlso []
***********************************************************************/
void Abc_NtkShow( Abc_Ntk_t * pNtk0, int fGateNames, int fSeq, int fUseReverse, int fKeepDot )
void Abc_NtkShow( Abc_Ntk_t * pNtk0, int fGateNames, int fSeq, int fUseReverse, int fKeepDot, int fAigIds )
{
FILE * pFile;
Abc_Ntk_t * pNtk;
@ -302,7 +302,7 @@ void Abc_NtkShow( Abc_Ntk_t * pNtk0, int fGateNames, int fSeq, int fUseReverse,
if ( fSeq )
Io_WriteDotSeq( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse );
else
Io_WriteDotNtk( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse );
Io_WriteDotNtk( pNtk, vNodes, NULL, FileNameDot, fGateNames, fUseReverse, fAigIds );
pNtk->nBarBufs = nBarBufs;
Vec_PtrFree( vNodes );

View File

@ -21,6 +21,11 @@
#include "abc.h"
#include "bool/kit/kit.h"
#ifdef _MSC_VER
# include <intrin.h>
# define __builtin_popcount __popcnt
#endif
ABC_NAMESPACE_IMPL_START
@ -1126,6 +1131,8 @@ Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth )
char * pToken = strtok( pCopy, " \r\n\t|" );
while ( pToken )
{
if ( pToken[0] == '0' && pToken[1] == 'x' )
pToken += 2;
if ( !Abc_SopCheckReadTruth( vRes, pToken, 1 ) )
break;
Vec_PtrPush( vRes, Abc_SopFromTruthHex(pToken) );
@ -1135,6 +1142,31 @@ Vec_Ptr_t * Abc_SopFromTruthsHex( char * pTruth )
return vRes;
}
Vec_Ptr_t * Abc_SopGenerateCounters( int nVars )
{
int m, i, o, nOuts = Abc_Base2Log( nVars + 1 );
Vec_Ptr_t * vRes = Vec_PtrAlloc( nOuts );
for ( o = 0; o < nOuts; o++ )
{
Vec_Str_t * vStr = Vec_StrAlloc( 1000 );
for ( m = 0; m < (1 << nVars); m++ ) {
int nOnes = __builtin_popcount(m);
if ( !((nOnes >> o) & 1) )
continue;
for ( i = 0; i < nVars; i++ )
Vec_StrPush( vStr, ((m >> i) & 1) ? '1' : '0' );
Vec_StrPush( vStr, ' ' );
Vec_StrPush( vStr, '1' );
Vec_StrPush( vStr, '\n' );
}
Vec_StrPush( vStr, '\0' );
//printf( "%s\n", Vec_StrArray(vStr) );
Vec_PtrPush( vRes, Vec_StrReleaseArray(vStr) );
Vec_StrFree( vStr );
}
return vRes;
}
/**Function*************************************************************
Synopsis [Creates one encoder node.]

View File

@ -24,6 +24,7 @@
#include "bool/dec/dec.h"
#include "opt/fxu/fxu.h"
#include "aig/miniaig/ndr.h"
#include "misc/util/utilTruth.h"
#ifdef ABC_USE_CUDD
#include "bdd/extrab/extraBdd.h"
@ -1924,25 +1925,16 @@ void Abc_NtkDetectMatching( Abc_Ntk_t * pNtk )
}
/**Function*************************************************************
Synopsis [Compares the pointers.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_ObjPointerCompare( void ** pp1, void ** pp2 )
{
if ( *pp1 < *pp2 )
return -1;
if ( *pp1 > *pp2 )
return 1;
return 0;
}
/// The legacy `Abc_ObjPointerCompare()` comparator is unused; keep the code here
/// commented to document its previous behavior without exposing a prototype.
// int Abc_ObjPointerCompare( void ** pp1, void ** pp2 )
// {
// if ( *pp1 < *pp2 )
// return -1;
// if ( *pp1 > *pp2 )
// return 1;
// return 0;
// }
/**Function*************************************************************
@ -3352,10 +3344,214 @@ Abc_Ntk_t * Abc_NtkFromArray()
return pNtkNew;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_PrintAT( Vec_Int_t * vRanks )
{
int i, Entry;
Vec_IntForEachEntryReverse( vRanks, Entry, i )
if ( Entry == 0 )
printf( " " );
else
printf( "%4d", Entry );
//printf( "\n" );
}
int Abc_NtkMatchGpcPattern( Vec_Int_t * vRanks, int i, char * pGPC )
{
int k, Cur, Min = ABC_INFINITY;
for ( k = 0; pGPC[k] != ':' && i+k < Vec_IntSize(vRanks); k++ ) {
if ( Abc_TtReadHexDigit(pGPC[k]) == 0 )
continue;
Cur = Vec_IntEntry(vRanks, i+k) / Abc_TtReadHexDigit(pGPC[k]);
if ( Min > Cur )
Min = Cur;
}
return Min;
}
void Abc_NtkUpdateGpcPattern( Vec_Int_t * vRank, int i, char * pGPC, int nGpcs, Vec_Int_t * vRank2, Vec_Int_t * vLevel )
{
int k; char * pOut = strstr(pGPC, ":");
assert( pOut && pOut[0] == ':' );
pOut++;
Vec_IntAddToEntry( vLevel, i, nGpcs );
for ( k = 0; pGPC[k] != ':'; k++ )
Vec_IntAddToEntry( vRank, i+k, -nGpcs * Abc_TtReadHexDigit(pGPC[k]) );
for ( k = 0; pOut[k] != ':'; k++ )
Vec_IntAddToEntry( vRank2, i+k, nGpcs * Abc_TtReadHexDigit(pOut[k]) );
}
int Abc_NtkGetGpcLutCount( char * pGPC )
{
char * pOut = strstr(pGPC, ":");
char * pLut = strstr(pOut+1, ":");
return atoi(pLut+1);
}
static inline int Vec_WecSum( Vec_Wec_t * p )
{
Vec_Int_t * vVec;
int i, Counter = 0;
Vec_WecForEachLevel( p, vVec, i )
Counter += Vec_IntSum(vVec);
return Counter;
}
char ** Abc_NtkTransformGPCs( char ** pGPCs, int nGPCs )
{
char * pOut, * pLut, ** pRes = ABC_ALLOC( char *, nGPCs );
int i, k, nLength;
for ( i = 0; i < nGPCs; i++ ) {
pRes[i] = Abc_UtilStrsav(pGPCs[i]);
pOut = strstr(pRes[i], ":");
nLength = (int)(pOut-pRes[i]);
for ( k = 0; k < nLength/2; k++ )
ABC_SWAP( char, pRes[i][k], pRes[i][nLength-1-k] )
pLut = strstr(pOut+1, ":");
nLength = (int)(pLut-pOut-1);
for ( k = 0; k < nLength/2; k++ )
ABC_SWAP( char, pOut[1+k], pOut[1+nLength-1-k] )
}
return pRes;
}
int Abc_NtkCheckGpc( char * pGPC, char * pGPC0 )
{
int RetValue = 0, k, Sum[2] = {0};
char * pOut = strstr(pGPC, ":");
for ( k = 0; pGPC[k] != ':'; k++ )
Sum[0] += (1 << k) * Abc_TtReadHexDigit(pGPC[k]);
for ( k = 0; pOut[1+k] != ':'; k++ )
Sum[1] += (1 << k) * Abc_TtReadHexDigit(pOut[1+k]);
//printf( "GPC %s has input sum %d and output sum %d\n", pGPC0, Sum[0], Sum[1] );
if ( Sum[0]+1 > (1 << Abc_Base2Log(Sum[1]+1)) )
printf( "The largest value of GPC inputs (%d) exceeds the capacity of outputs (%d) for GPC %s.\n", Sum[0], Sum[1], pGPC0 );
else if ( Sum[1]+1 > (1 << Abc_Base2Log(Sum[0]+1)) )
printf( "The largest value of GPC outputs (%d) exceeds the capacity of inputs (%d) for GPC %s.\n", Sum[1], Sum[0], pGPC0 );
else
RetValue = 1;
return RetValue;
}
void Abc_NtkATMap( int nXVars, int nYVars, int nAdder, char ** pGPCs0, int nGPCs, int fReturn, int fVerbose )
{
abctime clkStart = Abc_Clock();
char ** pGPCs = Abc_NtkTransformGPCs(pGPCs0, nGPCs);
int i, nGPCluts[100] = {0};
for ( i = 0; i < nGPCs; i++ )
if ( !Abc_NtkCheckGpc(pGPCs[i], pGPCs0[i]) )
return;
for ( i = 0; i < nGPCs; i++ )
nGPCluts[i] = Abc_NtkGetGpcLutCount(pGPCs[i]);
int x, n, Entry, iLevel = 0, Sum = 0, nGpcs = 0, nBits, fFinished, nRcaLuts = 0, nLuts = 0;
for ( x = 0; x < nXVars; x++ )
Sum += (1 << x) * nYVars;
nBits = Abc_Base2Log( Sum+1 );
printf( "Rectangular adder tree (X=%d Y=%d Sum=%d Out=%d) mapped with", nXVars, nYVars, Sum, nBits );
for ( i = 0; i < nGPCs; i++ )
printf( " GPC%d=%s", i, pGPCs0[i] );
printf( "\n" );
Vec_Int_t * vLevel;
Vec_Int_t * vRank[3] = { Vec_IntAlloc(100), Vec_IntAlloc(100), Vec_IntAlloc(100) };
Vec_Wec_t ** vGPCs = ABC_ALLOC( Vec_Wec_t *, nGPCs );
for ( i = 0; i < nGPCs; i++ )
vGPCs[i] = Vec_WecAlloc(100);
Vec_IntFill( vRank[0], nBits, 0 );
for ( x = 0; x < nXVars; x++ )
Vec_IntAddToEntry( vRank[0], x, nYVars );
if ( fVerbose ) {
printf( "Ranks: " );
for ( i = nBits-1; i >= 0; i-- )
printf( "%4d", i );
printf( " : " );
for ( i = nBits-1; i >= 0; i-- )
printf( "%4d", i );
printf( " LUT6\n" );
}
for ( n = 0; n < nGPCs; n++ )
for ( i = 0, fFinished = 0; !fFinished; i++ )
{
int fAdded = 0;
vLevel = Vec_WecPushLevel( vGPCs[n] );
Vec_IntFill( vLevel, nBits, 0 );
Vec_IntFill( vRank[1], nBits, 0 );
Vec_IntClear( vRank[2] );
Vec_IntAppend( vRank[2], vRank[0] );
fFinished = 1;
if ( Vec_IntFindMax(vRank[0]) > nAdder ) {
for ( x = 0; x < nBits; x++ )
if ( (nGpcs = Abc_NtkMatchGpcPattern(vRank[0], x, pGPCs[n])) )
Abc_NtkUpdateGpcPattern(vRank[0], x, pGPCs[n], nGpcs, vRank[1], vLevel), fFinished = 0, fAdded = 1;
nLuts += Vec_IntSum(vLevel) * nGPCluts[n];
Vec_IntForEachEntry( vRank[1], Entry, x )
Vec_IntAddToEntry( vRank[0], x, Entry );
}
if ( fVerbose && (fAdded || Vec_IntFindMax(vRank[2]) <= nAdder ) ) {
printf( "Lev%02d: ", iLevel++ );
Abc_PrintAT( vRank[2] );
if ( fAdded ) {
printf( " GPC%d: ", n );
Abc_PrintAT( vLevel );
printf( " %4d", Vec_IntSum(vLevel) * nGPCluts[n] );
}
else if ( Vec_IntFindMax(vRank[2]) <= nAdder ) {
printf( " ADD%d: ", nAdder );
for ( x = 0; x < nBits; x++ )
if ( Vec_IntEntry(vRank[2], x) > 1 )
break;
for ( i = nBits-1; i >= x; i-- )
printf( "%4d", 1 );
for ( ; i >= 0; i-- )
printf( " " );
printf( " %4d", (nBits-x)*(nAdder == 4 ? 2 : 1) );
}
printf( "\n" );
}
if ( fAdded ) {
if ( fReturn ) {
fFinished = 1;
n = -1;
}
}
else if ( Vec_IntFindMax(vRank[2]) <= nAdder ) {
fFinished = 1;
n = nGPCs;
}
}
if ( Vec_IntFindMax(vRank[0]) > nAdder )
printf( "Synthesis of the adder tree is incomplete. Try using the full adder \"3:11:1\" as the last GPC.\n" );
else if ( fVerbose && Vec_IntFindMax(vRank[0]) <= nAdder ) {
printf( "Lev%02d: ", iLevel++ );
for ( i = nBits-1; i >= 0; i-- )
printf( "%4d", 1 );
printf( "\n" );
}
printf( "Statistics: " );
for ( n = 0; n < nGPCs; n++ )
printf( "GPC%d = %d. ", n, Vec_WecSum(vGPCs[n]) );
for ( x = 0; x < nBits; x++ )
if ( Vec_IntEntry(vRank[0], x) > 1 )
break;
nRcaLuts = (nBits-x)*(nAdder == 4 ? 2 : 1);
printf( "ADD%d = %d. ", nAdder, nRcaLuts );
printf( "Total LUT count = %d. ", nLuts+nRcaLuts );
for ( i = 0; i < 3; i++ )
Vec_IntFree( vRank[i] );
for ( i = 0; i < nGPCs; i++ )
Vec_WecFree( vGPCs[i] );
ABC_FREE( vGPCs );
for ( i = 0; i < nGPCs; i++ )
ABC_FREE( pGPCs[i] );
ABC_FREE( pGPCs );
Abc_PrintTime( 0, "Total time", Abc_Clock() - clkStart );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
ABC_NAMESPACE_IMPL_END

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -18,6 +18,9 @@
***********************************************************************/
//#include <dirent.h>
//#include <sys/stat.h>
#include "base/abc/abc.h"
#include "base/main/main.h"
#include "aig/gia/giaAig.h"
@ -35,7 +38,9 @@
#include "opt/csw/csw.h"
#include "proof/pdr/pdr.h"
#include "sat/bmc/bmc.h"
#include "misc/util/utilTruth.h"
#include "map/mio/mio.h"
#include "misc/vec/vecMem.h"
ABC_NAMESPACE_IMPL_START
@ -658,6 +663,45 @@ Abc_Ntk_t * Abc_NtkFromAigPhase( Aig_Man_t * pMan )
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Aig_Man_t * Dar_ManResub( Aig_Man_t * pMan, int nCutsMax, int nNodesMax, int fUpdateLevel, int fUseZeros, int fVerbose )
{
extern int Abc_NtkResubstitute( Abc_Ntk_t * pNtk, int nCutMax, int nStepsMax, int nMinSaved, int nLevelsOdc, int fUpdateLevel, int fVerbose, int fVeryVerbose, int Log2Probs, int Log2Divs );
Abc_Ntk_t * pNtk = Abc_NtkFromAigPhase( pMan );
Aig_Man_t * pRes = NULL;
char * pName = NULL, * pSpec = NULL;
int nMinSaved = fUseZeros ? 0 : 1;
if ( pMan->pName )
pName = Abc_UtilStrsav( pMan->pName );
if ( pMan->pSpec )
pSpec = Abc_UtilStrsav( pMan->pSpec );
if ( pName )
{
ABC_FREE( pNtk->pName );
pNtk->pName = pName;
}
if ( pSpec )
{
ABC_FREE( pNtk->pSpec );
pNtk->pSpec = pSpec;
}
if ( !Abc_NtkResubstitute( pNtk, nCutsMax, nNodesMax, nMinSaved, 0, fUpdateLevel, fVerbose, 0, 0, 0 ) )
Abc_Print( 0, "Dar_ManResub(): Resubstitution has failed.\n" );
pRes = Abc_NtkToDar( pNtk, 0, 1 );
Abc_NtkDelete( pNtk );
return pRes;
}
/**Function*************************************************************
Synopsis []
@ -714,7 +758,7 @@ Hop_Obj_t * Abc_ObjHopFromGia_rec( Hop_Man_t * pHopMan, Gia_Man_t * p, int Id, V
Vec_PtrWriteEntry( vCopies, Id, gFunc );
return gFunc;
}
Hop_Obj_t * Abc_ObjHopFromGia( Hop_Man_t * pHopMan, Gia_Man_t * p, int GiaId, Vec_Ptr_t * vCopies )
static Hop_Obj_t * Abc_ObjHopFromGia2( Hop_Man_t * pHopMan, Gia_Man_t * p, int GiaId, Vec_Ptr_t * vCopies, Vec_Bit_t * vCompls )
{
int k, iFan;
assert( Gia_ObjIsLut(p, GiaId) );
@ -723,10 +767,107 @@ Hop_Obj_t * Abc_ObjHopFromGia( Hop_Man_t * pHopMan, Gia_Man_t * p, int GiaId, Ve
Gia_LutForEachFanin( p, GiaId, iFan, k )
{
Gia_ObjSetTravIdCurrentId(p, iFan);
Vec_PtrWriteEntry( vCopies, iFan, Hop_IthVar(pHopMan, k) );
Vec_PtrWriteEntry( vCopies, iFan, Hop_NotCond(Hop_IthVar(pHopMan, k), vCompls && Vec_BitEntry(vCompls, iFan)) );
}
return Abc_ObjHopFromGia_rec( pHopMan, p, GiaId, vCopies );
}
Hop_Obj_t * Abc_ObjHopFromGia( Hop_Man_t * pHopMan, Gia_Man_t * p, int GiaId, Vec_Ptr_t * vCopies )
{
return Abc_ObjHopFromGia2( pHopMan, p, GiaId, vCopies, NULL );
}
static int Abc_Tt5HasAndDec( word Truth )
{
int v;
for ( v = 0; v < 5; v++ )
if ( Abc_Tt6Cofactor0(Truth, v) == 0 || Abc_Tt6Cofactor1(Truth, v) == 0 )
return 1;
return 0;
}
static int Abc_Tt5AndDecPolarity( word Truth )
{
if ( Abc_Tt5HasAndDec(Truth) )
return 0;
if ( Abc_Tt5HasAndDec(~Truth) )
return 1;
return -1;
}
static word Abc_Tt5CofactorTo4( word Truth, int iVar, int fCompl )
{
word Result = 0;
int a, k;
for ( a = 0; a < 16; a++ )
{
int iMint = fCompl ? 0 : (1 << iVar);
for ( k = 0; k < 4; k++ )
if ( (a >> k) & 1 )
iMint |= 1 << (k < iVar ? k : k + 1);
if ( (Truth >> iMint) & 1 )
Result |= ((word)1) << a;
}
return Result;
}
static int Abc_Tt5FindAndDec( word Truth, int * piVar, int * pfCompl, word * pTruth4 )
{
int v;
for ( v = 0; v < 5; v++ )
{
if ( Abc_Tt6Cofactor0(Truth, v) == 0 )
{
*piVar = v;
*pfCompl = 0;
*pTruth4 = Abc_Tt5CofactorTo4( Truth, v, 0 );
return 1;
}
if ( Abc_Tt6Cofactor1(Truth, v) == 0 )
{
*piVar = v;
*pfCompl = 1;
*pTruth4 = Abc_Tt5CofactorTo4( Truth, v, 1 );
return 1;
}
}
return 0;
}
static void Abc_NtkFromMappedGiaPrint5Decs( Abc_Ntk_t * pNtk )
{
Hop_Man_t * pHopMan;
Abc_Obj_t * pObj;
Vec_Int_t * vTruth;
int i, nNodes5 = 0, nNodesOver5 = 0;
assert( Abc_NtkIsLogic(pNtk) && Abc_NtkHasAig(pNtk) );
Abc_NtkForEachNode( pNtk, pObj, i )
{
nNodes5 += Abc_ObjFaninNum(pObj) == 5;
nNodesOver5 += Abc_ObjFaninNum(pObj) > 5;
}
if ( nNodes5 == 0 || nNodesOver5 > 0 )
return;
pHopMan = (Hop_Man_t *)pNtk->pManFunc;
vTruth = Vec_IntAlloc( 64 );
Abc_Print( 1, "Top-level AND decompositions of 5-input nodes:\n" );
Abc_NtkForEachNode( pNtk, pObj, i )
{
word Truth, Truth4;
int iVar, fCompl;
if ( Abc_ObjFaninNum(pObj) != 5 )
continue;
Truth = (word)*Hop_ManConvertAigToTruth( pHopMan, (Hop_Obj_t *)pObj->pData, 5, vTruth, 0 );
if ( !Abc_Tt5FindAndDec( Truth, &iVar, &fCompl, &Truth4 ) )
{
Abc_Print( 1, "%05d : ", Abc_ObjId(pObj) );
Abc_TtPrintHexRev( stdout, &Truth, 5 );
Abc_Print( 1, " = <none>\n" );
continue;
}
Abc_Print( 1, "%05d : ", Abc_ObjId(pObj) );
Abc_TtPrintHexRev( stdout, &Truth, 5 );
Abc_Print( 1, " = %cx%d & ", fCompl ? '~' : ' ', iVar );
Abc_TtPrintHexRev( stdout, &Truth4, 4 );
Abc_Print( 1, "\n" );
}
Vec_IntFree( vTruth );
}
/**Function*************************************************************
@ -761,14 +902,14 @@ Abc_Obj_t * Abc_NtkFromMappedGia_rec( Abc_Ntk_t * pNtkNew, Gia_Man_t * p, int iO
pObjNew = Abc_NtkCreateNodeInv(pNtkNew, pObjNew);
return pObjNew;
}
Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs )
Abc_Ntk_t * Abc_NtkFromMappedGiaInt( Gia_Man_t * p, int fFindEnables, int fUseBuffs, int fCheckAnd5, int fVerbose )
{
int fVerbose = 0;
int fDuplicate = 0;
Abc_Ntk_t * pNtkNew;
Abc_Obj_t * pObjNew, * pObjNewLi, * pObjNewLo, * pConst0 = NULL;
Gia_Obj_t * pObj, * pObjLi, * pObjLo;
Vec_Ptr_t * vReflect;
Vec_Bit_t * vCompls = NULL;
int i, k, iFan, nDupGates, nCountMux = 0;
assert( Gia_ManHasMapping(p) || p->pMuxes || fFindEnables );
assert( !fFindEnables || !p->pMuxes );
@ -777,6 +918,8 @@ Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs
pNtkNew->pName = Extra_UtilStrsav(p->pName);
pNtkNew->pSpec = Extra_UtilStrsav(p->pSpec);
Gia_ManFillValue( p );
if ( fCheckAnd5 )
vCompls = Vec_BitStart( Gia_ManObjNum(p) );
// create constant
pConst0 = Abc_NtkCreateNodeConst0( pNtkNew );
Gia_ManConst0(p)->Value = Abc_ObjId(pConst0);
@ -874,6 +1017,7 @@ Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs
vReflect = Vec_PtrStart( Gia_ManObjNum(p) );
Gia_ManForEachLut( p, i )
{
Hop_Obj_t * pFunc;
pObj = Gia_ManObj(p, i);
assert( pObj->Value == ~0 );
if ( Gia_ObjLutSize(p, i) == 0 )
@ -881,10 +1025,36 @@ Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs
pObj->Value = Abc_ObjId(pConst0);
continue;
}
pFunc = Abc_ObjHopFromGia2( (Hop_Man_t *)pNtkNew->pManFunc, p, i, vReflect, vCompls );
if ( fCheckAnd5 && Gia_ObjLutSize(p, i) == 5 )
{
word Truth = Hop_ManComputeTruth6( (Hop_Man_t *)pNtkNew->pManFunc, pFunc, 5 );
int fCompl = Abc_Tt5AndDecPolarity( Truth );
if ( fCompl < 0 )
{
Abc_Print( -1, "Abc_NtkFromMappedGia(): 5-input node %d does not have AND-decomposition in either polarity.\n", i );
Vec_PtrFree( vReflect );
Vec_BitFreeP( &vCompls );
Abc_NtkDelete( pNtkNew );
return NULL;
}
pFunc = Hop_NotCond( pFunc, fCompl );
Truth = fCompl ? ~Truth : Truth;
assert( Abc_Tt5HasAndDec(Truth) );
if ( !Abc_Tt5HasAndDec(Truth) )
{
Abc_Print( -1, "Abc_NtkFromMappedGia(): Internal error: 5-input node %d failed AND-decomposition check.\n", i );
Vec_PtrFree( vReflect );
Vec_BitFreeP( &vCompls );
Abc_NtkDelete( pNtkNew );
return NULL;
}
Vec_BitWriteEntry( vCompls, i, fCompl );
}
pObjNew = Abc_NtkCreateNode( pNtkNew );
Gia_LutForEachFanin( p, i, iFan, k )
Abc_ObjAddFanin( pObjNew, Abc_NtkObj(pNtkNew, Gia_ObjValue(Gia_ManObj(p, iFan))) );
pObjNew->pData = Abc_ObjHopFromGia( (Hop_Man_t *)pNtkNew->pManFunc, p, i, vReflect );
pObjNew->pData = pFunc;
pObjNew->fPersist = Gia_ObjLutIsMux(p, i) && Gia_ObjLutSize(p, i) == 3;
pObj->Value = Abc_ObjId( pObjNew );
}
@ -896,8 +1066,12 @@ Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs
if ( !fFindEnables )
Gia_ManForEachCo( p, pObj, i )
{
int iFanin = Gia_ObjFaninId0p(p, pObj);
int fCompl = Gia_ObjFaninC0(pObj) ^ (vCompls && Vec_BitEntry(vCompls, iFanin));
pObjNew = Abc_NtkObj( pNtkNew, Gia_ObjValue(Gia_ObjFanin0(pObj)) );
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), Abc_ObjNotCond( pObjNew, Gia_ObjFaninC0(pObj) ) );
if ( fCheckAnd5 && fCompl && Gia_ObjIsLut(p, iFanin) && Gia_ObjLutSize(p, iFanin) == 5 )
pObjNew = Abc_NtkCreateNodeInv( pNtkNew, pObjNew ), fCompl = 0;
Abc_ObjAddFanin( Abc_NtkCo(pNtkNew, i), Abc_ObjNotCond( pObjNew, fCompl ) );
}
// create names
Abc_NtkAddDummyPiNames( pNtkNew );
@ -924,8 +1098,23 @@ Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs
// check the resulting AIG
if ( !Abc_NtkCheck( pNtkNew ) )
Abc_Print( 1, "Abc_NtkFromMappedGia(): Network check has failed.\n" );
if ( fVerbose && Gia_ManHasMapping(p) )
Abc_NtkFromMappedGiaPrint5Decs( pNtkNew );
Vec_BitFreeP( &vCompls );
return pNtkNew;
}
Abc_Ntk_t * Abc_NtkFromMappedGia2( Gia_Man_t * p, int fFindEnables, int fUseBuffs, int fCheckAnd5, int fVerbose )
{
return Abc_NtkFromMappedGiaInt( p, fFindEnables, fUseBuffs, fCheckAnd5, fVerbose );
}
Abc_Ntk_t * Abc_NtkFromMappedGia( Gia_Man_t * p, int fFindEnables, int fUseBuffs )
{
return Abc_NtkFromMappedGiaInt( p, fFindEnables, fUseBuffs, 0, 0 );
}
Abc_Ntk_t * Abc_NtkFromMappedGiaAnd5( Gia_Man_t * p, int fFindEnables, int fUseBuffs )
{
return Abc_NtkFromMappedGiaInt( p, fFindEnables, fUseBuffs, 1, 0 );
}
/**Function*************************************************************
@ -1221,6 +1410,8 @@ Abc_Ntk_t * Abc_NtkFromDarChoices( Abc_Ntk_t * pNtkOld, Aig_Man_t * pMan )
Aig_ManForEachNode( pMan, pObj, i )
{
pObj->pData = Abc_AigAnd( (Abc_Aig_t *)pNtkNew->pManFunc, (Abc_Obj_t *)Aig_ObjChild0Copy(pObj), (Abc_Obj_t *)Aig_ObjChild1Copy(pObj) );
}
Aig_ManForEachNode( pMan, pObj, i ) {
if ( (pTemp = Aig_ObjEquiv(pMan, pObj)) )
{
assert( pTemp->pData != NULL );
@ -4900,10 +5091,278 @@ Abc_Ntk_t * Abc_NtkDarTestNtk( Abc_Ntk_t * pNtk )
}
#if 0
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Data_ListDirsFilesCompareNames( char ** pp1, char ** pp2 )
{
return strcmp( *pp1, *pp2 );
}
char ** Data_ListDirsFiles(const char *path, const char *ext)
{
int iItems = 0, nItems = 1000;
char ** pRes = (char **)calloc( sizeof(char*), nItems );
DIR *dir;
struct dirent *entry;
struct stat statbuf;
// Open the directory
if ((dir = opendir(path)) == NULL) {
perror("opendir");
return NULL;
}
// Read each entry in the directory
while ((entry = readdir(dir)) != NULL) {
char full_path[1024];
snprintf(full_path, sizeof(full_path), "%s/%s", path, entry->d_name);
// Get the status of the entry
if (stat(full_path, &statbuf) == -1) {
perror("stat");
continue;
}
if (ext == NULL) {
// If no file extension is provided, list subdirectories
if (S_ISDIR(statbuf.st_mode)) {
// Skip "." and ".." directories
if (strcmp(entry->d_name, ".") == 0 || strcmp(entry->d_name, "..") == 0) {
continue;
}
// Print the directory name
//printf("%s\n", entry->d_name);
assert( iItems < nItems );
pRes[iItems] = (char *)calloc( sizeof(char), strlen(entry->d_name)+1 );
memcpy( pRes[iItems++], entry->d_name, strlen(entry->d_name) );
}
} else {
// If file extension is provided, list files with that extension
if (S_ISREG(statbuf.st_mode)) { // Check if it's a regular file
const char *dot = strrchr(entry->d_name, '.');
if (dot && strcmp(dot + 1, ext) == 0) {
// Print the file name
//printf("%s\n", entry->d_name);
assert( iItems <= nItems );
if ( iItems == nItems ) {
pRes = ABC_REALLOC( char *, pRes, nItems *= 2 );
memset( pRes + nItems/2, 0, sizeof(char *) * nItems/2 );
}
pRes[iItems] = (char *)calloc( sizeof(char), strlen(entry->d_name)+1 );
memcpy( pRes[iItems++], entry->d_name, strlen(entry->d_name) );
}
}
}
}
qsort( (void *)pRes, (size_t)iItems, sizeof(char *), (int (*)(const void *, const void *)) Data_ListDirsFilesCompareNames );
// Close the directory
closedir(dir);
if ( iItems == 0 )
ABC_FREE( pRes );
return pRes;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Gia_ManDeriveNodeClasses( Gia_Man_t * p, Vec_Wrd_t * vSims )
{
abctime clkStart = Abc_Clock();
int nVars = Gia_ManCiNum(p);
int nWords = Abc_Truth6WordNum( nVars );
Vec_Mem_t * vTtMem = Vec_MemAllocForTTSimple( nVars );
Vec_Int_t * vRes = Vec_IntStartFull( Gia_ManObjNum(p) );
Gia_Obj_t * pObj; int i;
for ( i = 0; i <= nVars; i++ ) {
int iFunc = Vec_MemHashInsert( vTtMem, Vec_WrdEntryP(vSims, i*nWords) );
assert( iFunc == i );
Vec_IntWriteEntry( vRes, i, i );
}
Gia_ManForEachAnd( p, pObj, i )
{
word * pTruth = Vec_WrdEntryP( vSims, i*nWords );
if ( pTruth[0] & 1 )
for ( int k = 0; k < nWords; k++ )
pTruth[k] = ~pTruth[k];
int iFunc = Vec_MemHashInsert(vTtMem, pTruth);
//assert( iFunc > nVars );
Vec_IntWriteEntry( vRes, i, iFunc );
}
printf( "Detected %d unique functions among %d nodes. ", Vec_MemEntryNum(vTtMem) - nVars - 1, Gia_ManAndNum(p) );
Abc_PrintTime( 1, "Time", Abc_Clock() - clkStart );
Vec_MemFree( vTtMem );
return vRes;
}
int Gia_ManExploreNode_rec( Gia_Man_t * p, int Obj, int Repr, Vec_Int_t * vFuncs )
{
if ( Obj == Repr || Vec_IntEntry(vFuncs, Obj) == -1 )
return 0;
if ( Obj < Repr )
return 1;
if ( Gia_ObjIsTravIdCurrentId(p, Obj) )
return 1;
Gia_ObjSetTravIdCurrentId(p, Obj);
Gia_Obj_t * pObj = Gia_ManObj(p, Obj);
if ( !Gia_ManExploreNode_rec( p, Gia_ObjFaninId0(pObj, Obj), Repr, vFuncs ) )
return 0;
if ( !Gia_ManExploreNode_rec( p, Gia_ObjFaninId1(pObj, Obj), Repr, vFuncs ) )
return 0;
if ( Vec_IntEntry(vFuncs, Obj) != Obj ) {
if ( !Gia_ManExploreNode_rec( p, Vec_IntEntry(vFuncs, Obj), Repr, vFuncs ) )
return 0;
}
return 1;
}
int Gia_ManChoiceCheck( Gia_Man_t * p, Gia_Obj_t * pObj, int i, Vec_Int_t * vFuncs )
{
if ( Vec_IntEntry(vFuncs, Gia_ObjFaninId0p(p, pObj)) == -1 || Vec_IntEntry(vFuncs, Gia_ObjFaninId1p(p, pObj)) == -1 )
return 0;
if ( i == Vec_IntEntry(vFuncs, i) )
return 1;
assert( i > Vec_IntEntry(vFuncs, i) );
Gia_ManIncrementTravId( p );
if ( !Gia_ManExploreNode_rec(p, i, Vec_IntEntry(vFuncs, i), vFuncs) )
return 0;
return 1;
}
void Gia_ManChoicesClean( Gia_Man_t * p, Vec_Int_t * vFuncs )
{
Gia_Obj_t * pObj; int i;
Gia_ManForEachAnd( p, pObj, i )
if ( Vec_IntEntry(vFuncs, i) <= Gia_ManCiNum(p) || !Gia_ManChoiceCheck(p, pObj, i, vFuncs) )
Vec_IntWriteEntry( vFuncs, i, -1 );
}
Gia_Man_t * Gia_ManTransformToChoices( Gia_Man_t * p )
{
Vec_Wrd_t * Gia_ManDeriveNodeFuncs( Gia_Man_t * p );
Vec_Wrd_t * vSims = Gia_ManDeriveNodeFuncs( p );
Vec_Int_t * vFuncs = Gia_ManDeriveNodeClasses( p, vSims );
Gia_ManChoicesClean( p, vFuncs );
Vec_WrdFree( vSims );
Gia_Man_t * pNew = Gia_ManStart( Gia_ManObjNum(p) );
pNew->pName = Abc_UtilStrsav( p->pName );
pNew->pSibls = ABC_CALLOC( int, Gia_ManObjNum(p) );
Gia_ManHashAlloc( pNew );
Gia_Obj_t * pObj; int i;
Gia_ManSetPhase(p);
Gia_ManConst0(p)->Value = 0;
Gia_ManForEachCi( p, pObj, i )
pObj->Value = Gia_ManAppendCi( pNew );
Gia_ManForEachAnd( p, pObj, i ) {
if ( Vec_IntEntry(vFuncs, i) == -1 )
continue;
else if ( Vec_IntEntry(vFuncs, i) == i )
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
else {
int iFunc = Vec_IntEntry(vFuncs, i);
pNew->pSibls[i] = pNew->pSibls[iFunc];
pNew->pSibls[iFunc] = i;
pObj->Value = Abc_Var2Lit( iFunc, pObj->fPhase ^ Gia_ManObj(p, iFunc)->fPhase );
//printf( "Adding choice %d -> %d\n", iFunc, i );
}
}
Gia_ManForEachCo( p, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Vec_IntFree( vFuncs );
return pNew;
}
void Gia_ManTestAppend( Gia_Man_t * pNew, Gia_Man_t * pTwo )
{
Gia_Obj_t * pObj; int i;
assert( Gia_ManCiNum(pNew) == Gia_ManCiNum(pTwo) );
Gia_ManConst0(pTwo)->Value = 0;
Gia_ManForEachCand( pTwo, pObj, i )
{
if ( Gia_ObjIsAnd(pObj) )
pObj->Value = Gia_ManHashAnd( pNew, Gia_ObjFanin0Copy(pObj), Gia_ObjFanin1Copy(pObj) );
else if ( Gia_ObjIsCi(pObj) )
pObj->Value = Gia_Obj2Lit( pNew, Gia_ManCi( pNew, Gia_ObjCioId(pObj) ) );
}
}
Gia_Man_t * Abc_NtkDarTestFiles()
{
char full_path[1024];
const char *directory_path = "temp";
const char *ext = "aig";
char ** pItems = Data_ListDirsFiles(directory_path, ext);
if ( pItems == NULL ) {
printf( "There are no files in directory \"%s\".\n", directory_path );
return NULL;
}
//for ( i = 0; pItems[i]; i++ )
// printf( "%d : %s\n", i, pItems[i] );
Gia_Obj_t * pObj; int i;
Gia_Man_t * pNew = NULL;
Gia_Man_t * pTemp = NULL;
for ( i = 0; pItems[i]; i++ )
{
snprintf(full_path, sizeof(full_path), "%s/%s", directory_path, pItems[i]);
Gia_Man_t * pTwo = Gia_AigerRead( full_path, 0, 0, 0 );
if ( i == 0 ) {
pNew = Gia_ManStart( 10000 );
pNew->pName = Abc_UtilStrsav( pTwo->pName );
pNew->pSpec = Abc_UtilStrsav( pTwo->pSpec );
for ( int k = 0; k < Gia_ManCiNum(pTwo); k++ )
Gia_ManAppendCi( pNew );
}
Gia_ManTestAppend( pNew, pTwo );
if ( i == 0 )
pTemp = pTwo;
else
Gia_ManStop( pTwo );
if ( i < 4 )
printf( "%d : %s\n", i, pItems[i] );
}
printf( "Finished reading %d files.\n", i );
Gia_ManForEachCo( pTemp, pObj, i )
Gia_ManAppendCo( pNew, Gia_ObjFanin0Copy(pObj) );
Gia_ManStop( pTemp );
Gia_ManPrintStats( pNew, NULL );
pNew = Gia_ManTransformToChoices( pTemp = pNew );
Gia_ManStop( pTemp );
Gia_ManPrintStats( pNew, NULL );
for ( i = 0; pItems[i]; i++ )
free( pItems[i] );
free( pItems );
//Gia_AigerWrite( pNew, "all.aig", 0, 0, 0 );
//Gia_ManStop( pNew );
return pNew;
}
#endif
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////
#include "abcDarUnfold2.c"
ABC_NAMESPACE_IMPL_END

View File

@ -458,6 +458,31 @@ void Abc_TtStoreLoadSave( char * pFileName )
printf( "Input file \"%s\" was copied into output file \"%s\".\n", pFileInput, pFileOutput );
}
/**Function*************************************************************
Synopsis [Read truth tables from input file and write them into output file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_TtStoreDump( char * pFileName, Vec_Mem_t * vTtMem, int nBytes )
{
word * pTruth; int i;
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL )
{
printf( "Cannot open file \"%s\" for writing.\n", pFileName );
return;
}
Vec_MemForEachEntry( vTtMem, pTruth, i )
fwrite( pTruth, nBytes, 1, pFile );
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Read truth tables in binary text form and write them into file as binary data.]
@ -709,6 +734,38 @@ void Abc_TruthDecTest( char * pFileName, int DecType, int nVarNum, int fVerbose
// printf( "Finished decomposing truth tables from file \"%s\".\n", pFileName );
}
/**Function*************************************************************
Synopsis [Read truth tables from file.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Mem_t * Abc_TruthDecRead( char * pFileName, int nVarNum )
{
Abc_TtStore_t * p; int i;
if ( nVarNum < 6 )
nVarNum = 6;
// allocate data-structure
p = Abc_TtStoreLoad( pFileName, nVarNum );
if ( p == NULL ) return NULL;
// consider functions from the file
Vec_Mem_t * vTtMem = Vec_MemAllocForTTSimple( nVarNum );
for ( i = 0; i < p->nFuncs; i++ )
Vec_MemHashInsert( vTtMem, (word *)p->pFuncs[i] );
// delete data-structure
Abc_TtStoreFree( p, nVarNum );
// printf( "Finished decomposing truth tables from file \"%s\".\n", pFileName );
return vTtMem;
}
/**Function*************************************************************

View File

@ -143,7 +143,7 @@ Abc_Ntk_t * Abc_NtkDsdInternal( Abc_Ntk_t * pNtk, int fVerbose, int fPrint, int
ppNamesCi = Abc_NtkCollectCioNames( pNtk, 0 );
ppNamesCo = Abc_NtkCollectCioNames( pNtk, 1 );
if ( fVerbose )
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1 );
Dsd_TreePrint( stdout, pManDsd, ppNamesCi, ppNamesCo, fShort, -1, 0 );
else
Dsd_TreePrint2( stdout, pManDsd, ppNamesCi, ppNamesCo, -1 );
ABC_FREE( ppNamesCi );

View File

@ -670,13 +670,29 @@ int Abc_NtkFraigStore( Abc_Ntk_t * pNtkAdd )
extern int Abc_NodeCompareCiCo( Abc_Ntk_t * pNtkOld, Abc_Ntk_t * pNtkNew );
if ( !Abc_NodeCompareCiCo(pNtk, (Abc_Ntk_t *)Vec_PtrEntry(vStore, 0)) )
{
// Abc_NtkCompareSignals() sorts the PIs/POs/boxes of both networks by name as a
// side effect, which is what makes the comparison meaningful when the two do use
// the same names. When they do not, the comparison fails, the store is reset and
// this network is kept -- so the sort has to be undone here. Otherwise the stored
// network is a permutation of the one the caller read in, and everything after it
// is off by that permutation with nothing to indicate it.
Vec_Ptr_t * vPis = Vec_PtrDup( pNtk->vPis );
Vec_Ptr_t * vPos = Vec_PtrDup( pNtk->vPos );
Vec_Ptr_t * vBoxes = Vec_PtrDup( pNtk->vBoxes );
// reorder PIs of pNtk2 according to pNtk1
if ( !Abc_NtkCompareSignals( pNtk, (Abc_Ntk_t *)Vec_PtrEntry(vStore, 0), 1, 1 ) )
{
Vec_PtrFree( pNtk->vPis ); pNtk->vPis = vPis; vPis = NULL;
Vec_PtrFree( pNtk->vPos ); pNtk->vPos = vPos; vPos = NULL;
Vec_PtrFree( pNtk->vBoxes ); pNtk->vBoxes = vBoxes; vBoxes = NULL;
Abc_NtkOrderCisCos( pNtk );
printf( "Trying to store the network with different primary inputs.\n" );
printf( "The previously stored networks are deleted and this one is added.\n" );
Abc_NtkFraigStoreClean();
}
if ( vPis ) Vec_PtrFree( vPis );
if ( vPos ) Vec_PtrFree( vPos );
if ( vBoxes ) Vec_PtrFree( vBoxes );
}
}
Vec_PtrPush( vStore, pNtk );

View File

@ -287,8 +287,11 @@ int Abc_NtkFxCheck( Abc_Ntk_t * pNtk )
// Abc_NtkForEachObj( pNtk, pNode, i )
// Abc_ObjPrint( stdout, pNode );
Abc_NtkForEachNode( pNtk, pNode, i )
if ( !Vec_IntCheckUniqueSmall( &pNode->vFanins ) )
if ( !Vec_IntCheckUniqueSmall( &pNode->vFanins ) ) {
printf( "Fanins of node %d: ", i );
Vec_IntPrint( &pNode->vFanins );
return 0;
}
return 1;
}

View File

@ -42,6 +42,32 @@ ABC_NAMESPACE_IMPL_START
SeeAlso []
***********************************************************************/
void Abc_WriteHalfAdder( FILE * pFile )
{
int fNaive = 0;
fprintf( pFile, ".model HA\n" );
fprintf( pFile, ".inputs a b\n" );
fprintf( pFile, ".outputs s cout\n" );
if ( fNaive )
{
fprintf( pFile, ".names a b s\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names a b cout\n" );
fprintf( pFile, "11 1\n" );
}
else
{
fprintf( pFile, ".names a b cout\n" );
fprintf( pFile, "11 1\n" );
fprintf( pFile, ".names a b and1_\n" );
fprintf( pFile, "00 1\n" );
fprintf( pFile, ".names cout and1_ s\n" );
fprintf( pFile, "00 1\n" );
}
fprintf( pFile, ".end\n" );
fprintf( pFile, "\n" );
}
void Abc_WriteFullAdder( FILE * pFile )
{
int fNaive = 0;
@ -50,6 +76,7 @@ void Abc_WriteFullAdder( FILE * pFile )
fprintf( pFile, ".outputs s cout\n" );
if ( fNaive )
{
/*
fprintf( pFile, ".names a b k\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
@ -60,6 +87,19 @@ void Abc_WriteFullAdder( FILE * pFile )
fprintf( pFile, "11- 1\n" );
fprintf( pFile, "1-1 1\n" );
fprintf( pFile, "-11 1\n" );
*/
fprintf( pFile, ".names a b s0\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names a b c0\n" );
fprintf( pFile, "11 1\n" );
fprintf( pFile, ".names s0 cin s\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names s0 cin c1\n" );
fprintf( pFile, "11 1\n" );
fprintf( pFile, ".names c0 c1 cout\n" );
fprintf( pFile, "00 0\n" );
}
else
{
@ -1205,6 +1245,679 @@ void Abc_GenGraph( char * pFileName, int nPis )
ABC_FREE( pTruth );
}
/**Function*************************************************************
Synopsis [Threshold function generation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_GenComp63a4( FILE * pFile )
{
fprintf( pFile, ".model C63a\n" );
fprintf( pFile, ".inputs x0 x1 x2 x3 x4 x5\n" );
fprintf( pFile, ".outputs z0 z1 z2\n" );
fprintf( pFile, ".names x1 x2 x3 x0 n10\n" );
fprintf( pFile, "--00 1\n" );
fprintf( pFile, "-0-0 1\n" );
fprintf( pFile, "0--0 1\n" );
fprintf( pFile, "000- 1\n" );
fprintf( pFile, ".names x4 x5 n13 n10 z0\n" );
fprintf( pFile, "--00 1\n" );
fprintf( pFile, "-1-0 1\n" );
fprintf( pFile, "1--0 1\n" );
fprintf( pFile, "111- 1\n" );
fprintf( pFile, ".names x1 x2 x3 x0 n13\n" );
fprintf( pFile, "-110 1\n" );
fprintf( pFile, "1-10 1\n" );
fprintf( pFile, "11-0 1\n" );
fprintf( pFile, "-001 1\n" );
fprintf( pFile, "0-01 1\n" );
fprintf( pFile, "00-1 1\n" );
fprintf( pFile, ".names x4 x5 n13 n16 z1\n" );
fprintf( pFile, "1-00 1\n" );
fprintf( pFile, "0-10 1\n" );
fprintf( pFile, "-101 1\n" );
fprintf( pFile, "-011 1\n" );
fprintf( pFile, ".names x1 x2 x3 x4 n16\n" );
fprintf( pFile, "1000 1\n" );
fprintf( pFile, "0100 1\n" );
fprintf( pFile, "0010 1\n" );
fprintf( pFile, "1110 1\n" );
fprintf( pFile, "0001 1\n" );
fprintf( pFile, "1101 1\n" );
fprintf( pFile, "1011 1\n" );
fprintf( pFile, "0111 1\n" );
fprintf( pFile, ".names x5 n16 z2\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".end\n\n" );
}
void Abc_GenComp63a6( FILE * pFile )
{
fprintf( pFile, ".model C63a\n" );
fprintf( pFile, ".inputs x0 x1 x2 x3 x4 x5\n" );
fprintf( pFile, ".outputs z0 z1 z2\n" );
fprintf( pFile, ".names x1 x2 x3 x4 x5 x0 z0\n" );
fprintf( pFile, "---111 1\n" );
fprintf( pFile, "--1-11 1\n" );
fprintf( pFile, "--11-1 1\n" );
fprintf( pFile, "-1--11 1\n" );
fprintf( pFile, "-1-1-1 1\n" );
fprintf( pFile, "-11--1 1\n" );
fprintf( pFile, "-1111- 1\n" );
fprintf( pFile, "1---11 1\n" );
fprintf( pFile, "1--1-1 1\n" );
fprintf( pFile, "1-1--1 1\n" );
fprintf( pFile, "1-111- 1\n" );
fprintf( pFile, "11---1 1\n" );
fprintf( pFile, "11-11- 1\n" );
fprintf( pFile, "111-1- 1\n" );
fprintf( pFile, "1111-- 1\n" );
fprintf( pFile, ".names x1 x2 x3 x4 x5 x0 z1\n" );
fprintf( pFile, "-00001 1\n" );
fprintf( pFile, "-00110 1\n" );
fprintf( pFile, "-01010 1\n" );
fprintf( pFile, "-01100 1\n" );
fprintf( pFile, "-10010 1\n" );
fprintf( pFile, "-10100 1\n" );
fprintf( pFile, "-11000 1\n" );
fprintf( pFile, "-11111 1\n" );
fprintf( pFile, "0-0001 1\n" );
fprintf( pFile, "0-0110 1\n" );
fprintf( pFile, "0-1010 1\n" );
fprintf( pFile, "0-1100 1\n" );
fprintf( pFile, "00-001 1\n" );
fprintf( pFile, "00-110 1\n" );
fprintf( pFile, "000-01 1\n" );
fprintf( pFile, "0000-1 1\n" );
fprintf( pFile, "1-0010 1\n" );
fprintf( pFile, "1-0100 1\n" );
fprintf( pFile, "1-1000 1\n" );
fprintf( pFile, "1-1111 1\n" );
fprintf( pFile, "11-000 1\n" );
fprintf( pFile, "11-111 1\n" );
fprintf( pFile, "111-11 1\n" );
fprintf( pFile, "1111-1 1\n" );
fprintf( pFile, ".names x1 x2 x3 x4 x5 z2\n" );
fprintf( pFile, "00001 1\n" );
fprintf( pFile, "00010 1\n" );
fprintf( pFile, "00100 1\n" );
fprintf( pFile, "00111 1\n" );
fprintf( pFile, "01000 1\n" );
fprintf( pFile, "01011 1\n" );
fprintf( pFile, "01101 1\n" );
fprintf( pFile, "01110 1\n" );
fprintf( pFile, "10000 1\n" );
fprintf( pFile, "10011 1\n" );
fprintf( pFile, "10101 1\n" );
fprintf( pFile, "10110 1\n" );
fprintf( pFile, "11001 1\n" );
fprintf( pFile, "11010 1\n" );
fprintf( pFile, "11100 1\n" );
fprintf( pFile, "11111 1\n" );
fprintf( pFile, ".end\n\n" );
}
void Abc_GenAdder4( FILE * pFile, int nBits, int nLutSize )
{
int i, n;
fprintf( pFile, ".model A%02d_4x\n", nBits );
for ( n = 0; n < 4; n++ ) {
fprintf( pFile, ".inputs" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " %c%02d", 'a'+n, i );
fprintf( pFile, "\n" );
}
fprintf( pFile, ".outputs" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " s%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".names v00\n" );
fprintf( pFile, ".names w00\n" );
for ( i = 0; i < nBits; i++ ) {
fprintf( pFile, ".subckt C63a" );
fprintf( pFile, " x0=w%02d", i );
fprintf( pFile, " x1=v%02d", i );
fprintf( pFile, " x2=a%02d", i );
fprintf( pFile, " x3=b%02d", i );
fprintf( pFile, " x4=c%02d", i );
fprintf( pFile, " x5=d%02d", i );
fprintf( pFile, " z0=w%02d", i+1 );
fprintf( pFile, " z1=v%02d", i+1 );
fprintf( pFile, " z2=s%02d", i );
fprintf( pFile, "\n" );
}
fprintf( pFile, ".end\n\n" );
if ( nLutSize == 4 )
Abc_GenComp63a4( pFile );
else if ( nLutSize == 6 )
Abc_GenComp63a6( pFile );
else assert( 0 );
}
void Abc_WriteAdder2( FILE * pFile, int nVars )
{
int i;
assert( nVars > 0 );
fprintf( pFile, ".model A%02d\n", nVars );
fprintf( pFile, ".inputs c\n" );
fprintf( pFile, ".inputs" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " a%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".inputs" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, " b%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".outputs" );
for ( i = 0; i <= nVars; i++ )
fprintf( pFile, " s%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".names c t00\n1 1\n" );
for ( i = 0; i < nVars; i++ )
fprintf( pFile, ".subckt FA a=a%02d b=b%02d cin=t%02d s=s%02d cout=t%02d\n", i, i, i, i, i+1 );
fprintf( pFile, ".names t%02d s%02d\n1 1\n", nVars, nVars );
fprintf( pFile, ".end\n\n" );
Abc_WriteFullAdder( pFile );
}
void Abc_GenAdder4test( FILE * pFile, int nBits )
{
int i, n;
fprintf( pFile, ".model A%02d_4x\n", nBits );
for ( n = 0; n < 4; n++ ) {
fprintf( pFile, ".inputs" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " %c%02d", 'a'+n, i );
fprintf( pFile, "\n" );
}
fprintf( pFile, ".outputs" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " o%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".names zero\n" );
fprintf( pFile, ".subckt A%02d c=zero", nBits );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " a%0d=a%02d", i, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " b%0d=b%02d", i, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i <= nBits; i++ )
fprintf( pFile, " s%0d=t%02d", i, i );
fprintf( pFile, "\n" );
fprintf( pFile, ".subckt A%02d c=zero", nBits );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " a%0d=c%02d", i, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " b%0d=t%02d", i, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i <= nBits; i++ )
fprintf( pFile, " s%0d=u%02d", i, i );
fprintf( pFile, "\n" );
fprintf( pFile, ".subckt A%02d c=zero", nBits );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " a%0d=d%02d", i, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " b%0d=u%02d", i, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i <= nBits; i++ )
fprintf( pFile, " s%0d=o%02d", i, i );
fprintf( pFile, "\n" );
fprintf( pFile, ".end\n\n" );
Abc_WriteAdder( pFile, nBits );
}
void Abc_WriteWeight( FILE * pFile, int Num, int nBits, int Weight )
{
int i;
fprintf( pFile, ".model W%02d\n", Num );
fprintf( pFile, ".inputs i\n" );
fprintf( pFile, ".outputs" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " o%02d", i );
fprintf( pFile, "\n" );
for ( i = 0; i < nBits; i++ )
if ( (Weight >> i) & 1 )
fprintf( pFile, ".names i o%02d\n1 1\n", i );
else
fprintf( pFile, ".names o%02d\n", i );
fprintf( pFile, ".end\n\n" );
}
Vec_Int_t * Abc_GenTreeFindGroups( char * pTree, int iPos )
{
Vec_Int_t * vRes = NULL;
int Counter = 1;
assert( pTree[iPos] == '(' );
while ( pTree[++iPos] ) {
if ( pTree[iPos] == '(' ) {
if ( Counter++ == 1 ) {
if ( vRes == NULL )
vRes = Vec_IntAlloc( 4 );
Vec_IntPush( vRes, iPos );
}
}
if ( pTree[iPos] == ')' )
Counter--;
if ( Counter == 0 )
return vRes;
}
assert( 0 );
return NULL;
}
int Abc_GenTree_rec( FILE * pFile, int nBits, char * pTree, int iPos, int * pSig, int * pUsed )
{
Vec_Int_t * vGroups = Abc_GenTreeFindGroups( pTree, iPos );
if ( vGroups == NULL )
return atoi(pTree+iPos+1);
int i, g, Group;
Vec_IntForEachEntry( vGroups, Group, g ) {
Group = Abc_GenTree_rec( pFile, nBits, pTree, Group, pSig, pUsed );
Vec_IntWriteEntry( vGroups, g, Group );
}
if ( Vec_IntSize(vGroups) == 3 )
Vec_IntPush(vGroups, 0);
if ( Vec_IntSize(vGroups) == 4 )
fprintf( pFile, ".subckt A%02d_4x", nBits ), *pUsed = 1;
else if ( Vec_IntSize(vGroups) == 2 )
fprintf( pFile, ".subckt A%02d c=zero", nBits );
else assert( 0 );
Vec_IntForEachEntry( vGroups, Group, g ) {
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " %c%02d=%02d_%02d", 'a'+g, i, Group, i );
}
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " s%02d=%02d_%02d", i, *pSig, i );
fprintf( pFile, "\n\n" );
return (*pSig)++;
}
void Abc_GenThreshAdder( FILE * pFile, int nBits, int A, int B, int S, int fOne )
{
if ( A > B ) ABC_SWAP( int, A, B ); int i;
fprintf( pFile, ".subckt A%02d c=%s", nBits, fOne ? "one" : "zero" );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " a%02d=%02d_%02d", i, A, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " b%02d=%02d_%02d", i, B, i );
fprintf( pFile, " \\\n" );
for ( i = 0; i <= nBits; i++ )
fprintf( pFile, " s%02d=%02d_%02d", i, S, i );
fprintf( pFile, "\n" );
}
void Abc_GenThresh( char * pFileName, int nBits, Vec_Int_t * vNums, int nLutSize, char * pArch )
{
FILE * pFile = fopen( pFileName, "w" );
int c, i, k, Temp, iPrev = 1, nNums = 1, nSigs = 1, fUsed = 0;
fprintf( pFile, "# %d-bit threshold function with %d variables generated by ABC on %s\n",
nBits, Vec_IntSize(vNums)-1, Extra_TimeStamp() );
fprintf( pFile, "# Weights:" );
Vec_IntForEachEntryStop( vNums, Temp, i, Vec_IntSize(vNums)-1 )
fprintf( pFile, " %d", Temp );
fprintf( pFile, "\n# Threshold: %d\n", Vec_IntEntryLast(vNums) );
fprintf( pFile, ".model TF%d_%d\n", Vec_IntSize(vNums)-1, nBits );
fprintf( pFile, ".inputs" );
for ( i = 0; i < Vec_IntSize(vNums)-1; i++ )
fprintf( pFile, " x%02d", i );
fprintf( pFile, "\n" );
fprintf( pFile, ".outputs F\n" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, ".names %02d_%02d\n", 0, i );
fprintf( pFile, ".names zero\n" );
fprintf( pFile, ".names one\n 1\n" );
Vec_IntForEachEntry( vNums, Temp, k ) {
fprintf( pFile, ".subckt W%02d", k );
if ( k < Vec_IntSize(vNums)-1 )
fprintf( pFile, " i=x%02d", k );
else
fprintf( pFile, " i=one" );
for ( i = 0; i < nBits; i++ )
fprintf( pFile, " o%02d=%02d_%02d", i, nSigs, i );
fprintf( pFile, "\n" );
nSigs++;
}
fprintf( pFile, "\n" );
if ( pArch == NULL )
{
Vec_IntForEachEntryStart( vNums, Temp, k, 1 ) {
Abc_GenThreshAdder( pFile, nBits, iPrev, k+1, nSigs, k == Vec_IntSize(vNums)-1 );
iPrev = nSigs++;
}
fprintf( pFile, ".names %02d_%02d F\n0 1\n", iPrev, nBits-1 );
}
else
{
Vec_Str_t * vArch = Vec_StrAlloc( 100 );
for ( c = 0; c < strlen(pArch); c++ ) {
if ( pArch[c] == '(' || pArch[c] == ')' ) {
Vec_StrPush( vArch, pArch[c] );
continue;
}
Temp = pArch[c] >= '0' && pArch[c] <= '9' ? pArch[c] - '0' : pArch[c] - 'A' + 10;
assert( Temp > 0 );
if ( Temp == 1 ) {
if ( nNums + Temp == Vec_IntSize(vNums) )
Abc_GenThreshAdder( pFile, nBits, nNums, nNums+1, iPrev = nSigs++, 1 );
else
iPrev = nNums++;
}
else {
int kLast = 0;
assert( nNums + Temp <= Vec_IntSize(vNums) );
if ( nNums + Temp == Vec_IntSize(vNums) )
kLast = Temp++;
iPrev = nNums++;
for ( k = 1; k < Temp; k++ ) {
Abc_GenThreshAdder( pFile, nBits, iPrev, nNums++, nSigs, k == kLast );
iPrev = nSigs++;
}
fprintf( pFile, "\n" );
}
Vec_StrPrintF( vArch, "(%d)", iPrev );
}
Vec_StrPush( vArch, '\0' );
Temp = Abc_GenTree_rec( pFile, nBits, Vec_StrArray(vArch), 0, &nSigs, &fUsed );
fprintf( pFile, ".names %02d_%02d F\n0 1\n", Temp, nBits-1 );
Vec_StrFree( vArch );
}
fprintf( pFile, ".end\n\n" );
Vec_IntForEachEntry( vNums, Temp, k )
Abc_WriteWeight( pFile, k, nBits, k == Vec_IntSize(vNums)-1 ? ~Temp : Temp );
Abc_WriteAdder2( pFile, nBits );
if ( fUsed )
Abc_GenAdder4( pFile, nBits, nLutSize == 4 ? 4 : 6 );
fclose( pFile );
}
/**Function*************************************************************
Synopsis [Adder tree generation.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
// Based on the paper: E. Demenkov, A. Kojevnikov, A. Kulikov, and G. Yaroslavtsev,
// "New upper bounds on the Boolean circuit complexity of symmetric functions".
// Information Processing Letters, Vol 110(7), March 2010, Pages 264-267.
// https://grigory.us/files/publications/2010_upper_bounds_symmetric_ipl.pdf
void Abc_WriteMDFA( FILE * pFile )
{
fprintf( pFile, ".model MDFA\n" );
fprintf( pFile, ".inputs z x1 y1 x2 y2\n" );
fprintf( pFile, ".outputs s c1 c2\n" );
fprintf( pFile, ".names x1 z g1\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names y1 g1 g2\n" );
fprintf( pFile, "00 0\n" );
fprintf( pFile, ".names y1 z g3\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names g2 g3 g4\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names x2 g3 g5\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names g3 y2 g6\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names g5 y2 g7\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, ".names g2 g7 g8\n" );
fprintf( pFile, "10 1\n" );
fprintf( pFile, "01 1\n" );
fprintf( pFile, ".names g6 s\n" );
fprintf( pFile, "1 1\n" );
fprintf( pFile, ".names g4 c1\n" );
fprintf( pFile, "1 1\n" );
fprintf( pFile, ".names g8 c2\n" );
fprintf( pFile, "1 1\n" );
fprintf( pFile, ".end\n" );
}
void Abc_GenAT( char * pFileName, Vec_Int_t * vNums )
{
word Sum = 0; int i, k, Num, nBits = 0;
Vec_IntForEachEntry( vNums, Num, i )
Sum += ((word)1 << i) * Num;
while ( Sum )
nBits++, Sum >>= 1;
Vec_Int_t * vTemp; int nFAs = 0, nHAs = 0, nItem = 0;
Vec_Wec_t * vItems = Vec_WecStart( nBits );
Vec_IntForEachEntry( vNums, Num, i )
for ( k = 0; k < Num; k++ )
Vec_WecPush( vItems, i, nItem++ );
FILE * pFile = fopen( pFileName, "w" );
fprintf( pFile, "# %d-bit %d-input adder tree generated by ABC on %s\n", nBits, nItem, Extra_TimeStamp() );
fprintf( pFile, "# Profile:" );
Vec_IntForEachEntry( vNums, Num, i )
fprintf( pFile, " %d", Num );
fprintf( pFile, "\n" );
fprintf( pFile, ".model AT%d_%d\n", nItem, nBits );
Vec_WecForEachLevel( vItems, vTemp, i ) {
if ( Vec_IntSize(vTemp) == 0 )
continue;
fprintf( pFile, ".inputs" );
Vec_IntForEachEntry( vTemp, Num, k )
fprintf( pFile, " %02d", Num );
fprintf( pFile, "\n" );
}
fprintf( pFile, ".outputs" );
for ( k = 0; k < nBits; k++ )
fprintf( pFile, " o%02d", k );
fprintf( pFile, "\n\n" );
assert( nItem == Vec_IntSum(vNums) );
Vec_WecForEachLevel( vItems, vTemp, i ) {
fprintf( pFile, "# Rank %d:\n", i );
Vec_IntForEachEntry( vTemp, Num, k ) {
if ( Vec_IntSize(vTemp) < 2 )
continue;
while ( Vec_IntSize(vTemp) > 2 ) {
int i1 = Vec_IntPop(vTemp);
int i2 = Vec_IntPop(vTemp);
int i3 = Vec_IntPop(vTemp);
int i4 = nItem++;
int i5 = nItem++;
fprintf( pFile, ".subckt FA a=%02d b=%02d cin=%02d s=%02d cout=%02d\n", i3, i2, i1, i4, i5 ); nFAs++;
Vec_IntPush( vTemp, i4 );
if ( i+1 < Vec_WecSize(vItems) )
Vec_WecPush( vItems, i+1, i5 );
}
if ( Vec_IntSize(vTemp) == 2 ) {
int i1 = Vec_IntPop(vTemp);
int i2 = Vec_IntPop(vTemp);
int i4 = nItem++;
int i5 = nItem++;
fprintf( pFile, ".subckt HA a=%02d b=%02d s=%02d cout=%02d\n", i2, i1, i4, i5 ); nHAs++;
Vec_IntPush( vTemp, i4 );
if ( i+1 < Vec_WecSize(vItems) )
Vec_WecPush( vItems, i+1, i5 );
}
assert( Vec_IntSize(vTemp) == 1 );
}
}
Vec_WecForEachLevel( vItems, vTemp, i )
if ( Vec_IntSize(vTemp) == 0 )
fprintf( pFile, ".names o%02d\n", i );
else if ( Vec_IntSize(vTemp) == 1 )
fprintf( pFile, ".names %02d o%02d\n1 1\n", Vec_IntEntry(vTemp, 0), i );
else assert( 0 );
fprintf( pFile, ".end\n\n" );
Abc_WriteHalfAdder( pFile );
Abc_WriteFullAdder( pFile );
printf( "Created %d-bit %d-input AT with %d FAs and %d HAs.\n", nBits, Vec_IntSum(vNums), nFAs, nHAs );
fclose( pFile );
Vec_WecFree( vItems );
}
void Abc_GenATDual( char * pFileName, Vec_Int_t * vNums )
{
word Sum = 0; int i, k, Num, nBits = 0, Iter = 0, fUsed = 0;
Vec_IntForEachEntry( vNums, Num, i )
Sum += ((word)1 << i) * Num;
while ( Sum )
nBits++, Sum >>= 1;
Vec_Int_t * vTemp; int nFAs = 0, nHAs = 0, nXors = 0, nItem = 1;
Vec_Wec_t * vItems = Vec_WecStart( nBits );
Vec_IntForEachEntry( vNums, Num, i )
for ( k = 0; k < Num; k++ )
Vec_WecPush( vItems, i, nItem++ );
FILE * pFile = fopen( pFileName, "w" );
fprintf( pFile, "# %d-bit %d-input adder tree generated by ABC on %s\n", nBits, Vec_IntSum(vNums), Extra_TimeStamp() );
fprintf( pFile, "# Profile:" );
Vec_IntForEachEntry( vNums, Num, i )
fprintf( pFile, " %d", Num );
fprintf( pFile, "\n" );
fprintf( pFile, ".model AT%d_%d\n", nItem, nBits );
Vec_WecForEachLevel( vItems, vTemp, i ) {
if ( Vec_IntSize(vTemp) == 0 )
continue;
fprintf( pFile, ".inputs" );
Vec_IntForEachEntry( vTemp, Num, k )
fprintf( pFile, " %02d", Num );
fprintf( pFile, "\n" );
}
fprintf( pFile, ".outputs" );
for ( k = 0; k < nBits; k++ )
fprintf( pFile, " o%02d", k );
fprintf( pFile, "\n\n" );
fprintf( pFile, ".names %02d\n", 0 );
while ( Vec_WecMaxLevelSize(vItems) > 2 )
{
fprintf( pFile, "# Iter %d:\n", Iter++ );
Vec_Wec_t * vItems2 = Vec_WecStart( nBits );
Vec_WecForEachLevel( vItems, vTemp, i ) {
while ( Vec_IntSize(vTemp) > 3 ) {
int i0 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
int i1 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
int i2 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
int i3 = Vec_IntEntry(vTemp, 0); Vec_IntDrop(vTemp, 0);
int i4 = (Vec_IntSize(vTemp) > 0 && Vec_IntEntryLast(vTemp) > 0) ? Vec_IntPop(vTemp) : 0;
assert( (i0 < 0) == (i1 < 0) );
assert( (i2 < 0) == (i3 < 0) );
if ( i1 > 0 )
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", i0, i1, nItem ), i1 = nItem++, nXors++;
else
i1 = -i1, i0 = -i0;
if ( i3 > 0 )
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", i2, i3, nItem ), i3 = nItem++, nXors++;
else
i3 = -i3, i2 = -i2;
int o0 = nItem++;
int o1 = nItem++;
int o2 = nItem++;
fprintf( pFile, ".subckt MDFA z=%02d x1=%02d y1=%02d x2=%02d y2=%02d s=%02d c1=%02d c2=%02d\n", i4, i0, i1, i2, i3, o0, o1, o2 ); nFAs += 2, fUsed = 1;
Vec_WecPush( vItems2, i, o0 );
if ( i+1 < Vec_WecSize(vItems2) ) {
Vec_WecPush( vItems2, i+1, -o1 );
Vec_WecPush( vItems2, i+1, -o2 );
}
}
if ( Vec_IntSize(vTemp) == 3 ) {
int i2 = Vec_IntPop(vTemp);
int i1 = Vec_IntPop(vTemp);
int i0 = Vec_IntPop(vTemp);
assert( (i0 < 0) == (i1 < 0) );
assert( i2 > 0 );
if ( i1 < 0 )
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", -i0, -i1, nItem ), i0 = -i0, i1 = nItem++, nXors++;
int o0 = nItem++;
int o1 = nItem++;
fprintf( pFile, ".subckt FA a=%02d b=%02d cin=%02d s=%02d cout=%02d\n", i0, i1, i2, o0, o1 ); nFAs++;
Vec_WecPush( vItems2, i, o0 );
if ( i+1 < Vec_WecSize(vItems2) )
Vec_WecPush( vItems2, i+1, o1 );
}
if ( Vec_IntSize(vTemp) == 2 ) {
int i1 = Vec_IntPop(vTemp);
int i0 = Vec_IntPop(vTemp);
assert( (i0 < 0) == (i1 < 0) );
if ( i1 < 0 ) {
Vec_IntInsert( Vec_WecEntry(vItems2, i), 0, i1 );
Vec_IntInsert( Vec_WecEntry(vItems2, i), 0, i0 );
}
else {
Vec_WecPush( vItems2, i, i0 );
Vec_WecPush( vItems2, i, i1 );
}
}
if ( Vec_IntSize(vTemp) == 1 ) {
int i0 = Vec_IntPop(vTemp);
assert( i0 > 0 );
Vec_WecPush( vItems2, i, i0 );
}
assert( Vec_IntSize(vTemp) == 0 );
}
Vec_WecFree( vItems );
vItems = vItems2;
}
Vec_WecForEachLevel( vItems, vTemp, i ) {
if ( Vec_IntSize(vTemp) == 2 ) {
int i1 = Vec_IntPop(vTemp);
int i0 = Vec_IntPop(vTemp);
assert( (i0 < 0) == (i1 < 0) );
if ( i1 < 0 )
fprintf( pFile, ".names %02d %02d %02d\n01 1\n10 1\n", -i0, -i1, nItem ), i0 = -i0, i1 = nItem++, nXors++;
Vec_IntPush( vTemp, i0 );
Vec_IntPush( vTemp, i1 );
}
if ( Vec_IntSize(vTemp) == 1 ) {
int i0 = Vec_IntPop(vTemp);
assert( i0 > 0 );
Vec_IntPush( vTemp, i0 );
Vec_IntPush( vTemp, 0 );
}
if ( Vec_IntSize(vTemp) == 0 ) {
Vec_IntPush( vTemp, 0 );
Vec_IntPush( vTemp, 0 );
}
assert( Vec_IntSize(vTemp) == 2 );
}
int cin = 0;
Vec_WecForEachLevel( vItems, vTemp, i ) {
int i1 = Vec_IntPop(vTemp);
int i0 = Vec_IntPop(vTemp);
assert( i0 >= 0 && i1 >= 0 );
fprintf( pFile, ".subckt FA a=%02d b=%02d cin=%02d s=o%02d cout=%02d\n", i0, i1, cin, i, nItem ); nFAs++;
cin = nItem++;
}
fprintf( pFile, ".end\n\n" );
Abc_WriteFullAdder( pFile );
if ( fUsed )
Abc_WriteMDFA( pFile );
printf( "Created %d-bit %d-input AT with %d FAs, %d HAs, and %d XORs.\n", nBits, Vec_IntSum(vNums), nFAs, nHAs, nXors );
fclose( pFile );
Vec_WecFree( vItems );
}
////////////////////////////////////////////////////////////////////////
/// END OF FILE ///
////////////////////////////////////////////////////////////////////////

View File

@ -116,7 +116,7 @@ Abc_Ntk_t * Abc_NtkIf( Abc_Ntk_t * pNtk, If_Par_t * pPars )
pPars->pTimesReq = Abc_NtkGetCoRequiredFloats(pNtk);
// update timing info to reflect logic level
if ( (pPars->fDelayOpt || pPars->fDsdBalance || pPars->fUserRecLib || pPars->fUserSesLib) && pNtk->pManTime )
if ( (pPars->fDelayOpt || pPars->fDsdBalance || pPars->fUserRecLib || pPars->fUserSesLib || pPars->fUserLutDec || pPars->fUserLut2D ) && pNtk->pManTime )
{
int c;
if ( pNtk->AndGateDelay == 0.0 )
@ -426,6 +426,131 @@ Hop_Obj_t * Abc_NodeBuildFromMini( Hop_Man_t * pMan, If_Man_t * p, If_Cut_t * pC
return Abc_NodeBuildFromMiniInt( pMan, p->vArray, If_CutLeaveNum(pCut) );
}
/**Function*************************************************************
Synopsis [Implements decomposed LUT-structure of the cut.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCutBest, If_Obj_t * pIfObj, Vec_Int_t * vCover, Abc_Obj_t * pNodeTop )
{
extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );
assert( !pIfMan->pPars->fUseTtPerm );
// get the truth table
word * pTruth = If_CutTruthW(pIfMan, pCutBest);
int v;
If_Obj_t * pIfLeaf;
if ( pCutBest->nLeaves <= pIfMan->pPars->nLutDecSize )
{
/* add fanins */
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, v )
Abc_ObjAddFanin( pNodeTop, (Abc_Obj_t *)If_ObjCopy( pIfLeaf ) );
pNodeTop->Level = Abc_ObjLevelNew( pNodeTop );
pNodeTop->pData = Kit_TruthToHop( (Hop_Man_t *)pNtkNew->pManFunc, (unsigned *)pTruth, If_CutLeaveNum(pCutBest), vCover );
return;
}
// get the delay profile
unsigned delayProfile = pCutBest->decDelay;
// perform LUT-decomposition and return the LUT-structure
unsigned char decompArray[92];
int val;
if ( pIfMan->pPars->fUserLutDec )
{
val = acd_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
}
else if ( pIfMan->pPars->fUserLut2D )
{
val = acd2_decompose( pTruth, pCutBest->nLeaves, pIfMan->pPars->nLutDecSize, &(delayProfile), decompArray );
}
else
{
val = acdXX_decompose( pTruth, pIfMan->pPars->nLutDecSize, pCutBest->nLeaves, decompArray );
}
assert( val == 0 );
// convert the LUT-structure into a set of logic nodes in Abc_Ntk_t
unsigned char bytes_check = decompArray[0];
assert( bytes_check <= 92 );
int byte_p = 2;
unsigned char i, j, k, num_fanins, num_words, num_bytes;
int level, fanin;
word *tt;
Abc_Obj_t *pNewNodes[5];
/* create intermediate LUTs */
assert( decompArray[1] <= 6 );
Abc_Obj_t * pFanin;
for ( i = 0; i < decompArray[1]; ++i )
{
if ( i < decompArray[1] - 1 )
{
pNewNodes[i] = Abc_NtkCreateNode( pNtkNew );
}
else
{
pNewNodes[i] = pNodeTop;
}
num_fanins = decompArray[byte_p++];
level = 0;
for ( j = 0; j < num_fanins; ++j )
{
fanin = (int)decompArray[byte_p++];
if ( fanin < If_CutLeaveNum(pCutBest) )
{
pFanin = (Abc_Obj_t *)If_ObjCopy( If_CutLeaf(pIfMan, pCutBest, fanin) );
}
else
{
assert( fanin - If_CutLeaveNum(pCutBest) < i );
pFanin = pNewNodes[fanin - If_CutLeaveNum(pCutBest)];
}
Abc_ObjAddFanin( pNewNodes[i], pFanin );
level = Abc_MaxInt( level, Abc_ObjLevel(pFanin) );
}
pNewNodes[i]->Level = level + (int)(Abc_ObjFaninNum(pNewNodes[i]) > 0);
/* extract the truth table */
tt = pIfMan->puTempW;
num_words = ( num_fanins <= 6 ) ? 1 : ( 1 << ( num_fanins - 6 ) );
num_bytes = ( num_fanins <= 3 ) ? 1 : ( 1 << ( Abc_MinInt( (int)num_fanins, 6 ) - 3 ) );
for ( j = 0; j < num_words; ++j )
{
tt[j] = 0;
for ( k = 0; k < num_bytes; ++k )
{
tt[j] |= ( (word)(decompArray[byte_p++]) ) << ( k << 3 );
}
}
/* extend truth table if size < 5 */
assert( num_fanins != 1 );
if ( num_fanins == 2 )
{
tt[0] |= tt[0] << 4;
}
while ( num_bytes < 4 )
{
tt[0] |= tt[0] << ( num_bytes << 3 );
num_bytes <<= 1;
}
/* add node data */
pNewNodes[i]->pData = Kit_TruthToHop( (Hop_Man_t *)pNtkNew->pManFunc, (unsigned *)tt, (int) num_fanins, vCover );
}
/* check correct read */
assert( byte_p == decompArray[0] );
}
/**Function*************************************************************
Synopsis [Derive one node after FPGA mapping.]
@ -464,13 +589,19 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
pNodeNew = Abc_NtkCreateNode( pNtkNew );
// if ( pIfMan->pPars->pLutLib && pIfMan->pPars->pLutLib->fVarPinDelays )
if ( !pIfMan->pPars->fDelayOpt && !pIfMan->pPars->fDelayOptLut && !pIfMan->pPars->fDsdBalance && !pIfMan->pPars->fUseTtPerm &&
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserRecLib && !pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize )
!pIfMan->pPars->pLutStruct && !pIfMan->pPars->fUserLutDec && !pIfMan->pPars->fUserLut2D && !pIfMan->pPars->fUserRecLib &&
!pIfMan->pPars->fUserSesLib && !pIfMan->pPars->nGateSize )
If_CutRotatePins( pIfMan, pCutBest );
if ( pIfMan->pPars->fUseCnfs || pIfMan->pPars->fUseMv )
{
If_CutForEachLeafReverse( pIfMan, pCutBest, pIfLeaf, i )
Abc_ObjAddFanin( pNodeNew, Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover) );
}
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D || pIfMan->pPars->fDeriveLuts )
{
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
Abc_NodeFromIf_rec(pNtkNew, pIfMan, pIfLeaf, vCover);
}
else
{
If_CutForEachLeaf( pIfMan, pCutBest, pIfLeaf, i )
@ -524,6 +655,11 @@ Abc_Obj_t * Abc_NodeFromIf_rec( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Obj_t
extern Hop_Obj_t * Abc_RecToHop3( Hop_Man_t * pMan, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj );
pNodeNew->pData = Abc_RecToHop3( (Hop_Man_t *)pNtkNew->pManFunc, pIfMan, pCutBest, pIfObj );
}
else if ( pIfMan->pPars->fUserLutDec || pIfMan->pPars->fUserLut2D || pIfMan->pPars->fDeriveLuts )
{
extern void Abc_DecRecordToHop( Abc_Ntk_t * pNtkNew, If_Man_t * pIfMan, If_Cut_t * pCut, If_Obj_t * pIfObj, Vec_Int_t * vMemory, Abc_Obj_t * pNodeTop );
Abc_DecRecordToHop( pNtkNew, pIfMan, pCutBest, pIfObj, vCover, pNodeNew );
}
else
{
extern Hop_Obj_t * Kit_TruthToHop( Hop_Man_t * pMan, unsigned * pTruth, int nVars, Vec_Int_t * vMemory );

View File

@ -430,10 +430,10 @@ Abc_Obj_t * Abc_NtkBddCurtis( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, Vec_Ptr_t
int b, c, u, i;
assert( nBits + 2 <= nLutSize );
assert( nLutSize < Abc_ObjFaninNum(pNode) );
// start BDDs for the decompoosed blocks
// start BDDs for the decomposed blocks
for ( b = 0; b < nBits; b++ )
bBits[b] = Cudd_ReadLogicZero(ddNew), Cudd_Ref( bBits[b] );
// add each bound set minterm to one of the blccks
// add each bound set minterm to one of the blocks
Vec_PtrForEachEntry( DdNode *, vCofs, bCof, c )
{
Vec_PtrForEachEntry( DdNode *, vUniq, bUniq, u )
@ -574,6 +574,479 @@ Abc_Obj_t * Abc_NtkBddFindCofactor( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int
return pNodeTop;
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
int Abc_NtkBddNodeCompareByLevel( DdNode ** pp1, DdNode ** pp2 )
{
return (*pp1)->Id - (*pp2)->Id;
}
Vec_Ptr_t * Abc_NtkBddCollectByLevel( DdManager * dd, DdNode * aFunc )
{
DdGen *gen; DdNode *node; int i;
Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
Cudd_ForeachNode( dd, aFunc, gen, node )
Vec_PtrPush( vNodes, node ), node->Id = Cudd_ReadPerm( dd, (int)node->index );
Vec_PtrSort( vNodes, (int (*)(const void *, const void *))Abc_NtkBddNodeCompareByLevel );
Vec_PtrForEachEntry( DdNode *, vNodes, node, i )
node->Id = i;
return vNodes;
}
void Abc_NtkBddCollectPrint3( DdManager * dd, DdNode * aFunc )
{
Vec_Ptr_t * vNodes = Abc_NtkBddCollectByLevel( dd, aFunc );
Vec_PtrPrintPointers( vNodes );
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Ptr_t * Abc_NtkBddFetchNodes( DdManager * dd, DdNode * aFunc )
{
Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
DdGen *gen; DdNode *node;
Cudd_ForeachNode( dd, aFunc, gen, node)
Vec_PtrPush(vNodes, node), node->Id = 0;
return vNodes;
}
void Abc_NtkBddCleanNodes( DdManager * dd, DdNode * aFunc )
{
DdGen *gen; DdNode *node;
Cudd_ForeachNode( dd, aFunc, gen, node)
node->Id = 0;
}
void Abc_NtkBddCollectPtr_rec( DdManager * dd, DdNode * aFunc, Vec_Ptr_t * vNodes )
{
if ( aFunc->Id )
return;
if ( !cuddIsConstant(aFunc) ) {
Abc_NtkBddCollectPtr_rec( dd, cuddE(aFunc), vNodes );
Abc_NtkBddCollectPtr_rec( dd, cuddT(aFunc), vNodes );
}
aFunc->Id = Vec_PtrSize(vNodes) + 1;
Vec_PtrPush(vNodes, aFunc);
}
Vec_Ptr_t * Abc_NtkBddCollectPtr( DdManager * dd, DdNode * aFunc )
{
Vec_Ptr_t * vNodes = Vec_PtrAlloc( 100 );
Abc_NtkBddCleanNodes( dd, aFunc );
Abc_NtkBddCollectPtr_rec( dd, aFunc, vNodes );
return vNodes;
}
void Abc_NtkBddCollectPrint2( DdManager * dd, DdNode * aFunc )
{
Vec_Ptr_t * vNodes = Abc_NtkBddCollectPtr( dd, aFunc );
Vec_PtrPrintPointers( vNodes );
Vec_PtrFree( vNodes );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
static inline word Abc_Bdd2Word( DdNode * f ) { union { DdNode * f; word w; } v; v.f = f; return v.w; }
static inline DdNode * Abc_Word2Bdd( word w ) { union { DdNode * f; word w; } v; v.w = w; return v.f; }
static inline int Abc_Bdd2Int( DdNode * F, DdNode * f ) { return (int)(Abc_Bdd2Word(F) ^ Abc_Bdd2Word(f)) >> 3; }
static inline DdNode * Abc_Int2Bdd( DdNode * F, int diff ) { return Abc_Word2Bdd(Abc_Bdd2Word(F) ^ (word)(diff << 3)); }
static inline int Abc_BddIndex( DdManager * dd, DdNode * f ) { return cuddIsConstant(f) ? dd->size : (int)f->index; }
static inline int Abc_BddLevel( DdManager * dd, DdNode * f ) { return cuddIsConstant(f) ? dd->size : Cudd_ReadPerm(dd, (int)f->index); }
void Abc_NtkBddCollectInt_rec( DdManager * dd, DdNode * aRef, DdNode * aFunc, Vec_Wec_t * vNodes )
{
if ( Cudd_IsComplement(aFunc->next) )
return;
aFunc->next = Cudd_Not(aFunc->next);
if ( !cuddIsConstant(aFunc) ) {
Abc_NtkBddCollectInt_rec( dd, aRef, cuddE(aFunc), vNodes );
Abc_NtkBddCollectInt_rec( dd, aRef, cuddT(aFunc), vNodes );
}
//assert( Abc_Bdd2Int(aRef, aFunc) % 8 == 0 );
Vec_WecPush( vNodes, Abc_BddLevel(dd, aFunc), Abc_Bdd2Int(aRef, aFunc) );
}
Vec_Wec_t * Abc_NtkBddCollectInt( DdManager * dd, DdNode * aFunc )
{
Vec_Wec_t * vNodes = Vec_WecStart( dd->size+1 );
Abc_NtkBddCollectInt_rec( dd, aFunc, aFunc, vNodes );
extern void ddClearFlag2( DdNode * f );
ddClearFlag2( aFunc );
return vNodes;
}
void Abc_NtkBddCollectPrint( DdManager * dd, DdNode * aFunc )
{
Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
Vec_WecPrint( vNodes, 0 );
Vec_WecFree( vNodes );
}
/**Function*************************************************************
Synopsis []
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Vec_Int_t * Abc_NtkBddCollectHighest( DdManager * dd, DdNode * aFunc, Vec_Wec_t * vNodes )
{
Vec_Int_t * vRes = Vec_IntStartFull( Vec_WecMaxEntry(vNodes)+1 );
Vec_Int_t * vLevel; int i, k, Obj, * pEntry;
Vec_WecForEachLevelStop( vNodes, vLevel, i, dd->size )
Vec_IntForEachEntry( vLevel, Obj, k ) {
DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
pEntry = Vec_IntEntryP( vRes, Abc_Bdd2Int(aFunc, cuddE(aNode)) );
if ( *pEntry == -1 ) *pEntry = i;
pEntry = Vec_IntEntryP( vRes, Abc_Bdd2Int(aFunc, cuddT(aNode)) );
if ( *pEntry == -1 ) *pEntry = i;
}
return vRes;
}
void Abc_NtkBddCollectProfile( DdManager * dd, DdNode * aFunc, Vec_Wec_t * vNodes, int * pProf )
{
memset( pProf, 0, sizeof(int)*(dd->size+1) );
Vec_Int_t * vHighest = Abc_NtkBddCollectHighest( dd, aFunc, vNodes );
Vec_Int_t * vLevel; int i, k, Obj;
pProf[0] = 1;
Vec_WecForEachLevelStart( vNodes, vLevel, i, 1 )
Vec_IntForEachEntry( vLevel, Obj, k ) {
int lev, Start = Vec_IntEntry( vHighest, Obj );
for ( lev = Start+1; lev <= i; lev++ )
pProf[lev]++;
}
printf( " Size = %5d ", Vec_IntSize(vHighest) );
Vec_IntFree( vHighest );
}
void Abc_NtkBddTestProfile( DdManager * dd, DdNode * aFunc )
{
Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
int i, Total = 0, Profile[100]; assert( dd->size < 100 );
Abc_NtkBddCollectProfile( dd, aFunc, vNodes, Profile );
printf( " " );
for ( i = 0; i <= dd->size; i++ )
printf( "%3d", Profile[i] ), Total += Profile[i];
printf( " Total = %d\n", Total );
Vec_WecFree( vNodes );
}
Vec_Wec_t * Abc_NtkBddCollectCofs( DdManager * dd, DdNode * aFunc, Vec_Wec_t * vNodes )
{
Vec_Wec_t * vCofs = Vec_WecStart( dd->size+1 );
Vec_Int_t * vHighest = Abc_NtkBddCollectHighest( dd, aFunc, vNodes );
Vec_Int_t * vLevel; int i, k, Obj;
Vec_WecPush( vCofs, 0, 0 );
Vec_WecForEachLevelStart( vNodes, vLevel, i, 1 )
Vec_IntForEachEntry( vLevel, Obj, k ) {
int lev, Start = Vec_IntEntry( vHighest, Obj );
for ( lev = Start+1; lev <= i; lev++ )
Vec_WecPush( vCofs, lev, Obj );
}
Vec_IntFree( vHighest );
return vCofs;
}
Vec_Wec_t * Abc_NtkBddCollecInfo1( DdManager * dd, DdNode * aFunc )
{
Vec_Wec_t * vInfo = Vec_WecStart( dd->size );
Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( dd, aFunc, vNodes );
Vec_Int_t * vLevel; int i, k, Obj;
for ( int a = 0; a < dd->size; a++ ) {
word Sign = (word)1 << a;
for ( int n = 0; n < 2; n++ ) {
word Value = (word)n << a;
Vec_WecForEachLevel( vNodes, vLevel, i )
Vec_IntForEachEntry( vLevel, Obj, k )
Abc_Int2Bdd(aFunc, Obj)->Id = 0;
aFunc->Id = 1;
//printf( " %c %d : ", 'a'+a, n );
//printf( " %2d", 1 );
if ( n == 0 )
Vec_IntPush( Vec_WecEntry(vInfo, a), 1 );
Vec_WecForEachLevelStop( vNodes, vLevel, i, dd->size ) {
Vec_IntForEachEntry( vLevel, Obj, k ) {
DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
if ( aNode->Id == 0 )
continue;
if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 0 )
cuddE(aNode)->Id |= 1;
if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 1 )
cuddT(aNode)->Id |= 1;
}
Vec_Int_t * vCof = Vec_WecEntry(vCofs, i+1);
int Counter = 0;
Vec_IntForEachEntry( vCof, Obj, k )
Counter += (int)Abc_Int2Bdd(aFunc, Obj)->Id;
if ( n == 0 )
Vec_IntPush( Vec_WecEntry(vInfo, a), Counter );
else {
int * pEntry = Vec_IntEntryP( Vec_WecEntry(vInfo, a), i+1 );
*pEntry = Abc_MaxInt( *pEntry, Counter );
}
//printf( " %2d", Counter );
}
//printf( "\n" );
}
}
Vec_WecFree( vCofs );
Vec_WecFree( vNodes );
return vInfo;
}
Vec_Wec_t * Abc_NtkBddCollecInfo2( DdManager * dd, DdNode * aFunc )
{
Vec_Wec_t * vInfo = Vec_WecStart( dd->size*(dd->size-1)/2 );
Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( dd, aFunc, vNodes );
Vec_Int_t * vLevel; int i, k, Obj, c = 0;
for ( int a = 0; a < dd->size; a++ )
for ( int b = a+1; b < dd->size; b++ ) {
Vec_Int_t * vInfo1 = Vec_WecEntry(vInfo, c++);
word Sign = ((word)1 << a) | ((word)1 << b);
for ( int n = 0; n < 4; n++ ) {
word Value = ((word)(n & 1) << a) | ((word)((n >> 1) & 1) << b);
Vec_WecForEachLevel( vNodes, vLevel, i )
Vec_IntForEachEntry( vLevel, Obj, k )
Abc_Int2Bdd(aFunc, Obj)->Id = 0;
aFunc->Id = 1;
if ( n == 0 )
Vec_IntPush( vInfo1, 1 );
Vec_WecForEachLevelStop( vNodes, vLevel, i, dd->size ) {
Vec_IntForEachEntry( vLevel, Obj, k ) {
DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
if ( aNode->Id == 0 )
continue;
if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 0 )
cuddE(aNode)->Id |= 1;
if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 1 )
cuddT(aNode)->Id |= 1;
}
Vec_Int_t * vCof = Vec_WecEntry(vCofs, i+1);
int Counter = 0;
Vec_IntForEachEntry( vCof, Obj, k )
Counter += (int)Abc_Int2Bdd(aFunc, Obj)->Id;
if ( n == 0 )
Vec_IntPush( vInfo1, Counter );
else {
int * pEntry = Vec_IntEntryP( vInfo1, i+1 );
*pEntry = Abc_MaxInt( *pEntry, Counter );
}
}
}
}
assert( c == Vec_WecSize(vInfo) );
Vec_WecFree( vCofs );
Vec_WecFree( vNodes );
return vInfo;
}
Vec_Wec_t * Abc_NtkBddCollecInfo3( DdManager * dd, DdNode * aFunc )
{
Vec_Wec_t * vInfo = Vec_WecStart( dd->size*(dd->size-1)*(dd->size-2)/6 );
Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( dd, aFunc );
Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( dd, aFunc, vNodes );
Vec_Int_t * vLevel; int i, k, Obj, d = 0;
for ( int a = 0; a < dd->size; a++ )
for ( int b = a+1; b < dd->size; b++ )
for ( int c = b+1; c < dd->size; c++ ) {
Vec_Int_t * vInfo1 = Vec_WecEntry(vInfo, d++);
word Sign = ((word)1 << a) | ((word)1 << b) | ((word)1 << c);
for ( int n = 0; n < 8; n++ ) {
word Value = ((word)(n & 1) << a) | ((word)((n >> 1) & 1) << b) | ((word)((n >> 2) & 1) << c);
Vec_WecForEachLevel( vNodes, vLevel, i )
Vec_IntForEachEntry( vLevel, Obj, k )
Abc_Int2Bdd(aFunc, Obj)->Id = 0;
aFunc->Id = 1;
if ( n == 0 )
Vec_IntPush( vInfo1, 1 );
Vec_WecForEachLevelStop( vNodes, vLevel, i, dd->size ) {
Vec_IntForEachEntry( vLevel, Obj, k ) {
DdNode * aNode = Abc_Int2Bdd(aFunc, Obj);
if ( aNode->Id == 0 )
continue;
if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 0 )
cuddE(aNode)->Id |= 1;
if ( !((Sign >> i) & 1) || ((Value >> i) & 1) == 1 )
cuddT(aNode)->Id |= 1;
}
Vec_Int_t * vCof = Vec_WecEntry(vCofs, i+1);
int Counter = 0;
Vec_IntForEachEntry( vCof, Obj, k )
Counter += (int)Abc_Int2Bdd(aFunc, Obj)->Id;
if ( n == 0 )
Vec_IntPush( vInfo1, Counter );
else {
int * pEntry = Vec_IntEntryP( vInfo1, i+1 );
*pEntry = Abc_MaxInt( *pEntry, Counter );
}
}
}
}
assert( d == Vec_WecSize(vInfo) );
Vec_WecFree( vCofs );
Vec_WecFree( vNodes );
return vInfo;
}
void Abc_NtkBddPrintInfo1( Vec_Wec_t * vInfo, Vec_Wec_t * vCofs )
{
Vec_Int_t * vLevel; int i, k, Obj;
printf( "Cofactor counts:\n" );
printf( " : " );
Vec_WecForEachLevel( vCofs, vLevel, i )
printf( " %2d", i );
printf( "\n" );
printf( " : " );
Vec_WecForEachLevel( vCofs, vLevel, i )
printf( " %2d", Vec_IntSize(vLevel) );
printf( "\n" );
Vec_WecForEachLevel( vInfo, vLevel, i ) {
printf( "%2d %c : ", i, 'a'+i );
Vec_IntForEachEntry( vLevel, Obj, k )
if ( k <= i )
printf( " -" );
else
printf( " %2d", Obj );
printf( "\n" );
}
}
void Abc_NtkBddPrintInfo2( Vec_Wec_t * vInfo, Vec_Wec_t * vCofs )
{
Vec_Int_t * vLevel; int i, k, Obj;
printf( "Cofactor counts:\n" );
printf( " : " );
Vec_WecForEachLevel( vCofs, vLevel, i )
printf( " %2d", i );
printf( "\n" );
printf( " : " );
Vec_WecForEachLevel( vCofs, vLevel, i )
printf( " %2d", Vec_IntSize(vLevel) );
printf( "\n" );
int c = 0, Limit = Vec_IntSize(Vec_WecEntry(vInfo, 0))-1;
for ( int a = 0; a < Limit; a++ )
for ( int b = a+1; b < Limit; b++ ) {
Vec_Int_t * vLevel = Vec_WecEntry(vInfo, c++);
printf( " %c%c : ", 'a'+a, 'a'+b );
int Limit = Abc_MaxInt(a,b);
Vec_IntForEachEntry( vLevel, Obj, k )
if ( k <= Limit )
printf( " -" );
else
printf( " %2d", Obj );
printf( "\n" );
}
assert( c == Vec_WecSize(vInfo) );
}
void Abc_NtkBddPrintInfo3( Vec_Wec_t * vInfo, Vec_Wec_t * vCofs )
{
Vec_Int_t * vLevel; int i, k, Obj;
printf( "Cofactor counts:\n" );
printf( " : " );
Vec_WecForEachLevel( vCofs, vLevel, i )
printf( " %2d", i );
printf( "\n" );
printf( " : " );
Vec_WecForEachLevel( vCofs, vLevel, i )
printf( " %2d", Vec_IntSize(vLevel) );
printf( "\n" );
int d = 0, Limit = Vec_IntSize(Vec_WecEntry(vInfo, 0))-1;
for ( int a = 0; a < Limit; a++ )
for ( int b = a+1; b < Limit; b++ )
for ( int c = b+1; c < Limit; c++ ) {
Vec_Int_t * vLevel = Vec_WecEntry(vInfo, d++);
printf( " %c%c%c : ", 'a'+a, 'a'+b, 'a'+c );
int Limit = Abc_MaxInt(a,Abc_MaxInt(b,c));
Vec_IntForEachEntry( vLevel, Obj, k )
if ( k <= Limit )
printf( " -" );
else
printf( " %2d", Obj );
printf( "\n" );
}
assert( d == Vec_WecSize(vInfo) );
}
void Abc_NtkBddDecExploreOne( DdManager * dd, DdNode * bFunc, int iOrder )
{
DdManager * ddNew = Cudd_Init( dd->size, 0, CUDD_UNIQUE_SLOTS, CUDD_CACHE_SLOTS, 0 );
int i, * pProfile = ABC_CALLOC( int, dd->size + 100 );
Cudd_AutodynEnable( ddNew, CUDD_REORDER_SYMM_SIFT );
Vec_Int_t * vPerm = Vec_IntStartNatural( dd->size ); if ( iOrder ) Vec_IntRandomizeOrder( vPerm );
Vec_Int_t * vPermInv = Vec_IntInvert( vPerm, -1 );
DdNode * bFuncNew = Extra_TransferPermute( dd, ddNew, bFunc, Vec_IntArray(vPerm) ); Cudd_Ref(bFuncNew);
if ( iOrder ) Cudd_ReduceHeap( ddNew, CUDD_REORDER_SYMM_SIFT, 1 );
Vec_IntFree( vPerm );
DdNode * aFuncNew = Cudd_BddToAdd( ddNew, bFuncNew ); Cudd_Ref( aFuncNew );
//Extra_ProfileWidth( ddNew, aFuncNew, pProfile, -1 );
if ( iOrder )
printf( "Random order %2d: ", iOrder );
else
printf( "Natural order: " );
printf( "BDD size = %3d ", Cudd_DagSize(aFuncNew) );
for ( i = 0; i < dd->size; i++ )
printf( " %c", 'a' + Vec_IntEntry(vPermInv, ddNew->invperm[i]) );
printf( "\n" );
//Abc_NtkBddTestProfile( ddNew, aFuncNew );
Vec_Wec_t * vNodes = Abc_NtkBddCollectInt( ddNew, aFuncNew );
printf( "Nodes by level:\n" );
Vec_WecPrint( vNodes, 0 );
Vec_Wec_t * vCofs = Abc_NtkBddCollectCofs( ddNew, aFuncNew, vNodes );
printf( "Cofactors by level:\n" );
Vec_WecPrint( vCofs, 0 );
Vec_Wec_t * vInfo1 = Abc_NtkBddCollecInfo1( ddNew, aFuncNew );
Abc_NtkBddPrintInfo1( vInfo1, vCofs );
Vec_Wec_t * vInfo2 = Abc_NtkBddCollecInfo2( ddNew, aFuncNew );
Abc_NtkBddPrintInfo2( vInfo2, vCofs );
Vec_Wec_t * vInfo3 = Abc_NtkBddCollecInfo3( ddNew, aFuncNew );
Abc_NtkBddPrintInfo3( vInfo3, vCofs );
printf( "\n" );
Vec_WecFree( vNodes );
Vec_WecFree( vCofs );
Vec_WecFree( vInfo1 );
Vec_WecFree( vInfo2 );
Vec_WecFree( vInfo3 );
Cudd_RecursiveDeref( ddNew, aFuncNew );
Cudd_RecursiveDeref( ddNew, bFuncNew );
Cudd_Quit( ddNew );
ABC_FREE( pProfile );
}
void Abc_NtkBddDecExplore( Abc_Obj_t * pNode )
{
DdManager * dd = (DdManager *)pNode->pNtk->pManFunc;
DdNode * bFunc = (DdNode *)pNode->pData;
int i; Abc_Random(1);
if ( Abc_ObjIsNode(pNode) )
for ( i = 0; i < 4; i++ )
Abc_NtkBddDecExploreOne( dd, bFunc, i );
}
/**Function*************************************************************
Synopsis [Decompose the function once.]
@ -610,16 +1083,18 @@ Abc_Obj_t * Abc_NtkBddDecompose( Abc_Ntk_t * pNtkNew, Abc_Obj_t * pNode, int nLu
}
// cofactor w.r.t. the bound set variables
vCofs = Abc_NtkBddCofactors( dd, (DdNode *)pNode->pData, nLutSize );
vUniq = Vec_PtrDup( vCofs );
Vec_PtrUniqify( vUniq, (int (*)(const void *, const void *))Vec_PtrSortCompare );
// only perform decomposition with it is support reduring with two less vars
// collect unique cofactors in the order they appear
vUniq = Vec_PtrAlloc( Vec_PtrSize(vCofs) );
Vec_PtrForEachEntry( DdNode *, vCofs, bCof, i )
Vec_PtrPushUnique( vUniq, bCof );
// only perform decomposition which it is support reducing with two less vars
if( Vec_PtrSize(vUniq) > (1 << (nLutSize-2)) )
{
Vec_PtrFree( vCofs );
vCofs = Abc_NtkBddCofactors( dd, (DdNode *)pNode->pData, 2 );
if ( fVerbose )
printf( "Decomposing %d-input node %d using cofactoring with %d cofactors.\n",
Abc_ObjFaninNum(pNode), Abc_ObjId(pNode), Vec_PtrSize(vCofs) );
printf( "Decomposing %d-input node %d using cofactoring with %d cofactors (myu = %d).\n",
Abc_ObjFaninNum(pNode), Abc_ObjId(pNode), Vec_PtrSize(vCofs), Vec_PtrSize(vUniq) );
// implement the cofactors
pCofs[0] = Abc_ObjFanin(pNode, 0)->pCopy;
pCofs[1] = Abc_ObjFanin(pNode, 1)->pCopy;
@ -688,13 +1163,13 @@ void Abc_NtkLutminConstruct( Abc_Ntk_t * pNtkClp, Abc_Ntk_t * pNtkDec, int nLutS
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkLutminInt( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
Abc_Ntk_t * Abc_NtkLutminInt( Abc_Ntk_t * pNtk, int nLutSize, int fReorder, int fVerbose )
{
extern void Abc_NtkBddReorder( Abc_Ntk_t * pNtk, int fVerbose );
Abc_Ntk_t * pNtkDec;
// minimize BDDs
// Abc_NtkBddReorder( pNtk, fVerbose );
Abc_NtkBddReorder( pNtk, 0 );
if ( fReorder )
Abc_NtkBddReorder( pNtk, 0 );
// decompose one output at a time
pNtkDec = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_BDD );
// make sure the new manager has enough inputs
@ -719,7 +1194,7 @@ Abc_Ntk_t * Abc_NtkLutminInt( Abc_Ntk_t * pNtk, int nLutSize, int fVerbose )
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fReorder, int fVerbose )
{
extern int Abc_NtkFraigSweep( Abc_Ntk_t * pNtk, int fUseInv, int fExdc, int fVerbose, int fVeryVerbose );
Abc_Ntk_t * pNtkNew, * pTemp;
@ -740,7 +1215,7 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
else
pNtkNew = Abc_NtkStrash( pNtkInit, 0, 1, 0 );
// collapse the network
pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, 1, 0, 0, 0 );
pNtkNew = Abc_NtkCollapse( pTemp = pNtkNew, 10000, 0, fReorder, 0, 0, 0 );
Abc_NtkDelete( pTemp );
if ( pNtkNew == NULL )
return NULL;
@ -755,7 +1230,7 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
if ( fVerbose )
printf( "Decomposing network with %d nodes and %d max fanin count for K = %d.\n",
Abc_NtkNodeNum(pNtkNew), Abc_NtkGetFaninMax(pNtkNew), nLutSize );
pNtkNew = Abc_NtkLutminInt( pTemp = pNtkNew, nLutSize, fVerbose );
pNtkNew = Abc_NtkLutminInt( pTemp = pNtkNew, nLutSize, fReorder, fVerbose );
Abc_NtkDelete( pTemp );
}
// fix the problem with complemented and duplicated CO edges
@ -773,7 +1248,8 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose )
#else
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose ) { return NULL; }
Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fReorder, int fVerbose ) { return NULL; }
void Abc_NtkBddDecExplore( Abc_Obj_t * pNode ) {}
#endif
@ -783,4 +1259,3 @@ Abc_Ntk_t * Abc_NtkLutmin( Abc_Ntk_t * pNtkInit, int nLutSize, int fVerbose ) {
ABC_NAMESPACE_IMPL_END

View File

@ -24,6 +24,7 @@
#include "map/mapper/mapper.h"
#include "misc/util/utilNam.h"
#include "map/scl/sclCon.h"
#include "map/scl/sclLib.h"
ABC_NAMESPACE_IMPL_START
@ -58,7 +59,7 @@ static Abc_Obj_t * Abc_NodeFromMapSuperChoice_rec( Abc_Ntk_t * pNtkNew, Map_Sup
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fUseProfile, int fUseBuffs, int fVerbose )
Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, Mio_Library_t* userLib, double DelayTarget, double AreaMulti, double DelayMulti, float LogFan, float Slew, float Gain, int nGatesMin, int fRecovery, int fSwitching, int fSkipFanout, int fUseProfile, int fUseBuffs, int fVerbose )
{
static int fUseMulti = 0;
int fShowSwitching = 1;
@ -87,6 +88,11 @@ Abc_Ntk_t * Abc_NtkMap( Abc_Ntk_t * pNtk, double DelayTarget, double AreaMulti,
Map_SuperLibFree( (Map_SuperLib_t *)Abc_FrameReadLibSuper() );
Abc_FrameSetLibSuper( NULL );
}
if ( userLib != NULL ) {
pLib = userLib;
}
// quit if there is no library
if ( pLib == NULL )
{
@ -275,6 +281,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
Map_ManSetAreaRecovery( pMan, fRecovery );
Map_ManSetOutputNames( pMan, Abc_NtkCollectCioNames(pNtk, 1) );
Map_ManSetDelayTarget( pMan, (float)DelayTarget );
Map_ManCreateAigIds( pMan, Abc_NtkObjNumMax(pNtk) );
// set arrival and requireds
if ( Scl_ConIsRunning() && Scl_ConHasInArrs() )
@ -297,6 +304,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
pNode->pCopy = (Abc_Obj_t *)pNodeMap;
if ( pSwitching )
Map_NodeSetSwitching( pNodeMap, pSwitching[pNode->Id] );
Map_NodeSetAigId( pNodeMap, pNode->Id );
}
// load the AIG into the mapper
@ -327,6 +335,7 @@ Map_Man_t * Abc_NtkToMap( Abc_Ntk_t * pNtk, double DelayTarget, int fRecovery, f
Map_NodeSetNextE( (Map_Node_t *)pPrev->pCopy, (Map_Node_t *)pFanin->pCopy );
Map_NodeSetRepr( (Map_Node_t *)pFanin->pCopy, (Map_Node_t *)pNode->pCopy );
}
Map_NodeSetAigId( pNodeMap, pNode->Id );
}
assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
Vec_PtrFree( vNodes );
@ -419,6 +428,7 @@ Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
uPhaseBest = Map_CutReadPhaseBest( pCutBest, fPhase );
nLeaves = Map_CutReadLeavesNum( pCutBest );
ppLeaves = Map_CutReadLeaves( pCutBest );
//Vec_Ptr_t * vAnds = Map_CutInternalNodes( pNodeMap, pCutBest );
// collect the PI nodes
for ( i = 0; i < nLeaves; i++ )
@ -430,6 +440,7 @@ Abc_Obj_t * Abc_NodeFromMapPhase_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap
// implement the supergate
pNodeNew = Abc_NodeFromMapSuper_rec( pNtkNew, pNodeMap, pSuperBest, pNodePIs, nLeaves );
Vec_IntWriteEntry( pNtkNew->vOrigNodeIds, pNodeNew->Id, Abc_Var2Lit( Map_NodeReadAigId(pNodeMap), fPhase ) );
Map_NodeSetData( pNodeMap, fPhase, (char *)pNodeNew );
return pNodeNew;
}
@ -461,6 +472,7 @@ Abc_Obj_t * Abc_NodeFromMap_rec( Abc_Ntk_t * pNtkNew, Map_Node_t * pNodeMap, int
// add the inverter
pNodeInv = Abc_NtkCreateNode( pNtkNew );
Vec_IntWriteEntry( pNtkNew->vOrigNodeIds, pNodeInv->Id, Abc_Var2Lit( Map_NodeReadAigId(pNodeMap), fPhase ) );
Abc_ObjAddFanin( pNodeInv, pNodeNew );
pNodeInv->pData = Mio_LibraryReadInv((Mio_Library_t *)Abc_FrameReadLibGen());
@ -477,6 +489,7 @@ Abc_Ntk_t * Abc_NtkFromMap( Map_Man_t * pMan, Abc_Ntk_t * pNtk, int fUseBuffs )
assert( Map_ManReadBufNum(pMan) == pNtk->nBarBufs );
// create the new network
pNtkNew = Abc_NtkStartFrom( pNtk, ABC_NTK_LOGIC, ABC_FUNC_MAP );
pNtkNew->vOrigNodeIds = Vec_IntStartFull( 2 * Abc_NtkObjNumMax(pNtk) );
// make the mapper point to the new network
Map_ManCleanData( pMan );
Abc_NtkForEachCi( pNtk, pNode, i )
@ -839,7 +852,7 @@ Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
// write the numbers of CI/CO/Node/FF
Vec_IntPush( vMapping, Abc_NtkCiNum(pNtk) );
Vec_IntPush( vMapping, Abc_NtkCoNum(pNtk) );
Vec_IntPush( vMapping, Abc_NtkNodeNum(pNtk) );
Vec_IntPush( vMapping, Vec_PtrSize(vNodes) );
Vec_IntPush( vMapping, Abc_NtkLatchNum(pNtk) );
// write the nodes
vGates = Vec_StrAlloc( 10000 );
@ -855,6 +868,15 @@ Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
// write the COs literals
Abc_NtkForEachCo( pNtk, pObj, i )
Vec_IntPush( vMapping, Abc_ObjFanin0(pObj)->iTemp );
// write signal names
Abc_NtkForEachCi( pNtk, pObj, i ) {
Vec_StrPrintStr( vGates, Abc_ObjName(pObj) );
Vec_StrPush( vGates, '\0' );
}
Abc_NtkForEachCo( pNtk, pObj, i ) {
Vec_StrPrintStr( vGates, Abc_ObjName(pObj) );
Vec_StrPush( vGates, '\0' );
}
// finish off the array
nExtra = 4 - Vec_StrSize(vGates) % 4;
for ( i = 0; i < nExtra; i++ )
@ -871,6 +893,129 @@ Vec_Int_t * Abc_NtkWriteMiniMapping( Abc_Ntk_t * pNtk )
return vMapping;
}
/**Function*************************************************************
Synopsis [Build mapped network from the mini-mapped format.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkFromMiniMapping( int *pArray )
{
if ( !pArray ) {
printf("Mapping is not available.\n");
return NULL;
}
Mio_Library_t * pLib = (Mio_Library_t *)Abc_FrameReadLibGen();
if ( !pLib ) {
printf("Library is not available.\n");
return NULL;
}
Abc_Ntk_t *pNtkMapped = Abc_NtkAlloc( ABC_NTK_LOGIC, ABC_FUNC_MAP, 1 );
pNtkMapped->pName = Extra_UtilStrsav( "mapped" );
pNtkMapped->pManFunc = pLib;
int nCis, nCos, nNodes, nFlops;
int i, k, nLeaves, Pos = 4;
char * pBuffer, * pName;
Mio_Gate_t *pGate;
Abc_Obj_t * pObj;
nCis = pArray[0];
nCos = pArray[1];
nNodes = pArray[2];
nFlops = pArray[3];
// create pis
for ( i = 0; i < nCis-nFlops; i++ )
Abc_NtkCreatePi( pNtkMapped );
// create nodes
for ( i = 0; i < nNodes; i++ )
Abc_NtkCreateNode( pNtkMapped );
// create pos
for ( i = 0; i < nCos-nFlops; i++ )
Abc_NtkCreatePo( pNtkMapped );
// create flops
for ( i = 0; i < nFlops; i++ )
Abc_NtkAddLatch( pNtkMapped, NULL, ABC_INIT_ZERO );
// connect nodes
for ( i = 0; i < nNodes; i++ )
{
nLeaves = pArray[Pos++];
for ( k = 0; k < nLeaves; k++ )
Abc_ObjAddFanin( Abc_NtkObj( pNtkMapped, nCis + i + 1 ), Abc_NtkObj( pNtkMapped, pArray[Pos++] + 1 ) );
}
for ( i = 0; i < nCos; i++ )
Abc_ObjAddFanin( Abc_NtkCo( pNtkMapped, i ), Abc_NtkObj( pNtkMapped, pArray[Pos++] + 1 ) );
pBuffer = (char *)(pArray + Pos);
for ( i = 0; i < nNodes; i++ )
{
pName = pBuffer;
pBuffer += strlen(pName) + 1;
pGate = Mio_LibraryReadGateByName( pLib, pName, NULL );
Abc_NtkObj( pNtkMapped, nCis + i + 1 )->pData = pGate;
}
assert( Abc_NtkCiNum(pNtkMapped) == nCis );
Abc_NtkForEachCi( pNtkMapped, pObj, i ) {
pName = pBuffer;
pBuffer += strlen(pName) + 1;
Abc_ObjAssignName( pObj, pName, NULL );
}
assert( Abc_NtkCoNum(pNtkMapped) == nCos );
Abc_NtkForEachCo( pNtkMapped, pObj, i ) {
pName = pBuffer;
pBuffer += strlen(pName) + 1;
Abc_ObjAssignName( pObj, pName, NULL );
}
if ( !Abc_NtkCheck( pNtkMapped ) ) {
fprintf( stdout, "Abc_NtkFromMiniMapping(): Network check has failed.\n" );
}
return pNtkMapped;
}
/**Function*************************************************************
Synopsis [File IO.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
Abc_Ntk_t * Abc_NtkReadFromFile( char * pFileName )
{
int nSize = Extra_FileSize( pFileName );
if ( nSize == 0 )
return NULL;
FILE * pFile = fopen( pFileName, "rb" );
char * pArray = ABC_ALLOC( char, nSize );
int nSize2 = fread( pArray, sizeof(char), nSize, pFile );
assert( nSize2 == nSize );
fclose( pFile );
Abc_Ntk_t * pNtk = Abc_NtkFromMiniMapping( (int*)pArray );
ABC_FREE( pArray );
return pNtk;
}
int Abc_NtkWriteToFile( char * pFileName, Abc_Ntk_t * pNtk )
{
Vec_Int_t * vRes = Abc_NtkWriteMiniMapping( pNtk );
FILE * pFile = fopen( pFileName, "wb" );
if ( pFile == NULL ) { printf( "Cannot open input file \"%s\" for writing.\n", pFileName ); return 0; }
int nSize = fwrite( Vec_IntArray(vRes), sizeof(int), Vec_IntSize(vRes), pFile );
assert( nSize == Vec_IntSize(vRes) );
Vec_IntFree( vRes );
fclose( pFile );
return 1;
}
/**Function*************************************************************
Synopsis [Prints mapped network represented in mini-mapped format.]
@ -895,8 +1040,8 @@ void Abc_NtkPrintMiniMapping( int * pArray )
printf( "The first %d object IDs (from 0 to %d) are reserved for the CIs.\n", nCis, nCis - 1 );
for ( i = 0; i < nNodes; i++ )
{
printf( "Node %d has fanins {", nCis + i );
nLeaves = pArray[Pos++];
printf( "Node %d has %d fanins {", nCis + i, nLeaves );
for ( k = 0; k < nLeaves; k++ )
printf( " %d", pArray[Pos++] );
printf( " }\n" );
@ -910,6 +1055,38 @@ void Abc_NtkPrintMiniMapping( int * pArray )
pBuffer += strlen(pName) + 1;
printf( "Node %d has gate \"%s\"\n", nCis + i, pName );
}
for ( i = 0; i < nCis; i++ )
{
pName = pBuffer;
pBuffer += strlen(pName) + 1;
printf( "CI %d has name \"%s\"\n", i, pName );
}
for ( i = 0; i < nCos; i++ )
{
pName = pBuffer;
pBuffer += strlen(pName) + 1;
printf( "CO %d has name \"%s\"\n", i, pName );
}
}
/**Function*************************************************************
Synopsis [Procedures to update internal ABC network using mini-mapped network.]
Description []
SideEffects []
SeeAlso []
***********************************************************************/
void Abc_NtkInputMiniMapping( Abc_Frame_t * pAbc, void *p )
{
Abc_Ntk_t * pNtk;
if ( pAbc == NULL )
printf( "ABC framework is not initialized by calling Abc_Start()\n" );
pNtk = Abc_NtkFromMiniMapping( (int *)p );
Abc_FrameReplaceCurrentNetwork( pAbc, pNtk );
}
/**Function*************************************************************

View File

@ -22,6 +22,7 @@
#include "bool/kit/kit.h"
#include "opt/sfm/sfm.h"
#include "base/io/ioAbc.h"
#include "misc/util/utilTruth.h"
ABC_NAMESPACE_IMPL_START
@ -330,6 +331,7 @@ void Abc_NtkInsertMfs( Abc_Ntk_t * pNtk, Sfm_Ntk_t * p )
// update fanins
vArray = Sfm_NodeReadFanins( p, pNode->iTemp );
pTruth = Sfm_NodeReadTruth( p, pNode->iTemp );
Abc_TtFlipVar5( pTruth, Vec_IntSize(vArray) );
pNode->pData = Abc_SopCreateFromTruthIsop( (Mem_Flex_t *)pNtk->pManFunc, Vec_IntSize(vArray), pTruth, vCover );
if ( Abc_SopGetVarNum((char *)pNode->pData) == 0 )
continue;

View File

@ -144,6 +144,22 @@ Mini_Aig_t * Abc_NtkToMiniAig( Abc_Ntk_t * pNtk )
Mini_AigSetRegNum( p, Abc_NtkLatchNum(pNtk) );
return p;
}
Mini_Aig_t * Abc_MiniAigFromNtk ( Abc_Ntk_t *pNtk )
{
Abc_Ntk_t *pNtkRes = NULL;
Mini_Aig_t *pAig;
if (!Abc_NtkIsStrash(pNtk)) {
pNtk = pNtkRes = Abc_NtkStrash( pNtk, 0, 1, 0 );
if ( pNtkRes == NULL )
{
printf("Strashing has failed.\n" );
return NULL;
}
}
pAig = Abc_NtkToMiniAig(pNtk);
if (pNtkRes) Abc_NtkDelete(pNtkRes);
return pAig;
}
/**Function*************************************************************

View File

@ -789,6 +789,7 @@ Abc_Ntk_t * Abc_NtkFrames( Abc_Ntk_t * pNtk, int nFrames, int fInitial, int fVer
pNtkFrames->pName = Extra_UtilStrsav(Buffer);
// map the constant nodes
Abc_AigConst1(pNtk)->pCopy = Abc_AigConst1(pNtkFrames);
// create new latches (or their initial values) and remember them in the new latches
if ( !fInitial )
{

View File

@ -319,10 +319,6 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
}
else if ( NpnType == 8 )
{
// typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres);
int fHigh = 1, iEnumThres = 25;
Abc_TtHieMan_t * pMan = Abc_TtHieManStart(p->nVars, 5);
for ( i = 0; i < p->nFuncs; i++ )
@ -337,11 +333,6 @@ void Abc_TruthNpnPerform( Abc_TtStore_t * p, int NpnType, int fVerbose )
}
else if ( NpnType == 9 || NpnType == 10 || NpnType == 11 )
{
// typedef unsigned(*TtCanonicizeFunc)(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeWrap(TtCanonicizeFunc func, Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int flag);
unsigned Abc_TtCanonicizeAda(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres);
unsigned Abc_TtCanonicizeCA(Abc_TtHieMan_t * p, word * pTruth, int nVars, char * pCanonPerm, int iThres);
Abc_TtHieMan_t * pMan = Abc_TtHieManStart(p->nVars, 5);
for ( i = 0; i < p->nFuncs; i++ )
{

View File

@ -237,7 +237,7 @@ Abc_Obj_t * Abc_NodeBddToMuxes_rec( DdManager * dd, DdNode * bFunc, Abc_Ntk_t *
{
Abc_Obj_t * pNodeNew, * pNodeNew0, * pNodeNew1, * pNodeNewC;
assert( !Cudd_IsComplement(bFunc) );
assert( b1 == a1 );
//assert( b1 == a1 );
if ( bFunc == a1 )
return Abc_NtkCreateNodeConst1(pNtkNew);
if ( bFunc == a0 )
@ -433,7 +433,8 @@ void * Abc_NtkBuildGlobalBdds( Abc_Ntk_t * pNtk, int nBddSizeMax, int fDropInter
// Cudd_ReduceHeap( dd, CUDD_REORDER_SYMM_SIFT, 1 );
Cudd_AutodynDisable( dd );
}
// Cudd_PrintInfo( dd, stdout );
if ( fVerbose )
Cudd_PrintInfo( dd, stdout );
return dd;
}

Some files were not shown because too many files have changed in this diff Show More