VHDL语言基础-Testbech

目录

VHDL仿真概述:

基本结构:

VHDL一般仿真过程:

仿真测试平台文件:

编写测试平台文件的语言:

一个测试平台文件的基本结构如下:

测试平台文件包含的基本语句:

产生激励信号的方式:

时钟信号:

复位信号:

周期信性信号:

使用延迟DELAYD:

一般的激励信号:

动态激励信号:

使用测试矢量:

测试平台文件:

定义所测试元件的VHDL程序,该程序是一个简单的Mealy型状态机演示程序:

仿真响应:

控制仿真:

断言语句(ASSERT):

文件I/O的读写:

从文件加载数据或将数据存储到文件中:

定义文件:

打开文件:

定义文件句柄后就可以在程序中打开指定文件,同时指定打开模式。

读写文件:

关闭文件:

VHDL’93标准包括如下重要的文件I/O操作子程序:


VHDL仿真概述:

VHDL仿真器,modelsim,需要以下输入

设计的描述(项目的VHDL程序)

驱动设计的激励

VHDL本身是自激励时则无需此输入

基本结构:

VHDL一般仿真过程:


仿真测试平台文件:

测试平台文件:

定义:可以用来验证所设计的硬件模型的正确性的VHDL模型。

作用:为所测试的原件提供了激励信号,仿真结果可以以波形的方式显示或存储测试结果到文件中。

激励信号:

可以直接集成在测试平台文件中,也可以从外部文件中加载。


编写测试平台文件的语言:

个测试平台文件的基本结构如下:


测试平台文件包含的基本语句:

实体的定义语句

需要定义端口,只和被测试元件(DUT)通过内部信号相连接

测试元件的例化语句

产生时钟信号语句

产生激励源语句


产生激励信号的方式:

一定的离散时间间隔产生激励信号

基于实体的状态产生激励信号

下面通过实例,讲述激励信号的产生


时钟信号:

个周期性的激励信号可以使用一个并行的信号赋值语句来建立;

例如下面的语句即是建立周期为40ns的信号。

A <= not A after 20 ns;  --产生一个周期为40ns的信号A     

其对应的时钟波形如下图:时钟信号是同步设计中最重要的信号之一。它既可以使用并行的信号赋值语句产生(如上面的语句),也可以使用时钟产生的进程来实现定义。当使用并行的信号赋值语句时,产生的时钟信号可以是对称的或不对称的,但是信号的初始值不能为‘u

如果使用进程来定义信号,也可以产生各种时钟信号,包括对称和不对称的。在大部分情况下,时钟信号是一直运行的,并且是对称的。当定义不对称的时钟信号,如果使用并行信号幅值语句,则需要使用条件信号赋值语句;如果使用进程,则比较简单,使用顺序逻辑就可以。下面语句使用条件信号赋值语句,定义了一个25%占空比的时钟信号:

W_CLK <= '0' after PERIOD/4 when W_CLK = '1' else

                   '1' after 3*PERIOD/4 when W_CLK = '0' else

                   '0';

上述两个对称和不对称的时钟信号,也可以使用进程来定义,如下:


复位信号:

实现方式

使用并行赋值语句

在进程中设定

例如下面复位信号设置:仿真开始时,复位信号为’0’;经过20ns后,复位信号变为’1’;再经过20ns后,复位信号变为’0’

RESET <= '0', '1' after 20 ns, '0' after 40 ns;

再例如另一个复位信号设置实例,代码如下:

RESET <= '0', '1' after 100 ns, '0' after 180 ns, '1' after 210 ns;

RESET信号初始为’0’,经过100ns后,变为’1’;再经过80ns,该信号变为’0’;再经过30ns,该信号返回到’1’。其波形如下:


周期信性信号:

可以在进程中使用信号赋值语句实现信号的周期性信号设置。

上例定义了两个周期性信号,为了实现信号的周期性变化,后面使用一个WAIT语句。其波形如下:

 


使用延迟DELAYD:

可使用预定义属性DELAYD关键词来产生信号。如果已经产生了一个时钟信号,在这个时钟信号的基础上,可以使用DELAYD来使已经产生的时钟信号延迟一定的时间,从而获得另一个时钟信号。

假如我们已经使用如下的语句定义了一个时钟信号W_CLK

W_CLK <= '1' after 30 ns when W_CLK = '0' else

                   '0' after 20 ns;

然后可以使用如下的延迟语句获得一个新的时钟信号DLY_W_CLK,它比W_CLK延迟了10ns

DLY_W_CLK <= W_CLK'DELAYED(10 ns);

以上两个时钟信号波形如下:


一般的激励信号:

