VHDL-文件读写
在使用FPGA进行数字信号的时候经常要用到matlab对FPGA设计运行的结果进行验证,因此就需要在仿真的时候把modelsim运行的结果写入文件,事后可以用matlab分析验证。
VHDL对文件操作包括创建文件,写入,读取。其实在仿真的时候还可以结合modelsim的控制台,更方便的完成仿真。
参考博文,在此感谢:
1、VHDL中的文件I/O
2、VHDL中的文件I/O
VHDL有4中数据对象:
常量:constant
变量:variable
信号:signal
文件:file
其中文件(file)是不能被综合的,且只能声明在进程内,其余三种可以被综合。
变量能被综合,但变量不对应实际的物理线路,它通过对FPGA内部的存储空间的访问实现其功能,因此只能声明在进程内。
常量可以声明在进程内也可以声明在进程外,因为它可以对应实际的物理线路也可以通过FPGA内部的存储器实现。
信号对应实际的物理线路,只能声明在进程外。如果声明在进程内,仿真都过不去,modelsim会提示该信号不能声明在此区域。如下:
process(rst_n_i, clk_i)
file file1:text;
variable file_status:file_open_status;
variable buf:LINE;
– variable cnt_from_file_r:std_logic_vector(7 downto 0):=(others=>’0’);
variable cnt_from_file_r:natural:=0;
variable file_name:string(1 to 11):=”nihaonihaon”;
constant rst_cnt_stop:natural:=5;
signal rst_cnt_stop2:natural:=5;
begin
…
编译时modelsim提示的错误如下:
Signal declaration ‘rst_cnt_stop2’ not allowed in this region.
1.
1、文件类型有两种,一种是integer,文中的数据是以二进制存取的,不易查看(也可以通过ultraedit来查看)
另一种就是文本类型(text),数据以ASCii码存储,文本类型的数据容易查看。
定义文件:
file romData:text; //定义一个文件
2、文件打开有4中状态:
open_ok:打开成功
status_error:打开失败
name_error:名字错误
mode_error:打开模式失败
用file_open_status类型的数据来表示文件状态,声明方式如下:
variable file_status:file_open_status
3、line类型,是以行的形式写入或读取数据的,还能借助于line来实现把integer,natural,bit_vector等类型的数据写入text类型的文件,下面有介绍。
声明形式:variable buf:line;
文件操作:
打开文件:file_open
写入文件:write,writeline
读取文件:read,readline
关闭文件:file_close
file_open(file_open_status,file_fid,file_name,mode);
file_open_status:文件打开的状态
file_fid:文件句柄(file声明)
file_name:文件名字(string类型,如:”data.txt”)
mode:打开的类型,write_mode和read_mode
write和writeline的区别:
write只能写对应于文件类型的数据,如text类型只能写string,integer类型只能写integer类型数据
如果要写入integer,natural,std_logic,std_logic_vector类型的数据到text类型文件,就只能使用line来操作,
首先write(buf,std_logic_vector),把要写入的std_logic_vector类型数据写入line类型的buf,
然后通过writeline(file,buf)来写入数据.
read和readline的区别与write和writeline一样。
file_close(file_fid);
对控制台的操作:
writeline(output,buf); //output代表输出数据到控制台,是关键字,buf是line类型,可以理解为一行的意思
readline(input,buf); //input代表从控制台输入数据,是关键字
示例:
向控制台写入数据
signal cnt:natural:=0;
write(buf,cnt);
writeline(output,buf);
从控制台读取数据
readline(input,buf);
write(buf,cnt);
工程示例代码如下:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use std.textio.all;
use ieee.std_logic_textio.all;
entity count_tb is
end entity;
architecture rt1 of count_tb is
component count is
port(
--input:
rst_n_i :in std_logic:='1';
clk_i :in std_logic:='0';
--output:
cnt_o :out std_logic_vector(7 downto 0):=(others=>'0')
);
end component;
signal rst_n_i : std_logic:='1';
signal clk_i : std_logic:='0';
signal cnt_o : std_logic_vector(7 downto 0):=(others=>'0');
signal rst_n_r:std_logic:='0';
signal rst_n_rise:std_logic:='0';
signal rst_cnt:natural:=0;
type status_type is (s_idle, s_write, s_write_end, s_read_begin, s_read, s_end);
signal c_status:status_type:=s_idle;
signal cnt_from_file:std_logic_vector(7 downto 0):=(others=>'0');
begin
count_inst:count port map
(
rst_n_i => rst_n_i,
clk_i => clk_i,
cnt_o => cnt_o
);
rst_n_i<='1',
'0' after 100 ns,
'1' after 200 ns,
'0' after 1 us,
'1' after 1100 ns,
'0' after 2 us,
'1' after 2100 ns,
'0' after 3 us,
'1' after 3100 ns,
'0' after 4 us,
'1' after 4100 ns,
'0' after 5 us,
'1' after 5100 ns,
'0' after 6 us,
'1' after 6100 ns;
clk_i<=not clk_i after 10 ns;
process(rst_n_i, clk_i)
file file1:text;
variable file_status:file_open_status;
variable buf:LINE;
-- variable cnt_from_file_r:std_logic_vector(7 downto 0):=(others=>'0');
variable cnt_from_file_r:natural:=0;
variable file_name:string(1 to 11):="nihaonihaon";
constant rst_cnt_stop:natural:=5;
begin
if rising_edge(clk_i) then
case c_status is
when s_idle => c_status<=s_write;
file_open(file_status,file1,"data_record.txt",write_mode);
when s_write => if rst_cnt>=rst_cnt_stop then
c_status<=s_write_end;
else
c_status<=s_write;
end if;
write(buf,cnt_o);
writeline(file1,buf);
when s_write_end => file_close(file1);
c_status<=s_read_begin;
when s_read_begin => file_open(file_status,file1,"sinWave.txt",read_mode);
readline(file1,buf);
--read(buf,file_name);
writeline(output,buf);
c_status<=s_read;
when s_read =>
if endfile(file1) then
c_status<=s_end;
else
c_status<=s_read;
readline(file1,buf);
read(buf,cnt_from_file_r);
cnt_from_file<=std_logic_vector(to_unsigned(cnt_from_file_r,8));
end if;
when s_end => c_status<=s_end;
file_close(file1);
when others => c_status<=s_end;
end case;
else
null;
end if;
end process;
process(clk_i)
begin
if rising_edge(clk_i) then
rst_n_r<=rst_n_i;
else
null;
end if;
end process;
rst_n_rise<=rst_n_i and (not rst_n_r);
process(clk_i)
begin
if rising_edge(clk_i) then
if rst_n_rise='1' then
rst_cnt<=rst_cnt+1;
else
null;
end if;
else
null;
end if;
end process;
end rt1;
例化的元件count是一个计数器,把计数的结果写入文件data_record.txt文件中,
从另一个存有波形数据的文件sinWave.txt中读取数据。