文章目录
前言
心中有电路,下笔自然神!!!
一、组合逻辑与时序逻辑
- 组合逻辑:没有时钟控制的数字电路,代码里的判断逻辑都是组合逻辑
- 组合逻辑的特点是任意时刻的输出仅仅取决于该时刻的输入,与电路原本的状态无关,逻辑中不牵涉跳变沿信号的处理,组合逻辑的verilog描述方式有两种:
(1)always @(电平敏感信号列表)
always模块的敏感列表为所有判断条件信号和输入信号,但一定要注意敏感列表的完整性。在always 模块中可以使用if、case 和for 等各种RTL 关键字结构。由于赋值语句有阻塞赋值和非阻塞赋值两类,建议读者使用阻塞赋值语句"="。always 模块中的信号必须定义为reg 型,不过最终的实现结果中并没有寄存器 。这是由于在组合逻辑电路描述中,将信号定义为reg型,只是为了满足语法要求。
(2)assign描述的赋值语句。
信号只能被定义为wire型。
如以下一条语句:
c
assign w_flag = r_cnt == 8 && r_en;
第一张图是人为思考画的,第二张为VIVADO综合结果,VIVADO节省了一级组合逻辑。
- 时序逻辑:有时钟控制的数字电路,有记忆功能,有保存功能,有时钟控制的寄存器都属于时序逻辑电路
时序逻辑是Verilog HDL 设计中另一类重要应用,其特点为任意时刻的输出不仅取决于该时刻的输入,而且还和电路原来的状态有关。电路里面有存储元件(各类触发器,在FPGA 芯片结构中只有D 触发器)用于记忆信息,从电路行为上讲,不管输入如何变化,仅当时钟的沿(上升沿或下降沿)到达时,才有可能使输出发生变化。
与组合逻辑不同的是:
(1)在描述时序电路的always块中的reg型信号都会被综合成寄存器,这是和组合逻辑电路所不同的。
(2)时序逻辑中推荐使用非阻塞赋值"<="。
(3)时序逻辑的敏感信号列表只需要加入所用的时钟触发沿即可,其余所有的输入和条件判断信号都不用加入,这是因为时序逻辑是通过时钟信号的跳变沿来控制的。
c
always @(posedge i_clk or posedge i_rst)begin
if(i_rst)
r_ack_lock <= 'd0;
else if(r_ack_valid && !w_iic_sda && r_st_cur == P_ST_DADDR1)
r_ack_lock <= 'd0;
else if(r_ack_valid && w_iic_sda && r_st_cur == P_ST_DADDR1)
r_ack_lock <= 'd1;
else
r_ack_lock <= r_ack_lock;
end
每一个always块都是由一堆组合逻辑(if-else判断调节都是组合逻辑)和一个时序逻辑构成(代码里只有r_ack_lock 这么一个触发器受时钟控制)
xilinx寄存器(D触发器)原语如下:采用源语设计,EDA软件会严格按照代码进行综合。
c
FDCE #(
.INIT(1'b0) // Initial value of register (1'b0 or 1'b1)
) FDCE_inst (
.Q(Q), // 1-bit Data output
.C(C), // 1-bit Clock input
.CE(CE), // 1-bit Clock enable input
.CLR(CLR), // 1-bit Asynchronous clear input
.D(D) // 1-bit Data input
);
二、建立时间和保持时间
一旦涉及到时序的内容,这俩者是无法绕开的概念,一定要非常清楚。
建立时间 :时钟上升沿到来之前,数据必须保持稳定的时间。
保持时间 :时钟上升沿结束之后,数据必须保持稳定的时间。
建立时间和保持时间就像一个窗口一样,在窗口内数据不可以变化,窗口外则无所谓
只有满足寄存器的建立时间和保持时间,才可以保证数据输出稳定和正确。
时序分析模型:
launch edge :时序分析的起点,第一级寄存器数据变化时钟沿。
latch edge :时序分析的终点,数据锁存的时钟沿
Tcycle :时钟周期
Tclk1 :时钟到达第一级寄存器的延时
Tclk2 :时钟到达第二级寄存器的延时
Tskew :Tskew = Tclk2 - Tclk1,可正可负
Tco :数据输出时延,即当时钟有效变化沿到达时,数据从寄存器D端(输入端)到Q端(输出端)的时延,该数值一般很小
Tdelay :数据传输时延,从D1的Q端到D2的D端所需时间,主要为组合逻辑时延和走线时延。
Tsu :建立时间,时钟上升沿到来之前,数据必须保持稳定的时间。
Thd:保持时间,时钟上升沿结束之后,数据必须保持稳定的时间。
三、建立时间和保持时间
建立时间余量:
数据要求到达时间 = Tskew + Tcycle - Tsu
数据实际到达时间 = Tco + Tdelay
Tsu_slack = 数据要求到达时间 - 数据实际到达时间 = (Tskew + Tcycle - Tsu) - (Tco + Tdelay)
只有当Tsu_slack > 0,电路设计才是稳定的。Tsu_slack 是可控的,当Tsu_slack > 0不满足时:
(1)首先考虑Tdelay,降低组合逻辑时延,如中间多加一级或几级寄存器打拍,这样可以将组合逻辑拆分为几部分,评估组合逻辑时延的方法主要是看组合逻辑级数,xilinx一级组合逻辑时延约为0.4ns,通过代码里的最大组合逻辑可以大概计算出最大的时钟频率。
(2)降低时钟频率
保持时间余量: (图中标注了建立时间要求到达时间和实际到达时间,保持时间的没有标注,但也很好理解)
数据要求到达时间 = Tskew + Thd
数据实际到达时间 = Tco + Tdelay
Thd_slack = 数据实际到达时间 - 数据要求到达时间 = (Tco + Tdelay) - (Tskew + Thd)
只有当Thd_slack> 0,电路设计才是稳定的。Thd_slack是我们没有办法控制的。