基于CPLD的主板上电时序控制--状态机方式
目錄
- 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ī)會(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)行獲取
不同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_ON3.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 定義變量
定義了一些變量:
3.4 例化模塊
例化了兩次模塊,因?yàn)榘存I輸入分為電源鍵和復(fù)位鍵,模塊支持復(fù)用,代碼在最后。
3.5 邏輯部分
見(jiàn)下文:
3.5.1 輔助邏輯
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)題。
- 上一篇: [Luogu P4168] [BZOJ
- 下一篇: 人物专访 | 从《黑客帝国》到《花木兰》