FPGA管腳分配時(shí)需注意的一些事項(xiàng)
平臺(tái):XC4VSX55 ISE10.1
本文引用地址:http://cafeforensic.com/article/201710/365696.htm設(shè)計(jì)過FPGA的原理圖,看FPGA的手冊(cè),說管腳的分配問題,如時(shí)鐘管腳要用GC類管腳,而且單端時(shí)鐘輸入時(shí)要用P類型的管腳,不能用N類型管腳等等。
一直以來都沒有試驗(yàn)過,今天試驗(yàn)一把,以求各種驗(yàn)證。
1)GC類全局時(shí)鐘管腳是否可用作普通IO使用?
所謂GC類管腳,就是在管腳的稱是諸如IO_L1P_GC_LC等帶有GC的管腳。其實(shí)手冊(cè)中說的是GC類管腳可以用作IO的,但在《Xilinx FPGA開發(fā)實(shí)用教程》(清華出版社)574頁倒數(shù)第八行提到:“所有從全局時(shí)鐘管腳輸入的信號(hào)必須經(jīng)過IBUF元,否則在布局布線時(shí)會(huì)報(bào)錯(cuò)”,于是今天我試了一下,將某一GC類管腳分配給一個(gè)普通的輸入口(也試驗(yàn)了分配給一個(gè)普通的輸出口),經(jīng)布局布線后,未出錯(cuò)。
因此得出結(jié)論:GC類全局時(shí)鐘管腳可以作為普通IO使用。(不知道是不是我對(duì)書中提到的全局時(shí)鐘管腳理解有誤,如果是,請(qǐng)網(wǎng)友別拍我,敬請(qǐng)留言指正)
2)非GC類全局時(shí)鐘管腳是否可以作時(shí)鐘使用?
其實(shí)至于說能否作為時(shí)鐘使用,這里有另一層函義。當(dāng)然,如果你把一個(gè)普通IO口配置成輸入口,就把它的輸入信號(hào)作為時(shí)鐘,那是沒問題的。但我們一般不這么做,因?yàn)闀r(shí)鐘信號(hào)對(duì)于我們來說是一個(gè)很重要的信號(hào),因此FPGA在內(nèi)部會(huì)有特殊照顧,如果你使用FPGA傳門為時(shí)鐘預(yù)留的管腳,并作一些處理,那么你的時(shí)鐘對(duì)于各種模塊的時(shí)延是可以忽略的,因?yàn)闀r(shí)鐘在布線時(shí)是單獨(dú)走的一層,而如果你就僅用普通IO的話,經(jīng)過FPGA內(nèi)部布局布線后,從它的輸?shù)?,再到各個(gè)使用時(shí)鐘的地方,有的線長,有的線短,它的時(shí)延將是不一樣的。這些東西還是看一些FPGA結(jié)構(gòu)的內(nèi)容吧。
在xilinx里有專門的DCM IP核可供調(diào)用,在ISE中執(zhí)行project——>New Source——>IP(CORE Generator Architecture Wizard)——>FPGA Features and Design——>Clocking——>Virtex-4——>Single DCM ADV v9.1i,可得如下界面:
需要特別注意的是CLKIN Source需要選擇是External還是Internal,各自生成的源文件如下:
==========================選擇External=========================
`TImescale 1ns / 1ps
module clk_test(CLKIN_IN,
CLKIN_IBUFG_OUT,
CLK0_OUT,
LOCKED_OUT);
input CLKIN_IN;
output CLKIN_IBUFG_OUT;
output CLK0_OUT;
output LOCKED_OUT;
wire CLKFB_IN;
wire CLKIN_IBUFG;
wire CLK0_BUF;
wire GND_BIT;
wire [6:0] GND_BUS_7;
wire [15:0] GND_BUS_16;
assign GND_BIT = 0;
assign GND_BUS_7 = 7b0000000;
assign GND_BUS_16 = 16b0000000000000000;
assign CLKIN_IBUFG_OUT = CLKIN_IBUFG;
assign CLK0_OUT = CLKFB_IN;
IBUFG CLKIN_IBUFG_INST (.I(CLKIN_IN),
.O(CLKIN_IBUFG));
BUFG CLK0_BUFG_INST (.I(CLK0_BUF),
.O(CLKFB_IN));
DCM_ADV DCM_ADV_INST (.CLKFB(CLKFB_IN),
.CLKIN(CLKIN_IBUFG),
.DADDR(GND_BUS_7[6:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.PSCLK(GND_BIT),
.PSEN(GND_BIT),
.PSINCDEC(GND_BIT),
.RST(GND_BIT),
.CLKDV(),
.CLKFX(),
.CLKFX180(),
.CLK0(CLK0_BUF),
.CLK2X(),
.CLK2X180(),
.CLK90(),
.CLK180(),
.CLK270(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT),
.PSDONE());
defparam DCM_ADV_INST.CLK_FEEDBACK = 1X;
defparam DCM_ADV_INST.CLKDV_DIVIDE = 2.0;
defparam DCM_ADV_INST.CLKFX_DIVIDE = 1;
defparam DCM_ADV_INST.CLKFX_MULTIPLY = 4;
defparam DCM_ADV_INST.CLKIN_DIVIDE_BY_2 = FALSE;
defparam DCM_ADV_INST.CLKIN_PERIOD = 16.129;
defparam DCM_ADV_INST.CLKOUT_PHASE_SHIFT = NONE;
defparam DCM_ADV_INST.DCM_AUTOCALIBRATION = TRUE;
defparam DCM_ADV_INST.DCM_PERFORMANCE_MODE = MAX_SPEED;
defparam DCM_ADV_INST.DESKEW_ADJUST = SYSTEM_SYNCHRONOUS;
defparam DCM_ADV_INST.DFS_FREQUENCY_MODE = LOW;
defparam DCM_ADV_INST.DLL_FREQUENCY_MODE = LOW;
defparam DCM_ADV_INST.DUTY_CYCLE_CORRECTION = TRUE;
defparam DCM_ADV_INST.FACTORY_JF = 16hF0F0;
defparam DCM_ADV_INST.PHASE_SHIFT = 0;
defparam DCM_ADV_INST.STARTUP_WAIT = FALSE;
endmodule
==========================選擇Internal=========================
`timescale 1ns / 1ps
module clk1_test(CLKIN_IN,
CLK0_OUT,
LOCKED_OUT);
input CLKIN_IN;
output CLK0_OUT;
output LOCKED_OUT;
wire CLKFB_IN;
wire CLK0_BUF;
wire GND_BIT;
wire [6:0] GND_BUS_7;
wire [15:0] GND_BUS_16;
assign GND_BIT = 0;
assign GND_BUS_7 = 7b0000000;
assign GND_BUS_16 = 16b0000000000000000;
assign CLK0_OUT = CLKFB_IN;
BUFG CLK0_BUFG_INST (.I(CLK0_BUF),
.O(CLKFB_IN));
DCM_ADV DCM_ADV_INST (.CLKFB(CLKFB_IN),
.CLKIN(CLKIN_IN),
.DADDR(GND_BUS_7[6:0]),
.DCLK(GND_BIT),
.DEN(GND_BIT),
.DI(GND_BUS_16[15:0]),
.DWE(GND_BIT),
.PSCLK(GND_BIT),
.PSEN(GND_BIT),
.PSINCDEC(GND_BIT),
.RST(GND_BIT),
.CLKDV(),
.CLKFX(),
.CLKFX180(),
.CLK0(CLK0_BUF),
.CLK2X(),
.CLK2X180(),
.CLK90(),
.CLK180(),
.CLK270(),
.DO(),
.DRDY(),
.LOCKED(LOCKED_OUT),
.PSDONE());
defparam DCM_ADV_INST.CLK_FEEDBACK = 1X;
defparam DCM_ADV_INST.CLKDV_DIVIDE = 2.0;
defparam DCM_ADV_INST.CLKFX_DIVIDE = 1;
defparam DCM_ADV_INST.CLKFX_MULTIPLY = 4;
defparam DCM_ADV_INST.CLKIN_DIVIDE_BY_2 = FALSE;
defparam DCM_ADV_INST.CLKIN_PERIOD = 16.129;
defparam DCM_ADV_INST.CLKOUT_PHASE_SHIFT = NONE;
defparam DCM_ADV_INST.DCM_AUTOCALIBRATION = TRUE;
defparam DCM_ADV_INST.DCM_PERFORMANCE_MODE = MAX_SPEED;
defparam DCM_ADV_INST.DESKEW_ADJUST = SYSTEM_SYNCHRONOUS;
defparam DCM_ADV_INST.DFS_FREQUENCY_MODE = LOW;
defparam DCM_ADV_INST.DLL_FREQUENCY_MODE = LOW;
defparam DCM_ADV_INST.DUTY_CYCLE_CORRECTION = TRUE;
defparam DCM_ADV_INST.FACTORY_JF = 16hF0F0;
defparam DCM_ADV_INST.PHASE_SHIFT = 0;
defparam DCM_ADV_INST.STARTUP_WAIT = FALSE;
endmodule
比較以上兩段代碼,區(qū)別在于選擇是External時(shí)CLKIN經(jīng)過了IBUFG才到的DCM_ADV,而選擇Internal的CLKIN則直接到了DCM_AV,而IBUFG就是原語“全局時(shí)鐘緩沖”單元,我們使用時(shí)要選擇External,只有當(dāng)我們的級(jí)聯(lián)兩個(gè)DCM模塊時(shí),直接與外面相連的選External,而另一個(gè)選擇Internal。
這也是本文的一個(gè)知識(shí)點(diǎn)吧:兩個(gè)DCM級(jí)聯(lián)時(shí),直接與外面相連的選External,而另一個(gè)選擇Internal。
所以本段的主題是“非GC類全局時(shí)鐘管腳是否可以作時(shí)鐘使用?”其實(shí)更多應(yīng)該指的是“非GC類全局時(shí)鐘管腳是否可以接到IBUFG?”
試驗(yàn)中,我們將External的DCM的輸入CLKIN輸入引腳配置成一個(gè)普通的IO口,即非GC類全局時(shí)鐘管腳,布局布線階段出現(xiàn)以下錯(cuò)誤:
ERROR:Place:645 - A clock IOB clock component is not placed at an optimal clock IOB site. The clock IOB component
因此得出結(jié)論:非GC類全局時(shí)鐘管腳不可以作時(shí)鐘使用(其實(shí)是不可以接到IBUFG的輸入端)。
3)在Xilinx手冊(cè)中提到,如果使用單端輸入時(shí)鐘,要使用P類型GC全局時(shí)鐘管腳,那么空間N類型的管腳是否可以么?
所謂P類型還是N類型其實(shí)指的是IO_L1P_GC_LC或IO_L1N_GC_LC,注意這里的L1P和L1N,這就標(biāo)識(shí)這個(gè)管腳是P類型還是N類型。
試驗(yàn)中,我們將N類型全局時(shí)鐘管腳配置給CLKIN,結(jié)果布局布線時(shí)出現(xiàn)與(2)中一樣的錯(cuò)誤。
因此得出結(jié)論:GC類全局時(shí)鐘管腳N類型管腳不可以作為單端時(shí)鐘輸入管腳(其實(shí)也是不能作為IBUFG的輸入端)
4)差分時(shí)鐘輸入時(shí)鐘管腳能否配置普通IO?N類型管腳和P類型管腳必須分別給配置P類型GC全局時(shí)鐘管腳和N類型GC全局時(shí)鐘管腳?
4.1>使用了一對(duì)普通IO配置給DCM的CLKIN_N_IN和CLKIN_P_IN,并且將這對(duì)普通的IO的P型分配給DCM的CLKIN_N_IN型輸入,IO的N型分配給DCM的CLKIN_P_IN型輸入,出現(xiàn)如下錯(cuò)誤:
ERROR:Place:604 - The I/O components clkp and clkn are the P- and N-sides of a differental I/O pair. The component
4.2>使用了一對(duì)普通IO配置給DCM的CLKIN_N_IN和CLKIN_P_IN,并且對(duì)應(yīng)地將這對(duì)普通的IO的P型分配給DCM的CLKIN_P_IN型輸入,IO的N型分配給DCM的CLKIN_N_IN型輸入,出現(xiàn)如下錯(cuò)誤:
ERROR:Place:645 - A clock IOB clock component is not placed at an optimal clock IOB site. The clock IOB component
4.3>使用一對(duì)GC類全局時(shí)鐘IO管腳配置給DCM的CLKIN_N_IN和CLKIN_P_IN,并且將這對(duì)普通的IO的P型分配給DCM的CLKIN_N_IN型輸入,IO的N型分配給DCM的CLKIN_P_IN型輸入,出現(xiàn)與4.1中相同的錯(cuò)誤。
4.4>正常配置,即使用了一對(duì)GC類全局時(shí)鐘IO管腳配置給DCM的CLKIN_N_IN和CLKIN_P_IN,并且對(duì)應(yīng)地將這對(duì)普通的IO的P型分配給DCM的CLKIN_P_IN型輸入,IO的N型分配給DCM的CLKIN_N_IN型輸入,則完全正確。
因此得出結(jié)論:差分時(shí)鐘輸入時(shí)必須使用一對(duì)GC類全局時(shí)鐘IO管腳配置給DCM的CLKIN_N_IN和CLKIN_P_IN,且N類型和P類型要匹配。
其實(shí)這個(gè)歸根到底還是原語IBUFGDS在作怪,查看一下差分輸入DCM的原文件就行了:
IBUFGDS CLKIN_IBUFGDS_INST (.I(CLKIN_P_IN),
.IB(CLKIN_N_IN),
.O(CLKIN_IBUFGDS));
5)那么如果將輸入輸出口配置成非IO管腳會(huì)怎么樣呢?
在試驗(yàn)中,將某一VCCO配置成了給了輸出口,結(jié)果在映射階段出現(xiàn)如下錯(cuò)誤:
ERROR:MapLib:30 - LOC constraint AF17 on q2> is invalid: No such site on the
因此,不能將輸入輸出口配置成非IO管腳,當(dāng)然這樣配置本身也是不合理的。
評(píng)論