Verilog HDL基础知识(一)
引言:本文我们介绍Verilog HDL的基础知识,重点对Verilog HDL的基本语法及其应用要点进行介绍。
1. Verilog HDL概述
什么是Verilog?Verilog是IEEE标准的硬件描述语言,一种基于文本的语言,用于描述最终将在硬件中实现的电路。Verilog和它的竞争对手VHDL一样,可以用于仿真和综合,实现对硬件进行建模。
Verilog最初是由Cadence收购的Gateway Design Automation创建的。1995年,它被IEEE采用为标准。2001年,采用了该语言的修订版本。2005年也进行了小的修订。同样值得注意的是,2005年SystemVerilog作为Verilog HDL的超集引入,其中还包括面向对象的验证技术。2009年,IEEE将Verilog标准与System Verilog标准合并为一个IEEE 1800-2009标准。
2. 行为建模和结构建模
当进行综合实现时,有两种方法可以进行电路建模:行为建模和结构建模。
2.1 行为建模
在行为建模中,您描述的是电路的功能,而不是电路的结构。输出行为是相对于输入来描述的。这里是描述移位操作的行为HDL代码的示例。
图1:移位操作行为建模示例
这种类型的建模依赖于综合引擎来创建与所描述的行为相匹配的正确电路。
2.2 结构建模
图2:结构建模示例
在结构建模方法中,指定了电路的功能和结构。编写HDL的工程师调用特定的硬件元件并将它们连接在一起。硬件元件可以像AND或OR门一样简单,也可以是表示另一抽象层的模块。
3. 其他术语
寄存器传输级(RTL):,这是一个常用术语,描述了一种行为建模风格,该风格根据硬件模型内的数据流操作定义输入输出关系。RTL构建体是可综合的。
综合(Synthesis):综合是指将HDL代码转换和优化为特定的电路。例如,查找表和FPGA的触发器。
RTL综合(RTL Synthesis):转换硬件RTL模型到优化的专用门电路的实现,简单理解为RTL模型映射。
图3:RTL综合示例
图3演示了RTL综合的过程。在第一步中,综合引擎使用特定目标器件的架构元素将原始代码转换为硬件逻辑门。然后,它将经过优化阶段,以确保电路描述的最佳实现。在这个特定的例子中,case语句是在一个软件通常推断的多路复用器块内实现的。
4. 典型的RTL综合和RTL仿真流程
Verilog模型可以通过综合仿真两种不同的流程转换,如图下图所示。
图4:典型的RTL综合和RTL仿真流程
在综合流程中,综合编译器(例如Synopsys的Synplify或Altera的Native synthesis Engine)将使用目标器件库中的可用技术,将verilog模型转换并优化为技术特定的网表,该网表可用于定时分析,或放置并路由(映射)到特定器件中。
在仿真流程中,例如使用Mentor Graphics Modelsim,仿真编译器将使用Verilog测试台或通过测试向量提供的激励来仿真Verilog模型。
大多数综合工具也可以写出科综合的Verilog文件,以便设计者在执行放置和布线之前检查综合结果。
5. 模块结构
Verilog HDL模块结构如下所示:
module module (port_list);
---------- // port declarations
---------- // data tpye declarations
---------- // circuit functionality
---------- // timing specifications
endmodule
Verilog HDL模块由关键字module和结endmodule封装,它还由几个主要部分组成。首先是端口列表,它是用模块声明指定的。接下来定义端口。然后在数据类型声明中声明模块中要使用的变量和网络。之后是定义电路功能的代码,最后是是否制定了适用的时序规范仿真环境。
(1)Verilog HDL区分大小写,所有关键字都是小写的;
(2)与C一样,Verilog HDL语句以分号结尾;
(3)单行注释以斜杠开头,而斜线星号用于多行注释的开头,星号斜杠用于多行注释的结尾;
(4)Verilog HDL对空格不敏感,有助于提高可读性。
图5:mult-acc模块Verilog HDL示例
图5为Verilog HDL代码,模块用于生成右侧所示的乘法器-累加器块。
在顶部,声明了mult-acc模块以及输入和输出端口的列表。橙色部分是将在该模块中使用的所有变量和端口的端口和数据类型声明。代码的绿色部分是一个连续的赋值语句,它将被综合到组合加法器中。粉红色部分是顺序时序寄存器的代码。最后,蓝色部分实例化了描述乘法器的另一个模块。
5.1 模块和端口声明
模块以关键字module开头,后跟模块名称。
Verilog HDL模块的第一部分是端口列表。端口列表包含模块的所有输入、输出和双向连接。端口列表位于模块名称后面的括号中。
图6:模块和端口声明示例
在端口列表之后是端口声明部分。本节将每个端口与端口类型相关联。有三种端口类型:输入、输出和双向端口的inout。端口声明部分的结构是端口类型,后跟端口名称。总线有一个方括号,跟在端口类型后面,里面有总线位宽。
图6例子中,ina和inb是8位输入,clk和aclr是1位输入,而out是16位输出总线。使用Verilog2001标准,您可以选择声明端口列表和端口类型以及模块声明。如图7所示,我这样更简洁。
图7:模块和端口声明示例,2001标准
5.2 数据类型
在端口声明部分之后是数据类型声明部分。Verilog HDL有Net和可变数据两种基本数据类型。
5.2.1 Net数据类型
Net数据类型表示进程或功能块之间的物理互连。它们需要不断地被驱动,而不能存储数值。
图8:Net数据类型
以下是综合支持的四种最常见的Net数据类型。
wire表示一个节点或者连接;
tri表示三态节点
supply0表示逻辑“0”;
supply1表示逻辑“1”。
总线声明:
<data_type> [MSB:LSB] <sginal name>
<data_type> [LSB:MSB] <sginal name>
//示例:
wire [7:0] out;
tri enable;
5.2.2 变量数据类型
变量数据类型用于临时存储数据。它们与其他语言中的变量相似。根据使用情况,可变数据类型可以整合为硬件触发器或寄存器或组合节点。
图9:变量数据类型
变量数据类型表示临时存储。它们可以是reg、integer、real、time和realtime类型。
reg类型是任意无符号位大小的变量,使用reg signed可以定义符号变量。
integer表示32位有符号变量。
real、time和realtime仅用于仿真目的,不支持综合。
变量数据类型需要在过程、任务或函数中分配,不能使用连续赋值语句assign来驱动它们。
使用reg数据类型,可以以与Net相同的方式进行总线声明。
reg [MSB:LSB] <sginal name>
reg [LSB:MSB] <sginal name>
//示例:
reg [7:0] out;
integer cnt;
5.3 模块实例化
5.3.1 模块例化格式
一旦一个模块被声明,它可能会通过使用这里的语法在更高级别的模块上实例化。模块例化格式如下:
<componet_name> #<delay> <instance_name> (port_list);
首先是较低级别的组件名称componet_name,这是您声明的组件的名称。
如果希望通过组件表达时间延迟delay,可以使用可选的#构造。这仅用于仿真,而不用于综合。
指定实例名称instance_name,这是应用于组件实例的唯一名称。
最后,指定要连接到较低级别组件的输入和输出的信号列表port_list。
通过实例化模块,您可以创建具有多个层次结构的设计,以实现更容易的可维护性,现代设计通常具有许多层次结构。
5.3.2 模块例化端口连接
将信号连接到较低级别的模块端口时,有两种方法可以定义连接:按信号顺序列表和名称。
图10:模块连接
图10给出的例子中,实例化了半加法器模块的两个实例,以形成一个全加法器。
对于第一个实例u1,使用有序列表方法进行实例化。在这里,通过以与较低级别模块声明中的端口列表相同的顺序列出端口列表,将较高级别的信号连接到半加器模块的端口。端口连接的顺序很重要,所以应该只在端口很少的模块中使用此方法。
对于第二个实例u2,使用connections-by-name方法进行实例化。在这里,已经说明了哪些电线连接到哪个端口。此时端口连接的顺序无关紧要,也可忽略不想连接的某些端口。这是推荐的方法。
5.3.3 例化端口连接规则
进出模块的连接必须遵守某些规则。模块的端口和到模块的连接只能声明为特定的数据类型。
图11:端口连接规则
当将信号连接到较低级别模块的端口时,变量类型数据不能连接到模块的输出或输出,而Net数据类型可以在所有情况下使用。
5.4 参数
参数可用于将值与符号名称相关联,这样可使代码更具有可读性和意义。
parameter size = 8;
localparam outsize = 16;
reg [size-1:0] dataaa,datab;
reg [outsize-1:0] out;
在这里的示例中,我将size和outsize分别声明为解析为8和16的参数。然后在声明变量dataa、datab和out时引用它们。
在编译期间,可以从实例化包含参数的模块的模块重写参数。关键字localparam参数只能用作本地参数。所有类型的参数在编译时解析为常数值,并且在模块执行期间不能更改。
使用Verilog-2001,您可以在声明模块的同时声明变量。
module mult_acc
#(parameter size = 8)
(...);
5.5 数字赋值
数字可以通过两种方式分配给变量,可以调整大小也可以取消大小。如果没有指定数字的大小或格式,它们将默认为32位十进制数字。
数字的格式是大小、进制,然后是实际数字本身。
16'd233 //16bit位宽的十进制数233
8'h9A //8bit位宽16进制
'b1010 //32bit位宽2进制
o'21 //32位宽8进制
16'shFA //有符号数据16bit位宽16进制
如果指定了一个有大小的数字,则必须在进制之前指定数字的宽度(以位为单位)。基本格式可以是d、h、b或o。也可以添加s来表示数字的有符号或2的补码表示。
负数表示:
-8'd3 //8bit负数,存储为3的二进制补码
提高数字可读性:使用下划线"_",例如:
32'h21_66_88_99 //32bit十六进制
数字中的特殊字符表示:"X"表示未知值,"Z"表示高阻抗。
12'h12x //12bit十六进制,LSB未知
1'bz //1bit高阻抗数值
5.6 运算符
运算符如下表所示。
在算术运算符方面,Verilog定义了加法、减法、乘法、除法、模和指数。某些综合工具可能不支持除法或指数。只有当第二个操作数是常量时,其他操作数才支持它们。
运算符将输入向量视为一个整数。因此,如果Z或X值出现在部分操作数中,结果将是未知的。例如表中,ain+din=>未知。
此外,如果结果向量与操作数大小相同,则进位可能存在丢失。
5.7 位算符
位运算符如下表所示。
Verilog HDL的位运算符可以是一元运算符或二进制运算符,它们包括反转、和、或、异或或和同或。这些运算符对操作数的每个位进行运算。如果操作数大小不同,则较小的操作数左扩展,结果为最大操作数的大小。
5.8 归约运算符
归约运算符如下表所示。
归约运算符是将向量归约为单个位的一元运算。Verilog支持and、nand、or、nor、xor和xnor归约运算符。
这些运算符中的每一个都会产生一个单比特结果。即使“X”和“Z”是未知值,结果可能仍然是已知的。例如,如果“and”向量中有一个零,则无论是否存在“X”或“Z”位,结果都将为0。
5.9 关系运算符
相等运算符如下表所示。
关系运算符用于比较操作数,它们返回一个值。以下是Verilog HDL支持的关系运算符:大于、小于、大于或等于以及小于或等于。
结果为true或false,由“1”或“0”表示。如果任一操作数包含“Z”或“X”,则结果将是未知的。
5.10 相等运算符
相等运算符如下表所示。
与关系运算符一样,等式运算符也用于比较值。它们返回一位真值或假值。Verilog HDL支持4个相等运算符:相等、不相等、大小写相等和大小写不相等。
相等运算符只支持已知值“1”和“0”,所以如果操作数中有x或z,结果将是未知的。
5.11 逻辑运算符
逻辑运算符如下表所示。
逻辑运算符可以是一元运算符,也可以是二进制运算符。
Verilog HDL支持not true、logic and和logic or。这些运算符通常用于“if”和“while”语句中。这些运算符返回一位true或false结果。操作数中出现“Z”或“X”位将导致未知结果。
5.12 移位运算符
移位运算符如下表所示。
支持Shift right和Shift left运算符。这些运算符将矢量向左或向右移动指定数量的位。
对于左移位,空出的位置用零填充,并且移位的比特丢失。对于右移,逻辑和算术无符号移位将用零填充,而算术有符号移位将使用符号位值填充。
5.13 混合运算符
混合运算符如下表所示。
条件运算符的作用类似于if-then语句。
串联运算符将两个或多个向量组合成一个更大的向量。
复制操作符获取一个矢量并复制指定次数。
5.14 操作运算符优先级
操作运算符优先级如下图所示。
当您同时使用多个运算符时,建议使用圆括号对操作进行分组以进行增强理解性和可读性。
如果括号不存在,您可以在这里看到verilog定义的运算符的优先级。一元运算符具有最高优先级。
欢迎关注FPGA技术实战公众号,喜欢就多多转发吧!
相关文章:

