FPGA基础入门【6】ChipScope的使用

当FPGA设计中复杂度慢慢变高的时候,仿真的手段也要增加,目前我们仿真的手段都是在ModelSim中配置相应的testbench,给模块发送需要的信号。这种软件仿真的方式有几个缺点:

  1. 一个是软件仿真速度很慢,一般都不会仿真超过1秒,对于一些需要等待一段时间的逻辑就只好暂时降低等待时间;
  2. 二是软件只能仿真逻辑,不会考虑电路内的逻辑延迟、时钟问题(其实可以设置延迟,但具体数字很难确定);
  3. 三是软件不会考虑引脚配置是否正确。

这时引入第二种仿真方式,多一种选择,少一点debug时间。这就是在FPGA内部集成一个逻辑分析器,Xilinx的Vivado中叫做ChipScope,相应Altera的叫做SignalTap,基本上是同一类。这种方式是在芯片内部调用逻辑和BRAM抓取特定信号并保存下来,通过JTAG和电脑实时通信,将捕捉到的信号在Vivado中显示。

这篇教程以上一篇的数码管project作为基础

FPGA基础入门【6】ChipScope的使用

设置ChipScope

设置ChipScope的前提条件是完成Synthesis,这样Vivado能够确认project中的所有信号名称信息。在左侧的Flow Navigator中展开Synthesis -> Open Synthesized Design -> Set Up Debug

navigator

系统会打开新界面开始为ChipScope添加需要的信号:
debug1
debug2

点击Find Nets to Add添加想要的信号。将数码管project中的top level代码拿出来看看:

// Verilog code for segment project

module segment(
    input clock,
    input reset,
    input button,
    output [7:0] segment_out,
    output [7:0] digit
);

// Pushdown detection
wire pushdown;

pushdown_detect pd(
    .clock(clock),
    .button(button),
    .pushdown(pushdown)
);

// Decimal counter digit0-3
wire [3:0] counter0;
wire [3:0] counter1;
wire [3:0] counter2;
wire [3:0] counter3;
wire [2:0] carry;

decimal_counter d0(
    .clock     (clock),
    .reset     (reset),
    .carryin   (pushdown),
    .carryout  (carry[0]),
    .result    (counter0)
);

decimal_counter d1(
    .clock     (clock),
    .reset     (reset),
    .carryin   (carry[0]),
    .carryout  (carry[1]),
    .result    (counter1)
);

decimal_counter d2(
    .clock     (clock),
    .reset     (reset),
    .carryin   (carry[1]),
    .carryout  (carry[2]),
    .result    (counter2)
);

decimal_counter d3(
    .clock     (clock),
    .reset     (reset),
    .carryin   (carry[2]),
    .carryout  (),
    .result    (counter3)
);

// Segment translation
segment_trans trans(
    .clock         (clock),
    .reset         (reset),
    .counter0      (counter0),
    .counter1      (counter1),
    .counter2      (counter2),
    .counter3      (counter3),
    .digit         (digit[3:0]),
    .segment_out   (segment_out)
);

assign digit[7:4] = 4'b1111;

endmodule

比较重要的几个信号分别是输入button,消抖后的信号pushdown,十进制的4位数,和译码之后的输出digit和segment_out。我们分别输入搜索后加入相应信号如下

debug3

debug4
将需要的信号一一搜索加入后如下
debug5
到下一步中,sample of data depth是采样深度,芯片内部的储存空间是有限的,不会无限捕捉信号。
Input pipe stages设置信号和储存采样之间的缓冲寄存器层数,这在时钟频率高的时候会用上,在那时缓冲有助于减少时钟冲突,给系统更多的空间来布线。在时钟不高的情况下就不用配置了。
Capture control和Advanced trigger是和信号触发条件和储存方式有关,为了简化教程不细讲。
debug6

debug7
除了这种初始化配置方式,在Netlist窗口中,也可以选中自己需要看的信号,右键后点击Mark Debug加入到debug清单中,之后可以在下方Debug窗口中点击Set up Debug(小虫标志),一路next下去就可以将标记好的信号配置到chipscope中。
debug8
debug9

编译烧写

ChipScope配置好之后就可以再点击Flow Navigator中Run Implementation,编译好后再generate bitstream生成image文件,就和上一篇教程一模一样,只是系统已经在相应的位置添加了模块用来保存你需要的信号。

需要注意的是ChipScope在内部添加了自己的成分,因此增加了编译需要的时间,对于初始project较小的情况尤其明显,需要耐心等待。

编译完成后烧写入编译好的bitstream。这一步可以看到Debug probes file就自动填入了刚刚配置好的ltx文件
program
在烧写完之后就会自动打开waveform,到这就可以实际使用chipscope了
chipscope

实测

这时如果去按按键,可以发现逻辑没有变化,原来是怎样工作的现在还是怎样,不同的是,配置好trigger之后,waveform就可以在满足trigger条件时开始捕捉信号。配置trigger如下:
trigger
在第一次使用chipscope时这个窗口应该是空着的,点击绿圈加号Add probes添加trigger,出现一个小菜单,选择自己需要的信号即可,这里我选择了pushdown。

在这之后需要选择operator,radix和value。operator是操作符,有等于和不等于,顾名思义就是选择符合条件时开始捕捉或者不符合条件时开始捕捉。radix是数字进制,可以选择二进制、八进制、十六进制、带符号十进制和无符号十进制,影响后面Value的形式。value就是实际数值,不过不只有数字可以选择,还有X无所谓,R上升沿,F下降沿,B上升或者下降沿,和N不动这些选项,这里选择上升沿,就是消抖后探测到上升沿时触发。

在绿圈加号右边还有个与门符号,这是当你有多个trigger触发条件时的逻辑关系,比如默认是AND,意思是多个条件都满足时才触发;也可以改为OR,当有一个条件满足时触发;NAND都不满足时才触发;NOR只要有一个不满足就触发。

这里可以看到旁边还有个capture setup窗口,这个是在前面选择了capture control才有内容。

result
配置好后点击绿圈,带触发条件开启chipscope,在你按下按键后就会出现相应waveform,可以看到十进制计数器counter0-3的计数跟实际的输出是相符的(顺序有点乱)。但digit刷新是每1ms的事情,在采样1024和时钟100MHz的条件下,最多只能看10us的数据,看到digit变化的可能性很低,如果想看就要设置digit的相应trigger。

好了写到这相信差不多会用了,工具部分到这一章已经基本都介绍过了,下一篇就集中于开发板上了。

  • 11
    点赞
  • 66
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值