天天看點

TMS320C6678上電配置和FPGA複位DSP

參考手冊:TMS320C6678使用者手冊。 https://blog.csdn.net/u014404875/article/details/79771589

1. DSP上電複位配置什麼?

    DSP的大、小端,自啟動(boot)模式,PCIe模式,網絡協處理器時鐘選擇需要在上電複位的時候選擇,怎麼選擇? 依靠上電時候鎖定DSP Device Configuration pins(裝置配置管腳)的邏輯電平。     配置管腳的邏輯電平怎麼設定? 一般采用兩種方式:

  • 第一種是把DSP的配置管腳全部和FPGA的IO連接配接,由FPGA上電控制(文末附FPGA複位DSP程式)
  • 第二種是通過外部上拉/下拉電阻。

   提示:     合理的闆載設計應該確定所有的裝置輸入引腳都在一個有效電平而不能懸空,可以通過上拉/下拉電阻實作,當然可以内部上拉或外部上拉。 裝置通過評估需求,一般内部實作上拉/下拉。但是一些管腳需要外部上拉/下拉。     (1) 裝置配置管腳:這些管腳同時需要輸出(C6678的配置管腳和GPIO是公用管腳)且沒有驅動(高阻态),即使内部上拉/下拉電阻也許滿足需求電平, 但是外部上拉/下拉也是必須,目的是為了確定配置有效,也友善切換模式。     (2) 其他輸入管腳:如果内部上拉/下拉沒有滿足需求電平,則需要外部上拉/下拉。     

2. TMS320C6678裝置配置管腳 (1) LENDIAN :決定DSP的大小端。 (2) BOOTMODE[12:0] :決定DSP的自啟動模式(詳情見BootLoader for the C66x DSP User Guide)。 (3) PCIESSMODE : 決定PCIe子系統處于EP、legacy EP還是RC。 (4) PCIESSEN : 決定是否使能PICe 子系統,預設是不使能。 (5) PACKSEL: 決定網絡協處理器的輸入時鐘是核時鐘還是PASSCLK時鐘。

3. DSP上電時序     DSP的上電時序,就是上電複位的時序。     裝置初始化分為兩個階段: (1) 所有的供電電源穩定,不同的電源有供電時序,可見下面時序圖。 (2) RESET、POR、RESERFULL按時序拉高,當然還包括時鐘輸入穩定。

TMS320C6678上電配置和FPGA複位DSP

                                上電時序圖 注意: (1) 在電源穩定期間,POR要保持低電平,是以複位前拉低。 (2) DDRCLK、REFCLK應該在POR拉高前觸發。 (3) 一旦獲得DVDD18供電,RESETSTAT拉低。       在DVDD18供電前,所有的LVCMOS輸入和雙向管腳不能驅動為低電平或拉高。 (4) 在DVDD18有效後,RESETSTAT可以在任何時刻被拉高。在POR控制boot下,RESET必須在POR拉高前拉高。 (5) 在電源穩定後,POR必須持續保持低電平至少100us。至此,電源穩定階段結束。 (6) 在電源穩定階段後裝置初始化需要500個REFCLK時鐘周期。最大時鐘周期是33.33nsec,是以在POR上升沿前延遲16us是必要的。在整個16us期間,時鐘必須是激活的。 (7) 在POR穩定在高電平之後,RESETFULL必須要保持低電平24個REFCLK時鐘周期。 (8) 在RESETFULL上升沿,裝置鎖定GPIO 配置管腳的電平,然後進行配置,到複位狀态位RESETSTAT信号拉高延遲大約10000到50000個時鐘周期。 (9) GPIO配置必須在RESETFULL上升沿前保持至少12個REFCLK時鐘周期(transitions)。 (10) GPIO配置必須在RESETFULL上升沿後保持至少12個REFCLK時鐘周期(transitions)。 總的來說:     在各個電源供電正常後,DSP的時鐘穩定後,驅動RESET、POR、RESETFULL依次拉高,在RESETFULL的上升沿鎖定DSP複位配置的GPIO電平,然後RESETSTAT拉高,則DSP上電複位完成。

4. DSP的複位模式     總共四種複位模式,前三種複位模式都會觸發RESETSTAT,局部複位不會觸發RESETSTAT. (1) 上電複位 (2) 硬體複位 (3) 軟體複位 詳見手冊。 (4) 局部複位    

TMS320C6678上電配置和FPGA複位DSP

                                        局部複位時序圖 上電複位後,可以進行局部複位,即對每個核單獨複位。 局部複位可以被以下方式觸發:

  • LRESET pin
  • Watchdog timer、CORESEL[3:0] and RSTCFG register
  • LPSC MMRs(memory-mapped registers)  
TMS320C6678上電配置和FPGA複位DSP
TMS320C6678上電配置和FPGA複位DSP

一般我們不使用局部複位,如果上電複位後,發現某些核處于複位狀态,而其他核可以連接配接使用,多半是局部複位造成的,應該把LRESETNMIEN 設定為1,則可以避免這個問題。

5. FPGA控制DSP上電複位程式。

module DSP_RST(
        input clk_25m,
        input RESETSTAT,                     //DSP複位狀态 0表示複位态 1表示工作态
        input LOCKED,                         //時鐘子產品是否正常

        output ref LRESETNMIENz = 1'b0,       //局部複位管腳
        output reg PORz=1'b0,                 //Power-on Reset
        output reg RESETFULL=1'b0,            //Full Reset
        output reg RESET=1'b0        
    );
        
        reg [2:0] RES_STATE=2'b00;
        reg [15:0] por_counter=16'b0,resetfull_counter=16'b0,reset_counter=16'b0;
        
        parameter IDLE=2'b00,PULL_RESET=2'b01,PULL_POR=2'b10,PULL_RESETFULL=2'b11;
        
always @(posedge clk_25m)
    if(LOCKED==1)
        begin
        case(RES_STATE)
        IDLE: 
                 RES_STATE<=PULL_RESET ;
        PULL_RESET: if(reset_counter<25000)
                            begin
                            reset_counter<=reset_counter+16'b1;
                            RES_STATE<=RES_STATE;
                            RESET<=1'b0;
                            PORz<=1'b0;
                            RESETFULL<=1'b0;
                            end
                        else
                            begin
                            RESET<=1'b1;
                            LRESETNMIENz<=1`b1;    //禁止局部複位。
                            RES_STATE<=PULL_POR;
                            end
        PULL_POR: if(por_counter<25000)  
                            begin
                            por_counter<=por_counter+16'b1;
                            RES_STATE<=RES_STATE;
                            PORz<=1'b0;
                            end
                     else
                            begin
                            PORz<=1'b1;
                            RES_STATE<=PULL_RESETFULL;
                            end
        PULL_RESETFULL:if(resetfull_counter<25000)
                                begin
                                resetfull_counter<=resetfull_counter+16'b1;
                                RES_STATE<=RES_STATE;
                                RESETFULL<=1'b0;
                                end
                            else
                                begin
                                RESETFULL<=1'b1;
                                RES_STATE<=RES_STATE;
                                end
        endcase                
        end
    else
        begin
        reset_counter<=16'b0;
        resetfull_counter<=16'b0;
        por_counter<=16'b0;
        RES_STATE<=IDLE;
        RESET<=1'b0;
        PORz<=1'b0;
        RESETFULL<=1'b0;
        end

endmodule`