Las declaraciones “IF” en un proceso no funcionan correctamente

0

Mi código VHDL no hace lo que necesito que haga. Tengo un código de 8 bits entrante que necesito agarrar con el "botón" "restablecer", luego necesito devolver el número del primer "1" que hay en este código. para esto lo estoy copiando en una secuencia secundaria y presionándolo hasta que aparezca un "1" al final.

pero "q" no deja de aumentar algo de cómo ... ¿Qué está mal?

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

entity count is
    port
    (
        clk : in std_logic;
        reset   : in std_logic;
        start   : in std_logic;     
        q       : out integer range 0 to 7;
        sequence : in bit_vector (0 to 7)
    );
end entity;

architecture rtl of count is

signal sub_seq : bit_vector (0 to 7);

begin
    process (clk)
        variable   cnt  : integer range 0 to 7 := 0;
    begin
        if (rising_edge(clk)) then
            if reset = '1' then
                sub_seq <= sequence;
            end if;
        end if;     

        if reset = '1' then
                cnt := 0;
                sub_seq <= sequence;
        end if;

        if ((reset = '0') and (sub_seq(0) = '0')) then
                cnt := cnt + 1;
                sub_seq <= sub_seq sra 1;
        end if;

        if (start = '0') then
                cnt := cnt + 1;
                sub_seq <= sub_seq sra 1;
        end if;
    q <= cnt;
    end process;

end rtl;
    
pregunta RKishmar

3 respuestas

0

hizo toda la lógica síncrona. De esta manera funciona.

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

entity count is
    port
    (
        clk : in std_logic;
        reset   : in bit;
        start   : in std_logic;     
        q       : out integer range 0 to 7;
        sequence : in std_logic_vector (0 to 7)
    );
end entity;

architecture rtl of count is

signal sub_seq : std_logic_vector (0 to 7);

begin
    process (clk, reset, start, sequence)
        variable   cnt  : integer range 0 to 7 := 0;
    begin
        if (rising_edge(clk)) then
            if reset = '1' then
                sub_seq <= sequence;
                cnt := 0;
            end if;

            if (((reset = '0') and (sub_seq(7) = '0'))) then
                cnt := cnt + 1;
                sub_seq <= '0' & sub_seq (0 to 6);
            end if;     

            if ((start = '1') and (sub_seq(7) = '1')) then
                cnt := cnt + 1;
                sub_seq <= '0' & sub_seq (0 to 6);
            end if;

        end if;     


    q <= cnt;
    end process;

end rtl;
    
respondido por el RKishmar
0

Tomó esto de allaboutfpga.com , no necesita "datos" en la lista de sensibilidad, y para el reinicio sincrónico, no necesita "reiniciar" en la lista de sensibilidad.

Reinicio asíncrono:

process(clock,Reset,data)
  if Reset = '1' then
    q <= '0';
  elsif Rising_edge(clock) then
    q <= data;
  end if;
end process;

Reinicio síncrono:

process(clock,Reset,data)
  if Rising_edge(clock) then
    if Reset = '0' then
      q <= '0';
    else
      q <= data;
    end if;
  end if;
end process;
    
respondido por el CapnJJ
0

Lo que diseñaste es un diseño asíncrono. Tiene un process con la señal clk en su lista de sensibilidad, eso está bien e incluso tiene una sentencia if para verificar el rising_edge(clk) , hasta ahora todo bien. Pero debe poner todo lo que es lógico dentro de esta declaración if excepto un restablecimiento dedicado (no la entrada de su botón). De hecho en tu caso

if (rising_edge(clk)) the
    if reset = '1' then
        sub_seq <= sequence;
    end if;
end if; 

No tiene un efecto especial porque haces la misma tarea de forma asíncrona también cuando lo haces

    if reset = '1' then
            cnt := 0;
            sub_seq <= sequence;
    end if;

¿Es sequence un valor estático? No estoy seguro al cien por cien de que lo haya entendido bien, pero su código debería tener un aspecto similar a este.

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

entity count is
port
(
    clk : in std_logic;
    reset   : in std_logic; --use this as an actual reset to have a defined initial state, generated by the FPGA
    button : in std_logic; -- this is your button input
    start   : in std_logic;     
    q       : out std_logic_vector(7 downto 0); -- try to use std_logic wherever possible
    sequence : in std_logic_vector (7 downto 0)
);
end entity;

architecture rtl of count is

signal sub_seq : std_logic_vector (7 downto 0); --use std_logic_vector
signal button_new, button_old : std_logic;
signal   cnt  : unsigned(7 downto 0);
begin
main_process : process (reset, clk) -- giving the process a name helps to read and understand the code
begin
    if reset = '1' then
        sub_seq <= (OTHERS => '0'); -- initialize the vector
        button_new <= '0';
        button_old <= '0';
        cnt <= to_unsigned(0, cnt'LENGTH);
    elsif (rising_edge(clk)) then
        button_new <= button;
        button_old <= button_new;
        if button_old = '0' AND button_new = '1' then -- only sample on the rising edge of the button input
            sub_seq <= sequence;
            cnt <= to_unsigned(0, cnt'LENGTH);
        elsif (sub_seq(0) = '0') then
           sub_seq <= sub_seq(0) & sub_seq(sub_seq'LEFT downto 1);
           cnt <= cnt+1; --be careful with variables, would suggest to use std_logic_vector.
        else 
            q <= cnt;
        end if;
    end if;     
end process;

end rtl;
    
respondido por el Humpawumpa

Lea otras preguntas en las etiquetas