A python module for parsing, processing, and simulating gate-level circuits.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

3503 lines
177 KiB

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# KyuPy Introduction\n",
"\n",
1 year ago
"This notebook introduces KyuPy's basic data structures and built-in functions step-by-step.\n",
"\n",
1 year ago
"## Working With Gate-Level Circuit Structures\n",
"\n",
1 year ago
"KyuPy has two parser modules:\n",
"\n",
1 year ago
"* `kyupy.bench`: The [ISCAS'89 Benchmark Format](https://www.researchgate.net/profile/Franc-Brglez/publication/224723140_Combination_profiles_of_sequential_benchmark_circuits) \".bench\"\n",
"* `kyupy.verilog`: Non-hierarchical gate-level verilog\n",
"\n",
1 year ago
"Files can be loaded using `.load(file)`, strings can be parsed using `.parse(text)`."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
1 year ago
"outputs": [],
"source": [
"from kyupy import bench, verilog\n",
"from kyupy.techlib import SAED32, GSC180\n",
"\n",
"# load a file\n",
1 year ago
"b15 = verilog.load('../tests/b15_2ig.v.gz', tlib=SAED32)\n",
"\n",
"# ... or specify the circuit as string \n",
"adder = verilog.parse('''\n",
"module adder(clk, a, b, s);\n",
" input clk, a, b;\n",
" output s;\n",
" wire cin, cout;\n",
" DFFX1 carry (.D(cout), .CK(clk), .Q(cin));\n",
" ADDFX1 adder (.A(a), .B(b), .CI(cin), .CO(cout), .S(s));\n",
"endmodule\n",
"''', tlib=GSC180)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"They return KyuPy's intermediate prepresentation of the circuit graph (objects of class `kyupy.circuit.Circuit`):"
]
},
{
"cell_type": "code",
"execution_count": 2,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"kyupy.circuit.Circuit"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"type(b15)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"{name: \"b15\", cells: 10789, forks: 10749, lines: 32032, io_nodes: 111}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
1 year ago
"source": [
"b15"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{name: \"adder\", cells: 6, forks: 6, lines: 12, io_nodes: 4}"
1 year ago
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"The `.stats` property returns a dictionary with more detailed statistics on the elements in the circuit."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
1 year ago
"outputs": [
{
"data": {
"text/plain": [
"{'__node__': 12,\n",
1 year ago
" '__cell__': 6,\n",
" '__fork__': 6,\n",
" '__io__': 4,\n",
" '__line__': 12,\n",
" 'DFFX1': 1,\n",
1 year ago
" '__dff__': 1,\n",
" 'ADDFX1': 1,\n",
" '__comb__': 1,\n",
" 'input': 3,\n",
" 'output': 1,\n",
1 year ago
" '__latch__': 0,\n",
" '__seq__': 1}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.stats"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
1 year ago
"outputs": [
{
"data": {
"text/plain": [
"{'__node__': 21538,\n",
" '__cell__': 10789,\n",
" '__fork__': 10749,\n",
" '__io__': 111,\n",
" '__line__': 32032,\n",
" 'TIEH_RVT': 1,\n",
" '__comb__': 10261,\n",
" 'NBUFFX4_RVT': 114,\n",
" 'NBUFFX2_RVT': 371,\n",
" 'INVX2_RVT': 27,\n",
" 'NBUFFX8_RVT': 40,\n",
" 'INVX0_RVT': 769,\n",
" 'AND2X1_RVT': 996,\n",
" 'OR2X1_RVT': 1087,\n",
" 'OR2X2_RVT': 8,\n",
" 'INVX8_RVT': 30,\n",
" 'NOR2X2_RVT': 20,\n",
" 'INVX4_RVT': 36,\n",
" 'AND2X2_RVT': 50,\n",
" 'SDFFARX1_RVT': 412,\n",
" '__dff__': 417,\n",
" 'NAND2X0_RVT': 6596,\n",
" 'NOR2X0_RVT': 74,\n",
" 'NOR2X1_RVT': 15,\n",
" 'NAND2X1_RVT': 3,\n",
" 'NOR2X4_RVT': 5,\n",
" 'NAND2X2_RVT': 9,\n",
" 'SDFFARX2_RVT': 5,\n",
" 'NAND2X4_RVT': 3,\n",
" 'AND2X4_RVT': 1,\n",
" 'INVX32_RVT': 4,\n",
" 'INVX16_RVT': 1,\n",
" 'NBUFFX32_RVT': 1,\n",
" 'output': 71,\n",
" 'input': 40,\n",
" '__latch__': 0,\n",
" '__seq__': 417}"
]
},
1 year ago
"execution_count": 6,
1 year ago
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b15.stats"
]
},
1 year ago
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The `.dot()` function shows the graph structure for small circuits. This requires the `graphviz` package."
1 year ago
]
},
1 year ago
{
"cell_type": "code",
1 year ago
"execution_count": 7,
1 year ago
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.30.1 (20201013.1554)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"734pt\" height=\"365pt\"\n",
" viewBox=\"0.00 0.00 734.00 365.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 361)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-361 731,-361 731,5 -4,5\"/>\n",
"<!-- 0 -->\n",
"<g id=\"node1\" class=\"node\"><title>0</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"0,-72.5 0,-125.5 104,-125.5 104,-72.5 0,-72.5\"/>\n",
"<text text-anchor=\"middle\" x=\"11.5\" y=\"-108.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"0,-99.5 23,-99.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"11.5\" y=\"-82.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"23,-72.5 23,-125.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"52\" y=\"-110.3\" font-family=\"Times,serif\" font-size=\"14.00\">0 [4]</text>\n",
"<text text-anchor=\"middle\" x=\"52\" y=\"-95.3\" font-family=\"Times,serif\" font-size=\"14.00\">DFFX1</text>\n",
"<text text-anchor=\"middle\" x=\"52\" y=\"-80.3\" font-family=\"Times,serif\" font-size=\"14.00\">carry</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"81,-72.5 81,-125.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"92.5\" y=\"-95.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node5\" class=\"node\"><title>1</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"148.5,-159.5 148.5,-212.5 259.5,-212.5 259.5,-159.5 148.5,-159.5\"/>\n",
"<text text-anchor=\"middle\" x=\"160\" y=\"-182.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"171.5,-159.5 171.5,-212.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-197.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-182.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-167.3\" font-family=\"Times,serif\" font-size=\"14.00\">cin</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"236.5,-159.5 236.5,-212.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"248\" y=\"-182.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>0:o0&#45;&gt;1:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M104,-99C133.937,-99 126.647,-129.018 148,-150 149.143,-151.123 150.465,-151.784 151.804,-152.244\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"149.805,-155.117 160,-158 153.828,-149.389 149.805,-155.117\"/>\n",
"<text text-anchor=\"middle\" x=\"126\" y=\"-120.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g id=\"node2\" class=\"node\"><title>5</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"8.5,-0.5 8.5,-53.5 95.5,-53.5 95.5,-0.5 8.5,-0.5\"/>\n",
"<text text-anchor=\"middle\" x=\"18.5\" y=\"-23.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"28.5,-0.5 28.5,-53.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-38.3\" font-family=\"Times,serif\" font-size=\"14.00\">5 [0]</text>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-23.3\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-8.3\" font-family=\"Times,serif\" font-size=\"14.00\">clk</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"72.5,-0.5 72.5,-53.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"84\" y=\"-23.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g id=\"node6\" class=\"node\"><title>6</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"148.5,-87.5 148.5,-140.5 259.5,-140.5 259.5,-87.5 148.5,-87.5\"/>\n",
"<text text-anchor=\"middle\" x=\"160\" y=\"-110.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"171.5,-87.5 171.5,-140.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-125.3\" font-family=\"Times,serif\" font-size=\"14.00\">6</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-110.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-95.3\" font-family=\"Times,serif\" font-size=\"14.00\">clk</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"236.5,-87.5 236.5,-140.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"248\" y=\"-110.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;6 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>5:o0&#45;&gt;6:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M97,-27C131.765,-27 155.26,-43.9502 159.359,-75.6805\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"155.887,-76.2361 160,-86 162.874,-75.8023 155.887,-76.2361\"/>\n",
"<text text-anchor=\"middle\" x=\"126\" y=\"-37.8\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 7 -->\n",
"<g id=\"node3\" class=\"node\"><title>7</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"8.5,-303.5 8.5,-356.5 95.5,-356.5 95.5,-303.5 8.5,-303.5\"/>\n",
"<text text-anchor=\"middle\" x=\"18.5\" y=\"-326.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"28.5,-303.5 28.5,-356.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-341.3\" font-family=\"Times,serif\" font-size=\"14.00\">7 [1]</text>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-326.3\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-311.3\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"72.5,-303.5 72.5,-356.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"84\" y=\"-326.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 8 -->\n",
"<g id=\"node7\" class=\"node\"><title>8</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"148.5,-303.5 148.5,-356.5 259.5,-356.5 259.5,-303.5 148.5,-303.5\"/>\n",
"<text text-anchor=\"middle\" x=\"160\" y=\"-326.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"171.5,-303.5 171.5,-356.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-341.3\" font-family=\"Times,serif\" font-size=\"14.00\">8</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-326.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-311.3\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"236.5,-303.5 236.5,-356.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"248\" y=\"-326.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;8 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>7:o0&#45;&gt;8:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M97,-330C115.771,-330 122.883,-330 137.646,-330\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"138,-333.5 148,-330 138,-326.5 138,-333.5\"/>\n",
"<text text-anchor=\"middle\" x=\"126\" y=\"-333.8\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 9 -->\n",
"<g id=\"node4\" class=\"node\"><title>9</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"8.5,-231.5 8.5,-284.5 95.5,-284.5 95.5,-231.5 8.5,-231.5\"/>\n",
"<text text-anchor=\"middle\" x=\"18.5\" y=\"-254.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"28.5,-231.5 28.5,-284.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-269.3\" font-family=\"Times,serif\" font-size=\"14.00\">9 [2]</text>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-254.3\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"50.5\" y=\"-239.3\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"72.5,-231.5 72.5,-284.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"84\" y=\"-254.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 10 -->\n",
"<g id=\"node8\" class=\"node\"><title>10</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"148.5,-231.5 148.5,-284.5 259.5,-284.5 259.5,-231.5 148.5,-231.5\"/>\n",
"<text text-anchor=\"middle\" x=\"160\" y=\"-254.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"171.5,-231.5 171.5,-284.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-269.3\" font-family=\"Times,serif\" font-size=\"14.00\">10</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-254.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"204\" y=\"-239.3\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"236.5,-231.5 236.5,-284.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"248\" y=\"-254.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 9&#45;&gt;10 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>9:o0&#45;&gt;10:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M97,-258C115.771,-258 122.883,-258 137.646,-258\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"138,-261.5 148,-258 138,-254.5 138,-261.5\"/>\n",
"<text text-anchor=\"middle\" x=\"126\" y=\"-261.8\" font-family=\"Times,serif\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node9\" class=\"node\"><title>2</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"310,-189.5 310,-258.5 426,-258.5 426,-189.5 310,-189.5\"/>\n",
"<text text-anchor=\"middle\" x=\"321.5\" y=\"-243.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"310,-235.5 333,-235.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"321.5\" y=\"-220.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"310,-212.5 333,-212.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"321.5\" y=\"-197.3\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"333,-189.5 333,-258.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"368\" y=\"-235.3\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"<text text-anchor=\"middle\" x=\"368\" y=\"-220.3\" font-family=\"Times,serif\" font-size=\"14.00\">ADDFX1</text>\n",
"<text text-anchor=\"middle\" x=\"368\" y=\"-205.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"403,-189.5 403,-258.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"414.5\" y=\"-237.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"403,-224.5 426,-224.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"414.5\" y=\"-203.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;2 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>1:o0&#45;&gt;2:i2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M260,-186C279.394,-186 285.091,-196.482 299.991,-199.921\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"299.683,-203.408 310,-201 300.433,-196.449 299.683,-203.408\"/>\n",
"<text text-anchor=\"middle\" x=\"285\" y=\"-199.8\" font-family=\"Times,serif\" font-size=\"14.00\">10</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;0 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>6:o0&#45;&gt;0:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"1,5\" d=\"M248,-142C248,-153.647 63.2922,-143.321 20.0013,-131.664\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"21.4891,-128.493 11,-127 18.2685,-134.708 21.4891,-128.493\"/>\n",
"<text text-anchor=\"middle\" x=\"126\" y=\"-147.8\" font-family=\"Times,serif\" font-size=\"14.00\">7</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;2 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>8:o0&#45;&gt;2:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M260,-330C297.72,-330 317.449,-305.993 320.562,-270.351\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"324.074,-270.139 321,-260 317.08,-269.843 324.074,-270.139\"/>\n",
"<text text-anchor=\"middle\" x=\"285\" y=\"-330.8\" font-family=\"Times,serif\" font-size=\"14.00\">8</text>\n",
"</g>\n",
"<!-- 10&#45;&gt;2 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>10:o0&#45;&gt;2:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M260,-258C282.884,-258 283.564,-233.345 299.857,-226.025\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"300.879,-229.39 310,-224 299.508,-222.526 300.879,-229.39\"/>\n",
"<text text-anchor=\"middle\" x=\"285\" y=\"-252.8\" font-family=\"Times,serif\" font-size=\"14.00\">9</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node10\" class=\"node\"><title>3</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"470.5,-215.5 470.5,-268.5 581.5,-268.5 581.5,-215.5 470.5,-215.5\"/>\n",
"<text text-anchor=\"middle\" x=\"482\" y=\"-238.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"493.5,-215.5 493.5,-268.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"526\" y=\"-253.3\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"<text text-anchor=\"middle\" x=\"526\" y=\"-238.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"526\" y=\"-223.3\" font-family=\"Times,serif\" font-size=\"14.00\">cout</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"558.5,-215.5 558.5,-268.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"570\" y=\"-238.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>2:o0&#45;&gt;3:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M426,-242C441.583,-242 447.853,-242 459.653,-242\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"460,-245.5 470,-242 460,-238.5 460,-245.5\"/>\n",
"<text text-anchor=\"middle\" x=\"448\" y=\"-245.8\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node11\" class=\"node\"><title>4</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"470.5,-143.5 470.5,-196.5 581.5,-196.5 581.5,-143.5 470.5,-143.5\"/>\n",
"<text text-anchor=\"middle\" x=\"482\" y=\"-166.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"493.5,-143.5 493.5,-196.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"526\" y=\"-181.3\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
"<text text-anchor=\"middle\" x=\"526\" y=\"-166.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"526\" y=\"-151.3\" font-family=\"Times,serif\" font-size=\"14.00\">s</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"558.5,-143.5 558.5,-196.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"570\" y=\"-166.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;4 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>2:o1&#45;&gt;4:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M426,-207C447.558,-207 445.871,-180.659 460.165,-172.428\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"461.13,-175.795 470,-170 459.453,-168.999 461.13,-175.795\"/>\n",
"<text text-anchor=\"middle\" x=\"448\" y=\"-198.8\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;0 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>3:o0&#45;&gt;0:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"1,5\" d=\"M570,-214C570,-202.853 479.517,-211.803 470,-206 457.048,-198.102 463.144,-187.292 452,-177 381.469,-111.86 352.85,-102.427 260,-78 192.899,-60.3466 173.364,-73.7065 104,-72 95.808,-71.7985 42.1297,-64.7898 20.2546,-67.0491\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"18.8227,-63.8547 11,-71 21.5712,-70.2926 18.8227,-63.8547\"/>\n",
"<text text-anchor=\"middle\" x=\"285\" y=\"-89.8\" font-family=\"Times,serif\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 11 -->\n",
"<g id=\"node12\" class=\"node\"><title>11</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"632,-143.5 632,-196.5 726,-196.5 726,-143.5 632,-143.5\"/>\n",
"<text text-anchor=\"middle\" x=\"643.5\" y=\"-166.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"655,-143.5 655,-196.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"680.5\" y=\"-181.3\" font-family=\"Times,serif\" font-size=\"14.00\">11 [3]</text>\n",
"<text text-anchor=\"middle\" x=\"680.5\" y=\"-166.3\" font-family=\"Times,serif\" font-size=\"14.00\">output</text>\n",
"<text text-anchor=\"middle\" x=\"680.5\" y=\"-151.3\" font-family=\"Times,serif\" font-size=\"14.00\">s</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"706,-143.5 706,-196.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"716\" y=\"-166.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"</g>\n",
"<!-- 4&#45;&gt;11 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>4:o0&#45;&gt;11:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M582,-170C600.403,-170 607.376,-170 621.849,-170\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"622,-173.5 632,-170 622,-166.5 622,-173.5\"/>\n",
"<text text-anchor=\"middle\" x=\"607\" y=\"-173.8\" font-family=\"Times,serif\" font-size=\"14.00\">11</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
1 year ago
"text/plain": [
"<graphviz.graphs.Digraph at 0x7fba1600e6e0>"
1 year ago
]
},
1 year ago
"execution_count": 7,
1 year ago
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.dot()"
1 year ago
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The rectangles are called _nodes_.\n",
"Every node has an _index_ (top-middle number), a _kind_ or type (string in the middle), and a _name_ (bottom-most string).\n",
"Nodes have numeric input pins on the left and numeric output pins on the right.\n",
"The pins are connected by directional _lines_.\n",
"Lines are 1-to-1 connections and also have an _index_.\n",
"\n",
"Some nodes have an additional number in brackets. These are primary inputs, primary outputs (_io_nodes_) or sequential nodes (flip-flops, _s_nodes_).\n",
"The number is the position of their corresponding data in test vectors.\n",
"\n",
"The graph above is topologically sorted with primary inputs and flip-flops on the left.\n",
"Lines that follow the sorting are shown as solid, lines back to the flip-flops are shown as dotted.\n",
"\n",
"Let's explore the components in more detail:\n",
"\n",
"### Cells and Forks\n",
"\n",
"Circuits contain `cells` and `forks` dictionaries that map names to `Node`-objects."
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'carry': 0:DFFX1\"carry\" <7 <6 >0,\n",
" 'adder': 2:ADDFX1\"adder\" <8 <9 <10 >1 >2,\n",
" 'clk': 5:input\"clk\" >3,\n",
" 'a': 7:input\"a\" >4,\n",
" 'b': 9:input\"b\" >5,\n",
" 's': 11:output\"s\" <11}"
]
},
1 year ago
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'cin': 1:__fork__\"cin\" <0 >10,\n",
" 'cout': 3:__fork__\"cout\" <1 >6,\n",
" 's': 4:__fork__\"s\" <2 >11,\n",
" 'clk': 6:__fork__\"clk\" <3 >7,\n",
" 'a': 8:__fork__\"a\" <4 >8,\n",
" 'b': 10:__fork__\"b\" <5 >9}"
]
},
1 year ago
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.forks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"Access any cell or fork by name using a simple dictionary lookup:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"2:ADDFX1\"adder\" <8 <9 <10 >1 >2"
]
},
1 year ago
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells['adder']"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"3:__fork__\"cout\" <1 >6"
]
},
1 year ago
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.forks['cout']"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Cells and forks are instances of class `Node`, which represent *things* that are connected to one or more other *things* in the circuit.\n",
"\n",
"* A **cell** represents a gate or a standard cell.\n",
"* A **fork** represents a named signal or a fan-out point (connecting the output of one cell to multiple other cells or forks).\n",
"\n",
"`Node`-objects have an `index`, a `kind`, and a `name`."
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(11, 'output', 's')"
]
},
1 year ago
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells['s'].index, adder.cells['s'].kind, adder.cells['s'].name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Forks* are `Node`-objects of the special kind `__fork__`.\n",
"\n",
1 year ago
"*Cells* are `Node`-objects of any other kind. A *kind* is just a string and can be anything.\n",
"\n",
"The namespaces of *forks* and *cells* are separate:\n",
"* A *cell* and a *fork* **can** have the same name.\n",
"* Two *cells* or two *forks* **cannot** have the same name."
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(4, '__fork__', 's')"
]
},
1 year ago
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.forks['s'].index, adder.forks['s'].kind, adder.forks['s'].name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"The `index` of a *node* in a circuit is a unique and consecutive integer.\n",
"\n",
1 year ago
"Although *Forks* and *cells* can have the same name, they all have separate indices.\n",
"\n",
"Nodes can be accessed by their index using the `nodes` list:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0:DFFX1\"carry\" <7 <6 >0,\n",
" 1:__fork__\"cin\" <0 >10,\n",
" 2:ADDFX1\"adder\" <8 <9 <10 >1 >2,\n",
" 3:__fork__\"cout\" <1 >6,\n",
" 4:__fork__\"s\" <2 >11,\n",
" 5:input\"clk\" >3,\n",
" 6:__fork__\"clk\" <3 >7,\n",
" 7:input\"a\" >4,\n",
" 8:__fork__\"a\" <4 >8,\n",
" 9:input\"b\" >5,\n",
" 10:__fork__\"b\" <5 >9,\n",
" 11:output\"s\" <11]"
]
},
1 year ago
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.nodes"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 15,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(4:__fork__\"s\" <2 >11, 11:output\"s\" <11)"
]
},
1 year ago
"execution_count": 15,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.nodes[4], adder.nodes[11]"
]
},
1 year ago
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A common use for the index is to store additional data for nodes. Since the index is positive, unique, and consecutive, it can be easily used with external arrays or lists.\n",
"\n",
"This is how you store an additional \"weight\" for each node in the circuit:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 16,
1 year ago
"metadata": {},
"outputs": [],
"source": [
"weights = [0] * len(adder.nodes)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Use the node instance to index into the external list. This also works with numpy arrays, of course."
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 17,
1 year ago
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"weights[adder.cells['s']] = 5"
1 year ago
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 18,
1 year ago
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5]"
1 year ago
]
},
1 year ago
"execution_count": 18,
1 year ago
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"weights"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Lines\n",
"\n",
"A `Line` is a directional 1:1 connection between two Nodes.\n",
"\n",
"A line has a circuit-unique and consecutive `index` just like nodes.\n",
"\n",
"Line and node indices are different!\n",
"\n",
"There is a `lines` list. If a line is printed, it just outputs its index:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11]"
]
},
1 year ago
"execution_count": 19,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.lines"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A line one `driver`-node and one `reader`-node:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(2:ADDFX1\"adder\" <8 <9 <10 >1 >2, 4:__fork__\"s\" <2 >11)"
]
},
1 year ago
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.lines[2].driver, adder.lines[2].reader"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Nodes show their connections to the lines with direction (\"<\" for input, \">\" for output) and the line index.\n",
"\n",
"In the example above, line 2 connects the output of cell \"axb\" to the input of fork \"axb\".\n",
"\n",
"The input connections and output connections of a node are ordered lists of lines called `ins` and `outs`:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([8, 9, 10], [1, 2])"
]
},
1 year ago
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells['adder'].ins, adder.cells['adder'].outs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"A line also stores its positions in the connection lists in `driver_pin` and `reader_pin`:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0, 1)"
]
},
1 year ago
"execution_count": 22,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.lines[9].driver_pin, adder.lines[9].reader_pin"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### IO_Nodes\n",
"\n",
"Any node in the circuit can be designated as a primary input or primary output by adding it to the `io_nodes` list:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[5:input\"clk\" >3, 7:input\"a\" >4, 9:input\"b\" >5, 11:output\"s\" <11]"
]
},
1 year ago
"execution_count": 23,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.io_nodes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"It is common that io_nodes either have only output connections (in a role as primary-input) or only input connections (in a role as primary-output).\n",
"\n",
"Inputs and outputs appear in the order they were defined in the loaded file. Inputs and outputs are often interspersed.\n",
"\n",
"A related list is `s_nodes`. It contains the io_nodes at the beginning and adds all sequential elements (flip-flops, latches)."
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[5:input\"clk\" >3,\n",
" 7:input\"a\" >4,\n",
" 9:input\"b\" >5,\n",
" 11:output\"s\" <11,\n",
" 0:DFFX1\"carry\" <7 <6 >0]"
]
},
1 year ago
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.s_nodes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### Basic Circuit Navigation\n",
"\n",
"A circuit can be traversed easily using the properties of `Circuit`, `Node`, and `Line`."
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 25,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"8:__fork__\"a\" <4 >8"
]
},
1 year ago
"execution_count": 25,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.io_nodes[1].outs[0].reader"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 26,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"3:__fork__\"cout\" <1 >6\n",
"4:__fork__\"s\" <2 >11\n"
]
}
],
"source": [
"for line in adder.cells['adder'].outs:\n",
" print(line.reader)"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'adder'"
]
},
1 year ago
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.forks['cout'].ins[0].driver.name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"Let's continue with `b15` loaded before. It has 111 io_nodes:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"({name: \"b15\", cells: 10789, forks: 10749, lines: 32032, io_nodes: 111},\n",
" [21386:output\"BE_n[3]\" <31961,\n",
" 21387:output\"BE_n[2]\" <31962,\n",
" 21388:output\"BE_n[1]\" <31963,\n",
" 21389:output\"BE_n[0]\" <31964,\n",
" 21390:output\"Address[29]\" <31965,\n",
" 21391:output\"Address[28]\" <31966,\n",
" 21392:output\"Address[27]\" <31967,\n",
" 21393:output\"Address[26]\" <31968,\n",
" 21394:output\"Address[25]\" <31969,\n",
" 21395:output\"Address[24]\" <31970,\n",
" 21396:output\"Address[23]\" <31971,\n",
" 21397:output\"Address[22]\" <31972,\n",
" 21398:output\"Address[21]\" <31973,\n",
" 21399:output\"Address[20]\" <31974,\n",
" 21400:output\"Address[19]\" <31975,\n",
" 21401:output\"Address[18]\" <31976,\n",
" 21402:output\"Address[17]\" <31977,\n",
" 21403:output\"Address[16]\" <31978,\n",
" 21404:output\"Address[15]\" <31979,\n",
" 21405:output\"Address[14]\" <31980])"
]
},
1 year ago
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"b15, b15.io_nodes[:20]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and even more sequential nodes:"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"528"
]
},
1 year ago
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"len(b15.s_nodes)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"The `.io_locs(prefix)` and `.s_locs(prefix)` methods return the locations of signals, busses and registers in `io_nodes` and `s_nodes`. :"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"107"
]
},
1 year ago
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"b15.io_locs('RESET')"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"[33,\n",
" 32,\n",
" 31,\n",
" 30,\n",
" 29,\n",
" 28,\n",
" 27,\n",
" 26,\n",
" 25,\n",
" 24,\n",
" 23,\n",
" 22,\n",
" 21,\n",
" 20,\n",
" 19,\n",
" 18,\n",
" 17,\n",
" 16,\n",
" 15,\n",
" 14,\n",
" 13,\n",
" 12,\n",
" 11,\n",
" 10,\n",
" 9,\n",
" 8,\n",
" 7,\n",
" 6,\n",
" 5,\n",
" 4]"
]
},
1 year ago
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"b15.io_locs('Address')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Example of a two-dimensional register file (16 8-bit registers):"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 32,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"[[349, 348, 350, 347, 351, 346, 352, 345],\n",
" [357, 356, 358, 355, 359, 354, 360, 353],\n",
" [365, 364, 366, 363, 367, 362, 368, 361],\n",
" [373, 372, 374, 371, 375, 370, 376, 369],\n",
" [381, 380, 382, 379, 383, 378, 384, 377],\n",
" [389, 388, 390, 387, 391, 386, 392, 385],\n",
" [397, 396, 398, 395, 399, 394, 400, 393],\n",
" [405, 404, 406, 403, 407, 402, 408, 401],\n",
" [413, 412, 414, 411, 415, 410, 416, 409],\n",
" [421, 420, 422, 419, 423, 418, 424, 417],\n",
" [429, 428, 430, 427, 431, 426, 432, 425],\n",
" [437, 436, 438, 435, 439, 434, 440, 433],\n",
" [445, 444, 446, 443, 447, 442, 448, 441],\n",
" [453, 452, 454, 451, 455, 450, 456, 449],\n",
" [461, 460, 462, 459, 463, 458, 464, 457],\n",
" [469, 468, 470, 467, 471, 466, 472, 465]]"
]
},
1 year ago
"execution_count": 32,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"b15.s_locs('InstQueue_reg')"
]
},
{
"cell_type": "code",
1 year ago
"execution_count": 33,
1 year ago
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"---------------\n",
1 year ago
"1385:SDFFARX1_RVT\"InstQueue_reg_0__0_\" <12704 <12707 <12708 <12706 <12705 >702\n",
"1383:SDFFARX1_RVT\"InstQueue_reg_0__1_\" <12699 <12702 <12703 <12701 <12700 >701\n",
"1387:SDFFARX1_RVT\"InstQueue_reg_0__2_\" <12709 <12712 <12713 <12711 <12710 >703\n",
"1381:SDFFARX1_RVT\"InstQueue_reg_0__3_\" <12694 <12697 <12698 <12696 <12695 >700\n",
"1389:SDFFARX1_RVT\"InstQueue_reg_0__4_\" <12714 <12717 <12718 <12716 <12715 >704\n",
"1379:SDFFARX1_RVT\"InstQueue_reg_0__5_\" <12689 <12692 <12693 <12691 <12690 >699\n",
"1391:SDFFARX1_RVT\"InstQueue_reg_0__6_\" <12719 <12722 <12723 <12721 <12720 >705\n",
"1377:SDFFARX1_RVT\"InstQueue_reg_0__7_\" <12684 <12687 <12688 <12686 <12685 >698\n",
1 year ago
"---------------\n",
1 year ago
"1401:SDFFARX1_RVT\"InstQueue_reg_1__0_\" <12744 <12747 <12748 <12746 <12745 >710\n",
"1399:SDFFARX1_RVT\"InstQueue_reg_1__1_\" <12739 <12742 <12743 <12741 <12740 >709\n",
"1403:SDFFARX1_RVT\"InstQueue_reg_1__2_\" <12749 <12752 <12753 <12751 <12750 >711\n",
"1397:SDFFARX1_RVT\"InstQueue_reg_1__3_\" <12734 <12737 <12738 <12736 <12735 >708\n",
"1405:SDFFARX1_RVT\"InstQueue_reg_1__4_\" <12754 <12757 <12758 <12756 <12755 >712\n",
"1395:SDFFARX1_RVT\"InstQueue_reg_1__5_\" <12729 <12732 <12733 <12731 <12730 >707\n",
"1407:SDFFARX1_RVT\"InstQueue_reg_1__6_\" <12759 <12762 <12763 <12761 <12760 >713\n",
"1393:SDFFARX1_RVT\"InstQueue_reg_1__7_\" <12724 <12727 <12728 <12726 <12725 >706\n",
1 year ago
"---------------\n",
1 year ago
"1417:SDFFARX1_RVT\"InstQueue_reg_2__0_\" <12784 <12787 <12788 <12786 <12785 >718\n",
"1415:SDFFARX1_RVT\"InstQueue_reg_2__1_\" <12779 <12782 <12783 <12781 <12780 >717\n",
"1419:SDFFARX1_RVT\"InstQueue_reg_2__2_\" <12789 <12792 <12793 <12791 <12790 >719\n",
"1413:SDFFARX1_RVT\"InstQueue_reg_2__3_\" <12774 <12777 <12778 <12776 <12775 >716\n",
"1421:SDFFARX1_RVT\"InstQueue_reg_2__4_\" <12794 <12797 <12798 <12796 <12795 >720\n",
"1411:SDFFARX1_RVT\"InstQueue_reg_2__5_\" <12769 <12772 <12773 <12771 <12770 >715\n",
"1423:SDFFARX1_RVT\"InstQueue_reg_2__6_\" <12799 <12802 <12803 <12801 <12800 >721\n",
"1409:SDFFARX1_RVT\"InstQueue_reg_2__7_\" <12764 <12767 <12768 <12766 <12765 >714\n",
1 year ago
"---------------\n",
1 year ago
"1433:SDFFARX1_RVT\"InstQueue_reg_3__0_\" <12824 <12827 <12828 <12826 <12825 >726\n",
"1431:SDFFARX1_RVT\"InstQueue_reg_3__1_\" <12819 <12822 <12823 <12821 <12820 >725\n",
"1435:SDFFARX1_RVT\"InstQueue_reg_3__2_\" <12829 <12832 <12833 <12831 <12830 >727\n",
"1429:SDFFARX1_RVT\"InstQueue_reg_3__3_\" <12814 <12817 <12818 <12816 <12815 >724\n",
"1437:SDFFARX1_RVT\"InstQueue_reg_3__4_\" <12834 <12837 <12838 <12836 <12835 >728\n",
"1427:SDFFARX1_RVT\"InstQueue_reg_3__5_\" <12809 <12812 <12813 <12811 <12810 >723\n",
"1439:SDFFARX1_RVT\"InstQueue_reg_3__6_\" <12839 <12842 <12843 <12841 <12840 >729\n",
"1425:SDFFARX1_RVT\"InstQueue_reg_3__7_\" <12804 <12807 <12808 <12806 <12805 >722\n",
1 year ago
"---------------\n",
1 year ago
"1449:SDFFARX1_RVT\"InstQueue_reg_4__0_\" <12864 <12867 <12868 <12866 <12865 >734\n",
"1447:SDFFARX1_RVT\"InstQueue_reg_4__1_\" <12859 <12862 <12863 <12861 <12860 >733\n",
"1451:SDFFARX1_RVT\"InstQueue_reg_4__2_\" <12869 <12872 <12873 <12871 <12870 >735\n",
"1445:SDFFARX1_RVT\"InstQueue_reg_4__3_\" <12854 <12857 <12858 <12856 <12855 >732\n",
"1453:SDFFARX1_RVT\"InstQueue_reg_4__4_\" <12874 <12877 <12878 <12876 <12875 >736\n",
"1443:SDFFARX1_RVT\"InstQueue_reg_4__5_\" <12849 <12852 <12853 <12851 <12850 >731\n",
"1455:SDFFARX1_RVT\"InstQueue_reg_4__6_\" <12879 <12882 <12883 <12881 <12880 >737\n",
"1441:SDFFARX1_RVT\"InstQueue_reg_4__7_\" <12844 <12847 <12848 <12846 <12845 >730\n",
1 year ago
"---------------\n",
1 year ago
"1465:SDFFARX1_RVT\"InstQueue_reg_5__0_\" <12904 <12907 <12908 <12906 <12905 >742\n",
"1463:SDFFARX1_RVT\"InstQueue_reg_5__1_\" <12899 <12902 <12903 <12901 <12900 >741\n",
"1467:SDFFARX1_RVT\"InstQueue_reg_5__2_\" <12909 <12912 <12913 <12911 <12910 >743\n",
"1461:SDFFARX1_RVT\"InstQueue_reg_5__3_\" <12894 <12897 <12898 <12896 <12895 >740\n",
"1469:SDFFARX1_RVT\"InstQueue_reg_5__4_\" <12914 <12917 <12918 <12916 <12915 >744\n",
"1459:SDFFARX1_RVT\"InstQueue_reg_5__5_\" <12889 <12892 <12893 <12891 <12890 >739\n",
"1471:SDFFARX1_RVT\"InstQueue_reg_5__6_\" <12919 <12922 <12923 <12921 <12920 >745\n",
"1457:SDFFARX1_RVT\"InstQueue_reg_5__7_\" <12884 <12887 <12888 <12886 <12885 >738\n",
1 year ago
"---------------\n",
1 year ago
"1481:SDFFARX1_RVT\"InstQueue_reg_6__0_\" <12944 <12947 <12948 <12946 <12945 >750\n",
"1479:SDFFARX1_RVT\"InstQueue_reg_6__1_\" <12939 <12942 <12943 <12941 <12940 >749\n",
"1483:SDFFARX1_RVT\"InstQueue_reg_6__2_\" <12949 <12952 <12953 <12951 <12950 >751\n",
"1477:SDFFARX1_RVT\"InstQueue_reg_6__3_\" <12934 <12937 <12938 <12936 <12935 >748\n",
"1485:SDFFARX1_RVT\"InstQueue_reg_6__4_\" <12954 <12957 <12958 <12956 <12955 >752\n",
"1475:SDFFARX1_RVT\"InstQueue_reg_6__5_\" <12929 <12932 <12933 <12931 <12930 >747\n",
"1487:SDFFARX1_RVT\"InstQueue_reg_6__6_\" <12959 <12962 <12963 <12961 <12960 >753\n",
"1473:SDFFARX1_RVT\"InstQueue_reg_6__7_\" <12924 <12927 <12928 <12926 <12925 >746\n",
1 year ago
"---------------\n",
1 year ago
"1497:SDFFARX1_RVT\"InstQueue_reg_7__0_\" <12984 <12987 <12988 <12986 <12985 >758\n",
"1495:SDFFARX1_RVT\"InstQueue_reg_7__1_\" <12979 <12982 <12983 <12981 <12980 >757\n",
"1499:SDFFARX1_RVT\"InstQueue_reg_7__2_\" <12989 <12992 <12993 <12991 <12990 >759\n",
"1493:SDFFARX1_RVT\"InstQueue_reg_7__3_\" <12974 <12977 <12978 <12976 <12975 >756\n",
"1501:SDFFARX1_RVT\"InstQueue_reg_7__4_\" <12994 <12997 <12998 <12996 <12995 >760\n",
"1491:SDFFARX1_RVT\"InstQueue_reg_7__5_\" <12969 <12972 <12973 <12971 <12970 >755\n",
"1503:SDFFARX1_RVT\"InstQueue_reg_7__6_\" <12999 <13002 <13003 <13001 <13000 >761\n",
"1489:SDFFARX1_RVT\"InstQueue_reg_7__7_\" <12964 <12967 <12968 <12966 <12965 >754\n",
1 year ago
"---------------\n",
1 year ago
"1513:SDFFARX1_RVT\"InstQueue_reg_8__0_\" <13024 <13027 <13028 <13026 <13025 >766\n",
"1511:SDFFARX1_RVT\"InstQueue_reg_8__1_\" <13019 <13022 <13023 <13021 <13020 >765\n",
"1515:SDFFARX1_RVT\"InstQueue_reg_8__2_\" <13029 <13032 <13033 <13031 <13030 >767 >768\n",
"1509:SDFFARX1_RVT\"InstQueue_reg_8__3_\" <13014 <13017 <13018 <13016 <13015 >764\n",
"1518:SDFFARX1_RVT\"InstQueue_reg_8__4_\" <13034 <13037 <13038 <13036 <13035 >769\n",
"1507:SDFFARX1_RVT\"InstQueue_reg_8__5_\" <13009 <13012 <13013 <13011 <13010 >763\n",
"1520:SDFFARX1_RVT\"InstQueue_reg_8__6_\" <13039 <13042 <13043 <13041 <13040 >770\n",
"1505:SDFFARX1_RVT\"InstQueue_reg_8__7_\" <13004 <13007 <13008 <13006 <13005 >762\n",
1 year ago
"---------------\n",
1 year ago
"1530:SDFFARX1_RVT\"InstQueue_reg_9__0_\" <13064 <13067 <13068 <13066 <13065 >775\n",
"1528:SDFFARX1_RVT\"InstQueue_reg_9__1_\" <13059 <13062 <13063 <13061 <13060 >774\n",
"1532:SDFFARX1_RVT\"InstQueue_reg_9__2_\" <13069 <13072 <13073 <13071 <13070 >776\n",
"1526:SDFFARX1_RVT\"InstQueue_reg_9__3_\" <13054 <13057 <13058 <13056 <13055 >773\n",
"1534:SDFFARX1_RVT\"InstQueue_reg_9__4_\" <13074 <13077 <13078 <13076 <13075 >777\n",
"1524:SDFFARX1_RVT\"InstQueue_reg_9__5_\" <13049 <13052 <13053 <13051 <13050 >772\n",
"1536:SDFFARX1_RVT\"InstQueue_reg_9__6_\" <13079 <13082 <13083 <13081 <13080 >778\n",
"1522:SDFFARX1_RVT\"InstQueue_reg_9__7_\" <13044 <13047 <13048 <13046 <13045 >771\n",
1 year ago
"---------------\n",
1 year ago
"1546:SDFFARX1_RVT\"InstQueue_reg_10__0_\" <13104 <13107 <13108 <13106 <13105 >783\n",
"1544:SDFFARX1_RVT\"InstQueue_reg_10__1_\" <13099 <13102 <13103 <13101 <13100 >782\n",
"1548:SDFFARX1_RVT\"InstQueue_reg_10__2_\" <13109 <13112 <13113 <13111 <13110 >784\n",
"1542:SDFFARX1_RVT\"InstQueue_reg_10__3_\" <13094 <13097 <13098 <13096 <13095 >781\n",
"1550:SDFFARX1_RVT\"InstQueue_reg_10__4_\" <13114 <13117 <13118 <13116 <13115 >785 >786\n",
"1540:SDFFARX1_RVT\"InstQueue_reg_10__5_\" <13089 <13092 <13093 <13091 <13090 >780\n",
"1553:SDFFARX1_RVT\"InstQueue_reg_10__6_\" <13119 <13122 <13123 <13121 <13120 >787\n",
"1538:SDFFARX1_RVT\"InstQueue_reg_10__7_\" <13084 <13087 <13088 <13086 <13085 >779\n",
1 year ago
"---------------\n",
1 year ago
"1563:SDFFARX1_RVT\"InstQueue_reg_11__0_\" <13144 <13147 <13148 <13146 <13145 >792\n",
"1561:SDFFARX1_RVT\"InstQueue_reg_11__1_\" <13139 <13142 <13143 <13141 <13140 >791\n",
"1565:SDFFARX1_RVT\"InstQueue_reg_11__2_\" <13149 <13152 <13153 <13151 <13150 >793\n",
"1559:SDFFARX1_RVT\"InstQueue_reg_11__3_\" <13134 <13137 <13138 <13136 <13135 >790\n",
"1567:SDFFARX1_RVT\"InstQueue_reg_11__4_\" <13154 <13157 <13158 <13156 <13155 >794\n",
"1557:SDFFARX1_RVT\"InstQueue_reg_11__5_\" <13129 <13132 <13133 <13131 <13130 >789\n",
"1569:SDFFARX1_RVT\"InstQueue_reg_11__6_\" <13159 <13162 <13163 <13161 <13160 >795\n",
"1555:SDFFARX1_RVT\"InstQueue_reg_11__7_\" <13124 <13127 <13128 <13126 <13125 >788\n",
1 year ago
"---------------\n",
1 year ago
"1579:SDFFARX1_RVT\"InstQueue_reg_12__0_\" <13184 <13187 <13188 <13186 <13185 >800\n",
"1577:SDFFARX1_RVT\"InstQueue_reg_12__1_\" <13179 <13182 <13183 <13181 <13180 >799\n",
"1581:SDFFARX1_RVT\"InstQueue_reg_12__2_\" <13189 <13192 <13193 <13191 <13190 >801\n",
"1575:SDFFARX1_RVT\"InstQueue_reg_12__3_\" <13174 <13177 <13178 <13176 <13175 >798\n",
"1583:SDFFARX1_RVT\"InstQueue_reg_12__4_\" <13194 <13197 <13198 <13196 <13195 >802\n",
"1573:SDFFARX1_RVT\"InstQueue_reg_12__5_\" <13169 <13172 <13173 <13171 <13170 >797\n",
"1585:SDFFARX1_RVT\"InstQueue_reg_12__6_\" <13199 <13202 <13203 <13201 <13200 >803\n",
"1571:SDFFARX1_RVT\"InstQueue_reg_12__7_\" <13164 <13167 <13168 <13166 <13165 >796\n",
1 year ago
"---------------\n",
1 year ago
"1595:SDFFARX1_RVT\"InstQueue_reg_13__0_\" <13224 <13227 <13228 <13226 <13225 >808\n",
"1593:SDFFARX1_RVT\"InstQueue_reg_13__1_\" <13219 <13222 <13223 <13221 <13220 >807\n",
"1597:SDFFARX1_RVT\"InstQueue_reg_13__2_\" <13229 <13232 <13233 <13231 <13230 >809\n",
"1591:SDFFARX1_RVT\"InstQueue_reg_13__3_\" <13214 <13217 <13218 <13216 <13215 >806\n",
"1599:SDFFARX1_RVT\"InstQueue_reg_13__4_\" <13234 <13237 <13238 <13236 <13235 >810\n",
"1589:SDFFARX1_RVT\"InstQueue_reg_13__5_\" <13209 <13212 <13213 <13211 <13210 >805\n",
"1601:SDFFARX1_RVT\"InstQueue_reg_13__6_\" <13239 <13242 <13243 <13241 <13240 >811\n",
"1587:SDFFARX1_RVT\"InstQueue_reg_13__7_\" <13204 <13207 <13208 <13206 <13205 >804\n",
1 year ago
"---------------\n",
1 year ago
"1611:SDFFARX1_RVT\"InstQueue_reg_14__0_\" <13264 <13267 <13268 <13266 <13265 >816\n",
"1609:SDFFARX1_RVT\"InstQueue_reg_14__1_\" <13259 <13262 <13263 <13261 <13260 >815\n",
"1613:SDFFARX1_RVT\"InstQueue_reg_14__2_\" <13269 <13272 <13273 <13271 <13270 >817\n",
"1607:SDFFARX1_RVT\"InstQueue_reg_14__3_\" <13254 <13257 <13258 <13256 <13255 >814\n",
"1615:SDFFARX1_RVT\"InstQueue_reg_14__4_\" <13274 <13277 <13278 <13276 <13275 >818\n",
"1605:SDFFARX1_RVT\"InstQueue_reg_14__5_\" <13249 <13252 <13253 <13251 <13250 >813\n",
"1617:SDFFARX1_RVT\"InstQueue_reg_14__6_\" <13279 <13282 <13283 <13281 <13280 >819\n",
"1603:SDFFARX1_RVT\"InstQueue_reg_14__7_\" <13244 <13247 <13248 <13246 <13245 >812\n",
1 year ago
"---------------\n",
1 year ago
"1627:SDFFARX1_RVT\"InstQueue_reg_15__0_\" <13304 <13307 <13308 <13306 <13305 >824\n",
"1625:SDFFARX1_RVT\"InstQueue_reg_15__1_\" <13299 <13302 <13303 <13301 <13300 >823\n",
"1629:SDFFARX1_RVT\"InstQueue_reg_15__2_\" <13309 <13312 <13313 <13311 <13310 >825\n",
"1623:SDFFARX1_RVT\"InstQueue_reg_15__3_\" <13294 <13297 <13298 <13296 <13295 >822\n",
"1631:SDFFARX1_RVT\"InstQueue_reg_15__4_\" <13314 <13317 <13318 <13316 <13315 >826\n",
"1621:SDFFARX1_RVT\"InstQueue_reg_15__5_\" <13289 <13292 <13293 <13291 <13290 >821\n",
"1633:SDFFARX1_RVT\"InstQueue_reg_15__6_\" <13319 <13322 <13323 <13321 <13320 >827\n",
"1619:SDFFARX1_RVT\"InstQueue_reg_15__7_\" <13284 <13287 <13288 <13286 <13285 >820\n"
1 year ago
]
}
],
"source": [
"for l in b15.s_locs('InstQueue_reg'):\n",
" print('---------------')\n",
" for i in l:\n",
" print(b15.s_nodes[i])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"### Example: Tracing A Scan Chain\n",
"\n",
"We start at the output of the scan chain \"test_so000\", then go backwards through the circuit.\n",
"\n",
1 year ago
"When we encounter a scan-cell (\"SDFF...\"), we continue with the \"SI\" pin.\n",
"\n",
"We do this on the original circuit `b15` that still contains the scan-cells themselves."
]
},
{
"cell_type": "code",
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
1 year ago
"length (with forks): 1123\n",
"length (without forks): 562\n",
"length only SDFF: 417\n",
"output\"test_so000\" __fork__\"test_so000\" NBUFFX8_RVT\"ZBUF_15_inst_543\" __fork__\"aps_rename_15_\" SDFFARX1_RVT\"W_R_n_reg\" __fork__\"ZBUF_17_48\" NBUFFX2_RVT\"ZBUF_17_inst_981\" __fork__\"N3897\" SDFFARX1_RVT\"uWord_reg_14_\" __fork__\"N3896\" ... __fork__\"Address[0]\" NBUFFX2_RVT\"ZBUF_19_inst_438\" __fork__\"aps_rename_14_\" SDFFARX1_RVT\"Address_reg_0_\" __fork__\"ADS_n\" NBUFFX2_RVT\"ZBUF_34_inst_547\" __fork__\"aps_rename_18_\" SDFFARX1_RVT\"ADS_n_reg\" __fork__\"test_si000\" input\"test_si000\"\n"
]
}
],
"source": [
1 year ago
"chain = [cell := b15.cells['test_so000']]\n",
"while len(cell.ins) > 0:\n",
1 year ago
" chain.append(cell := cell.ins[SAED32.pin_index(cell.kind,'SI') if cell.kind.startswith('SDFF') else 0].driver)\n",
" \n",
"print(f'length (with forks): {len(chain)}')\n",
"print(f'length (without forks): {len(list(filter(lambda n: n.kind != \"__fork__\", chain)))}')\n",
"print(f'length only SDFF: {len(list(filter(lambda n: n.kind.startswith(\"SDFF\"), chain)))}')\n",
"\n",
"names = [f'{c.kind}\"{c.name}\"' for c in chain]\n",
"print(' '.join(names[:10]) + ' ... ' + ' '.join(names[-10:]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"### Traversing a Circuit in Topological Order\n",
"\n",
"There are several generators to traverse the circuit in various topological orderings.\n",
"\n",
"The following loop prints all nodes:\n",
"* starting with primary inputs (nodes that don't have any input connections) and sequential elements,\n",
"* and continuing with nodes who's inputs are connected only to already printed nodes."
]
},
{
"cell_type": "code",
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0:DFFX1\"carry\" <7 <6 >0\n",
"5:input\"clk\" >3\n",
"7:input\"a\" >4\n",
"9:input\"b\" >5\n",
"1:__fork__\"cin\" <0 >10\n",
"6:__fork__\"clk\" <3 >7\n",
"8:__fork__\"a\" <4 >8\n",
"10:__fork__\"b\" <5 >9\n",
"2:ADDFX1\"adder\" <8 <9 <10 >1 >2\n",
"3:__fork__\"cout\" <1 >6\n",
"4:__fork__\"s\" <2 >11\n",
"11:output\"s\" <11\n"
]
}
],
"source": [
"for n in adder.topological_order():\n",
" print(n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"### Example: Determine Topological Level\n",
"\n",
"The topological (or logic level) of a node is its distance from inputs or sequential elements.\n",
"\n",
"Inputs and flip-flops themselves are level 0, *cells* driven by just inputs and flip-flops are level 1, and so on.\n",
"*Fork* nodes have the same level as their driver, because they do not increase the logic depth."
]
},
{
"cell_type": "code",
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
1 year ago
"Maximum logic depth: 44\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
1 year ago
"levels = np.zeros(len(b15.nodes), dtype=np.uint32) # array to store level for each node.\n",
"\n",
1 year ago
"for n in b15.topological_order():\n",
" if 'DFF' in n.kind or len(n.ins) == 0:\n",
1 year ago
" levels[n] = 0 # use the node n directly to index into the array.\n",
" elif n.kind == '__fork__':\n",
" levels[n] = levels[n.ins[0].driver] # forks only have exactly one driver\n",
" else:\n",
" levels[n] = max([levels[line.driver] for line in n.ins]) + 1\n",
" \n",
"print(f'Maximum logic depth: {np.max(levels)}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"List nodes with the highest depth and which nodes they are driving."
]
},
{
"cell_type": "code",
"execution_count": 37,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
1 year ago
"depth: 44 node: __fork__ n4587 driving: SDFFARX1_RVT EAX_reg_31_ \n",
"depth: 44 node: NAND2X0_RVT U737 driving: __fork__ n4587 \n",
"depth: 43 node: __fork__ n4478 driving: SDFFARX1_RVT Address_reg_29_\n",
"depth: 43 node: NAND2X0_RVT U738 driving: __fork__ n684 \n",
"depth: 43 node: __fork__ n4416 driving: SDFFARX1_RVT PhyAddrPointer_reg_29_\n",
"depth: 43 node: NAND2X0_RVT U220 driving: __fork__ n4416 \n",
"depth: 43 node: NAND2X0_RVT U214 driving: __fork__ n4414 \n",
"depth: 43 node: __fork__ n4414 driving: SDFFARX1_RVT PhyAddrPointer_reg_31_\n",
"depth: 43 node: __fork__ n684 driving: NAND2X0_RVT U737 \n",
"depth: 43 node: NAND2X0_RVT U408 driving: __fork__ n4478 \n",
"depth: 42 node: NAND2X0_RVT U216 driving: __fork__ n332 \n",
"depth: 42 node: __fork__ n4510 driving: SDFFARX1_RVT rEIP_reg_29_ \n",
"depth: 42 node: NAND2X0_RVT U595 driving: __fork__ n4540 \n",
"depth: 42 node: __fork__ n4540 driving: SDFFARX1_RVT EBX_reg_31_ \n",
"depth: 42 node: __fork__ n4588 driving: SDFFARX1_RVT EAX_reg_30_ \n",
"depth: 42 node: __fork__ n332 driving: NAND2X0_RVT U214 \n",
"depth: 42 node: NAND2X0_RVT U222 driving: __fork__ n337 \n",
"depth: 42 node: __fork__ n463 driving: NAND2X0_RVT U408 \n",
"depth: 42 node: __fork__ n4446 driving: SDFFARX1_RVT InstAddrPointer_reg_31_\n",
"depth: 42 node: NAND2X0_RVT U311 driving: __fork__ n4446 \n"
]
}
],
"source": [
"nodes_by_depth = np.argsort(levels)[::-1]\n",
"\n",
"for n_idx in nodes_by_depth[:20]:\n",
1 year ago
" n = b15.nodes[n_idx] # get the node itself by its index\n",
" readers = ', '.join([f'{l.reader.kind:12s} {l.reader.name:14s}' for l in n.outs])\n",
" print(f'depth: {levels[n_idx]} node: {n.kind:12s} {n.name:6s} driving: {readers}')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Working With Technology Libraries\n",
"\n",
"Kyupy's simulators only supports cells with at most 4 inputs and exactly 1 output.\n",
"To map a circuit to the supported simulation primitives, we use `.resolve_tlib_cells()` with the corresponding library."
]
},
{
"cell_type": "code",
"execution_count": 38,
"metadata": {},
"outputs": [],
"source": [
"adder.resolve_tlib_cells(GSC180)"
]
},
{
"cell_type": "code",
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.30.1 (20201013.1554)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"1214pt\" height=\"413pt\"\n",
" viewBox=\"0.00 0.00 1214.00 413.27\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 409.267)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-409.267 1211,-409.267 1211,5 -4,5\"/>\n",
"<!-- 0 -->\n",
"<g id=\"node1\" class=\"node\"><title>0</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"0,-276.143 0,-329.143 90,-329.143 90,-276.143 0,-276.143\"/>\n",
"<text text-anchor=\"middle\" x=\"11.5\" y=\"-312.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"0,-303.143 23,-303.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"11.5\" y=\"-285.943\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"23,-276.143 23,-329.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"45\" y=\"-313.943\" font-family=\"Times,serif\" font-size=\"14.00\">0 [4]</text>\n",
"<text text-anchor=\"middle\" x=\"45\" y=\"-298.943\" font-family=\"Times,serif\" font-size=\"14.00\">DFF</text>\n",
"<text text-anchor=\"middle\" x=\"45\" y=\"-283.943\" font-family=\"Times,serif\" font-size=\"14.00\">carry</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"67,-276.143 67,-329.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"78.5\" y=\"-298.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 12 -->\n",
"<g id=\"node5\" class=\"node\"><title>12</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"140.5,-274.143 140.5,-327.143 251.5,-327.143 251.5,-274.143 140.5,-274.143\"/>\n",
"<text text-anchor=\"middle\" x=\"152\" y=\"-296.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"163.5,-274.143 163.5,-327.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-311.943\" font-family=\"Times,serif\" font-size=\"14.00\">12</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-296.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-281.943\" font-family=\"Times,serif\" font-size=\"14.00\">carry~Q</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"228.5,-274.143 228.5,-327.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"240\" y=\"-296.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;12 -->\n",
"<g id=\"edge13\" class=\"edge\"><title>0:o0&#45;&gt;12:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M90,-302.643C108.417,-302.643 115.369,-301.271 129.844,-300.8\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"130.055,-304.297 140,-300.643 129.947,-297.298 130.055,-304.297\"/>\n",
"<text text-anchor=\"middle\" x=\"115\" y=\"-306.443\" font-family=\"Times,serif\" font-size=\"14.00\">12</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g id=\"node2\" class=\"node\"><title>5</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1.5,-200.143 1.5,-253.143 88.5,-253.143 88.5,-200.143 1.5,-200.143\"/>\n",
"<text text-anchor=\"middle\" x=\"11.5\" y=\"-222.943\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"21.5,-200.143 21.5,-253.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-237.943\" font-family=\"Times,serif\" font-size=\"14.00\">5 [0]</text>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-222.943\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-207.943\" font-family=\"Times,serif\" font-size=\"14.00\">clk</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"65.5,-200.143 65.5,-253.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"77\" y=\"-222.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g id=\"node6\" class=\"node\"><title>6</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"140.5,-201.143 140.5,-254.143 251.5,-254.143 251.5,-201.143 140.5,-201.143\"/>\n",
"<text text-anchor=\"middle\" x=\"152\" y=\"-223.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"163.5,-201.143 163.5,-254.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-238.943\" font-family=\"Times,serif\" font-size=\"14.00\">6</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-223.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-208.943\" font-family=\"Times,serif\" font-size=\"14.00\">clk</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"228.5,-201.143 228.5,-254.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"240\" y=\"-223.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;6 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>5:o0&#45;&gt;6:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M90,-226.643C108.406,-226.643 115.374,-227.329 129.848,-227.565\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"129.973,-231.066 140,-227.643 130.027,-224.066 129.973,-231.066\"/>\n",
"<text text-anchor=\"middle\" x=\"115\" y=\"-231.443\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 7 -->\n",
"<g id=\"node3\" class=\"node\"><title>7</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1.5,-127.143 1.5,-180.143 88.5,-180.143 88.5,-127.143 1.5,-127.143\"/>\n",
"<text text-anchor=\"middle\" x=\"11.5\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"21.5,-127.143 21.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-164.943\" font-family=\"Times,serif\" font-size=\"14.00\">7 [1]</text>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-134.943\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"65.5,-127.143 65.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"77\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 8 -->\n",
"<g id=\"node7\" class=\"node\"><title>8</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"140.5,-127.143 140.5,-180.143 251.5,-180.143 251.5,-127.143 140.5,-127.143\"/>\n",
"<text text-anchor=\"middle\" x=\"152\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"163.5,-127.143 163.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-164.943\" font-family=\"Times,serif\" font-size=\"14.00\">8</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-134.943\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"228.5,-127.143 228.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"240\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;8 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>7:o0&#45;&gt;8:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M90,-153.643C108.403,-153.643 115.376,-153.643 129.849,-153.643\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"130,-157.143 140,-153.643 130,-150.143 130,-157.143\"/>\n",
"<text text-anchor=\"middle\" x=\"115\" y=\"-157.443\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 9 -->\n",
"<g id=\"node4\" class=\"node\"><title>9</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1.5,-50.1431 1.5,-103.143 88.5,-103.143 88.5,-50.1431 1.5,-50.1431\"/>\n",
"<text text-anchor=\"middle\" x=\"11.5\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"21.5,-50.1431 21.5,-103.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-87.9431\" font-family=\"Times,serif\" font-size=\"14.00\">9 [2]</text>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"43.5\" y=\"-57.9431\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"65.5,-50.1431 65.5,-103.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"77\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 10 -->\n",
"<g id=\"node8\" class=\"node\"><title>10</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"140.5,-50.1431 140.5,-103.143 251.5,-103.143 251.5,-50.1431 140.5,-50.1431\"/>\n",
"<text text-anchor=\"middle\" x=\"152\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"163.5,-50.1431 163.5,-103.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-87.9431\" font-family=\"Times,serif\" font-size=\"14.00\">10</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"196\" y=\"-57.9431\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"228.5,-50.1431 228.5,-103.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"240\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 9&#45;&gt;10 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>9:o0&#45;&gt;10:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M90,-76.6431C108.403,-76.6431 115.376,-76.6431 129.849,-76.6431\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"130,-80.1432 140,-76.6431 130,-73.1432 130,-80.1432\"/>\n",
"<text text-anchor=\"middle\" x=\"115\" y=\"-80.4431\" font-family=\"Times,serif\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node9\" class=\"node\"><title>1</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"296.5,-257.143 296.5,-310.143 407.5,-310.143 407.5,-257.143 296.5,-257.143\"/>\n",
"<text text-anchor=\"middle\" x=\"308\" y=\"-279.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"319.5,-257.143 319.5,-310.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-294.943\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-279.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-264.943\" font-family=\"Times,serif\" font-size=\"14.00\">cin</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"384.5,-257.143 384.5,-310.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"396\" y=\"-279.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 12&#45;&gt;1 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>12:o0&#45;&gt;1:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M252,-300.643C269.034,-300.643 273.595,-289.42 285.951,-285.212\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"286.66,-288.644 296,-283.643 285.58,-281.728 286.66,-288.644\"/>\n",
"<text text-anchor=\"middle\" x=\"274\" y=\"-299.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;0 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>6:o0&#45;&gt;0:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"1,5\" d=\"M240,-255.643C240,-261.228 64.6719,-266.699 20.8398,-272.256\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"19.8929,-268.884 11,-274.643 21.5433,-275.687 19.8929,-268.884\"/>\n",
"<text text-anchor=\"middle\" x=\"115\" y=\"-270.443\" font-family=\"Times,serif\" font-size=\"14.00\">7</text>\n",
"</g>\n",
"<!-- 13 -->\n",
"<g id=\"node10\" class=\"node\"><title>13</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"296.5,-127.143 296.5,-180.143 407.5,-180.143 407.5,-127.143 296.5,-127.143\"/>\n",
"<text text-anchor=\"middle\" x=\"308\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"319.5,-127.143 319.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-164.943\" font-family=\"Times,serif\" font-size=\"14.00\">13</text>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-134.943\" font-family=\"Times,serif\" font-size=\"14.00\">adder~A</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"384.5,-127.143 384.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"396\" y=\"-163.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"384.5,-154.143 407.5,-154.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"396\" y=\"-136.943\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;13 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>8:o0&#45;&gt;13:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M252,-153.643C267.583,-153.643 273.853,-153.643 285.653,-153.643\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"286,-157.143 296,-153.643 286,-150.143 286,-157.143\"/>\n",
"<text text-anchor=\"middle\" x=\"274\" y=\"-157.443\" font-family=\"Times,serif\" font-size=\"14.00\">8</text>\n",
"</g>\n",
"<!-- 14 -->\n",
"<g id=\"node11\" class=\"node\"><title>14</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"296.5,-50.1431 296.5,-103.143 407.5,-103.143 407.5,-50.1431 296.5,-50.1431\"/>\n",
"<text text-anchor=\"middle\" x=\"308\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"319.5,-50.1431 319.5,-103.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-87.9431\" font-family=\"Times,serif\" font-size=\"14.00\">14</text>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-72.9431\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"352\" y=\"-57.9431\" font-family=\"Times,serif\" font-size=\"14.00\">adder~B</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"384.5,-50.1431 384.5,-103.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"396\" y=\"-86.4431\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"384.5,-77.1431 407.5,-77.1431 \"/>\n",
"<text text-anchor=\"middle\" x=\"396\" y=\"-59.9431\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 10&#45;&gt;14 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>10:o0&#45;&gt;14:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M252,-76.6431C267.583,-76.6431 273.853,-76.6431 285.653,-76.6431\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"286,-80.1432 296,-76.6431 286,-73.1432 286,-80.1432\"/>\n",
"<text text-anchor=\"middle\" x=\"274\" y=\"-80.4431\" font-family=\"Times,serif\" font-size=\"14.00\">9</text>\n",
"</g>\n",
"<!-- 15 -->\n",
"<g id=\"node12\" class=\"node\"><title>15</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"461,-248.143 461,-301.143 575,-301.143 575,-248.143 461,-248.143\"/>\n",
"<text text-anchor=\"middle\" x=\"472.5\" y=\"-270.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"484,-248.143 484,-301.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"518\" y=\"-285.943\" font-family=\"Times,serif\" font-size=\"14.00\">15</text>\n",
"<text text-anchor=\"middle\" x=\"518\" y=\"-270.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"518\" y=\"-255.943\" font-family=\"Times,serif\" font-size=\"14.00\">adder~CI</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"552,-248.143 552,-301.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"563.5\" y=\"-284.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"552,-275.143 575,-275.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"563.5\" y=\"-257.943\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 1&#45;&gt;15 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>1:o0&#45;&gt;15:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M408,-283.643C427.607,-283.643 434.381,-277.354 449.777,-275.29\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"450.241,-278.768 460,-274.643 449.799,-271.782 450.241,-278.768\"/>\n",
"<text text-anchor=\"middle\" x=\"433\" y=\"-285.443\" font-family=\"Times,serif\" font-size=\"14.00\">10</text>\n",
"</g>\n",
"<!-- 16 -->\n",
"<g id=\"node13\" class=\"node\"><title>16</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"458.5,-127.143 458.5,-180.143 577.5,-180.143 577.5,-127.143 458.5,-127.143\"/>\n",
"<text text-anchor=\"middle\" x=\"470\" y=\"-163.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"458.5,-154.143 481.5,-154.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"470\" y=\"-136.943\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"481.5,-127.143 481.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"518\" y=\"-164.943\" font-family=\"Times,serif\" font-size=\"14.00\">16</text>\n",
"<text text-anchor=\"middle\" x=\"518\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">XOR2</text>\n",
"<text text-anchor=\"middle\" x=\"518\" y=\"-134.943\" font-family=\"Times,serif\" font-size=\"14.00\">adder~AB</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"554.5,-127.143 554.5,-180.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"566\" y=\"-149.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 13&#45;&gt;16 -->\n",
"<g id=\"edge15\" class=\"edge\"><title>13:o0&#45;&gt;16:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M408,-167.643C426.403,-167.643 433.376,-167.643 447.849,-167.643\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"448,-171.143 458,-167.643 448,-164.143 448,-171.143\"/>\n",
"<text text-anchor=\"middle\" x=\"433\" y=\"-171.443\" font-family=\"Times,serif\" font-size=\"14.00\">14</text>\n",
"</g>\n",
"<!-- 18 -->\n",
"<g id=\"node16\" class=\"node\"><title>18</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"798,-86.6431 798,-178.643 906,-178.643 906,-86.6431 798,-86.6431\"/>\n",
"<text text-anchor=\"middle\" x=\"809.5\" y=\"-163.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"798,-155.643 821,-155.643 \"/>\n",
"<text text-anchor=\"middle\" x=\"809.5\" y=\"-140.443\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"798,-132.643 821,-132.643 \"/>\n",
"<text text-anchor=\"middle\" x=\"809.5\" y=\"-117.443\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"798,-109.643 821,-109.643 \"/>\n",
"<text text-anchor=\"middle\" x=\"809.5\" y=\"-94.4431\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"821,-86.6431 821,-178.643 \"/>\n",
"<text text-anchor=\"middle\" x=\"852\" y=\"-143.943\" font-family=\"Times,serif\" font-size=\"14.00\">18</text>\n",
"<text text-anchor=\"middle\" x=\"852\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\">AO22</text>\n",
"<text text-anchor=\"middle\" x=\"852\" y=\"-113.943\" font-family=\"Times,serif\" font-size=\"14.00\">adder~S</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"883,-86.6431 883,-178.643 \"/>\n",
"<text text-anchor=\"middle\" x=\"894.5\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 13&#45;&gt;18 -->\n",
"<g id=\"edge21\" class=\"edge\"><title>13:o1&#45;&gt;18:i2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M396,-125.643C396,-102.922 707.19,-118.971 787.838,-120.525\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"787.96,-124.027 798,-120.643 788.041,-117.027 787.96,-124.027\"/>\n",
"<text text-anchor=\"middle\" x=\"603\" y=\"-119.443\" font-family=\"Times,serif\" font-size=\"14.00\">20</text>\n",
"</g>\n",
"<!-- 14&#45;&gt;16 -->\n",
"<g id=\"edge16\" class=\"edge\"><title>14:o0&#45;&gt;16:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M396,-104.643C396,-110.991 430.312,-130.082 448.282,-137.576\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"447.41,-140.971 458,-140.643 449.517,-134.296 447.41,-140.971\"/>\n",
"<text text-anchor=\"middle\" x=\"433\" y=\"-137.443\" font-family=\"Times,serif\" font-size=\"14.00\">15</text>\n",
"</g>\n",
"<!-- 14&#45;&gt;18 -->\n",
"<g id=\"edge22\" class=\"edge\"><title>14:o1&#45;&gt;18:i3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M408,-63.6431C583.004,-63.6431 800.325,86.794 808.747,-75.5643\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"805.25,-75.734 809,-85.6431 812.248,-75.5585 805.25,-75.734\"/>\n",
"<text text-anchor=\"middle\" x=\"603\" y=\"-32.4431\" font-family=\"Times,serif\" font-size=\"14.00\">21</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node15\" class=\"node\"><title>2</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"803.5,-275.143 803.5,-328.143 900.5,-328.143 900.5,-275.143 803.5,-275.143\"/>\n",
"<text text-anchor=\"middle\" x=\"815\" y=\"-311.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"803.5,-302.143 826.5,-302.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"815\" y=\"-284.943\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"826.5,-275.143 826.5,-328.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"852\" y=\"-312.943\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"<text text-anchor=\"middle\" x=\"852\" y=\"-297.943\" font-family=\"Times,serif\" font-size=\"14.00\">XOR2</text>\n",
"<text text-anchor=\"middle\" x=\"852\" y=\"-282.943\" font-family=\"Times,serif\" font-size=\"14.00\">adder</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"877.5,-275.143 877.5,-328.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"889\" y=\"-297.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 15&#45;&gt;2 -->\n",
"<g id=\"edge18\" class=\"edge\"><title>15:o0&#45;&gt;2:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M576,-288.643C673.011,-288.643 699.751,-288.643 791.959,-288.643\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"792,-292.143 802,-288.643 792,-285.143 792,-292.143\"/>\n",
"<text text-anchor=\"middle\" x=\"688\" y=\"-292.443\" font-family=\"Times,serif\" font-size=\"14.00\">17</text>\n",
"</g>\n",
"<!-- 15&#45;&gt;18 -->\n",
"<g id=\"edge20\" class=\"edge\"><title>15:o1&#45;&gt;18:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M564,-246.643C564,-136.627 677.361,-144.064 787.68,-144.615\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"787.991,-148.116 798,-144.643 788.009,-141.116 787.991,-148.116\"/>\n",
"<text text-anchor=\"middle\" x=\"688\" y=\"-160.443\" font-family=\"Times,serif\" font-size=\"14.00\">19</text>\n",
"</g>\n",
"<!-- 17 -->\n",
"<g id=\"node14\" class=\"node\"><title>17</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"628.5,-199.143 628.5,-252.143 747.5,-252.143 747.5,-199.143 628.5,-199.143\"/>\n",
"<text text-anchor=\"middle\" x=\"640\" y=\"-221.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"651.5,-199.143 651.5,-252.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"688\" y=\"-236.943\" font-family=\"Times,serif\" font-size=\"14.00\">17</text>\n",
"<text text-anchor=\"middle\" x=\"688\" y=\"-221.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"688\" y=\"-206.943\" font-family=\"Times,serif\" font-size=\"14.00\">adder~AB</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"724.5,-199.143 724.5,-252.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"736\" y=\"-235.443\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"724.5,-226.143 747.5,-226.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"736\" y=\"-208.943\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 16&#45;&gt;17 -->\n",
"<g id=\"edge14\" class=\"edge\"><title>16:o0&#45;&gt;17:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M578,-153.643C581.3,-153.643 617.285,-177.921 632.871,-190.556\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"630.441,-193.075 640,-197.643 635.376,-188.111 630.441,-193.075\"/>\n",
"<text text-anchor=\"middle\" x=\"603\" y=\"-177.443\" font-family=\"Times,serif\" font-size=\"14.00\">13</text>\n",
"</g>\n",
"<!-- 17&#45;&gt;2 -->\n",
"<g id=\"edge17\" class=\"edge\"><title>17:o0&#45;&gt;2:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M736,-253.643C736,-255.648 776.313,-293.828 793.963,-309.256\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"791.994,-312.161 802,-315.643 796.349,-306.681 791.994,-312.161\"/>\n",
"<text text-anchor=\"middle\" x=\"773\" y=\"-300.443\" font-family=\"Times,serif\" font-size=\"14.00\">16</text>\n",
"</g>\n",
"<!-- 17&#45;&gt;18 -->\n",
"<g id=\"edge19\" class=\"edge\"><title>17:o1&#45;&gt;18:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M748,-212.643C775.091,-212.643 801.682,-210.962 807.725,-189.628\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"811.205,-190.006 809,-179.643 804.261,-189.119 811.205,-190.006\"/>\n",
"<text text-anchor=\"middle\" x=\"773\" y=\"-216.443\" font-family=\"Times,serif\" font-size=\"14.00\">18</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node17\" class=\"node\"><title>3</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"950.5,-314.143 950.5,-367.143 1061.5,-367.143 1061.5,-314.143 950.5,-314.143\"/>\n",
"<text text-anchor=\"middle\" x=\"962\" y=\"-336.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"973.5,-314.143 973.5,-367.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"1006\" y=\"-351.943\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"<text text-anchor=\"middle\" x=\"1006\" y=\"-336.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"1006\" y=\"-321.943\" font-family=\"Times,serif\" font-size=\"14.00\">cout</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"1038.5,-314.143 1038.5,-367.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"1050\" y=\"-336.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;3 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>2:o0&#45;&gt;3:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M902,-301.643C924.875,-301.643 951.863,-290.173 959.739,-302.874\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"956.335,-303.69 962,-312.643 963.155,-302.111 956.335,-303.69\"/>\n",
"<text text-anchor=\"middle\" x=\"928\" y=\"-303.443\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node18\" class=\"node\"><title>4</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"950.5,-106.143 950.5,-159.143 1061.5,-159.143 1061.5,-106.143 950.5,-106.143\"/>\n",
"<text text-anchor=\"middle\" x=\"962\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"973.5,-106.143 973.5,-159.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"1006\" y=\"-143.943\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
"<text text-anchor=\"middle\" x=\"1006\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"1006\" y=\"-113.943\" font-family=\"Times,serif\" font-size=\"14.00\">s</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"1038.5,-106.143 1038.5,-159.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"1050\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 18&#45;&gt;4 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>18:o0&#45;&gt;4:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M906,-132.643C921.583,-132.643 927.853,-132.643 939.653,-132.643\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"940,-136.143 950,-132.643 940,-129.143 940,-136.143\"/>\n",
"<text text-anchor=\"middle\" x=\"928\" y=\"-136.443\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;0 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>3:o0&#45;&gt;0:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"1,5\" d=\"M1050,-368.643C1050,-456.361 940.718,-356.643 853,-356.643 195,-356.643 195,-356.643 195,-356.643 116.12,-356.643 20.0731,-408.263 11.603,-340.949\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"15.0783,-340.422 11,-330.643 8.09022,-340.83 15.0783,-340.422\"/>\n",
"<text text-anchor=\"middle\" x=\"518\" y=\"-360.443\" font-family=\"Times,serif\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 11 -->\n",
"<g id=\"node19\" class=\"node\"><title>11</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"1112,-106.143 1112,-159.143 1206,-159.143 1206,-106.143 1112,-106.143\"/>\n",
"<text text-anchor=\"middle\" x=\"1123.5\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"1135,-106.143 1135,-159.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"1160.5\" y=\"-143.943\" font-family=\"Times,serif\" font-size=\"14.00\">11 [3]</text>\n",
"<text text-anchor=\"middle\" x=\"1160.5\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\">output</text>\n",
"<text text-anchor=\"middle\" x=\"1160.5\" y=\"-113.943\" font-family=\"Times,serif\" font-size=\"14.00\">s</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"1186,-106.143 1186,-159.143 \"/>\n",
"<text text-anchor=\"middle\" x=\"1196\" y=\"-128.943\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"</g>\n",
"<!-- 4&#45;&gt;11 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>4:o0&#45;&gt;11:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M1062,-132.643C1080.4,-132.643 1087.38,-132.643 1101.85,-132.643\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"1102,-136.143 1112,-132.643 1102,-129.143 1102,-136.143\"/>\n",
"<text text-anchor=\"middle\" x=\"1087\" y=\"-136.443\" font-family=\"Times,serif\" font-size=\"14.00\">11</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.graphs.Digraph at 0x7fba15fae860>"
]
},
"execution_count": 39,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.dot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The graph is getting quite big due to all the forks. If we don't need the signal names anymore, we can remove all forks that only connect to one successor node."
]
},
{
"cell_type": "code",
"execution_count": 40,
"metadata": {},
"outputs": [
{
"data": {
"image/svg+xml": [
"<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"no\"?>\n",
"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.1//EN\"\n",
" \"http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd\">\n",
"<!-- Generated by graphviz version 2.30.1 (20201013.1554)\n",
" -->\n",
"<!-- Title: %3 Pages: 1 -->\n",
"<svg width=\"907pt\" height=\"297pt\"\n",
" viewBox=\"0.00 0.00 906.77 297.00\" xmlns=\"http://www.w3.org/2000/svg\" xmlns:xlink=\"http://www.w3.org/1999/xlink\">\n",
"<g id=\"graph0\" class=\"graph\" transform=\"scale(1 1) rotate(0) translate(4 293)\">\n",
"<title>%3</title>\n",
"<polygon fill=\"white\" stroke=\"white\" points=\"-4,5 -4,-293 903.765,-293 903.765,5 -4,5\"/>\n",
"<!-- 0 -->\n",
"<g id=\"node1\" class=\"node\"><title>0</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"14.7652,-0.5 14.7652,-53.5 104.765,-53.5 104.765,-0.5 14.7652,-0.5\"/>\n",
"<text text-anchor=\"middle\" x=\"26.2652\" y=\"-36.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"14.7652,-27.5 37.7652,-27.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"26.2652\" y=\"-10.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"37.7652,-0.5 37.7652,-53.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"59.7652\" y=\"-38.3\" font-family=\"Times,serif\" font-size=\"14.00\">0 [4]</text>\n",
"<text text-anchor=\"middle\" x=\"59.7652\" y=\"-23.3\" font-family=\"Times,serif\" font-size=\"14.00\">DFF</text>\n",
"<text text-anchor=\"middle\" x=\"59.7652\" y=\"-8.3\" font-family=\"Times,serif\" font-size=\"14.00\">carry</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"81.7652,-0.5 81.7652,-53.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"93.2652\" y=\"-23.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 6 -->\n",
"<g id=\"node5\" class=\"node\"><title>6</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"154.765,-10.5 154.765,-63.5 268.765,-63.5 268.765,-10.5 154.765,-10.5\"/>\n",
"<text text-anchor=\"middle\" x=\"166.265\" y=\"-33.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"177.765,-10.5 177.765,-63.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-48.3\" font-family=\"Times,serif\" font-size=\"14.00\">6</text>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-33.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-18.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder~CI</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"245.765,-10.5 245.765,-63.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"257.265\" y=\"-46.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"245.765,-37.5 268.765,-37.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"257.265\" y=\"-20.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 0&#45;&gt;6 -->\n",
"<g id=\"edge13\" class=\"edge\"><title>0:o0&#45;&gt;6:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M104.765,-27C123.532,-27 129.964,-33.8579 144.491,-36.2153\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"144.528,-39.7282 154.765,-37 145.061,-32.7485 144.528,-39.7282\"/>\n",
"<text text-anchor=\"middle\" x=\"129.765\" y=\"-38.8\" font-family=\"Times,serif\" font-size=\"14.00\">12</text>\n",
"</g>\n",
"<!-- 5 -->\n",
"<g id=\"node2\" class=\"node\"><title>5</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"16.2652,-90.5 16.2652,-143.5 103.265,-143.5 103.265,-90.5 16.2652,-90.5\"/>\n",
"<text text-anchor=\"middle\" x=\"26.2652\" y=\"-113.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"36.2652,-90.5 36.2652,-143.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-128.3\" font-family=\"Times,serif\" font-size=\"14.00\">5 [0]</text>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-113.3\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-98.3\" font-family=\"Times,serif\" font-size=\"14.00\">clk</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"80.2652,-90.5 80.2652,-143.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"91.7652\" y=\"-113.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 5&#45;&gt;0 -->\n",
"<g id=\"edge4\" class=\"edge\"><title>5:o0&#45;&gt;0:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"1,5\" d=\"M3.93752,-16.7734C-9.49505,-27.5832 15.186,-66.9364 38.7652,-80 49.2493,-85.8085 91.7652,-78.0144 91.7652,-90\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"5.09172,-20.0845 13.7652,-14 3.19048,-13.3476 5.09172,-20.0845\"/>\n",
"<text text-anchor=\"middle\" x=\"42.2652\" y=\"-68.3\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"</g>\n",
"<!-- 7 -->\n",
"<g id=\"node3\" class=\"node\"><title>7</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"16.2652,-234.5 16.2652,-287.5 103.265,-287.5 103.265,-234.5 16.2652,-234.5\"/>\n",
"<text text-anchor=\"middle\" x=\"26.2652\" y=\"-257.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"36.2652,-234.5 36.2652,-287.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-272.3\" font-family=\"Times,serif\" font-size=\"14.00\">7 [1]</text>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-257.3\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-242.3\" font-family=\"Times,serif\" font-size=\"14.00\">a</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"80.2652,-234.5 80.2652,-287.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"91.7652\" y=\"-257.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 10 -->\n",
"<g id=\"node6\" class=\"node\"><title>10</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"156.265,-233.5 156.265,-286.5 267.265,-286.5 267.265,-233.5 156.265,-233.5\"/>\n",
"<text text-anchor=\"middle\" x=\"167.765\" y=\"-256.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"179.265,-233.5 179.265,-286.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-271.3\" font-family=\"Times,serif\" font-size=\"14.00\">10</text>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-256.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-241.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder~A</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"244.265,-233.5 244.265,-286.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"255.765\" y=\"-269.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"244.265,-260.5 267.265,-260.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"255.765\" y=\"-243.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 7&#45;&gt;10 -->\n",
"<g id=\"edge5\" class=\"edge\"><title>7:o0&#45;&gt;10:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M104.765,-261C123.172,-261 130.139,-260.314 144.613,-260.078\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"144.793,-263.577 154.765,-260 144.738,-256.577 144.793,-263.577\"/>\n",
"<text text-anchor=\"middle\" x=\"129.765\" y=\"-263.8\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
"</g>\n",
"<!-- 9 -->\n",
"<g id=\"node4\" class=\"node\"><title>9</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"16.2652,-162.5 16.2652,-215.5 103.265,-215.5 103.265,-162.5 16.2652,-162.5\"/>\n",
"<text text-anchor=\"middle\" x=\"26.2652\" y=\"-185.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"36.2652,-162.5 36.2652,-215.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-200.3\" font-family=\"Times,serif\" font-size=\"14.00\">9 [2]</text>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-185.3\" font-family=\"Times,serif\" font-size=\"14.00\">input</text>\n",
"<text text-anchor=\"middle\" x=\"58.2652\" y=\"-170.3\" font-family=\"Times,serif\" font-size=\"14.00\">b</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"80.2652,-162.5 80.2652,-215.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"91.7652\" y=\"-185.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 8 -->\n",
"<g id=\"node7\" class=\"node\"><title>8</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"156.265,-153.5 156.265,-206.5 267.265,-206.5 267.265,-153.5 156.265,-153.5\"/>\n",
"<text text-anchor=\"middle\" x=\"167.765\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"179.265,-153.5 179.265,-206.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-191.3\" font-family=\"Times,serif\" font-size=\"14.00\">8</text>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-176.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"211.765\" y=\"-161.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder~B</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"244.265,-153.5 244.265,-206.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"255.765\" y=\"-189.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"244.265,-180.5 267.265,-180.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"255.765\" y=\"-163.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 9&#45;&gt;8 -->\n",
"<g id=\"edge6\" class=\"edge\"><title>9:o0&#45;&gt;8:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M104.765,-189C123.464,-189 129.998,-182.828 144.515,-180.706\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"145.029,-184.179 154.765,-180 144.548,-177.196 145.029,-184.179\"/>\n",
"<text text-anchor=\"middle\" x=\"129.765\" y=\"-190.8\" font-family=\"Times,serif\" font-size=\"14.00\">5</text>\n",
"</g>\n",
"<!-- 2 -->\n",
"<g id=\"node10\" class=\"node\"><title>2</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"658.265,-81.5 658.265,-134.5 755.265,-134.5 755.265,-81.5 658.265,-81.5\"/>\n",
"<text text-anchor=\"middle\" x=\"669.765\" y=\"-117.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"658.265,-108.5 681.265,-108.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"669.765\" y=\"-91.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"681.265,-81.5 681.265,-134.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"706.765\" y=\"-119.3\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"<text text-anchor=\"middle\" x=\"706.765\" y=\"-104.3\" font-family=\"Times,serif\" font-size=\"14.00\">XOR2</text>\n",
"<text text-anchor=\"middle\" x=\"706.765\" y=\"-89.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"732.265,-81.5 732.265,-134.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"743.765\" y=\"-104.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;2 -->\n",
"<g id=\"edge9\" class=\"edge\"><title>6:o0&#45;&gt;2:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M268.765,-51C309.61,-51 578.963,-89.9948 646.587,-94.5645\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"646.625,-98.0693 656.765,-95 646.924,-91.0757 646.625,-98.0693\"/>\n",
"<text text-anchor=\"middle\" x=\"463.765\" y=\"-78.8\" font-family=\"Times,serif\" font-size=\"14.00\">8</text>\n",
"</g>\n",
"<!-- 1 -->\n",
"<g id=\"node11\" class=\"node\"><title>1</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"652.765,-156 652.765,-248 760.765,-248 760.765,-156 652.765,-156\"/>\n",
"<text text-anchor=\"middle\" x=\"664.265\" y=\"-232.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"652.765,-225 675.765,-225 \"/>\n",
"<text text-anchor=\"middle\" x=\"664.265\" y=\"-209.8\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"652.765,-202 675.765,-202 \"/>\n",
"<text text-anchor=\"middle\" x=\"664.265\" y=\"-186.8\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"652.765,-179 675.765,-179 \"/>\n",
"<text text-anchor=\"middle\" x=\"664.265\" y=\"-163.8\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"675.765,-156 675.765,-248 \"/>\n",
"<text text-anchor=\"middle\" x=\"706.765\" y=\"-213.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<text text-anchor=\"middle\" x=\"706.765\" y=\"-198.3\" font-family=\"Times,serif\" font-size=\"14.00\">AO22</text>\n",
"<text text-anchor=\"middle\" x=\"706.765\" y=\"-183.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder~S</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"737.765,-156 737.765,-248 \"/>\n",
"<text text-anchor=\"middle\" x=\"749.265\" y=\"-198.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 6&#45;&gt;1 -->\n",
"<g id=\"edge12\" class=\"edge\"><title>6:o1&#45;&gt;1:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M268.765,-24C359.528,-24 386.047,-21.4316 470.765,-54 552.456,-85.4047 580.985,-93.9542 634.765,-163 646.651,-178.26 635.499,-201.984 643.214,-210.67\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"642.17,-214.013 652.765,-214 644.475,-207.403 642.17,-214.013\"/>\n",
"<text text-anchor=\"middle\" x=\"463.765\" y=\"-57.8\" font-family=\"Times,serif\" font-size=\"14.00\">11</text>\n",
"</g>\n",
"<!-- 10&#45;&gt;1 -->\n",
"<g id=\"edge7\" class=\"edge\"><title>10:o1&#45;&gt;1:i2</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M268.765,-247C293.226,-247 295.167,-230.437 318.765,-224 459.344,-185.654 501.583,-189.778 642.45,-189.992\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"642.762,-193.492 652.765,-190 642.768,-186.492 642.762,-193.492\"/>\n",
"<text text-anchor=\"middle\" x=\"463.765\" y=\"-198.8\" font-family=\"Times,serif\" font-size=\"14.00\">6</text>\n",
"</g>\n",
"<!-- 4 -->\n",
"<g id=\"node8\" class=\"node\"><title>4</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"319.265,-233.5 319.265,-286.5 438.265,-286.5 438.265,-233.5 319.265,-233.5\"/>\n",
"<text text-anchor=\"middle\" x=\"330.765\" y=\"-269.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"319.265,-260.5 342.265,-260.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"330.765\" y=\"-243.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"342.265,-233.5 342.265,-286.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"378.765\" y=\"-271.3\" font-family=\"Times,serif\" font-size=\"14.00\">4</text>\n",
"<text text-anchor=\"middle\" x=\"378.765\" y=\"-256.3\" font-family=\"Times,serif\" font-size=\"14.00\">XOR2</text>\n",
"<text text-anchor=\"middle\" x=\"378.765\" y=\"-241.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder~AB</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"415.265,-233.5 415.265,-286.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"426.765\" y=\"-256.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 10&#45;&gt;4 -->\n",
"<g id=\"edge15\" class=\"edge\"><title>10:o0&#45;&gt;4:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M268.765,-274C287.168,-274 294.141,-274 308.615,-274\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"308.765,-277.5 318.765,-274 308.765,-270.5 308.765,-277.5\"/>\n",
"<text text-anchor=\"middle\" x=\"293.765\" y=\"-277.8\" font-family=\"Times,serif\" font-size=\"14.00\">14</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;4 -->\n",
"<g id=\"edge1\" class=\"edge\"><title>8:o0&#45;&gt;4:i1</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M268.765,-194C297.423,-194 324.007,-198.466 329.662,-222.012\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"326.188,-222.445 330.765,-232 333.146,-221.676 326.188,-222.445\"/>\n",
"<text text-anchor=\"middle\" x=\"293.765\" y=\"-200.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"</g>\n",
"<!-- 8&#45;&gt;1 -->\n",
"<g id=\"edge11\" class=\"edge\"><title>8:o1&#45;&gt;1:i3</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M268.765,-167C435.932,-167 480.295,-167 642.425,-167\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"642.765,-170.5 652.765,-167 642.765,-163.5 642.765,-170.5\"/>\n",
"<text text-anchor=\"middle\" x=\"463.765\" y=\"-170.8\" font-family=\"Times,serif\" font-size=\"14.00\">10</text>\n",
"</g>\n",
"<!-- 3 -->\n",
"<g id=\"node9\" class=\"node\"><title>3</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"489.265,-233.5 489.265,-286.5 608.265,-286.5 608.265,-233.5 489.265,-233.5\"/>\n",
"<text text-anchor=\"middle\" x=\"500.765\" y=\"-256.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"512.265,-233.5 512.265,-286.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"548.765\" y=\"-271.3\" font-family=\"Times,serif\" font-size=\"14.00\">3</text>\n",
"<text text-anchor=\"middle\" x=\"548.765\" y=\"-256.3\" font-family=\"Times,serif\" font-size=\"14.00\">__fork__</text>\n",
"<text text-anchor=\"middle\" x=\"548.765\" y=\"-241.3\" font-family=\"Times,serif\" font-size=\"14.00\">adder~AB</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"585.265,-233.5 585.265,-286.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"596.765\" y=\"-269.8\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"585.265,-260.5 608.265,-260.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"596.765\" y=\"-243.3\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 4&#45;&gt;3 -->\n",
"<g id=\"edge14\" class=\"edge\"><title>4:o0&#45;&gt;3:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M438.765,-260C457.168,-260 464.141,-260 478.615,-260\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"478.765,-263.5 488.765,-260 478.765,-256.5 478.765,-263.5\"/>\n",
"<text text-anchor=\"middle\" x=\"463.765\" y=\"-263.8\" font-family=\"Times,serif\" font-size=\"14.00\">13</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;1 -->\n",
"<g id=\"edge8\" class=\"edge\"><title>3:o1&#45;&gt;1:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M608.765,-247C617.52,-247 618.277,-241.145 626.765,-239 633.788,-237.225 637.661,-236.888 642.408,-236.884\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"642.727,-240.388 652.765,-237 642.805,-233.388 642.727,-240.388\"/>\n",
"<text text-anchor=\"middle\" x=\"630.765\" y=\"-242.8\" font-family=\"Times,serif\" font-size=\"14.00\">7</text>\n",
"</g>\n",
"<!-- 3&#45;&gt;2 -->\n",
"<g id=\"edge10\" class=\"edge\"><title>3:o0&#45;&gt;2:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M608.765,-274C667.987,-274 632.38,-175.662 652.765,-146 654.86,-142.952 658.213,-142.256 661.389,-141.812\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"663.545,-144.577 669.765,-136 659.554,-138.826 663.545,-144.577\"/>\n",
"<text text-anchor=\"middle\" x=\"630.765\" y=\"-272.8\" font-family=\"Times,serif\" font-size=\"14.00\">9</text>\n",
"</g>\n",
"<!-- 2&#45;&gt;0 -->\n",
"<g id=\"edge2\" class=\"edge\"><title>2:o0&#45;&gt;0:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" stroke-dasharray=\"1,5\" d=\"M743.765,-80C743.765,-41.7752 694.675,-71.0609 657.765,-81 646.427,-84.0531 645.84,-90.0969 634.765,-94 598.655,-106.726 588.052,-108 549.765,-108 210.765,-108 210.765,-108 210.765,-108 206.15,-108 71.6313,-72.4854 34.935,-59.3351\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"36.3018,-56.1099 25.7652,-55 33.3099,-62.4383 36.3018,-56.1099\"/>\n",
"<text text-anchor=\"middle\" x=\"378.765\" y=\"-111.8\" font-family=\"Times,serif\" font-size=\"14.00\">1</text>\n",
"</g>\n",
"<!-- 11 -->\n",
"<g id=\"node12\" class=\"node\"><title>11</title>\n",
"<polygon fill=\"none\" stroke=\"black\" points=\"804.765,-175.5 804.765,-228.5 898.765,-228.5 898.765,-175.5 804.765,-175.5\"/>\n",
"<text text-anchor=\"middle\" x=\"816.265\" y=\"-198.3\" font-family=\"Times,serif\" font-size=\"14.00\">0</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"827.765,-175.5 827.765,-228.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"853.265\" y=\"-213.3\" font-family=\"Times,serif\" font-size=\"14.00\">11 [3]</text>\n",
"<text text-anchor=\"middle\" x=\"853.265\" y=\"-198.3\" font-family=\"Times,serif\" font-size=\"14.00\">output</text>\n",
"<text text-anchor=\"middle\" x=\"853.265\" y=\"-183.3\" font-family=\"Times,serif\" font-size=\"14.00\">s</text>\n",
"<polyline fill=\"none\" stroke=\"black\" points=\"878.765,-175.5 878.765,-228.5 \"/>\n",
"<text text-anchor=\"middle\" x=\"888.765\" y=\"-198.3\" font-family=\"Times,serif\" font-size=\"14.00\"> </text>\n",
"</g>\n",
"<!-- 1&#45;&gt;11 -->\n",
"<g id=\"edge3\" class=\"edge\"><title>1:o0&#45;&gt;11:i0</title>\n",
"<path fill=\"none\" stroke=\"black\" d=\"M760.765,-202C776.349,-202 782.618,-202 794.418,-202\"/>\n",
"<polygon fill=\"black\" stroke=\"black\" points=\"794.765,-205.5 804.765,-202 794.765,-198.5 794.765,-205.5\"/>\n",
"<text text-anchor=\"middle\" x=\"782.765\" y=\"-205.8\" font-family=\"Times,serif\" font-size=\"14.00\">2</text>\n",
"</g>\n",
"</g>\n",
"</svg>\n"
],
"text/plain": [
"<graphviz.graphs.Digraph at 0x7fba15fef310>"
]
},
"execution_count": 40,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.eliminate_1to1_forks()\n",
"adder.dot()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Let's resolve the b15 circuit as well."
]
},
{
"cell_type": "code",
"execution_count": 41,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'__node__': 22819,\n",
" '__cell__': 11653,\n",
" '__fork__': 11166,\n",
" '__io__': 111,\n",
" '__line__': 33313,\n",
" '__const1__': 1,\n",
" '__comb__': 11125,\n",
" 'BUF1': 526,\n",
" 'INV1': 897,\n",
" 'AND2': 1464,\n",
" 'OR2': 1095,\n",
" 'NOR2': 114,\n",
" 'DFF': 417,\n",
" '__dff__': 417,\n",
" 'NAND2': 6611,\n",
" 'output': 71,\n",
" 'input': 40,\n",
" 'MUX21': 417,\n",
" '__latch__': 0,\n",
" '__seq__': 417}"
]
},
"execution_count": 41,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b15_prim = b15.copy()\n",
"b15_prim.resolve_tlib_cells(SAED32)\n",
"b15_prim.stats"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The resolved circuit `b15_prim` contains primitive DFF and no scan-cells.\n",
"The scan-chain is still present but it now contains ordinary multiplexers and flip-flops."
]
},
{
"cell_type": "code",
"execution_count": 42,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"---------------\n",
"1385:DFF\"InstQueue_reg_0__0_\" <32766 <12707 >32767\n",
"1383:DFF\"InstQueue_reg_0__1_\" <32763 <12702 >32764\n",
"1387:DFF\"InstQueue_reg_0__2_\" <32769 <12712 >32770\n",
"1381:DFF\"InstQueue_reg_0__3_\" <32760 <12697 >32761\n",
"1389:DFF\"InstQueue_reg_0__4_\" <32772 <12717 >32773\n",
"1379:DFF\"InstQueue_reg_0__5_\" <32757 <12692 >32758\n",
"1391:DFF\"InstQueue_reg_0__6_\" <32775 <12722 >32776\n",
"1377:DFF\"InstQueue_reg_0__7_\" <32754 <12687 >32755\n",
"---------------\n",
"1401:DFF\"InstQueue_reg_1__0_\" <32790 <12747 >32791\n",
"1399:DFF\"InstQueue_reg_1__1_\" <32787 <12742 >32788\n",
"1403:DFF\"InstQueue_reg_1__2_\" <32793 <12752 >32794\n",
"1397:DFF\"InstQueue_reg_1__3_\" <32784 <12737 >32785\n",
"1405:DFF\"InstQueue_reg_1__4_\" <32796 <12757 >32797\n",
"1395:DFF\"InstQueue_reg_1__5_\" <32781 <12732 >32782\n",
"1407:DFF\"InstQueue_reg_1__6_\" <32799 <12762 >32800\n",
"1393:DFF\"InstQueue_reg_1__7_\" <32778 <12727 >32779\n",
"---------------\n",
"1417:DFF\"InstQueue_reg_2__0_\" <32814 <12787 >32815\n",
"1415:DFF\"InstQueue_reg_2__1_\" <32811 <12782 >32812\n",
"1419:DFF\"InstQueue_reg_2__2_\" <32817 <12792 >32818\n",
"1413:DFF\"InstQueue_reg_2__3_\" <32808 <12777 >32809\n",
"1421:DFF\"InstQueue_reg_2__4_\" <32820 <12797 >32821\n",
"1411:DFF\"InstQueue_reg_2__5_\" <32805 <12772 >32806\n",
"1423:DFF\"InstQueue_reg_2__6_\" <32823 <12802 >32824\n",
"1409:DFF\"InstQueue_reg_2__7_\" <32802 <12767 >32803\n",
"---------------\n",
"1433:DFF\"InstQueue_reg_3__0_\" <32838 <12827 >32839\n",
"1431:DFF\"InstQueue_reg_3__1_\" <32835 <12822 >32836\n",
"1435:DFF\"InstQueue_reg_3__2_\" <32841 <12832 >32842\n",
"1429:DFF\"InstQueue_reg_3__3_\" <32832 <12817 >32833\n",
"1437:DFF\"InstQueue_reg_3__4_\" <32844 <12837 >32845\n",
"1427:DFF\"InstQueue_reg_3__5_\" <32829 <12812 >32830\n",
"1439:DFF\"InstQueue_reg_3__6_\" <32847 <12842 >32848\n",
"1425:DFF\"InstQueue_reg_3__7_\" <32826 <12807 >32827\n",
"---------------\n",
"1449:DFF\"InstQueue_reg_4__0_\" <32862 <12867 >32863\n",
"1447:DFF\"InstQueue_reg_4__1_\" <32859 <12862 >32860\n",
"1451:DFF\"InstQueue_reg_4__2_\" <32865 <12872 >32866\n",
"1445:DFF\"InstQueue_reg_4__3_\" <32856 <12857 >32857\n",
"1453:DFF\"InstQueue_reg_4__4_\" <32868 <12877 >32869\n",
"1443:DFF\"InstQueue_reg_4__5_\" <32853 <12852 >32854\n",
"1455:DFF\"InstQueue_reg_4__6_\" <32871 <12882 >32872\n",
"1441:DFF\"InstQueue_reg_4__7_\" <32850 <12847 >32851\n",
"---------------\n",
"1465:DFF\"InstQueue_reg_5__0_\" <32886 <12907 >32887\n",
"1463:DFF\"InstQueue_reg_5__1_\" <32883 <12902 >32884\n",
"1467:DFF\"InstQueue_reg_5__2_\" <32889 <12912 >32890\n",
"1461:DFF\"InstQueue_reg_5__3_\" <32880 <12897 >32881\n",
"1469:DFF\"InstQueue_reg_5__4_\" <32892 <12917 >32893\n",
"1459:DFF\"InstQueue_reg_5__5_\" <32877 <12892 >32878\n",
"1471:DFF\"InstQueue_reg_5__6_\" <32895 <12922 >32896\n",
"1457:DFF\"InstQueue_reg_5__7_\" <32874 <12887 >32875\n",
"---------------\n",
"1481:DFF\"InstQueue_reg_6__0_\" <32910 <12947 >32911\n",
"1479:DFF\"InstQueue_reg_6__1_\" <32907 <12942 >32908\n",
"1483:DFF\"InstQueue_reg_6__2_\" <32913 <12952 >32914\n",
"1477:DFF\"InstQueue_reg_6__3_\" <32904 <12937 >32905\n",
"1485:DFF\"InstQueue_reg_6__4_\" <32916 <12957 >32917\n",
"1475:DFF\"InstQueue_reg_6__5_\" <32901 <12932 >32902\n",
"1487:DFF\"InstQueue_reg_6__6_\" <32919 <12962 >32920\n",
"1473:DFF\"InstQueue_reg_6__7_\" <32898 <12927 >32899\n",
"---------------\n",
"1497:DFF\"InstQueue_reg_7__0_\" <32934 <12987 >32935\n",
"1495:DFF\"InstQueue_reg_7__1_\" <32931 <12982 >32932\n",
"1499:DFF\"InstQueue_reg_7__2_\" <32937 <12992 >32938\n",
"1493:DFF\"InstQueue_reg_7__3_\" <32928 <12977 >32929\n",
"1501:DFF\"InstQueue_reg_7__4_\" <32940 <12997 >32941\n",
"1491:DFF\"InstQueue_reg_7__5_\" <32925 <12972 >32926\n",
"1503:DFF\"InstQueue_reg_7__6_\" <32943 <13002 >32944\n",
"1489:DFF\"InstQueue_reg_7__7_\" <32922 <12967 >32923\n",
"---------------\n",
"1513:DFF\"InstQueue_reg_8__0_\" <32958 <13027 >32959\n",
"1511:DFF\"InstQueue_reg_8__1_\" <32955 <13022 >32956\n",
"1515:DFF\"InstQueue_reg_8__2_\" <32961 <13032 >32963\n",
"1509:DFF\"InstQueue_reg_8__3_\" <32952 <13017 >32953\n",
"1518:DFF\"InstQueue_reg_8__4_\" <32965 <13037 >32966\n",
"1507:DFF\"InstQueue_reg_8__5_\" <32949 <13012 >32950\n",
"1520:DFF\"InstQueue_reg_8__6_\" <32968 <13042 >32969\n",
"1505:DFF\"InstQueue_reg_8__7_\" <32946 <13007 >32947\n",
"---------------\n",
"1530:DFF\"InstQueue_reg_9__0_\" <32983 <13067 >32984\n",
"1528:DFF\"InstQueue_reg_9__1_\" <32980 <13062 >32981\n",
"1532:DFF\"InstQueue_reg_9__2_\" <32986 <13072 >32987\n",
"1526:DFF\"InstQueue_reg_9__3_\" <32977 <13057 >32978\n",
"1534:DFF\"InstQueue_reg_9__4_\" <32989 <13077 >32990\n",
"1524:DFF\"InstQueue_reg_9__5_\" <32974 <13052 >32975\n",
"1536:DFF\"InstQueue_reg_9__6_\" <32992 <13082 >32993\n",
"1522:DFF\"InstQueue_reg_9__7_\" <32971 <13047 >32972\n",
"---------------\n",
"1546:DFF\"InstQueue_reg_10__0_\" <33007 <13107 >33008\n",
"1544:DFF\"InstQueue_reg_10__1_\" <33004 <13102 >33005\n",
"1548:DFF\"InstQueue_reg_10__2_\" <33010 <13112 >33011\n",
"1542:DFF\"InstQueue_reg_10__3_\" <33001 <13097 >33002\n",
"1550:DFF\"InstQueue_reg_10__4_\" <33013 <13117 >33015\n",
"1540:DFF\"InstQueue_reg_10__5_\" <32998 <13092 >32999\n",
"1553:DFF\"InstQueue_reg_10__6_\" <33017 <13122 >33018\n",
"1538:DFF\"InstQueue_reg_10__7_\" <32995 <13087 >32996\n",
"---------------\n",
"1563:DFF\"InstQueue_reg_11__0_\" <33032 <13147 >33033\n",
"1561:DFF\"InstQueue_reg_11__1_\" <33029 <13142 >33030\n",
"1565:DFF\"InstQueue_reg_11__2_\" <33035 <13152 >33036\n",
"1559:DFF\"InstQueue_reg_11__3_\" <33026 <13137 >33027\n",
"1567:DFF\"InstQueue_reg_11__4_\" <33038 <13157 >33039\n",
"1557:DFF\"InstQueue_reg_11__5_\" <33023 <13132 >33024\n",
"1569:DFF\"InstQueue_reg_11__6_\" <33041 <13162 >33042\n",
"1555:DFF\"InstQueue_reg_11__7_\" <33020 <13127 >33021\n",
"---------------\n",
"1579:DFF\"InstQueue_reg_12__0_\" <33056 <13187 >33057\n",
"1577:DFF\"InstQueue_reg_12__1_\" <33053 <13182 >33054\n",
"1581:DFF\"InstQueue_reg_12__2_\" <33059 <13192 >33060\n",
"1575:DFF\"InstQueue_reg_12__3_\" <33050 <13177 >33051\n",
"1583:DFF\"InstQueue_reg_12__4_\" <33062 <13197 >33063\n",
"1573:DFF\"InstQueue_reg_12__5_\" <33047 <13172 >33048\n",
"1585:DFF\"InstQueue_reg_12__6_\" <33065 <13202 >33066\n",
"1571:DFF\"InstQueue_reg_12__7_\" <33044 <13167 >33045\n",
"---------------\n",
"1595:DFF\"InstQueue_reg_13__0_\" <33080 <13227 >33081\n",
"1593:DFF\"InstQueue_reg_13__1_\" <33077 <13222 >33078\n",
"1597:DFF\"InstQueue_reg_13__2_\" <33083 <13232 >33084\n",
"1591:DFF\"InstQueue_reg_13__3_\" <33074 <13217 >33075\n",
"1599:DFF\"InstQueue_reg_13__4_\" <33086 <13237 >33087\n",
"1589:DFF\"InstQueue_reg_13__5_\" <33071 <13212 >33072\n",
"1601:DFF\"InstQueue_reg_13__6_\" <33089 <13242 >33090\n",
"1587:DFF\"InstQueue_reg_13__7_\" <33068 <13207 >33069\n",
"---------------\n",
"1611:DFF\"InstQueue_reg_14__0_\" <33104 <13267 >33105\n",
"1609:DFF\"InstQueue_reg_14__1_\" <33101 <13262 >33102\n",
"1613:DFF\"InstQueue_reg_14__2_\" <33107 <13272 >33108\n",
"1607:DFF\"InstQueue_reg_14__3_\" <33098 <13257 >33099\n",
"1615:DFF\"InstQueue_reg_14__4_\" <33110 <13277 >33111\n",
"1605:DFF\"InstQueue_reg_14__5_\" <33095 <13252 >33096\n",
"1617:DFF\"InstQueue_reg_14__6_\" <33113 <13282 >33114\n",
"1603:DFF\"InstQueue_reg_14__7_\" <33092 <13247 >33093\n",
"---------------\n",
"1627:DFF\"InstQueue_reg_15__0_\" <33128 <13307 >33129\n",
"1625:DFF\"InstQueue_reg_15__1_\" <33125 <13302 >33126\n",
"1629:DFF\"InstQueue_reg_15__2_\" <33131 <13312 >33132\n",
"1623:DFF\"InstQueue_reg_15__3_\" <33122 <13297 >33123\n",
"1631:DFF\"InstQueue_reg_15__4_\" <33134 <13317 >33135\n",
"1621:DFF\"InstQueue_reg_15__5_\" <33119 <13292 >33120\n",
"1633:DFF\"InstQueue_reg_15__6_\" <33137 <13322 >33138\n",
"1619:DFF\"InstQueue_reg_15__7_\" <33116 <13287 >33117\n"
]
}
],
"source": [
"for l in b15_prim.s_locs('InstQueue_reg'):\n",
" print('---------------')\n",
" for i in l:\n",
" print(b15_prim.s_nodes[i])"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Working With Logic Values\n",
"\n",
"Sequential states of circuits, signals, and test patterns contain logic values.\n",
"\n",
"KyuPy provides some useful tools to deal with 2-valued, 4-valued, and 8-valued logic data.\n",
"\n",
"All logic values are stored in numpy arrays of dtype `np.uint8`.\n",
"\n",
"There are two storage formats:\n",
"* `mv` (for \"multi-valued\"): Each logic value is stored as uint8\n",
"* `bp` (for \"bit-parallel\"): Groups of 8 logic values are stored as three uint8"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### `mv` Arrays\n",
"\n",
"Suppose we want to simulate the adder circuit with 2 inputs, 1 output and 1 flip-flop."
]
},
{
"cell_type": "code",
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[5:input\"clk\" >3,\n",
" 7:input\"a\" >4,\n",
" 9:input\"b\" >5,\n",
" 11:output\"s\" <2,\n",
" 0:DFF\"carry\" <1 <3 >12]"
]
},
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.s_nodes"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"We can construct a set of vectors using the `mvarray` helper function.\n",
"\n",
1 year ago
"Each vector has 4 elements, one for each io_node and sequential element.\n",
"\n",
"This would be an exhaustive vector set (the output in `s_nodes` remains unassigned (\"-\")):"
]
},
{
"cell_type": "code",
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[0, 0, 0, 0, 0, 0, 0, 0],\n",
" [0, 3, 0, 3, 0, 3, 0, 3],\n",
" [0, 0, 3, 3, 0, 0, 3, 3],\n",
" [2, 2, 2, 2, 2, 2, 2, 2],\n",
" [0, 0, 0, 0, 3, 3, 3, 3]], dtype=uint8)"
]
},
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"from kyupy import logic\n",
"\n",
"inputs = logic.mvarray('000-0', '010-0', '001-0', '011-0', '000-1', '010-1', '001-1', '011-1')\n",
"inputs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The numeric values in this array are defined in `kyupy.logic`.\n",
1 year ago
"A logic-0 is stored as `0`, a logic-1 is stored as `3`, and 'unassigned' is stored as `2`.\n",
"\n",
"The **last** axis is always the number of vectors. It may be unintuitive at first, but it is more convenient for data-parallel simulations.\n",
"\n",
"The **second-to-last** axis corresponds to `s_nodes`. I.e., the first row is for input 'a', the second row for input 'b', and so on."
]
},
{
"cell_type": "code",
"execution_count": 45,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(5, 8)"
]
},
"execution_count": 45,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"inputs.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Get a string representation of a vector set. Possible values are '0', '1', '-', 'X', 'R', 'F', 'P', and 'N'."
]
},
{
"cell_type": "code",
"execution_count": 46,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"000-0\n",
"010-0\n",
"001-0\n",
"011-0\n",
"000-1\n",
"010-1\n",
"001-1\n",
"011-1\n"
]
}
],
"source": [
1 year ago
"print(logic.mv_str(inputs))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"Load a stuck-at fault test pattern set and expected fault-free responses from a STIL file. It contains 678 test vectors. Use the resolved circuit for arranging the patterns because the DFF positions may have changed by replacing the original technology cells."
]
},
{
"cell_type": "code",
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
"from kyupy import stil\n",
"\n",
1 year ago
"s = stil.load('../tests/b15_2ig.sa_nf.stil.gz')\n",
1 year ago
"stuck_tests = s.tests(b15_prim)\n",
"stuck_responses = s.responses(b15_prim)"
]
},
{
"cell_type": "code",
"execution_count": 48,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"528"
]
},
"execution_count": 48,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"len(b15_prim.s_nodes)"
]
},
{
"cell_type": "code",
"execution_count": 49,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"(528, 678)"
]
},
"execution_count": 49,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stuck_tests.shape"
]
},
{
"cell_type": "code",
"execution_count": 50,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"(528, 678)"
]
},
"execution_count": 50,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stuck_responses.shape"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"------------------------------------------------------------------------------------------------------0----00--000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"--------------------------------------1100011011011111--------10111110--------------------------------P-00000--0101111000011010-01----110---110-110---110-11001100110-11101010011010-10-1010-1010101010-10-10-1010-10-10-10-101-10101010101010-10-10100-01010101011-01-11101110111011101-101-111011101-111011101-111010101000-10-1010-101010010-10011--0100-100110000111100001-111111-000011100000-101-01000011110-11-001000011111111-0001010100010001000----1----1-----1---11-----------00-101010101010-1010-1010101010101--10-1101010111111111\n",
"---------------------------------------1-1--1--1---1--1000100000000011--------------------------------P-10-00--11000001101111011---0--01-1111111111111111--1111110-111011111-111---11--11-1--1--------------------------------000000001---1----1--010-1-1---10010110011111110101001-0-0-0-1-0-1-0-011-0-1-000-1-001-1000101111111111111111111101111001101----1----------1-----------------------------------------------------1-11011100011111111-----111-----1-111-0-1-1----------------01------1------1-1-------------1--011-01011110011101111\n",
"------------------------------------------------------------------------------------------------------P111100--11011-0110000-10--0-----0--0-0-1-0-1-0-0-1---1-0-1-------0-01-11---0-0--00-0-00--------------------------------001100110000011000111110011000100--0011-------------1---------------------0-1-----1---1-1-1-1111111111111111101000100--001000011001-----1--111111--1--11--111--011---------------------------------0-------0-0---------------------------------------------00--------------------------------10-110-10010010-01010\n",
"--------------------------------------1011011111010000--------00101101--------------------------------P001100--10001010001111100-1-10101-1-1-1-1-1-1-1-1-101-1-1-100-000----0--00--1-0---------------------------------------------1--------------------------110-0--00001-0011001-001-0011001-0-0-010-001-1-0110101-1-1-0-100000000000011--1-11-1110-1----1--------------0--00---00-01---00-0----00-00---11-00--00000001011-0001-00-01---001001--11100---00-00---00-00---------1100-----01-------------0---------------0--11------0101000-10---\n"
]
}
],
"source": [
1 year ago
"print(logic.mv_str(stuck_tests[:,:5]))"
]
},
{
"cell_type": "code",
"execution_count": 52,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------0000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"X0101010101010101X0101X01010101010XX11--------------------------------001X01X01X01X0101X01X01X01010101--------X0001010110000010X01XXXX110XXX110X110XXX110X11001100110X11101010011010X10X1010X1010101010X10X10X1010X10X10X10X101X10101010101010X10X10100X01010101110X00X01000100010001000X000X010001000X010001000X010000000000X10X1010X101010010X10001XX0100X100110000111100001X111111X000011100000X101X01000011110X11X001000011111111X00010101000100010001111011011110110110000011001110101X101010101010X1010X10101010101011X1001101010111111111\n",
"1X11XX1XXXXXXXXXXXXX1X1XXXXXX1XXXX1X1X--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------101010001101110010011111100000000000000000011000000110000000001000110000000001000XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000001XXX1XXXX1XX010X1X1XXX10110110011111110101001X0X0X0X1X0X1X0X011X0X1X000X1X001X1000101000000000000000000011111001010XXXX1XXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1X11011100011111111XXXXX111XXXXX1X111X0X1X1XXXXXXXXXXXXXXXX0110000100100010100101001011011001100100101100001110101\n",
"0101XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0X0X--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------011011X11100000000X0XXXXX0XX0X0X1X0X1X0X0X1XXX1X0X1XXXXXXX0X01X11XXX0X0XX00X0X00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011100110000011000111110011000100XX0011XXXXXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXX0X1XXXXX1XXX1X1X1X1111111111111111101000100XX001000011001XXXXX1XX111111XX1XX11XX111XX011XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0XXXXXXX0X0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX10X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX101110010110110X01010\n",
"1XXXXX0XXXXXXXXXXXXXXX0XXXXXXXXXXX1XXX--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------100011001101001100X1X10101X1X1X1X1X1X1X1X1X101X1X1X100X000XXXX0XX00XX1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXXX110X0XX00101X0011001X001X0011001X0X0X010X001X1X0110101X1X1X0X100000000000011XX1X11X1110X1XX1000101111100010X0XX00XXX00X01XXX00X0XXXX00X00XXX11X00XX00000001011X0001X00X01XXX001001XX11100XXX00X00XXX00X00XX01101100011011001011XXXXXXXXXXX0XXXXXXXXXXXXXXX0XX010X1X1X0101000X10XXX\n"
]
}
],
"source": [
1 year ago
"print(logic.mv_str(stuck_responses[:,:5]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The order of values in the vectors correspond to the circuit's `s_nodes`.\n",
"The test data can be used directly in the simulators as they use the same ordering convention.\n",
"\n",
"`stuck_tests` has values for all primary inputs and scan flip-flops, `stuck_responses` contains the expected values for all primary outputs and scan flip-flops.\n",
"\n",
1 year ago
"Since this is a static test, only '0', '1' and 'X' are used with the exception of the clock input, which has a positive pulse 'P'.\n",
"\n",
"A transition fault test is a dynamic test that also contains 'R' for rising transition and 'F' for falling transition:"
]
},
{
"cell_type": "code",
"execution_count": 53,
"metadata": {},
"outputs": [],
"source": [
1 year ago
"s = stil.load('../tests/b15_2ig.tf_nf.stil.gz')\n",
1 year ago
"transition_tests = s.tests_loc(b15_prim)\n",
"transition_responses = s.responses(b15_prim)"
1 year ago
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"STIL files for delay tests usually only contain the initialization patterns.\n",
"When loading launch-on-capture transition fault tests, use `.tests_loc()`. This function performs a logic simulation of the launch cycle to calculate the transitions for the delay test itself."
]
},
{
"cell_type": "code",
"execution_count": 54,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"------------------------------------------------------------------------------------------------------X----XX--000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"--------------------------------------RFRRRRFRRFRRRR1R--------RXXRXRRR--------------------------------00F0F00--RR1RRXRF00011010XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011X00XXX101X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X0XXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXRRXRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX00000000000000000111111000001001RFXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX11XXXXX\n",
"--------------------------------------1X111XX11X1XX1X11XX11XX111X11X11--------------------------------0-XXR00--F1FF1X0110011X01XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXFXX1XFFX1XFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFX0XFXFXFXF11110XX1XX1XXXXXXX1XXXX1XFR1F1XXXXXXXXXXXXXXXXX011101111000101101110111110001001000100010101011011001110111000X1XX11XXXXXXXX11XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000X011111111111111111111111111111R0F1R0R001RR100FF1XXX\n",
"--------------------------------------------------------------XXXXXXXX--------------------------------0--FX00--F11F1XFRR00R01111XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0XX1XXXXXRX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX111111111111111111111110X0XX10XXXXXXXXXRXXXRXRF1FFFRFRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXXXXXXXXX0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX11X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011001010010111111111\n",
"--------------------------------------------------------------FFXFFFFF--------------------------------0XXRR00--RF01FXRF00001XX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX010X010111111111X111111111111111X11100XX0101XXXXXX01XXXX01XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1X1111X110111111XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0RXRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXX\n"
]
}
],
"source": [
1 year ago
"print(logic.mv_str(transition_tests[:,:5]))"
]
},
{
"cell_type": "code",
"execution_count": 55,
1 year ago
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------0000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------X01001X0110000010XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011X00XXX000X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X1XXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXX11X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1111111111111111100000011111011010X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0X0X0X1XXXXXXX11XXXXX\n",
"0100111111111111111111111111111110101X--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------101011X0110011001000X0X0X1X0X0X1X0X0X0X1X1X0X0X1X1X010110100110001XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0XX1X00X1X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X0X000001XX1XX1XXXXXXX1XXXX1X01000XXXXXXXXXXXXXXXXX011101111000101101110111110001001000100010101011011001110111000X1XX11XXXXXXXX11XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0010100000000000000000000000000000111011011000000010XXX\n",
"1011XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX01--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------X00101X01100100010XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0XX1XXXXX1X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000000000000000000001X0XX11XXXXXXXX0100010101000101XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXXXXXXXXX0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX11101XXXXXXXXXXXXXXXXXXXXXXXXXXXXX001100000100001110100\n",
"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------X01000X1100101XX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000X0011000000000000000000000000000011XX1111XXXXXX11XXXX11XXXXXXXXXXXXXXXXXXXXXXXXXXXX11X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0100000001000000XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX01X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1X0X0X1XXXXXXXX0XXXXX\n"
1 year ago
]
}
],
"source": [
"print(logic.mv_str(transition_responses[:,:5]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Initialization patterns and launch patterns can be filtered by providing a call-back function. This can be used to fill in unassigned values."
]
},
{
"cell_type": "code",
"execution_count": 56,
1 year ago
"metadata": {},
"outputs": [],
"source": [
"import numpy as np\n",
"\n",
1 year ago
"def zero_fill(mva):\n",
" return np.choose(mva, logic.mvarray('0X01PRFN')) # maps '0X-1PRFN' -> '0X01PRFN'\n",
"\n",
1 year ago
"transition_tests_zf = s.tests_loc(b15_prim, init_filter=zero_fill, launch_filter=zero_fill)"
1 year ago
]
},
{
"cell_type": "code",
"execution_count": 57,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"00000000000000000000000000000000000000RFRRRRFRRFRRRR1R00000000RRRRRRRR0000000000000000000000000000000000F0F0000RR1RR0RF00011010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000010101010101010101010101010101010101010101010000000001000000000000000000000000RR0R000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111000001001RF0R000000000000000000000000000000R00000R00000001100000\n",
"00000000000000000000000000000000000000101110011010010110011001110110110000000000000000000000000000000000R0R0000F1FF1001100110010RR0R0R000R0R000R0R0R00000R0R00000R0R00R0RR00RRR0000000000000000000000000000000000000000000000000000000000000000000000000000000F0010FF010F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F000F0F0F0F1111000100100000001000010FR1F1000000000000000000111011110001011011101111100010010001000101010110110011101110000100110000000011000000000000000000000000000000000000011111111111111111111111111111R0F1R0R001RR100FF1000\n",
"000000000000000000000000000000000000000000000000000000000000000FF00F0000000000000000000000000000000000000F00000F11F10FRR00R01111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000R010000000000000000000000000000000000000000000000000111111111111111111111110000010000000000R000R0RF1FFFRFR000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001101000000000000000000000000000000011001010010111111111\n",
"00000000000000000000000000000000000000000000000000000000000000FFRFFFFF00000000000000000000000000000000000RR0000RF01F0RF00001001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000101111111110111111111111111011100000101000000010000010000000000000000000000000000RR0R0000000000000000000000000000000000000000000000000000000000000000000000000101111011011111100000000000000000000000000000000000000000R0R000000000000000000000000000000R0R000R00000001000000\n"
]
}
],
"source": [
1 year ago
"print(logic.mv_str(transition_tests_zf[:,:5]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"### `bp` Arrays\n",
"\n",
"The logic simulator uses bit-parallel storage of logic values, but our loaded test data uses one `uint8` per logic value.\n",
"\n",
"Use `mv_to_bp` to convert mv data to the bit-parallel storage layout.\n",
"Bit-parallel storage is more compact, but individual values cannot be easily accessed anymore."
]
},
{
"cell_type": "code",
"execution_count": 58,
"metadata": {},
"outputs": [],
"source": [
1 year ago
"stuck_tests_bp = logic.mv_to_bp(stuck_tests)"
]
},
{
"cell_type": "code",
"execution_count": 59,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"(528, 3, 85)"
]
},
"execution_count": 59,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stuck_tests_bp.data.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"Instead of 678 bytes per s_node, bit-parallel storage only uses 3*85=255 bytes.\n",
"\n",
"The reverse operation is `bp_to_mv`. Note that the number of vectors may be rounded up to the next multiple of 8:"
]
},
{
"cell_type": "code",
"execution_count": 60,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"(528, 680)"
]
},
"execution_count": 60,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"logic.bp_to_mv(stuck_tests_bp).shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Logic Simulation\n",
"\n",
1 year ago
"The following code performs a 8-valued logic simulation on all 678 vectors for one clock cycle."
]
},
{
"cell_type": "code",
"execution_count": 61,
"metadata": {},
"outputs": [],
"source": [
"from kyupy.logic_sim import LogicSim\n",
"\n",
1 year ago
"sim = LogicSim(b15_prim, sims=stuck_tests.shape[-1]) # 678 simulations in parallel\n",
"sim.s[0] = stuck_tests_bp\n",
"sim.s_to_c()\n",
"sim.c_prop()\n",
"sim.c_to_s()\n",
1 year ago
"sim_responses = logic.bp_to_mv(sim.s[1])[...,:stuck_tests.shape[-1]] # trim from 680 -> 678"
]
},
{
"cell_type": "code",
"execution_count": 62,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------010X110XXX011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"-0101010101010101-0101-01010101010--11--------------------------------001-01-01X01-0101-01-01-01010101---------0001010110000010X01XXXX110XXX110X110XXX110X11001100110X11101010011010X10X1010X1010101010X10X10X1010X10X10X10X101X10101010101010X10X10100X01010101110X00X01000100010001000X000X010001000X010001000X010000000000X10X1010X101010010X10001XX0100X100110000111100001X111111X000011100000X101X01000011110X11X001000011111111X00010101000100010001111011011110110110000011001110101X101010101010X1010X10101010101011X1001101010111111111\n",
"1-11--1-------------1-1------1----1-1---------------------------------0--------X------------------------------101010001101110010011111100000000000000000011000000110000000001000110000000001000XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000001XXX1XXXX1XX010X1X1XXX10110110011111110101001X0X0X0X1X0X1X0X011X0X1X000X1X001X1000101000000000000000000011111001010XXXX1XXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1X11011100011111111XXXXX111XXXXX1X111X0X1X1XXXXXXXXXXXXXXXX0110000100100010100101001011011001100100101100001110101\n",
"0101------------------------------0-0---------------------------------0--------X------------------------------011011X11100000000X0XXXXX0XX0X0X1X0X1X0X0X1XXX1X0X1XXXXXXX0X01X11XXX0X0XX00X0X00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011100110000011000111110011000100XX0011XXXXXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXX0X1XXXXX1XXX1X1X1X1111111111111111101000100XX001000011001XXXXX1XX111111XX1XX11XX111XX011XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0XXXXXXX0X0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX10X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX101110010110110X01010\n",
"1-----0---------------0-----------1-----------------------------------0--------X------------------------------100011001101001100X1X10101X1X1X1X1X1X1X1X1X101X1X1X100X000XXXX0XX00XX1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXXX110X0XX00101X0011001X001X0011001X0X0X010X001X1X0110101X1X1X0X100000000000011XX1X11X1110X1XX1000101111100010X0XX00XXX00X01XXX00X0XXXX00X00XXX11X00XX00000001011X0001X00X01XXX001001XX11100XXX00X00XXX00X00XX01101100011011001011XXXXXXXXXXX0XXXXXXXXXXXXXXX0XX010X1X1X0101000X10XXX\n"
]
}
],
"source": [
1 year ago
"print(logic.mv_str(sim_responses[:,:5]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Compare simulation results to expected fault-free responses loaded from STIL.\n",
"\n",
"The first test fails, because it is a flush test while simulation implicitly assumes a standard test with a capture clock.\n",
"\n",
1 year ago
"The remaining 677 responses should be compatible.\n",
"\n",
"The following checks for compatibility (unknown/unassigned values in STIL always match)."
]
},
{
"cell_type": "code",
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"677"
]
},
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"np.sum(np.min((sim_responses == stuck_responses) | \n",
" (stuck_responses == logic.UNASSIGNED) | \n",
" (stuck_responses == logic.UNKNOWN), axis=0))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Same simulation for the transition-fault test set:"
]
},
{
"cell_type": "code",
"execution_count": 64,
"metadata": {},
"outputs": [],
"source": [
1 year ago
"sim = LogicSim(b15_prim, sims=transition_tests_zf.shape[-1]) # 1147 simulations in parallel\n",
1 year ago
"sim.s[0] = logic.mv_to_bp(transition_tests_zf)\n",
"sim.s_to_c()\n",
"sim.c_prop()\n",
"sim.c_to_s()\n",
1 year ago
"sim_responses = logic.bp_to_mv(sim.s[1])[...,:transition_tests_zf.shape[-1]] # trim to 1147"
]
},
{
"cell_type": "code",
"execution_count": 65,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------0100110001011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"0000000000000000000000000000000000000R--------------------------------00000000000000000000000000000000--------0FNFFNPFRR0PFF01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000NNP0PP00F0FPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPF0F0F0F0FPRP0P0P0PN000000000000000000000000NNPNP000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000RRRRRRRRRRRRRRRRRFFFFFFRRRRRFRRFNPPNP00000000000000000000000000000FPP000NP0000P0NN00000\n",
"01001111111111111111111111111111101010--------------------------------00000000000000000000000000000000--------1PNPRN0PNN0011001PFF0F0F0R0F0F0R0F0F0F0R0R0F0F0R0R0FRFRRFRFFRRFFFR000000000000000PP0PP0PPP00PP00P00000000000000000000000000000000000000000000000P00N0PP0N0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P000P0P0P0PFFFFR00N00N0000000N0000N0PNFPF00000000000000000011101111000101101110111110001001000100010101011011001110111000010011000000001100000000000000000000000000000000PPRPRFFFFFFFFFFFFFFFFFFFFFFFFFFFFFNRRFNRFRRFFFFP0PRF000\n",
"10110000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0PFNP1PPNNPPNPFFNF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000PPPNP00PPNPNPPP0P0P0P0P0P0P0P0P0P0P0P0P0P0P000000000000000000FFFFFFFFFFFFFFFFFFFFFFFR0PPRNR000000000N000N0NPNPPPNPN0P000P0P0P000P0P0P000P0P0P000P0P0P000P0P0PN00P0P0000000000000000000000000000000000000000000000000000000011RFR000000000000000000000000000000F1R0F0F0RFPFFNNNFNFF\n",
"0000000000000000000000000000000000000R--------------------------------00000000000000000000000000000000--------0FRPFPPNRP0RPN00N00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F00PFRNFFFFFFFFPFFFFFFFFFFFFFFFPFFFRRP0RNRN000000RN0000RN000PP0PPPPPPP0P0000000000000NN0N0000000000000000000000000000000000000000000000000000000000000000000000000FRFFFFPFFRFFFFFFPPPPPPPPPPPPPPPP0000000000000000000000000N0N000000000000000000000000000000N0F000N00000PPF00PP00\n"
]
}
],
"source": [
1 year ago
"print(logic.mv_str(sim_responses[:,:5]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The simulator responses contain 'R' for rising transition, 'F' for falling transition, 'P' for possible positive pulse(s) (010) and 'N' for possible negative pulse(s) (101).\n",
"\n",
"We need to map each of these cases to the final logic values before we can compare:"
]
},
{
"cell_type": "code",
"execution_count": 66,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------0100110001011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"00000000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0010010011000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000010000000100000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111110000001111101101001000000000000000000000000000000000000100000001100000\n",
"01001111111111111111111111111111101010--------------------------------00000000000000000000000000000000--------1010110011001100100000000100000100000001010000010100101101001100010000000000000000000000000000000000000000000000000000000000000000000000000000000001000010000000000000000000000000000000000000000000000000000000010010010000000100001001000000000000000000000111011110001011011101111100010010001000101010110110011101110000100110000000011000000000000000000000000000000000010100000000000000000000000000000111011011000000010000\n",
"10110000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0001010011001000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000001010000000000000000000000000000000000000000000000000000000000000000000000001000111000000000100010101000101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001110100000000000000000000000000000001100000100001110100\n",
"00000000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0010000110010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000001100111100000011000011000000000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000000000000000000000101000000000000000000000000000000100000100000000000000\n"
]
}
],
"source": [
1 year ago
"sim_responses_final = np.choose(sim_responses, logic.mvarray('0X-10101')) # maps '0X-1PRFN' -> '0X-10101'\n",
"print(logic.mv_str(sim_responses_final[:,:5]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"Again, first test is a flush test, so we expect 1146 matches.\n",
"\n",
"We simulated zero-filled patterns and therefore have more specified output bits.\n",
"\n",
"The following checks for compatability (unknown/unassigned values in STIL always match)."
]
},
{
"cell_type": "code",
"execution_count": 67,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"1146"
]
},
"execution_count": 67,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"np.sum(np.min((sim_responses_final == transition_responses) | \n",
" (transition_responses == logic.UNASSIGNED) | \n",
" (transition_responses == logic.UNKNOWN), axis=0))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# Working With Delay Information and Timing Simulation"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"Delay data for gates and interconnect can be loaded from SDF files. In kyupy's timing simulators, delays are associated with the lines between nodes, not with the nodes themselves.\n",
"Each line in the circuit has 4 delays for the IOPATH of the reading node;\n",
"one for each combination rising/falling edges at the input and output of that node.\n",
"\n",
"These contents of the SDF file is matched by node names to the original (non-resolved) circuit `b15`. Resolving library cells does not change the line indices, so the resulting array is compatible with `b15_prim`."
]
},
{
"cell_type": "code",
"execution_count": 68,
"metadata": {},
"outputs": [],
"source": [
"from kyupy import sdf\n",
"\n",
1 year ago
"df = sdf.load('../tests/b15_2ig.sdf.gz')\n",
"delays = df.iopaths(b15, tlib=SAED32)[0]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The returned delay information is an `ndarray` with a set of delay values for each line in the circuit."
]
},
{
"cell_type": "code",
"execution_count": 69,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"(32032, 2, 2)"
]
},
"execution_count": 69,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"delays.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Number of non-0 values loaded:"
]
},
{
"cell_type": "code",
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"79010"
]
},
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"(delays != 0).sum()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The available timing simulators are `WaveSim` and `WaveSimCuda`.\n",
"They work similarly to `LogicSim` in that they evaluate all cells in topological order.\n",
"Instead of propagating a logic value, however, they propagate waveforms.\n",
"\n",
"`WaveSim` uses the numba just-in-time compiler for acceleration on CPU.\n",
"It falls back to pure python if numba is not available. `WaveSimCuda` uses numba for GPU acceleration.\n",
"If no CUDA card is available, it will fall back to pure python (not jit-compiled for CPU!).\n",
"Pure python is too slow for most purposes.\n",
"\n",
"Both simulators operate data-parallel.\n",
"The following instanciates a new engine for 32 independent timing simulations and each signal line in the circuit can carry at most 16 transitions. All simulators share the same circuit and the same line delay specification."
]
},
{
"cell_type": "code",
"execution_count": 71,
"metadata": {},
"outputs": [],
"source": [
"from kyupy.wave_sim import WaveSimCuda, TMAX\n",
"\n",
1 year ago
"wsim = WaveSimCuda(b15_prim, delays, sims=32, c_caps=16)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"These are various memories allocated, with waveforms usually being the largest. "
]
},
{
"cell_type": "code",
"execution_count": 72,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
1 year ago
"Waveforms : 66856.0 kiB\n",
"State Allocation Table : 134.3 kiB\n",
"Circuit Timing : 1074.1 kiB\n",
"Circuit Netlist : 1171.2 kiB\n",
1 year ago
"Sequential State : 726.0 kiB\n"
]
}
],
"source": [
"def print_mem(name, arr):\n",
" print(f'{name}: {arr.nbytes / 1024:.1f} kiB')\n",
" \n",
"print_mem('Waveforms ', wsim.c)\n",
1 year ago
"print_mem('State Allocation Table ', wsim.c_locs)\n",
"print_mem('Circuit Timing ', wsim.delays)\n",
"print_mem('Circuit Netlist ', wsim.ops)\n",
"print_mem('Sequential State ', wsim.s)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"This is a typical simulation loop where the number of patterns is larger than the number of simulators available.\n",
1 year ago
"We simulate `transition_tests_zf`.\n",
"The initial values, transition times and final values are loaded into `wsim.s` and the following three calls will update this array with simulation results. We collect all results in `wsim_results`."
]
},
{
"cell_type": "code",
"execution_count": 73,
"metadata": {},
"outputs": [],
"source": [
1 year ago
"from kyupy import batchrange\n",
"import numpy as np\n",
"\n",
1 year ago
"sims = 128 # transition_tests_zf.shape[-1] # Feel free to simulate all tests if CUDA is set up correctly.\n",
"\n",
1 year ago
"wsim_results = np.zeros((11, wsim.s_len, sims)) # space to store all simulation results\n",
"\n",
"for offset, size in batchrange(sims, wsim.sims):\n",
1 year ago
" wsim.s[0] = (transition_tests_zf[:,offset:offset+size] >> 1) & 1 # initial value (bit 1)\n",
1 year ago
" wsim.s[1] = 0.0 # transition time\n",
1 year ago
" wsim.s[2] = transition_tests_zf[:,offset:offset+size] & 1 # final value (bit 0)\n",
1 year ago
" wsim.s_to_c()\n",
" wsim.c_prop(sims=size)\n",
" wsim.c_to_s(time=1.5) # capture at time 1.5\n",
" wsim_results[:,:,offset:offset+size] = wsim.s[:,:,:size]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"The arrays `wsim.s` and `wsim_results` contain various information for each PI, PO, and scan flip-flop (axis 1), and each test (axis 2):\n",
"* ``s[0]`` (P)PI initial value\n",
"* ``s[1]`` (P)PI transition time\n",
"* ``s[2]`` (P)PI final value\n",
"* ``s[3]`` (P)PO initial value\n",
"* ``s[4]`` (P)PO earliest arrival time (EAT): The time at which the output transitioned from its initial value.\n",
"* ``s[5]`` (P)PO latest stabilization time (LST): The time at which the output settled to its final value.\n",
"* ``s[6]`` (P)PO final value\n",
"* ``s[7]`` (P)PO capture value: probability of capturing a 1 at a given capture time\n",
"* ``s[8]`` (P)PO sampled capture value: decided by random sampling according to a given seed.\n",
"* ``s[9]`` (P)PO sampled capture slack: (capture time - LST) - decided by random sampling according to a given seed.\n",
"* ``s[10]`` Overflow indicator: If non-zero, some signals in the input cone of this output had more\n",
" transitions than specified in ``c_caps``. Some transitions have been discarded, the\n",
" final values in the waveforms are still valid."
]
},
{
"cell_type": "code",
"execution_count": 74,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"(11, 528, 128)"
]
},
"execution_count": 74,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"wsim_results.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"For validating against known logic values, convert the samples capture values `wsim_results[8]` into an mvarray like this:"
]
},
{
"cell_type": "code",
"execution_count": 75,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"110011001100110011001100110011001100000000000000000000000000000000000001001100110011001100110011001100000000000100110001011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010010011000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000010000000100000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111110000001111101101001000000000000000000000000000000000000100000001100000\n",
"010011111111111111111111111111111010100000000000000000000000000000000000000000000000000000000000000000000000001010110011001100100000000100000100000001010000010100101101001100010000000000000000000000000000000000000000000000000000000000000000000000000000000001000010000000000000000000000000000000000000000000000000000000010010010000000100001001000000000000000000000111011110001011011101111100010010001000101010110110011101110000100110000000011000000000000000000000000000000000010100000000000000000000000000000111011011000000010000\n",
"101100000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000001010011001000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000001010000000000000000000000000000000000000000000000000000000000000000000000001000111000000000100010101000101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001110100000000000000000000000000000001100000100001110100\n",
"000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010000110010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000001100111100000011000011000000000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000000000000000000000101000000000000000000000000000000100000100000000000000\n"
]
}
],
"source": [
1 year ago
"wsim_responses_final = ((wsim_results[8] > 0.5) * logic.ONE).astype(np.uint8)\n",
"print(logic.mv_str(wsim_responses_final[:,:5]))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"We expect 127 matches here."
]
},
{
"cell_type": "code",
"execution_count": 76,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
1 year ago
"127"
]
},
"execution_count": 76,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"np.sum(np.min((wsim_responses_final == transition_responses[:,:sims]) | \n",
" (transition_responses[:,:sims] == logic.UNASSIGNED) | \n",
" (transition_responses[:,:sims] == logic.UNKNOWN), axis=0))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"The circuit delay is the maximum among all latest stabilization times:"
]
},
{
"cell_type": "code",
"execution_count": 77,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"1.0424000024795532"
]
},
"execution_count": 77,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"wsim_results[5].max()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
1 year ago
"Check for overflows. If too many of them occur, increase `c_caps` during engine instanciation:"
]
},
{
"cell_type": "code",
"execution_count": 78,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.0"
]
},
"execution_count": 78,
1 year ago
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"wsim_results[10].sum()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Check for capture failures by comparing the samples PPO capture value with the final PPO value:"
]
},
{
"cell_type": "code",
"execution_count": 79,
1 year ago
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 79,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
1 year ago
"(wsim_results[6] != wsim_results[8]).sum()"
]
},
{
"cell_type": "code",
"execution_count": null,
"metadata": {},
"outputs": [],
"source": []
}
],
"metadata": {
"kernelspec": {
"display_name": "Python 3 (ipykernel)",
"language": "python",
"name": "python3"
},
"language_info": {
"codemirror_mode": {
"name": "ipython",
"version": 3
},
"file_extension": ".py",
"mimetype": "text/x-python",
"name": "python",
"nbconvert_exporter": "python",
"pygments_lexer": "ipython3",
"version": "3.10.9"
},
"vscode": {
"interpreter": {
"hash": "31f2aee4e71d21fbe5cf8b01ff0e069b9275f58929596ceb00d14d90e3e16cd6"
}
}
},
"nbformat": 4,
"nbformat_minor": 4
}