Here is my code and it's pretty simple. I'm to cycle through the first 8 letters of the alphabet on a Altera Cyclone II board.
entity lettercycle is
port(
SW : in std_logic; -- toggle switch
HEX0 : out std_logic_vector(6 downto 0) -- 7-segment display
);
end lettercycle;
architecture behavioural of lettercycle is
signal counter : integer range 0 to 7 := 0;
begin
process
type SEGMENT_ARRAY is array (0 to 7) of std_logic_vector(6 downto 0);
variable SEVENSEG : SEGMENT_ARRAY := ("0001000","0000011","1000110","0100001","0000110","0001110","0010000","0001001");
begin
HEX0 <= SEVENSEG(counter);
wait until SW = '0';
counter <= counter + 1;
end process;
end behavioural;
This works great, it cycles but initially it doesn't display "A" on my seven segment display. It displays "8" (so nothing essentially). Once I push SW which is a logic 0 switch it changes to 'A' and cycles to 'B', 'C', etc properly. It also loops correctly. What it isn't doing is initially setting to 'A'. If I force
HEX0 <= SEVENSEG(0);
Then it will display 'A' initially so I'm out ideas. Could this be related to bouncing?
The synthesis tool implements the process with falling edge flip-flops, as a
result of the wait until SW = '0';
, so both the counter
and HEX0
inside
the process are updated at falling edge of SW
(thus HEX0
is not a latch).
The synthesis tool does however not propagate the initial 0 value of counter
to initial value on HEX0
based on mapping through SEVENSEG
, so you won't
see an initial 'A' on the output.
The synthesis output is shown on the figure below, whereby the flip-flops on the output can also be seen.
The intended operation is possible with update of process and HEX0
assign to:
process (SW) is
begin
if falling_edge(SW) then
counter <= counter + 1;
end if;
end process;
HEX0 <= SEVENSEG(counter);
This will also remove the unnecessary flip-flops on the output for HEX0
.
Note the SEVENSEG
is moved to architectural level declaration as constant.