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.

2313 lines
87 KiB

{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# KyuPy Introduction\n",
"\n",
2 years ago
"This notebook introduces KyuPy's basic data structures and built-in functions step-by-step.\n",
"\n",
2 years ago
"## Working With Gate-Level Circuit Structures\n",
"\n",
2 years ago
"KyuPy has two parser modules:\n",
"\n",
2 years 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",
2 years ago
"Files can be loaded using `.load(file)`, strings can be parsed using `.parse(text)`."
]
},
{
"cell_type": "code",
"execution_count": 1,
"metadata": {},
2 years ago
"outputs": [],
"source": [
"from kyupy import bench, verilog\n",
"\n",
"# load a file\n",
2 years ago
"b15 = verilog.load('../tests/b15_2ig.v.gz')\n",
"\n",
"# ... or specify the circuit as string \n",
"adder = bench.parse('''\n",
"INPUT(a, b)\n",
"OUTPUT(s)\n",
"cin = DFF(cout)\n",
"axb = XOR(a, b)\n",
"s = XOR(axb, cin)\n",
"aab = AND(a, b)\n",
"axbacin = AND(axb, cin)\n",
"cout = OR(aab, axbacin)\n",
"''', name='adder')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years 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": [
2 years ago
"kyupy.circuit.Circuit"
]
},
"execution_count": 2,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"type(b15)"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"{name: \"b15\", cells: 10789, forks: 10749, lines: 32032, io_nodes: 111}"
]
},
"execution_count": 3,
"metadata": {},
"output_type": "execute_result"
}
],
2 years ago
"source": [
"b15"
]
},
{
"cell_type": "code",
"execution_count": 4,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{name: \"adder\", cells: 6, forks: 8, lines: 17, io_nodes: 3}"
]
},
"execution_count": 4,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years ago
"The `.stats` property returns a dictionary with more detailed statistics on the elements in the circuit."
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"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}"
]
},
"execution_count": 5,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"b15.stats"
]
},
{
"cell_type": "code",
"execution_count": 6,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'__node__': 14,\n",
" '__cell__': 6,\n",
" '__fork__': 8,\n",
" '__io__': 3,\n",
" '__line__': 17,\n",
" 'DFF': 1,\n",
" '__dff__': 1,\n",
" 'XOR': 2,\n",
" '__comb__': 5,\n",
" 'AND': 2,\n",
" 'OR': 1,\n",
" '__latch__': 0,\n",
" '__seq__': 1}"
]
},
"execution_count": 6,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.stats"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Circuits contain `cells`, `forks`, `lines`, and `io_nodes`. Let's explore these...\n",
"\n",
"### Cells and Forks\n",
"\n",
2 years ago
"`cells` and `forks` are dictionaries that map names to `Node`-objects."
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 7,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'cin': 4:DFF\"cin\" <1 >0,\n",
" 'axb': 6:XOR\"axb\" <3 <4 >2,\n",
" 's': 8:XOR\"s\" <6 <7 >5,\n",
" 'aab': 9:AND\"aab\" <9 <10 >8,\n",
" 'axbacin': 11:AND\"axbacin\" <12 <13 >11,\n",
" 'cout': 13:OR\"cout\" <15 <16 >14}"
]
},
2 years ago
"execution_count": 7,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 8,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"{'a': 0:__fork__\"a\" >3 >9,\n",
" 'b': 1:__fork__\"b\" >4 >10,\n",
" 's': 2:__fork__\"s\" <5 ,\n",
" 'cout': 3:__fork__\"cout\" <14 >1,\n",
" 'cin': 5:__fork__\"cin\" <0 >7 >13,\n",
" 'axb': 7:__fork__\"axb\" <2 >6 >12,\n",
" 'aab': 10:__fork__\"aab\" <8 >15,\n",
" 'axbacin': 12:__fork__\"axbacin\" <11 >16}"
]
},
2 years ago
"execution_count": 8,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.forks"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years ago
"Access any cell or fork by name using a simple dictionary lookup:"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 9,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"6:XOR\"axb\" <3 <4 >2"
]
},
2 years ago
"execution_count": 9,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells['axb']"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 10,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"7:__fork__\"axb\" <2 >6 >12"
]
},
2 years ago
"execution_count": 10,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.forks['axb']"
]
},
{
"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",
2 years ago
"execution_count": 11,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(6, 'XOR', 'axb')"
]
},
2 years ago
"execution_count": 11,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells['axb'].index, adder.cells['axb'].kind, adder.cells['axb'].name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"*Forks* are `Node`-objects of the special kind `__fork__`.\n",
"\n",
2 years 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",
2 years ago
"execution_count": 12,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(7, '__fork__', 'axb')"
]
},
2 years ago
"execution_count": 12,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.forks['axb'].index, adder.forks['axb'].kind, adder.forks['axb'].name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years ago
"The `index` of a *node* in a circuit is a unique and consecutive integer.\n",
"\n",
2 years 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",
2 years ago
"execution_count": 13,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0:__fork__\"a\" >3 >9,\n",
" 1:__fork__\"b\" >4 >10,\n",
" 2:__fork__\"s\" <5 ,\n",
" 3:__fork__\"cout\" <14 >1,\n",
" 4:DFF\"cin\" <1 >0,\n",
" 5:__fork__\"cin\" <0 >7 >13,\n",
" 6:XOR\"axb\" <3 <4 >2,\n",
" 7:__fork__\"axb\" <2 >6 >12,\n",
" 8:XOR\"s\" <6 <7 >5,\n",
" 9:AND\"aab\" <9 <10 >8,\n",
" 10:__fork__\"aab\" <8 >15,\n",
" 11:AND\"axbacin\" <12 <13 >11,\n",
" 12:__fork__\"axbacin\" <11 >16,\n",
" 13:OR\"cout\" <15 <16 >14]"
]
},
2 years ago
"execution_count": 13,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.nodes"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 14,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(6:XOR\"axb\" <3 <4 >2, 7:__fork__\"axb\" <2 >6 >12)"
]
},
2 years ago
"execution_count": 14,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.nodes[6], adder.nodes[7]"
]
},
2 years 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",
"execution_count": 15,
"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",
"execution_count": 16,
"metadata": {
"tags": []
},
"outputs": [],
"source": [
"weights[adder.cells['axb']] = 5"
]
},
{
"cell_type": "code",
"execution_count": 17,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0, 0, 0, 0, 0, 0, 5, 0, 0, 0, 0, 0, 0, 0]"
]
},
"execution_count": 17,
"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",
2 years ago
"execution_count": 18,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16]"
]
},
2 years ago
"execution_count": 18,
"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",
2 years ago
"execution_count": 19,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(6:XOR\"axb\" <3 <4 >2, 7:__fork__\"axb\" <2 >6 >12)"
]
},
2 years ago
"execution_count": 19,
"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",
2 years ago
"execution_count": 20,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"([3, 4], [2])"
]
},
2 years ago
"execution_count": 20,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells['axb'].ins, adder.cells['axb'].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",
2 years ago
"execution_count": 21,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(0, 0, 1)"
]
},
2 years ago
"execution_count": 21,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.lines[2].driver_pin, adder.lines[2].reader_pin, adder.lines[4].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",
2 years ago
"execution_count": 22,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0:__fork__\"a\" >3 >9, 1:__fork__\"b\" >4 >10, 2:__fork__\"s\" <5 ]"
]
},
2 years ago
"execution_count": 22,
"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",
2 years ago
"execution_count": 23,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0:__fork__\"a\" >3 >9,\n",
" 1:__fork__\"b\" >4 >10,\n",
" 2:__fork__\"s\" <5 ,\n",
" 4:DFF\"cin\" <1 >0]"
]
},
2 years ago
"execution_count": 23,
"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",
2 years ago
"execution_count": 24,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"6:XOR\"axb\" <3 <4 >2"
]
},
2 years ago
"execution_count": 24,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.io_nodes[0].outs[0].reader"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 25,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"6:XOR\"axb\" <3 <4 >2\n",
"9:AND\"aab\" <9 <10 >8\n"
]
}
],
"source": [
"for line in adder.io_nodes[0].outs:\n",
" print(line.reader)"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 26,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"'cout'"
]
},
2 years ago
"execution_count": 26,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"adder.cells['cin'].ins[0].driver.name"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years ago
"Let's continue with `b15` loaded before. It has 111 io_nodes:"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 27,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years 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 ])"
]
},
2 years ago
"execution_count": 27,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"b15, b15.io_nodes[:20]"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"and even more sequential nodes:"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 28,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"528"
]
},
2 years ago
"execution_count": 28,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"len(b15.s_nodes)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years 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",
2 years ago
"execution_count": 29,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"107"
]
},
2 years ago
"execution_count": 29,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"b15.io_locs('RESET')"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 30,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years 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]"
]
},
2 years ago
"execution_count": 30,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"b15.io_locs('Address')"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Example of a two-dimensional register file (16 8-bit registers):"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 31,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years 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]]"
]
},
2 years ago
"execution_count": 31,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"b15.s_locs('InstQueue_reg')"
]
},
{
"cell_type": "code",
"execution_count": 32,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"---------------\n",
"1385:SDFFARX1_RVT\"InstQueue_reg_0__0_\" <12704 <12706 <12705 <12707 <12708 >702\n",
"1383:SDFFARX1_RVT\"InstQueue_reg_0__1_\" <12699 <12701 <12700 <12702 <12703 >701\n",
"1387:SDFFARX1_RVT\"InstQueue_reg_0__2_\" <12709 <12711 <12710 <12712 <12713 >703\n",
"1381:SDFFARX1_RVT\"InstQueue_reg_0__3_\" <12694 <12696 <12695 <12697 <12698 >700\n",
"1389:SDFFARX1_RVT\"InstQueue_reg_0__4_\" <12714 <12716 <12715 <12717 <12718 >704\n",
"1379:SDFFARX1_RVT\"InstQueue_reg_0__5_\" <12689 <12691 <12690 <12692 <12693 >699\n",
"1391:SDFFARX1_RVT\"InstQueue_reg_0__6_\" <12719 <12721 <12720 <12722 <12723 >705\n",
"1377:SDFFARX1_RVT\"InstQueue_reg_0__7_\" <12684 <12686 <12685 <12687 <12688 >698\n",
"---------------\n",
"1401:SDFFARX1_RVT\"InstQueue_reg_1__0_\" <12744 <12746 <12745 <12747 <12748 >710\n",
"1399:SDFFARX1_RVT\"InstQueue_reg_1__1_\" <12739 <12741 <12740 <12742 <12743 >709\n",
"1403:SDFFARX1_RVT\"InstQueue_reg_1__2_\" <12749 <12751 <12750 <12752 <12753 >711\n",
"1397:SDFFARX1_RVT\"InstQueue_reg_1__3_\" <12734 <12736 <12735 <12737 <12738 >708\n",
"1405:SDFFARX1_RVT\"InstQueue_reg_1__4_\" <12754 <12756 <12755 <12757 <12758 >712\n",
"1395:SDFFARX1_RVT\"InstQueue_reg_1__5_\" <12729 <12731 <12730 <12732 <12733 >707\n",
"1407:SDFFARX1_RVT\"InstQueue_reg_1__6_\" <12759 <12761 <12760 <12762 <12763 >713\n",
"1393:SDFFARX1_RVT\"InstQueue_reg_1__7_\" <12724 <12726 <12725 <12727 <12728 >706\n",
"---------------\n",
"1417:SDFFARX1_RVT\"InstQueue_reg_2__0_\" <12784 <12786 <12785 <12787 <12788 >718\n",
"1415:SDFFARX1_RVT\"InstQueue_reg_2__1_\" <12779 <12781 <12780 <12782 <12783 >717\n",
"1419:SDFFARX1_RVT\"InstQueue_reg_2__2_\" <12789 <12791 <12790 <12792 <12793 >719\n",
"1413:SDFFARX1_RVT\"InstQueue_reg_2__3_\" <12774 <12776 <12775 <12777 <12778 >716\n",
"1421:SDFFARX1_RVT\"InstQueue_reg_2__4_\" <12794 <12796 <12795 <12797 <12798 >720\n",
"1411:SDFFARX1_RVT\"InstQueue_reg_2__5_\" <12769 <12771 <12770 <12772 <12773 >715\n",
"1423:SDFFARX1_RVT\"InstQueue_reg_2__6_\" <12799 <12801 <12800 <12802 <12803 >721\n",
"1409:SDFFARX1_RVT\"InstQueue_reg_2__7_\" <12764 <12766 <12765 <12767 <12768 >714\n",
"---------------\n",
"1433:SDFFARX1_RVT\"InstQueue_reg_3__0_\" <12824 <12826 <12825 <12827 <12828 >726\n",
"1431:SDFFARX1_RVT\"InstQueue_reg_3__1_\" <12819 <12821 <12820 <12822 <12823 >725\n",
"1435:SDFFARX1_RVT\"InstQueue_reg_3__2_\" <12829 <12831 <12830 <12832 <12833 >727\n",
"1429:SDFFARX1_RVT\"InstQueue_reg_3__3_\" <12814 <12816 <12815 <12817 <12818 >724\n",
"1437:SDFFARX1_RVT\"InstQueue_reg_3__4_\" <12834 <12836 <12835 <12837 <12838 >728\n",
"1427:SDFFARX1_RVT\"InstQueue_reg_3__5_\" <12809 <12811 <12810 <12812 <12813 >723\n",
"1439:SDFFARX1_RVT\"InstQueue_reg_3__6_\" <12839 <12841 <12840 <12842 <12843 >729\n",
"1425:SDFFARX1_RVT\"InstQueue_reg_3__7_\" <12804 <12806 <12805 <12807 <12808 >722\n",
"---------------\n",
"1449:SDFFARX1_RVT\"InstQueue_reg_4__0_\" <12864 <12866 <12865 <12867 <12868 >734\n",
"1447:SDFFARX1_RVT\"InstQueue_reg_4__1_\" <12859 <12861 <12860 <12862 <12863 >733\n",
"1451:SDFFARX1_RVT\"InstQueue_reg_4__2_\" <12869 <12871 <12870 <12872 <12873 >735\n",
"1445:SDFFARX1_RVT\"InstQueue_reg_4__3_\" <12854 <12856 <12855 <12857 <12858 >732\n",
"1453:SDFFARX1_RVT\"InstQueue_reg_4__4_\" <12874 <12876 <12875 <12877 <12878 >736\n",
"1443:SDFFARX1_RVT\"InstQueue_reg_4__5_\" <12849 <12851 <12850 <12852 <12853 >731\n",
"1455:SDFFARX1_RVT\"InstQueue_reg_4__6_\" <12879 <12881 <12880 <12882 <12883 >737\n",
"1441:SDFFARX1_RVT\"InstQueue_reg_4__7_\" <12844 <12846 <12845 <12847 <12848 >730\n",
"---------------\n",
"1465:SDFFARX1_RVT\"InstQueue_reg_5__0_\" <12904 <12906 <12905 <12907 <12908 >742\n",
"1463:SDFFARX1_RVT\"InstQueue_reg_5__1_\" <12899 <12901 <12900 <12902 <12903 >741\n",
"1467:SDFFARX1_RVT\"InstQueue_reg_5__2_\" <12909 <12911 <12910 <12912 <12913 >743\n",
"1461:SDFFARX1_RVT\"InstQueue_reg_5__3_\" <12894 <12896 <12895 <12897 <12898 >740\n",
"1469:SDFFARX1_RVT\"InstQueue_reg_5__4_\" <12914 <12916 <12915 <12917 <12918 >744\n",
"1459:SDFFARX1_RVT\"InstQueue_reg_5__5_\" <12889 <12891 <12890 <12892 <12893 >739\n",
"1471:SDFFARX1_RVT\"InstQueue_reg_5__6_\" <12919 <12921 <12920 <12922 <12923 >745\n",
"1457:SDFFARX1_RVT\"InstQueue_reg_5__7_\" <12884 <12886 <12885 <12887 <12888 >738\n",
"---------------\n",
"1481:SDFFARX1_RVT\"InstQueue_reg_6__0_\" <12944 <12946 <12945 <12947 <12948 >750\n",
"1479:SDFFARX1_RVT\"InstQueue_reg_6__1_\" <12939 <12941 <12940 <12942 <12943 >749\n",
"1483:SDFFARX1_RVT\"InstQueue_reg_6__2_\" <12949 <12951 <12950 <12952 <12953 >751\n",
"1477:SDFFARX1_RVT\"InstQueue_reg_6__3_\" <12934 <12936 <12935 <12937 <12938 >748\n",
"1485:SDFFARX1_RVT\"InstQueue_reg_6__4_\" <12954 <12956 <12955 <12957 <12958 >752\n",
"1475:SDFFARX1_RVT\"InstQueue_reg_6__5_\" <12929 <12931 <12930 <12932 <12933 >747\n",
"1487:SDFFARX1_RVT\"InstQueue_reg_6__6_\" <12959 <12961 <12960 <12962 <12963 >753\n",
"1473:SDFFARX1_RVT\"InstQueue_reg_6__7_\" <12924 <12926 <12925 <12927 <12928 >746\n",
"---------------\n",
"1497:SDFFARX1_RVT\"InstQueue_reg_7__0_\" <12984 <12986 <12985 <12987 <12988 >758\n",
"1495:SDFFARX1_RVT\"InstQueue_reg_7__1_\" <12979 <12981 <12980 <12982 <12983 >757\n",
"1499:SDFFARX1_RVT\"InstQueue_reg_7__2_\" <12989 <12991 <12990 <12992 <12993 >759\n",
"1493:SDFFARX1_RVT\"InstQueue_reg_7__3_\" <12974 <12976 <12975 <12977 <12978 >756\n",
"1501:SDFFARX1_RVT\"InstQueue_reg_7__4_\" <12994 <12996 <12995 <12997 <12998 >760\n",
"1491:SDFFARX1_RVT\"InstQueue_reg_7__5_\" <12969 <12971 <12970 <12972 <12973 >755\n",
"1503:SDFFARX1_RVT\"InstQueue_reg_7__6_\" <12999 <13001 <13000 <13002 <13003 >761\n",
"1489:SDFFARX1_RVT\"InstQueue_reg_7__7_\" <12964 <12966 <12965 <12967 <12968 >754\n",
"---------------\n",
"1513:SDFFARX1_RVT\"InstQueue_reg_8__0_\" <13024 <13026 <13025 <13027 <13028 >766\n",
"1511:SDFFARX1_RVT\"InstQueue_reg_8__1_\" <13019 <13021 <13020 <13022 <13023 >765\n",
"1515:SDFFARX1_RVT\"InstQueue_reg_8__2_\" <13029 <13031 <13030 <13032 <13033 >767 >768\n",
"1509:SDFFARX1_RVT\"InstQueue_reg_8__3_\" <13014 <13016 <13015 <13017 <13018 >764\n",
"1518:SDFFARX1_RVT\"InstQueue_reg_8__4_\" <13034 <13036 <13035 <13037 <13038 >769\n",
"1507:SDFFARX1_RVT\"InstQueue_reg_8__5_\" <13009 <13011 <13010 <13012 <13013 >763\n",
"1520:SDFFARX1_RVT\"InstQueue_reg_8__6_\" <13039 <13041 <13040 <13042 <13043 >770\n",
"1505:SDFFARX1_RVT\"InstQueue_reg_8__7_\" <13004 <13006 <13005 <13007 <13008 >762\n",
"---------------\n",
"1530:SDFFARX1_RVT\"InstQueue_reg_9__0_\" <13064 <13066 <13065 <13067 <13068 >775\n",
"1528:SDFFARX1_RVT\"InstQueue_reg_9__1_\" <13059 <13061 <13060 <13062 <13063 >774\n",
"1532:SDFFARX1_RVT\"InstQueue_reg_9__2_\" <13069 <13071 <13070 <13072 <13073 >776\n",
"1526:SDFFARX1_RVT\"InstQueue_reg_9__3_\" <13054 <13056 <13055 <13057 <13058 >773\n",
"1534:SDFFARX1_RVT\"InstQueue_reg_9__4_\" <13074 <13076 <13075 <13077 <13078 >777\n",
"1524:SDFFARX1_RVT\"InstQueue_reg_9__5_\" <13049 <13051 <13050 <13052 <13053 >772\n",
"1536:SDFFARX1_RVT\"InstQueue_reg_9__6_\" <13079 <13081 <13080 <13082 <13083 >778\n",
"1522:SDFFARX1_RVT\"InstQueue_reg_9__7_\" <13044 <13046 <13045 <13047 <13048 >771\n",
"---------------\n",
"1546:SDFFARX1_RVT\"InstQueue_reg_10__0_\" <13104 <13106 <13105 <13107 <13108 >783\n",
"1544:SDFFARX1_RVT\"InstQueue_reg_10__1_\" <13099 <13101 <13100 <13102 <13103 >782\n",
"1548:SDFFARX1_RVT\"InstQueue_reg_10__2_\" <13109 <13111 <13110 <13112 <13113 >784\n",
"1542:SDFFARX1_RVT\"InstQueue_reg_10__3_\" <13094 <13096 <13095 <13097 <13098 >781\n",
"1550:SDFFARX1_RVT\"InstQueue_reg_10__4_\" <13114 <13116 <13115 <13117 <13118 >785 >786\n",
"1540:SDFFARX1_RVT\"InstQueue_reg_10__5_\" <13089 <13091 <13090 <13092 <13093 >780\n",
"1553:SDFFARX1_RVT\"InstQueue_reg_10__6_\" <13119 <13121 <13120 <13122 <13123 >787\n",
"1538:SDFFARX1_RVT\"InstQueue_reg_10__7_\" <13084 <13086 <13085 <13087 <13088 >779\n",
"---------------\n",
"1563:SDFFARX1_RVT\"InstQueue_reg_11__0_\" <13144 <13146 <13145 <13147 <13148 >792\n",
"1561:SDFFARX1_RVT\"InstQueue_reg_11__1_\" <13139 <13141 <13140 <13142 <13143 >791\n",
"1565:SDFFARX1_RVT\"InstQueue_reg_11__2_\" <13149 <13151 <13150 <13152 <13153 >793\n",
"1559:SDFFARX1_RVT\"InstQueue_reg_11__3_\" <13134 <13136 <13135 <13137 <13138 >790\n",
"1567:SDFFARX1_RVT\"InstQueue_reg_11__4_\" <13154 <13156 <13155 <13157 <13158 >794\n",
"1557:SDFFARX1_RVT\"InstQueue_reg_11__5_\" <13129 <13131 <13130 <13132 <13133 >789\n",
"1569:SDFFARX1_RVT\"InstQueue_reg_11__6_\" <13159 <13161 <13160 <13162 <13163 >795\n",
"1555:SDFFARX1_RVT\"InstQueue_reg_11__7_\" <13124 <13126 <13125 <13127 <13128 >788\n",
"---------------\n",
"1579:SDFFARX1_RVT\"InstQueue_reg_12__0_\" <13184 <13186 <13185 <13187 <13188 >800\n",
"1577:SDFFARX1_RVT\"InstQueue_reg_12__1_\" <13179 <13181 <13180 <13182 <13183 >799\n",
"1581:SDFFARX1_RVT\"InstQueue_reg_12__2_\" <13189 <13191 <13190 <13192 <13193 >801\n",
"1575:SDFFARX1_RVT\"InstQueue_reg_12__3_\" <13174 <13176 <13175 <13177 <13178 >798\n",
"1583:SDFFARX1_RVT\"InstQueue_reg_12__4_\" <13194 <13196 <13195 <13197 <13198 >802\n",
"1573:SDFFARX1_RVT\"InstQueue_reg_12__5_\" <13169 <13171 <13170 <13172 <13173 >797\n",
"1585:SDFFARX1_RVT\"InstQueue_reg_12__6_\" <13199 <13201 <13200 <13202 <13203 >803\n",
"1571:SDFFARX1_RVT\"InstQueue_reg_12__7_\" <13164 <13166 <13165 <13167 <13168 >796\n",
"---------------\n",
"1595:SDFFARX1_RVT\"InstQueue_reg_13__0_\" <13224 <13226 <13225 <13227 <13228 >808\n",
"1593:SDFFARX1_RVT\"InstQueue_reg_13__1_\" <13219 <13221 <13220 <13222 <13223 >807\n",
"1597:SDFFARX1_RVT\"InstQueue_reg_13__2_\" <13229 <13231 <13230 <13232 <13233 >809\n",
"1591:SDFFARX1_RVT\"InstQueue_reg_13__3_\" <13214 <13216 <13215 <13217 <13218 >806\n",
"1599:SDFFARX1_RVT\"InstQueue_reg_13__4_\" <13234 <13236 <13235 <13237 <13238 >810\n",
"1589:SDFFARX1_RVT\"InstQueue_reg_13__5_\" <13209 <13211 <13210 <13212 <13213 >805\n",
"1601:SDFFARX1_RVT\"InstQueue_reg_13__6_\" <13239 <13241 <13240 <13242 <13243 >811\n",
"1587:SDFFARX1_RVT\"InstQueue_reg_13__7_\" <13204 <13206 <13205 <13207 <13208 >804\n",
"---------------\n",
"1611:SDFFARX1_RVT\"InstQueue_reg_14__0_\" <13264 <13266 <13265 <13267 <13268 >816\n",
"1609:SDFFARX1_RVT\"InstQueue_reg_14__1_\" <13259 <13261 <13260 <13262 <13263 >815\n",
"1613:SDFFARX1_RVT\"InstQueue_reg_14__2_\" <13269 <13271 <13270 <13272 <13273 >817\n",
"1607:SDFFARX1_RVT\"InstQueue_reg_14__3_\" <13254 <13256 <13255 <13257 <13258 >814\n",
"1615:SDFFARX1_RVT\"InstQueue_reg_14__4_\" <13274 <13276 <13275 <13277 <13278 >818\n",
"1605:SDFFARX1_RVT\"InstQueue_reg_14__5_\" <13249 <13251 <13250 <13252 <13253 >813\n",
"1617:SDFFARX1_RVT\"InstQueue_reg_14__6_\" <13279 <13281 <13280 <13282 <13283 >819\n",
"1603:SDFFARX1_RVT\"InstQueue_reg_14__7_\" <13244 <13246 <13245 <13247 <13248 >812\n",
"---------------\n",
"1627:SDFFARX1_RVT\"InstQueue_reg_15__0_\" <13304 <13306 <13305 <13307 <13308 >824\n",
"1625:SDFFARX1_RVT\"InstQueue_reg_15__1_\" <13299 <13301 <13300 <13302 <13303 >823\n",
"1629:SDFFARX1_RVT\"InstQueue_reg_15__2_\" <13309 <13311 <13310 <13312 <13313 >825\n",
"1623:SDFFARX1_RVT\"InstQueue_reg_15__3_\" <13294 <13296 <13295 <13297 <13298 >822\n",
"1631:SDFFARX1_RVT\"InstQueue_reg_15__4_\" <13314 <13316 <13315 <13317 <13318 >826\n",
"1621:SDFFARX1_RVT\"InstQueue_reg_15__5_\" <13289 <13291 <13290 <13292 <13293 >821\n",
"1633:SDFFARX1_RVT\"InstQueue_reg_15__6_\" <13319 <13321 <13320 <13322 <13323 >827\n",
"1619:SDFFARX1_RVT\"InstQueue_reg_15__7_\" <13284 <13286 <13285 <13287 <13288 >820\n"
]
}
],
"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": [
2 years 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",
"When we encounter a scan cell \"SDFF\", we continue with the \"SI\" pin, which has index 2."
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 33,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years 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": [
2 years ago
"chain = [cell := b15.cells['test_so000']]\n",
"while len(cell.ins) > 0:\n",
" chain.append(cell := cell.ins[2 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": [
2 years 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",
2 years ago
"execution_count": 34,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"0:__fork__\"a\" >3 >9\n",
"1:__fork__\"b\" >4 >10\n",
"4:DFF\"cin\" <1 >0\n",
"6:XOR\"axb\" <3 <4 >2\n",
"9:AND\"aab\" <9 <10 >8\n",
"5:__fork__\"cin\" <0 >7 >13\n",
"7:__fork__\"axb\" <2 >6 >12\n",
"10:__fork__\"aab\" <8 >15\n",
"8:XOR\"s\" <6 <7 >5\n",
"11:AND\"axbacin\" <12 <13 >11\n",
"2:__fork__\"s\" <5 \n",
"12:__fork__\"axbacin\" <11 >16\n",
"13:OR\"cout\" <15 <16 >14\n",
"3:__fork__\"cout\" <14 >1\n"
]
}
],
"source": [
"for n in adder.topological_order():\n",
" print(n)"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years 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",
2 years ago
"execution_count": 35,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"Maximum logic depth: 44\n"
]
}
],
"source": [
"import numpy as np\n",
"\n",
2 years ago
"levels = np.zeros(len(b15.nodes), dtype=np.uint32) # array to store level for each node.\n",
"\n",
2 years ago
"for n in b15.topological_order():\n",
" if 'DFF' in n.kind or len(n.ins) == 0:\n",
2 years 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",
2 years ago
"execution_count": 36,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years 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",
2 years 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 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",
2 years ago
"execution_count": 37,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"[0:__fork__\"a\" >3 >9,\n",
" 1:__fork__\"b\" >4 >10,\n",
" 2:__fork__\"s\" <5 ,\n",
" 4:DFF\"cin\" <1 >0]"
]
},
2 years ago
"execution_count": 37,
"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",
2 years 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",
2 years ago
"execution_count": 38,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"array([[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)"
]
},
2 years ago
"execution_count": 38,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"from kyupy import logic\n",
"\n",
2 years ago
"inputs = logic.mvarray('00-0', '10-0', '01-0', '11-0', '00-1', '10-1', '01-1', '11-1')\n",
"inputs"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"The numeric values in this array are defined in `kyupy.logic`.\n",
2 years 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",
2 years ago
"execution_count": 39,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"(4, 8)"
]
},
2 years ago
"execution_count": 39,
"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",
2 years ago
"execution_count": 40,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"00-0\n",
"10-0\n",
"01-0\n",
"11-0\n",
"00-1\n",
"10-1\n",
"01-1\n",
"11-1\n"
]
}
],
"source": [
2 years ago
"print(logic.mv_str(inputs))"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years ago
"Load a stuck-at fault test pattern set and expected fault-free responses from a STIL file. It contains 678 test vectors."
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 41,
"metadata": {},
"outputs": [],
"source": [
"from kyupy import stil\n",
"\n",
2 years ago
"s = stil.load('../tests/b15_2ig.sa_nf.stil.gz')\n",
"stuck_tests = s.tests(b15)\n",
"stuck_responses = s.responses(b15)"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 42,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"528"
]
},
2 years ago
"execution_count": 42,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"len(b15.s_nodes)"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 43,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"(528, 678)"
]
},
2 years ago
"execution_count": 43,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stuck_tests.shape"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 44,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"(528, 678)"
]
},
2 years ago
"execution_count": 44,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stuck_responses.shape"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 45,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"------------------------------------------------------------------------------------------------------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": [
2 years ago
"print(logic.mv_str(stuck_tests[:,:5]))"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 46,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------0000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"X0101010101010101X0101X01010101010XX11--------------------------------001X01X01X01X0101X01X01X01010101--------X0001010110000010X01XXXX110XXX110X110XXX110X11001100110X11101010011010X10X1010X1010101010X10X10X1010X10X10X10X101X10101010101010X10X10100X01010101110X00X01000100010001000X000X010001000X010001000X010000000000X10X1010X101010010X10001XX0100X100110000111100001X111111X000011100000X101X01000011110X11X001000011111111X00010101000100010001111011011110110110000011001110101X101010101010X1010X10101010101011X1001101010111111111\n",
"1X11XX1XXXXXXXXXXXXX1X1XXXXXX1XXXX1X1X--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------101010001101110010011111100000000000000000011000000110000000001000110000000001000XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000000001XXX1XXXX1XX010X1X1XXX10110110011111110101001X0X0X0X1X0X1X0X011X0X1X000X1X001X1000101000000000000000000011111001010XXXX1XXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1X11011100011111111XXXXX111XXXXX1X111X0X1X1XXXXXXXXXXXXXXXX0110000100100010100101001011011001100100101100001110101\n",
"0101XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0X0X--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------011011X11100000000X0XXXXX0XX0X0X1X0X1X0X0X1XXX1X0X1XXXXXXX0X01X11XXX0X0XX00X0X00XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011100110000011000111110011000100XX0011XXXXXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXX0X1XXXXX1XXX1X1X1X1111111111111111101000100XX001000011001XXXXX1XX111111XX1XX11XX111XX011XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0XXXXXXX0X0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX10X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX101110010110110X01010\n",
"1XXXXX0XXXXXXXXXXXXXXX0XXXXXXXXXXX1XXX--------------------------------0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX--------100011001101001100X1X10101X1X1X1X1X1X1X1X1X101X1X1X100X000XXXX0XX00XX1X0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXXX110X0XX00101X0011001X001X0011001X0X0X010X001X1X0110101X1X1X0X100000000000011XX1X11X1110X1XX1000101111100010X0XX00XXX00X01XXX00X0XXXX00X00XXX11X00XX00000001011X0001X00X01XXX001001XX11100XXX00X00XXX00X00XX01101100011011001011XXXXXXXXXXX0XXXXXXXXXXXXXXX0XX010X1X1X0101000X10XXX\n"
]
}
],
"source": [
2 years 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",
2 years 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",
2 years ago
"execution_count": 47,
"metadata": {},
"outputs": [],
"source": [
2 years ago
"s = stil.load('../tests/b15_2ig.tf_nf.stil.gz')\n",
"transition_tests = s.tests_loc(b15)\n",
"transition_responses = s.responses(b15)"
]
},
{
"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",
2 years ago
"execution_count": 48,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"------------------------------------------------------------------------------------------------------X----XX--000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"--------------------------------------RFRRRRFRRFRRRR1R--------RXXRXRRR--------------------------------00F0F00--RR1RRXRF00011010XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011X00XXX101X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X1X0XXXXXXX1XXXXXXXXXXXXXXXXXXXXXXXXRRXRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX00000000000000000111111000001001RFXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX11XXXXX\n",
"--------------------------------------1X111XX11X1XX1X11XX11XX111X11X11--------------------------------0-XXR00--F1FF1X0110011X01XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXFXX1XFFX1XFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFXFX0XFXFXFXF11110XX1XX1XXXXXXX1XXXX1XFR1F1XXXXXXXXXXXXXXXXX011101111000101101110111110001001000100010101011011001110111000X1XX11XXXXXXXX11XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX000X011111111111111111111111111111R0F1R0R001RR100FF1XXX\n",
"--------------------------------------------------------------XXXXXXXX--------------------------------0--FX00--F11F1XFRR00R01111XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0XX1XXXXXRX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX111111111111111111111110X0XX10XXXXXXXXXRXXXRXRF1FFFRFRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXXXXXXXXX0XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX11X1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXX011001010010111111111\n",
"--------------------------------------------------------------FFXFFFFF--------------------------------0XXRR00--RF01FXRF00001XX1XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX010X010111111111X111111111111111X11100XX0101XXXXXX01XXXX01XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1X1111X110111111XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX0RXRXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX1XXXXXX\n"
]
}
],
"source": [
2 years ago
"print(logic.mv_str(transition_tests[:,:5]))"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 49,
"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"
]
}
],
"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": 50,
"metadata": {},
"outputs": [],
"source": [
"def zero_fill(mva):\n",
" return np.choose(mva, logic.mvarray('0X01PRFN')) # maps '0X-1PRFN' -> '0X01PRFN'\n",
"\n",
"transition_tests_zf = s.tests_loc(b15, init_filter=zero_fill, launch_filter=zero_fill)"
]
},
{
"cell_type": "code",
"execution_count": 51,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110110011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"00000000000000000000000000000000000000RFRRRRFRRFRRRR1R00000000RRRRRRRR0000000000000000000000000000000000F0F0000RR1RR0RF00011010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000010101010101010101010101010101010101010101010000000001000000000000000000000000RR0R000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111000001001RF0R000000000000000000000000000000R00000R00000001100000\n",
"00000000000000000000000000000000000000101110011010010110011001110110110000000000000000000000000000000000R0R0000F1FF1001100110010RR0R0R000R0R000R0R0R00000R0R00000R0R00R0RR00RRR0000000000000000000000000000000000000000000000000000000000000000000000000000000F0010FF010F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F0F000F0F0F0F1111000100100000001000010FR1F1000000000000000000111011110001011011101111100010010001000101010110110011101110000100110000000011000000000000000000000000000000000000011111111111111111111111111111R0F1R0R001RR100FF1000\n",
"000000000000000000000000000000000000000000000000000000000000000FF00F0000000000000000000000000000000000000F00000F11F10FRR00R01111000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000100000R010000000000000000000000000000000000000000000000000111111111111111111111110000010000000000R000R0RF1FFFRFR000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001101000000000000000000000000000000011001010010111111111\n",
"00000000000000000000000000000000000000000000000000000000000000FFRFFFFF00000000000000000000000000000000000RR0000RF01F0RF00001001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000101111111110111111111111111011100000101000000010000010000000000000000000000000000RR0R0000000000000000000000000000000000000000000000000000000000000000000000000101111011011111100000000000000000000000000000000000000000R0R000000000000000000000000000000R0R000R00000001000000\n"
]
}
],
"source": [
2 years 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",
2 years ago
"execution_count": 52,
"metadata": {},
"outputs": [],
"source": [
2 years ago
"stuck_tests_bp = logic.mv_to_bp(stuck_tests)"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 53,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"(528, 3, 85)"
]
},
2 years ago
"execution_count": 53,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
"stuck_tests_bp.data.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years 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",
2 years ago
"execution_count": 54,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"(528, 680)"
]
},
2 years ago
"execution_count": 54,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"logic.bp_to_mv(stuck_tests_bp).shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Logic Simulation\n",
"\n",
2 years ago
"The following code performs a 8-valued logic simulation on all 678 vectors for one clock cycle."
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 55,
"metadata": {},
"outputs": [],
"source": [
"from kyupy.logic_sim import LogicSim\n",
"\n",
2 years ago
"sim = LogicSim(b15, 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",
2 years ago
"sim_responses = logic.bp_to_mv(sim.s[1])[...,:stuck_tests.shape[-1]] # trim from 680 -> 678"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 56,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"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": [
2 years 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",
2 years 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",
2 years ago
"execution_count": 57,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"677"
]
},
2 years ago
"execution_count": 57,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years 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",
2 years ago
"execution_count": 58,
"metadata": {},
"outputs": [],
"source": [
2 years ago
"sim = LogicSim(b15, sims=transition_tests_zf.shape[-1]) # 1147 simulations in parallel\n",
"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",
2 years ago
"sim_responses = logic.bp_to_mv(sim.s[1])[...,:transition_tests_zf.shape[-1]] # trim to 1147"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 59,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------0100110001011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"0000000000000000000000000000000000000R--------------------------------00000000000000000000000000000000--------0FNFFNPFRR0PFF01000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000NNP0PP00F0FPFPFPFPFPFPFPFPFPFPFPFPFPFPFPFPF0F0F0F0FPRP0P0P0PN000000000000000000000000NNPNP000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000RRRRRRRRRRRRRRRRRFFFFFFRRRRRFRRFNPPNP00000000000000000000000000000FPP000NP0000P0NN00000\n",
"01001111111111111111111111111111101010--------------------------------00000000000000000000000000000000--------1PNPRN0PNN0011001PFF0F0F0R0F0F0R0F0F0F0R0R0F0F0R0R0FRFRRFRFFRRFFFR000000000000000PP0PP0PPP00PP00P00000000000000000000000000000000000000000000000P00N0PP0N0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P0P000P0P0P0PFFFFR00N00N0000000N0000N0PNFPF00000000000000000011101111000101101110111110001001000100010101011011001110111000010011000000001100000000000000000000000000000000PPRPRFFFFFFFFFFFFFFFFFFFFFFFFFFFFFNRRFNRFRRFFFFP0PRF000\n",
"10110000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0PFNP1PPNNPPNPFFNF000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000PPPNP00PPNPNPPP0P0P0P0P0P0P0P0P0P0P0P0P0P0P000000000000000000FFFFFFFFFFFFFFFFFFFFFFFR0PPRNR000000000N000N0NPNPPPNPN0P000P0P0P000P0P0P000P0P0P000P0P0P000P0P0PN00P0P0000000000000000000000000000000000000000000000000000000011RFR000000000000000000000000000000F1R0F0F0RFPFFNNNFNFF\n",
"0000000000000000000000000000000000000R--------------------------------00000000000000000000000000000000--------0FRPFPPNRP0RPN00N00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000F00PFRNFFFFFFFFPFFFFFFFFFFFFFFFPFFFRRP0RNRN000000RN0000RN000PP0PPPPPPP0P0000000000000NN0N0000000000000000000000000000000000000000000000000000000000000000000000000FRFFFFPFFRFFFFFFPPPPPPPPPPPPPPPP0000000000000000000000000N0N000000000000000000000000000000N0F000N00000PPF00PP00\n"
]
}
],
"source": [
2 years 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",
2 years ago
"execution_count": 60,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"11001100110011001100110011001100110000--------------------------------01001100110011001100110011001100--------0100110001011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"00000000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0010010011000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000010000000100000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111110000001111101101001000000000000000000000000000000000000100000001100000\n",
"01001111111111111111111111111111101010--------------------------------00000000000000000000000000000000--------1010110011001100100000000100000100000001010000010100101101001100010000000000000000000000000000000000000000000000000000000000000000000000000000000001000010000000000000000000000000000000000000000000000000000000010010010000000100001001000000000000000000000111011110001011011101111100010010001000101010110110011101110000100110000000011000000000000000000000000000000000010100000000000000000000000000000111011011000000010000\n",
"10110000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0001010011001000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000001010000000000000000000000000000000000000000000000000000000000000000000000001000111000000000100010101000101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001110100000000000000000000000000000001100000100001110100\n",
"00000000000000000000000000000000000001--------------------------------00000000000000000000000000000000--------0010000110010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000001100111100000011000011000000000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000000000000000000000101000000000000000000000000000000100000100000000000000\n"
]
}
],
"source": [
2 years 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": [
2 years 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",
2 years ago
"execution_count": 61,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"1146"
]
},
2 years ago
"execution_count": 61,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years 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": [
"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. Each line in the circuit has a rising delay, a falling delay, a negative pulse threshold, and a positive pulse threshold. "
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 62,
"metadata": {},
"outputs": [],
"source": [
"from kyupy import sdf\n",
"\n",
2 years ago
"df = sdf.load('../tests/b15_2ig.sdf.gz')\n",
2 years ago
"delays = df.iopaths(b15)[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",
2 years ago
"execution_count": 63,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"(32032, 2, 2)"
]
},
2 years ago
"execution_count": 63,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"delays.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"Number of non-0 values loaded:"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 64,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"79010"
]
},
2 years ago
"execution_count": 64,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years 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",
2 years ago
"execution_count": 65,
"metadata": {},
"outputs": [],
"source": [
"from kyupy.wave_sim import WaveSimCuda, TMAX\n",
"\n",
2 years ago
"wsim = WaveSimCuda(b15, 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",
2 years ago
"execution_count": 66,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"Waveforms : 64293.5 kiB\n",
"State Allocation Table : 129.3 kiB\n",
"Circuit Timing : 1034.1 kiB\n",
"Circuit Netlist : 750.8 kiB\n",
"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",
2 years 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",
2 years 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",
2 years ago
"execution_count": 67,
"metadata": {},
"outputs": [],
"source": [
2 years ago
"from kyupy import batchrange\n",
"import numpy as np\n",
"\n",
2 years ago
"sims = 128 # transition_tests_zf.shape[-1] # Feel free to simulate all tests if CUDA is set up correctly.\n",
"\n",
2 years 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",
" wsim.s[0] = (transition_tests_zf[:,offset:offset+size] >> 1) & 1 # initial value\n",
" wsim.s[1] = 0.0 # transition time\n",
" wsim.s[2] = transition_tests_zf[:,offset:offset+size] & 1 # final value\n",
" 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": [
2 years 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",
2 years ago
"execution_count": 68,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"(11, 528, 128)"
]
},
2 years ago
"execution_count": 68,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"wsim_results.shape"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years ago
"For validating against known logic values, convert the samples capture values `wsim_results[8]` into an mvarray like this:"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 69,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
2 years ago
"110011001100110011001100110011001100000000000000000000000000000000000001001100110011001100110011001100000000000100110001011010011101101001011010010110100101101001001100110011001100110011001100011001100110011001100110011001110011001100110011001100110011001011101001011010010110100101101001011010010110100101101001011101100110011001101100110000010010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101010101011100110011001100110011001100110011111100001001011000100\n",
"000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010010011000001000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000110000000000000000000000000000000000000000000000000010000000100000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111110000001111101101001000000000000000000000000000000000000100000001100000\n",
"010011111111111111111111111111111010100000000000000000000000000000000000000000000000000000000000000000000000001010110011001100100000000100000100000001010000010100101101001100010000000000000000000000000000000000000000000000000000000000000000000000000000000001000010000000000000000000000000000000000000000000000000000000010010010000000100001001000000000000000000000111011110001011011101111100010010001000101010110110011101110000100110000000011000000000000000000000000000000000010100000000000000000000000000000111011011000000010000\n",
"101100000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000001010011001000100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001000001010000000000000000000000000000000000000000000000000000000000000000000000001000111000000000100010101000101000000000000000000000000000000000000000000100000000000000000000000000000000000000000000000000000000000001110100000000000000000000000000000001100000100001110100\n",
"000000000000000000000000000000000000010000000000000000000000000000000000000000000000000000000000000000000000000010000110010100100000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000001100000000000000000000000000001100111100000011000011000000000000000000000000000011010000000000000000000000000000000000000000000000000000000000000000000000000010000000100000000000000000000000000000000000000000000000101000000000000000000000000000000100000100000000000000\n"
]
}
],
"source": [
2 years 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": [
2 years ago
"We expect 127 matches here."
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 70,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"127"
]
},
2 years ago
"execution_count": 70,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years 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": [
2 years ago
"The circuit delay is the maximum among all latest stabilization times:"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 71,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
2 years ago
"1.0424000024795532"
]
},
2 years ago
"execution_count": 71,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years ago
"wsim_results[5].max()"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
2 years ago
"Check for overflows. If too many of them occur, increase `c_caps` during engine instanciation:"
]
},
{
"cell_type": "code",
2 years ago
"execution_count": 72,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0.0"
]
},
2 years ago
"execution_count": 72,
"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": 73,
"metadata": {},
"outputs": [
{
"data": {
"text/plain": [
"0"
]
},
"execution_count": 73,
"metadata": {},
"output_type": "execute_result"
}
],
"source": [
2 years 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
}