EDA365欢迎您登录!
您需要 登录 才可以下载或查看,没有帐号?注册
x
大侠好,欢迎来到FPGA技术江湖。本系列将带来FPGA的系统性学习,从最基本的数字电路基础开始,最详细操作步骤,最直白的言语描述,手把手的“傻瓜式”讲解,让电子、信息、通信类专业学生、初入职场小白及打算进阶提升的职业开发者都可以有系统性学习的机会。
+ |& z: } o# H2 `1 E, `
系统性的掌握技术开发以及相关要求,对个人就业以及职业发展都有着潜在的帮助,希望对大家有所帮助。本次带来Vivado系列,Vivado逻辑分析仪使用教程。话不多说,上货。 1 G# K5 E! P+ o! \! T
* e" K. M+ U8 M: |1 pVivado逻辑分析仪使用教程 * F, z' C% S# @/ c0 C
2 L8 A% N; O; m2 s/ E" V; q X
- a2 L" z3 F. ^' A1 r; G# m传统的逻辑分析仪在使用时,我们需要将所要观察的信号连接到FPGA的IO管脚上,然后观察信号。当信号比较多时,我们操作起来会比较繁琐。在线逻辑分析仪就比较好的解决了这个问题,我们可以将这些功能加到FPGA设计当中。
3 C: U+ ?8 d2 e1 {" T' y k5 z3 Y" s# y' U3 k, e/ N: I
' r' ^. F6 a1 l& n. [5 L- Y0 s' K: Y7 }4 \. d
$ h/ }/ {' v/ S' g
, w! ~7 n( Z }5 ^ b1 }: v% _其中待测设计就是我们整个的逻辑设计模块,在线逻辑分析仪也同样是在FPGA设计中。通过一个或多个探针来采集希望观察的信号。然后通过JTAG接口,将捕获到的数据通过下载器回传给我们的用户界面,以便我们进行观察。 在逻辑分析仪使用的过程中,我们一般常用的调用方法有两种: 1、IP核 2、mark debug标记信号
* `: Y9 `4 q8 P. a0 Y; R# m
接下来我们先说一下第一种方法。这种方法需要我们打开IP核管理器,在程序设计中例化ILA。首先我们打开IP核管理器,搜索ILA,双击打开。
' h6 L1 D' ?3 b2 u3 v( a F
: v' c( x8 R. Y- ?6 o( {* W- Q! |9 l
4 [: z% |% D' ^% O) U' d3 S* {3 A3 U
! n6 ]" o3 ?& n2 g' R6 U" ~+ z- o9 H Z% K2 o: t! s
) I% k1 w. g. P
4 q8 ` L0 Q: J) |
4 E% r( ^1 a/ }% l
7 {+ e- k" _: [3 \+ t0 W1 v/ [& ?5 }9 w# ]
在此配置界面,我们配置几项内容。首先是Component Name,我们可以给我们的逻辑分析仪起一个名字,比如我在此改为my_ila。
+ I- o0 G- L, W( r& e; E1 v
' P, d9 \) f6 k" r在number of probes选项选择我们需要观察的信号个数,我们以流水灯为例,我们可以观察一下代码设计当中的计数器cnt以及输出led。所以我们在此项设置为2。Sample data depth为采样深度,采样深度影响到了我们可以观察的信号长度,大家可以根据自己的需要进行设置,在此我选择深度为1024。 : o$ y( t' J( H8 Z
2 T5 i: _! N H% N1 v
5 H2 g( s; x+ u2 H, ~ c7 r8 ?
: M( N" Q7 A4 ~1 l9 {4 \, E( k4 ~
$ ^# t; E" Y7 E1 }9 p, J
9 O9 J; j. Z2 Y, e
/ h* {: V2 w3 j9 v1 E& _3 x% O6 ]4 g9 x7 g k) p. U
0 c9 W M- y7 p% k
然后在Probe ports里面设置被观察信号的位宽。计数器为26位,led输出为4位,那么我们将位宽设置好,点击OK生成IP核。
8 ~. P7 m$ y2 H. }1 P6 ^# @4 h
0 b; j! ~0 P; j8 S9 T5 G
7 M) |& G5 b5 L ) w7 ?$ b% }* b# a% c
$ w) W" P' L% n$ q' U% L% F1 N( B, i9 D+ R; a# d( n6 s \
% k) {; N" `# k$ N* I在这里,我们简要介绍一下Vivado的OOC(Out-of-Context)综合的概念。对于顶层设计,Vivado使用自顶向下的全局(Global)综合方式,将顶层之下的所有逻辑模块都进行综合,但是设置为OOC方式的模块除外,它们独立于顶层设计而单独综合。通常,在整个设计周期中,顶层设计会被多次修改并综合。但有些子模块在创建完毕之后不会因为顶层设计的修改而被修改,如IP,它们被设置为OOC综合方式,OOC模块只会在综合顶层之前被综合一次。这样,在顶层的设计迭代过程中,OOC模块就不必跟随顶层模块,而进行一次次的会产生相同结果的多余的综合了。所以,OOC流程减少了设计周期时间,并消除了设计迭代,使大家可以保存和重用综合结果。 ) o; ]: N( |4 A* Q9 Z7 @1 y$ N, C
Out-of-Context(OOC) 综合是一种自底向上的设计流程,默认情况下,Vivado设计套件使用OOC的设计流程来综合OOC模块。OOC模块可以是来自IP catalog的IP、来自Vivado IP Integrator的block design或者顶层模块下手动设置为OOC方式的任何子模块。 3 i+ ^) r* g! G
来自IP catalog的IP就默认使用OOC综合的方式,例如上图中的“Synthesis Options”选项就设置为了“Out of Context Per IP”。这些IP会在顶层的全局综合之前,单独地进行OOC综合并生成输出产品(Generate Output Products),包括综合后的网表等各种文件。在对顶层进行综合时,OOC模块会被视为黑盒子,并且不会参与到顶层的综合中来。在综合之后的实现过程中,OOC模块的黑盒子才会被打开,这时其网表才是可见的并参与到全局设计的布局布线中来。
$ ~+ C; N( n X0 ^; p
OOC综合完毕之后如下图所示: $ {: x0 Z0 s5 S
8 m" y8 T# M8 N8 I% Q
/ t7 j; g3 A, O' y6 k
& m' e ]/ ]8 T" ?: n* A
" W5 {( g' n7 b; \7 k! O7 `) A9 I
# ^7 Q% O" h2 V3 m5 R
/ k7 V4 {) Q. F; yIP核调用完成之后,我们在IP sources窗口中打开IP核的instantiation template。my_ila.veo文件为例化的头文件,我们双击打开,将下图内容复制粘贴到顶层文件当中即可。
% ~! W* y( \# ?- t) T' J/ z0 Z9 b0 S$ L* a. P
8 y5 I' ^! v: k! Z
9 X" T' C3 z. u) J
4 A5 R* a9 J/ i J! D2 Q
; W' I# _7 |3 ]' A# o0 u # O% O' P* r+ Y( ~# f, I0 X
3 N0 C! B4 _" @* u- H/ z6 n
. z. J( |9 B$ {& }$ l
/ Z. X: l3 q6 K6 Y1 i4 m! Q" k" e8 `+ c+ v
2 n: v! s2 }. K5 s! K
复制好之后,我们将信号做一下连线,改一下例化名。那么我们的逻辑分析仪调用就完成了。 调用完成之后,我们将文件保存,然后生成下板文件进行下板。 # n( }) c/ L( ~6 L" {) d. m; ^) E
9 F$ ^* J2 H% Z. d% m1 c
) F" G7 D* D1 B+ y8 S
下板时,界面中出现两个文件。第一个文件为bit流文件。第二个为逻辑分析仪文件。直接点击program。下载完成之后会出现如下界面。 0 F5 v8 {* R9 F$ B) q+ X8 O
& p( z# s2 q+ X& S/ Y5 a
$ P; X, R7 a% l c% Z( }5 B
8 X5 s- y7 o7 f8 ]1 L- s/ x
在开始观察波形之前,我们需要先在右下角小窗口里面设置触发信号。这个我们可以理解为我们想要观察的波形的位置。比如我们可以观察一下led为第二个灯亮,且计数器数到1000的位置,那么我们的设置如下图:
0 O/ G$ R5 h+ O! f* V; ~, {
5 `7 z h$ n: t& R# {7 y
2 o; }! X( r: O" o- C7 h
1 t$ w& X. k' X' n+ D1 [, i& i
3 q- M, G- H4 _设置好之后,我们点击波形界面的三角形符号,进行触发,那么就可以观察到我们的波形了。
% h" E4 G; j, n( E( ~5 S! Z$ h4 E3 T4 w+ u: g$ S
6 _) p" n# _' F3 s5 S: w/ t. R
# t9 W$ |) A. R0 x6 l8 s2 a
4 j3 ^0 h( V, P# e8 F! Q- e* L4 A
& d3 L! d( {3 z
O4 k- d0 s( l9 g" G第二种方法:
% o& y9 K/ m% \4 E
“网表插入调试探针流程”需要在综合后的网表中,将要进行调试观察的各个信号,标记“Mark_Debug”属性,然后通过“Setup Debug”向导来设置ILA IP核的参数,最后工具会根据参数来自动创建ILA IP核。我们点击“Flow Navigator”窗口中的“Open Synthesized Design”按钮,如下图所示:
5 w( V+ ^6 `* _( J% M. @
- m# b% ^0 P8 ]4 d, z5 a
& q- _" i; Q0 @ s
) j2 F/ d* c/ E/ U) z8 i
在综合后设计的窗口布局选择器中,我们选择“Debug”窗口布局,如下图所示:
: a4 t- s* F; ~; c. a
3 t+ g$ D2 Y0 x' ^
+ h: \5 U# H7 C0 i; i+ n
2 a* T8 L0 {! D9 K
i* B0 y- b9 s6 T
此时,Vivado打开了“Netlist”子窗口、“Schematic”子窗口以及“Debug”子窗口。其中,“Netlist”子窗口和“Schematic”子窗口都用于标记要进行观察的信号,“Debug”子窗口用于显示并设置ILA IP核的各个参数。如下图所示: # P3 H, J. {, n
+ b4 \9 {# l( b1 v' |) L) D% C: c$ |) b
在“Debug”子窗口中,又包含两个选项卡“Debug Cores”和“Debug Nets”。这两个选项卡都用于显示所有的已标记为“Mark_Debug”的信号。不同之处在于,“Debug Cores”选项卡是一个更加以ILA IP核为中心的视图,所有已标记为“Mark_Debug”的信号并且已经被分配到ILA探针的信号都会被显示在各个ILA IP核的视图树下,已标记为“Mark_Debug”的信号但是还没有被分配到ILA探针的信号被显示在“Unassigned Debug Nets”下,当然也可以在其中查看和设置ILA IP核的各种属性和参数。“Debug Nets”选项卡仅显示已标记为“Mark_Debug”的信号,但不显示ILA IP核,所有已标记为“Mark_Debug”的信号并且已经被分配到ILA探针的信号都会被显示在“Assigned Debug Nets”下,已标记为“Mark_Debug”的信号但是还没有被分配到ILA探针的信号被显示在“Unassigned Debug Nets”下。
- a0 j$ l$ q B+ v& l
我们首先标记要进行观察的信号,以led信号为例,在“Netlist”子窗口中的“Nets”目录下,找到“led_OBUF”网络,右击该网络(此时右边的“Schematic”子窗口也会自动地高亮选择此网络,因为“Netlist”子窗口中的对象和“Schematic”子窗口中的对象,两者之间是交叉选择的),在弹出的菜单中心选择“Mark Debug”命令,如下图所示:
2 N& u& J" E" x% ?6 J. ~8 J+ d
8 c" Y8 [1 h. _) _ p/ ~3 i3 J# @6 ` y: ?
& x7 i) p/ U) j0 {" ]* @
: q6 x4 }- ?$ ^- F+ ~
也可以在“Schematic”子窗口中选择网络,然后右键选择“Mark Debug”命令,如下图所示:
) G _4 [! s" ]" j, S8 x
1 X8 Q$ u1 c. u( }& Y
: C v8 y% s, @, v
! c2 @2 H7 \3 V x9 P
- p6 u" e: h" z
另外,也可以在HDL源代码中为想要观察的reg或wire信号添加“Mark Debug”属性,例如:(* mark_debug = “true” *)reg [25:0] cnt ; 其中“(* mark_debug = “true” *)”必须紧挨在变量声明的前面。这样,在综合完之后打开综合后的设计,counter信号就自动被标记了“Mark Debug”属性。此时在“Debug”子窗口的“Debug Nets”选项卡的“Unassigned Debug Nets”目录下就会出现我们刚刚标记的“led_OBUF”网络。
# x6 j2 K1 [: s : N9 s1 g7 a6 T5 h* m
此时“Debug”子窗口的“Debug Nets”选项卡的“Unassigned Debug Nets”目录下就有了“led_OBUF”和“cnt”两个信号,如下图所示:
6 m4 p. m8 e* L
7 N) ~6 R" M7 b/ f% L( E, L6 x& j
+ k$ |( Y2 a4 N8 l6 ?: C Z
& |* Q, M0 T: W& R" Z
之后我们点击“Debug”子窗口中的“Setup Debug”按钮,如下图所示:
2 K) y2 n/ ~7 K6 t
: U: K& g/ u- k" b5 R( N" x; K
% T+ k; X* Z) f/ [& [
, c: y- T5 K+ I
2 D: p+ q( |3 h4 H2 k. C
+ g* K: ?# A' m4 O' r, Z. ~
弹出“Setup Debug”向导,我们直接点击next,如下图所示:
1 o% R0 B+ l" O I) h6 t. x& ^. l- h& c5 l3 G, ?
+ k) \2 P' ?" ~3 k1 f0 I! }* G4 c1 n6 {+ J" e
9 g' C, k) B/ k
, A! u" K3 ~. C1 c
' A# z. O) d* `2 X! h接下来的页面是选择用于采样待测信号的时钟域,Vivado会自动识别出各个待测信号所属的时钟域并将其自动设定为其采样时钟,例如,我们刚刚添加的这“led_OBUF”和“cnt”两个信号就属于“sys_clk_IBUF”时钟域,并且Vivado也已经自动将“sys_clk_IBUF”时钟设置为了这两个信号的采样时钟,如下图所示:
! D% D7 S( L. @& B; V! v0 X* q/ V
% @0 j5 q" f+ }; w' c 3 N* Z& F6 p# @- W u
! W0 `' y3 T* W0 L: `2 u8 n) Q
% i7 T. e4 {7 A% k% V, d+ [% \) |6 c+ N! E- ^
7 R6 e& O0 i" T# d t7 v& F
0 W% s9 G, Z9 V5 ]% y+ d当然,用户也可以手动指定各个用于采样待测信号的时钟域,右击待测信号,选择“Select Clock Domain”,弹出“Select Clock Domain”窗口,如下面两个图所示: # D4 o, |/ v$ e$ \4 Z1 P! W
1 {* Q/ ]7 ?8 V! k) a9 ~: }( t8 v% j) @
8 g' o5 |2 m! D- c3 z
x }. \! w+ q* g) k3 n% B9 q) |; h4 E
: `5 r, p. G m 6 h. I3 T+ R& t0 O
! g. Y8 d1 m% T) X) y
. k9 n% |( r+ A# k1 ` ~' w* G% \8 U* a* S* W* H( p
4 a6 X6 [, e* E! b
_/ @6 Q! H- ^5 Z! w7 ?3 o在“Select Clock Domain”窗口中就可以选择用于采样待测信号的时钟了。“Setup Debug”向导会为每个采样时钟生成一个单独的ILA IP核,由于本例程中只有一个时钟,所以这里最后只会生成一个ILA IP核。设置完采样时钟后,我们点击next,接下来的页面用于设置ILA IP核的全局设置,如下图所示:
5 T5 ~. Q8 a$ d' b, ]( O
, V7 r8 c. [! [# U$ E2 c0 |" k, z+ B+ h$ n7 D* q, I
$ v! N9 N; F- m: u- B4 O
1 v+ }; g* e+ I* ^6 x Z- f) t; `4 d+ Q8 V/ @
/ |' Y0 l5 y& `$ p7 g其中“Sample of data depth”用于设置采样深度,“Input pipe stages”用于设置待测信号和其采样时钟之间的同步级数。如果在上一个设置时钟域页面中,存在与其采样时钟之间是异步的待测信号,则为了避免亚稳态,此数值最好不要低于2。由于本例中的两个待测信号的其采样时钟是同步的,所以可以设置为0。我们点击next,就进入了最后的概览页面,确认无误后直接点击finish即可,如下图所示: 3 {5 k. k! o. y. E& Q
# i1 P0 M) m' [" R
) j" z* v6 C) G3 G( l
8 }9 X9 { X5 Z7 H6 M' ]4 c. L) _
: [, p3 m& a( L/ D6 M
8 c" W( z) R1 Z) `7 _# Z9 P 1 R6 H* o- T8 S* V% E
) R5 \' n4 h# K0 U 0 f9 z; C. d. D8 s
在“Debug”子窗口中的“Debug Cores”选项卡中,可以看到Vivado已经添加了ILA IP核,并且“Unassigned Debug Nets”目录下已经没有未被分配的信号了,如下图所示:
7 r0 b. R E4 P, x8 E2 K5 c) C- E! Y
) F* S, W3 F e/ l0 t, M: a' v2 u! M: }0 N, v( l
5 w) u$ k: R. i( H o/ ^7 l+ e# C3 `. f) G0 w
1 F, x2 v7 ^. b
/ Q% _0 L, e) t. B 3 o4 F P8 L) d% i+ ~- ~& `
. N, G" R6 X' ?! J8 \- l
/ j' Z) p/ I1 c$ e
网表中被标记为Mark Debug的信号也变为了虚线,以表示其完成了ILA IP核的分配,如下图所示:
8 x: L- N: i }. P$ K5 O* ?! _' u& @' `. L
6 X! @# j1 }7 J$ [& |3 \& O* U8 j, u. X
0 g8 A6 F9 L8 n l7 F8 ]( [$ G) h. f7 \
& L6 m! A2 c; K/ N- ~) d1 S. Z. Q
3 A7 O/ O3 c* X# k7 y( j, U, P1 h6 ?0 s. E1 w) q
' u* z/ O1 V5 h) l) y) p& D; v
前面我们提到过,在“网表插入调试探针流程”中,用户设置的调试信息会以Tcl XDC调试命令的形式保存到XDC约束文件中,在实现阶段,Vivado会读取这些XDC调试命令,并在布局布线时加入这些ILA IP核。此时,我们所做出的所有的更改和设置,都还只是停留在电脑内存中,我们需要将其保存在硬盘的XDC约束文件中,点击工具栏中的保存按钮,如下图所示:
8 S1 d$ ]! Q& i) W7 X
+ C7 H; s" h0 v+ B
" C$ d9 C4 n; M' V2 P
/ R0 F. K3 b, F1 F. |) P: ?$ X3 o: T' \
! p1 }: x2 ~- b4 K* q + i2 p9 S8 O! h7 n
3 W( a- o# P& @7 F
0 Z# |) o3 {% c在出现的对话框中直接点击OK,如下图所示: ( ^3 F2 X! K, K5 U x0 ^
7 G3 V7 `3 ?. d3 T4 [
# c- p, M. A. D* t! d; N, a# `9 w0 w; y
$ I+ F- @* X7 V0 ~& ]- W" R# r1 l6 [1 d2 i2 |& s8 _" c4 N& k
% j( n$ Q8 p. f; Y# q, i* L* H }
. l! C0 l: S- g; `3 Y$ b
( b- }- J3 B: ]( x% q4 ~ a
弹出的“Save Constraints”窗口中,用于询问用户将约束保存在哪个XDC约束文件中,本例的工程中只有一个XDC约束文件,如下图所示,我们直接点击OK即可:
. P2 G: E2 V* P6 _
5 Y) C! a" p! J; }) c% N8 k: A1 [9 h
2 X- t& f- x$ T% j( \& ?
' L' k2 z. d1 x% T8 o1 g : R G; l# R8 h5 D3 c
. U* L0 O' f! n/ |; J
+ Y( v9 F6 X% m n 0 @9 d) C. ^, O7 P2 f
- Y( [/ }. l- v( q6 z + e. b' i4 K- \) B3 @" n7 N5 K
此时,我们打开led_twinkle.xdc,就会看到在用户约束的下面,Vivado自动写入了用于debug的约束,如下图所示:
j5 O9 F8 k$ S$ U5 J7 u
: q0 g- @4 v' D4 h5 T+ f
A: G2 `+ b* m9 d; F. B6 E, w& V/ u) }" y9 S
" W9 N( |) ` s2 }* h: `
' v2 F( b& G, F$ N! y; H% v4 ^7 k6 d
; `. ?9 q" ^) ]4 R; Y8 K" j2 r0 S* V, H2 _
! L+ j1 G, T5 v
在实现阶段,Vivado会读取这些约束,并按照这些命令的参数来自动地在布局布线时加入ILA IP核。至此,我们就成功地使用“网表插入调试探针流程”将ILA IP核添加到了设计中。接下来就可以将实现设计并生成比特流,最后将比特流下载到FPGA中,以对信号进行在线观察,这一部分内容在上面第一种方法里面已经介绍过了,在此不再重复介绍。 * X8 h& N& T" E0 {
/ C$ X6 n' a0 T, Q+ M
. e: F+ J9 H8 ^9 O3 a |