Verilog初级教程(5)Verilog中的多维数组和存储器
博文目录
- 写在前面
- 正文
- 多维数组
- 多维数组赋值
- 内存
- 寄存器变量应用实例
- 寄存器阵列应用实例
- 参考资料
- 交个朋友
写在前面
上篇博客讲了单比特的变量称为标量,多比特的变量称为向量。其实向量就类似于C或者其他语言中的一维数组,如果是reg类型的变量,对应的硬件逻辑是寄存器。
本篇博文进一步延伸,Verilog中也存在多维数组,它对应的硬件逻辑可以是存储器,诸如RAM,ROM,以及FIFO等。
- 个人微信公众号: FPGA LAB
正文
多维数组
还是简单一些说吧,多维数组在Verilog中对应的硬件元素可以是存储器,向量,也即一维数组,可以认为是深度为0的二维数组。
由于能对应于硬件的数组,例如RAM,通常有这么几个参数,深度,宽度,因此我们一般做到二维数组,当然更多维的不是不可以,不违背语法,但用途极为有限。
例如:
reg y1 [11:0]; // y is an scalar reg array of depth=12, each 1-bit widewire [0:7] y2 [3:0] // y is an 8-bit vector net with a depth of 4reg [7:0] y3 [0:1][0:3]; // y is a 2D array rows=2,cols=4 each 8-bit wide
y1是一个reg类型的数组,其深度为12,宽度为1;
y2是一个wire类型的数组,其深度为4,宽度为8;
y3是一个多维(三维)数组,其意义不在多说。
上面的第二位定义,我们需要强调一下,还是统一规则为好,也就是宽度最好是高位在左,低位在右。
例如:
reg [0:0] y1 [11:0]; // y is an scalar reg array of depth=12, each 1-bit widewire [7:0] y2 [3:0] // y is an 8-bit vector net with a depth of 4
多维数组赋值
对于多维数组赋值,也就是对存储器赋值,我们不能像如下方式:
reg [7:0] a [15:0] = 0;
这种方式是错误的,我们需要选中对应的元素进行赋值,例如:
reg [7:0] a [15:0];initial begina[0] = 16'h0000;
a[1] = 16'h0101;
//.......or
a[0][0] = 1'b0;
a[0][1] = 1'b1;
//......orfor(integer i = 0; i <16; i = i + 1) begina[i] <= 0;
endend
上面的例子是在仿真文件中,当然在FPGA内,如此赋初值也是可以的,但更常用的还是通过系统函数readmemh:
$readmemh("file_name", mem_array, start_addr, stop_addr);
举一个仿真的例子:
module des ();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 beginint 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
仿真结果:
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等,它们可以使用二维数组进行建模。
例如:
mem就是一个深度为256,宽度为8bit的内存空间,而它在Verilog中就是通过一个二维数组建模的。
寄存器变量应用实例
寄存器变量,相当于一个一维数组,下面定义一个寄存器变量,并对其进行操作:复位有效时,对寄存器变量赋初值,当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) beginif (!rstn)register <= 0;else beginif (sel & wr) register <= wdata;elseregister <= register;endendassign rdata = (sel & ~wr) ? register : 0;
endmodule
硬件原理图显示,当写的控制逻辑处于有效状态时,会更新一个16位的触发器,当读的控制逻辑使能时,会返回当前值。
寄存器阵列应用实例
同理,举一个二位数组的例子:
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) beginif (!rstn) beginfor (i = 0; i < 4; i = i+1) begin register[i] <= 0;endend else beginif (sel & wr) register[addr] <= wdata;elseregister[addr] <= register[addr];end
endassign rdata = (sel & ~wr) ? register[addr] : 0;
endmodule
在硬件原理图中可以看到,数组的每个索引都是一个16位的触发器,输入地址用于访问特定的触发器。
参考资料
- 参考资料1
- 参考资料2
交个朋友
个人微信公众号:FPGA LAB
知乎:李锐博恩
FPGA/IC技术交流2020
Verilog初级教程(5)Verilog中的多维数组和存储器相关推荐
- Verilog初级教程(23)Verilog仿真中的显示任务
文章目录 前言 正文 Display/Write Tasks Verilog Strobes Verilog Continuous Monitors Verilog Format Specifiers ...
- Verilog初级教程(21)Verilog中的延迟控制语句
文章目录 前言 正文 延迟控制语句 事件控制语句 Named Events Event or operator 往期回顾 参考资料及推荐关注 前言 Verilog中的延迟控制有两种类型–延迟和事件表达 ...
- Verilog初级教程(20)Verilog中的`ifdef 条件编译语句
文章目录 前言 正文 语法 示例 Testbench文件 往期回顾 参考资料及推荐关注 前言 `ifdef条件编译语句在逻辑设计中还是很常见的,但也常见一些滥用的情况,这应该避免. 应该在什么情况下使 ...
- Verilog初级教程(15)Verilog中的阻塞与非阻塞语句
文章目录 前言 正文 阻塞赋值 非阻塞赋值 往期回顾 参考资料以及推荐关注 前言 本文通过仿真的方式,形象的说明阻塞赋值以及非阻塞赋值的区别,希望和其他教程相辅相成,共同辅助理解. 正文 阻塞赋值 阻 ...
- Verilog初级教程(14)Verilog中的赋值语句
文章目录 前言 正文 合理的左值 过程性赋值(Procedural assignment) 连续赋值 过程连续性赋值 往期回顾 前言 何为赋值语句?即将值放到线网或者变量上,这种操作称为赋值,英文:a ...
- Verilog初级教程(12)Verilog中的generate块
文章目录 前言 正文 generate for generate if generate case 参考资料 本系列博文 前言 verilog中的generate块可以称为生成块,所谓生成,可以理解为 ...
- Verilog初级教程(11)Verilog中的initial块
文章目录 前言 正文 语法格式 initial块是用来干什么的? initial块何时开始又何时结束? 一个模块中允许有多少个initial块? 参考资料 写在最后 前言 仿真中通常会依次执行一组Ve ...
- Verilog初级教程(19)Verilog中的参数
文章目录 前言 正文 模块参数 覆盖参数 例子说明 递增计数器 递减计数器 Specify参数 模块参数与Specify参数的区别 往期回顾 参考资料及推荐关注 前言 Verilog中的参数是使得设计 ...
- Verilog初级教程(16)Verilog中的控制块
文章目录 前言 正文 条件语句if 语法 硬件实现 循环语句 forever repeat while for 往期回顾 参考资料及推荐关注 前言 硬件行为的实现离不开条件语句和其他控制逻辑流的方式. ...
最新文章
- Udacity机器人软件工程师课程笔记(八)-ROS Turtlesim 包的相关命令
- 腾讯斥资3.17亿美元增持B站 持股增至12%
- 生信多组学整合工具的比较研究
- 使用proc文件系统
- SpringCloud相关概念介绍
- WildFly 8.0.0.Alpha1的发布和一些历史
- QT| C/C++之win98扫雷外挂增强版
- python语法基础题你好_Python基础要打牢,先学会基本语法
- 在html中直接使用%3c php%3e,HTB-靶机-Calamity
- LINQ-查询表达式基础
- 物联网工程专业该怎么学?老学长吐血整理!!
- IMAGE_DOS_HEADER解析
- Hadoop与MPP
- 系统临时文件的写和读:createTempFile和tempFileContent
- Java 求最大公约数
- JAVA 输出 1 3 6 10 15 ....
- agd插值算法_多目标自适应和声搜索算法
- MBT测试思想在苏宁蛙测的运用实践分享
- ECSHOP模板文件功能说明
- 删除Mysql数据库的表空间,日志文件
热门文章
- 微信九宫图生成HTML源码
- BAPI_GOODSMVT_CREATE(调拨 收货 发货 入库 退货)BAPI
- 解决backtrack5连接不上ssh问题
- 算法设计与分析: 2-7 士兵站队问题
- C++ system()函数的常用用法 (史上最详细)
- MySQL 数据库管理之 --- 日志查询
- anaconda安装及配置
- 【源码阅读技巧一】查看类关系图,接口实现关系图(idea版本)Diagrams关系图
- Expert 诊断优化系列------------------内存不够用么?
- ROSNOTE : ros::spin() / ros::spinOnce() /rospy.spin()