VHDL не может управлять выводами нагрузки

Используя первый фрагмент кода, я получаю эту ошибку из-за того, что куча моих сигналов не приводит к выводам. Я почти уверен, что это потому, что в первом фрагменте кода первый оператор if никогда не достигается. Почему это так? Во втором фрагменте я изменил код, и все мои проблемы были исправлены. Я сделал изменение как интуитивный импульс, я понятия не имею, почему это все исправило. Может ли кто-нибудь объяснить, как синтезатор генерирует схему?

Первый фрагмент:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity DataReg is
    generic(N: integer := 8);
    port(DIN: in std_logic_vector(N - 1 downto 0);
    DOUT: out std_logic_vector(N - 1 downto 0);
    CLK: in std_logic;
    ENABLE: in std_logic;
    RESET: in std_logic);
end DataReg;

architecture Behavioral of DataReg is
begin
    process(CLK, ENABLE)    
    begin
        if rising_edge(CLK) and ENABLE = '1' then
            DOUT <= DIN;
        end if;

        if rising_edge(CLK) and RESET = '1' then
            DOUT <= (others => '0');
        end if;
    end process;
end Behavioral;

Второй фрагмент: (исправленный код)

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;

entity DataReg is
    generic(N: integer := 8);
    port(DIN: in std_logic_vector(N - 1 downto 0);
    DOUT: out std_logic_vector(N - 1 downto 0);
    CLK: in std_logic;
    ENABLE: in std_logic
    RESET: in std_logic);
end DataReg;

architecture Behavioral of DataReg is
begin
    process(CLK, ENABLE)    
    begin
        if rising_edge(CLK) then
            if ENABLE = '1' then
                DOUT <= DIN;
            elsif RESET = '1' then
                DOUT <= (others => '0');
            end if;
        end if;
    end process;
end Behavioral;

person Chiorean Tudor    schedule 10.05.2018    source источник
comment
может ли быть так, что RESET зафиксировано как '1' где-то еще в коде? (Или ENABLE в '0'..)   -  person JHBonarius    schedule 10.05.2018
comment
Это не фрагменты. VHDL называет их единицами проектирования, двумя наборами единиц проектирования, каждая из которых состоит из первичной единицы проектирования (объекта) и вторичной единицы проектирования (архитектуры). Структуры для вывода последовательной логики изначально были стандартизированы (Стандарт IEEE 1076.6-2004, в настоящее время отозван, VHDL RTL Synthesis), а форма, включающая оператор if, требует, чтобы оценка сброса и фронта тактового сигнала была одним оператором if (и ваш второй 'snippet ' делает это). Без указания поставщика синтеза в его документации будут указаны по крайней мере некоторые из поддерживаемых (предпочтительных) форм.   -  person    schedule 10.05.2018


Ответы (2)


Потому что HDL-код должен уметь представлять существующее оборудование. Поэтому, когда вы пишете код RTL (уровень передачи регистра), вы должны придерживаться определенных структур. Даже второй код, который вы написали, неверен.

Я не могу объяснить все правила, но в основном, чтобы использовать фронт (растущий или падающий), у вас может быть только один сигнал. Не OR-es или And-es и т.д.:
if rising_edge(CLK) then

В такой тактовой секции ваш процесс может иметь на один или два сигнала чувствительности больше. Часто бывает асинхронный сброс, в некоторых исключительных случаях бывает и асинхронный набор. Чтобы они работали, вы должны поместить условие перед часами. Поэтому ваш код неверен. Ваши ENABLE и RESET рассматриваются только при наличии фронта тактового сигнала. Таким образом, добавление ENABLE в список чувствительности является излишним. С тем же успехом вы могли бы оставить это.

Кроме того, ENABLE if предшествует RESET. Таким образом, если ENABLE высокий, ваш RESET будет проигнорирован. Наверное, это не то, что вы хотите!

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

process(clk, reset_n) 
begin
    if (reset_n='0') then

    elsif rising_edge(clk) then

    end if; -- reset/clocked
