开发环境:Vivado 2018.3。 在上板调试I2C接口时,在顶层使用ILA IP对I2C控制器模块SCL和SDA信号进行抓线调试时,在顶层将SDA信号例化连接到ILA IP上,然后在进行Implementation时报错,具体顶层两个模块例化情况如下:
具体报错如下:
[DRC REQP-1582] iobuf_io_loaded: IOBUF I2C/Sda_IOBUF_inst pin IO drives one or more invalid loads.
大概是因为SDA是inout的原因,导致不能将该信号直接连在ILA上。可以看到这种错误情况下综合的电路图,其中SDA信号是接在一个IOBUF的IO口上的,SDA信号直接连到ILA模块的端口,估计是这样的接口是不能使用抓线调试的。
解决方法:
SDA信号是inout信号不能直接使用ILA对这个模块管脚进行抓线,我们可以在I2C模块内对SDA信号进行抓线,代码如下,在I2C模块内例化ILA IP,并将SDA连到ILA 模块一个端口。
在这种情况下,Implementation没有报错,查看综合后生成的电路如下,ILA包含在I2C模块内,实际与ILA相连的是IOBUF的O管脚,与之前报错的情况是不一样的,之前I2C与ILA是单独存在于顶层模块的两个子模块,连接在ILA上的SDA信号是从IOBUF的IO管脚输出。通过在I2C模块内例化ILA IP就可以正常对SDA信号进行抓线在线调试了。
根据上面的错误问题以及问题的解决方法,可以找到另一个比较好的解决方法,就是对I2C模块增加一个调试输出端口,并将SDA信号值直接给到该输出端口,相关代码如下图所示。
这样既可以在顶层去例化ILA进行抓线调试,模块化更加清晰,又能不改变子模块内部的代码。整个设计的资源使用也不会有增加。顶层模块例化如下:
修改后对工程Implementation不会有error,在顶层与ILA相连接的是sda_debug信号,生成相关的电路图如下:
从生成的电路图可以发现,与ILA模块相连的是IOBUF的O管脚。与第一种解决方法相比可以发现,解决的这个问题其实就是将与ILA与IOBUF上IO管脚相连的情况给变成ILA与IOBUF的O管脚相连,这样就可以避免工程Implementation出现error,同时还能满足我们想要在线调试看SDA信号的要求。 对于第二种方式,在代码设计的时候对模块额外增加一个调试端口,在顶层设计中例化添加ILA IP,这样既可以避免产生 Implementation出现error,又能让系统模块划分更加清晰。 下面附上最后上板调试抓取SDA和SCL信号的波形图,能够达到我们想要的效果,同时避免了由于ILA直接与IOBUF的IO管脚直接相连导致的Implementation错误。
使用ILA进行上板抓线调试是经常用到的一个调试方法,可以比较清楚看到信号实际上板的情况,比如I2C接口,通过抓线就能很清楚通过波形判断接口驱动设计是否有问题。
|