近日在一个基于Xilinx FPGA的I2C主控制器逻辑设计中,被Xilinx的工具折腾郁闷了,记录下来,供感兴趣的朋友参考。PS:仅为试验参考。。。
在我的设计中,有这样一段代码:
这个SCL_lut共计10个逻辑变量输入,其中FSM1_IsIdle、FSM1_IsARB、FSM1_IsStop、FSM1_IsHold为“独热”状态机的状态输出,BitClk、BitClk_180为系统时钟单周期脉冲信号,不同时有效 。10个逻辑变量,我的心理预期在2~3个LUTs,2个逻辑层级,但是ISE 14.7 + Spartan-6的综合结果,实在让我意外,如下图:
ISE这是抽什么疯,居然消耗了4x LUT6 + 1x LUT5 + 1x LUT3,共计6个LUTs来实现我一个10输入的逻辑表达式?最不能忍的是,居然要3个逻辑层级(Logic levels)。咋办?换个工具试一下咯,然后用Vivado 2019.2 + Artix-7试了一下,结果如下图:
Vivado 2019.2使用了2x LUT6 + 2x LUT5 + 1x LUT4 + 1x LUT3,共计6个LUTs,且其中LUT4、LUT3分别输出至其它逻辑电路 ,逻辑层级降为了2,但我还是不满意!
这段代码,ISE(14.7)和Vivado(2019.2)都使用了6个LUTs,分别需要占用32、29条布线资源,但我只有10个输入呀,总觉得哪里有问题,咋办?看来只有改代码了,考虑到FSM1_IsIdle = '1'时,SCL_lut <= '1',其它逻辑分支无效,故其它逻辑分支中的not FSM1_IsIdle是可以去掉的,于是,我把代码改成了这样(当然,改的时候也没报啥希望):
修改后,ISE 14.7的综合结果没有改变。Vivado 2019.2的综合结果变为了这个样子:
这一次Vivado 2019.2使用1x LUT6 + 3x LUT5 + 1x LUT3来实现我这个10输入的表达式,相比前一个代码,减少了1个LUT的消耗,布线资源由29条降低为24条,有所改善,但似乎还是不够啊!没办法了,只有对着我原来的代码,仔细地数一个、又一个、再一个逻辑分支的输入数量,然后把代码改成了这样:
改完后综合,ISE 14.7的结果如下图:
Vivado 2019.2的综合结果:
看着这个结果,我默默地喝了口水(其实是抽了颗烟,但抽烟不提倡呀)(奶奶的,太欺负人了,逻辑设计这样干,就不是人干的活儿了!!!)
看到这里,似乎感觉Vivado的逻辑综合效果比ISE要好一些,但不知道什么时候二者都会抽风,咋个看它们的综合结果都不顺眼。。。
各位别急,这个故事还有续集。。。
既然是I2C的设计,都有SCL_lut了,咋能少了SDA_lut呢?我的设计中,SDA_lut的代码是这样的:
这个SDA_lut比SCL_lut复杂些,有13个逻辑变量输入,其中FSM1_IsIdle、FSM1_IsStart、FSM1_IsData、FSM1_IsAck、FSM1_IsStop为“独热”状态机的状态输出,BitClk、BitClk_90、BitClk_180为系统时钟单周期脉冲信号,不同时有效。
ISE 14.7给出的SDA_lut综合结果如下图(看不太清楚):
ISE 14.7使用了3x LUT6,2个逻辑层级来实现这个13输入的逻辑表达式。而Vivado 2019.2的表现,至少在我眼中,是认为它抽风了,Vivado 2019.2不但消耗更多的逻辑资源,而且,随着我修改SCL_lut,SDA_lut的综合结果跟着变。
与SCL_lut代码1对应的SDA_lut,Vivado 2019.2的综合结果如下图,消耗2x LUT6 + 1x LUT5 + 1x LUT4 + 1x LUT3,其中LUT3与SCL_lut的逻辑电路共用,逻辑层级2:
与SCL_lut代码2对应的SDA_lut,Vivado 2019.2的综合结果如下图,消耗3x LUT5 + 1x LUT4 + 1x LUT3,逻辑层级2:
与SCL_lut代码3对应的SDA_lut,Vivado 2019.2的综合结果如下图,消耗3x LUT5 + 1x LUT6,逻辑层级2:
盯着Vivado 2019.2在这个13输入逻辑表达式的综合结果,我就只能静静地看着而不说话。。。