Constants are good. Good programming practice dictates that literals should always be avoided. However, constants have the annoying habit of needing to be changed over time as a design evolves. Or, in a multi-engineer project, it turns out that a universal system constant appears in every engineer's VHDL code. Say, six pieces of code, perhaps, all containing the same constant declaration. Or worse, six pieces of code with differently named constant objects all having the same value, representing the same “thing”. And supposing it doesn't get changed in one of those declarations (easily done) when it is updated. Oh, dear!
Now, in VHDL, we can put constants in packages. That's good. This universal system constant exists as a single declaration. But packages must be compiled before you can reference their contents using a use clause. So we make a change to the packaged constant, re-compile the package and then make all other design units dependent upon that package (Oh, dear again!). Of course, what we really want is the ability to change the value of the constant without having to re-compile. This is where deferred constants come to the rescue.
A constant can be declared in a package without an initialization. The corresponding package body contains the initialization. This is called a deferred constant. So, when you update the constant in the package body, you re-compile the package body. But the analysis rules for package bodies and packages are as per those for architectures and entities. You don't need to re-compile the package declaration. So we won't. This means that we have changed the value of the constant, and any simulation we now run will have the updated constant value. Well, almost...
Deferred constants have their value bound at elaboration time. Some simulators invoke an elaboration phase before the simulation is run, the deferred constant will have its new value. However, other simulators may create a simulation snapshot when a testbench design unit is compiled and you must re-elaborate the testbench design unit manually in order to update the constant's value in the simulation snapshot. If you simply, re-compile the package body and then re-run the simulation snapshot, the constant will still have its old snapshot value. Check your simulator documentation regarding support for VHDL deferred constants and what steps are needed in the simulation flow for the constant to see its new value.
In the following code example, we have two constants. The first is the number of ports in an ATM switch. This number has probably been defined by marketing! It could change as market requirements change. The second constant is for the number of bytes in an ATM cell. This has been defined by an international standard-definition body. It is most unlikely to change. We could use deferred constants for both to be absolutely safe.
package deferred is constant num_switch_ports : integer; -- deferred constant constant num_bytes_per_cell : integer := 53; end deferred;
package body deferred is constant num_switch_ports : integer := 16; end deferred;
Your e-mail comments are welcome - send email