深刻理解状态机设计需要避免的冒险;时序电路可能存在essential hazard;处理单元里的control和datapath;竞争冒险【SV】【VLSI】
- 0. 前言:时序电路可能存在essential hazard
- 1. 理解control和datapath
- 1.1 Datapath control
- 2. 硬件电路里Datapath control 状态机可能存在essential hazard
- 2.1 essential hazard的解决方案
- 2.2 essential hazard的仿真,添加#20内部分配延迟
0. 前言:时序电路可能存在essential hazard
任何数字电路的行为都可以通过其功能和时序响应来表示。 前者仅考虑电路的逻辑功能,因此仅传达其功能行为,而后者还考虑信号通过电路时的传播延迟,从而表达电路的实际行为。
essential hazard:由于组合逻辑中的延迟淹没了状态机反馈部分的延迟,从而导致不正确的操作,因此会出现基本危险。 最好通过改变状态机来实现,通过添加等待周期的方法实现寄存器内数据更新。
1. 理解control和datapath
针对一个处理器单元(可以是除法器、乘法器等),这里我们不讨论什么冯诺依曼、哈佛、改进型哈佛结构,处理单元完成数据处理和控制运行的所有工作,**按照功能划分:控制(control)和数据路径(datapath)**两个部分,这样有助于分析所设计电路的动作:
- 数据路径(datapath):是执行所有必需操作的硬件,例如 ALU、寄存器和内部总线,由组合逻辑电路和时序逻辑电路的互连组成;
- 控制(control):是告诉datapath要做什么动作的硬件,在切换、选择操作、ALU 组件之间的数据移动等方面,由纯 FSM(有限状态机) 组成;
请注意,这张图片只是简单的揭示了control和datapath的内部结构,但是并没有说明control和datapath之间的信号传递,将在下文展开。硬件电路的race hazard隐患是由这些信号造成的,是因为大部分情况状态机的设计不太规范。
Organization of Computer Systems: Processors
1.1 Datapath control
为了实现一种处理单元的计算功能,需要设计状态机进行控制,在有限的状态下,control单元实现从一种状态到另一种状态的更改,在状态机的“下一个状态”里会使得某些信号给1(打开function control、打开load control)
在Datapath里:
- function circuit unit负责完成想要的计算;
- bus总线是共用的数据通路,各种不一样的信号都经过bus传递到想去的地方;
- register用于存储想要的数据,在电路上是dff(D flip-flop触发器);
控制信号分为function control和load control:
-
function control控制着底下的计算单元,比如说是一个全加器,functional control通常可以理解为对总线(bus)的操作。因为在Datapath底层,可能只有一条总线连接着系统输入端、全加器的输入端、全加器的输出端、系统输出端…等,通过enable使能信号操作流向bus的数据是什么;
-
load control负责寄存器开关,如果load=1就代表着打开dff把数据存进去;
-
如上图所示,如果想要完成A+B需要先存A、再存B、通过加法器计算完加法之后通过总线得到想要的结果后存到结果寄存器;
State Machine Design using SystemVerilog
Finite State Machines in Hardware
这里遇到的一个问题是:因为传播延迟的影响,如果不能正确操作总线(控制信号),就可能得到错误的计算结果
任何数字电路的行为都可以通过其功能和时序响应来表示。 前者仅考虑电路的逻辑功能,因此仅传达其功能行为,而后者还考虑信号通过电路时的传播延迟,从而表达电路的实际行为。
2. 硬件电路里Datapath control 状态机可能存在essential hazard
essential hazard是由从同一点出发的两条或多条路径上的不相等延迟引起的。
这里想实现X一直加1,把进位存到Y里。如果用状态机写得话,如下图所示:左图是错误写法,右图是正确写法
- 左图没有考虑“进位数据”存到“进位寄存器”里面也是需要时间的:如果一个ff的时间算1个单位时间,那么进位寄存器里的值的更新需要2个单位的时间(先输入数据到x需要1个单位时间,因为加法器一直连着寄存器的输出,加1后输入进位寄存器需要1个单位时间),左图的结果很可能得到的是错误的(如果此时总线上的数据是第一次更新甚至是X值或者是前一次计算的错误数据);
- 这是因为硬件电路的传播延迟,状态机操作datapath单元必须考虑到延迟问题;如果在输入进位的同时直接判断寄存器里的结果是什么,很可能得到错误的判断!
- 寄存器register由目前是否输入成功和之前的存储决定,因为寄存器里的数据不稳定,可能存放着上一次的结果。在输出不稳定时逻辑导致动作,则很危险;
- 右图添加了一个空状态,用于避免hazard的出现,等待足够的时间之后,寄存器里的值可以更新,可以正确地判断进位,这是左图状态机所不能完成的!!!
- Since the datapath registers are updated at the end of the clock cycle, we must wait until the next state before judging new values. 非阻塞赋值(<=)给register,信号在这个周期的末尾才开始准备变化,再加上传播延迟造成的延迟时间,最好是再加一个Wait空周期,已确保存到寄存器里的进位数据是正确的。
2.1 essential hazard的解决方案
essential hazard:由于组合逻辑中的延迟淹没了状态机反馈部分的延迟,从而导致不正确的操作,因此会出现基本危险。
遗憾的是,查找和修复基本危险需要通过电路的组合逻辑部分详细分析最坏情况下的延迟路径,有时需要向电路的反馈路径添加延迟填充以确保反馈延迟克服电路中的其他延迟。
- 等待直到信号稳定(通过添加状态机):更可取(当有时钟时最容易设计——同步设计)
- the state machine shoule be designed such that a hazard is allowed to occur.
- Note that asynchronous systems are susceptible to hazards and the next state logic must prevent any hazards from occurring, which is one reason why synchronous systems are usually preferred.
- 数据一旦稳定之后,synchronize data 使得下次时钟上升沿来了,hazards occur can be ignored。
- 增加添加冗余的逻辑电路:如添加buffer、或者添加比较慢的路径上的器件数量(不使用所给的时钟——异步设计),既添加了很多buffer硬件,且大多数适合不建议使用,因为datapath系统变成异步了之后可能会造成更多的问题;
- 如尝试直接给datapath增加buffer,绕过给datapath每一个寄存器添加buffer的方法,强行延迟datapath的时钟,以符合预期设计,使得时钟刚刚好能吻合需求,这样仿真可以通过了;
- 但是有两点隐患:1. 在实际生产后,如果buffer的延迟效果跟所仿真的效果不一致(工艺上可能导致传播延迟更小这样buffer没有起到想要的作用),可能会导致essential hazard出现。2. 如果想提高系统的工作频率,时钟周期更短,这时buffer就不吻合了,得重头重新设计了;
- 注意区分hazard-free circuit,这是通过优化布尔代数表达式来减少不必要的电路以避免static hazard;
2.2 essential hazard的仿真,添加#20内部分配延迟
实际上,SystemVerilog提供了可以仿真延迟的做法,可以添加“ #时间 ”内部分配延迟达到考虑延迟的效果,
always_ff @(posedge Clock, negedge nReset)
if ( ! nReset )
begin
started <= 0;
toggled <= 0;
count <= 0;
end
else
begin
if (( started == 1 ) && ( toggled == 0 ))
count <= #20 count + 1;
else
count <= #20 count - 3;
started <= #20 1;
toggled <= #20 ! toggled;
end
这种延迟效果只出现在仿真里,实际上不可综合。这样添加延迟,设计者需要很清楚的知道在做什么,自己想做的仿真期待和实际效果相匹配,否则不应该使用。
Iain McNally - Race Hazards, Clock Skew, Cross Simulation & Intra-Assignment Delays
Lecture 02 – Verilog Events, Timing, and Testbenches