Verilog HDL
由于该语言与C语言比较接近,因此在FPGA的学习里面我先选择学习它,在后面如果有时间还需要学习VDHL。而且国内一般用Verilog用的比较多。
它具有一下的描述能力:设计的行为特性、设计的数据流特性、设计的结构组成、包含响应监控和设计验证方面的时延和波形产生机制。
基础
标识符
可以由任意顺序的字母、数字、美元符号和下划线组成,但第一个字符不能是数字或者美元符号,只能是字符或下划线,因为以美元符开始的标识符与系统的保留字冲突。
并且大小写相关,关键词全部小写。
转义标识符:与C中一致。
空白符:包括空格(\b)、制表符(\t)、换行和分页符(\n)。它们出现在字符串里面不可忽略,其他时候都会编译为分隔标识符,在编译阶段被忽略。
![在这里插入图片描述](https://img-blog.csdnimg.cn/20210708171413683.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl8
0NDQ0MTI2Mw==,size_16,color_FFFFFF,t_70)
注释:1.单行注释:// 2.多行注释/* … */
关键字包括关键字、系统任务、编译指令。
数据类型
逻辑值
与我们一般理解的不一样,在VerilogHDL语言中,有四个逻辑值:0、1、X、Z。
X:代表逻辑不确定
Z:代表高阻悬浮态。
在16进制基数中代表4位,在8进制中代表3位,在2进制中代表1位
在 Verilog 语言约定的常数表示中,间 号 “?” 是 z 的另一种表示- 使用间号的目的在于增强
casex 和 casez 语旬的可读性。在这两条语 旬中,"?” ( 即高阻抗)表示“不必关心 ”的 情况 斗
强度等级
为了解决数字电路中不同强度驱动源之间的赋值冲突引入了强度值的概念:
驱动为supply,strong,pull,weak,强度依次递减
存储为Large\Medium\Small依次递减
Highz(高阻)在整个强度中等级最低
在各种类型的线网中,只 有 trireg 类型的线网可以具有存储强度。
线网
表示硬件单元之间的连接,线网由其连接器件的输出端连续驱动。如线网a
在Verilog中的线网包括:wire(默认) tri tri0 supply0 wand triand tril supply1 wor trior trireg uwire. wire作为一般的电路连线,而剩下的几种用于构建总线,即多个驱动源连到一条线网的情况,或搭建电源、接地等。
线网与实际电线比较线,是连续赋值的,由赋值符右侧的驱动源决定,在初始化前值为x(trireg类型的相当于一个寄存器),未赋值时相当于z。
寄存器
不需要驱动源、也不需要像硬件寄存器那样需要时钟信号。关键词位reg,默认值是x
它和线网的区别是可以保存当前的数值,直到另一个数值被赋值给它。给它赋值必须在一个过程中进行。这与我们一般认为的寄存器不是完全一样的概念。
需要注意的是:在两个模块的信号连接点,提供信号的一方可以是寄存器或者线网,但是接收信号的一方必须是线网。并且,在**过程(always\initial)**中进行赋值的一定是寄存器类型,而连续赋值的一定是线网类型。
数字表示
<位宽>’<进制><数值>:4’b1111
进制:b\o\d\h
位宽默认32 ;进制默认十进制 ;负号加最前面即可
有时候位数较长:12’b1111_0011_1110,下划线的存在方便显示。
有时候数字的表示会用到?,它是“z”的另一种表示,可以增强casex和casez语句的可读性。
x/z:在二进制中表示1位,在8进制中表示3位,在16进制中表示4位。
向量表示
位宽大于1的网线或者寄存器类型的量就是向量。如:
reg[3:0] c;这样就可以使用向量的分量如:
c[3] 、c[2:0]等等。·
向县通过[high# : low#]或{low#: high#]进行说明,方括号中左边的数总是代表向量的最高有效位。在调用时要保持一致。
可变向量域的选择:
[ +: width]: 从起始位开始递增, 位宽为w idth 。
[-: width]: 从起始位开始递减, 位宽为 w idth 心
其他类型
除 re g 类型之外, Verilog 还支持 inte g e r , re a l (类似浮点数)和 tim e 寄存器数据类型。
整数默认位宽为PC机的位数。 $time可以得到当前的仿真时间。时间声明如下:
time save_sim_time
但是虽然单位表示相同,其对应关系需要用户自定义
数组
可以声明reg、integer、time、real、realtime及其向量类型的数组,定义时在后面加上位数即可,如:
reg [7:0] meme[255:0]
参数
参数代表常数。不能像变量那么赋值。但是每次在实例化时可以重载。通过模块实例化或使用 defparam 语句改变参数值。但localparam不能重载。
全局常数:parameter
局部常数:localparam
如:
parameter msa=7;
字符串
与C一样,“adcd…”
字符串是由双引号括起来的一个字符队列_,对于字符串的限制是,它必须在一行中书写完, 不能书写在多行中,即 不能包 含回车符 。 Verilog 将宇符串当做一个单字节的ACSII 字符队列。
字符串保存在 reg 类型的变蜇 屯 每个字符占用 8 位(一个字节 )勺因此寄存器变量的宽度
应足够大 , 以保证容纳全部字符。如果寄存器变世的宽度大于字符串的 大小(位), 则 Verilog使用 0 来填充左边的空余位 ;如 果寄存器变星的宽度小于字符串的大小(位 ), 则
Verilog 截去字符串最左边的位 因此呵在声明保存字符串的 reg 变量时, 其位宽应当比字符串的位长稍大。
存储器量
在数字电路仿真中,人们常常需要对寄存器文件, RAM 和 ROM 建模。在 Verilog 中.使用
寄存器的一维数组来表示存储牲。数组的每个元素称为一个元素或一个字( word )气由一个数组索引来指定, 每个宇的位宽 为 1 位或多位。注意 n个1位寄存器和一个n位寄存器是不同的尸如果需要访间存储器中的一个特定的字令则可以通过将字的地址作为数组的下标来完成
。
系统任务和编译指令
系统任务
也称系统函数,包括屏幕显示、
线网值动态监视,暂停和结束仿真等 所有的系统任务都具有$ <keyword> 的形式。
$display(p1,p1,…),它会自动在末尾插入一个换行符。
$monitor(p1,p1,…)可以监视,只需要调用一次可一直使用。
$stop:用来暂停仿真以检查信号 如 #100 $stop
$finish:用来结束仿真
编译指令
用法:’<keyword>
'define:宏定义
'define S $stop
'include:
使用 inc lude 可以在谝译期间将一个 Verilog 源文件包含在另一个 Verilog 文件中今作用类似于 C 语言中的# include 结构。 该指令通常用于将内含全局或公用定义的头文件包含在设计文件:
'include header.v
还有常用的’ifdef 和’timescale
运算符
- 算术操作符:+、-、*、/、(求幂**)
- 逻辑运算符:&&、||、!
- 关系运算符:> 、<、<=、==、!=、 case相等(三个=)、case不等(!+两个=)
- 位运算符:~、&、|、^(异或)、同或(非和异或组合)
- 缩减运算符:与位运算符类似,但是这里当成单元素操作符使用,并且需要注意的是是从最高位依次向最低位进行操作。
- 拼接运算符:两个操作数分别作为高低位进行拼接,如:{2’b10,2’b11}=4’b1011
- 重复操作符:**{n{m}}**表示操作数m重复n次
- 条件操作符:(a>b)?(a=a-1):(b=b-2)
- 移位操作符:>> 逻辑右移(移就完了) >>>:无符号数空位填0,有符号数填充符号位。
模块和端口
模块
在Verilog HDL 的编程中,总是需要将复杂的功能自顶而下进行模块化设计。
如
module add_sub(
input clk,
output signed [7:0] i_a
);
always@(posedge clk)
begin
i_a=1;
endendmodule
模块名:区分大小写,多个模块时模块名称要唯一
端口列表:按上述代码中模块命令格式写就行(过去可以是先定义名称,再定义端口(括号后面,每一个以分号结尾))
端口声明:如上面代码一样是和端口列表放在一起的。
关键字一般默认为unsigned。
module add_sub #(
parameter DATAWIDTH = 8
)
();
上述代码为带有参数的模块声明,这样在例化的的时候可以不用重新定义模块的位宽。
端口
端口是模块与外界环境交互的接口.例如 IC 芯片的输人,输出引脚就是它的端口。对于外部环境来讲,模块内部是不可见的,对模块的调用(实例引用)只能通过其端口进行。这种特点 为设计者提供了很大的灵活性:只要接口保持不变,模块内部的修改并不会影响到外部环境::我们也常常将端口称为终端 ( terminal )。端口类型及其声明:
在 Verilog 中, 所有的端口隐含地声明为wire 类型, 因此如果希望端口具有wire 数据类型.将其声明为三种类型之一即可;如果输出类型的端口需要保存数值,则必须将其显式地声明为reg类型。需要注意输入端口不能声明为reg类型。
端口的连接规则
要注意相应的位宽匹配。有未连接端口时也需要空出相应的端口定义位。
模块的例化
- 端口连接规则:就是按两个连接点连接时的端口定义规则进行
- 位宽匹配:模块的内外部位宽最好匹配
- 未连接端口:允许有未连接
- 端口和外部信号的连接:1.按顺序 2.按名字
(下面代码特指调用的那一行,括号里面的是新的连接名)
add_sub add_sub_01(clk_01 ,ret_m_01 ,....);
按名字
add_sub add_sub_02(.clk (clk_01) ,.ret_m (ret_m_01) ,....);
带参数模块的例化
add_sub #(.DATAWIDTH(16)
) add_sub_03(clk_01 ,ret_m_01 ,....);
层次命名
在前面的章节中 ,我们讲述了如何使用 Verilog 进行层次化设计。每一个模块实例、信号或变量都使用一个标识符进行定义; 在整个设计层次中.每个标识符都具有惟一的位置3 层次命名允许设计者在整个设计中通过惟一的名字表示每个标识符0 层次名由一连串使用 “,”
分隔的标识符组成,每个标识符代表一个层次令这样设计者就可以在设计中的任何地方通过指定完整的层次名 对每个标识符进行访问。
过程语句initial和always
initial只运行一次
always如果没有遇到$finish将不断执行
过程赋值
initial/always @ (posedge 。。。)
过程赋值有两种:阻塞赋值"=“和非阻塞赋值”<="
在顺序代码块中使用阻塞赋值,如果这一语句没有完成后面的语句不会执行,但如果使用非阻塞,相当于"同时进行".
数据流:
对寄存器变量连续赋值:使用assign和force关键字即可.
对线网变量的连续赋值:用assign
assign y=a&b;
时序控制
- 延时时序控制:用一个**#**表示,如:
#5 x=3
表示等待5个系统周期后开始赋值
z=#10 (x+y)
先计算再赋值
- 事件时序控制
关键字为 @,同样的,需要根据@所在的位置来判断执行和延时的顺序。 - 电平敏感时序控制:wait(a),等到a为true,执行后面的语句
顺序和并行
begin...end
fork
...
in
条件语句(未写完)
if…else if…else结构
case结构
case(i_sel)begin2'b00:...2'b01:...2'b02:...2'b03:...end
任务和函数
任务:相当于C中的子过程,不带返回值,任务中的赋值的变量只能是寄存器类型,而且只能用过程赋值语句。可以调用函数和任务。通过task声明。
函数:相当于C中的子函数,带返回值,不能包含时序结构,只有一个逻辑功能,只能调用函数。通过function声明。
如果任务或函数同时在多个地方被调用,则需要使用automatic.
系统任务
带有 $ 符号,可以用来执行一些系统设计所需的输入、输出、时序检查、仿真控制操作。如:
$display 用于显示指定的字符串,然后自动换行(类似c语言printf)
$monitor 用于监视变量,一旦被监视变量发生变化,会显示指定的字符串
$time 提取可以提取当前的仿真时间。
编译指令
`<keyword…>,如:
`define
阻塞与非阻塞
必须在 过程 initial 和 always中进行
Verilog HDL相关推荐
- 关于Verilog HDL的一些技巧、易错、易忘点(不定期更新)
本文记录一些关于Verilog HDL的一些技巧.易错.易忘点等(主要是语法上),一方面是方便自己忘记语法时进行查阅翻看,另一方面是分享给大家,如果有错的话,希望大家能够评论指出. 关键词: ·技巧篇 ...
- (多图) 基于Verilog HDL的FIR数字滤波器设计与仿真
引言:数字滤波器是语音与图像处理.模式识别.雷达信号处理.频谱分析等应用中的一种基本的处理部件,它能满足波器对幅度和相位特性的严格要求,避免模拟滤波器所无法克服的电压漂移.温度漂移和噪声等问题.有限冲 ...
- 移位寄存器专题(verilog HDL设计)
目录 移位寄存器简介 分类 4位右移位寄存器工作原理 1. 16位右移位寄存器 2. 16位左移寄存器 3. 串行输入并行输出寄存器 4. 并行输入串行输出移位寄存器 移位寄存器简介 移位寄存器内的数 ...
- 【Verilog HDL 训练】第 11 天(分频电路)
设计一个占空比50%的三分频电路. 针对这个分频器,博文的末尾会给出一个反面教材,这是我上次写的一个分频器,看起来很好,其实是不能综合的.针对其中的错误,我令立博文记录之:[ Verilog ]alw ...
- 【Verilog HDL 训练】第 06 天(边沿检测)
1. 复习verilog语法 [选做题] - reg和wire的区别 寄存器数据类型 Verilog中规定,凡是在程序块中被赋值的变量,都必须是寄存器类型的.(程序块:例如always块) 这里未免还 ...
- SPI的原理以及Verilog HDL实现
文章链接:SPI https://www.diangon.com/wenku/rd/danpianji/201501/00017903.html SPI是同步串行通信接口. SPI是英语Serial ...
- 【 FPGA 】MATLAB 生成 FIR 滤波器的操作步骤(包括生成Verilog HDL代码以及仿真过程)
使用MATLAB生成滤波器有很多学问,这里只是作为初步的探索,和FPGA的更多结合,也正在探索中,相关博文例如:[ FPGA ]FIR滤波器目录,该专题目录正在记录我学习FIR滤波器的过程. MATL ...
- 【 Verilog HDL 】赋值冲突问题
最近在看<FPGA之道>,对此爱不释手,真是开卷有益!很想收藏一本,可惜买不到了. 进入正题,今天记录这篇笔记,应该是学习使用Verilog HDL描述硬件电路时都会遇到的问题,记录下来, ...
- 【 Verilog HDL 】正确的变量访问思路
以前对这个话题也写了至少两次了,很多人在编写HDL程序时候,也时常遇到这个问题,那就是多驱动问题,今天终于看到了规范的说法了. Modelsim下进行功能仿真没问题,可是在ISE综合报错,如何解决? ...
- 【 Verilog HDL 】避免出现锁存器的组合电路描述方式
无论多么复杂的FPGA设计,如果我们将其中具有存储功能的机构(寄存器.RAM.FIFO等)全部拿掉,那么剩下的若干独立数字电路网络则都是纯组合逻辑电路,对应的,我们称FPGA设计中这些具有存储功能的结 ...
最新文章
- 他开发了基因界的百科全书,贡献却少有人知
- 【机器学习实战 第九章】树回归 CART算法的原理与实现 - python3
- android menu点击事件6,Android Menu
- 思科ssh验证方式_SSH的应用:一个实例两种验证模式的实现
- Oracle Enterprise Manager Cloud Control最新文档合集
- SqlServer中除了sql和bak你还可以使用mdf文件来进行数据库的添加和分离
- Windows7系统技巧:常用的10个快捷键
- JavaScript onerror 事件( window.onerror = )
- AIX系统root用户密码忘记
- 20181207 上课截图
- ngram模型中文语料实验step by step(3)-ngram模型的光滑处理
- 三相桥式全控整流电路simulink仿真_维修电工实训仿真软件-电工入门与提高
- 【Python爬虫系列】Python 爬取上海链家二手房数据
- 前端开发工程师需要具备哪些专业技能?
- 抽奖概率 php_php实现抽奖概率算法代码
- Java学习07–前端基础之CSS
- 苹果电脑可以装windows系统吗_iPhone 可以装 windows 了,想不想试试?
- 2020年8月-北京-百度度小满面试题(已offer)
- 嵌入式薪资真实情况,这届毕业生都拿多少钱?!
- 关于django在database或者后台输入字段为Incorrect string value: ‘\xE4\xBD\xA0\xE4\xBC\x9A问题