FIFO: duda en proceso (clk)

0
library IEEE;  
use IEEE.STD_LOGIC_1164.ALL;  
use IEEE.STD_LOGIC_ARITH.ALL;  
--use IEEE.STD_LOGIC_UNSIGNED.ALL;  
use ieee.std_logic_signed.all;  

entity fifo is  
    port (  clk : in std_logic;  
          read_data : in   std_logic;                                       --enable read,should be '0' when not in use.  
          insert : in   std_logic;                                          --enable write,should be '0' when not in use.  
          delete : in std_logic;  
          datain : in std_logic_vector (7 downto   0);                      --input data  
          dataout : out std_logic_vector(7 downto   0);                 --output data           
          empty : out std_logic :=   '1';                                   --set   as '1' when the queue is empty  
          full : out std_logic  :=   '0';                                       --set as '1' when the queue is full  
          no_insert : out std_logic;  
          no_delete : out std_logic  
         );  
end fifo;  

architecture Behavioral of fifo is  
    type memory_type is array (0 to 255) of std_logic_vector(7 downto 0);  
    signal memory : memory_type :=(others => (others =>   '0'));            --memory for queue.  
    signal rp,wp,tmp_ptr : std_logic_vector(7 downto 0) :="00000000";       --read and write pointers.  
    signal isfull : std_logic := '0';  
    signal isempty : std_logic := '1';  
    begin  
        --dataout <= "00000000";  
        process(clk)  
        begin  
            -- Reading Process                     
                -- Read when not empty  
                -- empty when Write_ptr = Read_ptr  
                -- increment as 0 1 2....255 0 1 2....255  
                -- If Last_wrt is high set low Last_rd,  
                -- overwrite Last_rd as high if actually   reading take place  
            if(clk'event and clk='1' and read_data ='1')   then                         --read the tail of FIFO  
                --if(isempty = '1') then  
                --  dataout <= "00000000";  
                --else   
                    dataout <= memory(conv_integer(rp));  
                --end if;  
            end if;  
            if(clk'event and clk='1' and insert ='1')   then                                --insert on the   top/head of FIFO  
                --if(isfull = '1') then   
                    --no_insert <= '1 ;  
                    --dataout <= "00000000";  
                --else  
                    no_insert <= '0';  
                    memory(conv_integer(wp)) <= datain;  
                    dataout <= datain;  
                    --if(wp = "11111111") then  
                    --  wp <= "00000000";  
                    --else   
                    --  wp <= wp + 1;  
                    --end if;  
                --end if;  
                --if(wp = rp) then  
                --      full <= '1';  
                --      isfull <= '1';  
                --  else   
                --      full <= '0';  
                --      isfull <= '0';  
                --end if;  
            end if;  

            if(clk'event and clk='1' and delete ='1')   then                            --pop/delete the tail   of FIFO  
                --if(isempty = '1') then  
                --  no_delete <='1';  
                --  dataout <= "00000000";  
                --else   
                    no_delete <= '0';  
                    dataout <= memory(conv_integer(rp));  
                --  if(rp = "11111111") then  
                --      rp <= "00000000";  
                --  else   
                        rp <= rp + 1;  
                --  end if;  
                --  if(rp = wp) then  
                --      empty <= '1';  
                --      isempty <= '1';  
                --  else  
                --      empty <= '0';  
                --      isempty <= '0';  
                --  end if;  
                --end if;  
            end if;  
            if(rp = "11111111")   then                                          --resetting read pointer.  
                rp <= "00000000";  
            end if;  
            if(wp = "11111111")   then                                          --resetting read pointer.  
                wp <= "00000000";  
            end if;  

            if(wp = rp and insert = '1')   then                                         --checking whether queue is full or not  
                full <='1';               
            else  
                full <='0';  
            end if;  

            if(wp = rp and delete = '1')   then                                     --checking whether queue is empty or not  
                empty <='1';  
            else  
                empty <='0';  
            end if;       
        end process;  

end Behavioral;

En el código vhdl anterior para FIFO no estoy obteniendo la simulación de escritura de testbench. A pesar de que el búfer FIFO no está lleno, entonces también el lleno se vuelve igual a 1. ¿Puede alguien por favor ayudarme a solucionar el error?

cuando el proceso (clk) se ejecuta cada vez que se hace clic en clk tick, ¿qué ocurre exactamente ... se llaman todos los ifs simultáneamente? Me refiero a todas las funciones diferentes en el proceso (clk) que bloquea el ron al mismo tiempo en paralelo?

    
pregunta zyxwvu

3 respuestas

4

Su problema es que está mezclando lógica combinacional y secuencial .

Cada proceso debe ser combinacional o secuencial. Los procesos secuenciales tienen todo (excepto las sentencias de restablecimiento dentro de una detección de reloj ( if rising_edge(clk) o if clk'event and clk='1' ). Los procesos combinacionales tienen una lista de sensibilidad que contiene todas las señales que usted lee.

Si bien su código es perfectamente legal e incluso determinista , no hay una manera fácil de predecir cómo se sintetizará, por lo que no es adecuado para RTL código .

    
respondido por el Philippe
1

Para su pregunta específica sobre la señal full , definitivamente estará llena ya que tanto wp como rp son 0 al comienzo. Además, no está utilizando un registro para marcar la señal completa . Esto puede potencialmente generar fallos en la salida.

Le aconsejo que deje de pensar en esto en términos de código, pero que lo haga en términos de hardware, es decir, en lugar de preguntar si los 'ifs se llaman simultáneamente' piense cómo se conectan las señales a través de multiplexores. registros y memoria.

Luego, codifique de acuerdo con el hardware que le gustaría generar, y no al revés. Hay una razón por la que es un 'Lenguaje de descripción de hardware'.

Para empezar, hay varios ejemplos de diseños FIFO que quizás desee estudiar primero.

¡Buena suerte!

    
respondido por el sybreon
1

El problema es que las señales de control de inserción y eliminación habilitan sus indicadores completos y vacíos. La bandera completa solo se activará cuando wp = rp e inserte = '1'. Si inserta / = '1', no se activará su marca completa. Por lo tanto, a menos que esté insertando activamente un artículo en la FIFO, no le dirá que está lleno.

Además, el indicador completo debería estar cuando el puntero de escritura + 1 = puntero de lectura (es decir, si agregar un elemento haría que el puntero de escritura fuera igual al puntero de lectura).

Debería deshacerse de las comprobaciones "Insertar = '1'" y "Eliminar = '1'", de modo que sus indicadores completos y vacíos se activarán independientemente de las señales de control.

Directamente dentro de su bloque de Proceso debería ser solo una sentencia if, que es clk'event o rising_edge (prefiero rising_edge). Esto representa la entrada de reloj de todos los flops.

Todas sus otras declaraciones if están anidadas dentro de rising_edge if. Esto sería como la entrada de habilitación de los flops.

Si las banderas están fuera de rising_edge si, serán combinacionales; es decir, se establecerán independientemente de la señal del reloj. Para registrar las banderas, inclúyalas dentro de rising_edge if, y solo cambiarán cuando cambie el reloj.

Con respecto a su pregunta sobre el bloque de proceso, todas las sentencias if en un bloque de proceso dado se ejecutarán simultáneamente. SIN EMBARGO, cuando las sentencias if múltiples asignan un valor a la misma señal, la última sentencia if "ganará", porque las sentencias dentro del bloque de proceso se ejecutan secuencialmente, a pesar de que ocurren simultáneamente.

Debes tener solo una línea de código con clk'event (aunque yo prefiero levantarme). Anidado dentro de este if (el cual representa las entradas de reloj de todos los flops en el bloque de proceso), hay más ifs (el cual representa las entradas de habilitación para todos los flops).

    
respondido por el ajs410

Lea otras preguntas en las etiquetas