Verilog设计10项注意

2025-10-15 12:11:18

1、不以if-else作为条件的区分

//不推荐的方式

Always@(posedge clk or negedge nrst)

  If(condition1) sig1<=data;

  If(~nrst) sig1<=0;

//推荐的方式

Always@(posedge clk or negedge nrst)

  If(~nrst) sig1<=0;

Else if(condition1) sig1<=data;

2、 

同时进行上升沿和下降沿的混合设计

Always@(posedge clk)

  If(condition1) sig1<=data;

Always@(negede clk)

  If(condition2) sig2<=data;

除非特殊情况(如DDR),一个设计中避免混合使用上升沿和下降沿触发,不利于时钟树综合,对自动测试向量产生也会有不利的影响。

3、 

多multipledrivers,一个信号进行多个驱动

Always@(posedge clk1)

  If(condition1) sig1<=data;

Always@(negede clk2)

  If(condition2) sig2<=data;

一般设计中用到的触发器只有一个时钟,除非在工艺中有专门的器件,并且在设计中进行专门的指定,否则这种设计在综合的时候是通不过的。

4、 

case语句里遗漏default的描述,这种情随盆况下一般会综合出锁存器。

//bad

Always(sel,a)

Case

2’b00:out=a;

2’b01:out=b;

2’b10:out=c;

Endcase

//good

Always(sel,a)

Case

2’b00:out=a;

2’b01:out=b;

2’b10:out=c;

Default:out=0;

Endcase

 

5、 

绝对避免多重驱动

always@(posedge clk)

  if (condition1) sig<=0;

always@(posedge clk)

  if(condition2) sig<=1;

wire sig=condition1?A:0;

wire sig=condition2?B:0;

如果condition1和condition2同时成立的话,那么sig的值到底为多少呢,因而多重驱动在设计中必须要避免。

6、 

混合同步与异步的reset语句,这种情况也不利于时序的分析

触发器的异步输入应该只有reset信号,不应合并其他同步信号,有些FPGA综合工具不允许酱材这样的语法。

//bad

Reg[3:0] cnt;

Always(posedge clk or negedge nrst)

If (~nrst) cnt<=0;

Else cnt<=cnt+1;

Wire syn_rst=(cnt>=10);

Always(posedge clk or negedge nrst)

If(~nrst | syn_rst)

Out<=0;

Else

Out<=in;

//good

Reg[3:0] cnt;

Always(posedge clk or negedge nrst)

If (~nrst) cnt<=0;

Else cnt<=cnt+1;

Wire syn_rst=(cnt>=10);

Always(posedge clk or negedge nrst)

If(~nrst)

Out<=0;

Else if (syn_rst)

Out<=0;

else

Out<=in;

7、 

模块之间使用双向信号

双向信号会使用到三态缓冲器,这种缓冲器一般只在chip-level才会使用,在chip内部使用Tristate的缺点如下:

Tristate logic存驾裕帽在信号碰撞的风险(bus contention),目前为止,没有攻击能帮助我们解决这个问题,内部控制使能逻辑也难保证不产生错误,Tristate logic是完全不必要的,因而可以用两组信号进行取代。

当Tristate皆不被输入或者输出使能时,此时bus上会呈现floating的状态,这将导致巨大的功耗。

增加静态时序分析、DFT与布线的困难程度。

8、 

状态机要有复位

没有初始状态的程序状态机,这样的程序状态机遗漏了reset描述,当系统开机时,无法确定进入哪个状态,有可能进入非预期的状态。

Verilog设计10项注意

9、 

最好用always@(*),敏感列表要完整

//bad

Reg a,b,c;

always@(a or b)

out=a & (b | c);

敏感列表不完整会导致前后仿不同。

10、 

对组合逻辑进行了复位操作

//bad

Reg a,b,c;

always@(*)

if(~nrst)

out=0;

else

out=a & (b | c);

//good,应该使用时序进行打拍子处理

Always(posedge clk or negedge nrst)

If (~nrst)

Begin

 a<=0;

 b<=0;

 c<=0;

end

else

begi

End

always@(*)

out=a & (b | c);

 

声明:本网站引用、摘录或转载内容仅供网站访问者交流或参考,不代表本站立场,如存在版权或非法内容,请联系站长删除,联系邮箱:site.kefu@qq.com。
猜你喜欢