├── .github
└── workflows
│ └── node_ci.yml
├── .gitignore
├── README.md
├── circuit
├── __init__.py
├── circuit
│ ├── __init__.py
│ ├── circuit.py
│ ├── circuit_loader.py
│ ├── convert.py
│ └── dft_circuit.py
├── config.py
├── experiments
│ ├── experiments.py
│ ├── g-experiments.py
│ ├── script_experiments.py
│ └── temp-experiments.py
├── fault_simulation
│ ├── __init__.py
│ ├── deductive_fs.py
│ ├── fault.py
│ ├── fault_simulation.py
│ ├── pfs.py
│ └── ppsf.py
├── inventory
│ ├── atpg_det.py
│ ├── atpg_new.py
│ ├── atpg_v0.py
│ ├── circuit_atpg.py
│ ├── d_alg.py
│ ├── d_alg_Gh.py
│ ├── dalg2.py
│ ├── good_faults
│ │ ├── c1355_good_faults.txt
│ │ ├── c1908_good_faults.txt
│ │ ├── c3540_good_faults.txt
│ │ ├── c432_good_faults.txt
│ │ ├── c499_good_faults.txt
│ │ ├── c5315_good_faults.txt
│ │ ├── c6288_good_faults.txt
│ │ └── c880_good_faults.txt
│ ├── main_experiments_old.py
│ ├── miscellaneous.py
│ ├── modelsim_simulator.py
│ ├── old_methods.py
│ ├── podem.py
│ ├── podem_new.py
│ └── rem.py
├── main_example.py
├── main_saeed.py
├── node
│ ├── __init__.py
│ ├── dft_node.py
│ └── node.py
├── pytest.ini
├── run-ee658.py
├── ssta
│ ├── __init__.py
│ ├── circuit_ssta.py
│ ├── distributions.py
│ ├── main_SSTA.py
│ └── utils_ssta.py
├── tests
│ ├── README.md
│ ├── __init__.py
│ ├── old
│ │ ├── checker_dfs.py
│ │ ├── checker_logicsim.py
│ │ └── main_test_pfs.py
│ ├── pfs_ppsf_test.py
│ ├── read_all_circuits.py
│ └── test_node.py
├── tp_generator.py
├── tpi
│ └── observation.py
└── utils.py
├── data
├── README.md
├── bench
│ ├── c1355.bench
│ ├── c17.bench
│ ├── c1908.bench
│ ├── c2670.bench
│ ├── c3540.bench
│ ├── c432.bench
│ ├── c499.bench
│ ├── c5315.bench
│ ├── c6288.bench
│ ├── c7552.bench
│ └── c880.bench
├── ckt
│ ├── FA.ckt
│ ├── FA_NAND.ckt
│ ├── add2.ckt
│ ├── c1.ckt
│ ├── c1355.ckt
│ ├── c17.ckt
│ ├── c1908.ckt
│ ├── c2.ckt
│ ├── c3.ckt
│ ├── c3540.ckt
│ ├── c4.ckt
│ ├── c432.ckt
│ ├── c499.ckt
│ ├── c5315.ckt
│ ├── c6288.ckt
│ ├── c880.ckt
│ ├── cmini.ckt
│ ├── others
│ │ ├── c2670.ckt
│ │ └── c7552.ckt
│ └── x3mult.ckt
├── config.py
├── convergence.py
├── download_data.py
├── iscas
│ ├── c1.isc
│ ├── c1355.isc
│ ├── c1355a.isc
│ ├── c17.isc
│ ├── c17a.isc
│ ├── c1908.isc
│ ├── c2670.isc
│ ├── c3540.isc
│ ├── c432.isc
│ ├── c499.isc
│ ├── c5.isc
│ ├── c5315.isc
│ ├── c6288.isc
│ ├── c7552.isc
│ ├── c880.isc
│ └── c880a.isc
├── library
│ └── library_cells.py
├── modelsim
│ └── NanGate_15nm_OCL_conditional.v
├── netlist_behavioral
│ ├── c432_logic_sim.py
│ ├── c499_logic_sim.py
│ └── c499_vec.txt
├── translator
│ ├── archive
│ │ ├── translator_from_bench_to_verilog.py
│ │ └── translator_from_verilog_to_spice_netlist.py
│ ├── bench2self_v1.py
│ ├── bench2self_v2.py
│ └── bench2self_v3.py
└── verilog
│ ├── EPFL
│ ├── v0
│ │ ├── adder_synV0.v
│ │ ├── arbiter_synV0.v
│ │ ├── bar_synV0.v
│ │ ├── cavlc_synV0.v
│ │ ├── dec_synV0.v
│ │ ├── int2float_synV0.v
│ │ ├── max_synV0.v
│ │ ├── multiplier_synV0.v
│ │ ├── priority_synV0.v
│ │ ├── sin_synV0.v
│ │ └── voter_synV0.v
│ ├── v1
│ │ ├── adder_synV1.v
│ │ ├── arbiter_synV1.v
│ │ ├── bar_synV1.v
│ │ ├── cavlc_synV1.v
│ │ ├── dec_synV1.v
│ │ ├── int2float_synV1.v
│ │ ├── max_synV1.v
│ │ ├── multiplier_synV1.v
│ │ ├── priority_synV1.v
│ │ ├── sin_synV1.v
│ │ └── voter_synV1.v
│ └── v2
│ │ ├── adder_synV2.v
│ │ ├── arbiter_synV2.v
│ │ ├── bar_synV2.v
│ │ ├── cavlc_synV2.v
│ │ ├── dec_synV2.v
│ │ ├── int2float_synV2.v
│ │ ├── max_synV2.v
│ │ ├── multiplier_synV2.v
│ │ ├── priority_synV2.v
│ │ ├── sin_synV2.v
│ │ └── voter_synV2.v
│ ├── ISCAS85
│ ├── v0
│ │ ├── c1355_synV0.v
│ │ ├── c17_synV0.v
│ │ ├── c1908_synV0.v
│ │ ├── c3540_synV0.v
│ │ ├── c432_synV0.v
│ │ ├── c499_synV0.v
│ │ ├── c5315_synV0.v
│ │ ├── c6288_synV0.v
│ │ ├── c7552_synV0.v
│ │ └── c880_synV0.v
│ ├── v1
│ │ ├── c1355_synV1.v
│ │ ├── c17_synV1.v
│ │ ├── c1908_synV1.v
│ │ ├── c3540_synV1.v
│ │ ├── c432_synV1.v
│ │ ├── c499_synV1.v
│ │ ├── c5315_synV1.v
│ │ ├── c6288_synV1.v
│ │ ├── c7552_synV1.v
│ │ └── c880_synV1.v
│ └── v2
│ │ ├── c1355_synV2.v
│ │ ├── c17_synV2.v
│ │ ├── c1908_synV2.v
│ │ ├── c3540_synV2.v
│ │ ├── c432_synV2.v
│ │ ├── c499_synV2.v
│ │ ├── c5315_synV2.v
│ │ ├── c6288_synV2.v
│ │ ├── c7552_synV2.v
│ │ └── c880_synV2.v
│ └── ISCAS89
│ ├── s1196.v
│ ├── s1238.v
│ ├── s13207.v
│ ├── s1423.v
│ ├── s1488.v
│ ├── s15850.v
│ ├── s27.v
│ ├── s298.v
│ ├── s344.v
│ ├── s349.v
│ ├── s35932.v
│ ├── s382.v
│ ├── s38417.v
│ ├── s38584.v
│ ├── s386.v
│ ├── s400.v
│ ├── s420.v
│ ├── s444.v
│ ├── s510.v
│ ├── s526.v
│ ├── s526_1.v
│ ├── s5378.v
│ ├── s641.v
│ ├── s713.v
│ ├── s820.v
│ ├── s832.v
│ ├── s838.v
│ ├── s9234.v
│ └── s953.v
└── gnn
├── config.py
├── gnn.py
├── gnn_pyg.py
├── graph
└── utils.py
├── main_test.py
├── models
├── lstm_gcn.py
├── pgy
│ └── sage_conv.py
└── vanilla_gcn.py
├── run_gnn.sh
├── run_gnn_pyg.sh
└── utils.py
/.github/workflows/node_ci.yml:
--------------------------------------------------------------------------------
1 | name: NodeTest
2 | on: push
3 |
4 | jobs:
5 | test:
6 | runs-on: ubuntu-latest
7 |
8 | steps:
9 | - name: Check out repository code
10 | uses: actions/checkout@v2
11 |
12 | - name: Setup Python
13 | uses: actions/setup-python@v2
14 | with:
15 | python-version: "3.x"
16 |
17 | - name: Run test suite
18 | run: |
19 | pip install pytest
20 | cd circuit/tests/
21 | pytest -v test_node.py
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | # git ignore
2 |
3 | circuit/run.sh
4 | circuit/script_experiments.py
5 | */*.sh
6 |
7 | # Saeed:
8 | **.swp
9 | **.csv
10 | data/modelsim/
11 | data/stafan-data/
12 | data/graph/*
13 | data/fault_sim/*
14 | # data/verilog/
15 | data/EPFL/
16 | data/patterns/
17 | data/observations/
18 | data/tpfc/
19 | **.png
20 | **.log
21 | gnn/notes.txt
22 | gnn/TEMP_func.py
23 | circuit/results/
24 | circuit/exp-results/
25 | data/ob_stat/
26 | data/cell_ssta/
27 | data/fault_dict/
28 | data/fault_list/
29 | data/scoap-data/
30 | data/graph-data/
31 |
32 | # **.graphml
33 | **.png
34 | *.pdf
35 | # python cache file
36 | __pycache__/:
37 | *.pyc
38 |
39 | # DS_Store file
40 | *.DS_Store
41 | ._*
42 |
43 | # log file
44 | *.log
45 |
46 |
47 | # from github/gitignore repo
48 | # https://github.com/github/gitignore/blob/master/Python.gitignore
49 | # Byte-compiled / optimized / DLL files
50 | __pycache__/
51 | *.py[cod]
52 | *$py.class
53 | circuit/main_personal.py
54 |
55 | # C extensions
56 | *.so
57 |
58 | # Distribution / packaging
59 | .Python
60 | build/
61 | develop-eggs/
62 | dist/
63 | downloads/
64 | eggs/
65 | .eggs/
66 | lib/
67 | lib64/
68 | parts/
69 | sdist/
70 | var/
71 | wheels/
72 | pip-wheel-metadata/
73 | share/python-wheels/
74 | *.egg-info/
75 | .installed.cfg
76 | *.egg
77 | MANIFEST
78 |
79 | # PyInstaller
80 | # Usually these files are written by a python script from a template
81 | # before PyInstaller builds the exe, so as to inject date/other infos into it.
82 | *.manifest
83 | *.spec
84 |
85 | # Installer logs
86 | pip-log.txt
87 | pip-delete-this-directory.txt
88 |
89 | # Unit test / coverage reports
90 | htmlcov/
91 | .tox/
92 | .nox/
93 | .coverage
94 | .coverage.*
95 | .cache
96 | nosetests.xml
97 | coverage.xml
98 | *.cover
99 | *.py,cover
100 | .hypothesis/
101 | .pytest_cache/
102 | cover/
103 |
104 | # Translations
105 | *.mo
106 | *.pot
107 |
108 | # Django stuff:
109 | *.log
110 | local_settings.py
111 | db.sqlite3
112 | db.sqlite3-journal
113 |
114 | # Flask stuff:
115 | instance/
116 | .webassets-cache
117 |
118 | # Scrapy stuff:
119 | .scrapy
120 |
121 | # Sphinx documentation
122 | docs/_build/
123 |
124 | # PyBuilder
125 | .pybuilder/
126 | target/
127 |
128 | # Jupyter Notebook
129 | .ipynb_checkpoints
130 |
131 | # IPython
132 | profile_default/
133 | ipython_config.py
134 |
135 | # pyenv
136 | # For a library or package, you might want to ignore these files since the code is
137 | # intended to run in multiple environments; otherwise, check them in:
138 | # .python-version
139 |
140 | # pipenv
141 | # According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
142 | # However, in case of collaboration, if having platform-specific dependencies or dependencies
143 | # having no cross-platform support, pipenv may install dependencies that don't work, or not
144 | # install all needed dependencies.
145 | #Pipfile.lock
146 |
147 | # PEP 582; used by e.g. github.com/David-OConnor/pyflow
148 | __pypackages__/
149 |
150 | # Celery stuff
151 | celerybeat-schedule
152 | celerybeat.pid
153 |
154 | # SageMath parsed files
155 | *.sage.py
156 |
157 | # Environments
158 | .env
159 | .venv
160 | env/
161 | venv/
162 | ENV/
163 | env.bak/
164 | venv.bak/
165 |
166 | # Spyder project settings
167 | .spyderproject
168 | .spyproject
169 |
170 | # Rope project settings
171 | .ropeproject
172 |
173 | # mkdocs documentation
174 | /site
175 |
176 | # mypy
177 | .mypy_cache/
178 | .dmypy.json
179 | dmypy.json
180 |
181 | # Pyre type checker
182 | .pyre/
183 |
184 | # pytype static type analyzer
185 | .pytype/
186 |
187 | # Cython debug symbols
188 | cython_debug/
189 |
190 | # static files generated from Django application using `collectstatic`
191 | media
192 | static
193 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # PyCAD: Python Package for Digital Circuit and Computer Aided Design (CAD) Research
2 | This package is written to cover different methods used for circuit netlists (graphs). The package reads the standard format circuit netlists and can perfom different *computer aided design* operations, including:
3 | - Basic operations:
4 | - Gate level logical simulation (binary and ternary)
5 | - Design for test (DFT):
6 | - Fault analysis, e.g. dominancy and equivalency relations
7 | - Testability measures (SCOAP)
8 | - Fault simulation (PFS, DFS, PPSF)
9 | - Systematic fault dropping (CPT)
10 | - Automatic test pattern generation (ATPG), different versions of D-Algorithm and PODEM
11 | - Test pattern generation
12 | - Logic built-in self test (LBIST):
13 | - Random test pattern analysis and testability measures (STAFAN)
14 | - Translation between different formats of circuits (.bench, .verilog, .ckt)
15 | - Statistical static timing analysis (SSTA)
16 |
17 | The package is capable of producing test-related datasets later used in down stream machine learning applications.
18 |
19 | ## Developers and Affiliation:
20 | PyCAD development was first started by a group of graduate students at the University of Southern California (USC) computer engineering as a joint research project with [**The System Power Optimization and Regulation Technology (SPORT) Lab**][1].
21 |
22 | **Main developers:**
23 | [M. Saeed Abrishami][10]
24 | [Ghazal Rafiei][21]
25 |
26 | **Graduate students who worked with this platform during their EE658 course**
27 | [Luke Grantham][20]
28 | [Yang Shen][14]
29 |
30 | **Advisors:**
31 | [Prof. Massoud Pedram][11]
32 | [Prof. Shahin Nazarian][12]
33 |
34 | [1]: http://sportlab.usc.edu/
35 | [10]: http://sportlab.usc.edu/~msabrishami/
36 | [11]: http://www.mpedram.com/
37 | [12]: http://sportlab.usc.edu/~shahin/
38 | [13]: https://www.linkedin.com/in/jiayi-wang-a40473101/
39 | [14]: https://www.linkedin.com/in/yshen245/
40 | [15]: https://www.linkedin.com/in/jiaming-li-73b873191/
41 | [16]: https://www.linkedin.com/in/han-zhang-usc/
42 | [17]: https://www.linkedin.com/in/shubo-li-760991193/
43 | [18]: https://www.linkedin.com/in/yida-yan-489b06191/
44 | [20]: https://www.linkedin.com/in/lukegrantham/
45 | [21]: https://github.com/ghazalrafiei
46 | ## Setup Environment
47 | Python3
48 |
49 | ## Circuit Input Format
50 | The initial implementation was aimed for test of digital circuits. on a modified version of *.CKT*, referred as *CKT658* [reference]. A translator is availabel to convert standard *.bench* format to *CKT658* and implemented inside the platform.
51 | `translator.py`
52 |
53 |
54 |
55 | ## Run code
56 |
57 | At the command line, type below commands:
58 |
59 | `cd src/`
60 |
61 | `python3 main.py`
62 |
63 | To run ATPG, type command:
64 |
65 | `python3 atpg_v0.py c17`
66 |
67 | c17 can be replaced with other circuits' name such as c432, c880, c1355...
68 |
69 | ## source codes:
70 |
71 | `classdef.py` is the source code ***class node***, it specifies attributes and methods for a node.
72 |
73 |
74 |
75 | `translator.py` is the source code to translate `bench` file to `ckt`
76 |
77 |
78 | `cread.py` is the source code to read input ckt file and instatiate ***class node***
79 |
80 |
81 | `lev.py` is the source code for levelization of nodes
82 |
83 |
84 | `logicsim.py` is the source code for logic simulation
85 |
86 |
87 | `flr.py` is the source code for fault list reduction. The function is tested with *c17* circuit
88 |
89 |
90 | `dfs.py` is the source code for deductive fault simulation
91 |
92 |
93 | `pfs.py` is the source code for parallel fault simulation. The faults dectected by given input sequence is generated to an output file called `pfsoutput.txt`. The function is tested with *c17* circuit
94 |
95 |
96 | `faultdict_gen.py` is the source code for generating fault dictionary. Generate a `full_fault_list.txt` for `pfs.py` to get the fault dictioanry. Output result in `fault_dict.txt`. PS: Changed pfs parameter format to achieve this function. Return a dictionary for Equvilance checking. The function is tested with *c17* circuit -- Problem: different size of bianry????
97 |
98 |
99 | `mini_faultlist_gen.py` is the source code for generating minimum size of fault list. Uitilize faut list from flr and fault dictionary to get minimum fault list. Output result of mini fault list is in `mini_faultlist.txt`.Output result of reduced fault list is in `reduce_faultlist_file` PS: The function is tested with *c17* circuit
100 |
101 | `pattern_information.py` use greedy to find the reduced test pattern, always find the test pattern that can detect the most remaining fault, the program will end when all the faults are detected, time complexity O(V + E)
102 |
103 |
104 | `equv_domain.py` is the source code for generating all the equivalence and domainance by going through the fault dictionary. PS: The function is tested with *c17* circuit
105 |
106 | `checker.py` is the script to check the fault coverage of D algrithm and Podem. For smaller circuits: If D / Podem algorithm succceeded, it checks if the test patterns D / Podem algorithm generated are valid (found in fault dictionary). If D / Podem algorithm failed, it checks if the fault is really undetectable by checking the fault dictionary. For bigger circuits, since creating a fault dictionary takes too long time, it simply performs checks on the detected faults and its corresponding patterns returned by D / Podem, using parallel fault simulation to check if those patterns are valid for its fault therefore proves the correctness of P / Podem.
107 |
108 | `d_alg.py` is the source code for d algorithm in recursive manner.
109 |
110 | `main.py` is the source code for main function for testing. `c17.ckt658` is used as testing input
111 |
112 |
113 | `MT.cpp` is the source code for multithreading fault dictionary generation. Each thread calls `parallel_processing.py` and generate a partial fault dictionary. This could speed up the fault dictionary generation significantly.
114 |
115 | To run this code, type command:
116 |
117 | `g++ MT.cpp -o MT -pthread && ./MT [CIRCUIT_NAME]`
118 |
119 |
120 |
121 | `atpg_vo.py` is the source code for implementtation of ATPG. Given circuit, atpg will return fault coverage, timing and respondning the number of input pattern. The detail explanations have been written in atpg_v0_report.pdf in documents repo
122 |
123 | ## Repository Structures
124 |
125 | source codes are included in `src/` folder
126 |
127 | input & output files are included in `tests/` folder
128 |
129 | circuit file. like `.ckt` and `.bench`, and description files of the circuits are included in `circuits/` folder
130 |
131 | fault dictionaries are included in `fault_dic/` folder
132 |
133 | documents includes some rerferences and reports
134 |
--------------------------------------------------------------------------------
/circuit/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msabrishami/DFT/919db427bd5af75bb5ca696631fd85048d760337/circuit/__init__.py
--------------------------------------------------------------------------------
/circuit/circuit/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msabrishami/DFT/919db427bd5af75bb5ca696631fd85048d760337/circuit/circuit/__init__.py
--------------------------------------------------------------------------------
/circuit/config.py:
--------------------------------------------------------------------------------
1 | import os
2 |
3 | ROOT_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__)))
4 | DATA_DIR = os.path.join(ROOT_DIR, 'data')
5 |
6 | LIB_CELLS_PATH = os.path.join(DATA_DIR, "library")
7 | MODELSIM_DIR = os.path.join(DATA_DIR, "modelsim")
8 |
9 | MODELSIM_INPUT_DIR = "input"
10 | MODELSIM_GOLD_DIR = "gold"
11 | MODELSIM_OUTPUT_DIR = "output"
12 |
13 | """Circuits Absolute Directories"""
14 | CKT_DIR = os.path.join(DATA_DIR, "ckt")
15 | VERILOG_DIR = os.path.join(DATA_DIR, 'verilog')
16 |
17 | ISAS89_DIR = os.path.join(VERILOG_DIR, 'ISCAS89')
18 | ISCAS85_DIR = os.path.join(VERILOG_DIR, 'ISCAS85')
19 | EPFL_DIR = os.path.join(VERILOG_DIR, 'EPFL')
20 |
21 | ISCAS85_V0_DIR = os.path.join(ISCAS85_DIR, 'v0')
22 | ISCAS85_V1_DIR = os.path.join(ISCAS85_DIR, 'v1')
23 | ISCAS85_V2_DIR = os.path.join(ISCAS85_DIR, 'v2')
24 |
25 | EPFL_V0_DIR = os.path.join(EPFL_DIR, 'v0')
26 | EPFL_V1_DIR = os.path.join(EPFL_DIR, 'v1')
27 | EPFL_V2_DIR = os.path.join(EPFL_DIR, 'v2')
28 |
29 | ISCAS89_DIR = os.path.join(VERILOG_DIR, 'ISCAS89')
30 |
31 | ALL_CIRCUIT_DIRS = [CKT_DIR,
32 | ISCAS85_V0_DIR, ISCAS85_V1_DIR, ISCAS85_V2_DIR,
33 | EPFL_V0_DIR, EPFL_V1_DIR, EPFL_V2_DIR,
34 | ISCAS89_DIR]
35 |
36 | """Others in data/"""
37 | PATTERN_DIR =os.path.join(DATA_DIR, "patterns")
38 | FAULT_DICT_DIR = os.path.join(DATA_DIR, "fault_dict")
39 | FAULT_SIM_DIR = os.path.join(DATA_DIR, "fault_sim")
40 | STAFAN_DIR = os.path.join(DATA_DIR, "stafan-data")
41 | FIG_DIR = os.path.join(DATA_DIR, "figures")
42 | SCOAP_DIR = os.path.join(DATA_DIR, "scoap-data")
43 | GRAPH_DIR = os.path.join(DATA_DIR, "graph-data")
44 |
45 | """Test Point Insertion Poblem"""
46 | HTO_TH = 0.1
47 | HTC_TH = 0.05
48 | STAFAN_B_MIN = 0.0001
49 | STAFAN_C_MIN = 0.001
50 |
51 | PPSF_STEPS = [50, 100, 200, 500,
52 | 1e3, 2e3, 5e3, 1e4, 2e4, 5e4,
53 | 1e5, 2e5, 5e5, 1e6, 2e6, 5e6]
54 | SAMPLES = 100
55 |
56 | V_FORMATS = ["EPFL", "ISCAS85"]
57 |
58 | """Logic Library Related"""
59 | CELL_NAMES = {
60 | "XOR": ["xor", "XOR2", "XOR2_X1"],
61 | "XNOR": ["xnor", "XNOR2", "XNOR2_X1"],
62 | "OR": ["or", "OR2", "OR2_X1", "OR", "OR2_X2", "OR3_X1", "OR4_X1"],
63 | "NOR": ["nor", "NOR2", "NOR2_X1", "NOR2_X2", "NOR3_X1", "NOR4_X1"],
64 | "AND": ["and", "AND2", "AND2_X1", "AND", "AND2_X2", "AND3_X1", "AND4_X1"],
65 | "NAND": ["nand", "NAND2", "NAND2_X2", "NAND3_X1", "NAND4_X1", "NAND2_X1"],
66 | "NOT": ["not", "inv", "NOT", "INV_X1", "INV_X2", "INV_X4"],
67 | "BUFF": ["buff", "buf",
68 | "CLKBUF_X12", "CLKBUF_X1", "CLKBUF_X2","CLKBUF_X4","CLKBUF_X8","CLKBUF_X16",
69 | "BUF_X1", "BUF_X2", "BUF_X4", "BUF_X8"]
70 | }
71 |
72 | # ALL_ISCAS85=["c17","c432","c499","c880","c1355","c1908","c2670",
73 | # "c3540","c5315","c6288","c7552"]
74 | ALL_ISCAS85=["c17","c432","c499","c880","c1355","c1908","c3540","c5315","c6288","c7552"]
75 | ALL_EPFL_EZ=["arbiter", "sin", "bar","dec", "int2float",
76 | "multiplier", "cavlc", "adder", "max", "priority", "voter"]
77 | ALL_EPFL_HARD = ["hyp", "square", "router", "log2", "div", "sqrt", "mem_ctrl", "i2c", "ctrl"]
78 |
79 | SSTA_DATA_DIR = os.path.join(DATA_DIR, "cell_ssta")
80 |
81 | PVS = "vth0-N0.03_lg-N0.05_w-N0.05_toxe-N0.10_ndep-N0.05_MC20000"
82 | TECH = "MOSFET_45nm_HP"
83 |
84 | AUTO_TP = {
85 | "c432_synV0": 890,
86 | "c432_synV1": 1090,
87 | "c432_synV2": 890,
88 | "c499_synV0": 1320,
89 | "c499_synV1": 2050,
90 | "c499_synV2": 2080,
91 | "c880_synV0": 4030,
92 | "c880_synV1": 3020,
93 | "c880_synV2": 3370,
94 | "c1355_synV0": 1290,
95 | "c1355_synV1": 2000,
96 | "c1355_synV2": 2070,
97 | "c1908_synV0": 3030,
98 | "c1908_synV1": 3610,
99 | "c1908_synV2": 3690,
100 | "c3540_synV0": 2830,
101 | "c3540_synV1": 2680,
102 | "c3540_synV2": 2700,
103 | "c5315_synV0": 1250,
104 | "c5315_synV1": 1310,
105 | "c5315_synV2": 1190,
106 | "c6288_synV0": 240,
107 | "c6288_synV1": 270,
108 | "c6288_synV2": 250}
109 |
110 | X_VALUE = 'X'
111 |
112 | PPSF_CI_TP_STEPS = [100, 200, 500, 1e3, 2e3, 5e3, 1e4, 2e4, 5e4, 1e5, 2e5, 5e5, 1e6]
113 |
--------------------------------------------------------------------------------
/circuit/experiments/temp-experiments.py:
--------------------------------------------------------------------------------
1 | # from g-exp
2 |
3 | # # TODO-Ghazal: not checked by MSA
4 | # def diff_tp_stafan(circuit, tps): #TODO: Must be changed
5 | # """
6 | # Fault coverage estimation
7 | # STAFAN measures are calculates many times with different tpLoad count of test patterns.
8 | # Then, the fault coverage is calculated using STAFAN values with the correspoing tp count.
9 | # TODO: list of tps should be generated automatically according to ?
10 | # """
11 |
12 | # set = 0
13 | # fc_sequence = []
14 | # tp_sequence = []
15 | # for tp in tps:
16 | # f = f"{tp}-{set}"
17 | # path = f"{config.STAFAN_DIR}/{circuit.c_name}"
18 | # if not os.path.exists(path):
19 | # os.makedirs(path)
20 | # fname = f"{path}/{circuit.c_name}-tp{f}.stafan"
21 | # if not os.path.exists(fname):
22 | # tpc = re.findall(r"\d+", f)[0]
23 | # circuit.STAFAN(int(tpc))
24 | # circuit.save_STAFAN(tp=tp, fname=fname)
25 | # else:
26 | # circuit.load_TMs(fname)
27 |
28 | # try:
29 | # fc_sequence.append(circuit.STAFAN_FC(tp)*100)
30 | # tp_sequence.append(tp)
31 | # except:
32 | # continue
33 |
34 | # plot = sns.lineplot(x=tp_sequence, y=fc_sequence,
35 | # color="green", label = "STAFAN (different tpLoads)")
36 | # plot = sns.scatterplot(x=tp_sequence, y=fc_sequence, color="green") #draw dots
37 |
38 | # plt.xscale("log")
39 | # plot.set_ylabel(f"Fault Coverage (FC%)", fontsize=13)
40 | # plot.set_xlabel("Test Pattern Count #TP", fontsize=13)
41 | # plot.set_title(
42 | # f"Dependency of fault coverage on random test patterns\n\
43 | # for circuit {circuit.c_name}\n \
44 | # method: STAFAN (different tpLoads)", fontsize=13)
45 |
46 | # # path = f"{config.FIG_DIR}/{circuit.c_name}/estimation-diff-tploads/"
47 | # path = "./results/figures/"
48 | # if not os.path.exists(path):
49 | # os.makedirs(path)
50 |
51 | # fname = path+f"tpfc-stafan-diff-tpLoad-{circuit.c_name}.png"
52 | # print(f"Figure saved in {fname}")
53 | # plt.tight_layout()
54 | # plt.savefig(fname)
55 |
56 | # experiments for reconvergent fanouts.
57 | """V0"""
58 | if RUN == "V0":
59 | po_nums = []
60 | print('#All PO', len(circuit.PO))
61 |
62 | for n in circuit.PI:
63 | print('node=',n.num, '--> #po=', len(circuit.get_fanout_PO(n)))
64 | po_nums.append(len(circuit.get_fanout_PO(n)))
65 |
66 | import matplotlib.pyplot as plt
67 | # plt.hist(x=po_nums)
68 | # plt.title(circuit.c_name)
69 | # plt.show()
70 |
71 | print('_'*50)
72 | pi_nums = []
73 | print('#All PI', len(circuit.PI))
74 |
75 | for n in circuit.PO:
76 | print('node=',n.num, '<-- #pi=', len(circuit.get_fanin_PI(n)))
77 | pi_nums.append(len(circuit.get_fanin_PI(n)))
78 |
79 | # plt.hist(x=pi_nums)
80 | # plt.title(circuit.c_name)
81 | # plt.show()
82 | print('_'*50)
83 |
84 | for n in circuit.nodes_lev:
85 | print(f'node:{n.num}, lev={n.lev}, reach to {len(circuit.get_fanout_PO(n))} POs, is fed by {len(circuit.get_fanin_PI(n))} PIs')
86 |
87 | print('_'*50)
88 |
89 | fanins_of_fanouts = []
90 | for n in circuit.nodes_lev:
91 | print(f'node:{n.num}, len(fanins of fanouts) = {len(circuit.imply_and_check_v0(n))}')
92 | fanins_of_fanouts.append(len(circuit.imply_and_check_v0(n)))
93 | plt.hist(x=fanins_of_fanouts)
94 | plt.title(circuit.c_name)
95 | plt.show()
96 |
97 | """V1"""
98 | if RUN == 'V1': # Not correct
99 | fl = FaultList(circuit)
100 | # fl.add_n_random(100)
101 | fl.add_all()
102 | for random_fault in fl.faults:
103 | tp = circuit.imply_and_check_v1(random_fault)
104 | constants = 0
105 | variables = 0
106 | ineffective = 0
107 | for t in tp:
108 | if t == 1 or t == 0:
109 | constants+=1
110 | elif t == config.X_VALUE:
111 | variables+=1
112 | elif t == '_':
113 | ineffective += 1
114 | # print(random_fault.__str__())
115 | # for n in circuit.nodes_lev:
116 | # print(n.num, n.value, n.gtype)
117 |
118 | """PART 2"""
119 | # print(tp)
120 | tg = TPGenerator(circuit)
121 | be_tested_tps = tg.gen_partial(tp)
122 | # print('TP:')
123 | # # print('PARTIALS:')
124 | # print(be_tested_tps)
125 | # for k in be_tested_tps:
126 | # print(k)
127 | faults = FaultList()
128 | faults.add_fault(random_fault)
129 | # for fault in faults.faults:
130 | # print(fault.__str__())
131 | # x = input()
132 |
133 | # print(be_tested_tps)
134 | # print(random_fault.__str__())
135 | pfs = PFS(circuit, faults)
136 | # for f in faults.faults:
137 | # print(f)
138 |
139 | is_detectable = False
140 | for tp_b in be_tested_tps:
141 | fl_temp = pfs._one_tp_run(tp_b)
142 | if random_fault in fl_temp:
143 | is_detectable = True
144 | break
145 |
146 | if not is_detectable:
147 | print(f'Fault {random_fault.__str__()} is not detectable.')
148 | # print(detected_faults)
149 | print('______________________')
150 |
151 | # ppsf = PPSF(circuit, faults)
152 | # pfs.run(be_tested_tps, verbose=True)
153 | # ppsf.run(be_tested_tps, verbose=True)
154 |
155 | # print(f'fault={random_fault.__str__():<5}, gate type={circuit.fault_to_node(random_fault).gtype:<4}'
156 | # f', --> all={len(tp)}, {constants=}, {variables=}, {ineffective=}, input reduction percent={100*(len(tp)-variables)/len(tp):.1f}%')
157 | # print(tp)
158 | # new_tps.append(tp)
159 |
160 | if RUN == 'V2':
161 | circuit.nodes_lev[11].value = 0
162 | print('Before:')
163 | print([f'{n.num}:{n.value}' for n in circuit.nodes_lev])
164 |
165 | circuit.imply_and_check_v2(circuit.nodes_lev[5])
166 | print('After')
167 | print([f'{n.num}:{n.value}' for n in circuit.nodes_lev])
168 |
169 | ################# Manually testing ####################
170 | # for p in circuit.PI:
171 | # print(p.num)
172 | # tp = [1, 1, 1, 1, 1]
173 | # print(circuit.logic_sim(tp))
174 | # tp = [1, 0, 1, 1, 1]
175 | # print(circuit.logic_sim(tp))
176 |
--------------------------------------------------------------------------------
/circuit/fault_simulation/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msabrishami/DFT/919db427bd5af75bb5ca696631fd85048d760337/circuit/fault_simulation/__init__.py
--------------------------------------------------------------------------------
/circuit/fault_simulation/deductive_fs.py:
--------------------------------------------------------------------------------
1 | import os
2 | import config
3 | from fault_simulation.fault_simulation import FaultSim
4 |
5 | class DFS(FaultSim):
6 | def __init__(self, circuit):
7 | FaultSim.__init__(self, circuit)
8 | self.fs_type = 'dfs'
9 |
10 | def fs_for_atpg(self, ipt_pattern):
11 | return self.single(ipt_pattern)
12 |
13 | def single(self, input_pattern):
14 | """ running deductive fault simulation on the circuit
15 | needs to make sure the levelization is updated """
16 | self.circuit.logic_sim(input_pattern)
17 | fault_set = set()
18 | for node in self.circuit.nodes_lev:
19 | node.dfs()
20 | for node in self.circuit.PO:
21 | # print(node.faultlist_dfs)
22 | fault_set = fault_set.union(node.faultlist_dfs)
23 | # return a fault set
24 | return fault_set
25 |
26 | def run(self, tp_num=1, t_mode='rand', r_mode='b'):
27 | """
28 | Execute fs in rand or full mode
29 | rand: the total faults can be detected by several random patterns
30 | full: the faults can be detected by each single pattern; all possible patterns are included
31 | """
32 |
33 | if t_mode == 'rand':
34 | # self.fs_folder(tp_mode='rand', r_mode='b')
35 | self.fs_folder()
36 | report_fname = self.circuit.c_name + '_' + str(tp_num) + '_dfs_'+ r_mode + '.log'
37 | # tp_fname = tp_path + self.c_name + '_' + str(tp_num) + "_tp_b.txt"
38 | tp_fname = self.circuit.c_name + '_' + str(tp_num) + "_tp_b.txt"
39 |
40 | self.fs_tp_gen(tp_num = tp_num, t_mode = 'rand', r_mode = r_mode)
41 | # tp_fname is bare name, the path is given in the method
42 | pattern_list = self.fs_input_fetch(tp_fname)
43 | # run fs multiple
44 | self.multiple(pattern_list=pattern_list, fname_log=report_fname, mode="b")
45 |
46 | elif t_mode == 'full':
47 | self.fs_folder(tp_mode='full', r_mode='b')
48 | report_fname = self.circuit.c_name + '_full_dfs_' + r_mode + '.log'
49 | tp_fname = self.circuit.c_name + '_full_tp_' + r_mode + '.txt'
50 | # generate all possible patterns in order
51 | self.fs_tp_gen(tp_num = tp_num, t_mode = 'full', r_mode = r_mode)
52 | pattern_list = self.fs_input_fetch(tp_fname)
53 | # run dfs
54 | self.multiple_separate(pattern_list=pattern_list, fname_log=report_fname, mode="b")
55 |
56 | else:
57 | raise NameError("Mode is not acceptable! Mode = 'rand' or 'full'!")
58 |
59 |
60 | ######################## just for golden file ########################################################
61 | def fs_exe_golden(self, tp_num=1, no=1, t_mode='rand', r_mode='b'):
62 | """
63 | Execute fs in rand or full mode
64 | rand: the total faults can be detected by several random patterns
65 | full: the faults can be detected by each single pattern; all possible patterns are included
66 | """
67 |
68 | if t_mode == 'rand':
69 | report_fname = self.circuit.c_name + '_' + str(tp_num) + '_' + str(no) +'_dfs_'+ r_mode + '.log'
70 | # tp_fname = tp_path + self.c_name + '_' + str(tp_num) + "_tp_b.txt"
71 | tp_fname = self.circuit.c_name + '_' + str(tp_num) + '_' + str(no) + "_tp_b.txt"
72 | self.fs_folder(tp_mode='rand', r_mode='b')
73 |
74 | self.fs_tp_gen_golden(tp_num = tp_num, no=no, t_mode = 'rand', r_mode = r_mode)
75 | # tp_fname is bare name, the path is given in the method
76 | pattern_list = self.fs_input_fetch(tp_fname)
77 | # run fs multiple
78 | self.multiple(pattern_list=pattern_list, fname_log=report_fname, mode="b")
79 |
80 | elif t_mode == 'full':
81 | report_fname = self.circuit.c_name + '_full_dfs_' + r_mode + '.log'
82 | tp_fname = self.circuit.c_name + '_full_tp_' + r_mode + '.txt'
83 | self.fs_folder(tp_mode='full', r_mode='b')
84 | # generate all possible patterns in order
85 | self.fs_tp_gen(tp_num = tp_num, t_mode = 'full', r_mode = r_mode)
86 | pattern_list = self.fs_input_fetch(tp_fname)
87 | # run dfs
88 | self.multiple_separate(pattern_list=pattern_list, fname_log=report_fname, mode="b")
89 |
90 | else:
91 | raise NameError("Mode is not acceptable! Mode = 'rand' or 'full'!")
92 |
93 | def FD_new_generator(self):
94 | """
95 | Creat a new FD in excel using dfs results
96 | """
97 | # output golden file
98 | fw_path = config.FAULT_DICT_DIR + '/' + self.circuit.c_name + '/'
99 | fr_path = config.FAULT_DICT_DIR + '/' + self.circuit.c_name + '/dfs/'
100 | fr = open(fr_path + self.circuit.c_name + '_full_dfs_b.log','r')
101 | # To create Workbook
102 | workbook = xlwt.Workbook()
103 | sheet = workbook.add_sheet("Sheet Name")
104 | # Specifying style
105 | # style = xlwt.easyxf('font: bold 1')
106 | # Specifying column
107 | PI_string = ""
108 | for node in self.circuit.PI:
109 | PI_string = PI_string + node.num + ','
110 | PI_string = PI_string[:-1]
111 | print(PI_string)
112 | # print(self.nodes)
113 | sheet.write(0, 0, PI_string)
114 | i = 1
115 | fault_mapping = {}
116 | for node in self.circuit.nodes_lev:
117 | sheet.write(0, i, node.num + '@' + '0')
118 | fault_mapping[node.num + '@' + '0'] = i
119 | sheet.write(0, i+1, node.num + '@' + '1')
120 | fault_mapping[node.num + '@' + '1'] = i+1
121 | print(0, i, node.num + '@' + '0')
122 | print(0, i+1, node.num + '@' + '1')
123 | i = i + 2
124 | j = 1
125 | sheet.write(j, 0, fr.readline())
126 | for line in fr.readlines():
127 | if line == '\n':
128 | j = j + 1
129 | elif '@' in line:
130 | sheet.write(j, fault_mapping[line[:-1]], 'X')
131 | else:
132 | sheet.write(j, 0, line)
133 |
134 | workbook.save(os.path.join(fw_path, self.circuit.c_name + '_FD_new.xls'))
--------------------------------------------------------------------------------
/circuit/fault_simulation/fault.py:
--------------------------------------------------------------------------------
1 | class Fault():
2 | def __init__(self, node_num, stuck_val):
3 | self.node_num = str(node_num)
4 | self.stuck_val = str(stuck_val)
5 | self.D_count = 0
6 | # Issue: in PPSFm D_count is set as an array
7 | self.D_count_list = [] # used in ppsf-bad!
8 |
9 | def __str__(self):
10 | return self.node_num + "@" + self.stuck_val
11 |
12 | def __repr__(self):
13 | return self.__str__()
14 |
15 |
16 | class FaultList:
17 | """ Fault list """
18 | def __init__(self, circuit=None, fname=None, fault_list=None, fault_count=None, nodes=None):
19 | """
20 | fname : str
21 | if not None, all faults from the given file is read and added
22 | fault_list: list of Fault
23 | if not None, all faults from the given list is added
24 | circuit : Circuit
25 | if the circuit is given, faults are added according to fault_count
26 | fault_count : int or None
27 | if None, all possible faults are added. If int, n random unique faults are added
28 | nodes : list of Node
29 | if given, all faults related to the given nodes are added
30 | """
31 | self.faults = []
32 | self.circuit = circuit
33 |
34 | if fname:
35 | self.add_file(fname)
36 |
37 | elif fault_list:
38 | for f in fault_list.faults:
39 | self.add_fault(f)
40 |
41 | elif circuit:
42 | if fault_count == 'all':
43 | self.add_all()
44 | elif isinstance(fault_count, int):
45 | self.add_n_random(fault_count)
46 |
47 | elif nodes:
48 | self.add_nodes(nodes)
49 |
50 | def add(self, node_num, stuck_val):
51 | self.faults.append(Fault(node_num, stuck_val))
52 |
53 | def add_str(self, fault_str):
54 | """ add a fault if the fault format is @ """
55 | num, val = fault_str.strip().split("@")
56 | self.faults.append(Fault(num, val))
57 |
58 | def add_str_list(self, faults_str_list):
59 | """ add faults with their string in faults_str_list """
60 | for fault in faults_str_list:
61 | self.add_str(fault)
62 |
63 | def add_all(self):
64 | for node in self.circuit.nodes_lev:
65 | self.add_node(node)
66 |
67 | def add_n_random(self, n=1):
68 | """Add n random unique faults"""
69 | if n > 2*len(self.circuit.nodes_lev):
70 | print("Required random faults are more than number of nodes in your circuit")
71 | n = 2*len(self.circuit.nodes_lev)
72 |
73 | import random
74 | for n_num in random.choices(list(self.circuit.nodes.keys()), k=n):
75 | self.add(node_num=n_num, stuck_val=random.randint(0,1))
76 |
77 | def add_fault(self, fault: Fault):
78 | self.faults.append(fault)
79 |
80 | def copy_fault(self, fault: Fault):
81 | new_f = Fault(fault.node_num, fault.stuck_val)
82 | new_f.D_count_list = fault.D_count_list.copy()
83 | self.add_fault(new_f)
84 |
85 | def remove_faults(self, faults):
86 | # TODO: this is not a good method, to be modified after
87 | # the main data structure is changed to a dict or set
88 | # Does not change the current faults
89 | current_faults = set([str(x) for x in self.faults])
90 | if isinstance(faults, list):
91 | faults = set([str(x) for x in faults])
92 | new_faults = current_faults - faults
93 | # self.faults = []
94 | # for fault in new_faults:
95 | # self.faults.add_str(fault)
96 | return list(new_faults)
97 |
98 | def add_node(self, node):
99 | """ adds both S@0 and S@1 faults for node """
100 | self.add(node.num, 0)
101 | self.add(node.num, 1)
102 |
103 | def add_nodes(self, nodes):
104 | assert isinstance(nodes, list), "the input should be a list of nodes"
105 | for node in nodes:
106 | self.add_node(node)
107 |
108 | def add_file(self, fname):
109 | """ read faults from a file and add it to the fault list
110 | file format: each fault @ in separate lines
111 |
112 | Arguments
113 | ---------
114 | fname : str
115 | the path and file name of the fault file
116 | """
117 | with open(fname, "r") as infile:
118 | for line in infile:
119 | self.add_str(line)
120 |
121 | def write_file(self, fname, verbose=False):
122 | with open(fname, "+w") as outfile:
123 | for fault in self.faults:
124 | outfile.write(str(fault) + "\n")
125 | if verbose:
126 | print("Fault list is stored in {}".format(fname))
127 |
128 | def write_file_extra(self, fname, verbose=False):
129 | with open(fname, "w") as outfile:
130 | for fault in self.faults:
131 | outfile.write(str(fault) + "," + ",".join([str(x) for x in fault.D_count])+"\n")
132 | if verbose:
133 | print("Fault list with D_counts is stored in {}".format(fname))
134 |
135 | def calc_fc(self):
136 | detected_count = 0
137 | for fault in self.faults:
138 | if fault.D_count > 0:
139 | detected_count += 1
140 | return detected_count / len(self.faults)
141 |
142 | def get_D_count(self):
143 | res = {}
144 | for fault in self.faults:
145 | res[str(fault)] = fault.D_count
146 | return res
147 |
--------------------------------------------------------------------------------
/circuit/fault_simulation/fault_simulation.py:
--------------------------------------------------------------------------------
1 | import math
2 | import os
3 | import sys
4 | from abc import ABC, abstractmethod
5 |
6 | import config
7 | from fault_simulation import fault
8 |
9 |
10 | class FaultSim(ABC):
11 | wordlen = int(math.log2(sys.maxsize))+1 # move to utils
12 | bitwise_not = 2**wordlen-1
13 |
14 | def __init__(self, circuit, faults=None): #TODO: rename fault mode
15 | """
16 | Parameters
17 | ----------
18 | fault_mode : int or FaultList or str
19 | str: all: add all possible faults
20 | None: None
21 | integer: add n random faults
22 | FaultList: user has passed the desired faults
23 | """
24 | self.circuit = circuit
25 |
26 | if not isinstance(faults, fault.FaultList):
27 | self.fault_list = fault.FaultList(circuit)
28 | else:
29 | self.fault_list = faults
30 |
31 | self.fs_type = ""
32 | self.fault_set_all = set()
33 | for node in self.circuit.nodes_lev:
34 | self.fault_set_all.add((node.num, 0))
35 | self.fault_set_all.add((node.num, 1))
36 | self.fault_set_rest = self.fault_set_all
37 |
38 | if faults == 'all':
39 | self.add_all()
40 |
41 | if isinstance(faults, int):
42 | self.add_n_random(faults)
43 |
44 | def add_n_random(self, n=1):
45 | self.fault_list.add_n_random(n)
46 |
47 | def add_all(self):
48 | self.fault_list.add_all()
49 |
50 | def fs_folder(self):
51 | """
52 | Creating the required directories for fault simulation
53 | """
54 | paths = [config.FAULT_SIM_DIR, config.FAULT_SIM_DIR + '/' + self.circuit.c_name]
55 |
56 | for path in paths:
57 | if not os.path.exists(path):
58 | print(f"Creating directory {path}")
59 | os.makedirs(path)
60 |
61 | # def single(self): -->renamed
62 | # """ Single pass of simulation.
63 | # DFS/PFSP: single test pattern
64 | # PPSF: single fault
65 | # """
66 | # raise NotImplementedError()
67 |
68 | # def fs_for_atpg(self):
69 | # """ DFS/PFS for ATPG use """
70 | # raise NotImplementedError()
71 |
72 | @abstractmethod
73 | def run(self, tp_num=1, t_mode='rand', r_mode='b'):
74 | """ Defined in children: DFS, PFS """
75 | pass
76 |
77 | def return_rest_fault(self): # seems redundant
78 | return self.fault_set_rest
79 |
--------------------------------------------------------------------------------
/circuit/inventory/atpg_det.py:
--------------------------------------------------------------------------------
1 | from d_alg import *
2 | from podem_ting import *
3 | from collections import deque
4 |
5 | import time
6 |
7 | '''
8 | D 1/0
9 | D_BAR 0/1
10 | five value define
11 | access value:five_value.ZERO.value
12 | access variable:five_value(0).name
13 | class five_value(Enum):
14 | ZERO = 0
15 | ONE = 15
16 | D = 12
17 | D_BAR = 3
18 | X = 9
19 | gtype:IPT, BRCH, XOR,OR,NOR,NOT,NAND,AND
20 | ntype:GATE,PI,FB,PO
21 | '''
22 |
23 | '''
24 | Function: imply_and_check, error_not_at_PO,
25 | '''
26 |
27 | def ATPG_DET(circuit, alg_type):
28 | """
29 | Stand alone function:
30 | execulte DALG or PODEM for a fault based on alg_type
31 | when the alg_type is chosen, all faults in the fault set will be exe by this alg
32 | """
33 | ############## Is it good??????????????????????
34 | fault_sim = FaultSim(circuit)
35 |
36 | # set: fault cannot be detected
37 | fault_non_det = set()
38 | fault_set_rest = fault_sim.fault_set_rest
39 |
40 | # record time
41 | start_time = time.time()
42 |
43 | if alg_type == "DALG":
44 | while fault_set_rest:
45 | fault = fault_set_rest.pop()
46 | alg_obj = D_alg(circuit, fault[0], fault[1])
47 |
48 | if alg_obj.dalg():
49 | IPI_list = alg_obj.return_IPI()
50 | IPI_binary_list = []
51 | #print(IPT_list)
52 | for x in IPI_list:
53 | if x == 15 or x == 12 or x == 9:
54 | IPI_binary_list.append(1)
55 | else:
56 | IPI_binary_list.append(0)
57 |
58 | #print(IPT_binary_list)
59 | dfs_test = DFS(circuit)
60 | fault_subset = dfs_test.single(IPI_binary_list)
61 | fault_set_rest = fault_set_rest.difference(fault_subset)
62 | else:
63 | # if the dalg fails, add the fault to non-det set
64 | fault_non_det.add(fault)
65 |
66 | end_time = time.time()
67 | exe_time = end_time - start_time
68 |
69 | fault_coverage = (len(circuit.nodes_lev) - len(fault_non_det)) / len(circuit.nodes_lev)
70 |
71 | print("Algorithm: DALG")
72 | print("Circuit: ", circuit.c_name)
73 | print("Fault Coverage: ", fault_coverage)
74 | print("Time: ", exe_time)
75 | print("None detectable faults: ", fault_non_det, "\n")
76 |
77 | elif alg_type == "PODEM":
78 | raise NameError("PODEM TBC")
79 |
80 | else:
81 | raise NameError("Algorithm type is invalid! alg_type = 'DALG' or 'PODEM'!")
82 |
83 |
--------------------------------------------------------------------------------
/circuit/inventory/atpg_new.py:
--------------------------------------------------------------------------------
1 |
2 | from d_alg import *
3 | from podem_new import *
4 | from parallel_fs import *
5 | from faul_simuation import deductive_fs
6 | from collections import deque
7 | from circuit.circuit import Circuit
8 |
9 | import time
10 | import os, sys
11 |
12 | class ATPG:
13 | def __init__(self, circuit):
14 | self.circuit = circuit
15 |
16 | self.total_fault_list = []
17 | self.reduce_fault_list = []
18 | #self.reduce_fault_list = []
19 | for node in self.circuit.nodes_lev:
20 | self.total_fault_list.append((node.num,0))
21 | self.total_fault_list.append((node.num,1))
22 | #self.total_fault_list.insert(0,(node.num,0))
23 | #self.total_fault_list.insert(0,(node.num,1))
24 | for node in self.circuit.nodes_lev:
25 | if node.gtype in ['BRCH', 'IPT']:
26 | self.reduce_fault_list.append((node.num,0))
27 | self.reduce_fault_list.append((node.num,1))
28 |
29 | def atpg_det(self, DFS_PFS = 'DFS', Podem_Dalg = 'Podem'):
30 | print('#####DETERMINISTIC#####')
31 | start = time.time()
32 | self.total_fault_set = set(self.total_fault_list)
33 | #self.reduce_fault_set = set(self.reduce_fault_list)
34 | self.fault_detected = set()
35 | self.error_list = []
36 | #self.circuit.lev()
37 | self.circuit.SCOAP_CC()
38 | self.circuit.SCOAP_CO()
39 | flag = 0
40 | count_set = 100 #500
41 | while(flag < 2 and len(self.total_fault_set) != 0):#len(self.reduce_fault_set) != 0):#len(self.total_fault_set) != 0):
42 | fault = self.total_fault_set.pop()
43 | #fault = self.reduce_fault_set.pop()
44 | #for fault in self.total_fault_set:
45 | #print('rest fault list', len(self.total_fault_set))
46 | #print('rest fault list', len(self.reduce_fault_set))
47 | #print(fault)
48 | if Podem_Dalg == 'Podem':
49 | test = Podem(self.circuit, fault[0], fault[1], count_set)
50 | else:
51 | test = D_alg(self.circuit, fault[0], fault[1], count_set)
52 | #blockPrint()
53 | if test.test() == True:
54 | IPT_list = test.return_IPT()
55 | IPT_binary_list = []
56 | for x in IPT_list:
57 | if x == 15 or x == 12 or x == 9:
58 | IPT_binary_list.append(1)
59 | else:
60 | IPT_binary_list.append(0)
61 | if DFS_PFS == 'DFS':
62 | dfs_test = DFS(self.circuit)
63 | fault_list_set = dfs_test.fs_for_atpg(IPT_binary_list)
64 | else:
65 | pfs_test = PFS(self.circuit)
66 | fault_list_set = pfs_test.fs_for_atpg(self.total_fault_set, IPT_binary_list)
67 | self.total_fault_set = self.total_fault_set - fault_list_set
68 | #self.reduce_fault_set = self.reduce_fault_set - fault_list_set
69 | self.fault_detected = self.fault_detected | fault_list_set
70 | if fault in self.error_list:
71 | self.error_list.remove(fault)
72 | self.error_list = list(set(self.error_list) - fault_list_set)
73 | else:
74 | if fault in self.error_list:
75 | pass
76 | else:
77 | self.error_list.append(fault)
78 | enablePrint()
79 | if len(self.total_fault_set) == 0 and len(self.error_list) != 0:
80 | #if len(self.reduce_fault_set) == 0 and len(self.error_list) != 0:
81 | self.total_fault_set = set(self.error_list)
82 | #self.reduce_fault_set = set(self.error_list)
83 | flag += 1
84 | count_set += 5000 #200000
85 | if len(self.total_fault_set) == 0 and len(self.error_list) == 0:
86 | #if len(self.reduce_fault_set) == 0 and len(self.error_list) == 0:
87 | flag = 2
88 | end = time.time()
89 |
90 | print('fault can not be detected >>',self.error_list)
91 | print('total num of fault >>',len(self.total_fault_list))
92 | print('total num of fault can not be detected >>',len(self.error_list))
93 | #print('fault coverage >>',(len(self.total_fault_list)-len(self.error_list))/len(self.total_fault_list))
94 | print('fault coverage >>',len(self.fault_detected)/len(self.total_fault_list))
95 | print('run time >>', end - start)
96 |
97 |
98 | def atpg_ran(self, DFS_PFS = 'DFS', Podem_Dalg = 'Podem', RAN_percentage = 75):
99 | if RAN_percentage > 100:
100 | raise ValueError('RAN_percentage should be smaller than 100')
101 | print('#####RANDOM#####')
102 | start = time.time()
103 | #self.circuit.lev()
104 | self.circuit.SCOAP_CC()
105 | self.circuit.SCOAP_CO()
106 | self.total_fault_set = set(self.total_fault_list)
107 | while((len(self.total_fault_list)-len(self.total_fault_set))/len(self.total_fault_list) < RAN_percentage/100):
108 | IPT_binary_list = self.circuit.gen_tp()
109 | if DFS_PFS == 'DFS':
110 | dfs_test = DFS(self.circuit)
111 | fault_list_set = dfs_test.fs_for_atpg(IPT_binary_list)
112 | else:
113 | pfs_test = PFS(self.circuit)
114 | fault_list_set = pfs_test.fs_for_atpg(self.total_fault_set, IPT_binary_list)
115 | self.total_fault_set = self.total_fault_set - fault_list_set
116 | flag = 0
117 | count_set = 100 #500
118 | while(flag < 2 and len(self.total_fault_set) != 0):
119 | fault = self.total_fault_set.pop()
120 | #print('rest fault list', len(self.total_fault_set))
121 | #print(fault)
122 | if Podem_Dalg == 'Podem':
123 | test = Podem(self.circuit, fault[0], fault[1], count_set)
124 | else:
125 | test = D_alg(self.circuit, fault[0], fault[1], count_set)
126 | #blockPrint()
127 | if test.test() == True:
128 | IPT_list = test.return_IPT()
129 | IPT_binary_list = []
130 | for x in IPT_list:
131 | if x == 15 or x == 12 or x == 9:
132 | IPT_binary_list.append(1)
133 | else:
134 | IPT_binary_list.append(0)
135 | if DFS_PFS == 'DFS':
136 | dfs_test = DFS(self.circuit)
137 | fault_list_set = dfs_test.fs_for_atpg(IPT_binary_list)
138 | else:
139 | pfs_test = PFS(self.circuit)
140 | fault_list_set = pfs_test.fs_for_atpg(self.total_fault_set, IPT_binary_list)
141 | self.total_fault_set = self.total_fault_set - fault_list_set
142 | if fault in self.error_list:
143 | self.error_list.remove(fault)
144 | self.error_list = list(set(self.error_list) - fault_list_set)
145 | else:
146 | if fault in self.error_list:
147 | pass
148 | else:
149 | self.error_list.append(fault)
150 | enablePrint()
151 | if len(self.total_fault_set) == 0 and len(self.error_list) != 0:
152 | self.total_fault_set = set(self.error_list)
153 | flag += 1
154 | count_set += 5000 #200000
155 | if len(self.total_fault_set) == 0 and len(self.error_list) == 0:
156 | flag = 2
157 | end = time.time()
158 |
159 | print('fault can not be detected >>',self.error_list)
160 | print('total num of fault >>',len(self.total_fault_list))
161 | print('total num of fault can not be detected >>',len(self.error_list))
162 | print('fault coverage >>',(len(self.total_fault_list)-len(self.error_list))/len(self.total_fault_list))
163 | print('run time >>', end - start)
164 |
165 | # Disable
166 | def blockPrint():
167 | sys.stdout = open(os.devnull, 'w')
168 |
169 | # Restore
170 | def enablePrint():
171 | sys.stdout = sys.__stdout__
172 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c1355_good_faults.txt:
--------------------------------------------------------------------------------
1 | 1100@0
2 | 1235@1
3 | 1144@1
4 | 1206@1
5 | 20@0
6 | 1259@1
7 | 923@1
8 | 947@1
9 | 902@0
10 | 901@1
11 | 719@0
12 | 100@0
13 | 30@1
14 | 512@0
15 | 433@0
16 | 625@1
17 | 430@1
18 | 440@1
19 | 67@1
20 | 406@1
21 | 674@1
22 | 324@1
23 | 61@1
24 | 662@1
25 | 805@1
26 | 588@1
27 | 244@1
28 | 723@1
29 | 326@0
30 | 368@0
31 | 412@0
32 | 681@0
33 | 779@1
34 | 654@1
35 | 1320@0
36 | 183@0
37 | 1243@0
38 | 1275@0
39 | 1326@0
40 | 175@0
41 | 1118@1
42 | 133@0
43 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c1908_good_faults.txt:
--------------------------------------------------------------------------------
1 | 2736@1
2 | 2546@1
3 | 542@0
4 | 539@0
5 | 961@0
6 | 806@1
7 | 919@1
8 | 820@0
9 | 1857@0
10 | 1090@1
11 | 857@1
12 | 823@1
13 | 318@0
14 | 2315@0
15 | 1317@1
16 | 2148@1
17 | 760@0
18 | 2086@1
19 | 86@0
20 | 1067@1
21 | 88@1
22 | 1212@1
23 | 800@0
24 | 1865@1
25 | 437@0
26 | 519@1
27 | 1727@1
28 | 890@0
29 | 1154@0
30 | 946@1
31 | 977@0
32 | 1342@1
33 | 628@1
34 | 152@0
35 | 2881@0
36 | 646@1
37 | 315@1
38 | 804@0
39 | 112@1
40 | 1210@0
41 | 1291@1
42 | 959@1
43 | 46@1
44 | 2779@0
45 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c3540_good_faults.txt:
--------------------------------------------------------------------------------
1 | 4078@1
2 | 1572@0
3 | 3192@1
4 | 3054@0
5 | 2515@1
6 | 1070@1
7 | 1554@1
8 | 675@1
9 | 681@0
10 | 1764@1
11 | 505@1
12 | 1129@0
13 | 865@1
14 | 1136@0
15 | 1205@0
16 | 430@1
17 | 3251@1
18 | 4822@1
19 | 3404@1
20 | 1726@0
21 | 3307@1
22 | 4694@0
23 | 887@1
24 | 784@0
25 | 670@0
26 | 3540@1
27 | 895@1
28 | 2636@1
29 | 5222@0
30 | 3135@1
31 | 1280@0
32 | 115@0
33 | 1804@0
34 | 333@1
35 | 3142@0
36 | 5217@1
37 | 5233@0
38 | 1941@1
39 | 2127@0
40 | 1956@1
41 | 1688@1
42 | 3950@0
43 | 1476@1
44 | 3696@0
45 | 3676@0
46 | 944@0
47 | 2189@1
48 | 2761@1
49 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c432_good_faults.txt:
--------------------------------------------------------------------------------
1 | 104@0
2 | 382@0
3 | 133@0
4 | 214@1
5 | 330@1
6 | 376@1
7 | 32@1
8 | 375@1
9 | 240@1
10 | 178@1
11 | 16@0
12 | 15@1
13 | 116@0
14 | 41@1
15 | 54@1
16 | 294@1
17 | 176@0
18 | 191@0
19 | 252@0
20 | 188@1
21 | 371@0
22 | 154@1
23 | 38@1
24 | 247@0
25 | 405@1
26 | 177@1
27 | 394@1
28 | 32@0
29 | 126@1
30 | 112@0
31 | 84@0
32 | 69@0
33 | 39@1
34 | 295@0
35 | 395@1
36 | 428@1
37 | 300@1
38 | 26@1
39 | 20@0
40 | 420@1
41 | 276@0
42 | 213@0
43 | 427@0
44 | 421@0
45 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c499_good_faults.txt:
--------------------------------------------------------------------------------
1 | 167@1
2 | 172@0
3 | 220@0
4 | 231@1
5 | 195@0
6 | 171@0
7 | 186@1
8 | 594@0
9 | 176@0
10 | 204@1
11 | 578@0
12 | 228@1
13 | 242@1
14 | 229@0
15 | 222@1
16 | 165@0
17 | 214@1
18 | 200@1
19 | 304@1
20 | 136@0
21 | 131@1
22 | 86@0
23 | 111@0
24 | 91@1
25 | 66@0
26 | 78@0
27 | 90@0
28 | 23@0
29 | 283@1
30 | 344@1
31 | 153@1
32 | 345@0
33 | 275@0
34 | 354@0
35 | 158@0
36 | 277@1
37 | 594@1
38 | 371@1
39 | 33@1
40 | 745@0
41 | 53@1
42 | 369@1
43 | 56@1
44 | 736@1
45 | 77@0
46 | 337@1
47 | 328@1
48 | 726@0
49 | 625@1
50 | 718@1
51 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c5315_good_faults.txt:
--------------------------------------------------------------------------------
1 | 7105@0
2 | 2793@0
3 | 2501@1
4 | 2413@1
5 | 3434@1
6 | 2914@1
7 | 8027@1
8 | 1045@0
9 | 1414@1
10 | 2103@0
11 | 814@0
12 | 2329@1
13 | 345@0
14 | 1343@1
15 | 1255@1
16 | 1033@0
17 | 1607@1
18 | 1446@0
19 | 814@1
20 | 1250@0
21 | 3555@1
22 | 2536@0
23 | 2970@0
24 | 8042@0
25 | 5121@1
26 | 199@0
27 | 3139@0
28 | 7416@0
29 | 1471@0
30 | 5104@0
31 | 119@1
32 | 68@0
33 | 1086@0
34 | 1117@0
35 | 2797@0
36 | 2921@1
37 | 21@1
38 | 5573@0
39 | 571@0
40 | 1776@0
41 | 4191@0
42 | 315@0
43 | 1553@1
44 | 3188@0
45 | 6382@0
46 | 2584@0
47 | 607@1
48 | 2874@1
49 | 4031@1
50 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c6288_good_faults.txt:
--------------------------------------------------------------------------------
1 | 929@1
2 | 4941@0
3 | 2405@0
4 | 2229@1
5 | 2659@0
6 | 4397@0
7 | 3192@1
8 | 2045@0
9 | 6248@0
10 | 3792@0
11 | 1084@0
12 | 4147@1
13 | 1722@0
14 | 4002@0
15 | 3152@0
16 | 3491@0
17 | 750@0
18 | 221@1
19 | 771@0
20 | 373@1
21 | 408@1
22 | 6257@0
23 | 4693@0
24 | 1129@1
25 | 1658@1
26 | 2111@0
27 | 4973@0
28 | 2762@0
29 | 4474@0
30 | 4078@0
31 | 3237@0
32 | 3448@0
33 | 4942@1
34 | 575@1
35 | 3461@0
36 | 3266@0
37 | 2278@0
38 | 5856@1
39 | 5683@1
40 | 1181@1
41 | 2724@0
42 | 4264@1
43 | 5094@0
44 | 4808@1
45 | 3024@0
46 | 1664@0
47 | 3821@0
48 | 651@1
49 | 1518@1
50 |
--------------------------------------------------------------------------------
/circuit/inventory/good_faults/c880_good_faults.txt:
--------------------------------------------------------------------------------
1 | 439@1
2 | 192@1
3 | 440@1
4 | 32@0
5 | 472@0
6 | 511@0
7 | 623@0
8 | 242@1
9 | 681@0
10 | 651@1
11 | 671@0
12 | 669@1
13 | 3@0
14 | 710@1
15 | 791@1
16 | 230@0
17 | 690@1
18 | 514@0
19 | 802@1
20 | 21@0
21 | 474@1
22 | 570@1
23 | 471@1
24 | 692@0
25 | 601@0
26 | 184@1
27 | 161@0
28 | 185@1
29 | 585@1
30 | 36@1
31 | 325@1
32 | 874@1
33 | 748@1
34 | 355@1
35 | 357@1
36 | 308@0
37 | 409@1
38 | 863@0
39 | 419@0
40 |
--------------------------------------------------------------------------------
/circuit/inventory/miscellaneous.py:
--------------------------------------------------------------------------------
1 | class five_value(Enum): # what are these?
2 | ZERO = 0
3 | ONE = 15
4 | D = 12
5 | D_BAR = 3
6 | X = 9
7 |
8 |
9 | class podem_node_5val(): # Change Case - move somewhere else
10 | def __init__(self):
11 | self.x = 1
12 | self.bit0 = 0
13 | self.bit1 = 0
14 |
15 | def fault_node(self, SA1):
16 | if self.x == 0:
17 | self.bit0 = SA1
18 | self.bit1 = not SA1
19 |
20 | def is_0(self):
21 | if self.x == 1:
22 | return False
23 | elif (self.bit0 | self.bit1) == 0:
24 | return True
25 |
26 | return False
27 |
28 | def is_1(self):
29 | if self.x == 1:
30 | return False
31 | elif (self.bit0 & self.bit1) == 1:
32 | return True
33 |
34 | return False
35 |
36 | def is_d(self):
37 | if self.x == 1:
38 | return False
39 | elif (self.bit0 ^ self.bit1) == 1:
40 | return True
41 |
42 | return False
43 |
44 | def is_sa0(self):
45 | if self.x == 1:
46 | return False
47 | elif (self.bit0 == 0) & (self.bit1 == 1):
48 | return True
49 |
50 | return False
51 |
52 | def is_sa1(self):
53 | if self.x == 1:
54 | return False
55 | elif (self.bit0 == 1) & (self.bit1 == 0):
56 | return True
57 |
58 | return False
59 |
60 | def __and__(self, other):
61 | val = podem_node_5val()
62 | val.bit0 = self.bit0 & other.bit0
63 | val.bit1 = self.bit1 & other.bit1
64 | val.x = 0
65 | if self.x == 1:
66 | if other.is_0():
67 | val.x = 0
68 | else:
69 | val.x = 1
70 | if other.x == 1:
71 | if self.is_0():
72 | val.x = 0
73 | else:
74 | val.x = 1
75 | return val
76 |
77 | def __or__(self, other):
78 | val = podem_node_5val()
79 | val.bit0 = self.bit0 | other.bit0
80 | val.bit1 = self.bit1 | other.bit1
81 | val.x = 0
82 | if self.x == 1:
83 | if other.is_1() == True:
84 | val.x = 0
85 | else:
86 | val.x = 1
87 | if other.x == 1:
88 | if self.is_1():
89 | val.x = 0
90 | else:
91 | val.x = 1
92 | return val
93 |
94 | def __xor__(self, other):
95 | val = podem_node_5val()
96 | val.bit0 = self.bit0 ^ other.bit0
97 | val.bit1 = self.bit1 ^ other.bit1
98 | val.x = self.x | other.x
99 | return val
100 |
101 | def __invert__(self):
102 | val = podem_node_5val()
103 | val.bit0 = not self.bit0
104 | val.bit1 = not self.bit1
105 | val.x = self.x
106 | return val
107 |
108 |
109 | # ---> methods that appears here must be removed from node.py
110 |
111 | # -*- coding: utf-8 -*-
112 |
113 | import pdb
114 | import math
115 | import sys
116 | from enum import Enum
117 | import node.node as node
118 |
119 | sys.path.insert(0,'..')
120 | import utils
121 |
122 |
123 | ##### DFS Functions #####
124 | class DFTNode(node.Node):
125 |
126 | def dfs(self):
127 | ''' deductive fault simulation (dfs) using unodes '''
128 | raise NotImplementedError()
129 |
130 |
131 | class DFTBUFF(node.BUFF):
132 | def dfs(self):
133 | self.faultlist_dfs.clear()
134 | self.faultlist_dfs = self.unodes[0].faultlist_dfs.copy()
135 | self.faultlist_dfs.add((self.num, utils.not_gate(self.value)))
136 |
137 | class DFTNOT(node.NOT):
138 | def dfs(self):
139 | self.faultlist_dfs.clear()
140 | self.faultlist_dfs = self.unodes[0].faultlist_dfs.copy()
141 | self.faultlist_dfs.add((self.num, utils.not_gate(self.value)))
142 |
143 | class DFTOR(node.OR):
144 | def dfs(self):
145 | self.faultlist_dfs.clear()
146 | dfs_general(self, 1)
147 |
148 | class DFTNOR(node.NOR):
149 | def dfs(self):
150 | # the controling value of NOR is 1
151 | self.faultlist_dfs.clear()
152 | dfs_general(self, 1)
153 |
154 | class DFTAND(node.AND):
155 | def dfs(self):
156 | # the controling value of AND is 0
157 | self.faultlist_dfs.clear()
158 | dfs_general(self, 0)
159 |
160 | class DFTNAND(node.NAND):
161 | def dfs(self):
162 | # the controling value of NAND is 0
163 | self.faultlist_dfs.clear()
164 | dfs_general(self, 0)
165 |
166 | class DFTXOR(node.XOR):
167 | def dfs(self):
168 | self.faultlist_dfs.clear()
169 | xor_FL_set = set()
170 | for unode in self.unodes:
171 | xor_FL_set = xor_FL_set.symmetric_difference(unode.faultlist_dfs)
172 | xor_FL_set.add((self.num, utils.not_gate(self.value)))
173 | self.faultlist_dfs = xor_FL_set
174 |
175 | class DFTXNOR(node.XNOR):
176 | def dfs(self):
177 | self.faultlist_dfs.clear()
178 | xnor_FL_set = set()
179 | for unode in self.unodes:
180 | xnor_FL_set = xnor_FL_set.symmetric_difference(unode.faultlist_dfs)
181 | xnor_FL_set.add((self.num, utils.not_gate(self.value)))
182 | self.faultlist_dfs = xnor_FL_set
183 |
184 | class DFTIPT(node.IPT):
185 | def dfs(self):
186 | self.faultlist_dfs.clear()
187 | self.faultlist_dfs.add((self.num, utils.not_gate(self.value)))
188 |
189 | class DFTBRCH(node.BRCH):
190 | def dfs(self):
191 | self.faultlist_dfs.clear()
192 | self.faultlist_dfs = self.unodes[0].faultlist_dfs.copy()
193 | self.faultlist_dfs.add((self.num, utils.not_gate(self.value)))
194 |
195 | def dfs_general(node, c_val):
196 | """
197 | Helper function; it doesn't belong to any node class
198 | The general dfs algorithm is suitable for (gates with controlling),
199 | such as AND, NAND, OR, NOR, etc., and does not include XOR, XNOR, INV, etc.
200 | node: an object from class Node
201 | c_val: controlling value for this node
202 | functionality:
203 | Making changes on node.faultlist_dfs, based on the fault list of node.unodes
204 | For PI nodes, faultlist_dfs is fault list on itself
205 | """
206 | # the fault list of the gate output
207 | fault_set = set()
208 | # intersection set of all faults implied by controling inputs
209 | c_FL_set = set()
210 | # union set of all faults implied by non-controling inputs
211 | nc_FL_set = set()
212 | # imply if there is any control value amoung the inputs
213 | flag_c = 0
214 | first_c = 1
215 | for unode in node.unodes:
216 | if unode.value == c_val :
217 | flag_c = 1
218 | # for the first controling value, use its FL as initialization
219 | if first_c == 1:
220 | c_FL_set = unode.faultlist_dfs.copy()
221 | first_c = 0
222 | else:
223 | c_FL_set = c_FL_set.intersection(unode.faultlist_dfs)
224 | else :
225 | nc_FL_set = nc_FL_set.union(unode.faultlist_dfs)
226 |
227 | # none of the inputs are controlling value
228 | if flag_c == 0:
229 | node.faultlist_dfs.clear()
230 | nc_FL_set.add((node.num, utils.not_gate(node.value)))
231 | # print(list(nc_FL_set))
232 | node.faultlist_dfs = nc_FL_set.copy()
233 |
234 | # there is a controlling value on inputs
235 | else :
236 | node.faultlist_dfs.clear()
237 | node.faultlist_dfs = c_FL_set.difference(nc_FL_set)
238 | node.faultlist_dfs.add((node.num, utils.not_gate(node.value)))
239 | c_FL_set.clear()
240 | nc_FL_set.clear()
241 | #TODO: clear this return, if it is correct, document it
242 | return fault_set
--------------------------------------------------------------------------------
/circuit/inventory/rem.py:
--------------------------------------------------------------------------------
1 | def get_inp_plus_one(tp):
2 | # for t in reversed[tp]:
3 | i = len(tp)-1
4 | success = False
5 | while tp[i]>=0:
6 | if tp[i] == 0:
7 | tp[i] = 1
8 | success = True
9 | break
10 | else:
11 | tp[i] = 0
12 | i-=1
13 | print(i)
14 | print
15 | if i == -1:
16 | success = False
17 | break
18 |
19 | return success, tp
20 |
21 | print(get_inp_plus_one([1,1,0,0]))
--------------------------------------------------------------------------------
/circuit/main_example.py:
--------------------------------------------------------------------------------
1 | import os
2 | from circuit.circuit import Circuit
3 | from circuit.dft_circuit import DFTCircuit
4 | from fault_simulation.ppsf import PPSF
5 | from fault_simulation.pfs import PFS
6 | from fault_simulation.fault import FaultList
7 | import config
8 | from tp_generator import TPGenerator
9 | import pdb
10 |
11 | # RUN = 'TEST'
12 | RUN = '-'
13 | # RUN = 'logicsim'
14 |
15 | if __name__ == '__main__':
16 |
17 | # circuit_path = '../data/ckt/c17.ckt'
18 | # circuit_path = '../data/ckt/add2.ckt'
19 | # circuit_path = '../data/ckt/c2.ckt'
20 | # circuit_path = '../data/ckt/c4.ckt'
21 | # circuit_path = '../data/ckt/c3540.ckt'
22 | # circuit_path = '../data/ckt/c1908.ckt'
23 | # circuit_path = '../data/ckt/c5315.ckt'
24 | circuit_path = '../data/verilog/ISCAS85/v0/c1355_synV0.v'
25 |
26 | circuit = DFTCircuit(circuit_path)
27 | f = FaultList(circuit)
28 | # f.add_all()
29 | # print(circuit)
30 | # for fa in f.faults:
31 | # print(fa)
32 | circuit.SCOAP_CC()
33 | circuit.SCOAP_CO()
34 |
35 | # for n in circuit.nodes_lev:
36 | # # print(n.num, f'{n.CO=}', f'{n.CC=}')
37 | # print(n.num, f'{n.CC0=}', f'{n.CC1=}', f'{n.CO=}')
38 |
39 | # #################### PPSF Example ###################
40 |
41 | ppsf = PPSF(circuit)
42 | # tg = TPGenerator(circuit)
43 | ppsf.multiprocess_ci_run(tp_steps=[50, 100, 500, 1000, 5000, 10000, 20000, 50000],
44 | #op=circuit.nodes_lev[5],
45 | verbose=True, ci=3, num_proc=8, fault_count='all', save_log=True)
46 |
47 | # tps = tg.gen_full()
48 | # f_dict = ppsf.run(tps=20000, verbose=True, save_log=True)
49 | # # print('_'*50)
50 | # print('_'*50)
51 |
52 | ##################### PFS Example ####################
53 |
54 | # tg = TPGenerator(circuit)
55 |
56 | # pfs = PFS(circuit)
57 | # pfs.tpfc(1000, verbose=True)
58 | # pfs.run(tps=10000, verbose=True, save_log=True, faults = 'all')
59 | # print('_'*50)
60 |
61 | # #################### STAFAN_FC Example ##############
62 | # tp = 10000
63 | # circuit.STAFAN(tp, num_proc=1)
64 | # fc = circuit.STAFAN_FC(tp)
65 | # print("Fault Coverage Estimation=", fc)
66 | # print('_'*50)
67 |
--------------------------------------------------------------------------------
/circuit/node/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msabrishami/DFT/919db427bd5af75bb5ca696631fd85048d760337/circuit/node/__init__.py
--------------------------------------------------------------------------------
/circuit/pytest.ini:
--------------------------------------------------------------------------------
1 | [pytest]
2 | markers =
3 | IPT: input node
4 | BUFF: buffer node
5 | NOT: not node
6 | NOR: nor node
7 | OR: or node
8 | NAND: nand nod
9 | AND: and node
10 | XOR: xor node
11 | XNOR: xnor node
12 | BRCH: branch node
--------------------------------------------------------------------------------
/circuit/run-ee658.py:
--------------------------------------------------------------------------------
1 | import os
2 | import glob
3 |
4 | MAIN_DIR = "/home/msabrishami/workspace/ee658-github-classroom-repos"
5 | AUTO_DIR = f"{MAIN_DIR}/phase2/auto-tests-phase2"
6 |
7 | def check_files(ckts):
8 | for ckt in ckts:
9 | os.system(f"find {AUTO_DIR}/ -name *{ckt}* | grep -v rtpg | grep -v rfl")
10 |
11 |
12 | def delete_all():
13 | paths = ["cmds/dfs/*", "cmds/pfs/*", "cmds/logicsim/*",
14 | "golden_results/pfs/*", "golden_results/dfs/*", "golden_results/logicsim/*",
15 | "inputs/logicsim/*", "inputs/pfs/tps/*", "inputs/pfs/faults/*", "inputs/dfs/*",
16 | "outputs/dfs/*", "outputs/pfs/*", "outputs/logicsim/*"]
17 | for path in paths:
18 | os.system(f"rm {AUTO_DIR}/{path} 2> /dev/null")
19 |
20 |
21 | ckts = glob.glob("../data/ckt/*.ckt")
22 | ckts = [x.split("/")[-1][:-4] for x in ckts]
23 | # delete_all()
24 | # check_files(ckts)
25 | print(ckts)
26 | for ckt in ckts:
27 | if "_" in ckt:
28 | continue
29 | if ckt not in ["c1", "c2", "c3", "c4", "c17", "x3mult", "add2", "c432", "c499", "c880"]:
30 | continue
31 | cmd = f"python3 main_saeed.py -ckt ../data/ckt/{ckt}.ckt -func ee658-p2 -tp 10 -fault 10"
32 | os.system(cmd)
33 |
34 |
35 |
--------------------------------------------------------------------------------
/circuit/ssta/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msabrishami/DFT/919db427bd5af75bb5ca696631fd85048d760337/circuit/ssta/__init__.py
--------------------------------------------------------------------------------
/circuit/ssta/main_SSTA.py:
--------------------------------------------------------------------------------
1 | import sys
2 | sys.path.insert(0,'..')
3 |
4 | import argparse
5 | import os
6 | import pdb
7 | from circuit.circuit import Circuit
8 | import sys
9 | import config
10 | import utils
11 |
12 | # sys.path.insert(1, "/home/msabrishami/workspace/StatisticsSTA/")
13 | from distributions import Distribution, Normal, SkewNormal, MaxOp, SumOp, NumDist
14 | import distributions as dist
15 |
16 |
17 | parser = argparse.ArgumentParser()
18 | parser.add_argument("-ckt", type=str, default="c17", help="circuit name, c17, no extension")
19 | parser.add_argument("-mode", type=str, default="alt", help="circuit name, c17, no extension")
20 | parser.add_argument("-samples", type=int, default=100, help="SSTA samples")
21 | args = parser.parse_args()
22 | config.SAMPLES = args.samples
23 |
24 |
25 | from distributions import Triangle, Uniform
26 | import matplotlib.pyplot as plt
27 |
28 |
29 | def test_triangle():
30 | """ Testing simple sum of simple distributions """
31 | d1 = Triangle(0,4,1)
32 | d2 = Triangle(10,18,11)
33 | d1 = Uniform(1,2)
34 | d2 = Uniform(4,6)
35 | T1,f1 = d1.pmf(100)
36 | T2,f2 = d2.pmf(100)
37 |
38 | plt.plot(T1, f1, color='r')
39 | plt.plot(T2, f2, color='b')
40 | T1,F1 = d1.cmf(100)
41 | T2,F2 = d2.cmf(100)
42 | plt.plot(T1,F1, color='g')
43 | plt.plot(T2,F2, color='c')
44 |
45 | opsum = SumOp()
46 | T, f_T = opsum.sum_num(d1, d2, 100).pmf()
47 | plt.plot(T, f_T, color='black', ls='-')
48 | plt.savefig("triangle-dist.pdf")
49 |
50 |
51 | def test_sum_chain():
52 |
53 | # Basic Distribution
54 | # d1 = Uniform(0, 2)
55 | # d1 = Triangle(0, 20, 10)
56 | # d1 = Normal(0, 1)
57 | # d1 = SkewNormal(0,1,1)
58 | # T, f_T = d1.pmf(512)
59 |
60 | # Load from HSPICE Simulation files
61 | fname = "MOSFET_45nm_LP_cand2_"
62 | fname += "vth0-N0.03_lg-N0.05_w-N0.05_toxe-N0.10_ndep-N0.05_MC50000.mcraw"
63 | fname = os.path.join(config.SSTA_DATA_DIR, "mcraw/"+fname)
64 | delays = utils.load_mcraw(fname)
65 |
66 | # T, f_T = utils.mcraw2mchist(delays, bins=200, pad=3) # , cut=(0.0005, 0.0005)
67 | T, f_T = utils.mcraw2mchist(delays, bins=200) # , cut=(0.0005, 0.0005)
68 | f_T = utils.smooth_hist(f_T, window=5)
69 | d1 = NumDist(T, f_T)
70 |
71 | plt.plot(T, f_T, label="Initial")
72 | print("Initial Area: \t{:.6f}".format(Distribution.area_pmf(T, f_T)))
73 | opsum = SumOp()
74 | dd = d1
75 | for i in range(20):
76 | dd = opsum.sum_num(dd, d1)
77 | T, f_T = dd.pmf()
78 | plt.plot(T, f_T, label="Sum {}".format(i))
79 | print("Level {} | Area: {:.6f}".format(i, dd.area()))
80 | plt.legend()
81 | plt.savefig("SumChain-MOSFET.pdf")
82 | plt.close()
83 |
84 |
85 | def test_mchist_plot():
86 |
87 | TECH = "MOSFET_45nm_LP"
88 | MCs = [10000, 20000, 50000]
89 | BINs = [100, 200, 400]
90 | SMs = [0, 3, 5, 11]
91 | MC = "MC10000"
92 |
93 | for cell in ["cnand2", "cnand3", "cnand4",
94 | "cnor2", "cnor3", "cnor4",
95 | "cand2", "cand3", "cand4",
96 | "cor2", "cor3", "cor4",
97 | "cbuff", "cinv"]:
98 |
99 | fig, ax = plt.subplots(len(BINs), len(SMs), figsize=(40,20))
100 | fig.suptitle("Cell: {}, {}".format(cell, MC))
101 |
102 | fname = "../data/cell_ssta/mcraw/" + TECH + "_" + cell + "_"
103 | fname += "vth0-N0.03_lg-N0.05_w-N0.05_toxe-N0.10_ndep-N0.05_" + MC + ".mcraw"
104 | delays = utils.load_mcraw(fname)
105 | # fname = "../data/cell_ssta/mchist/" + TECH + "_" + cell + "_" + MC
106 | # T, f_T = utils.mcraw2mchist(delays, bins, fname=fname + ".mchist", verbose=True)
107 |
108 | for i, bins in enumerate(BINs):
109 | for j, sm in enumerate(SMs):
110 | T, f_T = utils.mcraw2mchist(delays, bins)
111 | if sm != 0:
112 | f_T = utils.smooth_hist(f_T, window=sm)
113 | # print("Cell: {}\tArea: {:.6f}".format(cell, d.area()))
114 | ax[i,j].plot(T, f_T, linewidth=2, color='blue', linestyle='-')
115 | ax[i,j].set_title("Bins: {} Smooth-Window: {}".format(bins, sm))
116 |
117 | for ax in fig.get_axes():
118 | ax.label_outer()
119 | fig.savefig(TECH + "_" + cell + "_" + MC + ".pdf")
120 | plt.close()
121 |
122 |
123 | # test_sum_chain()
124 | # test_mchist_plot()
125 | circuit = Circuit(args.ckt)
126 | circuit.lev()
127 | # for node in circuit.nodes_lev:
128 | # print(node.ntype, node.gtype, utils.get_node_gtype_fin(node))
129 | print(args.ckt)
130 | # circuit.set_cell_ssta_delay(src="mcraw")
131 | # circuit.load_mchist("MOSFET_16nm_HP")
132 | # circuit.ssta_pmf()
133 | circuit.ssta_sim(mode=args.mode, src="mcraw", samples=args.samples)
134 | fname = "./results/ssta-{}-{}-s{}-{}.png".format(circuit.c_name, args.mode, args.samples, config.TECH)
135 | circuit.ssta_plot(fname=fname, select="gate")
136 | # temp = circuit.load_mchist("MOSFET_16nm_HP")
137 |
138 |
139 |
--------------------------------------------------------------------------------
/circuit/ssta/utils_ssta.py:
--------------------------------------------------------------------------------
1 | import numpy as np
2 | import matplotlib.pyplot as plt
3 |
4 | def smooth_hist(vals, window=5):
5 | """ Average smoothing over a floating point series, it can be a series of
6 | PDF values for a distribution, or histogram values.
7 |
8 | Warning: assumption is that both ends of this series converge to zero
9 | we pad the data with zero values before smoothing process
10 | the length of the output is not the same as input if padding added
11 |
12 | Parameters
13 | ----------
14 | f_T : list of float
15 | value series, both ends are assumed to converge to zero
16 | window : int (must be odd)
17 | smoothing filter length
18 |
19 | Returns
20 | -------
21 | sm : list of float
22 | smoothed series
23 | """
24 | assert len(vals) > 3*window, "Too small to smooth!"
25 | assert window%2==1, "Window must be odd number"
26 |
27 | hw = int(window/2)
28 | sm = list(vals)
29 |
30 | for idx in range(len(vals)):
31 | sm[idx] = np.mean(vals[max(0, idx-hw):min(len(vals)-1, idx+hw+1)])
32 |
33 | return sm
34 |
35 |
36 | def mcraw2mchist(delays, bins, fname=None, cut=None, pad=None, verbose=False):
37 | """ Gets Monte Carlo raw simulation (mcraw) results and returns
38 | Monte Carlo histogram distribution (mchist)
39 |
40 | Parameters
41 | ----------
42 | delays : list of float
43 | Monte Carlo raw simulation results, unit can vary, usually is ps
44 | bins : int
45 | Number of bins to be used for creating histogram distribution
46 | fname : str, optional
47 | If assigned, stores the results of histogram (mchist)
48 | cut : tuple of floats, optional
49 | Histogram resolution drops if outline points are present, if cut is
50 | assigned, it cuts the (low, high) percentage of the data.
51 | pad : int, optional, must be odd
52 | If assigned, adds pad number of zero values to both ends of histogram
53 | results, also adds extra bin values to equalize lengths of T and f_T
54 |
55 | Returns
56 | -------
57 | T, f_T : tuple of Numpy ndarrays, T is bin values, f_T is pdf values
58 |
59 | Warning: using cut can change the distribution drastically!
60 | Warning: the name can be missleading, does not return histogram, but a
61 | sampling of PDF (refer to np.histogram documentation for density argument)
62 | """
63 | Td = delays
64 | Td.sort()
65 | # Note: in np.histogram, len(f)=len(T)+1
66 | if cut:
67 | low = Td[int(len(delays)*cut)]
68 | high = Td[-int(len(delays)*cut)]
69 | f_T, _T = np.histogram(Td, bins=bins, range=cuts, density=True)
70 | else:
71 | f_T, _T = np.histogram(Td, bins=bins, density=True)
72 |
73 |
74 | T = np.zeros(len(f_T))
75 | for idx in range(len(f_T)):
76 | T[idx] = (_T[idx] + _T[idx+1])/2 # len(T)=len(f_T)
77 |
78 | if pad:
79 | f_T = np.append([0]*pad, f_T)
80 | f_T = np.append(f_T, [0]*pad)
81 | T_start = [T[0] - (k+1)*(T[1]-T[0]) for k in reversed(range(pad))]
82 | T_end = [T[-1] + (k+1)*(T[-1] - T[-2]) for k in range(pad)]
83 | T = np.append(T_start, T)
84 | T = np.append(T, T_end)
85 |
86 | if fname==None:
87 | return T, f_T
88 |
89 | outfile = open(fname, "w")
90 | for idx in range(len(T)):
91 | # print(idx, T[idx], f_T[idx])
92 | outfile.write("{}\t{}\n".format(T[idx], f_T[idx]))
93 | outfile.close()
94 | if verbose:
95 | print("PMF saved in {}".format(fname))
96 |
97 | return T, f_T
98 |
99 |
100 | def load_mcraw(fname):
101 | """ Loading Monte Carlo simulation results
102 | A simple file (fname) with delay values in each line
103 | The unit for values can vary, usually it is in ps """
104 | lines = open(fname, "r").readlines()
105 | lines = [float(line) for line in lines]
106 | print("Loaded {} with {} values".format(fname, len(lines)))
107 | return lines
108 |
109 | def load_mchist(fname):
110 | infile = open(fname)
111 | T = []
112 | f_T = []
113 | for line in infile:
114 | T.append(float(line.strip().split()[0]))
115 | f_T.append(float(line.strip().split()[1]))
116 |
117 | return np.asarray(T), np.asarray(f_T)
118 |
119 |
120 | def hist2pmf(T, h_T):
121 | f_T = np.zeros(len(T))
122 | tot = np.sum(h_T)
123 | for idx in range(len(T)-1):
124 | dT = T[idx+1] - T[idx]
125 | f_T[idx] = (h_T[idx]/tot) / dT
126 |
127 | f_T[-1] = f_T[-2]
128 | return (T, f_T)
129 |
130 |
131 | def plot_pmf(dist, fname=None):
132 | x1, y1 = dist.pmf()
133 | plt.plot(x1, y1, linewidth=2, color='blue', linestyle='--')
134 | plt.grid()
135 | if fname:
136 | plt.savefig(fname)
137 | plt.close()
138 |
139 | def get_cmap(n, name='prism'):
140 | '''Returns a function that maps each index in 0, 1, ..., n-1 to a distinct
141 | RGB color; the keyword argument name must be a standard mpl colormap name.'''
142 | return plt.cm.get_cmap(name, n)
143 |
144 |
145 |
--------------------------------------------------------------------------------
/circuit/tests/README.md:
--------------------------------------------------------------------------------
1 | # Testing
2 |
3 | ## User-defined tests
4 |
5 | ### Files format
6 |
7 | ```
8 | XXX_test.py
9 | ```
10 |
11 | ### Run
12 |
13 | ```
14 | python XXX_test.py
15 | ```
16 |
17 | ## PyTest
18 |
19 | ### Files format
20 |
21 | ```
22 | test_XXX.py
23 | ```
24 |
25 | ### Run
26 |
27 | ```
28 | pytest -v test*.py
29 | ```
30 |
--------------------------------------------------------------------------------
/circuit/tests/__init__.py:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/msabrishami/DFT/919db427bd5af75bb5ca696631fd85048d760337/circuit/tests/__init__.py
--------------------------------------------------------------------------------
/circuit/tests/old/checker_dfs.py:
--------------------------------------------------------------------------------
1 | import xlrd
2 | import os
3 | from itertools import groupby
4 |
5 | # change this
6 | from circuit.circuit import *
7 |
8 | def FD_excel_extractor(c_name):
9 | # output golden file
10 | output_path = '../data/modelsim/' + c_name + '/input/'
11 | fw = open(output_path + c_name + '_FD_golden.txt', mode='w')
12 | # Give the location of the file
13 | fr = ("../../simple_circuits/" + c_name + "/" + c_name + "_FD.xlsx")
14 | # To open Workbook
15 | wb = xlrd.open_workbook(fr)
16 | sheet = wb.sheet_by_index(0)
17 | for i in range(2, sheet.nrows):
18 | pattern = list(sheet.cell_value(i, 0))
19 | pattern_str = ','.join(pattern)
20 | fw.write(pattern_str + '\n')
21 | for j in range(2, sheet.ncols):
22 | if sheet.cell_value(i, j) == 'x':
23 | fw.write(str(int(sheet.cell_value(1, j))) + '@' + str(int(sheet.cell_value(0, j))) + '\n')
24 | fw.write('\n')
25 |
26 |
27 |
28 |
29 |
30 |
31 | def dfs_pfs_checker(circuit, tp_num=1, mode='rand'):
32 | golden_path = config.FAULT_SIM_DIR + '/' + circuit.c_name + '/dfs/'
33 | output_path = config.FAULT_SIM_DIR + '/' + circuit.c_name + '/pfs/'
34 | result_path = config.FAULT_SIM_DIR + '/' + circuit.c_name + '/compare/'
35 | if not os.path.exists(result_path):
36 | os.mkdir(result_path)
37 | if mode == 'rand':
38 | dfs_report_fname = circuit.c_name + '_' + str(tp_num) + '_dfs_b.log'
39 | pfs_report_fname = circuit.c_name + '_' + str(tp_num) + '_pfs_b.log'
40 | path_golden = golden_path + dfs_report_fname
41 | path_output = output_path + pfs_report_fname
42 | result_file = result_path + circuit.c_name + '_' + str(tp_num) + '_dfs_pfs_compare.txt'
43 | fw = open(result_file, 'w')
44 | file_golden = open(path_golden, mode='r+')
45 | file_out = open(path_output, mode='r+')
46 | line_golden = file_golden.readlines()
47 | line_golden = line_golden[:-1]
48 | line_out = file_out.readlines()
49 | line_out = line_out[:-1]
50 |
51 | pass_flag = 0
52 | for i in range(len(line_golden)):
53 | if line_golden[i] == line_out[i]:
54 | pass
55 | elif line_golden[i] != line_out[i]:
56 | fw.write('results are different!\n')
57 | pass_flag=1
58 | break
59 |
60 | if pass_flag == 0:
61 | fw.write('results are the same!\n')
62 |
63 |
64 | elif mode == 'full':
65 | dfs_report_fname = circuit.c_name + "_full_dfs_b.log"
66 | pfs_report_fname = circuit.c_name + "_full_pfs_b.log"
67 | path_golden = golden_path + dfs_report_fname
68 | path_output = output_path + pfs_report_fname
69 | result_file = result_path + circuit.c_name + '_full_dfs_pfs_compare.txt'
70 | fw = open(result_file, 'w')
71 | if os.stat(path_golden).st_size == 0:
72 | print('Golden file is empty!')
73 | fw.write('Golden file is empty!\n')
74 | return
75 | if os.stat(path_output).st_size == 0:
76 | print('Output file is empty!')
77 | fw.write('Output file is empty!\n')
78 | return
79 | file_golden = open(path_golden, mode='r+')
80 | file_out = open(path_output, mode='r+')
81 |
82 | content_golden = map(lambda line: len(line) > 1 and line[:-1], list(file_golden))
83 | content_out = map(lambda line: len(line) > 1 and line[:-1], list(file_out))
84 |
85 | gen_golden = (list(g) for _, g in groupby(content_golden, key='\n'.__ne__))
86 | patterns_golden = [a + b for a, b in zip(gen_golden, gen_golden)]
87 | gen_out = (list(g) for _, g in groupby(content_out, key='\n'.__ne__))
88 | patterns_out = [a + b for a, b in zip(gen_out, gen_out)]
89 |
90 | i, j = 0, 0
91 | while i < len(patterns_golden) and j < len(patterns_out):
92 | if patterns_golden[i] == patterns_out[j]:
93 | print(patterns_golden[i][0] + ': correct')
94 | fw.write(patterns_golden[i][0] + ': correct\n')
95 | else:
96 | print(patterns_golden[i][0]+ ': wrong')
97 | fw.write(patterns_golden[i][0]+ ': wrong\n')
98 | set_golden, set_out = set(patterns_golden[i]), set(patterns_out[j])
99 | dif_golden, dif_out = set_golden - set_out, set_out - set_golden
100 | longer_dif = dif_golden if len(dif_golden) > len(dif_out) else dif_out
101 | longer_dif = sorted(list(longer_dif), key = lambda dif: int(dif[:-2]))
102 | print('Golden\tOutput')
103 | fw.write('Golden\tOutput\n')
104 | for dif in longer_dif:
105 | num0, num1 = dif[:-1] + '0', dif[:-1] + '1'
106 | ele_golden = num0 if num0 in dif_golden else num1 if num1 in dif_golden else 'None'
107 | ele_out = num0 if num0 in dif_out else num1 if num1 in dif_out else 'None'
108 | print(ele_golden + '\t' + ele_out)
109 | fw.write(ele_golden + '\t' + ele_out + '\n')
110 | print('\n')
111 | fw.write('\n')
112 |
113 | i, j = i + 1, j + 1
114 |
115 | if i < len(patterns_golden):
116 | print('Golden not compared patterns:')
117 | fw.write('Golden not compared patterns:\n')
118 | for idx in range(i, len(patterns_golden)):
119 | print(patterns_golden[idx][0])
120 | fw.write(str(patterns_golden[idx][0]) + '\n')
121 |
122 | if j < len(patterns_out):
123 | print('Output not compared patterns:')
124 | fw.write('Output not compared patterns:\n')
125 | for idx in range(j, len(patterns_out)):
126 | print(patterns_out[idx][0])
127 | fw.write(str(patterns_out[idx][0]) + '\n')
128 | else:
129 | raise NameError("Mode is not acceptable! Mode = 'rand' or 'full'!")
130 |
131 |
132 | file_golden.close()
133 | file_out.close()
134 |
135 |
136 | # compare the dfs results with golden file
137 | # path = '../data/fault_sim/' + c_name + '/'
138 | # file_golden = open(path + c_name + '_FD_golden.txt', mode='r+')
139 | # file_out = open(path + c_name + '_full_dfs_out.txt', mode='r+')
140 | # number_of_line = 1
141 | # golden_line = file_golden.readline()
142 | # out_line = file_out.readline()
143 | # flag = 1
144 | # if len(golden_line) == 0:
145 | # print("original file is empty!")
146 | # flag = 0
147 | # if len(out_line) == 0:
148 | # print("new file is empty!")
149 | # flag = 0
150 |
151 | # if golden_line is not None and out_line is not None:
152 | # while golden_line :
153 | # if golden_line != '\n':
154 |
155 | # if golden_line != out_line:
156 | # print('file different! different line is #', number_of_line)
157 | # flag = 0
158 | # elif golden_line == '\n':
159 |
160 | # else:
161 | # flag = 1
162 | # golden_line = file_golden.readline()
163 | # out_line = file_out.readline()
164 | # number_of_line += 1
165 |
166 | # if flag == 1:
167 | # print('result are the same')
168 | # else:
169 | # print("result are not same!")
170 | # file_golden.close()
171 | # file_out.close()
172 |
173 | # dfs_checker(c_name = 'c17')
--------------------------------------------------------------------------------
/circuit/tests/old/checker_logicsim.py:
--------------------------------------------------------------------------------
1 |
2 | import re
3 | import config
4 | import os
5 |
6 | # change these
7 | from circuit.circuit import *
8 | from circuit.inventory.modelsim_simulator import *
9 | from circuit.load_circuit import *
10 |
11 | class Checker():
12 | def __init__(self, c_name, tp_count):
13 | """ create a circuit and a modelsim simulation
14 | we have two types of inputs: "gate-level-circuit" and a "verilog"
15 | verilog can be anything, gate level, behavioral, etc.
16 | But gate-level-circuit can only be gate-level ckt or gate-level verilog
17 | For now we are only supporting ckt for gate-level-circuit
18 | It is possible that both are the same, if we have a gate-level-verilog
19 | Objective:
20 | we want to simulate the gate-level-circuit with methods in class Circuit
21 | and compare the results with modelsim simulation of the verilog.
22 | Tasks:
23 | - Check if the PI/PO of the files are the same -- raise error if not match
24 | - etc.
25 | """
26 | self.c_name = c_name
27 | self.tp_count = tp_count
28 |
29 |
30 | def modelsim_wrapper(self):
31 | '''
32 | Given the circuit name and test pattern count, it will do the logic_sim on our platform and the simulation on ModelSim
33 | Return the check result between logic_sim and ModelSim
34 | #We use read_verilog() here
35 | '''
36 | #Generate random inputs patterns for circuit
37 | #Simulate the random input patterns with modelsim, using Modelsim class
38 | #Store the golden results in correct locations
39 | #This is simply a wrapper around class Modelsim
40 | circuit = Circuit(self.c_name)
41 | #self.circuit = circuit
42 | LoadCircuit(circuit, 'v')
43 | circuit.lev()
44 | sim = Modelsim()
45 | sim.project(circuit)
46 | #sim.gen_tb(sim.gen_rand_tp(tp_count= tp_count))
47 | sim.gen_rand_tp(tp_count= self.tp_count)
48 | sim.gen_tb()
49 | sim.simulation()
50 | self.tp_path = os.path.join(sim.path_gold, 'golden_' + circuit.c_name + '_'+ str(self.tp_count)+ '_b.txt')
51 | #return self.check_IO_golden(circuit, self.tp_path)
52 |
53 | def check_ckt_verilog(self, ckt_format = 'verilog'):
54 | #check verilog with golden_IO
55 | #check ckt with golden_IO
56 |
57 | circuit = Circuit(self.c_name)
58 | if ckt_format == 'verilog':
59 | LoadCircuit(circuit, 'v')
60 | elif ckt_format == 'ckt':
61 | LoadCircuit(circuit)
62 | circuit.lev()
63 | if self.check_IO_golden(circuit) == True:
64 | print(ckt_format + ': ' + circuit.c_name + ' matches golden_IO!')
65 | else:
66 | print(ckt_format + ': ' + circuit.c_name + ' does not match golden_IO!')
67 |
68 | def check_PI_PO(self):
69 | #Given a circuit name, check the PI/PO pins between verilog and ckt
70 | #from http://sportlab.usc.edu/~msabrishami/benchmarks.html
71 | #between CKT-658 and verilog
72 | #circuit: 1355 has different PI/PO pins
73 | #circuit: 17, 432, 499, 880, 1908, 3540, 5315, 6288 has the same PI/PO pins
74 |
75 | if self.find_file(config.VERILOG_DIR, self.c_name + '.v') == True and self.find_file(config.CKT_DIR, self.c_name + '.ckt'):
76 | circuit_verilog = Circuit(self.c_name)
77 | LoadCircuit(circuit_verilog, 'v')
78 | circuit_ckt = Circuit(self.c_name)
79 | LoadCircuit(circuit_ckt)
80 | if self.get_pin_num(circuit_verilog.PO) == self.get_pin_num(circuit_ckt.PO) and self.get_pin_num(circuit_verilog.PI) == self.get_pin_num(circuit_ckt.PI):
81 | print('PI/PO pins between ckt and verilog of {} are the same!'.format(self.c_name))
82 | return True
83 | else:
84 | print('PI/PO pins between ckt and verilog of {} are different!'.format(self.c_name))
85 | return False
86 | else:
87 | print('miss ckt or verilog files for {} circuit'.format(self.c_name))
88 | return False
89 |
90 | def get_pin_num(self, node_list):
91 | #get the pins number list
92 | num_list = []
93 | for node in node_list:
94 | num_list.append(node.num)
95 | return num_list
96 |
97 | def find_file(self, path, fname):
98 | #check if the file is exist
99 | for r, d, f in os.walk(path):
100 | if fname in f:
101 | return True
102 | else:
103 | return False
104 |
105 | def check_IO_golden(self, circuit):
106 | #we have golden_test() in circuit
107 | #We already generated golden-results
108 | #Now we just want to check if circuit.logicsim of ckt or verilog matches
109 | infile = open(self.tp_path, "r")
110 | lines = infile.readlines()
111 | PI_t_order = [x.lstrip('N') for x in lines[0][8:].strip().split(',')]
112 | PO_t_order = [x.lstrip('N') for x in lines[1][8:].strip().split(',')]
113 | PI_num = [x.num.lstrip('N') for x in circuit.PI]
114 | PO_num = [x.num.lstrip('N') for x in circuit.PO]
115 |
116 | #print("Logic-Sim validation with {} patterns".format(int((len(lines)-2)/3)))
117 | if PI_t_order != PI_num:
118 | print("Error:{} PI node order does not match! ".format(circuit.c_name))
119 | return False
120 | if PO_t_order != PO_num:
121 | print("Error:{} PO node order does not match! ".format(circuit.c_name))
122 | return False
123 | for t in range(int((len(lines)-2)/3)):
124 | test_in = [int(x) for x in lines[(t+1)*3].strip().split(',')]
125 | test_out = [int(x) for x in lines[(t+1)*3+1].strip().split(',')]
126 | circuit.logic_sim(test_in)
127 | logic_out = circuit.read_PO()
128 |
129 | logic_out = { k.replace('N', ''): v for k, v in logic_out.items() }
130 | for i in range(len(PO_t_order)):
131 | out_node = PO_t_order[i]
132 | out_node_golden = test_out[i]
133 | if out_node_golden != logic_out[out_node]:
134 | print("Error:{} PO values do not match! ".format(circuit.c_name))
135 | return False
136 | #print("Validation completed successfully - all correct")
137 | return True
138 |
--------------------------------------------------------------------------------
/circuit/tests/old/main_test_pfs.py:
--------------------------------------------------------------------------------
1 | # -*- coding: utf-8 -*-
2 |
3 |
4 | import argparse
5 | import pdb
6 | #import networkx as nx
7 | import math
8 | import time
9 | from random import randint
10 |
11 | from circuit.circuit import Circuit
12 | from circuit.inventory.modelsim_simulator import Modelsim
13 |
14 | import sys
15 | sys.path.insert(1, "../data/netlist_behavioral")
16 | from c432_logic_sim import c432_sim
17 | import config
18 |
19 | # change these
20 | from checker_logicsim import *
21 | from regular_tp_gen import *
22 | from checker_dfs import *
23 | from fault_sim import *
24 | from pfs import *
25 |
26 | def check_gate_netlist(circuit, total_T=1):
27 |
28 | for t in range(total_T):
29 | PI_dict = dict()
30 | PI_list = []
31 |
32 | PI_num = [x.num for x in circuit.PI]
33 | for pi in PI_num:
34 | val = randint(0,1)
35 | PI_dict["in" + str(pi)] = val
36 | PI_list.append(val)
37 |
38 | res_beh = c432_sim(PI_dict)
39 | circuit.logic_sim(PI_list)
40 | res_ckt = circuit.read_PO()
41 | if res_beh != res_ckt:
42 | print("Wrong")
43 | return False
44 | print("all test patterns passed")
45 | return True
46 |
47 |
48 | def main():
49 | parser = argparse.ArgumentParser()
50 | parser.add_argument("-ckt", type=str, required=True, help="circuit name, c17, no extension")
51 | parser.add_argument("-tp", type=int, required=False, help="number of tp for random sim")
52 | parser.add_argument("-cpu", type=int, required=False, help="number of parallel CPUs")
53 | args = parser.parse_args()
54 |
55 | print("\n======================================================")
56 | print("Run | circuit: {} | Test Count: {} | CPUs: {}".format(args.ckt, args.tp, args.cpu))
57 | print("======================================================\n")
58 |
59 | #Ting-Yu
60 |
61 | # for c in ['c17','c432','c499','c880','c1355','c1908','c2670','c3540','c5315','c6288','c7552']:
62 | # checker = Checker(c, args.tp)
63 | # if checker.check_PI_PO() == False:
64 | # print('#################################')
65 | # continue
66 | # checker.modelsim_wrapper()
67 | # checker.check_ckt_verilog('verilog')
68 | # checker.check_ckt_verilog('ckt')
69 | # print('#################################')
70 | # #exit()
71 |
72 |
73 | circuit = Circuit(args.ckt)
74 | circuit.lev()
75 |
76 | """ Testing PFS """
77 | print("PFS starts")
78 | pfs = PFS(circuit)
79 | # pfs.add_fault("full",None)
80 | # print(pfs.single([1,1,1,1,0]))
81 | pfs.fs_exe(tp_num=args.tp, t_mode='rand',
82 | r_mode='b', fault_list_type="full", fname = None)
83 |
84 | # circuit.FD_new_generator()
85 | exit()
86 |
87 |
88 |
89 | def parallel_graph():
90 | netlists = ["c17", "c432", "c499", "c880", "c1355", "c1908", "c2670",
91 | "c3540", "c5315", "c6288", "c7552"]
92 |
93 | if __name__ == "__main__":
94 | main()
95 |
--------------------------------------------------------------------------------
/circuit/tests/read_all_circuits.py:
--------------------------------------------------------------------------------
1 | # written in pfs_ppsf_test.py
2 |
3 | import os
4 | import sys
5 |
6 | sys.path.append('../')
7 | import config
8 | from tp_generator import TPGenerator
9 |
10 | from circuit.circuit import Circuit
11 |
12 | PRINT_PASSED = True
13 |
14 | if __name__ == '__main__':
15 | for dir in [config.CKT_DIR]:
16 | for cname in os.listdir(dir):
17 | if cname.endswith('v') or cname.endswith('ckt') and '_new' in cname:
18 | passed = True
19 | try:
20 | c = Circuit(os.path.join(dir,cname))
21 | except Exception as e:
22 | print(e)
23 | passed = False
24 | print(dir,cname, ':\terror in reading\n\n\n')
25 | # try: # [Test 1]
26 | tg = TPGenerator(c)
27 | # single_tp = tg.gen_single()
28 | # c.logic_sim(single_tp)
29 | # print('logic_sim passed')
30 | # except Exception as e:
31 | # # print(e)
32 | # passed = False
33 | # print(cname, ':\terror in single test implication')
34 |
35 | # try: # [Test 2]
36 | # temp_fname = 'temp.txt'
37 | # tg.gen_file(1, tp_fname=temp_fname)
38 | # single_tp = tg.load_file(temp_fname)
39 | # c.logic_sim(single_tp)
40 | # except Exception as e:
41 | # print(e)
42 | # passed = False
43 | # print(cname, ':\terror in test generating/reading test')
44 |
45 | # if PRINT_PASSED and passed:
46 | # print(dir, cname, ':\tpassed')
47 |
48 | # or_count = 0
49 | # and_count = 0
50 | # nand_count = 0
51 | # nor_count = 0
52 | # other_count = 0
53 | # xor_count = 0
54 | # xnor_count = 0
55 | # brch_count = 0
56 | # ipt_count = 0
57 | # buff_count = 0
58 | # not_count = 0
59 | # po_count = 0
60 | # for n in c.nodes_lev:
61 | # if n.gtype == 'NOR':
62 | # nor_count += 1
63 | # elif n.gtype == 'OR':
64 | # or_count += 1
65 | # elif n.gtype == 'NAND':
66 | # nand_count += 1
67 | # elif n.gtype == 'AND':
68 | # and_count += 1
69 | # elif n.gtype == 'XOR':
70 | # xor_count += 1
71 | # elif n.gtype == 'XNOR':
72 | # xnor_count += 1
73 | # elif n.gtype == 'BRCH':
74 | # brch_count += 1
75 | # elif n.gtype == 'IPT':
76 | # ipt_count += 1
77 | # elif n.gtype == 'BUFF':
78 | # buff_count += 1
79 | # elif n.gtype == 'NOT':
80 | # not_count += 1
81 | # if n.ntype == 'PO':
82 | # po_count += 1
83 |
84 |
85 | # else:
86 | # other_count += 1
87 | # print(f'{or_count=}, {and_count=}, {nand_count=}, {nor_count=}, {xor_count=}, {xnor_count=}\n'
88 | # f'{ipt_count=}, {brch_count=}, {not_count=}, {buff_count=}, {other_count=}')
89 | # print(f'{po_count=}')
90 | # print(f'#GATES = ',not_count+and_count+or_count+nand_count+nor_count+xor_count+xnor_count,'\n\n')
91 | # os.system(f'rm {temp_fname}')
--------------------------------------------------------------------------------
/circuit/tp_generator.py:
--------------------------------------------------------------------------------
1 | import random
2 | import config
3 | import os
4 | import utils
5 |
6 | class TPGenerator:
7 | def __init__(self, circuit):
8 | self.circuit = circuit
9 |
10 | def gen_single(self, mode="b"):
11 | """ Generate a random input pattern.
12 | mode b: generate values in {0, 1}
13 | mode x: generate values in {0, 1, X}
14 | returns a single input pattern
15 | """
16 | if mode not in ["b", "x"]:
17 | raise NameError("Mode is not acceptable")
18 |
19 | bits = [0, 1, config.X_VALUE]
20 | if mode == "b":
21 | tp = [int(bits[random.randint(0,1)]) for _ in range(len(self.circuit.PI))]
22 | elif mode == "x":
23 | tp = [bits[random.randint(0,2)] for _ in range(len(self.circuit.PI))]
24 |
25 | return tp
26 |
27 | def gen_n_random(self, tp_count, mode="b", unique=False):
28 | """ Generate multiple random input patterns
29 | mode b: generate values in {0, 1}
30 | mode x: generate values in {0, 1, X}
31 | returns a list of random test patterns
32 | does not store the generated tps in file
33 | """
34 |
35 | if 1< 12:
107 | print("Error: cannot generate full tp file for circuits with PI > 12")
108 | return []
109 | fn = os.path.join(config.PATTERN_DIR, self.circuit.c_name + "_tp_full.tp")
110 | tp_fname = fn if tp_fname==None else tp_fname
111 | outfile = open(tp_fname, 'w')
112 | outfile.write(",".join([str(node.num) for node in self.circuit.PI]) + "\n")
113 | tps = self.gen_full()
114 | for t in tps:
115 | outfile.write(",".join(str(t)) + "\n")
116 | outfile.close()
117 | print(f"Generated full test patterns and saved in {tp_fname}")
118 |
119 | return tps # better to return the file name
120 |
121 | def gen_partial(self, tp, default_value = 1):
122 | from collections import deque
123 |
124 | for t in range(len(tp)):
125 | if tp[t] == '_' or tp[t] is None: #'_' is different from None
126 | tp[t] = default_value
127 |
128 | all_tps = deque()
129 | all_tps.append(tp)
130 |
131 | while True:
132 | front_tp = all_tps.popleft()
133 | if not config.X_VALUE in front_tp:
134 | all_tps.append(front_tp)
135 | break
136 |
137 | first_x = None
138 | for t in range(len(front_tp)):
139 | if front_tp[t] == config.X_VALUE:
140 | first_x = t
141 | break
142 |
143 | #substitute zero and one
144 | if first_x is not None:
145 | tp_copy = front_tp.copy()
146 | tp_copy[first_x] = 1
147 | all_tps.append(tp_copy)
148 |
149 | front_tp[first_x] = 0
150 | all_tps.append(front_tp)
151 |
152 | return list(all_tps)
153 |
154 | @staticmethod
155 | def load_file(fname):
156 | """ Load single file with multiple test pattern vectors.
157 | Does not warn if the size of input nodes is less than each test pattern"""
158 | # do we need to check the order of the inputs in the file?
159 | # this can be done using "yield" or "generate" -- check online
160 |
161 | if not os.path.exists(fname):
162 | raise 'Test file does not exist. Use gen_tp_file() or gen_full_tp_file() instead'
163 | # return self.gen_tp_file(tp_count=tp_count,tp_fname=fname)
164 |
165 | infile = open(fname, 'r')
166 | tps = []
167 | lines = infile.readlines()
168 |
169 | for line in lines[1:]:
170 | words = line.rstrip().split(',')
171 | words = [int(word) if word == '1' or word == '0' else 'X' for word in words]
172 | tps.append(words)
173 | infile.close()
174 | return tps
175 |
--------------------------------------------------------------------------------
/data/README.md:
--------------------------------------------------------------------------------
1 |
2 | ##ISCAS
3 | These are netlists in ISCAS (.isc) format. Downloaded from the original website, last modified date is 2007.
4 |
--------------------------------------------------------------------------------
/data/bench/c17.bench:
--------------------------------------------------------------------------------
1 | # c17
2 | # 5 inputs
3 | # 2 outputs
4 | # 0 inverter
5 | # 6 gates ( 6 NANDs )
6 |
7 | INPUT(1)
8 | INPUT(2)
9 | INPUT(3)
10 | INPUT(6)
11 | INPUT(7)
12 |
13 | OUTPUT(22)
14 | OUTPUT(23)
15 |
16 | 10 = NAND(1, 3)
17 | 11 = NAND(3, 6)
18 | 16 = NAND(2, 11)
19 | 19 = NAND(11, 7)
20 | 22 = NAND(10, 16)
21 | 23 = NAND(16, 19)
--------------------------------------------------------------------------------
/data/bench/c432.bench:
--------------------------------------------------------------------------------
1 | # c432
2 | # 36 inputs
3 | # 7 outputs
4 | # 40 inverters
5 | # 120 gates ( 4 ANDs + 119 NANDs + 19 NORs + 18 XORs )
6 |
7 | INPUT(1)
8 | INPUT(4)
9 | INPUT(8)
10 | INPUT(11)
11 | INPUT(14)
12 | INPUT(17)
13 | INPUT(21)
14 | INPUT(24)
15 | INPUT(27)
16 | INPUT(30)
17 | INPUT(34)
18 | INPUT(37)
19 | INPUT(40)
20 | INPUT(43)
21 | INPUT(47)
22 | INPUT(50)
23 | INPUT(53)
24 | INPUT(56)
25 | INPUT(60)
26 | INPUT(63)
27 | INPUT(66)
28 | INPUT(69)
29 | INPUT(73)
30 | INPUT(76)
31 | INPUT(79)
32 | INPUT(82)
33 | INPUT(86)
34 | INPUT(89)
35 | INPUT(92)
36 | INPUT(95)
37 | INPUT(99)
38 | INPUT(102)
39 | INPUT(105)
40 | INPUT(108)
41 | INPUT(112)
42 | INPUT(115)
43 |
44 | OUTPUT(223)
45 | OUTPUT(329)
46 | OUTPUT(370)
47 | OUTPUT(421)
48 | OUTPUT(430)
49 | OUTPUT(431)
50 | OUTPUT(432)
51 |
52 | 118 = NOT(1)
53 | 119 = NOT(4)
54 | 122 = NOT(11)
55 | 123 = NOT(17)
56 | 126 = NOT(24)
57 | 127 = NOT(30)
58 | 130 = NOT(37)
59 | 131 = NOT(43)
60 | 134 = NOT(50)
61 | 135 = NOT(56)
62 | 138 = NOT(63)
63 | 139 = NOT(69)
64 | 142 = NOT(76)
65 | 143 = NOT(82)
66 | 146 = NOT(89)
67 | 147 = NOT(95)
68 | 150 = NOT(102)
69 | 151 = NOT(108)
70 | 154 = NAND(118, 4)
71 | 157 = NOR(8, 119)
72 | 158 = NOR(14, 119)
73 | 159 = NAND(122, 17)
74 | 162 = NAND(126, 30)
75 | 165 = NAND(130, 43)
76 | 168 = NAND(134, 56)
77 | 171 = NAND(138, 69)
78 | 174 = NAND(142, 82)
79 | 177 = NAND(146, 95)
80 | 180 = NAND(150, 108)
81 | 183 = NOR(21, 123)
82 | 184 = NOR(27, 123)
83 | 185 = NOR(34, 127)
84 | 186 = NOR(40, 127)
85 | 187 = NOR(47, 131)
86 | 188 = NOR(53, 131)
87 | 189 = NOR(60, 135)
88 | 190 = NOR(66, 135)
89 | 191 = NOR(73, 139)
90 | 192 = NOR(79, 139)
91 | 193 = NOR(86, 143)
92 | 194 = NOR(92, 143)
93 | 195 = NOR(99, 147)
94 | 196 = NOR(105, 147)
95 | 197 = NOR(112, 151)
96 | 198 = NOR(115, 151)
97 | 199 = AND(154, 159, 162, 165, 168, 171, 174, 177, 180)
98 | 203 = NOT(199)
99 | 213 = NOT(199)
100 | 223 = NOT(199)
101 | 224 = XOR(203, 154)
102 | 227 = XOR(203, 159)
103 | 230 = XOR(203, 162)
104 | 233 = XOR(203, 165)
105 | 236 = XOR(203, 168)
106 | 239 = XOR(203, 171)
107 | 242 = NAND(1, 213)
108 | 243 = XOR(203, 174)
109 | 246 = NAND(213, 11)
110 | 247 = XOR(203, 177)
111 | 250 = NAND(213, 24)
112 | 251 = XOR(203, 180)
113 | 254 = NAND(213, 37)
114 | 255 = NAND(213, 50)
115 | 256 = NAND(213, 63)
116 | 257 = NAND(213, 76)
117 | 258 = NAND(213, 89)
118 | 259 = NAND(213, 102)
119 | 260 = NAND(224, 157)
120 | 263 = NAND(224, 158)
121 | 264 = NAND(227, 183)
122 | 267 = NAND(230, 185)
123 | 270 = NAND(233, 187)
124 | 273 = NAND(236, 189)
125 | 276 = NAND(239, 191)
126 | 279 = NAND(243, 193)
127 | 282 = NAND(247, 195)
128 | 285 = NAND(251, 197)
129 | 288 = NAND(227, 184)
130 | 289 = NAND(230, 186)
131 | 290 = NAND(233, 188)
132 | 291 = NAND(236, 190)
133 | 292 = NAND(239, 192)
134 | 293 = NAND(243, 194)
135 | 294 = NAND(247, 196)
136 | 295 = NAND(251, 198)
137 | 296 = AND(260, 264, 267, 270, 273, 276, 279, 282, 285)
138 | 300 = NOT(263)
139 | 301 = NOT(288)
140 | 302 = NOT(289)
141 | 303 = NOT(290)
142 | 304 = NOT(291)
143 | 305 = NOT(292)
144 | 306 = NOT(293)
145 | 307 = NOT(294)
146 | 308 = NOT(295)
147 | 309 = NOT(296)
148 | 319 = NOT(296)
149 | 329 = NOT(296)
150 | 330 = XOR(309, 260)
151 | 331 = XOR(309, 264)
152 | 332 = XOR(309, 267)
153 | 333 = XOR(309, 270)
154 | 334 = NAND(8, 319)
155 | 335 = XOR(309, 273)
156 | 336 = NAND(319, 21)
157 | 337 = XOR(309, 276)
158 | 338 = NAND(319, 34)
159 | 339 = XOR(309, 279)
160 | 340 = NAND(319, 47)
161 | 341 = XOR(309, 282)
162 | 342 = NAND(319, 60)
163 | 343 = XOR(309, 285)
164 | 344 = NAND(319, 73)
165 | 345 = NAND(319, 86)
166 | 346 = NAND(319, 99)
167 | 347 = NAND(319, 112)
168 | 348 = NAND(330, 300)
169 | 349 = NAND(331, 301)
170 | 350 = NAND(332, 302)
171 | 351 = NAND(333, 303)
172 | 352 = NAND(335, 304)
173 | 353 = NAND(337, 305)
174 | 354 = NAND(339, 306)
175 | 355 = NAND(341, 307)
176 | 356 = NAND(343, 308)
177 | 357 = AND(348, 349, 350, 351, 352, 353, 354, 355, 356)
178 | 360 = NOT(357)
179 | 370 = NOT(357)
180 | 371 = NAND(14, 360)
181 | 372 = NAND(360, 27)
182 | 373 = NAND(360, 40)
183 | 374 = NAND(360, 53)
184 | 375 = NAND(360, 66)
185 | 376 = NAND(360, 79)
186 | 377 = NAND(360, 92)
187 | 378 = NAND(360, 105)
188 | 379 = NAND(360, 115)
189 | 380 = NAND(4, 242, 334, 371)
190 | 381 = NAND(246, 336, 372, 17)
191 | 386 = NAND(250, 338, 373, 30)
192 | 393 = NAND(254, 340, 374, 43)
193 | 399 = NAND(255, 342, 375, 56)
194 | 404 = NAND(256, 344, 376, 69)
195 | 407 = NAND(257, 345, 377, 82)
196 | 411 = NAND(258, 346, 378, 95)
197 | 414 = NAND(259, 347, 379, 108)
198 | 415 = NOT(380)
199 | 416 = AND(381, 386, 393, 399, 404, 407, 411, 414)
200 | 417 = NOT(393)
201 | 418 = NOT(404)
202 | 419 = NOT(407)
203 | 420 = NOT(411)
204 | 421 = NOR(415, 416)
205 | 422 = NAND(386, 417)
206 | 425 = NAND(386, 393, 418, 399)
207 | 428 = NAND(399, 393, 419)
208 | 429 = NAND(386, 393, 407, 420)
209 | 430 = NAND(381, 386, 422, 399)
210 | 431 = NAND(381, 386, 425, 428)
211 | 432 = NAND(381, 422, 425, 429)
--------------------------------------------------------------------------------
/data/bench/c499.bench:
--------------------------------------------------------------------------------
1 | # c499
2 | # 41 inputs
3 | # 32 outputs
4 | # 40 inverters
5 | # 162 gates ( 56 ANDs + 40 NANDs + 2 ORs + 104 XORs )
6 |
7 | INPUT(1)
8 | INPUT(5)
9 | INPUT(9)
10 | INPUT(13)
11 | INPUT(17)
12 | INPUT(21)
13 | INPUT(25)
14 | INPUT(29)
15 | INPUT(33)
16 | INPUT(37)
17 | INPUT(41)
18 | INPUT(45)
19 | INPUT(49)
20 | INPUT(53)
21 | INPUT(57)
22 | INPUT(61)
23 | INPUT(65)
24 | INPUT(69)
25 | INPUT(73)
26 | INPUT(77)
27 | INPUT(81)
28 | INPUT(85)
29 | INPUT(89)
30 | INPUT(93)
31 | INPUT(97)
32 | INPUT(101)
33 | INPUT(105)
34 | INPUT(109)
35 | INPUT(113)
36 | INPUT(117)
37 | INPUT(121)
38 | INPUT(125)
39 | INPUT(129)
40 | INPUT(130)
41 | INPUT(131)
42 | INPUT(132)
43 | INPUT(133)
44 | INPUT(134)
45 | INPUT(135)
46 | INPUT(136)
47 | INPUT(137)
48 |
49 | OUTPUT(724)
50 | OUTPUT(725)
51 | OUTPUT(726)
52 | OUTPUT(727)
53 | OUTPUT(728)
54 | OUTPUT(729)
55 | OUTPUT(730)
56 | OUTPUT(731)
57 | OUTPUT(732)
58 | OUTPUT(733)
59 | OUTPUT(734)
60 | OUTPUT(735)
61 | OUTPUT(736)
62 | OUTPUT(737)
63 | OUTPUT(738)
64 | OUTPUT(739)
65 | OUTPUT(740)
66 | OUTPUT(741)
67 | OUTPUT(742)
68 | OUTPUT(743)
69 | OUTPUT(744)
70 | OUTPUT(745)
71 | OUTPUT(746)
72 | OUTPUT(747)
73 | OUTPUT(748)
74 | OUTPUT(749)
75 | OUTPUT(750)
76 | OUTPUT(751)
77 | OUTPUT(752)
78 | OUTPUT(753)
79 | OUTPUT(754)
80 | OUTPUT(755)
81 |
82 | 250 = XOR(1, 5)
83 | 251 = XOR(9, 13)
84 | 252 = XOR(17, 21)
85 | 253 = XOR(25, 29)
86 | 254 = XOR(33, 37)
87 | 255 = XOR(41, 45)
88 | 256 = XOR(49, 53)
89 | 257 = XOR(57, 61)
90 | 258 = XOR(65, 69)
91 | 259 = XOR(73, 77)
92 | 260 = XOR(81, 85)
93 | 261 = XOR(89, 93)
94 | 262 = XOR(97, 101)
95 | 263 = XOR(105, 109)
96 | 264 = XOR(113, 117)
97 | 265 = XOR(121, 125)
98 | 266 = AND(129, 137)
99 | 267 = AND(130, 137)
100 | 268 = AND(131, 137)
101 | 269 = AND(132, 137)
102 | 270 = AND(133, 137)
103 | 271 = AND(134, 137)
104 | 272 = AND(135, 137)
105 | 273 = AND(136, 137)
106 | 274 = XOR(1, 17)
107 | 275 = XOR(33, 49)
108 | 276 = XOR(5, 21)
109 | 277 = XOR(37, 53)
110 | 278 = XOR(9, 25)
111 | 279 = XOR(41, 57)
112 | 280 = XOR(13, 29)
113 | 281 = XOR(45, 61)
114 | 282 = XOR(65, 81)
115 | 283 = XOR(97, 113)
116 | 284 = XOR(69, 85)
117 | 285 = XOR(101, 117)
118 | 286 = XOR(73, 89)
119 | 287 = XOR(105, 121)
120 | 288 = XOR(77, 93)
121 | 289 = XOR(109, 125)
122 | 290 = XOR(250, 251)
123 | 293 = XOR(252, 253)
124 | 296 = XOR(254, 255)
125 | 299 = XOR(256, 257)
126 | 302 = XOR(258, 259)
127 | 305 = XOR(260, 261)
128 | 308 = XOR(262, 263)
129 | 311 = XOR(264, 265)
130 | 314 = XOR(274, 275)
131 | 315 = XOR(276, 277)
132 | 316 = XOR(278, 279)
133 | 317 = XOR(280, 281)
134 | 318 = XOR(282, 283)
135 | 319 = XOR(284, 285)
136 | 320 = XOR(286, 287)
137 | 321 = XOR(288, 289)
138 | 338 = XOR(290, 293)
139 | 339 = XOR(296, 299)
140 | 340 = XOR(290, 296)
141 | 341 = XOR(293, 299)
142 | 342 = XOR(302, 305)
143 | 343 = XOR(308, 311)
144 | 344 = XOR(302, 308)
145 | 345 = XOR(305, 311)
146 | 346 = XOR(266, 342)
147 | 347 = XOR(267, 343)
148 | 348 = XOR(268, 344)
149 | 349 = XOR(269, 345)
150 | 350 = XOR(270, 338)
151 | 351 = XOR(271, 339)
152 | 352 = XOR(272, 340)
153 | 353 = XOR(273, 341)
154 | 354 = XOR(314, 346)
155 | 367 = XOR(315, 347)
156 | 380 = XOR(316, 348)
157 | 393 = XOR(317, 349)
158 | 406 = XOR(318, 350)
159 | 419 = XOR(319, 351)
160 | 432 = XOR(320, 352)
161 | 445 = XOR(321, 353)
162 | 554 = NOT(354)
163 | 555 = NOT(367)
164 | 556 = NOT(380)
165 | 557 = NOT(354)
166 | 558 = NOT(367)
167 | 559 = NOT(393)
168 | 560 = NOT(354)
169 | 561 = NOT(380)
170 | 562 = NOT(393)
171 | 563 = NOT(367)
172 | 564 = NOT(380)
173 | 565 = NOT(393)
174 | 566 = NOT(419)
175 | 567 = NOT(445)
176 | 568 = NOT(419)
177 | 569 = NOT(432)
178 | 570 = NOT(406)
179 | 571 = NOT(445)
180 | 572 = NOT(406)
181 | 573 = NOT(432)
182 | 574 = NOT(406)
183 | 575 = NOT(419)
184 | 576 = NOT(432)
185 | 577 = NOT(406)
186 | 578 = NOT(419)
187 | 579 = NOT(445)
188 | 580 = NOT(406)
189 | 581 = NOT(432)
190 | 582 = NOT(445)
191 | 583 = NOT(419)
192 | 584 = NOT(432)
193 | 585 = NOT(445)
194 | 586 = NOT(367)
195 | 587 = NOT(393)
196 | 588 = NOT(367)
197 | 589 = NOT(380)
198 | 590 = NOT(354)
199 | 591 = NOT(393)
200 | 592 = NOT(354)
201 | 593 = NOT(380)
202 | 594 = AND(554, 555, 556, 393)
203 | 595 = AND(557, 558, 380, 559)
204 | 596 = AND(560, 367, 561, 562)
205 | 597 = AND(354, 563, 564, 565)
206 | 598 = AND(574, 575, 576, 445)
207 | 599 = AND(577, 578, 432, 579)
208 | 600 = AND(580, 419, 581, 582)
209 | 601 = AND(406, 583, 584, 585)
210 | 602 = OR(594, 595, 596, 597)
211 | 607 = OR(598, 599, 600, 601)
212 | 620 = AND(406, 566, 432, 567, 602)
213 | 625 = AND(406, 568, 569, 445, 602)
214 | 630 = AND(570, 419, 432, 571, 602)
215 | 635 = AND(572, 419, 573, 445, 602)
216 | 640 = AND(354, 586, 380, 587, 607)
217 | 645 = AND(354, 588, 589, 393, 607)
218 | 650 = AND(590, 367, 380, 591, 607)
219 | 655 = AND(592, 367, 593, 393, 607)
220 | 692 = AND(354, 620)
221 | 693 = AND(367, 620)
222 | 694 = AND(380, 620)
223 | 695 = AND(393, 620)
224 | 696 = AND(354, 625)
225 | 697 = AND(367, 625)
226 | 698 = AND(380, 625)
227 | 699 = AND(393, 625)
228 | 700 = AND(354, 630)
229 | 701 = AND(367, 630)
230 | 702 = AND(380, 630)
231 | 703 = AND(393, 630)
232 | 704 = AND(354, 635)
233 | 705 = AND(367, 635)
234 | 706 = AND(380, 635)
235 | 707 = AND(393, 635)
236 | 708 = AND(406, 640)
237 | 709 = AND(419, 640)
238 | 710 = AND(432, 640)
239 | 711 = AND(445, 640)
240 | 712 = AND(406, 645)
241 | 713 = AND(419, 645)
242 | 714 = AND(432, 645)
243 | 715 = AND(445, 645)
244 | 716 = AND(406, 650)
245 | 717 = AND(419, 650)
246 | 718 = AND(432, 650)
247 | 719 = AND(445, 650)
248 | 720 = AND(406, 655)
249 | 721 = AND(419, 655)
250 | 722 = AND(432, 655)
251 | 723 = AND(445, 655)
252 | 724 = XOR(1, 692)
253 | 725 = XOR(5, 693)
254 | 726 = XOR(9, 694)
255 | 727 = XOR(13, 695)
256 | 728 = XOR(17, 696)
257 | 729 = XOR(21, 697)
258 | 730 = XOR(25, 698)
259 | 731 = XOR(29, 699)
260 | 732 = XOR(33, 700)
261 | 733 = XOR(37, 701)
262 | 734 = XOR(41, 702)
263 | 735 = XOR(45, 703)
264 | 736 = XOR(49, 704)
265 | 737 = XOR(53, 705)
266 | 738 = XOR(57, 706)
267 | 739 = XOR(61, 707)
268 | 740 = XOR(65, 708)
269 | 741 = XOR(69, 709)
270 | 742 = XOR(73, 710)
271 | 743 = XOR(77, 711)
272 | 744 = XOR(81, 712)
273 | 745 = XOR(85, 713)
274 | 746 = XOR(89, 714)
275 | 747 = XOR(93, 715)
276 | 748 = XOR(97, 716)
277 | 749 = XOR(101, 717)
278 | 750 = XOR(105, 718)
279 | 751 = XOR(109, 719)
280 | 752 = XOR(113, 720)
281 | 753 = XOR(117, 721)
282 | 754 = XOR(121, 722)
283 | 755 = XOR(125, 723)
--------------------------------------------------------------------------------
/data/ckt/FA.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 2 0
2 | 1 2 0 2 0
3 | 1 3 0 2 0
4 | 2 4 1 1
5 | 2 5 1 2
6 | 2 6 1 1
7 | 2 7 1 2
8 | 0 8 2 2 2 4 5
9 | 2 9 1 8
10 | 2 10 1 8
11 | 2 11 1 3
12 | 2 12 1 3
13 | 3 13 2 0 2 9 11
14 | 0 14 7 1 2 10 12
15 | 0 15 7 1 2 6 7
16 | 3 16 3 0 2 14 15
17 |
--------------------------------------------------------------------------------
/data/ckt/FA_NAND.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 2 0
2 | 1 2 0 2 0
3 | 1 3 0 2 0
4 | 2 4 1 1
5 | 2 5 1 2
6 | 2 6 1 1
7 | 2 7 1 2
8 | 0 8 6 3 2 4 5
9 | 2 9 1 8
10 | 2 11 1 8
11 | 2 24 1 8
12 | 0 12 6 1 2 6 9
13 | 0 13 6 1 2 11 7
14 | 0 14 6 2 2 12 13
15 | 2 15 1 14
16 | 2 16 1 14
17 | 2 17 1 3
18 | 2 18 1 3
19 | 0 19 6 3 2 16 17
20 | 2 20 1 19
21 | 2 22 1 19
22 | 2 23 1 19
23 | 0 25 6 1 2 15 20
24 | 0 26 6 1 2 22 18
25 | 3 27 6 0 2 25 26
26 | 3 28 6 0 2 23 24
27 |
--------------------------------------------------------------------------------
/data/ckt/add2.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 1 0
2 | 1 2 0 1 0
3 | 1 3 0 1 0
4 | 1 4 0 1 0
5 | 1 5 0 1 0
6 | 0 6 7 2 1 1
7 | 2 7 1 6
8 | 2 8 1 6
9 | 0 9 7 2 1 2
10 | 2 10 1 9
11 | 2 11 1 9
12 | 0 12 7 2 1 3
13 | 2 13 1 12
14 | 2 14 1 12
15 | 0 15 7 2 1 4
16 | 2 16 1 15
17 | 2 17 1 15
18 | 0 18 7 2 1 5
19 | 2 19 1 18
20 | 2 20 1 18
21 | 0 21 5 1 1 7
22 | 0 22 3 1 2 10 13
23 | 0 23 6 2 2 11 14
24 | 2 24 1 23
25 | 2 25 1 23
26 | 0 26 6 2 2 22 24
27 | 2 27 1 26
28 | 2 28 1 26
29 | 0 29 6 1 2 21 27
30 | 0 30 5 1 1 28
31 | 0 31 6 2 2 8 30
32 | 2 32 1 31
33 | 2 33 1 31
34 | 0 34 6 2 2 33 25
35 | 2 35 1 34
36 | 2 36 1 34
37 | 0 37 5 1 1 35
38 | 0 38 3 1 2 16 19
39 | 0 39 6 2 2 17 20
40 | 2 40 1 39
41 | 2 41 1 39
42 | 0 42 6 2 2 38 40
43 | 2 43 1 42
44 | 2 44 1 42
45 | 0 45 6 1 2 37 43
46 | 0 46 5 1 1 44
47 | 0 47 6 2 2 36 46
48 | 2 48 1 47
49 | 2 49 1 47
50 | 3 50 7 0 2 29 32
51 | 3 51 7 0 2 45 48
52 | 3 52 6 0 2 49 41
53 |
--------------------------------------------------------------------------------
/data/ckt/c1.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 1 0
2 | 1 2 0 2 0
3 | 2 10 1 2
4 | 2 11 1 2
5 | 1 5 0 1 0
6 | 1 6 0 2 0
7 | 2 12 1 6
8 | 2 13 1 6
9 | 1 9 0 1 0
10 | 0 14 4 1 2 1 10
11 | 0 15 6 2 3 11 12 5
12 | 2 19 1 15
13 | 2 20 1 15
14 | 0 18 5 1 1 13
15 | 0 21 4 1 2 18 9
16 | 3 22 7 0 2 14 19
17 | 3 23 7 0 2 20 21
18 |
--------------------------------------------------------------------------------
/data/ckt/c17.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 1 0
2 | 1 2 0 1 0
3 | 1 3 0 2 0
4 | 2 8 1 3
5 | 2 9 1 3
6 | 1 6 0 1 0
7 | 1 7 0 1 0
8 | 0 10 6 1 2 1 8
9 | 0 11 6 2 2 9 6
10 | 2 14 1 11
11 | 2 15 1 11
12 | 0 16 6 2 2 2 14
13 | 2 20 1 16
14 | 2 21 1 16
15 | 0 19 6 1 2 15 7
16 | 3 22 6 0 2 10 20
17 | 3 23 6 0 2 21 19
18 |
--------------------------------------------------------------------------------
/data/ckt/c2.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 1 0
2 | 1 2 0 1 0
3 | 1 3 0 2 0
4 | 2 8 1 3
5 | 2 9 1 3
6 | 1 4 0 2 0
7 | 2 10 1 4
8 | 2 11 1 4
9 | 1 5 0 2 0
10 | 2 12 1 5
11 | 2 13 1 5
12 | 1 6 0 1 0
13 | 1 7 0 1 0
14 | 0 14 7 1 2 1 2
15 | 0 15 7 1 2 8 10
16 | 0 16 5 1 1 9
17 | 0 17 5 1 1 11
18 | 0 18 5 1 1 13
19 | 0 19 7 1 3 12 6 7
20 | 0 20 3 1 2 14 15
21 | 0 21 3 1 3 16 17 18
22 | 3 22 7 0 3 20 21 19
--------------------------------------------------------------------------------
/data/ckt/c3.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 2 0
2 | 2 13 1 1
3 | 2 14 1 1
4 | 1 4 0 2 0
5 | 2 15 1 4
6 | 2 16 1 4
7 | 1 7 0 2 0
8 | 2 17 1 7
9 | 2 18 1 7
10 | 1 10 0 2 0
11 | 2 19 1 10
12 | 2 20 1 10
13 | 0 21 5 1 1 13
14 | 0 22 7 2 2 16 17
15 | 2 26 1 22
16 | 2 27 1 22
17 | 0 25 5 1 1 20
18 | 0 28 6 1 2 15 21
19 | 0 29 6 1 2 14 26
20 | 0 30 6 1 2 27 19
21 | 0 31 6 1 2 25 18
22 | 3 32 6 0 4 28 29 30 31
--------------------------------------------------------------------------------
/data/ckt/c4.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 2 0
2 | 2 13 1 1
3 | 2 14 1 1
4 | 1 4 0 3 0
5 | 2 15 1 4
6 | 2 16 1 4
7 | 2 17 1 4
8 | 1 8 0 3 0
9 | 2 18 1 8
10 | 2 19 1 8
11 | 2 20 1 8
12 | 1 12 0 2 0
13 | 2 21 1 12
14 | 2 22 1 12
15 | 0 23 6 1 2 13 18
16 | 0 24 6 2 2 16 19
17 | 2 28 1 24
18 | 2 29 1 24
19 | 0 27 6 1 2 17 22
20 | 0 30 6 1 2 15 23
21 | 0 31 6 1 2 14 28
22 | 0 32 6 1 2 29 21
23 | 0 33 6 1 2 27 20
24 | 3 34 6 0 4 30 31 32 33
--------------------------------------------------------------------------------
/data/ckt/cmini.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 1 0
2 | 1 2 0 2 0
3 | 2 3 1 2
4 | 2 4 1 2
5 | 1 5 0 1 0
6 | 0 6 7 2 2 1 3
7 | 2 7 1 6
8 | 2 8 1 4
9 | 2 9 1 4
10 | 2 10 1 27
11 | 2 11 1 27
12 | 0 12 8 2 2 7 8
13 | 2 13 1 12
14 | 0 14 8 2 2 11 13
15 | 2 15 1 14
16 | 2 16 1 14
17 | 0 17 5 2 1 16
18 | 2 18 1 28
19 | 2 19 1 28
20 | 2 20 1 17
21 | 2 21 1 17
22 | 0 22 5 1 1 18
23 | 0 23 8 1 2 21 9
24 | 3 24 6 0 2 10 15
25 | 3 25 3 0 2 20 22
26 | 3 26 6 0 3 23 19 5
27 | 2 27 1 6
28 | 2 28 1 12
--------------------------------------------------------------------------------
/data/ckt/x3mult.ckt:
--------------------------------------------------------------------------------
1 | 1 1 0 1 0
2 | 1 2 0 1 0
3 | 1 3 0 1 0
4 | 0 4 7 4 1 1
5 | 2 5 1 4
6 | 2 6 1 4
7 | 2 7 1 4
8 | 2 8 1 4
9 | 0 9 7 2 1 2
10 | 2 10 1 9
11 | 2 11 1 9
12 | 0 12 7 2 1 3
13 | 2 13 1 12
14 | 2 14 1 12
15 | 0 15 5 2 1 8
16 | 2 16 1 15
17 | 2 17 1 15
18 | 0 18 5 1 1 10
19 | 0 19 5 1 1 14
20 | 0 20 7 2 2 18 13
21 | 2 21 1 20
22 | 2 22 1 20
23 | 0 23 7 3 2 11 19
24 | 2 24 1 23
25 | 2 25 1 23
26 | 2 26 1 23
27 | 0 27 7 1 2 16 21
28 | 0 28 3 2 2 22 24
29 | 2 29 1 28
30 | 2 30 1 28
31 | 0 31 7 1 2 26 17
32 | 0 32 5 2 1 30
33 | 2 33 1 32
34 | 2 34 1 32
35 | 0 35 7 1 2 7 33
36 | 0 36 3 1 2 34 25
37 | 0 37 7 1 2 6 36
38 | 3 38 3 0 2 37 27
39 | 3 39 7 0 2 5 29
40 | 3 40 3 0 2 35 31
41 |
--------------------------------------------------------------------------------
/data/config.py:
--------------------------------------------------------------------------------
1 | #TODO: deprecate this file. Similar file exists in ../circuit/
2 |
3 | LIB_CELLS_PATH = "../data/library"
4 | MODELSIM_DIR = "../data/modelsim"
5 | MODELSIM_INPUT_DIR = "input"
6 | MODELSIM_GOLD_DIR = "gold"
7 | MODELSIM_OUTPUT_DIR = "output"
8 | VERILOG_DIR = "../data/verilog"
9 | ### VERILOG_DIR = "../data/EPFL" -- deprecated
10 | PATTERN_DIR ="../data/patterns"
11 | # in each modelsim prj directory where inputs will be stored
12 | ## TODO for Ting-Yu: read a good description for these constants
13 |
14 | FAULT_DICT_DIR = "../data/fault_dict_new"
15 | FAULT_SIM_DIR = "../data/fault_sim"
16 | CKT_DIR = "../data/ckt"
17 | FIG_DIR = "../data/figures"
18 | # TEST POINT INSERTION PROBLEM:
19 | HTO_TH = 0.1
20 | HTC_TH = 0.05
21 | STAFAN_B_MIN = 0.0001
22 | STAFAN_C_MIN = 0.001
23 |
24 | SAMPLES = 100
25 |
26 | V_FORMATS = ["EPFL", "ISCAS85"]
27 |
28 | # LOGIC LIBRARY RELATED:
29 | CELL_NAMES = {
30 | "XOR": ["xor", "XOR2", "XOR2_X1"],
31 | "XNOR": ["xnor", "XNOR2", "XNOR2_X1"],
32 | "OR": ["or", "OR2", "OR2_X1", "OR", "OR2_X2", "OR3_X1", "OR4_X1"],
33 | "NOR": ["nor", "NOR2", "NOR2_X1", "NOR2_X2", "NOR3_X1", "NOR4_X1"],
34 | "AND": ["and", "AND2", "AND2_X1", "AND", "AND2_X2", "AND3_X1", "AND4_X1"],
35 | "NAND": ["nand", "NAND2", "NAND2_X2", "NAND3_X1", "NAND4_X1", "NAND2_X1"],
36 | "NOT": ["not", "inv", "NOT", "INV_X1", "INV_X2", "INV_X4"],
37 | "BUFF": ["buff", "buf",
38 | "CLKBUF_X12", "CLKBUF_X1", "CLKBUF_X2","CLKBUF_X4","CLKBUF_X8","CLKBUF_X16",
39 | "BUF_X1", "BUF_X2", "BUF_X4", "BUF_X8"]
40 | }
41 |
42 | ALL_ISCAS85=["c17","c432","c499","c880","c1355","c1908","c2670","c3540","c5315","c6288","c7552"]
43 | ALL_EPFL_EZ=["arbiter", "sin", "bar","dec", "int2float",
44 | "multiplier", "cavlc", "adder", "max", "priority", "voter"]
45 | ISCAS89 = ["s1196", "s1238", "s13207", "s1423", "s1488", "s15850", "s27",
46 | "s298", "s344", "s349", "s35932", "s382", "s38417", "s38584", "s386",
47 | "s400", "s420", "s444", "s510", "s526_1", "s526", "s5378", "s641",
48 | "s713", "s820", "s832", "s838", "s9234", "s953"]
49 |
50 |
51 | SSTA_DATA_DIR = "../data/cell_ssta"
52 | PVS = "vth0-N0.03_lg-N0.05_w-N0.05_toxe-N0.10_ndep-N0.05_MC20000"
53 | TECH = "MOSFET_45nm_HP"
54 |
55 | CKTS = {"ISCAS85": ALL_ISCAS85, "ISCAS89": ISCAS89, "EPFL": ALL_EPFL_EZ}
56 |
57 |
--------------------------------------------------------------------------------
/data/convergence.py:
--------------------------------------------------------------------------------
1 | #!/usr/bin/python3
2 | import os
3 | import matplotlib.pyplot as plt
4 | import numpy as np
5 | import math
6 |
7 | import pdb
8 | ## SAEED added these:
9 | netlists_EPFL_EZ = ["arbiter", "sin", "bar","dec", "int2float", "multiplier", "cavlc", "adder", "max", "priority", "voter"]
10 |
11 | netlists_ISCAS = ["c17","c432","c499","c880","c1355","c1908","c2670","c3540","c5315","c6288","c7552"]
12 | netlists_ISCAS = ["c880","c1355","c1908","c3540","c5315","c6288","c7552"]
13 |
14 | all_netlists = netlists_ISCAS
15 | all_netlists.extend(netlists_EPFL_EZ)
16 |
17 | circuits = ["arbiter"]
18 | upper_bound = 3.2e-1
19 | # keys = [50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000]
20 | keys = [1000, 10000, 20000]
21 | # synv = ["V0", "V1", "V2"]
22 | synv = ["V1"]
23 | for c in circuits:
24 | print (f"circuit {c}")
25 | for v in synv:
26 | results = {}
27 | fname = f"ob_stat/{c}_syn{v}_REPORT.obsr"
28 | if not os.path.exists(fname):
29 | print("Not found {} {} ".format(c, v))
30 | continue
31 | with open(fname, "r") as flog:
32 | lines = flog.readlines()
33 | for line in lines:
34 | pattern_cnt = int(line.strip().split(",")[0])
35 | stafan = [float(x) for x in line.strip().split(",")[1:-1]]
36 | results[pattern_cnt] = stafan
37 |
38 |
39 | for k in keys:
40 | # Plot the convergence figure
41 | if k not in results:
42 | continue
43 | plt.figure()
44 | plt.title(f"{c} {v} {k} Convergence figure")
45 | plt.xlabel("STAFAN Values")
46 | plt.ylabel("Points Count")
47 | x = list(range(len(results[k])))
48 | # print (x)
49 | results[k].sort(reverse=True)
50 | y = results[k]
51 | y_min = min(y)
52 | print("MIN >>", y_min)
53 | count_zero = 0
54 | if c == "arbiter":
55 | y_prime = []
56 | for yy in y:
57 | if yy == 0:
58 | count_zero += 1
59 | if yy < 0.1:
60 | y_prime.append(math.log10(yy + 10e-25))
61 | y = y_prime
62 | print(count_zero)
63 | # print (y)
64 | # plt.plot(x, y, label=f"{k}")
65 | plt.hist(y, bins='auto', alpha=0.6, edgecolor="black", label=f"{k}")
66 | plt.legend()
67 | plt.savefig(f"figures/{c}_syn{v}_{k}_upper_{upper_bound}_convergence.png")
68 | plt.close()
69 |
70 |
71 |
72 |
73 | """
74 | for i in range(0, len(keys) - 1):
75 | if (keys[i+1] not in results) or (keys[i] not in results):
76 | continue
77 | error_rate = [abs((j-k)/j * 100) if j!=0 and j<=upper_bound else None for j,k in zip(results[keys[i]], results[keys[i+1]])]
78 | esum = 0
79 | elen = 0
80 | ebounded = []
81 | # @Yang, what is this? :-?
82 | for e in error_rate:
83 | if e:
84 | ebounded.append(e)
85 | esum += e
86 | elen += 1
87 | avg_error_rate = esum / elen
88 | # avg_error_rate = sum(error_rate)/len(error_rate)
89 |
90 | # np.histogram(enp, bins=[3.2e-6, 1e-5, 3.2e-5, 1e-4, 3.2e-4, 1e-3, 3.2e-3, 1e-2, 3.2e-2, 1e-1, 3.2e-1])
91 | plt.figure()
92 | enp = np.array(ebounded)
93 | # print (enp)
94 | plt.hist(enp, bins=[0,0.01,0.1,0.2, 0.5, 1, 2,3,4,5, 10, 20, 30, 40, 50, 60, 70, 80, 90, 100, 110, 120, 130], facecolor="blue", edgecolor="black", alpha=0.6)
95 | plt.title(f"circuit {c} {v} error rate histogram: {keys[i]} and {keys[i+1]}")
96 | plt.xlabel("STAFAN Difference Percentage")
97 | plt.ylabel("Frequency (Points)")
98 | plt.text(60, 40, f"upper_bound={upper_bound}\navg_error_rate={avg_error_rate}")
99 | plt.savefig(f"figures/{c}_syn{v}_upper_{upper_bound}_{keys[i]}_{keys[i+1]}_error_rate.png")
100 | plt.close()
101 |
102 | print(f"patterns : {keys[i]} and {keys[i+1]}")
103 | print (avg_error_rate)
104 |
105 | """
106 | print("Done")
107 |
108 |
109 |
110 |
111 |
--------------------------------------------------------------------------------
/data/download_data.py:
--------------------------------------------------------------------------------
1 |
2 | import sys
3 | import os
4 | sys.path.insert(1, "../circuit/")
5 | import config
6 | import pdb
7 |
8 | WEBADDR = "https://sportlab.usc.edu/~tegramax/files/"
9 |
10 | def download_primitive(dataset, dataset_format=None):
11 | if dataset not in config.CKTS:
12 | print("dataset {} not available".format(dataset))
13 | return
14 |
15 | if not os.path.exists("./verilog"):
16 | os.system("mkdir verilog")
17 |
18 | for ckt in config.CKTS[dataset]:
19 | if os.path.exists("./verilog/" + ckt + ".v"):
20 | print("{} already exists!".format(ckt))
21 | continue
22 | sc = "wget {}verilog/{}/{}.v -P ./verilog/".format(WEBADDR, dataset, ckt)
23 | os.system(sc)
24 |
25 | def download_syn(dataset, syn_version):
26 | """ downloading synthesized datasets uploaded on personal sport-lab page
27 | The netlists are synthesized with NanGate15nm:
28 | dataset_name should be within [ISCAS85, EPFL]
29 | syn_version should be a list
30 | V0: any AND, NAND, OR, NOR, INV, BUF, XOR, XNOR
31 | V1: only AND2, OR2, INV, BUF
32 | V2: only AND, OR, INV, BUF, with no limitation on fan-in is accepted """
33 |
34 | assert type(syn_version) == list, "synthesize version should be a list"
35 |
36 | if dataset not in config.CKTS:
37 | print("dataset {} not available".format(dataset))
38 | return
39 |
40 | if not os.path.exists("./verilog"):
41 | os.system("mkdir verilog")
42 |
43 | for version in versions:
44 | for ckt in config.CKTS[dataset]:
45 | cname = ckt + "_syn" + version + ".v"
46 | if os.path.exists("./verilog/" + cname):
47 | print("{} already exists!".format(cname))
48 | continue
49 | sc = "wget {}verilog_syn/{}/{}/{} -P ./verilog/".format(
50 | WEBADDR, dataset, version, cname)
51 | os.system(sc)
52 |
53 | def download_stafan(dataset, versions=["V0", "V1", "V2"]):
54 | """ downloading generated data of DFT package, currently includes:
55 | STAFAN, PPSF """
56 |
57 | for version in versions:
58 | for ckt in config.CKTS[dataset]:
59 | cname = ckt + "_syn" + version
60 | if not os.path.exists("./stafan-data/" + cname):
61 | os.mkdir("./stafan-data/" + cname)
62 | sc = "scp viterbi2:~/workspace/DFT/data/stafan-data/{}/"
63 | sc += "*.stafan ./stafan-data/{}/"
64 | os.system(sc.format(cname, cname))
65 |
66 |
67 |
68 | if __name__ == '__main__':
69 | print("Available benchmarks are EPFL, ISCAS85, and ISCAS89")
70 | print("Select what you want to download: ")
71 | print("1) Original design files")
72 | print("2) Synthesized files (gate level verilog)")
73 | print("3) STAFAN data")
74 | tmp = input()
75 | if tmp == "1":
76 | print("Write down the names of the datasets separated with space")
77 | print("\t(EPFL, ISCAS85, ISCAS89)")
78 | datasets = input().split(" ")
79 | print(datasets)
80 | for dataset in datasets:
81 | download_primitive(dataset, "v")
82 | elif tmp == "2":
83 | print("Write down the names of the datasets separated with space")
84 | print("\t(EPFL, ISCAS85)")
85 | datasets = input().split(" ")
86 | print("Write down the synthesis versions separated with space\n")
87 | print("\tV0: AND, NAND, OR, NOR, XOR, XNOR, INV, BUFF, no limit on gate inputs")
88 | print("\tV1: AND, NAND, OR, NOR, INV, BUFF, gate inputs limited to two")
89 | print("\tV2: AND, NAND, OR, NOR, INV, BUFF, no limites on gate inputs")
90 | versions = input().split(" ")
91 | for dataset in datasets:
92 | download_syn(dataset, versions)
93 |
94 | elif tmp == "3":
95 | print("Copying from the main repository to the current repository")
96 | download_stafan("ISCAS85", versions=["V0", "V1", "V2"])
97 |
98 |
99 | else:
100 | print("Argument not accepted")
101 |
--------------------------------------------------------------------------------
/data/iscas/c1.isc:
--------------------------------------------------------------------------------
1 | *c17 iscas example (to test conversion program only)
2 | *---------------------------------------------------
3 | *
4 | *
5 | * total number of lines in the netlist .............. 17
6 | * simplistically reduced equivalent fault set size = 22
7 | * lines from primary input gates ....... 5
8 | * lines from primary output gates ....... 2
9 | * lines from interior gate outputs ...... 4
10 | * lines from ** 3 ** fanout stems ... 6
11 | *
12 | * avg_fanin = 2.00, max_fanin = 2
13 | * avg_fanout = 2.00, max_fanout = 2
14 | *
15 | *
16 | *
17 | *
18 | *
19 | 1 1gat inpt 1 0 >sa1
20 | 2 2gat inpt 1 0 >sa1
21 | 3 3gat nand 0 2 >sa1
22 | 1 2
23 |
--------------------------------------------------------------------------------
/data/iscas/c17.isc:
--------------------------------------------------------------------------------
1 | *c17 iscas example (to test conversion program only)
2 | *---------------------------------------------------
3 | *
4 | *
5 | * total number of lines in the netlist .............. 17
6 | * simplistically reduced equivalent fault set size = 22
7 | * lines from primary input gates ....... 5
8 | * lines from primary output gates ....... 2
9 | * lines from interior gate outputs ...... 4
10 | * lines from ** 3 ** fanout stems ... 6
11 | *
12 | * avg_fanin = 2.00, max_fanin = 2
13 | * avg_fanout = 2.00, max_fanout = 2
14 | *
15 | *
16 | *
17 | *
18 | *
19 | 1 1gat inpt 1 0 >sa1
20 | 2 2gat inpt 1 0 >sa1
21 | 3 3gat inpt 2 0 >sa0 >sa1
22 | 8 8fan from 3gat >sa1
23 | 9 9fan from 3gat >sa1
24 | 6 6gat inpt 1 0 >sa1
25 | 7 7gat inpt 1 0 >sa1
26 | 10 10gat nand 1 2 >sa1
27 | 1 8
28 | 11 11gat nand 2 2 >sa0 >sa1
29 | 9 6
30 | 14 14fan from 11gat >sa1
31 | 15 15fan from 11gat >sa1
32 | 16 16gat nand 2 2 >sa0 >sa1
33 | 2 14
34 | 20 20fan from 16gat >sa1
35 | 21 21fan from 16gat >sa1
36 | 19 19gat nand 1 2 >sa1
37 | 15 7
38 | 22 22gat nand 0 2 >sa0 >sa1
39 | 10 20
40 | 23 23gat nand 0 2 >sa0 >sa1
41 | 21 19
42 |
--------------------------------------------------------------------------------
/data/iscas/c17a.isc:
--------------------------------------------------------------------------------
1 | *c17 iscas example (to test conversion program only)
2 | *---------------------------------------------------
3 | *
4 | *
5 | * total number of lines in the netlist .............. 17
6 | * simplistically reduced equivalent fault set size = 22
7 | * lines from primary input gates ....... 5
8 | * lines from primary output gates ....... 2
9 | * lines from interior gate outputs ...... 4
10 | * lines from ** 3 ** fanout stems ... 6
11 | *
12 | * avg_fanin = 2.00, max_fanin = 2
13 | * avg_fanout = 2.00, max_fanout = 2
14 | *
15 | *
16 | *
17 | *
18 | *
19 | 1 1gat inpt 1 0 >sa1
20 | 2 2gat inpt 1 0 >sa1
21 | 3 3gat inpt 2 0 >sa0 >sa1
22 | 8 8fan from 3gat >sa1
23 | 9 9fan from 3gat >sa1
24 | 6 6gat inpt 1 0 >sa1
25 | 7 7gat inpt 1 0 >sa1
26 | 10 10gat nand 1 2 >sa1
27 | 1 8
28 | 11 11gat nand 2 2 >sa0 >sa1
29 | 9 6
30 | 14 14fan from 11gat >sa1
31 | 15 15fan from 11gat >sa1
32 | 16 16gat nand 2 2 >sa0 >sa1
33 | 2 14
34 | 20 20fan from 16gat >sa1
35 | 21 21fan from 16gat >sa1
36 | 19 19gat nand 1 2 >sa1
37 | 15 7
38 | 22 22gat nand 0 2 >sa0 >sa1
39 | 10 20
40 | 23 23gat nand 0 2 >sa0 >sa1
41 | 21 19
42 |
--------------------------------------------------------------------------------
/data/iscas/c5.isc:
--------------------------------------------------------------------------------
1 | *c17 iscas example (to test conversion program only)
2 | *---------------------------------------------------
3 | *
4 | *
5 | * total number of lines in the netlist .............. 17
6 | * simplistically reduced equivalent fault set size = 22
7 | * lines from primary input gates ....... 5
8 | * lines from primary output gates ....... 2
9 | * lines from interior gate outputs ...... 4
10 | * lines from ** 3 ** fanout stems ... 6
11 | *
12 | * avg_fanin = 2.00, max_fanin = 2
13 | * avg_fanout = 2.00, max_fanout = 2
14 | *
15 | *
16 | *
17 | *
18 | *
19 | 1 1gat inpt 1 0 >sa1
20 | 2 2gat inpt 1 0 >sa1
21 | 3 3gat nand 1 2 >sa1
22 | 1 2
23 | 4 4gat inpt 1 0 >sa1
24 | 5 5gat and 0 2 >sa1
25 | 3 4
26 |
27 |
--------------------------------------------------------------------------------
/data/library/library_cells.py:
--------------------------------------------------------------------------------
1 |
2 | def NanGate_15nm():
3 | gate_IO = {}
4 | gate_IO["AND2_X1"] = ["A1","A2","Z"]
5 | gate_IO["AND2_X2"] = ["A1","A2","Z"]
6 | gate_IO["AND3_X1"] = ["A1","A2","A3","Z"]
7 | gate_IO["AND3_X2"] = ["A1","A2","A3","Z"]
8 | gate_IO["AND4_X1"] = ["A1","A2","A3","A4","Z"]
9 | gate_IO["AND4_X2"] = ["A1","A2","A3","A4","Z"]
10 | gate_IO["ANTENNA"] = ["I"]
11 | gate_IO["AOI21_X1"] = ["A1","A2","B","ZN"]
12 | gate_IO["AOI21_X2"] = ["A1","A2","B","ZN"]
13 | gate_IO["AOI22_X1"] = ["A1","A2","B1","B2","ZN"]
14 | gate_IO["AOI22_X2"] = ["A1","A2","B1","B2","ZN"]
15 | gate_IO["BUF_X1"] = ["I","Z"]
16 | gate_IO["BUF_X2"] = ["I","Z"]
17 | gate_IO["BUF_X4"] = ["I","Z"]
18 | gate_IO["BUF_X8"] = ["I","Z"]
19 | gate_IO["BUF_X12"] = ["I","Z"]
20 | gate_IO["BUF_X16"] = ["I","Z"]
21 | gate_IO["CLKBUF_X1"] = ["I","Z"]
22 | gate_IO["CLKBUF_X2"] = ["I","Z"]
23 | gate_IO["CLKBUF_X4"] = ["I","Z"]
24 | gate_IO["CLKBUF_X8"] = ["I","Z"]
25 | gate_IO["CLKBUF_X12"] = ["I","Z"]
26 | gate_IO["CLKBUF_X16"] = ["I","Z"]
27 | gate_IO["CLKGATETST_X1"] = ["CLK","E","TE","Q"]
28 | gate_IO["DFFRNQ_X1"] = ["D","RN","CLK","Q"]
29 | gate_IO["DFFSNQ_X1"] = ["D","SN","CLK","Q"]
30 | gate_IO["FA_X1"] = ["A","B","CI","CO","S"]
31 | gate_IO["FILLTIE"] = []
32 | gate_IO["FILL_X1"] = []
33 | gate_IO["FILL_X2"] = []
34 | gate_IO["FILL_X4"] = []
35 | gate_IO["FILL_X8"] = []
36 | gate_IO["FILL_X16"] = []
37 | gate_IO["HA_X1"] = ["A","B","CO","S"]
38 | gate_IO["INV_X1"] = ["I","ZN"]
39 | gate_IO["INV_X2"] = ["I","ZN"]
40 | gate_IO["INV_X4"] = ["I","ZN"]
41 | gate_IO["INV_X8"] = ["I","ZN"]
42 | gate_IO["INV_X12"] = ["I","ZN"]
43 | gate_IO["INV_X16"] = ["I","ZN"]
44 | gate_IO["LHQ_X1"] = ["D","E","Q"]
45 | gate_IO["MUX2_X1"] = ["I0","I1","S","Z"]
46 | gate_IO["NAND2_X1"] = ["A1","A2","ZN"]
47 | gate_IO["NAND2_X2"] = ["A1","A2","ZN"]
48 | gate_IO["NAND3_X1"] = ["A1","A2","A3","ZN"]
49 | gate_IO["NAND3_X2"] = ["A1","A2","A3","ZN"]
50 | gate_IO["NAND4_X1"] = ["A1","A2","A3","A4","ZN"]
51 | gate_IO["NAND4_X2"] = ["A1","A2","A3","A4","ZN"]
52 | gate_IO["NOR2_X1"] = ["A1","A2","ZN"]
53 | gate_IO["NOR2_X2"] = ["A1","A2","ZN"]
54 | gate_IO["NOR3_X1"] = ["A1","A2","A3","ZN"]
55 | gate_IO["NOR3_X2"] = ["A1","A2","A3","ZN"]
56 | gate_IO["NOR4_X1"] = ["A1","A2","A3","A4","ZN"]
57 | gate_IO["NOR4_X2"] = ["A1","A2","A3","A4","ZN"]
58 | gate_IO["OAI21_X1"] = ["A1","A2","B","ZN"]
59 | gate_IO["OAI21_X2"] = ["A1","A2","B","ZN"]
60 | gate_IO["OAI22_X1"] = ["A1","A2","B1","B2","ZN"]
61 | gate_IO["OAI22_X2"] = ["A1","A2","B1","B2","ZN"]
62 | gate_IO["OR2_X1"] = ["A1","A2","Z"]
63 | gate_IO["OR2_X2"] = ["A1","A2","Z"]
64 | gate_IO["OR3_X1"] = ["A1","A2","A3","Z"]
65 | gate_IO["OR3_X2"] = ["A1","A2","A3","Z"]
66 | gate_IO["OR4_X1"] = ["A1","A2","A3","A4","Z"]
67 | gate_IO["OR4_X2"] = ["A1","A2","A3","A4","Z"]
68 | gate_IO["SDFFRNQ_X1"] = ["D","RN","SE","SI","CLK","Q"]
69 | gate_IO["SDFFSNQ_X1"] = ["D","SE","SI","SN","CLK","Q"]
70 | gate_IO["TBUF_X1"] = ["EN","I","Z"]
71 | gate_IO["TBUF_X2"] = ["EN","I","Z"]
72 | gate_IO["TBUF_X4"] = ["EN","I","Z"]
73 | gate_IO["TBUF_X8"] = ["EN","I","Z"]
74 | gate_IO["TBUF_X12"] = ["EN","I","Z"]
75 | gate_IO["TBUF_X16"] = ["EN","I","Z"]
76 | gate_IO["TIEH"] = ["Z"]
77 | gate_IO["TIEL"] = ["ZN"]
78 | gate_IO["XNOR2_X1"] = ["A1","A2","ZN"]
79 | gate_IO["XOR2_X1"] = ["A1","A2","Z"]
80 | return gate_IO
81 |
82 |
83 | def default():
84 | # TODO: it only has output pins!
85 | gate_IO = {}
86 | gate_IO["and"] = ["Y"]
87 | gate_IO["nand"] = ["Y"]
88 | gate_IO["or"] = ["Y"]
89 | gate_IO["nor"] = ["Y"]
90 | gate_IO["xor"] = ["Y"]
91 | gate_IO["xnor"] = ["Y"]
92 | gate_IO["buf"] = ["Y"]
93 | gate_IO["not"] = ["Y"]
94 | return gate_IO
95 |
--------------------------------------------------------------------------------
/data/netlist_behavioral/c432_logic_sim.py:
--------------------------------------------------------------------------------
1 | import sys
2 | from collections import OrderedDict
3 | import re
4 | import numpy as np
5 | import pdb
6 |
7 | def M1(E, A):
8 | Ab = np.invert(A)
9 | EAb = np.invert(np.bitwise_and(Ab, E))
10 | for i in range(len(EAb)):
11 | if i == 0:
12 | PA = EAb[i]
13 | else:
14 | PA &= EAb[i]
15 | PA = np.invert(PA)
16 | X1 = EAb ^ np.repeat(PA, 9)
17 | return PA, X1
18 |
19 |
20 | def M2(E, X1, B):
21 | Eb = np.invert(E)
22 | EbB = np.invert(np.bitwise_or(Eb, B))
23 | XEB = np.invert(np.bitwise_and(X1, EbB))
24 | for i in range(len(XEB)):
25 | if i == 0:
26 | PB = XEB[i]
27 | else:
28 | PB &= XEB[i]
29 | PB = np.invert(PB)
30 | X2 = XEB ^ np.repeat(PB, 9)
31 | return PB, X2
32 |
33 |
34 | def M3(E, X1, X2, C):
35 | Eb = np.invert(E)
36 | EbC = np.invert(np.bitwise_or(Eb, C))
37 | XEC =np.invert(np.bitwise_and(np.bitwise_and(X1, X2), EbC))
38 | for i in range(len(XEC)):
39 | if i == 0:
40 | PC = XEC[i]
41 | else:
42 | PC &= XEC[i]
43 | PC = ~PC
44 | return PC
45 |
46 |
47 | def M4(E, A, B, C, PA, PB, PC):
48 | APA = np.invert(np.bitwise_and(A, np.repeat(PA, 9)))
49 | BPB = np.invert(np.bitwise_and(B, np.repeat(PB, 9)))
50 | CPC = np.invert(np.bitwise_and(C, np.repeat(PC, 9)))
51 | I = np.invert(np.bitwise_and(np.bitwise_and(E, APA), np.bitwise_and(BPB, CPC)))
52 | return I
53 |
54 |
55 | def M5(I):
56 | I8b = ~I[8-8]
57 | for i in range(1, len(I)):
58 | if i == 1:
59 | Iand = I[i]
60 | else:
61 | Iand &= I[i]
62 | Chan_3 = np.invert(np.bitwise_or(I8b, Iand))
63 |
64 | I1b = ~I[8-1]
65 | I2b = ~I[8-2]
66 | I3b = ~I[8-3]
67 | I5b = ~I[8-5]
68 |
69 | I56 = ~(I5b & I[8-6])
70 | I245 = ~(I2b & I[8-4] & I[8-5])
71 | I3456 = ~(I3b & I[8-4] & I[8-5] & I[8-6])
72 | I1256 = ~(I1b & I[8-2] & I[8-5] & I[8-6])
73 |
74 | Chan_2 = ~(I[8-4] & I[8-6] & I[8-7] & I56)
75 | Chan_1 = ~(I[8-6] & I[8-7] & I245 & I3456)
76 | Chan_0 = ~(I[8-7] & I56 & I1256 & I3456)
77 | return [Chan_0, Chan_1, Chan_2, Chan_3]
78 |
79 |
80 | def c432_sim(in_vec_dict):
81 | # Create the input and output variables (top level)
82 | E = np.array(
83 | [in_vec_dict['4'], in_vec_dict['17'], in_vec_dict['30'], in_vec_dict['43'], in_vec_dict['56'],
84 | in_vec_dict['69'], in_vec_dict['82'], in_vec_dict['95'], in_vec_dict['108']], dtype=bool)
85 | A = np.array(
86 | [in_vec_dict['1'], in_vec_dict['11'], in_vec_dict['24'], in_vec_dict['37'], in_vec_dict['50'],
87 | in_vec_dict['63'], in_vec_dict['76'], in_vec_dict['89'], in_vec_dict['102']], dtype=bool)
88 | B = np.array(
89 | [in_vec_dict['8'], in_vec_dict['21'], in_vec_dict['34'], in_vec_dict['47'], in_vec_dict['60'],
90 | in_vec_dict['73'], in_vec_dict['86'], in_vec_dict['99'], in_vec_dict['112']], dtype=bool)
91 | C = np.array(
92 | [in_vec_dict['14'], in_vec_dict['27'], in_vec_dict['40'], in_vec_dict['53'], in_vec_dict['66'],
93 | in_vec_dict['79'], in_vec_dict['92'], in_vec_dict['105'], in_vec_dict['115']], dtype=bool)
94 |
95 | # Call the modules in order
96 | PA, X1 = M1(E, A)
97 | PB, X2 = M2(E, X1, B)
98 | PC = M3(E, X1, X2, C)
99 | I = M4(E, A, B, C, PA, PB, PC)
100 | Chan = M5(I)
101 |
102 | # Get the output dictionary
103 | out_vec_dict = OrderedDict()
104 | out_vec_dict['223'] = PA.astype(int)
105 | out_vec_dict['329'] = PB.astype(int)
106 | out_vec_dict['370'] = PC.astype(int)
107 | out_vec_dict['421'] = Chan[3].astype(int)
108 | out_vec_dict['430'] = Chan[2].astype(int)
109 | out_vec_dict['431'] = Chan[1].astype(int)
110 | out_vec_dict['432'] = Chan[0].astype(int)
111 |
112 | return out_vec_dict
113 |
114 |
115 | if __name__ == '__main__':
116 | if len(sys.argv) != 3: # Check if the input arguments are enough
117 | print('Not enough arguments. ')
118 | exit(1)
119 |
120 | input_file = sys.argv[1] # This is the path for the input file
121 | output_file = sys.argv[2] # This is the path for the output file
122 |
123 | # Read the input vector and create the dictionary
124 | input_file = open(input_file, 'r')
125 | in_vec_dict = OrderedDict()
126 | for line in input_file:
127 | line = line.strip()
128 | vector_array = re.split(r',', line)
129 | in_vec_dict[vector_array[0]] = int(vector_array[1])
130 |
131 | # Simulate c432
132 | out_vec_dict = c432_sim(in_vec_dict)
133 |
134 | # Write output to file
135 | output_file = open(output_file, 'w')
136 | for dict_item in out_vec_dict:
137 | if out_vec_dict[dict_item].astype(int):
138 | output_file.write('%s,1\n' % dict_item)
139 | else:
140 | output_file.write('%s,0\n' % dict_item)
141 |
--------------------------------------------------------------------------------
/data/netlist_behavioral/c499_vec.txt:
--------------------------------------------------------------------------------
1 | in1,0
2 | in5,0
3 | in9,0
4 | in13,0
5 | in17,1
6 | in21,1
7 | in25,1
8 | in29,1
9 | in33,1
10 | in37,1
11 | in41,1
12 | in45,1
13 | in49,1
14 | in53,1
15 | in57,1
16 | in61,1
17 | in65,1
18 | in69,1
19 | in73,1
20 | in77,1
21 | in81,1
22 | in85,1
23 | in89,1
24 | in93,1
25 | in97,1
26 | in101,1
27 | in105,1
28 | in109,1
29 | in113,1
30 | in117,0
31 | in121,0
32 | in125,0
33 | in129,1
34 | in130,1
35 | in131,1
36 | in132,1
37 | in133,1
38 | in134,0
39 | in135,0
40 | in136,0
41 | in137,0
42 |
--------------------------------------------------------------------------------
/data/translator/archive/translator_from_bench_to_verilog.py:
--------------------------------------------------------------------------------
1 | import re
2 | file=open('c1355.bench.txt','r')
3 | file_lines=file.readlines()
4 | file.close()
5 | file_lines=file_lines[6:]
6 | #count_list=len(file_lines)
7 |
8 |
9 | input_list=[]
10 | output_list=[]
11 | internal_list=[]
12 |
13 | for item in file_lines:
14 | if item[0]=='I':
15 | input_list.append(item)
16 | if item[0]=='O':
17 | output_list.append(item)
18 | if item[0] == '0' or item[0] == '1' or item[0] == '2' or item[0] == '3'\
19 | or item[0] == '4' or item[0] == '5' or item[0] == '6' or item[0] == '7'\
20 | or item[0] == '8' or item[0] == '9':
21 | internal_list.append(item)
22 |
23 | input_num=[]
24 | pi=''
25 | for item in input_list:
26 | input_num=input_num+re.findall('\d+',item)
27 | ##print(input_num)
28 | for item in input_num:
29 | pi=str(pi)+str('N')+str(item)+str(',')
30 | pi=pi.rstrip(',')
31 | ##print(pi)
32 | nin=len(input_num)
33 |
34 | output_num=[]
35 | po=''
36 | for item in output_list:
37 | output_num=output_num+re.findall('\d+',item)
38 | for item in output_num:
39 | po=str(po)+str('N')+str(item)+str(',')
40 | po=po.rstrip(',')
41 | nout=len(output_num)
42 |
43 | wire_num=[]
44 | wire=''
45 | for item in internal_list:
46 | wire_num=wire_num+re.findall('\d+', item)
47 |
48 | wire_num=sorted(set(wire_num),key=wire_num.index)
49 |
50 |
51 | internal=wire_num
52 | for item in input_num:
53 | if item in internal:
54 | wire_num.remove(item)
55 |
56 | for item in output_num:
57 | if item in internal:
58 | wire_num.remove(item)
59 |
60 | for item in wire_num:
61 | wire=str(wire)+str('N')+str(item)+str(',')
62 | wire=wire.rstrip(',')
63 | nwire=len(wire_num)
64 | ##print(wire_num)
65 |
66 | connection=file_lines
67 | for item in input_list:
68 | if item in file_lines:
69 | connection.remove(item)
70 | for item in output_list:
71 | if item in file_lines:
72 | connection.remove(item)
73 |
74 | count_list = len(connection)
75 | for i in range(count_list):
76 | connection[i] = connection[i].strip('\n')
77 | connection.remove('')
78 | connection.remove('')
79 | #print(connection)
80 |
81 |
82 |
83 |
84 | verilog=open('c1355.v','w')
85 | verilog.write('module c1355('+pi+','+po+');'+'\n\n')
86 | verilog.write('input '+pi+';'+'\n\n')
87 | verilog.write('output '+po+';'+'\n\n')
88 | verilog.write('wire '+wire+';'+'\n\n')
89 |
90 | a='AND'
91 | b='NAND'
92 | c='NOT'
93 | d='OR'
94 | e='BUFF'
95 | numb=[]
96 | number=''
97 | count_n=''
98 | i=0
99 | j=0
100 | k=0
101 | l=0
102 | m=0
103 | n=0
104 | o=0
105 | p=0
106 | q=0
107 |
108 | for item in connection:
109 | if b in item:
110 | numb=numb+re.findall('\d+', item)
111 | for item in numb:
112 | number=str(number)+str('N')+str(item)+str(',')
113 | number=number.rstrip(',')
114 | verilog.write('nand NAND2_'+str(i)+'('+str(number)+');\n')
115 | i=i+1
116 | elif a in item:
117 | numb=numb+re.findall('\d+', item)
118 | count_n=len(numb)
119 | for item in numb:
120 | number=str(number)+str('N')+str(item)+str(',')
121 | number=number.rstrip(',')
122 | if count_n==3:
123 | verilog.write('and AND2_'+str(j)+'('+str(number)+');\n')
124 | j=j+1
125 | elif count_n==4:
126 | verilog.write('and AND3_'+str(k)+'('+str(number)+');\n')
127 | k=l+1
128 | elif count_n==5:
129 | verilog.write('and AND4_'+str(l)+'('+str(number)+');\n')
130 | l=l+1
131 | elif count_n==6:
132 | verilog.write('and AND5_'+str(m)+'('+str(number)+');\n')
133 | m=m+1
134 | elif c in item:
135 | numb=numb+re.findall('\d+', item)
136 | for item in numb:
137 | number=str(number)+str('N')+str(item)+str(',')
138 | number=number.rstrip(',')
139 | verilog.write('not NOT1_'+str(n)+'('+str(number)+');\n')
140 | n=n+1
141 | elif d in item:
142 | numb=numb+re.findall('\d+', item)
143 | for item in numb:
144 | number=str(number)+str('N')+str(item)+str(',')
145 | number=number.rstrip(',')
146 | verilog.write('or OR4_'+str(o)+'('+str(number)+');\n')
147 | o=o+1
148 | elif e in item:
149 | numb=numb+re.findall('\d+', item)
150 | for item in numb:
151 | number=str(number)+str('N')+str(item)+str(',')
152 | number=number.rstrip(',')
153 | verilog.write('buf BUFF1_'+str(p)+'('+str(number)+');\n')
154 | p=p+1
155 |
156 | numb=[]
157 | number=''
158 | verilog.write('\n'+'endmodule')
159 |
160 | verilog.close()
161 | print(numb)
162 | print(number)
163 |
164 |
165 |
166 |
167 |
168 |
169 |
170 |
171 |
172 |
--------------------------------------------------------------------------------
/data/translator/archive/translator_from_verilog_to_spice_netlist.py:
--------------------------------------------------------------------------------
1 | # input file type : .v
2 | # output file type : .sp
3 | import re
4 |
5 | fin = open ('c17.v','r')
6 | f = fin.readlines()
7 | fin.close()
8 | count_line = len(f)
9 | for i in range(count_line):
10 | f[i] = f[i].strip('\n')
11 | f[i] = f[i].strip(' ')
12 | count = 0
13 | for line in f:
14 | if line == '':
15 | f.remove(line)
16 | if line[:2] == '//':
17 | count += 1
18 | f = f[count:]
19 | print(f)
20 |
21 | input_line = []
22 | output_line = []
23 | wire_line = []
24 | gate_line = []
25 | for line in f:
26 | if re.search('input', line[:6], re.IGNORECASE):
27 | input_line.append(line)
28 | if re.search('output', line[:6], re.IGNORECASE):
29 | output_line.append(line)
30 | if re.search('wire', line[:6], re.IGNORECASE):
31 | wire_line.append(line)
32 | if re.search('and', line[:6], re.IGNORECASE) or\
33 | re.search('or', line[:6], re.IGNORECASE) or\
34 | re.search('nand', line[:6], re.IGNORECASE) or\
35 | re.search('nor', line[:6], re.IGNORECASE) or\
36 | re.search('not', line[:6], re.IGNORECASE) or\
37 | re.search('xor', line[:6], re.IGNORECASE) or\
38 | re.search('buf', line[:6], re.IGNORECASE):
39 | gate_line.append(line)
40 |
41 |
42 | fout = open ('c17.sp', 'w')
43 | #fout.writelines('.option NOMOD\n')
44 | #fout.writelines('.global vdd\n')
45 | #fout.writelines('.temp 25\n')
46 |
47 | #fout.writelines('.param vdd=0.7\n\n')
48 | #fout.writelines(".include './7nm_LSTP.pm'\n\n")
49 |
50 | fout.writelines('vhi hi 0 vdd\n')
51 | fout.writelines('vlo lo 0 0\n\n')
52 |
53 | for line in gate_line:
54 | a = line.find(' ') #index1 of ' '
55 | b = line[a+1:].find(' ') #index2 of ' '
56 | gate_name = line[a+1:a+b+1]
57 | gate_ports = line[a+b+2:]
58 | c = gate_ports.find(',') #index1 of ','
59 | gate_output = gate_ports[1:c]
60 | gate_input = gate_ports[c+2:-2]
61 | d = gate_name.find('_') #index of '_'
62 | gate_type = gate_name[:d]
63 | gate_input = gate_input.replace(',','')
64 | fout.writelines([gate_name, '\t', 'hi\t', '0\t', \
65 | gate_input, '\t\t', gate_output, '\t\t', gate_type.upper(), '\n'])
66 |
67 | fout.writelines('\n')
68 |
69 | fout.close()
70 |
--------------------------------------------------------------------------------
/data/translator/bench2self_v1.py:
--------------------------------------------------------------------------------
1 | # input file type : .bench
2 | # output file type : .ckt658
3 | import re
4 | import sys
5 | import pdb
6 |
7 | """ Note: only works with bench files that have integer values for node IDs
8 | """
9 |
10 |
11 |
12 | class Nets:
13 | def __init__(self):
14 | self.gtype = None
15 | self.ntype = None
16 | self.output = None
17 | self.fanouts = []
18 | self.fanins = []
19 | self.ntypes = {"GATE":0, "PI":1, "FB":2, "PO":3}
20 | self.gtypes = {"BUFF":9, "BUF":9, "XOR":2, "OR":3, "NOR":4,
21 | "NOT":5, "NAND":6, "AND":7, "XNOR":8}
22 | def __str__(self):
23 | print(f"{self.ntype}\t{self.output}")
24 |
25 | class Stem(Nets):
26 | def __init__(self, brch, fanout, net_number):
27 | """ brch and stem are Gate type """
28 | super().__init__()
29 | self.ntype = "FB"
30 | self.gtype = 1
31 | self.fanins = [brch]
32 | self.fanouts = [fanout]
33 | self.output = net_number
34 |
35 | # brch is still a fanin to fanout gate,
36 | # bech should be replaced with this new stem in fanout.fanins
37 | for idx in range(len(fanout.fanins)):
38 | if fanout.fanins[idx].output == brch.output:
39 | fanout.fanins[idx] = self
40 |
41 | def ckt_line(self):
42 | line = f"2 {self.output} 1 {self.fanins[0].output}"
43 | return line
44 |
45 | class Gate(Nets):
46 | def __init__(self, line):
47 | super().__init__()
48 | self.fanouts = []
49 | self.fanins = []
50 | self.inputs = []
51 |
52 | if line.lower().startswith("input("):
53 | self.ntype = "PI"
54 | self.gtype = 0
55 | self.output = line[:-1].split('(')[-1]
56 |
57 | elif '=' in line:
58 | words = re.split(r',|=|\(|\)', line.replace(')', ''))
59 | self.ntype = "GATE"
60 | try:
61 | self.gtype = self.gtypes[words[1].upper()]
62 | except:
63 | pdb.set_trace()
64 | self.output = words[0]
65 | self.inputs = words[2:]
66 |
67 | def ckt_line(self):
68 | if self.ntype == "PI":
69 | line = f"1 {self.output} 0 {len(self.fanouts)} 0"
70 | elif self.ntype in ["GATE", "PO"]:
71 | line = f"{self.ntypes[self.ntype]} "
72 | line += f"{self.output} {self.gtype} {len(self.fanouts)} "
73 | line += f"{len(self.fanins)} "
74 | line += " ".join([x.output for x in self.fanins])
75 | return line
76 |
77 |
78 | def new_net(gates, start_val=1):
79 | nets = set([int(gate.output) for gate in gates.values()])
80 | for net in range(start_val, max(nets)):
81 | if net not in nets:
82 | return str(net)
83 |
84 | def read_bench(bench_fname):
85 | """ TODO: we are not handling a line that is:
86 | both PI and PO
87 | both BRCH and PO """
88 |
89 | with open(bench_fname, "r") as infile:
90 | lines = infile.readlines()
91 | lines = [line.strip().replace(' ','') for line in lines if len(line) > 3]
92 | lines = [line for line in lines if line[0] != '#']
93 |
94 | lines_po = [line for line in lines if line.startswith("OUTPUT")]
95 | lines_pi = [line for line in lines if line.startswith("INPUT")]
96 | POs = set([line[:-1].split('(')[-1] for line in lines_po])
97 | PIs = set([line[:-1].split('(')[-1] for line in lines_pi])
98 |
99 | gates = dict()
100 | for line in lines:
101 | if '=' in line or "INPUT" in line:
102 | new_gate = Gate(line)
103 | gates[new_gate.output] = new_gate
104 |
105 | # setting the data structure
106 | for output, gate in gates.items():
107 | for inline in gate.inputs:
108 | gates[inline].fanouts.append(gate)
109 | gate.fanins.append(gates[inline])
110 |
111 | # Sanity checks
112 | for po in POs:
113 | # Checking if PO net is not shared with another gate
114 | if po in gates:
115 | if len(gates[po].fanouts) > 1:
116 | print(f"(ERROR): PO {po} is also a branch")
117 | pdb.set_trace()
118 | else:
119 | gates[po].ntype = "PO"
120 | # Checking if PO net is also PI net
121 | elif po in PIs:
122 | print(f"(ERROR): PO {po} is also a PI")
123 | # PO should be something!
124 | else:
125 | print(f"(ERROR): PO {po} is also a PI")
126 |
127 | FB_gates = [gate for gate in gates.values() if len(gate.fanouts) > 1]
128 | for brch in FB_gates:
129 | for fanout in brch.fanouts:
130 | new_stem = Stem(brch, fanout, new_net(gates, int(brch.output)))
131 | gates[new_stem.output] = new_stem
132 |
133 | return gates
134 |
135 |
136 | def write_ckt(ckt_fname):
137 | with open(ckt_fname, 'w') as outfile:
138 | for gate in gates.values():
139 | outfile.write(gate.ckt_line() + "\n")
140 |
141 |
142 | if __name__ == "__main__":
143 | if len(sys.argv) != 3:
144 | print("(ERROR) bench and ckt file names should be given as arguments")
145 | exit()
146 | gates = read_bench(sys.argv[1])
147 | write_ckt(sys.argv[2])
148 |
--------------------------------------------------------------------------------
/data/translator/bench2self_v2.py:
--------------------------------------------------------------------------------
1 | # input file type : .bench
2 | # output file type : .ckt658
3 | import re
4 | def translator(src,dst):
5 | fin = open ('../circuits/' + src,'r')
6 | f = fin.readlines()
7 | fin.close()
8 | f = f[6:]
9 | count_list = len(f)
10 | for i in range(count_list):
11 | f[i] = f[i].strip('\n')
12 | f.remove('')
13 | f.remove('')
14 | # input file lists include 3 lists: PI list, PO list, internal list
15 | input_list = []
16 | output_list = []
17 | internal_list = []
18 | for item in f:
19 | if item[0] == 'I':
20 | input_list.append(item)
21 | if item[0] == 'O':
22 | output_list.append(item)
23 | if item[0] == '0' or item[0] == '1'or item[0] == '2'\
24 | or item[0] == '3'or item[0] == '4'or item[0] == '5'\
25 | or item[0] == '6'or item[0] == '7'or item[0] == '8'\
26 | or item[0] == '9':
27 | internal_list.append(item)
28 |
29 | ##print(input_list)
30 | ##print(output_list)
31 | ##print(internal_list)
32 | all_line_list = []
33 | input_of_gate_list = []
34 | gate_input_line = []
35 | for item in internal_list:
36 | all_line_list = all_line_list + re.findall('\d+', item)
37 | item_tmp = item.split('=')
38 | input_of_gate_list = input_of_gate_list + item_tmp
39 |
40 | for i in range(len(input_of_gate_list)):
41 | if (i % 2) == 1:
42 | gate_input_line = gate_input_line + re.findall('\d+', input_of_gate_list[i])
43 |
44 | line = [0] * len(all_line_list)
45 | line2 = [0] * len(gate_input_line)
46 | for i in range(len(all_line_list)):
47 | line[i] = int(all_line_list[i])
48 | for i in range(len(gate_input_line)):
49 | line2[i] = int(gate_input_line[i])
50 |
51 | line.sort(reverse=False)
52 | line2.sort(reverse=False)
53 | ##print(line)
54 | ##print(line2)
55 | branch_list = [0,0] * len(line2)
56 | a = line2
57 | b = set(a)
58 | i = 0
59 | for each_b in b:
60 | count = 0
61 | for each_a in a:
62 | if each_b == each_a:
63 | count += 1
64 | branch_list[i] = [each_b, count]
65 | i += 1
66 | while 0 in branch_list:
67 | branch_list.remove(0)
68 | ##print(branch_list)
69 | number_of_branch = 0
70 | for num in branch_list:
71 | if num[1] > 1:
72 | number_of_branch += 1
73 | ##print('number_of_branch = ', number_of_branch)
74 | number_of_line = len(line2) + len(output_list) + number_of_branch
75 |
76 | first_column = [-1] * number_of_line
77 | second_column = [-1] * number_of_line
78 | third_column = [-1] * number_of_line
79 | fourth_column = [-1] * number_of_line
80 | fifth_column = [-1] * number_of_line
81 | sixth_column = [''] * number_of_line
82 |
83 | ##print('number_of_line = ', number_of_line)
84 |
85 | new_line = list(set(line))
86 | ##print(new_line)
87 | for num in branch_list:
88 | if num[1] > 1:
89 | x = num[0]
90 | for index in range(len(new_line)):
91 | if x == new_line[index]:
92 | for i in range(num[1]):
93 | new_line.insert(index+i+1, x+i+1)
94 | first_column[index+i+1] = 2
95 | third_column[index+i+1] = 1
96 | fourth_column[index+i+1] = num[0]
97 | break
98 | ##print(len(new_line))
99 | for i in range(number_of_line):
100 | second_column[i] = new_line[i]
101 |
102 | PI_list = []
103 | for item in input_list:
104 | PI_list = PI_list + re.findall('\d+', item)
105 | for item in PI_list:
106 | a = second_column.index(int(item))
107 | first_column[a] = 1
108 | third_column[a] = 0
109 | fifth_column[a] = 0
110 | PO_list = []
111 | for item in output_list:
112 | PO_list = PO_list + re.findall('\d+', item)
113 | for item in PO_list:
114 | a = second_column.index(int(item))
115 | first_column[a] = 3
116 | fourth_column[a] = 0
117 |
118 | ## for third column gate indication
119 | def gate_index(string):
120 | out = 0
121 | if string.find('XOR') >= 0:
122 | out = 2
123 | elif string.find('NOR') >= 0:
124 | out = 4
125 | elif string.find('OR') >= 0:
126 | out = 3
127 | elif string.find('NOT') >= 0:
128 | out = 5
129 | elif string.find('NAND') >= 0:
130 | out = 6
131 | elif string.find('AND') >= 0:
132 | out = 7
133 | return out
134 |
135 | c = []
136 | for item in internal_list:
137 | c = item.split('=')
138 | a1 = int(c[0])
139 | a2 = second_column.index(a1)
140 | third_column[a2] = gate_index(item)
141 | a3 = len(re.findall('\d+', c[1]))
142 | fifth_column[a2] = a3
143 |
144 | for i in range(len(first_column)):
145 | if first_column[i] == -1:
146 | first_column[i] = 0
147 |
148 | branch_list_ext = []
149 | for num in branch_list:
150 | if num[1] > 1:
151 | fourth_column[second_column.index(num[0])] = num[1]
152 | branch_list_ext.append(num[0])
153 |
154 | for i in range(len(fourth_column)):
155 | if fourth_column[i] == -1:
156 | fourth_column[i] = 1
157 |
158 | for i in range(len(fifth_column)):
159 | if fifth_column[i] == -1:
160 | fifth_column[i] = ''
161 |
162 | gate_line_list = []
163 | for item in internal_list:
164 | d = re.findall('\d+', item)
165 | for i in range(len(d)):
166 | d[i] = int(d[i])
167 | ## print(d)
168 | gate_line_list.append(d)
169 |
170 | for branch_num in branch_list_ext:
171 | count = 1
172 | for item in gate_line_list:
173 | item_input = item[1:]
174 | for n in item_input:
175 | if n == branch_num:
176 | f = item.index(n)
177 | e = second_column.index(branch_num)
178 | item[f] = second_column[e + count]
179 | count += 1
180 | ##print(gate_line_list)
181 | for item in gate_line_list:
182 | r = second_column.index(item[0])
183 | sixth_column[r] = item[1:]
184 |
185 |
186 | ##print(first_column)
187 | ##print(second_column)
188 | ##print(third_column)
189 | ##print(fourth_column)
190 | ##print(fifth_column)
191 | ##print(sixth_column)
192 |
193 | fv = open('../circuits/'+dst,'w')
194 | for i in range(number_of_line):
195 | fv.writelines([str(first_column[i]),' ',str(second_column[i]),' ',str(third_column[i]),' ',\
196 | str(fourth_column[i]),' ',str(fifth_column[i]),' '])
197 | if sixth_column[i] != '':
198 | for num in sixth_column[i]:
199 | fv.writelines([str(num),' '])
200 | fv.writelines(['\n'])
201 | fv.close()
202 |
203 |
204 |
205 |
206 |
207 |
--------------------------------------------------------------------------------
/data/translator/bench2self_v3.py:
--------------------------------------------------------------------------------
1 | # input file type : .bench
2 | # output file type : .ckt658
3 | # important : the finin parameter is not useable
4 |
5 | import re
6 | import argparse
7 |
8 | def translator(src, dst):
9 | '''
10 | translates a bench circuit format to ckt-658 format.
11 | src: path for source bench file, with .bench suffix
12 | dst: path for destination ckt658 file, with .ckt suffix
13 | '''
14 |
15 | fin = open(src, 'r')
16 | f = fin.readlines()
17 | fin.close()
18 | for i in range(len(f)):
19 | f[i] = f[i].strip()
20 |
21 | input_list = []
22 | output_list = []
23 | internal_list = []
24 |
25 | for item in f:
26 | try:
27 | item[0]
28 | except:
29 | continue
30 | if item[0] != '#':
31 | if item[0] == 'I':
32 | input_list.append(item)
33 | if item[0] == 'O':
34 | output_list.append(item)
35 | if item.find('=')!=-1:
36 | internal_list.append(item)
37 |
38 | in_list = set()
39 | for item in input_list:
40 | item=item.split('#')
41 | item=re.findall('[0-9]+',item[0])
42 | in_list.add(item[0])
43 |
44 | out_list = set()
45 | for item in output_list:
46 | item=item.split('#')
47 | item=re.findall('[0-9]+',item[0])
48 | out_list.add(item[0])
49 |
50 | def gate_index(string):
51 | out = 0
52 | if string.upper().find('BUFF') >= 0:
53 | out=1
54 | elif string.upper().find('XOR') >= 0:
55 | out = 2
56 | elif string.upper().find('NOR') >= 0:
57 | out = 4
58 | elif string.upper().find('OR') >= 0:
59 | out = 3
60 | elif string.upper().find('NOT') >= 0:
61 | out = 5
62 | elif string.upper().find('NAND') >= 0:
63 | out = 6
64 | elif string.upper().find('AND') >= 0:
65 | out = 7
66 | return out
67 |
68 | finout={}
69 | for item in internal_list:
70 | item=item.split('#')
71 | item=item[0]
72 | item=re.findall('[0-9]+',item)
73 | for number in item[1:]:
74 | if number in finout:
75 | finout[number]=finout[number]+1
76 | else:
77 | finout[number]=1
78 |
79 | ckt_set=list()
80 | for item in in_list:
81 | if item in finout:
82 | fino=finout[number]
83 | else:
84 | fino=1
85 | node=[1,item,0,fino,0]
86 | ckt_set.append(node)
87 |
88 | for item in internal_list:
89 | item=item.split('#')
90 | item=item[0]
91 | item=re.findall('[a-zA-Z0-9]+',item)
92 | if item[0] in finout:
93 | fino=finout[item[0]]
94 | else:
95 | fino=0
96 | if(item[0] in out_list):
97 | if(gate_index(item[1])==1):
98 | node=[3,item[0],gate_index(item[1]),0,1,item[2]]
99 | else:
100 | node=[3,item[0],gate_index(item[1]),0,len(item[2:])]+item[2:]
101 | out_list.remove(item[0])
102 | else:
103 | if(gate_index(item[1])==1):
104 | node=[2,item[0],1,item[2]]
105 | else:
106 | node=[0,item[0],gate_index(item[1]),fino,len(item[2:])]+item[2:]
107 | ckt_set.append(node)
108 |
109 | for item in out_list:
110 | if(item in in_list):
111 | node=[3,item,0,0,0]
112 | ckt_set.append(node)
113 | else:
114 | print("error input",item)
115 |
116 | output_write=[]
117 | for item in ckt_set:
118 | item2 = [str(x) for x in item]
119 | output_str=" ".join(item2)+'\n'
120 | output_write.append(output_str)
121 | fv = open(dst, 'w')
122 | fv.writelines(output_write)
123 | fv.close()
124 |
125 |
126 | if __name__ == "__main__":
127 | parser = argparse.ArgumentParser()
128 | parser.add_argument("-ckt", type=str, required=True, help="path to store the ckt file")
129 | parser.add_argument("-bench", type=str, required=True, help="path to read the bench file")
130 | args = parser.parse_args()
131 | translator(args.bench, args.ckt)
132 |
133 |
--------------------------------------------------------------------------------
/data/verilog/ISCAS85/v0/c17_synV0.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////
2 | // Created by: Synopsys DC Expert(TM) in wire load mode
3 | // Version : P-2019.03-SP1-1
4 | // Date : Wed Nov 18 14:13:55 2020
5 | /////////////////////////////////////////////////////////////
6 |
7 |
8 | module c17 ( N1, N2, N3, N6, N7, N22, N23 );
9 | input N1, N2, N3, N6, N7;
10 | output N22, N23;
11 | wire n6, n7, n8, n9, n10;
12 |
13 | NOR2_X1 U8 ( .A1(n6), .A2(n7), .ZN(N23) );
14 | NOR2_X1 U9 ( .A1(N2), .A2(N7), .ZN(n7) );
15 | INV_X1 U10 ( .I(n8), .ZN(n6) );
16 | NAND2_X1 U11 ( .A1(n9), .A2(n10), .ZN(N22) );
17 | NAND2_X1 U12 ( .A1(N2), .A2(n8), .ZN(n10) );
18 | NAND2_X1 U13 ( .A1(N6), .A2(N3), .ZN(n8) );
19 | NAND2_X1 U14 ( .A1(N1), .A2(N3), .ZN(n9) );
20 | endmodule
21 |
22 |
--------------------------------------------------------------------------------
/data/verilog/ISCAS85/v0/c432_synV0.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////
2 | // Created by: Synopsys DC Expert(TM) in wire load mode
3 | // Version : P-2019.03-SP1-1
4 | // Date : Wed Nov 18 14:14:03 2020
5 | /////////////////////////////////////////////////////////////
6 |
7 |
8 | module c432 ( N1, N4, N8, N11, N14, N17, N21, N24, N27, N30, N34, N37, N40,
9 | N43, N47, N50, N53, N56, N60, N63, N66, N69, N73, N76, N79, N82, N86,
10 | N89, N92, N95, N99, N102, N105, N108, N112, N115, N223, N329, N370,
11 | N421, N430, N431, N432 );
12 | input N1, N4, N8, N11, N14, N17, N21, N24, N27, N30, N34, N37, N40, N43, N47,
13 | N50, N53, N56, N60, N63, N66, N69, N73, N76, N79, N82, N86, N89, N92,
14 | N95, N99, N102, N105, N108, N112, N115;
15 | output N223, N329, N370, N421, N430, N431, N432;
16 | wire n121, n122, n123, n124, n125, n126, n127, n128, n129, n130, n131,
17 | n132, n133, n134, n135, n136, n137, n138, n139, n140, n141, n142,
18 | n143, n144, n145, n146, n147, n148, n149, n150, n151, n152, n153,
19 | n154, n155, n156, n157, n158, n159, n160, n161, n162, n163, n164,
20 | n165, n166, n167, n168, n169, n170, n171, n172, n173, n174, n175,
21 | n176, n177, n178, n179, n180, n181, n182, n183, n184, n185, n186,
22 | n187, n188, n189, n190, n191, n192, n193, n194, n195, n196, n197,
23 | n198, n199, n200, n201, n202, n203, n204, n205, n206, n207, n208,
24 | n209, n210, n211, n212, n213, n214, n215, n216, n217, n218, n219,
25 | n220, n221, n222, n223, n224, n225, n226;
26 |
27 | NAND2_X1 U128 ( .A1(n121), .A2(n122), .ZN(N432) );
28 | NAND2_X1 U129 ( .A1(n123), .A2(n124), .ZN(n122) );
29 | NAND3_X1 U130 ( .A1(n125), .A2(n126), .A3(n127), .ZN(n123) );
30 | NAND2_X1 U131 ( .A1(n128), .A2(n129), .ZN(n127) );
31 | INV_X1 U132 ( .I(n130), .ZN(n128) );
32 | NAND4_X1 U133 ( .A1(n131), .A2(n132), .A3(n133), .A4(n134), .ZN(n125) );
33 | NAND2_X1 U134 ( .A1(N105), .A2(N370), .ZN(n132) );
34 | NAND3_X1 U135 ( .A1(n121), .A2(n124), .A3(n135), .ZN(N431) );
35 | NAND3_X1 U136 ( .A1(n126), .A2(n129), .A3(n136), .ZN(n135) );
36 | NOR2_X1 U137 ( .A1(n137), .A2(n138), .ZN(N421) );
37 | NOR4_X1 U138 ( .A1(N108), .A2(N430), .A3(n131), .A4(n136), .ZN(n138) );
38 | NAND2_X1 U139 ( .A1(n130), .A2(n133), .ZN(n136) );
39 | NAND4_X1 U140 ( .A1(N82), .A2(n139), .A3(n140), .A4(n141), .ZN(n133) );
40 | NAND2_X1 U141 ( .A1(N86), .A2(N329), .ZN(n140) );
41 | NAND2_X1 U142 ( .A1(N92), .A2(N370), .ZN(n139) );
42 | NAND3_X1 U143 ( .A1(n142), .A2(n143), .A3(n144), .ZN(n130) );
43 | INV_X1 U144 ( .I(n145), .ZN(n144) );
44 | NAND2_X1 U145 ( .A1(N73), .A2(N329), .ZN(n143) );
45 | NAND2_X1 U146 ( .A1(N79), .A2(N370), .ZN(n142) );
46 | AND2_X1 U147 ( .A1(N95), .A2(n146), .Z(n131) );
47 | NAND2_X1 U148 ( .A1(N89), .A2(N223), .ZN(n146) );
48 | NAND4_X1 U149 ( .A1(n126), .A2(n129), .A3(n121), .A4(n124), .ZN(N430) );
49 | NAND4_X1 U150 ( .A1(N30), .A2(n147), .A3(n148), .A4(n149), .ZN(n124) );
50 | NAND2_X1 U151 ( .A1(N34), .A2(N329), .ZN(n148) );
51 | NAND2_X1 U152 ( .A1(N40), .A2(N370), .ZN(n147) );
52 | NAND4_X1 U153 ( .A1(N17), .A2(n150), .A3(n151), .A4(n152), .ZN(n121) );
53 | NAND2_X1 U154 ( .A1(N21), .A2(N329), .ZN(n151) );
54 | NAND2_X1 U155 ( .A1(N27), .A2(N370), .ZN(n150) );
55 | NAND3_X1 U156 ( .A1(n153), .A2(n154), .A3(n155), .ZN(n129) );
56 | INV_X1 U157 ( .I(n156), .ZN(n155) );
57 | NAND2_X1 U158 ( .A1(N60), .A2(N329), .ZN(n154) );
58 | NAND2_X1 U159 ( .A1(N66), .A2(N370), .ZN(n153) );
59 | NAND4_X1 U160 ( .A1(N43), .A2(n157), .A3(n158), .A4(n159), .ZN(n126) );
60 | NAND2_X1 U161 ( .A1(N47), .A2(N329), .ZN(n158) );
61 | NAND2_X1 U162 ( .A1(N53), .A2(N370), .ZN(n157) );
62 | NOR4_X1 U163 ( .A1(n160), .A2(n161), .A3(n162), .A4(n163), .ZN(n137) );
63 | AND2_X1 U164 ( .A1(N370), .A2(N14), .Z(n162) );
64 | NAND4_X1 U165 ( .A1(n164), .A2(n165), .A3(n166), .A4(n167), .ZN(N370) );
65 | NOR4_X1 U166 ( .A1(n168), .A2(n169), .A3(n170), .A4(n171), .ZN(n167) );
66 | NOR2_X1 U167 ( .A1(N329), .A2(n172), .ZN(n171) );
67 | NOR4_X1 U168 ( .A1(n173), .A2(n174), .A3(n175), .A4(n176), .ZN(n172) );
68 | NOR2_X1 U169 ( .A1(N27), .A2(n177), .ZN(n176) );
69 | NOR2_X1 U170 ( .A1(N115), .A2(n178), .ZN(n175) );
70 | NOR2_X1 U171 ( .A1(N40), .A2(n179), .ZN(n174) );
71 | NAND2_X1 U172 ( .A1(n180), .A2(n181), .ZN(n173) );
72 | OR2_X1 U173 ( .A1(n182), .A2(N53), .Z(n181) );
73 | OR2_X1 U174 ( .A1(n183), .A2(N92), .Z(n180) );
74 | NOR3_X1 U175 ( .A1(n183), .A2(N92), .A3(N86), .ZN(n170) );
75 | NAND2_X1 U176 ( .A1(n184), .A2(n185), .ZN(n169) );
76 | OR3_X1 U177 ( .A1(N21), .A2(N27), .A3(n177), .Z(n185) );
77 | OR3_X1 U178 ( .A1(N34), .A2(N40), .A3(n179), .Z(n184) );
78 | NOR3_X1 U179 ( .A1(n182), .A2(N53), .A3(N47), .ZN(n168) );
79 | NOR3_X1 U180 ( .A1(n186), .A2(n187), .A3(n188), .ZN(n166) );
80 | NOR3_X1 U181 ( .A1(n156), .A2(N66), .A3(n189), .ZN(n188) );
81 | NOR2_X1 U182 ( .A1(n190), .A2(n191), .ZN(n189) );
82 | NOR3_X1 U183 ( .A1(n145), .A2(N79), .A3(n192), .ZN(n187) );
83 | NOR2_X1 U184 ( .A1(n193), .A2(n191), .ZN(n192) );
84 | INV_X1 U185 ( .I(N329), .ZN(n191) );
85 | NOR4_X1 U186 ( .A1(N105), .A2(n194), .A3(n195), .A4(n196), .ZN(n186) );
86 | INV_X1 U187 ( .I(n134), .ZN(n195) );
87 | NAND2_X1 U188 ( .A1(N99), .A2(N329), .ZN(n134) );
88 | OR4_X1 U189 ( .A1(n163), .A2(n161), .A3(n160), .A4(N14), .Z(n165) );
89 | AND2_X1 U190 ( .A1(N8), .A2(N329), .Z(n160) );
90 | OR3_X1 U191 ( .A1(N112), .A2(N115), .A3(n178), .Z(n164) );
91 | NAND4_X1 U192 ( .A1(n197), .A2(n198), .A3(n199), .A4(n200), .ZN(N329) );
92 | NOR4_X1 U193 ( .A1(n201), .A2(n202), .A3(n203), .A4(n204), .ZN(n200) );
93 | NOR2_X1 U194 ( .A1(N86), .A2(n183), .ZN(n204) );
94 | NAND2_X1 U195 ( .A1(N82), .A2(n141), .ZN(n183) );
95 | NAND2_X1 U196 ( .A1(N223), .A2(n205), .ZN(n141) );
96 | NOR2_X1 U197 ( .A1(N47), .A2(n182), .ZN(n203) );
97 | NAND2_X1 U198 ( .A1(N43), .A2(n159), .ZN(n182) );
98 | NAND2_X1 U199 ( .A1(N37), .A2(N223), .ZN(n159) );
99 | NOR2_X1 U200 ( .A1(N34), .A2(n179), .ZN(n202) );
100 | NAND2_X1 U201 ( .A1(N30), .A2(n149), .ZN(n179) );
101 | NAND2_X1 U202 ( .A1(N223), .A2(n206), .ZN(n149) );
102 | NOR2_X1 U203 ( .A1(N21), .A2(n177), .ZN(n201) );
103 | NAND2_X1 U204 ( .A1(N17), .A2(n152), .ZN(n177) );
104 | NAND2_X1 U205 ( .A1(N223), .A2(n207), .ZN(n152) );
105 | NOR3_X1 U206 ( .A1(n208), .A2(n190), .A3(n193), .ZN(n199) );
106 | NOR2_X1 U207 ( .A1(n145), .A2(N73), .ZN(n193) );
107 | NAND2_X1 U208 ( .A1(N69), .A2(n209), .ZN(n145) );
108 | NAND2_X1 U209 ( .A1(N63), .A2(N223), .ZN(n209) );
109 | NOR2_X1 U210 ( .A1(n156), .A2(N60), .ZN(n190) );
110 | NAND2_X1 U211 ( .A1(N56), .A2(n210), .ZN(n156) );
111 | NAND2_X1 U212 ( .A1(N50), .A2(N223), .ZN(n210) );
112 | NOR3_X1 U213 ( .A1(n196), .A2(N99), .A3(n194), .ZN(n208) );
113 | AND2_X1 U214 ( .A1(N89), .A2(N223), .Z(n194) );
114 | OR3_X1 U215 ( .A1(n161), .A2(N8), .A3(n163), .Z(n198) );
115 | AND2_X1 U216 ( .A1(N1), .A2(N223), .Z(n161) );
116 | OR2_X1 U217 ( .A1(n178), .A2(N112), .Z(n197) );
117 | NAND2_X1 U218 ( .A1(N108), .A2(n211), .ZN(n178) );
118 | NAND2_X1 U219 ( .A1(N102), .A2(N223), .ZN(n211) );
119 | NAND4_X1 U220 ( .A1(n212), .A2(n213), .A3(n214), .A4(n215), .ZN(N223) );
120 | NOR4_X1 U221 ( .A1(n216), .A2(n217), .A3(n218), .A4(n219), .ZN(n215) );
121 | NOR2_X1 U222 ( .A1(N89), .A2(n196), .ZN(n219) );
122 | INV_X1 U223 ( .I(N95), .ZN(n196) );
123 | NOR2_X1 U224 ( .A1(N63), .A2(n220), .ZN(n218) );
124 | INV_X1 U225 ( .I(N69), .ZN(n220) );
125 | NOR2_X1 U226 ( .A1(N50), .A2(n221), .ZN(n217) );
126 | INV_X1 U227 ( .I(N56), .ZN(n221) );
127 | NOR2_X1 U228 ( .A1(N37), .A2(n222), .ZN(n216) );
128 | INV_X1 U229 ( .I(N43), .ZN(n222) );
129 | AND3_X1 U230 ( .A1(n205), .A2(n207), .A3(n206), .Z(n214) );
130 | NAND2_X1 U231 ( .A1(n223), .A2(N30), .ZN(n206) );
131 | INV_X1 U232 ( .I(N24), .ZN(n223) );
132 | NAND2_X1 U233 ( .A1(n224), .A2(N17), .ZN(n207) );
133 | INV_X1 U234 ( .I(N11), .ZN(n224) );
134 | NAND2_X1 U235 ( .A1(n225), .A2(N82), .ZN(n205) );
135 | INV_X1 U236 ( .I(N76), .ZN(n225) );
136 | OR2_X1 U237 ( .A1(n163), .A2(N1), .Z(n213) );
137 | INV_X1 U238 ( .I(N4), .ZN(n163) );
138 | NAND2_X1 U239 ( .A1(N108), .A2(n226), .ZN(n212) );
139 | INV_X1 U240 ( .I(N102), .ZN(n226) );
140 | endmodule
141 |
142 |
--------------------------------------------------------------------------------
/data/verilog/ISCAS85/v1/c17_synV1.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////
2 | // Created by: Synopsys DC Expert(TM) in wire load mode
3 | // Version : P-2019.03-SP1-1
4 | // Date : Tue Nov 17 22:19:56 2020
5 | /////////////////////////////////////////////////////////////
6 |
7 |
8 | module c17 ( N1, N2, N3, N6, N7, N22, N23 );
9 | input N1, N2, N3, N6, N7;
10 | output N22, N23;
11 | wire n6, n7, n8, n9, n10;
12 |
13 | NOR2_X1 U8 ( .A1(n6), .A2(n7), .ZN(N23) );
14 | NOR2_X1 U9 ( .A1(N2), .A2(N7), .ZN(n7) );
15 | INV_X1 U10 ( .I(n8), .ZN(n6) );
16 | NAND2_X1 U11 ( .A1(n9), .A2(n10), .ZN(N22) );
17 | NAND2_X1 U12 ( .A1(N2), .A2(n8), .ZN(n10) );
18 | NAND2_X1 U13 ( .A1(N6), .A2(N3), .ZN(n8) );
19 | NAND2_X1 U14 ( .A1(N1), .A2(N3), .ZN(n9) );
20 | endmodule
21 |
22 |
--------------------------------------------------------------------------------
/data/verilog/ISCAS85/v2/c17_synV2.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////
2 | // Created by: Synopsys DC Expert(TM) in wire load mode
3 | // Version : P-2019.03-SP1-1
4 | // Date : Tue Nov 17 22:20:03 2020
5 | /////////////////////////////////////////////////////////////
6 |
7 |
8 | module c17 ( N1, N2, N3, N6, N7, N22, N23 );
9 | input N1, N2, N3, N6, N7;
10 | output N22, N23;
11 | wire n6, n7, n8, n9, n10;
12 |
13 | NOR2_X1 U8 ( .A1(n6), .A2(n7), .ZN(N23) );
14 | NOR2_X1 U9 ( .A1(N2), .A2(N7), .ZN(n7) );
15 | INV_X1 U10 ( .I(n8), .ZN(n6) );
16 | NAND2_X1 U11 ( .A1(n9), .A2(n10), .ZN(N22) );
17 | NAND2_X1 U12 ( .A1(N2), .A2(n8), .ZN(n10) );
18 | NAND2_X1 U13 ( .A1(N6), .A2(N3), .ZN(n8) );
19 | NAND2_X1 U14 ( .A1(N1), .A2(N3), .ZN(n9) );
20 | endmodule
21 |
22 |
--------------------------------------------------------------------------------
/data/verilog/ISCAS85/v2/c432_synV2.v:
--------------------------------------------------------------------------------
1 | /////////////////////////////////////////////////////////////
2 | // Created by: Synopsys DC Expert(TM) in wire load mode
3 | // Version : P-2019.03-SP1-1
4 | // Date : Tue Nov 17 22:20:26 2020
5 | /////////////////////////////////////////////////////////////
6 |
7 |
8 | module c432 ( N1, N4, N8, N11, N14, N17, N21, N24, N27, N30, N34, N37, N40,
9 | N43, N47, N50, N53, N56, N60, N63, N66, N69, N73, N76, N79, N82, N86,
10 | N89, N92, N95, N99, N102, N105, N108, N112, N115, N223, N329, N370,
11 | N421, N430, N431, N432 );
12 | input N1, N4, N8, N11, N14, N17, N21, N24, N27, N30, N34, N37, N40, N43, N47,
13 | N50, N53, N56, N60, N63, N66, N69, N73, N76, N79, N82, N86, N89, N92,
14 | N95, N99, N102, N105, N108, N112, N115;
15 | output N223, N329, N370, N421, N430, N431, N432;
16 | wire n121, n122, n123, n124, n125, n126, n127, n128, n129, n130, n131,
17 | n132, n133, n134, n135, n136, n137, n138, n139, n140, n141, n142,
18 | n143, n144, n145, n146, n147, n148, n149, n150, n151, n152, n153,
19 | n154, n155, n156, n157, n158, n159, n160, n161, n162, n163, n164,
20 | n165, n166, n167, n168, n169, n170, n171, n172, n173, n174, n175,
21 | n176, n177, n178, n179, n180, n181, n182, n183, n184, n185, n186,
22 | n187, n188, n189, n190, n191, n192, n193, n194, n195, n196, n197,
23 | n198, n199, n200, n201, n202, n203, n204, n205, n206, n207, n208,
24 | n209, n210, n211, n212, n213, n214, n215, n216, n217, n218, n219,
25 | n220, n221, n222, n223, n224, n225, n226;
26 |
27 | NAND2_X1 U128 ( .A1(n121), .A2(n122), .ZN(N432) );
28 | NAND2_X1 U129 ( .A1(n123), .A2(n124), .ZN(n122) );
29 | NAND3_X1 U130 ( .A1(n125), .A2(n126), .A3(n127), .ZN(n123) );
30 | NAND2_X1 U131 ( .A1(n128), .A2(n129), .ZN(n127) );
31 | INV_X1 U132 ( .I(n130), .ZN(n128) );
32 | NAND4_X1 U133 ( .A1(n131), .A2(n132), .A3(n133), .A4(n134), .ZN(n125) );
33 | NAND2_X1 U134 ( .A1(N105), .A2(N370), .ZN(n132) );
34 | NAND3_X1 U135 ( .A1(n121), .A2(n124), .A3(n135), .ZN(N431) );
35 | NAND3_X1 U136 ( .A1(n126), .A2(n129), .A3(n136), .ZN(n135) );
36 | NOR2_X1 U137 ( .A1(n137), .A2(n138), .ZN(N421) );
37 | NOR4_X1 U138 ( .A1(N108), .A2(N430), .A3(n131), .A4(n136), .ZN(n138) );
38 | NAND2_X1 U139 ( .A1(n130), .A2(n133), .ZN(n136) );
39 | NAND4_X1 U140 ( .A1(N82), .A2(n139), .A3(n140), .A4(n141), .ZN(n133) );
40 | NAND2_X1 U141 ( .A1(N86), .A2(N329), .ZN(n140) );
41 | NAND2_X1 U142 ( .A1(N92), .A2(N370), .ZN(n139) );
42 | NAND3_X1 U143 ( .A1(n142), .A2(n143), .A3(n144), .ZN(n130) );
43 | INV_X1 U144 ( .I(n145), .ZN(n144) );
44 | NAND2_X1 U145 ( .A1(N73), .A2(N329), .ZN(n143) );
45 | NAND2_X1 U146 ( .A1(N79), .A2(N370), .ZN(n142) );
46 | AND2_X1 U147 ( .A1(N95), .A2(n146), .Z(n131) );
47 | NAND2_X1 U148 ( .A1(N89), .A2(N223), .ZN(n146) );
48 | NAND4_X1 U149 ( .A1(n126), .A2(n129), .A3(n121), .A4(n124), .ZN(N430) );
49 | NAND4_X1 U150 ( .A1(N30), .A2(n147), .A3(n148), .A4(n149), .ZN(n124) );
50 | NAND2_X1 U151 ( .A1(N34), .A2(N329), .ZN(n148) );
51 | NAND2_X1 U152 ( .A1(N40), .A2(N370), .ZN(n147) );
52 | NAND4_X1 U153 ( .A1(N17), .A2(n150), .A3(n151), .A4(n152), .ZN(n121) );
53 | NAND2_X1 U154 ( .A1(N21), .A2(N329), .ZN(n151) );
54 | NAND2_X1 U155 ( .A1(N27), .A2(N370), .ZN(n150) );
55 | NAND3_X1 U156 ( .A1(n153), .A2(n154), .A3(n155), .ZN(n129) );
56 | INV_X1 U157 ( .I(n156), .ZN(n155) );
57 | NAND2_X1 U158 ( .A1(N60), .A2(N329), .ZN(n154) );
58 | NAND2_X1 U159 ( .A1(N66), .A2(N370), .ZN(n153) );
59 | NAND4_X1 U160 ( .A1(N43), .A2(n157), .A3(n158), .A4(n159), .ZN(n126) );
60 | NAND2_X1 U161 ( .A1(N47), .A2(N329), .ZN(n158) );
61 | NAND2_X1 U162 ( .A1(N53), .A2(N370), .ZN(n157) );
62 | NOR4_X1 U163 ( .A1(n160), .A2(n161), .A3(n162), .A4(n163), .ZN(n137) );
63 | AND2_X1 U164 ( .A1(N370), .A2(N14), .Z(n162) );
64 | NAND4_X1 U165 ( .A1(n164), .A2(n165), .A3(n166), .A4(n167), .ZN(N370) );
65 | NOR4_X1 U166 ( .A1(n168), .A2(n169), .A3(n170), .A4(n171), .ZN(n167) );
66 | NOR2_X1 U167 ( .A1(N329), .A2(n172), .ZN(n171) );
67 | NOR4_X1 U168 ( .A1(n173), .A2(n174), .A3(n175), .A4(n176), .ZN(n172) );
68 | NOR2_X1 U169 ( .A1(N27), .A2(n177), .ZN(n176) );
69 | NOR2_X1 U170 ( .A1(N115), .A2(n178), .ZN(n175) );
70 | NOR2_X1 U171 ( .A1(N40), .A2(n179), .ZN(n174) );
71 | NAND2_X1 U172 ( .A1(n180), .A2(n181), .ZN(n173) );
72 | OR2_X1 U173 ( .A1(n182), .A2(N53), .Z(n181) );
73 | OR2_X1 U174 ( .A1(n183), .A2(N92), .Z(n180) );
74 | NOR3_X1 U175 ( .A1(n183), .A2(N92), .A3(N86), .ZN(n170) );
75 | NAND2_X1 U176 ( .A1(n184), .A2(n185), .ZN(n169) );
76 | OR3_X1 U177 ( .A1(N21), .A2(N27), .A3(n177), .Z(n185) );
77 | OR3_X1 U178 ( .A1(N34), .A2(N40), .A3(n179), .Z(n184) );
78 | NOR3_X1 U179 ( .A1(n182), .A2(N53), .A3(N47), .ZN(n168) );
79 | NOR3_X1 U180 ( .A1(n186), .A2(n187), .A3(n188), .ZN(n166) );
80 | NOR3_X1 U181 ( .A1(n156), .A2(N66), .A3(n189), .ZN(n188) );
81 | NOR2_X1 U182 ( .A1(n190), .A2(n191), .ZN(n189) );
82 | NOR3_X1 U183 ( .A1(n145), .A2(N79), .A3(n192), .ZN(n187) );
83 | NOR2_X1 U184 ( .A1(n193), .A2(n191), .ZN(n192) );
84 | INV_X1 U185 ( .I(N329), .ZN(n191) );
85 | NOR4_X1 U186 ( .A1(N105), .A2(n194), .A3(n195), .A4(n196), .ZN(n186) );
86 | INV_X1 U187 ( .I(n134), .ZN(n195) );
87 | NAND2_X1 U188 ( .A1(N99), .A2(N329), .ZN(n134) );
88 | OR4_X1 U189 ( .A1(n163), .A2(n161), .A3(n160), .A4(N14), .Z(n165) );
89 | AND2_X1 U190 ( .A1(N8), .A2(N329), .Z(n160) );
90 | OR3_X1 U191 ( .A1(N112), .A2(N115), .A3(n178), .Z(n164) );
91 | NAND4_X1 U192 ( .A1(n197), .A2(n198), .A3(n199), .A4(n200), .ZN(N329) );
92 | NOR4_X1 U193 ( .A1(n201), .A2(n202), .A3(n203), .A4(n204), .ZN(n200) );
93 | NOR2_X1 U194 ( .A1(N86), .A2(n183), .ZN(n204) );
94 | NAND2_X1 U195 ( .A1(N82), .A2(n141), .ZN(n183) );
95 | NAND2_X1 U196 ( .A1(N223), .A2(n205), .ZN(n141) );
96 | NOR2_X1 U197 ( .A1(N47), .A2(n182), .ZN(n203) );
97 | NAND2_X1 U198 ( .A1(N43), .A2(n159), .ZN(n182) );
98 | NAND2_X1 U199 ( .A1(N37), .A2(N223), .ZN(n159) );
99 | NOR2_X1 U200 ( .A1(N34), .A2(n179), .ZN(n202) );
100 | NAND2_X1 U201 ( .A1(N30), .A2(n149), .ZN(n179) );
101 | NAND2_X1 U202 ( .A1(N223), .A2(n206), .ZN(n149) );
102 | NOR2_X1 U203 ( .A1(N21), .A2(n177), .ZN(n201) );
103 | NAND2_X1 U204 ( .A1(N17), .A2(n152), .ZN(n177) );
104 | NAND2_X1 U205 ( .A1(N223), .A2(n207), .ZN(n152) );
105 | NOR3_X1 U206 ( .A1(n208), .A2(n190), .A3(n193), .ZN(n199) );
106 | NOR2_X1 U207 ( .A1(n145), .A2(N73), .ZN(n193) );
107 | NAND2_X1 U208 ( .A1(N69), .A2(n209), .ZN(n145) );
108 | NAND2_X1 U209 ( .A1(N63), .A2(N223), .ZN(n209) );
109 | NOR2_X1 U210 ( .A1(n156), .A2(N60), .ZN(n190) );
110 | NAND2_X1 U211 ( .A1(N56), .A2(n210), .ZN(n156) );
111 | NAND2_X1 U212 ( .A1(N50), .A2(N223), .ZN(n210) );
112 | NOR3_X1 U213 ( .A1(n196), .A2(N99), .A3(n194), .ZN(n208) );
113 | AND2_X1 U214 ( .A1(N89), .A2(N223), .Z(n194) );
114 | OR3_X1 U215 ( .A1(n161), .A2(N8), .A3(n163), .Z(n198) );
115 | AND2_X1 U216 ( .A1(N1), .A2(N223), .Z(n161) );
116 | OR2_X1 U217 ( .A1(n178), .A2(N112), .Z(n197) );
117 | NAND2_X1 U218 ( .A1(N108), .A2(n211), .ZN(n178) );
118 | NAND2_X1 U219 ( .A1(N102), .A2(N223), .ZN(n211) );
119 | NAND4_X1 U220 ( .A1(n212), .A2(n213), .A3(n214), .A4(n215), .ZN(N223) );
120 | NOR4_X1 U221 ( .A1(n216), .A2(n217), .A3(n218), .A4(n219), .ZN(n215) );
121 | NOR2_X1 U222 ( .A1(N89), .A2(n196), .ZN(n219) );
122 | INV_X1 U223 ( .I(N95), .ZN(n196) );
123 | NOR2_X1 U224 ( .A1(N63), .A2(n220), .ZN(n218) );
124 | INV_X1 U225 ( .I(N69), .ZN(n220) );
125 | NOR2_X1 U226 ( .A1(N50), .A2(n221), .ZN(n217) );
126 | INV_X1 U227 ( .I(N56), .ZN(n221) );
127 | NOR2_X1 U228 ( .A1(N37), .A2(n222), .ZN(n216) );
128 | INV_X1 U229 ( .I(N43), .ZN(n222) );
129 | AND3_X1 U230 ( .A1(n205), .A2(n207), .A3(n206), .Z(n214) );
130 | NAND2_X1 U231 ( .A1(n223), .A2(N30), .ZN(n206) );
131 | INV_X1 U232 ( .I(N24), .ZN(n223) );
132 | NAND2_X1 U233 ( .A1(n224), .A2(N17), .ZN(n207) );
133 | INV_X1 U234 ( .I(N11), .ZN(n224) );
134 | NAND2_X1 U235 ( .A1(n225), .A2(N82), .ZN(n205) );
135 | INV_X1 U236 ( .I(N76), .ZN(n225) );
136 | OR2_X1 U237 ( .A1(n163), .A2(N1), .Z(n213) );
137 | INV_X1 U238 ( .I(N4), .ZN(n163) );
138 | NAND2_X1 U239 ( .A1(N108), .A2(n226), .ZN(n212) );
139 | INV_X1 U240 ( .I(N102), .ZN(n226) );
140 | endmodule
141 |
142 |
--------------------------------------------------------------------------------
/data/verilog/ISCAS89/s27.v:
--------------------------------------------------------------------------------
1 | //# 4 inputs
2 | //# 1 outputs
3 | //# 3 D-type flipflops
4 | //# 2 inverters
5 | //# 8 gates (1 ANDs + 1 NANDs + 2 ORs + 4 NORs)
6 |
7 | module dff (CK,Q,D);
8 | input CK,D;
9 | output Q;
10 |
11 | wire NM,NCK;
12 | trireg NQ,M;
13 |
14 | nmos N7 (M,D,NCK);
15 | not P3 (NM,M);
16 | nmos N9 (NQ,NM,CK);
17 | not P5 (Q,NQ);
18 | not P1 (NCK,CK);
19 |
20 | endmodule
21 |
22 | module s27(GND,VDD,CK,G0,G1,G17,G2,G3);
23 | input GND,VDD,CK,G0,G1,G2,G3;
24 | output G17;
25 |
26 | wire G5,G10,G6,G11,G7,G13,G14,G8,G15,G12,G16,G9;
27 |
28 | dff DFF_0(CK,G5,G10);
29 | dff DFF_1(CK,G6,G11);
30 | dff DFF_2(CK,G7,G13);
31 | not NOT_0(G14,G0);
32 | not NOT_1(G17,G11);
33 | and AND2_0(G8,G14,G6);
34 | or OR2_0(G15,G12,G8);
35 | or OR2_1(G16,G3,G8);
36 | nand NAND2_0(G9,G16,G15);
37 | nor NOR2_0(G10,G14,G11);
38 | nor NOR2_1(G11,G5,G9);
39 | nor NOR2_2(G12,G1,G7);
40 | nor NOR2_3(G13,G2,G12);
41 |
42 | endmodule
--------------------------------------------------------------------------------
/data/verilog/ISCAS89/s298.v:
--------------------------------------------------------------------------------
1 | //# 3 inputs
2 | //# 6 outputs
3 | //# 14 D-type flipflops
4 | //# 44 inverters
5 | //# 75 gates (31 ANDs + 9 NANDs + 16 ORs + 19 NORs)
6 |
7 | module dff (CK,Q,D);
8 | input CK,D;
9 | output Q;
10 |
11 | wire NM,NCK;
12 | trireg NQ,M;
13 |
14 | nmos N7 (M,D,NCK);
15 | not P3 (NM,M);
16 | nmos N9 (NQ,NM,CK);
17 | not P5 (Q,NQ);
18 | not P1 (NCK,CK);
19 |
20 | endmodule
21 |
22 | module s298(GND,VDD,CK,G0,G1,G117,G118,G132,G133,G2,G66,G67);
23 | input GND,VDD,CK,G0,G1,G2;
24 | output G117,G132,G66,G118,G133,G67;
25 |
26 | wire G10,G29,G11,G30,G12,G34,G13,G39,G14,G44,G15,G56,G16,G86,G17,G92,G18,G98,
27 | G19,G102,G20,G107,G21,G113,G22,G119,G23,G125,G28,G130,G38,G40,G45,G46,G50,
28 | G51,G54,G55,G59,G60,G64,II155,II158,G76,G82,G87,G91,G93,G96,G99,G103,G108,
29 | G112,G114,II210,II213,G120,G124,G121,II221,G126,G131,G127,II229,II232,
30 | II235,II238,G26,G27,G31,G32,G33,G35,G36,G37,G42,G41,G48,G47,G49,G52,G57,
31 | G61,G58,G65,G62,G63,G74,G75,G88,G89,G90,G94,G95,G100,G105,G104,G110,G109,
32 | G111,G115,G122,G123,G128,G129,G24,G25,G68,G69,G70,G71,G72,G73,G77,G78,G79,
33 | G80,G81,G83,G84,G85,G43,G97,G101,G106,G116,G53;
34 |
35 | dff DFF_0(CK,G10,G29);
36 | dff DFF_1(CK,G11,G30);
37 | dff DFF_2(CK,G12,G34);
38 | dff DFF_3(CK,G13,G39);
39 | dff DFF_4(CK,G14,G44);
40 | dff DFF_5(CK,G15,G56);
41 | dff DFF_6(CK,G16,G86);
42 | dff DFF_7(CK,G17,G92);
43 | dff DFF_8(CK,G18,G98);
44 | dff DFF_9(CK,G19,G102);
45 | dff DFF_10(CK,G20,G107);
46 | dff DFF_11(CK,G21,G113);
47 | dff DFF_12(CK,G22,G119);
48 | dff DFF_13(CK,G23,G125);
49 | not NOT_0(G28,G130);
50 | not NOT_1(G38,G10);
51 | not NOT_2(G40,G13);
52 | not NOT_3(G45,G12);
53 | not NOT_4(G46,G11);
54 | not NOT_5(G50,G14);
55 | not NOT_6(G51,G23);
56 | not NOT_7(G54,G11);
57 | not NOT_8(G55,G13);
58 | not NOT_9(G59,G12);
59 | not NOT_10(G60,G22);
60 | not NOT_11(G64,G15);
61 | not NOT_12(II155,G16);
62 | not NOT_13(G66,II155);
63 | not NOT_14(II158,G17);
64 | not NOT_15(G67,II158);
65 | not NOT_16(G76,G10);
66 | not NOT_17(G82,G11);
67 | not NOT_18(G87,G16);
68 | not NOT_19(G91,G12);
69 | not NOT_20(G93,G17);
70 | not NOT_21(G96,G14);
71 | not NOT_22(G99,G18);
72 | not NOT_23(G103,G13);
73 | not NOT_24(G108,G112);
74 | not NOT_25(G114,G21);
75 | not NOT_26(II210,G18);
76 | not NOT_27(G117,II210);
77 | not NOT_28(II213,G19);
78 | not NOT_29(G118,II213);
79 | not NOT_30(G120,G124);
80 | not NOT_31(G121,G22);
81 | not NOT_32(II221,G2);
82 | not NOT_33(G124,II221);
83 | not NOT_34(G126,G131);
84 | not NOT_35(G127,G23);
85 | not NOT_36(II229,G0);
86 | not NOT_37(G130,II229);
87 | not NOT_38(II232,G1);
88 | not NOT_39(G131,II232);
89 | not NOT_40(II235,G20);
90 | not NOT_41(G132,II235);
91 | not NOT_42(II238,G21);
92 | not NOT_43(G133,II238);
93 | and AND2_0(G26,G28,G50);
94 | and AND2_1(G27,G51,G28);
95 | and AND3_0(G31,G10,G45,G13);
96 | and AND2_2(G32,G10,G11);
97 | and AND2_3(G33,G38,G46);
98 | and AND3_1(G35,G10,G11,G12);
99 | and AND2_4(G36,G38,G45);
100 | and AND2_5(G37,G46,G45);
101 | and AND2_6(G42,G40,G41);
102 | and AND4_0(G48,G45,G46,G10,G47);
103 | and AND3_2(G49,G50,G51,G52);
104 | and AND4_1(G57,G59,G11,G60,G61);
105 | and AND2_7(G58,G64,G65);
106 | and AND4_2(G62,G59,G11,G60,G61);
107 | and AND2_8(G63,G64,G65);
108 | and AND3_3(G74,G12,G14,G19);
109 | and AND3_4(G75,G82,G91,G14);
110 | and AND2_9(G88,G14,G87);
111 | and AND2_10(G89,G103,G96);
112 | and AND2_11(G90,G91,G103);
113 | and AND2_12(G94,G93,G13);
114 | and AND2_13(G95,G96,G13);
115 | and AND3_5(G100,G99,G14,G12);
116 | and AND3_6(G105,G103,G108,G104);
117 | and AND2_14(G110,G108,G109);
118 | and AND2_15(G111,G10,G112);
119 | and AND2_16(G115,G114,G14);
120 | and AND2_17(G122,G120,G121);
121 | and AND2_18(G123,G124,G22);
122 | and AND2_19(G128,G126,G127);
123 | and AND2_20(G129,G131,G23);
124 | or OR4_0(G24,G38,G46,G45,G40);
125 | or OR3_0(G25,G38,G11,G12);
126 | or OR4_1(G68,G11,G12,G13,G96);
127 | or OR2_0(G69,G103,G18);
128 | or OR2_1(G70,G103,G14);
129 | or OR3_1(G71,G82,G12,G13);
130 | or OR2_2(G72,G91,G20);
131 | or OR2_3(G73,G103,G20);
132 | or OR4_2(G77,G112,G103,G96,G19);
133 | or OR2_4(G78,G108,G76);
134 | or OR2_5(G79,G103,G14);
135 | or OR2_6(G80,G11,G14);
136 | or OR2_7(G81,G12,G13);
137 | or OR4_3(G83,G11,G12,G13,G96);
138 | or OR3_2(G84,G82,G91,G14);
139 | or OR3_3(G85,G91,G96,G17);
140 | nand NAND3_0(G41,G12,G11,G10);
141 | nand NAND3_1(G43,G24,G25,G28);
142 | nand NAND4_0(G52,G13,G45,G46,G10);
143 | nand NAND4_1(G65,G59,G54,G22,G61);
144 | nand NAND4_2(G97,G83,G84,G85,G108);
145 | nand NAND4_3(G101,G68,G69,G70,G108);
146 | nand NAND2_0(G106,G77,G78);
147 | nand NAND4_4(G109,G71,G72,G73,G14);
148 | nand NAND4_5(G116,G79,G80,G81,G108);
149 | nor NOR2_0(G29,G10,G130);
150 | nor NOR4_0(G30,G31,G32,G33,G130);
151 | nor NOR4_1(G34,G35,G36,G37,G130);
152 | nor NOR2_1(G39,G42,G43);
153 | nor NOR3_0(G44,G48,G49,G53);
154 | nor NOR2_2(G47,G50,G40);
155 | nor NOR2_3(G53,G26,G27);
156 | nor NOR3_1(G56,G57,G58,G130);
157 | nor NOR2_4(G61,G14,G55);
158 | nor NOR4_2(G86,G88,G89,G90,G112);
159 | nor NOR3_2(G92,G94,G95,G97);
160 | nor NOR2_5(G98,G100,G101);
161 | nor NOR2_6(G102,G105,G106);
162 | nor NOR2_7(G104,G74,G75);
163 | nor NOR2_8(G107,G110,G111);
164 | nor NOR2_9(G112,G62,G63);
165 | nor NOR2_10(G113,G115,G116);
166 | nor NOR3_3(G119,G122,G123,G130);
167 | nor NOR3_4(G125,G128,G129,G130);
168 |
169 | endmodule
--------------------------------------------------------------------------------
/data/verilog/ISCAS89/s386.v:
--------------------------------------------------------------------------------
1 | //# 7 inputs
2 | //# 7 outputs
3 | //# 6 D-type flipflops
4 | //# 41 inverters
5 | //# 118 gates (83 ANDs + 0 NANDs + 35 ORs + 0 NORs)
6 |
7 | module dff (CK,Q,D);
8 | input CK,D;
9 | output Q;
10 |
11 | wire NM,NCK;
12 | trireg NQ,M;
13 |
14 | nmos N7 (M,D,NCK);
15 | not P3 (NM,M);
16 | nmos N9 (NQ,NM,CK);
17 | not P5 (Q,NQ);
18 | not P1 (NCK,CK);
19 |
20 | endmodule
21 |
22 | module s386(GND,VDD,CK,v0,v1,v13_D_10,v13_D_11,v13_D_12,v13_D_6,v13_D_7,
23 | v13_D_8,v13_D_9,v2,v3,v4,v5,v6);
24 | input GND,VDD,CK,v6,v5,v4,v3,v2,v1,v0;
25 | output v13_D_12,v13_D_11,v13_D_10,v13_D_9,v13_D_8,v13_D_7,v13_D_6;
26 |
27 | wire v12,v13_D_5,v11,v13_D_4,v10,v13_D_3,v9,v13_D_2,v8,v13_D_1,v7,v13_D_0,
28 | v3bar,v6bar,v5bar,B35Bbar,B35B,B14Bbar,B14B,B34Bbar,B34B,v4bar,v11bar,
29 | v8bar,v7bar,v12bar,v0bar,v10bar,v9bar,v1bar,II198,Lv13_D_12,II201,
30 | Lv13_D_11,II204,Lv13_D_10,II207,Lv13_D_9,II210,Lv13_D_8,II213,Lv13_D_7,
31 | II216,Lv13_D_6,II219,Lv13_D_5,II222,Lv13_D_4,II225,Lv13_D_3,II228,Lv13_D_2,
32 | II231,Lv13_D_1,II234,Lv13_D_0,II64,II65,IIII114,IIII113,IIII111,IIII109,
33 | IIII108,IIII106,IIII105,IIII103,IIII102,IIII100,IIII98,IIII96,II89,IIII94,
34 | IIII93,IIII91,IIII90,II97,II98,IIII87,II104,IIII85,IIII84,IIII79,IIII77,
35 | IIII76,IIII74,IIII73,IIII71,IIII69,II124,B40B,IIII66,IIII65,IIII63,IIII62,
36 | B23B,IIII60,B42B,IIII59,B43B,IIII57,B32B,IIII56,IIII54,IIII53,B27B,IIII51,
37 | IIII50,B21B,IIII48,IIII47,II148,B38B,IIII44,B29B,IIII43,B30B,IIII41,B17B,
38 | IIII40,B16B,IIII39,II158,B39B,IIII36,B25B,B26B,IIII35,B28B,II164,B15B,
39 | II167,B33B,IIII31,B36B,II171,IIII30,II175,IIII28,IIII27,B44B,IIII25,B22B,
40 | IIII24,B24B,IIII22,B18B,IIII21,B19B,II186,B31B,IIII18,B41B,IIII17,B45B,
41 | II192,B37B,II195,B20B;
42 |
43 | dff DFF_0(CK,v12,v13_D_5);
44 | dff DFF_1(CK,v11,v13_D_4);
45 | dff DFF_2(CK,v10,v13_D_3);
46 | dff DFF_3(CK,v9,v13_D_2);
47 | dff DFF_4(CK,v8,v13_D_1);
48 | dff DFF_5(CK,v7,v13_D_0);
49 | not NOT_0(v3bar,v3);
50 | not NOT_1(v6bar,v6);
51 | not NOT_2(v5bar,v5);
52 | not NOT_3(B35Bbar,B35B);
53 | not NOT_4(B14Bbar,B14B);
54 | not NOT_5(B34Bbar,B34B);
55 | not NOT_6(v4bar,v4);
56 | not NOT_7(v11bar,v11);
57 | not NOT_8(v8bar,v8);
58 | not NOT_9(v7bar,v7);
59 | not NOT_10(v12bar,v12);
60 | not NOT_11(v0bar,v0);
61 | not NOT_12(v10bar,v10);
62 | not NOT_13(v9bar,v9);
63 | not NOT_14(v1bar,v1);
64 | not NOT_15(II198,Lv13_D_12);
65 | not NOT_16(v13_D_12,II198);
66 | not NOT_17(II201,Lv13_D_11);
67 | not NOT_18(v13_D_11,II201);
68 | not NOT_19(II204,Lv13_D_10);
69 | not NOT_20(v13_D_10,II204);
70 | not NOT_21(II207,Lv13_D_9);
71 | not NOT_22(v13_D_9,II207);
72 | not NOT_23(II210,Lv13_D_8);
73 | not NOT_24(v13_D_8,II210);
74 | not NOT_25(II213,Lv13_D_7);
75 | not NOT_26(v13_D_7,II213);
76 | not NOT_27(II216,Lv13_D_6);
77 | not NOT_28(v13_D_6,II216);
78 | not NOT_29(II219,Lv13_D_5);
79 | not NOT_30(v13_D_5,II219);
80 | not NOT_31(II222,Lv13_D_4);
81 | not NOT_32(v13_D_4,II222);
82 | not NOT_33(II225,Lv13_D_3);
83 | not NOT_34(v13_D_3,II225);
84 | not NOT_35(II228,Lv13_D_2);
85 | not NOT_36(v13_D_2,II228);
86 | not NOT_37(II231,Lv13_D_1);
87 | not NOT_38(v13_D_1,II231);
88 | not NOT_39(II234,Lv13_D_0);
89 | not NOT_40(v13_D_0,II234);
90 | and AND4_0(II64,v0bar,v5,v7bar,v8bar);
91 | and AND4_1(II65,v9,v10,v11bar,v12bar);
92 | and AND2_0(Lv13_D_12,II64,II65);
93 | and AND2_1(IIII114,v9bar,v12bar);
94 | and AND2_2(IIII113,v7bar,v8bar);
95 | and AND2_3(IIII111,v7bar,v8bar);
96 | and AND3_0(IIII109,v3bar,v4bar,v11bar);
97 | and AND2_4(IIII108,v7,v11);
98 | and AND4_2(IIII106,v5bar,v7bar,v11,v12);
99 | and AND3_1(IIII105,v2,v11bar,v12bar);
100 | and AND3_2(IIII103,v8,v11,v12bar);
101 | and AND3_3(IIII102,v8bar,v11bar,v12);
102 | and AND2_5(IIII100,v2,v8bar);
103 | and AND2_6(IIII98,v0,v5);
104 | and AND2_7(IIII96,v1,v9bar);
105 | and AND3_4(II89,v5bar,v7bar,v8bar);
106 | and AND3_5(IIII94,v10,v11bar,II89);
107 | and AND2_8(IIII93,v9bar,v10bar);
108 | and AND3_6(IIII91,v0,v11bar,v12bar);
109 | and AND2_9(IIII90,v9bar,v10bar);
110 | and AND4_3(II97,v0,v6bar,v7bar,v8bar);
111 | and AND4_4(II98,v9bar,v10,v11bar,v12bar);
112 | and AND2_10(Lv13_D_8,II97,II98);
113 | and AND4_5(IIII87,v5bar,v9,v11bar,v12bar);
114 | and AND3_7(II104,v2,v3,v8);
115 | and AND3_8(IIII85,v11bar,v12bar,II104);
116 | and AND3_9(IIII84,v8bar,v11,v12);
117 | and AND2_11(IIII79,v11bar,v12bar);
118 | and AND3_10(IIII77,v0,v8bar,v10);
119 | and AND4_6(IIII76,v1bar,v4,v10bar,B34Bbar);
120 | and AND3_11(IIII74,v7,v8bar,v11);
121 | and AND3_12(IIII73,v4bar,v11bar,B34Bbar);
122 | and AND3_13(IIII71,v4bar,v11bar,B34Bbar);
123 | and AND2_12(IIII69,v7,v11bar);
124 | and AND4_7(II124,B40B,v1,v7bar,v8bar);
125 | and AND4_8(Lv13_D_10,v9,v11bar,v12bar,II124);
126 | and AND2_13(IIII66,v4,v7);
127 | and AND2_14(IIII65,B35B,B34B);
128 | and AND3_14(IIII63,v9bar,v10bar,v12bar);
129 | and AND3_15(IIII62,B23B,v7bar,v8bar);
130 | and AND2_15(IIII60,v1,B42B);
131 | and AND3_16(IIII59,B43B,v8,v12bar);
132 | and AND2_16(IIII57,B32B,v7bar);
133 | and AND3_17(IIII56,v11,v12bar,B14Bbar);
134 | and AND3_18(IIII54,v0bar,v9bar,v10bar);
135 | and AND2_17(IIII53,B27B,v1);
136 | and AND3_19(IIII51,v9bar,v10bar,v12bar);
137 | and AND3_20(IIII50,B21B,v7bar,v8bar);
138 | and AND2_18(IIII48,B14B,v11);
139 | and AND3_21(IIII47,v4bar,v11bar,B34Bbar);
140 | and AND3_22(II148,B38B,v0,v1bar);
141 | and AND4_9(Lv13_D_7,v9bar,v10bar,v12bar,II148);
142 | and AND2_19(IIII44,v8bar,B29B);
143 | and AND2_20(IIII43,B30B,v12bar);
144 | and AND3_23(IIII41,v4,v11bar,B17B);
145 | and AND3_24(IIII40,v3,v8,B16B);
146 | and AND4_10(IIII39,v5,v7,v8bar,v11);
147 | and AND3_25(II158,B39B,v7bar,v9bar);
148 | and AND3_26(Lv13_D_9,v11bar,v12bar,II158);
149 | and AND4_11(IIII36,v7bar,v8bar,B25B,B26B);
150 | and AND2_21(IIII35,B28B,v12bar);
151 | and AND3_27(II164,B15B,v0,v1bar);
152 | and AND4_12(Lv13_D_0,v9bar,v10bar,v12bar,II164);
153 | and AND3_28(II167,B33B,v0,v1bar);
154 | and AND3_29(Lv13_D_5,v9bar,v10bar,II167);
155 | and AND3_30(IIII31,B36B,v11bar,v12bar);
156 | and AND3_31(II171,v5,v7bar,v8bar);
157 | and AND3_32(IIII30,v11,v12,II171);
158 | and AND3_33(II175,v0,v7bar,v8bar);
159 | and AND4_13(IIII28,v10,v11bar,v12bar,II175);
160 | and AND2_22(IIII27,B44B,v10bar);
161 | and AND2_23(IIII25,v0bar,B22B);
162 | and AND2_24(IIII24,B24B,v1);
163 | and AND2_25(IIII22,v7bar,B18B);
164 | and AND2_26(IIII21,B19B,v12bar);
165 | and AND3_34(II186,B31B,v0,v1bar);
166 | and AND3_35(Lv13_D_4,v9bar,v10bar,II186);
167 | and AND3_36(IIII18,v0bar,v10bar,B41B);
168 | and AND2_27(IIII17,B45B,v9bar);
169 | and AND3_37(II192,B37B,v0,v1bar);
170 | and AND3_38(Lv13_D_6,v9bar,v10bar,II192);
171 | and AND3_39(II195,B20B,v0,v1bar);
172 | and AND3_40(Lv13_D_1,v9bar,v10bar,II195);
173 | or OR2_0(B41B,IIII113,IIII114);
174 | or OR2_1(B42B,IIII111,v12bar);
175 | or OR2_2(B43B,IIII108,IIII109);
176 | or OR2_3(B29B,IIII105,IIII106);
177 | or OR2_4(B18B,IIII102,IIII103);
178 | or OR2_5(B17B,v7,IIII100);
179 | or OR2_6(B40B,IIII98,v10bar);
180 | or OR2_7(B26B,v0bar,IIII96);
181 | or OR2_8(B27B,IIII93,IIII94);
182 | or OR2_9(B23B,IIII90,IIII91);
183 | or OR2_10(B21B,v10bar,IIII87);
184 | or OR2_11(B32B,IIII84,IIII85);
185 | or OR2_12(B34B,v8bar,v3);
186 | or OR2_13(B14B,v7bar,v8bar);
187 | or OR2_14(B35B,v2,v7);
188 | or OR2_15(B25B,v10bar,IIII79);
189 | or OR2_16(B39B,IIII76,IIII77);
190 | or OR2_17(B38B,IIII73,IIII74);
191 | or OR2_18(B30B,IIII71,v7);
192 | or OR2_19(B16B,B35Bbar,IIII69);
193 | or OR2_20(B36B,IIII65,IIII66);
194 | or OR2_21(B24B,IIII62,IIII63);
195 | or OR2_22(B44B,IIII59,IIII60);
196 | or OR2_23(B33B,IIII56,IIII57);
197 | or OR2_24(B28B,IIII53,IIII54);
198 | or OR2_25(B22B,IIII50,IIII51);
199 | or OR2_26(B15B,IIII47,IIII48);
200 | or OR2_27(B31B,IIII43,IIII44);
201 | or OR3_0(B19B,IIII39,IIII40,IIII41);
202 | or OR2_28(Lv13_D_3,IIII35,IIII36);
203 | or OR2_29(B37B,IIII30,IIII31);
204 | or OR2_30(B45B,IIII27,IIII28);
205 | or OR2_31(Lv13_D_2,IIII24,IIII25);
206 | or OR2_32(B20B,IIII21,IIII22);
207 | or OR2_33(Lv13_D_11,IIII17,IIII18);
208 |
209 | endmodule
--------------------------------------------------------------------------------
/gnn/config.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | EPOCH_MAX = 5000
4 | GRAPH_DIR = "../data/graph"
5 | TRAIN_BATCH_RATIO = 0.05
6 | TRAIN_RATIO = 0.5
7 | BC_TH = 0.5
8 | # Used for visualization
9 | EPS = 1e-6
10 |
11 | GTYPES = None
12 |
13 | OPT = "ADAM" # "SGD"
14 |
--------------------------------------------------------------------------------
/gnn/graph/utils.py:
--------------------------------------------------------------------------------
1 |
2 | def BFS(self, g, s):
3 |
4 | # Mark all the vertices as not visited
5 | visited = [False] * (len(self.graph)) # Create a queue for BFS
6 | queue = []
7 | # Mark the source node as
8 | # visited and enqueue it
9 | queue.append(s)
10 | visited[s] = True
11 | while queue:
12 | # Dequeue a vertex from
13 | # queue and print it
14 | s = queue.pop(0)
15 | print (s, end = " ")
16 | # Get all adjacent vertices of the
17 | # dequeued vertex s. If a adjacent
18 | # has not been visited, then mark it
19 | # visited and enqueue it
20 | for i in self.graph[s]:
21 | if visited[i] == False:
22 | queue.append(i)
23 | visited[i] = True
24 |
--------------------------------------------------------------------------------
/gnn/main_test.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | import sys
4 | import os
5 | sys.path.insert(1, '../circuit/')
6 |
7 | import dgl
8 | import dgl.function as fn
9 | import torch
10 | import torch.nn as nn
11 | import torch.nn.functional as F
12 | from dgl import DGLGraph
13 | from dgl.nn.pytorch.utils import Sequential
14 | import numpy as np
15 | import time
16 | import copy
17 | import networkx as nx
18 |
19 | import matplotlib
20 | matplotlib.use('Agg') # Must be before importing matplotlib.pyplot or pylab!
21 | import matplotlib.pyplot as plt
22 | from optparse import OptionParser
23 | from models.vanilla_gcn import VanillaGCN
24 | from models.lstm_gcn import LSTMGCN
25 | import seaborn as sns; sns.set()
26 | import pdb
27 |
28 |
29 | import config
30 |
31 | path = os.path.join(config.GRAPH_DIR, "c17_10e4.graphml")
32 | print("Loading train graph from {}".format(path))
33 | graph_train = nx.read_graphml(path)
34 | g_train = DGLGraph(graph_train)
35 | all_types = []
36 | all_ids_train = list(graph_train.nodes.keys())
37 |
38 | for node_id in graph_train.nodes:
39 | if graph_train.nodes[node_id]['gtype'] not in all_types:
40 | all_types.append(graph_train.nodes[node_id]['gtype'])
41 |
42 | print(all_types)
43 | features_list = [x.strip() for x in options.features.split(",")] if options.features else []
44 | feature_dim = 1 #1 is the default feature_dim when no features are provided
45 | for feature_name in features_list:
46 | if feature_name == "gtype":
47 | feature_dim += len(all_types)
48 | else:
49 | feature_dim += 1
50 |
51 |
--------------------------------------------------------------------------------
/gnn/models/lstm_gcn.py:
--------------------------------------------------------------------------------
1 |
2 | import dgl
3 | import dgl.function as fn
4 | import torch
5 | import torch.nn as nn
6 | import torch.nn.functional as F
7 | from dgl import DGLGraph
8 | from dgl.nn.pytorch import Sequential
9 | import numpy as np
10 | from torch.autograd import Variable
11 |
12 | gcn_msg = fn.copy_src(src='h', out='m')
13 | gcn_reduce = fn.mean(msg='m', out='h')
14 |
15 | def max_reduce(nodes):
16 | return {'h': torch.max(nodes.mailbox['m'], dim=1)[0]}
17 |
18 |
19 | def max_norm_reduce(nodes):
20 | batch_size, incoming_count, weight_dim = nodes.mailbox['m'].shape
21 | norms = torch.norm(nodes.mailbox['m'], p=2, dim=2)
22 | ind_max = torch.max(norms, dim=1)[1] #.repeat(weight_dim).view(batch_size, weight_dim)
23 | reduced = nodes.mailbox['m'][range(batch_size), ind_max]
24 | return {'h': reduced}
25 |
26 |
27 | class GCNLayer(nn.Module):
28 | def __init__(self, in_feats, out_feats):
29 | super(GCNLayer, self).__init__()
30 | self.linear = nn.Linear(in_feats, out_feats)
31 |
32 | def forward(self, g, feature):
33 | with g.local_scope():
34 | g.ndata['h'] = feature
35 | g.update_all(gcn_msg, gcn_reduce)
36 | h = g.ndata['h']
37 | x = torch.cat((h, feature), dim=1)
38 |
39 | return self.linear(x)
40 |
41 |
42 | class GCNLSTMLayer(nn.Module):
43 | def __init__(self, weight_dim, num_layers=3, rev=False):
44 | super(GCNLSTMLayer, self).__init__()
45 | self.weight_dim = weight_dim
46 | self.num_layers = num_layers
47 | in_feats = 3*weight_dim if rev else 2*weight_dim
48 | self.lstm = nn.LSTM(in_feats, weight_dim, num_layers=self.num_layers)
49 |
50 | def forward(self, g, g_rev, feature, state):
51 | with g.local_scope():
52 | g.ndata['h'] = feature.view(-1,self.weight_dim)
53 | g.update_all(gcn_msg, gcn_reduce)
54 | h_in = g.ndata['h']
55 | if g_rev:
56 | with g_rev.local_scope():
57 | g_rev.ndata['h'] = feature.view(-1,self.weight_dim)
58 | g_rev.update_all(gcn_msg, gcn_reduce)
59 | h_out = g_rev.ndata['h']
60 | output = self.lstm(torch.cat((h_in.view(1,-1,self.weight_dim), \
61 | h_out.view(1,-1,self.weight_dim), \
62 | feature.view(1,-1,self.weight_dim)), 2), state)
63 | else:
64 | output = self.lstm(torch.cat((h_in.view(1,-1,self.weight_dim), \
65 | feature.view(1,-1,self.weight_dim)), 2), state)
66 | return output
67 |
68 | def init_hidden(self, batch_size):
69 | return (Variable(torch.zeros(self.num_layers, batch_size, self.weight_dim)),
70 | Variable(torch.zeros(self.num_layers, batch_size, self.weight_dim)))
71 |
72 |
73 | class LSTMGCN(nn.Module):
74 | def __init__(self, feature_dim=6, output_dim=1, weight_dim=512, depth=10, rev=False):
75 | super(LSTMGCN, self).__init__()
76 | self.input_layer = nn.Linear(feature_dim, weight_dim)
77 | self.lstm_layer = GCNLSTMLayer(weight_dim, rev=rev)
78 | self.output_layer = nn.Linear(weight_dim, output_dim)
79 | self.weight_dim = weight_dim
80 | self.feature_dim = feature_dim
81 | self.depth = depth
82 |
83 | def forward(self, g, features, g_rev=None):
84 | batch_size = features.size(0)
85 | x = F.relu(self.input_layer(features))
86 |
87 | h_t, c_t = self.lstm_layer.init_hidden(batch_size)
88 | h_t, c_t = h_t.cuda(), c_t.cuda()
89 |
90 | output, state = self.lstm_layer(g, g_rev, x.view(-1,batch_size,self.weight_dim),(h_t,c_t))
91 | for i in range(self.depth):
92 | _, state = self.lstm_layer(g, g_rev, state[0][-1], state)
93 |
94 | x = self.output_layer(state[0][-1])
95 | return x
96 |
97 |
--------------------------------------------------------------------------------
/gnn/models/pgy/sage_conv.py:
--------------------------------------------------------------------------------
1 | import os.path as osp
2 | import argparse
3 |
4 | import torch
5 | import torch.nn.functional as F
6 | from torch_geometric.datasets import Planetoid
7 | import torch_geometric.transforms as T
8 | from torch_geometric.nn import GCNConv, ChebConv # noqa
9 |
10 | parser = argparse.ArgumentParser()
11 | parser.add_argument('--use_gdc', action='store_true',
12 | help='Use GDC preprocessing.')
13 | args = parser.parse_args()
14 |
15 | dataset = 'Cora'
16 | path = osp.join(osp.dirname(osp.realpath(__file__)), '..', 'data', dataset)
17 | dataset = Planetoid(path, dataset, transform=T.NormalizeFeatures())
18 | data = dataset[0]
19 |
20 | if args.use_gdc:
21 | gdc = T.GDC(self_loop_weight=1, normalization_in='sym',
22 | normalization_out='col',
23 | diffusion_kwargs=dict(method='ppr', alpha=0.05),
24 | sparsification_kwargs=dict(method='topk', k=128,
25 | dim=0), exact=True)
26 | data = gdc(data)
27 |
28 |
29 | class Net(torch.nn.Module):
30 | def __init__(self):
31 | super(Net, self).__init__()
32 | self.conv1 = GCNConv(dataset.num_features, 16, cached=True,
33 | normalize=not args.use_gdc)
34 | self.conv2 = GCNConv(16, dataset.num_classes, cached=True,
35 | normalize=not args.use_gdc)
36 | # self.conv1 = ChebConv(data.num_features, 16, K=2)
37 | # self.conv2 = ChebConv(16, data.num_features, K=2)
38 |
39 | self.reg_params = self.conv1.parameters()
40 | self.non_reg_params = self.conv2.parameters()
41 |
42 | def forward(self):
43 | x, edge_index, edge_weight = data.x, data.edge_index, data.edge_attr
44 | x = F.relu(self.conv1(x, edge_index, edge_weight))
45 | x = F.dropout(x, training=self.training)
46 | x = self.conv2(x, edge_index, edge_weight)
47 | return F.log_softmax(x, dim=1)
48 |
49 |
--------------------------------------------------------------------------------
/gnn/models/vanilla_gcn.py:
--------------------------------------------------------------------------------
1 | import dgl
2 | import dgl.function as fn
3 | import torch
4 | import torch.nn as nn
5 | import torch.nn.functional as F
6 | from dgl import DGLGraph
7 | from dgl.nn.pytorch import Sequential
8 | import numpy as np
9 |
10 | gcn_msg = fn.copy_src(src='h', out='m')
11 | gcn_reduce = fn.mean(msg='m', out='h')
12 |
13 |
14 | # Note: for now dropout is just in the level of layers, and not messages
15 | # You can implement dropout in the level of messages, look at edGNN
16 |
17 |
18 | class GCNLayer(nn.Module):
19 | def __init__(self, in_feats, out_feats, dropout=None):
20 | super(GCNLayer, self).__init__()
21 | self.dropout = dropout
22 | self.linear = nn.Linear(in_feats, out_feats)
23 |
24 | if self.dropout:
25 | self.dropout = nn.Dropout(p=self.dropout)
26 |
27 | def forward(self, g, feature, g_rev=None):
28 | with g.local_scope():
29 | g.ndata['h'] = feature
30 | g.update_all(gcn_msg, gcn_reduce)
31 | h_in = g.ndata['h']
32 | if g_rev:
33 | with g_rev.local_scope():
34 | g_rev.ndata['h'] = feature
35 | g_rev.update_all(gcn_msg, gcn_reduce)
36 | h_out = g_rev.ndata['h']
37 | x = torch.cat((h_in, h_out, feature), dim=1)
38 | else:
39 | x = torch.cat((h_in, feature), dim=1)
40 | x = F.relu(self.linear(x))
41 | if self.dropout:
42 | x = self.dropout(x)
43 | # added g_rev in the output because dgl.Sequentional doesn't provide g_rev for the next layer
44 | return x, g_rev
45 |
46 |
47 |
48 | class GCNLayerF(nn.Module):
49 | def __init__(self,
50 | in_feats,
51 | out_feats,
52 | dropout=None):
53 | """
54 | Fake-GCN layer
55 | Does not communicate with neighbors
56 | Only one layer of activation
57 | No batchnorm
58 | For better syntax, look at edGNN
59 | """
60 | super(GCNLayerF, self).__init__()
61 |
62 | self.dropout = dropout
63 | self.linear = nn.Linear(in_feats, out_feats)
64 |
65 |
66 | if dropout:
67 | self.dropout = nn.Dropout(p=dropout)
68 |
69 | def forward(self, g, feature, g_rev=None):
70 | # with g.local_scope():
71 | # g.ndata['h'] = feature
72 | # g.update_all(gcn_msg, gcn_reduce)
73 | # h_in = g.ndata['h']
74 |
75 | # if g_rev:
76 | # with g_rev.local_scope():
77 | # g_rev.ndata['h'] = feature
78 | # g_rev.update_all(gcn_msg, gcn_reduce)
79 | # h_out = g_rev.ndata['h']
80 | # x = torch.cat((h_in, h_out, feature), dim=1)
81 | # else:
82 | # x = torch.cat((h_in, feature), dim=1)
83 | x = F.relu(self.linear(feature))
84 | if self.dropout:
85 | x = self.dropout(x)
86 | return x, g_rev
87 |
88 |
89 | class FakeGCN(nn.Module):
90 |
91 | def __init__(self, feature_dim=6, output_dim=1,
92 | weight_dim=512, depth=10,
93 | rev=False, dropout=None):
94 | super(FakeGCN, self).__init__()
95 | self.input_layer = nn.Linear(feature_dim, weight_dim)
96 | self.hidden_layers = Sequential(*[GCNLayerF(weight_dim, weight_dim, dropout) for i in range(depth)])
97 | self.output_layer = nn.Linear(weight_dim, output_dim)
98 |
99 | def forward(self, g, features, g_rev=None):
100 | x = F.relu(self.input_layer(features))
101 | x, _ = self.hidden_layers(g, x, g_rev)
102 | x = self.output_layer(x)
103 | return x
104 |
105 |
106 | class VanillaGCN(nn.Module):
107 |
108 | def __init__(self, feature_dim=6, output_dim=1,
109 | weight_dim=512, depth=10,
110 | dropout=None, rev=False):
111 |
112 | super(VanillaGCN, self).__init__()
113 | self.input_layer = nn.Linear(feature_dim, weight_dim)
114 | self.hidden_layers = Sequential(*[GCNLayer(3*weight_dim if rev else 2*weight_dim, weight_dim) for i in range(depth)])
115 | self.output_layer = nn.Linear(weight_dim, output_dim)
116 |
117 | def forward(self, g, features, g_rev=None):
118 | x = F.relu(self.input_layer(features))
119 | x, _ = self.hidden_layers(g, x, g_rev)
120 | x = self.output_layer(x)
121 | return x
122 |
123 |
--------------------------------------------------------------------------------
/gnn/run_gnn.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Classification task on level
3 | # python gnn.py --weight-dim=32 --depth=10 --objective=lev --model=VanillaGCN --train-circuit=c3540 --test-circuit=c432 --problem=classification --loss=CE --bidirectional
4 |
5 |
6 | # Regression, gtype given
7 | # python gnn.py --weight-dim=256 --depth=3 --objective=B0 --features=C0,C1,CO,CC0,CC1,gtype --model=VanillaGCN --train-circuit=c7552 --test-circuit=c7552 --problem=regression --loss=L2 --sigmoid
8 |
9 |
10 | # Regression problem with limited features, output is input
11 | # THIS WORKED -- DON't CHANGE SETUP
12 | # python gnn.py --weight-dim=32 --depth=1 --objective=B0 --features=C0,C1,B0,B1 --model=FakeGCN --train-circuit=c432 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
13 |
14 | # THIS WORKED -- DON't CHANGE SETUP
15 | # python gnn.py --weight-dim=32 --depth=1 --objective=B0 --features=C0,C1,B0,B1 --model=FakeGCN --train-circuit=c6288 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
16 |
17 | # THIS DOES NOT WORK, SCOAP is not scaled!
18 | # python gnn.py --weight-dim=32 --depth=1 --objective=B0 --features=C0,C1,B0,B1,CO,CC0,CC1 --model=FakeGCN --train-circuit=c6288 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
19 |
20 | # WORKED!
21 | # python gnn.py --weight-dim=32 --depth=1 --objective=B0 --features=C0,C1,B0,B1,CB0,CB1 --model=FakeGCN --train-circuit=c6288 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
22 |
23 | # Worked! Run it again with better otimizer, but loss is around 0.002 with ADAM10e-2
24 | # python gnn.py --weight-dim=32 --depth=1 --objective=B --features=C0,C1,B0,B1,CB0,CB1 --model=FakeGCN --train-circuit=c6288 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
25 |
26 |
27 | python gnn.py --weight-dim=32 --depth=1 --objective=B --features=C0,C1,B0,B1 --model=FakeGCN --train-circuit=c6288 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
28 |
29 |
30 |
31 | # Regression problem with limited features, output not input
32 | # python gnn.py --weight-dim=64 --depth=3 --objective=B --features=C0,C1,B0,B1,CO,CC0,CC1 --model=FakeGCN --train-circuit=c6288 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
33 |
34 |
35 | # Regression problem with more features
36 | # python gnn.py --weight-dim=64 --depth=3 --objective=B --features=C0,C1,B0,B1,CO,CC0,CC1,CB0,CB1 --model=FakeGCN --train-circuit=c6288 --test-circuit=c432 --problem=regression --loss=L2 --sigmoid
37 |
38 |
39 | # python gnn.py --weight-dim=64 --depth=3 --objective=HTO --features=C0,C1,B0,B1,CO,CC0,CC1,CB0,CB1,B --model=FakeGCN --train-circuit=c432 --test-circuit=c432 --problem=classification --loss=CE
40 |
--------------------------------------------------------------------------------
/gnn/run_gnn_pyg.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | python gnn_pyg.py --weight-dim=1024 --depth=30 --objective=level --model=LSTMGCN --train-circuit=c499 --test-circuit=c432 --problem=classification --loss=CE
3 |
--------------------------------------------------------------------------------
/gnn/utils.py:
--------------------------------------------------------------------------------
1 |
2 |
3 | from optparse import OptionParser
4 |
5 | def get_options():
6 | parser = OptionParser()
7 | parser.add_option('-w', '--weight-dim', dest='weight_dim', default=512, type='int',
8 | help='weight dimension (default: 512)')
9 | parser.add_option('-d', '--depth', dest='depth', default=20, type='int',
10 | help='number of hops explored in the graph (default: 20)')
11 | parser.add_option('-o', '--objective', dest='objective', default="lev", type='str',
12 | help='learning objective (default: level)')
13 | parser.add_option('-m', '--model', dest='model', default="LSTMGCN", type='str',
14 | help='model architecture (default: LSTMGCN)')
15 | parser.add_option('--train-circuit', dest='circuit_train', default="c1355", type='str',
16 | help='circuit name (default: c1355)')
17 | parser.add_option('--test-circuit', dest='circuit_test', default="c432", type='str',
18 | help='circuit name (default: c432)')
19 | parser.add_option('-p', '--problem', dest='problem', default="classification", type='str',
20 | help='classification or regression? (default: classification)')
21 | parser.add_option('-l', '--loss', dest='loss', default="CE", type='str',
22 | help='loss function (default: cross entropy)')
23 | parser.add_option('-b', '--bidirectional', dest='bidirectional', action="store_true",
24 | help='make the graph uni-directional or bi-directional')
25 | parser.add_option('-s', '--sigmoid', dest='sigmoid', action="store_true",
26 | help='Sigmoid function applied to the logits')
27 | parser.add_option('-f','--features', dest='features', type='str',
28 | help='What features are given to the nodes', default=None)
29 | (options, args) = parser.parse_args()
30 |
31 | return options, args
32 |
--------------------------------------------------------------------------------