Verilog用于芯片的设计和验证,被广大硬件码农们所使用,写出来一段verilog代码很容易,然而想写好一段verilog代码却非易事,verilog设计中有很多讲究的地方,本节对其中的一部分进行总结,供广大硬件码农们参考。部分代码是自己根据理解进行撰写的,部分思路参考书籍。本节的图片均来自本人的亲自截取。
方法/步骤
1、不以if-else作为条件的区分//不推荐的方式Always@(posedgeclkornegedgenrst)If(condition1)sig1<=data;If(~nrst)sig1<=0;//推荐的方式Always@(posedgeclkornegedgenrst)If(~nrst)sig1<=0;Elseif(condition1)sig1<=data;
2、同时进行上升沿和下降沿的混合设计Always@(posedgeclk)If(condition1)sig1<=data;Always@(negedeclk)If(condition2)sig2<=data;除非特殊情况(如DDR),一个设计中避免混合使用上升沿和下降沿触发,不利于时钟树综合,对自动测试向量产生也会有不利的影响。
3、多multipledrivers,一个信号进行多个驱动Always@(posedgeclk1)If(condition1)sig1<=data;Always@(negedeclk2)If(condition2)sig2<=data;一般设计中用到的触发器只有一个时钟,除非在工艺中有专门的器件,并且在设计中进行专门的指定,否则这种设计在综合的时候是通不过的。
4、case语句里遗漏default的描述,这种情况下一般会综合出锁存器。//badAlways(sel,a)Case2’b00:out=a;2’b01:out=b;2’b10:out=c;Endcase//goodAlways(sel,a)Case2’b00:out=a;2’b01:out=b;2’b10:out=c;Default:out=0;Endcase
5、 绝对避免多重驱动 al嘛术铹砾ways@(posedgeclk) if(condition1)sig<=0; always@烫喇霰嘴(posedgeclk) if(condition2)sig<=1; wiresig=condition1?A:0; wiresig=condition2?B:0; 如果condition1和condition2同时成立的话,那么sig的值到底为多少呢,因而多重驱动在设计中必须要避免。
6、混合同步与异步的reset语句,这种情况也不利于张虢咆噘时序的分析触发器的异步输入应该只有reset信号,不应合并其他同步信号,有些FPGA综合工具不允许这样的语法。//badReg缪梨痤刻[3:0]cnt;Always(posedgeclkornegedgenrst)If(~nrst)cnt<=0;Elsecnt<=cnt+1;Wiresyn_rst=(cnt>=10);Always(posedgeclkornegedgenrst)If(~nrst|syn_rst)Out<=0;ElseOut<=in;//goodReg[3:0]cnt;Always(posedgeclkornegedgenrst)If(~nrst)cnt<=0;Elsecnt<=cnt+1;Wiresyn_rst=(cnt>=10);Always(posedgeclkornegedgenrst)If(~nrst)Out<=0;Elseif(syn_rst)Out<=0;elseOut<=in;
7、模块易七淄苷之间使用双向信号双向信号会使用到三态缓冲器,这种缓冲器一般只在chip-level才会使用,在chip内部使用Tristate的缺点如下:Trist锾攒揉敫atelogic存在信号碰撞的风险(buscontention),目前为止,没有攻击能帮助我们解决这个问题,内部控制使能逻辑也难保证不产生错误,Tristatelogic是完全不必要的,因而可以用两组信号进行取代。当Tristate皆不被输入或者输出使能时,此时bus上会呈现floating的状态,这将导致巨大的功耗。增加静态时序分析、DFT与布线的困难程度。
8、 状态机要有复位 没有初始状态的程序状态机,这样的程序状态机遗漏了reset描述,当系统开机时,无法确定进入哪个状态,有可能进入非预期的状态。
9、最好用always@(*),敏感列表要完整//badRega,b,c;always@(aorb)out=a&(b|c);敏感列表不完整会导致前后仿不同。
10、对组合逻辑进行了复位操作//badRega,b,c;always@(*)if(~nrst)out=0;elseout=a&(b|c);//good,应该使用时序进行打拍子处理Always(posedgeclkornegedgenrst)If(~nrst)Begina<=0;b<=0;c<=0;endelsebegi…Endalways@(*)out=a&(b|c);