zxq6 发表于 2017-9-14 20:12:19

有如下两段Verilog代码,哪个好点?

本帖最后由 zxq6 于 2017-9-14 20:13 编辑

或者有更好的实现方法,请指教,谢谢!

代码片段1:
        always @(posedge S_AXI_ACLK) begin
        if(DIR==1'b1)begin
            if((ab_cnt_sum>=slv_reg2) && (ab_cnt_sum<=(slv_reg2+slv_reg3)))begin
                    pulse_width2<=0;
            end
      end
      else begin
            if((ab_cnt_sum>=slv_reg2+slv_reg5-2000) && (ab_cnt_sum<=(slv_reg2+slv_reg3+slv_reg5-2000)))begin
                 pulse_width2<=0;
            end
      end
          if(pulse_width<250)pulse_width<=pulse_width+1'b1;
        end


代码片段2:

        always @(posedge S_AXI_ACLK) begin
        if(DIR==1'b1)begin
            if((ab_cnt_sum>=slv_reg2) && (ab_cnt_sum<=(slv_reg2+slv_reg3)))begin
                    pulse_width<=0;
            end
            else begin
                    pulse_width<=pulse_width;
            end
      end
      else begin
            if((ab_cnt_sum>=slv_reg2+slv_reg5-2000) && (ab_cnt_sum<=(slv_reg2+slv_reg3+slv_reg5-2000)))begin
                   pulse_width<=0;
                 end
                 else begin
                   pulse_width<=pulse_width;
                 end
      end
          if(pulse_width<250)
                  pulse_width<=pulse_width+1'b1;
          else
                  pulse_width<=pulse_width
        end

xiaocat85 发表于 2017-9-14 21:56:21

代码1更利于插入clock gating。另外,看代码风格,有C语言的影子

wye11083 发表于 2017-9-15 00:36:59

xiaocat85 发表于 2017-9-14 21:56
代码1更利于插入clock gating。另外,看代码风格,有C语言的影子

后半句你说错鸟。LZ经验看起来相当丰富了,已经能写出准确无误的代码(下面一段)。上面一段在ISE下综合有可能会得到不正确的结果{:funk:}

其实LZ这有很多地方可以精简。比如if(XXX) a = a + 1,可以直接精简为a = a + (XXX)。这样可以省好几行代码。

verilog中由于综合器的不同,对于每一项if()为了不产生意外,是要跟着那么一行else的(避免出错)。但是这里面一般不需要填东西{:lol:} 直接来个空的begin end即可,就是告诉综合器“只有在前面if里面一堆满足条件时,才更改寄存器的值,不要给我综合成latch”。主要是ise在不完整的敏感信号条件下(比如一个always块写了好多个if,然后每个if又不以else终结,对某些if,可能会被其它if的敏感列表干扰而出错),有可能会把边沿触发给错误理解成电平触发。用synplicity则几乎不存在这个问题,毕竟人家是专业级的。vivado不太了解,但是估计没太大改变。所以写verilog一定要注意if的闭包性,避免出现意外。这类小毛病很小,但是你根本没法调试。碰到只能吃哑巴亏,谁叫代码不规范呢。

LQS1200 发表于 2017-9-15 09:25:12

wye11083 发表于 2017-9-15 00:36
后半句你说错鸟。LZ经验看起来相当丰富了,已经能写出准确无误的代码(下面一段)。上面一段在ISE下综合 ...

可以讲讲更多常用到的经验吗?谢谢

xiaocat85 发表于 2017-9-15 09:51:46

wye11083 发表于 2017-9-15 00:36
后半句你说错鸟。LZ经验看起来相当丰富了,已经能写出准确无误的代码(下面一段)。上面一段在ISE下综合 ...

ISE那么弱?一直用quartus和DC,没有发生过类似的情况。有时候我们为了追求低功耗,是不能用代码二的写法,影响插入ICG。

wye11083 发表于 2017-9-15 11:12:43

xiaocat85 发表于 2017-9-15 09:51
ISE那么弱?一直用quartus和DC,没有发生过类似的情况。有时候我们为了追求低功耗,是不能用代码二的写法 ...

gating在fpga代码中一般是不允许的。asic没有限制,但是通常为了保证可靠性(尤其是使能路径可能较长),你只能对整个block使能与否。

xilinx要显式声明CLOCK_DEDICATED_ROUTE=FALSE才允许布线,而且不保证性能和质量。在xilinx中是用BUFGCE来使能时钟的。altera我不清楚,但是xilinx代码中的gating都要在时钟上串个lut,本身就是不稳定的(lut延时随温度变化而变化),会带来严重的setup/hold问题,甚至根本就跑不起来。也即,不使用全局clock使能,而使用局部串lut使能,其实是非常不健康的方法,在任何地方都是严重不建议的。非要这么用,除非你路径延时可以忽略不计。fpga更可靠的设计是使用CE信号掩码输入数据,因为时钟线耗不了几个ma,反而是dff翻转消耗的电比较多。

wye11083 发表于 2017-9-15 11:14:21

LQS1200 发表于 2017-9-15 09:25
可以讲讲更多常用到的经验吗?谢谢

没有太多可归纳总结的经验,只能遇事解决事情。这东西,需要很长时间的积累。

xiaocat85 发表于 2017-9-16 09:25:16

wye11083 发表于 2017-9-15 11:12
gating在fpga代码中一般是不允许的。asic没有限制,但是通常为了保证可靠性(尤其是使能路径可能较长), ...

ISE中timing不是按照best/worst两个corner来计算的?理论上即使是窜入lut,其delay应该也是可以被计算出来的。串入lut的作用是在clock上构建MUX吧?ISE的timing太弱了,PT在这方面还是强大不少。另外,如果在fpga综合后也跑一次formal,这样应该可以发现综合网表和RTL不一致的情况。

wye11083 发表于 2017-9-16 10:49:48

xiaocat85 发表于 2017-9-16 09:25
ISE中timing不是按照best/worst两个corner来计算的?理论上即使是窜入lut,其delay应该也是可以被计算出 ...

ise只有worst case。另外LUT延时并不是可控的——从idelay_tap可以计算出,xilinx手册上给的是接近50ps,但实际上每个tap只有22ps左右,40度。

你在时钟上串个lut,那么这个lut会导致额外的hold time。虽然在绝大多数时间内都能正常工作,但是你能保证LUT在任何时间内都是在这个范围内吗?显然保证不了,电子芯片就是量子效应,测不准,你不知道它到底会在什么时间达到什么状态,你只能知道它大概在哪个时间段达到什么状态。就算它best case,就算它是覆盖了99.9999%的情况,它还有0.0000001的几率是会出错的。而这一个错,就叫你心血白费了。

所以啊,我还是建议你尽量避免用这么个方法。FPGA里面的clock gating资源很丰富,xilinx有global,regional等多组时钟,完全可以进行分块设计。串lut是最坏的选择。别的我也不多说了,你做的接口之类的,以及跨时钟域之类的多了就知道了。像我用spartan6跑800Mbps的IO,都要手动摆放关键寄存器的,否则根本跑不起来(因为xilinx的selectio根本不好用,约束条件无比多)。

争论这个意义其实不大,我们设计基本都到了纯verilog的峰顶,进一步就是做算法芯片,cnn加速,之类的。为了达到目的,可以使用任何方法。但是FPGA毕竟有它的局限性。

wx85105157 发表于 2017-9-16 11:37:06

wye11083 发表于 2017-9-16 10:49
ise只有worst case。另外LUT延时并不是可控的——从idelay_tap可以计算出,xilinx手册上给的是接近50ps, ...

好厉害。不明觉厉。

xycfwrj 发表于 2017-9-16 12:05:57

学习了,之前一直没用clock gating 还觉得不心安

xiaocat85 发表于 2017-9-16 12:58:28

wye11083 发表于 2017-9-16 10:49
ise只有worst case。另外LUT延时并不是可控的——从idelay_tap可以计算出,xilinx手册上给的是接近50ps, ...

你说得对,不可能有100%的保证,只能是尽量去降低发生的概率,只要不是在航空航天上使用,那极小概率的事件也是可以容忍的吧。在工艺不变的前提下,要降低功耗,clock gating是最有效的方法之一,要不然功耗就会成为客户压价的借口,百万门以上的设计,使用clock gating,动态功耗一般能降低30%左右,我们已经在好多量产芯片上使用了,目前还没有发现timing上重大问题,FPGA上对功耗的追求没有ASIC那么严格,所以vendor也没有动力去把这一块做好吧。另外有一点还是不明白,LUT的延时为什么会不可控呢?因为实现一种固定的function,其内部的连线方式也固定了,内部的device类型也能确认,至于温度的影响,根据代工厂给的数据是可以计算出来的,没有道理出现不可控,或者说误差不应该那么大,vivado也是一样吗?

jianfengxixi 发表于 2017-9-16 13:08:52

惊现fpga大神

偏偏倒倒 发表于 2017-9-16 13:50:52

3楼是高手

wye11083 发表于 2017-9-16 15:04:33

xiaocat85 发表于 2017-9-16 12:58
你说得对,不可能有100%的保证,只能是尽量去降低发生的概率,只要不是在航空航天上使用,那极小概率的事 ...

哈哈,你把代工厂延时数据当成真理就不对了。这个世界其实很奇妙,你永远都只能知道一个范围,却永远不可能知道真正的值,就如PI,就如光速,就如温度,就如星球运行轨迹,等等。而且这个范围也只是个大概率事件,总有很小概率会跑出去,而且在微观上几率更大(宏观上你要把几十数量级的原子同时跑偏,微观上嘛{:sleepy:} {:sleepy:} )。

你要是看手册,-2的Z7都能跑667,但据说Z7的arm有很少一部分跑不稳667M。毕竟FPGA不是CPU,没法定性定量去测。说不定,你手里2片一样的FPGA,有一块极品,有一块甚至不能正常工作。曾经我不知道要给时钟留余量,手里同样的板子同样的配置,有一片OK,另一片老是出错。当年刚工作嘛,好多事情还不知道怎么回事。现在我这做产品的遇到多了,50片XC6SLX45,所有时钟全部同步好,异步全部握手或FIFO,但是仍然有至少3片工作不稳定,其它的可以连续120小时工作,就这几片老是出毛病。

zxq6 发表于 2017-9-16 21:04:37

wye11083 发表于 2017-9-16 15:04
哈哈,你把代工厂延时数据当成真理就不对了。这个世界其实很奇妙,你永远都只能知道一个范围,却永远不可 ...

不稳定这个事情遇到过,ep2芯片里面搞了个nios,没啥外设,sram都是内置的。nios设置100M频率,就有很大几率下载不成功,跟很苦恼。某天突然来灵感,降低100M为50M,瞬间好使了。

fengyunyu 发表于 2017-9-17 07:50:41

3楼是老司机,高手

justdomyself 发表于 2017-9-17 18:27:55

wye11083 发表于 2017-9-15 00:36
后半句你说错鸟。LZ经验看起来相当丰富了,已经能写出准确无误的代码(下面一段)。上面一段在ISE下综合 ...

大师,,,,,,

sdram 发表于 2017-9-20 07:48:45

最早用verilog 觉得乱 现在一直用vhdl

zxq6 发表于 2017-9-22 17:47:13

sdram 发表于 2017-9-20 07:48
最早用verilog 觉得乱 现在一直用vhdl

能不能举个简单的例子说明一下vhdl比verilog简单?

yf869778412 发表于 2017-10-16 15:51:36

wye11083 发表于 2017-9-15 00:36
后半句你说错鸟。LZ经验看起来相当丰富了,已经能写出准确无误的代码(下面一段)。上面一段在ISE下综合 ...

我怎么记得好像是只有电平触发时缺省else才会产生latch
页: [1]
查看完整版本: 有如下两段Verilog代码,哪个好点?