error VHDL: múltiples controladores constantes para red

1

No puedo encontrar la forma de lidiar con el error: "varias unidades constantes" que se producen cuando intento leer y configurar la misma red en un solo proceso.

Necesito configurar la "salida" para algunos ciclos de reloj en el flanco 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.

    
pregunta dwEprew

2 respuestas

2

Sé que eres un principiante, pero tu VHDL se lee como si estuvieras intentando escribir un programa de computadora, no 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 observe cómo puede implementar el circuito que desee. Recuerde: el diseño del circuito (sin importar cuán ampliamente) viene primero, y luego el diseño VHDL.

Mientras tanto, aquí está el diseño que querías. (No lo he compilado con ModelSim por lo que podría 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ías una entrada de reinicio pero el diseño necesita uno. Además de eso y como pautas generales: no use variables, use señales; solo usa rising_edge con un reloj; no use máquinas de estado a menos que sea absolutamente necesario (algunos los usan para todo, un mal hábito).

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

    
respondido por el TonyM
2
  1. Use rising_edge solo para señales, que se supone que son relojes.

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

  3. No especificaste exactamente qué intentas lograr, pero creo que no tienes que (y no debes) 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;
    
respondido por el Staszek

Lea otras preguntas en las etiquetas