Skip to content

VHDL · Chapter 19.6 · Interview and Industry Readiness

RTL Design Problems

The hardest interview round is open-ended: design a working block live. It is graded less on the final code than on your process, meaning how you clarify, structure, and communicate. The winning method is repeatable. Clarify the spec and interface first, including widths, reset style, throughput, and whether it is a valid-ready stream. Sketch the datapath and control separately, choose the right state element such as a counter, a shift register, or a state machine, and write clean RTL with reset, default assignments, and registered outputs. State every assumption out loud and mention the corner cases and how you would verify them. The classic problems, from counters and edge detectors to debouncers, FIFOs, and arbiters, all yield to the same approach. This lesson works the method end to end through a synchronous edge detector, emphasizing the thought process interviewers actually score.

Foundation15 min readVHDLInterviewRTLDesignMethodologyEdge Detector

1. Engineering intuition — they are watching how you think, then what you build

A design problem is deliberately under-specified, because the interviewer wants to see you ask the right questions before writing anything. Jumping straight to code signals a junior; pausing to pin down the interface, reset, and throughput signals an engineer. So treat the prompt as the start of a conversation: what are the widths, is there a reset and which kind, how fast must it run, does it use valid/ready flow control, what happens at the boundaries? Then structure the answer the way you structure real RTL — datapath and control separated — pick the simplest state element that fits, and write clean code (reset, defaults, registered outputs). Narrate your assumptions and the corner cases as you go. The code is the deliverable; the method is what earns the offer.

2. Formal explanation — the design-problem method

design_method.txt
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- A REPEATABLE METHOD for any 'design this block' problem:
--  1. CLARIFY spec + INTERFACE: widths, reset (sync/async), throughput, valid/ready? boundary behaviour.
--     -> ask questions; state assumptions you are making.
--  2. SKETCH datapath + control (18.5): what MOVES data vs what SEQUENCES it.
--  3. CHOOSE the state element: counter / shift register / FSM (9.x) — the simplest that fits.
--  4. CODE clean RTL:
--       * one synchronous clock; reset only what needs it (19.4)
--       * combinational logic: default-assign outputs (no latch, 19.3)
--       * register outputs that must be glitch-free
--  5. STATE ASSUMPTIONS out loud (widths, reset, single clock, input synchronous).
--  6. VERIFICATION: name the corner cases + how you'd test (reset, back-to-back, empty/full, metastable in).
--
-- The SAME method solves: counter+enable, edge/pulse detector, debouncer, FIFO,
--   serial<->parallel, arbiter, pattern detector.

The method is six beats: clarify, sketch datapath/control, choose the state element, code cleanly, state assumptions, mention verification. It applies to every classic problem and keeps you from the two failure modes — coding before understanding, and writing latchy/unreset RTL under pressure.

3. Production usage — a worked example: synchronous edge detector

edge_detector.vhd
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- PROBLEM: detect a rising edge on input sig and emit a one-cycle pulse.
-- CLARIFY (state aloud): synchronous to clk; sig assumed already synchronized; sync reset; 1-cycle pulse.
-- STRUCTURE: tiny datapath (a 1-bit delay register) + trivial control (compare now vs delayed).
process (clk)
begin
    if rising_edge(clk) then
        if rst = '1' then sig_d <= '0';
        else              sig_d <= sig;        -- remember last cycle's value (the only state)
        end if;
    end if;
end process;
rising_pulse <= sig and not sig_d;             -- '1' for ONE cycle when sig goes 0->1
-- (register rising_pulse too if a glitch-free, registered output is required)
 
-- ASSUMPTIONS stated: sig is synchronous to clk (else add a 2-FF synchronizer, 17.5);
--   one clock; synchronous reset; output is a single-cycle pulse.
-- VERIFICATION mentioned: test no-edge, single edge, back-to-back edges, edge during reset,
--   and (if async input) metastability handling.

What hardware does this become? A single flip-flop (the delay sig_d) and a tiny gate (sig and not sig_d) — the minimal edge detector. The point of the worked example is not the three lines of code; it is that you clarified (synchronous, already-synchronized input, sync reset, one-cycle pulse), chose the simplest state element (one delay register), wrote clean RTL (reset, clear intent), stated assumptions (and what changes if the input is asynchronous — add a synchronizer), and named verification corner cases. The same beats turn "design a debouncer" into a counter that requires the input stable for N cycles, or "design an arbiter" into request/grant with a fairness policy. Show the process and the simple block falls out.

