verilog数组定义及其初始化
这⾥的内存模型指的是内存的⾏为模型。Verilog中提供了两维数组来帮助我们建⽴内存的⾏为模型。具体来说,就是可以将内存宣称为⼀个reg类型的数组,这个数组中的任何⼀个单元都可以通过⼀个下标去访问。这样的数组的定义⽅式如下:
reg [wordsize : 0] array_name [0 : arraysize];
例如:
reg [7:0] my_memory [0:255];
其中 [7:0] 是内存的宽度,⽽[0:255]则是内存的深度(也就是有多少存储单元),其中宽度为8位,深度为256。地址0对应着数组中的0存储单元。
如果要存储⼀个值到某个单元中去,可以这样做:
my_memory [address] = data_in;
⽽如果要从某个单元读出值,可以这么做:
data_out = my_memory [address];
但要是只需要读⼀位或者多个位,就要⿇烦⼀点,因为Verilog不允许读/写⼀个位。这时,就需要使⽤⼀个变量转换⼀下:(wolf点评:菜鸟易犯的错误,注意!)
例如:
data_out = my_memory[address];
data_out_it_0 = data_out[0];
这⾥⾸先从⼀个单元⾥⾯读出数据,然后再取出读出的数据的某⼀位的值。
初始化内存
初始化内存有多种⽅式,这⾥介绍的是使⽤$readmemb 和 $readmemh系统任务来将保存在⽂件中的数据填充到内存单元中去。$readmemb 和 $readmemh是类似的,只不过$readmemb⽤于内存的⼆进制表⽰,⽽$readmemh则⽤于内存内容的16进制表⽰。这⾥以$readmemh系统任务来介绍。
语法
$readmemh("file_name", mem_array, start_addr, stop_addr);
注意的是:
file_name是包含数据的⽂本⽂件名,mem_array是要初始化的内存单元数组名,start_addr 和 stop_addr是可选的,指⽰要初始化单元的起始地址和结束地址。
下⾯是⼀个简单的例⼦:
module memory ();
reg [7:0] my_memory [0:255];
initial begin
$readmemh("memory.list", my_memory);
end
endmodule
这⾥使⽤内存⽂件memory.list来初始化my_memory数组。
⽽下⾯就是⼀个内存⽂件的例⼦。
// Comments are allowed (wolf点评:段注释也可以,空⾏空格不影响!)
CC // This is first address i.e 8'h00
AA // This is second address i.e 8'h01
@55 // Jump to new address 8'h55
5A // This is address 8'h55
69 // This is address 8'h56
对于内存⽂件,要注意的是下列⼏点:
a、注释标记//在内存⽂件中是被允许的;
b、使⽤@符号将跳到新的⽬标地址,没有@符号就表⽰地址将顺序递增。
关于这个系统任务,有下列常见的⽤法:
1、顺序初始化所有的数组单元;
这种情况下,可以使⽤@符号来指⽰地址,也可以不使⽤它,⽽只在每⼀⾏存放要存放的数据。这样数据将顺序按地址递增存放,从0地址开始。
2、只初始化部分的数组单元;
这种情况下,可以使⽤@符号来指⽰下⼀个要初始化的地址,然后对该地址单元进⾏初始化。例如下列的内存⽂件就只初始化8'h00,8'h01,8'h55和8'h564个内存地址单元。
// Comments are allowed
CC // This is first address i.e 8'h00
AA // This is second address i.e 8'h01
@55 // Jump to new address 8'h55
5A // This is address 8'h55
定义数组初始化69 // This is address 8'h56
3、只初始化数组的地址区间的⼀部分单元。
这个时候,还可以使⽤$readmemh任务的start_addr 和 stop_addr选项来指定初始化的范围。
例如,只初始化100到104这5个单元,就可以这么做:
内存⽂件memory.list定义为:
CC
AA
55
5A
69
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论