Verilog HDL基础知识(一)
引言:本文我们介绍Verilog HDL的基础知识,重点对Verilog HDL的基本语法及其应用要点进行介绍。 1. Verilog HDL概述 什么是Verilog?Verilog是IEEE标准的硬件描述语言,一种基于文本的语言,用于描述最终将在硬件中实现…...

Django之文件上传(一)
一、环境搭建 建立项目 django-admin startproject project_demo配置数据库(以MySQL为例) # settings.py DATABASES = {default: {ENGINE: django.db.backends.mysql,NAME: django_file4,USER: root,PASSWORD: 123,HOST: 192.168.31.151,PORT: 3306,} }建立模型 class UploadF…...

光纤现网与接入网概念对应
OLT 一般在机房 一级分光可能在机房也可能在光交交接箱 路边的光交交接箱功能有分光或者光纤汇聚转换一下 二级分光在分光光纤箱里,楼道里面挂着的那种 ONU是家里的光猫...

通过扩展指令增强基于覆盖引导的模糊测试
本文由Bruno Oliveira于2024年4月25日发表于IncludeSec的官方网站上。作为IncludeSec的安全研究人员,在他们日常的安全审计和渗透测试工作中,有时需要为客户开发一些模糊测试工具。在安全评估方法中使用模糊测试技术,可以有效地在复杂的现代化…...

