问题描述
我正在尝试在 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),im(1)) ;
Mux3: mux2to1 PORT MAP ( w(4),w(5),im(2)) ;
Mux4: mux2to1 PORT MAP ( w(6),w(7),im(3)) ;
Mux5: mux2to1 PORT MAP ( w(8),w(9),im(4)) ;
MUX6: mux2to1 PORT MAP ( w(10),w(11),im(5));
Mux7: mux2to1 PORT MAP ( w(12),w(13),im(6)) ;
Mux8: mux2to1 PORT MAP ( w(14),w(15),im(7)) ;
Mux9: mux2to1 PORT MAP ( im(0),im(1),s(1),q(0)) ;
Mux10: mux2to1 PORT MAP ( im(2),im(3),q(1)) ;
Mux11: mux2to1 PORT MAP ( im(4),im(5),q(2)) ;
Mux12: mux2to1 PORT MAP ( im(6),im(7),q(3)) ;
Mux13: mux2to1 PORT MAP ( q(0),q(1),s(2),p(0)) ;
Mux14: mux2to1 PORT MAP ( q(2),q(3),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;
我的模拟:
但是当我尝试模拟这个时,我的输出中没有任何显示。我想这可能是因为我在并发部分编写了代码并且信号 im
和 q
和 p
尚未初始化,所以我尝试对 {{ 使用默认值“00000000” 1}} 和 im
的“0000”和 q
的“00”在我声明信号时,但后来我在模拟中收到一堆错误,说“实例 mux2to1 未绑定”,但实际上没有任何变化.
知道有什么问题吗??
此外,我认为我的选择输入在逻辑上有问题。 但我不明白我应该如何使用选择来解决这个问题。 如果有人能帮助我解决我的问题,我将不胜感激。
解决方法
使用组件声明的虚拟组件绑定可以显式地使用配置规范提供绑定指示,也可以依赖默认绑定指示。
默认绑定指示将依赖于查找在参考库中声明的实体,其名称与组件名称匹配。此处并非如此,您的实体名为 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;
mux16to1 的输出 f 是使用行进“0”模式为 w 的每个值选择的。 f 与 w 的所选名称元素值之间的任何不匹配都会与诊断信息一起报告。
在这里我们看到 mux16t01 正确实现了 16:1 选择,而无需修改原始海报设计。
在没有错误注入的情况下,可以在波形显示中查看 w、s 和 f 的测试台波形,以验证正确的操作。