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、寄存器变量案例

  1. 一维数组案例:具体功能为:复位时,对寄存器赋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
  1. 二维数组案列:
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


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部