5-1 门级建模
VerilogHDL内建基元门:
多输入门:and, nand, or, nor, xor, xnor;
多输出门:buf, not
三态门:bufif0, bufif1, notif0, notif1;
上拉、下拉门:pullup, pulldown;
MOS开关:cmos, nmos, pmos, rcmos, rnmos, rpmmos;
双向开关:tran, tranif0, tranif1, rtran, rtranif0, rtranif1;
示例1:2-4译码器
module dec24(a,b,en,dataout); input a, b, en; output [0:3]dataout; wire abar, bbar; not #(1,2) u0(abar, a); u1(bbar, b); nand #(4,3) s0(dataout[0],en,abar,bbar), s1(dataout[1],en,abar,b), s2(dataout[2],en,a,bbar), s3(dataout[3],en,a,b); endmodule
示例2:主从触发器
module d_flipflop(d, clk, q, qbar); input d, clk; output q, qbar; not n0(not_d, d), n1(not_clk, clk), n3(not_y, y); nand x1(d1,d,clk), x2(d2,clk,not_d), x3(y,d1,ybar), x4(ybar,y,d2), x5(y1,y,not_clk), x6(y2,not_y,not_clk), x7(q,qbar,y1), x8(qbar,y2,q); endmodule
5-2 数据流建模:
(1)连续性赋值语句:可以用来对线网进行赋值,不能用来对寄存器赋值。
如:
module full_adder(a,b,cin,sum,cout); input a,b,cin; output sum,cout; assign sum = a^b^cin; assign cout = (a&cin)|(b&cin)|(a&b); endmodule
(2)赋值延迟:assign #(rise,fall,turn_off); //上升延迟,下降延迟,截止延迟
三种形式:assign #2 svm = bnm; //等同于assign #(2,2,2) svm = bnm; assign #(2,4) svm = bnm; //等同于assign #(2,4,2) svm = bnm;第三项取前两项的最小值 assign #(2,4,6) svm = bnm;
(3)线网延迟:
如:wire #4 jkl;
5-3 行为建模
(1)语句:initial,always
一个模块可以包含多条initial和always语句,每条语句启动一个单独的控制流,而且在0时刻并行执行。
(2)事件控制:跳变沿控制、电平控制
并行块:fork ... join
顺序块中的语句按顺序执行,并行块中所有的语句在0时刻都执行,即并行执行。
(4)阻塞性赋值、非阻塞性赋值
阻塞性赋值:赋值操作符 = ,下一个语句执行之前,赋值语句必须全部执行完毕。
非阻塞性赋值:赋值操作符 <= ,按顺序计算表达式右侧所有的值,在语句块结束时同时赋给左边的变量。
*使用<=时不能出现assign,因为它是驱动变量的,而用 = 是驱动线网的。
(5)条件语句:if, else if, else
(6)case语句:
(8)deassign: 用来结束对assign 的连续性赋值
(10)握手协议:略
一个模块可以包含多条initial和always语句,每条语句启动一个单独的控制流,而且在0时刻并行执行。
(2)事件控制:跳变沿控制、电平控制
@(posedge clk); // 正跳变沿 @(negedge clk); // 负跳变沿 @(posedge clr or negedge reset);//@(posedge clr, negedge reset);
(3)语句块
顺序块:begin ... end并行块:fork ... join
顺序块中的语句按顺序执行,并行块中所有的语句在0时刻都执行,即并行执行。
(4)阻塞性赋值、非阻塞性赋值
阻塞性赋值:赋值操作符 = ,下一个语句执行之前,赋值语句必须全部执行完毕。
非阻塞性赋值:赋值操作符 <= ,按顺序计算表达式右侧所有的值,在语句块结束时同时赋给左边的变量。
*使用<=时不能出现assign,因为它是驱动变量的,而用 = 是驱动线网的。
(5)条件语句:if, else if, else
(6)case语句:
case(case_expr) case_item : procedual_statement ... endcase
(7)循环语句
forever procedual_statement //连续执行不停歇,可加终止语句。 repeat(loop_count) procedual_statement //按循环次数loop_count循环。 while(condition) procedual_statement //按循环条件循环。 for(initial_assignment; condition; step_assignment) procedual_statement // 类似C/C++。
tmp = 2; assign x = tmp; assign x = tmp + 5; deassign x; //x一直保持x=7;
(9)force、release
force过程性语句对线网进行赋值时,该赋值语句将忽略该线网所有的其它驱动源,直到执行release语句。(10)握手协议:略
5-4 结构建模
(1)端口:输入端口input、输出端口output、双向端口inout,默认为线网类型。
(2)模块引用
(3)genertate语句
循环语句:genertate-loop
分支语句:genertate-case
条件语句:genertate-conditional
(2)模块引用
module_name instance_name(port_associations); port_expr //按位置连接 .PortName(port_expr) //按名称连接
例:
module half_adder(a,b,s,c); ... endmodule module full_adder(p,q,cin,sum,cout); wire s1,c1,c2; ... //引用 half_adder u1(x,y,s1,c1);//按位置连接 half_adder u2(.a(fin),.s(sum),.b(s1),.c(c2));//按位置连接
未连接端口则留空 (cc,,ll,...)
端口匹配:位宽不一致时,输入端口从端口表达式往端口赋值,输出端口从端口往表达式进行赋值。(3)genertate语句
循环语句:genertate-loop
分支语句:genertate-case
条件语句:genertate-conditional
genertate //循环语句 //分支语句 //条件语句 endgenertate
(4)配置
库:存储编译配置、UPD和模块的地方,可以是逻辑库,可以是符号库,包含许多已经编译好的源代码。
使用库声明:
使用库声明:
library library_name "file_name"; //把指定名的文件编译进名为library_name的逻辑库中。
eg: library lib_rtl "./xx/cc/source.v"
映像库文件则由许多上述库声明语句组成的列表。
include library_map_file; eg:esoc_lib.map library lib_rtl "./xx/cc/source.v" library lib_glp "./xx/mm/so.vg" library lib_work "./xx/IP/s.v"
配置:确定实例与某个库中的某个单元对应的关系,其基本语法格式如下:
configuration config_name; design rootModuleName; default liblist list_of_libraries; instance instance_name use library.cell; instance instance_name liblist list_of_libraries; cell cell_name use library.cell; cell cell_name liblist list_of_libraries; endconfig
场景例子:
//文件f1.v包含: module m1; m3 u0... endmodule module m2; m3 u1... endmodule //文件f2.v包含: module m3; m3 u2... endmodule module m4; m3 u3... endmodule //库映像文件内容: library lib1 f1.v; library lib2 f2.v; //编译之后,库中的文件如下: Library lib1 contains cells m1,m2 Library lib2 contains cells m3,m4 //m1的配置: configuration m1_config; design lib1.m1; default liblist lib2; instance m1.u0 use lib2; endconfig