Divisor de frecuencia de reloj VHDL del quartus 2: no se puede determinar la definición del operador “+”

1

Soy extremadamente nuevo en VHDL y estoy tratando de hacer algunos proyectos sencillos para que aprenda lo básico y la sintaxis. Uso Quartus 2 en casa e ISE 10.1 en la computadora de la escuela. Escribí exactamente el mismo código en ambos donde el código es:

        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';

    begin

    process(clk) 



    begin
    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;
    count4<='0';
    end if;

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

    end if;
    end process;

    clkdividedby2<=clkdividedby2_temp;
    clkdividedby4<=clkdividedby4_temp;
    clkdividedby8<=clkdividedby8_temp;

    end karakter;

Esto se sintetiza perfectamente en ISE 10.1 en la escuela, pero en Quartus 2, recibo el error:

  

No se puede determinar la definición del operador "" + "": se encontraron 0 definiciones posibles

No tengo idea de por qué sucede esto. Escribí todas las bibliotecas y todo eso, y todavía no funciona.

    
pregunta Deniz Yildirim

2 respuestas

2

Está intentando realizar una adición en std_logic y std_logic_vector , eso no tiene sentido en VHDL, porque estos tipos no tienen valores numéricos.

Si desea que la adición funcione, debe utilizar cualquiera de las dos

  • un tipo que tiene una semántica de desbordamiento bien definida, por lo que está claro lo que debería suceder si dos valores '1' se encuentran en una adición, o
  • un tipo que es un valor numérico puro y no tiene una representación adjunta.

Para un contador que solo se compara con un valor fijo, pero nunca se lee, me gustaría ir con este último, cambiar el tipo a natural y darle una restricción range , y dejarlo en manos del compilador para seleccionar una representación interna.

    
respondido por el Simon Richter
1

La adición para el tipo std_logic_vector se admite en el paquete IEEE numeric_std_unsigned, así como en el paquete Synopsys std_logic_unsigned.

Lo que no se admite es la adición para el tipo std_logic, donde la adición sería equivalente a "y". Reemplace count4 <= count4 + '1'; con count4 <= not count4; o simplemente use clkdividedby2_temp.

También podría mostrar los flip-flops temporales como parte de los mismos std_logic_vectors haciendo count4 length 2 y count8 length 3 y asignando los MSB a clkdividedby4 y clkdividedby8, así como renombrando clkdividedby2_temp count2.

También puede usar un solo contador de 3 bits:

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;
        clkdividedby2, 
        clkdividedby4, 
        clkdividedby8:  out std_logic
    );
end entity freq_divider;

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

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

end architecture;

y con un pequeño banco de pruebas:

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;
begin
DUT:
    entity work.freq_divider
        port map (
            clk => clk,
            clkdividedby2 => clkdividedby2,
            clkdividedby4 => clkdividedby4,
            clkdividedby8 => clkdividedby8
        );
CLOCK:
    process
    begin
        wait for 5 ns;
        clk <= not clk;
        if now > 160 ns then
            wait;
        end if;
    end process;
end architecture;

Obtendrías:

mientras guarda algunos flip flops modelando hardware.

    
respondido por el user8352

Lea otras preguntas en las etiquetas