FPGA

VHDL SR Flip Flop Code

By CourseTron Team ·  4 min read ·  Updated Oct 2026 💬 𝕏 in f
Table of Contents
    ? Print / Save as PDF

    In short: An SR element stores one bit using Set and Reset inputs, S=R=1 is the forbidden state, and in VHDL a clocked process (rising_edge(clk)) infers a flip-flop while an incompletely assigned combinational process infers a latch.

    What an SR latch actually does

    The SR (Set-Reset) element is the smallest memory cell in digital design: two cross-coupled gates whose feedback loop holds a bit. With NOR gates the inputs are active high. S=1, R=0 forces Q=1. S=0, R=1 forces Q=0. S=0, R=0 means "hold", because each NOR output feeds the other gate and the loop keeps the previous value. The foundations are covered in our SR flip flop article; here we focus on how you describe and synthesise it in VHDL.

    If you build the same loop from NAND gates, the inputs become active low (S' and R'), and the hold condition is both inputs at 1. Interviewers love asking "what is the forbidden state of a NAND latch?" The answer flips: it is S'=R'=0.

    SR latch from two cross-coupled NOR gates NOR 1 NOR 2 R S Q Q̄ (Qn) Blue wires = the feedback loop that stores the bit CourseTron · coursetron.com
    Each NOR output feeds the other gate's second input. That loop is the memory.

    The forbidden state, explained properly

    With S=R=1 both NOR outputs are forced to 0, so Q = Qn = 0. That already breaks the contract that Qn is the complement of Q. The real damage happens when both inputs fall together. Each gate now sees 0 on both inputs and both want to rise to 1; each rising output then forces the other low. In an ideal symmetric circuit this oscillates or lingers near mid-rail (metastability). In silicon, tiny delay differences decide the winner, so the result is unpredictable.

    Key fact: the forbidden state is not illegal electrically; the outcome of leaving it is undefined. Data sheets typically mark the next state as "indeterminate".

    SRNext QMeaning
    00Q (previous)Hold
    010Reset
    101Set
    11undefinedForbidden

    Designers dodge the problem in two ways. They either guarantee in the surrounding logic that S and R are never both high, or they move to a JK flip flop, which turns the S=R=1 case into a useful toggle. A D flip flop avoids it entirely by driving R from the inverse of S.

    Latch versus flip-flop: level against edge

    A latch is level sensitive: while its enable is active, the output follows the inputs, and it holds only when the enable drops. A flip-flop samples on a clock edge and ignores the inputs the rest of the cycle. The practical consequence is timing analysis. A flip-flop gives a clean setup/hold check at one instant, which is what static timing tools such as Synopsys PrimeTime and Cadence Tempus are built around. Latches allow time borrowing but make closure far harder. Our latch vs flip flop page compares the two in detail.

    Latch (level) vs flip-flop (edge) Latch Flip-flop enable (high = transparent) Output follows input for the whole window, so glitches pass through. clk (sample at rising edge) Output changes only at the edge, input is ignored in between. CourseTron · coursetron.com
    Shaded band = the window in which a latch is transparent. The flip-flop only looks at the instant of the edge.

    VHDL: describing a clocked SR flip-flop

    A flip-flop in VHDL needs a clock-edge condition in a process with only the clock (and an optional async reset) in the sensitivity list. Note how the forbidden case is handled explicitly: here we resolve it to a known value instead of leaving it undefined, which keeps simulation and synthesis in agreement.

    library ieee;
    use ieee.std_logic_1164.all;
    
    entity sr_ff is
      port (clk, rst_n, s, r : in  std_logic;
            q, qn            : out std_logic);
    end entity;
    
    architecture rtl of sr_ff is
      signal q_i : std_logic;
    begin
      process (clk, rst_n)
      begin
        if rst_n = '0' then
          q_i <= '0';
        elsif rising_edge(clk) then
          if    s = '1' and r = '0' then q_i <= '1';
          elsif s = '0' and r = '1' then q_i <= '0';
          elsif s = '1' and r = '1' then q_i <= 'X'; -- forbidden, flagged in sim
          end if;                    -- s=0,r=0 : hold, no assignment needed
        end if;
      end process;
      q  <= q_i;
      qn <= not q_i;
    end architecture;

    Notice that "hold" requires no code. Inside a clocked process, not assigning a signal means it keeps its value, which is exactly what a register does. Assigning 'X' is a simulation aid; synthesis tools treat it as a don't-care and may pick either value, so many teams instead give reset priority (r wins) so that hardware behaviour is deterministic. For the rules on process behaviour, see concurrent vs sequential statements in VHDL.

    Key fact: on a Xilinx 7-series FPGA, a clocked process like this maps onto a dedicated FDRE/FDCE flip-flop in every slice, with essentially zero extra LUT cost for the hold path.

    VHDL: how a latch gets inferred

    Latches appear when a combinational process does not assign an output on every path. The synthesiser must remember the old value, so it builds a storage element.

    process (s, r)           -- no clock: combinational intent
    begin
      if    s = '1' and r = '0' then q_i <= '1';
      elsif s = '0' and r = '1' then q_i <= '0';
      end if;                -- no else: q_i must hold, so a LATCH is inferred
    end process;

    Vivado reports this as an inferred latch (warning Synth 8-327), Synopsys Design Compiler prints a "latch inferred" message, and Cadence Genus lists it under its inferred-sequential report. Treat it as an error unless you meant it. To remove the latch, either add a default assignment at the top of the process or finish with an else/when others branch.

    • Missing else: the most common accident; one branch skips the assignment.
    • Incomplete case: a case without when others on a non-fully-covered type.
    • Sensitivity list typos: not a latch cause by itself, but it creates simulation/synthesis mismatch that looks similar. Prefer process(all) in VHDL-2008.

    Watch it work: set, hold, reset

    SR flip-flop timing (animated scan cursor) clk S R Q set hold reset . CourseTron · coursetron.com
    The red cursor sweeps across time. Q rises at the first edge after S=1, holds while S and R are both 0, and falls at the first edge after R=1.

    Practical rules for real designs

    • Default to flip-flops. Registers map cleanly onto FPGA fabric; a latch needs an LDCE primitive, which consumes a flop-site and confuses timing.
    • Reserve latches for clock gating and deliberate time borrowing in ASIC flows, as in standard integrated clock-gating cells.
    • Ask the tool for a latch report on every run and make "zero inferred latches" a sign-off item.
    • Don't build SR cells from gates in an FPGA; combinational loops are flagged by Vivado (DRC LUTLP-1) and are not timed reliably. Use the register primitives, as when choosing between BRAM inference and instantiation, inference from clean RTL is usually the right call.

    The same style carries to other flip-flops: the T flip flop is a JK with both inputs tied, and our next article on the VHDL JK flip-flop (vhdl-jk-flip-flop) shows how the S=R=1 hole disappears. If you are weighing hardware targets, read FPGA vs CPLD too, since CPLD macrocells handle registers differently.

    Teams that want hands-on RTL review can talk to Avecas design services, and learners preparing for VLSI roles can look at ChipXpert training.

    Want to write, simulate and synthesise this on a real tool flow? Explore the hands-on FPGA and digital design tracks in our CourseTron courses.

    FAQ

    Why is S=R=1 forbidden in an SR latch?

    It drives both outputs to the same level (0 for NOR, 1 for NAND), breaking the Q/Qn complement relationship. When both inputs are released together, the next state depends on gate delay and is unpredictable.

    How do I avoid inferring a latch in VHDL?

    Assign every output on every path of a combinational process: add a default value at the top, finish if/elsif chains with else, and include when others in case statements.

    Is an SR flip-flop the same as an SR latch?

    No. The latch is level sensitive and transparent while enabled. The flip-flop updates only on a clock edge, so it has a defined setup and hold window.

    Can I use a latch in an FPGA?

    You can, using primitives such as LDCE, but it is rarely wise. Timing tools handle it poorly and most FPGA logic is designed around edge-triggered registers.

    Advertisement