Virtual JTAG仿真要点
0赞半 年前应jack0321朋友的要求,riple就想着要写这个题目,四 个月前终于有机会做了仿真,还写了个自动生成测试向量的脚本,后来忙着其他事情,就拖到了现在。
VJI的部分功能是通过自定义逻辑来实现的。对VJI仿真的目的就是验证这部分逻辑以及这部分逻辑与用户设计之间配合的正确性。
仿真是上板实测前最重要的一步,仿真都通不过,电路板上能跑通那才叫怪呢。VJI的仿真也不例外,如果不通过仿真验证VJI接口的正确性,而通过实 测,甚至是SignalTap II调试的话,麻烦可就大了。在riple最初使用VJI时,就是通过实测和SignalTap II来调试VJI的,好在那时用的比较简单,没费太大力气。
Virtual JTAG是支持仿真的。不过,就像Altera所有硬核模块一样,对VJI的仿真是通过行为级模型实现的。与其他硬核模块不同的是,VJI除了和用户逻辑 有接口之外,还有一个隐藏起来的“虚拟”接口——JTAG接口。对这个接口的模拟可不太容易做:在真实电路中,这个接口是连接到调试宿主机(PC机)上 的,而且它的行为是通过Tcl程序,受到用户的“动态控制”的。
“动态控制”在Modelsim这种编译执行的仿真器中是无法实现的,我目前也不知道哪款仿真工具能够支持这样的用户交互。为了绕开这个难 点,VJI的仿真模型采用了“静态控制”的方法。所谓“静态控制”,就是把对VJI的操作,通过参数配置的方式传递给VJI的行为模型,由于参数配置是在 编译前指定好的,在仿真过程中不会也不能发生变化,所以是静态的。如果需要更改对VJI的控制,就要重新配置参数,重新编译后才能生效。这样做虽然与真实 操作有些差异,但是也足够验证VJI与用户逻辑配合动作的正确性了。
费了上面这么些话,才说到重点上。
VJI的行为模型提供了三个参数接口:
sld_virtual_jtag_component.sld_sim_action
sld_virtual_jtag_component.sld_sim_n_scan
sld_virtual_jtag_component.sld_sim_total_length
这三个参数分别代表“扫描链操作序列”、“扫描链操作次数”和“扫描链操作总长度”。
其中sld_sim_action比较复杂,由一系列的扫描链操作组成,每一次扫描链操作由4个操作参数组成:time type value length。这四个参数设定了具体一次扫描链操作的相对时间、操作类型(IR/DR)、串行移入数值、串行移入数值的位数(长度)。两个参数之间用逗号 分隔,每组参数用括号保持在一起,两组参数之间用逗号隔开。就像下面这个样子:
((time,type,value,length),(time,type,value,length),(time,type,value,length))
其余 两个参数sld_sim_n_scan和sld_sim_total_length是这一系列扫描链操作的统计信息,可以由第一个参数推算得到。“扫描链 操作次数”无需解释,“扫描链操作总长度”是第一个参数中所有length值之和。这两个参数都不区分IR或DR。
这些 参数就是一组参数化的测试激励。在仿真开始后,这一系列测试激励绕过了VJI的“虚拟”JTAG接口,直接施加到VJI行为模型内部,在VJI的用户逻辑 接口产生相应的波形,实现了对VJI的仿真。这一仿真过程与真实的硬件操作有两个不同点:一是激励是静态施加到仿真环境中的,无法实现用户交互,所以需要 设计一组最有效的操作参数,保证测试的功能覆盖率;二是仿真过程绕开了真实的JTAG操作,无法验证Tcl脚本与JTAG API的配合。对VJI仿真的主要目的是验证用户自定义扫描链逻辑与VJI的配合正确性,实践证明这一部分逻辑也是最容易出错和难以直接调试的。
需要 说明的是,实际的JTAG电路运行速度不快,TCK只有不到10MHz的频率。所以仿真中的电路跑起来也不快,需要耐心等待。
手工 输入上述三个参数非常繁琐,而且容易出错。试试手工生成下面这组参数,嘿嘿,不是很容易吧。
sld_sim_action : (1,1,1,4),(1,2,6,6),(1,1,2,4),(1,2,0,6),(1,1,8,4),(1,2,3,2),(1,1,4,4),(1,2,55aa,10),(1,1,4,4),(1,2,f0f0,10),(1,1,4,4),(1,2,0123,10),(1,1,4,4),(1,2,4567,10),(1,1,4,4),(1,2,89ab,10),(1,1,4,4),(1,2,cdef,10),(1,1,1,4),(1,2,4,6),(1,1,2,4),(1,2,0,6),(1,1,8,4),(1,2,2,2),(1,1,4,4),(1,2,55aa,10),(1,1,4,4),(1,2,55aa,10),(1,1,4,4),(1,2,55aa,10),(1,1,4,4),(1,2,55aa,10),(1,1,1,4),(1,2,4,6),(1,1,2,4),(1,2,0,6),(1,1,8,4),(1,2,2,2),(1,1,4,4),(1,2,55aa,10),(1,1,4,4),(1,2,55aa,10),(1,1,4,4),(1,2,55aa,10),(1,1,4,4),(1,2,55aa,10)
sld_sim_n_scan : 46
sld_sim_total_length : 358
由于 有规律可循,可以用Tcl自动生成上面的参数。实际硬件调试时总是需要写一组Tcl脚本来完成对JTAG API的操作和用户交互,可以在这组脚本中生成上述仿真参数。在Tcl脚本中设置一个变量,用于区分是实际调试还是仅生成仿真参数,再编写一组用户操作就 可以在实际调试之前得到仿真参数。