下载 第11章验证 本章介绍了如何编写测试验证程序( test bench)。测试验证程序用于测试和验证设计的正 确性。 Verilog hdl提供强有力的结构来说明测试验证程序, 11.1编写测试验证程序 测试验证程序有三个主要目的 1)产生模拟激励(波形)。 2)将输入激励加入到测试模块并收集其输出响应 3)将响应输出与期望值进行比较 Ⅴ erilog HDl提供了大量的方法以编写测试验证程序。在本章中,我们将对其中的某些方 法进行探讨。典型的测试验证程序形式如下: 通常测试验证程序没有输入和输出端I cal reg and net declarations Generate waveforms using initial always statements Instantiate module under test Moni tor output and compare with expected values endmodule 测试中,通过在测试验证程序中进行实例化,激励自动加载于测试模块。 112波形产生 有两种产生激励值的主要方法: 1)产生波形,并在确定的离散时间间隔加载激励。 2)根据模块状态产生激励,即根据模块的输出响应产生激励。 通常需要两类波形。一类是具有重复模式的波形,例如时钟波形,另一类是一组指定的 值确定的波形。 11.21值序列 产生值序列的最佳方法是使用 initial语句。例如 in⊥t⊥a1 Reset= #100 Reset=1 #80 Reset =0 #30 Reset 产生的波形如图11-1所示。 Initial语句中的赋值语句用时延控制产生波形。此外,语句内 时延也能够按如下实例所示产生波形
下载 第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语句中的赋值语句用时延控制产生波形。此外,语句内 时延也能够按如下实例所示产生波形
第章验证 119 下载 ⊥n⊥tia1 beG⊥n Reset =0 Reset =#800; Reset =#30 1 end Reset 图11-1使用 initial语句产生的波形 因为使用的是阻塞性过程赋值,上面语句中的时延是相对时延。如果使用绝对时延,可 用带有语句内时延的非阻塞性过程性赋值,例如, initial begin Reset Reset < #100 1 Reset <=#1800 Reset<=#2101; 这三个 initial语句产生的波形与图11-1中所示的波形一致。 为重复产生一个值序列,可以使用 always语句替代 initial语句,这是因为 initial语句只执行 次而 al ways语句会重复执行。下例的 always语句所产生的波形如图12所示。 parameter REPEAT DELAY= 35 integer Coinvalue always begin co⊥ n value=0 #7 Coinvalue 25 #2 Coinvalue=5 #8 Coinvalue= 10 #6. Coinvalue =5 排 REPEAT DELAY Coin value o251050510 个周期 图12使用 always语句产生的重复序列 1122重复模式 重复模式的生成通过使用如下形式的连续赋值形式加以简化
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 下载 一个周期
120 Verilog hdl硬件描述语言 下载 assign #(PERIOD/2) clock = clock; 但是这种做法并不完全正确。问题在于 Clock是一个线网(只有线网能够在连续赋值中被赋 值),它的初始值是z,并且,z等于x,~x等于x。因此Cock的值永远固定为值x。 现在需要一种初始化 Clock的方法。可以用 initial语句实现。 in⊥七ia1 但是现在 Clock必须是寄存器数据类型(因为只有寄存器数据类型能够在 initial语句中被赋 值),因此连续赋值语句需要被变换为 always语句。下面是一个完整的时钟产生器模块。 module Gen Clk A(Clk A output CIk A: reg clk parameter tPERIOD= 1( ⊥n主七ia1 ClK A=0 always #(tPERIOD/2) clk A=-Clk A 图11-3显示了该模块产生的时钟波形 Clk_A 」「1「L「L 20 30 图11-3周期性的时钟波形 下面给出了产生周期性时钟波形的另一种可选方式。 module Gen Clk B(Clk B) output Clk B start =1 end nor #2(Clk B, Start Clk B)i endmodul //产生一个高、低电平宽度均为2的时钟 initial语句将Sant置为1,这促使或非门的输出为0(从x值中获得)。5个时间单位后,在 iar变为0时,或非门反转产生带有周期为4个时间单位的时钟波形。产生的波形如图11-4所 如果要产生高低电平持续时间不同的时钟波形,可用 always语句建立模型,如下所示 module Gen Clk C(clk C) parameter toN 5, tOFF =10 output Clk C
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 硬件描述语言 下载
Chinaopub.com 第1验证121 下载 reg Clk c begin Cik C= 0 tOFF Clk C=1 endmodul Start 图11-4受控时钟 因为值0和1被显式地赋值,在这种情况下不必使用 initial语句。图11-5显示了这一模块生 成的波形。 为在初始时延后产生高低电平持续时间不同的时钟,可以在 initial语句中使用 forever循环 语句。 Clk C 「L 图11-5高低电平持续时间不同的时钟 module Gen Clk D (CIk D) output Clk D; parameter START DELAY 5, LOW TIME 2, HIGH TIME =3 ⊥n⊥tia1 begi Clk D =0: START DELAY forever begin 普 LOW TIME; Clk D= 1 HIGH TIME Clk D=0 上面模块所产生的波形如图11-6所示 为产生确定数目的时钟脉冲,可以使用 repeat循环语句。下面带参数的时钟模块产生一定 数目的时钟脉冲数列,时钟脉冲的高低电平持续时间也是用参数表示的
第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循环语句。下面带参数的时钟模块产生一定 数目的时钟脉冲数列,时钟脉冲的高低电平持续时间也是用参数表示的
122 Verilog hdl硬停横述语言 下载 CIK E parameter Tburst 10, Ton =2, Toff =5 initial begin CIK E=1'b0: repeat( Burst begin Toff Clk E=1b1 Ton Clk E= 1'b0 Clk D 202225 图11-6带有初始时延的时钟 模块 Gen Clk e在具体应用时,参数 Burst、Ton和To〃可带不同的值 module Test wire Clk Ea, Cik Eb, Cik Ec Gen Cik E GIClk Ea //产生10个时钟脉冲,高、低电平持续时间分别为2个和5个时间单位 Gen Cik E (5, 1,3) Clk Eb) /产生5个时钟脉冲,高、低电平持续时间分别为1个和3个时间单位。 Gen Clk E #(25,8, 10) Ik Ec)i //产生25个时钟脉冲,高、低电平持续时间分别为8个和10个时间单位 Clk eb的波形如图11-7所示 Clk eb 3478111215161920 图11-7确定数目的时钟脉冲 可用连续赋值产生一个时钟的相移时钟。下述模块产生的两个时钟波形如图11-8所示。 个时钟是另一个时钟的相移时钟 module Phase (Master Clk, Slave C2l output Master Clk, Slave Clki
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 硬件描述语言 下载
Chinaopub.com 第1验证123 载 wire slave Clk parameter toN= 2, toFF =3, tPHASE DELAY= 1; #toN Master Clk= 0 e toFF Master cik assign井 t PHASE DELAY S1aveC1片 Master Clk endmodule Master Clock 113测试验证程序实例 11.3.1解码器 下面是2-4解码器和它的测试验证程序。任何时候只要输入或输出信号的值发生变化,输 信号的值都会被显示输出 module Dec2x4(A, B, Enable, e input output [0:32 wire Abar, Bbar not#(1,2) V1(Bar, B)i No(Z [0], Enable, Abar, Bbar 1(z[1],Enab1e,A上 N2(Z[2], Enable, A, bbar, N3(Z[3,Enable, A, B wire [0:3 Dz/ //被测试的模块: Dec2x4 Di(Da, Db, Dena, DEi
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 下载
124D)硬件述语言 Chinapub.com 下载 //产生输入激励 in⊥七ia1 begin Dena #10 Dena =1 #10Da #10Db=1 #10Db=0; #10 sstop //输出模拟结果: e( Dena or Da。 r Db or Dz) disp⊥ay(" At time各t, input⊥s旨b詈bb, output⊥s,b stime, Da, Db, Dena, Dk; endmodule 下面是测试模块执行时产生的输出。 At time output is 1111 t time 10, input is 001, output is 1111 At time 13, input is 00l, 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 1ll, output is 1101 At time .t time 36, input is 1ll, output is 1110 At time 40, input is 0ll, output is 1110 At time tis011,。 utput is1011 At time 50, input is 001, output is 1011 At time 54, input is 001, output is 0111 1132触发器 下例是主从D触发器及其测试模块 module MSDFF (D, C, Q, obar output o, obar NT1(NotD, D) NT2(NotC, C) NT3(NotY, Y) D, g ND3(¥,D1,Yba↓
/ /产生输入激励: 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 硬件描述语言 下载
Chinaopub.com 第1验证125 下载 ND6(Y2, NotY, Notc MD7(Q,Qbar,¥J ND8 (Obar, Y2,oi odule Test SDFF MI(D,C, 0, QA always in⊥tia1 #40D=0 sstop end in⊥tia1 s monitor ("Time t :: time,"C=tb, D=b, Q=bb Qb=b", C,D, 0, ob 在此测试验证模块中,触发器的两个输入和两个输出结果均设置了监控,故只要其中任 何值发生变化就输出指定变量的值。下面是执行产生的输出结果 ⊥me= 0::C=0,D=0,Q=x,Qb= 5::c=1,D=0,Q=x,Qb=x Time= 35::C=1,D=0,Q=0,Qb=1 40::C=0,D=1,Q=0,Qb= Time= 50::C=0,D=1,Q=1,Qb=0 55::C=1,D=1,Q=1,Qb=0 Time= 60::C=0,D=1,Q=1,Qb=0 65::C=1,D=1,Q=1,Qb= 80::C=0,D=0,Q=1,Qb=0
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 下载
126wimD硬停述语言 Chinapub.com 下载 Time= T ame= Time= 95::C=1,D=0,Q=0,Qb=1 Time 100::C=0,D=0,Q=0,Qb= T⊥me 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= 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= C=0,D=1,Q=1,Qb=0 Time= C=1,D=1,Q=1,Qb=0 114从文本文件中读取向量 可用 Sreadmemb系统任务从文本文件中读取向量(可能包含输入激励和输出期望值)。下 面为测试3位全加器电路的例子。假定文件“ test vec”包含如下两个向量 期头的Sum 010010 0d01l1 头的Cout 向量的前三位对应于输入A,接下来的三位对应于输入B,再接下来的位是进位,八到十 位是期望的求和结果,最后一位是期望进位值的输出结果。下面是全加器模块和相应的测试 验证程序。 module AdderiBit(A, b, cin, Sum, Cout input A,B,c⊥n, output sum, Cout assign Sum =(A B Cin ssign Cout =(A B)I(A& Cin)I(b& Cin)i endmodule module Adder3Bit (First, second, Carry In, Sum Out, Carry put input [0: 2] First, second input Carry in output [0: 2] Sum Out output Carry outi Adder ibit Al (First [2], Second[2], Carry In, Sum out[2], Car[1]) A2 (First[l], Second[l], Car[l, Sum Out [l, Car[o]), A3(F⊥rst[0] ond[o], Car [o], Sum Out [0], Carry out)i
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; 期头的 期头的
第1取验证127 载 parameter BITS =1l, WORDS= 2; reg [1: BITS] Vmem [1: WORDS]; reg [0: 2]A, B, Sum Ex; reg cin, Cout Ex integer J wire [0: 2] Sum wire cout: /被测试验证的模块实例 Adder3Bit FI(A, B, Cin, Sum, Cout in⊥tia1 begin Sreadmemb ("test. vec",Vmem =1: J<= WORDS; J=J+ 1) begin (A, B, Cin, Sum Ex, Cout Ex Vmem [J]i 5;//延迟5个时间单位等待电路稳定 if((Sum ! = Sum Ex)I 1( Cout = Cout Ex)) Display ("****Mismatch on v Display ("No mismatch on vector b"Wmem [J]) end 测试模块中首先定义存储器Vmem,字长对应于每个向量的位数,存储器字数对应于文件 中的向量数。系统任务$ readmemb从文件“ test vec”中将向量读入存储器Imem中。for循环 通过存储器中的每个字,即每个向量,将这些向量应用于待测试的模块,等待模块稳定并探 测模块输出。条件语句用于比较期望输出值和监测到的输出值。如果发生不匹配的情况,则 输出不匹配消息。下面是以上测试验证模块模拟执行时产生的输出。因为模型中不存在错误 因此没有报告不匹配情形 No mismatch on vector 01001001000 No mismatch on vector 01001111100 115向文本文件中写入向量 在上节的模拟验证模块实例中,我们看到值如何被打印输出。设计中的信号值也能通过 如$ display、 Sfmonitor和 Sfstrobe等具有写文件功能的系统任务输出到文件中。下面是与前 节中相同的测试验证模块实例,本例中的验证模块将所有输λ向量和观察到的输岀结果输岀 module F Test Bench parameter BITS =11, WORDS= 2 reg [1: BITS] Vmem [1: wORDS]i reg [0: 2]A, B, Sum Ex reg Cin, Cout Ex
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 下载