Chipbase Competition 01: Systolic Array AI Accelerator
- Array
- 16 × 16, 8-bit integer
- Process
- ASAP7
- Runtime budget
- 12 h, 16 threads, 64 GB of memory
Harden Gemmini, an open-source AI accelerator built around a 16 by 16 systolic array, on ASAP7 (Arizona State University's 7 nm predictive process) with any open tools. Partition, place, and route it however you like; entries are scored on clock speed, area and power.
The design
Gemmini, from the University of California, Berkeley. A systolic-array accelerator: a 16 by 16 grid of multiply-accumulate processing elements (PEs), fed by a banked scratchpad of SRAM (Static Random-Access Memory) and draining into a banked accumulator. The array's wide buses on three of its edges are what make the floorplan matter.
Hover over or tap any block to see what it does.
The reference layout, stage by stage
How you win
Pass every gate to be ranked, then score highest; the reference scores 1.000.
T the clock period you declare and pass timing at · A die area · P power at a fixed 1,000 ps clock with the pinned activity, so a slower clock does not lower it
| Speed (clock period) | Area (die) | Power | |
|---|---|---|---|
| Weight | 0.30 | 0.50 | 0.20 |
| 10% smaller adds | +3.2% | +5.4% | +2.1% |
Area weighs most because the die is almost all blocks and memories, so its size comes down to how you partition, shape and pack them. How the weights were chosen.
Slide each value against the reference and watch your score. The reference is 6,391 ps, 628,065 µm² and 1.3455 W.
Start in five steps
Basic requirements: a Linux machine with Docker, 16 threads, 64 GB of memory and about 120 GB of free disk. Full requirements.
What's in the harness:
systolic-array-ai-accelerator-harness/ design/ # the fixed inputs: RTL (Register-Transfer Level), # SRAM macros, activity file flow/ # the reference flow (flow/gemmini/) and the evaluator reproduce/ # the reference packaged as an entry judge/ # the official runner (step 4) setup.sh # step 1 run_baseline.sh # steps 2 and 4: runs the flow evaluate.sh # step 4: scores a result # made as you go, never committed: work/ # the flow's working files (about 40 GB per run) baseline/ # the flow's result judge_work/ # your entry, built as the official run builds it eval_work/ # the evaluator's work and evaluation.json
- 1Clone the harness, start the pinned container, and run
./setup.shinside it:git clone https://github.com/Samcooper01/systolic-array-ai-accelerator-harness cd systolic-array-ai-accelerator-harness # the pinned image: OpenROAD-flow-scripts at the challenge commit DIGEST=sha256:6bc088ee563c76374f7ef5d0a3244d607a6162c8979f1815f92eef683c1169a4 docker run --rm -it \ -v "$PWD":/work -w /work \ openroad/orfs@$DIGEST bash # inside the container: ./setup.sh # links the container's tools and checks them
- 2Optional:
./run_baseline.shreproduces the reference in 5 to 6 hours, then./evaluate.sh baseline/should score 1.000, confirming your machine matches it. - 3Make the flow your own: edit or replace the reference flow in
flow/.run_baseline.shruns it, both here and in the official run, wherereproduce/run.shcopies its result to/result. Here are some places to start:- The reference top level: Every script and setting the reference uses.
- The reference floorplan: Where every block and memory sits.
- The floorplan editor: Draws floorplans and writes placement scripts.
- The reference as an entry: A Dockerfile and run script; point them at your flow.
- The submission spec: What
run.shmust write.
- 4Build and score your flow inside the container:
./run_baseline.sh # runs your flow, as reproduce/run.sh does, # into baseline/ (5 to 6 hours for the reference) ./evaluate.sh baseline/ # checks every gate and scores it (about an hour)
Before you submit, test it once the way the official run will: commit, then run the official runner in a terminal on your own machine, outside the container (for an entry that is not a fork of the harness, add its path and commit):
git add -A && git commit -m "my entry" # builds your commit's container and runs it with no network under the # 12 hour budget, then scores it (6 to 7 hours for the reference), # writing eval_work/mine/evaluation.json judge/run_entry.sh
- 5Once you are ready to submit, push your source, without build outputs, and open an issue on the harness repository with your repository, the commit, and your
eval_work/mine/evaluation.json.
- Open-source tools, or your own: write your own placer, router, or scripts if you like, as long as it is open source and in your repository.
- Physical design changes only: floorplan, placement, clock tree, routing, sizing, and buffering are yours. Synthesis is pinned, and the evaluator proves your final netlist against its own run of it.
- Only the SRAM macros are fixed: everything else you can harden, split, or leave flat, and you place all of it.
- Your repository must build the layout from the RTL within the 12 hour budget, on 16 threads and 64 GB of memory.
- The evaluator takes every measurement itself from your layouts, so every entry is scored the same way.
The rules
- Any open-source tools, stock or patched.
- Your own tooling: write custom placers, routers, scripts, or anything else, as long as it is open source and in your repository.
- Enter alone or as a team.
- Submit again when you improve: your best score counts.
- Any partition: harden blocks at any granularity, reuse the reference blocks, or run flat.
- Any optimization: floorplan, block shapes, pins, sizing, buffering, clock gating, manual placement.
- Clock period: a faster clock scores better
- Die size, aspect ratio, and utilization
- I/O (Input/Output) pin placement
- Clock tree targets and useful skew
- Cell choices, including the threshold-voltage mix
- Power grid design (straps, pitch, layers), as long as it meets the IR drop limit
- Any other knob in the flow: tool settings, scripts, effort levels, anything not in the fixed list
- Commercial or proprietary tools, libraries, or IP (Intellectual Property).
- Changing the design's function or interface (checked by equivalence against the pinned synthesis of the golden RTL).
- Changing synthesis in any way: the evaluator re-synthesizes each module with the pinned settings, and your netlist must be equivalent to it. Retiming, scan insertion, and adding, removing, duplicating, or merging registers are therefore out, beyond the occasional load-splitting copy the pinned synthesis itself makes.
- Anything fetched from outside: your build must run offline, from your repository and the fixed inputs only.
- One clock, on the clock port: you choose its period and nothing else about it
- Input and output paths: input to register and register to output within 80 percent of your period, input to output within 60 percent
- Every path is timed: there are no false or multicycle paths
- No clock uncertainty, input drive, or output load: the same ideal conditions for every entry
- Operating corners: setup at the slow corner, hold at the fast, power at the typical
- Wire resistance and capacitance per layer, pinned for M2 through M9
- Switching activity for power: one pinned file for everyone
- IR drop limit: 110 mV worst-case static drop
Submit an entry
A git repository of source that builds your layout from the pinned RTL, with nothing prebuilt. The official run builds the result from it, so the layout is never committed: the reference result is about 2.4 GB, and GitHub refuses any file over 100 MB. The harness has the full submission spec.
# what you submit: a git repository of source, nothing built your-entry/ reproduce/ Dockerfile # the container your flow runs in: open tools, pinned run.sh # builds the result from the pinned RTL, within the budget flow/ # your scripts, settings, and any tools you add floorplan/ # optional: block and macro locations, pins, regions .gitignore # keeps result/ and the flow's work directories out of git # not committed: run.sh writes top.def, top.v, blocks/ and period.txt # into /result in the official run
To send it in, open an issue on the harness repository with your repository, the commit to build, and the evaluation.json from your test with the official runner (eval_work/mine/evaluation.json). The official run builds your repository at that commit and scores what it builds; your own numbers are checked against its run.
Requirements
- A Linux machine on x86-64.
- 16 threads and 64 GB of memory: the same limits the official run builds under.
- About 120 GB of free disk, counting Docker's own storage: the reference run takes about 40 GB, the official-runner test in step 4 about 45 GB while it runs, and each evaluation about 16 GB. Deleting a run's work folder frees most of its 40 GB.
- Docker, or any OCI (Open Container Initiative) container runtime.
- Git and Python 3 on your machine itself, outside the container, and a repository for your entry.
- OpenROAD-flow-scripts @ bde10c7 → the flow and the ASAP7 platform files
- Gemmini RTL @ 8c8b38b → generated with Chipyard 1.11.0 and firtool 1.61.0, and shipped in the harness as fixed Verilog
- FakeRAM2.0 (memory macros) @ 8e6cd66 → the SRAM macros for the scratchpad and accumulator
- ASAP7 PDK (Process Design Kit) @ flow/platforms/asap7 → inside the flow, pinned by the commit above
How entries are scored
The evaluator is what scores you. It is fixed, it uses the tools pinned in versions.lock, and it computes every number from your layouts itself; anything your own flow reports is ignored. It runs the same way on your machine (./evaluate.sh baseline/) and in the official run, and in a fresh clone of the harness it reproduces the reference numbers exactly. Steps marked GATE decide pass or fail: miss any gate and the entry is not ranked. The other steps produce the numbers the score is built from.
-
Build your entryThe official runner clones your repository at the commit you submit, builds its container, and runs your flow with no network, 16 threads, and 64 GB of memory. Your flow writes result/: the top-level DEF (Design Exchange Format) layout, the top-level netlist, period.txt, and, for every block you hardened, its DEF layout and netlist. Only these files are read: any parasitics, timing models, abstracts, or reports your flow writes are ignored. Locally, judge/run_entry.sh runs every step here; ./evaluate.sh baseline/ runs every step from Blocks on, on the result you built.
-
Compute budget GATE 01The official runner checks that the longest dependency chain (a block, then the block that contains it, then the top) is 12 hours or less. The chain comes from the per-step times your flow writes to result/runtime.json, as run_baseline.sh does for the reference (5.6 hours); a flow that writes none is judged on its wall-clock time. The official run keeps the tool logs, so the reported times can be checked against them, and a person reviews the flow of every leading entry before it is certified. judge/run_entry.sh reports this gate locally, in judge.json.
-
Blocks GATE 02Reads every hardened block's layout, extracts its parasitics with the pinned rules, and derives its own abstract and its own fast-corner and slow-corner timing models for the levels above. Each block must be placement-legal and fully routed. Children are processed before the blocks that contain them.
-
Timing, legality, routing, area GATE 03Reads the top-level layout with the evaluator's block models in place, extracts its parasitics, and times it with OpenSTA at your declared period with propagated clocks: setup at the slow corner (0.63 V, 100 °C), hold at the fast corner. Checks that no cell or macro overlaps, that everything is on the placement grid, and that no net is unrouted. The die area comes from the layout's outline.
-
PowerTotal power at the typical corner with a fixed 1,000 ps reference clock, from the pinned switching activity: one tiled matrix multiply, C = relu(scale × (A × B + D)) at 128 by 128 by 128, simulated on the golden RTL. Activity is applied per flip-flop by register name (99.97% of the reference's flip-flops are covered) and propagated through the rest. A slower clock does not lower your power score.
-
Power integrity GATE 04Static IR drop analysis of your power grid with OpenROAD, using that power; the worst drop must be at most 110 mV. The reference's is 84.4 mV.
-
Design rules GATE 05Every layout, block and top, is checked with the detailed router's own rule checker against the technology's routing and via rules. Any short, or any via spacing, enclosure, or off-grid violation, fails the entry. The checker's other findings (end-of-line keep-out and spacing, corner and metal spacing, minimum width) are reported as counts but do not fail the entry: run standalone, the checker reports them on every block of the reference even where the router's own sign-off found none. The open ASAP7 KLayout deck is not a gate for the same reason; it is available for information.
-
Logic equivalence GATE 06For every module you submit, the evaluator runs the pinned synthesis itself: the golden RTL through the pinned Yosys with the pinned settings, with your other hardened blocks and the SRAM macros as black boxes. Your final netlist of that module must be equivalent to the result. The proof cuts the black boxes and every register, pairs each flip-flop with the synthesized register of the same name, and has ABC prove the whole module. A module the prover cannot finish is checked with 2,000,000 random vectors instead: it passes, and the report says it was checked, not proven. Every reference block and the reference top are proven, in seconds to minutes each. Keep synthesis as pinned: the gate is what you did after it.
-
Layout matches netlist GATE 07The pin-level connectivity of every layout is compared with that of the netlist that passed equivalence, net by net. ASAP7 has no open transistor-level LVS (Layout Versus Schematic) deck, so this compares the connectivity the layout declares; opens and shorts in the metal are caught by routing and the design-rule check.
-
ScoreThe figure of merit from your clock period, die area, and power against the reference values (6,391 ps, 628,065 µm², 1.3455 W). The report lists every gate's result and details, every metric, and the score, and evaluation.json holds the same as JSON (JavaScript Object Notation) for the leaderboard.
The evaluator is deterministic: the same result always gets the same numbers. Its own runtime does not count toward your budget; on the reference it takes about an hour.
Closing the loopholes
- No shipped answers. Your repository may carry scripts, tools, and floorplan constraints: block and macro locations, pin placement, and placement regions. It may not carry a finished standard-cell placement, routing, or gate netlist, and your flow must synthesize from the pinned RTL, the same RTL everyone downloads. The official run mounts that RTL at /design and builds with no network, a person reads the flow of every leading entry before it is certified, and the tool logs are kept, so a run too fast to be real is examined.
- Every layer is charged for its wires. M2 through M7 have calibrated resistance and capacitance in the flow. M8 and M9 have no calibrated values in stock OpenROAD-flow-scripts, so the evaluator uses our pinned values for them, derived from the ASAP7 layer geometry. You may route on M8 and M9, and those wires are charged at the pinned values, never at zero.
- The evaluator is the same one you run. The evaluator is public, and everyone can run it locally as often as they like. If you find a gap in it, report it on the harness repository.
How the score weights are set
The factors multiply rather than add, so a gain on any axis moves your score and no single term drowns the others. The weights are fixed before the competition opens and do not change once entries arrive: area 0.50, speed 0.30, power 0.20. Area counts most because the die is almost all blocks and memories, so its size comes down to how you partition, shape and pack them. Speed is won mostly inside the blocks. Power moves least: most of it is drawn inside the blocks, by logic the pinned synthesis fixes. The weights sum to 1 and are pinned in scoring.yaml.
Helpful information
The challenge and its tools
- Challenge harness: The pinned inputs, the reference flow, the evaluator, and the submission spec, in one repository to clone.
- OpenROAD-flow-scripts @ bde10c7: The exact flow and PDK the harness pins.
- Chipyard: The framework Gemmini's RTL is generated in.
- ASAP7 PDK: The process design kit.
- OpenROAD: Place and route, timing, extraction, and DRC (Design Rule Check).
- Yosys: Synthesis.
- OpenSTA: The static timing engine the timing gate uses.
- ABC: The logic-equivalence prover the gate uses, through Yosys.
- KLayout: Layout viewing and DRC.
Understand the design
- One matrix multiply, step by step: New to systolic arrays? Start here.
- Gemmini's documentation: The architecture, straight from the designers at the University of California, Berkeley.
- The Gemmini paper (Genc et al., Design Automation Conference 2021): Why the blocks are shaped the way they are.
Learn the steps you will change
- Floorplanning: Where the macros go, and why it matters most here.
- Placement: Spreading the standard cells around the macros.
- Clock tree synthesis: One clock to every tile and memory bank.
- Routing: Connecting it all on nine metal layers.
- Static timing analysis: How the evaluator decides your clock period is real.
- Methods and algorithms: The algorithms behind each stage, if you want to write your own tools.
Know the process
- ASAP7, the predictive 7 nm process kit: The process the challenge is built on.
- The metal stack and design rules: The layers you route on and the rules the design-rule check enforces.
- PVT (Process, Voltage, Temperature) corners: Why setup is checked at the slow corner and hold at the fast.
Practice first
- Harden riscv32i in your browser: Take a real processor through the flow in seconds, and see what the clock and utilization do.
- Graded problems: Small physical design tasks, some graded by a real OpenROAD run.
Tool documentation
- OpenROAD: The place-and-route tool the reference flow uses.
- OpenROAD-flow-scripts: The flow the harness pins, and its settings.



