Verilog HDL程序设计——基本要素
Verilog基本上熟悉了,继续整理一下Verilog的学习笔记吧。前面记载了Verilog的结构,写Verilog的结构有了,但是该怎么写呢?在写之前就得了解一下Verilog的一些基本要素了,也就是Verilog是怎么一点一点写出来的。
一、标识符与注释
前面已经说到,模块名的定义要符合标识符的定义,那么什么是标识符呢?它的语法是什么呢?
①标识符是赋给对象的唯一名称,通过标识符可以提及相应的对象,Verilog语法将对转义标识符中的字符逐个处理。
②标识符可以是字母、数字、下划线和美元符$的组合,并且标识符的第一个字母必须是字母或者是下划线。此外,在Verilog的标识符中,是区分大小写的。
③Verilog中有一些关键字,简单地了解就是,预定义好了的,用来说明语言节后的标识符,都是小写的。标识符不能和关键字重复。
④Verilog中还有一种叫做转义标识符的东西,定义为以\(反斜杠)符号开头,以空白结尾(如一个空格)的字符。如\initial就是一个转义字符。转义标识符和关键字是不一样的,比如\initial是非关键字,而initial是关键字。
语言中总需要一些注释的,Verilog中两种注释方法:
①以/*开始注释,*/结束注释,即/* 注释内容*/,可以多行注释。
②以//开头,这种注释只能注释一行
二、常量
对于一门语言,我们总可言考虑它的常量有哪些,变量有哪些,现在就让我们看看Verilog中的常量有哪些吧。
(1)数值逻辑
数字逻辑就是一种状态,可言说说一种常量了,有下面的知识点/注意点:
①Verilog中有四种罗家数值:逻辑0,逻辑1,x:未知态,Z高阻态;其中x、z是不区分大小写的;在verilog中,表达式和逻辑门输入的z通常解释为x,也就是不定态,不能确定这个逻辑值是1还是0。
②实际电路中只有0或者1,没有x和z,当你给电路中设置为x或z时,由编译软件或者综合软件等EDA软件决定电路最终是0或者1.
(2)数值
一个数也是一种常量。
①Verilog中主要可以这么对数值进行组合,整数和实数,有符号数和无符号数。在Verilog中,下划线’_’可以随意用在整数和实数中,没有实际意义,只是提高了可读性。
②对于Verilog中的整数,可以分为简单的十进制数和基数表示的整数。
One:简单的十进制格式的整数定义为带有“+”或者“-”操作符的数字序列,你如45表示十进制数45,-45表示十进制数-45。
注意,简单的十进制数格式的整数代表一个有符号的数,其中负数可使用两种补码形式表示。下面举例子进行说明:
对于简单的十进制32,它是一个有符号的数,由于二进制中才对有无符号进行区分,因此它在二进制中,用6位表示就是100000或者用7位表示就是0100000(最高位是符号位);对于简单的十进制数-15,在二进制中,用5位表示就是10001,用6位表示就是110001(最高位是符号扩展位)。
Two:基数格式的整数格式是:[位宽]’基数 数值,位宽是一个数值,表示数值位长,基数可以是二进制(b)、八进制(o)、十进制(d)、十六进制(h),字母不区分大小写,不然7’d100表示7位的十进制数100。
③实数有十进制计数法(如2.0)和科学计数法,但是根据Verilog的定义,实数都通过四舍五入隐式的转换为最相近的整数。
(3)字符串
字符串是双引号内的字符序列,不能分成多行写。此外,字符串是8位ASCII值的序列,比如“char”这个字符串,就要8x4=32bit寄存器存储它。一些综合器是不支持字符串的。
(4)参数
通过parameter 、localparam等定义的参数,也可以看成是常量,它们的格式记录在前面一篇的博文里面了。
三、变量--数据类型
在Verilog中,它的变量可以用另外的名称代替:数据类型。Verilog的数据类型是一种“变量”,用来表示数字电路硬件中的数据存储和传送元素。Verilog中主要有两大数据类型(变量):线网类型和寄存器类型。
(1)线网类型
①线网类型主要表示表示Verilog中的结构化元件之间的物理连线,其数值由驱动单元决定;如果没有驱动元件连接到网线上,则其默认值为高阻z。此外线网类型的变量只能用assign进行赋值驱动,不能在always中进行赋值。
(可综合的线网类型:)
②线网类型中的wire变量是最常用的,它可以最为任何表达式的输入,也可以用做assign语句和模块例化的输出。Wire的取值是0、1、x、z。此外虽然Verilog语法允许wire类型的数据变量允许多个驱动源,但是仅用于仿真当中,综合中任何变量连接多个驱动源都是错误的。
③tri线网类型,这个类型与wire类型功能几乎一样,但是当总线上需要描述高阻态的特性时,用它来描述以跟wire进行区分。
④supply1和supply0线网类型:supply1用来对电源建模,即高电平1,;supply0用来对低电平进行建模,即低电平0。
(不可综合,进用于仿真的线网类型:)
⑤wor(线或)、trior(三态或):专门用于单信号多驱动;
Wand(线与)、triand(三态与):专门用于多驱动源;
Trireg:具有电荷保持特性的连线;
Tri1:上拉电阻;tri0:下拉电阻。
(2)寄存器类型
①寄存器型变量,都有“寄存特性”,即在接受下一个赋值之前,将保持原值不变。寄存器变量没有强度之分,且所以的寄存器类型变量都必须明确给出类型说明(无默认状态)。
(可综合的寄存器类型:)
②最常用的是reg类型的寄存器变量。寄存器变量可以取任意长度,默认值未知,reg类型的数据可以是正值或者负值。但当一个reg类型的数据是一个表达式的操作数时,它的值被当做无符号数,即正值(比如,你定义了reg [3:0] a;...a = -2;那么由于-2的补码是1110,a中存储的值是1110,也就是值其实是14)。
③integer类型,这种类型是整数寄存器类型,可以作为32位的普通寄存器使用,但是不能直接取这个变量的某一位,而是通过把这个变量赋予给一个32位的reg变量,对reg变量进行操作。
④赋值注意:赋值总是从最右端的位向最左端的位进行;任何多余的位将被截断。此外由于整数的负数形式实质上是以补码向量表示的,因此需要注意赋值的位宽。
⑤reg的扩展类型——memory类型:reg [n-1:0] 存储器名 [m-1:0] ;(表示深度是m,字宽是n的存储器,可以存储mxn个bit)。此外不能直接对memory进行读写,而是先定义一个地址寄存器,通过这个地址寄存器进行索引,再取值。
(不可综合,仅用于仿真的寄存器变量有:)
⑥time类型:用于存储和处理时间,只存储无符号数;
Real类型:实数类型;realtime类型;
由于这种电路设计中不常用,所以不过多记载。
四、运算符
在Verilog中,所谓的运算符就是用来进行运算的,根据运算符所带的操作数的个数,可以分为单目、双目、三目。然后我们还是喜欢根据功能进行划分,大概有9种功能类型的运算符。
(1)赋值运算符
①赋值运算分为连续赋值和过程赋值。
②连续赋值语句,也成为数据流描述方式,用assign关键字表示,赋值符号是“=”,只能对线网赋值。
一个线网型变量一旦被连续赋值语句赋值之后,赋值语句右端赋值表达式的值将连续对被赋值变量产生连续驱动。只要右端表达式任一个操作数的值发生变化,就会立即出发对被赋值变量的更新操作。
③过程赋值,主要用于initial模块和always模块中的赋值语句。
在过程块中,只能使用过程赋值语句,同时过程赋值语句也只能用在过程赋值模块中。
过程赋值的赋值符号是“=”“<=”,分别表示阻塞赋值和非阻塞赋值。这两种赋值在后面的章节中会有讲解,前面写的博文也有一些介绍:
http://www.cnblogs.com/IClearner/p/7188875.html。
(2)算术运算符
①算术运算符又称为二进制运算符,有+(加)、-(减)、*(乘)、/(除)、%(取余)。
②+、-、*是可以综合的,/和%只有在除数或者模值是2的整数次(2、4、8...)的时候才是可以综合。
③在进行乘除运算时,结果值会略去小数部分;在取余操作中,结果的符号位和取余运算第一位操作数的符号位保持一致(-12/(6/4),符号位与-12一致)。
④在进行基本算术运算时,如果某一操作数有不确定的值x,则运算结果也是不确定值x。
⑤算术表达式结果的位宽由位宽最大的操作数决定;在赋值赋值语句中(无论是连续还是过程赋值),算术操作的结果的位宽由操作符左端目标位宽决定;在较长的表达式中,中间结果的位宽应取最大操作数的位宽;此外由于位宽的关系,在运算是要进行位宽保留,也就是结果位宽取大一点,防止溢出。
⑥有无符号的算术运算讨论:在设计中,所有的算术运算都是按照无符号数进行的;如果要完成有符号数的计算,对于加减操作,通过补码处理即可用无符号加法完成;对于乘法操作,无符号数直接采用“*”操作,有符号数,通过定义输入输出和中间变量的符号类型为signed来处理。
(3)逻辑运算符
①逻辑运算符有:逻辑与&&、逻辑或||和逻辑非!;其中&&和||是双目运算符,运算结果是一位;!是单目运算符,结果是一位。
(4)关系运算符
①关系运算符有8种:大于(>)、大于等于(>=)、小于(<)、小于等于(<=)、逻辑相等(==)、逻辑不相等(!=)、全等(===)、全不等(!==)。
②关系运算符的结果是1位(包括1、0、x、z)。
③“===”和“!==”可以比较含有x和z的操作数,但是由于实际硬件中不存在x态和z态,在综合时将按照“==”和“!=”来进行;其实际的功能仅用在仿真中。
(5)条件运算符
①条件运算符,三目运算符:(条件表达式)?():();
(6)位运算符
①位运算符有:按位与(&)、按位或(|)、按位反(~)、按位异或(^)、按位同或(^~或者~^)。除~外,都是双目运算符。
②运算结果可能是多位(每一个操作数的对应位进行运算,得出的结果也是各个位运算“拼”起来的结果),不仅仅是1为,注意与逻辑运算符的区别!,此外如果两个操作数的长度不相等,将会对较短的数进行高位补0,然后进行相应的位运算,使输出结果的长度与位宽的操作数保持一致。
(7)拼接运算符
①拼接运算符可以将两个或者更多信号的某些位拼接起来进行运算操作,{a1,b1,c1...}这样子拼接,拼接运算也可以复制一个常量或者变量。
(8)移位运算符
①移位运算符有两个:左移(<<)、右移(>>),移位过程中都用0来填补移出的空位,左移会引起位数扩大,而右移则不会(如4’b1101<<2 = 6’b110100);因此要注意移位后变量的位数,以及存储移位后结果的存储器/线网位宽。
②左移相当于乘2,而右移相当于除2,在实际运算中,经常通过不同移位数的组合来计算简单的乘法和除法,比如result=data*19中,因为20=16 + 2 + 1=2^4+2^1+2^0,所以result = data<<4 + data<<1+data;(当然实际代码中不是这样的,而是在always块中进行不同的移位,中间寄存器进行存储移位结果,然后用assign语句进行加起来)
(9)一元简约/归约运算符
①一元归约运算符是单目运算符,操作数放在右边,操作符有归约与(&)、归约或(|)、归约与非(~&)、归约或非(~|)、归约异或(^)、归约同或(~^),运算形式是(?):首先将操作数的第一位和第二位进行相应的与、或等操作,然后再讲运算结果和第三位进行操作,依次类推直至最后一位。
Verilog HDL程序设计——基本要素的更多相关文章
- 你知道Verilog HDL程序是如何构成的吗
本节通过硬件描述语言Verilog HDL对二十进制编码器的描述,介绍Verilog HDL程序的基本结构及特点. 二十进制编码器及Verilog HDL描述 二十进制编码器是数字电路中常用的电路单元 ...
- 基于Verilog HDL整数乘法器设计与仿真验证
基于Verilog HDL整数乘法器设计与仿真验证 1.预备知识 整数分为短整数,中整数,长整数,本文只涉及到短整数.短整数:占用一个字节空间,8位,其中最高位为符号位(最高位为1表示为负数,最高位为 ...
- 【Verilog HDL】赋值语句之阻塞赋值方式与非阻塞赋值方式
刚开始接触Verilog HDL语言时,这种硬件描述语言有一点与软件的程序设计语言直观上的最大区别大概就是这个赋值语句了(这里只是强调直观上的最大区别,事实上的最大区别并非如此). Verilog H ...
- 自己动手写处理器之第二阶段(2)——Verilog HDL简单介绍
将陆续上传本人写的新书<自己动手写处理器>(尚未出版),今天是第六篇.我尽量每周四篇 2.3 Verilog HDL简单介绍 本书实现的OpenMIPS处理器是使用Verilog HDL编 ...
- 关于初次使用Verilog HDL语言需要懂的基本语法
关于初次使用Verilog HDL语言需要懂的基本语法 1.常量 数字表达式全面的描述方式为:<位宽><进制><数字> 8’b10101100,表示位宽为8的二进制 ...
- FPGA Verilog HDL 系列实例--------步进电机驱动控制
[连载] FPGA Verilog HDL 系列实例 Verilog HDL 之 步进电机驱动控制 步进电机的用途还是非常广泛的,目前打印机,绘图仪,机器人等等设备都以步进电机为动力核心.那么,下面我 ...
- Verilog HDL基础语法讲解之模块代码基本结构
Verilog HDL基础语法讲解之模块代码基本结构 本章主要讲解Verilog基础语法的内容,文章以一个最简单的例子"二选一多路器"来引入一个最简单的Verilog设计文件的 ...
- Verilog HDL模块的结构
一个设计是由一个个模块(module)构成的.一个模块的设计如下: 1.模块内容是嵌在module 和endmodule两个语句之间.每个模块实现特定的功能,模块可进行层次的嵌套,因此可以将大型的数字 ...
- 写自己的第二级处理器(3)——Verilog HDL行为语句
我们会继续上传新书<自己动手写处理器>(未公布),今天是第七章,我每星期试试4 2.6 Verilog HDL行为语句 2.6.1 过程语句 Verilog定义的模块一般包含有过程语句,过 ...
随机推荐
- Python学习:基本概念
Python学习:基本概念 一,python的特点: 1,python应用场景多;爬虫,网站,数据挖掘,可视化演示. 2,python运行速度慢,但如果CPU够强,这差距并不明显. 3,严格的缩进式编 ...
- 用html5调取谷歌地图获取位置
function getmap(){ if(!navigator.geolocation) throw "Geolocation not supported"; var image ...
- 日常踩坑 searter
目录 es7中的async, await Django生成二维码并转为base64 Django配置404页面 很傻逼的坑 no module named pil 其他 es7中的async, awa ...
- 破解 Adobe 系列的最佳方法,手把手教
此方法是个人认为最方便的而且最安全的方法(可以避免下载到可能捆绑病毒的破解版本) 1.首先到Adobe的官网上下载 Creative Cloud: 打开官网上creative cloud 的下载页面: ...
- SQL VIEW(视图)
视图是可视化的表. SQL CREATE VIEW 语句 什么是视图? 在 SQL 中,视图是基于 SQL 语句的结果集的可视化的表. 视图包含行和列,就像一个真实的表.视图中的字段就是来自一个或多个 ...
- Spring定时任务实例
一.Quartz介绍 在企业应用中,我们经常会碰到时间任务调度的需求,比如每天凌晨生成前天报表,每小时生成一次汇总数据等等.Quartz是出了名的任务调度框架,它可以与J2SE和J2EE应用程序相结合 ...
- Kafka 源代码分析之Log
这里分析Log对象本身的源代码. Log类是一个topic分区的基础类.一个topic分区的所有基本管理动作.都在这个对象里完成.类源代码文件为Log.scala.在源代码log目录下. Log类是L ...
- 【Android Developers Training】 40. 序言:通过NFC共享文件
注:本文翻译自Google官方的Android Developers Training文档,译者技术一般,由于喜爱安卓而产生了翻译的念头,纯属个人兴趣爱好. 原文链接:http://developer ...
- JavaScript中的栈及通过栈操作的实例
<script> /*栈操作*/ function Stack() { this.dataStore = []; this.top = 0; this.push = push; this. ...
- 无法将类型为excel.applicationclass的com 强制转换为接口类型的解决方法[转]
c#解决方案EXCEL 导出 今天碰到客户的电脑在导出EXCEL的时候提示,无法将类型为 excel.applicationclass 的 com 强制转换为接口类型 excel._applicati ...