I'm extremely new to VHDL and trying to make some easy projects such that I learn the basics and syntax. I use Quartus 2 at home and ISE 10.1 at the school computer. I wrote exactly the same code in both of them where the code is:

        library ieee;
    use ieee.std_logic_1164.all;
    use ieee.numeric_std.all;
    use ieee.std_logic_unsigned.all;

    entity freq_divider is port(        

        clk: in std_logic;
        clkdividedby2,clkdividedby4,clkdividedby8: out std_logic

    end freq_divider;

    architecture karakter of freq_divider is

    signal count4 : std_logic := '0'; --In this line, count4 is initialized as 0.
    signal count8 : std_logic_vector (1 downto 0) := "00"; -- Count 8 is initialized as 0.
    signal clkdividedby2_temp,clkdividedby4_temp,clkdividedby8_temp : std_logic :='0';



    if(rising_edge(clk)) then

    clkdividedby2_temp<= not clkdividedby2_temp;
    count4 <= count4 + '1';
    count8 <= count8 + "01";

    if(count4 = '1') then -- = Tests for equality, not ==
    clkdividedby4_temp<= not clkdividedby4_temp;
    end if;

    if(count8 = "11") then
    clkdividedby8_temp<= not clkdividedby8_temp;
    end if;

    end if;
    end process;


    end karakter;

This synthesized perfectly on ISE 10.1 in school, but in Quartus 2, I get the error:

Can't determine definition of operator ""+"" -- found 0 possible definitions

I have no idea why this is happening. I wrote all the libraries and stuff, and it is still not working.


You are trying to perform addition on std_logic and std_logic_vector -- that makes no sense in VHDL, because these types do not hold numerical values.

If you want addition to work, you need to use either

  • a type that has well-defined overflow semantics, so it is clear what should happen if two '1' values meet in an addition, or
  • a type that is a pure numerical value and does not have a representation attached.

For a counter that is only compared against a fixed value, but never read, I'd go with the latter, change the type to natural and give it a range constraint, and leave it up to the compiler to select an internal representation.

  • \$\begingroup\$ But why it makes sense in ISE, but not Quartus ? I used my code in school in ISE 10.1 and it worked, in quartus 2 it did not. \$\endgroup\$ – Deniz Yildirim Jun 22 '16 at 20:29
  • \$\begingroup\$ My initial guess is that they are trying to be "helpful". \$\endgroup\$ – Simon Richter Jun 22 '16 at 20:35
  • \$\begingroup\$ well, I defined count4 and count8 as integers and now the code is working perfectly, but the thing is, compiler uses two 32 bits numbers when a single bit and two bits are necessary for count4 and count8 respectively. Isnt it a waste of memory or will it reduce the number of bits used in the optimization ? \$\endgroup\$ – Deniz Yildirim Jun 22 '16 at 20:39
  • 1
    \$\begingroup\$ In VHDL, you can limit allowed values using the range keyword. If you limit to 0 to 3, you would get the desired behaviour, but also an error in simulation because you assign the value 4 for a short time, even if you immediately overwrite it later (because <= assignments are not performed until the end of the block). \$\endgroup\$ – Simon Richter Jun 23 '16 at 13:03

Addition for type std_logic_vector is supported in the IEEE package numeric_std_unsigned as well as the Synopsys package std_logic_unsigned.

What isn't supported is addition for type std_logic, where addition would be equivalent to "and". Replace count4 <= count4 + '1'; with count4 <= not count4; or just use clkdividedby2_temp.

You could likewise show the temp flipflops as part of same std_logic_vectors by making count4 length 2 and count8 length 3 and assigning the MSB's to clkdividedby4 and clkdividedby8 as well as renaming clkdividedby2_temp count2.

You could also use use a single 3 bit counter:

library ieee;
use ieee.std_logic_1164.all;
-- use ieee.numeric_std.all;
use ieee.std_logic_unsigned.all;
-- OR use ieee.numeric_std_unsigned.all;

entity freq_divider is
     port (        
        clk:            in  std_logic;
        clkdividedby8:  out std_logic
end entity freq_divider;

architecture foo of freq_divider is
    signal count : std_logic_vector (2 downto 0) := (others => '0');
    process (clk) 
        if rising_edge(clk) then
            count <= count + 1;
        end if;
    end process;

    clkdividedby2 <= count(0);
    clkdividedby4 <= count(1);
    clkdividedby8 <= count(2);

end architecture;

and with a small testbench:

library ieee;
use ieee.std_logic_1164.all;

entity freq_divider_tb is
end entity;

architecture foo of freq_divider_tb is
    signal clk:             std_logic := '0';
    signal clkdividedby2:   std_logic;
    signal clkdividedby4:   std_logic;
    signal clkdividedby8:    std_logic;
    entity work.freq_divider
        port map (
            clk => clk,
            clkdividedby2 => clkdividedby2,
            clkdividedby4 => clkdividedby4,
            clkdividedby8 => clkdividedby8
        wait for 5 ns;
        clk <= not clk;
        if now > 160 ns then
        end if;
    end process;
end architecture;

You would get:


while saving some flip flops by modeling hardware.

  • \$\begingroup\$ There is very little difference between your code and mine. I tried to write count4<=count4+1 in my code but mine is still not working and giving the same error. I did not understand how count<= count + '1' means and operation but count<=count +1 does not ? I also tried your code with count<=count+"001" and it is working as well. Im confused \$\endgroup\$ – Deniz Yildirim Jun 23 '16 at 14:54
  • \$\begingroup\$ Oh I got you I guess. For single bits, we cant make the things work by count<=count + '1'; . I still dont get why it means and though ? But it is safe to say count4<=count4 +"01" if it was a std_logic_vector of size 2 right ? \$\endgroup\$ – Deniz Yildirim Jun 23 '16 at 14:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.