目录
前言
结构化建模是Verilog HDL极其重要的建模方式。它就是将硬件电路描述成一个分级子模块系统,通过逐层调用模块构成复杂的数字电路逻辑电路和系统的一种描述方式。根据调用子模块的不同抽象级别将模块结构描述方式分成以下三类:
(1)模块级建模:模块是由(用户自己设计的)低级模块的实例组成的;
(2)门级建模:模块将由基本门级元件的实例组成;
(3)开关级建模:模块将由基本开关级元件的实例组成。区别于VHDL的一个主要特点。
模块级建模
模块级建模分为两个部分:模块设计与模块调用。模块级建模就是通过调用由用户自己描述产生的module模块对于硬件电路结构进行说明,并设计出电路。模块中被调用模块属于低一层次的模块,如果当前模块不被其他模块所调用,那么这个模块就是顶级模块。在对一个硬件系统的描述中,必定有而且只能有一个顶层模块。
模块调用方式
模块名<参数值列表>实例名(端口名列表)
模块名:被调用模块的名称;
参数值列表:模块间参数的传递;
实例名:被调用模块在当前模块中的名称,当电路层次丰富时,实例名为其提供一个索引;
端口列表名:所有输入输出信号。
//一个简单的与门模块调用例子 module and1(a,b,c); input a,b; output c; assign c=a&b; endmodule; module logic(in1,in2,q);//顶层模块 input in1,in2; output 1; and1 U1(in1,in2,q);//模块调用 endmodule;
如果一个模块在当前模块被调用几次,有两种方法:
方法一:基本调用方式
语法格式为:
模块名 <参数值列表>实例名1(端口名列表),
<参数值列表>实例名2(端口名列表),
........
<参数值列表>实例名n(端口名列表);
方法二:阵列调用方式
(定义的是标量但需要矢量调用)
语法格式为:
模块名 实例阵列名[阵列左边界:阵列有边界](端口连接表);
//与门模块调用例子 module and2(c,a,b); input a,b; output c; assign c=a&b; endmodule; module prog1(out,a1,b1);//顶层模块 input[15:0]a1,b1; output[15:0]out; wire[15:0]out; and2 u2[15:0](out,a1,b1);//可用 assign out=a1&b1;实现 endmodule;
模块端口对应方式
(一)端口位置对应方式
端口位置对应方式的缺点在于有部分信号不存在的情况下,无法一一对应。基本语法格式如下:
模块名 参数值列表 实例名 (信号名1,信号名2,....,信号名n);
(二)端口名对应方式
端口名对应方式的优势在于顺序可变,若有一种信号为空,不写即可。基本语法格式如下:
模块名 参数值列表 实例名(.端口名1(信号名1),.端口名2(信号名2),.....,.端口名n(信号名n))
(三)不同端口为位宽匹配
右对齐缺位补零,右对齐舍弃多余位。
模块参数值
模块参数值的设定提高了电路设计的效率,以下是两种改变模块实例的参数值方法:
使用带有参数的模块实例语句修改参数值
在本方法中,模块实例的本身就能指定新的参数值,参数值列表分为位置对应和名称对应,其语法格式是:
模块名 参数值列表 实例名 (端口名列表);
module para1(c,d); parameter a=1; parameter b=1; ... endmodule; module para2;//顶层模块 para1 #(4,3) U1(c1,d1);//位置对应 para1 #(.b(3),.a(5)) U2(c2,d2);//名称对应 ... endmodule;
使用定义参数语句(defparam语句)修改参数值
语法格式:
defparam 参数名1=参数值1,
参数名2=参数值2;
需要注意的是,参数名必须采用分级路径的形式,才能锁定需要修改的参数是在哪个模块中。
门级建模
门级建模更多的会使用数据流建模代替门级建模。
基本门级元件
门级模块的调用
多输入元件调用
语法格式:
门类型 实例名(输出端口,输入端口,输入端口,......);
//例子 and u1(out1,a1,b1);//out1=a1andb1 or u2(out2,a2,b2,b3);//out2=b2orb3ora2
多输出元件调用
语法格式:
门类型 实例名(输出端口,输出端口,...,输入端口);
三态门元件调用
语法格式:
元件名 实例名(数据输出端口,数据输入端口,控制输入端口);
bufif1 bf1(data_bus,mem_data,enable); bufif0 bf2(out,in,ctrl);
调用门级元件的2-4译码器
module
u1111(in0,in1,en,out0,out1,out2,out3);
output out0,out1,out2,out3;
input in0,in1,en;
wire1,wrie2,wrie3;
not u1(wrie1,in0);
u2(wrie2,in1);
nand u3(out0,en,wrie1,wrie2);
u4(out1,en,wrie1,in1);
u5(out2,en,in0,wrie2);
u6(out3,en,in0,in1);
endmodule;
开关级建模
开关级建模是比门级建模更为低级抽象层次上的设计,是区别于VHDL的基本特点。Verilog语言提供了十几种开关级单元,它们是实际的MOS管的抽象表示。这些开关级单元分为两大类:MOS开关,双向开关。每一大类可以分为电阻型和非电阻型。本节主要以非电阻型开关为例,介绍MOS开关和双向开关。
MOS开关
MOS开关模拟了实际的MOS器件的功能,包括nmos、pmos、cmos三种。
nmos和pmos
语言格式:
nmos/pmos 实例名 (out,data,control);
cmos
语言格式:
cmos 实例名 (out,data,ncontrol,pcontrol);
双向开关
NMOS、PMOS、CMOS 开关门都是从漏极向源极导通,方向是单向的。Verilog 中还提供了双向导通的开关器件,数据可以双向流动,两边的信号都可以是驱动信号。
双向开关及其阻抗模式的关键字声明如下:
tran tranif1 tranif0 rtran rtranif1 rtranif0注:
tran 开关为两个信号直接的缓存,inout1 或 inout2 均可以是驱动信号。
tranif1 仅当 control 信号为 1 时,开关两边的信号导通。当 control 为 0 时,两个信号断开,有驱动源的信号会和驱动源保持一致的信号值,没有驱动源的信号则呈现为高阻状态。
tranif0 同理。
因此,双向开关常用来进行总线或信号之间的隔离。
例化时,双向开关前
两个端口为数据端,第三个端口为 control 控制输入端。
tranif0 tr0 (inout1, inout2, control) ; //no instantiation name tranif1 (inout1, inout2, control) ;