vhdl и гейт возвращают неизвестное значение

Я реализовал мультиплексор, но гейт без причины возвращает x, пожалуйста, помогите. Как вы можете видеть на скриншоте, результат просто стал x из 1. Я сделал тестовый стенд для и гейта, он отлично работает сам по себе. Это должен был быть 3-битный мультиплексор 4:1. это проблема

Это исходник, я использую ghdl.

LIBRARY IEEE;
USE IEEE.std_logic_1164.ALL;

ENTITY mux41 IS
    PORT (
        i1 : IN std_logic_vector(2 DOWNTO 0); 
        i2 : IN std_logic_vector(2 DOWNTO 0);
        i3 : IN std_logic_vector(2 DOWNTO 0);
        i4 : IN std_logic_vector(2 DOWNTO 0);
        sel : IN std_logic_vector(1 DOWNTO 0); 
        y : OUT std_logic_vector(2 DOWNTO 0)
        );
END mux41;


  
ARCHITECTURE rtl OF mux41 IS

COMPONENT andgate
PORT (
    input1 : IN std_logic;
    input2 : IN std_logic;
    input3 : IN std_logic;
    and_output : OUT std_logic
    );
END COMPONENT;

COMPONENT orgate
  PORT (
    input1 : IN std_logic;
    input2 : IN std_logic;
    input3 : IN std_logic;
    input4 : IN std_logic;
    or_output : OUT std_logic
  );
END COMPONENT;

signal not_sel : std_logic_vector(1 DOWNTO 0); 
signal and_result : std_logic_vector(3 DOWNTO 0);
signal or_result : std_logic_vector(2 DOWNTO 0);

BEGIN
    
    not_sel <= not sel;
    
    and_gate_assignment : for i in 0 to 2 generate
        and_output1: andgate port map(input1=>i1(i), input2=>not_sel(1), input3=>not_sel(0), and_output=>and_result(0));
        and_output2: andgate port map(input1=>i2(i), input2=>not_sel(1), input3=>sel(0), and_output=>and_result(1));
        and_output3: andgate port map(input1=>i3(i), input2=>sel(1), input3=>not_sel(0), and_output=>and_result(2));
        and_output4: andgate port map(input1=>i4(i), input2=>sel(1), input3=>sel(0), and_output=>and_result(3));
        or_output: orgate port map(input1=>and_result(0), input2=>and_result(1), input3=>and_result(2), input4=>and_result(3), or_output=>or_result(i));
    end generate and_gate_assignment;
    y <= or_result;
END rtl;

Вот то и ворота;

library ieee;
use ieee.std_logic_1164.all;

entity andgate is
  port (
    input1 : in std_logic;
    input2 : in std_logic;
    input3 : in std_logic;
    and_output : out std_logic
  );
end andgate;

architecture rtl of andgate is
signal and1 : std_logic;
signal and2 : std_logic;
begin
    and1 <= input1 and input2;
    and2 <= and1 and input3;
    and_output <= and2;
end rtl;

на самом деле в этом нет ничего особенного, может быть, это проблема времени?


person Tawpik Talat    schedule 11.12.2020    source источник
comment
может быть, это проблема времени? Нет. Предоставьте минимально воспроизводимый пример, ваша проблема ваши читатели не смогут воспроизвести его без orgate и тестового стенда. Оператор генерации представляет собой один или несколько операторов блока. Вы связали вместе некоторые выходы этих блоков. Объявление and_result следует переместить из декларативного элемента архитектурного блока в декларативную область блока операторов генерации and_gate_assignment (где вам понадобится следующий begin, чтобы отделить объявления от части оператора генерации).   -  person    schedule 12.12.2020
comment
Причина, вероятно, скрыта в вашем тестовом стенде, который вы не показали.   -  person user_1818839    schedule 12.12.2020
comment
Нет, проблема проявляется в mux41, где разные вентили и в трех сгенерированных блоках имеют свои выходы, связанные вместе с помощью общего объявления для and_result. Исправление заключается в перемещении объявления в область описания блока для каждого сгенерированного блока, чтобы соединения между andgates и orgate не разделялись между тремя однобитными мультиплексорами 4:1.   -  person    schedule 12.12.2020


