5 — разрядный счетчик D-триггеров в VHDL Приводит к неопределенным результатам

#vhdl #xilinx

Вопрос:

Я пытаюсь создать этот 5-разрядный счетчик, используя (восходящий край) D-триггеры со сбросом и включением CK с использованием VHDL, но возвращаемое значение всегда не определено, что бы я ни делал. Я могу убедиться, что триггер работает идеально. Проверьте приведенный ниже код:

DFF.vhd

 library IEEE;
use IEEE.std_logic_1164.all;

entity DFFis
    port(
        D:  in std_logic; -- Data input
        C:  in std_logic; -- Clock input
        CE:     in std_logic; -- Clock enable
        CLR:    in std_logic; -- Asynchronous reset
        Q:  out std_logic -- Data output
    );
end DFF;


architecture arch of DFF is
    signal q_i: std_logic;
begin
    process(C, CE, CLR)
    begin
        if (CLR='1') then
            Q<='0';
        elsif (rising_edge(C)) and (CE ='1') then
            Q<=D;
        end if;
    end process;
end arch;
 

счетчик.vhd

 library IEEE;
use IEEE.std_logic_1164.all;

entity counter is
    port (
        C:  in std_logic; 
        CLR:    in std_logic;
        bits: out std_logic_vector(4 downto 0)
    );
end counter;

architecture arch of counter is
    component DFF
        port(
            D:  in std_logic; -- Data input
            C:  in std_logic; -- Clock input
            CE:     in std_logic; -- Clock enable
            CLR:    in std_logic; -- Asynchronouse reset
            Q:  out std_logic -- Data output
        );
    end component;
    signal q: std_logic_vector(4 downto 0); 
    signal nq: std_logic_vector(4 downto 0);
    
begin
    
    bits<=q;
    
    q(0) <= '1';
    nq <= not q;
    
    DFF0: DFF port map (
        D=>nq(0),
        C=>C,
        CE=>'1',
        CLR=>CLR,
        Q=>q(0)
    );
    DFF1: DFF port map (
        D=>nq(1),
        C=>nq(0),
        CE=>'1',
        CLR=>CLR,
        Q=>q(1)
    );
    DFF2: DFF port map (
        D=>nq(2),
        C=>nq(1),
        CE=>'1',
        CLR=>CLR,
        Q=>q(2)
    );
    DFF3: DFF port map (
        D=>nq(3),
        C=>nq(2),
        CE=>'1',
        CLR=>CLR,
        Q=>q(3)
    );
    DFF4: DFF port map (
        D=>nq(4),
        C=>nq(3),
        CE=>'1',
        CLR=>CLR,
        Q=>q(4)
    );
end arch;
 

И в целях тестирования, counter_TB.vhd

 library IEEE;
use IEEE.std_logic_1164.all;

entity counter_TB is
end counter_TB;

architecture arch of counter_TB is
    component counter
        port(
            C:  in std_logic; 
            CLR:    in std_logic;
            bits: out std_logic_vector(4 downto 0)
        );
    end component;
    signal C: std_logic:='0';
    signal CLR: std_logic:='0';
    signal bits: std_logic_vector(4 downto 0);
begin
    test: counter port map (C=>C, CLR=>CLR, bits=>bits);
    
    process
    begin
        C<='1'; CLR<='0'; 
        wait for 1 us;
        C<='0'; CLR<='0'; 
        wait for 1 us;
        C<='1'; CLR<='0'; 
        wait for 1 us;
    end process;
end arch;
 

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

Результат

Я попытался инициализировать сигнал q на «00000» и «00001», но результат был тот же.

Ответ №1:

В представленном здесь коде есть три заметные ошибки.

Во-первых, в объявлении сущности DFF отсутствует разделитель (пробел) между DFF и is.

Во-вторых, в архитектуре арки счетчика есть два драйвера для сигнала q(0). Параллельное присвоение q(0) должно быть удалено.

В-третьих, тестовый стенд не обеспечивает условие CLR = ‘1’ для очистки в DFF. Перевернутая буква «U» — это «U».

     process
    begin
        C<='1'; -- CLR<='1';
        if now < 1 us then 
            CLR <= '1';
        end if;
        wait for 1 us;
        C<='0'; CLR<='0'; 
        wait for 1 us;
        -- C<='1'; CLR<='0';
        -- wait for 1 us;
    end process;
 

Это приводит к:
counter_tb.jpg

(Этот пример изменения не является всеохватывающим в качестве метода обеспечения сброса в среде тестирования.)