verilog HDL -模块代码基本结构
Posted caiya
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了verilog HDL -模块代码基本结构相关的知识,希望对你有一定的参考价值。
1--verilog HDL 语言的预编译指令作用:指示在编译verliog HDL源代码前,需要执行哪些操作。
2--模块内容是嵌在module 和endmodule两个语句之间。每个模块实现特定的功能,模块可进行层次的嵌套,因此可以将大型的数字电路设计分割成大小不一的小模块来实现特定的功能,最
后通过由顶层模块调用子模块来实现整体功能。
3--模块包括接口描述部分和逻辑功能描述部分。这可以把模块与器件相类比。
01 /*=======================================
02 * file neme : mux2.v
03 * author : 小梅哥
04 * Verison : V1.0
05 * date : 2015年07月01日
06 * description:
07 * 当sel为0时,将输入端口in_a上的数据通过out端口输出,
08 * 否则将输入端口in_b上的数据通过out端口输出
09 =======================================*/
10
11 module mux2(in_a,in_b,sel,out);
12
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
19
20 /*--------------------------------------------
21 当sel为0时,选择将in_a端口的数据通过out端口输出,
22 当sel为1时,选择将in_b端口的数据通过out端口输出.
23 --------------------------------------------*/
24 assign out = (sel == 1‘b0)? in_a : in_b;
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;"效果是一样的。
第24行:24 assign out = (sel == 1‘b0)? in_a : in_b;
这一行为赋值语句,这里是Verilog中最基础的一种赋值方式——连续赋值语句。这段代码的意义就是"判断括号中的条件是否成立,若成立,则将in_a的值赋给out,否则,则将in_b的值赋给out",即通过这种方式实现了根据条件选择通道的功能。其中,"?"之后":"之前的信号为括号中条件满足时需要赋给out的的源信号,":"之后的信号则是括号中条件不满足时需要赋给out的源信号。此种赋值方式还支持多重选择,例如下面的代码:
assign out = (sel1 == 1‘b0)? in_a : (sel2 == 1)? in_b : in_c; |
这里有三个数据输入端口"in_a , in_b , in_c",两个选择输入端口"sel1 , sel2"。该句话的意思就是,当第一个括号中的条件满足时,则将in_a的数据赋值给out,否则再判断第二个括号中的条件是否满足,满足则将in_b的值赋给out,不满足则将in_c的值赋给out。括号中的内容可以直接简写为(!sel1)或者(!sel2),这一点与C语言一样。
【内容部分来自https://www.cnblogs.com/xiaomeige/p/4617264.html】
以上是关于verilog HDL -模块代码基本结构的主要内容,如果未能解决你的问题,请参考以下文章