如何为 32 位线宽的 8x1 多路复用器实现测试台文件?
How to implement a test bench file for a 8x1 Multiplexer with 32-bit line width?
我正在编写一个 VHDL 代码来模拟一个 8x1 多路复用器,其中每个输入都有 32 位宽度。所以我创建了一个数组来为 MUX 建模,但现在我被测试台困住了,它变得如此复杂。这是我的原始文件(我确定它有很多冗余)我怎样才能真正让测试台从组件文件中识别我的数组(R_in),然后我将如何激励它?
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY mux8_1 IS
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
ARCHITECTURE behaviour OF mux8_1 IS
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
signal R_in:t_array_mux;
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
process(R_in, Rs)
BEGIN
CASE Rs IS
WHEN "000"=>R_out<=R_in(0);
WHEN "001"=>R_out<=R_in(1);
WHEN "010"=>R_out<=R_in(2);
WHEN "011"=>R_out<=R_in(3);
WHEN "100"=>R_out<=R_in(4);
WHEN "101"=>R_out<=R_in(5);
WHEN "110"=>R_out<=R_in(6);
WHEN "111"=>R_out<=R_in(7);
WHEN OTHERS=>R_out<= (others => '0');
END CASE;
END process;
END behaviour;
这是我的 "in progress" 测试台文件。忽略 "stimulus process" 部分我知道这是错误的我只是不知道如何为 32 位信号编写它。
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY mux8_1_TB IS
END mux8_1_TB;
ARCHITECTURE behaviour OF mux8_1_TB IS
COMPONENT mux8_1
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
--Inputs
signal R_in:t_array_mux:=(others=>'0');
signal in0,in1,in2,in3,in4,in5,in6,in7 :STD_LOGIC_VECTOR(31 DOWNTO 0):=(others=>'0');
signal Rs :STD_LOGIC_VECTOR(2 DOWNTO 0):=(others=>'0');
--Outputs
signal R_out:STD_LOGIC_VECTOR(31 DOWNTO 0);
-- Instantiate the Unit Under Test + connect the ports to my signal
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
uut: mux8_1 PORT MAP(
Rs=>Rs,
R_in=>R_in,
R_out=>R_out
);
-- Stimulus process (where the values -> inputs are set)
PROCESS
begin
R_in<="01010101";
wait for 10 ns;
Rs<="001";
wait for 10 ns;
Rs<="010";
wait for 20 ns;
Rs<="011";
wait for 30 ns;
Rs<="100";
wait for 40 ns;
Rs<="101";
wait for 50 ns;
Rs<="110";
wait for 60 ns;
Rs<="111";
wait for 70 ns;
END PROCESS;
END;
使用测试台,您可以通过给出一系列输入信号然后将输出信号与预期输出进行比较来测试模块的 correctness/output 行为。
- 首先,
R_in
对于您的测试台文件是未知的,因为它是您模块的内部信号。因此,为该信号提供值没有意义。
- 其次,您需要为您的
in0, in1, ..., in7
信号提供输入,因为它们似乎驱动您的 输出 信号 R_out
,以及其他输入信号 Rs
您需要更改您的 uut
端口映射,而不是 R_in
,它有单独的 in0 - in7
端口来匹配您的 mux8_1
组件定义。然后,将 in0 - in7
测试台信号直接映射到这些端口:
uut: mux8_1 port map(
...
in0 => in0,
in1 => in1,
...
);
或者如果你想保留 R_in
信号,端口映射如下:
uut: mux8_1 port map(
...
in0 => R_in(0),
in1 => R_in(1),
...
);
在您的测试平台中对 R_in
的分配 不正确:
R_in<="01010101";
R_in
定义为t_array_mux
类型,所以不能赋位向量值。它必须分配给 32 位 std_logic_vector
的 数组 。该行应该完全删除,因为您已经在流程之外的另一个位置对 R_in
进行了分配。多次赋值会引起信号争用。
您正在像这样在测试台中初始化 R_in
:
signal R_in:t_array_mux:=(others=>'0');
您使用的 others
关键字仅对个人 std_logic_vector
有效。您需要为 std_logic_vector
:
数组嵌套 others
signal R_in:t_array_mux:=(others=>(others=>'0'));
您需要为 32 位 in0 - in7
信号分配值,以便您可以在 sim 中看到多路复用器输出的变化。它们可以在刺激过程之外分配。您可以使用十六进制表示法(x 在“”之前)或仅使用二进制来分配它们:
in0 <= x"12345678"; --hex
或
in0 <= "00010010001101000101011001111000"; --binary
你的刺激过程看起来很好。当您更改 Rs
时,您会期望在 R_out
上看到不同的输入值。您可以在过程结束时添加一个 wait;
,否则该过程将一直重复直到 sim 结束。
具有用户定义类型的组件端口
或者,您可以 port map
您的 R_in
测试平台信号直接发送到组件上的 R_in
端口,就像您所做的那样,但这需要更多的工作。您的 mux8_1
组件定义没有 R_in
端口。您可以添加名为 R_in
的 t_array_mux
类型端口,如果您在 package 中定义 t_array_mux
类型,然后将其包含在组件和测试台文件中
library work;
use work.your_package_name.all;
除了library IEEE
,等等。那么你可以在你的组件端口定义中使用t_array_mux
类型:
ENTITY mux8_1 IS
PORT(Rs : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
R_in : IN T_ARRAY_MUX; --User-defined port type
R_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
这将允许您按照当前的方式对 uut
进行端口映射。您必须在您使用的任何工具中将包添加到项目或编译列表中。
我正在编写一个 VHDL 代码来模拟一个 8x1 多路复用器,其中每个输入都有 32 位宽度。所以我创建了一个数组来为 MUX 建模,但现在我被测试台困住了,它变得如此复杂。这是我的原始文件(我确定它有很多冗余)我怎样才能真正让测试台从组件文件中识别我的数组(R_in),然后我将如何激励它?
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
USE ieee.numeric_std.ALL;
ENTITY mux8_1 IS
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
ARCHITECTURE behaviour OF mux8_1 IS
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
signal R_in:t_array_mux;
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
process(R_in, Rs)
BEGIN
CASE Rs IS
WHEN "000"=>R_out<=R_in(0);
WHEN "001"=>R_out<=R_in(1);
WHEN "010"=>R_out<=R_in(2);
WHEN "011"=>R_out<=R_in(3);
WHEN "100"=>R_out<=R_in(4);
WHEN "101"=>R_out<=R_in(5);
WHEN "110"=>R_out<=R_in(6);
WHEN "111"=>R_out<=R_in(7);
WHEN OTHERS=>R_out<= (others => '0');
END CASE;
END process;
END behaviour;
这是我的 "in progress" 测试台文件。忽略 "stimulus process" 部分我知道这是错误的我只是不知道如何为 32 位信号编写它。
LIBRARY ieee;
USE ieee.std_logic_1164.ALL;
use ieee.numeric_std.all;
ENTITY mux8_1_TB IS
END mux8_1_TB;
ARCHITECTURE behaviour OF mux8_1_TB IS
COMPONENT mux8_1
PORT(Rs :IN STD_LOGIC_VECTOR(2 DOWNTO 0);
in0,in1,in2,in3,in4,in5,in6,in7 :IN STD_LOGIC_VECTOR(31 DOWNTO 0);
R_out :OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END COMPONENT;
type t_array_mux is array (0 to 7) of STD_LOGIC_VECTOR(31 DOWNTO 0);
--Inputs
signal R_in:t_array_mux:=(others=>'0');
signal in0,in1,in2,in3,in4,in5,in6,in7 :STD_LOGIC_VECTOR(31 DOWNTO 0):=(others=>'0');
signal Rs :STD_LOGIC_VECTOR(2 DOWNTO 0):=(others=>'0');
--Outputs
signal R_out:STD_LOGIC_VECTOR(31 DOWNTO 0);
-- Instantiate the Unit Under Test + connect the ports to my signal
BEGIN
R_in(0) <= in0;
R_in(1) <= in1;
R_in(2) <= in2;
R_in(3) <= in3;
R_in(4) <= in4;
R_in(5) <= in5;
R_in(6) <= in6;
R_in(7) <= in7;
uut: mux8_1 PORT MAP(
Rs=>Rs,
R_in=>R_in,
R_out=>R_out
);
-- Stimulus process (where the values -> inputs are set)
PROCESS
begin
R_in<="01010101";
wait for 10 ns;
Rs<="001";
wait for 10 ns;
Rs<="010";
wait for 20 ns;
Rs<="011";
wait for 30 ns;
Rs<="100";
wait for 40 ns;
Rs<="101";
wait for 50 ns;
Rs<="110";
wait for 60 ns;
Rs<="111";
wait for 70 ns;
END PROCESS;
END;
使用测试台,您可以通过给出一系列输入信号然后将输出信号与预期输出进行比较来测试模块的 correctness/output 行为。
- 首先,
R_in
对于您的测试台文件是未知的,因为它是您模块的内部信号。因此,为该信号提供值没有意义。 - 其次,您需要为您的
in0, in1, ..., in7
信号提供输入,因为它们似乎驱动您的 输出 信号R_out
,以及其他输入信号Rs
您需要更改您的 uut
端口映射,而不是 R_in
,它有单独的 in0 - in7
端口来匹配您的 mux8_1
组件定义。然后,将 in0 - in7
测试台信号直接映射到这些端口:
uut: mux8_1 port map(
...
in0 => in0,
in1 => in1,
...
);
或者如果你想保留 R_in
信号,端口映射如下:
uut: mux8_1 port map(
...
in0 => R_in(0),
in1 => R_in(1),
...
);
在您的测试平台中对 R_in
的分配 不正确:
R_in<="01010101";
R_in
定义为t_array_mux
类型,所以不能赋位向量值。它必须分配给 32 位 std_logic_vector
的 数组 。该行应该完全删除,因为您已经在流程之外的另一个位置对 R_in
进行了分配。多次赋值会引起信号争用。
您正在像这样在测试台中初始化 R_in
:
signal R_in:t_array_mux:=(others=>'0');
您使用的 others
关键字仅对个人 std_logic_vector
有效。您需要为 std_logic_vector
:
others
signal R_in:t_array_mux:=(others=>(others=>'0'));
您需要为 32 位 in0 - in7
信号分配值,以便您可以在 sim 中看到多路复用器输出的变化。它们可以在刺激过程之外分配。您可以使用十六进制表示法(x 在“”之前)或仅使用二进制来分配它们:
in0 <= x"12345678"; --hex
或
in0 <= "00010010001101000101011001111000"; --binary
你的刺激过程看起来很好。当您更改 Rs
时,您会期望在 R_out
上看到不同的输入值。您可以在过程结束时添加一个 wait;
,否则该过程将一直重复直到 sim 结束。
具有用户定义类型的组件端口
或者,您可以 port map
您的 R_in
测试平台信号直接发送到组件上的 R_in
端口,就像您所做的那样,但这需要更多的工作。您的 mux8_1
组件定义没有 R_in
端口。您可以添加名为 R_in
的 t_array_mux
类型端口,如果您在 package 中定义 t_array_mux
类型,然后将其包含在组件和测试台文件中
library work;
use work.your_package_name.all;
除了library IEEE
,等等。那么你可以在你的组件端口定义中使用t_array_mux
类型:
ENTITY mux8_1 IS
PORT(Rs : IN STD_LOGIC_VECTOR(2 DOWNTO 0);
R_in : IN T_ARRAY_MUX; --User-defined port type
R_out : OUT STD_LOGIC_VECTOR(31 DOWNTO 0)
);
END mux8_1;
这将允许您按照当前的方式对 uut
进行端口映射。您必须在您使用的任何工具中将包添加到项目或编译列表中。