Ayuda para resolver la advertencia "infering latch (es) for signal or variable" .. ", que mantiene su valor anterior en una o más rutas a través del proceso"

0

A continuación se muestra el código para la implementación de mi unidad de sucursal. Esta unidad calcula la dirección de destino del salto y la escribe en el registro de la PC.

Hay algunos tipos diferentes de saltos, etc., historia estándar.

library IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;
USE work.defPaket.all;

entity BR_UNIT is
Port ( 
    CLK                 : in  STD_LOGIC; -- clock
    RST                 :       in  STD_LOGIC;

    N                       : in  STD_LOGIC; -- negative
    Z                       : in  STD_LOGIC; -- zero
    C                       : in  STD_LOGIC; -- carry
    V                       : in  STD_LOGIC; -- overflow

    flushfifo           : out STD_LOGIC;
    pcOUT                   : out STD_LOGIC_VECTOR (31 downto 0);
    pcWrEn              : out STD_LOGIC;

    in1                 : in STD_LOGIC_VECTOR (31 downto 0); --input1
    in2                 : in STD_LOGIC_VECTOR (31 downto 0); --input1

    validOut                : out STD_LOGIC; --output
    wr_reg              : out STD_LOGIC;
    regOut              : out STD_LOGIC_VECTOR (4 downto 0);
    dataVal             : out STD_LOGIC_VECTOR (31 downto 0)
);

end BR_UNIT;

architecture Behavioral of BR_UNIT is

signal opc              : STD_LOGIC_VECTOR (4 downto 0);
signal newpc            : STD_LOGIC_VECTOR (31 downto 0);
signal offset           : STD_LOGIC_VECTOR (31 downto 0);

signal validOut_t       : STD_LOGIC;
signal wr_reg_t     : STD_LOGIC;
signal regOut_t     : STD_LOGIC_VECTOR (4 downto 0);
signal dataVal_t        : STD_LOGIC_VECTOR (31 downto 0);
signal pcOUT_t          : STD_LOGIC_VECTOR (31 downto 0);
signal pcWrEn_t     : STD_LOGIC;
signal flushfifo_t  : STD_LOGIC;

begin

clk_part : process (CLK)

begin

if (CLK'event and CLK = '1') then
    validOut <= validOut_t;
    wr_reg <= wr_reg_t;
    regOut <= regOut_t;
    dataVal <= dataVal_t;
    pcOUT <= pcOUT_t;
    pcWrEn <= pcWrEn_t;
    flushfifo <= flushfifo_t;
end if;

end process;

comb_part : process (in1, in2, N, Z, C, V)
    variable temp : signed(31 downto 0);

    begin

    if(
        (in1(31 downto 27) = OPC_BEQ) or
        (in1(31 downto 27) = OPC_BGT) or
        (in1(31 downto 27) = OPC_BHI) or
        (in1(31 downto 27) = OPC_BAL) or
        (in1(31 downto 27) = OPC_BLAL)
    ) then

        opc <= in1(31 downto 27);

    elsif(
        (in2(31 downto 27) = OPC_BEQ) or
        (in2(31 downto 27) = OPC_BGT) or
        (in2(31 downto 27) = OPC_BHI) or
        (in2(31 downto 27) = OPC_BAL) or
        (in2(31 downto 27) = OPC_BLAL)
    ) then

        opc <= in2(31 downto 27);

    end if;

    offset <= std_logic_vector(resize(signed(in1(26 downto 0)), 32));
    temp := signed(offset) + signed(in1(8 downto 1)) + 1;
    newpc <= std_logic_vector(signed(temp));

    regOut_t <= "00000";
    validOut_t <= '1';

        case opc is

            when OPC_BEQ =>
                if (Z = '1') then
                    flushfifo_t <= '1';
                    pcOUT_t <= newPC;
                    pcWrEn_t <= '1';
                end if;

            when OPC_BGT =>
                if (((N xor V) or Z) = '0') then
                    flushfifo_t <= '1';
                    pcOUT_t <= newPC;
                    pcWrEn_t <= '1';
                end if;

            when OPC_BHI =>
                if ((C or Z) = '0') then
                    flushfifo_t <= '1';
                    pcOUT_t <= newPC;
                    pcWrEn_t <= '1';
                end if;

            when OPC_BAL =>
                    flushfifo_t <= '1';
                    pcOUT_t <= newPC;
                    pcWrEn_t <= '1';

            when OPC_BLAL =>
                    flushfifo_t <= '1';
                    pcOUT_t <= newPC;
                    pcWrEn_t <= '1';

                    regOut_t <= "00000";
                    dataVal_t <= newpc; 
                    wr_reg_t <= '1';

            when OTHERS =>
        end case;

end process;

end Behavioral;

Quartus altera lanza las siguientes advertencias:

  

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (94): la señal "offset" se lee dentro de la Declaración de Proceso pero no está en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (100): la señal "opc" se lee dentro de la Declaración de Proceso pero no está en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (105): la señal "newpc" se lee dentro de la Declaración de Proceso pero no se encuentra en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (112): la señal "newpc" se lee dentro de la Declaración de Proceso pero no está en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (119): la señal "newpc" se lee dentro de la Declaración de Proceso pero no se encuentra en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (125): la señal "newpc" se lee dentro de la Declaración de Proceso pero no está en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (130): la señal "newpc" se lee dentro de la Declaración de Proceso pero no está en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10492): Advertencia de Declaración de Proceso VHDL en IDEXWBBranchUnit.vhd (134): la señal "newpc" se lee dentro de la Declaración de Proceso pero no está en la lista de sensibilidad de la Declaración de Proceso

     

