Verilog文件读写系统任务

verilog中读写文件操作 简述在verilog设计验证中,我们经常需要从文件中读取验证数据,有些数据是文本文件,有些数据是二进制文件。但是verilog读写文件的操作和软件语言还是有不同的,下面就具体总结一下verilog中的读写文件的操作。读写二进制文件不管是读写二进制文件还是读写文件文件,都要把读取到的数据放入到硬件设计中某个寄存器或者存储器中,这是verilog和软件语言读写文件最大的不同。 其实verilog读写文 阅读详情

Verilog文件读写系统任务

Verilog 提供了可以对文件进行操作的系统任务

  • 文件打开、关闭

    $fopen
    $fclose
    $ferror
    
  • 文件写入

    $fdisplay
    $fwrite
    $fstrobe
    $fmonitor
    
  • 字符串写入

    $sformat
    $swrite
    
  • 文件读取

    $fgetc
    $fgets
    $fscanf
    $fread
    
  • 文件定位

    $fseek
    $ftell
    $feof
    $frewind
    
  • 存储器加载

    $readmemh
    $readmemb
    

文件操作过程中,要保证参数以及读写变量类型与文件内容的一致。

不要将字符串类型和多进制类型相混淆。

文件打开关闭

$fopen
integer fd;
fd = $fopen("fname",mode);
  • fname为打开文件的名字,fd返回32bit的文件描述符

    • 正确打开, fd为非0值
    • 打开错误时, fd为0
  • mode 可选,用于指定打开文件的方式

    mode类型说明
    r只读模式
    w只写模式,如果文件存在,则原文件内容会被删除。如果文件不存在,则创建新文件。
    a追加打开一个文本文件,并在文件末尾写数据。如果文件如果文件不存在,则创建新文件。
    rb只读打开一个二进制文件,只允许读数据。
    wb只写打开或建立一个二进制文件,只允许写数据。
    ab追加打开一个二进制文件,并在文件末尾写数据。
    r+读写打开一个文本文件,允许读和写
    w+读写打开或建立一个文本文件,允许读写。
    a+读写打开一个文本文件,允许读和写。读写打开一个文本文件,允许读和写。
    rb+读写打开一个二进制文本文件,功能与 “r+” 类似。
    wb+读写打开一个二进制文本文件,功能与 “r+” 类似。
    ab+读写打开一个二进制文本文件,功能与 “a+” 类似。
$fclose
$fclose(fd);
  • 关闭fd描述的对应文件
$ferror
err = $ferror(fd,str);

正常打开文件时

  • err 与 str均为零值

打开文件出错时

  • err返回非零值表示错误
  • str返回非零值存储错误类型

建议str长度为640 bit位宽

demo
integer fd;
integer err;
reg [320:0] str;
initial begin
    fd = $fopen("xxx.txt","r");
    err = $ferror(fd,str);
    $display("file descriptor is %h",fd);
    $display("error number is %h",err);
    $display("error info is %s",str);
    $fclose(fd);
end

文件写入

写入文件的系统任务主要包含

  • $fdisplay
  • $fwrite
  • $fstrobe
  • $fmonitor

对应的自带格式的系统任务

  • $fdisplayb
  • $fdisplayh
  • $fdisplayo 等
$fdisplay
$fdisplay(fd, arguments);

按顺序或条件写文件,自动换行

$fwrite
$fwrite(fd, arguments);

按顺序或条件写文件,不自动换行

$fstrobe
$fstrobe(fd,arguments);

语句执行完毕后选通写文件

$fmonitor
$fmonitor(fd,arguments);

只要数据有变化就写文件

demo

相对于标准显示任务,$display, w r i t e , write, write,strobe,$monitor, 写文件系统任务除了用法格式上需要多指定文件描述符fd, 其余与对应的显示任务保持一致。

