Error de VHDL: múltiples controladores constantes para la red

No puedo encontrar cómo lidiar con el error: "múltiples unidades constantes" que ocurre cuando intento leer y configurar la misma red en un solo proceso.

Necesito configurar la "salida" para algunos ciclos de reloj en el borde ascendente de la entrada "habilitar" y luego restablecer la "salida". Mi código:

library ieee;
use ieee.std_logic_1164.all;

entity trigger_slave is
    generic (
        OUT_ON_PERIOD   : integer := 10 - 1                                 
    );
    port (
        enable          : in std_logic; 
        clk_1MHz        : in std_logic;                                                                         
        OUTPUT          : buffer std_logic                           
    );
end trigger_slave;

architecture behavior of trigger_slave is

begin   
    process (enable)
    begin
        if (rising_edge(enable)) then
            OUTPUT <= '1';
        end if;
    end process;

    process (clk_1MHz)  
        variable counter        : integer range 0 to OUT_ON_PERIOD := 0;
    begin
        if (rising_edge(clk_1MHz) and OUTPUT = '1') then        -- here is the problem!
            if (counter = OUT_ON_PERIOD) then
                counter := 0;
                OUTPUT <= '0';
            else 
                counter := counter + 1;
                OUTPUT <= '1';
            end if;         
        end if;
    end process;

end behavior;

Por favor, ayúdame con este código. Muchas gracias.

¿Qué estás tratando de lograr exactamente? Parece que estás tratando de hacer algo, que es simple de alguna manera difícil. ¿No es solo un simple contador?
Sí, tal vez sea simple, pero soy un principiante. Es una especie de contador disparado con un reloj externo.
¿ Quieres decir enableque es otro reloj?

Respuestas (2)

Sé que eres un principiante, pero tu VHDL se lee como si estuvieras tratando de escribir un programa de computadora, no de diseñar un circuito lógico digital.

Lea sobre el diseño de lógica digital síncrona, mucho en Internet.

Luego, después de eso, lea sobre VHDL y vea cómo puede implementar el circuito que desea. Recuerde: el diseño del circuito (no importa cuán amplio) es lo primero, el diseño VHDL es lo segundo.

Mientras tanto, aquí está el diseño que querías. (No lo he compilado con ModelSim, por lo que puede haber errores tipográficos).

library ieee;
use ieee.std_logic_1164.all;

entity TRIGGER_SLAVE is
  generic(
    OUT_ON_PERIOD                 : integer := 10 - 1
  );
  port(
    CLK                           : in  std_logic;
    RST                           : in  std_logic;
    ENABLE                        : in  std_logic;
    OUTPUT                        : out std_logic
  );
end entity TRIGGER_SLAVE;

architecture behaviour of TRIGGER_SLAVE is
  signal delayCtr                 : natural range 0 to OUT_ON_PERIOD;
  signal enableOld1               : std_logic;

begin

  pDelay : process(RST, CLK) is
  begin
    if (RST = '1') then
      delayCtr    <=   0 ;
      enableOld1  <=  '0';
      OUTPUT      <=  '0';`

    elsif rising_edge(CLK) then

      -- Keep old enable level from 1 CLK ago, for edge detection.
      enableOld1  <=  ENABLE;

      -- Reload delay counter on ENABLE rising edge then run it down to zero.
      if (ENABLE = '1' and enableOld1 = '0') then
        delayCtr  <=  OUT_ON_PERIOD;

      elsif (delayCtr /= 0) then
        delayCtr  <=  delayCtr - 1;

      end if;

      -- Assert OUTPUT while the delay counter is running.
      if (delayCtr /= 0) then
        OUTPUT  <=  '1';
      else
        OUTPUT  <=  '0';
      end if;
    end if;
  end process pDelay;

end architecture behaviour;

No tenía una entrada de reinicio, pero el diseño necesita una. Además de eso y como pautas generales: no uses variables, usa señales; solo use el borde ascendente con un reloj; no use máquinas de estado a menos que sea absolutamente necesario (algunos las usan para todo, un mal hábito).

Por cierto, el problema en su diseño era que tenía dos procesos que controlaban un puerto de salida.

No diría que es un mal hábito usar máquinas donde se puede. Le dará un diseño un poco más grande, pero también tendrá más confianza al respecto. Recientemente hice un proyecto, en el que traté de hacer una cosa sin FSM, y fue doloroso, porque tenía un error oculto en esta cosa, y pasé aproximadamente un día encontrándolo, finalmente haciéndolo con FSM. Pero de todos modos, buen trabajo :)
@Staszek, sé que no lo harías, pero yo sí y como conclusión final, no la primera :-) Buena guía para un recién llegado. No tengamos una gran discusión de comentarios (todos), esto será demasiado largo, estoy feliz de ir a chatear si usted/alguien quiere.
  1. Úselo rising_edgesolo para señales, que se supone que son relojes.

  2. No puede asignar señal o salida en dos procesos diferentes.

  3. No especificó exactamente qué está tratando de lograr, pero creo que no tiene que (y no debe) usar el búfer para OUTPUT.

Este código debería funcionar como esperas (si te entiendo correctamente):

library ieee;
use ieee.std_logic_1164.all;

entity trigger_slave is
    generic (
        OUT_ON_PERIOD   : integer := 10 - 1                                 
    );
    port (
        clk_1MHz        : in std_logic;
        resetn          : in std_logic;

        enable          : in std_logic;
        output          : out std_logic
    );
end trigger_slave;

architecture behavior of trigger_slave is

type state_t is (IDLE, COUNTING);
signal machine: state_t;

begin   

    process (clk_1MHz)  
        variable counter        : integer range 0 to OUT_ON_PERIOD := 0;
    begin
        if resetn = '0' then
            machine <= IDLE;
        elsif rising_edge(clk_1MHz) then

            case machine is

            when IDLE =>

                machine <= IDLE;

                if enable = '1' then
                    counter := 0;
                    machine <= COUNTING;
                end if;

            when COUNTING =>

                machine <= COUNTING;

                if (counter = OUT_ON_PERIOD) then
                    machine <= IDLE;
                else 
                    counter := counter + 1;
                end if; 

            when others =>

                machine <= IDLE;

            end case;

        end if;
    end process;

output <= '1' when machine = COUNTING else '0';

end behavior;
Está asignando "SALIDA" tanto en el primer proceso como en la última declaración
Gracias por el ejemplo. 1. No pude compilar la línea "salida <= '1' when machine = COUNTING else '0';" 2. Intentaré hacer esto con este "reinicio" adicional
¿Cuál es el mensaje de error?