verilog仿真系统任务$fopen/$fdisplay/$readmemh 应用

发布时间:2024-02-02 12:00

读任务

在verilog语言中有两个系统任务$readmemb,$readmemh可以用来从文件中读取数据到存储器中。这两个任务可以在仿真的任何时刻被执行使用,其使用方法如下:

$readmemb

1,$readmemb("<数据文件名(路径地址和文件名)>",<存储器名>);

2, $readmemb("<数据文件名>",<存储器名>,<起始地址(存储器的地址)>);

3, $readmemb("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);

$readmemh

4,$readmemh("<数据文件名(路径地址和文件名)>",<存储器名>);

5, $readmemh("<数据文件名>",<存储器名>,<起始地址(存储器的地址)>);

5, $readmemh("<数据文件名>",<存储器名>,<起始地址>,<结束地址>);

注意

1,存储器的空间要足够,如设定[7:0] remember[0:15];即是初始化了一个16个字长为8位的存储器;

2,文件中的数据是一次读到寄存器中的,仿真中通常使用数据文件来做信号源。并且读数据总是从文件起始地址读到结束地址结束,存储器容量要足够;

3,文件应为标准数据文件,常用*.mif, *.mem文件。

4,文件若只写文件名需要将文件放置在默认文件路径下,可以通过modelsim->file->changedirectory来更改。

 

写任务

写任务用$fopen和$fdisplay两个系统任务完成,其中前者用来得到文件句柄,所谓句柄就是用来打开这个文件的读写通道,

注意

在modelsim环境下一旦用$fopen打开文件就会将文件清空。因此要读文件最好用$readmemb/$readmemh任务,写文件再用$fopen,注意最好新建个新文件来写,以免重要数据被清空。

 

应用举例

搭建仿真环境

verilog仿真系统任务$fopen/$fdisplay/$readmemh 应用_第1张图片

目标为搭建上面的仿真环境,traffic_gen 负责产生碎片数据,长度随机;然后经过DUT模块,DUT数据处理位宽为512bit,将碎片拼接成完整数据,传送回来。

traffic_gen模块

这里用发包软件生成一个长度为3000byte的UDP报文,然后用主机网卡发送出去,用wireshark抓取报文,网卡自动将报文切分成3个子报文。用wireshark将3个子报文按照hex dump 复制出来,保存为 *.mem文件。

module traffic_gen(

	user_clk          ,
	user_rstn         ,
	trig_in           ,
	frag_last         ,
	sop               ,
	eop               ,
	data              ,
	valid             ,
	mty               ,
	
	rec_sop           ,
	rec_eop           ,
	rec_valid         ,
	rec_data                  

);

//--------------- port definition ---------------------
	input                user_clk    ;
	input                user_rstn   ;
	input                trig_in     ;
	output  reg          sop         ;
	output  reg          eop         ;
	output  reg  [511:0] data        ;
	output  reg    [5:0] mty         ;
	output  reg          valid       ;
	output  reg          frag_last   ;
	
	input                rec_sop     ;
	input                rec_eop     ;
	input                rec_valid   ;
	input        [511:0] rec_data    ;
	
//----------------wire & reg --------------------------
	parameter    FRAG_NUM  = 8'd3 ;   //原始报文长度为3000,分片后切分成3个报文
	parameter    FRAG1_LEN = 1514 ;
	parameter    FRAG2_LEN = (1514 - 34) ;
	parameter    FRAG3_LEN = (82-34) ;
	
	reg [7:0]    frag1 [0:(FRAG1_LEN-1)] ; //第1个分片,报文长度1518
	reg [7:0]    frag2 [0:(FRAG2_LEN-1)] ; //第2个分片,报文长度1518 - 34 , 报文头部信息(da+sa+type+ip)无用
	reg [7:0]    frag3 [0:(FRAG3_LEN-1)] ; //第3个分片,报文长度82 -34 ,报文头部信息无用
	integer fg ;
	
	initial fg = $fopen("recombine_pkt.out", "w");
	//fg1 = $fopen("udp_frag1.txt","r");
	initial $readmemh("udp_frag1.mem",frag1);
	initial $readmemh("udp_frag2.mem",frag2);
	initial $readmemh("udp_frag3.mem",frag3);

//------------------main code -------------------------
	task frag_init ;
		begin
			sop = 1'b0 ;
			eop = 1'b0 ;
			valid = 1'b0 ;
			data = 'd0 ;
			mty = 6'h3f ;
			frag_last = 1'b0 ;
			repeat(1)@(posedge user_clk);
		end 
	endtask 
	
	task frag_send ;
		integer i,j,k ;
		begin
			;//send frag1,frag2,frag3
		end 
	endtask 

	always @(posedge user_clk) begin
		if(rec_valid)
			$fdisplay(fg,"%h",rec_data);
	end 
	
	initial begin
		frag_init ;
		wait(user_rstn);
//		#1000;
		$display("frag send start>>>>");
		frag_send ;
		
		if(rec_eop)
		$display("frag recombine compelete >>>>");
		$stop ;
		
	end 

endmodule 

问题记录

1.报错 open readmem file "frag1.txt" in read mode. 文件格式不对,改为.mem格式正常。

2.*mem文件需要放在仿真目录下。   

 

ItVuer - 免责声明 - 关于我们 - 联系我们

本网站信息来源于互联网,如有侵权请联系:561261067@qq.com

桂ICP备16001015号