FPGA综合过程中应该注意的几个代码风格的问题
2017-11-03 10:43
531 查看
决策树
优先级译码电路
避免滥用锁存器Latch
什么是可综合的HDL
阻塞赋值与阻塞赋值
for循环
组合逻辑环路
设计的项目配置
模块划分
数据链路与控制模块
时钟和复位模块
多重实例化
参数化设计
宏定义
可变参数
然而如果用case结构,各条件就是平级的,比如下面描述的电路,所有的路径是并行的关系:
一种解决方法是在HDL的条件判断语句最后加一种default情况,可以确保所有情况都被描述到如何置位
这种方法虽然有效避免了Latch产生,但是default条件导致了额外的逻辑资源浪费,为此可以把default条件提前进一步优化
## 3.多控制路径
对于一个寄存器最好不要有多个控制路径对它同时赋值。下面的例子就是一个典型的错误示范
非阻塞赋值是指一个模块内所有赋值操作在下一个时钟周期同时执行。两种赋值操作在一个模块内不能混用
通常建议在组合逻辑中用阻塞赋值,在时序逻辑中用非阻塞赋值
可以在这种组合逻辑环路中插入时序器件,避免这种情况
`ifdef的宏定义可以用来定义两种设计类型,然后在这两种设计类型中轻易的切换,比如ASIC设计和FPGA设计有略微的不同,可以用这种方式实现设计在这两种平台上的迁移
这里的WIDTH是一个默认参数,在不对它进行特殊说明的时候,WIDTH就是8。可以用下面的方法调用这个带有默认参数的模块
优先级译码电路
避免滥用锁存器Latch
什么是可综合的HDL
阻塞赋值与阻塞赋值
for循环
组合逻辑环路
设计的项目配置
模块划分
数据链路与控制模块
时钟和复位模块
多重实例化
参数化设计
宏定义
可变参数
决策树
1.优先级译码电路
HDL描述中的if/else结构在综合后会形成优先级电路,越先描述的条件有更高的优先级module regwrite( output reg rout, input clk, input [3:0] in, input [3:0] ctrl); always @(posedge clk) if(ctrl[0]) rout <= in[0]; else if(ctrl[1]) rout <= in[1]; else if(ctrl[2]) rout <= in[2]; else if(ctrl[3]) rout <= in[3]; endmodule
然而如果用case结构,各条件就是平级的,比如下面描述的电路,所有的路径是并行的关系:
module regwrite( output reg rout, input clk, input [3:0] in, input [3:0] ctrl); always @(posedge clk) case(1) ctrl[0]: rout <= in[0]; ctrl[1]: rout <= in[1]; ctrl[2]: rout <= in[2]; ctrl[3]: rout <= in[3]; endcase endmodule
2.避免滥用锁存器Latch
锁存器是由使能信号En控制透明还是不透明的,由于锁存器不利于静态时序分析而且可能产生亚稳态,这对整个设计都是灾难性的,所以在FPGA设计中同行避免使用锁存器,用触发器替代这一部分的功能。但是经常会因为不正确的变成风格无意间在设计中写出了锁存器。通常情况下是因为条件判断语句没有包含所有条件。一种解决方法是在HDL的条件判断语句最后加一种default情况,可以确保所有情况都被描述到如何置位
module regwrite( output reg rout, input clk, input [3:0] in, input [3:0] ctrl); always @(posedge clk) case(1) ctrl[0]: rout <= in[0]; ctrl[1]: rout <= in[1]; ctrl[2]: rout <= in[2]; ctrl[3]: rout <= in[3]; default: rout <= 0; //描述默认情况避免出现锁存器 endcase endmodule
这种方法虽然有效避免了Latch产生,但是default条件导致了额外的逻辑资源浪费,为此可以把default条件提前进一步优化
module regwrite( output reg rout, input clk, input [3:0] in, input [3:0] ctrl); always @(posedge clk) begin rout <= 0; case(1) ctrl[0]: rout <= in[0]; ctrl[1]: rout <= in[1]; ctrl[2]: rout <= in[2]; ctrl[3]: rout <= in[3]; endcase end endmodule
## 3.多控制路径
对于一个寄存器最好不要有多个控制路径对它同时赋值。下面的例子就是一个典型的错误示范
module separated( output reg oDat, input iClk, input iDat1,iDat2,iCtrl11,iCtrl12); always @(posedge iClk) begin if(iCtrl12) oDat <= iDat2; if(iCtrl11) oDat <= iDat1; end endmodule
什么是可综合的HDL
1.阻塞赋值与阻塞赋值
阻塞赋值是指在一个模块内各赋值操作按顺序依次执行非阻塞赋值是指一个模块内所有赋值操作在下一个时钟周期同时执行。两种赋值操作在一个模块内不能混用
通常建议在组合逻辑中用阻塞赋值,在时序逻辑中用非阻塞赋值
2.for循环
不同于软件设计,HDL设计不能用for循环这样的循环结构,这样的设计往往是不能综合的,即使能综合也是以大量复制电路浪费资源为代价的,可以按下面的方法优化module forloop( output reg [7:0] PowerX, output reg Done, input Clk,Start, input [7:0] X,N); integer i; always @(posedge Clk) if(Start) begin PowerX <= 1; i <= 0; Done <= 0; end else if (i < N) begin PowerX <= PowerX*X; i <= i + 1; end else Done <= 1; endmodule
3.组合逻辑环路
在组合逻辑设计中带有环路也是典型的错误设计,由于没有时序期间延时,这种组合环路很可能在某种情况下出现震荡现象,比如下面一个设计module combfeedback( output out, input a); reg b; assign out = b; always @(a) b = out ^ a; endmodule
可以在这种组合逻辑环路中插入时序器件,避免这种情况
设计的项目配置
组织设计项目配置的目的是方面分模块管理项目,有利于提高代码的可读性和可重用性模块划分
模块划分是对项目进行模块和层级级别上的划分,这种划分往往是自底向上考虑的数据链路与控制模块
数据链路与控制模块最好被划分在不同的模块内,因为数据链路往往是设计的关键路径,需要floorplan布局优化达到最好的性能时钟和复位模块
好的设计风格在同一个模块内只有一种类型的时钟和一种类型的复位,但是由于实际应用的需要又会涉及到多时钟域和多种复位,所以需要用不同模块将多个时钟域和多种复位划分开多重实例化
多重实例化也是能提高代码可读和重用性的一种代码组织风格,允许程序员将顶层模块设计、架构设计和底层函数功能的设计分离开参数化设计
宏定义
参数和宏定义在很多情况下都是相似并且可以互相替换的。宏定义通常是用来定义全局变量,`define语句代表宏定义`define CHIPID 8'bC9
`ifdef的宏定义可以用来定义两种设计类型,然后在这两种设计类型中轻易的切换,比如ASIC设计和FPGA设计有略微的不同,可以用这种方式实现设计在这两种平台上的迁移
`ifdef ASIC input TESETMODE output TESTOUT `endif `ifdef FPGA output DEBUGOUT `endif
可变参数
参数是用来定义不同的实例,可以再大小和位宽等方面对实例进行调整module paramreg #(parameter WIDTH = 8)( output reg [WIDTH-1:0] rout, input clk, input [WIDTH-1:0] rin, input rst); always @(posedge clk) if(!rst) rout <= 0; else rout <= rin; endmodule
这里的WIDTH是一个默认参数,在不对它进行特殊说明的时候,WIDTH就是8。可以用下面的方法调用这个带有默认参数的模块
paramreg #(2) r1(.clk(clk),.rin(rin),.rst(rst),.rout(rout)); //这个模块的WIDTH参数是2
相关文章推荐
- eXosip2开发过程中应该注意的几个问题
- 程序员在开发过程中应该注意的几个问题[转载]
- 浅谈网站运营初期应该注意的几个问题
- 论文读后感,关于机器学习实践过程中应该注意的问题
- 标准建站过程中应该注意CSS的兼容性问题
- 编写网络程序应该注意的几个问题
- iOS视图加阴影应该注意的几个问题
- 程序员应聘应该注意的几个问题
- STP选举过程中几个要注意的问题
- 搞IT的朋友应该注意的几个问题
- SSH配置的步骤以及配置过程应该注意的问题
- CPU卡发卡程序设计过程中应当注意的几个问题
- 与人交谈的过程中 应该注意哪些问题
- 公司开发时候,使用svn进行版本控制,在提交代码的时候应该注意的问题,总结!!!!
- 使用存储过程中应该注意的问题(原创)
- 程序员面试应该注意的几个问题.
- Microsoft System Center Operations Manager (SCOM) 部署中应该注意的几个小问题
- ASP.net:Regex.Match 方法 中应该注意的几个问题
- (原创)报考计算机博士之前应该注意的几个问题---写给应届硕士毕业生
- Java和jsp编程中应该注意的几个常见问题