从二进制文件中读取 n 个字节,直到 verilog 中的文件结尾
reading n bytes from a binary file until end of file in verilog
我有一个二进制文件。我每次都需要从中读取 512 位,直到文件结束并将其作为输入传递给我的设计。我正在使用 readmemh/readmemb 从文件中读取。但是我们必须在 readmemh 之前指定内存数组的大小以作为其参数传递。所以如果我们不知道寄存器的深度,我们怎么能读取完整的二进制文件。
reg [511:0]packet[1:0];
$readmemh("abc.bin",packet); //this abc.bin has 237kb size
内存深度应该是多少'packet'?
$readmemh 方法不适合此类连续数据处理。
相反,我会使用与标准编程语言相同的方法:
打开一个文件,从中读取你需要的数据,关闭文件。通过这种方式,您可以处理许多兆字节大小的文件,但不需要太多兆字节的存储空间。
fd = $fopen(filename,"rb");
if (fd==0)
begin
$display("%m @%0t: Could not open file '%s'",$time,filename);
$stop;
end
else
begin
$display("%m @%0t: Opened %s for reading",$time,filename);
file_is_open = 1'b1;
end
if (file_is_open)
value= $fgetc(fd);
警告:
这使用二进制文件。您的 $readmemh 使用 ASCII 文件。如果需要,您可以读取 ASCII 文件,但随后您必须自己编写一个小的 Verilog 函数将 ASCII 转换为十六进制。
你有几个选择
- 如果文件有最大可能大小,只需声明具有所需最大大小的数组即可。
$readmemh
. 将保留剩余元素未初始化 (X
)
- 编译设计时,在命令行中通过数组大小传递参数或宏定义。命令将取决于您使用的工具。
- 不是将整个文件读入数组,而是使用
$fscanf(fd,"%h", value)
一次读取一行。 value
可以根据需要应用于您的输入。
do begin
repeat (64) begin
code = $fscanf(fd,"%h", value); // get byte
pattern = {pattern,value}; // shift into pattern
end
send_to_dut(pattern);
end while (code == 1);
我有一个二进制文件。我每次都需要从中读取 512 位,直到文件结束并将其作为输入传递给我的设计。我正在使用 readmemh/readmemb 从文件中读取。但是我们必须在 readmemh 之前指定内存数组的大小以作为其参数传递。所以如果我们不知道寄存器的深度,我们怎么能读取完整的二进制文件。
reg [511:0]packet[1:0];
$readmemh("abc.bin",packet); //this abc.bin has 237kb size
内存深度应该是多少'packet'?
$readmemh 方法不适合此类连续数据处理。
相反,我会使用与标准编程语言相同的方法: 打开一个文件,从中读取你需要的数据,关闭文件。通过这种方式,您可以处理许多兆字节大小的文件,但不需要太多兆字节的存储空间。
fd = $fopen(filename,"rb");
if (fd==0)
begin
$display("%m @%0t: Could not open file '%s'",$time,filename);
$stop;
end
else
begin
$display("%m @%0t: Opened %s for reading",$time,filename);
file_is_open = 1'b1;
end
if (file_is_open)
value= $fgetc(fd);
警告:
这使用二进制文件。您的 $readmemh 使用 ASCII 文件。如果需要,您可以读取 ASCII 文件,但随后您必须自己编写一个小的 Verilog 函数将 ASCII 转换为十六进制。
你有几个选择
- 如果文件有最大可能大小,只需声明具有所需最大大小的数组即可。
$readmemh
. 将保留剩余元素未初始化 ( - 编译设计时,在命令行中通过数组大小传递参数或宏定义。命令将取决于您使用的工具。
- 不是将整个文件读入数组,而是使用
$fscanf(fd,"%h", value)
一次读取一行。value
可以根据需要应用于您的输入。
X
)
do begin
repeat (64) begin
code = $fscanf(fd,"%h", value); // get byte
pattern = {pattern,value}; // shift into pattern
end
send_to_dut(pattern);
end while (code == 1);