VHDL学习之TEXTIO在仿真中的应用

TEXTIO 在VHDL 仿真与磁盘文件之间架起了桥梁,使用文本文件扩展VHDL 的仿真功能。本文介绍TEXTIO 程序包,以一个加法器实例说明TEXTIO 的使用方法,最后使用ModelSim 对设计进行仿真,并分析仿真结果。在对VHDL 源程序进行仿真时, 由于有的输入输出关系仅仅靠输入波形或编写testbench 中的信号输入是难以验证结果正确性的,例如, 设计8 位加法器,如果将所有的输入都验证一遍, 是非常麻烦的,因为要全面判断输出是否正确需要一个个的验证。此外,若用VHDL 设计一个处理器,需要读入指令,这时候采用文本文件非常必要。
    TEXTIO 提供了VHDL 仿真时与磁盘文件的交互。在验证加法器时候, 可以将所有输入保存在一个文本文件中,将其它软件计算出的结果保存在另外的文件中。在VHDL 仿真时,可以直接读取输入文件作为设计的输入参数,并自动将结果与事先保存的文件相比较,给出一定的信息来确定结果的正确与否。在对VHDL 编写的处理器调试时,可以将包括指令类型、源地址、目标地址在内的指令保存成文本文件, 利用TEXTIO 来读取这些指令。同时,将结果及中间变量保存成文本文件,以事后判断是否正确及便于查找原因。由于TEXTIO 的文本输入输出功能非常有限,一些公司提供了扩展其功能的程序包,例如std_developerskit库中的std_iopak 程序包。在本文中,仅仅对TEXTIO 程序包做简单的介绍及其简单的使用。
1 TEXTIO介绍
    TEXTIO 是VHDL 标准库STD 中的一个程序包(Package)。在该包中定义了三个类型:LINE 类型、TEXT类型以及SIDE 类型。另外,还有一个子类型(subtype)WIDTH。此外,在该程序包中还定义了一些访问文件所必须的过程(Procedure)。

1.1 类型定义
(1)type LINE is access string
    定义了LINE 为存取类型的变量,它表示该变量是指向字符串的指针,它是TEXTIO 中所有操作的基本单元。读文件时,先按行(LINE)读出一行数据,再对LINE 操作来读取各种数据类型的数据;写文件时,先将各种的数据类型组合成LINE,再将LINE 写入文件。在用户使用时, 必须注意只有变量才可以是存取类型,而信号则不能是存取类型。例如, 我们可以定义
variable DLine : LINE;
但不能定义成
signal DLine : LINE;
(2)type TEXT is file of string
定义了TEXT 为ASCII 文件类型。 定义成为TEXT 类型的文件是长度可变的ASCII 文件。例如在TEXTIO 中定义了两个标准的文本文件。
file input : TEXT open read_mode is STD_INPUT;
file output : TEXT open write_mode is STD_OUTPUT;
定义好以后,就可以通过文件类型变量input 和output 来访问其对应的文件STD _ INPUT 和STD_OUTPUT。
(3)type SIDE is (right,left)
定义了SIDE 类型。表示定义了一个名为SIDE 的数据类型,其中只能有两种状态,即right 和left,分别表示将数据从左边还是右边写入行变量。该类型主要是在TEXTIO 程序包包含的过程中使用。
(4)subtype WIDTH is natural
定义WIDTH 为自然数的子类型。所谓子类型表示其取值范围是父类型范围的子集。

1.2 过程定义
  TEXTIO 提供了基本的用于访问文本文件的过程。类似于C++,VHDL 提供了重载功能,即完成相近功能的不同过程可以有相同的过程名, 但其参数列表不同, 或参数类型不同或参数个数不同。
TEXTIO 提供的基本过程有:

procedure READLINE(文件变量;行变量);用于从指定文件读取一行数据到行变量中。
procedure WRITELINE(文件变量;行变量);用于向指定文件写入行变量所包含的数据。
procedure READ(行变量;数据类型);用于从行变量中读取相应数据类型的数据。
  
