需求分析 -> 功能划分 -> 文本描述 -> 功能仿真(前仿真) -> 逻辑综合(综合,就是在标准单元库和特定的设计约束的基础上,将设计的高层次描述(Verilog 建模)转换为门级网表的过程) -> 布局布线 -> 时序仿真(后仿真)(布局布线后,电路模型中已经包含了时延信息。利用在布局布线中获得的精确参数,用仿真软件验证电路的时序。单元器件的不同、布局布线方案都会给电路的时序造成影响。) -> FPGA/CPLD 下载后调试或 ASIC 制造工艺生产
顾名思义,Verilog门级描述注重的是门的使用,关键的语法在于门的实例化引用。
module logic_gate(iA, iB, iC, oY);
input iA, iB, iC;
output oY;
wire n_1, n_2, n_3;
and and1(.A(iA), .B(iB), .Y(n_1));
and and2(.A(iB), .B(iC), .Y(n_2));
not not1(.A(n_1), .Y(n_3));
or or1(.A(n_2), .B(n_3), .Y(oY));
endmodule
以上Verilog代码描述的电路关系如下图所示,其中,port、pin、cell、net的概念在图中也有说明。
模块定义以关键字module
开始,以关键字endmodule
结束,在这两个关键字之间的代码被识别为一个模块,描述一个具有某种基本功能的电路模型。
module 模块名(端口1,端口2,端口3,……); // 端口列表,不用体现端口所具有的位宽
………… // 模块部分
endmodule
类型:输入端口、输出端口和双向端口,关键字分别是input
、output
和 inout
。
结构:
端口类型 [端口宽度] 端口名; // 默认1位宽度
规则:端口默认为wire
(线网)类型,input和inout必须为wire类型,output可能为reg
(寄存器)类型
wire和reg区别:wire的电路形式是连线,能够传递数值,不能保存数值;reg的电路形式是寄存器,可以保存数值
input [31:0] iA; // 声明一个32位input接口,分别为iA[31],iA[30],iA[29]……iA[0];
output [31:0] oB; // 声明一个32位output接口,分别位oB[31],oB[30],oB[29]……oB[0];
内部连线声明语法格式为:
wire [线宽] 线名称;; // 默认1位宽度
在Verilog代码的编译过程中,凡是在模块实例化中没有定义过的端口连接信号均被默认为1位的wire类型。
门级调用语法格式为:逻辑门类型 <实例名称,可选>(端口连接);
,当示例名称未定义时,Verilog的内建语法会在编译过程中自动给这个逻辑门命名,使得每个逻辑门都有自己独有的实例名称。
逻辑门总共有以下几种基本类型,且自己定义的模块也可以作为逻辑门来调用。
单输入逻辑门:buf
缓冲门、not(或inv)
非门,真值表如下。
多输入逻辑门:and
与门、nand
与非门、or
或门、nor
或非门、xor
异或门、xnor
同或门,电路图及真值表如下。
三态门:bufif0
、bufif1
、notif0
、notif1
,在原有的buf和not门上增加控制信号,控制信号生效时,输出有效数据,控制信号不生效时,输出数据变为高阻态。电路图和真值表如下。
eg:
not n1(in, out);
not (in, out); // 未定义实例名称
nand n[2:0](A, B, Y);
/* 门数组,等同于:
nand n2(A2, B2, Y2);
nand n1(A1, B1, Y1);
nand n0(A0, B0, Y0);
*/
Verilog的语法将模块内调用其他模块来完成设计的过程统称为模块的实例化,它可以类比为C语言中的函数的调用。
(1) 顺序连接(小工程)
顺序连接要求连接到实例的信号必须与模块声明时目标端口在端口列表中的位置保持一致。
module Test;
reg a, b, c;
wire y;
logic_gate mylogic_gate(a, b, c, y);
endmodule
(2) 名称连接(一般使用这个)
当模块的端口比较多的时候,端口的先后次序就容易混淆,按顺序连接方式就容易发生错误,此时就可以使用按名称连接的方式。
module Test;
reg a, b, c;
wire y;
logic_gate mylogic_gate(.iA(a), .iB(b), .iC(c), .oY(y));
endmodule
Verilog门级描述