VERILOG语言编写规范.docx
《VERILOG语言编写规范.docx》由会员分享,可在线阅读,更多相关《VERILOG语言编写规范.docx(22页珍藏版)》请在冰豆网上搜索。
VERILOG语言编写规范
VERILOG语言编写规范
1 目的
本规范的目的是提高书写代码的可读性可修改性 可重用性,优化代码综合和仿真结果,指导设计工程师使用VerilogHDL规范代码和优化电路 ,规范化公司的ASIC设计输入从而做到
1.逻辑功能正确2.可快速仿真3.综合结果最优如果是hardwaremodel)4.可读性较好。
2范围
本规范涉及VerilogHDL编码风格,编码中应注意的问题, Testbench的编码等。
本规范适用于Verilogmodel的任何一级( RTL behavioral,gate_level),也适用于出于仿真,综合或二者结合的目的而设计的模块。
3 定义
VerilogHDL:
Verilog硬件描述语言
FSM :
有限状态机
伪路径 :
静态时序分析(STA)认为是时序失败,而设计者认为是正确的路径
4引用标准和参考资料
下列标准包含的条文 通过在本标准中引用而构成本标准的条文在标准出版时所示版本
均为有效 所有标准都会被修订 使用本标准的各方应探讨使用下列标准最新版本的可能性
ActelHDLCodingStyle Guider
SunMicrosystems
Revision1.0
VerilogStyle andCoding Guidelines
5规范内容
5.1Verilog 编码风格
本章节中提到的Verilog编码规则和建议适应于Verilog model的任何一级( RTLbehavioral,gate_level)也适用于出于仿真,综合或二者结合的目的而设计的模块。
5.1.1 命名规范
选择有意义的信号和变量名,对设计是十分重要的。
命名包含信号或变量诸如出处,有效状态等基本含义下面给出一些命名的规则。
1.用有意义而有效的名字
有效的命名有时并不是要求将功能描述出来如
For (I =0; I < 1024;I=I+ 1 )
Mem[I]<=#132’b0;
For语句中的循环指针I就没必要用loop_index作为指针名。
2.用连贯的缩写
长的名字对书写和记忆会带来不便, 甚至带来错误 采用缩写时应注意同一信号在模块中的一致性。
缩写的例子如下:
Addr address
Pntr pointer
Clk clock
Rst reset
3. 用名字前加小写n表示低电平有效高电平有效的信号不得以下划线表示短暂
的引擎信号建议采用高有效
如nRst,nTrdy, nIrdynIdsel.
4. 大小写原则
名字一般首字符大写,其余小写 (但parameter,integer 定义的数值名可全部用大写),两个词之间要用下划线连接(或第二个单词首字母大写)
如:
Packet_addr, Data_in,Mem_wr, Mem_ce_
Or:
PacketAddr, DataIn, MemWr ,MemCe
5.全局信号名字中应包含信号来源的一些信息
如:
D_addr[7:
2] 这里的D 指明了地址是解码模块(Decodermodule)中的地址.
6.同一信号在不同层次应保持一致性
7.自己定义的常数类型等用大写标识
如:
parameter CYCLE=100.
8.避免使用保留字
如inout xz等不能够做为变量端口或模块名
9. 添加有意义的后缀 使信号名更加明确 常用的后缀如下
芯片的双向信号-xbio
芯片的三态输出_xz
芯片的漏极开路输出_xod
芯片原始输出信号 _xo
芯片原始输入信号 _xi
下降沿有效的寄存器_f
连到三态输出的信号 _z
寄存前的信号_next
时钟信号 _Clk
5.1.2Modules
1.顶层模块应只是内部模块间的互连
Verilog设计一般都是层次型的设计, 也就是在设计中会出现一个或多个模块,模块间的调用在所难免。
可把设计比喻成树, 被调用的模块就是树叶,没被调用的模块
就是树根, 那么在这个树根模块中, 除了内部的互连和模块的调用外, 尽量避免再做逻辑, 如:
不能再出现对reg变量赋值等, 这样做的目的是为了更有效的综合, 因为在顶层模块中出现中间逻辑,Synopsys的designcompiler 就不能把子模块中的逻辑综合到最优。
2.每一个模块应在开始处注明文件名功能描述引用模块设计者设计时间及版
权信息等
如 /*=========================== *\
Filename﹕SPI_M.v
Author﹕whq
Description﹕Filedescription
Calledby﹕Top module
RevisionHistory ﹕timeyy-mm-dd
Revision1.0
Email﹕wuhaoqian1@
Copyright(c)1999,~~~~~~~~~~~~~,Allrightreserved
/*===========================*\
3.不要对Inpu t进行驱动, 在module内不要存在没有驱动的信号,更不能在模块端口中出现没有驱动的输出信号,避免在仿真或综合时产生warning,干扰错误定位
4.每行应限制在80个字符以内以保持代码的清晰美观和层次感
一条语句占用一行如果较长,超出80个字符则要换行。
5.电路中调用的module 名用Uxx标示。
向量大小表示要清晰, 采用基于名字(name_based)的调用而非基于顺序的 (order_based)。
Instance UInstance2(
.DataOut(DOUT ),
.DataIn(DIN),
.Cs_(Cs_)
);
6.用一个时钟的上沿或下沿采样信号,不能一会儿用上沿, 一会儿用下沿。
如果既要用上沿又要用下沿,则应分成两个模块设计。
建议在顶层模块中对Clock做一非门,在层次模块中如果要用时钟下沿就可以用非门产生的PosedgeClk_, 这样的好处是在整个设计中采用同一种时钟沿触发,有利于综合。
基于时钟的综合策略
7. 在模块中增加注释
对信号, 参量,引脚,模块, 函数及进程等加以说明, 便于阅读与维护。
8.Module 名要用大写标示,且应与文件名保持一致。
如Module DFF_ASYNC_RST(
Reset,
Clk,
Data,
Qout
);
严格芯片级模块的划分
只有顶层包括IO引脚(pads),中间层是时钟产生模块,JTAG,芯片的内核(CORE),这样便于对每个模块加以约束仿真,对时钟也可以仔细仿真。
模块输出寄存器化
对所有模块的输出加以寄存( 如图1)使得输出的驱动强度和输入的延迟可以预测,从而使得模块的综合过程更简单
-输出驱动的强度都等于平均的触发器驱动强度
图1
9.将关键路径逻辑和非关键路径逻辑放在不同模块
保证DC可以对关键路径模块实现速度优化,而对非关键路径模块实施面积优化在。
同一模块DC无法实现不同的综合策略,将相关的组合逻辑放在同一模块,有助于DC对其进行优化 因为DC通常不能越过模块的边界来优化逻辑。
5.1.3Netand Register
1. 一个reg变量只能在一个always语句中赋值
2.向量有效位顺序的定义一般是从大数到小数
尽管定义有效位的顺序很自由,但如果采用毫无规则的定义势必会给作者和读代码
的人带来困惑,如Data[-4:
0],则LSB[0][-1][-2][-3][-4]MSB,或Data[0:
4]则
LSB[4][3][2][1][0]MSB这两种情况的定义都不太好,推荐Data[4:
0]这种格式的定
义。
3.对net和register类型的输出要做声明 在PORT中。
如果一个信号名没做声明Verilog将假定它为一位宽的wire变量。
4.线网的多种类型。
寄存器的类型。
5.1.4Expressions
1.用括号来表示执行的优先级
尽管操作符本身有优先顺序,但用括号来表示优先级对读者更清晰,更有意义。
If((alpha< beta)&&(gamma>=delta))....比下面的表达更合意
If (alpha
)
2.用一个函数(function)来代替表达式的多次重复
如果代码中发现多次使用一个特殊的表达式,那么就用一个函数来代替,这样在以后的版本升级时更便利,这种概念在做行为级的代码设计时同样使用, 经常使用的一组描述可以写到一个任务(task)中。
5.1.5IF语句
1. 向量比较时 比较的向量要相等
当比较向量时verilog将对位数小的向量做0扩展以使它们的长度相匹配它的自动
扩展为隐式的建议采用显示扩展这个规律同样适用于向量同常量的比较
Reg Abc[7:
0];
Reg Bca[3:
0];
......
If(Abc= ={4’b0,Bca})begin
.......
If(Abc==8’b0)begin
2. 每一个If都应有一个else和它相对应
在做硬件设计时,常要求条件为真时执行一种动作而条件为假时执行另一动作即使认为条件为假不可能发生, 没有else可能会使综合出的逻辑和,RTL级的逻辑不同。
如果条件为假时不进行任何操作, 则用一条空语句。
always@(Cond)
begin
if(Cond)
DataOut<=DataIn;
End
// Else
以上语句DataOut会综合成锁存器.
3.应注意If..else if ...elseif ...else的优先级
4. 如果变量在If-else 或case语句中做非完全赋值 则应给变量一个缺省值。
即
V1=2’b00;
V2=2’b00;
V3= 2’b00;
If (a = =b) begin
V1=2’b01;//V3isnotassigned
V2=2’b10;
End
Elseif (a ==c)begin
V2=2’b10;//V1isnot assigned
V3 =2’b11;
End
Else
5.1.6case语句
1. case语句通常综合成一级多路复用器(图的右边部分),而if-then-else则综合成优先编码的串接的多个多路复用器,如图的左边部分通常使用case 语句要比if语句快,优先编码器的结构仅在信号的到达有先后时使用。
条件赋值语句也能综合成多路复用器,而case语句仿真要比条件赋值语句快。
2所有的Case应该有一个defaultcase允许空语句
Default:
;
5.1.7Writing functions
1.在function的最后给function赋值
Function CompareVectors;// (Vector1,Vector2,Length)
Input [199:
0]Vector1,Vector2;
Input[31:
0]Length;
//local variables
Integeri;