vhdl比较矢量输出

时间:2014-04-08 22:43:04

标签: loops testing vector vhdl

我有一个长度为64位的向量A,我希望输出B等于3,而A为30-35,其他地方为零。我无法弄清楚测试平台在矢量A中的循环。我已经尝试了几种不同的方法,但只有1/5的数组才能提供任何输出。就没有语法/编译错误而言,这是我能得到的。

主要代码

library IEEE;
use IEEE.STD_LOGIC_1164.all;     
use IEEE.NUMERIC_STD.ALL;

entity ent is
port(A:in std_logic_vector(5 downto 0);
     B:out std_logic_vector(3 downto 0));
end ent;

architecture arch_ent of ent is
begin               
with A select
B <= "0011" when "011110",
      "0011" when "011111", 
      "0011" when "100000",
      "0011" when "100001",
      "0011" when "100010",
      "0011" when "100011",
      "0000" when others;       
end arch_ent;

测试平台

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity tb is
end tb;

architecture arch_tb of tb is

component ent 
port(A:in std_logic_vector(5 downto 0);
B:out std_logic_vector(3 downto 0));
end component;

signal A_tb: std_logic_vector(5 downto 0);
signal B_tb: std_logic_vector(3 downto 0);

begin
uut: entity ent port map(A=>A_tb, B=>B_tb);
tb: process 
constant period: time := 20ns;
begin
for i in A_tb'range loop
    A_tb <= std_logic_vector(to_unsigned(i,6));
    wait for period;
    assert (B_tb = "0011") 
    report "test failed" severity error; 
end loop;   
wait;
end process;  
end arch_tb;

最后,我试图绘制出如下波形: http://i10.photobucket.com/albums/a142/blargonblop/wave.png

其中A将变为63,每个输出的正确值为30-35,其他地方为0

3 个答案:

答案 0 :(得分:1)

用于指定&#39;测试数量的循环参数&#39;是A_tb&#39;范围,恰好是5 downto 0或6次测试,i依次分配5,4,3,2,1和0。

您想指定i in 0 to 2**A-tb'length-1i in 0 to 63以获取所有64个可能的A_tb&#39;二进制&#39;值。

(A_tb&#39; length = 6,2 ** 6-1 = 63,其中**是取幂运算符,2到6次幂减去1等于63)

我在你的测试平台上发现了两个语法错误,20ns,标准需要20到ns之间的空间:

    constant period: time := 20 ns;

并且实体必须只是ent(你有一个组件声明)或实体work.ent而不需要组件声明:

uut: ent port map(A=>A_tb, B=>B_tb);

uut: entity work.ent port map(A=>A_tb, B=>B_tb);

与Russell的答案一致,除了通过综合解决循环迭代之外,没有隐含的逻辑复制在循环中通过并行逻辑(复制)解开。并非所有循环语句都是合成目标。

测试平台通常不会被合成,并且可用于为可能用作合成目标的VHDL模型编写测试(如您的情况)。

答案 1 :(得分:0)

你真的不应该为此使用for循环。对于VHDL中的循环用于REPLICATE LOGIC,而不是多次执行某些操作。在你的测试平台上试试这样的东西:

signal r_CLOCK : std_logic := '0';
signal r_INDEX : unsigned(5 downto 0) := (others => '0');

begin

  r_CLOCK <= not r_CLOCK after period/2;

  process (r_CLOCK)
  begin
    if rising_edge(r_CLOCK) then
      r_INDEX <= r_INDEX + 1;
    end if;
  end process;

现在只需将r_INDEX转换为std_logic_vector并将其传递给ent组件。

答案 2 :(得分:0)

首先,在测试平台中,循环很好,很常见。 @Russell的评论适用于RTL代码。您可以针对此问题调整他的方法并使其工作。您需要使用64作为标记(结束)值,然后结束测试检查。请记住,尽管您所做的最重要的事情是代码的可读性。测试用例通常从一个进程的顶部到底部运行一次。

除了@DavidKoontz给出的建议之外,你循环还有一些问题。具体来说,

  • 当您希望B为0时,不应检查您的断言。
  • 使用numeric_std_unsigned(需要VHDL-2008编译开关)将简化您的转换。
  • 保持错误计数,以便您可以在结束时报告通过或失败。
  • 将您的常量保留在体系结构或包中

所以修改后的代码是:

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.numeric_std_unsigned.all;

entity tb is
end tb;

architecture arch_tb of tb is
  constant period: time := 20 ns;
...
begin
...

tb: process 
  variable ErrorCount : 
begin
  for i in i in 0 to 2**A-tb'length-1
    A_tb <= to_slv(i,6);
    wait for period;
    if i >= 30 and i <= 35 then 
      if B_tb /= 3 then 
        ErrorCount := Error Count + 1 ; 
        report "B_tb = " & to_string(B_tb) & "  Expecting: 0011" severity ERROR ; 
      end if; 
    else 
      if B_tb /= 0 then 
        ErrorCount := Error Count + 1 ; 
        report "B_tb = " & to_string(B_tb) & "  Expecting: 0000" severity ERROR ; 
      end if; 
  end loop;   
  if ErrorCount = 0 then 
    report "Test Passed" severity NOTE ; 
  else
    report "Test FAILED.  There were " & to_string(ErrorCount) & " Errors " severity NOTE; 
  end if; 
  std.env.stop(0) ; -- testbench stops here
end process; 

请注意,有关使用(或禁止使用)numeric_std_unsigned的规则不适用于测试平台。