├── .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 | --------------------------------------------------------------------------------