orbitality

3-stage MCU generation teardown · Qwen3.6-27B base vs SFT-top2 adapter · skywater130 PDK

Experiment

Both models were prompted with the same 3-stage pipelined MCU contract (4-op ISA, 4 registers, F/X/W pipeline, sky130). Each produced 8 candidates at temperature 0.5. Each candidate was compiled with Verilator, run against 4 test programs, and synthesized with yosys + abc against the sky130_fd_sc_hd typical-corner library. Reported metrics are line items, not aggregate scores.

Reference: a hand-written MCU passing 3/4 programs (the 4th fails a branch-forwarding edge case). It is shown to anchor the magnitude of the numbers, not as a target the LLMs were trained for.

Aggregate

metricbase 27BSFT-top2 27Bhand-written ref
candidates generated881
compiled (Verilator)0/81/81/1
programs passed (of compiled)2/43/4
area_um2 (median)1573.0min 1573.0 · max 1573.01126.0min 1126.0 · max 1126.0
fmax_mhz (median)2074.2min 2074.2 · max 2074.21183.1min 1183.1 · max 1183.1
ops_per_sec (median)592600000.0min 592600000.0 · max 592600000.0591600000.0min 591600000.0 · max 591600000.0
est_power_uW (median)580.8min 580.8 · max 580.8373.6min 373.6 · max 373.6

Candidates

namesourcecompiledtests pass area um²fmax MHzops/secest power µW first diagnostic
referencereferenceyes3/411261183.15.916e+08373.55
base_0baseno0/0SYSTEMVERILOG `int` declaration in a for-loop or task. Yosys (default Verilog-2005) rejects this; we use --sv to accept it.
base_1baseno0/0ILLEGAL LITERAL `8's0`: per IEEE 1800-2017 §5.7.1, the unsized literals `'0`/`'1`/`'x`/`'z` cannot take a size prefix. Use `8'sd0` instead. Frequent LLM confusion between sized literals and the unsized constant-context literals.
base_2baseno0/0
base_3baseno0/0
base_4baseno0/0
base_5baseno0/0SYSTEMVERILOG `int` declaration in a for-loop or task. Yosys (default Verilog-2005) rejects this; we use --sv to accept it.
base_6baseno0/0
base_7baseno0/0
sft_0sftno0/0
sft_1sftno0/0BYTE-ORDER BUG: descending slice `[255 - pc*8 -: 8]` on an ascending `[0:255]` vector reads from the wrong end — every byte is the trailing padding byte (0x00). Should be `[pc*8 +: 8]` for the byte-0-at-MSB convention.
sft_2sftno0/0BYTE-ORDER BUG: descending slice `[255 - pc*8 -: 8]` on an ascending `[0:255]` vector reads from the wrong end — every byte is the trailing padding byte (0x00). Should be `[pc*8 +: 8]` for the byte-0-at-MSB convention.
sft_3sftno0/0SYSTEMVERILOG `int` declaration in a for-loop or task. Yosys (default Verilog-2005) rejects this; we use --sv to accept it.
sft_4sftno0/0BYTE-ORDER BUG: descending slice `[255 - pc*8 -: 8]` on an ascending `[0:255]` vector reads from the wrong end — every byte is the trailing padding byte (0x00). Should be `[pc*8 +: 8]` for the byte-0-at-MSB convention.
sft_5sftno0/0ILLEGAL LITERAL `8's0`: per IEEE 1800-2017 §5.7.1, the unsized literals `'0`/`'1`/`'x`/`'z` cannot take a size prefix. Use `8'sd0` instead. Frequent LLM confusion between sized literals and the unsized constant-context literals.
sft_6sftno0/0SYSTEMVERILOG `int` declaration in a for-loop or task. Yosys (default Verilog-2005) rejects this; we use --sv to accept it.
sft_7sftyes2/415732074.25.926e+08580.75

What changed between base and SFT?

The SFT-top2 adapter was trained on 2 high-throughput 4×4 int8 matmul implementations (~13 GOPS each on sky130). It was not exposed to any MCU code. The point of this experiment was to measure how that narrow specialization affects an out-of-distribution task.

n=8 per model is a small sample. The compile-rate spread (0 vs 1) is not statistically meaningful by itself — it is consistent with the matmul-RL evaluation, where the SFT'd model also showed slightly more reliable Verilog generation at lower temperature.