end process;
person Oldfart    schedule 10.05.2018
comment
Я не уверен, что с синхронным сбросом в его коде что-то не так, просто подразумеваемый приоритет включения/сброса кажется странным. Лично я бы не рекомендовал использовать асинхронный сброс по умолчанию. - person scary_jeff; 10.05.2018
comment
Я не говорил, что синхронные сбросы это плохо. Я родом из мира ASIC, где предпочитают асинхронный сброс. Также в FPGA я бы не стал их использовать, поскольку они потребляют ресурсы. - person Oldfart; 10.05.2018
comment
Достаточно справедливо в мире ASIC, я мало что знаю об этом. Каков сценарий, когда сброс синхронизации использует больше ресурсов в FPGA? - person scary_jeff; 10.05.2018
comment
Вам нужно передать сброс в LUT, чтобы обнулить ввод, что будет стоить вам ввода. Но большинство (все?) ПЛИС уже имеют сеть асинхронного сброса регистров, которая вам ничего не стоит. - person Oldfart; 10.05.2018

Прежде всего, два фрагмента кода, которые вы представляете, даже не эквивалентны в симуляторе, потому что, когда ENABLE и RESET оба равны 1 на фронте часов, первый фрагмент приводит к тому, что DOUT равен 00000000, тогда как во втором он оценивается как DIN.

У меня сложилось впечатление, что списки чувствительности (часть в скобках после process) игнорируются при синтезе Xilinx Vivado. Я считаю их пережитком тех времен, когда инструменты моделирования не могли позволить себе определить, какие переменные следует отслеживать, чтобы определить, когда переменные должны быть обновлены. Я не знаю, что с ними делают другие инструменты синтеза.

В любом случае, вы указали ENABLE в своем списке конфиденциальности, что означает, что вы хотите оценить операторы процесса, если ENABLE изменит значение. Все операторы if оцениваются как ложные, если только не происходит нарастающий фронт тактового сигнала. Поэтому для симуляции достаточно одного CLK в списке чувствительности.

При этом вы должны ограничить свой код форматами, явно рекомендованными поставщиком инструмента синтеза. Инструменты синтеза могут реализовать только подмножество всего, что вы можете написать на VHDL. Для Vivado рекомендуемую структуру кода можно найти в синтезе. руководство (это для Vivado 2017.3). На странице 71 вы увидите, что они рекомендуют триггеры вида:

process(clk) is
begin
    if rising_edge(clk) then
        if clr = '1' then
            dout <= "00000000";
        elsif ce = '1' then
            dout <= d_in;
        end if;
    end if;
end process;

Конечно, вы можете переименовать переменные по мере необходимости. На странице 69 вы также увидите, что Xilinx рекомендует использовать синхронные реализации (помещая все в оператор rising_edge if) вместо асинхронных реализаций. В руководстве есть гораздо больше, например, о том, как писать регистры сдвига или ОЗУ, с которыми вам следует ознакомиться, если вы хотите писать код для синтеза с помощью Vivado. Другие поставщики имеют аналогичную документацию с рекомендуемым кодом.

person Gyzuh    schedule 10.05.2018
comment
вы должны ограничить свой код форматами, которые явно рекомендуются поставщиком инструмента синтеза, но это не совсем так. Проблема, например, в том, что поставщики инструментов не обновляют регулярно свои руководства пользователя. Xilinx, например, все еще использует устаревший пакет std_logic_arith в своих рекомендациях... - person JHBonarius; 11.05.2018
comment
Я считаю их пережитком тех времен, когда инструменты моделирования не могли позволить себе определить, какие переменные следует отслеживать... Я не знаю, что с ними делают другие инструменты синтеза. IEEE Std 1076.6-2004 (отозван , RTL Synthesis), 5. Методология проверки Процесс проверки результатов синтеза с использованием моделирования состоит из применения эквивалентных входных данных как к исходной модели, так и к синтезированной... Отдельный анализ (компиляция) и уточнение (связывание/загрузка) требуют списков чувствительности. Ограничение списков конфиденциальности, например. ( clk, rst) может повысить производительность по сравнению с зарезервированным словом all в -2008. - person ; 12.05.2018