VHDL para almacenar solo elementos únicos en una matriz

0

Quiero que mi componente reciba datos y los almacene en una matriz, solo si aún no está en la matriz. Debería ser simple ¿verdad?

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


entity repetition is
  port(
    data_in: in unsigned(6 downto 0);
    start  : in std_logic;
    output  : out unsigned(6 downto 0));
end entity;

architecture arh of repetition is
signal i: integer := 0;
type niz is array (6 downto 0) of unsigned(6 downto 0);
signal niz1: niz;
signal repeat: std_logic := '0';
begin
process(start, repeat)
variable ind : std_logic := '0';
begin
if( to_integer(data_in) < 100) then
    if (start='0' or repeat = '1') then

        for j in 0 to 6 loop
            if(j<i) then
                if(data_in = niz1(j)) then
                    ind := '1';
                end if;
            end if;
        end loop;   
        if (ind = '0') then
            niz1(i)<=data_in;
            i<=i+1;
            output<=data_in;
            repeat <= '0';
        else
            repeat <= '1';
        end if;
    end if;
end if;
end process;
end arh;

i es un número entero que nos dice cuánto hemos avanzado en una matriz (de longitud 7), repetir está en la lista de sensibilidad del proceso, que se utiliza para reiniciar procesar si un elemento ya está presente en la matriz y salida genera la entrada única más nueva. Cuando ejecuto esto, salida es todo 0s.

Lo que es realmente interesante es si pongo if (ind = '1'), toma la rama siempre, es decir, creo que es de alguna manera una actualización anticipada de i y de array , antes de que finalice el bucle, por lo que siempre encuentra que los datos que verifica están en el array.

¿Cómo corrijo esto?

    
pregunta rkcepelin

1 respuesta

3

Lamento decirlo, pero hay muchos errores aquí que no sé por dónde empezar. Básicamente, comete el error común que veo con la mayoría de los principiantes en VHDl / Verilog: Usted escribe el código como si fuera un programa de computadora. No es un programa de computadora. Es un lenguaje de simulación de hardware. Los errores más comunes que veo (también aquí) son:

  • No se está inicializando la variable mediante un restablecimiento
  • Reutilizando una variable varias veces
  • Mezcla combinatoria y registro de secciones
  • Pensando que los módulos / procesos / arquitecturas son una especie de funciones que se llaman cada vez.

El último es el error más común y más grande que debes sacar de tu mente. El código representa el hardware que se "instanciará" y luego se debe introducir en los datos y hay que capturar lo que sale. Y todo su hardware en todos sus archivos funciona al mismo tiempo.

No voy a reescribir el código. Te puedo dar algunos consejos y orientación:

  1. Encuentre el código VHDL de otros y estudie lo que hacen. Trate de entender por qué hacen las cosas de esa manera.
  2. Agrega un reloj y un reinicio, no tienes ninguno.
  3. Deje de inicializar sus variables: "señal i: entero: = 0;" Funciona solo en bancos de pruebas. De hecho, deploro toda la idea y me gustaría verla eliminada de VHDL.
  4. Separa tu control de tus datos. Así dividir el código en dos partes. Una parte comprueba si los datos ya están en la matriz. La otra parte que almacena los datos si no lo está. Sugerencia: la parte que se compara tiene una salida única: acierto / error.
  5. Ahora que tiene un reloj, decida qué tan rápido debe ser su comparación. ¿Un ciclo de reloj, dos ciclos de reloj, 8 ciclos de reloj? Dependerá de su flujo de datos. ¿Con qué frecuencia llega un nuevo elemento de datos?
  6. A partir de eso, debe implementar el código para 8, 4 o una comparación a la vez.

Edición de publicación: inicialización
Hay algunos comentarios sobre la inicialización. Permítanme profundizar un poco más en eso.
Como se mencionó, la inicialización en el código de comportamiento está bien. Funcionará en la mayoría de los FPGA si usa cero, pero nunca funcionará en ASIC (mi fondo). Pero en todos los casos, el usuario debe ser muy cuidadoso y darse cuenta de lo que está haciendo. Ahora déjame tomar un ejemplo basado en el código anterior:

process(...)
variable found_it std_logic := '0';

La idea errónea es que esto es equivalente a C:

void proces(...)
{ int found_it = 0;

Pero de hecho está más cerca de:

void proces(...)
{ static int found_it = 0;

La variable se establece en cero una vez y solo una vez: cuando se crea una instancia del código. Si luego lo configura en '1' en un bucle, no se restablecerá nuevamente. Es un peligro potencial para los programadores que provienen de un fondo de software.

    
respondido por el Oldfart

Lea otras preguntas en las etiquetas