Search code examples
vhdl

difference between using reset logic vs initial values on signals


Let's say I have a signal, I can either assign a initial value of zero OR I can set it to zero upon RESET. I've seen my co-workers using the two method interchangeably. I just want to see others opinion on this.

Example (using initial value):

architecture arch of xxx is

    signal flag : STD_LOGIC   := 0;

begin
    process (clk) begin
        if rising_edge(clk) then
            -- do something
        end if;
    end process;
end arch;

Example (using reset value):

architecture arch of xxx is

    signal flag : STD_LOGIC;

begin
    process (clk,rst) begin
        if (rst = '1') then
            flag <= '0';
        elsif rising_edge(clk) then
            -- do something
        end if;
    end process;
end arch;

Solution

  • If possible, use a dedicated reset signal, for several reasons:

    • Designs using complex clock generation may require that a module is held idle (reset) until the clock is stable. Using initial values with an unstable but running clock may change the initial value from the expected.

    • A module that interfaces to other or external modules may get protocol violations on an interface during startup, and to avoid wrong operation or hangup due to protocol violations, it may be required to hold the module in reset until the protocol operation is well defined in the interface.

    • Restart of the entire system, or part of the system, is possible by asserting reset, instead of having to reload the entire FPGA, which takes much longer time, and may be more complicated if it requires CPU interaction.

    • Some FPGA technologies, for example Altera partial reconfiguration, does not support initial values for the modules used in partial reconfiguration. Reuse of modules is therefore easier if only reset is used.

    • Simulation of different start/restart conditions is easier when it is possible to apply reset, and continue the same simulation sequence. If initial value is used, then the entire simulation must be restarted.

    Apply reset to as few flip-flops as possible, for the resource reasons that Russell points out. Also, applying it to only the required flip-flop, makes it easier to catch bugs and oversights in the design during simulation, since unknown X values may then appear. The reset should be asynchronous, since most FPGA and ASIC technologies have flip-flops with dedicated reset input, and the reset will then not slow down the timing of the synchronous design part, by insertion of logic to apply a reset value. The slow down can be seen in for example Altera Cyclone V, where logic is inserted in the data path due to the synchronous reset through a MLABCELL, as shown in the data path timing report here:

    enter image description here

    A flip-flop using asynchronous reset does not have this extra delay in the data path, as can be seen in figure through this link.

    The process for flip-flops with reset should be written with the reset part as:

    process (clk, rst) begin
      if rising_edge(clk) then
        -- Flip-flops updated at clock
      end if;
      if (rst = '1') then
        -- Flip-flops reset
      end if;
    end process;
    

    This coding style makes it possible to apply reset to only some of the flip-flops updated at the rising clock, while the remaining flip-flops are implemented without reset.

    The combined if-then-elsif-end if in question code, actually specified that the state is held during reset for flip-flops that are not reset, since the rising_edge(clk) part of the if does then not take effect. This is probably not the intended implementation.

    For proper timing, the reset signal (rst) should be synchronized to the clock (clk), at least for deassertion (1 to 0), so recovery and removal time are not violated.