Section 14.1 Parametrized designs
The VHDL model for a counter depends on two parameters: the width of the register and the maximum count value. For example, in a decade counter process that is part of an architecture:
architecture behavior of example is
signal uy: unsigned(3 downto 0) := "0000"; -- 1, 2
begin
process(clk)
begin
if rising_edge(clk) then
if uy < 9 then -- 3
uy <= uy+1;
else
uy <= "0000"; -- 4
end if;
end if;
end process;
...
end behavior;
There are four points in this model, marked by comments, where constant values are used:
- The length of the counter register (4 bits, indexed
3 downto 0) - The initial state of the counter,
"0000" - The maximum value of the counter,
9 - The reset value,
"0000"
All four of these numerical constants must be entered correctly in order for the counter to work as desired. If, at some future time, you want to change the counter from counting to 9 to counting to 11, you will have to change one number. If you want to change the maximum count to 23, you must modify all four points in the model: the length of
uy from 4 to 5, the initial and reset values from "0000" to "00000", and the upper count limit from 9 to 23. If you miss one of these changes you’ll have a syntax error or a functional bug.You know from prior programming experience that it is dangerous to have unnamed constants, sometimes called “magic numbers”, in your code. They often go undocumented and when changes have to be made, they are often overlooked, leading to costly rounds of debugging. These risks are mitigated by replacing the magic numbers with documented named constants. Here is how that would be done in the decade counter:
architecture behavior of example is
constant REGSIZE: integer := 4; -- register length
constant MAXVAL: integer := 9; -- maximum count
signal uy: unsigned(REGSIZE-1 downto 0) := (others=>'0');
begin
process(clk)
begin
if rising_edge(clk) then
if uy < MAXVAL then
uy <= uy+1;
else
uy <= (others=>'0');
end if;
end if;
end process;
end behavior;
In this version, the register length and the maximum count parameters are assigned to named constants, REGSIZE and MAXVAL at the beginning of the architecture. These named parameters replace the instances of the magic numbers in the model. Additionally, we have used the
(others=>'0') construction to replace the "0000". This represents a string "0...0" of length that matches the vector it is assigned to. With these modifications, if you want to change the maximum count from 9 to 23, you only have to change REGSIZE and MAXVAL, and their values will propagate through the model. These two changes make the code easier to read, thus less prone to bugs, and also scalable, by changing the parameter values rather than by rewriting the code. Large designs often contain many registers of the same size. Making the register size a named constant parameter, and using that parameter throughout the design, makes it easy to scale the design to different register sizes in the future. 
