Verilog代码规范
历史修改信息
版本 | 更改描述 | 更改人 | 批准人 | 修订日期/生效日期 |
A01 | 发布首版 | ldy | ||
一、目的
作为我司verilog开发过程中的输入文件,用于统一FPGA开发人员的代码风格。从而在满足功能和性能目标的前提下,能够规范代码和优化电路,增强代码的整洁度、可读性、可修改性、可维护性、可重用性、可移植性。另一方面有助于开发人员养成良好的编程习惯并理清思路,同时为FPGA选型提供指导。
二、开发流程
设计时需要把设计文档/方案写好。在设计文档中要把设计思路、 数据通路、状态机状态转移条件实现细节等描述清楚,在经过评审后才能开始编写代码,初看觉得很花费时间,但是从整个项目过程来看,绝对比一上来就编写代码节约时间,而且这种做法可以使项目处于可控、可实现的状态。
三、编写规范
项目组织形式
项目的文件统一存放在一个统一的文件夹下,根据各自功能的不同,分门别类的存放。由于编译器/开发环境的不同,存储的架构可能有所差别,但总体来说,需要至少包括以下内容:
DOC:存放项目相关的文档,包括该项目用到的datasheet、芯片规格书、设计文档等。
IP:存放官方自带的成熟IP以及项目中自己定义的常用/可复用的代码。
SIM:存放项目的仿真代码。
RTL:存放项目的 rtl 代码。这是项目的核心,文件名与 module 名称应当一致,建议按照模块的层次/子系统分开存放。
因此,组织形式如下所示:
XXX
|-- DOC
|--- IP
|-- SIM
|-- RTL
工程代码架构
Verilog 设计都是层次型的设计,是由模块一级级搭建出来的,需要按照合理的层次结构组织各个模块。顶层模块一般只实例化子模块,该模块除了内部互连线和模块实例化之外,尽量不要添加其他的逻辑,这样看起来简单直观,同时还有利于分布式的布局布线。即使要添加逻辑,也应该是很简单的 glue logic(胶合逻辑)。
单个文件构成
Verilog 文件主要有以下几个部分组成:文件声明,module IO 声明,宏定义, wire定义,parameter 定义,module 具体实现。同时规定:
① 不使用 include 包含文件;
② 一个.V 只包括一个 module;
文件声明
每一个 Verilog 文件的开头,都必须有一段声明的文字。包括文件的版权,作者,创建日期以及内容介绍等,如下表所示。
// ************************ ***************************************
// Copyright (C) xx Coporation
// File name: xx.v
// Author: xxxxxxxxxx
// Date: 2012-01-01
// Version: 1.0
// Abstract: xxxxxxx
//*****************************************************************
如果对该文件进行了修改,请在开头声明中添加以下语句,如下表所示。
// Version: 1.1
// Date: 2012-01-01
// Abstract: XXX
// Author: xxxxxxxxxx
IO/模块输入输出定义
采用 Verilog 2001 语法格式。下面是一个例子,包括 module 名字、输入输出、信号名字、输出类型、注
释。
module divider7_fsm (
//input
input sys_clk , // system clock;
input sys_rst_n , // system reset, low is active;
//output
output reg clk_divide_7 // output divide 7 clk
);
规范:
① 一行只定义一个信号;
② 信号需要对齐;
③ 同一组的的信号放一起;
Prameter 定义
规范:
① 对于本地的parameter,需要将 Prameter 定义放在紧跟着 module 的输入输出定义之后;
② Prameter 等常量命名全部使用大写。
③ 一行只定义一个信号;
对于状态机状态的parameter定义,为方便与后仿一致(后仿真会将状态优化编码为热独码),采用热独码编码。
如下所示:
// Prameter
parameter S0 = 7'b0000000;
parameter S1 = 7'b0000001;
parameter S2 = 7'b0000010;
parameter S3 = 7'b0000100;
parameter S4 = 7'b0001000;
parameter S5 = 7'b0010000;
parameter S6 = 7'b0100000;
WIRE/REG 定义
规范:
① 将 reg 与 wire 的定义放在紧跟着 prameter 之后;
② 建议具有相同功能的信号集中放在一起;
③ 信号需要对齐,reg 和位宽需要空 2 格,位宽和信号名字至少空四格;
④ 位宽使用降序描述,[6:0];
⑤ 时钟使用前缀 clk,复位使用后缀 rst;
⑥ 不能使用 Verilog 保留字作为信号名字;
⑦ 一行只定义一个信号;
//reg define
reg [6:0] curr_st ; // FSM current state
reg [6:0] next_st ; // FSM next state
reg clk_divide_7 ; // generated clock,divide by 7
//wire define
wire [6:0] aa ;
信号命名
WIRE类型一律采用w_xxx命名,如w_fifo_rd_en;
REG类型一律采用r_xxx命名,如r_ram_wr_data;
① 信号命名需要体现其意义,比如 fifo_wr 代表 FIFO 读写使能;
② 可以使用“_”隔开信号,比如 sys_clk;
③ 内部信号不要使用大写,也不要使用大小写混合,建议全部使用小写;
④ 顶层 PAD 信号名字建议全部使用大写,比如 CPU_WR 代表 CPU 写使能管脚;
⑤ 模块名字使用小写;
⑥ 低电平有效的信号,使用_n 作为信号后缀;
⑦纯延迟打拍信号使用_dly 作为后缀;
Always 块描述方式
① if 与end需要结构对齐;
② 一个 always 需要配一个 begin 和 end;
③ always 前面需要有注释;
④ 信号和逻辑运算符有空格;
⑤ beign 建议和 always 放在同一行;
⑥ 一个 always 和下一个 always 空一行即可,不要空多上;
⑦ 时钟复位触发描述使用 posedge sys_clk 和 negedge sys_rst_n
⑧ 一个 always 块只包含一个时钟和复位;
⑨ 时序逻辑使用非阻塞赋值
⑩ 信号逻辑处理的位宽需要一致,即使+1,也要和信号保持一致;
// gen a 1S counter , 1S = 50000000 * 20ns
always @(posedge sys_clk or negedge sys_rst_n) begin
if (sys_rst_n ==1'b0)
clk_cnt <= 26'b0;
else if ( clk_cnt == 26'd50000000 )
clk_cnt <= 26'b0;
else
clk_cnt <= clk_cnt + 26'b1;
end
always @(posedge sys_clk or negedge sys_rst_n) begin
xxx
其他规范
要避免适应锁存器 Latch,也要避免出现因为敏感列表不全而生成的Latch。
如果在 always 中 case 或 if 语句的分支逻辑不全,就会生成锁存器,需注意检查它们的分支结构,将条件赋值语句写全,例如在 if 语句最后加一else,在 case 语句最后加一个 default。
模块应尽量采用“寄存输入,寄存输出”
即对于模块的输入信号尽量在寄存器锁存之后再用,但是如果输入信号是其他模块的寄存器输出,那么可以不用寄存器锁存;对于模块的输出信号,尽量用寄存器锁存之后再输出。这么做的可以使输入时序、输出强度和输出延迟都得到预测,可以更好的 Timing。
优先级
在表达式内使用括号表示运算的优先级。
仿真文件
针对每个模块撰写仿真文件,再进行该功能的聚类仿真,依次类推完成整个顶层仿真。
Verilog代码规范的更多相关文章
- Verilog代码规范I
Verilog代码规范I "规范"这问题 "规范"这个富含专业气息的词汇(个人感觉),其实规范这种东西,就是大家都约定熟成的东西,一旦你不遵守这个东西,专业人士 ...
- Verilog代码规范(持续更新)
1.输入输出的定义,看起来整齐 2.always.if或其他语句后begin写在同一行,这样可以避免begin占用过多的行,代码密度更大 3.end后面要有注释,以标明是哪个关键词的结束,除了endc ...
- Verilog 编写规范
在学习Python时,作者有一句话对我影响很大.作者希望我们在学习编写程序的时候注意一些业内约定的规范.在内行人眼中,你的编写格式,就已经暴露了你的程度.学习verilog也是一样的道理,一段好的ve ...
- iOS代码规范(OC和Swift)
下面说下iOS的代码规范问题,如果大家觉得还不错,可以直接用到项目中,有不同意见 可以在下面讨论下. 相信很多人工作中最烦的就是代码不规范,命名不规范,曾经见过一个VC里有3个按钮被命名为button ...
- 谈谈PHP代码规范
[转] http://www.syyong.com/php/Talk-about-PHP-code-specification.html 我向往这样一个php世界,里面没有代码规范之争.你我都一样,都 ...
- 2016 正确 sublime安装PHPcs PHPcodesniffer代码规范提示插件,修正网上部分不详细描述
对你有助请点赞,请顶,不好请踩------送人玫瑰,手留余香!-------------------14:37 2016/3/212016 正确 sublime安装PHPcs PHPcodesniff ...
- C#与Java对比学习:类型判断、类与接口继承、代码规范与编码习惯、常量定义
类型判断符号: C#:object a; if(a is int) { } 用 is 符号判断 Java:object a; if(a instanceof Integer) { } 用 inst ...
- 作业三: 代码规范、代码复审、PSP
分) 对于是否需要有代码规范,请考虑下列论点并反驳/支持: 这些规范都是官僚制度下产生的浪费大家的编程时间.影响人们开发效率, 浪费时间的东西. 我是个艺术家,手艺人,我有自己的规范和原则. 规范不能 ...
- 转!!Java代码规范、格式化和checkstyle检查配置文档
为便于规范各位开发人员代码.提高代码质量,研发中心需要启动代码评审机制.为了加快代码评审的速度,减少不必要的时间,可以加入一些代码评审的静态检查工具,另外需要为研发中心配置统一的编码模板和代码格式化模 ...
- C#代码规范
C#代码规范 一.文件命名 1 文件名 文件名统一使用帕斯卡命名法,以C#类名命名,拓展名小写. 示例: GameManager.cs 2 文件注释 每个文件头须包含注释说明,文件头位置指的是文件最 ...
随机推荐
- 如何使用 Shebang
什么是 Shebang? 简单来说,就是你在脚本开头看到的这个: #!/usr/bin/bash Shebang(也称为 hash-bang.pound-bang 或者 bang)是一个作为脚本文件中 ...
- 总结:redis 突然变慢
用户量暴增,无法下单,凌晨的夜,静悄悄... 经过查找发现Redis. 获取不到连接资源,并且集群中的单台 Redis 连接量很高. 大量的流量没了 Redis 的缓存响应,直接打到了 MySQL,最 ...
- 《放弃繁琐的if-else》开启Assert断言的新时代
一.场景再现 我们平时在service操作数据库,难免会出现这种情况: if(null == result){ }else{ } 这样的代码会吞噬掉你有限的代码空间,虽然通俗易懂,但一旦爆炸式的袭来, ...
- 工具 – Vite
前言 一直想 try Vite, 但一直没有机会. 今天突然 Live Server IP Address 手机连不上...也不知道是 Bug 还是怎么回事儿. 总之 IIS IP Address 没 ...
- 离线安装Redis
redis 直接去官网下载tar包就可以 主要是gcc 环境的安装包不太好找,我下载的还缺少 make 如果服务器比较干净,还得预装一下lrzsz-0.12.20.tar.gz 上传下载文件,unzi ...
- 【赵渝强老师】使用Oracle的跟踪文件
一.什么是跟踪文件? 跟踪文件中包含了大量而详细的诊断和调试信息.通过对跟踪文件的解读和分析,我们可以定位问题.分析问题和解决问题.从跟踪文件的产生的来源来看,跟踪文件又可以分为两类:一类是数据库的操 ...
- Js运算符(操作符)
算数运算符 a = 1 + 1 // 2 a = 10 - 5 // 5 a = 10 / 5 // 2 a = 10 / 0 // js中除以0不会报错,结果是Infinity a = 2*2 // ...
- linux安装SVN并设置SVN钩子
linux安装SVN并设置SVN钩子 检查已安装版本 #检查是否安装了低版本的SVN rpm -qa subversion #卸载旧版本SVN yum rovesubversion 一.安装SVN y ...
- google 搜索技巧
size qq.com inurl : size 指定网站 inurl 这个网站的指定内容 filetype 指定搜索的文件类型
- 38. data为什么是一个函数
vue中的data为什么是返回对象的函数,而不是直接使用对象形式 : 我们复用组件的时候,要求每一份data数据之间是独立的,不能互相影响,如果写成对象的形式所有的组件使用一份data数据 ,如果使用 ...