Ответы (1)


Добавление сущности и архитектуры orgate

use ieee.std_logic_1164.all;

entity orgate is
    port (
        input1:     in  std_logic;
        input2:     in  std_logic;
        input3:     in  std_logic;
        input4:     in  std_logic;
        or_output:  out std_logic
    );
end entity;

architecture foo of orgate is
begin
    or_output <= input1 or input2 or input3 or input4;
end architecture;

и испытательный стенд

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity mux41_tb is
end entity;

architecture foo of mux41_tb is
    signal i1:     std_logic_vector(2 downto 0); 
    signal i2:     std_logic_vector(2 downto 0);
    signal i3:     std_logic_vector(2 downto 0);
    signal i4:     std_logic_vector(2 downto 0);
    signal sel:    std_logic_vector(1 downto 0);
    signal y:      std_logic_vector(2 downto 0);
begin
    
DUT:
    entity work.mux41
        port map (
            i1 => i1,
            i2 => i2,
            i3 => i3,
            i4 => i4,
            sel => sel,
            y => y
        );

STIMULI:
    process
    begin
        for i in 0 to 7 loop
            i1 <= std_logic_vector(to_unsigned(i, 3));
            for j in 0 to 7 loop
                i2 <= std_logic_vector(to_unsigned(j, 3));
                for k in 0 to 7 loop
                    i3 <= std_logic_vector(to_unsigned(k, 3));
                    for m in 0 to 7 loop
                        i4 <= std_logic_vector(to_unsigned(m, 3));
                        for n in 0 to 3 loop
                            sel <= std_logic_vector(to_unsigned(n,2));
                            wait for 10 ns;
                        end loop;
                    end loop;
                end loop;
            end loop;
        end loop;
        wait;
    end process;
end architecture;

позволяет читателям воспроизвести вашу проблему. Добавление дополнительных сигналов может помочь понять проблему:

расширенная кривая, показывающая конфликт драйверов

«X» возникает из-за конфликта драйверов. Здесь есть несколько драйверов, подключенных к and_result (от 3 до 0) через сгенерированные блоки. Когда все драйверы равны «0», сигнал разрешается до «0». Когда есть конфликт, есть «X».

Решение состоит в том, чтобы переместить объявление and_result в декларативную область блока операторов generate (со следующим началом отделения объявлений от операторов):


signal not_sel : std_logic_vector(1 DOWNTO 0); 
-- signal and_result : std_logic_vector(3 DOWNTO 0); -- MOVE FROM HERE
signal or_result : std_logic_vector(2 DOWNTO 0);

BEGIN
    
    not_sel <= not sel;
    
    and_gate_assignment : for i in 0 to 2 generate
        signal and_result : std_logic_vector(3 DOWNTO 0); -- TO HERE
        BEGIN        -- AND ADD A FOLLOWING BEGIN
        and_output1: andgate port map(input1=>i1(i), input2=>not_sel(1), input3=>not_sel(0), and_output=>and_result(0));

И это дает вам

исправлено

предполагаемый результат.

Оператор generate представляет ноль или более блочных операторов в разработке. Здесь каждый из трех операторов блока содержит мультиплексор 4:1 для элемента std_logic слайса.

Индивидуальный мультиплексор имеет сигнальные цепи, соединяющие выход каждого из четырех экземпляров логического элемента и с экземпляром логического элемента. Полагаясь на общее объявление для and_result, вы замкнули выходы andgate во всех трех блоках.

Перемещение объявления and_result в декларативную область блока операторов генерации приводит к тому, что оно реплицируется для каждого оператора сгенерированного блока. Поскольку оператор блока является декларативной областью, эти три объявления and_result не видны за пределами каждого сгенерированного блока из-за правил области действия и видимости, которые сопоставляют их с локальными для каждого блока в иерархической блок-диаграмме — три элемента and_result больше не связаны с все три блока. Это устраняет несколько драйверов.

person Community    schedule 12.12.2020
comment
Спасибо, это сработало - person Tawpik Talat; 13.12.2020