Verilog模型可以是实际电路不同级别的抽象,因此有多种不同的建模方法。其中最常用的建模方法有以下三种:
1)门级结构建模
2) 行为描述建模
3) 数据流建模
1.门级结构建模
一个逻辑网络是由许多逻辑门和开关所组成,因此用逻辑门的模型来描述逻辑网络是最直观的。VerilogHDL提供了一些门类型的关键字,可以用于门级结构建模。其中最常用的有8个。
and 与门
nand 与非门
nor 或非门
or 或门
xor 异或门
xnor 异或非门
buf 缓冲器
not 非门
一个模块能在其他模块中被引用,如果已经编制了一个模块,我们可以在另外的模块中引用这个模块,引用的方法与门类型的实例引用非常类似,这样就建立了描述的层次。信号的端口可以通过位置或名称关联,但是不能和混合使用。
例:nand #10nd1(a,data,clock,clear);
实例:
1位全加器(结构描述方式)
1位全加器的逻辑图
module FA_Str(A,B,Cin,Sum,Cout)
input A,B,Cin;
output Cout,Sum;
wire S1,T1,T2,T3;
xor
X1(S1,A,B),
X2(Sum,S1,Cin),
A1(T3,A,B),
A2(T2,B,Cin),
A3(T1,A,Cin);
or
O1(Cout,T1,T2,T3);
endmodule
用两块半加器构成全加器(在一个模块中引用其他模块):
module HA(A,B,S,C) //定义一个半加器
input A,B;
output S,C;
parameter AND_DELAY = 1,XOR_DELAY =2;
assign #XOR_DELAY S = A^B;
assign #AND_DELAY C =A&B;
endmodule
moduleFA(P,Q,Cin,Sum,Cout);
input P,Q,Cin;
Cout Sum,Out;
parameter OR_DELAY = 1;
wire S1,C1,C2;
//两个模块实例语句
HA h1(P,Q,S,C1);//通过位置关联
HA h2(.A(Cin),.S(Sum),.B(S1),.C(C2));//通过端口与信号的名字关联
or # OR_DELAY O1(Cout,C1,C2);
endmodule
门级结构描述如下图所示的D触发器;
moduleflop(data,clock,clear,q,qb);
input data,clock,clear;
output q,qb;
nand #10nd1(a,data,clock,clear),
nd2(b,ndata,clock),
nd4(d,c,b,clear),
nd5(e,c,nclock),
nd6(f,d,nclock),
nd8(qb,q,f,clear);
nand #9 nd3(c,a,d),
nd7(q,e,qb);
not #10 iv1(ndata,data),
iv2(nclock,clock);
endmodule
D触发器
用上述的D触发器构成下图的四位寄存器:
modulehardreg(d,clk,clrb,q);
input clk,clrb;
input[3:0] d;
output[3:0] q;
flopf1(d[0],clk,clrb,q[0],),
f2(d[1],clk,clrb,q[1],),
f3(d[2],clk,clrb,q[2],),
f4(d[3],clk,clrb,q[3],);
endmodule
四位寄存器
2.Verilog HDL的行为描述建模
行为建模主要用initial和always语句,这些语句相互并行执行,,都在0时刻开始执行,与语句出现的顺序无关。
行为建模的时序控制:(1)时延控制,(2)事件控制。
时延控制:#delayprocedural_statement;其中delay可以是任意表达式而不必是常量。
事件控制:1边沿触发事件控制 2电平敏感事件控制。
边沿触发事件控制:@event procedural_statement;
例如:@(posedgeClock)Count =0;
电平敏感事件控制:wait(condition)
procedural_statement;
例如:wait(Sum > 22)
Sum = 0;
语句块:begin….end;fork…..join;
过程性赋值:阻塞性赋值,非阻塞性赋值。
条件语句:if….else;case;
循环语句:forever,while,repeat,for。
1forever
procedural_statement;//永远执行下去
2repeat(Count)
procedural_statement;//循环Count次
3while(condition)
procedural_statement;
4for(;;)
procedural_statement;
实例:
1位全加器(行为描述方式):
module FA_Seq(A,B,Cin,Cout,Sum);l
input Cin,A,B;
output Cout,Sum;
reg Cout,Sum;
reg T1,T2,T3;
always
@(A or B or Cin)begin
Sum=(A^B)^Cin;
T1=A&Cin;
T2=B&Cin;
T3=A&B;
Cout=(T1 | T2) | T3;
end
endmodule
带异步预置的负边沿触发的D触发器(行为描述方式):
module DFF(Clk,D,Set,Q,Qbar);
input Clk,D,Dset;
outptut Q,Qbar;
reg Q,Qbar;
always
wait(Set == 1)
begin
#3 Q = 1;
#2 Qbar = 0;
wait(Set ==0)
end
always
@(negedge Clk)
begin
if(Set != 1)
begin
#5 Q = D;
#1 = Qbar = ~Q;
end
end
endmodule
3.Verilog HDL的数据流建模
数据流描述的特征:连续赋值,那么连续赋值什么时候执行呢?只要表达式右端的操作数上有事件发生,表达式即被计算。
下面是一些例子:
--------------------------------
wireCout,Cin;
wire[3:0] Sum,A,B;
assign (cout,Sum) = A+B+Cin;
-------------------------------
assign Mux = (S == 0)? A : ‘bz,
Mux= (S == 1)? B : ‘bz,
Mux= (S == 2)? C : ‘bz,
Mux= (S == 3)? D : ‘bz;:
建模实例:
1位全加器(数据流描述)
moduleFA_Df(A<B<Cin,Sum,Cout)
input A,B,Cin;
output Sum,Cout;
assign Sum = A^B^Cin;
assign Cout =(A&Cin)|(B&Cin)|(A&B);
endmodule
主从触发器(数据流描述)
主从触发器逻辑连接图
module MSDFF_DF(D,C,Q,Qbar)
input D,C;
output Q,Qbar;
wire NotC,NotD,NotY,Y,D1,D2,Ybar,Y1,Y2;
assign NotD = ~D;
assign NotC = ~C;
assign NotY = ~Y;
assign D1 =~(D&C);
assign D2 =~(C&NotD);
assign Y =~(D1&Ybar);
assign Ybar =~(Y&D2);
assign Y1 =~(Y&NotC);
assign Y2 =~(NotY&NotC);
assign Q =~(Qbar&Y1);
assign Qbar =~(Y2&NotQ);
endmodule
2-4解码器(数据流描述方式)
2-4解码器的逻辑图
timescale 1ns/1ns
module Decoder2x4(A,B,EN,Z)
input A,B,EN;
output [0:3] Z;
wire Abar,Bbar;
assign #1 Abar=~A;
assign #1 Bbar=~B;
assign #2Z[0]=~(Abar&Bbar&EN);
assign #2Z[1]=~(Abar&B&EN);
assign #2Z[2]=~(A&Bbar&EN);
assign #2Z[3]=~(A&B&EN);
endmodule