Search code examples
vhdl

A simple VHDL circuit won't display initial value


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?


Solution

  • 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.

    enter image description here

    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.