Verilog 门级建模:从硬件原理图到代码的桥梁
大多数数字设计在更高抽象层级(如 RTL)完成,但有时使用组合元件(如 and 和 or) 构建较小的确定性电路更直观。这种建模层级称为门级建模,因为它涉及门,且硬件原理图与 Verilog 代码一一对应。
Verilog 支持一些基本逻辑门,称为基本单元,因为它们像模块一样可以实例化,且已预定义。
与/或/异或门
这些基本单元实现与和或门,接受多个标量输入并提供单个标量输出。参数列表中的第一个端口是输出,当任一输入变化时更新。
module gates ( input a, b, output c, d, e); and (c, a, b); // c 为输出,a、b 为输入 or (d, a, b); // d 为输出,a、b 为输入 xor (e, a, b); // e 为输出,a、b 为输入 endmodule
module tb; reg a, b; wire c, d, e; integer i; gates u0 ( .a(a), .b(b), .c(c), .d(d), .e(e)); initial begin {a, b} = 0; $monitor ("[T=%0t a=%0b b=%0b c(and)=%0b d(or)=%0b e(xor)=%0b", $time, a, b, c, d, e); for (i = 0; i < 10; i = i+1) begin #1 a <= $random; b <= $random; end end endmodule
仿真日志
ncsim> run [T=0 a=0 b=0 c(and)=0 d(or)=0 e(xor)=0 [T=1 a=0 b=1 c(and)=0 d(or)=1 e(xor)=1 [T=2 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 [T=4 a=1 b=0 c(and)=0 d(or)=1 e(xor)=1 [T=5 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 [T=6 a=0 b=1 c(and)=0 d(or)=1 e(xor)=1 [T=7 a=1 b=0 c(and)=0 d(or)=1 e(xor)=1 [T=10 a=1 b=1 c(and)=1 d(or)=1 e(xor)=0 ncsim: *W,RNQUIE: Simulation is complete.
与非/或非/异或非门
上述门的反相版本也以 nand、nor 和 xnor 形式提供。同上例,仅将基本单元替换为其反相版本。
module gates ( input a, b, output c, d, e); // 使用 nand、nor、xnor 替代 and、or、xor nand (c, a, b); // c 为输出,a、b 为输入 nor (d, a, b); // d 为输出,a、b 为输入 xnor (e, a, b); // e 为输出,a、b 为输入 endmodule
module tb; reg a, b; wire c, d, e; integer i; gates u0 ( .a(a), .b(b), .c(c), .d(d), .e(e)); initial begin {a, b} = 0; $monitor ("[T=%0t a=%0b b=%0b c(nand)=%0b d(nor)=%0b e(xnor)=%0b", $time, a, b, c, d, e); for (i = 0; i < 10; i = i+1) begin #1 a <= $random; b <= $random; end end endmodule
仿真日志
ncsim> run [T=0 a=0 b=0 c(nand)=1 d(nor)=1 e(xnor)=1 [T=1 a=0 b=1 c(nand)=1 d(nor)=0 e(xnor)=0 [T=2 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 [T=4 a=1 b=0 c(nand)=1 d(nor)=0 e(xnor)=0 [T=5 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 [T=6 a=0 b=1 c(nand)=1 d(nor)=0 e(xnor)=0 [T=7 a=1 b=0 c(nand)=1 d(nor)=0 e(xnor)=0 [T=10 a=1 b=1 c(nand)=0 d(nor)=0 e(xnor)=1 ncsim: *W,RNQUIE: Simulation is complete.
这些门可拥有两个以上输入。
module gates ( input a, b, c, d, output x, y, z); and (x, a, b, c, d); // x 为输出,a、b、c、d 为输入 or (y, a, b, c, d); // y 为输出,a、b、c、d 为输入 nor (z, a, b, c, d); // z 为输出,a、b、c、d 为输入 endmodule
module tb; reg a, b, c, d; wire x, y, z; integer i; gates u0 ( .a(a), .b(b), .c(c), .d(d), .x(x), .y(y), .z(z)); initial begin {a, b, c, d} = 0; $monitor ("[T=%0t a=%0b b=%0b c=%0b d=%0b x=%0b y=%0b z=%0b", $time, a, b, c, d, x, y, z); for (i = 0; i < 10; i = i+1) begin #1 a <= $random; b <= $random; c <= $random; d <= $random; end end endmodule
仿真日志
ncsim> run [T=0 a=0 b=0 c=0 d=0 x=0 y=0 z=1 [T=1 a=0 b=1 c=1 d=1 x=0 y=1 z=0 [T=2 a=1 b=1 c=1 d=0 x=0 y=1 z=0 [T=3 a=1 b=1 c=0 d=1 x=0 y=1 z=0 [T=4 a=1 b=0 c=1 d=0 x=0 y=1 z=0 [T=5 a=1 b=0 c=1 d=1 x=0 y=1 z=0 [T=6 a=0 b=1 c=0 d=0 x=0 y=1 z=0 [T=7 a=0 b=1 c=0 d=1 x=0 y=1 z=0 [T=8 a=1 b=1 c=1 d=0 x=0 y=1 z=0 [T=9 a=0 b=0 c=0 d=1 x=0 y=1 z=0 [T=10 a=0 b=1 c=1 d=1 x=0 y=1 z=0 ncsim: *W,RNQUIE: Simulation is complete.
缓冲/非门
这些门仅有一个标量输入和一个或多个输出。buf 代表缓冲器,直接将输入值传递给输出而不改变极性。not 代表反相器,将输入信号极性反转,输入 0 输出 1,反之亦然。
module gates ( input a, output c, d); buf (c, a); // c 为输出,a 为输入 not (d, a); // d 为输出,a 为输入 endmodule
module tb; reg a; wire c, d; integer i; gates u0 ( .a(a), .c(c), .d(d)); initial begin a = 0; $monitor ("[T=%0t a=%0b c(buf)=%0b d(not)=%0b", $time, a, c, d); for (i = 0; i < 10; i = i+1) begin #1 a <= $random; end end endmodule
仿真日志
xcelium> run [T=0 a=0 c(buf)=0 d(not)=1 [T=2 a=1 c(buf)=1 d(not)=0 [T=8 a=0 c(buf)=0 d(not)=1 [T=9 a=1 c(buf)=1 d(not)=0 xmsim: *W,RNQUIE: Simulation is complete.
端口列表中的最后一个端口连接到门的输入,所有其他端口连接到输出端口。下例展示多输出缓冲器(虽少用)。
module gates ( input a, output c, d); not (c, d, a); // c、d 为输出,a 为输入 endmodule
仿真日志
xcelium> run [T=0 a=0 c=1 d=1 [T=2 a=1 c=0 d=0 [T=8 a=0 c=1 d=1 [T=9 a=1 c=0 d=0 xmsim: *W,RNQUIE: Simulation is complete.
带控制的缓冲/反相器
带额外控制信号以启用输出的缓冲器和反相器,通过 bufif 和 notif 基本单元提供。这些门仅在控制信号使能时输出有效值,否则输出高阻态。有两个版本:控制极性为正(1 使能)的 bufif1 和 notif1,以及控制极性为负(0 使能)的 bufif0 和 notif0。
Verilog