4. Structural interpretation — the design-problem method

design-problem method: clarify, sketch datapath/control, choose state element, code cleanly, verify1. clarify spec +interfacewidths, reset, throughput,valid/ready2-3. datapath/control+ state elementcounter / shift reg / FSM4-5. clean RTL +assumptionsreset, defaults, registeredoutputs6. verification +corner casesreset, back-to-back,boundaries12
Open-ended RTL design problems are scored on method, not just code. The repeatable flow: clarify the specification and interface (widths, reset style, throughput, valid/ready, boundary behaviour) and state your assumptions; sketch the datapath and control separately; choose the simplest state element that fits (counter, shift register, or FSM); write clean RTL with one clock, reset only what needs it, default-assigned combinational outputs, and registered outputs where glitch-freedom matters; then name the corner cases and how you would verify them. The same method solves every classic problem — counter, edge detector, debouncer, FIFO, serial-to-parallel, arbiter, pattern detector. This is a design-methodology structure; the waveform below shows the worked edge detector's one-cycle pulse.

5. Simulation interpretation — the edge detector's one-cycle pulse

Synchronous edge detector: one-cycle pulse on each rising edge of sig

8 cycles
Synchronous edge detector: one-cycle pulse on each rising edge of sigsig goes 0->1; sig_d still 0 -> rising_pulse = 1 for ONE cyclesig goes 0->1; sig_d s…sig still 1 but sig_d now 1 -> pulse deasserts (no level, only edges)sig still 1 but sig_d …next rising edge -> another single-cycle pulsenext rising edge -> an…clksig01110110sig_d00111011rising_pulse01000100t0t1t2t3t4t5t6t7
The delayed copy sig_d lags sig by one cycle, so sig and not sig_d is high for exactly one clock whenever sig rises from 0 to 1 — a clean single-cycle pulse per edge, with no pulse while sig stays high. This minimal design (one flip-flop, one gate) is what the method produces once you have clarified that the input is synchronous and the output is a one-cycle pulse.

6. Debugging example — coding before clarifying

Expected: a correct block plus a strong impression. Observed: the candidate starts coding immediately, builds something that technically works for the happy path but misreads the spec (wrong reset style, no backpressure where the interface needed valid/ready, breaks on back-to-back inputs), and never mentions verification — coming across as a coder, not a designer. Root cause: the method was skipped — no clarifying questions, no datapath/control sketch, no stated assumptions, so the design was built on guesses and the corner cases were never considered. Fix: run the method — clarify the spec/interface and state assumptions first, sketch datapath/control, choose the simplest fitting state element, write clean RTL (reset, defaults, registered outputs), then name the corner cases and verification. Engineering takeaway: design problems reward process — clarify and state assumptions before coding, structure datapath vs control, write clean RTL, and finish with verification; jumping straight to code on an under-specified prompt is the most common way to fail the round.

clarify_then_build.txt
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
-- BUG (method): code first on an under-specified prompt -> wrong reset, no backpressure, misses corners.
-- FIX (method): clarify (widths/reset/throughput/valid-ready) + state assumptions
--   -> sketch datapath/control -> simplest state element -> clean RTL -> name verification corners.

7. Common mistakes & what to watch for

  • Coding before clarifying. Pin down widths, reset, throughput, and valid/ready first; state every assumption out loud.
  • Skipping datapath/control structure. Separate what moves data from what sequences it (18.5); pick the simplest state element.
  • Latchy/unreset RTL under pressure. Default-assign combinational outputs, reset what needs it, register glitch-sensitive outputs.
  • Ignoring corner cases / verification. Name reset, back-to-back, empty/full, and asynchronous-input cases and how you would test them.
  • Over-engineering. Build the simplest block that meets the (clarified) spec; complexity without a stated requirement loses points.

8. Engineering insight & continuity

RTL design problems are won by method: clarify the spec and interface and state assumptions, sketch datapath/control, choose the simplest state element, write clean RTL (reset, defaults, registered outputs), and finish with verification and corner cases — as shown by the minimal edge detector that falls out once the questions are asked. The same six beats solve every classic problem. The final interview round flips design into diagnosis — reading broken code and explaining why it fails — which is the next lesson, Debugging and Sim/Synth Interview Questions.