Forum Discussion

Altera_Forum's avatar
Altera_Forum
Icon for Honored Contributor rankHonored Contributor
16 years ago

integer doesn't wrap around

I'm setting up an integer signal by saying "signal counter: integer range 0 to 11". To me this means that it would be impossible for me to count higher than 11, but for some reason the counter actually goes up to 15 before wrapping around. Any idea why?

4 Replies

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    I am not that familiar with VHDL, but what I suspect is happening is the compiler uses the RANGE value to determine the size of the counter (4 bits), but does not add any logic to start an early wraparound. You probably need to add logic to test for counter == 11 and load the counter with 0 at that point.

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If I end at 15 and subtract the right amount that I want to count to start at it works. I guess it just has to do with vhdl trying to make its life easier by just going by bits

  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    --- Quote Start ---

    To me this means that it would be impossible for me to count higher than 11, but for some reason the counter actually goes up to 15 before wrapping around. Any idea why?

    --- Quote End ---

    You're expecting Quartus to implement a modulo 12 counter without specifying it. You simply shouldn't do that.

    What do you expect, if you assign a STD_LOGIC_VECTOR of "1111" to the integer signal? The FPGA throwing an exception? Performing a modulo operation? Saturation?

    In my opinion, integer is an abstract data type, that is converted to synthesizable SIGNED/UNSIGNED types according to the range definition. But no additional code is involved. You get a more convenient VHDL syntax, e.g. you can write count <= 3; instead of count <= conv_unsigned(3,4); But the implemented behaviour is still unsigned(3 downto 0);
  • Altera_Forum's avatar
    Altera_Forum
    Icon for Honored Contributor rankHonored Contributor

    If you had simulated this before you synthesised it, you would have had the similation throw an out of range error when the integer rolled over passed 11. Integers in VHDL do not roll over.

    Like everyone else has said, the synthesiser has converted it to 4 bits and just lets it roll over when it gets to 15. All you have to do to fix this is just do something like this:

    
    process( clk)
    begin
      if rising_edge(clk) = '1' then
        if count = 11 then 
          count <= 0;
        else
          count <= count + 1;
        end if; 
      end if;
    end process;
    

    No need to convert it to an unsigned or std_logic_vector - if you mean an integer, then use an integer.