VHDL не может управлять нагрузкой - PullRequest
0 голосов
/ 10 мая 2018

Используя первый фрагмент кода, я получаю эту ошибку, что куча моих сигналов не выводила пинов.Я почти уверен, что это потому, что в первом фрагменте кода первый оператор 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;

Ответы [ 2 ]

0 голосов
/ 10 мая 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 рекомендует использовать синхронные реализации (помещая все внутри оператора if rising_edge) над асинхронными реализациями. В руководстве есть гораздо больше, например, о том, как записывать сдвиговые регистры или ОЗУ, с которыми вам следует ознакомиться, если вы хотите написать код, синтезируемый с помощью Vivado. Другие поставщики имеют аналогичную документацию с рекомендуемым кодом.

0 голосов
/ 10 мая 2018

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

Я не могу объяснить все правила, но в принципе, для использования ребра (повышения или понижения) у вас может быть только один сигнал.Не «ИЛИ» или «И» и т. Д.:
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;
...