系统任务也属于行为级建模,系统任务的调用要出现在initial与always结构中。所有的任务都已$开头。
1、$display,$write用于信息的显示和输出。其中,
%b或%B 二进制
%o或%O 八进制
%d或%D 十进制
%h或%H 十六进制
%e或%E 实数
%c或%C 字符
%s或%S 字符串
%v或%V 信号强度
%t或%T 时间
%m或%M 层次实例
\n 换行
\t 制表符
\\ 反斜杠\
\" 引号”
\%% 百分号%
调用方式:eg:$display("%b+%b=%b",a,b,sum);
$write("%b+%b=%b",a,b,sum);
注:如果没有在指定变量的显示格式,不会输出数值。如果没有指定变量显示的位置,变量值会在字符串部分之后直接显示出来,变量之间是没有间隔的,只是一次简单的显示。
显示任务$display默认显示的格式是十进制的,还有$displayb,$displayo,$displaybh的显示格式分别是二进制,八进制,十六进制。同理有$write,$writeo,$writeb,$writeh。
$display与$write的区别是:$display会在每次显示信息后自动换行,$write不会换行。
2、$strobe探测任务
探测任务的语法和显示任务完全相同,也是把信息显示出来。也有$strobe,$strobeb,$strobeo,$strobeh四种。
两者的区别在于:$strobe命令会在当前时间部结束时完成;而$display是只要仿真器看到就会立即执行。
3、$monitor监测任务
监测任务用于持续监测指定变量,只要这些变量发生了变化,就会立即显示对应的输出语句。
eg:
initial
begin
$monitor("x=%b,y=%b,cin=%b",x,y,cin);
end
同理,有$monitor,$monitorb$monitoro$monitorh。
可用$monitoroff,monitoeron关闭监事和打开监视。
4、$stop,$finish仿真控制任务
区别:$stop暂停当前方针,$finish中值当前方针。
读操作用到的语句是:$readmemb()或$readmemh()。
大部分编译器和仿真器在读文件的时候需要预先打开文件。在VIVADO自带仿真器中,读文件不需要预先打开要读取的文件,也不需要将文件加入VIVADO工程内部,只需要利用系统函数readmemh、readmemb就可以了(readmemh表示读取16进制数、readmemb表示读取二进制数)。函数使用方式例子如下:
reg [31:0] mem [0:100]
$readmemh(“D:/…/filename.txt”,mem,0,100);
reg [31:0] mem [0:100];
$readmemh(“D:/…/filename.txt”,mem,0,100);
其中,“D:/…/”表示文件路径(注意是“/”,方向不能反);
“filename.txt”表示文件;
“mem”为预先定义的寄存器组;
“0”读取文件内容的初始地址;
“100”读取文件内容的结束地址。
读取文件格式最好是纯数据,且每一行最好只有一个数。对应不同的系统函数,数字需要对应的进制。
1. 读操作
读操作用到的语句是:$readmemb()或$readmemh()。
以$readmemb()为例,它的调用为
$readmemb("file_name",memory)
file_name:可以是.txt、.doc等格式的文件,但必须遵守ROM的规范,即其内容形式必须 如下:
@00 01010_01001010010010101010
@01 000010100101001001_0010010
.......
@0f 0010101010101_010010010010
其中:@后紧跟的ROM单元的地址,它必须用十六进制表示。在ROM单元地址与其后 的二进制比特流串之间至少要有一个空格(亦可以有回车);比特流可以用"_"隔开,以增强程序的可读性。
memory:memory的声明格式为:
reg[WORD_LEN-1 : 0] my_rom [WORD_NUM-1 : 0];
其中:WORD_LEN代表的是每一个ROM向量的长度,即二进制流的长度;WORD_NUM代表的是ROM向量的个数。
值得注意的是执行完$readmemb()指令后文件中的对应单元就一次性的存储到my_rom当中。在后续的处理中my_rom只能通过其地址访问,一次性地读取对应地址上的向量,如my_rom[k];而不能访问到具体的每一位或几位,如my_rom[k][n];如果要取其中的某一位,可通过将ROM得向量赋给以个寄存器组,再进行引用,需强调的是ROM单元存储文件中向量的时候,将文件二进制串前头的数据存于高位,将二进制串中末尾的数据存于低位。
一般情况下,可由matlab生成内存文件。如以下的一个简单的.m文件。
clear all
clc
fid = fopen('test.txt','wt');
for i = 0 : 63
fprintf(fid,'@%x %s\n',i,dec2bin(i,6));
end
fclose(fid);
对于写文件,VIVADO和所有的FPGA仿真器一样,下面只是简单的给出一个例子,不做过多的赘述:
integer fid;
fid=$fopen(“D:/…/filename.txt”);
$fwrite(fid,”%d\n”,mem);
$fwrite不会自动换行
2. 写操作
写操作用用到的操作主要有$fopen(),$fdisplay()和$fclose()。
$fopen()用于打开一个待写入得文件,并返回一个整型句柄,如:
integer fid;//定义一个整型变量
fid = $fopen("my_file");
$fdisplay()用于向一个打开的文件写入一个向量,如:
$fdisplay(fid,"%b",data_out);
$display()将根据data_out的长度向fid指向的文件输入一个data_out长度的向量(每次写入后就加一个回车)。同时和$readmemb相似的,写入的向量索引高的放文件头,索引低的放文件尾。
$fclose()用于关闭文件,每次文件操作结束后一定要关闭文件。
end process rst_gen;
data_record : process(aclk,reset) is
FILE FILE_OUT : TEXT;
variable file_status:file_open_status;
variable buf:LINE;
begin
if(reset = '0') then
file_open(file_status,FILE_OUT,"E:/indata.txt",write_mode);
file_close(FILE_OUT);
file_open(file_status,FILE_OUT,"E:/indata.txt",append_mode);
elsif(rising_edge(aclk))then
if(s_axis_data_tvalid ='1') then
write(buf,s_axis_data_tdata);
writeline(FILE_OUT,buf);
end if;
if(s_axis_data_tlast = '1') then
file_close(FILE_OUT);
end if;
end if;
end process data_record;