第一节:Redis的数据类型和基本操作
最近整理了关于Redis的一些文档,分享给大家,后续会持续更新...... Redis的数据类型 字符串String String:字符串,可以存储String、Integer、Float型的数据,甚至是二进制数据,一个字符串最大容量是512M 列表…...

组件的传参等
一:组件的生命周期函数 组件的生命周期函数: created只是创建了组件内的实例对象 attached,给组件实例绑定了属性,绑定到页面节点树之后 ready准备好渲染之后,还未渲染之前 moved组件实例被移动到另一个位置后执行 detached在整个组件被被移除执行 error执行的时候,组件内…...

构建php环境、安装、依赖、nginx配置、ab压力测试命令、添加php-fpm为系统服务
目录 php简介 官网php安装包 选择下载稳定版本 (建议使用此版本,文章以此版本为例) 安装php解析环境 准备工作 安装依赖 zlib-devel 和 libxml2-devel包。 安装扩展工具库 安装 libmcrypt 安装 mhash 安装mcrypt 安装php 选项含…...

服装服饰商城小程序的作用是什么
要说服装商家,那数量是非常多,厂家/经销门店/小摊/无货源等,线上线下同行竞争激烈,虽然用户群体广涵盖每个人,但每个商家肯定都希望更多客户被自己转化,渠道运营方案营销环境等不可少。 以年轻人为主的消费…...

