{ "cells": [ { "cell_type": "markdown", "metadata": { "id": "uINjDJNf39eD" }, "source": [ "# Semicustom digital design demo using OpenROAD\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", "\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", "
" ] }, { "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": 2, "metadata": { "id": "rbT-vP0h0enK" }, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ "Writing 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 25 35\",\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": 3, "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/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.27.15\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.04.30_19.27.15/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.04.30_19.27.15/logs/synthesis/2-sta.log)...\u001b[39m\n", "[STEP 3]\n", "\u001b[36m[INFO]: Running Initial Floorplanning (log: build/runs/RUN_2023.04.30_19.27.15/logs/floorplan/3-initial_fp.log)...\u001b[39m\n", "\u001b[36m[INFO]: Floorplanned with width 13.8 and height 10.88.\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.04.30_19.27.15/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.04.30_19.27.15/logs/floorplan/6-pdn.log)...\u001b[39m\n", "[STEP 7]\n", "\u001b[36m[INFO]: Running Global Placement (log: build/runs/RUN_2023.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/logs/placement/9-resizer.log)...\u001b[39m\n", "[STEP 10]\n", "\u001b[36m[INFO]: Running Detailed Placement (log: build/runs/RUN_2023.04.30_19.27.15/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.04.30_19.27.15/logs/placement/11-sta.log)...\u001b[39m\n", "[STEP 12]\n", "\u001b[36m[INFO]: Running Placement Resizer Timing Optimizations (log: build/runs/RUN_2023.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/logs/routing/16-sta-resizer_timing.log)...\u001b[39m\n", "[STEP 17]\n", "\u001b[36m[INFO]: Running Global Routing (log: build/runs/RUN_2023.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/logs/routing/19-sta-groute.log)...\u001b[39m\n", "[STEP 20]\n", "\u001b[36m[INFO]: Running Fill Insertion (log: build/runs/RUN_2023.04.30_19.27.15/logs/routing/20-fill.log)...\u001b[39m\n", "[STEP 21]\n", "\u001b[36m[INFO]: Running Detailed Routing (log: build/runs/RUN_2023.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/logs/signoff/29-rcx_sta.log)...\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 30]\n", "\u001b[36m[INFO]: Creating IR Drop Report (log: build/runs/RUN_2023.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/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.04.30_19.27.15/logs/signoff/34-spice.log)...\u001b[39m\n", "[STEP 35]\n", "\u001b[36m[INFO]: Writing Powered Verilog (logs: build/runs/RUN_2023.04.30_19.27.15/logs/signoff/35-write_powered_def.log, build/runs/RUN_2023.04.30_19.27.15/logs/signoff/35-write_powered_verilog.log)...\u001b[39m\n", "[STEP 36]\n", "\u001b[36m[INFO]: Writing Verilog (log: build/runs/RUN_2023.04.30_19.27.15/logs/signoff/35-write_powered_verilog.log)...\u001b[39m\n", "[STEP 37]\n", "\u001b[36m[INFO]: Running LVS (log: build/runs/RUN_2023.04.30_19.27.15/logs/signoff/37-lvs.lef.log)...\u001b[39m\n", "\u001b[31m[ERROR]: There are LVS errors in the design: See 'build/runs/RUN_2023.04.30_19.27.15/reports/signoff/37-xor3.lvs.rpt' for a summary and 'build/runs/RUN_2023.04.30_19.27.15/logs/signoff/37-lvs.lef.log' for details.\u001b[39m\n", "\u001b[31m[ERROR]: Step(37:lvs) failed with error:\n", "-code 1 -level 0 -errorstack {INNER {invokeStk1 throw_error} CALL {quit_on_lvs_error -rpt /home/pierre/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.27.15/reports/signoff/37-xor3.lvs.rpt -log /home/pierre/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.27.15/logs/signoff/37-lvs.lef.log} CALL run_lvs CALL run_lvs_step CALL {run_non_interactive_mode -design build}} -errorcode NONE -errorinfo {\n", " while executing\n", "\"throw_error\"\n", " (procedure \"quit_on_lvs_error\" line 13)\n", " invoked from within\n", "\"quit_on_lvs_error -rpt $count_lvs_rpt -log $log\"\n", " (procedure \"run_lvs\" line 76)\n", " invoked from within\n", "\"run_lvs\"\n", " (procedure \"run_lvs_step\" line 10)\n", " invoked from within\n", "\"run_lvs_step\"} -errorline 1\u001b[39m\n", "\u001b[36m[INFO]: Saving current set of views in 'build/runs/RUN_2023.04.30_19.27.15/results/final'...\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.04.30_19.27.15/reports/manufacturability.rpt'.\u001b[39m\n", "\u001b[36m[INFO]: Created metrics report at 'build/runs/RUN_2023.04.30_19.27.15/reports/metrics.csv'.\u001b[39m\n", "\u001b[36m[INFO]: Saving runtime environment...\u001b[39m\n" ] }, { "name": "stdout", "output_type": "stream", "text": [ "\u001b[31m[ERROR]: Flow failed.\u001b[39m\r", "\r\n", "\u001b[36m[INFO]: The failure may have been because of the following warnings:\u001b[39m\r", "\r\n", "[WARNING]: Module sky130_ef_sc_hd__decap_12 blackboxed during sta\r", "\r\n", "[WARNING]: Module sky130_fd_sc_hd__fill_1 blackboxed during sta\r", "\r\n", "[WARNING]: Module sky130_fd_sc_hd__fill_2 blackboxed during sta\r", "\r\n", "\r", "\r\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": 4, "metadata": { "colab": { "base_uri": "https://localhost:8080/", "height": 650 }, "id": "WOnhdtp3ivRi", "outputId": "b4bd26f8-d3da-47b7-e321-99272b0591ef", "scrolled": false }, "outputs": [ { "data": { "image/svg+xml": [ "" ], "text/plain": [ "\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", "
\n", " | 0 | \n", "
---|---|
design | \n", "/home/pierre/Documents/freechips/semicustom/build | \n", "
design_name | \n", "xor3 | \n", "
config | \n", "RUN_2023.04.30_19.27.15 | \n", "
flow_status | \n", "flow failed | \n", "
total_runtime | \n", "0h0m17s0ms | \n", "
routed_runtime | \n", "0h0m10s0ms | \n", "
(Cell/mm^2)/Core_Util | \n", "13714.285714 | \n", "
DIEAREA_mm^2 | \n", "0.000875 | \n", "
CellPer_mm^2 | \n", "6857.142857 | \n", "
OpenDP_Util | \n", "27.08 | \n", "
Final_Util | \n", "-1 | \n", "
Peak_Memory_Usage_MB | \n", "469.18 | \n", "
synth_cell_count | \n", "2 | \n", "
tritonRoute_violations | \n", "0 | \n", "
Short_violations | \n", "0 | \n", "
MetSpc_violations | \n", "0 | \n", "
OffGrid_violations | \n", "0 | \n", "
MinHole_violations | \n", "0 | \n", "
Other_violations | \n", "0 | \n", "
Magic_violations | \n", "-1 | \n", "
pin_antenna_violations | \n", "-1 | \n", "
net_antenna_violations | \n", "-1 | \n", "
lvs_total_errors | \n", "17 | \n", "
cvc_total_errors | \n", "-1 | \n", "
klayout_violations | \n", "-1 | \n", "
wire_length | \n", "88 | \n", "
vias | \n", "30 | \n", "
wns | \n", "0.0 | \n", "
pl_wns | \n", "-1 | \n", "
optimized_wns | \n", "-1 | \n", "
fastroute_wns | \n", "-1 | \n", "
spef_wns | \n", "0.0 | \n", "
tns | \n", "0.0 | \n", "
pl_tns | \n", "-1 | \n", "
optimized_tns | \n", "-1 | \n", "
fastroute_tns | \n", "-1 | \n", "
spef_tns | \n", "0.0 | \n", "
HPWL | \n", "98756.0 | \n", "
routing_layer1_pct | \n", "0.0 | \n", "
routing_layer2_pct | \n", "4.41 | \n", "
routing_layer3_pct | \n", "4.6 | \n", "
routing_layer4_pct | \n", "0.0 | \n", "
routing_layer5_pct | \n", "0.0 | \n", "
routing_layer6_pct | \n", "0.0 | \n", "
wires_count | \n", "5 | \n", "
wire_bits | \n", "5 | \n", "
public_wires_count | \n", "4 | \n", "
public_wire_bits | \n", "4 | \n", "
memories_count | \n", "0 | \n", "
memory_bits | \n", "0 | \n", "
processes_count | \n", "0 | \n", "
cells_pre_abc | \n", "2 | \n", "
AND | \n", "0 | \n", "
DFF | \n", "0 | \n", "
NAND | \n", "0 | \n", "
NOR | \n", "0 | \n", "
OR | \n", "0 | \n", "
XOR | \n", "2 | \n", "
XNOR | \n", "0 | \n", "
MUX | \n", "0 | \n", "
inputs | \n", "3 | \n", "
outputs | \n", "1 | \n", "
level | \n", "2 | \n", "
DecapCells | \n", "16 | \n", "
WelltapCells | \n", "0 | \n", "
DiodeCells | \n", "0 | \n", "
FillCells | \n", "3 | \n", "
NonPhysCells | \n", "6 | \n", "
TotalCells | \n", "25 | \n", "
CoreArea_um^2 | \n", "150.144 | \n", "
power_slowest_internal_uW | \n", "-1 | \n", "
power_slowest_switching_uW | \n", "-1 | \n", "
power_slowest_leakage_uW | \n", "-1 | \n", "
power_typical_internal_uW | \n", "0.000001 | \n", "
power_typical_switching_uW | \n", "0.000002 | \n", "
power_typical_leakage_uW | \n", "0.0 | \n", "
power_fastest_internal_uW | \n", "-1 | \n", "
power_fastest_switching_uW | \n", "-1 | \n", "
power_fastest_leakage_uW | \n", "-1 | \n", "
critical_path_ns | \n", "0.64 | \n", "
suggested_clock_period | \n", "10.0 | \n", "
suggested_clock_frequency | \n", "100.0 | \n", "
CLOCK_PERIOD | \n", "10.0 | \n", "
FP_ASPECT_RATIO | \n", "1 | \n", "
FP_CORE_UTIL | \n", "50 | \n", "
FP_PDN_HPITCH | \n", "153.18 | \n", "
FP_PDN_VPITCH | \n", "153.6 | \n", "
GRT_ADJUSTMENT | \n", "0.3 | \n", "
GRT_REPAIR_ANTENNAS | \n", "1 | \n", "
PL_TARGET_DENSITY | \n", "0.6 | \n", "
RUN_HEURISTIC_DIODE_INSERTION | \n", "0 | \n", "
STD_CELL_LIBRARY | \n", "sky130_fd_sc_hd | \n", "
SYNTH_MAX_FANOUT | \n", "10 | \n", "
SYNTH_STRATEGY | \n", "AREA 0 | \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", "#### ↕️ 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", "The counter example can be synthetized:" ] }, { "cell_type": "code", "execution_count": 6, "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": 7, "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": 9, "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/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.28.02\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.04.30_19.28.02/logs/synthesis/1-synthesis.log)...\u001b[39m\n", "\u001b[31m[ERROR]: during executing yosys script /home/pierre/anaconda3/envs/semicustom/share/openlane/scripts/yosys/synth.tcl\u001b[39m\n", "\u001b[31m[ERROR]: Log: build/runs/RUN_2023.04.30_19.28.02/logs/synthesis/1-synthesis.log\u001b[39m\n", "\u001b[31m[ERROR]: Last 10 lines:\n", " Yosys 0.27+30 (git sha1 e56dad56c, x86_64-conda-linux-gnu-cc 11.2.0 -fvisibility-inlines-hidden -fmessage-length=0 -march=nocona -mtune=haswell -ftree-vectorize -fPIC -fstack-protector-strong -fno-plt -O2 -ffunction-sections -fdebug-prefix-map=/root/conda-eda/conda-eda/workdir/conda-env/conda-bld/yosys_1681341442694/work=/usr/local/src/conda/yosys-0.27_33_ge56dad56c -fdebug-prefix-map=/home/pierre/anaconda3/envs/semicustom=/usr/local/src/conda-prefix -fPIC -Os -fno-merge-constants)\n", "\n", "[TCL: yosys -import] Command name collision: found pre-existing command `cd' -> skip.\n", "[TCL: yosys -import] Command name collision: found pre-existing command `eval' -> skip.\n", "[TCL: yosys -import] Command name collision: found pre-existing command `exec' -> skip.\n", "[TCL: yosys -import] Command name collision: found pre-existing command `read' -> skip.\n", "[TCL: yosys -import] Command name collision: found pre-existing command `trace' -> skip.\n", "ERROR: Can't open input file `/home/pierre/Documents/freechips/semicustom/build/v/cnt.v' for reading: No such file or directory\n", "ERROR: TCL interpreter returned an error: Yosys command produced an error\n", "child process exited abnormally\n", "\u001b[39m\n", "\u001b[31m[ERROR]: Creating issue reproducible...\u001b[39m\n", "\u001b[36m[INFO]: Saving runtime environment...\u001b[39m\n", "OpenLane TCL Issue Packager\n", "\n", "EFABLESS CORPORATION AND ALL AUTHORS OF THE OPENLANE PROJECT SHALL NOT BE HELD\n", "LIABLE FOR ANY LEAKS THAT MAY OCCUR TO ANY PROPRIETARY DATA AS A RESULT OF USING\n", "THIS SCRIPT. THIS SCRIPT IS PROVIDED ON AN \"AS IS\" BASIS, WITHOUT WARRANTIES OR\n", "CONDITIONS OF ANY KIND.\n", "\n", "BY USING THIS SCRIPT, YOU ACKNOWLEDGE THAT YOU FULLY UNDERSTAND THIS DISCLAIMER\n", "AND ALL IT ENTAILS.\n", "\n", "Parsing config file(s)…\n", "Setting up /home/pierre/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.28.02/issue_reproducible…\n", "Done.\n", "\u001b[36m[INFO]: Reproducible packaged: Please tarball and upload 'build/runs/RUN_2023.04.30_19.28.02/issue_reproducible' if you're going to submit an issue.\u001b[39m\n", "\u001b[31m[ERROR]: Step(1:synthesis) failed with error:\n", "-code 1 -level 0 -errorstack {INNER {invokeStk1 throw_error} CALL {run_tcl_script -tool yosys -no_consume /home/pierre/anaconda3/envs/semicustom/share/openlane/scripts/yosys/synth.tcl -indexed_log /home/pierre/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.28.02/logs/synthesis/1-synthesis.log} CALL {run_yosys_script /home/pierre/anaconda3/envs/semicustom/share/openlane/scripts/yosys/synth.tcl -indexed_log /home/pierre/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.28.02/logs/synthesis/1-synthesis.log} CALL {run_yosys -indexed_log /home/pierre/Documents/freechips/semicustom/build/runs/RUN_2023.04.30_19.28.02/logs/synthesis/1-synthesis.log} CALL run_synthesis CALL {run_non_interactive_mode -design build}} -errorcode NONE -errorinfo {\n", " while executing\n", "\"throw_error\"\n", " (procedure \"run_tcl_script\" line 219)\n", " invoked from within\n", "\"run_tcl_script -tool yosys -no_consume {*}$args\"\n", " (procedure \"run_yosys_script\" line 2)\n", " invoked from within\n", "\"run_yosys_script $::env(SYNTH_SCRIPT) -indexed_log $arg_values(-indexed_log)\"\n", " (procedure \"run_yosys\" line 44)\n", " invoked from within\n", "\"run_yosys -indexed_log $log\"\n", " (procedure \"run_synthesis\" line 13)\n", " invoked from within\n", "\"run_synthesis\"} -errorline 1\u001b[39m\n", "\u001b[36m[INFO]: Saving current set of views in 'build/runs/RUN_2023.04.30_19.28.02/results/final'...\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.04.30_19.28.02/reports/manufacturability.rpt'.\u001b[39m\n", "\u001b[36m[INFO]: Created metrics report at 'build/runs/RUN_2023.04.30_19.28.02/reports/metrics.csv'.\u001b[39m\n", "\u001b[36m[INFO]: Saving runtime environment...\u001b[39m\n", "\u001b[31m[ERROR]: Flow failed.\u001b[39m\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": 10, "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\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", "