一、顶层模块的划分
在RTL编码中,我们是以模块为单位进行设计的,模块之间的连接和嵌套关系对于电路结构有着很大的影响。一个好的系统设计中,我们应该使得模块尽量满足以下两个标准:
- 顶层模块扁平化
- 内部模块层次化
1.1 顶层模块扁平化
1.2 内部模块层次化
二、行为化与结构化划分
我们以一个32位二选一选择器为例:
2.1 行为化描述
module mux32(
input [31:0] out,
input [31:0] a,
input [31:0] b);
wire sel;
assign out = sel ? a : b;
endmodule
2.2 结构化描述
module mux32(
input [31:0] out,
input [31:0] a,
input [31:0] b);
wire sel;
mux2_1L8 m0(out[7:0],a[7:0],b[7:0],sel); //bit 7 through 0
mux2_1L8 m1(out[15:8],a[15:8],b[15:8],sel); //bit 15 through 8
mux2_1L8 m2(out[23:16],a[23:16],b[23:16],sel); //bit 23 through 16
mux2_1L8 m3(out[31:24],a[31:24],b[31:24],sel); //bit 31 through 24
endmodule
行为化描述的优化程度高,但综合出的电路结构缺乏层次和对称性;结构化描述的综合效率高(特别是通用元件库能提供底层单元时),但优化程度依赖于底层单元的性能。 通常简单的底层模块用行为级描述来构造,然后以其为单元来组建上层较大的模块。尽量避免或尽量少地在同一个模块中混合使用行为化描述和结构化描述。
三、速度与面积的折中
这里我们以加法器举例:
逐次进位加法器 :Carry-Propagate Adder 串行计算进位,速度慢 (9个门延迟),用的逻辑门少。
四、组合逻辑优化
4.1 组合逻辑与寄存器
一般来说,我们要求模块输出或/和输入端要有寄存器。我们考虑以下的几种情况:
情况1
情况2
尚可 每个模块输入端有寄存器,时序可控,但前一模块的输出驱动强度和输出延迟可能受连线影响而无法预测。
情况3
情况4
情况5
4.2 关键路径中的组合逻辑
模块尺寸不宜过大,譬如控制逻辑不超过5-10k门。在延时长的组合逻辑中插入寄存器,分解为若干较小的组合逻辑,可以提高电路的工作频率。
模块的大小尽量一致,尽可能使寄存器间的组合逻辑延时均匀化,也有利于提高电路的工作频率。
4.3 模块按照不同的设计目标优化
关键路径和非关键路径的逻辑最好分配到不同的模块中。将关键路径逻辑和非关键路径逻辑分配到不同的模块中,使得综合工具可以对关键路径逻辑进行速度优化,而对非关键路径逻辑进行面积优化。综合工具的优化基本上是针对模块的优化。
4.4 避免组合逻辑内出现反馈
五、时钟与复位优化
5.1 时钟
一般来说,在设计中我们推荐只使用单时钟沿(上升沿)。
-
所有时序控制均使用上升沿触发的寄存器,有利于产生更优的综合结果。
-
同时使用上升沿和下降沿触发,会使时钟周期分析复杂化,难以精确估计时钟频率,还可能使时钟抖动转化为时钟偏斜,同时增加门数
- 若必须使用混合时钟沿,应将它们放在不同的模块中,同时明确给出时钟信号占空比要求,而且在综合和时序分析中确保其时序周期在最坏情况下也是正确的
5.2 复位
相关内容可以阅读:
复位电路reset(同步复位,异步复位,异步复位同步释放电路)https://blog.csdn.net/apple_53311083/article/details/132049729?spm=1001.2014.3001.5502