科普一下Verilog代码命名规范

描述

代码规范的文档,就是一份设计工程师的血泪史。

命名规范

命名规范包括模块命名规范和代码命名规范,代码命名需要有确定的含义,提高代码可读性和可维护性。模块名命名规范处理好认,一眼就能把看出你是哪个IP里面的一个子模块之外,更重要的一个原因是防止两个module重名 ,比如你把模块起名叫,shift_reg_dly_module,但是整个soc中可能会有其他IP也叫这个module名,这样同名不同工的文件,会影响集成级的工作。

所以代码规范module命名这样,子系统_子模块_function_module。例如ddr_shift_reg_dly_module。避免模块名重名。

综合自动插时钟门控

并不是所有的寄存器都需要带复位,这样规范颠覆初入行的朋友认知。有研究表明,带复位的寄存器和不带复位的寄存器相比,面积会相差10%。但是这样也有一个原则,就是控制寄存器必须带复位,数据寄存器可以不复位,但是不能用去做条件。

计数器

计数器,必须有使能端和清零端,不允许裸奔

 

always @(posedge clk or negedge rst_n)begin
  if(rst_n == 1'b0)begin
    o_cnt[7:0] <= 8’d0;
  end
  else if(cnt_clr == 1’b1)begin
    o_cnt[7:0] <= 8’d0;
  end
  else if (cnt_en == 1’b1)begin
    o_cnt[7:0] <= o_cnt[7:0] + 1'b1;
  end
end

 

数据寄存器带使能打拍锁存使用

 

always @(posedge clk)begin
  if(data_vld)
    dout[63:0] <= din;
end

 

这种写法综合自动插时钟门控,而且不带复位。注意不能裸奔。

 

always @(posedge clk)begin
    dout[63:0] <= din;
end

 

这样写就GG了

优先使用spram

有一种代码规范是要求必须使用spram,single port ram。即使有同时读写的需求,也自己做逻辑,将读写分开做。强烈这么要求的原因是,有研究数据表明,在某工艺下,spram比dpram的面积基本会小30%。

30%的memory收益,这个收益还是很猛的。

memory规范操作

Memory必须先写后读,读写使能默认复位值必须是无效值。不用的时候不允许读,否则会出现上电后芯片的memory一直扫描读写,徒增功耗。

Memory的数据读出必须锁存后使用。

memory和logic分开

Memory不散在逻辑中,将memory的读写控制端口都从IP的顶层伸出统一管理,为的是mem方便统一替换处理。而且后端实现上memory放边摆开。

方便不同工艺的适配,比如你要换一个工艺,那你的memory要全部替换,就要在logic里面找,假如有些工艺十分恶心,要加个寄存器或者输出到寄存器上,你就要一层层穿线到顶层寄存器模块。作为IP供应商也应该做好memory的wrapper提供给客户,方便客户替换。

后端实现memory放边摆开,logic要也考虑到memory的走线,所以对于memory的入口和出口都要是寄存器。不然PR出了问题,该做的还是得做。

模块必须寄存器入寄存器出

在后端布局布线过程中,逻辑少的模块之间还好,但harden之间有逻辑交互,两个harden的距离并不一定摆的位置靠近。如果不是寄存器入寄存器出,会导致两个harden之间交互的信号时序差。造成工作反复。

自研IP不建议用`define来定义参数

要求用parameter,define使用要谨慎,因为define是全局定义的,如果再使用过程中不当,没有undef掉,可能会影响其他IP的同名define值。正确使用没问题,无对错,遵守公司代码规范即可 。







审核编辑:刘清

打开APP阅读更多精彩内容
声明:本文内容及配图由入驻作者撰写或者入驻合作网站授权转载。文章观点仅代表作者本人,不代表电子发烧友网立场。文章及其配图仅供工程师学习之用,如有内容侵权或者其他违规问题,请联系本站处理。 举报投诉

全部0条评论

快来发表一下你的评论吧 !

×
20
完善资料,
赚取积分