Verilog HDL语言设计框架及代码风格!

Verilog HDL语言设计框架及代码风格!

模块(module)

module是Verilog代码编写的主体。那么,这个主体有什么内容就值得一个新手关注。一个模块(module)中有很多内容。下面介绍一个完整的module参考模型(这个模型仅供参考)。
注:使用这个模块基本没有问题,放心使用!

完整module参考模型:

`define AAAA aaaa       //宏定义
`include"abc.v"		   //文件包含
`timescale 1ns/1ns    //时间刻度定义
//-----------------------------------
module main (完整端口列表);	 //模块声明,端口列表要完整
input	[宽度]	a;			//输入、输出的位宽
output	[宽度]	b1;
output	[宽度]	b2;
inout	[宽度]	c;
//---------------------------------------
//wire	[宽度]	b1;		//b1是线网型输出,可以省略
reg		[宽度]	b2;		//b2是寄存器型输出,常用于时序电路

reg		[宽度]	e;		//模块内使用的向量
wire	[宽度]	f;		//模块内使用的连接线
integer	[宽度]	g;		//整数型
//-----------------------------------
parameter	H=数值;		//参数声明
//------------------------------------
//时序逻辑电路设计,使用非阻塞赋值
always @ (posedge 信号 or negedeg 信号)
begin		
	b2<=a;
end
//-------------------------------------
//组合逻辑设计,使用阻塞赋值
always @ (信号)
begin
	b1=a;
end
//-------------------------------------
//简单或者逻辑清晰的组合逻辑,这是数据流语句
assign = b1=~a;
//-------------------------------------
//门级调用
and and1 (b1,a,~a);
//------------------------------------
//模块实例化,可以提高模块的可读性
ZZZ my_zzz (端口连接);

endmodule 

所有的module设计都是取自以上模板的某几个部分来完成,如果设计(验证)的代码编写都可以照搬这个模块;久而久之,可以编写出美观的代码(当然,只要自己编写的代码别人看着舒服就可以,语言具有灵活性。)

代码风格:

代码风格可不是说我想怎么写就怎么写,我感觉这个好看就可以了,我想自成一派(怎么不上天去)。风格,其实在某种程度上是大家的“习惯”,这种“习惯”是为了帮助设计者(新手,例如我)尽可能减少不必要的错误。比如,大家说西瓜和羊肉不能一起吃。那偏偏你不信,你去吃一次;还好就是拉肚子,自己难受。代码风格就是尽可能让你少拉肚子或者说不拉肚子。
常见的代码风格如下:

1、多重驱动问题

代码如下:

reg clk,rst;
reg [1:0] out,a,s;

always @ (posedge clk)
if (rst)
out=2'b00;
......

always @ (posedge clk)
if (a==0)
out=2'b11;
......

在这个代码中,如果不懂数字电路的人可能会这样想。每次到了时钟上升沿时,如果复位信号有效则输出为0;如果a==0则输出11。看似功能清晰,其实这里面出现多重驱动。在可综合电路中,一个信号的赋值只会发生在一个always中;如果如上述代码,这个电路会尝试给同一个输出赋值,这样会“碰撞”。
这种情况是我们没有把思路正确变为电路。设计思路不是“在这些情况下,输出都是什么”,而是“每个输出在这些情况下都应该输出什么”,我们要想象自己是一个电路(如果做芯片,就想象自己是一个芯片)。

2、敏感列表不完整

对于组合电路,在@引导的敏感列表必须包含完整的敏感列表。对于时序电路,@的敏感事件如果不全会变成异步电路,不过异步电路的设计很多综合器不支持(在公司,设计人员就是无用功)。
如果敏感列表不完整,会造成逻辑错误。甚至有可能出现锁存器。比如:

always @ (a)	//敏感列表没有b
c=a~^b;

b的变化不会促使always结构变化,这样就是一个带控制的锁存器。
修改代码如下:

always @ (a or b)
c=a~^b;

3、if和else不成对出现

4、case语句缺少default

5、组合和时序混合设计(这个是废话)

注:

reg型输出不代表输出一定是reg 型。输出只能说大部分是reg 型。

以上都是一些前人经验,不要犯这种低级错误。当然,可以自己故意编写几个这种代码玩玩。不过,你会发现有的时候即使犯错也会得到你想要的结果,这是要感谢你的编译器和综合器。对不对看天意。
还有一些小习惯,用了有帮助,不用也无所谓。
1、电路中尽可能使用参数化设计;便于修改,顶层模块的参数影响子模块。
2、不要使用Tab,使用空格;转移代码的时候格式不会出错,功能没有任何问题,说白了还是一个颜控。
3、设计中只能使用单行注释,注释量要占到设计代码的35%以上;人会遗忘,便于记忆。端口列表必须写清注释。
4、在模块划分中。层次化设计的要求是子模块之间相互独立;时钟模块和复位模块单独划分;相关逻辑放在一起。
5、命名的一些规则,比如。input write_clk;代表写时钟;模块实例化u_模块名_n这里的模块名是实例化模块的名称(不容随意修改),n表示实例化的次数。

总结:

这篇博客内容属于值得反复去看的。如同品茶一般,慢慢回味里面的妙趣。

感想:

猜你喜欢

转载自blog.csdn.net/yixiaoyaobd/article/details/108088316