常用的verilog系统函数 $feof, fscanf,$fopen,$readmemb,$readmemh,$fdisplay,$display,$fclose,函数的使用

一般常用到的系统函数有几个:$readmemb,$readmemh,$display,$fmonitor,$fwrite,$fopen,$fclose等

fscanf函数:    $fscanf(文件指针,读取格式,数组)

注意:该系统函数每次读取文件中的每一行数据,这当中需要特别注意一点,每一行只能是同一种数据格式,例如:0011_0001,如果出现0b0011_0001,则无法正常的读取。

文件指针:指向某一文件的开头,举个栗子,f_r = $fopen(‘xxx.txt’, ‘r’),文件指针f_r指向xxx.txt文件的开头。

读取格式:%d %b %h为分别表示十进制、2进制、16进制。

数组:存放从xxx.txt读取的数据,例如xxx.txt第一行存放0011_0001,则数组a=0011_0001。此时若没有将数组a中的数据及时的进行处理(写入另外一个文件、给寄存器reg1)在读取xxx.txt文件中的下一行(1111_1111)数据时,之前存放于数组a的数据将会被覆盖,即此时数组a中的数据为0011_0001。依次类推。

关闭:使用fclose系统函数。

fscanf函数的返回值:例如count = $fscanf(fp_r,"%b" ,img_rgb_dat_reg)返回值为1,返回值为1表示成功,读取格式可以为%b,%d,%h(注意,如果读取格式为二进制,则文件中只能识别 0 1)

             1       integer = count;
             2       count=$fscanf(fp_r,"%b" ,reg1) ; //fp_r文件指针,%b读取格式,reg1:数组


举个例子:reg [7:0]reg1,表示定义8bits的数组一个,该数组最大只能存放8bits的数据,如果读取的数据小于8bits,则在数据的前面补零(亲测)。

函数所参考的网络资料的链接:

https://blog.csdn.net/weizhl10131729/article/details/78556489

https://blog.csdn.net/cxc19890214/article/details/41146531

实际举例用$fscanf读txt中的数据:

 

注意:图中第一行定义一个文件句柄。由于打开的文件中一行中有两个10bit的十进制数据,所以定义了2个reg变量。

第6行到12行就是文件的读取过程。

使用的系统函数$fopen打开文件;

使用$feof判断文件是否读完(eof :end of file),如果文件结束,则返回非0值,如果没结束返回0;

使用$fscanf读取文件内容。

在实际验证中,仿真一段时间后,仿真会结束,注意在仿真结束时,要使用$fclose(dti_fid)关闭文件。

用$fwrite函数把数据写入到 txt文件中:

 

在写文件时,首先要建一个文件句柄如15行;

147-148行,声明2个10bit的输出数据dto_i和dto_r;

150-152行,以写的方式打开一个文件,;

154-159行,写文件。dto_vld是dto_i和dto_r数据的有效指示。

还是要注意在仿真结束时,要用$fclose(dto_fid)关闭文件句柄。

$display ("string")

关于$fopen,

       $readmemb(把txt文档中的数据写入到数组中),

       $fdisplay(把数据写入到制定的文件中去)

在工程文件夹目录下,有一个meomoryb.txt的文本文件,文件内容如下:
 
10101101 00011101 01101111 01100001
 
00000001 11111110 11111111 11101110
 
有一个meomoryh.txt的文本文件,文件内容如下:
 
ef ab 3e 4f
 
这个文件就符合要求,可以通过$readmemb读取。10101101第一个数据地址为0,向后以此类推。
 
举例:
 
module readmem;
    reg [7:0] mem[7:0];
    reg [2:0] i;
    integer file;
    initial
    begin
        file = $fopen("memory.txt","w");//以写的方式打开文件
        $readmemb("memoryb.txt",mem,4,0);// 从文本中读取数据向mem[4]开始写入,直到写到mem[0]
        for(i =0;i<7;i= i+1)
        begin
            $display("mem[%d] = %b",i,mem[i]);
            $fdisplay(file,"mem[%d] = %b",i,mem[i]);//$fdisplay(文件指针,"显示内容",显示变量)
        end
 
        $readmemh("memoryh.txt",mem);//如果没有地址的限制,就默认从//mem[0]到mem定义的最大地址。
        for(i =0;i<7;i= i+1)
        begin
            $display("mem[%d] = %h",i,mem[i]);
            $fdisplay(file,"mem[%d] = %h",i,mem[i]);
        end
        $fclose(file);
    end
endmodule
 
 
控制台输出与生成的memory.txt中内容一致。
 
mem[0] = 00000001
 
mem[1] = 01100001
 
mem[2] = 01101111
 
mem[3] = 00011101
 
mem[4] = 10101101
 
mem[5] = xxxxxxxx
 
mem[6] = xxxxxxxx
 
mem[0] = 32
 
mem[1] = 36
 
mem[2] = 4f
 
mem[3] = 8a
 
mem[4] = ad
 
mem[5] = xx
 
mem[6] = xx
 
//结果分析:
//    首先读取memoryb.txt中从地址4到地址0的数据写入mem[0]至 mem[4],没有写入的存储器内容为xx,
// 然后读取memoryh.txt从地址0到地址6的数据写入mem[0]至mem[6],由于 memoryh.txt只有4个数据,mem[4]以后的数据就没有了,
//保持上一次写的内容,所以,mem[4]为ad(十六进制)即二进制 10101101
`define NULL 0
module file_scanf;
integer fp_r,fp_w;
integer flag1,flag2;
reg [3:0] bin;
reg [15:0] data_in [15:0];
reg [15:0] cnt = 15;
initial
begin :file_fscanf
    fp_r = $fopen("data_in.txt","r");
    fp_w = $fopen("data_out.txt","w");
 
    if(fp_r == `NULL)
      $display("failture to open data_in.txt ");
    if(fp_w == `NULL)
      $display("failture to open data_out.txt ");
 
    //repeat(10)
    while(!$feof(fp_r))
    begin
        flag1 = $fscanf(fp_r,"%h",data_in[cnt]);//flag1 为$fscanf的返回值
         $display("data_in[%d]=%h ",cnt,data_in[cnt]);
         $fdisplay(fp_w,"%h",data_in[cnt]);
    //    cnt = cnt -1;
    end
$fclose(fp_w);
$fclose(fp_r);
end
endmodule
 
1.文件打开和关闭:首先定义integer指针,然后调用$fopen(file_name,mode)任务,不需要文件时,调用$fclose(file_name)
2.输出到文件:显示任务前加f,调用格式:
$fdisplay(文件指针,"显示内容",显示变量),再如$fmonitor(…)
 

  • 0
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值