【问题标题】:Simple test bench in vhdl with generic带有通用的 vhdl 中的简单测试台
【发布时间】:2018-02-28 09:53:14
【问题描述】:

我有一个用 VHDL 编写的非常简单的“程序”

library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use ieee.numeric_std;


entity Xand is
    generic(width   : integer:=8);
    port(   clk : in std_logic;
        A,B : in std_logic_vector(width-1 downto 0);
        C   : out std_logic_vector(width-1 downto 0)
    );
end Xand;

architecture Behavioral of Xand is
begin
    C<= A and B;
end Behavioral;

我的实际测试台如下所示:

LIBRARY ieee;
USE ieee.std_logic_1164.ALL;

use ieee.numeric_std.all;

ENTITY Xand_tb IS
    --generic(width : integer);
END Xand_tb;

ARCHITECTURE behavior OF Xand_tb IS 

    COMPONENT Xand IS
        generic(width   : integer);
        port(   clk : in std_logic;
            A,B : in std_logic_vector(width-1 downto 0);
            C   : out std_logic_vector(width-1 downto 0)
        );
    end COMPONENT;

    signal width : integer := 8;

   -- inputs
   signal clk : std_logic := '0';
   signal A, B : std_logic_vector(width-1 downto 0) := (others => '0');

   --Outputs
   signal C : std_logic_vector(width-1 downto 0);
   constant period : time := 10 ns;

BEGIN

    -- instantiate the Unit Under Test (UUT)
   uut: Xand generic map (width => 8)
        PORT MAP (
          clk => clk,
          A => A,
          B => B,
          C => C
        );

    -- Stimulus process
   stim_proc: process
   begin        
      -- hold reset state for 100 ns.
      wait for 100 ns;  

      wait for period*10;

      for i in 0 to 2**width loop
        A <= std_logic_vector( unsigned(A) + 1 );
        for j in 0 to 2**width loop
            B <= std_logic_vector( unsigned(B) + 1 );
            wait for period;
        end loop;
        for j in 0 to width loop
            B(j) <= '0';
        end loop;
        wait for period;
      end loop;

      wait;

    end process;
END;

很遗憾我得到了错误(当我想用 --vcd=xand.vcd 模拟它时)。

ghdl:error: overflow detected
  from: process work.xand_tb(behavior).stim_proc at Xand_tb.vhd:57
ghdl:error: simulation failed

B(j) &lt;= '0'; 行不工作。据我了解,A 和 B 是具有 8 位的向量。所以我想用来自 [0,256) 的不同 A 和 B 值来测试我的 Xand 程序。可悲的是,我不知道如何使向量 B 等于 0 与循环不同的方式,这是行不通的。 有人可以解释一下我的 generic() 是做什么的吗?

【问题讨论】:

  • 您需要驱动输入信号。您是否尝试过这样做,如果是,出了什么问题?
  • 您的问题是什么?您是否正在寻找像 Modelsim 或 GHDL 这样的仿真工具? “不清楚你在问什么。”
  • @scary_jeff 我想我做到了,编辑了我的问题。你介意再看一遍吗?
  • 你定义B : in std_logic_vector(width-1 downto 0);。然后循环j in 0 to width,所以j 将在某个时候成为width。因此,您分配的 B(width) 超出范围...
  • 离题了,但是关于“to”这个词:通常不清楚范围是包括还是不包括最终数字。您实际上应该写“直到并包括”,但这在编程中是不切实际的。

标签: generics testing vhdl


【解决方案1】:

通常您希望驱动输入信号并验证输出是否具有预期值。

例如组件实例化后,

clk <= not clk after period/2;

stim : process is
begin
   -- first test
   A <= "00000010";
   B <= "00000010";
   wait for 10 ns;
   assert C = "00000100" report "2 + 2 should be 4" severity ERROR;
   -- second test
   A <= "00000000";
   -- etc
   std.env.stop;    -- in VHDL-2008, to end the simulation
end process;

