在Testbench中很可能需要文件的读写操作,在可综合的设计中也可能会用到文件写入。SystemVerilogVerilog提供的文件写入读取方法并不多,主要有两类。 第一类是writemembwritememhreadmembreadmemh,第二类是fscanffwrite。第一类用法简单,但是功能弱,文件读取也不支持多维数组;第二类用法复杂一点,功能相对强大,配合循环语句可以处理多维数组。1。writemem〔bh〕readmem〔bh〕 writemem〔bh〕主要有以下用法: (1)readmemb(数据文件名,存储器名); (2)readmemb(数据文件名,存储器名,起始地址); (3)readmemb(数据文件名,存储器名,起始地址,终止地址); 其中起始地址和终止地址都是相对于存储器名指定的数据而言,而不是指写入文件时的位置。参考以下代码。parameterWIDTH8;parameterINDEX016;parameterFILEPATHBE:FPGAPRACTICEFileReadWritefilesfileb。parameterFILEPATHHE:FPGAPRACTICEFileReadWritefilesfileh。parameterFILEPATHFE:FPGAPRACTICEFileReadWritefilesfilef。parameterFILEPATHHALFE:FPGAPRACTICEFileReadWritefilesfilehalf。reg〔WIDTH1:0〕dat0〔INDEX01:0〕,dat1〔INDEX01:0〕;wire〔WIDTH1:0〕dat1comp〔INDEX01:0〕;reg〔WIDTH1:0〕dat0read〔INDEX01:0〕;integeri,j;initialbeginfor(i0;iINDEX0;i)dat0〔i〕i1;writememb(FILEPATHB,dat0,0);writememh(FILEPATHH,dat0,0);writememh(FILEPATHHALF,dat0,INDEX02);readmemh(FILEPATHH,dat0read,INDEX02);for(i0;iINDEX0;i)display(d,dat0read〔i〕);end writememb(FILEPATHB,dat0,0)将以二进制的格式写入数据,如下图所示。每个数据占据一行。注意,使用writememb写入的文件也要通过readmemb读出,否则数据可能是错误的。 writememb(FILEPATHB,dat0,0)将以二进制的格式写入数据。 writememh(FILEPATHHALF,dat0,INDEX02)将从dat0〔8〕开始按照十六进制写入数据,如下图所示。 readmemb和reamdmemh可以从文件中读取数据,其用法如下。 (1)readmem〔bh〕(数据文件名,存储器名); (2)readmem〔bh〕(数据文件名,存储器名,起始地址); (3)readmem〔bh〕(数据文件名,存储器名,起始地址,终止地址); 其中起始地址是指从数据文件中读取的数据将从存储器名的指定地址开始填充,参考上文程序中的以下语句。 readmemh(FILEPATHH,dat0read,INDEX02); for(i0;iINDEX0;i)display(d,dat0read〔i〕); 从FILEPATHH中读取的数据将从dat0read的地址INDEX02的位置开始填充,而dat0read中未初始化且未填充的数据为x,如下图所示。 注意,readmem〔bh〕是将数据放在存储器中,所以dat0read应该定义为reg型,而不是wire。 此外,readmem〔bh〕是不能填充二维数据的。比如reg〔M:N〕dat〔X:Y〕是可以使用readmem〔bh〕填充的,而reg〔M:N〕dat〔X:Y〕〔A:B〕是不可以用作readmem〔bh〕的操作对象的。2。fwrite和fscanf2。1基本用法 这两个系统函数的功能更强大,参考以下代码。initialbeginfor(i0;iINDEX01;i)dat1〔i〕i1;dat1〔INDEX01〕b000x0001;fidfopen(FILEPATHF,w);for(i0;iINDEX02;i)beginfwrite(fid,dd,dat1〔i2〕,dat1〔i21〕);endfclose(fid);fidfopen(FILEPATHF,r);for(i0;iINDEX0;i)beginfscanf(fid,d,dat1comp〔i〕);display(Readdatais:b,Origindatais:b。,dat1comp〔i〕,dat1〔i〕);if(dat1comp〔i〕!dat1〔i〕)begindisplay(Datanotidentical!Indexd。,i);endendend 上述代码首先对dat1进行赋值,注意dat1〔INDEX01〕被单独赋值,且其值包括x。通过fopen打开或新建一个可写的文本文件,将每两个连续的数据写入文件。如下图所示。 通过fwrite(fid,dd,dat1〔i2〕,dat1〔i21〕)将dat1按照十进制的格式写入文件,每两个数据为一行。fwrite函数会自动换行,所以上述代码中的是多余的。后续代码通过fscanf将数据从文件中读出,可以每次读出一个数据,也可以每次读出多个数据。 注意,写入文件格式和读出格式必须匹配,否则读出数据出错。比如按照十进制写入,就需要按照十进制读出。 fscanf和c语言中的printf的使用方法基本一致。 dat1〔INDEX01〕中的一个bit包含x,所以整个数据存储为x。2。2多维数据读写 fwrite和fscanf可以支持多维数组读写。写入函数不再赘述,主要描述读出操作,参考以下代码。parameterINDEX14;parameterINDEX24;parameterFILEPATH2DBE:FPGAPRACTICEFileReadWritefilesfile2Db。parameterFILEPATH2DHE:FPGAPRACTICEFileReadWritefilesfile2Dh。reg〔WIDTH1:0〕dat2〔INDEX11:0〕〔INDEX21:0〕;wire〔WIDTH1:0〕dat2comp〔INDEX11:0〕〔INDEX21:0〕;initialbeginfor(i0;iINDEX1;i)beginfor(j0;jINDEX2;j)begindat2〔i〕〔j〕iINDEX1j;endendwritememb(FILEPATH2DB,dat2,0);writememh(FILEPATH2DH,dat2,0);readmemb(FILEPATH2DB,dat2comp);fidfopen(FILEPATH2DB,r);for(i0;iINDEX1;i)beginfor(j0;jINDEX2;j)beginfscanf(fid,b,dat2comp〔i〕〔j〕);display(data〔。2d〕〔。2d〕is:d,i,j,dat2comp〔i〕〔j〕);endendfclose(fid);fidfopen(FILEPATH2DH,r);for(i0;iINDEX1;i)beginfor(j0;jINDEX22;j)beginfscanf(fid,hh,dat2comp〔i〕〔j2〕,dat2comp〔i〕〔j21〕);display(data〔。2d〕〔。2d〕is:ddata〔。2d〕〔。2d〕is:d,i,j2,dat2comp〔i〕〔j2〕,i,j21,dat2comp〔i〕〔j21〕);endendend 上述代码展示了如何通过for循环从文件中读出数据并填充多维数组的,可以一次读出一个数据,也可以读出多个,比如fscanf(fid,hh,dat2comp〔i〕〔j2〕,dat2comp〔i〕〔j21〕)。下一句将读出数据打印出来。注意文件数据类型要和读出类型一致。 版权声明:本文为CSDN博主小苍蝇别闹的原创文章,遵循CC4。0BYSA版权协议,转载请附上原文出处链接及本声明。 原文链接:https:blog。csdn。netyinyeyyarticledetails112499675