Advertencia (10631): Advertencia de declaración de proceso VHDL en IDEXWBBranchUnit.vhd (66): inferir latch (es) para señal o variable "opc", que mantiene su valor anterior en una o más rutas a través del proceso

     

Advertencia (10631): Advertencia de declaración de proceso VHDL en IDEXWBBranchUnit.vhd (66): inferir latch (es) para la señal o variable "flushfifo_t", que mantiene su valor anterior en una o más rutas a través del proceso

     

Advertencia (10631): Advertencia de declaración de proceso VHDL en IDEXWBBranchUnit.vhd (66): inferir latch (es) para señal o variable "pcOUT_t", que mantiene su valor anterior en una o más rutas a través del proceso

     

Advertencia (10631): Advertencia de declaración de proceso VHDL en IDEXWBBranchUnit.vhd (66): inferir latch (es) para señal o variable "pcWrEn_t", que mantiene su valor anterior en una o más rutas a través del proceso

     

Advertencia (10631): Advertencia de declaración de proceso VHDL en IDEXWBBranchUnit.vhd (66): inferir latch (es) para señal o variable "dataVal_t", que mantiene su valor anterior en una o más rutas a través del proceso

     

Advertencia (10631): Advertencia de declaración de proceso VHDL en IDEXWBBranchUnit.vhd (66): inferir latch (es) para señal o variable "wr_reg_t", que mantiene su valor anterior en una o más rutas a través del proceso

Con respecto a estas advertencias sobre señales que no están en la lista de sensibilidad, ¿cómo puedo resolver eso? ¿Debo omitir su uso siempre que sea posible o utilizar variables cuando no sea posible?

La pregunta principal y principal es: qué significan estos errores:

  

Advertencia (10631): Advertencia de declaración de proceso VHDL en IDEXWBBranchUnit.vhd (66): inferir latch (es) para señal o variable "opc", que mantiene su valor anterior en una o más rutas a través del proceso

¿Qué significan y cuáles son tus sugerencias sobre cómo resolverlos?

    
pregunta idjuradj

1 respuesta

3

Supongo que, como yo, probablemente provenga de un fondo de desarrollo de software y ahora esté aprendiendo HDL.

El caso when others está vacío; Ahí es donde estás implícito haciendo todos los pestillos. Para borrar esta advertencia, establezca explícitamente el siguiente valor de la salida en su valor anterior, como x <= x; . Recuerde que este es un lenguaje de descripción de hardware, no un lenguaje de programación de computadora de procedimiento. Por lo tanto, debe pensar qué hardware real espera que implemente cada módulo.

Como regla general, cuando tiene una declaración de caso, cada cláusula (es decir, cada "ruta de ejecución" aunque sea la terminología incorrecta) - debe definir el valor de cada uno de los puertos de salida de la declaración, incluso si no hay cambios destinado a. Hay ciertos patrones de código que las herramientas de síntesis de HDL reconocen, y para obtener los mejores resultados, debe tratar de mantener esos formularios siempre que sea posible.

Respuesta al comentario:

Hay dos tipos de mesasges de advertencia aquí.

La advertencia # 10492 parece indicar que falta una señal de entrada en el sensitivity list .

Warning (10492): VHDL Process Statement warning at IDEXWBBranchUnit.vhd(105): signal "newpc" is read inside the Process Statement but isn't in the Process Statement's sensitivity list

En la separación

comb_part : process (in1, in2, N, Z, C, V)

la lista de sensibilidad solo declara in1, in2, N, Z, C, V como las señales de entrada disponibles. En términos de hardware, esto es como declarar que comb_part se implementa con un bloque de hardware que tiene estas seis entradas, y por cierto, sorpresa, aquí está esta otra señal llamada offset , que parece que estaba destinada a ser otra entrada.

offset <= std_logic_vector(resize(signed(in1(26 downto 0)), 32));

Entonces, debido a que esta es una declaración non-blocking assignment , el desplazamiento debe ser algún tipo de señal, pero ¿es un registro interno o una salida? El compilador HDL no puede decir que fue lo que se pretendía, por lo que aparece el mensaje de error.

La solución recomendada es que necesita revisar su diseño y determinar si necesita agregar esas entradas a la lista de sensibilidad.

La advertencia # 10631 parece indicar que una señal de salida tiene un inferred latch .

Warning (10631): VHDL Process Statement warning at IDEXWBBranchUnit.vhd(66): inferring latch(es) for signal or variable "flushfifo_t", which holds its previous value in one or more paths through the process

En el software se asume que las variables mantienen su valor hasta que se cambian explícitamente, pero en la síntesis de HDL que requiere un pestillo o un flip-flop. Cuando tiene un módulo HDL que describe el código en términos de declaraciones de "comportamiento" como if / else, o swtich / case, y hay al menos un non-blocking assignment en una señal, entonces cada "ruta de ejecución" debe hacer explícitamente un non -bloqueo de asignación a esa señal.

    case opc is

        when OPC_BEQ =>
            if (Z = '1') then
                flushfifo_t <= '1';
                pcOUT_t <= newPC;
                pcWrEn_t <= '1';
            end if;
        -- etc...
        when OPC_BLAL =>
                flushfifo_t <= '1';
                pcOUT_t <= newPC;
                pcWrEn_t <= '1';
                regOut_t <= "00000";
                dataVal_t <= newpc; 
                wr_reg_t <= '1';
        when OTHERS =>
                -- [MarkU] here's the problem, missing non-blocking assignments should go here
                flushfifo_t <= flushfifo_t;
                pcOUT_t <= pcOUT;
                pcWrEn_t <=pcWrEn_t;
                -- [MarkU] and so on for all the non-blocking assignments that are unchanged in this case
    end case;
    
respondido por el MarkU

Lea otras preguntas en las etiquetas