将自己编写的运动估计IP核通过PLB总线与 ML403的ppc405相连,但是结果不正确。从下图可以看出:
我们使用的序列是标准测试序列foreman.qcif的第1帧做当前帧,第0帧做参考帧,对于宏块左上角位置(16,16)的宏块,使用纯软件的结果是0x7d0267,即mv=(5, -1),sad=0x267;使用硬件IP得到的结果是0xa80285,即mv=(0, 2),sad=0x285;我们设计的ME核的结果见文献:
Yang, K.-M., Sun, M.-T., Wu L, “A family of VLSI designs for the motion compensation block-matching algorithm,” IEEE Trans. Circuits and Systems for Video Technology, vol. 36, no. 10, pp.1317-1325, Oct. 1989.
我们使用VHDL语言将它实现,在ISE中使用ModelSim做了后仿结果是正确的,仿真图见:
可以看到它的结果是正确的:0x7d0267。
那么我们错在那里了?
1、怀疑是执行时钟的问题,是不是太快了(100Mhz),于是开始降频到50Mhz和25Mhz,问题依旧。
2、怀疑是PLB总线的问题,于是将它移植的OPB接口,问题依旧。
3、怀疑是逻辑资源占的太多了(整个设计占了XC4VFX12的93%),place或route时处理问题(因为某些PE单元的工作时正常的,从运算结果可以看出),于是使用ML402进行试验,将同样的IP核挂载到Microblaze的OPB总线上,结果依旧。
4、没辙了,唯一的救命稻草是Chipscope pro了,经过一天的学习,我们开始捕获一个PE单元的内部信号(这里是PE8),具体的结果见下图
其中的b信号是当前宏块的象素值:可以看出它的输出顺序是127,140,142,133,208,166,121,119,...
但是我们取出这块数据,我们希望的数据顺序是133,142,140,127,119,121,166,208,....
所以这是因为PPC405是大端工作模式,而我们的ME IP采用的是小端工作模式所致。于是在数据输入的时候先转换为小端模式,问题解决了,大端到小端的程序如下:
small_endian_value = *(pointer1);
byte0 = small_endian_value & 0xff;
byte1 = (small_endian_value & 0xff00)>>8;
byte2 = (small_endian_value & 0xff0000)>>16;
byte3 = (small_endian_value & 0xff000000)>>24;
big_endian_value = (byte0 << 24) + (byte1 << 16) + (byte2 << 8) + (byte3);
正确的结果如下:
相应使用chipscop pro捕获的数据是:
同样的大端小端问题还出现在视频输入IP中,这个问题正在调试。