阿扣的Verilog HDL 学习笔记⑤
第5章 门级建模
用表示门的术语描述电路(eg. and、nand…)。
门级原语;实例引用、门的符号、各类门的真值表;根据电路逻辑图生成Verilog描述;讲述上升、下降和关断延迟;最小、最大和典型延迟。
5.1门的类型
- 门级原语实例引用时不用指定实例名字
- 门的类型:类似于预定义的(无需声明)的模块。分为:与或门类(and/or);缓冲器非门类(buf/not)
- 与门(and)&或门(or):单输出,多输入。门的端口列表第一个为输出端口,其后为输入端口
- 该类含有 and or xor nand nor xnor;实例与真值表如下:
wire OUT, IN1, IN2;
and a1(OUT, IN1, IN2);
nand na1(OUT, IN1, IN2);
or or1(OUT, IN1, IN2);
nor nor1(OUT, IN1, IN2);
xor x1(OUT, IN1, IN2);
xnor nx1(OUT, IN1, IN2);
nand na1_3inp(OUT, IN1, IN2, IN3);
and (OUT, IN1, IN2);//不给实例命名也合法
首行为in1,首列为in2
and |
0 |
1 |
x |
z |
|
nand |
0 |
1 |
x |
z |
0 |
0 |
0 |
0 |
0 |
|
0 |
1 |
1 |
1 |
1 |
1 |
0 |
1 |
x |
x |
|
1 |
1 |
0 |
x |
x |
x |
0 |
x |
x |
x |
|
x |
1 |
x |
x |
x |
z |
0 |
x |
x |
x |
|
z |
1 |
x |
x |
x |
首行为in1,首列为in2
or |
0 |
1 |
x |
z |
|
nor |
0 |
1 |
x |
z |
0 |
0 |
1 |
x |
x |
|
0 |
1 |
0 |
x |
x |
1 |
1 |
1 |
1 |
1 |
|
1 |
0 |
0 |
0 |
0 |
x |
x |
1 |
x |
x |
|
x |
x |
0 |
x |
x |
z |
x |
1 |
x |
x |
|
z |
x |
0 |
x |
x |
首行为in1,首列为in2
xor |
0 |
1 |
x |
z |
|
xnor |
0 |
1 |
x |
z |
0 |
0 |
1 |
x |
x |
|
0 |
1 |
0 |
x |
x |
1 |
1 |
0 |
x |
x |
|
1 |
0 |
1 |
x |
x |
x |
x |
x |
x |
x |
|
x |
x |
x |
x |
x |
z |
x |
x |
x |
x |
|
z |
x |
x |
x |
x |
- 缓冲器/非门:单输入(标量),多输出(标量)。门的端口列表最后一个终端连接至输入端口,其他为输出端口
- buf not bufif1 notif1 bufif0 notif0;
- 多个输出端的buf/not门,所有输出一样。实例与真值表如下:
buf b1(OUT1, IN);
not n1(OUT1, IN)
buf b1_2out(OUT1, OUT2, IN);
not (OUT, IN); //不给实例命名也合法
bufif1 b1(out, in, ctr1);
bufif0 b0(out, in, ctr1);
notif1 b0(out, in, ctr1);
notif0 b0(out, in, ctr1);
buf_in |
buf_out |
|
not_in |
not_out |
0 |
0 |
|
0 |
1 |
1 |
1 |
|
1 |
0 |
x |
x |
|
x |
x |
x |
x |
|
x |
x |
首行为ctr1,首列为in
bufif1 |
0 |
1 |
x |
z |
|
bufif0 |
0 |
1 |
x |
z |
0 |
z |
0 |
L |
L |
|
0 |
1 |
z |
L |
L |
1 |
z |
1 |
H |
H |
|
1 |
0 |
z |
H |
H |
x |
z |
x |
x |
x |
|
x |
x |
z |
x |
x |
z |
z |
x |
x |
x |
|
z |
x |
z |
x |
x |
首行为ctr1,首列为in
notif1 |
0 |
1 |
x |
z |
|
notif0 |
0 |
1 |
x |
z |
0 |
z |
1 |
H |
H |
|
0 |
1 |
z |
H |
H |
1 |
z |
0 |
L |
L |
|
1 |
0 |
z |
L |
L |
x |
z |
x |
x |
x |
|
x |
z |
z |
x |
x |
z |
z |
x |
x |
x |
|
z |
z |
z |
x |
x |
- 实例数组:相当于在不同的向量信号位上,对门多次调用。
wire [7:0] OUT, IN1, IN2;
nand n_gate[7:0] (OUT, IN1, IN2);//该语句与以下8条语句一致
nand n_gate0 (OUT[0], IN1[0], IN2[0]);
nand n_gate1 (OUT[1], IN1[1], IN2[1]);
nand n_gate2 (OUT[2], IN1[2], IN2[2]);
nand n_gate3 (OUT[3], IN1[3], IN2[3]);
nand n_gate4 (OUT[4], IN1[4], IN2[4]);
nand n_gate5 (OUT[5], IN1[5], IN2[5]);
nand n_gate6 (OUT[6], IN1[6], IN2[6]);
nand n_gate7 (OUT[7], IN1[7], IN2[7]);
- 实例① 门级多路选择器(四选一),假设s1和s0不能为z或x:
module mux4_to_1 (out, i0, i1, i2, i3, s0, s1);
//端口声明 详见逻辑图
output out;
input i0, i1, i2, i3;
input s0, s1;
//内部线网声明;两个中间线网变量s0n s1n通过反相门与输入信号s0和s1相连
wire s1n, s0n;
wire y0, y1, y2, y3;
//门级实例引用
//生成s1n和s0n信号
not (s1n, s1);
not (s0n, s0);
//调用三态输入与门
and (y0, i0, s1n, s0n);
and (y1, i1, s1n, s0);
and (y2, i2, s1, s0n);
and (y3, i3, s1, s0);
//调用四输入或门
or (out, y0, y1, y2, y3);
endmodule
- 激励模块,用于测试。(也可以用$monitor来监视)
module sitimulus; //无端口激励模块
//声明连接到输入端口的变量
reg IN0, IN1, IN2, IN3;
reg S1, S0;
//声明输出连线
wire OUTPUT;
//调用多路器
mux4_to_1 mymux(OUTPUT, IN0, IN1, IN2, IN3, S1, S0);
//产生输入激励信号
initial
begin
- //输入线信号设置
IN0 = 1; IN1 = 0; IN2 = 1; IN3 = 0;
#1 $display("IN0 = %b, IN1 = %b, IN2 = %b, IN3 = %b\n", IN0, IN1, IN2, IN3);
//选择IN0
S1 = 0; S0 = 0;
#1 $display("S1 = %b, S0 = %b, OUTPUT = %b\n", S1, S0, OUTPUT);
//选择IN1
S1 = 0; S0 = 1;
#1 $display("S1 = %b, S0 = %b, OUTPUT = %b\n", S1, S0, OUTPUT);
//选择IN2
S1 = 1; S0 = 0;
#1 $display("S1 = %b, S0 = %b, OUTPUT = %b\n", S1, S0, OUTPUT);
//选择IN3
S1 = 1; S0 = 1;
#1 $display("S1 = %b, S0 = %b, OUTPUT = %b\n", S1, S0, OUTPUT);
end
endmodule
- 仿真结果:
- 实例② 四位脉动进位全加器
- 一位全加器 sum= a ⊕b⊕cin ; cout= a⋅b +cin ⋅ a⊕b
module fulladd(sum, c_out, a, b, c_in);
output sum, c_out;
input a, b, c_in;
//注意 别忘了声明内部线网
wire abxor, abx, cxabxor;
xor (abxor, a, b);
and (cxabxor, c_in, abxor);
and (abx, a, b);
xor (sum, c_in, anxor);
or (c_out, abx, cxabxor);
endmodule
- Q:p66 例5.7 为什么是xor (c_out, c2, c1); ???
//四位脉动进位全加器
module fulladd4(sum, c_out, a, b, c_in)
output [3:0] sum;
output c_out;
input [3:0] a, b;
input c_in;
//内部线网
wire c1, c2, c3;
//调用4个一位全加器
fulladd fa0(sum[0], c1, a[0], b[0], c_in);
fulladd fa1(sum[1], c2, a[1], b[1], c1);
fulladd fa2(sum[2], c3, a[2], b[2], c2);
fulladd fa3(sum[3], c_out, a[3], b[3], c3);
endmodule
- 四位脉动进位全加器的激励模块(顶层模块)
module stimulus;
reg [3:0] A, B;
reg C_IN;
wire [3;0] SUM;
wire C_OUT;
fulladd4 FA1_4(SUM, C_OUT, A, B, C_IN);
initial
begin
$minitor( $time, " A = %b, B = %b, C_IN = %b, --- C_OUT = %b, SUM = %b\n", A, B, C_IN, C_OUT, SUM);
end
//激励信号输入
initial
begin
A = 4'd0; B = 4'd0; C_IN = 1'b0;
#5 A = 4'd3; B = 4'd4;
#5 A = 4'd2; B = 4'd5;
#5 A = 4'd9; B = 4'd9;
#5 A = 4'd10; B = 4'd15;
#5 A = 4'd10; B = 4'd4; C_IN = 1'b1;
end
endmodule
- 仿真结果:
5.2门延迟
- 上升延迟:门的输入变化是,输出从0,x,z变为1所需时间 t_rise
- 下降延迟:输出同1,x,z变为0所需时间 t_fall
- 关断延迟:输出同0,1,x变化为高阻抗z所需时间
- 值变化到x所需时间为上述三者最小值。
- ①指定一个延迟值。#(<上升/下降/关断延迟>);
and #(delay_time) a1(out, i1, i2);//所有延迟时间都等于<delay_time>;注意是逗号
- ②指定两个延迟值,#(<上升延迟>, <下降延迟>);//较小者为关断延迟;
and #(rise_val, fall_val) a2(out, i1, i2);//上升、下降延迟
- ③指定三个延迟值。#(<上升延迟>, <下降延迟>, <关断延迟>);
bufif0 #(rise_val, fall_val, turnoff_val) b1(out, in, control);//上升、下降、关断延迟
- *默认延迟值为0。
and #(5) a1(out, i1, i2);//所有延迟时间都等于5
and #(4, 6) a2(out, i1, i2);//上升、下降延迟分别为4,6
bufif0 #(3, 4, 5) b1(out, in, control);//上升、下降、关断延迟分别为3,4,5
- 对每种类型延迟还可以指定最小值、最大值和典型值。建立行为模型时要用到。
- 最小延迟:逻辑门的预期最小延迟;
- 典型延迟:逻辑门的预期典型延迟;
- 最大延迟:逻辑门的预期最大延迟。
- 仿真开始时&过程中可以控制延迟值。
- ①指定一个延迟。#(<最小延迟>:<典型延迟>:<最大延迟>);
and #(4:5:6) a1(out, i1, i2);
- ②指定两个延迟。#(<最小上升延迟>:<典型上升延迟>:<最大上升延迟>, <最小下降延迟>:<典型下降延迟>:<最大下降延迟>);
and #(3:4:5, 5:6:7) a2(out, i1, i2);
- ③指定三个延迟。#(<最小上升延迟>:<典型上升延迟>:<最大上升延迟>, <最小下降延迟>:<典型下降延迟>:<最大下降延迟>, <最小关断延迟>:<典型关断延迟>:<最大关断延迟>);
and #(2:3:4, 3:4:5, 4:5:6) a3(out, i1, i2);
- 控制方法与系统有关,例如Verilog-XL仿真器中:
//启动仿真器,用最大延迟值仿真
>verilog test.v +maxdelays
//启动仿真器,用最小延迟值仿真
>verilog test.v +mindelays
//启动仿真器,用典型延迟值仿真
>verilog test.v +typdelays
- 实例 实现逻辑功能为 out = (a·b) + c的模块D;
- 模块描述:
module D(out, a, b, c);
output out;
input a, b, c;
wire e;
and #(5) a1(e, a, b); //Delay of 5 on gate a1
or #(4) o1(out, e, c); //Delay of 4 on gate o1
endmodule
- 测试激励模块:
module stimulus;
reg A, B, C;
wire OUT;
D d1(OUT, A, B, C);
initial
begin
A = 1'b0; B = 1'b0; C = 1'b0;
#10 A = 1'b1; B = 1'b1; C = 1'b1;
#10 A = 1'b1; B = 1'b0; C = 1'b0;
#20 $finish;
end
endmodule