引言
自己verilog设计寄存器堆的时候,整理了简单的相关知识点:
- verilog定义存储器
- 存储器读
- 存储器写
- 内存初始化
- $readmemh、$readmemb的使用
存储器
定义
在Verilog当中存储器的定义本质定义一个2维数组。下面举一个定义存储器的例子:
reg[7:0] good_mem[0:255]; //good_mem是256个8位的寄存器构成的阵列,实际可以存放2Mbit的数据
再举一个定义数组的例子:
wire[7:0] addr_bus[3:0]
你可能发现了这个后面good_mem内标号顺序和正常定义数组不同,这个其实只是表示了在存储器堆里面,从上到下,每一个寄存器编号不同,无论顺序是[0:255],还是[255:0],这个存储容量都是一样的。
以下是good_mem[0:255],如果是改成good_mem[255:0]只是寄存器的编号逆序。其它没有区别。一般存储器第一个寄存器都是从0开始编号,所以设计寄存器堆/存储器后面一个都是[0:arraysize]。
reg [7:0] good_mem[0];
reg [7:0] good_mem[1];
reg [7:0] good_mem[2];
reg [7:0] good_mem[3];
:
:
reg [7:0] good_mem[255];
读操作
就是将数据从存储单元当中读出:
data_out = good_mem[address]
写操作
将数据写入存储单元:
good_mem[address] = data_in
内存初始化
这个有两种方法,第一种是直接赋值。第二种是使用$readmemb系统函数。
直接赋值
reg [0:3] good_mem [1:4]
:
:
good_mem[1] = 4'hA;
good_mem[2] = 4'hB;
good_mem[3] = 4'hC;
good_mem[4] = 4'hD;
调用系统函数
- $readmemb:读取二进制数字
- $readmemh:读取十六进制数字 如果文件中包含不定值x,或者高阻值z,或者下划线(__)这个和Verilog当中的内容相同。
$readmemb的使用
在Verilog代码目录下准备一个file.txt文件,放入二进制数据 1111 1010 0101 1x1z 1_1_ 1_111 数据写在一行里面需要用空格隔开,或者分行写也可以。
module test;
reg[3:0] memory[0:7];//申请八个四位的存储单元
reg[4:0] n;
initial
begin
$readmemb("file.txt",memory); //读取file.txt中的数字到memory
for(n=0;n<=7;n=n+1) //显示结果
$display("%b",memory[n]);
end
endmodule
显示结果为: 1111 1010 0101 1x1z 0011 1111 xxxx xxxx
文件中不定态x和高阻值z保持不变。下划线忽略。由于文件中只有6个数据,输出八个,剩下两个就是不定态x。
$readmemh的使用
在Verilog代码目录下新建file2.txt,写入数据: 1234 5678 9ABC
module test;
reg set;
reg[15:0] memory[0:7];
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 9ABC xxxx xxxx xxxx xxxx xxxx
参考资料
- (75条消息) 数字IC设计——数组、存储器(Memory)的定义及Verilog语言实现(二)(存储器的读、取、及初始化赋值)_摆渡沧桑的博客-_memory verilog
- 2.3 Verilog 数据类型 | 菜鸟教程 (runoob.com)
- (75条消息) verilog中readmemh的使用_甲六乙的博客-_$readmemh