{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "uINjDJNf39eD" }, "source": [ "# Semicustom digital design crashbook\n", "\n", "## Sources\n", "\n", "### RTL description (Verilog)\n", "\n", "The OpenROAD workflow takes the circuit's RTL description as an input. For instance, it can be a three bits XOR gate.\n", "\n", "\n", "
\n", "\n", "\n", " \n", "#### ↕️ Types in Verilog\n", "\n", "\n", " \n", "```verilog\n", "// Three scalar nets\n", "wire op_b, op_a, result;\n", "// One 16-bit net\n", "wire [15:0] word_bus;\n", "// 1K-array of 8-bit nets\n", "wire [7:0] byte_array [0:1023];\n", "```\n", " \n", "
\n", "\n", "
\n", "\n", "\n", " \n", "#### ↕️ Assignation (non-blocking) in Verilog\n", "\n", "\n", " \n", "```verilog\n", "// 16-bit, hexadecimal constant\n", "assign address = 16'hCAFE;\n", "// Unsized, decimal constant\n", "assign counter = 'd42;\n", "// 1-bit, binary constant\n", "assign answer = 1'b1;\n", "\n", "// Ternary assignation\n", "assign muxed = which ? source_1 : source_2;\n", "\n", "// Concatenation\n", "assign padded_packet = {5'b00000,body,suffix};\n", "// Replication\n", "assign odd_mask = {10{2'b10}};\n", "\n", "// Indexing\n", "assign one_bit = bus[4];\n", "assign bits = bus[15:12];\n", "```\n", " \n", "
\n", "\n", "
\n", "\n", "\n", " \n", "#### ↕️ Operators in Verilog\n", "\n", "\n", " \n", "```verilog\n", "// Addition, substraction, negation\n", "assign sum = op_a + op_b; assign sub = op_a + op_b; assign opp = -op_a\n", "// Multiplication, division, modulo\n", "assign prod = op_a * op_b; assign div = op_a / op_b; assign rem = op_a & op_b\n", " \n", "// Bitwise not, or, and, xor\n", "assign n = ~m; assign a = b | c; assign d = e & f; assign x = y ^ z\n", "\n", "// Logical not, and, or\n", "assign ans = !v; assign ans = v || w; assign ans = v && w;\n", "// Logical equality, difference\n", "assign ans = v == w; assign ans = v != w;\n", "// Relations (strictly) greater, (strictly) lower than\n", "assign sg = a > b; assign gt = a >= b; assign sl = a < b; assign lt = a <= b;\n", " \n", "// Left, right shift by n bits\n", "assign l << n; assign r >> n;\n", "// Left, right arithmetic shift by n bits\n", "assign l <<< n; assign r >>> n;\n", "```\n", " \n", "
" ] }, { "cell_type": "code", "execution_count": 1, "metadata": { "id": "gpgkIYB739Ii" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing v/xor3.v\n" ] } ], "source": [ "%%writefile v/xor3.v\n", "module xor3(\n", " input wire a,\n", " input wire b,\n", " input wire c,\n", " output wire out\n", ");\n", " assign out = a ^ b ^ c;\n", "endmodule" ] }, { "cell_type": "markdown", "metadata": { "id": "hp8h5vH8TUXr" }, "source": [ "### Configuration file (JSON)\n", "\n", "A configuration file should be provided. It describes constraints and strategies applied during synthesis and implementation of the circuit." ] }, { "cell_type": "code", "execution_count": 4, "metadata": { "id": "rbT-vP0h0enK" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting build/config.json\n" ] } ], "source": [ "%%writefile build/config.json\n", "{\n", " \"DESIGN_NAME\": \"xor3\",\n", " \"VERILOG_FILES\": \"dir::../v/xor3.v\",\n", " \"CLOCK_TREE_SYNTH\": false,\n", " \"CLOCK_PORT\": null,\n", " \"FP_SIZING\": \"absolute\",\n", " \"DIE_AREA\": \"0 0 35 45\",\n", " \"FP_PDN_AUTO_ADJUST\": false,\n", " \"FP_PDN_VOFFSET\": 0,\n", " \"FP_PDN_HOFFSET\": 0,\n", " \"DIODE_INSERTION_STRATEGY\": 3\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Workflow\n", "The provided `flow.tcl` is a script describing the OpenROAD workflow. A _GDS_ file will be generated using the RTL circuit description, the PDK and the configuration file." ] }, { "cell_type": "code", "execution_count": 5, "metadata": { "colab": { "base_uri": "https://localhost:8080/" }, "id": "VP60fdObiP15", "outputId": "41aa85e4-c663-4778-d448-928dbe474b11" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "env: PDK=sky130A\n", "OpenLane 2023.04.07_0_gcb634fd5-conda\n", "All rights reserved. (c) 2020-2022 Efabless Corporation and contributors.\n", "Available under the Apache License, version 2.0. See the LICENSE file for more details.\n", "\n", "\u001b[36m[INFO]: Using configuration in 'build/config.json'...\u001b[39m\n", "\u001b[36m[INFO]: PDK Root: /home/pierre/anaconda3/envs/semicustom/share/pdk\u001b[39m\n", "\u001b[36m[INFO]: Process Design Kit: sky130A\u001b[39m\n", "\u001b[36m[INFO]: Standard Cell Library: sky130_fd_sc_hd\u001b[39m\n", "\u001b[36m[INFO]: Optimization Standard Cell Library: sky130_fd_sc_hd\u001b[39m\n", "\u001b[33m[WARNING]: DIODE_INSERTION_STRATEGY is now deprecated; use GRT_REPAIR_ANTENNAS, DIODE_ON_PORTS and RUN_HEURISTIC_DIODE_INSERTION instead.\u001b[39m\n", "\u001b[36m[INFO]: DIODE_INSERTION_STRATEGY set to 3. Setting GRT_REPAIR_ANTENNAS to 1\u001b[39m\n", "\u001b[36m[INFO]: Run Directory: /home/pierre/Bureau/freechips/semicustom/build/runs/RUN_2023.05.03_00.24.56\u001b[39m\n", "\u001b[36m[INFO]: Preparing LEF files for the nom corner...\u001b[39m\n", "\u001b[36m[INFO]: Preparing LEF files for the min corner...\u001b[39m\n", "\u001b[36m[INFO]: Preparing LEF files for the max corner...\u001b[39m\n", "[STEP 1]\n", "\u001b[36m[INFO]: Running Synthesis (log: build/runs/RUN_2023.05.03_00.24.56/logs/synthesis/1-synthesis.log)...\u001b[39m\n", "[STEP 2]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.24.56/logs/synthesis/2-sta.log)...\u001b[39m\n", "[STEP 3]\n", "\u001b[36m[INFO]: Running Initial Floorplanning (log: build/runs/RUN_2023.05.03_00.24.56/logs/floorplan/3-initial_fp.log)...\u001b[39m\n", "\u001b[36m[INFO]: Floorplanned with width 23.92 and height 21.76.\u001b[39m\n", "[STEP 4]\n", "\u001b[36m[INFO]: Running IO Placement...\u001b[39m\n", "[STEP 5]\n", "\u001b[36m[INFO]: Running Tap/Decap Insertion (log: build/runs/RUN_2023.05.03_00.24.56/logs/floorplan/5-tap.log)...\u001b[39m\n", "\u001b[36m[INFO]: Power planning with power {VPWR} and ground {VGND}...\u001b[39m\n", "[STEP 6]\n", "\u001b[36m[INFO]: Generating PDN (log: build/runs/RUN_2023.05.03_00.24.56/logs/floorplan/6-pdn.log)...\u001b[39m\n", "[STEP 7]\n", "\u001b[36m[INFO]: Running Global Placement (log: build/runs/RUN_2023.05.03_00.24.56/logs/placement/7-global.log)...\u001b[39m\n", "[STEP 8]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.24.56/logs/placement/8-sta-global.log)...\u001b[39m\n", "[STEP 9]\n", "\u001b[36m[INFO]: Running Placement Resizer Design Optimizations (log: build/runs/RUN_2023.05.03_00.24.56/logs/placement/9-resizer.log)...\u001b[39m\n", "[STEP 10]\n", "\u001b[36m[INFO]: Running Detailed Placement (log: build/runs/RUN_2023.05.03_00.24.56/logs/placement/10-detailed.log)...\u001b[39m\n", "[STEP 11]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.24.56/logs/placement/11-sta.log)...\u001b[39m\n", "[STEP 12]\n", "\u001b[36m[INFO]: Running Placement Resizer Timing Optimizations (log: build/runs/RUN_2023.05.03_00.24.56/logs/cts/12-resizer.log)...\u001b[39m\n", "[STEP 13]\n", "\u001b[36m[INFO]: Running Global Routing Resizer Design Optimizations (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/13-resizer_design.log)...\u001b[39m\n", "[STEP 14]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/14-sta-resizer_design.log)...\u001b[39m\n", "[STEP 15]\n", "\u001b[36m[INFO]: Running Global Routing Resizer Timing Optimizations (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/15-resizer_timing.log)...\u001b[39m\n", "[STEP 16]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/16-sta-resizer_timing.log)...\u001b[39m\n", "[STEP 17]\n", "\u001b[36m[INFO]: Running Global Routing (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/17-global.log)...\u001b[39m\n", "\u001b[36m[INFO]: Starting OpenROAD Antenna Repair Iterations...\u001b[39m\n", "[STEP 18]\n", "\u001b[36m[INFO]: Writing Verilog (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/17-global_write_netlist.log)...\u001b[39m\n", "[STEP 19]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/19-sta-groute.log)...\u001b[39m\n", "[STEP 20]\n", "\u001b[36m[INFO]: Running Fill Insertion (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/20-fill.log)...\u001b[39m\n", "[STEP 21]\n", "\u001b[36m[INFO]: Running Detailed Routing (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/21-detailed.log)...\u001b[39m\n", "\u001b[36m[INFO]: No DRC violations after detailed routing.\u001b[39m\n", "[STEP 22]\n", "\u001b[36m[INFO]: Checking Wire Lengths (log: build/runs/RUN_2023.05.03_00.24.56/logs/routing/22-wire_lengths.log)...\u001b[39m\n", "[STEP 23]\n", "\u001b[36m[INFO]: Running SPEF Extraction at the min process corner (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/23-parasitics_extraction.min.log)...\u001b[39m\n", "[STEP 24]\n", "\u001b[36m[INFO]: Running Multi-Corner Static Timing Analysis at the min process corner (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/24-rcx_mcsta.min.log)...\u001b[39m\n", "[STEP 25]\n", "\u001b[36m[INFO]: Running SPEF Extraction at the max process corner (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/25-parasitics_extraction.max.log)...\u001b[39m\n", "[STEP 26]\n", "\u001b[36m[INFO]: Running Multi-Corner Static Timing Analysis at the max process corner (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/26-rcx_mcsta.max.log)...\u001b[39m\n", "[STEP 27]\n", "\u001b[36m[INFO]: Running SPEF Extraction at the nom process corner (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/27-parasitics_extraction.nom.log)...\u001b[39m\n", "[STEP 28]\n", "\u001b[36m[INFO]: Running Multi-Corner Static Timing Analysis at the nom process corner (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/28-rcx_mcsta.nom.log)...\u001b[39m\n", "[STEP 29]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis at the nom process corner (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/29-rcx_sta.log)...\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_fd_sc_hd__tapvpwrvgnd_1 blackboxed during sta\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_ef_sc_hd__decap_12 blackboxed during sta\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_fd_sc_hd__fill_2 blackboxed during sta\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_fd_sc_hd__fill_1 blackboxed during sta\u001b[39m\n", "[STEP 30]\n", "\u001b[36m[INFO]: Creating IR Drop Report (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/30-irdrop.log)...\u001b[39m\n", "[STEP 31]\n", "\u001b[36m[INFO]: Running Magic to generate various views...\u001b[39m\n", "\u001b[36m[INFO]: Streaming out GDSII with Magic (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/31-gdsii.log)...\u001b[39m\n", "\u001b[36m[INFO]: Generating MAGLEF views...\u001b[39m\n", "[STEP 32]\n", "\u001b[36m[INFO]: Streaming out GDSII with KLayout (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/32-gdsii-klayout.log)...\u001b[39m\n", "[STEP 33]\n", "\u001b[36m[INFO]: Running XOR on the layouts using KLayout (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/33-xor.log)...\u001b[39m\n", "\u001b[36m[INFO]: No XOR differences between KLayout and Magic gds.\u001b[39m\n", "[STEP 34]\n", "\u001b[36m[INFO]: Running Magic Spice Export from LEF (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/34-spice.log)...\u001b[39m\n", "[STEP 35]\n", "\u001b[36m[INFO]: Writing Powered Verilog (logs: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/35-write_powered_def.log, build/runs/RUN_2023.05.03_00.24.56/logs/signoff/35-write_powered_verilog.log)...\u001b[39m\n", "[STEP 36]\n", "\u001b[36m[INFO]: Writing Verilog (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/35-write_powered_verilog.log)...\u001b[39m\n", "[STEP 37]\n", "\u001b[36m[INFO]: Running LVS (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/37-lvs.lef.log)...\u001b[39m\n", "[STEP 38]\n", "\u001b[36m[INFO]: Running Magic DRC (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/38-drc.log)...\u001b[39m\n", "\u001b[36m[INFO]: Converting Magic DRC database to various tool-readable formats...\u001b[39m\n", "\u001b[36m[INFO]: No DRC violations after GDS streaming out.\u001b[39m\n", "[STEP 39]\n", "\u001b[36m[INFO]: Running OpenROAD Antenna Rule Checker (log: build/runs/RUN_2023.05.03_00.24.56/logs/signoff/39-antenna.log)...\u001b[39m\n", "\u001b[36m[INFO]: Saving current set of views in 'build/runs/RUN_2023.05.03_00.24.56/results/final'...\u001b[39m\n", "\u001b[36m[INFO]: Saving runtime environment...\u001b[39m\n", "\u001b[36m[INFO]: Generating final set of reports...\u001b[39m\n", "\u001b[36m[INFO]: Created manufacturability report at 'build/runs/RUN_2023.05.03_00.24.56/reports/manufacturability.rpt'.\u001b[39m\n", "\u001b[36m[INFO]: Created metrics report at 'build/runs/RUN_2023.05.03_00.24.56/reports/metrics.csv'.\u001b[39m\n", "\u001b[36m[INFO]: There are no max slew, max fanout or max capacitance violations in the design at the typical corner.\u001b[39m\n", "\u001b[36m[INFO]: There are no hold violations in the design at the typical corner.\u001b[39m\n", "\u001b[36m[INFO]: There are no setup violations in the design at the typical corner.\u001b[39m\n", "\u001b[32m[SUCCESS]: Flow complete.\u001b[39m\n", "\u001b[36m[INFO]: Note that the following warnings have been generated:\u001b[39m\n", "[WARNING]: Module sky130_fd_sc_hd__tapvpwrvgnd_1 blackboxed during sta\n", "[WARNING]: Module sky130_ef_sc_hd__decap_12 blackboxed during sta\n", "[WARNING]: Module sky130_fd_sc_hd__fill_2 blackboxed during sta\n", "[WARNING]: Module sky130_fd_sc_hd__fill_1 blackboxed during sta\n", "\n" ] } ], "source": [ "%env PDK=sky130A\n", "!flow.tcl -design build" ] }, { "cell_type": "markdown", "metadata": { "id": "luguFgZ43AeL" }, "source": [ "## Output products\n", "\n", "### Display layout\n", "\n", "The implemented layout can be retrieved as follows:" ] }, { "cell_type": "code", "execution_count": 12, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 650 }, "id": "WOnhdtp3ivRi", "outputId": "b4bd26f8-d3da-47b7-e321-99272b0591ef", "scrolled": false }, "outputs": [ { "data": { "image/svg+xml": [ "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VPWR\n", "VGND\n", "tapvpwrvgnd_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "A1\n", "B1\n", "A1\n", "A1\n", "Y\n", "B1\n", "Y\n", "A2\n", "VPWR\n", "VGND\n", "VPB\n", "VNB\n", "a21oi_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "B\n", "Y\n", "A\n", "VPB\n", "VNB\n", "VGND\n", "VPWR\n", "nor2_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VPWR\n", "VGND\n", "VPB\n", "VNB\n", "decap_8\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "decap_12\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "fill_2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VPWR\n", "VGND\n", "VPB\n", "VNB\n", "decap_6\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VPWR\n", "VGND\n", "VPB\n", "VNB\n", "decap_3\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "X\n", "A\n", "X\n", "A\n", "X\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "clkbuf_4\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VGND\n", "VPWR\n", "X\n", "X\n", "X\n", "A\n", "VPB\n", "VNB\n", "clkbuf_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VPWR\n", "VGND\n", "X\n", "X\n", "X\n", "X\n", "X\n", "X\n", "B\n", "A\n", "A\n", "VPB\n", "VNB\n", "and2_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "A\n", "X\n", "B\n", "VPB\n", "VNB\n", "VGND\n", "VPWR\n", "or2_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "A\n", "Y\n", "Y\n", "Y\n", "VPB\n", "VNB\n", "VPWR\n", "VGND\n", "inv_2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VPWR\n", "VGND\n", "VPWR\n", "VGND\n", "X\n", "X\n", "X\n", "A\n", "VPB\n", "VNB\n", "buf_2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "X\n", "C\n", "C\n", "A\n", "C\n", "B\n", "B\n", "D\n", "X\n", "X\n", "X\n", "X\n", "X\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "and4_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "X\n", "X\n", "X\n", "X\n", "X\n", "X\n", "A\n", "A\n", "VNB\n", "VNB\n", "VPB\n", "VPB\n", "VGND\n", "VPWR\n", "clkbuf_16\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "B\n", "X\n", "A\n", "VNB\n", "VPB\n", "VPWR\n", "VGND\n", "xor2_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Q\n", "Q\n", "Q\n", "Q\n", "RESET_B\n", "D\n", "CLK\n", "CLK\n", "RESET_B\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "dfrtp_2\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VGND\n", "VPWR\n", "B\n", "Y\n", "A\n", "VPB\n", "VNB\n", "xnor2_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "decap_4\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "A2\n", "B1\n", "A1\n", "A3\n", "A2\n", "A3\n", "X\n", "A1\n", "X\n", "X\n", "B1\n", "VPB\n", "VNB\n", "VGND\n", "VPWR\n", "a31o_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "X\n", "A_N\n", "A_N\n", "B\n", "X\n", "A_N\n", "B\n", "X\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "and2b_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VGND\n", "VPWR\n", "X\n", "X\n", "B\n", "A\n", "C\n", "VPB\n", "VNB\n", "and3_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Y\n", "Y\n", "Y\n", "B\n", "A\n", "VPB\n", "VNB\n", "VGND\n", "VPWR\n", "nand2_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "Q\n", "Q\n", "Q\n", "Q\n", "RESET_B\n", "D\n", "CLK\n", "CLK\n", "RESET_B\n", "VGND\n", "VPWR\n", "VPB\n", "VNB\n", "dfrtp_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VPWR\n", "VGND\n", "VPB\n", "VNB\n", "fill_1\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "\n", "VGND\n", "VPWR\n", "_00_\n", "_01_\n", "_02_\n", "_03_\n", "_04_\n", "_05_\n", "_06_\n", "_07_\n", "_08_\n", "_09_\n", "_10_\n", "_11_\n", "_12_\n", "_13_\n", "_14_\n", "_15_\n", "_16_\n", "clk\n", "clknet_0_clk\n", "clknet_1_0__leaf_clk\n", "clknet_1_1__leaf_clk\n", "count[0]\n", "count[1]\n", "count[2]\n", "count[3]\n", "count[4]\n", "count[5]\n", "count[6]\n", "count[7]\n", "net1\n", "net2\n", "net3\n", "net4\n", "net5\n", "net6\n", "net7\n", "net8\n", "net9\n", "rst\n", "VGND\n", "VPWR\n", "clk\n", "count[0]\n", "count[1]\n", "count[2]\n", "count[3]\n", "count[4]\n", "count[5]\n", "count[6]\n", "count[7]\n", "rst\n", "\n", "" ], "text/plain": [ "" ] }, "execution_count": 12, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import glob\n", "import gdstk\n", "import IPython.display\n", "\n", "gdsii = sorted(glob.glob(\"./build/runs/*/results/final/gds/*.gds\"))[-1]\n", "top = gdstk.read_gds(gdsii).top_level()\n", "top[0].write_svg('svg/inverter.svg')\n", "IPython.display.SVG('svg/inverter.svg')" ] }, { "cell_type": "markdown", "metadata": { "id": "NW_7YdgTZYQK" }, "source": [ "### Reporting\n", "\n", "Many reports are available under:\n", "\n", "```\n", "freeechips/semicustom/runs/RUN_YYYY.MM.DD_HH.MM.SS/reports/.\n", "```\n", "\n", "An overview of the main figures can be retrieved as well:" ] }, { "cell_type": "code", "execution_count": 7, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 1000 }, "id": "OWAwQI3fZC4W", "outputId": "d50dcf9f-30cd-42a3-dab5-12992bc9dca2", "scrolled": true }, "outputs": [ { "data": { "text/html": [ "
\n", "\n", "\n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", " \n", "
0
design/home/pierre/Bureau/freechips/semicustom/build
design_namexor3
configRUN_2023.05.03_00.24.56
flow_statusflow completed
total_runtime0h0m18s0ms
routed_runtime0h0m9s0ms
(Cell/mm^2)/Core_Util7619.047619
DIEAREA_mm^20.001575
CellPer_mm^23809.52381
OpenDP_Util7.16
Final_Util-1
Peak_Memory_Usage_MB468.28
synth_cell_count2
tritonRoute_violations0
Short_violations0
MetSpc_violations0
OffGrid_violations0
MinHole_violations0
Other_violations0
Magic_violations0
pin_antenna_violations0
net_antenna_violations0
lvs_total_errors0
cvc_total_errors-1
klayout_violations-1
wire_length127
vias30
wns0.0
pl_wns-1
optimized_wns-1
fastroute_wns-1
spef_wns0.0
tns0.0
pl_tns-1
optimized_tns-1
fastroute_tns-1
spef_tns0.0
HPWL138445.0
routing_layer1_pct0.0
routing_layer2_pct2.06
routing_layer3_pct3.96
routing_layer4_pct0.0
routing_layer5_pct0.0
routing_layer6_pct0.0
wires_count5
wire_bits5
public_wires_count4
public_wire_bits4
memories_count0
memory_bits0
processes_count0
cells_pre_abc2
AND0
DFF0
NAND0
NOR0
OR0
XOR2
XNOR0
MUX0
inputs3
outputs1
level2
DecapCells47
WelltapCells5
DiodeCells0
FillCells9
NonPhysCells6
TotalCells67
CoreArea_um^2520.4992
power_slowest_internal_uW-1
power_slowest_switching_uW-1
power_slowest_leakage_uW-1
power_typical_internal_uW0.000001
power_typical_switching_uW0.000002
power_typical_leakage_uW0.0
power_fastest_internal_uW-1
power_fastest_switching_uW-1
power_fastest_leakage_uW-1
critical_path_ns0.67
suggested_clock_period10.0
suggested_clock_frequency100.0
CLOCK_PERIOD10.0
FP_ASPECT_RATIO1
FP_CORE_UTIL50
FP_PDN_HPITCH153.18
FP_PDN_VPITCH153.6
GRT_ADJUSTMENT0.3
GRT_REPAIR_ANTENNAS1
PL_TARGET_DENSITY0.6
RUN_HEURISTIC_DIODE_INSERTION0
STD_CELL_LIBRARYsky130_fd_sc_hd
SYNTH_MAX_FANOUT10
SYNTH_STRATEGYAREA 0
\n", "
" ], "text/plain": [ " 0\n", "design /home/pierre/Bureau/freechips/semicustom/build\n", "design_name xor3\n", "config RUN_2023.05.03_00.24.56\n", "flow_status flow completed\n", "total_runtime 0h0m18s0ms\n", "routed_runtime 0h0m9s0ms\n", "(Cell/mm^2)/Core_Util 7619.047619\n", "DIEAREA_mm^2 0.001575\n", "CellPer_mm^2 3809.52381\n", "OpenDP_Util 7.16\n", "Final_Util -1\n", "Peak_Memory_Usage_MB 468.28\n", "synth_cell_count 2\n", "tritonRoute_violations 0\n", "Short_violations 0\n", "MetSpc_violations 0\n", "OffGrid_violations 0\n", "MinHole_violations 0\n", "Other_violations 0\n", "Magic_violations 0\n", "pin_antenna_violations 0\n", "net_antenna_violations 0\n", "lvs_total_errors 0\n", "cvc_total_errors -1\n", "klayout_violations -1\n", "wire_length 127\n", "vias 30\n", "wns 0.0\n", "pl_wns -1\n", "optimized_wns -1\n", "fastroute_wns -1\n", "spef_wns 0.0\n", "tns 0.0\n", "pl_tns -1\n", "optimized_tns -1\n", "fastroute_tns -1\n", "spef_tns 0.0\n", "HPWL 138445.0\n", "routing_layer1_pct 0.0\n", "routing_layer2_pct 2.06\n", "routing_layer3_pct 3.96\n", "routing_layer4_pct 0.0\n", "routing_layer5_pct 0.0\n", "routing_layer6_pct 0.0\n", "wires_count 5\n", "wire_bits 5\n", "public_wires_count 4\n", "public_wire_bits 4\n", "memories_count 0\n", "memory_bits 0\n", "processes_count 0\n", "cells_pre_abc 2\n", "AND 0\n", "DFF 0\n", "NAND 0\n", "NOR 0\n", "OR 0\n", "XOR 2\n", "XNOR 0\n", "MUX 0\n", "inputs 3\n", "outputs 1\n", "level 2\n", "DecapCells 47\n", "WelltapCells 5\n", "DiodeCells 0\n", "FillCells 9\n", "NonPhysCells 6\n", "TotalCells 67\n", "CoreArea_um^2 520.4992\n", "power_slowest_internal_uW -1\n", "power_slowest_switching_uW -1\n", "power_slowest_leakage_uW -1\n", "power_typical_internal_uW 0.000001\n", "power_typical_switching_uW 0.000002\n", "power_typical_leakage_uW 0.0\n", "power_fastest_internal_uW -1\n", "power_fastest_switching_uW -1\n", "power_fastest_leakage_uW -1\n", "critical_path_ns 0.67\n", "suggested_clock_period 10.0\n", "suggested_clock_frequency 100.0\n", "CLOCK_PERIOD 10.0\n", "FP_ASPECT_RATIO 1\n", "FP_CORE_UTIL 50\n", "FP_PDN_HPITCH 153.18\n", "FP_PDN_VPITCH 153.6\n", "GRT_ADJUSTMENT 0.3\n", "GRT_REPAIR_ANTENNAS 1\n", "PL_TARGET_DENSITY 0.6\n", "RUN_HEURISTIC_DIODE_INSERTION 0\n", "STD_CELL_LIBRARY sky130_fd_sc_hd\n", "SYNTH_MAX_FANOUT 10\n", "SYNTH_STRATEGY AREA 0" ] }, "execution_count": 7, "metadata": {}, "output_type": "execute_result" } ], "source": [ "import glob\n", "import pandas as pd\n", "pd.options.display.max_rows = None\n", "\n", "pd.read_csv(sorted(glob.glob(\"./build/runs/*/reports/metrics.csv\"))[-1]).T" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# To have fun going further...\n", "\n", "## Sequential circuits in Verilog\n", "\n", "The tutorial above focuses on combinational circuits. Sequential circuits can obviously be described in Verilog as well. Sequential blocks feature an `always` block. Refer to the vendor's reference to get the sensitivity list's syntax (e.g. to determine if reset is synchronous or asynchronous).\n", "\n", "
\n", "\n", "\n", " \n", "#### ↕️ Sequential structures in Verilog\n", "\n", "\n", "\n", "Nets which store data are declared as `reg`s:\n", " \n", "```verilog\n", "// Three scalar register\n", "reg op_b, op_a, result;\n", "// One 16-bit register\n", "reg [15:0] word_bus;\n", "// 1K-array of 8-bit registers\n", "reg [7:0] byte_array [0:1023];\n", "```\n", "\n", "The following structure updates the memory points:\n", " \n", "```verilog\n", "always @(posedge clk or negedge rst) begin\n", " if (!rst) begin \n", " counter <= 0;\n", " end else begin\n", " counter <= counter + 1;\n", " end\n", "end\n", "```\n", " \n", "
\n", "\n", "Advanced structures like the `case` structure can be used to describe finite state machines. FSM decoders can be described in an abstract way using `always` blocks in a fully combinational way:\n", "\n", "
\n", "\n", "\n", " \n", "#### ↕️ Advanced structures in Verilog\n", "\n", "\n", "\n", "```verilog\n", " \n", "/*\n", " * Case structure\n", " */\n", " \n", "case (state)\n", "\n", " 3'b000: idle_led <= 1'b1;\n", " \n", " 3'b001,\n", " 3'b010: work_led <= 1'b1;\n", " \n", " 3'b011: begin\n", " muxed <= spi_1;\n", " work_led <= 1'b1;\n", " end\n", " \n", " default: begin\n", " muxed <= 0;\n", " work_led <= 1'b0; \n", " idle_led <= 1'b1;\n", " end\n", "\n", "endcase\n", "\n", "/*\n", " * Combinational always structure\n", " * To describe priorities in a procedural fashion,\n", " * use blocking `<=` assignations instead of\n", " * non-blocking `=` assignations.\n", " */\n", " \n", "always @( * ) begin\n", " flag <= 1'b0;\n", " if (error) begin \n", " flag <= 1'b1;\n", " end\n", "end\n", "```\n", "\n", "
\n", " \n", "The counter example can be synthetized:" ] }, { "cell_type": "code", "execution_count": 8, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing v/cnt.v\n" ] } ], "source": [ "%%writefile v/cnt.v\n", "module cnt(\n", " input wire clk,\n", " input wire rst,\n", " output wire [7:0] count\n", ");\n", "\n", " reg [7:0] counter;\n", " assign count = counter;\n", "\n", " always @(posedge clk or negedge rst) begin\n", " if (!rst) begin \n", " counter <= 0;\n", " end else begin\n", " counter <= counter + 1;\n", " end\n", " end\n", "\n", "endmodule" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "For sequential circuits, one must specify to synthesize the clock tree as well:" ] }, { "cell_type": "code", "execution_count": 10, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Overwriting build/config.json\n" ] } ], "source": [ "%%writefile build/config.json\n", "{\n", " \"DESIGN_NAME\": \"cnt\",\n", " \"VERILOG_FILES\": \"dir::../v/cnt.v\",\n", " \"CLOCK_TREE_SYNTH\": true,\n", " \"CLOCK_PORT\": \"clk\",\n", " \"FP_SIZING\": \"absolute\",\n", " \"DIE_AREA\": \"0 0 40 50\",\n", " \"FP_PDN_AUTO_ADJUST\": false,\n", " \"FP_PDN_VOFFSET\": 0,\n", " \"FP_PDN_HOFFSET\": 0,\n", " \"DIODE_INSERTION_STRATEGY\": 3\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The flow can be started:" ] }, { "cell_type": "code", "execution_count": 11, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "env: PDK=sky130A\n", "OpenLane 2023.04.07_0_gcb634fd5-conda\n", "All rights reserved. (c) 2020-2022 Efabless Corporation and contributors.\n", "Available under the Apache License, version 2.0. See the LICENSE file for more details.\n", "\n", "\u001b[36m[INFO]: Using configuration in 'build/config.json'...\u001b[39m\n", "\u001b[36m[INFO]: PDK Root: /home/pierre/anaconda3/envs/semicustom/share/pdk\u001b[39m\n", "\u001b[36m[INFO]: Process Design Kit: sky130A\u001b[39m\n", "\u001b[36m[INFO]: Standard Cell Library: sky130_fd_sc_hd\u001b[39m\n", "\u001b[36m[INFO]: Optimization Standard Cell Library: sky130_fd_sc_hd\u001b[39m\n", "\u001b[33m[WARNING]: DIODE_INSERTION_STRATEGY is now deprecated; use GRT_REPAIR_ANTENNAS, DIODE_ON_PORTS and RUN_HEURISTIC_DIODE_INSERTION instead.\u001b[39m\n", "\u001b[36m[INFO]: DIODE_INSERTION_STRATEGY set to 3. Setting GRT_REPAIR_ANTENNAS to 1\u001b[39m\n", "\u001b[36m[INFO]: Run Directory: /home/pierre/Bureau/freechips/semicustom/build/runs/RUN_2023.05.03_00.26.40\u001b[39m\n", "\u001b[36m[INFO]: Preparing LEF files for the nom corner...\u001b[39m\n", "\u001b[36m[INFO]: Preparing LEF files for the min corner...\u001b[39m\n", "\u001b[36m[INFO]: Preparing LEF files for the max corner...\u001b[39m\n", "[STEP 1]\n", "\u001b[36m[INFO]: Running Synthesis (log: build/runs/RUN_2023.05.03_00.26.40/logs/synthesis/1-synthesis.log)...\u001b[39m\n", "[STEP 2]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.26.40/logs/synthesis/2-sta.log)...\u001b[39m\n", "[STEP 3]\n", "\u001b[36m[INFO]: Running Initial Floorplanning (log: build/runs/RUN_2023.05.03_00.26.40/logs/floorplan/3-initial_fp.log)...\u001b[39m\n", "\u001b[36m[INFO]: Floorplanned with width 28.52 and height 27.2.\u001b[39m\n", "[STEP 4]\n", "\u001b[36m[INFO]: Running IO Placement...\u001b[39m\n", "[STEP 5]\n", "\u001b[36m[INFO]: Running Tap/Decap Insertion (log: build/runs/RUN_2023.05.03_00.26.40/logs/floorplan/5-tap.log)...\u001b[39m\n", "\u001b[36m[INFO]: Power planning with power {VPWR} and ground {VGND}...\u001b[39m\n", "[STEP 6]\n", "\u001b[36m[INFO]: Generating PDN (log: build/runs/RUN_2023.05.03_00.26.40/logs/floorplan/6-pdn.log)...\u001b[39m\n", "[STEP 7]\n", "\u001b[36m[INFO]: Running Global Placement (log: build/runs/RUN_2023.05.03_00.26.40/logs/placement/7-global.log)...\u001b[39m\n", "[STEP 8]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.26.40/logs/placement/8-sta-global.log)...\u001b[39m\n", "[STEP 9]\n", "\u001b[36m[INFO]: Running Placement Resizer Design Optimizations (log: build/runs/RUN_2023.05.03_00.26.40/logs/placement/9-resizer.log)...\u001b[39m\n", "[STEP 10]\n", "\u001b[36m[INFO]: Running Detailed Placement (log: build/runs/RUN_2023.05.03_00.26.40/logs/placement/10-detailed.log)...\u001b[39m\n", "[STEP 11]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.26.40/logs/placement/11-sta.log)...\u001b[39m\n", "[STEP 12]\n", "\u001b[36m[INFO]: Running Clock Tree Synthesis (log: build/runs/RUN_2023.05.03_00.26.40/logs/cts/12-cts.log)...\u001b[39m\n", "[STEP 13]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.26.40/logs/cts/13-sta.log)...\u001b[39m\n", "[STEP 14]\n", "\u001b[36m[INFO]: Running Placement Resizer Timing Optimizations (log: build/runs/RUN_2023.05.03_00.26.40/logs/cts/14-resizer.log)...\u001b[39m\n", "[STEP 15]\n", "\u001b[36m[INFO]: Running Global Routing Resizer Design Optimizations (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/15-resizer_design.log)...\u001b[39m\n", "[STEP 16]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/16-sta-resizer_design.log)...\u001b[39m\n", "[STEP 17]\n", "\u001b[36m[INFO]: Running Global Routing Resizer Timing Optimizations (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/17-resizer_timing.log)...\u001b[39m\n", "[STEP 18]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/18-sta-resizer_timing.log)...\u001b[39m\n", "[STEP 19]\n", "\u001b[36m[INFO]: Running Global Routing (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/19-global.log)...\u001b[39m\n", "\u001b[36m[INFO]: Starting OpenROAD Antenna Repair Iterations...\u001b[39m\n", "[STEP 20]\n", "\u001b[36m[INFO]: Writing Verilog (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/19-global_write_netlist.log)...\u001b[39m\n", "[STEP 21]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/21-sta-groute.log)...\u001b[39m\n", "[STEP 22]\n", "\u001b[36m[INFO]: Running Fill Insertion (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/22-fill.log)...\u001b[39m\n", "[STEP 23]\n", "\u001b[36m[INFO]: Running Detailed Routing (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/23-detailed.log)...\u001b[39m\n", "\u001b[36m[INFO]: No DRC violations after detailed routing.\u001b[39m\n", "[STEP 24]\n", "\u001b[36m[INFO]: Checking Wire Lengths (log: build/runs/RUN_2023.05.03_00.26.40/logs/routing/24-wire_lengths.log)...\u001b[39m\n", "[STEP 25]\n", "\u001b[36m[INFO]: Running SPEF Extraction at the min process corner (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/25-parasitics_extraction.min.log)...\u001b[39m\n", "[STEP 26]\n", "\u001b[36m[INFO]: Running Multi-Corner Static Timing Analysis at the min process corner (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/26-rcx_mcsta.min.log)...\u001b[39m\n", "[STEP 27]\n", "\u001b[36m[INFO]: Running SPEF Extraction at the max process corner (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/27-parasitics_extraction.max.log)...\u001b[39m\n", "[STEP 28]\n", "\u001b[36m[INFO]: Running Multi-Corner Static Timing Analysis at the max process corner (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/28-rcx_mcsta.max.log)...\u001b[39m\n", "[STEP 29]\n", "\u001b[36m[INFO]: Running SPEF Extraction at the nom process corner (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/29-parasitics_extraction.nom.log)...\u001b[39m\n", "[STEP 30]\n", "\u001b[36m[INFO]: Running Multi-Corner Static Timing Analysis at the nom process corner (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/30-rcx_mcsta.nom.log)...\u001b[39m\n", "[STEP 31]\n", "\u001b[36m[INFO]: Running Single-Corner Static Timing Analysis at the nom process corner (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/31-rcx_sta.log)...\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_fd_sc_hd__tapvpwrvgnd_1 blackboxed during sta\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_ef_sc_hd__decap_12 blackboxed during sta\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_fd_sc_hd__fill_1 blackboxed during sta\u001b[39m\n", "\u001b[33m[WARNING]: Module sky130_fd_sc_hd__fill_2 blackboxed during sta\u001b[39m\n", "[STEP 32]\n", "\u001b[36m[INFO]: Creating IR Drop Report (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/32-irdrop.log)...\u001b[39m\n", "[STEP 33]\n", "\u001b[36m[INFO]: Running Magic to generate various views...\u001b[39m\n", "\u001b[36m[INFO]: Streaming out GDSII with Magic (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/33-gdsii.log)...\u001b[39m\n", "\u001b[36m[INFO]: Generating MAGLEF views...\u001b[39m\n", "[STEP 34]\n", "\u001b[36m[INFO]: Streaming out GDSII with KLayout (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/34-gdsii-klayout.log)...\u001b[39m\n", "[STEP 35]\n", "\u001b[36m[INFO]: Running XOR on the layouts using KLayout (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/35-xor.log)...\u001b[39m\n", "\u001b[36m[INFO]: No XOR differences between KLayout and Magic gds.\u001b[39m\n", "[STEP 36]\n", "\u001b[36m[INFO]: Running Magic Spice Export from LEF (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/36-spice.log)...\u001b[39m\n", "[STEP 37]\n", "\u001b[36m[INFO]: Writing Powered Verilog (logs: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/37-write_powered_def.log, build/runs/RUN_2023.05.03_00.26.40/logs/signoff/37-write_powered_verilog.log)...\u001b[39m\n", "[STEP 38]\n", "\u001b[36m[INFO]: Writing Verilog (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/37-write_powered_verilog.log)...\u001b[39m\n", "[STEP 39]\n", "\u001b[36m[INFO]: Running LVS (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/39-lvs.lef.log)...\u001b[39m\n", "[STEP 40]\n", "\u001b[36m[INFO]: Running Magic DRC (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/40-drc.log)...\u001b[39m\n", "\u001b[36m[INFO]: Converting Magic DRC database to various tool-readable formats...\u001b[39m\n", "\u001b[36m[INFO]: No DRC violations after GDS streaming out.\u001b[39m\n", "[STEP 41]\n", "\u001b[36m[INFO]: Running OpenROAD Antenna Rule Checker (log: build/runs/RUN_2023.05.03_00.26.40/logs/signoff/41-antenna.log)...\u001b[39m\n", "\u001b[36m[INFO]: Saving current set of views in 'build/runs/RUN_2023.05.03_00.26.40/results/final'...\u001b[39m\n", "\u001b[36m[INFO]: Saving runtime environment...\u001b[39m\n", "\u001b[36m[INFO]: Generating final set of reports...\u001b[39m\n", "\u001b[36m[INFO]: Created manufacturability report at 'build/runs/RUN_2023.05.03_00.26.40/reports/manufacturability.rpt'.\u001b[39m\n", "\u001b[36m[INFO]: Created metrics report at 'build/runs/RUN_2023.05.03_00.26.40/reports/metrics.csv'.\u001b[39m\n", "\u001b[36m[INFO]: There are no max slew, max fanout or max capacitance violations in the design at the typical corner.\u001b[39m\n", "\u001b[36m[INFO]: There are no hold violations in the design at the typical corner.\u001b[39m\n", "\u001b[36m[INFO]: There are no setup violations in the design at the typical corner.\u001b[39m\n", "\u001b[32m[SUCCESS]: Flow complete.\u001b[39m\n", "\u001b[36m[INFO]: Note that the following warnings have been generated:\u001b[39m\n", "[WARNING]: Module sky130_fd_sc_hd__tapvpwrvgnd_1 blackboxed during sta\n", "[WARNING]: Module sky130_ef_sc_hd__decap_12 blackboxed during sta\n", "[WARNING]: Module sky130_fd_sc_hd__fill_1 blackboxed during sta\n", "[WARNING]: Module sky130_fd_sc_hd__fill_2 blackboxed during sta\n", "\n" ] } ], "source": [ "%env PDK=sky130A\n", "!flow.tcl -design build" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The cell above can be reused to display the lyaout." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## High-Level Synthesis (HLS)\n", "\n", "RTL description of circuits does not follow an imperative programming paradigm. It is a description language that produces highly parallelized designs.\n", "\n", "High-Level Synthesis provides an imperative language and a compiler that synthesizes the imperative instructions into RTL. For instance, _XLS_ provides a _Rust_-like language:" ] }, { "cell_type": "code", "execution_count": 13, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing xls/x/find_max.x\n" ] } ], "source": [ "%%writefile xls/x/find_max.x\n", "\n", "//\n", "// Input: an array of 32-bit unsigned integers (u32) of parametrized length N\n", "// Output: the largest element of the array\n", "//\n", "pub fn find_max(array: u32[N]) -> u32 {\n", " let max: u32 = u32:0;\n", " for (i, max): (u32, u32) in range(u32:0,N) {\n", " if (array[i] > max) {array[i]} else {max}\n", " }(max)\n", "}\n", "\n", "//\n", "// Input: an array of 32-bit unsigned integers (u32) of parametrized length 4\n", "// Output: the largest element of the array\n", "//\n", "pub fn find_max_impl(array: u32[4]) -> u32 {\n", " find_max(array)\n", "}\n", " \n", "#[test]\n", "fn find_max_impl_test() {\n", " let _= assert_eq(find_max_impl(u32[4]:[45,3,15,6]), u32:45);\n", " let _= assert_eq(find_max_impl(u32[4]:[3,45,15,6]), u32:45);\n", " let _= assert_eq(find_max_impl(u32[4]:[15,3,45,6]), u32:45);\n", " let _= assert_eq(find_max_impl(u32[4]:[6,3,15,45]), u32:45);\n", "}\n", "\n", "#[test]\n", "fn find_max_test() {\n", " let _= assert_eq(find_max(u32[1]:[39]), u32:39);\n", " let _= assert_eq(find_max(u32[2]:[4,90]), u32:90);\n", " let _= assert_eq(find_max(u32[3]:[7,21,15]), u32:21);\n", " let _= assert_eq(find_max(u32[8]:[1,3,45,1,5,56,0,34]), u32:56);\n", "}" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Testing, parsing and linting can be performed prior to RTL synhesis:" ] }, { "cell_type": "code", "execution_count": 14, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "[ RUN UNITTEST ] find_max_impl_test\n", "[ OK ]\n", "[ RUN UNITTEST ] find_max_test\n", "[ OK ]\n", "[===============] 2 test(s) ran; 0 failed; 0 skipped.\n" ] } ], "source": [ "!interpreter_main xls/x/find_max.x" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "Now that the imperative instructions are tested, the RTL design can be synthesized by _XLS_:" ] }, { "cell_type": "code", "execution_count": 15, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "module __find_max__find_max_impl(\r\n", " input wire [127:0] array,\r\n", " output wire [31:0] out\r\n", ");\r\n", " wire [31:0] array_unflattened[4];\r\n", " assign array_unflattened[0] = array[31:0];\r\n", " assign array_unflattened[1] = array[63:32];\r\n", " assign array_unflattened[2] = array[95:64];\r\n", " assign array_unflattened[3] = array[127:96];\r\n", " wire [31:0] array_index_74;\r\n", " wire [31:0] array_index_75;\r\n", " wire [31:0] array_index_78;\r\n", " wire [31:0] sel_79;\r\n", " wire [31:0] array_index_82;\r\n", " wire [31:0] sel_83;\r\n", " assign array_index_74 = array_unflattened[2'h1];\r\n", " assign array_index_75 = array_unflattened[2'h0];\r\n", " assign array_index_78 = array_unflattened[2'h2];\r\n", " assign sel_79 = array_index_74 > array_index_75 ? array_index_74 : array_index_75;\r\n", " assign array_index_82 = array_unflattened[2'h3];\r\n", " assign sel_83 = array_index_78 > sel_79 ? array_index_78 : sel_79;\r\n", " assign out = array_index_82 > sel_83 ? array_index_82 : sel_83;\r\n", "endmodule\r\n" ] } ], "source": [ "XLS_DESIGN_NAME = 'find_max_impl'\n", "XLS_DESIGN_FILE = 'find_max'\n", "!ir_converter_main --top={XLS_DESIGN_NAME} xls/x/{XLS_DESIGN_FILE}.x > xls/ir/{XLS_DESIGN_FILE}.ir\n", "!opt_main xls/ir/{XLS_DESIGN_FILE}.ir > xls/ir/{XLS_DESIGN_FILE}_opt.ir\n", "!codegen_main --generator=combinational xls/ir/{XLS_DESIGN_FILE}_opt.ir > v/{XLS_DESIGN_FILE}.v\n", "!cat v/{XLS_DESIGN_FILE}.v" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Verilog simulation\n", "\n", "A test bench can be written to simulate the `xor3` circuit described above:" ] }, { "cell_type": "code", "execution_count": 16, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing tb/xor3_tb.v\n" ] } ], "source": [ "%%writefile tb/xor3_tb.v\n", "module xor3_tb;\n", "\n", " wire value;\n", " reg w1, w2, w3;\n", " initial begin\n", " $dumpfile(\"tb/xor3_tb.vcd\");\n", " $dumpvars(0,xor3_tb);\n", " # 0 w1 = 0; w2 = 0; w3 = 0;\n", " # 5 w1 = 0; w2 = 0; w3 = 1;\n", " # 5 w1 = 0; w2 = 1; w3 = 0;\n", " # 5 w1 = 0; w2 = 1; w3 = 1;\n", " # 5 w1 = 1; w2 = 0; w3 = 0;\n", " # 5 w1 = 1; w2 = 0; w3 = 1;\n", " # 5 w1 = 1; w2 = 1; w3 = 0;\n", " # 5 w1 = 1; w2 = 1; w3 = 1;\n", " # 5 $finish;\n", " end\n", "\n", " xor3 xor3_i (w1, w2, w3, value);\n", "\n", " initial\n", " $monitor(\"At time %t, value = %h (%0d)\",\n", " $time, value, value);\n", "endmodule" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The simulation can then be performed using _Icarus Verilog_:" ] }, { "cell_type": "code", "execution_count": 17, "metadata": { "scrolled": true }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "VCD info: dumpfile tb/xor3_tb.vcd opened for output.\r\n", "At time 0, value = 0 (0)\r\n", "At time 5, value = 1 (1)\r\n", "At time 15, value = 0 (0)\r\n", "At time 20, value = 1 (1)\r\n", "At time 25, value = 0 (0)\r\n", "At time 35, value = 1 (1)\r\n", "tb/xor3_tb.v:16: $finish called at 40 (1s)\r\n" ] } ], "source": [ "!iverilog -o tb/xor3_tb tb/xor3_tb.v v/xor3.v\n", "!vvp tb/xor3_tb" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "The waveforms are dumped in a `.vcd` file, located under:\n", "\n", "```\n", "tb/xor3_tb.vcd\n", "```\n", "\n", "It can be opened with https://vc.drom.io/ for instance." ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "## Some ideas...\n", "\n", "Here are a couple ideas to spend a good time exploring those beautiful pieces of software:\n", "\n", " * Play with RTL2GDS configuration parameters and observe the impact on the layout.\n", " * Simulate the `cnt` sequential circuit.\n", " * Simulate the `find_max_impl` circuit synthesized using HLS.\n", " * Try to make _Klayout_ GUI work (no warranty).\n", "\n", " **Do not start from scratch! Use the provided examples, examples you can find on the internet and the documentation to adapt from them!**\n", " \n", " > Good luck and read the docs. 😉\n", " \n", "## More food for the brain\n", "\n", " * GDS2RTL flow configuration parameters: https://armleo-openlane.readthedocs.io/en/latest/docs/source/configuration.html\n", " * DSLX language reference: https://google.github.io/xls/dslx_reference/" ] }, { "cell_type": "markdown", "metadata": {}, "source": [ "# References\n", "Inspired from:\n", "“Silicon Notebooks.” CHIPS Alliance, Apr. 08, 2023. Accessed: Apr. 10, 2023. [Online]. Available: https://github.com/chipsalliance/silicon-notebooks/blob/b65134a43b01ae31423f7ee87110740b2257ac42/digital-inverter-openlane.ipynb (Apache License 2.0)" ] } ], "metadata": { "colab": { "name": "digital-inverter-openlane.ipynb", "provenance": [] }, "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.7.16" } }, "nbformat": 4, "nbformat_minor": 1 }