FPGA设计规范之Verilog编码规范
0 2023-03-21

No.1

命名规则

  1. 首先每个文件只包含一个module,而且module名要小写,并且与文件名保持一致;

  2. 除parameter外,信号名全部小写,名字中的两个词之间用下划线连接,如receive_clk_b;

  3. 由parameter定义的常量要求全部字母大写,自己定义的参数、类型用大写标识,推荐使用parameter来定义有实际意义的常数,包括单位延时、版本号、板类型、单板在位信息、LED亮灯状态、电源状态、电扇状态等;

  4. 信号名长度不超过20字符,并且避免使用Verilog和VHDL保留字命令,建议给信号名添加有意义的前缀或后缀,命名符合常用命名规范(如_clk 或clk_表示时钟, n表示低电平有效, z表示三态信号, en表示使能控制,rst 表示复位);

  5. 保持缩写意义在模块中的一致性,同一信号在不同层次应该保持一致性。


No.2

注释规则

  1. 每个文件有一个文件头,文件头中注明文件名、功能描述、引用模块、设计者、设计时间、版权信息以及修改信息等;

  2. 对信号、参量、引脚、模块、函数及进程等加以说明,便于阅读与维护,如信号的作用、频率、占空比、高低电平宽度等。用“//”做小于1行的注释,用“/* */”做多于1行的注释。更新的内容要做注释,记录修改原因,修改日期和修改人。

No.3

模块规则

  1. module例化名用u_xx_x标示;

  2. 建议给每个模块要加timescale;

  3. 不要书写空的模块,即:一个模块至少要有一个输入和一个输出;

  4. 为了保持代码的清晰、美观和层次感,一条语句应占用一行,每行限制在80个字符以内,如果较长(超出80个字符)则换行;

  5. 采用基于名字(name_based)的调用而不是基于顺序的(order_based)的调用;

  6. 模块的接口信号按输入、双向、输出顺序定义;

  7. 使用降序定义向量有效位顺序,最低位为0;

  8. 管脚和信号说明部分:一个管脚和一组总线占用一行,说明要清晰;

  9. 不要采用向量的方式定义一组时钟信号;

  10. 逻辑内部不对input进行驱动,在module内不存在没有驱动源的信号,更不能在模块端口存在没有驱动的输出信号,避免在elabarate和compile时产生warning;

  11. 在顶层模块中,除了内部的互连和module的例化外,避免在做其他逻辑;

  12. 出于层次设计和同步设计的考虑,子模块输出信号建议用寄存器;

  13. 内部模块端口避免inout,最好在最顶层模块处理双向总线;

  14. 子模块中禁止使用三态逻辑,可以在顶层模块使用;

  15. 如果能确保该信号不会被其它子模块使用,而是直接通过顶层模块输出I/O口,可以在子模块中使用三态;

  16. 禁止出现未连接的端口;

  17. 为逻辑升级保留的无用端口和信号要注释;对于层次化设计的逻辑,在升级中采用增量编译;建议采用层次化设计,模块之间相对独立。


No.4

线网和寄存规则

  1. 锁存器和触发器不允许在不同的always块中赋值,造成多重驱动;

  2. 出于功能仿真考虑,非阻塞赋值应该增加单位延时,对于寄存器类型的变量赋值时,尤其要注意这一点;阻塞赋值不允许使用单位延时;

  3. always语句实现时序逻辑采用非阻塞赋值;always语句实现的组合逻辑和assign语句块中使用阻塞赋值;

  4. 同一信号赋值不能同时使用阻塞和非阻塞两种方式;

  5. 不允许出现定义了parameter、wire、reg却没有使用的情况;

  6. 不建议使用integer类型寄存器;

  7. 寄存器类型的信号要初始化;

  8. 除移位寄存器外,每个always语句只对一个变量赋值,尽量避免在一个always语句出现多个变量进行运算或赋值。

No.5

