verilog编码风格.docx
- 文档编号:30654066
- 上传时间:2023-08-19
- 格式:DOCX
- 页数:75
- 大小:107.84KB
verilog编码风格.docx
《verilog编码风格.docx》由会员分享,可在线阅读,更多相关《verilog编码风格.docx(75页珍藏版)》请在冰豆网上搜索。
verilog编码风格
1编程书写和命名规范3
1.1文件头和修订列表3
1.1.1文件头3
1.1.2修订列表4
1.2联机注释4
1.3命名规则4
1.3.1module命名5
1.3.2端口5
1.3.3函数和任务5
1.3.4变量5
1.3.5测试工作台testbench5
1.3.6其它6
1.4verilog书写风格6
2逻辑设计编码风格6
2.1能综合的语句6
2.2不能综合的语句7
2.3组合电路编码风格8
2.4组合电路编码风格8
2.4.1敏感表的使用8
2.4.2赋值9
2.4.3if语句12
2.4.4case语句13
2.4.5for语句14
2.4.6避免引入Latch的方法15
2.5时序电路编码风格15
2.5.1同步复位D触发器15
2.5.2异步复位D触发器15
2.5.3Latch标准写法16
2.6状态机编码设计风格16
2.6.1几种编码方式16
2.6.2建议的描述方法16
2.6.3描述FSM注意的事项17
2.7其它要求和建议18
2.8好的习惯20
3低功耗设计代码风格24
3.1clock-gating24
3.2AutomaticOperandIsolation25
3.3因式分解25
4TestBench编码风格25
4.1书写testbench的一些注意事项25
4.2文本文件中读取向量26
4.3文本文件中写入向量27
5.一些典型电路的Verilog编码28
5.1.D触发器28
1.带同步set的D触发器28
2.带同步reset的D触发器28
5.2.DLatch29
1.带异步set的DLatch29
2.带异步set和reset的DLatch29
5.3.3-8译码器30
5.4加法器30
5.5比较器31
5.6多路选择器33
5.7时钟信号的生成:
33
5.8有限状态机34
5.9模块实例化35
5.10对一个简单的ROM建模36
5.11对一个简单的RAM建模36
5.12单端口异步读同步写RAM36
5.13单端口同步读写RAM37
5.14单端口异步读写RAM38
5.15双端口同步读写RAM39
5.16双端口异步读写RAM40
5.17T触发器41
1.异步复位T触发器41
2.同步复位T触发器42
5.18计数器42
1.一个8位的up-down计数器。
42
2.异步加载初值的计数器43
3.独热计数器(onehotcounter)43
5.19同步FIFO44
前言
本文主要针对上海集成电路设计中心的verilog设计编码风格给出指导性的规范。
依据规范为TransEDA公司的Vncheck编码风格检查工具的检查规则,[]为Vncheck的规则项目。
1编程书写和命名规范
1.1文件头和修订列表
作为好的源代码,其中必须包含所有需要的信息。
因此源代码中要包含文件头和修订列表(以获得修改情况)。
1.1.1文件头
文件头包含以下内容:
1.模块名
2.文件名
3.作者名字和e-mail
4.最后修改时间、修改作者
5.模块描述
6.需要的库
7.使用的仿真器--其运行平台和版本
8.使用的综合工具,其运行平台和版本
文件头例子:
/****************************************************************
**Title:
**Project:
*****************************************************************
**File:
**Author:
name
**Organization:
**Created:
**Lastupdate:
**Platform:
**Simulators:
**Synthesizers:
**Targets:
**Dependency:
*****************************************************************
**Description:
*****************************************************************
**Copyright(c)notice
*****************************************************************
**Revisions:
**RevisionNumber:
**Version:
**Date:
**Modifier:
name
**Desccription:
****************************************************************/
1.1.2修订列表
包含以下内容:
1.修订版本号
2.修订者名字,日期,改动的详细描述
3.改动的数据
例子
/****************************************************************
**RevisionNumber:
1
**DateofChange:
20thMarch2000
**Modifier:
HarishYS(harish@opencores.org)
**Description:
InitialDesign
*****************************************************************
**RevisionNumber:
2
**DateofChange:
ddmmyyyy
**Modifier:
XYZ(email)
**Description:
Modifiedthe?
?
?
?
.toimprove?
?
?
?
..
****************************************************************/
1.2联机注释
a)每一个重要信号名、操作后都要加上注释,描述操作和声明的使用。
b)在Verilog中有两种形式的注释。
●/*第一种形式:
可以扩展至
多行*/
●//第二种形式:
在本行结束
c)为了使代码可以跨平台,建议用简明扼要的英文书写注释。
1.3命名规则
a)命名要直观且有意义,不同的前、后缀代表不同的含义:
pre_AAA_BBB_CCC_DDD:
其中
0)pre代表信号可见程度,包括g(全局),s(静态),l(局部)
1)AAA代表顶层模块名称,包括CBOX,MBOX,IBOX,EFBOX
2)BBB代表信号类型,包括reg,wire
3)CCC代表次级模块名称,如Fetch等,由各小组负责定义完成。
4)DDD代表信号内容,可以继续定义层次,由用户自行负责完成。
b)建议长度在32字符以内。
c)文件名定义必须包括以上1)和3)项,如
IBOX_Fetch.v
IBOX_Fetch_module1.v
1.3.1module命名
a)module名除个别最低层通用模块如mux,decode外必须包含以上1)和3)项;
b)module名只能用大写字母,不超过16个字符;
1.3.2端口
a)端口名应包含以上2),4)项,并在端口声明后要有详细注释。
b)建议不超过16个字符;
c)端口名不能以数字结尾。
1.3.3函数和任务
a)一般不超过16个字母;
b)函数名除个别最低层通用函数外应包含以上0),1),3),4)。
1.3.4变量
a)变量名要简单并能用注释描述其功能,
b)不要出现标识符完全相同的局部变量和全局变量,尽管两者的作用域不同而不会发生语法错误。
1.3.5测试工作台testbench
a)其名称要与实体名一致,且加后缀“_TB”;
b)出错报告要在通用文件头信息外提供下述信息:
模块名,信号或变量名,过程或函数名,当前时间点,错误号或错误名,可能的出错原因,出错位置。
问题解决过程。
1.3.6其它
a)尽量多定义参数,这样可以增加代码的可读性。
1.4verilog书写风格
a)[LineLength]行太长会降低代码的可读性和可维护性,建议一行不要超过70。
b)[MaximumIdentifierLength]各种标识符的长度最好不要超过15。
c)[ModulePortOrdering]模块各部分的书写顺序:
参数声明,
输入声明,
输出声明,
inout声明,
wire声明,
reg声明,
integer声明,
real声明,
time声明,
event声明,
模块实例化,
函数声明,
任务声明,
初始化,
always块,
assign语句。
d)[ModulesPerFile]一个文件中只用一个模块,文件名要和模块名相同。
e)[FileSize]一个文件不要超过3000行。
a)[TabsInSource]不使用Tab空格,以保证在不同环境下文件格式一致。
2逻辑设计编码风格
2.1能综合的语句
语句和结构
说明
If-else
条件语句结构,单个的if语句蕴含并行的结构,多个的if语句蕴含串行结构
Case
条件语句结构,属于并行结构
For
循环结构,每次只能加一或者减一
结构说明语句(always、task、function)
Always是不断重复执行的,task、function分别是任务和函数说明语句
赋值语句(=、<=)
阻塞和非阻塞赋值
primitives
只在安装时使用
算术运算符(+、-、*、/、%)
可综合的算术运算符
赋值运算符(=、<=)
可综合的赋值运算符
关系运算符(>、<、>=、<=)
可综合的关系运算符
逻辑运算符(&&、||、!
)
可综合的逻辑运算符
条件运算符(?
:
)
可综合的条件运算符
位运算符(~、|、^、&、^~)
可综合的位运算符
移位运算符(<<、>>)
可综合的移位运算符
等式运算符(==、!
=)
可综合的等式运算符
位拼接运算符({})
可综合的位拼接运算符
2.2不能综合的语句
Verilog中的以下语句和结构是不可综合的,在逻辑设计中禁止使用,必要时可以在testbench中使用。
结构
说明
initial
只能用在testbench中
Forever、while、repeat
只能用在testbench中
Wait
不能综合
events
只能用在testbench中
real
不支持real数据类型
time
不支持time数据类型
Force、release
不支持force、release数据类型
assignanddeassign
Assign和deassign对reg数据类型是不支持的,但是assign支持wire数据类型
forkjoin
不可综合,使用非阻塞连续赋值来获取同样的效果
table
不支持UDP和table
===、!
==
不能综合,可以在testbench中使用
具体来说:
a)不允许使用的构造和操作(在Vncheck的DisallowConcurrentStatement规则中规定):
CmosSwitchInstantiations,InitialBlocks,NmosSwitchInstantiations,PmosSwitchInstantiations,PulldownGateInstantiations,PullupGateInstantiations,RcmosSwitchInstantiations,RnmosSwitchInstantiations,RpmosSwitchInstantiations,RtranSwitchInstantiations,Rtranif0SwitchInstantiations,Rtranif1SwitchInstantiations,SpecifyBlocks,TranSwitchInstantiations,Tranif0SwitchInstantiations,Tranif1SwitchInstantiations。
b)不允许使用的声明(在Vncheck的DisallowDeclaration规则中规定):
EventDeclarations,MacromoduleDeclarations,RealtimeDeclarations,Supply0NetDeclarations,Supply1NetDeclarations,TriNetDeclarations,Tri0NetDeclarations,Tri1NetDeclarations,TriandNetDeclarations,TriorNetDeclarations,TrireqNetDeclarations,UDPDeclarations。
c)在函数中不允许使用的语句(在Vncheck的DisallowInFunctionScope规则中规定):
BlockDisableStatements,CaseStatements,DeassignStatements,EventTriggerStatements,ForceAssignments,ProceduralContinuousAssignments,ProceduralNon-BlockingAssignments,ProceduralTimingControlStatements,ReleaseStatements,TaskDisableStatements,UserTaskEnables,WaitStatements。
d)不允许使用的verilog运算符(在Vncheck的DisallowOperator规则中规定):
===,!
==。
e)不允许使用的verilog语句(在Vncheck的DisallowSequentialStatement规则中规定):
DeassignStatements,EventTriggerStatements,ForceAssignments,ForeverLoops,ParallelBlocks,ProceduralContinuousAssignments,ReleaseStatements,RepeatLoops,SystemTaskEnables,TaskDisableStatements,WaitStatements,WhileLoops。
f)不允许使用的verilog构造(在Vncheck的DisallowVerilogConstruct规则中规定):
ChargeStrengths,Delays,DriveStrengths,EventExpressions,RealLiterals,RepeatEventControl,StringLiterals,SystemFunctionCalls。
2.3组合电路编码风格
2.4组合电路编码风格
2.4.1敏感表的使用
敏感表是用来触发always块的时间控制部分,没有敏感表的always块会造成仿真死锁。
它可以是沿触发也可以是电平触发,可以是单个信号也可以是多个信号,多个信号之间用or连接。
1)敏感表中应该包含所有在always块中的赋值语句右边出现的信号和变量以及if和case语句的条件中出现的信号和变量,如果敏感表不全就会引入锁存器。
不好的例子
inputA,B,C
regE,D;
always@(AorBorC)
begin
E=D&A&B;
/*因为D没有在敏感电平列表中,所以D变化时E不能立刻变化,要等到A或B或C变化时才体现出来,相当于存在一个电平敏感的透明锁存器在起作用*/
D=E|C;
End
好的例子
inputA,B,C
regE,D;
always@(AorBorCorDorE)
begin
E=D&A&B;
/*敏感表中包含了赋值语句右边所有的信号和变量不会产生锁存器*/
D=E|C;
End
2)[SensitivitySignalModification]在敏感表中声明的信号在进程中不能被修改,否则会使模拟/综合不匹配。
不好的例子:
moduleM;
regSENSE;
regA,B;
always@(SENSE)
begin
A=B;
SEMSE=A&B;//敏感表中的信号“SENSE”被改动
end
endmodule
3)[SensitivitySignalReplication]不允许在一个敏感表中对一个信号声明多次。
不好的例子:
moduleM;
regA,B;
always@(AorBorA)//敏感表中的信号'A'被声明2次
A=B;
endmodule
4)敏感表不要既有边沿敏感又有电平敏感的信号或者变量。
2.4.2赋值
1)阻塞性赋值和非阻塞性赋值的用法:
在verilogHDL语言中,信号有两种赋值方式。
⏹非阻塞赋值(如b<=a)
◆块结束后才完成赋值操作
◆b的值不是立刻改变
◆一种比较常用的赋值方式
⏹阻塞赋值(如b=a)
✧赋值语句执行完后块才结束
✧b的值在赋值语句执行完后立刻就改变
✧可能会产生意想不到的结果
⏹在描述组合逻辑的always块中用阻塞赋值
⏹在描述时序逻辑的always块中使用非阻塞赋值
⏹非阻塞赋值操作只能用于对寄存器类型变量进行赋值
⏹非阻塞赋值不允许用于连续赋值
⏹在一个always块中不允许既使用非阻塞赋值又使用阻塞赋值
2)[RedundantAssignments]在任何时间单元中对一个特定的声明只使用一个非阻塞性赋值。
当在同一个时间单元中对于同一个寄存器存在复杂的赋值时,Verilog语言不能保证它的顺序。
通常在时序电路中对reg型的信号使用非阻塞式赋值,而在组合电路中使用阻塞式赋值。
不好的例子:
moduleM;
regA_REG;
reg[3:
0]V_REG;
regINREG,INLREG;
always@(INREG)
begin
A_REG<=INREG;
A_REG<=INLREG;//在同一时间单元对A_REG进行了多次赋值
V_REG<=0;
V_REG[0]<=1;//太模糊,V_REG[0]的值可以是'0'或'1'
end
endmodule
3)禁止在一个模块中对同一个变量既使用阻塞性赋值又使用非阻塞性赋值。
不好的例子:
moduleM;
regREGA,REGB,REGC;
always@(REGB)
REGA=REGB;//阻塞性赋值
always@(REGC)
REGA<=REGC;//非阻塞性赋值
Endmodule
4)[SynthesizableProcess]组合块中的赋值必须用到敏感表中的信号。
不好的例子:
moduleM;
wiresigA;
rega,b;
always@(sigA)
a=b;//bisnotinthesensitivitylist
endmodule
5)always块外的赋值必须用assign,赋值表达式左边为wire型。
6)[AssignmentToInput]禁止对输入信号赋值。
7)[RegisterInitialization]寄存器最好被初始化为一个常量值,建议统一初始化为0。
8)信号禁止为自身赋值。
9)[IllegalInExpression]禁止用‘x’或者‘z’来对变量赋值。
10)[SizedBasedNumbers]要求带基数的常量都给定长度和进制。
例子:
moduleM;
wire[7:
0]WA=8'b0;//此常量符合规范
wire[3:
0]WB='b0;//此常量没有给出长度,不规范
endmodule
11)[SizedSequentialAssignments]禁止一个赋值左右两边的位数不等。
如果不相等就要确保左边位数足够大,能够包含右边可能的最大位数。
下例是个不好的例子:
不好的例子:
moduleM;
wire[7:
0]RESULT;
wire[15:
0]RHS;
assignRESULT=RHS;
endmodule
12)[UnequalTernaryOperands]在使用条件操作符的三重操作中,要求操作数长度要相同。
不好的例子:
moduleM;
regA,B;
reg[3:
0]C;
wireWA;
assignWA=A?
B:
C;//B的长度是1,而C的长度是4
endmodule
13)[SignalDrivenInMultipleProcesses]不建议在多个过程中驱动同一个信号。
不好的例子:
moduleM;
wirePROCA,PROCB;
reg[3:
0]SIG;
always@(PROCA)
SIG[1:
0]<=PROCA;
always@(PROCB)
SIG[3:
2]<=PROCB;
Endmodule
14)[ConstantLoopStatements]如果一个赋值语句的源表达式是恒量,可以在不影响功能的情况下把这个语句放到循环外,这样能提高模拟性能。
不好的例子:
moduleM;
integerI;
wireSIGNAL;
reg[3:
0]CONST;
reg[3:
0]OUT;
always@(SIGNAL)
begin
for(I=0;I<4;I=I+1)
begin
CONST=4'b1010;
OUT[I]=OUT[I+1]&CONST;
end
end
endmodule
15)[ContinuousAssignmentTarget]连续赋值语句的对象必须是简单对象。
好的例子:
moduleM;
wireWIREA;
wire[3:
0]SIG;
assignWIR
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- verilog 编码 风格