定义的普通的激励信号来用作模型的输入信号;

通常在进程中定义;

一般使用WAIT语句来定义。

例如下面的激励信号定义:

波形如下:


动态激励信号:

动态激励信号,就是被仿真的实体(DUT)的行为模型相关,即DUT的输入激励信号受模型的行为所影响。

如下信号的定义,模型的输入信号Sig_A和模型输出信号Count相关。


使用测试矢量:

将一组固定的输入输出矢量值存储在一个常量表或一个ascii文件中,然后将这些值应用到输入信号从而产生激励信号;

矢量的值序列可以使用多维数组或使用多列记录来描述。

如下面的数据表存储了输入矢量:

假设所测试的实体(DUT)具有4个输入:ABCD信号,如果以一般的时间间隔应用测试矢量,则可以使用一个GENERATE语句,例:

如果将信号应用于任意时间间隔,则需要使用并行的信号赋值语句产生多个信号的波形;使用这种方法可以将一个矢量赋值给多个信号,例如下面的代码:

 


测试平台文件:

时钟周期为20ns,在一个时钟波形产生进程中定义。激励信号波形在另一个进程中产生。实体为一个空实体,没有输入输出信号端口。

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY S_MACHINE_TB IS
END;
 
ARCHITECTURE BHV OF S_MACHINE_TB IS
  COMPONENT S_MACHINE
      PORT (CLK, RESET: IN STD_LOGIC;
              STARE_INPUTS: IN STD_LOGIC_VECTOR (0 TO 1);
              COMB_OUTPUTS: OUT STD_LOGIC_VECTOR (0 TO 1)
              );
  END COMPONENT;
  --INPUT SIGNAL
  SIGNAL CLK: STD_LOGIC := '0';
SIGNAL RESET: STD_LOGIC := '0';
SIGNAL STARE_INPUTS: STD_LOGIC_VECTOR (0 TO 1) := "00";
--OUTPUT SIGNAL
SIGNAL COMB_OUTPUTS: STD_LOGIC_VECTOR (0 TO 1);
  
--TIMER PERIOD DEFINE
CONSTANT CLK_PERIOD: TIME := 20 NS;
BEGIN
    --component instantiation
    DUT:S_MACHINE PORT MAP(CLK=>CLK, 
                            RESET=>RESET, 
                            STARE_INPUTS=>STARE_INPUTS, 
                            COMB_OUTPUTS=>COMB_OUTPUTS);
    --generate clock signal
    clk_gen: PROCESS
    BEGIN
CLK <= '1';
        WAIT FOR CLK_PERIOD/2;
        CLK <= '0';
        WAIT FOR CLK_PERIOD/2;
     END PROCESS;
     --drive signal
     TB: PROCESS
     BEGIN
        WAIT FOR 20 NS;
        RESET <= '1';
        WAIT FOR 20 NS;
        RESET <= '0';
        WAIT FOR 210 NS;
        STARE_INPUTS <= "01";
        WAIT FOR 20 NS;
        STARE_INPUTS <= "10";      
        WAIT  FOR  20 NS;
STARE_INPUTS <= "11";
        WAIT FOR 20 NS;
        STARE_INPUTS <= "00";
        WAIT FOR 20 NS;
        STARE_INPUTS <= "11";
        WAIT FOR 20 NS;
        STARE_INPUTS <= "10";
        WAIT FOR 20 NS;
        STARE_INPUTS <= "01";
        WAIT FOR 20 NS;
        STARE_INPUTS <= "00";
        WAIT FOR 20 NS;
       WAIT;
     END PROCESS;   
  END;



定义所测试元件的VHDL程序,该程序是一个简单的Mealy型状态机演示程序:

LIBRARY IEEE;
USE IEEE.STD_LOGIC_1164.ALL;
ENTITY S_MACHINE IS
  PORT (CLK, RESET: IN STD_LOGIC;
        STARE_INPUTS: IN STD_LOGIC_VECTOR(0 TO 1);
          COMB_OUTPUTS: OUT STD_LOGIC_VECTOR(0 TO 1)
          );
END;
 
ARCHITECTURE ART OF S_MACHINE IS
  TYPE STATES IS (ST0, ST1, ST2, ST3); --define STATES as enum
  SIGNAL CURRENT_STATE, NEXT_STATE: STATES;
    BEGIN
