16 到 1 多路复用器在 vhdl 中使用 2 到 1 多路复用器

16 to 1 mux using 2 to 1 mux in vhdl

我正在尝试在 vhdl 中编写代码以使用 2 到 1 多路复用器创建 16 到 1 多路复用器。 我实际上认为要做到这一点,我们可能需要 15 个二对一多路复用器,通过将它们连接在一起并使用结构模型,我编写了下面的代码。 首先我写了一个2对1的多路复用器:

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

entity MUX_2_1 is
 port (
 w0 , w1 : IN STD_LOGIC;
 SELECT_I: IN std_logic;
 DATA_O: out std_logic
);
end MUX_2_1;
architecture MUX_2_1_arch of MUX_2_1 is
--
begin
--
WITH SELECT_I SELECT
DATA_O <= w0 WHEN '0',
w1 WHEN '1',
'X' when others;
--
end MUX_2_1_arch;

并从中制作了一个包,只是为了简单易用:

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

PACKAGE mux2to1_package IS
COMPONENT mux2to1
PORT (w0, w1: IN STD_LOGIC ;
 SELECT_I: IN std_logic;
 DATA_O: out std_logic ) ;
END COMPONENT ;
END mux2to1_package ;

然后我的 16 到 1 多路复用器看起来像这样:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE work.mux2to1_package.all ;

ENTITY mux16to1 IS
PORT (w : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ;
s : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ;
f : OUT STD_LOGIC ) ;
END mux16to1 ;

ARCHITECTURE Structure OF mux16to1 IS
SIGNAL im : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
SIGNAL q : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL p : STD_LOGIC_VECTOR(1 DOWNTO 0);

BEGIN
Mux1: mux2to1 PORT MAP ( w(0), w(1), s(0), im(0)) ;
Mux2: mux2to1 PORT MAP ( w(2), w(3), s(0), im(1)) ;
Mux3: mux2to1 PORT MAP ( w(4), w(5), s(0), im(2)) ;
Mux4: mux2to1 PORT MAP ( w(6), w(7), s(0), im(3)) ;
Mux5: mux2to1 PORT MAP ( w(8), w(9), s(0), im(4)) ;
MUX6: mux2to1 PORT MAP ( w(10), w(11), s(0), im(5));
Mux7: mux2to1 PORT MAP ( w(12), w(13), s(0), im(6)) ;
Mux8: mux2to1 PORT MAP ( w(14), w(15), s(0), im(7)) ;
Mux9: mux2to1 PORT MAP ( im(0), im(1), s(1), q(0)) ;
Mux10: mux2to1 PORT MAP ( im(2), im(3), s(1), q(1)) ;
Mux11: mux2to1 PORT MAP ( im(4), im(5), s(1), q(2)) ;
Mux12: mux2to1 PORT MAP ( im(6), im(7), s(1), q(3)) ;
Mux13: mux2to1 PORT MAP ( q(0), q(1), s(2), p(0)) ;
Mux14: mux2to1 PORT MAP ( q(2), q(3), s(2), p(1)) ;
Mux15: mux2to1 PORT MAP ( p(0), p(1), s(3), f) ;
END Structure ;

而且我的测试平台是:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
USE work.mux2to1_package.all ;

ENTITY Mux_test IS
END Mux_test;

ARCHITECTURE test OF Mux_test IS

COMPONENT mux16to1 PORT(w : IN STD_LOGIC_VECTOR(15 DOWNTO 0) ;
                        s : IN STD_LOGIC_VECTOR(3 DOWNTO 0) ;
                        f : OUT STD_LOGIC ) ;
END COMPONENT;

SIGNAL wi : STD_LOGIC_VECTOR(15 DOWNTO 0) ;
SIGNAL selecting : STD_LOGIC_VECTOR(3 DOWNTO 0) ;
SIGNAL fi : STD_LOGIC ;

BEGIN
a1: mux16to1 PORT MAP(wi , selecting , fi);

wi<= "0101110010001010" , "1001000101010101" after 100 ns;
selecting <= "0011" , "1010" after 20 ns , "1110" after 40 ns, "1100" after 60 ns , "0101" after 80 ns,
          "0011" after 100 ns , "1010" after 120 ns , "1110" after 140 ns, "1100" after 160 ns , "0101" after 180 ns;
