一 时钟缓冲器、管理和路由
垂直时钟中心(clock backbone)将设备分为相邻的左侧和右侧区域,水平中心线将设备分为顶部和底部两侧。clock backbone中的资源镜像到水平相邻区域的两侧,从而将某些时钟资源扩展到水平相邻区域。BUFG不属于任何一个时钟区域,并且可以到达设备上的任何时钟点。
图:7系列FPGA的时钟架构图
下图是时钟区域内可用的时钟资源及其基本连接性的概述。从下图中左侧的垂直时钟中心(clock backbone)开始看,BUFG可以通过水平时钟行(HROW)驱动到每个区域,即使它们并未物理位于那里。BUFH通过HROW驱动到区域内的每个时钟点。BUFG和BUFH在HROW中共享路由轨迹。I/O缓冲器(BUFIO)和区域时钟缓冲器(BUFR)位于I/O bank内。BUFIO仅驱动I/O时钟资源,而BUFR驱动I/O资源和逻辑资源。BUFMR支持BUFIO和BUFR的多区域链结。时钟功能输入将外部时钟连接到设备上的时钟资源。某些资源可以通过CMT骨干连接到上方和下方的区域。
图:基本时钟区域的原理图
二 时钟管理片CMT
CMT包括一个混模式时钟管理器(MMCM)和一个相位锁定环(PLL)。从MMCM和PLL的示意图上可以看出,MMCM反馈这里可以分数分频,并且CLKOUT0~CLKOUT3可以反相输出。CMT 的输入可以是 BUFR, IBUFG, BUFG, GT, BUFH,本地布线(不推荐使用)。
图:MMCM示意图
图:PLL示意图
二 控制PLL输出时钟
调用 Xilinx 提供的 PLL IP 核来产生不同频率的时钟, 并把其中的一个时钟输出到 FPGA 外部 IO 上,配置输入时钟50M,输出时钟为200M,100M,50M,10M。并且driver的类型都是BUFG。
图:输入时钟的配置
图:输出时钟的配置
pll_test文件:
module pll_test(
input sys_clk, //system clock 50Mhz on board
input rst_n, //reset ,low active
output clk_out //pll clock output J8_Pin3
);
wire locked;
/PLL IP call
clk_wiz_0 clk_wiz_0_inst
(// Clock in ports
.clk_in1(sys_clk), // IN 50Mhz
// Clock out ports
.clk_out1(), // OUT 200Mhz
.clk_out2(), // OUT 100Mhz
.clk_out3(), // OUT 50Mhz
.clk_out4(clk_out), // OUT 10Mhz
// Status and control signals
.reset(~rst_n), // pll reset, high-active
.locked(locked)); // OUT
endmodule
ip文件:
module clk_wiz_0_clk_wiz
(// Clock in ports
// Clock out ports
output clk_out1,
output clk_out2,
output clk_out3,
output clk_out4,
// Status and control signals
input reset,
output locked,
input clk_in1
);
// Input buffering
//------------------------------------
wire clk_in1_clk_wiz_0;
wire clk_in2_clk_wiz_0;
IBUF clkin1_ibufg
(.O (clk_in1_clk_wiz_0),
.I (clk_in1));
// Clocking PRIMITIVE
//------------------------------------
// Instantiation of the MMCM PRIMITIVE
// * Unused inputs are tied off
// * Unused outputs are labeled unused
wire clk_out1_clk_wiz_0;
wire clk_out2_clk_wiz_0;
wire clk_out3_clk_wiz_0;
wire clk_out4_clk_wiz_0;
wire clk_out5_clk_wiz_0;
wire clk_out6_clk_wiz_0;
wire clk_out7_clk_wiz_0;
wire [15:0] do_unused;
wire drdy_unused;
wire psdone_unused;
wire locked_int;
wire clkfbout_clk_wiz_0;
wire clkfbout_buf_clk_wiz_0;
wire clkfboutb_unused;
wire clkout4_unused;
wire clkout5_unused;
wire clkout6_unused;
wire clkfbstopped_unused;
wire clkinstopped_unused;
wire reset_high;
PLLE2_ADV
#(.BANDWIDTH ("OPTIMIZED"),
.COMPENSATION ("ZHOLD"),
.STARTUP_WAIT ("FALSE"),
.DIVCLK_DIVIDE (1),
.CLKFBOUT_MULT (20),
.CLKFBOUT_PHASE (0.000),
.CLKOUT0_DIVIDE (5),
.CLKOUT0_PHASE (0.000),
.CLKOUT0_DUTY_CYCLE (0.500),
.CLKOUT1_DIVIDE (10),
.CLKOUT1_PHASE (0.000),
.CLKOUT1_DUTY_CYCLE (0.500),
.CLKOUT2_DIVIDE (20),
.CLKOUT2_PHASE (0.000),
.CLKOUT2_DUTY_CYCLE (0.500),
.CLKOUT3_DIVIDE (100),
.CLKOUT3_PHASE (0.000),
.CLKOUT3_DUTY_CYCLE (0.500),
.CLKIN1_PERIOD (20.000))
plle2_adv_inst
// Output clocks
(
.CLKFBOUT (clkfbout_clk_wiz_0),
.CLKOUT0 (clk_out1_clk_wiz_0),
.CLKOUT1 (clk_out2_clk_wiz_0),
.CLKOUT2 (clk_out3_clk_wiz_0),
.CLKOUT3 (clk_out4_clk_wiz_0),
.CLKOUT4 (clkout4_unused),
.CLKOUT5 (clkout5_unused),
// Input clock control
.CLKFBIN (clkfbout_buf_clk_wiz_0),
.CLKIN1 (clk_in1_clk_wiz_0),
.CLKIN2 (1'b0),
// Tied to always select the primary input clock
.CLKINSEL (1'b1),
// Ports for dynamic reconfiguration
.DADDR (7'h0),
.DCLK (1'b0),
.DEN (1'b0),
.DI (16'h0),
.DO (do_unused),
.DRDY (drdy_unused),
.DWE (1'b0),
// Other control and status signals
.LOCKED (locked_int),
.PWRDWN (1'b0),
.RST (reset_high));
assign reset_high = reset;
assign locked = locked_int;
// Clock Monitor clock assigning
//--------------------------------------
// Output buffering
//-----------------------------------
BUFG clkf_buf
(.O (clkfbout_buf_clk_wiz_0),
.I (clkfbout_clk_wiz_0));
BUFG clkout1_buf
(.O (clk_out1),
.I (clk_out1_clk_wiz_0));
BUFG clkout2_buf
(.O (clk_out2),
.I (clk_out2_clk_wiz_0));
BUFG clkout3_buf
(.O (clk_out3),
.I (clk_out3_clk_wiz_0));
BUFG clkout4_buf
(.O (clk_out4),
.I (clk_out4_clk_wiz_0));
endmodule
仿真结果:
从结果看输出的时钟是10M,sys_clk为50M