Предупреждение (10631): Предупреждение оператора процесса VHDL: вывод защелки (ей) для сигнала или переменной - PullRequest
1 голос
/ 28 сентября 2019

Я пытаюсь научиться кодировать на VHDL, и приведенный ниже код не выдает никаких ошибок при компиляции, но выдает мне защелкивающееся предупреждение.Мне нужно избавиться от этой защелки, поскольку я считаю, что это вызывает у меня проблемы с моим следующим фрагментом кода, который будет использовать этот (множитель 8x8).

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
USE IEEE.NUMERIC_STD.ALL;

ENTITY control IS
    PORT (
        clk, reset_a, start : IN STD_LOGIC;
        count : IN UNSIGNED (1 DOWNTO 0);
        input_sel, shift_sel : OUT UNSIGNED(1 DOWNTO 0);
        state_out : OUT UNSIGNED(2 DOWNTO 0);
        done, clk_ena, sclr_n : OUT STD_LOGIC
        );

END ENTITY control;

ARCHITECTURE logic OF control IS

    type logic_state is (idle, lsb, mid, msb, calc_done, err);

    signal current_state: logic_state;
    signal next_state: logic_state;

BEGIN
    PROCESS (clk, reset_a)
    BEGIN
        if reset_a = '1' then
            current_state <= idle;
        elsif rising_edge (clk) then
            current_state <= next_state;
        end if;
    END PROCESS;

    PROCESS (current_state, start, count)
    BEGIN

    CASE current_state IS
        when idle =>
        if start = '1' then
            next_state <= lsb;
        else
            next_state <= idle;
        end if;

        when lsb =>
        if start = '0' and count = "00" then
            next_state <= mid;
        else
            next_state <= err;
        end if;

        when mid =>
        if start = '0' then
            if (count = "01") then
                next_state <= mid;
            elsif (count = "10") then
                next_state <= msb;
            else
                next_state <= err;
            end if;
        end if;

        when msb =>
        if start = '0' then
            if (count = "11") then
                next_state <= calc_done;
            else
                next_state <= err;
            end if;
        end if;

        when calc_done =>
        if start = '0' then
            next_state <= idle;
        else
            next_state <= err;
        end if;

        when err =>
        if start = '1' then
            next_state <= lsb;
        else
            next_state <= err;
        end if;

    END CASE;
    END PROCESS;

    mealy: PROCESS (current_state, start, count) 
    BEGIN     
        input_sel <= "00";
        shift_sel <= "00";
        done <= '0';
        clk_ena <= '0';
        sclr_n <= '1';

    CASE current_state IS
        when idle =>
        if start = '1' then
            sclr_n <= '0';
            clk_ena <= '1';
        END IF;

        when lsb =>
        if start = '0' and count = "00" then
            sclr_n <= '1';                                                                       
        end if;

        when mid =>
        if start = '0' then
            if (count = "01") then
                input_sel <= "01";
                shift_sel <= "01";
            elsif (count = "10") then
                input_sel <= "10";
                shift_sel <= "01";
            end if;
        end if;

        when msb =>
        if start = '0' then
            if (count = "11") then
                input_sel <= "11";
                shift_sel <= "10";
            end if;
        end if;

        when calc_done =>
        if start = '0' then
            input_sel <= "00";
            shift_sel <= "00";
            done <= '1';
            clk_ena <= '0';
        end if;

        when err =>
        if start = '1' then
            input_sel <= "00";
            shift_sel <= "00";
            done <= '0';
            clk_ena <= '1';
            sclr_n <= '0';
        end if;

    END CASE;
    END PROCESS mealy;

    moore: PROCESS(current_state)
    BEGIN
        state_out <= "000";

    CASE current_state IS
        WHEN idle =>

        WHEN lsb =>
            state_out <= "001";

        WHEN mid =>
            state_out <= "010";

        WHEN msb =>
            state_out <= "011";

        WHEN calc_done =>
            state_out <= "100";

        WHEN err =>
            state_out <= "101";

    END CASE;
    END PROCESS moore;
END ARCHITECTURE logic;

Я получаю следующее предупреждение:

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

Это указывает на этот узел (строка 33):

    PROCESS (current_state, start, count)

И это предупреждение приводит к другим предупреждениям (для каждого типа .idle, .mid, .msb и т. Д.):

Warning (13012): Latch next_state.idle_218 has unsafe behavior
    Warning (13013): Ports D and ENA on the latch are fed by the same signal start

Спасибо!

1 Ответ

1 голос
/ 29 сентября 2019

строка 33 находится во втором процессе (без метки).

Почему существуют предполагаемые защелки?

См. Стандарт IEEE 1076.6-2004 (отозвано) Синтез RTL
6.2.1.1 Чувствительное к уровню хранилище из процесса со списком чувствительности

Чувствительный к уровню элемент памяти должен моделироваться для сигнала (или переменной), когда применяются все следующие условия:

a) Сигнал (или переменная) имеет явное присвоение.
b) Сигнал (или переменная) не имеет пути выполнения в качестве условия.
c) Существуют исполнения процесса, которые не выполняютсяявное присвоение (через оператор присваивания) сигналу (или переменной).

По умолчанию эффект от присвоения идентификатора сигналу (или переменной) должен быть таким, как если бы назначение отсутствовало.Если комбинационный атрибут украшает сигнал (или переменную), должна быть синтезирована комбинационная логика с обратной связью.

Чтобы избежать непреднамеренных защелок, поскольку условие c) должно быть недействительным.

Примерв коде вопроса, который может вызвать защелки:

        when msb =>
        if start = '0' then
            if (count = "11") then
                next_state <= calc_done;
            else
                next_state <= err;
            end if;
        end if;

Отсутствует оператор else для внешнего оператора if и соответствует правилу c), приведенному выше.Это можно вылечить:

        when msb =>
        if start = '0' then
            if (count = "11") then
                next_state <= calc_done;
            else
                next_state <= err;
            end if;
        else  -- now all binary values of start in state msb assign next_state
            next_state <= msb;
        end if;

Вы можете присвоить значение цели перед оператором if, который в противном случае соответствует c):

        when msb =>
        next_state <= msb;  -- not always assigned in the if statement
        if start = '0' then
            if (count = "11") then
                next_state <= calc_done;
            else
                next_state <= err;
            end if;
        end if;

В последовательности операторов 'default'назначение происходит, если не перезаписано последующим присваиванием в операторе if.

В коде вопроса есть другие случаи в) проблем (в том числе в других процессах), которые могут быть обработаны аналогичным образом.

...