variable VHDL que se comporta de manera extraña

0

Tengo el siguiente fragmento de código VHDL que se está comportando mal y no sé por qué:

process (clock)

variable counter : std_logic_vector (15 downto 0) :=  x"0000";
variable op : std_logic_vector (7 downto 0);

begin

if (clock = '1') then

    op := cw (15 downto 8);

    -- This if statement is misbehaving 
    if (op = x"20") then
        counter  := counter + cw (7 downto 0);
    end if;

    counter := counter + 2;

    ia <= counter;

    end if;

end process;

Como muestra la simulación, el código se incrementa en conteos de 2, pero el ciclo después de la sentencia if, suceden cosas extrañas

Losentimos,laformadeondasuperioreselreloj,luego"cw" y "ia" en la parte inferior

EDITAR: El código se supone que cuenta 2 por defecto. Si el byte superior de "cw" es 0x20, entonces se incrementa en 2 y otro número

    
pregunta user929404

3 respuestas

0

La solución terminó siendo:

counter  := cw (7 downto 0) + counter;

a diferencia de lo que tenía antes:

counter  := counter + cw (7 downto 0);

Aunque el "contador" tiene 16 bits y estoy agregando un std_logic_vector de 8 bits, no tuve que concatenar con:

counter  := ("0000000" & cw (7 downto 0) ) + counter;

Este método en realidad no es robusto ya que solo asume números sin firmar. El método anterior controla la extensión de signo si se utiliza la biblioteca, ieee.std_logic_signed.all,

    
respondido por el user929404
2

No dices lo que quieres que haga el código, pero puedo ver un par de áreas problemáticas. La primera es que no tiene ninguna lógica de reinicio en su proceso. Es importante asegurarse de que inicializa correctamente todo para evitar un funcionamiento inusual. Sin embargo, esto probablemente no sea la causa de su problema.

Lo que creo que está causando la operación incorrecta es que está buscando que la señal del reloj sea alta en lugar de verificar que el reloj pase de baja a alta. Esto se llama el "borde ascendente" del reloj. La lógica síncrona funciona en los bordes del reloj en lugar de en los niveles del reloj.

Usted menciona que no debería tener que buscar un flanco ascendente ya que el reloj está en la lista de sensibilidad y, por lo tanto, si su proceso se ejecuta, solo puede verificar el nivel del reloj. Esto puede ser teóricamente cierto, pero las herramientas de síntesis funcionan al inferir la lógica del lenguaje utilizado para describirlo. La mayoría de las herramientas de síntesis que he usado están diseñadas para producir la lógica correcta cuando se describe a continuación.

process(clock, reset)

variable counter : std_logic_vector (15 downto 0) :=  x"0000";
variable op : std_logic_vector (7 downto 0);

begin

if reset = '1' then
    -- reset everything to a known state here

elsif rising_edge(clock) then
    op := cw(15 downto 8);

    if op = x"20" then
        counter := counter + cw(7 downto 0);
    end if;

    counter := counter + 2;
    ia <= counter;
end if;
end process;

Escribir un buen HDL tiene tanto que ver con corregir la lógica como con describirlo en la forma en que las herramientas de síntesis esperan verlo. Si decides "es lo mismo" y escribes las cosas de una manera no estándar, puedes encontrar que el simulador te dice una cosa pero el sintetizador no lo ve de la misma manera. Este es un buen punto para aprender, y uno que puede causarle muchos dolores de cabeza y frustración en caso de que decida lo contrario.

    
respondido por el akohlsmith
0

En teoría ...

process (clock)
...
begin
   if (clock = '1') then

debería simular lo mismo que

process (clock)
...
begin
   if rising_edge(clock) then

pero no sé si el simulador de Altera se se comportará de la misma manera que el primer código es "inusual" y, por lo tanto, posiblemente no esté probado.

El hecho de que tus formas de onda de simulación parecen mostrar una breve transición de otra cosa entre [0] [29] y [0] [11] me hace preguntarme si algo extraño está ocurriendo en la programación del simulador.

    
respondido por el Martin Thompson

Lea otras preguntas en las etiquetas