日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

基于CPLD的主板上电时序控制--状态机方式

發(fā)布時(shí)間:2024/3/7 编程问答 62 豆豆
生活随笔 收集整理的這篇文章主要介紹了 基于CPLD的主板上电时序控制--状态机方式 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

目錄

    • 1. 前言
      • 1.1 需求
    • 2. 背景介紹
    • 3. 代碼部分
      • 3.1 定義端口
      • 3.2 定義參數(shù)
      • 3.3 定義變量
      • 3.4 例化模塊
      • 3.5 邏輯部分
        • 3.5.1 輔助邏輯
        • 3.5.2 CPU狀態(tài)獲取邏輯
        • 3.5.3 狀態(tài)機(jī)邏輯
        • 3.5.4 按鍵捕捉
    • 4. 后言

1. 前言

博主第一份工作做FPGA工程師,公司給了CPLD的任務(wù)給我練手,大大小小參與了幾款主板上電的設(shè)計(jì),同一套代碼進(jìn)行了多次修改運(yùn)用。跳槽后,把代碼整理一下,改善代碼結(jié)構(gòu),優(yōu)化可移植性。

CLPD是安路的,CPU是FT2000系列;

常用的上電控制有使用單片機(jī)CPLD或者EC的方式,本文使用CPLD實(shí)現(xiàn)上電控制操作

如果覺(jué)得對(duì)你有幫助的話,還請(qǐng)不忘點(diǎn)個(gè)贊!!!!

1.1 需求

以下需求均可完成

