P07’s tiny SoC, with the 16-byte flop RAM swapped for a real sky130
OpenRAM SRAM macro (sky130_sram_1kbyte_1rw1r_8x1024_8, 455 × 446 µm,
1024 × 8 bits). First time the ladder integrates anything that isn’t
synthesizable RTL — a hard-IP block the place-and-route flow has to
abut against, route power around, and treat as opaque.
What happened
Status: rtl-pass. Three programs verified under iverilog (SRAM round-trip, UART TX of “Hi”, GPIO write/read), demo runs the P07 echo loop unchanged. The harden flow needed several config rounds before it would even start cleanly; landing a clean signoff is still outstanding.
The four delta-from-P07 changes:
- RAM module replaced by
sram_wrapperthat instantiates the macro. Sync-read macro means the CPU FSM gained a newS_MEMWAITstage between EXECUTE and WB on LD. - Address decoder remapped because the macro is 1 KB not 16 B:
0x00..0x7FRAM,0x80..0x82UART,0xC0..0xC1GPIO. - Sim/synth model split. OpenRAM ships a
.vmodel but iverilog can’t schedule itsdout0 <= #DELAY mem[]read. Synthesis gets the upstream model; sim gets a port-compatible stub attest/sram_model.v. Same fork pattern other sky130 educational projects use (raulbehl’s cocotb harness, Cornell ECE 5745 Tut 8). - librelane config uses the
MACROSschema (gds, lef, nl, lib, instances, fixed location) andVDD_NETS=vccd1to match the macro’s Caravel-style power pins.
The macro-aware flow surfaced things the standard-cell-only ladder never had to think about:
- Verilator rejects USE_POWER_PINS-conditional vccd1/vssd1 as tristate-port shorts. The wrapper drops the explicit power-pin block entirely; LibreLane’s MACROS schema handles power connection externally via PDN hooks.
- PVT corner library shortage. OpenRAM only ships the
typical-typical (TT 025C 1v80) lib for this macro. Initial config
used
*_tt_025C_1v80, which made the slow and fast corners come up empty. Switched the wildcard to*so the single TT corner stands in for every PVT corner the flow asks for. Compliance trade-off, documented. - Schema migrations.
FP_PDN_MACRO_HOOKSis the right key to stitch chip-level vccd1/vssd1 onto the macro’s pre-placed pins, notpower_connections(which isn’t in LibreLane’s Macro dataclass at all). SimilarlyERROR_ON_MAGIC_DRCrather thanQUIT_ON_MAGIC_DRC. Set to false because OpenRAM macros have known OPC mismatches that aren’t real DRC violations. - klayout-render multi-top-cell bug.
RUN_KLAYOUT_RENDER: falseis the canonical workaround — the macro’s GDS exposes itself as a top alongside ours, the render step chokes. Cosmetic anyway; the site’sbuild_layout_assets.shgenerates its own previews. - DEFAULT_PROG width mismatch. Verilator caught that the program
ROM concatenations totaled 1008 bits instead of
ROM_DEPTH × 16 = 1024. Added a16'h0000NOP at PC=0 to round out.
The page got rewritten from a single big RTL block to four focused
sections — one per delta — each with a focused <Source> snippet
and per-line annotations. It reads much better.
Receipts
98af31b— RTL pass. Wrapper, S_MEMWAIT FSM stage, sim-vs-synth model split.ea13b0d— P08 lint fixes (USE_POWER_PINS removal, ROM width fix). P09 also lands in this commit.ac3c158— focused-narrative page rewrite, lib wildcard fix, FP_PDN_MACRO_HOOKS, RUN_KLAYOUT_RENDER=false.
Project page: /projects/08_macro_integration/.