萌新小白,为做FPGA大创,开始学习Verilog HDL
端口与模块
把电路放进一个小黑盒,那电路与外界连接的地方就可以理解为端口,整个小黑盒可以理解为模块,大的黑盒里可以引用小的黑盒,开始套娃(不可以直接嵌套,但是可以引用)。
端口的类别
端口的类别可以分为input、output、inout,其中input、inout只支持定义为线网类型即net,而output支持线网类型和寄存器类型。输入端口只是把上一级的信号传递,不做存储功能,但是输出端口,比如计时器的q要在下一个脉冲到来时才会改变值,那么输出端口就需要有寄存功能。(输入端口的定义是线网,外部连接的却是寄存器或线网。)
端口引用
端口引用有两种方式,一种是按照module设定时的顺序比如module fulladd4(sum,c_out,a,b,c_in),那我引用的时候就需要fulladd4 fa_ordered(SUM,C_OUT,A,B,C_IN);另外一种是当模块多了以后,可以用名字进行说明,比如fulladd4 fa_byname(.c_out(C_OUT), .sum(SUM), .b(B), .c_in(C_IN), .a(A))。需要注意的是,端口的位数一定要对应。
一些简单的电路可以直接通过门建模
一些常用门的书写方法:
与门和或门(and,nand,or,nor,xor异或,xnor同或)
wire OUT, IN1,IN2,IN3;
and a1(OUT,IN1,IN2);
nand na1_3inp(OUT,IN1,IN2,IN3);
//对于数组
wire [7:0] OUT,IN1,IN2;
nand n_gate[7:0] (OUR,IN1,IN2);缓冲器和非门(buf,not)带控制端的缓冲器/非门(bufif1,bufif0,notif0,notif1)
buf b1(OUT1,IN);
buf b1_2out(OUT1,OUT2,IN);
bufif1 b1(out,in,ctr1);例子:一个四位全加器
module fulladd(sum,c_out,a,b,c_in);
output sum,c_out;
input a,b,c_in;
wire s1,c1,c2;
xor (s1,a,b);
and (c1,a,b);
xor (sum,s1,c_in);
and (c2,s1,c_in);
xor (c_out,c2,c1);
endmodule//一位全加器
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;
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
$monitor($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;
end
endmodule门延迟
门延迟分为上升延迟、下降延迟、关断延迟,设计时又有最小值、典型值和最大值
可以书写为and #(2:3:4,3:4:5,4:5:6) a3(out,i1,i2);这里第一个3:4:5表示上升延迟的最小值是3,典型值4,最大值5,第二个表示下降延迟,第三个表示关断延迟。如果不指定,默认延迟0;指定一个延时值,则上升下降关断都是这个值;指定两个,则分别代表上升延迟和下降延迟,关断延迟等于其中小的值。
参考书目:Verilog HDL数字设计与综合(第二版)[美] Samir Palnitkar