本文目录

  • 前言
  • 一、Verilog入门教程
    • 1.基础语法
    • 2.数值表示
    • 3.数据类型
    • 4.表达式
    • 5.编译指令
    • 6.过程结构
    • 7.过程赋值
    • 8.语句块
    • 9.连续赋值语句
    • 10.延时语句
    • 11.时序控制
    • 12.条件语句
    • 13.多路分支语句
    • 14.循环语句
    • 15.过程连续赋值
    • 16.数值转换
  • 二、Verilog实例分享
    • 1.计算数据位数
    • 2.多次判断
    • 3.循环计数
    • 4.捕捉上升&下降沿
  • 总结

前言

本文记录了Verilog语言的入门基础知识,并通过一些代码实例帮助大家上手,主要基于Xilinx Vivado完成,以下个人学习经验仅供参考。


一、Verilog入门教程

1.基础语法

(1)关键字必须小写,如reginput

(2)标识符区分大小写,开头必须是字母或下划线,如CLK、clk(两者不同)

(3)每行必须以;结束

(4)单行注释用//xxx,跨行注释用/* xxx */

2.数值表示

(1)基本数值种类:0(0 或 假)、1(1 或 真)、x/X(未知)、z/Z(高阻)

(2)整数基数格式:二进制('b 或 'B),八进制('o 或 'O),十进制('d 或 'D),十六进制('h 或 'H)

(3)整数表示方法:4’b1001(指明位宽,4位二进制“1001”)或100(不指明位宽,默认十进制“100”)

(4)负数表示方法:-4’b1001(指明位宽时)或-100(不指明位宽时)

(5)实数表示方法:十进制(0.001)或科学记数法(1.2e4)

(6)字符串表示方法:需要定义相应大小的存储单元,比如字符串"www.csdn.net"需要12*8bit的存储单元,代码如下:

reg [12*8-1:0] str;
assign str = "www.csdn.net";

3.数据类型

(1)线网:wire,表示硬件单元之间的物理连线,由其连接的器件输出端连续驱动

(2)寄存器:reg,表示存储单元,它会保持数据原有的值直到被改写

(3)向量:当位宽大于 1 时线网或寄存器即可表示向量,举例如下:

wire [8-1:0] addr;
reg [8-1:0] addr_temp;
addr_temp[7:6] = addr[1:0] + 1'b1 ;

(4)整数:用integer声明,注意变量为有符号数

(5)实数:用 real 声明,十进制或科学计数法表示

(6)时间:用time声明, 通过调用系统函数 $time 获取当前时间

(7)数组:数组中的每个元素都可视为一个标量或者向量,形如<数组名字>[<位数>],举例如下:

integer flag [7:0] ; //8个整数组成的数组flag
reg [3:0] counter [3:0] ; //4个4位reg型变量组成的数组counter
wire [7:0] addr [3:0] ; //4个8位wire型变量组成的数组addr
flag [1] = 32'd0 ; //将flag中第2个元素赋值为32位的0值
counter [3] = 4'hF ;  //将counter中第4个元素赋值为4位的十六进制数F
assign addr [0] = 8'b0 ; //将addr中第1个元素赋值为0

(8)参数:用parameterlocalparam声明,表示常量

4.表达式

(1)表达式:由操作符和操作数构成,目的是根据操作符的意义得到一个计算结果

(2)操作数:可以是任意数据类型,如常数、整数、实数、线网、寄存器、时间、函数等

(3)操作符:包括算术、关系、等价、逻辑、按位、归约、移位、拼接、条件操作符等,圆括号内表达式优先执行,同类型操作符之间除条件操作符从右往左关联,其余操作符都是自左向右关联

(4)算术操作符:包括单目操作符(“+”、“-”,表示操作数正负,优先级最高)和双目操作符(加“+”、减“-”、乘“*”、除“/”、求幂(两个星号)、取模“%”)

(5)关系操作符:大于“>”、小于“<”、大于等于“> =”、小于等于“< =”,结果为真“1”或假“0”

(6)等价操作符:逻辑相等“= =”、逻辑不等“! =”、全等”= = =“、非全等“! = =”,结果为真“1”或假“0”

(7)逻辑操作符:逻辑与“& &”、逻辑或“| |”、逻辑非“!”

(8)按位操作符:取反“~ ”、与“&”、或“|”、异或“^”、同或“~ ^”

(9)归约操作符:归约与“&”、归约与非“~ &”、归约或“|”、归约或非“~ |”、归约异或“^”、归约同或“~ ^”

(10)移位操作符:左移“<<”、右移“>>”、算术左移“<<<”、算术右移“>>>”