HNU-计算机体系结构-实验2-Tomasulo算法
计算机体系结构 实验2 计科210X 甘晴void 202108010XXX 1 实验目的 熟悉Tomasulo模拟器同时加深对Tomasulo算法的理解,从而理解指令级并行的一种方式-动态指令调度。 掌握Tomasulo算法在指令流出、执行、写结果各阶段对浮点操作指令以及load和store指令进行什么…...

深入分析 Android Activity (一)
文章目录 深入分析 Android Activity (一)1. Activity 的窗口管理2. Activity 的生命周期管理onCreateonStartonResumeonPauseonStoponDestroyonRestart 3. Activity 与 Fragment 的交互添加 FragmentFragment 的生命周期 4. Activity 的任务和返回栈5. 配置变化处理 总结 深入…...

Python 调整PDF文件的页面大小
在处理PDF文件时,我们可能会遇到这样的情况:原始PDF文档不符合我们的阅读习惯,或者需要适配不同显示设备等。这时,我们就需要及时调整PDF文档中的页面尺寸,以满足不同应用场景的需求。 利用Python语言的高效性和灵活性…...

支付功能、支付平台、支持渠道如何测试?
有学员提问:作为一个支付平台,接入了快钱、易宝或直连银行等多家的渠道,内在的产品流程是自己的。业内有什么比较好的测试办法,来测试各渠道及其支持的银行通道呢? 作为产品,我自己办了十几张银行卡方便测…...
永久代(Permanent Generation)和元空间(Metaspace)
永久代(Permanent Generation)和元空间(Metaspace)是Java虚拟机(JVM)内存管理中的两个概念,主要区别在于它们的实现方式和内存分配策略。 永久代(Permanent Generation)…...
前端面试题23-34
23. 说说你对 Promise 的理解 Promise 是 ECMAScript6 引入的一种异步编程解决方案,用于处理异步操作。它表示一个尚未完成但最终会结束的操作,具有三种状态:pending(进行中)、fulfilled(已完成࿰…...

Hadoop3:HDFS中DataNode与NameNode的工作流程
一、DataNode中的数据情况 数据位置 /opt/module/hadoop-3.1.3/data/dfs/data/current/BP-823420375-192.168.31.102-1714395693863/current/finalized/subdir0/subdir0块信息 每个块信息,由两个文件保存,xxx.meta保存的是数据长度、校验和、时间戳&am…...

MySQL(一) 库和表的基础操作
1. 数据库基础 1.1 什么是数据库 存储数据用文件就可以了,为什么还要弄个数据库? 文件保存数据有以下几个缺点: 文件的安全性问题文件不利于数据查询和管理文件不利于存储海量数据文件在程序中控制不方便 数据库存储介质:磁盘内存 为了解…...
python -【二】判断语句
判断语句 一、 布尔类型 True:真(1)False:假(0) 比较运算符 运算符实例1 1 True!1 ! 1 Flase<1 < 1 Flse>1 > 1 Flse<1 < 1 True>1 > 1 True b1 True b2 False print(f"b1值是{b1},类型是{type(b1)}") print(…...

高通Android 12/13 设置和获取ADB状态
/*** 设置ADB状态** param isEnable*/public void setADB(boolean isEnable) {Settings.Global.putInt(mContext.getContentResolver(), Settings.Global.ADB_ENABLED, isEnable ? 1 : 0);}/*** 获取ADB状态** return*/public boolean getADB() {return Settings.Global.getIn…...

存储器和CPU的连接与TCP的流量控制
存储器与CPU的连接 存储容量的拓展 (1)位拓展:增加存储字长 (2)字拓展 增加存储器字的数量 例题:设CPU有16根地址线,8根数据线,并用MREQ作为访问存储控制信号(低电平有效),WR作为…...

红蓝对抗提权篇之一文看懂提权
一、计算机中的权限 1.1 不同的权限系统 权限在不同的应用中有着不同的分类,与安全相关的大致上我们分为: 匿名访问权限 来宾权限 用户权限 管理员权限 系统权限 不同的权限对应的权力各不相同,我们对自己电脑一般是用户权限和管理员权限。…...

手游刚开服就被攻击怎么办?如何防御DDoS?
开服初期是手游最脆弱的阶段,极易成为DDoS攻击的目标。一旦遭遇攻击,可能导致服务器瘫痪、玩家流失,甚至造成巨大经济损失。本文为开发者提供一套简洁有效的应急与防御方案,帮助快速应对并构建长期防护体系。 一、遭遇攻击的紧急应…...
vue3 字体颜色设置的多种方式
在Vue 3中设置字体颜色可以通过多种方式实现,这取决于你是想在组件内部直接设置,还是在CSS/SCSS/LESS等样式文件中定义。以下是几种常见的方法: 1. 内联样式 你可以直接在模板中使用style绑定来设置字体颜色。 <template><div :s…...

Netty从入门到进阶(二)
二、Netty入门 1. 概述 1.1 Netty是什么 Netty is an asynchronous event-driven network application framework for rapid development of maintainable high performance protocol servers & clients. Netty是一个异步的、基于事件驱动的网络应用框架,用于…...

RabbitMQ入门4.1.0版本(基于java、SpringBoot操作)
RabbitMQ 一、RabbitMQ概述 RabbitMQ RabbitMQ最初由LShift和CohesiveFT于2007年开发,后来由Pivotal Software Inc.(现为VMware子公司)接管。RabbitMQ 是一个开源的消息代理和队列服务器,用 Erlang 语言编写。广泛应用于各种分布…...

2025年渗透测试面试题总结-腾讯[实习]科恩实验室-安全工程师(题目+回答)
安全领域各种资源,学习文档,以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各种好玩的项目及好用的工具,欢迎关注。 目录 腾讯[实习]科恩实验室-安全工程师 一、网络与协议 1. TCP三次握手 2. SYN扫描原理 3. HTTPS证书机制 二…...
【Nginx】使用 Nginx+Lua 实现基于 IP 的访问频率限制
使用 NginxLua 实现基于 IP 的访问频率限制 在高并发场景下,限制某个 IP 的访问频率是非常重要的,可以有效防止恶意攻击或错误配置导致的服务宕机。以下是一个详细的实现方案,使用 Nginx 和 Lua 脚本结合 Redis 来实现基于 IP 的访问频率限制…...

结构化文件管理实战:实现目录自动创建与归类
手动操作容易因疲劳或疏忽导致命名错误、路径混乱等问题,进而引发后续程序异常。使用工具进行标准化操作,能有效降低出错概率。 需要快速整理大量文件的技术用户而言,这款工具提供了一种轻便高效的解决方案。程序体积仅有 156KB,…...
大模型智能体核心技术:CoT与ReAct深度解析
**导读:**在当今AI技术快速发展的背景下,大模型的推理能力和可解释性成为业界关注的焦点。本文深入解析了两项核心技术:CoT(思维链)和ReAct(推理与行动),这两种方法正在重新定义大模…...
Flask和Django,你怎么选?
Flask 和 Django 是 Python 两大最流行的 Web 框架,但它们的设计哲学、目标和适用场景有显著区别。以下是详细的对比: 核心区别:哲学与定位 Django: 定位: "全栈式" Web 框架。奉行"开箱即用"的理念。 哲学: "包含…...
stress-ng 服务器压力测试的工具学习
一、stress-ng (下一代压力测试) 介绍 项目地址:https://github.com/ColinIanKing/stress-ng stress-ng 将以多种可选方式对计算机系统进行压力测试。它旨在锻炼计算机的各种物理子系统以及各种操作系统内核接口。stress-ng 的特点: 360 压力测试100 …...