From eb345b646b23e4dfdac490292665de240da583b0 Mon Sep 17 00:00:00 2001 From: Avik De Date: Fri, 5 Jun 2026 09:29:32 -0400 Subject: [PATCH 1/7] Changed from a single `-p` with semicolons to multiple `-p` flags (one per Yosys command) to prevent CMake from interpreting `;` as list separators. --- CMakeLists.txt | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-) diff --git a/CMakeLists.txt b/CMakeLists.txt index 9dc73a0..570085f 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -25,17 +25,16 @@ add_custom_target(compile ALL DEPENDS ${COMPILED_VVP}) if(YOSYS) set(SYNTH_JSON "${CMAKE_BINARY_DIR}/synth.json") - # Build a read_verilog command for each source file - set(YOSYS_READ_CMDS "") - foreach(src ${SV_SOURCES}) - string(APPEND YOSYS_READ_CMDS "read_verilog -sv ${src}; ") - endforeach() - + # Yosys does not support unpacked array ports used in array.sv, pe_col.sv, + # and requant.sv. Since we only need to synthesize the pe module, read + # only pe.sv. Multiple -p flags avoid CMake splitting on semicolons. add_custom_command( OUTPUT ${SYNTH_JSON} - COMMAND ${YOSYS} -p - "${YOSYS_READ_CMDS} synth -top pe; write_json ${SYNTH_JSON}" - DEPENDS ${SV_SOURCES} + COMMAND ${YOSYS} + -p "read_verilog -sv ${CMAKE_SOURCE_DIR}/src/pe.sv" + -p "synth -top pe" + -p "write_json ${SYNTH_JSON}" + DEPENDS ${CMAKE_SOURCE_DIR}/src/pe.sv COMMENT "Synthesising with Yosys" ) From c14f4f1b8eadce1e0e1b42b418d7aed8bb2e95b8 Mon Sep 17 00:00:00 2001 From: Avik De Date: Fri, 5 Jun 2026 09:49:02 -0400 Subject: [PATCH 2/7] make synth wors now --- CMakeLists.txt | 21 +------ cmake/synth.cmake | 137 ++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+), 19 deletions(-) create mode 100644 cmake/synth.cmake diff --git a/CMakeLists.txt b/CMakeLists.txt index 570085f..d076197 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -21,25 +21,8 @@ add_custom_command( add_custom_target(compile ALL DEPENDS ${COMPILED_VVP}) -# ---------- optional: Yosys synthesis ---------- -if(YOSYS) - set(SYNTH_JSON "${CMAKE_BINARY_DIR}/synth.json") - - # Yosys does not support unpacked array ports used in array.sv, pe_col.sv, - # and requant.sv. Since we only need to synthesize the pe module, read - # only pe.sv. Multiple -p flags avoid CMake splitting on semicolons. - add_custom_command( - OUTPUT ${SYNTH_JSON} - COMMAND ${YOSYS} - -p "read_verilog -sv ${CMAKE_SOURCE_DIR}/src/pe.sv" - -p "synth -top pe" - -p "write_json ${SYNTH_JSON}" - DEPENDS ${CMAKE_SOURCE_DIR}/src/pe.sv - COMMENT "Synthesising with Yosys" - ) - - add_custom_target(synth DEPENDS ${SYNTH_JSON}) -endif() +# ---------- optional: Yosys synthesis (cmake/synth.cmake) ---------- +include(cmake/synth.cmake) add_subdirectory(onnx-plugin) diff --git a/cmake/synth.cmake b/cmake/synth.cmake new file mode 100644 index 0000000..59ea1e0 --- /dev/null +++ b/cmake/synth.cmake @@ -0,0 +1,137 @@ +# Yosys synthesis target for the systolic array. +# +# Yosys does not support unpacked array module ports (used in array.sv and +# pe_col.sv). This file generates a flat module that directly instantiates +# every PE with individual scalar wires — no unpacked arrays anywhere. +# +# Exposes a `synth` target that runs: read_verilog → synth → write_json. + +if(NOT YOSYS) + return() +endif() + +set(SYNTH_JSON "${CMAKE_BINARY_DIR}/synth.json") + +# Cache variables for array dimensions (shared with onnx-plugin). +set(SIM_ROWS 16 CACHE STRING "Systolic array row count") +set(SIM_COLS 16 CACHE STRING "Systolic array column count") + +set(SYNTH_SRC "${CMAKE_BINARY_DIR}/synth_array.sv") +set(DW 8) +set(AW 32) +math(EXPR MAX_R "${SIM_ROWS} - 1") +math(EXPR MAX_C "${SIM_COLS} - 1") + +file(WRITE ${SYNTH_SRC} + "// Auto-generated flat array for Yosys synthesis\n" + "// Array: ${SIM_ROWS}x${SIM_COLS}, DATA_WIDTH=${DW}, ACC_WIDTH=${AW}\n" + "`timescale 1ns / 1ps\n\n" + "module synth_array (\n" + " input logic clk,\n" + " input logic rst_n") + +foreach(r RANGE 0 ${MAX_R}) + file(APPEND ${SYNTH_SRC} + ",\n input logic signed [${DW}-1:0] data_in_left_${r}") +endforeach() +foreach(r RANGE 0 ${MAX_R}) + file(APPEND ${SYNTH_SRC} + ",\n output logic signed [${DW}-1:0] data_out_right_${r}") +endforeach() +foreach(c RANGE 0 ${MAX_C}) + file(APPEND ${SYNTH_SRC} + ",\n input logic weight_ld_${c}") +endforeach() +foreach(c RANGE 0 ${MAX_C}) + file(APPEND ${SYNTH_SRC} + ",\n input logic signed [${AW}-1:0] acc_in_top_${c}") +endforeach() +foreach(c RANGE 0 ${MAX_C}) + file(APPEND ${SYNTH_SRC} + ",\n output logic signed [${AW}-1:0] acc_out_bottom_${c}") +endforeach() + +file(APPEND ${SYNTH_SRC} "\n);\n\n") + +# Data wires across rows (n + 1 columns: 0..COLS) +foreach(c RANGE 0 ${SIM_COLS}) + foreach(r RANGE 0 ${MAX_R}) + file(APPEND ${SYNTH_SRC} + " logic signed [${DW}-1:0] data_wire_${c}_${r};\n") + endforeach() +endforeach() +file(APPEND ${SYNTH_SRC} "\n") + +# Acc wires down columns (n + 1 rows per column: 0..ROWS) +foreach(c RANGE 0 ${MAX_C}) + foreach(r RANGE 0 ${SIM_ROWS}) + file(APPEND ${SYNTH_SRC} + " logic signed [${AW}-1:0] acc_wire_${c}_${r};\n") + endforeach() +endforeach() +file(APPEND ${SYNTH_SRC} "\n") + +# Left-edge data inputs +foreach(r RANGE 0 ${MAX_R}) + file(APPEND ${SYNTH_SRC} + " assign data_wire_0_${r} = data_in_left_${r};\n") +endforeach() +file(APPEND ${SYNTH_SRC} "\n") + +# Right-edge data outputs +foreach(r RANGE 0 ${MAX_R}) + file(APPEND ${SYNTH_SRC} + " assign data_out_right_${r} = data_wire_${SIM_COLS}_${r};\n") +endforeach() +file(APPEND ${SYNTH_SRC} "\n") + +# Top-edge acc inputs +foreach(c RANGE 0 ${MAX_C}) + file(APPEND ${SYNTH_SRC} + " assign acc_wire_${c}_0 = acc_in_top_${c};\n") +endforeach() +file(APPEND ${SYNTH_SRC} "\n") + +# Bottom-edge acc outputs +foreach(c RANGE 0 ${MAX_C}) + file(APPEND ${SYNTH_SRC} + " assign acc_out_bottom_${c} = acc_wire_${c}_${SIM_ROWS};\n") +endforeach() +file(APPEND ${SYNTH_SRC} "\n") + +# Instantiate all PEs +foreach(c RANGE 0 ${MAX_C}) + math(EXPR NEXT_C "${c} + 1") + foreach(r RANGE 0 ${MAX_R}) + math(EXPR NEXT_R "${r} + 1") + file(APPEND ${SYNTH_SRC} + " pe #(\n" + " .DATA_WIDTH (${DW}),\n" + " .ACC_WIDTH (${AW})\n" + " ) u_pe_${c}_${r} (\n" + " .clk (clk),\n" + " .rst_n (rst_n),\n" + " .weight_ld (weight_ld_${c}),\n" + " .data_in (data_wire_${c}_${r}),\n" + " .data_out (data_wire_${NEXT_C}_${r}),\n" + " .acc_in (acc_wire_${c}_${r}),\n" + " .acc_out (acc_wire_${c}_${NEXT_R})\n" + " );\n") + endforeach() +endforeach() + +file(APPEND ${SYNTH_SRC} "\nendmodule\n") + +add_custom_command( + OUTPUT ${SYNTH_JSON} + COMMAND ${YOSYS} + -p "read_verilog -sv ${CMAKE_SOURCE_DIR}/src/pe.sv ${SYNTH_SRC}" + -p "synth -top synth_array" + -p "write_json ${SYNTH_JSON}" + DEPENDS + ${CMAKE_SOURCE_DIR}/src/pe.sv + ${SYNTH_SRC} + COMMENT "Synthesising array (${SIM_ROWS}x${SIM_COLS}) with Yosys" +) + +add_custom_target(synth DEPENDS ${SYNTH_JSON}) From aa627d3dd6686360d69b2431fca0fa136233d401 Mon Sep 17 00:00:00 2001 From: Avik De Date: Fri, 5 Jun 2026 10:41:27 -0400 Subject: [PATCH 3/7] make synth with STA --- AGENTS.md | 13 +++++++++++++ README.md | 36 ++++++++++++++++++++++++++++++++++++ cmake/synth.cmake | 42 ++++++++++++++++++++++++++++++++++++++---- 3 files changed, 87 insertions(+), 4 deletions(-) diff --git a/AGENTS.md b/AGENTS.md index f9fb403..6e054fc 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -29,6 +29,8 @@ make -j Key CMake flags: - `-DSIM=ON` — enables Verilator backend (required for end-to-end runs) - `-DSIM_ROWS=N -DSIM_COLS=N` — override array size (default **64×64**) +- `$SKYWATER_LIB` — **env var** pointing to the SkyWater130 Liberty .lib file (required for `synth` target) +- `-DCLOCK_PERIOD_NS=N` — clock period in ns for STA (default: **10**) The EP shared library is built at `build/onnx-plugin/libtinyxpu_ep.{so,dylib}`. @@ -56,6 +58,17 @@ python scripts/run_matmul.py # ONNX → TinyXPU EP → verify vs NumPy `run_matmul.py` defaults to `scripts/matmul_integer_16x16.onnx` and the plugin at `build/onnx-plugin/libtinyxpu_ep.{so,dylib}`. It will fail with a helpful message if either is missing. +## Frequency Analysis + +```sh +export SKYWATER_LIB=/path/to/sky130_fd_sc_hd__tt_025C_1v80.lib # see README +cmake -B build -DSIM=ON -DCLOCK_PERIOD_NS=10 +cmake --build build --target synth +``` + +The `synth` target synthesises the array to SkyWater130 cells and runs STA. +Results (critical path slack, max frequency) appear in the build log and in `build/synth_sta.rpt`. + ## Architecture Notes - **PE (`pe.sv`):** `weight_ld=1` latches `acc_in` as a new weight, sets `acc_out` to the weight value (cascading it south), and sets `data_out=0`. `weight_ld=0` performs MAC: `acc_out = acc_in + weight_r * data_in` (first untagged input is bias, subsequent are partial sums). `int8×int8→int32` MAC. diff --git a/README.md b/README.md index 1af4ba7..e7fd385 100644 --- a/README.md +++ b/README.md @@ -54,6 +54,8 @@ ctest --verbose # waveforms written to test/sim_build/*.fst Key CMake flags: - `-DSIM=ON` — use Verilator simulation backend (required for software runs) - `-DSIM_ROWS=N -DSIM_COLS=N` — override array size (default **64×64**) +- `$SKYWATER_LIB` — **env var** pointing to the SkyWater130 Liberty .lib file (required for `synth` target) +- `-DCLOCK_PERIOD_NS=N` — clock period in ns for static timing analysis (default: **10**) Install the [Surfer](https://marketplace.visualstudio.com/items?itemName=surfer-project.surfer) VSCode extension to view `.fst` waveforms. @@ -67,6 +69,40 @@ python scripts/run_matmul.py # 2-D MatMulInteger via Verilator, verifies vs python scripts/test_ops.py # batched MatMulInteger + Gemm tests ``` +## Frequency Analysis + +Synthesise the array to SkyWater130 standard cells and run static timing analysis to estimate the maximum clock frequency. + +### 1. Download the SkyWater130 PDK Library + +```sh +brew install zstd +cd ~/projects # where you want to put the PDK +curl -L -o sky130_fd_sc_hd.tar.zst \ + https://github.com/fossi-foundation/ciel-releases/releases/download/sky130-ff08c23db8359afce3f134c454e7930586d0641c/sky130_fd_sc_hd.tar.zst +tar --zstd -xf sky130_fd_sc_hd.tar.zst +ls "$PWD/sky130A/libs.ref/sky130_fd_sc_hd/lib/sky130_fd_sc_hd__tt_025C_1v80.lib" +``` +Copy the path, and export it as `SKYWATER_LIB` in your shell rc file. + +Add the `export` line to your shell rc file for persistence. + +### 2. Build with Synthesis & STA + +```sh +mkdir -p build && cd build +cmake .. -DSIM=ON -DCLOCK_PERIOD_NS=10 +make synth +``` + +The `synth` target runs Yosys to: +1. Read the Liberty library and the RTL +2. Elaborate and flatten the array +3. Map DFFs and combinational logic to SkyWater130 cells via ABC +4. Run static timing analysis with the specified clock constraint + +STA results (critical path, slack, max frequency) are printed to the build log and captured in `synth_sta.rpt`. + ## Systolic Array Architecture A `ROWS × COLS` PE grid. Dataflow is **weight-stationary**: weights load once, then activations stream east (→) while partial sums cascade south (↓). diff --git a/cmake/synth.cmake b/cmake/synth.cmake index 59ea1e0..647f503 100644 --- a/cmake/synth.cmake +++ b/cmake/synth.cmake @@ -1,15 +1,37 @@ -# Yosys synthesis target for the systolic array. +# Yosys synthesis + STA target for the systolic array. # # Yosys does not support unpacked array module ports (used in array.sv and # pe_col.sv). This file generates a flat module that directly instantiates # every PE with individual scalar wires — no unpacked arrays anywhere. # -# Exposes a `synth` target that runs: read_verilog → synth → write_json. +# Exposes a `synth` target that runs: +# read_liberty → read_verilog → hierarchy → flatten → proc → techmap +# → dfflibmap → abc -liberty → write_json → sdc → sta +# +# Requires $SKYWATER_LIB env var pointing to the SkyWater130 Liberty .lib file. if(NOT YOSYS) return() endif() +# --- SkyWater130 Liberty library (env var only, no caching) --- +if(NOT DEFINED ENV{SKYWATER_LIB} OR "$ENV{SKYWATER_LIB}" STREQUAL "") + message(FATAL_ERROR + "Set the SKYWATER_LIB env var to the path of sky130_fd_sc_hd__tt_025C_1v80.lib.\n" + "See README.md for download instructions.") +endif() +if(NOT EXISTS "$ENV{SKYWATER_LIB}") + message(FATAL_ERROR "SKYWATER_LIB=$ENV{SKYWATER_LIB} does not exist") +endif() + +# --- Clock period for STA --- +set(CLOCK_PERIOD_NS 10 CACHE STRING "Clock period in ns for STA") + +# --- SDC constraints file (generated at configure time) --- +set(SDC_FILE "${CMAKE_BINARY_DIR}/synth.sdc") +file(WRITE ${SDC_FILE} + "create_clock -name clk -period ${CLOCK_PERIOD_NS} [get_ports clk]\n") + set(SYNTH_JSON "${CMAKE_BINARY_DIR}/synth.json") # Cache variables for array dimensions (shared with onnx-plugin). @@ -125,13 +147,25 @@ file(APPEND ${SYNTH_SRC} "\nendmodule\n") add_custom_command( OUTPUT ${SYNTH_JSON} COMMAND ${YOSYS} + -p "read_liberty -ignore_miss_func $ENV{SKYWATER_LIB}" -p "read_verilog -sv ${CMAKE_SOURCE_DIR}/src/pe.sv ${SYNTH_SRC}" - -p "synth -top synth_array" + -p "hierarchy -check -top synth_array" + -p "flatten" + -p "proc" + -p "opt" + -p "techmap" + -p "opt" + -p "dfflibmap -liberty $ENV{SKYWATER_LIB}" + -p "abc -liberty $ENV{SKYWATER_LIB}" + -p "opt_clean" -p "write_json ${SYNTH_JSON}" + -p "sdc ${SDC_FILE}" + -p "tee -o ${CMAKE_BINARY_DIR}/synth_sta.rpt sta" DEPENDS ${CMAKE_SOURCE_DIR}/src/pe.sv ${SYNTH_SRC} - COMMENT "Synthesising array (${SIM_ROWS}x${SIM_COLS}) with Yosys" + ${SDC_FILE} + COMMENT "Synthesising array (${SIM_ROWS}x${SIM_COLS}) to SkyWater130 + STA" ) add_custom_target(synth DEPENDS ${SYNTH_JSON}) From ab21a1659b5c40843e25f50981eeacad037ba2ba Mon Sep 17 00:00:00 2001 From: Avik De Date: Fri, 5 Jun 2026 11:27:09 -0400 Subject: [PATCH 4/7] load liberty after hierarchy --- cmake/synth.cmake | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/cmake/synth.cmake b/cmake/synth.cmake index 647f503..3e570d4 100644 --- a/cmake/synth.cmake +++ b/cmake/synth.cmake @@ -5,8 +5,9 @@ # every PE with individual scalar wires — no unpacked arrays anywhere. # # Exposes a `synth` target that runs: -# read_liberty → read_verilog → hierarchy → flatten → proc → techmap -# → dfflibmap → abc -liberty → write_json → sdc → sta +# read_verilog → hierarchy → flatten → proc → techmap → +# dfflibmap → abc -liberty → opt_clean → read_liberty -lib -overwrite → +# write_json → sdc → sta # # Requires $SKYWATER_LIB env var pointing to the SkyWater130 Liberty .lib file. @@ -147,7 +148,6 @@ file(APPEND ${SYNTH_SRC} "\nendmodule\n") add_custom_command( OUTPUT ${SYNTH_JSON} COMMAND ${YOSYS} - -p "read_liberty -ignore_miss_func $ENV{SKYWATER_LIB}" -p "read_verilog -sv ${CMAKE_SOURCE_DIR}/src/pe.sv ${SYNTH_SRC}" -p "hierarchy -check -top synth_array" -p "flatten" @@ -158,6 +158,7 @@ add_custom_command( -p "dfflibmap -liberty $ENV{SKYWATER_LIB}" -p "abc -liberty $ENV{SKYWATER_LIB}" -p "opt_clean" + -p "read_liberty -lib -overwrite $ENV{SKYWATER_LIB}" -p "write_json ${SYNTH_JSON}" -p "sdc ${SDC_FILE}" -p "tee -o ${CMAKE_BINARY_DIR}/synth_sta.rpt sta" From 805e71772bb2c4e4cbe9ef9bd0710c2e0303e665 Mon Sep 17 00:00:00 2001 From: Avik De Date: Fri, 5 Jun 2026 11:58:51 -0400 Subject: [PATCH 5/7] Storing synth outputs --- .gitignore | 1 + AGENTS.md | 7 +- README.md | 24 +++++-- cmake/synth.cmake | 36 +++++----- synth_outputs/synth_stats.txt | 83 +++++++++++++++++++++++ synth_outputs/synth_timing.rpt | 120 +++++++++++++++++++++++++++++++++ 6 files changed, 247 insertions(+), 24 deletions(-) create mode 100644 synth_outputs/synth_stats.txt create mode 100644 synth_outputs/synth_timing.rpt diff --git a/.gitignore b/.gitignore index 3ffa486..c446db9 100644 --- a/.gitignore +++ b/.gitignore @@ -11,3 +11,4 @@ scripts/*.onnx scripts/*.png .DS_Store __cmake_systeminformation +synth_outputs/synth.json diff --git a/AGENTS.md b/AGENTS.md index 6e054fc..d281963 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -30,7 +30,7 @@ Key CMake flags: - `-DSIM=ON` — enables Verilator backend (required for end-to-end runs) - `-DSIM_ROWS=N -DSIM_COLS=N` — override array size (default **64×64**) - `$SKYWATER_LIB` — **env var** pointing to the SkyWater130 Liberty .lib file (required for `synth` target) -- `-DCLOCK_PERIOD_NS=N` — clock period in ns for STA (default: **10**) +- `-DCLOCK_PERIOD_NS=N` — clock period in ns for ABC timing-driven mapping (default: **10**) The EP shared library is built at `build/onnx-plugin/libtinyxpu_ep.{so,dylib}`. @@ -66,8 +66,9 @@ cmake -B build -DSIM=ON -DCLOCK_PERIOD_NS=10 cmake --build build --target synth ``` -The `synth` target synthesises the array to SkyWater130 cells and runs STA. -Results (critical path slack, max frequency) appear in the build log and in `build/synth_sta.rpt`. +The `synth` target synthesises the array to SkyWater130 cells with ABC timing-driven mapping. +ABC's `stime -p` reports the estimated critical path delay. +Outputs go to `synth_outputs/`: `synth.json` (netlist), `synth_stats.txt` (cells), `synth_timing.rpt` (timing). ## Architecture Notes diff --git a/README.md b/README.md index e7fd385..37156e7 100644 --- a/README.md +++ b/README.md @@ -55,7 +55,7 @@ Key CMake flags: - `-DSIM=ON` — use Verilator simulation backend (required for software runs) - `-DSIM_ROWS=N -DSIM_COLS=N` — override array size (default **64×64**) - `$SKYWATER_LIB` — **env var** pointing to the SkyWater130 Liberty .lib file (required for `synth` target) -- `-DCLOCK_PERIOD_NS=N` — clock period in ns for static timing analysis (default: **10**) +- `-DCLOCK_PERIOD_NS=N` — clock period in ns for ABC timing-driven mapping (default: **10**) Install the [Surfer](https://marketplace.visualstudio.com/items?itemName=surfer-project.surfer) VSCode extension to view `.fst` waveforms. @@ -96,12 +96,26 @@ make synth ``` The `synth` target runs Yosys to: -1. Read the Liberty library and the RTL +1. Read the RTL 2. Elaborate and flatten the array -3. Map DFFs and combinational logic to SkyWater130 cells via ABC -4. Run static timing analysis with the specified clock constraint +3. Map DFFs and combinational logic to SkyWater130 cells via ABC (timing-driven with `-D CLOCK_PERIOD_NS`) +4. Report ABC's estimated critical path delay, area, and cell counts -STA results (critical path, slack, max frequency) are printed to the build log and captured in `synth_sta.rpt`. +**Output files (in `synth_outputs/`):** +- `synth.json` — gate-level netlist +- `synth_stats.txt` — cell counts +- `synth_timing.rpt` — ABC timing log (critical path delay) + +**Key line in `synth_outputs/synth_timing.rpt`:** +``` +ABC: Gates = 129761 Area = 928743.25 Delay = 10676.35 ps +``` +This is ABC's pre-layout critical path estimate (no wireload model). The +reported delay is optimistic vs. post-P&R but gives a useful frequency target. + +**Note:** Yosys's built-in `sta` command is unavailable due to a +[known bug](https://github.com/YosysHQ/yosys/issues/4232) with non-parametric +blackbox cells. ABC's `stime -p` provides a comparable pre-layout estimate. ## Systolic Array Architecture diff --git a/cmake/synth.cmake b/cmake/synth.cmake index 3e570d4..c645e21 100644 --- a/cmake/synth.cmake +++ b/cmake/synth.cmake @@ -1,4 +1,4 @@ -# Yosys synthesis + STA target for the systolic array. +# Yosys synthesis target for the systolic array. # # Yosys does not support unpacked array module ports (used in array.sv and # pe_col.sv). This file generates a flat module that directly instantiates @@ -6,10 +6,12 @@ # # Exposes a `synth` target that runs: # read_verilog → hierarchy → flatten → proc → techmap → -# dfflibmap → abc -liberty → opt_clean → read_liberty -lib -overwrite → -# write_json → sdc → sta +# dfflibmap → abc -liberty (stime -p timing report) → opt_clean → +# write_json → stat # # Requires $SKYWATER_LIB env var pointing to the SkyWater130 Liberty .lib file. +# Timing estimates, cell statistics, and gate-level netlist are written to +# /synth_outputs/. if(NOT YOSYS) return() @@ -25,15 +27,19 @@ if(NOT EXISTS "$ENV{SKYWATER_LIB}") message(FATAL_ERROR "SKYWATER_LIB=$ENV{SKYWATER_LIB} does not exist") endif() -# --- Clock period for STA --- -set(CLOCK_PERIOD_NS 10 CACHE STRING "Clock period in ns for STA") +# --- Clock period for timing-driven mapping --- +set(CLOCK_PERIOD_NS 10 CACHE STRING "Clock period in ns for ABC timing-driven mapping") -# --- SDC constraints file (generated at configure time) --- -set(SDC_FILE "${CMAKE_BINARY_DIR}/synth.sdc") -file(WRITE ${SDC_FILE} - "create_clock -name clk -period ${CLOCK_PERIOD_NS} [get_ports clk]\n") +# --- Output directory for synthesis results --- +set(SYNTH_OUT "${CMAKE_SOURCE_DIR}/synth_outputs") +file(MAKE_DIRECTORY ${SYNTH_OUT}) -set(SYNTH_JSON "${CMAKE_BINARY_DIR}/synth.json") +# --- ABC timing script (generated at configure time) --- +set(ABC_SCRIPT "${CMAKE_BINARY_DIR}/abc_timing.script") +file(WRITE ${ABC_SCRIPT} + "strash; &get -n; &fraig -x; &put; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put; stime -p\n") + +set(SYNTH_JSON "${SYNTH_OUT}/synth.json") # Cache variables for array dimensions (shared with onnx-plugin). set(SIM_ROWS 16 CACHE STRING "Systolic array row count") @@ -156,17 +162,15 @@ add_custom_command( -p "techmap" -p "opt" -p "dfflibmap -liberty $ENV{SKYWATER_LIB}" - -p "abc -liberty $ENV{SKYWATER_LIB}" + -p "tee -o ${SYNTH_OUT}/synth_timing.rpt abc -liberty $ENV{SKYWATER_LIB} -script ${CMAKE_BINARY_DIR}/abc_timing.script" -p "opt_clean" - -p "read_liberty -lib -overwrite $ENV{SKYWATER_LIB}" -p "write_json ${SYNTH_JSON}" - -p "sdc ${SDC_FILE}" - -p "tee -o ${CMAKE_BINARY_DIR}/synth_sta.rpt sta" + -p "tee -o ${SYNTH_OUT}/synth_stats.txt stat -width" DEPENDS ${CMAKE_SOURCE_DIR}/src/pe.sv ${SYNTH_SRC} - ${SDC_FILE} - COMMENT "Synthesising array (${SIM_ROWS}x${SIM_COLS}) to SkyWater130 + STA" + ${ABC_SCRIPT} + COMMENT "Synthesising array (${SIM_ROWS}x${SIM_COLS}) to SkyWater130 cells" ) add_custom_target(synth DEPENDS ${SYNTH_JSON}) diff --git a/synth_outputs/synth_stats.txt b/synth_outputs/synth_stats.txt new file mode 100644 index 0000000..6cfff5d --- /dev/null +++ b/synth_outputs/synth_stats.txt @@ -0,0 +1,83 @@ + +13. Printing statistics. + +=== synth_array === + + +----------Local Count, excluding submodules. + | + 132435 wires + 165235 wire bits + 2674 public wires + 35474 public wire bits + 82 ports + 1298 port bits + 142305 cells + 256 $scopeinfo + 12 sky130_fd_sc_hd__a2111o_1 + 38 sky130_fd_sc_hd__a2111oi_0 + 176 sky130_fd_sc_hd__a211o_1 + 325 sky130_fd_sc_hd__a211oi_1 + 31 sky130_fd_sc_hd__a21bo_1 + 546 sky130_fd_sc_hd__a21boi_0 + 948 sky130_fd_sc_hd__a21o_1 + 5524 sky130_fd_sc_hd__a21oi_1 + 6 sky130_fd_sc_hd__a221o_1 + 20 sky130_fd_sc_hd__a221oi_1 + 1144 sky130_fd_sc_hd__a22o_1 + 1080 sky130_fd_sc_hd__a22oi_1 + 92 sky130_fd_sc_hd__a2bb2oi_1 + 27 sky130_fd_sc_hd__a311o_1 + 32 sky130_fd_sc_hd__a311oi_1 + 450 sky130_fd_sc_hd__a31o_1 + 490 sky130_fd_sc_hd__a31oi_1 + 247 sky130_fd_sc_hd__a32o_1 + 3 sky130_fd_sc_hd__a32oi_1 + 2145 sky130_fd_sc_hd__and2_0 + 922 sky130_fd_sc_hd__and3_1 + 237 sky130_fd_sc_hd__and3b_1 + 260 sky130_fd_sc_hd__and4_1 + 4926 sky130_fd_sc_hd__clkinv_1 + 12288 sky130_fd_sc_hd__dfrtp_1 + 1363 sky130_fd_sc_hd__lpflow_inputiso1p_1 + 5013 sky130_fd_sc_hd__lpflow_isobufsrc_1 + 11507 sky130_fd_sc_hd__maj3_1 + 341 sky130_fd_sc_hd__mux2_1 + 19563 sky130_fd_sc_hd__nand2_1 + 2206 sky130_fd_sc_hd__nand2b_1 + 1696 sky130_fd_sc_hd__nand3_1 + 534 sky130_fd_sc_hd__nand3b_1 + 1671 sky130_fd_sc_hd__nand4_1 + 3 sky130_fd_sc_hd__nand4b_1 + 10 sky130_fd_sc_hd__nand4bb_1 + 7317 sky130_fd_sc_hd__nor2_1 + 89 sky130_fd_sc_hd__nor2b_1 + 672 sky130_fd_sc_hd__nor3_1 + 78 sky130_fd_sc_hd__nor3b_1 + 33 sky130_fd_sc_hd__nor4_1 + 84 sky130_fd_sc_hd__nor4b_1 + 11 sky130_fd_sc_hd__nor4bb_1 + 3 sky130_fd_sc_hd__o2111ai_1 + 34 sky130_fd_sc_hd__o211a_1 + 14 sky130_fd_sc_hd__o211ai_1 + 390 sky130_fd_sc_hd__o21a_1 + 12743 sky130_fd_sc_hd__o21ai_0 + 71 sky130_fd_sc_hd__o21bai_1 + 301 sky130_fd_sc_hd__o22a_1 + 323 sky130_fd_sc_hd__o22ai_1 + 16 sky130_fd_sc_hd__o311a_1 + 112 sky130_fd_sc_hd__o311ai_0 + 233 sky130_fd_sc_hd__o31a_1 + 1146 sky130_fd_sc_hd__o31ai_1 + 17 sky130_fd_sc_hd__o32a_1 + 4 sky130_fd_sc_hd__o32ai_1 + 30 sky130_fd_sc_hd__o41a_1 + 483 sky130_fd_sc_hd__o41ai_1 + 349 sky130_fd_sc_hd__or3_1 + 9 sky130_fd_sc_hd__or3b_1 + 46 sky130_fd_sc_hd__or4_1 + 8 sky130_fd_sc_hd__or4b_1 + 23392 sky130_fd_sc_hd__xnor2_1 + 3124 sky130_fd_sc_hd__xnor3_1 + 14173 sky130_fd_sc_hd__xor2_1 + 868 sky130_fd_sc_hd__xor3_1 + diff --git a/synth_outputs/synth_timing.rpt b/synth_outputs/synth_timing.rpt new file mode 100644 index 0000000..6422e58 --- /dev/null +++ b/synth_outputs/synth_timing.rpt @@ -0,0 +1,120 @@ + +10. Executing ABC pass (technology mapping using ABC). + +10.1. Extracting gate netlist of module `\synth_array' to `/input.blif'.. +ABC: using cached merged SCL: /var/folders/w5/sdsm9h5908gb9z8f7l6b83xr0000gn/T/yosys-liberty-scl-cache/yosys_merged_40d90887.scl (1 files) + +10.1.1. Executed ABC. +Extracted 210176 gates and 222481 wires to a netlist network with 12304 inputs and 12288 outputs. +Running ABC script: /abc.script +ABC: ======== ABC command line "source /abc.script" +ABC: + read_blif /input.blif +ABC: + read_scl /var/folders/w5/sdsm9h5908gb9z8f7l6b83xr0000gn/T/yosys-liberty-scl-cache/yosys_merged_40d90887.scl +ABC: Warning: Detected 9 multi-output cells (for example, "sky130_fd_sc_hd__fa_1"). +ABC: + source /Users/avik/projects/tiny-xpu/build/abc_timing.script +ABC: Warning: The network is combinational (run "fraig" or "fraig_sweep"). +ABC: WireLoad = "none" Gates = 129761 ( 3.8 %) Cap = 6.3 ff ( 6.5 %) Area = 928743.25 ( 80.5 %) Delay = 10676.35 ps ( 3.5 %) +ABC: Path 0 -- 11711 : 0 11 pi A = 0.00 Df = 0.0 -0.0 ps S = 0.0 ps Cin = 0.0 ff Cout = 27.6 ff Cmax = 0.0 ff G = 0 +ABC: Path 1 -- 32656 : 4 1 sky130_fd_sc_hd__a22o_1 A = 8.76 Df = 199.7 -89.9 ps S = 44.0 ps Cin = 2.4 ff Cout = 2.4 ff Cmax = 159.3 ff G = 98 +ABC: Path 2 -- 32657 : 2 2 sky130_fd_sc_hd__nand2_1 A = 3.75 Df = 288.1 -73.7 ps S = 89.4 ps Cin = 2.3 ff Cout = 7.7 ff Cmax = 166.6 ff G = 318 +ABC: Path 3 -- 32658 : 2 2 sky130_fd_sc_hd__xor2_1 A = 8.76 Df = 636.0 -103.3 ps S = 248.9 ps Cin = 4.4 ff Cout = 10.1 ff Cmax = 76.9 ff G = 225 +ABC: Path 4 -- 32682 : 3 2 sky130_fd_sc_hd__xnor3_1 A = 22.52 Df = 971.5 -14.2 ps S = 105.7 ps Cin = 3.7 ff Cout = 7.9 ff Cmax = 154.7 ff G = 204 +ABC: Path 5 -- 32685 : 2 1 sky130_fd_sc_hd__xnor2_1 A = 8.76 Df =1144.8 -34.3 ps S = 156.0 ps Cin = 4.5 ff Cout = 4.7 ff Cmax = 69.6 ff G = 100 +ABC: Path 6 -- 32689 : 2 2 sky130_fd_sc_hd__xnor2_1 A = 8.76 Df =1320.6 -39.2 ps S = 171.3 ps Cin = 4.5 ff Cout = 5.4 ff Cmax = 69.6 ff G = 114 +ABC: Path 7 -- 32708 : 3 2 sky130_fd_sc_hd__maj3_1 A = 10.01 Df =1694.8 -150.3 ps S = 87.9 ps Cin = 2.8 ff Cout = 6.7 ff Cmax = 155.7 ff G = 235 +ABC: Path 8 -- 32709 : 3 2 sky130_fd_sc_hd__maj3_1 A = 10.01 Df =2080.7 -337.9 ps S = 92.0 ps Cin = 2.8 ff Cout = 7.1 ff Cmax = 155.7 ff G = 246 +ABC: Path 9 -- 32712 : 3 2 sky130_fd_sc_hd__a21oi_1 A = 5.00 Df =2266.1 -290.3 ps S = 175.6 ps Cin = 2.3 ff Cout = 6.4 ff Cmax = 74.2 ff G = 262 +ABC: Path 10 -- 32714 : 3 2 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =2416.4 -194.6 ps S = 251.4 ps Cin = 1.7 ff Cout = 6.9 ff Cmax = 50.4 ff G = 390 +ABC: Path 11 -- 32715 : 3 2 sky130_fd_sc_hd__a21oi_1 A = 5.00 Df =2627.6 -276.8 ps S = 174.7 ps Cin = 2.3 ff Cout = 6.3 ff Cmax = 74.2 ff G = 259 +ABC: Path 12 -- 32716 : 3 2 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =2762.5 -171.8 ps S = 251.4 ps Cin = 1.7 ff Cout = 6.9 ff Cmax = 50.4 ff G = 390 +ABC: Path 13 -- 32717 : 3 2 sky130_fd_sc_hd__a21oi_1 A = 5.00 Df =2975.7 -256.0 ps S = 174.7 ps Cin = 2.3 ff Cout = 6.3 ff Cmax = 74.2 ff G = 259 +ABC: Path 14 -- 32718 : 3 2 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =3120.3 -142.8 ps S = 275.4 ps Cin = 1.7 ff Cout = 7.8 ff Cmax = 50.4 ff G = 446 +ABC: Path 15 -- 32719 : 3 2 sky130_fd_sc_hd__maj3_1 A = 10.01 Df =3515.5 -280.4 ps S = 90.1 ps Cin = 2.8 ff Cout = 6.9 ff Cmax = 155.7 ff G = 239 +ABC: Path 16 -- 32720 : 2 1 sky130_fd_sc_hd__nand2_1 A = 3.75 Df =3586.1 -300.7 ps S = 48.1 ps Cin = 2.3 ff Cout = 1.5 ff Cmax = 166.6 ff G = 62 +ABC: Path 17 -- 32731 : 4 34 sky130_fd_sc_hd__nor4b_1 A = 8.76 Df =7037.1-3259.8 ps S =4540.7 ps Cin = 2.1 ff Cout = 112.0 ff Cmax = 33.9 ff G = 5075 +ABC: Path 18 -- 32802 : 2 3 sky130_fd_sc_hd__xor2_1 A = 8.76 Df =8290.9-4221.4 ps S = 737.3 ps Cin = 4.4 ff Cout = 6.7 ff Cmax = 76.9 ff G = 146 +ABC: Path 19 -- 32805 : 4 3 sky130_fd_sc_hd__a211oi_1 A = 7.51 Df =8496.2-2109.0 ps S = 304.7 ps Cin = 2.4 ff Cout = 7.0 ff Cmax = 47.6 ff G = 273 +ABC: Path 20 -- 32808 : 5 3 sky130_fd_sc_hd__o311ai_0 A = 8.76 Df =8933.1-2347.5 ps S = 468.2 ps Cin = 1.8 ff Cout = 6.5 ff Cmax = 29.3 ff G = 353 +ABC: Path 21 -- 32810 : 3 2 sky130_fd_sc_hd__nand3_1 A = 5.00 Df =9062.7-2347.7 ps S = 93.0 ps Cin = 2.4 ff Cout = 3.0 ff Cmax = 146.5 ff G = 121 +ABC: Path 22 -- 32812 : 3 2 sky130_fd_sc_hd__or3_1 A = 6.26 Df =9394.1-2564.8 ps S = 79.5 ps Cin = 1.5 ff Cout = 4.8 ff Cmax = 167.6 ff G = 305 +ABC: Path 23 -- 32817 : 3 4 sky130_fd_sc_hd__a21o_1 A = 7.51 Df =9583.1-2612.3 ps S = 90.3 ps Cin = 2.4 ff Cout = 9.0 ff Cmax = 177.6 ff G = 358 +ABC: Path 24 -- 32822 : 4 2 sky130_fd_sc_hd__o31a_1 A = 8.76 Df =9881.7-2745.2 ps S = 91.2 ps Cin = 2.4 ff Cout = 7.1 ff Cmax = 149.2 ff G = 290 +ABC: Path 25 -- 32824 : 3 3 sky130_fd_sc_hd__o21a_1 A = 7.51 Df =10100.5-2790.6 ps S = 103.1 ps Cin = 2.4 ff Cout = 9.7 ff Cmax = 163.0 ff G = 388 +ABC: Path 26 -- 32826 : 4 2 sky130_fd_sc_hd__a211o_1 A = 8.76 Df =10404.7-2953.0 ps S = 61.1 ps Cin = 2.4 ff Cout = 4.9 ff Cmax = 176.7 ff G = 196 +ABC: Path 27 -- 152967 : 4 1 sky130_fd_sc_hd__a31o_1 A = 8.76 Df =10601.2-3024.2 ps S = 38.8 ps Cin = 2.4 ff Cout = 1.8 ff Cmax = 160.2 ff G = 72 +ABC: Path 28 -- 152968 : 3 1 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =10676.3 -68.6 ps S = 88.5 ps Cin = 1.7 ff Cout = 0.0 ff Cmax = 50.4 ff G = 0 +ABC: Start-point = pi11710 (\u_pe_0_12.weight_r [5]). End-point = po11631 ($flatten\u_pe_0_12.$0\acc_out[31:0] [31]). +ABC: + write_blif /output.blif + +10.1.2. Re-integrating ABC results. +ABC RESULTS: sky130_fd_sc_hd__a2111o_1 cells: 12 +ABC RESULTS: sky130_fd_sc_hd__a2111oi_0 cells: 38 +ABC RESULTS: sky130_fd_sc_hd__a211o_1 cells: 176 +ABC RESULTS: sky130_fd_sc_hd__a211oi_1 cells: 325 +ABC RESULTS: sky130_fd_sc_hd__a21bo_1 cells: 31 +ABC RESULTS: sky130_fd_sc_hd__a21boi_0 cells: 546 +ABC RESULTS: sky130_fd_sc_hd__a21o_1 cells: 948 +ABC RESULTS: sky130_fd_sc_hd__a21oi_1 cells: 5524 +ABC RESULTS: sky130_fd_sc_hd__a221o_1 cells: 6 +ABC RESULTS: sky130_fd_sc_hd__a221oi_1 cells: 20 +ABC RESULTS: sky130_fd_sc_hd__a22o_1 cells: 1144 +ABC RESULTS: sky130_fd_sc_hd__a22oi_1 cells: 1080 +ABC RESULTS: sky130_fd_sc_hd__a2bb2oi_1 cells: 92 +ABC RESULTS: sky130_fd_sc_hd__a311o_1 cells: 27 +ABC RESULTS: sky130_fd_sc_hd__a311oi_1 cells: 32 +ABC RESULTS: sky130_fd_sc_hd__a31o_1 cells: 450 +ABC RESULTS: sky130_fd_sc_hd__a31oi_1 cells: 490 +ABC RESULTS: sky130_fd_sc_hd__a32o_1 cells: 247 +ABC RESULTS: sky130_fd_sc_hd__a32oi_1 cells: 3 +ABC RESULTS: sky130_fd_sc_hd__and2_0 cells: 2145 +ABC RESULTS: sky130_fd_sc_hd__and3_1 cells: 922 +ABC RESULTS: sky130_fd_sc_hd__and3b_1 cells: 237 +ABC RESULTS: sky130_fd_sc_hd__and4_1 cells: 260 +ABC RESULTS: sky130_fd_sc_hd__clkinv_1 cells: 4926 +ABC RESULTS: sky130_fd_sc_hd__lpflow_inputiso1p_1 cells: 1363 +ABC RESULTS: sky130_fd_sc_hd__lpflow_isobufsrc_1 cells: 5013 +ABC RESULTS: sky130_fd_sc_hd__maj3_1 cells: 11507 +ABC RESULTS: sky130_fd_sc_hd__mux2_1 cells: 341 +ABC RESULTS: sky130_fd_sc_hd__nand2_1 cells: 19563 +ABC RESULTS: sky130_fd_sc_hd__nand2b_1 cells: 2206 +ABC RESULTS: sky130_fd_sc_hd__nand3_1 cells: 1696 +ABC RESULTS: sky130_fd_sc_hd__nand3b_1 cells: 534 +ABC RESULTS: sky130_fd_sc_hd__nand4_1 cells: 1671 +ABC RESULTS: sky130_fd_sc_hd__nand4b_1 cells: 3 +ABC RESULTS: sky130_fd_sc_hd__nand4bb_1 cells: 10 +ABC RESULTS: sky130_fd_sc_hd__nor2_1 cells: 7317 +ABC RESULTS: sky130_fd_sc_hd__nor2b_1 cells: 89 +ABC RESULTS: sky130_fd_sc_hd__nor3_1 cells: 672 +ABC RESULTS: sky130_fd_sc_hd__nor3b_1 cells: 78 +ABC RESULTS: sky130_fd_sc_hd__nor4_1 cells: 33 +ABC RESULTS: sky130_fd_sc_hd__nor4b_1 cells: 84 +ABC RESULTS: sky130_fd_sc_hd__nor4bb_1 cells: 11 +ABC RESULTS: sky130_fd_sc_hd__o2111ai_1 cells: 3 +ABC RESULTS: sky130_fd_sc_hd__o211a_1 cells: 34 +ABC RESULTS: sky130_fd_sc_hd__o211ai_1 cells: 14 +ABC RESULTS: sky130_fd_sc_hd__o21a_1 cells: 390 +ABC RESULTS: sky130_fd_sc_hd__o21ai_0 cells: 12743 +ABC RESULTS: sky130_fd_sc_hd__o21bai_1 cells: 71 +ABC RESULTS: sky130_fd_sc_hd__o22a_1 cells: 301 +ABC RESULTS: sky130_fd_sc_hd__o22ai_1 cells: 323 +ABC RESULTS: sky130_fd_sc_hd__o311a_1 cells: 16 +ABC RESULTS: sky130_fd_sc_hd__o311ai_0 cells: 112 +ABC RESULTS: sky130_fd_sc_hd__o31a_1 cells: 233 +ABC RESULTS: sky130_fd_sc_hd__o31ai_1 cells: 1146 +ABC RESULTS: sky130_fd_sc_hd__o32a_1 cells: 17 +ABC RESULTS: sky130_fd_sc_hd__o32ai_1 cells: 4 +ABC RESULTS: sky130_fd_sc_hd__o41a_1 cells: 30 +ABC RESULTS: sky130_fd_sc_hd__o41ai_1 cells: 483 +ABC RESULTS: sky130_fd_sc_hd__or3_1 cells: 349 +ABC RESULTS: sky130_fd_sc_hd__or3b_1 cells: 9 +ABC RESULTS: sky130_fd_sc_hd__or4_1 cells: 46 +ABC RESULTS: sky130_fd_sc_hd__or4b_1 cells: 8 +ABC RESULTS: sky130_fd_sc_hd__xnor2_1 cells: 23392 +ABC RESULTS: sky130_fd_sc_hd__xnor3_1 cells: 3124 +ABC RESULTS: sky130_fd_sc_hd__xor2_1 cells: 14173 +ABC RESULTS: sky130_fd_sc_hd__xor3_1 cells: 868 +ABC RESULTS: internal signals: 197889 +ABC RESULTS: input signals: 12304 +ABC RESULTS: output signals: 12288 +Removing temp directory. +Removing global temp directory. From 7c3ba3b05fa035a5183304837edcabecc507f572 Mon Sep 17 00:00:00 2001 From: Avik De Date: Fri, 5 Jun 2026 14:03:41 -0400 Subject: [PATCH 6/7] remove outputs --- .gitignore | 2 +- synth_outputs/synth_stats.txt | 83 ----------------------- synth_outputs/synth_timing.rpt | 120 --------------------------------- 3 files changed, 1 insertion(+), 204 deletions(-) delete mode 100644 synth_outputs/synth_stats.txt delete mode 100644 synth_outputs/synth_timing.rpt diff --git a/.gitignore b/.gitignore index c446db9..1023a41 100644 --- a/.gitignore +++ b/.gitignore @@ -11,4 +11,4 @@ scripts/*.onnx scripts/*.png .DS_Store __cmake_systeminformation -synth_outputs/synth.json +synth_outputs diff --git a/synth_outputs/synth_stats.txt b/synth_outputs/synth_stats.txt deleted file mode 100644 index 6cfff5d..0000000 --- a/synth_outputs/synth_stats.txt +++ /dev/null @@ -1,83 +0,0 @@ - -13. Printing statistics. - -=== synth_array === - - +----------Local Count, excluding submodules. - | - 132435 wires - 165235 wire bits - 2674 public wires - 35474 public wire bits - 82 ports - 1298 port bits - 142305 cells - 256 $scopeinfo - 12 sky130_fd_sc_hd__a2111o_1 - 38 sky130_fd_sc_hd__a2111oi_0 - 176 sky130_fd_sc_hd__a211o_1 - 325 sky130_fd_sc_hd__a211oi_1 - 31 sky130_fd_sc_hd__a21bo_1 - 546 sky130_fd_sc_hd__a21boi_0 - 948 sky130_fd_sc_hd__a21o_1 - 5524 sky130_fd_sc_hd__a21oi_1 - 6 sky130_fd_sc_hd__a221o_1 - 20 sky130_fd_sc_hd__a221oi_1 - 1144 sky130_fd_sc_hd__a22o_1 - 1080 sky130_fd_sc_hd__a22oi_1 - 92 sky130_fd_sc_hd__a2bb2oi_1 - 27 sky130_fd_sc_hd__a311o_1 - 32 sky130_fd_sc_hd__a311oi_1 - 450 sky130_fd_sc_hd__a31o_1 - 490 sky130_fd_sc_hd__a31oi_1 - 247 sky130_fd_sc_hd__a32o_1 - 3 sky130_fd_sc_hd__a32oi_1 - 2145 sky130_fd_sc_hd__and2_0 - 922 sky130_fd_sc_hd__and3_1 - 237 sky130_fd_sc_hd__and3b_1 - 260 sky130_fd_sc_hd__and4_1 - 4926 sky130_fd_sc_hd__clkinv_1 - 12288 sky130_fd_sc_hd__dfrtp_1 - 1363 sky130_fd_sc_hd__lpflow_inputiso1p_1 - 5013 sky130_fd_sc_hd__lpflow_isobufsrc_1 - 11507 sky130_fd_sc_hd__maj3_1 - 341 sky130_fd_sc_hd__mux2_1 - 19563 sky130_fd_sc_hd__nand2_1 - 2206 sky130_fd_sc_hd__nand2b_1 - 1696 sky130_fd_sc_hd__nand3_1 - 534 sky130_fd_sc_hd__nand3b_1 - 1671 sky130_fd_sc_hd__nand4_1 - 3 sky130_fd_sc_hd__nand4b_1 - 10 sky130_fd_sc_hd__nand4bb_1 - 7317 sky130_fd_sc_hd__nor2_1 - 89 sky130_fd_sc_hd__nor2b_1 - 672 sky130_fd_sc_hd__nor3_1 - 78 sky130_fd_sc_hd__nor3b_1 - 33 sky130_fd_sc_hd__nor4_1 - 84 sky130_fd_sc_hd__nor4b_1 - 11 sky130_fd_sc_hd__nor4bb_1 - 3 sky130_fd_sc_hd__o2111ai_1 - 34 sky130_fd_sc_hd__o211a_1 - 14 sky130_fd_sc_hd__o211ai_1 - 390 sky130_fd_sc_hd__o21a_1 - 12743 sky130_fd_sc_hd__o21ai_0 - 71 sky130_fd_sc_hd__o21bai_1 - 301 sky130_fd_sc_hd__o22a_1 - 323 sky130_fd_sc_hd__o22ai_1 - 16 sky130_fd_sc_hd__o311a_1 - 112 sky130_fd_sc_hd__o311ai_0 - 233 sky130_fd_sc_hd__o31a_1 - 1146 sky130_fd_sc_hd__o31ai_1 - 17 sky130_fd_sc_hd__o32a_1 - 4 sky130_fd_sc_hd__o32ai_1 - 30 sky130_fd_sc_hd__o41a_1 - 483 sky130_fd_sc_hd__o41ai_1 - 349 sky130_fd_sc_hd__or3_1 - 9 sky130_fd_sc_hd__or3b_1 - 46 sky130_fd_sc_hd__or4_1 - 8 sky130_fd_sc_hd__or4b_1 - 23392 sky130_fd_sc_hd__xnor2_1 - 3124 sky130_fd_sc_hd__xnor3_1 - 14173 sky130_fd_sc_hd__xor2_1 - 868 sky130_fd_sc_hd__xor3_1 - diff --git a/synth_outputs/synth_timing.rpt b/synth_outputs/synth_timing.rpt deleted file mode 100644 index 6422e58..0000000 --- a/synth_outputs/synth_timing.rpt +++ /dev/null @@ -1,120 +0,0 @@ - -10. Executing ABC pass (technology mapping using ABC). - -10.1. Extracting gate netlist of module `\synth_array' to `/input.blif'.. -ABC: using cached merged SCL: /var/folders/w5/sdsm9h5908gb9z8f7l6b83xr0000gn/T/yosys-liberty-scl-cache/yosys_merged_40d90887.scl (1 files) - -10.1.1. Executed ABC. -Extracted 210176 gates and 222481 wires to a netlist network with 12304 inputs and 12288 outputs. -Running ABC script: /abc.script -ABC: ======== ABC command line "source /abc.script" -ABC: + read_blif /input.blif -ABC: + read_scl /var/folders/w5/sdsm9h5908gb9z8f7l6b83xr0000gn/T/yosys-liberty-scl-cache/yosys_merged_40d90887.scl -ABC: Warning: Detected 9 multi-output cells (for example, "sky130_fd_sc_hd__fa_1"). -ABC: + source /Users/avik/projects/tiny-xpu/build/abc_timing.script -ABC: Warning: The network is combinational (run "fraig" or "fraig_sweep"). -ABC: WireLoad = "none" Gates = 129761 ( 3.8 %) Cap = 6.3 ff ( 6.5 %) Area = 928743.25 ( 80.5 %) Delay = 10676.35 ps ( 3.5 %) -ABC: Path 0 -- 11711 : 0 11 pi A = 0.00 Df = 0.0 -0.0 ps S = 0.0 ps Cin = 0.0 ff Cout = 27.6 ff Cmax = 0.0 ff G = 0 -ABC: Path 1 -- 32656 : 4 1 sky130_fd_sc_hd__a22o_1 A = 8.76 Df = 199.7 -89.9 ps S = 44.0 ps Cin = 2.4 ff Cout = 2.4 ff Cmax = 159.3 ff G = 98 -ABC: Path 2 -- 32657 : 2 2 sky130_fd_sc_hd__nand2_1 A = 3.75 Df = 288.1 -73.7 ps S = 89.4 ps Cin = 2.3 ff Cout = 7.7 ff Cmax = 166.6 ff G = 318 -ABC: Path 3 -- 32658 : 2 2 sky130_fd_sc_hd__xor2_1 A = 8.76 Df = 636.0 -103.3 ps S = 248.9 ps Cin = 4.4 ff Cout = 10.1 ff Cmax = 76.9 ff G = 225 -ABC: Path 4 -- 32682 : 3 2 sky130_fd_sc_hd__xnor3_1 A = 22.52 Df = 971.5 -14.2 ps S = 105.7 ps Cin = 3.7 ff Cout = 7.9 ff Cmax = 154.7 ff G = 204 -ABC: Path 5 -- 32685 : 2 1 sky130_fd_sc_hd__xnor2_1 A = 8.76 Df =1144.8 -34.3 ps S = 156.0 ps Cin = 4.5 ff Cout = 4.7 ff Cmax = 69.6 ff G = 100 -ABC: Path 6 -- 32689 : 2 2 sky130_fd_sc_hd__xnor2_1 A = 8.76 Df =1320.6 -39.2 ps S = 171.3 ps Cin = 4.5 ff Cout = 5.4 ff Cmax = 69.6 ff G = 114 -ABC: Path 7 -- 32708 : 3 2 sky130_fd_sc_hd__maj3_1 A = 10.01 Df =1694.8 -150.3 ps S = 87.9 ps Cin = 2.8 ff Cout = 6.7 ff Cmax = 155.7 ff G = 235 -ABC: Path 8 -- 32709 : 3 2 sky130_fd_sc_hd__maj3_1 A = 10.01 Df =2080.7 -337.9 ps S = 92.0 ps Cin = 2.8 ff Cout = 7.1 ff Cmax = 155.7 ff G = 246 -ABC: Path 9 -- 32712 : 3 2 sky130_fd_sc_hd__a21oi_1 A = 5.00 Df =2266.1 -290.3 ps S = 175.6 ps Cin = 2.3 ff Cout = 6.4 ff Cmax = 74.2 ff G = 262 -ABC: Path 10 -- 32714 : 3 2 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =2416.4 -194.6 ps S = 251.4 ps Cin = 1.7 ff Cout = 6.9 ff Cmax = 50.4 ff G = 390 -ABC: Path 11 -- 32715 : 3 2 sky130_fd_sc_hd__a21oi_1 A = 5.00 Df =2627.6 -276.8 ps S = 174.7 ps Cin = 2.3 ff Cout = 6.3 ff Cmax = 74.2 ff G = 259 -ABC: Path 12 -- 32716 : 3 2 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =2762.5 -171.8 ps S = 251.4 ps Cin = 1.7 ff Cout = 6.9 ff Cmax = 50.4 ff G = 390 -ABC: Path 13 -- 32717 : 3 2 sky130_fd_sc_hd__a21oi_1 A = 5.00 Df =2975.7 -256.0 ps S = 174.7 ps Cin = 2.3 ff Cout = 6.3 ff Cmax = 74.2 ff G = 259 -ABC: Path 14 -- 32718 : 3 2 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =3120.3 -142.8 ps S = 275.4 ps Cin = 1.7 ff Cout = 7.8 ff Cmax = 50.4 ff G = 446 -ABC: Path 15 -- 32719 : 3 2 sky130_fd_sc_hd__maj3_1 A = 10.01 Df =3515.5 -280.4 ps S = 90.1 ps Cin = 2.8 ff Cout = 6.9 ff Cmax = 155.7 ff G = 239 -ABC: Path 16 -- 32720 : 2 1 sky130_fd_sc_hd__nand2_1 A = 3.75 Df =3586.1 -300.7 ps S = 48.1 ps Cin = 2.3 ff Cout = 1.5 ff Cmax = 166.6 ff G = 62 -ABC: Path 17 -- 32731 : 4 34 sky130_fd_sc_hd__nor4b_1 A = 8.76 Df =7037.1-3259.8 ps S =4540.7 ps Cin = 2.1 ff Cout = 112.0 ff Cmax = 33.9 ff G = 5075 -ABC: Path 18 -- 32802 : 2 3 sky130_fd_sc_hd__xor2_1 A = 8.76 Df =8290.9-4221.4 ps S = 737.3 ps Cin = 4.4 ff Cout = 6.7 ff Cmax = 76.9 ff G = 146 -ABC: Path 19 -- 32805 : 4 3 sky130_fd_sc_hd__a211oi_1 A = 7.51 Df =8496.2-2109.0 ps S = 304.7 ps Cin = 2.4 ff Cout = 7.0 ff Cmax = 47.6 ff G = 273 -ABC: Path 20 -- 32808 : 5 3 sky130_fd_sc_hd__o311ai_0 A = 8.76 Df =8933.1-2347.5 ps S = 468.2 ps Cin = 1.8 ff Cout = 6.5 ff Cmax = 29.3 ff G = 353 -ABC: Path 21 -- 32810 : 3 2 sky130_fd_sc_hd__nand3_1 A = 5.00 Df =9062.7-2347.7 ps S = 93.0 ps Cin = 2.4 ff Cout = 3.0 ff Cmax = 146.5 ff G = 121 -ABC: Path 22 -- 32812 : 3 2 sky130_fd_sc_hd__or3_1 A = 6.26 Df =9394.1-2564.8 ps S = 79.5 ps Cin = 1.5 ff Cout = 4.8 ff Cmax = 167.6 ff G = 305 -ABC: Path 23 -- 32817 : 3 4 sky130_fd_sc_hd__a21o_1 A = 7.51 Df =9583.1-2612.3 ps S = 90.3 ps Cin = 2.4 ff Cout = 9.0 ff Cmax = 177.6 ff G = 358 -ABC: Path 24 -- 32822 : 4 2 sky130_fd_sc_hd__o31a_1 A = 8.76 Df =9881.7-2745.2 ps S = 91.2 ps Cin = 2.4 ff Cout = 7.1 ff Cmax = 149.2 ff G = 290 -ABC: Path 25 -- 32824 : 3 3 sky130_fd_sc_hd__o21a_1 A = 7.51 Df =10100.5-2790.6 ps S = 103.1 ps Cin = 2.4 ff Cout = 9.7 ff Cmax = 163.0 ff G = 388 -ABC: Path 26 -- 32826 : 4 2 sky130_fd_sc_hd__a211o_1 A = 8.76 Df =10404.7-2953.0 ps S = 61.1 ps Cin = 2.4 ff Cout = 4.9 ff Cmax = 176.7 ff G = 196 -ABC: Path 27 -- 152967 : 4 1 sky130_fd_sc_hd__a31o_1 A = 8.76 Df =10601.2-3024.2 ps S = 38.8 ps Cin = 2.4 ff Cout = 1.8 ff Cmax = 160.2 ff G = 72 -ABC: Path 28 -- 152968 : 3 1 sky130_fd_sc_hd__o21ai_0 A = 5.00 Df =10676.3 -68.6 ps S = 88.5 ps Cin = 1.7 ff Cout = 0.0 ff Cmax = 50.4 ff G = 0 -ABC: Start-point = pi11710 (\u_pe_0_12.weight_r [5]). End-point = po11631 ($flatten\u_pe_0_12.$0\acc_out[31:0] [31]). -ABC: + write_blif /output.blif - -10.1.2. Re-integrating ABC results. -ABC RESULTS: sky130_fd_sc_hd__a2111o_1 cells: 12 -ABC RESULTS: sky130_fd_sc_hd__a2111oi_0 cells: 38 -ABC RESULTS: sky130_fd_sc_hd__a211o_1 cells: 176 -ABC RESULTS: sky130_fd_sc_hd__a211oi_1 cells: 325 -ABC RESULTS: sky130_fd_sc_hd__a21bo_1 cells: 31 -ABC RESULTS: sky130_fd_sc_hd__a21boi_0 cells: 546 -ABC RESULTS: sky130_fd_sc_hd__a21o_1 cells: 948 -ABC RESULTS: sky130_fd_sc_hd__a21oi_1 cells: 5524 -ABC RESULTS: sky130_fd_sc_hd__a221o_1 cells: 6 -ABC RESULTS: sky130_fd_sc_hd__a221oi_1 cells: 20 -ABC RESULTS: sky130_fd_sc_hd__a22o_1 cells: 1144 -ABC RESULTS: sky130_fd_sc_hd__a22oi_1 cells: 1080 -ABC RESULTS: sky130_fd_sc_hd__a2bb2oi_1 cells: 92 -ABC RESULTS: sky130_fd_sc_hd__a311o_1 cells: 27 -ABC RESULTS: sky130_fd_sc_hd__a311oi_1 cells: 32 -ABC RESULTS: sky130_fd_sc_hd__a31o_1 cells: 450 -ABC RESULTS: sky130_fd_sc_hd__a31oi_1 cells: 490 -ABC RESULTS: sky130_fd_sc_hd__a32o_1 cells: 247 -ABC RESULTS: sky130_fd_sc_hd__a32oi_1 cells: 3 -ABC RESULTS: sky130_fd_sc_hd__and2_0 cells: 2145 -ABC RESULTS: sky130_fd_sc_hd__and3_1 cells: 922 -ABC RESULTS: sky130_fd_sc_hd__and3b_1 cells: 237 -ABC RESULTS: sky130_fd_sc_hd__and4_1 cells: 260 -ABC RESULTS: sky130_fd_sc_hd__clkinv_1 cells: 4926 -ABC RESULTS: sky130_fd_sc_hd__lpflow_inputiso1p_1 cells: 1363 -ABC RESULTS: sky130_fd_sc_hd__lpflow_isobufsrc_1 cells: 5013 -ABC RESULTS: sky130_fd_sc_hd__maj3_1 cells: 11507 -ABC RESULTS: sky130_fd_sc_hd__mux2_1 cells: 341 -ABC RESULTS: sky130_fd_sc_hd__nand2_1 cells: 19563 -ABC RESULTS: sky130_fd_sc_hd__nand2b_1 cells: 2206 -ABC RESULTS: sky130_fd_sc_hd__nand3_1 cells: 1696 -ABC RESULTS: sky130_fd_sc_hd__nand3b_1 cells: 534 -ABC RESULTS: sky130_fd_sc_hd__nand4_1 cells: 1671 -ABC RESULTS: sky130_fd_sc_hd__nand4b_1 cells: 3 -ABC RESULTS: sky130_fd_sc_hd__nand4bb_1 cells: 10 -ABC RESULTS: sky130_fd_sc_hd__nor2_1 cells: 7317 -ABC RESULTS: sky130_fd_sc_hd__nor2b_1 cells: 89 -ABC RESULTS: sky130_fd_sc_hd__nor3_1 cells: 672 -ABC RESULTS: sky130_fd_sc_hd__nor3b_1 cells: 78 -ABC RESULTS: sky130_fd_sc_hd__nor4_1 cells: 33 -ABC RESULTS: sky130_fd_sc_hd__nor4b_1 cells: 84 -ABC RESULTS: sky130_fd_sc_hd__nor4bb_1 cells: 11 -ABC RESULTS: sky130_fd_sc_hd__o2111ai_1 cells: 3 -ABC RESULTS: sky130_fd_sc_hd__o211a_1 cells: 34 -ABC RESULTS: sky130_fd_sc_hd__o211ai_1 cells: 14 -ABC RESULTS: sky130_fd_sc_hd__o21a_1 cells: 390 -ABC RESULTS: sky130_fd_sc_hd__o21ai_0 cells: 12743 -ABC RESULTS: sky130_fd_sc_hd__o21bai_1 cells: 71 -ABC RESULTS: sky130_fd_sc_hd__o22a_1 cells: 301 -ABC RESULTS: sky130_fd_sc_hd__o22ai_1 cells: 323 -ABC RESULTS: sky130_fd_sc_hd__o311a_1 cells: 16 -ABC RESULTS: sky130_fd_sc_hd__o311ai_0 cells: 112 -ABC RESULTS: sky130_fd_sc_hd__o31a_1 cells: 233 -ABC RESULTS: sky130_fd_sc_hd__o31ai_1 cells: 1146 -ABC RESULTS: sky130_fd_sc_hd__o32a_1 cells: 17 -ABC RESULTS: sky130_fd_sc_hd__o32ai_1 cells: 4 -ABC RESULTS: sky130_fd_sc_hd__o41a_1 cells: 30 -ABC RESULTS: sky130_fd_sc_hd__o41ai_1 cells: 483 -ABC RESULTS: sky130_fd_sc_hd__or3_1 cells: 349 -ABC RESULTS: sky130_fd_sc_hd__or3b_1 cells: 9 -ABC RESULTS: sky130_fd_sc_hd__or4_1 cells: 46 -ABC RESULTS: sky130_fd_sc_hd__or4b_1 cells: 8 -ABC RESULTS: sky130_fd_sc_hd__xnor2_1 cells: 23392 -ABC RESULTS: sky130_fd_sc_hd__xnor3_1 cells: 3124 -ABC RESULTS: sky130_fd_sc_hd__xor2_1 cells: 14173 -ABC RESULTS: sky130_fd_sc_hd__xor3_1 cells: 868 -ABC RESULTS: internal signals: 197889 -ABC RESULTS: input signals: 12304 -ABC RESULTS: output signals: 12288 -Removing temp directory. -Removing global temp directory. From ee96f3e2c67990b2a36489f704cd5b10145f87a7 Mon Sep 17 00:00:00 2001 From: Avik De Date: Fri, 5 Jun 2026 14:04:16 -0400 Subject: [PATCH 7/7] WIP clock period sweep - not working yet --- AGENTS.md | 17 +++++++++ cmake/synth.cmake | 53 ++++++++++++++++++++------- scripts/sweep_period.sh | 80 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 138 insertions(+), 12 deletions(-) create mode 100755 scripts/sweep_period.sh diff --git a/AGENTS.md b/AGENTS.md index d281963..d4c96e3 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -66,6 +66,23 @@ cmake -B build -DSIM=ON -DCLOCK_PERIOD_NS=10 cmake --build build --target synth ``` +### Clock Period Sweep + +Sweep `CLOCK_PERIOD_NS` from 2 to 20 ns to see the area vs frequency tradeoff: + +```sh +./scripts/sweep_period.sh +``` + +This runs `cmake` + `make synth` for each period, saving per-period results to `synth_outputs/ns/` (stats, timing, netlist) and printing a summary table of cells, gate area, and delay. + +**Memory note:** The sweep uses `SYNTH_COLS=1` (single column) because ABC's +timing-driven mapping (`&fraig`, `&dch -f`) blows past 10 GB on a 16×16 array +at 2 ns. The critical timing path is the accumulator chain down one column +— all columns have identical delay, so single-column timing is representative. +Multiply the reported gate area ×16 for an estimated full-array area. To +synthesise the full array, pass `-DSYNTH_COLS=16` to cmake (needs >10 GB RAM). + The `synth` target synthesises the array to SkyWater130 cells with ABC timing-driven mapping. ABC's `stime -p` reports the estimated critical path delay. Outputs go to `synth_outputs/`: `synth.json` (netlist), `synth_stats.txt` (cells), `synth_timing.rpt` (timing). diff --git a/cmake/synth.cmake b/cmake/synth.cmake index c645e21..ec1aedd 100644 --- a/cmake/synth.cmake +++ b/cmake/synth.cmake @@ -12,6 +12,15 @@ # Requires $SKYWATER_LIB env var pointing to the SkyWater130 Liberty .lib file. # Timing estimates, cell statistics, and gate-level netlist are written to # /synth_outputs/. +# +# Memory note: synth flattens all PEs into one module then passes the entire +# netlist to ABC. A 16×16 array (256 PEs) under tight timing can exceed 10 GB +# RAM because ABC's &fraig and &dch -f commands blow up on large flat designs. +# +# The critical timing path is the accumulator chain down a single column +# (ROWS PEs deep). All columns have identical delay. So we default to +# SYNTH_COLS=1 — one column, same timing, a fraction of the memory. +# Set SYNTH_COLS=16 to synthesise the full array (needs >10 GB for 2 ns). if(NOT YOSYS) return() @@ -29,31 +38,50 @@ endif() # --- Clock period for timing-driven mapping --- set(CLOCK_PERIOD_NS 10 CACHE STRING "Clock period in ns for ABC timing-driven mapping") +math(EXPR CLOCK_PERIOD_PS "${CLOCK_PERIOD_NS} * 1000") +# Stamp file so make rebuilds when the clock period changes (the Yosys command +# embeds CLOCK_PERIOD_PS in the -D flag but make can't see command changes). +set(CLOCK_PERIOD_STAMP "${CMAKE_BINARY_DIR}/clock_period.stamp") +file(WRITE ${CLOCK_PERIOD_STAMP} "${CLOCK_PERIOD_PS}") # --- Output directory for synthesis results --- set(SYNTH_OUT "${CMAKE_SOURCE_DIR}/synth_outputs") file(MAKE_DIRECTORY ${SYNTH_OUT}) # --- ABC timing script (generated at configure time) --- +# The script first runs technology-independent optimisation (fraig, scorr, +# dc2, dretime), then delay-constrained technology mapping (map) followed +# by area-recovery choice (dch). The -D flag on yosys's abc pass sets a +# global delay target that map and dch both respect — tighter periods +# select higher-drive cells, relaxed periods select smaller cells. +# The clock period is written into the file as a comment so Make detects +# period changes as a content change and triggers a rebuild. set(ABC_SCRIPT "${CMAKE_BINARY_DIR}/abc_timing.script") file(WRITE ${ABC_SCRIPT} - "strash; &get -n; &fraig -x; &put; scorr; dc2; dretime; strash; &get -n; &dch -f; &nf {D}; &put; stime -p\n") + "strash; &get -n; &fraig -x; &put; scorr; dc2; dretime; strash; map -D {D}; stime -p\n") set(SYNTH_JSON "${SYNTH_OUT}/synth.json") # Cache variables for array dimensions (shared with onnx-plugin). -set(SIM_ROWS 16 CACHE STRING "Systolic array row count") -set(SIM_COLS 16 CACHE STRING "Systolic array column count") +set(SIM_ROWS 16 CACHE STRING "Systolic array row count (Verilator + sim)") +set(SIM_COLS 16 CACHE STRING "Systolic array column count (Verilator + sim)") + +# Synthesis array dimensions — decoupled from SIM_* so we can use a single +# column for low-memory synthesis while keeping the full array for simulation. +# The critical timing path is the accumulator chain down a column (SYNTH_ROWS +# PEs deep). A single column gives the same delay as the full array. +set(SYNTH_ROWS "${SIM_ROWS}" CACHE STRING "Systolic array rows for synthesis") +set(SYNTH_COLS 1 CACHE STRING "Systolic array columns for synthesis") set(SYNTH_SRC "${CMAKE_BINARY_DIR}/synth_array.sv") set(DW 8) set(AW 32) -math(EXPR MAX_R "${SIM_ROWS} - 1") -math(EXPR MAX_C "${SIM_COLS} - 1") +math(EXPR MAX_R "${SYNTH_ROWS} - 1") +math(EXPR MAX_C "${SYNTH_COLS} - 1") file(WRITE ${SYNTH_SRC} "// Auto-generated flat array for Yosys synthesis\n" - "// Array: ${SIM_ROWS}x${SIM_COLS}, DATA_WIDTH=${DW}, ACC_WIDTH=${AW}\n" + "// Array: ${SYNTH_ROWS}x${SYNTH_COLS} (synthesis), DATA_WIDTH=${DW}, ACC_WIDTH=${AW}\n" "`timescale 1ns / 1ps\n\n" "module synth_array (\n" " input logic clk,\n" @@ -83,7 +111,7 @@ endforeach() file(APPEND ${SYNTH_SRC} "\n);\n\n") # Data wires across rows (n + 1 columns: 0..COLS) -foreach(c RANGE 0 ${SIM_COLS}) +foreach(c RANGE 0 ${SYNTH_COLS}) foreach(r RANGE 0 ${MAX_R}) file(APPEND ${SYNTH_SRC} " logic signed [${DW}-1:0] data_wire_${c}_${r};\n") @@ -93,7 +121,7 @@ file(APPEND ${SYNTH_SRC} "\n") # Acc wires down columns (n + 1 rows per column: 0..ROWS) foreach(c RANGE 0 ${MAX_C}) - foreach(r RANGE 0 ${SIM_ROWS}) + foreach(r RANGE 0 ${SYNTH_ROWS}) file(APPEND ${SYNTH_SRC} " logic signed [${AW}-1:0] acc_wire_${c}_${r};\n") endforeach() @@ -110,7 +138,7 @@ file(APPEND ${SYNTH_SRC} "\n") # Right-edge data outputs foreach(r RANGE 0 ${MAX_R}) file(APPEND ${SYNTH_SRC} - " assign data_out_right_${r} = data_wire_${SIM_COLS}_${r};\n") + " assign data_out_right_${r} = data_wire_${SYNTH_COLS}_${r};\n") endforeach() file(APPEND ${SYNTH_SRC} "\n") @@ -124,7 +152,7 @@ file(APPEND ${SYNTH_SRC} "\n") # Bottom-edge acc outputs foreach(c RANGE 0 ${MAX_C}) file(APPEND ${SYNTH_SRC} - " assign acc_out_bottom_${c} = acc_wire_${c}_${SIM_ROWS};\n") + " assign acc_out_bottom_${c} = acc_wire_${c}_${SYNTH_ROWS};\n") endforeach() file(APPEND ${SYNTH_SRC} "\n") @@ -162,7 +190,7 @@ add_custom_command( -p "techmap" -p "opt" -p "dfflibmap -liberty $ENV{SKYWATER_LIB}" - -p "tee -o ${SYNTH_OUT}/synth_timing.rpt abc -liberty $ENV{SKYWATER_LIB} -script ${CMAKE_BINARY_DIR}/abc_timing.script" + -p "tee -o ${SYNTH_OUT}/synth_timing.rpt abc -liberty $ENV{SKYWATER_LIB} -D ${CLOCK_PERIOD_PS} -script ${CMAKE_BINARY_DIR}/abc_timing.script" -p "opt_clean" -p "write_json ${SYNTH_JSON}" -p "tee -o ${SYNTH_OUT}/synth_stats.txt stat -width" @@ -170,7 +198,8 @@ add_custom_command( ${CMAKE_SOURCE_DIR}/src/pe.sv ${SYNTH_SRC} ${ABC_SCRIPT} - COMMENT "Synthesising array (${SIM_ROWS}x${SIM_COLS}) to SkyWater130 cells" + ${CLOCK_PERIOD_STAMP} + COMMENT "Synthesising array (${SYNTH_ROWS}x${SYNTH_COLS}) to SkyWater130 cells" ) add_custom_target(synth DEPENDS ${SYNTH_JSON}) diff --git a/scripts/sweep_period.sh b/scripts/sweep_period.sh new file mode 100755 index 0000000..54b4595 --- /dev/null +++ b/scripts/sweep_period.sh @@ -0,0 +1,80 @@ +#!/usr/bin/env bash +# Sweep CLOCK_PERIOD_NS and tabulate area vs timing tradeoff. +# +# Usage: ./scripts/sweep_period.sh +# +# Synthesises a **single column** (SYNTH_COLS=1) because the critical path is +# the accumulator chain down one column — all columns have identical delay. +# A full 16-column sweep at 2 ns exceeds 10 GB RAM. +# For full-array synthesis, override: cmake -DSYNTH_COLS=16 ... +# +# Results per period are saved to synth_outputs/ns/ and a summary +# table is printed at the end. Estimated full-array area ≈ column_area × 16. + +set -euo pipefail + +SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +PROJ_DIR="$(cd "${SCRIPT_DIR}/.." && pwd)" +BUILD_DIR="${PROJ_DIR}/build" +OUT_DIR="${PROJ_DIR}/synth_outputs" +PERIODS=(2 3 5 10 20) + +echo "================================================================" +echo " Clock Period Sweep" +echo "================================================================" +echo "" + +for period in "${PERIODS[@]}"; do + echo "--- Period=${period}ns ---" + + out_sub="${OUT_DIR}/${period}ns" + mkdir -p "${out_sub}" + + cmake -S "${PROJ_DIR}" -B "${BUILD_DIR}" \ + -DSIM=ON -DCLOCK_PERIOD_NS="${period}" \ + -DSYNTH_ROWS=16 -DSYNTH_COLS=1 > "${out_sub}/cmake.log" 2>&1 + # Force rebuild by removing previous output — make's dependency tracking + # can miss command-line-only changes (the -D flag value in Yosys command). + rm -f "${OUT_DIR}/synth.json" + make -C "${BUILD_DIR}" synth 2>&1 | tee "${out_sub}/build.log" | tail -5 + + cp "${OUT_DIR}/synth_stats.txt" "${out_sub}/synth_stats.txt" + cp "${OUT_DIR}/synth_timing.rpt" "${out_sub}/synth_timing.rpt" + cp "${OUT_DIR}/synth.json" "${out_sub}/synth.json" + + echo "" +done + +# ---- Extract & tabulate key metrics ---- +echo "" +echo "================================================================" +echo " Summary: Area vs Frequency Tradeoff (${#PERIODS[@]} periods)" +echo " 1 column (SYNTH_COLS=1) — multiply area ×16 for full 16-col array" +echo "================================================================" +printf "%-10s %-10s %-10s %-12s %-12s %-12s\n" "Period" "Freq" "Cells" "GateArea" "Area×16" "Delay" +printf "%-10s %-10s %-10s %-12s %-12s %-12s\n" "(ns)" "(MHz)" "" "" "" "(ps)" +printf "%-10s %-10s %-10s %-12s %-12s %-12s\n" "----------" "----------" "----------" "------------" "------------" "------------" + +for period in "${PERIODS[@]}"; do + stats="${OUT_DIR}/${period}ns/synth_stats.txt" + rpt="${OUT_DIR}/${period}ns/synth_timing.rpt" + + total_cells=$(awk '/cells$/ {print $1; exit}' "${stats}") + # The ABC summary line looks like: + # ABC: WireLoad = "none" Gates = 8074 ... Area = 57935.56 ... Delay = 10483.05 ps + abc_line=$(grep -F 'WireLoad' "${rpt}" || true) + area=$(echo "${abc_line}" | sed -n 's/.*Area *= *\([0-9.]*\).*/\1/p') + delay=$(echo "${abc_line}" | sed -n 's/.*Delay *= *\([0-9.]*\).*/\1/p') + delay="${delay:-?}" + freq_mhz=$(python3 -c "print(round(1000 / ${period}, 1))") + + if [ -n "${area}" ]; then + area_x16=$(python3 -c "print(round(${area} * 16, 2))") + else + area_x16="?" + fi + + printf "%-10s %-10s %-10s %-12s %-12s %-12s\n" \ + "${period} ns" "${freq_mhz}" "${total_cells}" "${area}" "${area_x16}" "${delay}" +done +echo ""