之前一直相不明白,為什么從官網下載的AC97的IP不能跑起來,整個IP就像空殼一樣,bit_clk輸進去,沒有任何信號輸出來。從IP的RTL來看,即使是IP不連到CPU的BUS上,只要是綜合進FPGA了,當BIT_CLK信號輸進IP時,SD_OUT,SYNC就應該有數據和信號輸出,但奇怪的是,它們不是為高就是為低,跳都不跳一下,很顯然,IP的輸出信號並沒有成功的輸出到管腳上。
后來才發現,原來是約束的問題,看來對於FPGA設計來說,約束真的很重要啊。
下面介紹幾種常用的約束語句,以備查閱。
NET "clk0" TNM_NET = "sys_clk_grp"; #在時鍾網線clk上附加一個TNM_NET約束,把clk0驅動的所有同步元件定義為一個名為sys_clk的分組
#使用TIMESPEC約束sys_clk_grp的周期
TIMESPEC "TS_ sys_clk_grp " = PERIOD " sys_clk_grp " 9.9 ns HIGH 50 %;#周期9.9ns,HIGH指出時鍾周期里的第一個脈沖是高電平,如果是LOW表示是低電平,占空比50%
# FROM_TO用來定義兩個邏輯組之間的時序約束
#語法:TIMESPEC "TS_name " = FROM "group1" TO " group2" value;
TIMESPEC "TS_p2s" = FROM "pads" TO "ffs" 10; # pads到ffs延遲10ns
#最大偏移約束MAXSKEW用於說明同一點驅動的時鍾信號經過路徑傳播后,到達兩個或多個終點的時間差
NET “AC97_Bit_Clk” MAXSKEW =10ns;
NET tft_wr LOC=C11 | IOSTANDARD = LVCMOS33;
NET clk0 IOSTANDARD = LVCMOS33;#IO電平標准 有LVCMOS25、LVTTL、SSTL2_I、LVDCI_33等
NET sys_rst_in LOC = D6;
NET sys_rst_in PULLUP;# PULLUP、 PULLDOWN上拉和下拉設置
NET sys_rst_in TIG;# TIG(Timing Ignore)不進行時序約束
NET SYNC DRIVE = 8 | SLEW = SLOW;# DRIVE :最小驅動電流,單位mA,可以有2,4,6,8,12,16這幾種模式,SLEW ={FAST|SLOW|QUIETIO}, QUIETIO僅用在Spartan-3A。SLEW是壓擺 ,如果slew=fast 會出現過沖,此時DRIVE如果很大(12mA)會導致輸出功率的失真很厲害,有可能會不滿足外接的器件的要求。
#通配符
NET gpio_char_lcd<6> LOC = AE13;
NET gpio_char_lcd<5> LOC = AC17;
NET gpio_char_lcd<4> LOC = AB17;
NET gpio_char_lcd<3> LOC = AF12;
NET gpio_char_lcd<2> LOC = AE12;
NET gpio_char_lcd<1> LOC = AC10;
NET gpio_char_lcd<0> LOC = AB10;
NET gpio_char_lcd<*> IOSTANDARD = LVCMOS33;
NET gpio_char_lcd<*> TIG;
NET gpio_char_lcd<*> PULLDOWN; # *表示任意字符串
#區域約束
# Locate DCM/BUFG - Tools can probably figure them out automatically
# but just LOC them down to be safe
INST dcm_0/dcm_0/DCM_ADV_INST LOC = DCM_ADV_X0Y1;
INST dcm_1/dcm_1/DCM_ADV_INST LOC = DCM_ADV_X0Y2;
INST dcm_2/dcm_2/DCM_ADV_INST LOC = DCM_ADV_X0Y0;
INST dcm_0/dcm_0/CLK0_BUFG_INST LOC = BUFGCTRL_X0Y0;
INST dcm_0/dcm_0/CLK90_BUFG_INST LOC = BUFGCTRL_X0Y1;
INST dcm_0/dcm_0/CLKDV_BUFG_INST LOC = BUFGCTRL_X0Y2;
INST dcm_1/dcm_1/CLK0_BUFG_INST LOC = BUFGCTRL_X0Y31;
INST dcm_1/dcm_1/CLK90_BUFG_INST LOC = BUFGCTRL_X0Y30;
區域的約束相當於將布局過程中指定特定型號的器件的位置,這完全可以通過FloorPlanner的GUI界面進行設置,用圖形界面設置完后,配置信息會放到UCF中,這里只介紹UCF的使用。
例如:
INST "Done" LOC = "SLICE_X32Y163" ; #Done映射為一個寄存器,映射到SLICE_X32Y163的位置上。(32,163)相當於一個坐標,可以用FloorPlanner進行查看。INST"BRAM4/BU2/U0/blk_mem_generator/valid.cstr/ramloop[0].ram.r/v4_init.ram/TRUE_DP.SINGLE_PRIM.TDP"LOC = "RAMB16_X2Y22" ;#RAM16的一個映射。
又例如,X,Y,Z是對應的是寄存器。現在想把它們放在一個指定的區域中,我可以這樣寫,
INST “X” AREA_GROUP = reg;
INST “X” AREA_GROUP = reg;
INST “X” AREA_GROUP = reg;
AREA_GROUP reg RANGE = SLICE_X1Y1 :SLICE_X1Y6;
注:如何查看INST中的名稱呢?在ISE中 Timing constraints editor中可以查看。
參考:
1 . http://www.eefocus.com/yq000cn/blog/10-03/185475_6dce2.html
2. http://bbs.ednchina.com/BLOG_ARTICLE_144140.HTM
轉載自:心的微笑的博客
轉載自 :http://blog.sina.com.cn/s/blog_8200ad9b0101ordv.html