readmemb和readmemh用来从文件中读取数据到存储器中。
读取的内容只包括:空白位置(空格、换行、制表格(tab和form-feeds),注释行、二进制或十六进制的数字。
数字中不能包含位宽说明和格式说明,其中readmemb要求每个数字是二进制数,readmemh要求每个数字必须是十六进制数字。数字中不定值x或X,高阻值z或Z,和下划线(_)的使用方法和代表意义与一般Verilog HDL程序中的用法一致。
在Verilog语法中,一共有以下六种用法:
(1)$readmemb("<数据文件名>",<存储器名>);
(2)$readmemb("<数据文件名>",<存储器名>,<起始地址>);
(3)$readmemb("<数据文件名>",<存储器名>,<起始地址>,<终止地址>);
(4)$readmemh("<数据文件名>",<存储器名>);
(5)$readmemh("<数据文件名>",<存储器名>,<起始地址>);
(6)$readmemh("<数据文件名>",<存储器名>,<起始地址>,<终止地址>);
这里只说一下最简单的第一种和第四种(因为我也只了解这两种,哈哈)
(1)$readmemb的使用
先在Verilog代码目录下准备一个文件file1.txt,存入数据:
1111 1010 0101 1x1z 1_1_ 1_111
或者
1111
1010
0101
1x1z
1_1_
1_111
存在一行每个用空格隔开,跟分行存,输出结果是一样的,但是若在一行中不用空格隔开会出错,编译器会试图
把一整行数据存在一个四位的存储单元中。
`timescale 10ns/1ns
module test;
reg[3:0] memory[0:7];//申请八个四位的存储单元
reg[4:0] n;
initial
begin
$readmemb(“file1.txt”,memory); //读取file1.txt中的数字到memory
for(n=0;n<=7;n=n+1) //把八个存储单元的数字都读取出来,若存的数不到八个单元输出x态,程序结果中会看到
$display("%b",memory[n]);
end
endmodule
编译,仿真,运行之后的输出结果:
1111
1010
0101
1x1z 不定态和高阻态输出依旧为不定态和高阻态
0011 文件中存的是1_1_,空格当没有
1111 空格当没有
xxxx 文件中只有六个数据,剩下两个输出为不定态x
xxxx
2)$readmemh的使用
准一个文件file2.txt,存入:
1234 5678 9012
//使用r e a d m e m b 读 取 时 , 每 一 位 都 会 转 换 成 为 二 进 制 , 1 变 为 0001 , 2 变 为 0010 , 3 变 为 0011.... / / 使 用 readmemb读取时,每一位都会转换成为二进制,1变为0001,2变为0010,3变为0011.... //使用readmemb读取时,每一位都会转换成为二进制,1变为0001,2变为0010,3变为0011....//使用readmemh读取时,每一位都会转换成为十六进制,如上述所示
代码:
`timescale 10ns/1ns
module test;
reg set;
reg[15:0] memory[0:7]; //注意这里每个存储单元的长度为16位,因为每个数字是四位十六进制数,换算成二进制数是16位
reg[4:0] n;
initial
begin
$readmemh(“file2.txt”,memory);
for(n=0;n<=7;n=n+1)
$display("%h",memory[n]);
end
endmodule
输出:
1234
5678
9012
xxxx
xxxx
xxxx
xxxx
xxxx