【BUG记录】Xilinx复数乘法器、乘法器IP核,在modelsim仿真时,出现一个时钟内先算错,再算对的情况
问题描述
在vivado中使用复数乘法器IP核时,使用modelsim仿真看计算结果,发现了如下的情况:
图中,clk是IP核的工作时钟,result是乘法的计算结果,×代表计算结果不对,√表示计算结果正确,valid是IP核产生的输出结果有效信号(高有效)。
在一个时钟内,输出的结果先是算不对,然后又算对了。而我期望的波形如下:
问题分析
- 如果是输入的两个乘数没有按照自己想要的顺序对齐,即使算错,也应该是以时钟为单位错,不能是在一个时钟内先错后对。
通过更改代码,使得两个乘数串位,发现上述问题依旧存在,故排除该问题。 - 怀疑是乘法器配置的问题,有可能影响的只有signed usigned选项。
排列组合输入数据的signed usigned选项,上述问题依旧存在,排除该问题。 - 怀疑是输入数据的问题,目前输入的两个乘数,一个是1-48的递增,一个是5位数的负数,把两个乘数都换成1-48的递增,上述问题解决了,但是没懂,为啥负数就会导致计算错误。
- 把乘法器使用的资源从dsp48改为lut,计算结果正确。
反复确认操作4,发现,使用lut时,计算结果就正确,使用dsp48时,计算结果就会先错再对。
也不光是一个LUT、DSP选项导致的。使用DSP的情况下,如果是1~48自己乘自己,就也能算对,乘数中带负数的话,就会先错后对。
先用着LUT吧,后面LUT不够需要优化了再说。
【24/2/28更新】:
LUT马上就不够用了,这里非得用DSP不可。
经过多次尝试,发现使用DSP的乘法器出现先算错,后算对的情况,可能和乘法结果的位数有关系,位数过大,就会有此问题,乘数较小,就不会有该问题。或许是因为DSP底层硬件的限制,它超过多少位之后,就不能一次算完,看了调用DSP48的原语:
MULT_MACRO #(
.DEVICE("7SERIES"), // Target Device: "7SERIES"
.LATENCY(3), // Desired clock cycle latency, 0-4
.WIDTH_A(18), // Multiplier A-input bus width, 1-25
.WIDTH_B(18) // Multiplier B-input bus width, 1-18
) MULT_MACRO_inst (
.P(P), // Multiplier output bus, width determined by WIDTH_P parameter
.A(A), // Multiplier input A bus, width determined by WIDTH_A parameter
.B(B), // Multiplier input B bus, width determined by WIDTH_B parameter
.CE(CE), // 1-bit active high input clock enable
.CLK(CLK), // 1-bit positive edge clock input
.RST(RST) // 1-bit input active high reset
);
其支持的是25bit*18bit的有符号乘法,超过了就会有bug?
解决方法:这里不想深入研究乘法器的设计,就顺着这个bug,既然它是在上升沿处有错误数据,那就在下降沿取乘法器输出,这样取出的数据就是计算正确的,再用上升沿打一拍,将其转换到上升沿,用于后续模块的使用。