REG: PROCESS (RESET, CLK)
        BEGIN
          IF RESET = '1' THEN
            CURRENT_STATE <= ST0;
          ELSIF(CLK = '1' AND CLK'EVENT) THEN
            CURRENT_STATE <= NEXT_STATE;
          END IF;
        END PROCESS;
        
        COM: PROCESS(CURRENT_STATE, STARE_INPUTS)  
         --feedback signal
        BEGIN
          CASE CURRENT_STATE IS
          WHEN ST0=>
            COMB_OUTPUTS<="00";
             IF STARE_INPUTS="00" THEN
               NEXT_STATE<=ST0;
             ELSE
               NEXT_STATE<=ST1;
             END IF;
          WHEN ST1=>
            COMB_OUTPUTS<="01";
             IF STARE_INPUTS = "00" THEN
               NEXT_STATE <= ST1;
             ELSE
               NEXT_STATE <= ST2;
             END IF;
          WHEN ST2=>
            COMB_OUTPUTS <= "10";
             IF STARE_INPUTS = "11" THEN
NEXT_STATE <= ST2;
             ELSE
               NEXT_STATE <= ST3;
             END IF;
          WHEN ST3=>
            COMB_OUTPUTS <= "11";
             IF STARE_INPUTS = "11" THEN
               NEXT_STATE <= ST3;
             ELSE 
               NEXT_STATE <= ST0;
             END IF;
          END CASE;
        END PROCESS;
     END ART;

 使用以上测试平台文件对元件进行功能仿真,仿真结果如下图:


仿真响应:

控制仿真:

控制,则仿真会一直持续到时间等于设定的仿真时间;

如果想在某个时间终止仿真,可使用断言语句ASSERT来实现;

另外,ASSERT语句可以实现对某些值或行为作出响应。

断言语句(ASSERT):

适合于执行仿真的自动响应;

可以检查一个条件并报告信息;

根据所选择的严重级别和仿真工具的设置,在ASSERT语句报告了信息后,仿真可以继续执行(警告级别WARNING)或者停止(错误ERROR或致命错误FAILURE),默认的严重级别为ERROR

使用断言语句判断仿真的时间,如果当前时间为1000ns,则仿真完成,使用ERROR严重级别终止仿真过程。

断言语句判断条件时,如果条件的判断结果为FALSE,则执行后面的报告及严重级语句,否则仿真会忽略后面的报告和严重级语句并继续执行。

可以使用ASSERT语句设定一个判断条件,以便对仿真的某个结果或值做出响应,例如:

下面的程序为4位计数器的行为模型,计数器的位数为4位。方向由信号DIR决定,如果DIR为高电平,则正向计数,如果DIR为低电平,则反向计数。计数结果保存在CT_RESULT信号中。

下面的程序为测试平台,在程序中,一个断言语句用于判断计数结果是否等于”1001”。条件判断使用了“不等于(/=)逻辑”,如果判断条件为FALSE,即等于“1001”,则报告信息,并终止仿真。

以上测试文件在Modelsim中的仿真波形如下:

当计数到”1001”,在Modelsim的信息栏输出所要报告的信息,如下:


文件I/O的读写:

从文件加载数据或将数据存储到文件中:

例如用户定义的测试矢量可以保存在文件中,然后在仿真时从文件中读取这些测试矢量。

另外,仿真的结果可以保存在文件中。

VHDL’93的文件I/O读写主要是用于仿真,综合工具并不支持文件I/O的读写。

如果想在仿真时进行文件操作,必须包括标准库STD中的TEXTIO定义的程序库,该程序库中包含了文件啊你输入输出所需要的基本子程序(函数和过程)。


定义文件:

文件的两个类型:

Integer:文件中的数据是以二进制存取的,不能被人识别,只有integer型的数据能够存入这列文件。

String:文件是以ascii码形式读取的,可以被人识别;integerbit_vector(x downto y)string(x downto 1)std_logic_vector(x downto o)bit等都可以被存入此类文件。

定义语法:

FILE FILEIN : TEXT;

TYPE INTEGERFILE IS FILE OF INTEGER;

FILE FILEIN : INTEGERFILE;


打开文件:

定义文件句柄后就可以在程序中打开指定文件,同时指定打开模式。

读写文件:

打开文件后就可以对文件进行读写操作,其语句格式如下:

使用以上语句只能写入指定类型的数据,如integer类型的只能写入integer型数据。如果写入其他类型需要遵循以下步骤:


关闭文件:

在文件读写完毕后,需使用file_close(file_handle);关闭文件。

ENDFILE(file_handle);判断在文件操作中是否读取到文件的末尾


VHDL’93标准包括如下重要的文件I/O操作子程序:

下面举一个例子,使用了上面介绍的各种语法:

h3

modelsim控制台做如下操作:

等待数秒后,在modelsim工程目录下将会新建一个”DATAIN.TXT”文本文档,打开文档其内容如下:

猜你喜欢

转载自blog.csdn.net/weixin_50932441/article/details/129004822