我想介绍下这种方法。
这种方法的目的就是让模块好好沟通,好好配合~~
首先理解下“模块的沟通,至少需要一个周期的延时”(原文中的一句话)是什么意思?
这句话的前提是,所有的逻辑都基于时序逻辑,而不是组合逻辑.
并不是指直连的信号,从一个模块传到另一个模块需要一个周期,而是说模块检测到另一个模块的信号需要一个周期.
举个例子:完成信号Done(初始化时为0),从该模块直接连到了顶层模块.Done在某一个时钟值1.该信号瞬间传至顶层模块(可认为延时为0);
那么顶层模块,在该时钟仍然认为Done信号为0,只有到下一个时钟,才知道Done信号变为1;
(因为需要if判断,它判断根据该时间点之前的状态,该时钟点之前Done信号为0)
这就是所谓的:"模块的沟通,至少需要一个周期的延时."注意沟通二字!!!!
如果是一个模块单方向的控制另一个模块(而不用相互沟通),就不存在这个一个周期的延时了!!
所以两者要好好的区别!!!!!!!!!!!
举一个模块沟通的金典例子:
//--------------------------------功能模块------------------------------------
always @(posedge CLK)
if(Start_Sig)
case(i)
.
.
.
6://时钟6
begin
Done_sig <= 1'b1;
i <= i + 1'b1;
end
7://时钟7
begin
Done_sig <= 1'b0;
i <= 0;
end
endcase
//--------------------------------控制模块------------------------------------
always @(posedge CLK)
case(i)
0:
begin
if(Done) begin Start_Sig <= 1'b0; i <= i + 1'b1; end
else begin Start_Sig <= 1'b1; i <= i; end
end
1:
begin
.........
end
endcase
//----------------------------------------------------------------------------------
我来分析一下这两个模块是如何完美沟通的~~~~
首先、“控制模块”将Start_Sig置1,一个时钟后“功能模块”开始工作,到步骤6时“功能模块”完成任务将Done_sig置1,接下来即将来临的时钟,我们叫它——时钟7,我们看看在时钟7发生了什么。
一、时钟7发生的事情:
1、因为,“功能模块”在时钟6将Done_sig置1,
所以,“控制模块”在时钟7的上升沿来临时,检测到Done_sig == 1'b1;
并将Start_Sig置0;
2、于此同时“功能模块”在该时钟的上升沿来临时完成了“Done_sig <= 1'b0; i <= 0;”
二、时钟7后一个时钟发生的事情:
1、因为,“控制模块”在时钟7的上升沿将Start_Sig置0,
所以,“功能模块”在该时钟的上升沿来临时,检测到Start_Sig == 1'b0;所以该模块无法运行。
2、于此同时“控制模块”进入了下一个步骤执行命令~~~~~
在这里可能读者发现一个比较“奇怪”的地方。在时钟7时,“功能模块”将Done_sig置0;而此时,
也是在时钟7时“控制模块”检测到Done_sig == 1'b1;
这不是很矛盾吗,其实不然。我们再次分析if的特性:if判断根据该时间点之前的状态,该时钟
点之前Done信号为1的。
所以说这个设计十分巧妙~~~!!!