1

我正在实现一个多路复用器,但是门无缘无故地返回“x”,请帮忙。正如您在屏幕截图中看到的,结果刚刚从“1”变为“x”。我为和门做了一个测试台,它自己工作得很好。它应该是一个 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;

这真的没什么,这可能是时间问题吗?

4

1 回答 1

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 downto 0)。当所有驱动器都为“0”时,信号被解析为“0”。当发生冲突时,会有一个“X”。

解决方案是将 and_result 声明移动到生成语句块声明区域(以下开始将声明与语句分开):


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 语句代表零个或多个细化块语句。这里三个块语句中的每一个都包含一个用于切片的 std_logic 元素的 4 比 1 多路复用器。

一个单独的多路复用器具有将四个和门实例中的每一个的输出连接到一个门实例的信号网络。通过依赖一个共同的声明,and_result您已经将所有三个块的 andgate 输出短接在一起。

and_result声明移动到生成语句块声明区域会导致为每个生成的块语句复制它。因为块语句是一个声明性区域,所以这三个声明and_result在每个生成的块之外是不可见的,因为范围和可见性规则与它们相匹配是分层框图中每个块的本地 - 这三个and_result元素不再连接到所有三个块。这消除了多个驱动程序。

于 2020-12-12T00:42:34.887 回答