(11)拼接操作符:用大括号 {,} 表示,用于将多个操作数拼接成新的操作数,每个操作数必须指定位宽

(12)条件操作符:判断条件condition是否满足,满足执行true对应语句,不满足执行false对应语句,可嵌套执行多次判断,格式如下:

condition ? true : false

5.编译指令

(1)宏定义编译指令(与C一致)

`define

`undef

(2)条件编译指令(与C一致)

`ifdef

`ifndef

`else

`elsif

`endif

(3)`include:用于将全局或公用头文件包含在设计文件里,使用相对或绝对路径皆可

(4)`timescale:定义时间单位和时间精度,两者都是由数字和单位(s、ms、us、ns、ps、fs)组成,时间精度大小小于等于时间单位大小,举例如下:

`timescale 1ns/100ps     //合法
//`timescale 100ps/1ns   //不合法

(5)`resetall:将所有编译指令重设为缺省值

(6)单元模块定义(cell)

`celldefine

`endcelldefine

举例如下:

`celldefine
module (input      clk,input      rst,output   A,output   B );
endmodule
`endcelldefine

6.过程结构

(1)initial语句:
initial语句从0时刻开始执行,单次执行,多个语句之间并行执行,单个语句内顺序执行;
块内包含多个语句时需要使用关键字beginend,只有一条语句时可不用

(2)always语句:
always语句从0时刻开始执行,重复执行,多个语句之间并行执行,单个语句内顺序执行;
块内包含多个语句时需要使用关键字beginend,只有一条语句时可不用

7.过程赋值

(1)阻塞赋值“=”:语句顺序执行,即下一条语句执行前当前语句一定会执行完毕

(2)非阻塞赋值“<=”:语句并行执行,即其他语句的执行和当前语句的执行同时进行

8.语句块

(1)顺序块:块中语句顺序执行,但非阻塞赋值仍按并行执行,用begin & end表示

(2)并行块:块中语句并行执行,包括阻塞赋值,用fork & join表示

(3)嵌套块:顺序块+并行块

(4)命名块:给块语句结构命名,块中可以声明局部变量,通过层次名引用的方法对变量进行访问,格式如下:

module test;initial begin: A //块命名为A,disable后禁用命名块integer B; //变量B可通过text.A.B被其他模块调用end
endmodule

9.连续赋值语句

连续赋值语句“assign”用于对wire型变量进行赋值,格式如下:

wire      z, x, y;
assign  z = x & y;  //只要x、y改变z就会相应改变,注意z必须是wire型变量,x、y可以是wire型或reg型变量

10.延时语句

(连续赋值)延时语句“assign #time”用于控制任意操作数发生变化到语句左端赋予新值之间的延时时间,格式如下:

wire z, x, y;
assign #10 z = x & y; //延时10个时间单位后赋值,若信号脉冲宽度小于延时则对输出无影响,称为惯性延时

11.时序控制

(1)延时控制:包括常规延时控制与内嵌延时控制

常规延时格式为:(先延时再赋值,无惯性延时问题)

#10;
y = x; //或直接合并为#10 y = x;

内嵌延时格式为:(先赋值再延时,有惯性延时问题)

y = #10 x;

(2)事件控制:包括边沿触发事件控制与电平敏感事件控制

边沿触发事件格式为:

always @(posedge clk or negedge rst_n) //用@表示边沿触发条件,只有当信号发生特定变化时才能继续执行语句AbeginA;end

posedge指信号边沿正向跳变时触发,negedge指信号边沿负向跳变时触发,未指明时正负边沿跳变都会触发;
用关键字or连接多个变量,当变量很多时可简写为@(*),表示对所有输入变量的边沿跳变都会触发;
命名事件控制是一种特殊的事件控制,用关键字event声明并触发该变量来识别该事件是否发生,格式如下:

event A;
always @(posedge clk) begin //clk上升沿作为A触发-> A; //->表示触发end
always @(A) begin //A触发时执行BB;end

电平敏感事件格式为:

wait (x); //x为电平敏感条件,只有当电平敏感条件为真时才能继续执行语句AbeginA;end

12.条件语句

条件语句“if”用于根据条件判断是否执行相应语句,格式如下:

if (x) A; //如果满足条件x则执行A语句(若语句不只一行则应用“ begin A end; ”格式)
else if (y) B; //如果满足条件y则执行B语句(else if可有多级或者没有)
else C; //否则执行C语句

13.多路分支语句

多路分支语句"case"用于解决if语句中条件选项过多时使用不方便的问题,格式如下:

case (variable)x : A; //variable = x时执行A语句(若语句不只一行则应用“ begin A end; ”格式)y : B; //variable = y时执行B语句(除x、y还可以有多级case)default : Z; //default语句可没有

14.循环语句

(1)while循环语句(所有循环语句只能在“always”或“initial”块中使用)

while  (x) beginA; //满足x条件时执行A语句,A只有一行时begin & end可省略end

(2)for循环语句

for (x; y; z) //x为初始条件,y为终止条件,z为控制变量的过程赋值语句,注意增加或减少变量计数不能写成 i++或i--beginA;end

(3)repeat循环语句

repeat (n) //执行固定次数n个循环beginA;end

(4)forever循环语句

forever //相当于while(1),表示永久循环,通过系统函数$finish退出beginA;end

15.过程连续赋值

(1)assign(过程赋值) & deassign(取消过程赋值):
赋值对象只能是reg型变量而不能是wire型变量,赋值过程中对寄存器连续赋值,寄存器中的值被保留直到被重新赋值

(2)force(强制赋值) & release(取消强制赋值):
赋值对象可以是reg型或wire型变量;
force作用在寄存器上时,寄存器当前值被覆盖,release时该寄存器值将继续保留强制赋值时的值;
force作用在线网上时,线网当前值被覆盖,但release时该线网值马上变为原有的驱动值

16.数值转换

(1)十进制有符号数转二进制补码:
正数的补码为原码;
负数的补码有两种计算方式:
a、将有符号数最高位符号位改写为1,剩余数值部分取反加1
比如4位数字-7的数值部分为4’b0111,高位改写后为4’b1111,剩余数值部分取反加1后为4’b1001
b、将有符号数直接与其代表的最大数值范围相加
比如4位数字-7与16(2的4次幂)的和为9, 即对应4’b1001

(2)二进制补码转十进制有符号数:
补码最高位为0时其数值大小即为表示的十进制正数;
补码最高位为1时有两种计算方式:
a、将补码取反加1,并增加符号位
比如4位数字-7的补码为4’b1001,取反加1后为4’b0111,增加符号位后为-7
b、将补码对应的无符号数与其代表的最大数值范围相减
比如4位数字-7的补码为4’b1001,无符号数为9,9-16=-7

(3)求二进制补码的绝对值:
将补码取反加1,比如4位数字-7的补码为4’b1001,取反加1后为4’b0111,即7

(4)符号位扩展:
将代表符号位的最高位填充至扩展的高位数据位中,比如4’b1011(-7)扩展到8位为8’b11111010(-7)

二、Verilog实例分享

1.计算数据位数

代码如下:

function integer log2(input integer n);integer i;     for( i=0; 2**i<=n; i=i+1) log2 = i + 1;
endfunction

假设n=15(0000 1111),那么log2=4,也就是4位;
假设n=16(0001 0000),那么log2=5,也就是5位。

2.多次判断

代码如下:

reg x;
x <= ((x == 4'd0)    ?   A   :   ((x == 4'd1) ?   B   :   ((x == 4'd2) ?   C   :   D)));

变量x为4’d0执行A语句,为4’d1执行B语句,为4’d2执行C语句,否则执行D语句。

3.循环计数

代码如下:

(*mark_debug = "true"*)reg    [5:0] CNT;
always @ (posedge CLK or negedge RST)
beginif(!RST)CNT    <=  1'b0;elseCNT   <=  (CNT==最大计数-1) ? 1'd0 : CNT + 1'd1;
end

“最大计数”位置应给定一个值,CNT将在0~最大计数区间内循环+1。注意第一句(mark_debug = “true”)表示监视该变量。

4.捕捉上升&下降沿

代码如下:

reg triger, triger_dly1, triger_dly2;
always @ (posedge CLK or negedge RST)
beginif(!RST)begintriger_dly1 <= 1'b0;triger_dly2 <= 1'b0;endelsebegintriger_dly1 <= triger;triger_dly2 <= triger_dly1;end
end
wire posedge_triger = triger_dly1 && (~triger_dly2);
wire negedge_triger = (~triger_dly1) && triger_dly2;

对triger延时1拍和2拍产生triger_dly1和triger_dly2变量,triger_dly1为上升沿时通过posedge_triger捕捉,triger_dly2为下降沿时通过negedge_triger捕捉。


总结

如果文章中有错误或疏漏之处烦请指正,希望大家多交流共同进步!

Verilog入门教程与实例分享相关推荐

  1. eBPF Tracing 入门教程与实例

    2019独角兽企业重金招聘Python工程师标准>>> 原文链接 Learn eBPF Tracing: Tutorial and Examples 译者 弃余 在 LPC'18(L ...

  2. 【收藏向】谷歌技术团队出品,Android开发入门教程,开源分享

    程序员圈子中,python.java等都是热门领域,网络上相关学习资源也比较多,相较之下Android的学习资料就比较少了,并且大多是碎片化的知识,不够系统和全面. 今天就来整理一下Android开发 ...

  3. Quartus ii 与 Verilog入门教程(1)——Verilog实现8位计数器

    下载:Quartus ii与verilog实现8位计数器,Modelsim仿真工程 1.计数器原理 在时钟作用下,输出信号从0开始,每个时钟的上升沿输出加1.当复位信号有效时,输出清零.计时实现只需累 ...

  4. 【Flash新手入门教程】实例讲解引导层的应用

    引导层是什么呢? 引导层就等于一个引路者,指引相关物体按着我们的想法来行动. 引导层在导出的SWF文件中是不可见的,所以不会画面的美观造成影响. 引导层一般是和补间一块用的,两者相辅相成. 引导层怎么 ...

  5. Scikit-learn快速入门教程和实例(一)

    一,什么是SKlearn SciKit learn的简称是SKlearn,是一个python库,专门用于机器学习的模块. 以下是它的官方网站,文档等资源都可以在里面找到http://scikit-le ...

  6. 微搭低代码入门教程-问卷调查实例

    目录 01 总体介绍 02 应用介绍 03 页面介绍 04 hello,world 05 变量定义 06 数据绑定 07 低代码编辑器介绍 08 数据源介绍 我们用了8篇篇幅介绍了低代码的基础知识,有 ...

  7. 微信小程序入门教程及实例

    原文地址:https://mp.weixin.qq.com/s?__biz=MzAwNjI5MTYyMw==&mid=2651493295&idx=1&sn=4dc4c5701 ...

  8. 素描初学者入门教程素描高手分享经…

    素描是什么东西就不说了,说了也没有用-- 画人物,我觉得必须从几何开始,可以跳过静物,石膏同理,因为可以把人脸分解和统一成基本的几何物体,好像结婚一样,可以先斩后奏的--我想新手们点字把它读完后,多多 ...

  9. 学习嵌入式的书籍推荐,嵌入式编程入门教程学习大纲

    嵌入式系统是当前热门.具发展前景的IT应用领域之一,很多数字包括手机.电子字典.可视电话.数字相机.数字摄像机.机顶盒.智能玩具医疗仪器和航空航天设备等都是典型的嵌入式系统.越来越多的人想要了解学习嵌 ...

  10. JsRender实用入门教程

    这篇文章主要介绍了JsRender实用入门实例,包含了tag else使用.循环嵌套访问父级数据等知识点,并提供了完整的实例下载,非常具有实用价值,需要的朋友可以参考下 本文是一篇JsRender的实 ...

最新文章

  1. (C++)用upper_bound函数取代自己写的二分查找
  2. php base64处理
  3. TableView的集合
  4. [html] 你是如何理解html与css分离的?
  5. [html] 怎样在页面上实现一个圆形的可点击区域?
  6. django-后台管理-编辑页的选项
  7. 创建,删除和移动文件夹以及文件夹列表
  8. Iperf性能测试的问题小结
  9. python井字棋_用python井字棋
  10. Python软件封装打包
  11. towe/ jira / tapd / 禅道 协作平台对比
  12. 米思齐(Mixly)图形化系列教程(四)-运算符
  13. Python 微信自动化工具开发系列06_根据用户信息自动回复升级版本(2022年10月可用)
  14. Android 设置桌面背景
  15. jq小插件tiptip
  16. linux crond定时任务,Linux之定时任务Crond使用
  17. oracle 登录失败次数,Oracle用户连续登录失败次数限制如何取消
  18. 深度之眼Paper带读笔记GNN.09.GGNN
  19. C4D的GPU渲染器Octane和Redshift的渲染对比
  20. ES设置自定义分词器

热门文章

  1. poj 2195 二分图带权匹配+最小费用最大流
  2. 基于jQuery的AJAX和JSON的实例
  3. SilverLight自定义集合控件中的集合项数据绑定问题
  4. C++对ascii文件按行和分隔符读取并显示
  5. 图像旋转之以原点为中心
  6. 解决RHEL6 vncserver 启动 could not open default font 'fixed'错误.
  7. LibXML2不支持中文补遗
  8. jdbc mysql 存储过程执行失败_JDBC连接执行MySQL存储过程报权限错误
  9. 十款常见的开源数据库学习资料大汇总
  10. 基于springboot人事管理系统设计与实现