integer fd;
integer err;
reg [320:0] str;
initial begin
    fd = $fopen("xxx.txt","a+");
    err = $ferror(fd,str);
    if(!err)begin
        $fdisplay(fd,"new data: %h",fd);
        $write(fd,"new data: %h",err);  // 最后一行不换行打印
    end
    $fclose(fd);
end

字符串写入

提供了向字符串中写数据的系统任务$write 和 $sformat

$swrite
$swrite(reg,list_of_arguments);

按顺序或者条件写字符串到变量reg中

$sformat
len = $sformat(reg,format_str,arguments);

按格式froamt_str 写字符串到变量reg中,格式与$display指定格式一致,可返回字符串长度len

demo
reg [299:0] str_swrite,str_sformat;
reg [63:0] str_buf;
integer len, age;
initial begin
   	#20;
   	str_buf = "wkk";
    age = 9;
    $swrite(str_swrite,"%s age is %d",str_buf,age);
    $swrite(str_swrite,"years","old"); // 直接写不含有格式字符串的字符串
    
    $sformat(str_sformat,"%s age is %d",str_buf,age);
    len = $sformat(str_sformat,"years old");
    
end

文件读取

$fgetc
c = $fgetc(fd);

按照字符格式将fd数据输出到变量c, c位宽最少为8位。读取错误时,c的值为EOF(-1),可以用$ferrror检查错误类型

$ungetc
code = $ungetc(c,fd);

向文件fd缓存区写字符c

c值在下次调用$getc时返回,文件fd自身内容不会发生变化,正常写缓冲区返回值code=0, 错误返回值为EOF

$fgets
code = $fgets(str,fd);

按字符连续读,直至str被填满,或者一行内容读取完毕,或者文件结束。

正常读取返回值code为读取行数,发生错误时code为0

$fscanf
code = $fscanf(fd,format,args);

按格式format将文件fd中的数据读取到变量args中

读取一次的停止条件为空格或者换行。

读取发生错误时返回值code = 0

$sscanf
code = $sscanf(str,format,args);

按格式format将字符串型变量str读取到变量args中

$fread
code = $fread(store,fd,start,count);

按二进制数据流格式将数据从文件fd读取到数组或者寄存器变量store中

start为文件起始地址,count为读取长度

若start/count未指定,数据会全部填充至变量store中

若store为寄存器类型,则start/count参数无效,store变量填充满一次数据后便会停止读取

demo
integer i;
reg	[31:0] char_buf;
initial begin
   #30;
    fd = $fopen("xxx.txt","r");
    $write("Read char:");
    err = $ferror(fd,str);
    if( !err ) begin
        for(i=0;i<13;i++)begin
            char_buf[7:0] = $fgetc(fd); // 按照单个字符读取, 包含换行符
            $write("%c",char_buf[7:0]);
        end
    end
    
    $ungetc("1", fd) ;            //连续写3次文件缓冲区
    $ungetc("2", fd) ;
    $ungetc("3", fd) ;
    // 先写后出, 堆栈
    char_buf[7:0]   = $fgetc(fd) ;  //read 3  
    char_buf[15:8]  = $fgetc(fd) ;  //read 2
    char_buf[23:16] = $fgetc(fd) ;  //read 1,read buffer end\
    char_buf[31:24] = $fgetc(fd) ;  //fd中原来的内容,紧随上一次文件读取的位置
end
integer code;
reg [99:0] line_buf[9:0];
initial begin
   #32;
    fd = $fopen("...txt","r");
    err = $ferror(fd,str);
    if(!err) begin
        for(i=0;i<6;i++) begin
            code = $fgets(line_buf[i],fd);  // 读取内容包含"\n"
            $write("Get line content: %d->%s",i,line_buf[i]);
        end
    end
    
     //十六进制显示,将显示对应的 ASCIII 码字
     $display("Show hex line data%d: %h", 2, line_buf[2]) ;
end

$fgets 任务读取时是按照字符串类型读取的, 文件中的1 --> ASCII码: 49

reg [32:0] data_buf[9:0];
reg [63:0] string_buf [9:0];

