Verilog编程陷阱——数组的声明和使用

本文介绍了Verilog中数组的声明和初始化,强调了区间表示法在确定数组元素个数和索引时的特殊性,指出了一种常见的误解——认为数组索引总是从0开始。通过实例展示了如何正确声明和初始化数组,以及不正确操作可能导致的问题。推荐使用`reg/wire[m-1:0]数组名[0:n-1]`的形式以避免陷阱。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一.数组的声明

wire [31 : 0] a_array [11 : 0]; // 12个32位wire型变量构成的数组
reg  [31 : 0] b_array [11 : 0]; // 12个32位reg型变量构成的数组
wire [31 : 0] c_array [12 : 1]; // 12个32位wire型变量构成的数组
wire [31 : 0] d_array [18 : 7]; // 12个32位wire型变量构成的数组
wire [31 : 0] e_array [0 : 11]; // 12个32位wire型变量构成的数组
wire [31 : 0] e_array [3 : 14]; // 12个32位wire型变量构成的数组

声明语法:变量类型 数组名 [a : b]

其中,a,b的位置可以调换,(a-b)的绝对值 + 1等于数组元素的个数。

在C语言中,数组只需要指定类型和元素个数,语法如下:

变量类型 数组名 [元素个数]

int a_array [12]

但在Verilog中,并不能直接指定元素个数(SV中引入了这个功能,但Verilog中不行),而是采用区间表示,像 [0 : 11],[11 : 0],[18 : 7]都可以表示区间,它们都表示数组内的元素个数为12

二. 数组的初始化

reg [31 : 0] addr_array [6 : 2];
always @(posedge clk) begin
  addr_array[2] <= 'h8;   // 12 注意这里是从2开始,与数组的定义对应,不存在addr_array[0]和addr_array[1]
  addr_array[3] <= 'h14;  // 20
  addr_array[4] <= 'h18;  // 24
  addr_array[5] <= 'h20;  // 32
  addr_array[6] <= 'h24;  // 36
end

使用时序逻辑对数组进行初始化,这相当于定义了一个ROM。

这里其实就很可能掉入陷阱,一般我们可能认为,数组的区间仅用于表示元素个数,数组元素的索引一直都是从0开始,到元素个数-1结束。这对于以下两个数组来说是对的,

reg [31 : 0] a_array [4 : 0];
// 或者
reg [31 : 0] b_array [0 : 4];

但对于上面的reg [31 : 0] addr_array [6 : 2]不对。[6 : 2]这种写法不仅表示了数组的元素个数,还额外规定了数组的索引。

Verilog的这个语法是为了具体规定每个元素在寄存器中存储的位置,是有它的作用在的,但我们很可能参考C语言的规则去理解这个数组的语法,而错误的去访问addr_array[0]addr_array[1],其实这两个元素是未定义的,根本不存在与数组中

更难受的是,赋值和使用addr_array[0]addr_array[1]这两个原本不存在的元素,综合和实现都不报错!这简直是灾难,可能导致很多令人费解的程序错误。

三. 推荐写法

为避免掉入陷阱和使用的方便,推荐仅使用以下的写法来声明数组

reg [31 : 0] addr_array [0 : 4];
always @(posedge clk) begin
  addr_array[0] <= 'h8;
  addr_array[1] <= 'h14;
  addr_array[2] <= 'h18;
  addr_array[3] <= 'h20;
  addr_array[4] <= 'h24;
end

reg/wire [m-1 : 0] 数组名 [0 : n-1]

这样声明了一个:由n个位宽为m的reg/wire型变量组成的数组。这种写法也方便检查访问数组元素是否正确,0~4正好对应每个元素的索引值。

评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值