[英]Simple test bench in vhdl with generic
我有一个非常简单的用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) <= '0';
行不起作用。 据我了解,A和B是具有8位的向量。 因此,我想用来自[0,256)的不同A和B值测试Xand程序。 可悲的是,我不知道如何使向量B等于0,而不是循环,这是行不通的。 有人可以解释我的generic()功能吗?
通常,您要驱动输入信号并验证输出是否具有预期值。
例如,在组件实例化之后,
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 <= (others => '0');
的聚合B <= (others => '0');
将完全消除循环。
由于@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
gate。
实例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
gate将在您的硬件上实现。
使用if-generate
语句可以定义几种不同的行为。 这已经在这里解释了
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.