在 VHDL 的测试台中将 STD_LOGIC 连接到 STD_LOGIC_VECTOR
Concatenating STD_LOGIC to STD_LOGIC_VECTOR within testbench in VHDL
enter image description here
这是我的 4 对 1 MUX 的简单示意图。我无法将 LOGIC 连接到 LOGIC_VECTOR...
这是我的测试平台代码。我只想展示所有可能输入的 MUX 性能。它编译得很好,但没有像我预期的那样工作。
我猜新声明的向量 "X" 和 "I" 没有与 Schematic
的实际输入链接
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
LIBRARY UNISIM;
USE UNISIM.Vcomponents.ALL;
ENTITY MUX_SCHE_MUX_SCHE_sch_tb IS
END MUX_SCHE_MUX_SCHE_sch_tb;
ARCHITECTURE behavioral OF MUX_SCHE_MUX_SCHE_sch_tb IS
COMPONENT MUX_SCHE
PORT( X3 : IN STD_LOGIC;
X2 : IN STD_LOGIC;
X1 : IN STD_LOGIC;
X0 : IN STD_LOGIC;
I0 : IN STD_LOGIC;
I1 : IN STD_LOGIC;
Y : OUT STD_LOGIC);
END COMPONENT;
SIGNAL X3 : STD_LOGIC := '0';
SIGNAL X2 : STD_LOGIC := '0';
SIGNAL X1 : STD_LOGIC := '0';
SIGNAL X0 : STD_LOGIC := '0';
SIGNAL I0 : STD_LOGIC := '0';
SIGNAL I1 : STD_LOGIC := '0';
SIGNAL Y : STD_LOGIC;
---------- New Variable ----------
SIGNAL X : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL I : STD_LOGIC_VECTOR(1 downto 0);
SIGNAL j : integer := 0;
SIGNAL k : integer := 0;
BEGIN
X <= X3 & X2 & X1 & X0;
I <= I1 & I0;
UUT: MUX_SCHE PORT MAP(
X3 => X3,
X2 => X2,
X1 => X1,
X0 => X0,
I0 => I0,
I1 => I1,
Y => Y
);
-- *** Test Bench - User Defined Section ***
tb : PROCESS
BEGIN
X <= "0000";
I <= "00";
while(j<4) loop
while(k<8) loop
X <= X + '1'; WAIT FOR 10 NS;
end loop;
I <= I + '1'; WAIT FOR 10 NS;
end loop;
END PROCESS;
-- *** End Test Bench - User Defined Section ***
END;
您的代码中有两个问题:首先,X <= X3 & X2 & X1 & X0;
将 X3
连接到 X0
并将结果分配给 X
。在过程 tb
中,您再次分配给 X
,创建通常称为 "multiple drivers" 的内容,即。代码的多个部分将(可能不同的)值驱动到同一信号。在编写良好的 VHDL 代码中,这很少是您想要的。
VHDL 通过使用 解析函数 处理多个驱动程序:一个函数应用于驱动到信号的所有值,然后将其输出写入信号;请参阅 this 了解所使用的分辨率 table。
我强烈建议不要使用已解析的类型,例如 std_logic
或 std_logic_vector
并使用它们未解析的吊坠 std_ulogic
和 std_ulogic_vector
(注意 u
);如果你使用了那些,你的错误就会在阐述过程中被发现。
其次,如评论中所述,X3
到 X0
从未分配任何值,将它们保留为 U
。
正如 Brian 指出的那样,对 X(和 I)的分配是不正确的。
还有一种情况是X总是全是'X',有两个驱动。对 X 的并发信号分配和未标记进程中的分配。此外,未标记的进程将无法成功初始化 X,因为在第一次分配给“0000”和内部 while 循环中的第一次分配之间没有进程的干预暂停。
您可能还注意到没有对 j 和 k 的赋值,这意味着您永远不会完成内部 while 循环并提供不同的 I 值。
克服当前测试平台中的问题还可以涉及简化:
library ieee;
use ieee.std_logic_1164.all;
entity mux_sche_tb is
end entity mux_sche_tb;
architecture foo of mux_sche_tb is
use ieee.numeric_std.all;
component mux_sche
port (
x3: in std_logic;
x2: in std_logic;
x1: in std_logic;
x0: in std_logic;
i0: in std_logic;
i1: in std_logic;
y: out std_logic
);
end component;
-- signal x3: std_logic := '0';
-- signal x2: std_logic := '0';
-- signal x1: std_logic := '0';
-- signal x0: std_logic := '0';
-- signal i0: std_logic := '0';
-- signal i1: std_logic := '0';
signal y: std_logic;
-- ---------- new variable ----------
signal x: unsigned(3 downto 0);
signal i: unsigned(1 downto 0);
-- signal j: integer := 0;
-- signal k: integer := 0;
begin
-- x <= x3 & x2 & x1 & x0;
-- i <= i1 & i0;
uut:
mux_sche
port map (
x3 => x(3),
x2 => x(2),
x1 => x(1),
x0 => x(0),
i0 => i(0),
i1 => i(1),
y => y
);
tb:
process
begin
-- x <= "0000";
-- i <= "00";
wait for 10 ns; -- show initial state
for j in 0 to 3 loop
I <= to_unsigned(j, 2);
for k in 0 to 15 loop
X <= to_unsigned(k, 4);
wait for 10 ns;
end loop;
end loop;
wait;
-- while(j < 4) loop
-- while(k < 8) loop
-- x <= x + '1';
-- wait for 10 ns;
-- end loop;
-- i <= i + '1';
-- wait for 10 ns;
-- end loop;
end process;
end architecture;
在循环语句中使用迭代方案的 while 循环而不是 while 循环。
布赖恩建议将 X 的元素分配扩展到 I,并且只提供对其中任何一个的单个分配,从而消除了多个驱动程序。
使包 ieee.numeric_std 中的声明可见的 use 子句被移动到允许分析原始架构的架构(并且它的 use 子句允许在 Synopsys 包 ieee.std_logic_unsigned 中找到的声明被移动到它的架构声明区域)。
for 循环迭代器是在循环语句迭代方案中隐式声明的变量,并从其默认整数类型转换为无符号 X 和 I。
无符号 X 和 I 具有与 mux_sche 的 std_logic 正式端口相同的基本类型的元素,可以用作实际值(如 Brian 推荐的那样)。
要提供 Minimal, Complete and Verifiable example,必须提供兼容的 mux_sche:
library ieee;
use ieee.std_logic_1164.all;
entity mux_sche is
port (
X3: in std_logic;
X2: in std_logic;
X1: in std_logic;
X0: in std_logic;
I0: in std_logic;
I1: in std_logic;
Y: out std_logic
);
end entity;
architecture foo of mux_sche is
begin
process (X3, X2, X1, X0, I0, I1)
variable I: std_logic_vector (1 downto 0);
begin
I := TO_X01(I1 & I0);
case I is
when "00" =>
Y <= TO_X01(X0);
when "01" =>
Y <= TO_X01(X1);
when "10" =>
Y <= TO_X01(X2);
when "11" =>
Y <= TO_X01(X3);
when others =>
Y <= 'X';
end case;
end process;
end architecture;
如果在测试台之前对其进行了分析,并且对测试台进行了分析、详细说明和模拟,我们最终得到:
未显示 X
并增加了 X 和 I。
此测试平台版本依赖于 numeric_std 包 to_unsigned 从自然范围整数转换并注明 X 并且我在循环迭代方案隐式声明中指定了范围。
可以用原来的testbench吗?不适用于 j 和 k 的阈值测试。将会发生的是 k 将经历 8 次迭代,然后 j 将经历 4 次迭代:
使用带有信号迭代器的 while 循环比使用带有变量迭代器的 for 循环要难一些。
enter image description here
这是我的 4 对 1 MUX 的简单示意图。我无法将 LOGIC 连接到 LOGIC_VECTOR...
这是我的测试平台代码。我只想展示所有可能输入的 MUX 性能。它编译得很好,但没有像我预期的那样工作。 我猜新声明的向量 "X" 和 "I" 没有与 Schematic
的实际输入链接LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.std_logic_unsigned.all;
USE ieee.numeric_std.ALL;
LIBRARY UNISIM;
USE UNISIM.Vcomponents.ALL;
ENTITY MUX_SCHE_MUX_SCHE_sch_tb IS
END MUX_SCHE_MUX_SCHE_sch_tb;
ARCHITECTURE behavioral OF MUX_SCHE_MUX_SCHE_sch_tb IS
COMPONENT MUX_SCHE
PORT( X3 : IN STD_LOGIC;
X2 : IN STD_LOGIC;
X1 : IN STD_LOGIC;
X0 : IN STD_LOGIC;
I0 : IN STD_LOGIC;
I1 : IN STD_LOGIC;
Y : OUT STD_LOGIC);
END COMPONENT;
SIGNAL X3 : STD_LOGIC := '0';
SIGNAL X2 : STD_LOGIC := '0';
SIGNAL X1 : STD_LOGIC := '0';
SIGNAL X0 : STD_LOGIC := '0';
SIGNAL I0 : STD_LOGIC := '0';
SIGNAL I1 : STD_LOGIC := '0';
SIGNAL Y : STD_LOGIC;
---------- New Variable ----------
SIGNAL X : STD_LOGIC_VECTOR(3 downto 0);
SIGNAL I : STD_LOGIC_VECTOR(1 downto 0);
SIGNAL j : integer := 0;
SIGNAL k : integer := 0;
BEGIN
X <= X3 & X2 & X1 & X0;
I <= I1 & I0;
UUT: MUX_SCHE PORT MAP(
X3 => X3,
X2 => X2,
X1 => X1,
X0 => X0,
I0 => I0,
I1 => I1,
Y => Y
);
-- *** Test Bench - User Defined Section ***
tb : PROCESS
BEGIN
X <= "0000";
I <= "00";
while(j<4) loop
while(k<8) loop
X <= X + '1'; WAIT FOR 10 NS;
end loop;
I <= I + '1'; WAIT FOR 10 NS;
end loop;
END PROCESS;
-- *** End Test Bench - User Defined Section ***
END;
您的代码中有两个问题:首先,X <= X3 & X2 & X1 & X0;
将 X3
连接到 X0
并将结果分配给 X
。在过程 tb
中,您再次分配给 X
,创建通常称为 "multiple drivers" 的内容,即。代码的多个部分将(可能不同的)值驱动到同一信号。在编写良好的 VHDL 代码中,这很少是您想要的。
VHDL 通过使用 解析函数 处理多个驱动程序:一个函数应用于驱动到信号的所有值,然后将其输出写入信号;请参阅 this 了解所使用的分辨率 table。
我强烈建议不要使用已解析的类型,例如 std_logic
或 std_logic_vector
并使用它们未解析的吊坠 std_ulogic
和 std_ulogic_vector
(注意 u
);如果你使用了那些,你的错误就会在阐述过程中被发现。
其次,如评论中所述,X3
到 X0
从未分配任何值,将它们保留为 U
。
正如 Brian 指出的那样,对 X(和 I)的分配是不正确的。
还有一种情况是X总是全是'X',有两个驱动。对 X 的并发信号分配和未标记进程中的分配。此外,未标记的进程将无法成功初始化 X,因为在第一次分配给“0000”和内部 while 循环中的第一次分配之间没有进程的干预暂停。
您可能还注意到没有对 j 和 k 的赋值,这意味着您永远不会完成内部 while 循环并提供不同的 I 值。
克服当前测试平台中的问题还可以涉及简化:
library ieee;
use ieee.std_logic_1164.all;
entity mux_sche_tb is
end entity mux_sche_tb;
architecture foo of mux_sche_tb is
use ieee.numeric_std.all;
component mux_sche
port (
x3: in std_logic;
x2: in std_logic;
x1: in std_logic;
x0: in std_logic;
i0: in std_logic;
i1: in std_logic;
y: out std_logic
);
end component;
-- signal x3: std_logic := '0';
-- signal x2: std_logic := '0';
-- signal x1: std_logic := '0';
-- signal x0: std_logic := '0';
-- signal i0: std_logic := '0';
-- signal i1: std_logic := '0';
signal y: std_logic;
-- ---------- new variable ----------
signal x: unsigned(3 downto 0);
signal i: unsigned(1 downto 0);
-- signal j: integer := 0;
-- signal k: integer := 0;
begin
-- x <= x3 & x2 & x1 & x0;
-- i <= i1 & i0;
uut:
mux_sche
port map (
x3 => x(3),
x2 => x(2),
x1 => x(1),
x0 => x(0),
i0 => i(0),
i1 => i(1),
y => y
);
tb:
process
begin
-- x <= "0000";
-- i <= "00";
wait for 10 ns; -- show initial state
for j in 0 to 3 loop
I <= to_unsigned(j, 2);
for k in 0 to 15 loop
X <= to_unsigned(k, 4);
wait for 10 ns;
end loop;
end loop;
wait;
-- while(j < 4) loop
-- while(k < 8) loop
-- x <= x + '1';
-- wait for 10 ns;
-- end loop;
-- i <= i + '1';
-- wait for 10 ns;
-- end loop;
end process;
end architecture;
在循环语句中使用迭代方案的 while 循环而不是 while 循环。 布赖恩建议将 X 的元素分配扩展到 I,并且只提供对其中任何一个的单个分配,从而消除了多个驱动程序。
使包 ieee.numeric_std 中的声明可见的 use 子句被移动到允许分析原始架构的架构(并且它的 use 子句允许在 Synopsys 包 ieee.std_logic_unsigned 中找到的声明被移动到它的架构声明区域)。
for 循环迭代器是在循环语句迭代方案中隐式声明的变量,并从其默认整数类型转换为无符号 X 和 I。
无符号 X 和 I 具有与 mux_sche 的 std_logic 正式端口相同的基本类型的元素,可以用作实际值(如 Brian 推荐的那样)。
要提供 Minimal, Complete and Verifiable example,必须提供兼容的 mux_sche:
library ieee;
use ieee.std_logic_1164.all;
entity mux_sche is
port (
X3: in std_logic;
X2: in std_logic;
X1: in std_logic;
X0: in std_logic;
I0: in std_logic;
I1: in std_logic;
Y: out std_logic
);
end entity;
architecture foo of mux_sche is
begin
process (X3, X2, X1, X0, I0, I1)
variable I: std_logic_vector (1 downto 0);
begin
I := TO_X01(I1 & I0);
case I is
when "00" =>
Y <= TO_X01(X0);
when "01" =>
Y <= TO_X01(X1);
when "10" =>
Y <= TO_X01(X2);
when "11" =>
Y <= TO_X01(X3);
when others =>
Y <= 'X';
end case;
end process;
end architecture;
如果在测试台之前对其进行了分析,并且对测试台进行了分析、详细说明和模拟,我们最终得到:
未显示 X
并增加了 X 和 I。
此测试平台版本依赖于 numeric_std 包 to_unsigned 从自然范围整数转换并注明 X 并且我在循环迭代方案隐式声明中指定了范围。
可以用原来的testbench吗?不适用于 j 和 k 的阈值测试。将会发生的是 k 将经历 8 次迭代,然后 j 将经历 4 次迭代:
使用带有信号迭代器的 while 循环比使用带有变量迭代器的 for 循环要难一些。