Verilog数组和内存(Verilog Arrays and Memories)

net或变量的数组声明可以是标量或向量。可以通过在标识符名称后面指定地址范围来创建任意数量的维度,并将其称为多维数组。Verilog中允许对reg、wire、integer和real数据类型使用数组。

  reg        y1 [11:0];        // y是深度12的标量reg数组,每个1位宽
  wire [0:7] y2 [3:0]          // y 是8位向量 net 深度为4
  reg  [7:0] y3 [0:1][0:3];    //y是一个二维数组,行=2,列=4,每个8位宽

必须为每个维度指定一个索引来访问数组中的特定元素,并且可以是其他变量的表达式。可以为Verilog中支持的任何不同数据类型形成一个数组。注意,n位reg的内存与n位向量reg是不同的。

分配(Assignment)


  y1 = 0;             //非法-无法一次分配所有元素
 
  y2[0] = 8'ha2;       // 将0xa2分配给index = 0
  y2[2] = 8'h1c;      
  y3[1][2] = 8'hdd;  
  y3[0][0] = 8'haa; 

下面显示的代码仅显示如何对不同的数组进行建模,分配和访问。 mem1是8位向量,mem2是深度为4(由[0:3]指定的深度)的8位数组,mem3是具有4行2列的16位向量2D数组。 这些变量被分配了不同的值并被打印。

module des ();
  reg [7:0]  mem1;               // reg向量8位宽
  reg [7:0]  mem2 [0:3];         // 深度= 4的8位宽向量数组
  reg [15:0] mem3 [0:3][0:1];   // 行数= 4,cols = 2的16位宽矢量2维数组
 
  initial begin
    int 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]);
    end
 
    for(int i = 0; i < 4; i += 1) begin
      for(int j = 0; j < 2; j += 1) begin
        mem3[i][j] = i + j;
        $display("mem3[%0d][%0d] = 0x%0h", i, j, mem3[i][j]);
      end
    end
  end
endmodule
 
Simulation Log
ncsim> run
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
ncsim: *W,RNQUIE: Simulation is complete.

存储器Memories

存储器是数字存储元件,有助于在数字电路中存储数据和信息。 RAM和ROM是这种存储元件的很好的例子。 可以使用reg类型的一维数组对存储元素进行建模,称为存储。 存储器中的每个元素可以代表一个单词,并使用单个数组索引进行引用。
在这里插入图片描述

寄存器向量Register Vector

在下面显示的代码中,设计模块时钟,复位和一些控制信号以对模块进行读写。

它包含一个称为寄存器的16位存储元素,该元素仅在写入期间进行更新,并在读取期间返回当前值。 当sel和wr在同一时钟沿上为高电平时,写入寄存器。 当sel为高而wr为低时,它将返回当前数据。

module des (    input           clk,
                input           rstn,
                input           wr,
                input           sel,
                input [15:0]    wdata,
                output [15:0]   rdata);
 
  reg [15:0] register;
 
  always @ (posedge clk) begin
    if (!rstn)
      register <= 0;
    else begin
      if (sel & wr) 
        register <= wdata;
      else
        register <= register;
    end
  end
 
  assign rdata = (sel & ~wr) ? register : 0;
endmodule

硬件示意图显示,当用于写入的控制逻辑处于活动状态时,将更新16位触发器,而当将控制逻辑配置为用于读取时,将返回当前值。
在这里插入图片描述

Array数组

在此示例中,寄存器是一个具有四个位置的数组,每个位置的宽度为16位。设计模块接受一个称为addr的附加输入信号,以访问阵列中的特定索引。

module des (    input           clk,
                input           rstn,
                input  [1:0]    addr,
                input           wr,
                input           sel,
                input [15:0]    wdata,
                output [15:0]   rdata);
 
reg [15:0] register [0:3];
integer i;
 
always @ (posedge clk) begin
    if (!rstn) begin
        for (i = 0; i < 4; i = i+1) begin 
            register[i] <= 0;
        end
    end else begin
        if (sel & wr) 
            register[addr] <= wdata;
        else
            register[addr] <= register[addr];
    end
end
 
assign rdata = (sel & ~wr) ? register[addr] : 0;
endmodule

在硬件示意图中可以看到,阵列的每个索引都是一个16位触发器,并且输入地址用于访问一组特定的触发器。

在这里插入图片描述
参考文献:
【1】https://www.chipverify.com/verilog/verilog-arrays-memories

发布了124 篇原创文章 · 获赞 8 · 访问量 6687

猜你喜欢

转载自blog.csdn.net/qq_43042339/article/details/104550208