Verilog基础语法(2)之标量和向量、多维数组和存储器
标量和向量、多维数组和存储器
- 一、标量和向量
- 1、表达方式
- 2、位宽规范性
- 3、位选择
- 二、多维数组和存储器
- 1、多维数组赋值
- 2、RAM二维数组
- 3、寄存器变量案例
一、标量和向量
Verilog中常用的数据类型为wire、reg,两者都可以定义为一位变量和多位变量,其中一位的称为标量,多位的称为向量。
- 1bit的时序器件即为一个触发器;16bit的时序器件即为一个能够存储16bit数据的存储器。
- 若没有指定wire或reg的位宽,则认为1bit的标量;若指定了位宽,则wire或reg变成多比特实体向量。
1、表达方式
wire a1; // 单比特wire型标量wire [7:0] a2; // 8-bit wire型矢量reg a3; // 单比特reg型变量reg [31:0] a4; // 32 bit 存储地址的矢量变量
2、位宽规范性
位宽的表达方式在上下代码中应统一风格,一般以最左边为最高位,最右边为最低位。
wire [msb:lsb] b1;integer msb_1;wire [15:0] b2; // 合法表达,msb = 15, lsb = 0wire [msb_1: 2] b3; // 非法表达
msb以及lsb可以是任何整数值–正负或零,不允许使用变量,而且Isb的值可以大于、等于或小于msb的值。但为了保持风格统一,也就是左边的值要比右边的值大,所以不建议lsb大于或等于msb。
3、位选择
向量中的各个位都是可以被单独选中进行操作,如赋值,运算等。例如:
reg [7:0] addr; // 8-bit reg variable [7, 6, 5, 4, 3, 2, 1, 0]addr [0] = 1; // assign 1 to bit 0 of addraddr [3] = 0; // assign 0 to bit 3 of addr
结果示意图:

reg [31:0] addr;
addr [23:16] = 8'h23; // 23至16位被赋值为8'h23

若想要进行批量操作,可以使用:
[<start_bit> +: <width>] // 选中宽度为start_bit再加上width
[<start_bit> -: <width>] // 选中宽度为start_bit再减去width
例如:
module weikuan;reg [31:0] data;int i;initial begindata = 32'hFACE_CAFE;for (i = 0; i < 4; i = i+ 1) begin$display ("data[8*%0d +: 8] = 0x%0h", i, data[8*i +: 8]);end$display ("data[7:0] = 0x%0h", data[7:0]);$display ("data[15:8] = 0x%0h", data[15:8]);$display ("data[23:16] = 0x%0h", data[23:16]);$display ("data[31:24] = 0x%0h", data[31:24]);end
endmodule
仿真结果:
data[8*0 +: 8] = 0xfe // 等价于 data [8*0+8 : 8*0]
data[8*1 +: 8] = 0xca // 等价于 data [8*1+8 : 8*1]
data[8*2 +: 8] = 0xce // 等价于 data [8*2+8 : 8*2]
data[8*3 +: 8] = 0xfa // 等价于 data [8*3+8 : 8*3]data[7:0] = 0xfe
data[15:8] = 0xca
data[23:16] = 0xce
data[31:24] = 0xfa
二、多维数组和存储器
在Verilog中,多维数组对应存储器,而向量可悲认为是一个深度为0的二维数组。
常用的二维数组有RAM、ROM等,主要由深度和位宽两个参数。
reg y1 [11:0]; // reg型数组,深度为12,位宽为1wire [7:0] y2 [3:0] // wire型数组,深度为4,位宽为8reg [7:0] y3 [0:1][0:3]; // reg型三维数组,2行(rows = 2)3列(cols = 3),每个单元数据位宽8bit
1、多维数组赋值
例子:
module mem();reg [7:0] mem1; // reg vector 8-bit widereg [7:0] mem2 [0:3]; // 8-bit wide vector array with depth=4reg [15:0] mem3 [0:3][0:1]; // 16-bit wide vector 2D array with rows=4,cols=2initial begininteger i;mem1 = 8'ha9;$display ("mem1 = 0x%0h", mem1);mem2[0] = 8'haa;mem2[1] = 8'hbb;mem2[2] = 8'hcc;mem2[3] = 8'hdd;for(i = 0; i < 4; i = i + 1) begin$display("mem2[%0d] = 0x%0h", i, mem2[i]);endfor(int i = 0; i < 4; i += 1) beginfor(int j = 0; j < 2; j += 1) beginmem3[i][j] = i + j;$display("mem3[%0d][%0d] = 0x%0h", i, j, mem3[i][j]);endendend
endmodule
仿真结果:
mem1 = 0xa9
mem2[0] = 0xaa
mem2[1] = 0xbb
mem2[2] = 0xcc
mem2[3] = 0xdd
mem3[0][0] = 0x0
mem3[0][1] = 0x1
mem3[1][0] = 0x1
mem3[1][1] = 0x2
mem3[2][0] = 0x2
mem3[2][1] = 0x3
mem3[3][0] = 0x3
mem3[3][1] = 0x4
2、RAM二维数组
mem为一个shendu256,位宽8bit的内存空间。

3、寄存器变量案例
- 一维数组案例:具体功能为:复位时,对寄存器赋0初值;当sel和wr有效时,将输入值赋给寄存器;其他情况,寄存器保持不变。
module dff(input clk,input rst_n,input wr,input sel,input [15:0] wdata,output [15:0] rdata );
reg [15:0] reg;
always@(posedge clk or negedge rst_n)beginif(!rst_n)reg <= 16'b0;else beginif(sel & wr)reg <= wdata;elsereg <= reg;end
end
assign rdata = (sel & ~wr) ? reg : 16'b0;
endmodule
- 二维数组案列:
module mem(input clk,input rst_n,input [1:0] addr,input wr,input sel,input [15:0] wdata,output [15:0] rdata );reg [15:0]mem[3:0];
integer i;always@(posedge clk or negedge rst_n)beginif(!rst_n)beginfor(i = 0; i < 4; i = i + 1)beginmem[i] <= 16'b0; endendelse beginif(sel & wr)mem[addr] <= wdata;elsemem[addr] <= mem[addr];end
end
assign rdata = (sel & ~wr) ? mem[addr] : 16'b0;
endmodule
本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!