END ARCHITECTURE;

我的模拟:

但是当我尝试对此进行模拟时,我的输出中没有显示任何内容。我在想这可能是因为我在并发部分编写了我的代码并且信号 imqp 尚未初始化所以我尝试使用默认值“00000000” [=当我声明信号时,q 的 14=] 和 q 的“0000”和 p 的“00”,但后来我在模拟中遇到了一堆错误,说“Instance mux2to1 is unbound”,实际上没有任何改变. 知道有什么问题吗??

而且我认为我的 select 输入在逻辑上有问题。 但我不明白我应该如何使用 select 来解决这个问题。 如果有人能帮助我解决我的问题,我将不胜感激。

使用组件声明的虚拟组件绑定可以使用配置规范来显式提供绑定指示,也可以依赖默认绑定指示。

默认绑定指示将依赖于查找在名称与组件名称匹配的参考库中声明的实体。这里不是这种情况,您的实体名为 MUX_2_1(不区分大小写),而组件名称为 mux2to1.

在 VHDL 中不绑定组件并不违法,这相当于不在印刷电路或面包板的特定位置加载组件,它只是不产生输出,在此处的模拟中显示为 'U'.

这里的解决方案可能是将实体声明及其体系结构中的实体名称从 MUX_2_1 更改为 mux2to1,将组件声明更改为 MUX_2_1 或提供配置规范在 mux16to1 的体系结构中提供显式绑定指示作为块声明项,形式为

ARCHITECTURE Structure OF mux16to1 IS
SIGNAL im : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
SIGNAL q : STD_LOGIC_VECTOR(3 DOWNTO 0);
SIGNAL p : STD_LOGIC_VECTOR(1 DOWNTO 0);
for all: mux2to1 use entity work.MUX_2_1;  -- ADDED 

当使用后一种方法时,在仿真期间在测试台信号 fi 上提供“1”和“0”输出。

可以更详细地说明测试平台以证明选择是有效的。一种方法是在扫描所有元素并查找不匹配的同时在 w 元素中移动“0”或“1”:

library ieee;
use ieee.std_logic_1164.all;

entity mux16to1_tb is
end mux16to1_tb;

architecture test of mux16to1_tb is
    component mux16to1 is
        port (
            w:  in  std_logic_vector(15 downto 0);
            s:  in  std_logic_vector(3 downto 0);
            f:  out std_logic
        );
    end component;

    signal w:       std_logic_vector(15 downto 0);
    signal s:       std_logic_vector(3 downto 0);
    signal f:       std_logic;
    
    function to_string (inp: std_logic_vector) return string is
        variable image_str: string (1 to inp'length);
        alias input_str:  std_logic_vector (1 to inp'length) is inp;
    begin
        for i in input_str'range loop
            image_str(i) := character'VALUE(std_ulogic'IMAGE(input_str(i)));
        end loop;
        return image_str;
    end function;

begin
    
DUT: 
    mux16to1 
        port map (
            w => w,
            s => s,
            f => f
        );

STIMULI:
    process
        use ieee.numeric_std.all;
    begin
        for i in w'reverse_range loop
            w <= (others => '1');
            w(i) <= '0';
            for j in w'reverse_range loop
                s <= std_logic_vector(to_unsigned(j, s'length));
                wait for 10 ns;
            end loop;
        end loop;
        wait;
end process;

VALIDATE:
    process
    begin
        for x in w'reverse_range loop
            for y in w'reverse_range loop
                wait for 10 ns;
                assert f = w(y)
                report 
                    LF & HT & "f = " & std_ulogic'image(f) & " " &
                              "expected " & std_ulogic'image(w(y)) &
                    LF & HT & "w = " & to_string(w) &
                    LF & HT & "s = " & to_string(s)
                severity ERROR;
            end loop;
        end loop;
        wait;
    end process;

end architecture;

使用步进“0”模式为 w 的每个值选择 mux16to1 的输出 f。 f 和 w 的选定名称元素值之间的任何不匹配都将连同诊断信息一起报告。

这里我们看到 mux16t01 正确实现了 16:1 选择,无需修改原始海报设计。

在没有错误注入的情况下,可以在波形显示中查看 w、s 和 f 的测试台波形以验证正确的操作。