亿迅智能制造网
工业4.0先进制造技术信息网站!
首页 | 制造技术 | 制造设备 | 工业物联网 | 工业材料 | 设备保养维修 | 工业编程 |
home  MfgRobots >> 亿迅智能制造网 >  >> Industrial programming >> Verilog

Verilog 数组与存储器:掌握多维数据结构

数组 声明的线网或变量可以是标量或向量。通过在标识符名后指定地址范围可创建任意维度数组,称为多维数组。Verilog 允许 reg、wire、integer 和 real 数据类型形成数组。

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

访问数组特定元素需为每个维度指定索引,索引可以是其他变量的表达式。数组可用于 Verilog 支持的所有数据类型。

注意:n 个 1 位 reg 组成的存储器不等同于 n 位向量 reg。

赋值

y1 = 0; // 非法 - 不能一次性赋值所有元素
y2[0] = 8'ha2; // 索引 0 赋 0xa2
y2[2] = 8'h1c; // 索引 2 赋 0x1c
y3[1][2] = 8'hdd; // 行=1 列=2 赋 0xdd
y3[0][0] = 8'haa; // 行=0 列=0 赋 0xaa

示例

下面代码展示如何建模、赋值和访问不同数组。mem1 是 8 位向量,mem2 是深度 4 的 8 位向量数组(范围 [0:3]),mem3 是 4 行 2 列的 16 位向量二维数组。这些变量被赋予不同值并打印。

module des ();
reg [7:0] mem1; // 8位 reg 向量
reg [7:0] mem2 [0:3]; // 8位向量数组,深度=4
reg [15:0] mem3 [0:3][0:1]; // 16位向量二维数组,行=4,列=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

仿真日志

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.

存储器

存储器是数字存储元件,用于在数字电路中存储数据和信息。RAM 和 ROM 是典型例子。存储元件可用一维 reg 数组建模,称为 存储器。存储器每个元素可代表一个字,用单个数组索引引用。

寄存器向量

Verilog 向量在变量名左侧声明尺寸范围,综合时会实例化匹配尺寸的触发器。下面代码中,设计模块接受时钟、复位和控制信号进行读写。

包含一个 16 位存储元件 register,写时更新,读时返回当前值。当 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 位触发器更新,读控制逻辑配置时返回当前值。

数组

此例中 register 是数组,有 4 个位置,每个 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 位触发器,输入地址用于访问特定触发器组。

Verilog

  1. 球栅阵列(BGA)技术全景指南:高密度PCB互连的终极方案
  2. 掌握 C# 数组:声明、初始化与核心操作完全指南
  3. 深入理解C语言数组与指针的关系
  4. C++ 数组完全指南:声明、初始化、多维数组与指针技巧
  5. C++ 动态数组分配实战指南:new/delete、初始化、扩容与内存管理
  6. Verilog基础:设计你的第一个与门
  7. Verilog 入门:数字电路设计完整教程
  8. 掌握 Verilog 拼接操作:实用指南
  9. 深入理解 Verilog 中的赋值间延迟与赋值内延迟
  10. MATLAB 多维数组与特殊数组完全指南
  11. Java 数组复制技术:全面指南
  12. Java 数组教程:声明、创建、初始化与示例代码