1. 程式人生 > >Xilinx的clocking wizard_時鐘輸出接普通I/O口遇到的問題以及需要注意的問題

Xilinx的clocking wizard_時鐘輸出接普通I/O口遇到的問題以及需要注意的問題

一開始是使用了clocking wizard 想分出來2個時鐘來輸出(CLK_50M和MCLK),並且再用產生的一個時鐘生成其他訊號輸出,結果一開始就報錯,提示不可以用做輸出。然後沒有直接輸出MCLK訊號,而是將次訊號做了個暫存器快取再輸出,然而綜合卻出現了錯誤:
WARNING:Place:1205 - This design contains a global buffer instance,<PR_MCLK_TYPE_PLL/clkout2_buf>, driving the net, <PR_MCLK_TYPE_OBUF>, that is driving the following (first 30) non-clock source pins off chip.
< PIN: PR_MCLK.O; >
This design practice, in Spartan-6, can lead to an unroutable situation due to limitations in the global routing. If the design does route there may be excessive delay or skew on this net. It is recommended to use a Clock Forwarding technique to create a reliable and repeatable low skew solution:
Synthesize - XST綜合過了,但是Implement Design 過不了。經過網上查詢及借鑑和Xilinx的ug381手冊發現,此處需要例項化一個小元件ODDR2。手冊中有原始碼。
更改前的程式碼:

  Pr_clk PR_CLK
   (// Clock in ports
    .CLK_IN1(sys_clk),      // IN
    // Clock out ports
    .CLK_OUT1(clk_out1),     // OUT  CLK_50M
    .CLK_OUT2(clk_out2),     // OUT  MCLK
    // Status and control signals
    .RESET(~sys_rst));       // IN

更改後的程式碼為

Pr_clk PR_CLK
   (// Clock in ports
    .CLK_IN1(sys_clk),      // IN
    // Clock out ports
    .CLK_OUT1(clk_out1),     // OUT
    .CLK_OUT2(clk_out2),     // OUT
    .CLK_OUT3(CLK_50M),     // OUT  //此處是要引入內部的時鐘
    .CLK_OUT4(MCLK_TYPE),     // OUT //同樣要引入內部
    // Status and control signals
    .RESET(~sys_rst));       // IN
// INST_TAG_END ------ End INSTANTIATION Template ---------

wire clk_out1;
wire clk_out2;

 //clk_out1
 
 ODDR2 #(
   // The following parameters specify the behavior
   // of the component.
   .DDR_ALIGNMENT("NONE"), // Sets output alignment 
                           // to "NONE", "C0" or "C1"
   .INIT(1'b0),    // Sets initial state of the Q  
                   //   output to 1'b0 or 1'b1
   .SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" 
                   //   set/reset
)
ODDR2_clkout1 (
   .Q(clk_50M),   // 1-bit DDR output data  需要輸出到外部而不能再引入內部的時鐘
   .C0(clk_out1), // 1-bit clock input
   .C1(~clk_out1), // 1-bit clock input
   .CE(1'b1), // 1-bit clock enable input
   .D0(1'b1), // 1-bit data input (associated with C0)
   .D1(1'b0), // 1-bit data input (associated with C1)
   .R(1'b0),   // 1-bit reset input
   .S(1'b0)    // 1-bit set input
);

//clk_out2 
 
 ODDR2 #(
   // The following parameters specify the behavior
   // of the component.
   .DDR_ALIGNMENT("NONE"), // Sets output alignment 
                           // to "NONE", "C0" or "C1"
   .INIT(1'b0),    // Sets initial state of the Q  
                   //   output to 1'b0 or 1'b1
   .SRTYPE("SYNC") // Specifies "SYNC" or "ASYNC" 
                   //   set/reset
)
ODDR2_clkout2 (
   .Q(MCLK),   // 1-bit DDR output data  
   .C0(clk_out2), // 1-bit clock input
   .C1(~clk_out2), // 1-bit clock input
   .CE(1'b1), // 1-bit clock enable input
   .D0(1'b1), // 1-bit data input (associated with C0)
   .D1(1'b0), // 1-bit data input (associated with C1)
   .R(1'b0),   // 1-bit reset input
   .S(1'b0)    // 1-bit set input
);

一開始覺得既然clk_50M、MCLK_TYPE可以輸出,那麼也就可以引入別的模組,結果一到Implement Design 就報錯。
錯誤型別:
The dual data rate register “ODDR2_clkout2” failed to join an OLOGIC component as required.
錯誤原因是ODDR的輸出必須直接連到輸出上,不可以再引進邏輯內部。因此會出現do_oddr的輸出無法連入OLOGIC中。
解決方法:

  1. 修改clocking引數,另設需要接入邏輯內部的時鐘訊號。
  2. 參考Xilinx的器件手冊。
    注意
    產生的時鐘不可以相互計數取樣,否則綜合會出錯,例如用clk_out1去計數clk_out2是不可以的