|
| 1 | +#!/usr/bin/env bash |
| 2 | +# |
| 3 | +# DFT "pre-placed ODB" demos (no full ORFS flow re-run). |
| 4 | +# |
| 5 | +# Each non-comment line is a standalone command. Comment out all but one line and run: |
| 6 | +# bash demo.sh |
| 7 | +# |
| 8 | +# Optional: override the input run dir (must contain 3_5_place_dp.odb, 3_place.sdc, 6_final.def): |
| 9 | +# DEMO_RUN_DIR=flow/results/<platform>/<design>/<variant> bash demo.sh |
| 10 | +# |
| 11 | +# Outputs land in ./demo-outputs/<demo>/ (plots + stitched DEF/Verilog + logs + JSON metrics). |
| 12 | + |
| 13 | +# 01) JPEG: K=1, begin=LL, end=UR, HEURISTIC (baseline). |
| 14 | +( set -euo pipefail; ROOT="$PWD"; RUN="${DEMO_RUN_DIR:-$ROOT/flow/results/nangate45/jpeg/jpeg_scanopt500_routeaware}"; OR="$ROOT/tools/OpenROAD/build/bin/openroad"; LIB="$ROOT/flow/platforms/nangate45/lib/NangateOpenCellLibrary_typical.lib"; ODB="$RUN/3_5_place_dp.odb"; SDC="$RUN/3_place.sdc"; OUT="$ROOT/demo-outputs/01_k1_heuristic_ll_to_ur"; rm -rf "$OUT"; mkdir -p "$OUT"; read -r X0 Y0 X1 Y1 <<<"$(awk '/^DIEAREA/ {gsub(/[();]/,"",$0); print $2,$3,$4,$5; exit}' "$RUN/6_final.def")"; [[ -n "$X1" && -n "$Y1" ]]; printf "# demo: endpoints in DBU\nchain chain_0 begin %s %s end %s %s\n" "$X0" "$Y0" "$X1" "$Y1" >"$OUT/constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/constraints.txt" --out-prefix "$OUT/heuristic" --chain-counts 1 --max-imbalances 2 --scan-order-solver HEURISTIC --scanopt-time-limit 0 --out-json "$OUT/heuristic.json"; echo "DONE: $OUT"; ) |
| 15 | + |
| 16 | +# 02) JPEG: K=1, begin=LL, end=UR, SCANOPT (15s). |
| 17 | +( set -euo pipefail; ROOT="$PWD"; RUN="${DEMO_RUN_DIR:-$ROOT/flow/results/nangate45/jpeg/jpeg_scanopt500_routeaware}"; OR="$ROOT/tools/OpenROAD/build/bin/openroad"; LIB="$ROOT/flow/platforms/nangate45/lib/NangateOpenCellLibrary_typical.lib"; ODB="$RUN/3_5_place_dp.odb"; SDC="$RUN/3_place.sdc"; OUT="$ROOT/demo-outputs/02_k1_scanopt15_ll_to_ur"; rm -rf "$OUT"; mkdir -p "$OUT"; read -r X0 Y0 X1 Y1 <<<"$(awk '/^DIEAREA/ {gsub(/[();]/,"",$0); print $2,$3,$4,$5; exit}' "$RUN/6_final.def")"; [[ -n "$X1" && -n "$Y1" ]]; printf "# demo: endpoints in DBU\nchain chain_0 begin %s %s end %s %s\n" "$X0" "$Y0" "$X1" "$Y1" >"$OUT/constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/constraints.txt" --out-prefix "$OUT/scanopt15" --chain-counts 1 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 15 --out-json "$OUT/scanopt15.json"; echo "DONE: $OUT"; ) |
| 18 | + |
| 19 | +# 03) JPEG: K=2, begin=LL, end=LL, SCANOPT (15s), max_imbalance=2% (default for K>1). |
| 20 | +( set -euo pipefail; ROOT="$PWD"; RUN="${DEMO_RUN_DIR:-$ROOT/flow/results/nangate45/jpeg/jpeg_scanopt500_routeaware}"; OR="$ROOT/tools/OpenROAD/build/bin/openroad"; LIB="$ROOT/flow/platforms/nangate45/lib/NangateOpenCellLibrary_typical.lib"; ODB="$RUN/3_5_place_dp.odb"; SDC="$RUN/3_place.sdc"; OUT="$ROOT/demo-outputs/03_k2_scanopt15_ll_to_ll_bal2"; rm -rf "$OUT"; mkdir -p "$OUT"; read -r X0 Y0 X1 Y1 <<<"$(awk '/^DIEAREA/ {gsub(/[();]/,"",$0); print $2,$3,$4,$5; exit}' "$RUN/6_final.def")"; [[ -n "$X1" && -n "$Y1" ]]; printf "# demo: endpoints in DBU\nchain chain_0 begin %s %s end %s %s\nchain chain_1 begin %s %s end %s %s\n" "$X0" "$Y0" "$X0" "$Y0" "$X0" "$Y0" "$X0" "$Y0" >"$OUT/constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/constraints.txt" --out-prefix "$OUT/scanopt15" --chain-counts 2 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 15 --out-json "$OUT/scanopt15.json"; echo "DONE: $OUT"; ) |
| 21 | + |
| 22 | +# 04) JPEG: K=2, begin=LL, end=UR, SCANOPT (15s), max_imbalance=2%. |
| 23 | +( set -euo pipefail; ROOT="$PWD"; RUN="${DEMO_RUN_DIR:-$ROOT/flow/results/nangate45/jpeg/jpeg_scanopt500_routeaware}"; OR="$ROOT/tools/OpenROAD/build/bin/openroad"; LIB="$ROOT/flow/platforms/nangate45/lib/NangateOpenCellLibrary_typical.lib"; ODB="$RUN/3_5_place_dp.odb"; SDC="$RUN/3_place.sdc"; OUT="$ROOT/demo-outputs/04_k2_scanopt15_ll_to_ur_bal2"; rm -rf "$OUT"; mkdir -p "$OUT"; read -r X0 Y0 X1 Y1 <<<"$(awk '/^DIEAREA/ {gsub(/[();]/,"",$0); print $2,$3,$4,$5; exit}' "$RUN/6_final.def")"; [[ -n "$X1" && -n "$Y1" ]]; printf "# demo: endpoints in DBU\nchain chain_0 begin %s %s end %s %s\nchain chain_1 begin %s %s end %s %s\n" "$X0" "$Y0" "$X1" "$Y1" "$X0" "$Y0" "$X1" "$Y1" >"$OUT/constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/constraints.txt" --out-prefix "$OUT/scanopt15" --chain-counts 2 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 15 --out-json "$OUT/scanopt15.json"; echo "DONE: $OUT"; ) |
| 24 | + |
| 25 | +# 05) JPEG: strict subpath ordering (constraints: `path` + `assign`), plus an index/contiguity check. |
| 26 | +( set -euo pipefail; ROOT="$PWD"; RUN="${DEMO_RUN_DIR:-$ROOT/flow/results/nangate45/jpeg/jpeg_scanopt500_routeaware}"; OR="$ROOT/tools/OpenROAD/build/bin/openroad"; LIB="$ROOT/flow/platforms/nangate45/lib/NangateOpenCellLibrary_typical.lib"; ODB="$RUN/3_5_place_dp.odb"; SDC="$RUN/3_place.sdc"; OUT="$ROOT/demo-outputs/05_constraints_path_k1"; rm -rf "$OUT"; mkdir -p "$OUT"; read -r X0 Y0 X1 Y1 <<<"$(awk '/^DIEAREA/ {gsub(/[();]/,"",$0); print $2,$3,$4,$5; exit}' "$RUN/6_final.def")"; [[ -n "$X1" && -n "$Y1" ]]; python3 "$ROOT/flow/util/dft_demo_make_constraints.py" --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --chain-count 1 --max-imbalance 2 --mode path --count 10 --out "$OUT/constraints.txt" --out-meta "$OUT/constraints.meta.json"; printf "chain chain_0 begin %s %s end %s %s\n" "$X0" "$Y0" "$X1" "$Y1" >>"$OUT/constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/constraints.txt" --out-prefix "$OUT/scanopt15" --chain-counts 1 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 15 --out-json "$OUT/scanopt15.json"; PYTHONPATH="$ROOT/flow/util" python3 -c "import json,sys; from pathlib import Path; from scan_chain_plot import reconstruct_chains_from_verilog; meta=json.load(open(sys.argv[1])); raw=meta['selected_cells']; cells=[c.replace('\\\\','') for c in raw]; chains,errs=reconstruct_chains_from_verilog(Path(sys.argv[2]), scan_in='scan_in_0', scan_out='scan_out_0', auto_chains=True, scan_in_prefix='scan_in_', scan_out_prefix='scan_out_', max_chain_count=1); order=chains[0].cells if chains else []; found=[c for c in cells if c in order]; missing=[c for c in cells if c not in order]; idx=[order.index(c) for c in found]; print('path_cells_raw=', raw); print('path_cells_norm=', cells); print('path_found=', len(found), 'missing=', len(missing)); print('path_indices=', idx); print('path_contiguous=', all(idx[i]+1==idx[i+1] for i in range(len(idx)-1))); print('reconstruct_errors=', errs[:10] if errs else []);" "$OUT/constraints.meta.json" "$OUT/scanopt15_k1_imb2.v"; echo "DONE: $OUT"; ) |
| 27 | + |
| 28 | +# 06) JPEG: exclusions (constraints: `exclude`) vs baseline, prints delta (cells + total_um). |
| 29 | +( set -euo pipefail; ROOT="$PWD"; RUN="${DEMO_RUN_DIR:-$ROOT/flow/results/nangate45/jpeg/jpeg_scanopt500_routeaware}"; OR="$ROOT/tools/OpenROAD/build/bin/openroad"; LIB="$ROOT/flow/platforms/nangate45/lib/NangateOpenCellLibrary_typical.lib"; ODB="$RUN/3_5_place_dp.odb"; SDC="$RUN/3_place.sdc"; OUT="$ROOT/demo-outputs/06_constraints_exclude_k1"; rm -rf "$OUT"; mkdir -p "$OUT"; read -r X0 Y0 X1 Y1 <<<"$(awk '/^DIEAREA/ {gsub(/[();]/,"",$0); print $2,$3,$4,$5; exit}' "$RUN/6_final.def")"; [[ -n "$X1" && -n "$Y1" ]]; printf "chain chain_0 begin %s %s end %s %s\n" "$X0" "$Y0" "$X1" "$Y1" >"$OUT/base.constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/base.constraints.txt" --out-prefix "$OUT/base" --chain-counts 1 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 15 --out-json "$OUT/base.json"; python3 "$ROOT/flow/util/dft_demo_make_constraints.py" --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --chain-count 1 --max-imbalance 2 --mode exclude --count 100 --out "$OUT/exclude.constraints.txt" --out-meta "$OUT/exclude.meta.json"; printf "chain chain_0 begin %s %s end %s %s\n" "$X0" "$Y0" "$X1" "$Y1" >>"$OUT/exclude.constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/exclude.constraints.txt" --out-prefix "$OUT/exclude" --chain-counts 1 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 15 --out-json "$OUT/exclude.json"; python3 -c "import json,sys; a=json.load(open(sys.argv[1]))[0]; b=json.load(open(sys.argv[2]))[0]; print('baseline: max_chain_len=%s total_um=%s openroad_s=%s' % (a.get('max_chain_len'), a.get('total_um'), a.get('openroad_runtime_s'))); print('exclude : max_chain_len=%s total_um=%s openroad_s=%s' % (b.get('max_chain_len'), b.get('total_um'), b.get('openroad_runtime_s')));" "$OUT/base.json" "$OUT/exclude.json"; echo "DONE: $OUT"; ) |
| 30 | + |
| 31 | +# 07) JPEG: heavier SCANOPT run (15s vs 120s), prints delta (total_um + runtime). |
| 32 | +( set -euo pipefail; ROOT="$PWD"; RUN="${DEMO_RUN_DIR:-$ROOT/flow/results/nangate45/jpeg/jpeg_scanopt500_routeaware}"; OR="$ROOT/tools/OpenROAD/build/bin/openroad"; LIB="$ROOT/flow/platforms/nangate45/lib/NangateOpenCellLibrary_typical.lib"; ODB="$RUN/3_5_place_dp.odb"; SDC="$RUN/3_place.sdc"; OUT="$ROOT/demo-outputs/07_scanopt_time_limit_sweep_k1"; rm -rf "$OUT"; mkdir -p "$OUT"; read -r X0 Y0 X1 Y1 <<<"$(awk '/^DIEAREA/ {gsub(/[();]/,"",$0); print $2,$3,$4,$5; exit}' "$RUN/6_final.def")"; [[ -n "$X1" && -n "$Y1" ]]; printf "chain chain_0 begin %s %s end %s %s\n" "$X0" "$Y0" "$X1" "$Y1" >"$OUT/constraints.txt"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/constraints.txt" --out-prefix "$OUT/t15" --chain-counts 1 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 15 --out-json "$OUT/t15.json"; python3 "$ROOT/flow/util/dft_preplaced_regress.py" --echo-openroad --openroad "$OR" --liberty "$LIB" --odb "$ODB" --sdc "$SDC" --constraints-file "$OUT/constraints.txt" --out-prefix "$OUT/t120" --chain-counts 1 --max-imbalances 2 --scan-order-solver SCANOPT --scanopt-time-limit 120 --out-json "$OUT/t120.json"; python3 -c "import json,sys; a=json.load(open(sys.argv[1]))[0]; b=json.load(open(sys.argv[2]))[0]; ta=float(a.get('total_um') or 0); tb=float(b.get('total_um') or 0); ra=float(a.get('openroad_runtime_s') or 0); rb=float(b.get('openroad_runtime_s') or 0); d=(tb-ta); pct=(100.0*d/ta) if ta else 0.0; print('t15 : total_um=%s openroad_s=%s' % (a.get('total_um'), a.get('openroad_runtime_s'))); print('t120: total_um=%s openroad_s=%s' % (b.get('total_um'), b.get('openroad_runtime_s'))); print('delta: total_um=%+.3f (%+.2f%%) runtime_s=%+.3f' % (d, pct, (rb-ra)));" "$OUT/t15.json" "$OUT/t120.json"; echo "DONE: $OUT"; ) |
0 commit comments