因为它是自检的,所以您通常不需要费心检查波形,除非其中一个断言报告错误。然后您必须进一步分析以查看为什么输出与预期结果不匹配,记住测试可能出错。


于是我又看了一遍。

我做到了。第 57 行是"end loop;",不能溢出。

但正如 ghdl 所说,前面的行显然溢出了。为什么要写入 8 元素数组中的 9 个元素?

您可以使用类型系统而不是与之抗衡。

for j in B'range loop

将遍历 B 中的所有元素仅此而已

但是像B &lt;= (others =&gt; '0'); 这样的聚合会完全消除循环。

【讨论】:

  • 我添加了我的问题,你介意再看一遍吗?
  • ..当然还有std_logic_vector(to_unsigned([number], [width])),以便能够输入简单的自然数(您可以将其放入函数中,以减少类型工作)。
  • B'RANGE 将是 B'REVERSE_RANGE 以获取从 0 到 WIDTH-1 的订单。 OP 还为外部 for 循环执行 0 to 2**WIDTH 范围,对于 WIDTH=8 是 257 次迭代。操作数排序应该是 0 到 2**WIDTH - 1` 范围。 OP 也有一个不合适的 wait for period' 声明。 i.stack.imgur.com/xaq4P.jpg
【解决方案2】:

由于@Briandrummond 已经回答了您的溢出问题的解决方案,我将只回答问题:

谁能解释一下 generic() 的作用?

GENERIC 用于在实例化时定义实体行为,即将在您的硬件上实现的行为。它以您在示例中所做的方式在具有默认值的实体中声明

entity Xand is
    generic(
       width : integer := 8                            -- generic integer value, default is 8
    );
    port(  
       A,B   : in  std_logic_vector(width-1 downto 0); -- input signals, with length equal to generic value "width"
       C     : out std_logic_vector(width-1 downto 0)  -- output signal, with length equal to generic value "width"
    );
end Xand;

在您的示例中,GENERIC 定义了信号 A、B 和 C 的长度。这意味着当您的编译器创建网表以在您的 ASIC 或 FPGA 上实现时,它将创建具有您的 GENERIC 值定义的长度的信号.让我们看看这个实体的两个实例:

Xand_2bits : entity work.Xand
generic map(
    width => 2
)
port map(
     A => 2bits_signal_A
    ,B => 2bits_signal_B
    ,C => 2bits_signal_C
);

Xand_default : entity work.Xand
port map(
     A => 8bits_signal_A
    ,B => 8bits_signal_B
    ,C => 8bits_signal_C
);

您的编译工具不会以相同的方式合成来自同一实体的这两个实例。 实例Xand_2bits 将被合成为以下等式:

2bits_signal_C(0) <= 2bits_signal_A(0) and 2bits_signal_B(0);
2bits_signal_C(1) <= 2bits_signal_A(1) and 2bits_signal_B(1);

只有 2 个and 门将在您的硬件上实现。

实例Xand_default 将被合成为以下等式:

8bits_signal_C(0) <= 8bits_signal_A(0) and 8bits_signal_B(0);
8bits_signal_C(1) <= 8bits_signal_A(1) and 8bits_signal_B(1);
 [...]
8bits_signal_C(6) <= 8bits_signal_A(6) and 8bits_signal_B(6);
8bits_signal_C(7) <= 8bits_signal_A(7) and 8bits_signal_B(7);

这一次,8 个and 门将在您的硬件上实现。


可以使用if-generate 语句定义几种不同的行为。这个已经解释过了here


也可以定义不同的type。这个已经解释过了here

【讨论】:

  • 有泛型常量、泛型类型、泛型包和泛型子程序,所有这些都可以出现在泛型子句中并在泛型映射中关联。您似乎正在处理通用常量(保留字常量在这里是可选的)。可能收集到的问题太宽泛或您的答案不够宽泛。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-08-05
  • 1970-01-01
  • 2019-04-23
  • 1970-01-01
相关资源
最近更新 更多