Reset

Bij het maken van een hardware ontwerp dat registers bevat, is het noodzakelijk om de begintoestand te kennen: wat is de initiele waarde? De tekstboek manier om dit te bekomen is door gebruik te maken van een reset signaal. Het actief worden van dit signaal zorgt ervoor dat de hele schakeling in een gekende begintoestand komt. Er zijn typisch 2 manieren om dit te doen: met een synchrone reset of met een asynchrone reset.

Asynchrone reset

Onderstaand voorbeeld is van een D flip-flop met asynchrone reset. Je ziet hier dat de reset onderdeel is van de sensitivity list. De reset staat hier als eerste in het process, maar die volgorde is echter niet van belang.

Synchrone reset

Onderstaand voorbeeld is van een D flip-flop met synchrone reset. Je ziet hier dat de reset geen onderdeel is van de sensitivity list. De reset staat hier na de if van de stijgende flank van de clock.

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity asynchronous_reset is
    Port (
        clock: in std_logic;
        reset: in std_logic;
        data_in: in std_logic;
        data_out: out std_logic
    );
end asynchronous_reset;

architecture Behavioral of asynchronous_reset is

    signal clock_i: std_logic;
    signal reset_i: std_logic;
    signal data_in_i: std_logic;
    signal data_out_o: std_logic;

begin

    clock_i <= clock;
    reset_i <= reset;
    data_in_i <= data_in;
    data_out <= data_out_o;

    PREG: process(reset_i, clock_i)
    begin
        if reset_i =  '1' then
            data_out_o <= '0';
        else
            if clock_i'event and clock_i = '1' then
                data_out_o <= data_in_i;    
            end if;
        end if;

    end process;
end Behavioral;
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;

entity synchronous_reset is
    Port (
        clock: in std_logic;
        reset: in std_logic;
        data_in: in std_logic;
        data_out: out std_logic
    );
end synchronous_reset;

architecture Behavioral of synchronous_reset is

    signal clock_i: std_logic;
    signal reset_i: std_logic;
    signal data_in_i: std_logic;
    signal data_out_o: std_logic;

begin

    clock_i <= clock;
    reset_i <= reset;
    data_in_i <= data_in;
    data_out <= data_out_o;

    PREG: process(clock_i)
    begin
        if clock_i'event and clock_i = '1' then
            if reset_i =  '1' then
                data_out_o <= '0';
            else
                data_out_o <= data_in_i;    
            end if;
        end if;
    end process;

end Behavioral;

ff_withreset.png

Welke reset gebruik je nu best? Dat hangt af van de toepassing. De tabel hieronder vergelijkt enkele belangrijkte criteria.

Asynchrone reset Synchrone reset
Voorspelbaarheid
Kan op ieder moment komen, dus ook dicht bij klokflanken.
Voorspelbaar (bv. bij een stijgende klokflank)
Glitches …
kunnen een catastrofaal effect hebben omdat ze vals-positief kunnen geven.
worden (tot op zeker hoogte) opgevangen
Timing …
is gemakklijker om te halen aangezien de reset niet meegenomen wordt in de timing-analyse.
is moeilijker om te behalen want de reset signalen kunnen een hoge fan-out hebben.
De afwezigheid van de klok …
heeft géén impact.
zorgt dat een reset niet gezien wordt.

De vuistregel voor (beginnende) hardware designers is om een asynchrone reset te gebruiken waar het niet anders kan (bv. bij IP blokken van third-parties), maar waar mogelijk (en zeker voor FPGA ontwerp) wordt aangeraden om een synchrone reset te gebruiken.

Voor sequentiële processen zijn er maximaal 2 signalen (clock en eventueel reset) die in de sensitivity list staan. Bij combinatorische processen zijn het alle signalen.