reg [31:0]   data_get ;
reg [63:0]   data_test ;
initial begin
	#32;
    fd = $fopen("xxx.txt","r");
    err = $ferror(fd,str);
    if(!err) begin
        for(i = 0;i<4;i++) begin
            code = $fscanf(fd,"%h",data_buf[i]);
        end
        for(i = 4;i<16;i++) begin
            code = $fscanf(fd,"%s",string_buf[i]); 
        end
    end
    
    data_test = "fedcba98";
    code = $sscanf(data_test,"%h",data_get);
    
    code = $sformat(data_test, "%h", data_buf[2]);
    code = $sscanf(data_test, "%h", data_get);
    
end
reg [71:0]   bin_buf [3:0] ; //每行有8个字型数据和1个换行符
reg [143:0]  bin_reg ;

initial begin
    #40;
    fd = $fopen("xxx.txt","r");
    err = $ferror(fd,str);
    if ( !err ) begin
        code = $fread(bin_buf,fd,0,4);  // 数组型读取,读取4次 
    end
    $fclose(fd);
    
    fd = $fopen("DATA_RD.HEX", "r");
    code = $fread(bin_reg, fd); //单个寄存器读取
    $fclose(fd) ;
end

起始地址和读取长度都是设置数组型变量的参数, 如果存储数据的变量类型是非数组的 reg 型,则只会进行一次读取,直至 reg 型变量被填充完毕。

文件定位

$ftell

获取文件位置

pos = $ftell(fd);

返回文件当前位置距离文件首部的偏移量,初始地址为0

偏移量按照字节为1单位( 8bits)

配置$fseek使用

$fseek

重定位

code = $fseek(fd,offset,type);

设置文件下一个输入或者输出的位置

offset为设置的偏移量

type 为偏移量的参考位置

  • 0 设置位置到偏移地址( 参考位置为文件头 )
  • 1 设置位置到当前位置加偏移量( 参考位置为当前位置 )
  • 2 设置位置到文件尾加偏移量,经常使用负数来表示文件尾向前的偏移量( 参考位置为文件尾 )
$rewind(fd)

无偏移重定位

code = $rewind(fd);

等价于$fseek(fd,0,0)

$feof

判断文件尾部

code = $feof(fd);

判断是否到文件尾部

检测文件尾部时返回值为1,否则为0

demo
reg [31:0]   data;
reg [199:0]  str_long;

integer pos ;
initial begin
   #40;
    fd = $fopen("xxx.txt","r");
    err = $ferror(fd,str);
    if(!err) begin
        code = $fscanf(fd,"%h",data);
        pos = $ftell(fd); // 结果为8
        
        code = $rewind(fd); // 重新将文件指针的位置指向文件首部
        while( !$feof(fd)) begin
            code = $fgets(str_long,fd); 
        end
    end
    
    $fclose(fd);
end

加载存储器

$readmemh

加载十六进制文件

$readmemh("fname",mem,start_addr,finish_addr);
  • fname : 为数据文件名字
  • mem: 为数组型/存储器型变量
  • start_addr, finish_addr 分别为起始地址和终止地址, start_addr和finish_addr可以省略,此时加载数据的停止条件为存储器mem被填充完毕,或者文件读取完毕。
  • 文件内容只应该有空白符(换行、空格),十六进制数据, 注释使用"//"进行标注,数据间建议使用换行符区分
$readmemb
$readmemb("fname",mem,start_addr,finish_addr);

用法格式同$readmemb , 不过文件内容为二进制数据

demo
reg [31:0] mem_load [3:0];
initial begin
   	#50
    $readmemh("xxx.hex",mem_load);
end

常用例子

1. 文件写
integer fid;
initial begin
    fid=$fopen("xxx.txt");
    #`STOPTIME  $fclose(fid);
end

always @ (posedge clk) begin
    if(data_valid)
	   $fwrite(fid,"%d  %d\n",$signed(RE) ,$signed(IM));
