下载第 11章 验 证本章介绍了如何编写测试验证程序 (test bench)。测试验证程序用于测试和验证设计的正确性。 Verilog HDL提供强有力的结构来说明测试验证程序。
11.1 编写测试验证程序测试验证程序有三个主要目的:
1) 产生模拟激励 (波形 )。
2) 将输入激励加入到测试模块并收集其输出响应;
3) 将响应输出与期望值进行比较。
Verilog HDL提供了大量的方法以编写测试验证程序。在本章中,我们将对其中的某些方法进行探讨。典型的测试验证程序形式如下:
module T e s t _ B e n c h;
/ /通常测试验证程序没有输入和输出端口。
L o c a l _ r e g _ a n d _ n e t _ d e c l a r a t i o n s
G e n e r a t e _ w a v e f o r m s _ u s i n g _ i n i t i a l _ & _ a l w a y s _ s t a t e m e n t s
I n s t a n t i a t e _ m o d u l e _ u n d e r _ t e s t
M o n i t o r _ o u t p u t _ a n d _ c o m p a r e _ w i t h _ e x p e c t e d _ v a l u e s
e n d m o d u l e
测试中,通过在测试验证程序中进行实例化,激励自动加载于测试模块。
11.2 波形产生有两种产生激励值的主要方法:
1) 产生波形,并在确定的离散时间间隔加载激励。
2) 根据模块状态产生激励,即根据模块的输出响应产生激励。
通常需要两类波形。一类是具有重复模式的波形,例如时钟波形,另一类是一组指定的值确定的波形。
11.2.1 值序列产生值序列的最佳方法是使用 i n i t i a l语句。例如,
i n i t i a l
b e g i n
R e s e t = 0;
#100 R e s e t = 1;
#80 Reset = 0;
#30 Reset = 1;
e n d
产生的波形如图 11 - 1所示。 I n i t i a l语句中的赋值语句用时延控制产生波形。此外,语句内时延也能够按如下实例所示产生波形。
i n i t i a l
b e g i n
R e s e t = 0;
R e s e t = #100 1;
R e s e t = #80 0;
R e s e t = #30 1;
e n d
图 11-1 使用 initial语句产生的波形因为使用的是阻塞性过程赋值,上面语句中的时延是相对时延。如果使用绝对时延,可用带有语句内时延的非阻塞性过程性赋值,例如,
i n i t i a l
b e g i n
R e s e t <= 0;
R e s e t <= #100 1;
R e s e t <= #180 0;
R e s e t <= #210 1;
e n d
这三个 i n i t i a l语句产生的波形与图 11 - 1中所示的波形一致。
为重复产生一个值序列,可以使用 a l w a y s语句替代 i n i t i a l语句,这是因为 i n i t i a l语句只执行一次而 a l w a y s语句会重复执行。下例的 a l w a y s语句所产生的波形如图 11 - 2所示。
p a r a m e t e r REPEAT_DELAY = 35;
i n t e g e r C o i n V a l u e ;
a l w a y s
b e g i n
CoinValue = 0;
#7 C o i n V a l u e = 25;
#2 C o i n V a l u e = 5;
#8 C o i n V a l u e = 10;
#6 C o i n V a l u e = 5;
#R E P E A T _ D E L A Y;
e n d
图 11-2 使用 always语句产生的重复序列
11.2.2 重复模式重复模式的生成通过使用如下形式的连续赋值形式加以简化:
第 11章 验 证 119下载一个周期
a s s i g n # (P E R I O D/2) Clock = ~ C l o c k;
但是这种做法并不完全正确。问题在于 C l o c k是一个线网 (只有线网能够在连续赋值中被赋值 ),它的初始值是 z,并且,z等于 x,~ x等于 x。因此 C l o c k的值永远固定为值 x。
现在需要一种初始化 C l o c k的方法。可以用 i n i t i a l语句实现。
i n i t i a l
C l o c k = 0;
但是现在 C l o c k必须是寄存器数据类型 (因为只有寄存器数据类型能够在 i n i t i a l语句中被赋值 ),因此连续赋值语句需要被变换为 a l w a y s语句。下面是一个完整的时钟产生器模块。
m o d u l e Gen_Clk_A (C l k _ A) ;
o u t p u t C l k _ A;
r e g C l k _ A ;
p a r a m e t e r tPERIOD = 10;
i n i t i a l
C l k _ A = 0;
always
# (t P E R I O D/2) Clk_A = ~ C l k _ A;
e n d m o d u l e
图 11 - 3显示了该模块产生的时钟波形。
图 11-3 周期性的时钟波形下面给出了产生周期性时钟波形的另一种可选方式。
m o d u l e Gen_Clk_B (C l k _ B) ;
o u t p u t C l k _ B;
r e g S t a r t;
i n i t i a l
b e g i n
S t a r t = 1;
#5 S t a r t = 0;
e n d
n o r #2 (Clk_B,Start,C l k _ B) ;
e n d m o d u l e
/ /产生一个高、低电平宽度均为 2的时钟。
i n i t i a l语句将 S t a rt置为 1,这促使或非门的输出为 0 (从 x值中获得 )。 5个时间单位后,在
S t a rt变为 0时,或非门反转产生带有周期为 4个时间单位的时钟波形。产生的波形如图 11 - 4所示。
如果要产生高低电平持续时间不同的时钟波形,可用 a l w a y s语句建立模型,如下所示:
m o d u l e Gen_Clk_C (C l k _ C) ;
p a r a m e t e r tON = 5,t O F F = 10;
o u t p u t C l k _ C ;
120 Verilog HDL 硬件描述语言 下载第 11章 验 证 121下载
r e g C l k _ C ;
a l w a y s
b e g i n
# tON Clk_C = 0;
# tOFF Clk_C= 1;
e n d
e n d m o d u l e
图 11-4 受控时钟因为值 0和 1被显式地赋值,在这种情况下不必使用 i n i t i a l语句。图 11 - 5显示了这一模块生成的波形。
为在初始时延后产生高低电平持续时间不同的时钟,可以在 i n i t i a l语句中使用 f o r e v e r循环语句。
图 11-5 高低电平持续时间不同的时钟
m o d u l e Gen_Clk_D (Clk_D);
o u t p u t C l k _ D ;
r e g C l k _ D ;
p a r a m e t e r START_DELAY = 5,LOW_TIME = 2,HIGH_TIME = 3;
i n i t i a l
b e g i n
Clk_D = 0;
# S T A R T _ D E L A Y ;
f o r e v e r
b e g i n
# LOW_TIME ;
Clk_D = 1;
# H I G H _ T I M E;
Clk_D = 0;
e n d
e n d
e n d m o d u l e
上面模块所产生的波形如图 11 - 6所示。
为产生确定数目的时钟脉冲,可以使用 r e p e a t循环语句。下面带参数的时钟模块产生一定数目的时钟脉冲数列,时钟脉冲的高低电平持续时间也是用参数表示的。
m o d u l e Gen_Clk_E (C l k _ E) ;
o u t p u t C l k _ E ;
r e g C l k _ E ;
p a r a m e t e r Tburst = 10,Ton = 2,Toff = 5;
i n i t i a l
b e g i n
C l k _ E = 1'b0;
r e p e a t(T b u r s t)
b e g i n
# Toff Clk_E= 1'b1;
# Ton Clk_E = 1'b0;
e n d
e n d
e n d m o d u l e
图 11-6 带有初始时延的时钟模块 G e n _ C l k _ E在具体应用时,参数 T b u r s t,To n和 To f f可带不同的值。
m o d u l e T e s t;
w i r e Clk_Ea,Clk_Eb,Clk_Ec;
Gen_Clk_E G1(C l k _ E a) ;
/ /产生 1 0个时钟脉冲,高、低电平持续时间分别为 2个和 5个时间单位。
Gen_Clk_E # (5,1,3) (C l k _ E b) ;
/ /产生 5个时钟脉冲,高、低电平持续时间分别为 1个和 3个时间单位。
Gen_Clk_E # (25,8,10) (C l k _ E c) ;
/ /产生 2 5个时钟脉冲,高、低电平持续时间分别为 8个和 1 0个时间单位。
e n d m o d u l e
C l k _ E b的波形如图 11 - 7所示。
图 11-7 确定数目的时钟脉冲可用连续赋值产生一个时钟的相移时钟。下述模块产生的两个时钟波形如图 11 - 8所示。
一个时钟是另一个时钟的相移时钟。
m o d u l e Phase (Master_Clk,Slave_Clk) ;
o u t p u t Master_Clk,Slave_Clk;
reg Master_Clk;
122 Verilog HDL 硬件描述语言 下载
w i r e S l a v e _ C l k ;
p a r a m e t e r t O N = 2,tOFF = 3,tPHASE_DELAY = 1;
a l w a y s
b e g i n
#tON Master_Clk= 0;
#tOFF Master_Clk= 1;
e n d
assign #tPHASE_DELAY Slave_Clk = M a s t e r _ C l k;
e n d m o d u l e
图 11-8 相移时钟
11.3 测试验证程序实例
11.3.1 解码器下面是 2 - 4解码器和它的测试验证程序。任何时候只要输入或输出信号的值发生变化,输出信号的值都会被显示输出。
` t i m e s c a l e 1ns / 1ns
m o d u l e D e c 2 x 4 (A,B,Enable,Z) ;
i n p u t A,B,Enable;
o u t p u t [0:3] Z;
w i r e Abar,Bbar;
n o t # (1,2)
V0 (Abar,A),
V1 (Bar,B) ;
n a n d # (4,3)
N0 (Z [0],Enable,Abar,Bbar),
N1 (Z [1],Enable,Abar,B),
N2 (Z [2],Enable,A,Bbar),
N3 (Z [3],Enable,A,B),
e n d m o d u l e
m o d u l e D e c _ T e s t ;
r e g Da,Db,Dena;
w i r e [0:3] D z ;
/ /被测试的模块:
Dec2x4 D1(Da,Db,Dena,Dz) ;
第 11章 验 证 123下载
/ /产生输入激励:
i n i t i a l
b e g i n
Dena = 0;
Da = 0;
D b = 0;
#10 Dena = 1;
#10 Da = 1;
#10 D b = 1;
#10 D a = 0;
#10 D b = 0;
#10 $stop;
e n d
/ /输出模拟结果:
a l w a y s
@ (Dena o r Da o r Db or D z)
$d i s p l a y ("At time %t,input is %b%b%b,output is %b",
$ t i m e,Da,Db,Dena,Dz) ;
e n d m o d u l e
下面是测试模块执行时产生的输出。
At time 4,input is 000,output is 1111
At time 10,input is 001,output is 1111
At time 13,input is 001,output is 0111
At time 20,input is 101,output is 0111
At time 23,input is 101,output is 0101
At time 26,input is 101,output is 1101
At time 30,input is 111,output is 1101
At time 33,input is 111,output is 1100
At time 36,input is 111,output is 1110
At time 40,input is 011,output is 1110
At time 44,input is 011,output is 1011
At time 50,input is 001,output is 1011
At time 54,input is 001,output is 0111
11.3.2 触发器下例是主从 D触发器及其测试模块。
m o d u l e MSDFF (D,C,Q,Qbar) ;
i n p u t D,C;
o u t p u t Q,Qbar;
not
NT1 (NotD,D),
NT2 (NotC,C),
NT3 (NotY,Y);
nand
N D 1 (D1,D,C),
N D 2 (D2,C,NotD),
N D 3 (Y,D1,Ybar),
124 Verilog HDL 硬件描述语言 下载
ND4 (Ybar,Y,D2),
ND5 (Y1,Y,NotC),
ND6 (Y2,NotY,NotC),
N D 7 (Q,Qbar,Y1),
N D 8 (Qbar,Y2,Q) ;
e n d m o d u l e
m o d u l e T e s t ;
r e g D,C;
w i r e Q,Qb;
MSDFF M1(D,C,Q,Qb) ;
a l w a y s
#5 C = ~ C;
i n i t i a l
b e g i n
D = 0;
C = 0;
#40 D = 1;
#40 D = 0;
#40 D = 1;
#40 D = 0;
$s t o p;
e n d
i n i t i a l
$ m o n i t o r ("Time = %t,:",$t i m e,"C=%b,D=%b,Q=%b,
Qb=%b",C,D,Q,Qb ) ;
e n d m o d u l e
在此测试验证模块中,触发器的两个输入和两个输出结果均设置了监控,故只要其中任何值发生变化就输出指定变量的值。下面是执行产生的输出结果。
Time= 0:,C=0,D=0,Q=x,Qb=x
Time= 5:,C=1,D=0,Q=x,Qb=x
Time= 10:,C=0,D=0,Q=0,Qb=1
Time= 15:,C=1,D=0,Q=0,Qb=1
Time= 20:,C=0,D=0,Q=0,Qb=1
Time= 25:,C=1,D=0,Q=0,Qb=1
Time= 30:,C=0,D=0,Q=0,Qb=1
Time= 35:,C=1,D=0,Q=0,Qb=1
Time= 40:,C=0,D=1,Q=0,Qb=1
Time= 45:,C=1,D=1,Q=0,Qb=1
Time= 50:,C=0,D=1,Q=1,Qb=0
Time= 55:,C=1,D=1,Q=1,Qb=0
Time= 60:,C=0,D=1,Q=1,Qb=0
Time= 65:,C=1,D=1,Q=1,Qb=0
Time= 70:,C=0,D=1,Q=1,Qb=0
Time= 75:,C=1,D=1,Q=1,Qb=0
Time= 80:,C=0,D=0,Q=1,Qb=0
第 11章 验 证 125下载
126 Verilog HDL 硬件描述语言 下载
Time= 85:,C=1,D=0,Q=1,Qb=0
Time= 90:,C=0,D=0,Q=0,Qb=1
Time= 95:,C=1,D=0,Q=0,Qb=1
Time= 100:,C=0,D=0,Q=0,Qb=1
Time= 105:,C=1,D=0,Q=0,Qb=1
Time= 110:,C=0,D=0,Q=0,Qb=1
Time= 115:,C=1,D=0,Q=0,Qb=1
Time= 120:,C=0,D=1,Q=0,Qb=1
Time= 125:,C=1,D=1,Q=0,Qb=1
Time= 130:,C=0,D=1,Q=1,Qb=0
Time= 135:,C=1,D=1,Q=1,Qb=0
Time= 140:,C=0,D=1,Q=1,Qb=0
Time= 145:,C=1,D=1,Q=1,Qb=0
Time= 150:,C=0,D=1,Q=1,Qb=0
Time= 155:,C=1,D=1,Q=1,Qb=0
11.4 从文本文件中读取向量可用 $ re a d m e m b系统任务从文本文件中读取向量 (可能包含输入激励和输出期望值 )。下面为测试 3位全加器电路的例子。假定文件,t e s t,v e c”包含如下两个向量。
向量的前三位对应于输入 A,接下来的三位对应于输入 B,再接下来的位是进位,八到十位是期望的求和结果,最后一位是期望进位值的输出结果。下面是全加器模块和相应的测试验证程序。
m o d u l e Adder1Bit (A,B,Cin,Sum,Cout) ;
i n p u t A,B,Cin;
o u t p u t Sum,Cout;
a s s i g n S u m = (A ^ B ) ^ Cin;
a s s i g n Cout = (A ^ B )| (A & Cin) | (B & Cin) ;
e n d m o d u l e
m o d u l e Adder3Bit (First,Second,Carry_In,Sum_Out,Carry_Out) ;
i n p u t [0:2] First,Second;
i n p u t C a r r y _ I n;
o u t p u t [0:2] S u m _ O u t;
o u t p u t C a r r y _ O u t ;
wire [0:1] C a r ;
A d d e r 1 B i t
A1 (F i r s t[2],S e c o n d[2],Carry_In,Sum_Out [2],C a r[ 1 ] ),
A2 (F i r s t[1],S e c o n d[1],C a r[1],Sum_Out [ 1 ],C a r[ 0 ] ),
A3 (F i r s t[0],S e c o n d[0],C a r[0],Sum_Out [0],C a r r y _ O u t) ;
e n d m o d u l e
m o d u l e T e s t B e n c h;
期头的期头的
p a r a m e t e r B I T S = 11,WORDS= 2 ;
reg [1:BITS] V m e m [ 1,W O R D S] ;
r e g[ 0,2 ]A,B,S u m _ E x;
r e g Cin,Cout_Ex;
i n t e g e r J;
w i r e [0:2] S u m;
w i r e C o u t;
/ /被测试验证的模块实例。
A d d e r 3 B i t F1 (A,B,Cin,Sum,Cout) ;
i n i t i a l
b e g i n
$readmemb ("test.vec",Vmem) ;
f o r (J = 1; J <= W O R D S; J = J + 1)
b e g i n
{A,B,Cin,Sum_Ex,Cout_Ex} = V m e m [J] ;
#5; //延迟 5个时间单位等待电路稳定。
i f ( (S u m ! = = S u m _ E x) | | (Cout ! = = C o u t _ E x) )
$d i s p l a y ("****Mismatch on vector %b *****",Vmem [J] ) ;
e l s e
$d i s p l a y ("No mismatch on vector %b",Vmem [J] ) ;
e n d
e n d
e n d m o d u l e
测试模块中首先定义存储器 V m e m,字长对应于每个向量的位数,存储器字数对应于文件中的向量数。系统任务 $re a d m e m b从文件,t e s t,v e c”中将向量读入存储器 V m e m中。 f o r循环通过存储器中的每个字,即每个向量,将这些向量应用于待测试的模块,等待模块稳定并探测模块输出。条件语句用于比较期望输出值和监测到的输出值。如果发生不匹配的情况,则输出不匹配消息。下面是以上测试验证模块模拟执行时产生的输出。因为模型中不存在错误,
因此没有报告不匹配情形。
No mismatch on vector 01001001000
No mismatch on vector 01001111100
11.5 向文本文件中写入向量在上节的模拟验证模块实例中,我们看到值如何被打印输出。设计中的信号值也能通过如 $f d i s p l a y,$ f m o n i t o r和 $ f s t r o b e等具有写文件功能的系统任务输出到文件中。下面是与前一节中相同的测试验证模块实例,本例中的验证模块将所有输入向量和观察到的输出结果输出到文件,m o n,O u t”中。
m o d u l e F _ T e s t _ B e n c h;
p a r a m e t e r BITS = 11,WORDS= 2 ;
r e g [ 1,B I T S] Vmem [ 1,W O R D S] ;
r e g [0:2] A,B,Sum_Ex;
r e g C i n,C o u t _ E x
第 11章 验 证 127下载
128 Verilog HDL 硬件描述语言 下载
i n t e g e r J ;
w i r e [0:2] S u m;
w i r e C o u t;
/ /待测试验证模块的实例。
A d d e r 3 B i t F1 (A,B,Cin,Sum,Cout) ;
i n i t i a l
b e g i n,I N I T _ L A B L E
i n t e g e r M o n _ O u t _ F i l e;
Mon_Out_File = $f o p e n (" m o n,o u t ") ;
$r e a d m e m b ("test.vec",Vmem) ;
f o r (J = 1; J <= W O R D S; J = J + 1)
b e g i n
{A,B,Cin,Sum_Ex,Cout_Ex} = Vmem [J] ;
#5; //延迟 5个时间单位,等待电路稳定。
i f ( (Sum ! = = Sum_Ex) | | (Cout ! = = Cout_Ex) )
$d i s p l a y ("****Mismatch on vector %b *****",V m e m [J] ) ;
e l s e
$d i s p l a y ("No mismatch on vector %b",V m e m [J] ) ;
/ /将输入向量和输出结果输入到文件,
$f d i s p l a y (Mon_Out_File,"Input = %b%b%b,Output = %b%b",
A,B,Cin,Sum,Cout) ;
e n d
$f c l o s e (M o n _ O u t _ F i l e) ;
e n d
e n d m o d u l e
下面是模拟执行后文件,m o n,o u t”包含的内容。
Input = 0100100,Output = 1000
Input = 0100111,Output = 1100
11.6 其他实例
11.6.1 时钟分频器下面是应用波形方法的完整测试验证程序。待测试的模块名为 D i v。输出响应写入文件以便于以后进行比较。
m o d u l e D i v (Ck,Reset,TestN,Ena) ;
i n p u t Ck,Reset,TestN;
o u t p u t E n a;
r e g [0:3] C o u n t e r;
al w a y s
@ (p o s e d g e C k) b e g i n
i f (~ R e s e t)
Counter = 0;
e l s e
b e g i n
i f (~ T e s t N)
Counter = 15;
e l s e
Counter = Counter + 1
e n d
e n d
assign E n a = (C o u n t e r = = 15)? 1,0;
e n d m o d u l e
m o d u l e D i v _ T B;
i n t e g e r O u t _ F i l e;
r e g Clock,Reset,TestN;
w i r e E n a b l e;
i n i t i a l
Out_File = $fopen ("out.vec");
a l w a y s
b e g i n
#5 C l o c k = 0;
#3 C l o c k = 1;
e n d
Div D1 (Clock,Reset,TestN,Enable) ;
i n i t i a l
b e g i n
Reset = 0;
#50 Reset = 1;
e n d
i n i t i a l
b e g i n
TestN = 0;
#100 TestN = 1;
#50 TestN = 0;
#50 $f c l o s e (O u t _ F i l e) ;
$f i n i s h; //模拟结束。
e n d
/ /将使能输出信号上的每个事件写入文件。
i n i t i a l
$f m o n i t o r (O u t _ F i l e,"Enable changed to %b at time %t",E n a b l e,$time);
e n d m o d u l e
模拟执行后,文件,o u t,v e c”所包含的输出结果如下:
Enable changed to x at time 0
Enable changed to 0 at time 8
第 11章 验 证 129下载
Enable changed to 1 at time 56
Enable changed to 0 at time 104
Enable changed to 1 at time 152
11.6.2 阶乘设计本例介绍产生输入激励的另一种方式,在该方式中,根据待测模块的状态产生相应的输出激励。该输出激励产生方式对有穷状态自动机( F S M)的模拟验证非常有效,因为状态机的模拟验证需根据各个不同的状态产生不同的输入激励。设想一个用于计算输入数据阶乘
( f a c t o r i a l )的设计。待测试模块与测试验证模块之间的握手机制如图 11 - 9所示。
图 11-9 测试验证模块与待测试模块间的握手机制模块的输入信号 R e s e t将阶乘模型复位到初始状态,在加载输入数据 D a t a后,S t a rt信号被置位;计算完成时,对输出 D o n e置位,表明计算结果出现在输出 F a c _ O u t和 E x p _ O u t上。阶乘结果值为 F a t _ O u t * 2E x p _ O u t,测试验证模块在 D a t a上提供从值 1开始递增到 2 0的输入数据。测试验证模块加载数据,对 S t a rt信号置位并等待 D o n e信号有效,然后加载于下一输入数据。若输出结果不正确,即打印错误信息。阶乘模块及其测试验证模块描述如下:
` t i m e s c a l e 1ns / 1ns
m o d u l e FACTORIAL (Reset,StartSig,Clk,Data,Done,
FacOut,ExpOut) ;
i n p u t Reset,StartSig,Clk,
i n p u t [4:0] D a t a;
o u t p u t D o n e;
o u t p u t [ 7,0 ] FacOut,ExpOut;
r e g S t o p;
reg [4,0] I n L a t c h;
r e g [7:0] Exponent,Result;
integer I;
i n i t i a l S t o p = 1;
a l w a y s
@ (p o s e d g e C l k) b e g i n
i f (( S t a r t S i g = = 1) && (Stop = = 1) && (Reset = = 1))
b e g i n
R e s u l t = 1;
E x p o n e n t = 0;
InLatch = D a t a;
130 Verilog HDL 硬件描述语言 下载驱动器被测试的模块监控器
Stop = 0;
e n d
e l s e
b e g i n
if (( InLatch > 1) && (Stop = = 0)
begin
Result = Result * InLatch;
InLatch = InLatch - 1;
e n d
i f (I n L a t c h < 1)
Stop = 1;
/ /标准化:
f o r (I = 1; I <= 5; I = I + 1)
i f (Result > 2 5 6 )
b e g i n
R e s u l t = R e s u l t / 2;
Exponent = Exponent+ 1;
e n d
e n d
e n d
a s s i g n Done = Stop;
a s s i g n FacOut = Result;
a s s i g n ExpOut = Exponent;
e n d m o d u l e
m o d u l e F A C _ T B;
p a r a m e t e r I N _ M A X = 5,O U T _ M A X = 8;
p a r a m e t e r RESET_ST = 0,START_ST = 1,A P P L _ D A T A _ S T = 2,
W A I T _ R E S U L T _ S T = 3;
r e g Clk,Reset,Start;
w i r e D o n e;
r e g [I N _ M A X-1,0] Fac_Out,Exp_Out;
i n t e g e r N e x t _ S t a t e;
p a r a m e t e r MAX_APPLY = 20;
i n t e g e r N u m _ A p p l i e d;
i n i t i a l
Num_Applied = 1;
a l w a y s
b e g i n,C L K _ P
#6 Clk = 1;
#4 Clk = 0;
e n d
a l w a y s
@ (n e g e d g e C l k) //时钟下跳边沿触发
c a s e (N e x t _ S t a t e)
第 11章 验 证 131下载
R E S E T _ S T:
b e g i n
R e s e t = 1;
S t a r t = 0;
Next_State = APPL_DATA_ST;
e n d
A P P L _ D A T A _ S T,
b e g i n
Data = Num_Applied;
Next_State = START_ST;
e n d
S T A R T _ S T,
b e g i n
Start = 1;
Next_State = WAIT_RESULT_ST;
e n d
W A I T _ R E S U L T _ S T:
b e g i n
Reset = 0;
Start = 0;
w a i t (Done = = 1);
i f (N u m _ A p p l i e d = =
Fac_Out * ('h0001 << E x p _ O u t) )
$d i s p l a y ("Incorrect result from factorial",
"model for input value %d",Data) ;
Num_Applied = Num_Applied + 1;
if (Num_Applied < MAX_APPLY)
Next_State = APPL_DATA_ST;
e l s e
b e g i n
$d i s p l a y ( "Test completed successfully" ) ;
$f i n i s h; //模拟结束。
e n d
e n d
d e f a u l t,
Next_State = START_ST;
e n d c a s e
/ /将输入激励加载到待测试模块:
FACRORIAL F1 (Reset,Start,Clk,Data,Done,
Fac_Out,Exp_Out) ;
e n d m o d u l e
11.6.3 时序检测器下面是时序检测器的模型。模型用于检测数据线上连续三个 1的序列。在时钟的每个下沿检查数据。图 11 - 1 0列出了相应的状态图。带有测试验证模块的模型描述如下:
132 Verilog HDL 硬件描述语言 下载
m o d u l e Count3_ls (Data,Clock,Detect3_ls) ;
i n p u t Data,Clock;
o u t p u t D e t e c t 3 _ l s ;
i n t e g e r C o u n t ;
r e g D e t e c t 3 _ 1 s;
initial
b e g i n
Count = 0;
Detect3_ls = 0;
e n d
a l w a y s
@ (n e g e d g e C l o c k) b e g i n
i f ( D a t a = = 1)
Count = Count + 1;
e l s e
Count = 0;
i f (Count >= 3)
D e t e c t 3 _ l s = 1;
e l s e
Detect3_ls = 0;
e n d
e n d m o d u l e
m o d u l e To p;
r e g Data,Clock;
i n t e g e r O u t _ F i l e;
/ /待测试模块的应用实例。
Count3_ls F1 (Data,Clock,Detect ) ;
i n i t i a l
b e g i n
C l o c k = 0;
f o r e v e r
#5 Clock = ~ Clock;
e n d
i n i t i a l
b e g i n
D a t a = 0;
#5 Data = 1;
#40 D a t a = 0;
#10 D a t a = 1;
#40 D a t a = 0;
#20 $s t o p; // 模拟结束。
e n d
第 11章 验 证 133下载
134 Verilog HDL 硬件描述语言 下载
i n i t i a l
b e g i n
/ /在文件中保存监控信息。
O u t _ F i l e = $f o p e n ( " r e s u l t s,v e c t o r s " ) ;
$f m o n i t o r (O u t _ F i l e,"Clock = %b,Data = %b,Detect = %b",
C l o c k,Data,Detect);
e n d
e n d m o d u l e
图 11-10 时序检测器习题
1,产生一个高电平持续时间和低电平持续时间分别为 3 ns和 10 ns的时钟。
2,编写一个产生图 11 - 11所示波形的 Verilog HDL模型。
图 11-11 波形
3,产生一个时钟 C l o c k V,该时钟是模块 G e n _ C l k _ D中描述的时钟 C l k _ D(如图 11 - 6所示 )的相移时钟,相位延迟为 15 ns。 [提示:用连续赋值语句可能会不合适。 ]
4,编写测试时序检测器的测试验证程序。时序列检测器按模式 1 0 0 1 0在每个时钟正沿检查输入数据流。如果找到该模式,将输出置为 1;否则输出置为 0。
5,编写一个模块生成两个时钟,C l o c k A和 C l o c k B。 C l o c k A 延迟 10 ns后有效,C l o c k B延迟 4 0
n s后有效。两个时钟有相同的高、低电平持续时间,高电平持续时间为 1 ns,低电平持续时间为 2 n s。 C l o c k B与时钟 C l o c k A边沿同步,但极性相反。
6,描述 4位加法 /减法器的行为模型。用测试验证模块测试该模型。在测试验证模块内描述所有输入激励及其期望的输出值。将输入激励、期望的输出结果和监控输出结果转储到文本文件中。
7,描述在两个 4位操作数上执行所有关系操作 (<,<=,>,>=)的 A L U。编写一个从文本文件中读取测试模式和期望结果的测试验证模块。
8,编写一个对输入向量作算术移位操作的模块。指定输入长度用参数表示,缺省值为 3 2。同时指定移位次数用参数表示,缺省值为 1。编写一个模拟、测试模块以验证对 1 2位向量进行
8次移位算术操作的正确性。
9,编写 N倍时钟倍频器模型。输入是频率未知的参考时钟。输出时钟的倍数与参考时钟的每个正沿同步。 [提示:确定参考时钟的时钟周期。
10,编写一个模型,显示输入时钟每次由 0转换到 1的时间。
11,编写一个计数器模型,该计数器在 C o u n t _ F l a g为 1期间对时钟脉冲 (正沿 )计数。如果计数超过 M A X _ C O U N T,O v e r F l o w被置位,并且计数值停留 在 M A X _ C O U N T界限上。 C o u n t _ F l a g
的上沿促使计数器复位到 0,并重新开始计数。编写测试验证模块,并测试该模型的正确性。
12,编写参数化的格雷( G r a y)码计数器,其缺省长度是 3。当变量 R e s e t为 0时,计数器被异步复位。计数器在每个时钟负沿计数。然后在模拟验证模块中对 4位格雷码计数器进行测试验证。
13,编写一个带异步复位的 T触发器的行为模型。如果开关为 1,输出在 0和 1之间反复。如果开关为 0,输出停留在以前状态。接下来用 s p e c i f y块指定 T触发器的数据建立时间为 2 ns,保持时间为 3 ns。编写模拟测试模块以测试该模型。
第 11章 验 证 135下载