如何在测试平台 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;

如果p0p1是被测设备的输入并且它们的基类型与类型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 从二进制值中提取订单输入的地方。