verilog学习——gate/switch modeling 门/开关建模
(一)gate level modeling /门级建模
门级建模涉及门,并且硬件原理图和verilog代码之间具有一对一的关系;
Verilog支持一些被称为原语的基本逻辑门,可以像模块一样实例化,因为它们已经预定义了。
1.and/or/xor门
这些原语的参数列表中的第一个终端是输出,每当任何输入更改时,它就会更新。
2.nand/nor/xnor门
这些门可以有两个或两个以上的输入。
3.buf/not门
这些门只有一个标量输入和一个或多个输出。端口列表总最后一个端口是input;
buf 代表缓冲器,只需将值从输入传输到输出,而不会改变极性。
not 代表逆变器,在其输入端反转信号的极性。因此,输入端的 0 将产生 1,反之亦然。
4.bufif/notif
缓冲器和逆变器具有额外的控制信号,以使能输出,可通过 bufif 和 notif 基元使用
只有当控制信号使能时,这些门才具有有效的输出,否则输出将处于高阻抗状态。
(二)Verilog gate delay/Verilog的门延迟
数字元件是二进制实体,只能包含两个值中的任何一个:0或1;从0-1或从1-0的转换过程有一个延迟。门元件中将值从输入传到输出也有延迟。
1.上升、下降和关闭延迟
有三种方法表示门级延迟:
// Single delay specified - used for all three types of transition delays
or #(<delay>) o1 (out, a, b);
// Two delays specified - used for Rise and Fall transitions
or #(<rise>, <fall>) o1 (out, a, b);
// Three delays specified - used for Rise, Fall and Turn-off transitions
or #(<rise>, <fall>, <turn_off>) o1 (out, a, b);
2.延迟规范格式
3.min/typ/max delays 最小/典型/最大延迟
每个数字门和晶体管单元都具有基于工艺节点指定的最小、典型和最大延迟,通常由制造代工厂的库提供。
对于每种类型的延迟(上升、下降和关断),可以指定三个值 min、typ 和 max,分别代表最小、典型和最大延迟。
module des ( input a, b,
output out1, out2);
and #(2:3:4, 3:4:5) o1 (out1, a, b);
bufif0 #(5:6:7, 6:7:8, 7:8:9) b1 (out2, a, b);
endmodule
(三)switch modeling/开关建模
1.nmos/pmos
module des (input d, ctrl,
output outn, outp);
nmos (outn, d, ctrl);
pmos (outp, d, ctrl);
endmodule
2.cmos switches
module des (input d, nctrl, pctrl,
output out);
cmos (out, d, nctrl, pctrl);
endmodule
3.bidirectional switches
Tran:
module des (input io1, ctrl,
output io2);
tran (io1, io2);
endmodule
$monitor ("T=%0t io1=%0b ctrl=%0b io2=%0b", $time, io1, ctrl, io2);
T=0 io1=0 ctrl=0 io2=0
T=10 io1=1 ctrl=0 io2=1
T=20 io1=1 ctrl=1 io2=1
T=30 io1=1 ctrl=0 io2=1
T=40 io1=0 ctrl=0 io2=0
Tranif0:
module des (input io1, ctrl,
output io2);
tranif0 (io1, io2, ctrl);
endmodule
T=0 io1=0 ctrl=0 io2=0
T=10 io1=1 ctrl=0 io2=1
T=20 io1=1 ctrl=1 io2=z
T=30 io1=1 ctrl=0 io2=1
T=40 io1=0 ctrl=0 io2=0
Tranif1
module des (input io1, ctrl,
output io2);
tranif1 (io1, io2, ctrl);
endmodule
T=0 io1=0 ctrl=0 io2=z
T=10 io1=1 ctrl=0 io2=z
T=20 io1=1 ctrl=1 io2=1
T=30 io1=1 ctrl=0 io2=z
T=40 io1=0 ctrl=0 io2=z
4.power and ground 电源和接地
module des (output vdd,
output gnd);
supply1 _vdd;
supply0 _gnd;
assign vdd = _vdd;
assign gnd = _gnd;
endmodule
module tb;
wire vdd, gnd;
des u0 (.vdd(vdd), .gnd(gnd));
initial begin
#10;
$display ("T=%0t vdd=%0d gnd=%0d", $time, vdd, gnd);
end
endmodule
T=10 vdd=1 gnd=0
(四)Verilog用户定义的原语/primitives
标准的verilog的原语,可能并不能容易的或并不足以表示复杂的逻辑。称为UDP的、或自定义的原语能够对组合逻辑或顺序逻辑建模。
所有的UDP只有一个输出,可以是0、1、x。但不能是z,任何值为z的输入都将被视为x。
1.verilog UDP符号
Verilog自定义原语可以与module定义相同的级别,但不能在endmodule和module之间。可以有多个输入端口,但始终只有一个输出端口,双向端口无效。所有的端口信号都必须是标量,即必须是1位宽。
硬件行为被描述为一个原始状态表,在table和endtable之间列出了不同的可能输入组合及其相应的输出。输入和输出信号的值可以使用以下符号表示。
2.组合UDP
输出应始终在端口列表的第一位;
primitive mux (out, sel, a, b);
output out;
input sel, a, b;
table
// sel a b out
0 1 ? : 1;
0 0 ? : 0;
1 ? 0 : 0;
1 ? 1 : 1;
x 0 0 : 0;
x 1 1 : 1;
endtable
endprimitive
2.顺序UDP
输出端口应在 UDP 定义中声明为 reg 类型,并且可以选择在 initial 语句中初始化。
顺序 UDP 在输入和输出字段之间有一个附加字段,该字段由表示当前状态的:分割;
① Level-sensitive UDP
primitive d_latch (q, clk, d);
output q;
input clk, d;
reg q;
table
// clk d q q+
1 1 : ? : 1;
1 0 : ? : 0;
0 ? : ? : -;
endtable
endprimitive
② Edge-sensitive UDP
primitive d_flop (q, clk, d);
output q;
input clk, d;
reg q;
table
// clk d q q+
// obtain output on rising edge of clk
(01) 0 : ? : 0;
(01) 1 : ? : 1;
(0?) 1 : 1 : 1;
(0?) 0 : 0 : 0;
// ignore negative edge of clk
(?0) ? : ? : -;
// ignore data changes on steady clk
? (??): ? : -;
endtable
endprimitive
时钟的上升沿由 01 或 0? 指定。