FPGA设计系统时钟的影响因素及其分析
f the FSM
wire [SIZE-1:0] next_state ;// combo part of FSM
//----------Code startes Here------------------------
assign next_state = fsm_function(req_0, req_1);
function [SIZE-1:0] fsm_function;
input req_0;
input req_1;
case(state)
IDLE : if (req_0 == 1’b1)
fsm_function = GNT0;
else if (req_1 == 1‘b1)
fsm_function= GNT1;
else
fsm_function = IDLE;
GNT0 : if (req_0 == 1’b1)
fsm_function = GNT0;
else
fsm_function = IDLE;
GNT1 : if (req_1 == 1‘b1)
fsm_function = GNT1;
else
fsm_function =IDLE;
default : fsm_function = IDLE;
endcase
endfunction
always@(posedge clock)
begin
if (reset == 1’b1)
state =IDLE;
else
state =next_state;
end
//----------Output Logic-----------------------------
always @ (posedge clock)
begin
if (reset == 1‘b1) begin
gnt_0 = #1 1’b0;
gnt_1 = #1 1‘b0;
end
else begin
case(state)
IDLE : begin
gnt_0 = #1 1’b0;
gnt_1 = #1 1‘b0;
end
GNT0 : begin
gnt_0 = #1 1’b1;
gnt_1 = #1 1‘b0;
end
GNT1 : begin
gnt_0 = #1 1’b0;
gnt_1 = #1 1‘b1;
end
default : begin
gnt_0 = #1 1’b0;
gnt_1 = #1 1‘b0;
end
endcase
end
end // End Of Block OUTPUT_
endmodule
状态机通常要写成3段式,从而避免出现过大的组合逻辑。
上面说的都是可以通过流水的方式切割组合逻辑的情况,但是有些情况下我们是很 难去切割组合逻辑的,在这些情况下我们又该怎么做呢?
状态机就是这么一个例子,我们不能通过往状态译码组合逻辑中加入流水。如果我 们的设计中有一个几十个状态的状态机,它的状态译码逻辑将非常之巨大,毫无疑问, 这极有可能是设计中的关键路径。那我们该怎么做呢?还是老思路,减少组合逻辑。我 们可以对状态的输出进行分析,对它们进行重新分类,并根据这个重新定义成一组组小 状态机,通过对输入进行选择(case语句)并去触发相应的小状态机,从而实现了将大的 状态机切割成小的状态机。在ATA6的规范中(硬盘的标准),输入的命令大概有20十种 ,每一个命令又对应很多种状态,如果用一个大的状态机(状态套状态)去做那是不可想象的,我们可以通过case语句去对命令进行译码,并触发相应的状态机,这样做下来 这一个模块的频率就可以跑得比较高了。
总结:提高工作频率的本质就是要减少寄存器到寄存器的时延,最有效的方法就是 避免出现大的组合逻辑,也就是要尽量去满足四输入的条件,减少LUT级联的数量。我们 可以通过加约束、流水、切割状态的方法提高工作频率。
在FPGA中进行时钟设计时也要注意一下几点:
一个模块尽量只用一个时钟,这里的一个模块是指一个module或者是一个entity。在多时钟域的设计中涉及到跨时钟域的设计中最好有专门一个模块做时钟域的隔 离。这样做可以让综合器综合出更优的结果。
除非是低功耗设计,不然不要用门控时钟--这会增加设计的不稳定性,在要用到门控时钟的地方,也要将门控信号用时钟的下降沿 打一拍再输出与时钟相与。
禁止用计数器分频后的信号做其它模块的时钟,而要用改成时钟使能的方式,否则这种时钟满天飞的方式对设计的可靠性极为不利,也大大增加了静态时序分析的复杂性。
1.4 不同时钟域之间的同步
当一个设计中的两个模块分别用的是两个工作时钟,那么在它们的接口处就工作在异步模式,这时为了保证数据能正确的处理那么就要对两个模块进行同步。
这里的不同的时钟域通常是以下的两种情况:
1、 两个时钟的频率不同;
2、 虽然两个时钟的频率相同,但是它们是两个独立的时钟,其相位没有任何关系。
分别如下两个图所示:
图10 两个时钟的频率完全不同
图11两个时钟的频率相同,但相位不相关
两个时钟域之间传输的数据根据不同的位宽通常采用不同的同步的方法。
1、单bit之间的同步且发送的每个pulse至少有1个周期宽度的情况
这类同步主要是用于一些控制信号自己的同步。通常的采用方法就是输出数据在接收的模块中利用两个触发器采用系统时钟打两拍,如下图12所示。对于这种同步需要说明以下几点。
图12 一位同步器设计
(1)图12中的同步电路其实叫“一位同步器”,它只能用来对一位异步信号进行同步,而且这个信号的宽度必须大于本级时钟的脉冲宽度,否则有可能根本采不到这个异步信号。
(2)为什么图一中的同步电路只能用来对一位异步信号进行同步呢? (a)当有两个或更
- STM32学习笔记(3):系统时钟和SysTick定时器(11-28)
- C8051F340系统时钟配置(11-28)
- S5PV210(TQ210)学习笔记——系统时钟和串口(11-28)
- STM32学习笔记——RCC系统时钟配置(11-28)
- STM32 开发板入门教程 (三) 系统时钟 SysTick(11-28)
- stm32系统时钟配置问题(11-27)