硬件加速设计方法:专题一 高质量VerilogHDL描述方法
VerilogHDL 可综合描述
VerilogHDL 是描述可综合的硬件电路
HDL 语言具有以下的硬件设计的基本概念
- 互联 (connectivity) - wire 型变量描述各个模块之间的端口和网线连接关系
- 并发 (concurrency) - 可以有效地描述并行的硬件系统
- 时间 (time) - 定义了绝对和相对的时间度量,可综合操作符都是具有物理延时的
Verilog HDL 用于可综合描述的语句
可用于综合的语句
always
if-else: 映射的硬件结构-多路选择器,输出结果由输入的选择确定
- 代码和电路是互相等价的。硬件结构比较复杂,以及控制通道的延迟等。代码在书写的时候就要注意综合电路的性能最优化,要综合考虑硬件电路的性能和结构。
- 要根据输入约束,小心设计:先”加”后“选”,还是先”选”后“加”
- 单 if 语句:无优先级的判断结构,描述多条件判断结构
- 多 if 语句:有优先级的判断结构,最后一级信号具有最高优先级,具有优先级的多选结构会消耗组合逻辑。若某些设计中,有些信号要求先到达(如关键使能信号、选择信号等),有些信号要求后到达(如慢速信号、有效时间较长的信号等),此时需要使用 if..if 语句。设计方法:最高优先级给最迟到达的关键信号
case:无优先级的判断结构,与单 if 语句的区别是条件互斥,通常用于指令编码译码电路
assign
不可用于综合的语句
function、for 、fork-join、while
Latch和D触发器
一般情况下避免使用 latch (锁存器),一般只有在异步电路和门控时钟时会用到 latch
latch 是电平触发,非同步控制。DFF 由时钟沿触发,同步控制。Latch 容易产生毛刺(glitch),而 DFF 不易产生毛刺。
latch 将 STA 变得复杂。因为 Latch 不能过滤毛刺,对下一级电路极其危险,所以避免产生 Latch, 尽可能使用 D 触发器
避免产生 Latch 的措施
易引入 latch 的途径:使用不完备的条件判断语句(if-else 语句缺少 else、case 语句缺少 default)
防止产生 latch 的措施
- 使用完备的 if… Else 语句
- 为每个输入条件设计输出操作,为 case 语句设置 default 操作
- 仔细检查综合器生成的报告,latch 会以 warning 的形式报告
full-case 和 parallel-case 综合器指令
有时会出现设计目标缘故产生 Latchfull-case
: 告诉综合器,当前 case 结构所列条件已完备(//synopsys full_case
)parallel-case
: 告诉 DC,所有条件均互斥,且并行,无优先权(//synopsys parallel_case
)
逻辑复制->均衡负载
通过逻辑复制,降低关键信号的扇出,进而降低该信号的传播延迟,提高电路性能
资源共享->减小面积
一般进行资源共享会减小电路面积,但是性能会下降,要综合考虑性能和面积而进行取舍
资源顺序重排->降低传播延时
如果一个输入信号来的晚我们可以尽可能的把它放在后面,隐藏其延迟
assign 仅用来连线,always 用于逻辑运算
尽量少用 assign 进行逻辑运算,不仅难以阅读,且多层嵌套之后很难被综合器解释(不过现在好像更多用是assign
来描述逻辑电路)
可综合风格
完整的 always
敏感信号列表
敏感信号列表必须包含输入信号
- 原因:综合过程中会产生一个取决于除敏感列表中所有其他值的结构,它将可能在行为仿真和门级仿真间产生潜在的失配
每个 always
敏感信号列表只能对应一个时钟
- 将每个过程限制在单一寄存器中,有利于 STA 和逻辑综合
不允许 wait
声明和 #delay
声明
- 综合器不允许,但是可以在测试模块和表示行为的虚拟模块中使用
语法说明
在时序电路中必须使用非阻塞赋值<=
在组合逻辑电路中必须使用阻塞赋值=
模块划分
分开异步逻辑和同步逻辑
- 原因:避免综合时的问题,简化约束和编码难度。
- 例外:不可应用于非综合模块中(例如:总线模块、总线监视器或是模拟模块)除非他们被设计来综合仿真
分开控制逻辑和存储器模块
- 通常来说,存储器都是用 memory complier 来生成的,其综合方式和 RTL 代码不同,混合在一起不利于综合,不利于很方便地更换工艺库和平台
在 RTL 书写中如何考虑延迟、面积等
在 RTL 代码中考虑时
- 针对控制信号来到比较晚,尽可能将延时较大的分支单独拿出来,放在出口最近的选择器中
- 注意“先加后选”和“先选后加”
- 加法器、乘法器等复杂的器件少用
- 减少设计面积:首先要估计使用设计资源的数量,比如使用了多少触发器、加法器、乘法器。可以借助工具,最终应该知道在设计中哪些部分占了较大的面积,进而分析和改进
- 一般来说触发器由功能决定,很难减少,只能从组合逻辑出发。对于 RTL 代码,就是各种操作符,应该了解各种操作符对应的电路,如使用“+”、”-“、”x”、”/“以及一些条件语句中的比较运算,对于这些操作,首先判断其必要性,是否能用更简单的方法解决
- 如果必须使用复杂的运算符,应考虑资源共享,从代码出发,而不是只依靠综合器
- 多比特的信号也会占用大量的资源,针对不同的设计有不同的改进方法,对于有可能简化的地方尽可能简化,逻辑简化的同时也对应面积减少和时延减少
对于功耗控制
- 门控时钟,时钟电路的翻转消耗大量资源,此时可以使用门控时钟,减少时钟电路的翻转
- 增加使能信号,使得部分电路只有工作的时候才工作,与门控时钟的差别在与,使用使能信号只使得被控制的电路不再工作,但是其时钟仍然在工作,而门控时钟是使时钟停止工作
- 对芯片各个模块进行控制,只有工作的时候才使用
- 除了有用信号和时钟的翻转会消耗功耗,组合逻辑的毛刺也会大量消耗功耗,但是在设计过程中毛刺是不可避免的,但是要尽量减少毛刺的传播,才可以减少功耗。
- 有限状态机,通过低功耗编码来减少电路的翻转,比如独热码
- 在 RTL 编码阶段对布局布线进行考虑,避免无法布通的情况。如果采用大的 mux,可以将其分解为多级较小的 mux。
RTL 设计指导规则
- RTL 级的设计评判标准很多,如时序性能、所占面积、可测试性、可重用性、功耗、时钟域的分配、复位信号设计以及与所用 EDA 工具匹配等。
- 一般的指导原则:面积与速度互换、乒乓操作、流水线设计
面积与速度互换
面积:一个设计所消耗的目标器件的硬件资源数量或者 ASIC 芯片面积
- FPGA 可以用所消耗的触发器CFF 和查找表数量来衡量
速度:设计在芯片上稳定运行时所能达到的最高频率,这个频率一般由设计的时序状况来决定 - 时序特征向量:时钟周期,PAD to PAD time,Clock setup time, Clock hold time, Clock-to-Output Delay
科学的设计目标: - 在满足设计时序的要求(包含对设计的最高频率要求)的前提下,占用最小的芯片面积。
- 在所规定的面积下,使设计的时序余量更大,频率更高。
- 如果设计的时序余量更大,频率更高——设计的健壮性更强, 整个系统的设计质量更有保证
- 设计所消耗的面积小——在单位芯片上实现的功能更多,需要的芯片数量更少,成本更低
- 满足时序和工作频率的要求更高,即速度优先
速度与面积互换
- 如果时序余量大,速度->面积
- 模块复用
- 如果一个设计时序要求高,普通方法达不到设计频率
- 数据流串并转换
- 并行复制多个操作模块
- “乒乓操作”和“串并转换”
- 在芯片模块输出处在对数据进行“并串转换”
乒乓操作
- 乒乓操作一个常常用于数据流控制的处理方法
- 节约缓冲区
- 巧妙运用乒乓操作可以做到低速模块处理高速数据流的效果
流水线
电路的最高频率取决于最长的组合逻辑链路的延迟值
流水线当方法可以有效提高系统的工作频率,但是考虑一个电路的性能通常都是<=”background: #FF5582A6;”>其单位时间的计算量,或者是一定计算总量下的处理时间**
特点
- 通过插入寄存器,将长的串行逻辑链分成较小的部分
- 当系统运算是串行时,利用时钟控制,使运算依照顺序接续执行
- 在任何制定时刻,大部分电路都在运行
好处
- 每一部分延时更小->可使用更快的时钟
- 大部分电路同时进行计算->可提高数据通过量(吞吐量)
流水线参数设计
- 系统时钟取决于最慢的流水线级的延时
- 流水线时钟周期:
- 第 i 级的时钟周期:
- 流水线分割点及参数确定要考虑的因素
- 单位延迟时间及时间频率的大小决定了数据通过速率
- 过多的级数不一定能产生最快的结果
- 太多的寄存器的插入会导致芯片面积的增加,布线困难,时钟偏差增加