Playground · research instrument
On-device AIFPGA Verilog Live Sculptor
Type Verilog and watch silicon sculpt itself: live parser infers LUTs/registers/DSPs/BRAM, estimates logic depth and critical path, lights a CLB floorplan, draws cycle-accurate setup/hold waveforms with slack, flashes red on violation, and locks a harmonic triad when timing closes. Place & Route is animated — all client-side, no server.
Independent research instrument — not claimed as MakerPortal shipped product code. Methods, equations, assumptions, and limitations are disclosed so you can inspect what the page does and does not establish.
Verilog RTL
// live parseLUTs
—
Regs
—
DSP / BRAM
—
Critical paths (est)
How parsing maps
assign→ 1 LUT + op weightalways @(*)→ 2 LUTs, combalways @(posedge clk)+<=→ registers*→ DSP48,reg [..][..]→ BRAM- T_route grows with spread slider — mimics congestion
CLB floorplan — LUTs lighting, spine = clk, orange=DSP purple=BRAM
Timing visualizer — CLK, Data arrival, Required, Slack
Anatomy of the sculptor
Parser → Netlist → Delay
- Strip: remove // and /* */ comments, preserve line numbers for LUT tracing.
- Lex: regex for
module,assign,always @(posedge),always_comb,<=, operators. No elaboration — fast O(n). - Infer: LUT = assigns + ⌈0.35·bitwise⌉ + ⌈0.5·unary-~⌉ + ⌈0.55·addSub⌉ + 2·combBlocks + muxes. Regs = non-blocking
<=assignments — the first depth-0 assignment operator in a statement, soif (a <= b), aforbound andassigncomparisons are not counted. DSP = isolated*(sensitivity star excluded). BRAM =reg [...] mem [...]. - Levels: N_logic = ⌈1.2·log2(LUTs) + 0.15·assigns + 0.25·muxes⌉ mimics fanin growth. Depth visualized in heat.
- Floorplan: 14×14 CLB grid (196 LUTs). Regs cluster towards central clock spine (col 6-7). DSP stacked bottom, BRAM right edge. Placement animates in PnR to show iterations.
Delay model
T_route slider maps to congestion 0.12 → 0.57 ns per hop.
Visual-audio closure
- Floorplan cells: base #1e232e, lit LUT #a3e635 with alpha = 0.5 + 0.5·(depth/max). Animated fill sweep simulates placer passes.
- Timing canvas: CLK as 50% duty square, scaled so 1 ns = ~36 px. Data arrival drawn as rising edge with arrow at T_arr. Required = T_clk - T_setup - T_jitter.
- Setup violation: red overlay between T_arr and T_required when slack<0, pulses via sin flash at 6Hz.
- Hold lane: thin cyan trace at T_arr_min=0.22·T_arr. If < T_hold, lane flashes red & sub-blast.
- Audio: Web Audio, 3 oscillators saw→sine, just major 4:5:6 (220,275,330Hz). Gain=0 when violation, ramps to 0.1–0.14 on closure. Spatial: left/right staggered ±15ms to widen.
Hold check
The math and physics, in full
Setup slack
Positive means data arrives before setup window. T_uncert includes jitter slider.
Hold slack
Logic levels & utilization
Gear behind this build
Verilog stack · 5 picks
Hardware picks5
$496.01KitArty A7: Artix-7 FPGA Development Board for Makers and Hobbyists (Arty A7-35T)
Xilinx Artix-7 XC7A35T with 33k LUTs, 90 DSPs — synthesize Verilog typed here, match reported LUT/FF utilization vs simulated floorplan packing and timing report T_ns slack.
$74.50BookDigital Design and Computer Architecture: ARM Edition
From gates to RISC-V pipeline — Chapter 3 defines setup/hold T_su/T_h and clock skew that this sculptor checks live; Chapter 7 datapath mapping explains LUT vs MUX vs adder inference.
$104.99BookFPGA Prototyping by Verilog Examples: Xilinx Spartan-3 Version
Hands-on Verilog FPGA prototyping text paired with the Live Sculptor.
$18.50KitSparkFun MicroMod Main Board - Single
SparkFun Original MicroMod carrier — swap processor blades for FPGA/MCU experiments next to Verilog Live Sculptor. 10% Originals.
$30.95MicrocontrollerSparkFun Thing Plus - RP2350
SparkFun Original RP2350 Thing Plus (Feather) — dual-core lab MCU with Qwiic. 10% Originals commission.
Prices shown were retrieved from the Amazon Product Advertising API on 19 July 2026 and are indicative only — the price and availability on Amazon at the time of purchase apply.
More gear across every app: the full Gear list →
Hardware Kit Builder
Build the physical hardware platform. Select your components below to generate a live, real-time bill of materials and build instructions.
Build this lab
Verilog → FPGA hardware path
Arty A7-35T Artix-7 + SparkFun MicroMod + Thing Plus RP2350 — synthesize live, validate timing with real LUT/FF utilization. MicroMod & RP2350 are SparkFun Originals (10%).
- $496
- $19
- $31
- $75
- $105
Prices shown were retrieved from the Amazon Product Advertising API on 19 July 2026 and are indicative only — the price and availability on Amazon at the time of purchase apply.
Estimated total
$545
Prices from Amazon catalog cache · may change
Core solver — TypeScript
// Mirrors src/lib/verilog-netlist.ts — the parser this page actually runs.
// The listing below is kept fragment-identical to the lib by
// verilog-netlist.test.ts; editing one without the other fails the suite.
// Tells `q <= d;` apart from the RELATIONAL <= in `if (a <= b)`,
// `for (i = 0; i <= 7; ...)` and `assign lt = a <= b;`. The regex this
// replaced matched any <= with a semicolon after it, so a purely
// combinational module reported registers it does not have.
export function countNonBlocking(src) {
const statements = []; let depth = 0, start = 0;
for (let i = 0; i < src.length; i++) { // cut at ; / begin / end / else,
const c = src[i]; // but only at paren depth 0, so a
if (c === '(') { depth++; continue; } // for(...;...;...) header stays whole
if (c === ')') { if (depth > 0) depth--; continue; }
if (depth !== 0) continue;
if (c === ';') { statements.push(src.slice(start, i)); start = i + 1; continue; }
if (c === 'b' || c === 'e') {
if (/[\w$]/.test(src[i - 1] ?? '')) continue;
const kw = /^(?:begin|end|else)\b/.exec(src.slice(i, i + 6));
if (!kw) continue; // endmodule / endcase fail \b
statements.push(src.slice(start, i)); i += kw[0].length - 1; start = i + 1;
}
}
statements.push(src.slice(start));
let count = 0;
for (const stmt of statements) {
let d = 0; // no assign special case: lhs = rhs puts = first
for (let i = 0; i < stmt.length; i++) { // first depth-0 assignment op decides
const c = stmt[i];
if (c === '(') { d++; continue; }
if (c === ')') { if (d > 0) d--; continue; }
if (d !== 0) continue;
if (c === '<' && stmt[i + 1] === '=') { count++; break; }
if (c === '=' && stmt[i + 1] !== '=' && !'=!<>'.includes(stmt[i - 1] ?? '')) break;
}
}
return count;
}
export function parseVerilogToNetlist(src, clkPeriod, routingSpread, jitter) {
const noComments = src.replace(/\/\/.*$/gm,'').replace(/\/\*[\s\S]*?\*\//g,'');
const modules = [...noComments.matchAll(/module\s+(\w+)/g)].map(m=>m[1]);
const assigns = (noComments.match(/^\s*assign\s+/gm)||[]).length;
const alwaysPos = (noComments.match(/always\s*@\s*\(\s*posedge/gi)||[]).length + (noComments.match(/always_ff\s*@/gi)||[]).length;
const alwaysComb = (noComments.match(/always\s*@\s*\(\s*\*/g)||[]).length + (noComments.match(/always_comb/gi)||[]).length;
const ops = (noComments.match(/[&|^]/g)||[]).length;
const tildes = (noComments.match(/~/g)||[]).length;
const addSub = (noComments.match(/(?<![=!<>])\+(?!\+)|(?<![=!<>])-(?!-)/g)||[]).length;
// isolated * not part of ** and not the @(*) sensitivity star
const noSensitivity = noComments.replace(/@\s*\(\s*\*\s*\)/g, '@ALL');
const dsp = (noSensitivity.match(/(?<!\*)\*(?!\*)/g)||[]).length;
const nb = countNonBlocking(noComments);
const bram = (noComments.match(/reg\s*\[[^\]]+\]\s*\w+\s*\[[^\]]+\]|\bBRAM|\bRAMB|mem\[|memory/gi)||[]).length;
const muxes = (noComments.match(/\bcase\b|\?\s*:/g)||[]).length;
let luts = assigns + Math.ceil(ops * 0.35) + Math.ceil(tildes * 0.5) + Math.ceil(addSub * 0.55) + alwaysComb * 2 + muxes;
if (luts === 0 && noComments.trim().length > 10) luts = 1;
const regs = nb>0? nb : alwaysPos*2;
const levels = Math.max(1, Math.ceil(Math.log2(Math.max(1,luts))*1.2 + assigns*0.15 + muxes * 0.25));
const tLut=0.35, tRoute=0.12+routingSpread*0.45, tDsp=1.15, tCq=0.18, tSetup=0.08, tHold=0.05;
const arrival = tCq + levels*(tLut+tRoute) + dsp*tDsp + bram*0.9;
const required = clkPeriod - tSetup - jitter;
const slack = required - arrival;
const holdSlack = arrival*0.22 - 0.05;
const fmax = 1000/(arrival + tSetup);
return { modules, luts, regs, dsps:dsp, brams:bram, levels, arrival, required, slack, holdSlack, fmax };
}Export · Soft gate
Export Verilog + timing report
Your RTL plus synthesized LUT/FF estimate and slack — free watermarked, clean after email. Use with Digilent Arty A7-35T + MicroMod carrier (SparkFun Originals).
File · verilog-module.v
verilog-module.vtext/x-verilog+ watermark line on free pathFree download adds a small footer:
# Export from makerportal.ai — free watermarked build. Unlock c…Clean export removes footer. Both are generated fresh from your current sim tuning.
Privacy: email stays in your browser localStorage (mp_export_email_verilog-live-sculptor) + unlock flag (mp_export_unlock_verilog-live-sculptor). If Buttondown username is configured, we also POST to Buttondown (privacy-first mode, no tracking pixels per D-014). See privacy → affiliates & email.
Unlock clean export
Soft gate — no hard paywall, no Clerk. Email stays local unless you explicitly check the newsletter box. Unsubscribe anytime. RSS at /rss.xml.
✓ Lab Pro — clean export on every lab
Your licence unlocks this and every other gated simulator, so there is nothing to enter here. Manage or sign out on the shop page.
✓ Unlocked — clean exports enabled
Stored in mp_export_unlock_verilog-live-sculptor. Clean file omits watermark. Re-lock via browser devtools → localStorage.
Fabricate this design
From sim → PCB
Export your live Verilog with LUT/slack header + notes for MicroMod carrier PCB. Order carrier on PCBWay Shared Project (10% PCB+SMT) or JLCPCB Brand Advocate path when live.
What you get
- Stackup CSV / Gerbers tuned in sim (W/H/εr, microstrip Z₀, array spacing → fab notes)
- PCBWay Shared Project if available — 10% PCB + 10% SMT revenue when others order same design
- Privacy-safe — no extra tracking beyond merchant checkout; disclosure in /privacy#affiliates
verilog-live-sculptorNo export yet — tune then exportOrder boards
Order on PCBWayReferral · 5%+↗PCBWay Shared Projects pay 10% PCB + 10% SMT — one fab conversion beats many Amazon electronics clicks.
Frequently asked questions
How does LUT counting work without synthesis?
We lex Verilog with regex: each `assign`, each operator chain, and each combinational `always @(*)` infers LUTs. An assign is 1 LUT + ceil(0.35*bitwiseOps) + ceil(0.5*unary-~) + ceil(0.55*addSubs); each case/ternary mux adds ~1; a comb always block is 2 LUTs. It is not Vivado, but correlates within ~30% for <200 LUT designs. DSP inference is any `*` not part of `**` and not the `@(*)` sensitivity star, BRAM is pattern `reg [A:0] mem [B:0]`.
How is timing estimated?
Critical path T_arr = T_cq + N_logic*(T_LUT+T_route) + N_DSP*T_DSP + N_BRAM*T_BRAM. T_LUT=0.35ns, T_route=0.12ns+ spread*0.45ns, T_DSP=1.15ns, T_cq=0.18ns. Logic levels N_logic = ceil(1.2*log2(LUTs)+0.15*assigns+0.25*muxes). Slack_setup = T_clk - T_setup - T_jitter - T_arr. T_setup=0.08ns. Hold slack = T_arr_min - T_hold, T_arr_min≈0.22*T_arr, T_hold=0.05ns.
Why do I hear a chord only when timing closes?
Audio uses 3 sine oscillators forming a just-intoned major triad (110Hz base: 220Hz, 275Hz, 330Hz ≈ 4:5:6). Master gain ramps to 0.12 only when slack_setup ≥0 and slack_hold ≥0. If slack <0, gain →0 and a 30Hz sub is pulsed for hold violations. This is intentional biofeedback: green ears = closed timing.
What maps to the floorplan canvas?
A 14×14 CLB grid (196 LUT slots). Placement order is heuristic: registers anchor to nearest clock spine column (center), LUTs spread by fanout estimate from textual dependency. DSPs appear as 2×2 orange tiles, BRAM as 1×3 purple bars. Color intensity = logic depth estimate. When you click Place & Route, we animate incremental lighting to mimic PnR iterations, adding routing congestion heat on high spread.
Can I paste my own SystemVerilog?
Yes. Parser ignores comments, handles `always_ff @(posedge)`, `always_comb`, `logic`, `module`. It does not elaborate generates. For big files >500 lines, we cap floorplan to first 196 LUTs and show utilization % >100 as overflow, which matches real FPGA overflow behavior.
Shareable still
The instrument, captured—not illustrated.
This 16:9 frame is rendered from the real browser instrument above. It is the page's canonical preview for image search, link unfurls, and posts that need to show what the tool actually does.
Download 1280 × 720 JPEG
Continue the experiment