根据参数数据类型及参数个数的不同,有多种重载方式,TEXTIO 提供了bit、bit_vector 、BOOLEAN 、character、 integer、real、string、time数据类型的重载。同时,提供了返回过程是否正确执行的BOOLEAN 数据类型的重载。例如, 读取整数的过程为
procedure READ(L:inout LINE; VALUE: out integer; GOOD: out BOOLEAN);其中,GOOD 用于返回过程是否正确执行, 若正确执行, 则返回TRUE 。
procedure WRITE(行变量; 数据变量; 写入方式; 位宽);
该过程将数据写入行变量。其中写入方式表示写在行变量的左边还是右边,且其值只能为left 或right,位宽表示写入数据时占的位宽。例如:
write(OutLine,OutData,left,2);
表示将变量OutData 写入LINE 变量OutLine 的左边占2 个字节。

2 TEXTIO应用实例
  下面以一个简单的8 位加法器来说明TEXTIO 的使用。输入数据为两个8 位的有符号数, 输出为9 位的有符号数,以防止溢出。在编写加法器的描述文件时,首先要对两个数进行位的扩展,再进行加法运算。在编写测试文件时,要注意读入数据与得到结果之间相差一个时钟周期。因此,需要在读出的结果与计算的结果之间插入一个时钟周期的等待。textio包如下

-- textio.vhdl

library std; use std.standard.all;    -- needed for bootstrap mode

package TEXTIO is

  -- Type Definitions for Text I/O

  type LINE is access STRING;    -- a line is a pointer to a STRING value

  type TEXT is file of STRING;    -- a file of variable-length ASCII records

  type SIDE is (RIGHT, LEFT);    -- for justifying output data within fields

  subtype WIDTH is NATURAL;    -- for specifying widths of output fields

  -- Standard Text Files

  file INPUT: TEXT open READ_MODE is "STD_INPUT";

  file OUTPUT: TEXT open WRITE_MODE is "STD_OUTPUT";

  -- Input Routines for Standard Types

  procedure READLINE (file F: TEXT; L: inout LINE);

  procedure READ (L: inout LINE; VALUE: out BIT; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out BIT);

  procedure READ (L: inout LINE; VALUE: out BIT_VECTOR; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out BIT_VECTOR);

  procedure READ (L: inout LINE; VALUE: out BOOLEAN; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out BOOLEAN);

  procedure READ (L: inout LINE; VALUE: out CHARACTER; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out CHARACTER);

  procedure READ (L: inout LINE; VALUE: out INTEGER; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out INTEGER);

  procedure READ (L: inout LINE; VALUE: out REAL; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out REAL);

  procedure READ (L: inout LINE; VALUE: out STRING; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out STRING);

  procedure READ (L: inout LINE; VALUE: out TIME; GOOD: out BOOLEAN);
  procedure READ (L: inout LINE; VALUE: out TIME);

  -- Output Routines for Standard Types

  procedure WRITELINE (file F: TEXT; L: inout LINE);

  procedure WRITE (L: inout LINE; VALUE: in BIT;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);

  procedure WRITE (L: inout LINE; VALUE: in BIT_VECTOR;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);

  procedure WRITE (L: inout LINE; VALUE: in BOOLEAN;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);

  procedure WRITE (L: inout LINE; VALUE: in CHARACTER;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);

  procedure WRITE (L: inout LINE; VALUE: in INTEGER;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);

  procedure WRITE (L: inout LINE; VALUE: in REAL;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0;
            DIGITS: in NATURAL := 0);

  procedure WRITE (L: inout LINE; VALUE: in STRING;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0);

  procedure WRITE (L: inout LINE; VALUE: in TIME;
            JUSTIFIED: in SIDE := RIGHT; FIELD: in WIDTH := 0;
            UNIT: in TIME := ns);

  -- File Position Predicates

  function ENDLINE (L: in LINE) return BOOLEAN;

end TEXTIO;

8位全加器如下:

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_signed.all;

entity Add2In is
    port( D1        : in std_logic_vector(7 downto 0);
            D2        : in std_logic_vector(7 downto 0);
            Q         : out std_logic_vector(8 downto 0);
            Clk    : in std_logic
    );
end entity;

architecture beha of Add2In is
begin
    process(Clk)
    begin
        if Clk‘event and Clk = ‘1‘ then
            Q <= (‘0‘ & D1) + D2;
        end if;
    end process;
end beha;

