Xilinx ISE advierte que una señal se recorta ya que tiene un valor constante de 0, pero la señal se usa dentro de mi código

3

He creado el siguiente módulo VHDL, que se utiliza como un contador arriba / abajo.

entity counter is
Port(clk        : in  STD_LOGIC;
     count_clk  : in  STD_LOGIC;
     reset      : in  STD_LOGIC;
     count_up   : in  STD_LOGIC;
     count_down : in  STD_LOGIC;
     counting   : out STD_LOGIC;
     value      : out signed(19 downto 0));
end counter;

architecture Behavioral of counter is
    signal temp_value   : signed(19 downto 0) := (others => '0');
    signal last_clk_val : STD_LOGIC           := '0';
begin
process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        if (last_clk_val = '0' and count_clk = '1') then
            if (count_up = '1') then
                temp_value <= temp_value + 1;
            elsif (count_down = '1') then
                temp_value <= temp_value - 1;
            end if;
        end if;
    end if;
end process;
last_clk_val <= count_clk;
counting     <= count_up or count_down;
value        <= temp_value;
end Behavioral;

ISE me presenta la siguiente advertencia (para cada bit de temp_value):

WARNING:Xst:1896 - Due to other FF/Latch trimming, FF/Latch <ttl_top_inst/COUNTER_COMPONENT/temp_value_0> has a constant value of 0 in block <ttl_oneshot_inputs_top>. This FF/Latch will be trimmed during the optimization process.

Al agregar las siguientes líneas al código marcado con - LAS LÍNEAS AÑADIDAS elimina la advertencia, pero el valor de temperatura no debe modificarse en ese punto del código.

entity counter is
Port(clk        : in  STD_LOGIC;
     count_clk  : in  STD_LOGIC;
     reset      : in  STD_LOGIC;
     count_up   : in  STD_LOGIC;
     count_down : in  STD_LOGIC;
     counting   : out STD_LOGIC;
     value      : out signed(19 downto 0));
end counter;

architecture Behavioral of counter is
    signal temp_value   : signed(19 downto 0) := (others => '0');
    signal last_clk_val : STD_LOGIC           := '0';
begin
process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        if (last_clk_val = '0' and count_clk = '1') then
            if (count_up = '1') then
                temp_value <= temp_value + 1;
            elsif (count_down = '1') then
                temp_value <= temp_value - 1;
            end if;
        else --ADDED LINES
            temp_value <= temp_value - 1; --ADDED LINES
        end if;
    end if;
end process;
last_clk_val <= count_clk;
counting     <= count_up or count_down;
value        <= temp_value;
end Behavioral;

El código funciona sin problemas en la simulación, pero sé que la simulación no es igual a la implementación real.

¿Podría alguien darme instrucciones sobre cómo solucionar este problema?
Gracias de antemano!

    
pregunta Jazula

1 respuesta

7

Porque esta línea:

last_clk_val <= count_clk;

está fuera del proceso cronometrado, ambas señales tendrán el mismo valor en el hardware (y también en la simulación después de un ciclo delta 1 ). Por lo tanto, esta condición dentro de su proceso

if (last_clk_val = '0' and count_clk = '1') then

nunca será cierto y el proceso será equivalente a:

process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        null;
    end if;
end process;

Junto con la inicialización de la señal, esto da un valor constante de todos '0' para temp_value .

Si desea retrasar count_clk durante un ciclo para detectar un flanco ascendente en esta señal, debe mover la asignación de last_clk_val dentro del proceso:

process(clk, reset)
begin
    if (reset = '1') then
        temp_value <= (others => '0');
    elsif (rising_edge(clk)) then
        if (last_clk_val = '0' and count_clk = '1') then
            if (count_up = '1') then
                temp_value <= temp_value + 1;
            elsif (count_down = '1') then
                temp_value <= temp_value - 1;
            end if;

        last_clk_val <= count_clk;  -- moved here
    end if;
end process;

En la simulación, todas las asignaciones de señal se retrasan. Si no se da ningún retraso, entonces la asignación de la señal se retrasa por un ciclo delta. Por lo tanto, si count_clk cambia, entonces count_clk diferirá de last_clk_val para un ciclo delta en el código original. En el hardware, ambas señales están representadas por el mismo cable.

    
respondido por el Martin Zabel

Lea otras preguntas en las etiquetas