Verilog HDL基础语法讲解之模块代码基本结构
Verilog HDL基础语法讲解之模块代码基本结构
本章主要讲解Verilog基础语法的内容,文章以一个最简单的例子"二选一多路器"来引入一个最简单的Verilog设计文件的基本结构。
以下为本章中例子中的代码:
01 /*======================================= 02 * file neme : mux2.v 03 * author : 小梅哥 04 * Verison : V1.0 月01日 06 * description: 时,将输入端口in_a上的数据通过out端口输出, 08 * 否则将输入端口in_b上的数据通过out端口输出 09 =======================================*/ 10 11 module mux2(in_a,in_b,sel,out); 12 13 input 14 input 15 16 input 17 18 output 19 20 /*-------------------------------------------- 时,选择将in_a端口的数据通过out端口输出, 时,选择将in_b端口的数据通过out端口输出. 23 --------------------------------------------*/ 24 assign out = 25 26 endmodule |
(注:最左侧一列行号是作者为了讲解方便加上的,不属于代码内容,请知悉)
以上代码描述的电路如下图所示:
图:二选一多路器电路模型
第1到9行:
该部分为文件头,记录了本设计文件中的一些基本信息如设计者、版本号、修改历史以及代码实现的功能描述。在编译时,该部分属于注释内容,将不被综合成任何内容。
第11行:module mux2(in_a,in_b,sel,out);
该行第一个字符串"module"为Verilog中的一个保留字(关键词),该保留字的出现表明了一个模块内容的开始。相对应的,第26行的"endmodule"也是一个保留字,该保留字的出现表明了一个模块内容的结束。在Verilog语法中,module和encmodule总是成对出现,module和encmodule之间的内容则是用户代码。
module之后是一个空格(或制表符"tab"),空格或制表符数量不一定限定为1个,也可以是多个,对结果没有任何影响。紧跟空格之后的mux2则是模块名称,该名称由用户自己定义,但一般要求与设计内容有一定关系,通过该名称能够体现出模块的功能或作用,例如这里使用mux2表明这是一个二选一多路器,让人一目了然。换个例子,如果要做PWM波生成模块,则可以直接以PWM作为模块名(module PWM(……);)这样简洁直观,一看就能理解模块的功能。
mux2之后使用圆括号括起来的部分则是端口列表,该列表中列出了该模块所有需要外部输入或者需要输出到外部的信号,信号间以英文中的逗号","隔开。端口名的命名也尽量能够代表该端口信号的实际功能或意义,例如"in_a",很清晰的就能告诉读者这是数据输入通道的a端口。
第13行到18行:
13 input
[1:0] in_a; //输入端口in_a
14 input
[1:0] in_b; //输入端口in_b
15
16 input
[0:0] sel; //通路选择线
17
18 output
[1:0] out; //输出端口out
这里蓝色保留字"input"和"output"是端口类型,input表示该端口是本模块的输入型端口,output表示该端口是本模块的输出型端口。另外,在实际项目中,还有一种很常见的端口类型是双向端口,Verilog中用关键字"inout"来表示。在本例中,由于没有使用到双向端口,因此不做介绍,该部分内容将在后面以一个单独的章节来进行讲解。
第13行紧跟着"input"之后用方括号括起来的部分[1:0]表示端口的宽度,这里表示输入端口in_a的位宽为2。需要注意的是,定义位宽时虽然写成[1:0]和[0:1]表示的位宽是一致的,但是Verilog中习惯使用[MSB:LSB]的形式,请大家在自己写代码时也统一遵照这一要求。当位宽为1时,位宽定义部分可以省略,例如第16行的[0:0]是可以省略的,即写成"input sel;",与"input
[0:0] sel;"效果是一样的。
第20行到23行:
该部分为注释内容,注释主要是为了方便阅读和理解代码,在综合电路时会被忽略。Verilog语法中,注释的格式与C语言中一致,也支持单行注释和块注释。单行注释以"//"开始,有效作用域只在以此符号开始的本行紧随其后的内容,换行后就不起作用了。例如第13行的"//输入端口in_a"就是注释内容,换行后第14行就不再是被注释掉的内容了。第20行到第23行为块注释,块注释以"/* */"组织,两个"*"之间的内容即为注释内容,此种注释方式支持换行,注释内容以"/*"开始,换行后注释属性依然有效,直到出现"*/",则注释部分结束。不过需要注意的是,块注释不支持嵌套,当强行使用这种方式时会导致编译错误。例如以下这种格式就是错误的:
/*
一级块注释内容
/*
二级块注释内容
*/
……
*/
第24行:24 assign out =
(sel ==
1'b0)? in_a : in_b;
这一行为赋值语句,这里是Verilog中最基础的一种赋值方式——连续赋值语句。这段代码的意义就是"判断括号中的条件是否成立,若成立,则将in_a的值赋给out,否则,则将in_b的值赋给out",即通过这种方式实现了根据条件选择通道的功能。其中,"?"之后":"之前的信号为括号中条件满足时需要赋给out的的源信号,":"之后的信号则是括号中条件不满足时需要赋给out的源信号。此种赋值方式还支持多重选择,例如下面的代码:
assign out = |
这里有三个数据输入端口"in_a , in_b , in_c",两个选择输入端口"sel1 , sel2"。该句话的意思就是,当第一个括号中的条件满足时,则将in_a的数据赋值给out,否则再判断第二个括号中的条件是否满足,满足则将in_b的值赋给out,不满足则将in_c的值赋给out。括号中的内容可以直接简写为(!sel1)或者(!sel2),这一点与C语言一样。
通过这一章,我们学习了采用Verilog HDL设计简单的模块的基本代码结构,包括声明模块的"module endmodule"、端口的定义、端口类型以及位宽的声明、注释内容的格式以及连续赋值语句的写法,而且通过此例子完成了一个简单的二选一多路器的设计。希望对于Verilog HDL语法零基础的读者在看罢此文后能够关闭此文档,在Quartus II或Modelsim、ISE等工具中实际动手敲一遍。可结合前面介绍Altera 公司FPGA器件开发流程一章中的步骤,实际建立工程并输入代码,然后分析和综合,通过综合工具,查看自己编写的代码是否有错误,如有错误,则根据软件提示加以改正。
下一章,将以此模块的测试文件(testbench)为例,介绍Testbench的基本语法。
小梅哥FPGA设计思想与验证方法教程系列文档
2015年07月02号于Snow Dream电子工作室
Verilog HDL基础语法讲解之模块代码基本结构的更多相关文章
- verilog HDL -模块代码基本结构
1--verilog HDL 语言的预编译指令作用:指示在编译verliog HDL源代码前,需要执行哪些操作. 2--模块内容是嵌在module 和endmodule两个语句之间.每个模块实现特定的 ...
- Lua基础语法讲解
Lua 是什么? Lua 是一种轻量小巧的脚本语言,用标准C语言编写并以源代码形式开放, 其设计目的是为了嵌入应用程序中,从而为应用程序提供灵活的扩展和定制功能. Lua 是巴西里约热内卢天主教大学( ...
- Python基础语法05--函数模块
Python 函数 函数是组织好的,可重复使用的,用来实现单一,或相关联功能的代码段. 函数能提高应用的模块性,和代码的重复利用率.你已经知道Python提供了许多内建函数,比如print().但你也 ...
- 【python基础语法】OS模块处理文件绝对路径,内置的异常类型、捕获、处理(第9天课堂笔记)
import os """ 通过文件的路径去打开文件 相对路径:相对当前的工作路径去定位文件位置 .:代表当前路径 ..:代表上一级路径(父级路径) 绝对路径:相对于电脑 ...
- python2学习------基础语法4(模块)
1.整体结构层次(a.py,b.py) 目标:b.py文件中导入a.py里面定义的class A,并调用A类里面的属性或相关方法. 2.模块导入 <1> __init__.py < ...
- Python基础系列讲解——random模块随机数的生成
随机数参与的应用场景大家一定不会陌生,比如密码加盐时会在原密码上关联一串随机数,蒙特卡洛算法会通过随机数采样等等.Python内置的random模块提供了生成随机数的方法,使用这些方法时需要导入ran ...
- Python基础系列讲解——时间模块详解大全之time模块
Python中提供处理时间日期相关的内置模块有time.datetime和calendar. time模块中大多数函数调用了所在平台C library 的同名函数,因此更依赖于操作系统层面,所以tim ...
- Swift基础语法(五)枚举、结构体与类的区别
swift中的结构体值可以是整型.浮点型.字符串.字符.元祖,如果不赋值默认为整型且从0开始计数,如果为整型枚举且要求不是从0开始只需指定枚举的第一个值以后的值自动依次加1 引用方式也与oc有所出入 ...
- Verilog HDL的程序结构及其描述
这篇博文是写给要入门Verilog HDL及其初学者的,也算是我对Verilog HDL学习的一个总结,主要是Verilog HDL的程序结构及其描述,如果有错,欢迎评论指出. 一.Verilog ...
随机推荐
- php Memcache
<?php $mem = new Memcache();//实例化一个对象 $mem->connect("localhost",11211);//连接memcache服 ...
- QT中静态库的生成与使用
一. 静态库的生成 1. 测试目录: lib 2. 源码文件名: mywindow.h, mywindow.cpp, 类MyWindow继承于QPushButton, 并将文字设置为&qu ...
- 一台电脑多个文件夹安装多个Redis服务
思路: 在弄Mongodb的时候,可以在不同的文件夹下面运行不同的mongodb实例 那么Redis可以吗 现在添加一个Redis文件夹,里面放置redis,修改配置端口为6378 将以前的那个Red ...
- 第三篇 Integration Services:增量加载-Adding Rows
本篇文章是Integration Services系列的第三篇,详细内容请参考原文. 增量加载是什么增量加载仅加载与先前加载差异的.差异包括:->新增的行->更新的行->删除的行通过 ...
- 分享书籍[writing idiomatic python ebook]
你是不是总是觉得学了python好久,蓦然回首,总是感觉写的代码不是那么有pythonic的味道.看看别人的代码(django,webpy),再看看自己的代码,觉得就是一java-python的混合体 ...
- 学习OpenCV——ORB简化版&Location加速版
根据前面surf简化版的结构,重新把ORB检测的代码给简化以下,发现虽然速度一样,确实能省好多行代码,关键是有 BruteForceMatcher<HammingLUT>matcher的帮 ...
- using gulp
原 荐 gulp构建前端工程 半张一块 发布时间: 2016/07/27 16:22 阅读: 895 收藏: 4 点赞: 4 评论: 2 摘要 Gulp 是一个自动化工具,前端开发者可以使用它来处理常 ...
- Subversion how[Reprint]
1. Subversion简介 Subversion(简称SVN)是一款功能强大的开源版本控制工具,支持Linux和Windows平台. SVN可以有两个访问方式,一种是独立服务器直接访问,即利用 ...
- 使用git做服务器端代码的部署
传统部署方案 windows 远程桌面 FTP/SFTP 登录服务器pull github代码 Phing(PHP专业部署工具) git 自动部署流程图 服务器端准 ...
- URAL 1018 Binary Apple Tree(树DP)
Let's imagine how apple tree looks in binary computer world. You're right, it looks just like a bina ...