编写测试文件。
  在测试程序中, 首先读出输入文件的一行内容,再从该行中提取出两个值输入加法器。从预定结果文件中提取出一个值,将加法器计算结果与该值比较, 若两者不同则输出警告信息。也可以将输出写入一个文本文件,再比较两个文本文件的异同以获知出错的地方。这里要注意的是要使用TEXTIO 程序包, 另外, 测试文件实体内的端口为空,相当于一块独立的电路板。使用Component 在其中包含了上面定义的加法器,该独立的电路板所完成的功能是对设计的加法器进行测试。在程序中使用了assert 断言语句,要注意该语句后的表达式或变量为真时不执行后续的输出,为假时执行后续的输出。在程序中,还使用了类型转换函数CONV _ STD _LOGIC_VECTOR (),将整数转换为8 位的标准类型。另外,在程序中定义了变量Dlatch ,该变量的作用是将计算结果与预定结果的比较延迟一个时钟周期, 周期地与预定结果比较。

LIBRARY ieee;
USE ieee.std_logic_1164.all;
USE ieee.std_logic_arith.all;
USE ieee.std_logic_signed.all;
USE std.textio.all;

ENTITY Add2In_vhd_tst IS
END Add2In_vhd_tst;
ARCHITECTURE Add2In_arch OF Add2In_vhd_tst IS

SIGNAL Clk : STD_LOGIC := ‘0‘;
SIGNAL D1 : STD_LOGIC_VECTOR(7 DOWNTO 0):=(others => ‘0‘);
SIGNAL D2 : STD_LOGIC_VECTOR(7 DOWNTO 0):=(others => ‘0‘);
SIGNAL Q : STD_LOGIC_VECTOR(8 DOWNTO 0);
SIGNAL SResult    :    INTEGER;
SIGNAL OutData :     INTEGER;
SIGNAL Dlatch    :    boolean := false;

COMPONENT Add2In
    PORT (
    Clk : IN STD_LOGIC;
    D1 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    D2 : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
    Q : OUT STD_LOGIC_VECTOR(8 DOWNTO 0)
    );
END COMPONENT;
BEGIN
    i1 : Add2In
    PORT MAP (
    Clk => Clk,
    D1 => D1,
    D2 => D2,
    Q => Q
    );

init : PROCESS(Clk)
BEGIN
    Clk <= not Clk after 10ns;
END PROCESS init;

always : PROCESS
    FILE InputD    :    text open read_mode is "TestData.dat";
    FILE OutputD    :    text open write_mode is "OutData.txt";
    VARIABLE Dline    :    LINE;
    VARIABLE Rline    :    LINE;
    VARIABLE    Data1    :    INTEGER;
    VARIABLE Data2    :    INTEGER;
    VARIABLE    OutData    :    INTEGER;
BEGIN
    WAIT UNTIL Clk‘event and CLk = ‘1‘;
        readline(InputD, Dline);
        read(Dline, Data1);
        read(Dline, Data2);

        D1 <= conv_std_logic_vector(Data1, 8);
        D2 <= conv_std_logic_vector(Data2, 8);
        OutData <= conv_integer(Q);

        writeline(OutputD, Rline);
        write(Rline, OutData);
END PROCESS always;                                          

PROCESS
FILE InputR    :    text open read_mode is "Result.dat";
VARIABLE    Rline    :    LINE;
VARIABLE    Result    :    INTEGER;
BEGIN
    WAIT UNTIL Clk‘event and Clk = ‘1‘;
        Dlatch <= true;
        if Dlatch then
            readline(InputR, Rline);
            read(Rline, Result);
            SResult <= Result;

            if(SResult /= Q) then
                assert false report "Two values are different"
                    severity warning;
            end if;
        end if;
END PROCESS;

END Add2In_arch;

TEXTIO 使得VHDL 的仿真功能有了大的飞跃, 在使用VHDL 描述处理器等模型及判断系统对不规则输入的响应时,起到了非常大的作用。本文通过简单的实例,说明了TEXTIO 库及其简单的应用流程。在当前嵌入式系统广泛应用的背景下,将更为需要TEXTIO 的应用。

引用地址:http://www.eefocus.com/article/08-03/9143280903334AkJ.html

时间: 2024-12-15 18:29:38

VHDL学习之TEXTIO在仿真中的应用的相关文章

Maven学习笔记之——仓库(中)

Maven学习笔记之--仓库(中) 1.    远程仓库的配置 当出现默认的中央仓库无法满足我们的需求或者连接不上的时候.我们可以通过POM文件来指定远程仓库. <repositories> <repository> <id>jboss-maven2-release-repository</id> <name>JBoss Repository</name> <url>http://repository.jboss.org/

Java Web学习系列——Maven Web项目中集成使用Spring、MyBatis实现对MySQL的数据访问

