1 引言 * A3 P/ Z! [3 I4 C; L# `+ h 8 C8 x; `8 t1 ^ C 4 g/ \$ d" k/ f f ^5 L5 r1 \) i1 f
- d0 Y3 @9 U+ p) r1 c 在对复杂数字系统进行仿真测试时,设计者常常面对测试向量数量庞大而难以实现的问题。以数字图像处理系统的仿真测试为例,如果采用完备性测试方法.那么所需测试向量的数量将非常巨大,甚至无法实现:而采用测试向量波形图或者用HDL语言描述等常用方法.不仅仿真测试工作的效率低下,而且工作量巨大。在数字图像处理系统中,一帧320x240的数字图像所产生的测试向量数量达到320x240x2=153 600个。无论采用完备性测试方法还是向量波形图或者.HDL语言描述的方法,由于测试向量的数量极其巨大,采用这些方法都难以进行仿真测试。. t' w c8 i6 x c! h
6 ?, V( s* P/ c" e3 u6 J. x7 l* t
$ C7 a) R5 u" B! V1 e. e$ w8 `3 } * ~' K. l i" |. K6 A7 N 针对这个难题,笔者提出一种进行仿真测试的新方法.该方法应用TEXTI0和:MATLAB来辅助仿真测试过程.使测试向量数量巨大、难以处理的难题得到很好的解决。以电视视频系统中实时多目标捕获单元的仿真测试为例.对这种新方法进行全面的讨论。* H( L* s# L: l2 ~! x! R
1 y# \) g! b6 |! ~! z7 P5 S+ v - x2 t8 A% O# i: L- m3 t; Q$ h6 N: C( I: r; H: h e
2 基于TEXTIO的VlII)L仿真 4 |. r3 N ^/ h0 j. O5 U6 [' t' @' X" ?
1 n& o" O- p F8 n0 j- l* p. [ $ H% w7 F j8 {9 V0 L7 m 2.1 TEXTIO的功能 " l6 u! _0 L6 U: x5 k$ u' K: K! _
8 t' c- X& t, s+ z+ N! U2 ^3 h9 D N
TEXXTl0是VHDL标准库STD中的程序包(Package),它提供了VHDL与磁盘文件直接访问的桥梁。TEXTIO定义了3种类型:LINE类型、TEXT类型及SIDE类型。TEXTI0在程序包中定义了一些访问文件的过程(Procedure)。 " E. O' a3 Q" ~& R3 H 0 T4 u5 ]- f- k3 Z6 _ . D7 F4 F0 H, }- r( t: Y
$ f1 r# P$ m: o3 U4 F$ V
TEXTIO提供的基本过程有:$ d. j8 B5 ?6 Q5 t
3 V) b4 {; {% {1 l3 O ) \+ K- o j9 b) ^; b3 b3 o* u- k7 v
/ k3 b( d5 h& F7 u- X ' Z0 V; g4 y! }& A/ M$ C1 R* ?! S8 y' e
. S& u! Z; N$ z1 ?9 r. y
. r H$ x- h6 M9 J& A! x 2.3 仿真测试步骤 ' U, v; @2 C! i$ W " c$ J& P$ n8 n 7 z- f8 _2 P3 Z7 l8 Y% J4 x9 c- F
2.3.1 使用MATLAB生成测试激励文件. M) j' T5 V8 c. [) N4 k
! f1 |3 T, t! O, r$ b7 @- i8 y7 Q6 U
9 z3 s+ m- \! C% w' ?# k' \
+ C( B- ~* Z- W MATLAB是矩阵实验室(Matrix Laboratory)的缩写,是1984年MathWorks公司推出的软件。经过20多年的发展,MATLAB已成为通用科技计算、图视交互系统和程序语言,广泛应用于研究和解决各种具体工程问题。4 }- g/ R' ?0 v* S3 X$ r& N6 H
# `7 \- Z0 k# {+ R( `, B 2 Y9 Y7 ^2 u" t1 W5 {% F# U' F$ D! w' s. K% S; j* ~) `4 y t3 }
在复杂数字系统仿真中,用户可以利用MAT-LAB的强大处理功能生成测试激励文件。测试激励文件的数据格式由设计者自行定义。测试激励文件应包含输入信号的测试激励数据.也可以包含输出信号的期望输出数据.这些内容常常以.ASCII码表示。 7 ^, G4 W" z( [6 J. g- P6 S7 a: E
; x, F) o h/ |* J6 f
2 F- x. O4 M, @9 J) d( v$ Y
2.3.2 编写TestBench I$ N, H9 k) c7 j6 F
8 O3 f, |( }/ x4 ?
. h, A6 ]* F' g) i2 ]1 l
9 p; V M0 Q: Q& K0 e TestBench是测试平台程序。TEXTI0的使用是通过TestBench来进行的,TestBench利用TEXTIO读取测试激励文件或写入仿真结果输出。进行复杂数字系统仿真时,用户根据测试的目的和要求设计TestBench。0 W, }! E- [. Y3 P. F: B. P
7 T. [4 [" {7 Y . S- s; T' y5 u1 {0 U' u& {0 p! F6 B, h9 D7 N
2.3.3 在Modelsim中进行仿真+ ]2 M. F7 a* n& R1 @
% |7 U R9 z5 o+ m 1 G5 I2 R! p$ e- V% p+ i3 Y
! _+ i2 D( z5 z* x
Modelsim是Model Technology(Mentor Graphics的子公司)的HDL(Hardware Description Language)仿真软件。可以实现VHDL、Verilog及VHDL一Ver-ilog混合设计的仿真。Modelsim为’TestBench提供一种良好的HDL仿真环境。 C3 A+ Y4 I$ {7 ^ O( A2 T; Q. |
1 E5 m7 {$ E+ z+ h
2 S. i' `5 w2 D# M4 m/ M, [* f9 `2 z
2.3.4 结果分析 % s' L0 @) ^. q9 x: z/ \9 o, ]* l' H* U& C6 x& F
7 @& }& M" @. u1 q4 y
2 Z% X" ~; F0 ^
仿真结束后,仿真结果是否符合要求,用户可以通过二种方法来判断。一种是应用软件自动判断。即通过TestBench或其他软件(如MATLAB)对仿真输出结果和期望输出结果进行对比,从而得到分析结果:另外一种是人工判断.即设计者自行对仿真输出结果和期望输出结果进行对比,从而得到分析结果。 - R6 h8 l; }7 A 2 W/ x' c; a2 G8 }$ N' P- ]; t7 k # x4 V2 R% o9 G5 d$ R
8 `3 W+ Z) ^1 `9 l! q
3 仿真测试实例 - D n5 p" ]; ^# l! O- Z8 }3 P* Q9 \% C% }5 z' S6 Q M1 t, I. e
( m& [4 n$ H7 d& M1 z$ {. [- l$ E3 p. \
3.1 电视图像实时目标捕获单元功能( c$ g [6 Q& k3 g: {7 u7 R
5 ~9 y% ~3 E" H. r; ~! s, z
. \3 G6 D3 E8 a; E# \# p 8 F3 {. v6 L/ G) p 电视图像实时目标捕获单元(以下简称待测单元)具有对电视图像中的目标图像进行实时捕获的功能。本例将用TEXllO和MATLAB辅助Test-Bench对待测单元进行仿真测试。 4 M Q) S+ C+ W. V5 y 2 Z0 [4 Y6 k9 k0 Z! k . r* e9 Y9 A7 p8 G/ u5 Y' S3 n0 G2 H5 {, k* l! B/ |
3.2 需要产生的测试信号及波形 & K4 n4 i* C# v z/ k% t V: ?! b2 I8 j! V2 K: {0 b
8 _3 F) R5 B: K- @( U6 d 0 ], _7 b$ b8 V6 \' r% w% L 待测单元输入信号的时序如图2所示。其中,clk、vsy、hsy和ccd分别代表像素时钟、数字化后的场同步、行同步和二值图像信号。 6 M0 P: D7 Q7 Y5 }1 @ r& M . F$ ^! h( ^3 o * x) F, x+ x* h
2 o6 U) Z0 |$ b, ] 4 |6 F' j% Z# O0 e# j
0 p7 H1 n8 K' E4 x8 x
用户设计的测试激励信号即测试激励文件中输入信号的激励数据,应符合图2所示时序的要求。( q1 ]* e) @+ j# W- Y+ n. V
4 P0 Y% k$ m1 E' J" Z
( \4 y# A3 }- |1 P
/ y# B; w2 Z, F # d7 S; a' Y x& @: E+ u1 [
- i! I; R1 e! c( T7 D9 L- j/ B! X
以下是生成测试激励程序的核心代码: 7 | v: S2 A' G7 ^/ D* z % m6 s! E+ p/ q image=imread(‘pic.bmp’);%读取图像文件" \- ?* p( t# ?2 Y) c. @& ?
: A, h3 Q4 U4 N
[YN,XN]=size(image); %得到图像大小# Z6 q8 f" }7 r- i5 X' o
1 |% {, v& O( N0 c
FZ=20; %晶体振荡器频率(MHz): B+ J3 M9 }* z/ r, n) `- e& F7 E- C
0 L, g* ]2 I$ m' U* w1 V! i8 k
%定义常数 %对应于图2所示的时序 # }- O' |1 ~8 O4 e 5 x6 O3 ^( Y$ P: n POSTIME=52.2; %行正程时间(μ8)7 W- C5 E/ [% a5 ?3 h
$ ]$ n: }& X$ m) w' E: G4 f NEGTIME=11.8; %行逆程时间(μs), W3 Z! M, _# E8 i. U. U/ O
! U$ {# @$ F' `9 ] p. \3 v HORTIME=64;%行正逆程总时间' `% q( U3 r6 P/ B2 D" Y- A' n6 J
: C N: W( Q( s5 ]6 x7 J9 ?" }* ^
VSYTIME=1615; %场信号时间(μB)5 z2 ^: w7 N8 A
$ k4 E3 [6 }: X" J
PPDOT=POSTIME*FZ/XN; %行正程时间*晶体振: k |2 s$ y/ E5 D) S
8 O \, L4 \0 m% b 荡器频率,图像X方向分辨率 0 V; k4 C+ K6 F5 D ' U3 h. n$ R# [! D, ~) K …… * Q0 Y& |% ]% I3 m$ m* _0 [$ X' v& P: B c- ^0 u4 v
0 W3 a4 n. E9 n8 P- P7 U2 l+ f
$ l+ @4 T2 O, u# E+ v8 q fid=fopen(‘TestVectors.inp’,‘W’) ;%指定测试激励文件的文件名称 h& K) W* q' q: Z
# Q( W" Q0 {) b+ x& R# a
for j=1:1:YN;- W! \5 G; i, x( h1 l1 a
, Q3 D4 L7 ^* t* s/ Q* l yy_j;xx=0; 8 v% ]7 z5 ~# I! h, `* I ; c: c7 c1 x# O6 C5 a for i=l:1:HORTIME*FZ;0 z* a) p. Q" k% I1 R6 N
* y! P( f( w3 o9 {1 o %产生行同步激励 1 d8 c0 {. {' q: N4 A- b' Y: }9 e8 v) K8 j; Q+ P" w
if(i<(HFNTIME+HDLTIME)*FZ)(i>(HFNTIME+HDLTIME+HSYTIME)*FZ)- E9 [, _" U* e* P5 A9 \2 x
! z' B' K% R* Q. M3 A5 I0 j hsy=l; . A& ]$ y' }3 ~7 e3 w4 _9 Z- _% l2 F6 ~
else% N! M$ R$ v4 U" P$ S) m, E" ]
2 d% S6 n% p% |" X; {8 d; Z
hsy=0; 0 y4 y, C9 U- e y, R, {+ e+ a) u # W7 Q3 `/ N2 Y8 M* D' | end;0 ?. M; p& H0 a( ~, @
# Z( h! J1 v, A$ ?$ X
%产生像素时钟激励: t3 [7 }7 a. }+ L- s; N
; E$ G4 v* m, T
if clk==1 5 \* {" E8 _: Y9 o7 q0 w( I. e6 i. w# }7 g; p! K2 Q
clk=0;( e/ {, X4 |. w8 N
# u/ {0 q5 [1 X; p6 N
else3 V9 t& w; H8 Q- B, d; }
! M: e }2 U# R( V
clk=l; $ G4 E, l& w5 H0 x3 ^) G7 X+ Z3 q; r" ~1 W L6 f+ s) F5 f
end;; J4 j" I8 U+ n) B, E+ h
) f6 v6 |; T. V5 a
%产生CCD激励 ! u( d: V9 b, l3 {- }8 `. V/ c) f* |& s9 U2 l
if i>NEGTIME*FZ & R; M( U1 l0 H: W: P# n8 n1 F' z2 d4 j
xx=round((i-NEGTIME*FZ)/PPDOT+0.45): 1 f' P5 p6 l; a; [1 @/ p- c5 g$ Y: T. L- O( G( a( X
ccd=round(image(yy,xx)); 6 |0 Q$ n/ b2 p: F! L# C ! @* \& n! h O1 k; ~2 D4 l C) Z else 2 S( x ~9 w4 T; ?* H ' W2 b2 D/ p" @: Q. q ccd=0;% _/ z/ @/ s$ E4 z9 z
) p* H' h! t, J& f. S end;2 D" d2 [) M9 H j
7 J. h/ X: a- p0 D2 C8 b% C
%将激励写入测试激励文件 3 v8 V; t) h) o2 | 4 e* @7 S6 i, i* @5 J2 y$ O fprintf md.‘%d%d%d%d%d%d、Il’,clk,ccd,hsy,vsy); 7 a' u" S/ h4 C$ `" b% `, D: m1 J3 O& B& _4 u* n7 [3 a' ~
end;' ~3 _7 z8 s& f2 F& L8 n# k( o0 u
; a$ \( W; Y4 W' J# X6 w
end; $ h& f0 ~0 v8 B' P2 H; Z' L ) w8 m+ P+ p: `; k6 y& f5 _ 产生的测试激励文件名称为TestVectors.inp,激励内容以ASCII码表示,信号之间用空格隔开,且一行代表一次激励。下面是测试激励文件中的一段内容,激励包含clk,ccd,hsy,vsy 4个信号:7 S4 k2 h9 Z' p; V
7 i( L6 n* P- P+ ^! j$ F 0 0 1 1—clk=0 eed=0 hsy=l vsy=l B3 ]1 E3 d$ m% i3 V1 r/ U. Y% Y) n2 h
8 @/ n1 X8 l N
1 0 1 1—clk=l ccd=0 hsy=l vsy=1! U9 J2 }6 c- n1 U
/ @3 a: E& b5 y/ r4 l1 r
… $ k3 \+ s1 T4 a0 R$ Y1 g/ ~$ C, F3 I- ~& U: P9 C8 j
6 r @# \; }: @. w$ O* J3 n- D3 W( j4 r
' ?- }% ^/ Q, [ u% y& ~ 0 0 0 1——clk=O ccd=0 hsy=0 vsy=1 * F. n9 L" r0 s& }& N& H1 z$ w* ?4 D/ e$ ?" L
… ' C# f& \0 V8 _4 t$ t$ }" G " J0 J3 n: A: a, Y! G , y3 d, r6 I: F0 U" ^4 j9 U: e& @' C) ]7 i
进行仿真时。TestBeneh应用TEXTIO通过逐行读取测试激励文件得到待测单元输入信号的激励。3 \3 O: {# C! Z* }- P
, E$ S% }' K# Z
! P A$ t( N. _' a, v9 }8 f3 a- X4 [, ?+ Z
3.4 编写TestBench5 [; }7 v3 n: \9 B
$ a* a7 y9 R# d' |9 m0 J5 C7 a 9 V! C+ S( s {) r5 b
; W" V' ]0 V- o. C
TestBench调用TEXTIO读取测试激励文件得到激励,然后将这些激励分别驱动到待测单元的输入端口。同时,TestBench读取待测单元的输出结果,调用TEXTIO将仿真输出结果写入文件名称为Re-sult.out的仿真结果输出文件。( d6 T. i z3 M4 \( [+ c6 ?
+ j# r6 | W* z & l! \0 \1 h0 f# P O" K . s% q0 s6 a& c3 X' m 以下是TestBeneh的核心代码: - P4 G# l1 \2 o- u7 @( n; P" ]% x 7 S$ j9 m6 n6 k, F4 w$ d testprocess:process* ^6 d8 @" }; l
$ Y S2 o# y" X$ `7 \; v# |3 j1 g; `
file vector_file:text open read_mode is“TestVectors.$ G8 z& V; R: O. g/ b) |
& K1 w4 M* ?' @9 ~7 a
inp”:一指定测试激励文件& K9 d' W" R0 ^
: K$ K# a, \0 U0 A3 q6 _" s& o file output_file:text open write_mode is“Reset.out”: 9 ]$ { A/ _3 m3 @. q& f B & f% n9 Q4 i( _, _ @2 E/ ] 一指定仿真结果输出文件 % [8 ?7 Z% w7 |; k4 J. ^ * o: V1 { C0 G3 j: Y variable invecs,outvecs:line; # @: J7 ^; x6 [+ V0 I- m4 v+ |5 H) K) U* q" G& Y: ^
variable good:boolean; ! u7 |- Z/ C' J4 R0 z( l8 S( j 9 n5 e/ r0 }4 B0 d) E: j' v. ` variable eh:eharacter;: }& e5 ^2 B2 ^; w# ^2 |# ~
7 |4 Z" O, V1 C k1 B
…… / V' N: m% P, Z9 b5 c' p) N2 F; k$ P. {% Y8 z
5 ~6 f: A$ D( |5 U; \0 K3 V) u
+ t" o. z/ n3 B- E9 V9 K
while not endfile(veetor_file)loop* `# R/ {/ \- \% V$ d
+ ^" ?2 n V- N$ n8 m readline(veetor_file.invecs);一读出测试激励文件一行内容.得到激励! {2 ]) ]+ x& q! U+ G
- Q+ L( s# w) _2 w+ e9 O
read(invees,vclk,good); 一一读取一个值给信号vclk1 m) d `' g& ?. Q& Y7 v
+ }( ]9 i, n, ^" q9 n
read(invees,ch); 一一读取空格& Z/ Y0 J* p' U1 c
* ~7 u9 P9 D8 o" U/ z* h ……$ s6 }/ \* [' \
. u; I% e: o% G( y/ q2 F* p) i 0 r& k3 G2 o9 J* h
5 \1 B. p- H3 R( \
read(invees,wBy,good); 一读取一个值给信号vvsy9 ?5 d% R# [. i9 p
! b$ t* |3 V% w" U
read(invecs,ch); 一读取空格 $ X+ p6 d1 }6 ^% g : P% [9 t8 z" d2 p, }& P+ s …… $ _4 T) o* e# E & p4 d, h* l& t5 P/ E , l! w4 h: g+ O" U1 b/ d) Y- f * f) b3 _' ]! w clk<=vclk;一驱动待测单元的输入信号clk , {9 T0 @6 ]4 s- F6 s6 i; {$ Q, l' N+ g5 }( i! Z
ccd<=vced;一驱动待测单元的输入信号ccd , O* z" [+ a3 t: C% ]+ H1 V$ T& D+ C2 M4 ?. D
hsy<=vhsy;一驱动待测单元的输入信号hsy5 s6 V) X: ~- H- ~
7 i% f5 l) a: h1 ]0 j
vsy<=wsy;一驱动待测单元的输入信号vsy ! F! n" F4 D% h6 L) b 2 S s! I" q5 w {# N+ N1 {+ y2 p ……% ]* U, v' P- x. S
! C0 o7 ?2 s/ B3 F$ E
8 Z+ x$ I7 M/ T' q# g+ L7 |* Z % e4 g1 ^$ d. }1 t% `; d1 ?. C caseiis ( t" Z- e/ |6 R, N 6 h- w- m! Y2 p6 s& L4 u$ f when 0=>out_string:=“frame_Yup0:”:一将目标0左上角Y坐标写入仿真结果 7 b) x: R" D1 g+ D! W. P* r$ P2 U6 ~
when 1=>out_string=“frame_Ydn0:”:一将目标0右下角Y坐标写入仿真结果 / F3 R8 ^# n+ p: e7 i' n: ~% J. [6 O) f; d
when 14=>out_strlng:=“frame_Xli3:”:一将目标3左上角X坐标写入仿真结果 ( N. `! X- e/ z6 v% j& t6 r+ ~4 e5 b: \
when 15=>out_string:=“frame_Xrt3:”:一将目标3右下角X坐标写入仿真结果& o1 {: G6 S( d
7 y6 `( E. D: h/ X& x. g when other8=>null; ; ]& ]# N m# p6 Q. X( Q# `* C* U; t; l; M1 l. e$ _$ U
end case; \% ]% V W1 s% o) u* r
* K- {5 A7 C1 P- M write(outvees,string’(out_string)); ! X$ l3 B( O) z9 [ 3 O& A- T, J0 L& ] …… 3 l* g' K* \* z' R. l- [: V ; e) A% Y" c" o" v1 P& K % r9 H8 t. e6 ]! V 9 _ X. l$ p% F 3.5 Modelsim中显示的测试波形及测试结果 8 R6 m# L7 S/ X- m 8 S, \, T# A: J1 l ; t* g. T! u- J' M, Z* K1 A% M, ]6 R1 C4 m: U6 a
在Modelsim提供的HDL仿真环境中,运行TestBeneh进行仿真测试,得到测试向量波形(如图3所示)、仿真波形(如图4所示)和仿真输出结果文件ResuIt.out。对仿真输出结果进行分析表明,仿真输出的目标位置与输入电视图像中的目标位置完全一致。- g7 [6 \- ?1 U. W
# z6 U E$ a6 I' ~; m8 U3 { % F6 y2 i- P, v- O
. r/ ^; W1 a7 v, E, }" l + ]: V1 A6 K# j) @6 e* | " w5 I( S1 Q2 a) U8 V 3 \( \8 D3 T$ o3 n- j2 }' [& P7 b, M
, m% ^- ]5 I7 U
/ a# ~- U1 q [+ t
& b5 k: G& Q& G4 n% S
本例的结果分析是通过人工对比进行的。还可以将仿真预期输出结果保存在测试激励文件或其他文件中.TestBench调用TEXTIO读取仿真预期输出结果.并和仿真实际输出结果进行对比,然后自动判断结果是否正确。在某些场合下,例如对VHDL编写的处理器进行仿真调试时,用户可以将包括指令类型、源地址、目标地址在内的指令保存成文本文件。TestBench调用TEXTIO读取这些指令。同时.TestBeneh调用TEXTIO将结果及中间变量保存成文本文件,以便设计者事后分析和查找问题的原因。 . k7 x% D# x& \8 y f& j! x, X5 x0 c
' Z. w; R- U% ?' F9 E