Sequential Logic Design
Async reset should be asserted asynchronously, de-asserted synchronously (reset synchronizer, §27).
13.1 D flip-flop
process (clk)
begin
if rising_edge(clk) then
q <= d;
end if;
end process;13.2 Resets
Async reset should be asserted asynchronously, de-asserted synchronously (reset synchronizer, §27).
-- Synchronous reset (recommended for most FPGA designs)
process (clk)
begin
if rising_edge(clk) then
if rst = '1' then
q <= '0';
else
q <= d;
end if;
end if;
end process;
-- Asynchronous reset
process (clk, rst_n)
begin
if rst_n = '0' then -- active-low async reset
q <= '0';
elsif rising_edge(clk) then
q <= d;
end if;
end process;13.3 Register with clock enable
Never gate the clock with logic (clk and en) in FPGAs — use clock enables.
process (clk)
begin
if rising_edge(clk) then
if rst = '1' then
reg <= (others => '0');
elsif en = '1' then
reg <= d;
end if;
end if;
end process;13.4 Counters
Variants: up/down counter, loadable counter, BCD counter, ring counter, Johnson counter, LFSR (pseudo-random):
-- Up counter with terminal count
process (clk)
begin
if rising_edge(clk) then
if rst = '1' then
cnt <= (others => '0');
elsif en = '1' then
if cnt = MAX then
cnt <= (others => '0');
tc <= '1';
else
cnt <= cnt + 1;
tc <= '0';
end if;
end if;
end if;
end process;-- 8-bit Fibonacci LFSR, taps 8,6,5,4
lfsr <= lfsr(6 downto 0) & (lfsr(7) xor lfsr(5) xor lfsr(4) xor lfsr(3));13.5 Shift registers
process (clk)
begin
if rising_edge(clk) then
if load = '1' then
sr <= parallel_in;
else
sr <= sr(sr'high-1 downto 0) & serial_in; -- shift left
end if;
end if;
end process;
serial_out <= sr(sr'high);13.6 Clock divider / tick generator
-- Generate a 1-cycle tick at 1 Hz from a 100 MHz clock (use as an enable, NOT as a clock)
process (clk)
begin
if rising_edge(clk) then
tick <= '0';
if cnt = 100_000_000 - 1 then
cnt <= 0;
tick <= '1';
else
cnt <= cnt + 1;
end if;
end if;
end process;13.7 Edge detection & debouncing
Debouncer: wait until the (synchronized) input is stable for N ms before accepting it.
process (clk)
begin
if rising_edge(clk) then
btn_d <= btn_sync;
end if;
end process;
btn_rise <= btn_sync and not btn_d; -- one-cycle pulse on rising edge13.8 Latches (usually unintended!)
Latches cause timing problems in FPGAs; synthesis tools warn "inferred latch". Fix with defaults or complete if/else.
process (en, d) -- level-sensitive: latch
begin
if en = '1' then q <= d; end if; -- no else → q holds its value → latch
end process;