本篇内容还是建立在上一篇Java Web学习系列——Maven Web项目中集成使用Spring基础之上,对之前的Maven Web项目进行升级改造,实现对MySQL的数据访问. 添加依赖Jar包 这部分内容需要以下Jar包支持 mysql-connector:MySQL数据库连接驱动,架起服务端与数据库沟通的桥梁: MyBatis:一个支持普通SQL查询,存储过程和高级映射的优秀持久层框架: log4j:Apache的开源项目,一个功能强大的日志组件,提供方便的日志记录: 修改后的pom.xm

网络仿真中的有限状态机(FSM)

最近在看<OMNET++ User Mannul>,了解到了有限状态机的工作机制.相比早之前看过的<OPNET xxx>教材中讲解FSM不明不白,<OMENT++ User Mannul>讲解的更为清晰简洁,且有偏底层的代码做实例,更易理解. FSM是指完成模块功能的一种手法(例如OMNET++中的模块功能可选择是否由FSM完成),下文的FSM均指模块中的FSM. 构成FSM的主体为状态(State)和状态跳转(State Transition),其中状态分为两种:1)

php学习之道:php中soap的使用实例以及生成WSDL文件,提供自动生成WSDL文件的类库——SoapDiscovery.class.php类

1. web service普及: Webservice soap wsdl区别之个人见解 Web Service实现业务诉求:  Web Service是真正"办事"的那个,提供一种办事接口的统称. WSDL提供"能办的事的文档说明":  对要提供的服务的一种描述格式.我想帮你的忙,但是我要告诉你我都能干什么,以及干这些事情需要的参数类型. SOAP提供"请求"的规范:  向服务接口传递请求的格式,包括方法和参数等.你想让人家办事,总得告诉人家

Android学习笔记_78_ Android开发中使用软引用和弱引用防止内存溢出

在<Effective Java 2nd Edition>中,第6条"消除过期的对象引用"提到,虽然Java有 垃圾回收机制,但是只要是自己管理的内存,就应该警惕内存泄露的问题,例如的对象池.缓存中的过期对象都有可能引发内存泄露的问题.书中还提到可以用 WeakHashMap来作为缓存的容器可以有效解决这一问题.之前也确实遇到过类似问题,但是没有接触过"弱引用"相关的问题,于是查阅了一些资料. <Java 理论与实践: 用弱引用堵住内存泄漏>

c++学习笔记5,多重继承中派生类的构造函数与析构函数的调用顺序(二)

现在来测试一下在多重继承,虚继承,MI继承中虚继承中构造函数的调用情况. 先来测试一些普通的多重继承.其实这个是显而易见的. 测试代码: //测试多重继承中派生类的构造函数的调用顺序何时调用 //Fedora20 gcc version=4.8.2 #include <iostream> using namespace std; class base { public: base() { cout<<"base created!"<<endl; }

php学习之道:php中iconv函数 详解

iconv函数库能够完成各种字符集间的转换,是php编程中不可缺少的基础函数库. 用法如下: $string = "亲爱的朋友欢迎访问胡文芳的博客,希望给您带来一点点的帮助!"; iconv("utf8","gbk",$string)//将字符串string  编码由utf8转变成gbk: 扩展如下: echo $str= '你好,欢迎访问胡文芳的博客,该博客记录一个程序员的成长过程!'; echo ' '; echo iconv('GB2312

【C#学习路途之一】数据类型中的值类型

刚刚学习了C#的数据类型中的值类型,在C#中,数据类型分为三中,一种是值类型,另一种是引用类型,最后一种不常用,是指针类型,这个在C语言中经常使用,到现在我都没搞明白! 整数类型: 数据类型 含义 取值范围 sbyte 有符号8位整数 -128到127 byte 无符号8位整数 0到255 short 有符号16位整数 -32768到32767 ushort 无符号16位整数 0到65535 int常用 有符号32位整数 2三十一次方 到 2三十一次方-1 uint 无符号32位整数 0到429

lua学习笔记11:lua中的小技巧

lua中的小技巧,即基础lua语言本身的特种,进行一个些简化的操作 一 巧用or x = x or v 等价于: if not x then x = v end 如果x为nil或false,就给他赋值为 二 三元运算符实现 a and b or c 类似C语言: a ? b : c and 的运算由优先级高于or lua学习笔记11:lua中的小技巧,布布扣,bubuko.com