end
2. 文件读
localparam nums = 65536;
reg [23:0] file_source [nums-1:0];

reg [15:0] read_cnt;
reg [23:0] data_I;
reg data_in_valid;
initial $readmemh("xxxx.txt",file_source);

always @(posedge i_clk) begin
    if(!i_rstn) begin
       read_cnt <=  16'b0;
       data_I  <= 24'b0;
       data_in_valid <= 1'b0;
    end 
    else if(data_in_ready) begin
        if(read_cnt <= nums) begin
            data_I <= file_source[read_cnt];
            read_cnt <= read_cnt + 1'b1;
            data_in_valid <= 1'b1;
        end else begin
        	data_I <= data_I;
            read_cnt <= read_cnt;
            data_in_valid <= 1'b0;    
        end
    end else begin
        data_I <= data_I;
		read_cnt <= read_cnt;
		data_in_valid <= 1'b0;    
	end
end

参考

7.2 Verilog 文件操作 | 菜鸟教程 (runoob.com)

systemverilog/verilog文件操作 阅读详情

相关推荐

[SV] 文件操作实战:Verilog系统任务高效读写技巧

本文详细介绍了Verilog文件操作的系统任务和高效读写技巧,包括$fopen、$fclose、$ferror等基础操作,以及$fdisplay、$fwrite、$fstrobe和$fmonitor等写入方式。通过实战案例和避坑指南,帮助开发者掌握SV文件操作,提升数字设计验证的效率和质量。

weixin_28678831的博客 369

verilog学习笔记——文件操作

大部分编译器和仿真器在读文件的时候需要预先打开文件。在Vivado自带仿真器中,读文件不需要预先打开要读取的文件,也不需要将文件加入Vivado工程内部。介于此,本文总结了利用Verilog语言进行文件系统操作的各种详细使用方法。

weixin_45075177的博客 7395

Verilog十大基本功2(testbench的设计 文件读取和写入操作 源代码)

需求说明:Verilog设计基础 内容       :testbench的设计 读取文件 写入文件 来自       :时间的诗 十大基本功之 testbench 1. 激励的产生 对于 testbench 而言,端口应当和被测试的 module 一一对应。 端口分为 input,output 和 inout 类型产生激励信号的时候, input  对

时间的诗 5万+

systemverilog读写二进制文件

int rd; int file = $fopen(path,"wb"); // open in binary mode if (!file) begin $error("File could not be open: ", path); return; end $fwrite(file, "%u", 32'h4D424D42); $fclose(file); // read back binary data from file file = $fopen (path,"r

tanfuz的博客 3972

Verilog读写文件

一.读写文件相关的系统任务    在进行FPGA模块的开发过程中,常常需要对数据的处理过程进行行为仿真,以验证FPGA的功能逻辑是否正确,因此需要将FPGA行为仿真的结果与MATLAB或C/C++的处理结果进行对比验证。但需要对比的数据量比较大时,将输入输出结果数据存入文件进行对比是非常常用的方法。    Verilog中读写文件常用到的系统任务主要有以下几个:1.文件打开、关闭与定位操作:$fo...

零阶简正波的博客 1万+

[SV] 文件操作

