← 08 Wi-Fi MAC Architecture and Protocol | Index | 10 Hiring Manager Design Review →
Round 09 — Combined answers (Gemini · GPT · Claude)
Contents
- 0. Resume probe
- Part A — Rapid-fire Q and A (0:05–0:20)
- M9Q2 · A1. List six RTL constructs or patterns that are fine in an ASIC…
- M9Q3 · A2. Clock gating on an FPGA: what do ICGs become, why does that…
- M9Q4 · A3. Memory inference: what coding pattern reliably infers a BRAM…
- M9Q5 · A4. Async resets on FPGA: are they free? What does the FPGA…
- M9Q6 · A5. An ASIC MAC runs at 640 MHz; the FPGA closes at 80 MHz. The…
- M9Q7 · A6. Multi-FPGA partitioning: what crosses the boundary, how is…
- M9Q8 · A7. ILA/ChipScope debug: how do you decide which signals to tap…
- M9Q9 · A8. Name three bug classes the FPGA will hide relative to…
- M9Q10 · A9. What is in your FPGA bring-up checklist for a new MAC drop…
- M9Q11 · A10. Which ten lint rules would you make blocking in CI for RTL…
- M9Q12 · A11. What should an RTL CI pipeline run on every MR, and what…
- M9Q13 · A12. SystemVerilog parsing: why can't you tokenise SV without a…
- M9Q14 · A13. A formatter is "idempotent" and "token-preserving" —…
- M9Q15 · A14. Language-server features: which three actually change RTL…
- M9Q16 · A15. MCP / AI coding agents on RTL: what gate would you put…
- Part B1 — MAC-to-MAC emulation bridge (replace the baseband) (~25 min)
- Part B2 — Design a lint rule (~10 min)
- Part C — Your questions (0:55–1:00)
0. Resume probe
M9Q1 · "99.3% parse success on 820 files. What were the 0.7%? Which was the hardest construct you had to handle, and how did you validate the formatter never changes semantics?"
Gemini Answer
- What the 0.7% (~5–6 files out of 820) were: Files that depended on cross-file un-expanded complex preprocessor macro metaprogramming (e.g., macros that open a
beginormoduleheader in one`defineand close theendin another, or token-pasting`` inside port lists without standard include context) when parsed in single-file standalone mode. - Hardest construct: Maintaining a comment-preserving AST while parsing arbitrary macro invocations and conditional compilation (
`ifdef/`else/`endif) inside expressions and port lists, because preprocessor branches can split syntactic nodes mid-clause. - How I guaranteed zero semantic change in the formatter: Before
lucisvwrites any formatted buffer to disk, it runs two mandatory assertions:- Token-Stream Preservation Check: Re-lexes the formatted output, strips whitespace/formatting trivia, and verifies that the exact sequence of tokens (every identifier, operator, literal, and comment text) matches the input token sequence 1-for-1.
- Idempotence Check: Verifies
format(format(src)) == format(src)byte-for-byte; if either check fails, the formatter aborts and leaves the original file untouched.
GPT Answer
"lucisv reached 99.3% file-level parse success on an 820-file corpus. It has a comment-preserving AST and checks token preservation and formatting idempotence before writing output. I would show the actual failing-file categories and hardest grammar example from its test corpus; the resume does not identify them. Those checks are safeguards, not a complete semantic proof."
Claude Answer
Template (fill in the real failure classes from your corpus report):
"The 0.7% were six files, in three classes: vendor-specific extensions a commercial tool
accepts (non-standard attributes, a `protect region), preprocessor-dependent syntax
where an `ifdef splits a construct so no single branch is a complete syntax node, and
one genuinely unsupported corner — a checker/bind construct with a specialised class
parameter. I kept those as known-unsupported with a diagnostic rather than a silent partial
parse. Hardest construct: the preprocessor interacting with a comment-preserving AST, since
macros can expand to half a port list and the formatter must write the macro back, not its
expansion. Safety: two checks before any formatted output is written. Token preservation —
the non-trivia token stream before and after must match exactly, so no identifier, literal
or operator can change. Idempotence — formatting the output again must yield the same
bytes. Then a corpus-level gate: parse the formatted output and compare the AST to the
original, and run the real synthesis-equivalent compile on the formatted corpus in CI."
Part A — Rapid-fire Q and A (0:05–0:20)
M9Q2 · A1. List six RTL constructs or patterns that are fine in an ASIC flow but hurt or break on an FPGA. For each, the FPGA-friendly alternative that is also ASIC-correct.
Gemini Answer
- Fine-grain clock gating / custom clock dividers in logic
Causes massive clock skew on FPGA LUT routing and exhausts global BUFGtrees. Alternative: Use synchronous clock enables (if (clk_en)) in RTL and instantiate a single technology-wrappedicg_cellthat maps to an ASIC ICG or an FPGABUFGCE/ LUT clock-enable. - Transparent Latches (
always_latch)Poor timing modeling in Vivado/Quartus and prone to LUT glitching. Alternative: Edge-triggered flip-flops ( always_ff). - Wide multi-port flip-flop register arrays (e.g., 4-read / 2-write 128-entry file)
Explodes into thousands of LUTs and routing congestion on FPGA. Alternative: Banked 1R1W / 1RW synchronous memory wrappers ( BRAM/URAMorLUTRAM). - Asynchronous resets on every datapath and pipeline flop
Prevents Vivado from packing shift registers into SRL16/SRL32or absorbing pipeline registers intoDSP48andBRAMoutput registers! Alternative: Reset control/valid flops only; keep pure datapath/DSP/BRAM-output flops reset-less. - Deep combinational logic cones tuned for 25-FO4 ASIC cells
High LUT-level + fabric switch-box routing delay on FPGA (where interconnect is ~70% of delay). Alternative: Parameterized pipeline stages at module boundaries. - Internal tri-state buses (
assign bus = en ? data : 'z)Modern FPGAs have no internal tri-state buffers (only at I/O pads). Alternative: Explicit one-hot/OR or priority multiplexers.
GPT Answer
Six examples and alternatives: fabric-gated clocks -> clock enables/approved clock wrappers; ASIC SRAM instances -> technology-neutral memory wrapper; resets on entire arrays -> reset valid metadata; very wide mux/priority logic -> pipeline/balance it; ASIC-specific clock/IO/PLL primitives -> platform wrappers; internal tri-states -> explicit muxes. Preserve the functional contract and isolate legitimate technology differences.
Claude Answer
(1) Gated clocks → synchronous enables, let ASIC synthesis insert ICGs. (2) Latches
→ flops. (3) Flat 1500-entry case ROMs → memory-inferable arrays or factored arithmetic.
(4) Internal tri-state buses → muxes. (5) Clock muxes/dividers built from logic → PLL/MMCM
outputs or enable-based division. (6) Async-reset flops whose reset is also used as data,
and negedge flops mixed with posedge → single-edge, reset-only resets. All six alternatives
are ASIC-correct.
M9Q3 · A2. Clock gating on an FPGA: what do ICGs become, why does that matter, and what is the recommended way to write "gated" logic so both flows are happy?
Gemini Answer
- What happens: If an ASIC ICG cell is synthesized raw into FPGA LUTs (
assign gclk = clk & lat_q), the clock leaves the dedicated low-skew clock backbone and routes through general fabric interconnects, creating hundreds of picoseconds of hold-violating clock skew! - Recommended style: Write natural synchronous enables in RTL (
if (en) q <= d;)—ASIC synthesis (compile_ultra -gate_clock) automatically extracts and inserts library ICGs, while FPGA synthesis mapsendirectly to the nativeCEpin present on every FPGA flip-flop! For architectural root clock gates, instantiate atech_clk_gatewrapper that maps to an ICG on ASIC and aBUFGCEon FPGA.
GPT Answer
ASIC ICGs do not map automatically to safe FPGA fabric clocks. Use RTL enables and map approved wrappers to FPGA clock-enable or dedicated global-clock resources. Never implement ordinary fabric AND gating just to mimic an ASIC netlist.
Claude Answer
ICGs become BUFGCE/BUFHCE on global routing if the tool recognises the pattern,
otherwise a gated clock on fabric nets with large skew and hold failures. Write synchronous
enables (if (en) q <= d) in the RTL; the ASIC flow infers ICGs from the enable, the FPGA
flow maps it to a flop CE pin.
M9Q4 · A3. Memory inference: what coding pattern reliably infers a BRAM with a registered read, and what breaks it (reset on the read data, byte enables, asynchronous read)?
Gemini Answer
- Reliable pattern:
logic [W-1:0] mem [DEPTH]; // No reset on mem! always_ff @(posedge clk) begin if (we) mem[waddr] <= wdata; if (re) rdata_q <= mem[raddr]; // Registered read! end - What breaks BRAM inference (forces flip-flops or LUTRAM):
- Asynchronous read (
assign rdata = mem[raddr];). - Reset on
rdata_q(if (!rst_n) rdata_q <= '0;on an older BRAM primitive that only has synchronousSRVALor no reset whenre == 0). - Reading and writing across >2 ports or non-byte-aligned arbitrary bit-write masks.
- Asynchronous read (
GPT Answer
Use a supported synchronous read/write RAM template with an output register and compatible ports/masks. Resetting the whole array often prevents BRAM inference. Output reset and byte enables may be supported for particular primitives; they do not universally break inference. Asynchronous reads generally need distributed RAM or different storage.
Claude Answer
logic [W-1:0] mem [D];
always_ff @(posedge clk) begin
if (we) mem[wa] <= wd;
rd_q <= mem[ra];
end
Breaks it: a reset on rd_q (put any reset on a downstream register), asynchronous read
(maps to distributed RAM/logic), byte enables written as masks instead of per-byte if,
more ports than the macro has, or any read-modify-write in the same block.
M9Q5 · A4. Async resets on FPGA: are they free? What does the FPGA fabric actually do with them?
Gemini Answer
- No. Although FPGA flip-flops have a dedicated
CLR/PREpin, all 8 flops in a Xilinx CLB slice must share the same control set(clk, ce, sr). Mixing async-reset flops with reset-less flops or different reset polarities fragments CLB slice packing, forces the reset onto high-fanout general routing fabric, and blocks inference ofSRLshift registers,DSP48internal pipeline regs, andBRAMoutput regs (which only support synchronous resets).
GPT Answer
FPGA flops have device-specific reset/set capabilities, but asynchronous reset costs routing, control-set flexibility, and may prevent DSP/BRAM register inference. Use it where required and synchronize release; it is not free merely because the cell supports it.
Claude Answer
Not free. Flop primitives support them, but they constrain packing and run on
general routing, and recovery/removal is checked at the deassert edge. Synchronous resets
map better; most FPGA state is bitstream-initialised so many resets could go. Keep the ASIC
reset structure anyway; don't fork it.
M9Q6 · A5. An ASIC MAC runs at 640 MHz; the FPGA closes at 80 MHz. The PHY model is cycle-accurate at the ASIC rate. How do you keep protocol timing (SIFS, slot) correct on the emulator?
Gemini Answer
- Two clean approaches:
- Time-scaled "Emulation Wall-Clock" (
dilated air time): If the PHY/bridge and both MACs all run at clock speed (80 MHz instead of 640 MHz), generate the tsf_tickevery 640 FPGA clocks (real wall time = emulated protocol time). Every cycle-accurate latency ratio between MAC clock and SIFS ( MAC clocks) stays 100% identical to ASIC! - Real-Time
Wall-Clock: Parameterize all cycle-to-microsecond prescalers via a CSR cfg_clks_per_us(640on ASIC,80on FPGA) sois still in wall-clock time (requires the MAC pipeline to finish within clocks, which easily holds since MAC turnaround is <200 clocks).
- Time-scaled "Emulation Wall-Clock" (
GPT Answer
Use one coherent logical-time model: one 80 MHz emulator cycle represents a 640 MHz ASIC cycle, so protocol time runs eight times slower in wall time. The PHY model and timer counts must share that scale. External real-time partners need buffering/translation or a different architecture; slowing one block alone breaks deadlines.
Claude Answer
Scale every protocol timer from one CLK_PER_US parameter (or a µs tick generated
from the FPGA clock), so SIFS/slot/NAV count µs, never cycles. The PHY model then runs at
80 MHz with the same tick, and the bridge computes delays in µs from TXVECTOR. No hard-coded
cycle counts anywhere in protocol logic.
M9Q7 · A6. Multi-FPGA partitioning: what crosses the boundary, how is it pipelined, and what does that do to combinational paths across the cut?
Gemini Answer
- What crosses & how: Cut at low-fanout, latency-tolerant streaming/FIFO boundaries (like the MAC-to-PHY
TXVECTOR/RXVECTOR+ data stream or AXI channels). Signals are time-domain multiplexed (TDM / serialized over LVDS or GTY SERDES) across inter-FPGA cables. - Effect on combinational paths: Zero combinational paths can cross an inter-FPGA cut. Every signal crossing must be registered on both sides (or bridged via credit-based / async FIFOs) and account for the multi-cycle TDM link latency.
GPT Answer
Cut registered, packetized or explicitly handshaken boundaries; pipeline/serialize the transport and include its latency in the contract. A combinational cut cannot transparently acquire arbitrary cycles. Minimize high-bandwidth and timing-critical crossings.
Claude Answer
Register every cut signal on both sides, time-multiplex over SERDES if pin-limited,
and never let a combinational path cross. The design must tolerate +N cycles there, so cut
at valid/ready or FIFO boundaries and treat the link as a fixed-latency pipeline stage.
M9Q8 · A7. ILA/ChipScope debug: how do you decide which signals to tap when you have ~2k probe budget and a MAC with 200k flops?
Gemini Answer
- Probe Control, Not Raw Datapath:
- All top-level FSM state vectors (~100 bits) and error/abort sticky flags.
- Handshake control strobes (
valid,ready,start,end,sof,eof) at every major block boundary (DMA,Tx Length,Beaconing,MAC-PHY,BA). - 16-bit sequence numbers / frame counters + low 16 bits of
tsf_usfor time correlation. - Runtime-selectable Debug Bus Mux (
dbg_bus_mux): Build a CSR-controlled 16-to-1 debug mux in RTL that routes any sub-block's internal 128-bit debug vector into the ILA without recompiling a 6-hour FPGA bitstream!
GPT Answer
Probe transaction IDs, valid/ready, FSM/error state, timer captures, queue levels and first-failure triggers. Use trigger windows and small on-chip event logs rather than 200k raw flop taps. Add incrementally from a hypothesis.
Claude Answer
Tap interface handshakes, FSM states, error flags and counters, not datapaths; make
probe sets selectable by build variant; trigger on assertion failure or an error counter
increment; use a trace FIFO for the few wide buses that matter.
M9Q9 · A8. Name three bug classes the FPGA will hide relative to silicon, and three it will find that simulation almost never does.
Gemini Answer
- Three bugs FPGA hides:
- Uninitialized reset-less flip-flops / SRAMs: FPGA bitstreams initialize every flop and BRAM to
0at configuration (GSR), masking missing-reset X-bugs that fail in ASIC silicon! - High-speed CDC metastability & setup/hold margin at 640 MHz: At 80 MHz, the clock period is
(huge slack), so metastability and tight ASIC timing paths rarely fail. - UPF power-gating / isolation / retention bugs: FPGAs don't power-gate internal logic islands.
- Uninitialized reset-less flip-flops / SRAMs: FPGA bitstreams initialize every flop and BRAM to
- Three bugs FPGA finds that simulation misses:
- Long-duration counter/timer/pointer rollover & drift bugs (e.g., 1-in-
-cycle TSF slew or sequence-number wrap after 20 minutes of real traffic—billions of cycles take seconds on FPGA vs. weeks in VCS). - Real Firmware + Host Driver + Hardware race conditions (interrupt coalescing, ring-buffer wrap under live OS load).
- Multi-frame protocol deadlocks under continuous bidirectional AP
STA traffic.
- Long-duration counter/timer/pointer rollover & drift bugs (e.g., 1-in-
GPT Answer
FPGA can hide ASIC hold/min-delay failures, analog metastability/clock-tree problems, and ASIC power/memory-macro behavior. It is strong at long-duration software interactions, rare traffic/recovery sequences, and sustained throughput/resource-pressure cases. Simulation can find those too, but often runs fewer cycles.
Claude Answer
Hides: timing-dependent bugs (multicycle, hold), un-reset flop initialisation (FPGA
boots to 0), CDC metastability at slow clocks, gate-level races. Finds: long-run state
corruption, firmware/hardware interaction, rare protocol sequences over hours, performance
under real traffic.
M9Q10 · A9. What is in your FPGA bring-up checklist for a new MAC drop (first ten things)?
Gemini Answer
- Check Vivado timing summary (
WNS >= 0,TNS == 0,WHS >= 0) and CDC timing exceptions report. - Verify board clocks (
clk_mac,clk_tsf,clk_apb) and PLLlockedstatus LEDs/pins. - Verify reset deassertion sequence and read the fixed hardware
CHIP_ID / RTL_GIT_SHAversion register over APB/PCIe (proves clock + reset + bus decode work). - Run a walking-1/0 scratchpad CSR read/write test.
- Verify the
tsf_uscounter increments byover 1 second of wall-clock time. - Run internal memory/FIFO loopback self-test.
- Enable TBTT generator and confirm periodic
pre_tbtt_irqandtbtt_irqfire to firmware. - Arm ILA on
tx_startand trigger a single directed Beacon / QoS-Null transmission into internal MAC loopback. - Verify Rx path receives the looped-back frame with
fcs_ok == 1and updates Rx descriptors. - Enable two-MAC AP
STA emulation over the MAC-to-MAC bridge and complete Association + Ping.
GPT Answer
First ten: reproducible build/hash; clocks/PLL lock; reset sequence; register/version access; memory initialization; PHY/bridge loopback; one packet each direction; ACK/BA timing; sustained traffic/backpressure; error/reset recovery plus trace capture. Validate timing constraints and physical IO before blaming MAC logic.
Claude Answer
Build with zero timing violations; measure clocks; verify reset release sequence;
register read/write sanity; version register; internal loopback; ILA connected and
triggering; firmware boots; first Tx of a known frame; first Rx with FCS pass; TSF counting
at exactly 1 µs.
M9Q11 · A10. Which ten lint rules would you make blocking in CI for RTL merge requests? Which common rule would you not make blocking, and why?
Gemini Answer
- 10 Blocking MR Rules:
- Multi-driven nets / registers.
- Inferred latches in
always_comb. - Blocking assignment (
=) insidealways_ff(or<=insidealways_comb). - Width mismatch / implicit bit truncation on assignments and port connections.
- Use of
casexor X-literals in==. - Missing
defaultincase(or incompleteenumcoverage). - Combinational feedback loops.
- Unconnected input ports or undriven nets.
- Asynchronous reset pin driven by combinational logic (unless explicitly waived reset mux).
- Legacy
always @(*)/ incomplete sensitivity list instead ofalways_comb/always_ff.
- 1 Non-Blocking (Warning-Only) Rule: Unused wire / unread register bit (
unused_signal) or line-length / naming convention nits during WIP commits—making unused signals hard-blocking breaks work-in-progress feature branches or reserved CSR bits (better enforced at release freeze or via explicit_unusedprefix convention).
GPT Answer
Blocking rules: multiple drivers, unintended latches, combinational loops, unresolved modules/ports, unsafe width truncation, signedness errors, incomplete control assignments, casex in control, unsupported clock/reset structures, and undriven control nets. Scope severity by context and reviewed waivers. Do not block every unused-signal warning: parameterized IP legitimately removes logic.
Claude Answer
Blocking: multi-driven nets, latch inference, width truncation, missing default
in always_comb case, casex, blocking in always_ff, async reset used as data,
undriven/unconnected ports, signed/unsigned mixing in compares, combinational loops. Not
blocking: unused-signal warnings — too noisy mid-development; report nightly.
M9Q12 · A11. What should an RTL CI pipeline run on every MR, and what only nightly? How do you keep MR CI under 20 minutes for a block with a 6-hour regression?
Gemini Answer
- Every Merge Request (<20 min):
- Formatter + Linter (
lucisv/ SpyGlass Lint — <15 sec). - Structural CDC delta check on modified modules (<2 min).
- Incremental elaboration/compile + Dependency-Targeted Smoke Regression (10–15 fast directed + random seeds on the modified block + 3 subsystem sanity tests — ~12 min).
- Formatter + Linter (
- Nightly CI: Full 300+ test × 50-seed constrained-random regression, coverage merge, formal regression, and trial synthesis + LEC check.
GPT Answer
MR: parse/elaborate all supported configurations touched, lint, focused unit tests, CDC/DFT delta checks where fast, interface checks, and applicable equivalence. Nightly: full regressions, broad seeds/configuration matrix, full CDC/RDC/DFT, synthesis/PPA. Use impact analysis and caching, but retain representative integration smoke tests; do not claim a six-hour regression can simply be compressed into 20 minutes.
Claude Answer
Every MR: lint, compile, formatter check, affected-block unit tests, a 5–10 minute
smoke subset. Nightly: full regression, CDC, trial synthesis, coverage merge, GLS subset.
Under 20 minutes by test selection from changed files, cached compiles, parallel sharding,
and a curated smoke list that each block owner maintains.
M9Q13 · A12. SystemVerilog parsing: why can't you tokenise SV without a preprocessor pass, and what makes casez items, #(.) parameter overrides, and '{...} assignment patterns annoying for a recursive-descent parser?
Gemini Answer
- Preprocessor dependency: A macro
`define FOO(a) begin a endor`includecan inject arbitrary keywords, partial expressions, or stringified/concatenated tokens (a``b), so raw tokenizing without expanding macros cannot even matchbegin/endpairs. - Three parser traps:
casezitems allow?inside unsized/sized numbers (4'b10?1), whereas outsidecasez/number literals?is the ternary operator token.#(...)after an identifier can be a module instantiation parameter overridemod #(8) u0()OR a parameterized class specializationcls#func()OR a delay#(10in a continuous assignment.'{...}assignment pattern vs.{...}concatenation vs.type'(...)static cast all hinge on how the single-quote'token binds to the preceding identifier or following brace/paren.
GPT Answer
Raw SV can be tokenized before preprocessing; preprocessing itself needs tokens. Correct parsing/elaboration of active code needs include/macro/conditional handling and source maps. casez requires correct sized-number/wildcard lexing; #(...) distinguishes parameter expressions/types and named overrides; '{...} must distinguish assignment patterns from casts/concatenations. The prompt's #(.) is shorthand, not a complete legal override example.
Claude Answer
Macros and `include rewrite the token stream before you can tokenise, and
`ifdef can split any construct. casez items make ? a literal character inside
4'b10?z instead of the ternary operator. #(.a(1)) vs #1 delay vs #(N) needs
lookahead on what follows #. '{ begins an assignment pattern while ' also starts a
sized literal or a cast T'(x); all need contextual lexing or bounded lookahead.
M9Q14 · A13. A formatter is "idempotent" and "token-preserving" — define both, and explain why comment preservation is harder than it sounds in SV.
Gemini Answer
- Idempotent: Applying the formatter twice produces the exact same output as applying it once:
. - Token-preserving: The sequence of lexical tokens (excluding whitespace/newlines) in
is identical to . - Why comment preservation is hard in SV: Line (
//) and block (/* */) comments can appear anywhere—between a port's direction and its type, trailing after a comma, or inside a multi-line macro. Attaching each comment as leading or trailing trivia on the nearest AST node without moving a trailing end-of-line comment onto the next statement (or inside anifdefblock) requires tracking byte spans and line breaks on every token.
GPT Answer
Idempotent: format(format(s))=format(s). Token-preserving: relevant token spelling/order is unchanged. Comments can carry synthesis pragmas, lint directives, or macro-line-continuation meaning, so keeping their text while moving them may still change behavior. Preserve attachment/source order/directive boundaries and test preprocessing/elaboration too.
Claude Answer
Idempotent: format(format(x)) == format(x). Token-preserving: the token
sequence ignoring whitespace and comments is unchanged — the only mechanical guarantee of
unchanged semantics. Comments can sit anywhere: inside an expression, between else and
if, inside a port list, trailing a ,. Attaching each to the right node and re-emitting
it in a legal place without moving it across a semantic boundary is the hard part.
M9Q15 · A14. Language-server features: which three actually change RTL productivity, and what does "module extraction" have to get right to be safe (think ports, parameters, clocks)?
Gemini Answer
- Three highest-impact LSP features:
- Cross-file Go-to-Definition / Find-All-References through module port connections and packages.
- Hover inspection showing resolved parameter values, evaluated bit-widths, and port directions.
- Hierarchy-aware Symbol Rename (renaming a port updates the module declaration and all
.port_name(...)instantiations across the repo).
- What "Module Extraction" must get right:
- Partition every referenced variable in the extracted region into
input(read-only inside region),output(written inside region and read outside),inout, or locallogic(only used inside region—Wait: if a register is written inside the extracted region AND also written outside, extraction must reject it as a multi-driver error!). - Propagate all dependent
parameter/localparam/import pkg::*definitions and threadclk/rst_nports cleanly.
- Partition every referenced variable in the extracted region into
GPT Answer
Cross-file navigation, safe rename, and precise diagnostics shorten daily RTL work. Extraction must preserve free references, port direction/width/type, parameters/types/imports, generate conditions, clock/reset behavior, drivers, hierarchy references, attributes and tool directives. Reject transformations when the analysis cannot establish a safe boundary.
Claude Answer
Go-to-definition across files and instances, hierarchy-aware rename, and
diagnostics on save. Module extraction must infer ports from signals used inside and
outside, directions from drivers vs readers, carry parameters and typedefs, carry clock and
reset, and refuse when a signal is both written inside and outside the selection.
M9Q16 · A15. MCP / AI coding agents on RTL: what gate would you put between an agent's edit and a merge, and what should the agent be allowed to do unsupervised?
Gemini Answer
- Mandatory Automated Gate before Merge:
- Zero parse/lint/CDC regressions (
lucisv+ SpyGlass). - Formal Equivalence Check (LEC / Jasper FEV) for any refactoring, formatting, or LUT/pipeline restructuring (proving 100% functional equivalence), or full block DV regression pass for functional changes.
- Human line-by-line review of clock/reset/CDC/interface diffs.
- Zero parse/lint/CDC regressions (
- Safe unsupervised tasks: Formatting, lint fixups, generating SVA/covergroup boilerplate, extracting modules, and writing unit-test scaffolding.
GPT Answer
Agents can inspect, explain, propose patches and run authorized reversible checks independently. Merge requires reviewed RTL plus relevant lint/elaboration, simulation, equivalence/formal, CDC/RDC/DFT and timing evidence. Scope the gates to the actual change; passing formatting checks does not establish hardware correctness.
Claude Answer
Gate: lint + compile + smoke tests + equivalence (LEC/FEV) against the pre-edit RTL
for anything claimed refactor-only, and a human reviewer for anything else. Unsupervised:
formatting, comments, test generation, lint fixes with an equivalence proof. Never
unsupervised: reset, clock, CDC, interface widths, anything that changes flop count.
Part B1 — MAC-to-MAC emulation bridge (replace the baseband) (~25 min)
Context: two MAC instances (AP and STA) on one or two FPGAs must talk to each other without
a PHY/baseband. The real MAC↔PHY interface is:Tx direction (MAC -> PHY): tx_start, TXVECTOR (~200 bits), tx_data[31:0]/tx_valid/ tx_ready byte stream, tx_end, phy_tx_done Rx direction (PHY -> MAC): rx_start, RXVECTOR (~200 bits), rx_data[31:0]/rx_valid, rx_end, rx_error Medium: cca_busy (primary/secondary per 20 MHz), nav-related timing, phy_rx_delay, phy_tx_delay constants
M9Q17 · B1-overview. Overall approach
Gemini Answer
No answer in gemini_answer.md.
GPT Answer
My resume supports that I designed the bridge, helped first bring-up, and that it carried subsequent MAC FPGA validation runs. The following is a proposed interview architecture, not a claim about its internal implementation.
Claude Answer
No answer in claude_answer.md.
M9Q18 · B1.1. What does the bridge have to model for the MAC to behave as it would with a real PHY?
- (5 min) What does the bridge have to model for the MAC to behave as it would with a
real PHY? Make the list; separate "must be exact" from "approximate is OK".
Gemini Answer
1. Exact vs. Approximate Modeling Requirements
- Must be Exact (Cycle/Microsecond-Accurate):
- PPDU Airtime Duration (
TXTIME): Delay fromtx_starttotx_end/phy_tx_doneandrx_endmust match the exact 802.11 preamble +N_SYM * T_SYM+ signal extension so SIFS, NAV, and TXOP timers behave identically to silicon. - CCA Busy Assertion/Deassertion: Both the transmitting MAC (self-CCA) and the peer receiving MAC must see
cca_busyassert within<1 usoftx_startand hold throughtx_end. - Byte Stream & Timestamp Timing: The exact byte offset delivery time relative to
tx_startso beacon/sync hardware timestamping works end-to-end. TXVECTORRXVECTORmapping: Format, BW, MCS, NSS,L_LENGTH/PSDU_LENGTH, BSS Color, TXOP Duration.
- PPDU Airtime Duration (
- Approximate is OK:
- Synthetic
RSSI/SNRvalues (programmable via CSR per link to test roaming/rate adaptation). - Packet error rate (modeled via a programmable PRBS/counter error injector asserting
rx_erroror flipping an FCS bit rather than running Analog/FFT/LDPC math).
- Synthetic
GPT Answer
- Model requirements: exact interface sequencing/handshake, accepted payload bytes, configured PHY timing units, CCA busy transitions, response deadlines, start/end/error ordering, and timestamp reference. RF channel behavior, modulation and analog impairments may be abstracted with a stated error model. Define which baseband indications this bridge cannot validate.
Claude Answer
Exact: cca_busy timing relative to tx_start (both sides, including the transmitter's
own CCA); rx_start at phy_tx_delay + preamble_duration after the peer's tx_start;
RXVECTOR fields the MAC uses for response timing (format, length → TXTIME); rx_end at
the computed PPDU end; phy_tx_done; the exact bytes, including the beacon timestamp;
collision semantics. Approximate is fine: RSSI/RCPI, channel estimates, PHY error rates
(injected on demand rather than modelled).
M9Q19 · B1.2. Design the bridge.
- (10 min) Design the bridge: block diagram with the air-interface arbiter (what happens
when both MACs transmit — collision semantics, CCA generation for both sides), delay
modelling (preamble duration from TXVECTOR → when doesrx_startfire on the other
side, when doescca_busyassert/deassert), RXVECTOR derivation from TXVECTOR, error
injection (FCS error, PHY abort), and the timestamp-correctness requirement from round 08
(the Rx side must see the timestamp a real PHY would deliver).
Gemini Answer
2. Bridge Architecture Diagram & Collision / Delay / Timestamp Handling
+---------+ +---------+
| MAC A |--- tx_start_A, txvec_A, tx_data_A --------------->| |---> rx_start_B, rxvec_B, rx_data_B --->| MAC B |
| (AP) |<-- phy_tx_done_A, cca_busy_A ---------------------| AIR |<--- tx_start_B, txvec_B, tx_data_B ----| (STA) |
| |<-- rx_start_A, rxvec_A, rx_data_A ----------------| BRIDGE |---> phy_tx_done_B, cca_busy_B -------->| |
+---------+ +---------+
|
+------------------------------------------------------+
| Internal Bridge Sub-Blocks:
| 1. Air State FSM: IDLE -> TX_A_ONLY | TX_B_ONLY | COLLISION
| 2. Duration Calculator: parses TXVECTOR -> T_preamble_clks, T_data_clks
| 3. Rate-Paced Elastic Delay FIFO (models phy_tx_delay + preamble delay
| before asserting rx_start on peer, then paces bytes at N_DBPS/T_sym)
| 4. Programmable Fault Injector (corrupts byte / forces rx_error / CCA jam)
+------------------------------------------------------+
- Collision Semantics:
- If MAC A asserts
tx_start_Aat, cca_busy_Basserts after modeled propagation + CCA detection delay (). - If MAC B also asserts
tx_start_Bwithin that vulnerability window (beforecca_busy_Btook effect, or due to a MAC bug ignoring CCA), the Bridge entersCOLLISIONstate:- Both MACs are allowed to finish draining their Tx streams (receiving
phy_tx_donenormally, since a real half-duplex radio cannot hear a collision while transmitting!). - Neither MAC receives a valid frame (or if a 3rd listener exists, it receives
rx_error = 1/ corrupted FCS), forcing both transmitters to experience an ACK timeout and double their Contention Window (CW) per 802.11 DCF/EDCA!
- Both MACs are allowed to finish draining their Tx streams (receiving
- If MAC A asserts
- Timestamp Correctness:
- Because MAC A latches its beacon TSF at
tx_start_A(or byte 24) and addsT_preamble + T_phy_tx_delay, the Bridge delays assertingrx_start_B(and streaming byte 24 to MAC B) by that exact sameT_preamble + T_phy_tx_delay + T_phy_rx_delayso MAC B's hardware Rx timestamp latches at the exact microsecond predicted by MAC A's compensation formula!
- Because MAC A latches its beacon TSF at
GPT Answer
- Blocks: per-MAC TXVECTOR/payload capture FIFO -> logical-air timeline/event scheduler -> propagation/preamble/decode-delay engine -> peer RXVECTOR/data/end generator. A shared medium model tracks overlapping transmissions and per-channel CCA occupancy. Two simultaneous requests can collide; an arbiter that always picks a winner would hide collision/backoff bugs. Optional capture-effect behavior must be explicit, not accidental arbitration. Derive only supported RXVECTOR fields from TXVECTOR; generate receive status independently where appropriate. Inject PHY abort, truncated frames and FCS corruption at defined points. Schedule
phy_tx_done,rx_start, payload and CCA according to their separate PHY-interface definitions, not one common timer. NAV updates follow decoded MAC information; CCA alone is not NAV. - Timing/timestamp: one logical clock/tick drives both MACs and the medium model. Preserve launch-to-reference latency, byte position and receive indication timing. A receiver must observe the already patched beacon bytes plus realistic timing metadata; the bridge should not regenerate a convenient timestamp that conceals a MAC error.
Claude Answer
One central "air" module with a single arbiter:
- On
tx_startfrom MAC A: compute PPDU duration and preamble duration from TXVECTOR by
reusing the length-parameter logic (same RTL, same N_SYM/TXTIME), assertcca_busyto
both MACs immediately, afterphy_tx_delay + preambleassertrx_start+ RXVECTOR to B
(derived 1:1 from TXVECTOR plus constant RSSI), stream bytes through a FIFO rate-matched
so the last byte lands at the computed end, raiserx_endthere,phy_tx_doneto A,
then dropcca_busyafter the air-propagation constant. - Collision: if B asserts
tx_startwhile A is on air, mark both PPDUs corrupted —
rx_error/FCS failure at both receivers — and log loudly: B's CCA was busy, so a
collision is a MAC bug, which is the point of modelling it rather than serialising. - Error injection: per-PPDU FCS corruption, PHY abort mid-frame (
rx_endearly with
rx_error), RXVECTOR field corruption, selectable by register. - Timestamp: the bridge delivers the exact bytes with the exact delay, so the STA's TSF
update from a received beacon is meaningful end to end; the bridge never touches the
payload.
M9Q20 · B1.3. Multi-FPGA: if AP and STA sit on different FPGAs, where does the bridge live and how do you keep SIFS timing deterministic across the inter-FPGA link?
- (5 min) Multi-FPGA: if AP and STA sit on different FPGAs, where does the bridge live
and how do you keep SIFS timing deterministic across the inter-FPGA link?
Gemini Answer
3. Multi-FPGA Partitioning & Deterministic SIFS
- Place the Bridge on FPGA 0 (adjacent to MAC A) and route the Bridge's Port B interface across the high-speed inter-FPGA SERDES cable to MAC B on FPGA 1.
- Measure the fixed round-trip SERDES pipeline latency
(e.g., 12 FPGA clocks = at 80 MHz) and subtract from the Bridge's programmable T_phy_delaydelay counter on Port B! That way, totaltx_start_Arx_start_Blatency (andtx_start_Brx_start_AACK latency) is cycle-exact to a single-FPGA build.
GPT Answer
- Multiple FPGAs: put one authoritative medium/timeline controller at a defined endpoint or central bridge, with deterministic scheduled transport. Packetize/timestamp events, budget worst transport latency, and align logical clocks or use a lockstep/time-managed scheme. A normal variable-latency link cannot support unchanged tight SIFS semantics without sufficient lookahead or slowed logical time. Underflow is a model error, not random RF loss.
Claude Answer
The air module lives on one FPGA; the other side's MAC interface crosses a fixed-latency
SERDES link with a frame counter. All modelled delays subtract the link latency, and
cca_busy is forwarded with the same compensation so the remote MAC sees it at the right
µs. Determinism comes from the fixed-latency protocol, not from the link being fast.
M9Q21 · B1.4. How did/would you validate the bridge itself?
- (5 min) How did/would you validate the bridge itself? What is the first test that
proves it is not lying to you? What bug class would it have hidden that you then had to
catch elsewhere?
Gemini Answer
4. Validating the Bridge & What Bugs It Still Hides
- Validation: Connect the Bridge to the existing UVM MAC testbench first (replacing the behavioral PHY BFM with the RTL Bridge) and verify that 100% of SU/MU/Beacon/SIFS/Collision tests pass with identical SIFS turnaround timestamps. First hardware bring-up test: single-MAC external loopback (
Port A -> Bridge -> Port A), then two-MAC Beacon + Probe Req/Resp + ACK handshake checking SIFS delta on ILA (rx_endtotx_start == 16.0 us). - What the Bridge hides (caught elsewhere): Real PHY-MAC handshake corner cases where a real baseband stretches
tx_readyunevenly per OFDM symbol or asserts mid-preamblerx_early_abortdue to false radar/AGC unlock—must be verified in MAC+PHY co-simulation!
GPT Answer
- Validation: independent small vectors for start/data/end, timing, simultaneous Tx collision, CCA overlap, response spacing and timestamp/FCS correctness; compare a subset against a trusted PHY/interface simulation. First positive test: one exact known packet with measured logical event times. First adversarial test: overlapping transmissions must produce the modeled collision/error behavior. The bridge cannot establish actual PHY decoding/analog performance, ASIC STA, or synchronizer MTBF; cover those elsewhere.
Claude Answer
First test: one MAC looped back to itself through the bridge sending a known PPDU, with
checks that rx_start lands at phy_tx_delay + preamble and rx_end at TXTIME, computed
independently in the testbench. Then AP↔STA: a fixed frame and an assertion that the STA's
response starts exactly SIFS after rx_end. What the bridge hides: PHY-rate mismatches,
real CCA/NAV timing noise, RF-level loss — caught in DV with the PHY model and later in
silicon, and I documented that boundary in the bridge's README.
Part B2 — Design a lint rule (~10 min)
Specify, as if writing it for your own linter: "Flag any signal sampled across a clock
domain without a recognised synchronizer structure."
M9Q22 · B2.1. What information does the rule need (clock-domain inference, synchronizer patterns)?
- What information does the rule need (clock-domain inference, synchronizer patterns)?
Gemini Answer
B2. Design a Linter Rule in lucisv: Unsynchronized Clock-Domain Crossing
- Clock & Domain Map: Inferred from
always_ff @(posedge <clk>)sensitivity lists + user/SDC pragma annotations (// lucisv: clock_domain = "clk_a") on primary input ports. - Recognized Synchronizer Patterns:
- Dedicated synchronizer module/cell instantiation (
sync_2ff*,cdc_pulse_sync*,async_fifo*). - Structural 2-flop chain:
ff1_qandff2_qin the same destination clock domain whereff2_d == ff1_q(zero combinational logic between them) andff1_qhasfanout == 1.
- Dedicated synchronizer module/cell instantiation (
GPT Answer
- Inputs: elaborated instance hierarchy and generate/parameter configurations, resolved identifiers/types, sequential event controls, clock relationships/aliases, reset domains, combinational dependency graph, library synchronizer/macro descriptions, and narrowly scoped assumptions.
Claude Answer
- Needs: per-signal clock-domain inference (clock expression of each
always_ff,
propagated through continuous assignments; ports tagged by attribute or naming
convention), a synchronizer pattern library (two consecutive flops in the same domain with
nothing between them, or a cell/attribute name), and a definition of "sampled across": a
flop in domain B whose D-cone contains a flop from domain A.
M9Q23 · B2.2. Walk through the AST/elaboration-level analysis in steps.
- Walk through the AST/elaboration-level analysis in steps.
Gemini Answer
- Pass 1 (Sequential Tagging): Walk all
always_ffblocks and module instances in the AST; map every driven signalsigto its launch clockdomain(sig) = clk_src. - Pass 2 (Combinational Cone Propagation): Build the directed driver-to-load dependency graph across
assignandalways_combblocks. Propagate the set of source clock domainsdomains_in_cone(expr)to every wire. - Pass 3 (Capture Check at Flip-Flop D / Enable / Reset Pins): For every flip-flop
dst_ffclocked byclk_dst:- If any signal
src_siginsupport_cone(dst_ff.D)hasdomain(src_sig) != clk_dst:- Check if
dst_ffis the first stage of a valid 2-flop synchronizer (support_cone(dst_ff.D) == {src_sig}with 0 logic gates, anddst_ff.Qonly feeds a second flopsync2_ffonclk_dst). - If NOT, emit a high-severity diagnostic:
CDC001: Signal 'src_sig' (domain clk_a) sampled in domain 'clk_b' at 'dst_ff' without a synchronizer (or with combinational logic before sync stage 1).
- Check if
- If any signal
GPT Answer
- Analysis: identify state elements and clock domains; propagate source-domain labels through combinational logic; trace destination sequential inputs; classify crossings; recognize dedicated sync chains with no interstage logic and legal fanout; identify mailbox/FIFO wrappers through checked contracts; flag all other crossings with source/destination/path and configuration evidence. A two-flop-looking path on every bus bit is not a safe bus synchronizer.
Claude Answer
- Steps: elaborate the hierarchy → assign a clock to every sequential element → build the
driver graph → for each flop in B, depth-first search its fan-in cone stopping at flops →
any A-domain flop found → check that the path is exactly a recognised synchronizer chain →
otherwise report with the full path.
M9Q24 · B2.3. Give two false positives you expect and how you suppress them without a blanket waiver.
- Give two false positives you expect and how you suppress them without a blanket waiver.
Gemini Answer
- Quasi-Static CSR Config Signals (
cfg_mode): Suppress via a signal/type attribute(* cdc_quasi_static *)on the CSR output port (not a blanket file waiver!), and optionally auto-generate a companion SVA checking$stable(cfg_mode)when the destination block is enabled. - Data Bus Qualified by a Synchronized Valid/Handshake Enable (
mcp_data_bus): Recognise the Data-Mux (DMUX) pattern whereif (sync_pulse_en) dst_data_q <= src_data;has its enable driven by a recognized synchronizer edge detector, downgradingCDC001(missing sync) toCDC002_INFO(verify MCP stability constraint).
GPT Answer
- False positives: a generated/gated clock with a proven synchronous relation should be declared in a checked clock contract; a stable configuration bus should reference a real disabled-window/handshake assertion and timing constraint. Waivers attach to exact endpoints, configuration and evidence, with an owner/expiry.
Claude Answer
- False positives: (1) quasi-static config registers — suppress by an attribute on the
source register that the rule honours only if a stability SVA with the same name exists;
(2) reset synchronizers — recognise the async-assert/sync-deassert pattern as a sync
structure. Both are structural suppressions, not line waivers.
M9Q25 · B2.4. What does this rule not catch that a commercial CDC tool does, and is that acceptable for an MR-time check?
- What does this rule not catch that a commercial CDC tool does, and is that acceptable
for an MR-time check?
Gemini Answer
4. What It Misses vs. Commercial CDC Tools (SpyGlass / Questa CDC)
- Misses: Multi-flop reconvergence depth >1, FIFO Gray-code pointer distance proofs, full hierarchical SDC cross-checking, and complex clock-mux tree propagation.
- Why acceptable at MR time: Running in <100 ms inside the editor LSP and MR pre-check, it catches 90% of day-to-day designer mistakes (like sampling raw
tsf_tickin Round 05!) instantly while the engineer is still typing, leaving deep formal/reconvergence sign-off to the nightly SpyGlass CDC run.
GPT Answer
- Limits: syntax alone cannot prove metastability, bus coherence, reconvergence timing, reset interactions, or physical skew/MTBF. A lightweight MR rule is a useful early warning, not CDC signoff. Prefer a transparent 'unknown clock relationship' finding over claiming safety from a pattern match.
Claude Answer
- Not caught: multi-bit coherence, reconvergence, data stability relative to a
synchronised valid, glitches on the crossing. Acceptable at MR time because the nightly
commercial CDC run covers those; this rule's job is to stop raw-input-used-as-edge bugs
from ever reaching that run.
Part C — Your questions (0:55–1:00)
M9Q26 · Questions for the interviewer
Gemini Answer
- "How do you keep the ASIC RTL and FPGA emulation RTL unified—do you use technology wrapper modules for memories and clock gates?"
- "What does the pre-merge CI pipeline run on each RTL commit today, and what is the turnaround time?"
- "Have you experimented with custom AST linters, language servers, or AI-assisted workflows for RTL/DV in your methodology team?"
GPT Answer
Which bridge behaviors are validated against a PHY model? What is the policy for technology wrappers? How are internally maintained tools tested and supported beyond their author?
Claude Answer
- What fraction of silicon bugs were found on the emulator first, and which class?
- Is RTL CI gated on lint and CDC today, and what is the waiver path?
- Which internal tool would you replace tomorrow, and what has stopped you?