I have some questions about reg initialization.
- Can I put Initial blocks in the design? Is that a good way?
- How to initial regs in my bottom design? Do I need to create ports in each level and give initial value from top to bottom? For each simulation, initial values are different.
Point 1:
We recently had a discussion about initial statements on the Electronics forum.
- Initial statements in test benches are normal. In fact without initial statements it becomes a lot more difficult to write test code.
- Initial statements are not possible in ASICs, CPLDs or hard programmed FPGAs.
- You can use initial statements in a most RAM based FPGAs where the state is valid after the FPGA is loaded. However if you would have a 'reset' pin or command that would not restore the initial state. As such, the FPGA condition after such a reset could well be different from your start-up state and thus your design might not work correctly.
- There are some cases where an initial state in an actual synthesize-able module is allowed or even mandatory for the module to work. See examples below.
Example 1: You have a divide by two register without reset coded as:
divide_by_two <= ~divide_by_two;
or
divide_by_two <= not(divide_by_two);
In simulation that will always remain 'X' but in reality it will start in a 0 or 1 conditions and then toggle between the two. To work around the 'X' in simulation you have the set an initial condition. Your code should work independent if the initial condition is '1' or '0'.
Example 2: You have a divide by four register without reset coded as:
divide_by_four[1:0] <= {divide_by_four[0],~divide_by_four[1]};
or
divide_by_four[1:0] <= divide_by_four[0] & not(divide_by_four[1]);
The reason why this is allowed is that during operation the two registers go through every of the four possible states: 00, 01, 11, 10. It does not matter in which of the four it starts, the sequence will always be repeated. Again to work around the 'XX' in simulation you have the set an initial condition. Your code should work independent if the initial condition is 00, 01, 10 or 11.
A lot of designers feel that, apart for examples like above, the use of initial statements in synthesized code is dangerous and it is better to avoid them.
Point 2:
Instead of initial statements you can use a 'reset' signal with the appropriate HDL code to set the start condition. It is normal for the reset to go to every module which has registers.
Depends on your target design.
You can usually use initial
blocks with FPGAs. You can initialization the registers in the same module that declares it. Hierarchically assignment is not allowed. You can also initialization registers with a synchronous reset if you add a reset input. Most FPGAs have a limited number of flops with asynchronous reset/preset (if any). Hence initial
blocks and synchronous resets are the best options FPGA.
ASICs typically do not synthesize initial
blocks. Initialization of flops is done with reset condition in synchronous logic. This is commonly an asynchronous reset but not required. In sort, synchronous or asynchronous reset for ASIC.
For both cases, to be synthesizable the initialization value needs to be deterministic and determined by constants. It cannot be derived on an input port or the current state of another register.
It is a good idea to follow these guidelines even if you plan to never synthesize. Otherwise is extra challenging to debug.