表达式规则

  1. 在表达式内使用括号表示运算的优先级,一行中不能出现多个表达式;

  2. 不要给信号赋“x”态,以免x值传递;

  3. 设计中使用到的0,1,z等常数采用基数表示法书写(即表示为1'b0,1'b1,1'bz或十六进制);

  4. 端口申明、比较、赋值等操作时,数据位宽要匹配。

No.6

条件语句规则

  1. if 都有else和它对应,变量在if-else或case语句中所有变量在所有分支中都赋值;

  2. 如果用到case语句,记得default项;

  3. 禁止使用casex,case语句item必须使用常数;

  4. 不允许使用常数作为if语句的条件表达式;

  5. 条件表达式必须是1bit value;

  6. 如异步复位:

    高电平有效使用“if(asynch_reset==1'b1)”,

    低电平“if(asynch_reset==1'b0)”,

    不要写成

    “if(!asynch_reset)”或者“if(asynch_reset==0)”;

  7. 不推荐嵌套使用5级以上if…else if…结构。

No.7

可综合部分规则

  1. 不要使用include语句;

  2. 不要使用disable、initial等综合工具不支持的电路,而应采用复位方式进行初时化,但在testbench电路中可以使用;

  3. 不使用specify模块,不使用===、!==等不可综合的操作符;

  4. 除仿真外,不使用fork-join语句;

  5. 除仿真外,不使用while语句;

  6. 除仿真外,不使用repeat语句;

  7. 除仿真外,不使用forever语句;

  8. 除仿真外,不使用系统任务($);

  9. 除仿真外,不使用deassign语句;

  10. 除仿真外,不使用force,release语句;

  11. 除仿真外,不使用named events语句;不在连续赋值语句中引入驱动强度和延时;

  12. 禁止使用trireg型线网;

  13. 制止使用tri1、tri0、triand和trior型的连接;

  14. 不要位驱动supply0和supply1型的线网赋值;

  15. 设计中不使用macro_module;

  16. 不要在RTL代码中实例门级单元尤,其下列单元:(CMOS/RCOMS/NMOS/PMOS/RNMOS/RPMOS/trans/rtrans/tranif0/tranif1/rtranif0/tranif1/pull_gate)。


No.8

可重用的部分规则

  1. 考虑未使用的输入信号power_down,避免传入不稳定态;

  2. 接口信号尽量少,接口时序尽量简单;

  3. 将状态机(FSM)电路与其它电路分开,便于综合和后端约束;

  4. 将异步电路和同步电路区分开,便于综合和后端约束,将相关的逻辑放在一个模块内;

  5. 合理划分设计的功能模块,保证模块功能的独立性;

  6. 合理划分模块的大小,避免模块过大;

  7. 在设计的顶层(top)模块,将I/O口、Boundary scan电路、以及设计逻辑(corelogic)区分开。

No.9

同步设计规则

  1. 同一个module中,要在时钟信号的同一个沿动作;

  2. 如果必须使用时钟上升沿和时钟下降沿,则要分两个module设计;

  3. 在顶层模块中,时钟信号必须可见,不在模块内部生成时钟信号,而要使用DCM/PLL产生的时钟信号;

  4. 避免使用门控时钟和门控复位;

  5. 同步复位电路,建议在同一时钟域使用单一的全局同步复位电路;

    异步复位电路,建议使用单一的全局异步复位电路;

  6. 不在时钟路径上添加任何buffer;

  7. 不在复位路径上添加任何buffer;

  8. 避免使用latch;

  9. 寄存器的异步复位和异步置位信号不能同时有效;

  10. 避免使用组合反馈电路;

  11. always有且仅有一个的敏感事件列表,敏感事件列表要完整,否则可能会造成前后仿真的结果不一致;

  12. 异步复位情况下需要异步复位信号和时钟沿做敏感量,同步复位情况下只需要时钟沿做敏感量;

  13. 时钟事件的表达式要用:

    “negedge”

    “posedge”的形式;

  14. 复杂电路将组合逻辑和时序逻辑电路分成独立的always描述。

No.10

循环语句规则

  1. 在设计中不推荐使用循环语句;

  2. 在非常有必要使用的循环语句时,可以使用for语句。

No.11

约束规则

  1. 对所有时钟频率和占空比都进行约束;

  2. 对全局时钟skew进行约束;

  3. 对于时序要求的路径需要针对特殊要求进行约束,如锁相环鉴相信号;

  4. 要根据输出管脚驱动要求进行约束,包括驱动电流和信号边沿特性;

  5. 要根据输入和输出信号的特性进行管脚上下拉约束;

  6. 针对关键I/O是否约束了输入信号和输入时钟的相位关系,控制输入信号在CLK信号之后或之前多少ns到达输入pad;

  7. 综合设置时,fanout建议设置为3030;

  8. 要使用输入输出模块中的寄存器,如Xinlinx公司的IOB,map properties选项pack I/O register/latches into IOBsactor需要设置成为“for input and output”,这样可以控制管脚到内部触发器的延时时间;

  9. 布局布线报告中IOB、LUTs、RAM等资源利用率应小于百分之八十;

  10. 对于逻辑芯片对外输入接口,进行tsu/th约束;对于逻辑芯片对外输出接口,进行约束。

No.12

PLL/DCM规则

  1. 如果使用FPGA内部DCM和PLL时,应该保证输入时钟的抖动小于300ps,防止DCM/PLL失锁;如果输入时钟瞬断后必须复位PLL/DCM。

  2. 对于所有厂家的FPGA,其片内锁相环只能使用同频率的时钟信号进行锁相,如果特殊情况下需要使用不同频率的信号进行锁相,需要得到厂家的认可,以避免出时钟。

No.13

代码编辑规则

由于不同编辑器处理不同,对齐代码使用空格,而不是tab键。


声明: 本文转载自其它媒体或授权刊载,目的在于信息传递,并不代表本站赞同其观点和对其真实性负责,如有新闻稿件和图片作品的内容、版权以及其它问题的,请联系我们及时删除。(联系我们,邮箱:evan.li@aspencore.com )
0
评论
  • 相关技术文库
  • FPGA
  • 可编程
  • PLC
  • verilog
  • 时钟发生器的相位噪声和抖动性能

    系统设计师通常侧重于为应用选择最合适的数据转换器,在向数据转换器提供输入的时钟发生器件的选择上往往少有考虑。然而,如果不慎重考虑时钟发生器的相位噪声和抖动性能,

    前天
  • 雷达信号处理上是选FPGA还是GPU,它们各自的特点又是什么?

      FPGA和CPU一直是雷达信号处理不可分割的组成部分。传统上FPGA用于前端处理,CPU用于后端处理。随着雷达系统的处理能力越来越强,越来越复杂,对信息处理

    05-29
  • PLC的相关知识分析

    写点纯理论的东西,最近一直在思考怎么跟零基础的人讲PLC。也就是当你面对一个门外汉时,怎么让他对PLC感兴趣,然后慢慢的带着学习PLC。思考了很多,又把学校的里

    05-27
  • 一文分析DDR线长匹配与时序

    DDR布线在PCB设计中占有举足轻重的地位,设计成功的关键就是要保证系统有充足的时序裕量。要保证系统的时序,线长匹配又是一个重要的环节。我们来回顾一下,DDR布

    05-27
  • 带你区分时序图、活动图、状态图、协作图

      时序图  时序图用于描述对象之间的传递消息的时间顺序,即用例中的行为顺序。  当执行一个用例时,时序图中的每条消息对应了一个类操作或者引起转换的触发事件。 

    05-26
  • 区分FPGA与DSP特点及用途

      FPGA是一种可编程的硅芯片,DSP是数字信号处理,当系统设计人员在项目的架构设计阶段就面临到底采用FPGA还是DSP的重要问题。本文将首先分别介绍FPGA

    05-26
  • FPGA概念对比CPU架构有啥特点

      你还没听过FPGA?那你一定是好久没有更新自己在企业级IT领域的知识了。今天笔者就和大家聊聊何为FPGA?FPGA主要应用场景是什么?有人说FPGA是替代传

    05-26
  • 时序收敛十大准则

    本文摘自《Vivado使用误区与进阶》,作者为Xilinx工具与方法学应用专家Ally Zhou。 时序收

    05-26
  • 仿真软件ModelSim及其应用

    如果您是FPGA开发方面的初学者,那么这个教程一定能够帮助你在仿真技术上越过新人的台阶;如果您是FPGA开发的老手,这篇文档也并非对您没有帮助,您可以把教程发给其他刚入门的同事,免去您亲自上阵指导的麻烦,把主要的精力放在更有价值的地方。

    05-25
  • 快速认识FPGA

      学习FPGA,在不同层次的人明显有不同的答案。先说一句,说不要开发版的都是菜鸟级选手。  我把FPGA层次划分为,鸡蛋级别,菜鸟级别,老鸟级别,高手级别四类

    05-25
  • 分析FPGA与CPLD的差别在哪

      1.CPLD  CPLD主要是由可编程逻辑宏单元(LMC,LogicMacroCell)围绕中心的可编程互连矩阵单元组成,其中LMC逻辑结构较复杂,并具有复

    05-25
  • FPGA与CPLD的作用及不同之处

      FPGA/CPLD能完成任何数字器件的功能,上至高性能CPU,下至简单的74电路,都可以用FPGA/CPLD来实现。  FPGA/CPLD如同一张白纸或是一

    05-24
下载排行榜
更多
广告