以Quartus为例(延时数据为Stratix III器件典型延时)
手动布局:
module top(input clk,din,output dout);
reg din_ff,din_ff2;
always@(posedge clk)
begin
din_ff <= din;
din_ff2 <= din_ff;
end
assign dout = din_ff2;
endmodule
CLKCTRL -> din_ff|clk 平均延时2ns(min 1.5ns,max 2.5ns)
CLKCTRL -> din_ff2|clk 平均延时2ns(min 1.5ns,max 2.5ns)
工具先修Hold Time,din_ff到din_ff2的最快路径为(我们假定Tco(min)+线延时(min)-Th =250ps):
Data(early):CLKCTRL ----1.5ns----> din_ff|clk ----250ps----> din_ff2|d
din_ff2的最慢时钟路径为:
Clock(late):CLKCTRL ----2.5ns----> din_ff2|clk
(1.5ns+250ps<2.5ns)此时工具发现需要在din_ff后面插750ps(min)的Buffer才能使Hold Time无违规(FPGA中不插Delay Cell,一般是绕线)。插完Buffer后,我们来看看此时能达到的最小周期(计算Setup Time):
Data(late): CLKCTRL ----2.5ns----> din_ff|clk ----350ps+950ps=1.3ns----> din_ff2|d
din_ff2的最快时钟路径为:
Clock(early): CLKCTRL ----1.5ns----> din_ff2|clk
数据路径相对于时钟的延时为(2.5ns+1.3ns-1.5ns=2.3ns),所以最小时钟周期2.3ns,对应fmax为435MHz,与一开始预测的3GHz差别巨大。
module top(input clk,din,output dout);
wire clk_buf/*synthesis keep*/;
assign clk_buf = clk;
reg din_ff,din_ff2;
always@(posedge clk_buf)
begin
din_ff <= din;
din_ff2 <= din_ff;
end
assign dout = din_ff2;
endmodule
通过Location规则把clk_buf节点放在与两个寄存器同一个LAB内,取得最大的共同时钟路径和最小的分离时钟路径。此时再计算一下Hold Time(假定clk_buf到寄存器时钟端的延时min=300ps,max=400ps):
Data(early):clk_buf ----300ps----> din_ff|clk ----250ps----> din_ff2|d
Clock(late):clk_buf ----400ps----> din_ff2|clk
(300ps+250ps>400ps)可见Hold Time无违规,不需要插Buffer。此时计算Setup余量:
Data(late):clk_buf ----400ps----> din_ff|clk ----350ps----> din_ff2|d
Clock(early):clk_buf ----300ps----> din_ff2|clk
数据路径相对延时为(400ps+350ps-300ps=450ps),如不考虑Minimum Pulse Width约束,则最小周期450ps,fmax为2.2GHz。这就是
手动时钟树 -- 创建共同时钟路径
的威力。
module top(input clk,din,output dout);
wire clk_buf/*synthesis keep*/;
wire clk_buf2/*synthesis keep*/;
assign clk_buf = clk;
assign clk_buf2 = clk_buf;
reg din_ff,din_ff2;
always@(posedge clk_buf)
din_ff <= din;
always@(posedge clk_buf2)
din_ff2 <= din_ff;
assign dout = din_ff2;
endmodule
假定clk_buf到clk_buf2的延时为250ps~300ps(如需更大Skew,在SDC中用set_net_delay -min/max对clk_buf到clk_buf2的延时进行约束即可):
Data(early):clk_buf ----300ps----> din_ff|clk ----250ps----> din_ff2|d
Clock(late):clk_buf ----300ps----> clk_buf2 ----400ps----> din_ff2|clk
(300ps+250ps<300ps+400ps)可见Hold Time违规,工具需要插150ps(min)的Buffer。假设Buffer的延时为150ps~200ps,此时计算Setup余量
Data(late):clk_buf ----400ps----> din_ff|clk ----350ps+200ps----> din_ff2|d
Clock(early):clk_buf ----250ps----> clk_buf2 ----300ps----> din_ff2|clk
(400ps+350ps+200ps-250ps-300ps=400ps), 如不考虑Minimum Pulse Width约束, 则最小周期缩短到400ps,fmax可达2.5GHz。
这就是手动时钟树 -- 手动Skew调整,这个手段在优化对外控制器模块时非常有用,用于平衡内部时钟输出到Pad的巨大延时。
****************........我是分割线.......*****************
在顶楼的DDR2-1066控制器实现过程中,大量应用了“手动布局、手动时钟树 -- 创建共同时钟路径、手动时钟树 -- 手动Skew调整”三项PR技术,使得用内部ALUT搭的控制器/PHY电路,最高频率得以赶超片内硬核。
altera亚太支持中心应用工程师宋健(Jean Song)的email
[email protected]