Verilog的$readmemb和$readmemh简介和使用

$readmemx的格式:

这两个系统任务用来从文件中读取数据到存储器中。可以在仿真的任何时刻被执行使用,使用格式共六种:

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

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

在这两个系统任务中,被读取的数据文件的内容只能包含:空白位置(空格、换行、制表格、注释行、二进制或十六进制的数字。数字中不能包含位宽说明和格式说明,对于$readmemb和$readmemh系统任务,每个数字可以是二进制十六进制数字。另外,数字必须用空白位置或注释行来分隔开。

对于上面6种系统任务格式,需补充说明一下5点:
(1) 如果系统任务声明语句中和数据文件里都没有进行地址说明,则默认存放起始地址为该存储器定义语句中的起始地址。数据文件里的数据被连续存放到该存储器中,直到该存储单元存满为止或数据文件里的数据存完。
(2) 如果系统任务中说明了存放的起始地址,没有说明存放的结束地址,则数据从起始地址开始存放,存到该存储器定义语句中的结束地址为止。
(3) 如果系统任务声明语句中,结束地址和起始地址都进行了说明,则数据文件里的数据按该起始地址开始存放到存储单元中,直到该结束地址,而不考虑该存储器的定义语句的起始地址和结束地址。
(4) 如果地址信息在系统任务和数据文件里面都进行了说明,那么数据文件里的地址必须在系统任务中地址参数声明的范围之内。否则提示错误,并且装载数据到存储器中的操作被中断。
(5) 如果数据文件里的数据个数和系统任务中起始地址及结束地址暗示的数据个数不同的话,也要提示错误信息。

简单的代码:

module data_read;

reg [31:0] mem [0:11];
integer i;

initial $readmemh("./data.txt",mem);

initial begin
  for(i=0; i<12; i=i+1)
    $display("%d: %h", i, mem[i]);
end

endmodule

data.txt

// Hexadecimal values for $readmemh demo
 // can include comments with double forward slash (standard Verilog comment)
 // second 32-bit value
 // third value
 // etc.

// can break up into related groups, insert comments, etc.

8e700002
ae700001
1232fffa
1210fff9  // last value

note: 

如果将mem的宽度调整为[15:0],则会产生错误,无输出

Warning: (vsim-PLI-3406) Too many digits (8) in data on line 2 of file "./data.txt". (Max is 4.)    : data_read.v(6)

如果将mem的宽度调整为[63:0],则结果变为

#           0: 0000000002328020

#           1: 0000000002328022

#           2: 0000000002328024 

这种比较可以看出,系统任务是按行读取的。

注意:$readmemb和$readmemh只能读取二进制和十六进制。

猜你喜欢

转载自blog.csdn.net/qq_33231534/article/details/106167484