如何在测试平台 VHDL 中使用 for 循环遍历多个输入组合?
How to go through multiple input combinations with a for loop in a testbench VHDL?
我是 VHDL 新手,正在为 XNOR 门编写测试平台。简单的解决方案是手动检查两个输入的每个组合,但如果输入更多,这将花费太长时间。如何在 VHDL 中将其写成 for 循环?
process
begin
p0 <= '1';
p1 <= '0';
wait for 1 ns;
if (pout = '1') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '1';
p1 <= '1';
wait for 1 ns;
if (pout = '0') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '0';
p1 <= '1';
wait for 1 ns;
if (pout = '1') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '0';
p1 <= '0';
wait for 1 ns;
if (pout = '0') then
error <= '1';
end if;
wait for 200 ns;
end process;
如果p0
和p1
是被测设备的输入并且它们的基类型与类型unsigned
的元素类型兼容:
library ieee;
use ieee.std_logic_1164.all;
entity xnor2 is
port (
p0: in std_logic;
p1: in std_logic;
pout: out std_logic
);
end entity;
architecture foo of xnor2 is
begin
pout <= not (p0 xor p1);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity inputs is
end entity;
architecture foo of inputs is
signal p0, p1, pout: std_logic;
signal error: std_logic := '0';
begin
DUT:
entity work.xnor2
port map (
p0 => p0,
p1 => p1,
pout => pout
);
process
use ieee.numeric_std.all; -- for example, if not already visible
variable elements: unsigned (1 downto 0);
begin
elements := (others => '0');
for i in 0 to 2 ** elements'length - 1 loop
p0 <= elements(0);
p1 <= elements(1);
wait for 1 ns;
report LF & "i = " & integer'image(i) &
LF & HT & "p0 = " & std_ulogic'image(p0) &
" p1 = " & std_ulogic'image(p1) &
" error = " & std_ulogic'image(error);
if pout = '0' then
error <= '1';
end if;
wait for 200 ns;
elements := elements + 1;
end loop;
wait;
end process;
end architecture;
哪个报告:
ghdl -r inputs
inputs.vhdl:45:13:@1ns:(report note):
i = 0
p0 = '0' p1 = '0' error = '0'
inputs.vhdl:45:13:@202ns:(report note):
i = 1
p0 = '1' p1 = '0' error = '0'
inputs.vhdl:45:13:@403ns:(report note):
i = 2
p0 = '0' p1 = '1' error = '1'
inputs.vhdl:45:13:@604ns:(report note):
i = 3
p0 = '1' p1 = '1' error = '1'
我们也看到error
的地方没有明显的意义。
如果不在问题中提供最小的、完整的和可验证的示例,则存在一些风险,答案可能有一个或多个错误,并且未来的读者无法轻易验证解决方案。
这里的想法是使用二进制表示计数器,其位(元素)与输入一样多,并在每次循环迭代中将位(元素)的值分配给相应的输入。
也可以直接从循环参数的整数值中提供该二进制值。请参阅 ,它也使用聚合赋值:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity agg_assign is
end entity;
architecture foo of agg_assign is
signal A, B, C: std_logic;
begin
process
begin
wait for 10 ns;
for i in 0 to 7 loop
(A, B, C) <= std_logic_vector(to_unsigned(i, 3));
wait for 10 ns;
end loop;
wait;
end process;
end architecture;
您还可以创建记录子类型来混合元素和数组赋值:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity aggr_rec_assign is
end entity;
architecture foo of aggr_rec_assign is
signal A, B, C: std_logic;
signal D: std_logic_vector (2 downto 0);
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
process
type inputs_rec is
record
A: std_logic;
B: std_logic;
C: std_logic;
D: std_logic_vector (2 downto 0);
end record;
variable elements: unsigned (5 downto 0);
begin
wait for 10 ns;
for i in 0 to 2 ** elements'length - 1 loop
elements := to_unsigned(i, elements'length);
(A, B, C, D) <=
inputs_rec'(
elements(5),
elements(4),
elements(3),
std_logic_vector(elements(2 downto 0))
);
wait for 10 ns;
report LF & HT & "i = "& integer'image(i) & " (A, B, C, D) = " &
std_ulogic'image(A) & " " &
std_ulogic'image(B) & " " &
std_ulogic'image(C) & " " &
to_string(D);
end loop;
wait;
end process;
end architecture;
在这两种情况下,聚合分配都是 select 从二进制值中提取订单输入的地方。
我是 VHDL 新手,正在为 XNOR 门编写测试平台。简单的解决方案是手动检查两个输入的每个组合,但如果输入更多,这将花费太长时间。如何在 VHDL 中将其写成 for 循环?
process
begin
p0 <= '1';
p1 <= '0';
wait for 1 ns;
if (pout = '1') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '1';
p1 <= '1';
wait for 1 ns;
if (pout = '0') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '0';
p1 <= '1';
wait for 1 ns;
if (pout = '1') then
error <= '1';
end if;
wait for 200 ns;
p0 <= '0';
p1 <= '0';
wait for 1 ns;
if (pout = '0') then
error <= '1';
end if;
wait for 200 ns;
end process;
如果p0
和p1
是被测设备的输入并且它们的基类型与类型unsigned
的元素类型兼容:
library ieee;
use ieee.std_logic_1164.all;
entity xnor2 is
port (
p0: in std_logic;
p1: in std_logic;
pout: out std_logic
);
end entity;
architecture foo of xnor2 is
begin
pout <= not (p0 xor p1);
end architecture;
library ieee;
use ieee.std_logic_1164.all;
entity inputs is
end entity;
architecture foo of inputs is
signal p0, p1, pout: std_logic;
signal error: std_logic := '0';
begin
DUT:
entity work.xnor2
port map (
p0 => p0,
p1 => p1,
pout => pout
);
process
use ieee.numeric_std.all; -- for example, if not already visible
variable elements: unsigned (1 downto 0);
begin
elements := (others => '0');
for i in 0 to 2 ** elements'length - 1 loop
p0 <= elements(0);
p1 <= elements(1);
wait for 1 ns;
report LF & "i = " & integer'image(i) &
LF & HT & "p0 = " & std_ulogic'image(p0) &
" p1 = " & std_ulogic'image(p1) &
" error = " & std_ulogic'image(error);
if pout = '0' then
error <= '1';
end if;
wait for 200 ns;
elements := elements + 1;
end loop;
wait;
end process;
end architecture;
哪个报告:
ghdl -r inputs
inputs.vhdl:45:13:@1ns:(report note):
i = 0
p0 = '0' p1 = '0' error = '0'
inputs.vhdl:45:13:@202ns:(report note):
i = 1
p0 = '1' p1 = '0' error = '0'
inputs.vhdl:45:13:@403ns:(report note):
i = 2
p0 = '0' p1 = '1' error = '1'
inputs.vhdl:45:13:@604ns:(report note):
i = 3
p0 = '1' p1 = '1' error = '1'
我们也看到error
的地方没有明显的意义。
如果不在问题中提供最小的、完整的和可验证的示例,则存在一些风险,答案可能有一个或多个错误,并且未来的读者无法轻易验证解决方案。
这里的想法是使用二进制表示计数器,其位(元素)与输入一样多,并在每次循环迭代中将位(元素)的值分配给相应的输入。
也可以直接从循环参数的整数值中提供该二进制值。请参阅
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity agg_assign is
end entity;
architecture foo of agg_assign is
signal A, B, C: std_logic;
begin
process
begin
wait for 10 ns;
for i in 0 to 7 loop
(A, B, C) <= std_logic_vector(to_unsigned(i, 3));
wait for 10 ns;
end loop;
wait;
end process;
end architecture;
您还可以创建记录子类型来混合元素和数组赋值:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity aggr_rec_assign is
end entity;
architecture foo of aggr_rec_assign is
signal A, B, C: std_logic;
signal D: std_logic_vector (2 downto 0);
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
process
type inputs_rec is
record
A: std_logic;
B: std_logic;
C: std_logic;
D: std_logic_vector (2 downto 0);
end record;
variable elements: unsigned (5 downto 0);
begin
wait for 10 ns;
for i in 0 to 2 ** elements'length - 1 loop
elements := to_unsigned(i, elements'length);
(A, B, C, D) <=
inputs_rec'(
elements(5),
elements(4),
elements(3),
std_logic_vector(elements(2 downto 0))
);
wait for 10 ns;
report LF & HT & "i = "& integer'image(i) & " (A, B, C, D) = " &
std_ulogic'image(A) & " " &
std_ulogic'image(B) & " " &
std_ulogic'image(C) & " " &
to_string(D);
end loop;
wait;
end process;
end architecture;
在这两种情况下,聚合分配都是 select 从二进制值中提取订单输入的地方。