Verilog 提供了很多对文件进行操作的系统任务。$fopen$fclose$ferror$fdisplay$fwrite$fstrobe$fmonitor$sformat$swrite$fgetc$fgets$fscanf$fread$fseek$ftell$feof$frewind$readmemh$readmemb使用文件操作任务(尤其注意 ​$sforamt​, ​$gets​, ​$sscanf。

lbt_dvshare的博客 3609

verilog系统任务读写文件的使用

参考https://www.cnblogs.com/pengwangguoyh/articles/3167498.html $readmemb,$readmemh,$fopen,$fdisplay;基本上就可以完成对文件的读写操作。 一、读任务 在verilog语言中有两个系统任务$readmemb,$readmemh可以用来从文件中读取数据到存储器中。这两个任务可以在仿真的任何时刻被执行使...

ygyglg的专栏 921

Verilog实现有符号十进制数的文本文件读写:从读取到写入的完整流程

本文详细介绍了在Verilog仿真中实现有符号十进制数文本文件读写的完整流程。核心内容包括使用$fopen、$fscanf和$fwrite等系统任务,重点阐述了如何正确处理有符号数的符号位,特别是写入时必须使用$signed()函数进行格式转换,以避免数据错误。文章提供了从文件路径处理、数据读取到写入的实战代码示例和常见问题排查指南,帮助数字电路设计者高效完成仿真数据的导入与导出。

weixin_29162439的博客 194

verilog系统任务对文件的读写操作

几个简单的系统任务,$readmemb,$readmemh,$fopen,$fdisplay;基本上就可以完成对文件的读写操作。 一、读任务  在verilog语言中有两个系统任务$readmemb,$readmemh可以用来从文件中读取数据到存储器中。这两个任务可以在仿真的任何时刻被执行使用,其使用方法如下:$readmemb 1,$readmemb("",); 2,

baijingdong的专栏 5385

Verilog文件操作函数:使用fwrite函数进行文件写入

需要注意的是,在使用fwrite函数进行文件写入时,需要保证写入的数据类型与文件打开时指定的文件格式相符。在FPGA开发过程中,文件操作是经常使用的功能之一,可以通过读取或者写入数据到文件中进行调试和数据存储等操作。总之,使用fwrite函数进行文件写入是Verilog中一种常用的文件操作方法,可以方便地将数据写入到指定的文件中进行保存和调试。fwrite函数将数据以十六进制格式写入文件中,并使用$fclose函数关闭文件句柄。下面是一个简单的例子,演示了如何使用fwrite函数将数据写入文件中。

学习使你进步。 3197

[SV]Verilog系统任务及应用实例 ---- 文件讀寫任务及应用案例(File I/O tasks and example)

Verilog系统任务及应用实例 ---- 文件讀寫任务及应用案例(File I/O tasks and example) 一、文件讀寫任務列表 1.1、File I/O task list No. T...

元直的博客 1429

.verilog系统任务读写文件$fopen和$fdisplay的使用

1.$fopen打开文件   用法1.$fopen("");   用法2.=$fopen(""); 注意:用$fopen打开文件会将原来的文件清空,若要读数据就用$readmemb,$readmemh就可以了,这个语句不会清空原来文件中的数据。 用$fopen的情况是为了取得句柄,即文件地址,也就是写文件时用$fdisplay(desc,"display1");时才用。 用法1自然无须多

baijingdong的专栏 3万+

宇树G1双足机器人SLAM开发环境搭建实战指南

SLAM(同步定位与建图)是机器人自主导航的核心技术。在双足人形机器人平台上,由于运动模型复杂、机身晃动带来高频IMU噪声,SLAM开发对环境配置和依赖管理提出了更高要求。以宇树G1为例,系统阐述如何通过Ubuntu 20.04、ROS Noetic与Docker容器化方案构建可复现的SLAM开发环境。先介绍依赖分层管理与版本锁定原理,再深入catkin工作空间编译、传感器驱动集成、网络与多机通信配置等工程实践,最后提供常见问题排查与避坑指南。这套方法论不仅适用于G1,也可迁移至其他双足或轮式机器人平台,帮

weixin_32025789的博客 265

7.2 Verilog 文件操作

Verilog 文件操作

qq_33300585的博客 1290

本地大模型5:在pycharm用python调用ollama本地大模型

python调用ollama本地大模型

weixin_74825941的博客 8375

数字IC设计实现之hierarchical flow系列(一)

数字IC设计实现之hierarchical flow系列(一) 最近这段时间小编又比较忙起来了,今天抽空来咖啡厅码字来了,刚到时脑子一片空白,不知道要分享些什么(项目结束后将会在知识星球上分享数字 IC 设计实现 Tapeout 前要review的那些 checklist)。突然间想起来有个星友希望小编分享些数字 IC 设计实现 hierarchical flow 的相关内容。考虑到现在大都采用这种方式来做 design 和实现,那就选这个 topic 了。限于篇幅和时间限制,今天只分享逻辑综合部分和布局布

weixin_37584728的博客 5998

Verilog篇(二)系统函数

显示任务:$display,$write, 前者总会输出一个换行符,后者不会。   固定输出格式版:$displayb/$displayo/$displayh/$writeb/$writeo/$writeh。     只是固定默认的输出格式,也可以通过%0x执行输出方式。   (%m 显示模块路径, \转义字符)   (%p 可以直接打印出,enum,struct,array) ...

ahr7882的博客 1657

深度学习之基于Pytorch手指静脉识别系统(

一、项目背景与目标手指静脉识别技术是一种新兴的生物特征识别技术,它依据人类手指中流动的血液可吸收特定波长的光线这一科学原理,利用手指内的静脉分布图像来进行身份识别。与传统的生物识别技术(如指纹识别)相比,手指静脉识别技术具有不易伪造、识别精度高、非接触性等特点,因此在安全性要求较高的场景(如金融、医疗、公安等)具有广阔的应用前景。本项目旨在利用PyTorch深度学习框架,构建一套高效、准确的手指静脉识别系统。

Q1744828575的博客 830

Verilog 系统函数介绍

1&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;$display &nbsp;&nbsp;&nbsp;&nbsp;这个函数系统任务的作用是用来在控制台输出信息。 &nbsp;&nbsp;&nbsp;&nbsp;1)&nbsp;&nbsp;直接显示字符串 $display("!!! Start Simulation !!!"); &a

alangaixiaoxiao的博客 9199

【openEuler容器镜像部署指南】

【代码】【List集合排序 】

weixin_43878094的博客 1111

Android11原生设置屏幕亮由Gamma变化改为线性变化

从Android9 开始屏幕亮度调解变成非线性变化,这样的话就会出现 之前亮度变化很小,到后面时变化亮度很快; 修改为线性变化,只需要修改 ./frameworks/base/packages/SettingsLib/src/com/android/settingslib/display/BrightnessUtils.java /* * Copyright (C) 2018 The Android Open Source Project * * Licensed under the Apache L

Android 4923

verilog VHDL 显示display && 读写文件

系统任务也属于行为级建模,系统任务的调用要出现在initial与always结构中。所有的任务都已$开头。   1、$display,$write用于信息的显示和输出。其中,       %b或%B    二进制       %o或%O    八进制       %d或%D    十进制       %h或%H    十六进制       %e或%E    实数       %c或...

weixin_41967965的博客 5452

基于GA-BP遗传算法优化神经网络的多输入多输出数据预测-Python代码实现

多输入多输出的GA-BP神经网络

2301_80449389的博客 2306

Testbench编写指南(2)文件的读写操作

Testbench编写指南(2)文件的读写操作 文章转自:https://blog.youkuaiyun.com/FPGADesigner/article/details/80470972 文章目录Testbench编写指南(2)文件的读写操作读取txt文件数据将数据写入txt文件   第2篇的题材是文件的读写控制,仿真时经常需要从文件中读取测试激励,还要将仿真结果存取在文件中供其它程序读取调用。 读取...

OpenFPGA的博客 8497

LVGL hal indev(porting evdev)

LVGL中对输入设备的管理是单例实现的,而在Linux的输入设备是多个的,所以需要对其进行改造成多例实现。

Bigan(安)的博客 3344

霍尼韦尔SoftMaster使用说明

霍尼韦尔SoftMaster使用说明

上一篇: FPGA 串口通信
下一篇: matlab定点化_(fi函数)
暴风雨中的白杨
博客等级 码龄6年 1070粉丝 162原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

暴风雨中的白杨

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值