需求如下:

  • 主板插電后,能夠進(jìn)行上電自啟動(dòng)
  • 指示運(yùn)行狀態(tài)
  • 支持軟件關(guān)機(jī)重啟(系統(tǒng)發(fā)送關(guān)機(jī)重啟指令)
  • 支持按鍵開(kāi)關(guān)機(jī)重啟(硬件按鍵,可以多個(gè)實(shí)體按鍵也可以單個(gè))
  • 支持遠(yuǎn)程開(kāi)關(guān)機(jī)重啟(遠(yuǎn)程,網(wǎng)絡(luò)或者串口或者就一根數(shù)據(jù)線)
  • 支持看門狗,檢測(cè)系統(tǒng)運(yùn)行是否正常
  • 串口通信
  • 串口通信和看門狗以后有機(jī)會(huì)再補(bǔ)充。

    2. 背景介紹

    上電時(shí)序控制說(shuō)到底,是要求芯片在限定的時(shí)間對(duì)電源發(fā)出Enable信號(hào),并檢測(cè)Power Good信號(hào),在繼續(xù)下一電源的上電。所以打算使用狀態(tài)機(jī)的方式進(jìn)行時(shí)序控制。

    CPU狀態(tài)能夠通過(guò)PWR_CTR0-1引腳進(jìn)行獲取

  • 1個(gè)脈沖表示CPU上電完成,工作正常
  • 12個(gè)脈沖表示CPU發(fā)送關(guān)機(jī)請(qǐng)求
  • 5個(gè)脈沖表示CPU發(fā)送重啟請(qǐng)求
  • 不同CPU的反饋不相同,要根據(jù)芯片參考手冊(cè)。

    FT2000的上電要求如下:

    掉電要求如下:


    3. 代碼部分

    3.1 定義端口

    端口的名稱最好按照硬件設(shè)計(jì)師給出的原理圖進(jìn)行相似的命名,方便交流

    input CPLD_CLK_50M, //1.8V //CPU reset low active output reg FT_POR_N, //CPU power state out and control 1.8output reg FT_GPIO0_A1,input FT_PWR_CTR1,input FT_PWR_CTR0, output LED0, //DDR reset ,low activeoutput MEM_RESET_S3_N, // POWER CONTROLoutput reg VDD_CORE_EN, input VDD_CORE_PWRGD,output reg VDDQ_EN, input VDDQ_PWRGD, output reg VTT_EN, output reg VPP_EN, output reg P3V3_EN, output reg P1V8_EN, //control input RST_IN, input RST_OUT, input PWRBTN, input PS_ON

    3.2 定義參數(shù)

    定義了狀態(tài)機(jī)的所有狀態(tài)和需要用到的延時(shí)值

    //state machine parameter S0_WAIT_PWOER_ON = 5'd0; parameter S1_IDLE = 5'd1;parameter S2_OTHER_ON = 5'd2;parameter S3_CPU_CORE_UP = 5'd3;parameter S4_P1V8_ON = 5'd4;parameter S5_GPIO0_A1_DOWN = 5'd5;parameter S6_PCIE_RST = 5'd6;parameter S7_FT_RST_N_UP = 5'd7;parameter S8_WAIT_CPU_ACK = 5'd8;parameter S9_RECEIVE_CPU_ACK = 5'd9;parameter S10_S0_WORK = 5'd10;parameter S11_POWER_DOWN = 5'd11;parameter S12_PCIe_FT_DOWN = 5'd12;parameter S13_IO_PWR_DOWN = 5'd13;parameter S14_CORE_PWR_DOWN = 5'd14;parameter S15_OTHER_PWR_DOWN = 5'd15;// delay timeparameter TIME_20ms = 27'd20;parameter TIME_120ms = 27'd120; parameter TIME_140ms = 27'd140;parameter TIME_150ms = 27'd150;parameter TIME_1000ms = 27'd1000;

    3.3 定義變量

    定義了一些變量:

  • CPU狀態(tài)捕捉相關(guān)的信號(hào)
  • 狀態(tài)機(jī)
  • 一些flag信號(hào)
  • 延時(shí)計(jì)數(shù)器
  • //******** variable definition ********//// 1kHZ clkreg [20:0] count_1kclk=1'b0;reg clk_1K=1'b0;//cpu statereg soft_reset=1'b0;reg soft_s3_flag=1'b0;reg soft_s5_flag=1'b0;reg receive_cpu_1p=1'b0;reg soft_s3_vtt_off_flag=1'b0;reg soft_s3_vtt_on_flag=1'b0;reg soft_s3_vtt_flag=1'b0;reg [7:0] pm_count, pm_count_a, pm_count_b, pm_count_c;reg [7:0] statu_pm_count=8'b0;reg cpu_ack=0;//state machinereg [5:0] current_state;reg [5:0] next_state;//power onreg first_power_on_flag = 1;reg power_on_flag = 1; //soft power downwire soft_power_off_flag = soft_s5_flag; //soft resetwire soft_reset_flag = soft_reset; wire sys_rst;reg first_sys_rst_flag =0 ;reg [15:0] sys_rst_cnt =0 ; //keywire hard_reset_flag;wire hard_power_on_flag;wire hard_power_off_flag; reg clear_hard_flag =1'b0;//led conuterreg [15:0] led_cnt =0; //delay counterreg [15:0] delay_cnt =0;reg [15:0] delay_time_set =0;reg delay_cnt_enable=0;//******** end variable definition ********//

    3.4 例化模塊

    例化了兩次模塊,因?yàn)榘存I輸入分為電源鍵和復(fù)位鍵,模塊支持復(fù)用,代碼在最后。

  • 可以捕捉一路信號(hào)
  • 可以設(shè)置三種延時(shí)時(shí)間
  • 可以輸出三個(gè)flag信號(hào)
  • // ******** Instantiated module ******** // // ***** PWRBTN key catch *****////KEY_DELAY1 > KEY_DELAY2 > KEY_DELAY3// if key time > KEY_DELAY1 key_on_flag1=1// if KEY_DELAY1 > key time > KEY_DELAY2 key_on_flag2=1// if KEY_DELAY2 > key time > KEY_DELAY3 key_on_flag3=1key_catch #(.KEY_DELAY1(PWOER_OFF_DELAY), .KEY_DELAY2(PWOER_ON_DELAY), .KEY_DELAY3(PWOER_ON_DELAY-10),.ACTIVE_LEVEL(0) ) key_catch_pwrpin(.clk (clk_1K),.reset (sys_rst),.key_in (PWRBTN),.clear_flag (clear_hard_flag),.key_on_flag1 (hard_power_off_flag),.key_on_flag2 (hard_power_on_flag),.key_on_flag3 ());// ***** RST_IN key catch *****////KEY_DELAY1 > KEY_DELAY2 > KEY_DELAY3// if key time > KEY_DELAY1 key_on_flag1=1// if KEY_DELAY1 > key time > KEY_DELAY2 key_on_flag2=1// if KEY_DELAY2 > key time > KEY_DELAY3 key_on_flag3=1key_catch #(.KEY_DELAY1(PWOER_RST_DELAY), .KEY_DELAY2(PWOER_RST_DELAY-10), .KEY_DELAY3(PWOER_RST_DELAY-10),.ACTIVE_LEVEL(0) ) key_catch_rst(.clk (clk_1K),.reset (sys_rst),.key_in (RST_IN),.clear_flag (clear_hard_flag),.key_on_flag1 (hard_reset_flag),.key_on_flag2 (),.key_on_flag3 ());

    3.5 邏輯部分

    見(jiàn)下文:

    3.5.1 輔助邏輯

  • 上電復(fù)位
  • LED指示
  • 首次開(kāi)機(jī)標(biāo)志
  • 系統(tǒng)復(fù)位完成
  • 延時(shí)計(jì)數(shù)器
  • //***** CLK_1K generate *****// always @( posedge CPLD_CLK_50M )begincount_1kclk <= count_1kclk+1'b1; //poweroff reset flagif( count_1kclk == 25000 )beginclk_1K <= ~clk_1K;count_1kclk <= 1'b0;endend//***** LED *****//always @(posedge clk_1K ) beginled_cnt <=led_cnt+1; endassign LED0 =led_cnt[11];//***** system reset *****//always@(posedge clk_1K) begin if(sys_rst_cnt<TIME_150ms)begin sys_rst_cnt<=sys_rst_cnt+16'd1;end else begin sys_rst_cnt<=sys_rst_cnt;end end assign sys_rst = (sys_rst_cnt>TIME_20ms && sys_rst_cnt<TIME_120ms) ? 1:0;//***** first power on *****//always @(posedge clk_1K) beginif (soft_reset_flag || soft_power_off_flag) beginfirst_power_on_flag <=0; end else beginfirst_power_on_flag <=first_power_on_flag;endend//***** system reset done flag *****//always @(posedge clk_1K ) beginif (sys_rst) beginfirst_sys_rst_flag <= 1;end else beginfirst_sys_rst_flag <= first_sys_rst_flag;endend//***** delay conuter *****//always @(posedge clk_1K ) beginif (sys_rst) begindelay_cnt<=27'h0; end else if(delay_cnt_enable==1 && (delay_cnt<delay_time_set)) begindelay_cnt<=delay_cnt+1;end else begindelay_cnt<=27'h0;end end

    3.5.2 CPU狀態(tài)獲取邏輯

    暫時(shí)不貼出來(lái),需要的可以評(píng)論留言!

    3.5.3 狀態(tài)機(jī)邏輯

    //***** Three-stage state machine *****//// firstalways @(posedge CPLD_CLK_50M) begincurrent_state <= next_state;end//secondalways @(*) begincase (current_state)S0_WAIT_PWOER_ON:beginif (first_power_on_flag && first_sys_rst_flag && (delay_cnt== TIME_1000ms)) beginnext_state =S1_IDLE;end else if(soft_reset_flag ) beginnext_state =S1_IDLE;end else if(hard_power_on_flag || hard_reset_flag) beginnext_state =S1_IDLE;end else begin next_state =S0_WAIT_PWOER_ON;endend//S1_IDLE:beginif (delay_cnt== TIME_20ms) beginnext_state =S2_OTHER_ON;end else begin next_state =S1_IDLE;end endS2_OTHER_ON :beginif ( (delay_cnt== TIME_20ms)) beginnext_state =S3_CPU_CORE_UP;end else begin next_state =S2_OTHER_ON;end endS3_CPU_CORE_UP :beginif ( (delay_cnt== TIME_20ms)) beginnext_state =S4_P1V8_ON;end else begin next_state =S3_CPU_CORE_UP;end endS4_P1V8_ON :beginif ((delay_cnt== TIME_20ms)) beginnext_state =S5_GPIO0_A1_DOWN;end else begin next_state =S4_P1V8_ON;end endS5_GPIO0_A1_DOWN :beginif ( (delay_cnt== TIME_140ms)) beginnext_state =S6_PCIE_RST;end else begin next_state =S5_GPIO0_A1_DOWN;end endS6_PCIE_RST :beginif ((delay_cnt== TIME_20ms)) beginnext_state =S7_FT_RST_N_UP;end else begin next_state =S6_PCIE_RST;end endS7_FT_RST_N_UP :beginif ((delay_cnt== TIME_120ms)) beginnext_state =S8_WAIT_CPU_ACK;end else begin next_state =S7_FT_RST_N_UP;end endS8_WAIT_CPU_ACK :beginif (receive_cpu_1p == 1'b1) beginnext_state =S9_RECEIVE_CPU_ACK;end else begin next_state =S8_WAIT_CPU_ACK;end endS9_RECEIVE_CPU_ACK:beginif (cpu_ack==1'b1) beginnext_state =S10_S0_WORK;end else begin next_state =S9_RECEIVE_CPU_ACK;end endS10_S0_WORK :beginif((soft_power_off_flag == 1'b1) || (soft_reset_flag == 1'b1))begin next_state = S11_POWER_DOWN;end else if(hard_power_off_flag || hard_reset_flag) beginnext_state = S11_POWER_DOWN;end else begin next_state = S10_S0_WORK;endend S11_POWER_DOWN :beginif ((delay_cnt== TIME_20ms)) beginnext_state =S12_PCIe_FT_DOWN;end else begin next_state =S11_POWER_DOWN;end endS12_PCIe_FT_DOWN :beginif ((delay_cnt== TIME_150ms)) beginnext_state =S13_IO_PWR_DOWN;end else begin next_state =S12_PCIe_FT_DOWN;end endS13_IO_PWR_DOWN :beginif ((delay_cnt== TIME_20ms)) beginnext_state =S14_CORE_PWR_DOWN;end else begin next_state =S13_IO_PWR_DOWN;end endS14_CORE_PWR_DOWN :beginif ((delay_cnt== TIME_20ms)) beginnext_state =S15_OTHER_PWR_DOWN;end else begin next_state =S14_CORE_PWR_DOWN;end endS15_OTHER_PWR_DOWN :beginif ((delay_cnt== TIME_1000ms)) beginnext_state =S0_WAIT_PWOER_ON;end else begin next_state =S15_OTHER_PWR_DOWN;end enddefault: beginnext_state <= S0_WAIT_PWOER_ON;endendcase end //thirdalways @(posedge CPLD_CLK_50M)beginif(sys_rst) beginVDD_CORE_EN <=1'b0; VDDQ_EN <=1'b0; VTT_EN <=1'b0; VPP_EN <=1'b0; P3V3_EN <=1'b0; P1V8_EN <=1'b0; FT_GPIO0_A1 <=1'b1;FT_POR_N <=1'b0; clear_hard_flag <=1'b1; endelse begincase (current_state)S0_WAIT_PWOER_ON :begindelay_cnt_enable <=1'b1;delay_time_set <=TIME_1000ms;end //S1_IDLE :beginVDD_CORE_EN <=1'b0; VDDQ_EN <=1'b0; VTT_EN <=1'b0; VPP_EN <=1'b0; P3V3_EN <=1'b0; P1V8_EN <=1'b0; FT_GPIO0_A1 <=1'b1;FT_POR_N <=1'b0; // GAMC_RST_N <=1'b0; delay_time_set <=TIME_20ms;endS2_OTHER_ON :beginVDDQ_EN <=1'b1; VTT_EN <=1'b1; VPP_EN <=1'b1; P3V3_EN <=1'b1;delay_time_set <=TIME_20ms;endS3_CPU_CORE_UP :beginVDD_CORE_EN <=1'b1;delay_time_set <=TIME_20ms;endS4_P1V8_ON :beginP1V8_EN <=1'b1; delay_time_set <=TIME_20ms;endS5_GPIO0_A1_DOWN :beginFT_GPIO0_A1 <=1'b0;delay_time_set <=TIME_140ms; endS6_PCIE_RST :begin//GAMC_RST_N <=1'b1; //display card reset,pcie,low activedelay_time_set <=TIME_20ms; endS7_FT_RST_N_UP :beginFT_POR_N <=1'b1;delay_time_set <=TIME_120ms; endS8_WAIT_CPU_ACK :begincpu_ack <= 1'b1;clear_hard_flag <= 1'b1;delay_time_set <=TIME_20ms;endS9_RECEIVE_CPU_ACK :beginclear_hard_flag <=1'b0;delay_time_set <=TIME_20ms;endS10_S0_WORK :begindelay_time_set <=TIME_20ms;endS11_POWER_DOWN :beginpower_on_flag <=1'b0; delay_time_set <=TIME_20ms;endS12_PCIe_FT_DOWN :beginFT_POR_N <=1'b0;delay_time_set <=TIME_150ms; endS13_IO_PWR_DOWN :beginP1V8_EN <=1'b0;delay_time_set <=TIME_20ms; endS14_CORE_PWR_DOWN :beginVDD_CORE_EN <=1'b0;delay_time_set <=TIME_20ms; endS15_OTHER_PWR_DOWN :beginVDDQ_EN <=1'b0; VTT_EN <=1'b0; VPP_EN <=1'b0; P3V3_EN <=1'b0; delay_time_set <=TIME_1000ms; enddefault: begin;endendcaseendend// ******** sequential logic ******** //

    3.5.4 按鍵捕捉

    見(jiàn)我的另一篇博客:

    4. 后言

    我的代碼在我參與的項(xiàng)目中能夠穩(wěn)定運(yùn)行,但是如果讀者想要進(jìn)行移植和二次開(kāi)發(fā)還需要結(jié)合自己項(xiàng)目的實(shí)際情況,最好是理解設(shè)計(jì)代碼。

    完整代碼不貼了,代碼不是最完善的狀態(tài),歡迎批評(píng)指正,本篇博客僅供參考!

    有任何疑問(wèn)歡迎評(píng)論留言

    總結(jié)

    以上是生活随笔為你收集整理的基于CPLD的主板上电时序控制--状态机方式的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

    如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。