I usually initialize state registers of my FSMs by specifying an initial value in my VHDL code, so that, I do not require a reset pulse after startup of the configured FPGA. The following example demonstrates this by a "ring-counter" which just merges all state registers together:
library ieee; use ieee.std_logic_1164.all; use ieee.numeric_std.all; entity counter_init is port ( clock : in std_logic; msb : out std_logic); end entity counter_init; architecture rtl of counter_init is -- large counter to detect excessive skew on Global Write Enable (GWE) signal counter : unsigned(255 downto 0) := x"55555555_55555555_55555555_55555555_55555555_55555555_55555555_55555555"; begin -- architecture rtl counter <= counter(0) & counter(counter'left downto 1) when rising_edge(clock); -- The counter value will be observed by an on-chip logic analyzer. -- Output most-significant bit to prevent synthesizing away the above logic. msb <= counter(counter'left); end architecture rtl;
This technique has worked in my designs for Altera or Xilinx FPGAs so far. I have explicitly checked it using the vendor-specific on-chip logic analyzer and a startup trigger. Here is a screenshot of ChipScope, ok one cycle is missed apparently:
But, after reading the docs, I wonder how it works:
How do all the flip-flops (connected to the same clock signal) start to toggle at the same time?
The startup sequence for a Xilinx FPGA is described in the 7 Series FPGAs Configuration User Guide (UG470) for example. After configuration of the FPGA, a startup sequence is executed which asserts a "Global Write Enable (GWE)" Table 5-12:
When asserted, GWE
enables the CLB and the IOB flip-flops as well as other
synchronous elements on the FPGA.
and in the footnote:
GWE is asserted synchronously to the configuration clock (CCLK) and has a significant skew across the part. Therefore, sequential
elements are not released synchronously to the user's system clock and timing violations can occur during startup. It is
recommended to reset the design after startup and/or apply some other synchronization technique.
So, this actually means: If the clock at the flip-flops already toggles, then all the flip-flops may start to toggle at different times / clock edges. Given that the clock oscillator on the FPGA board is already running, and that I'm using a global clock-buffer without an enable input (
BUFG): Will the clock input at the flip-flops already toggle before GWE is asserted?
I didn't find any information in UG470 about if and how clock-buffers are enabled. And the Xilinx 7 Series FPGA and Zynq-7000 All Programmable SoC Libraries Guide for HDL Designs (UG768) only states that the clock-enable input of a
BUFGCTRL must be asserted synchronously. But, this is actually a user-driven input.
For the Altera Cyclone III FPGA I'm using too, I didn't find any relevant information in the Cyclone III Device Handbook.
To repeat: I didn't observed any failing initialization so far, but this seems not to be specified in the docs.
You should assume the clock input to your flip-flops is toggling unless you can prove otherwise (by a guaranteed power on or post configuration delay). All the flip-flops on a given clock domain are not guaranteed to start on the same clock edge based on GWE or GSR. Both act like an asynchronous reset and cause potential problems for some logic (counters, one-hot state machines, etc).
Specifically a one-hot state-machine that transitions immediately after configuration WILL (eventually) FAIL (transition to an invalid state). The frequency of failure will depending on the clock period compared to the device (and place and route) specific skew for your design.
Another simple experiment to see this behavior initialize a relatively fast count down counter with 10000000 and look at its behavior immediately after configuration. Some bits make the transition to 01111111 and some bits miss that first transition but the subsequent counting sequence will be correct.
The white paper mentioned by Krunal Desai talks about this very problem and is a great reference. Any SRAM based FPGA will most likely have a similar issue.
There is no need to reset the registers to get a known value. If you have logic that is sensitive to all starting on the same clock edge will need to add synchronization logic (this can consist of a synchronously de-asserted reset or other synchronous logic). Xilinx AR44174 talks about the issue a little more. I would add a third method of mitigation which is to guarantee clocked logic is not changing/transitioning during the first several clock cycles after startup.