:FPGA 實現(xiàn)低功耗接收狀態(tài)機與常見問題排查)
1. MIPI LP RX 到底在解決什么問題1.1 從一條“沒信號”的調試日志說起如果你調過 MIPI 屏大概率見過這種場景上電、復位、初始化序列全發(fā)完了示波器上 CLK 有波形但 DATA 線上就是不動或者干脆連 LP 狀態(tài)都進不去。日志里翻來覆去就一句話——“mipi屏調試沒信號”。這時候很多人第一反應是去查屏的初始化代碼改時序、改延時、換屏參折騰一圈發(fā)現(xiàn)沒用。真正的問題往往出在LP RX這一側接收端根本沒有正確識別到發(fā)送端發(fā)出的低功耗狀態(tài)信號。MIPI LP RX拆開看就是MIPI 低功耗接收模式。MIPI D-PHY 的物理層把鏈路分成兩種工作狀態(tài)HSHigh Speed高速和 LPLow Power低功耗。HS 用來傳像素數(shù)據(jù)、命令參數(shù)這些大流量內(nèi)容LP 則負責控制、同步、進入退出 HS 的握手。LP RX 就是接收端在 LP 模式下對差分線電平狀態(tài)的采樣與解碼邏輯。它不傳圖像但它是圖像能不能傳的前提。這個內(nèi)容適合誰看三類人一是做嵌入式工業(yè)設備、用 FPGA 或 SoC 接 MIPI 屏的驅動工程師二是調試 MIPI 攝像頭、DVP 攝像頭轉 MIPI 鏈路的硬件工程師三是剛接觸 MIPI 協(xié)議、被 LP/HS 切換搞得一頭霧水的初學者。它解決的問題很具體讓接收端正確識別 LP 狀態(tài)從而完成 HS 進入握手最終點亮屏幕或拿到圖像數(shù)據(jù)。1.2 LP 模式不是“慢速版 HS”很多人有個誤解覺得 LP 就是 HS 降速。完全不是。LP 和 HS 在電氣特性上是兩套東西。HS 是差分小信號共模電壓低擺幅大概 100mV 到 300mV終端匹配 100 歐姆。LP 則是單端大信號0 到 1.2V 邏輯電平兩條線各自獨立判斷高低不靠差分。也就是說LP RX 的輸入級和 HS RX 的輸入級在硬件上就是分開的切換靠的是內(nèi)部的狀態(tài)機。這就解釋了為什么“CLK 有波形但 DATA 不動”——你看到的可能是 HS 時鐘但 LP 狀態(tài)機沒走完DATA 線還鎖在 LP-11 或者卡在某個中間態(tài)。LP RX 要做的就是持續(xù)監(jiān)測 Dp 和 Dn 兩條線的單端電平組合出 LP-00、LP-01、LP-10、LP-11 四種狀態(tài)再根據(jù)狀態(tài)跳變序列判斷發(fā)送端想干什么。提示LP 四種狀態(tài)里LP-11 是空閑態(tài)LP-00 是進入 HS 的起點LP-01 和 LP-10 用于總線翻轉和雙向通信。接收端如果分不清這四個狀態(tài)后面全免談。1.3 為什么現(xiàn)在 LP RX 越來越受關注翻一下最近的搜索熱詞就明白了mipi c-phy s參數(shù)、st7701s mipi、rk3588 mipi 輸入1080i信號、紫光同創(chuàng)fpga驅動mipi、mipi和lvds。這些詞背后是同一個趨勢——MIPI 正在從手機屏往工業(yè)、車載、FPGA 方案里滲透。以前 MIPI 是手機 SoC 的專屬屏廠和主控廠把 LP/HS 時序都調好了驅動工程師不用管物理層。現(xiàn)在不一樣了工業(yè)設備要用 FPGA 直接驅動 MIPI 屏或者用 RK3588 這類芯片接非標準 MIPI 信號源LP RX 就得自己實現(xiàn)或者自己調。FPGA 實現(xiàn) MIPI 尤其典型。FPGA 的 IO 標準里沒有現(xiàn)成的 MIPI D-PHY 硬核LP 接收要靠普通 LVCMOS 輸入加過采樣邏輯來做。這時候 LP RX 的設計質量直接決定鏈路能不能建起來。我見過不少項目HS 數(shù)據(jù)通路用 SelectIO 或者專用 IP 跑得挺好結果卡在 LP 狀態(tài)識別上屏就是不出圖。2. LP RX 的核心機制與狀態(tài)機拆解2.1 D-PHY 的 LP 狀態(tài)編碼與跳變規(guī)則LP RX 的核心是一張狀態(tài)跳變圖。Dp 和 Dn 兩條線每條線有高1和低0兩種電平組合起來就是四種狀態(tài)DpDn狀態(tài)名含義11LP-11空閑鏈路停止01LP-01準備進入 HS 或總線翻轉10LP-10準備進入 HS 或總線翻轉00LP-00HS 進入序列的起點發(fā)送端要進入 HS標準流程是LP-11 → LP-01 → LP-00 → HS-0差分 0→ HS 同步序列。接收端 LP RX 必須按順序識別到 LP-11、LP-01、LP-00然后在 LP-00 之后把接收通路切到 HS 模式。如果中間任何一個狀態(tài)識別錯了或者跳變順序不對狀態(tài)機就進不去 HS。這里有個容易踩的坑LP-01 和 LP-10 的順序不能反。有些實現(xiàn)里為了省事把 LP-01 和 LP-10 都當成“準備態(tài)”不區(qū)分先后。短距離、理想信號下可能能用但一旦線長超過 10cm 或者有干擾順序識別錯誤就會導致誤觸發(fā)。我建議嚴格按規(guī)范來該先 LP-01 就先 LP-01。2.2 接收端采樣時鐘從哪來LP RX 有個很實際的問題HS 有專門的 DDR 時鐘隨路傳輸LP 沒有。LP 狀態(tài)的持續(xù)時間是不固定的發(fā)送端想停多久停多久。接收端怎么采樣常見做法是過采樣。用一個比 LP 狀態(tài)最小持續(xù)時間高得多的時鐘去采 Dp 和 Dn比如 LP 狀態(tài)最短可能 50ns那就用 200MHz 甚至 400MHz 去采每個 LP 狀態(tài)能采到 10 到 20 個點再做多數(shù)表決或者邊沿檢測。FPGA 里用 IDDR 或者普通寄存器打拍都能做關鍵是采樣時鐘要足夠快且穩(wěn)定。另一個做法是異步狀態(tài)機加去抖。把 Dp/Dn 當異步信號先打兩拍同步到本地時鐘域再用計數(shù)器做去抖連續(xù) N 個采樣點一致才認這個狀態(tài)。N 取多少要看你的采樣率和現(xiàn)場噪聲。我一般取 4 到 8太小了容易誤判太大了會漏掉快速跳變。注意過采樣時鐘的抖動要控制好。如果采樣時鐘本身抖動大LP 狀態(tài)邊沿位置飄狀態(tài)機就可能采到中間態(tài)。用 FPGA 的全局時鐘資源別用普通 IO 分頻出來的時鐘。2.3 LP RX 與 HS RX 的切換時機LP RX 識別到 LP-00 之后不能立刻切 HS。規(guī)范里要求發(fā)送端在 LP-00 之后拉出 HS-0 差分信號接收端要等一段時間T HS-SETTLE再使能 HS 接收。這個時間典型值是 85ns 到 100ns 左右具體看數(shù)據(jù)率。切早了HS 接收器還沒穩(wěn)定采到的是垃圾切晚了HS 同步序列的前幾個 bit 丟了后面字節(jié)對齊就錯。FPGA 實現(xiàn)的時候這個切換通常用一個延時計數(shù)器來做。LP 狀態(tài)機輸出一個“進入 HS”的脈沖計數(shù)器開始數(shù)數(shù)到設定值再打開 HS 接收通路。計數(shù)器時鐘就是你的采樣時鐘所以延時值 計數(shù)目標 × 采樣周期。比如 200MHz 采樣要 100ns 延時計數(shù)目標就是 20。這里有個經(jīng)驗延時值留一點余量。規(guī)范給的是最小值實際鏈路因為線損、連接器、ESD 器件HS 信號建立時間可能更長。我一般會在規(guī)范值基礎上加 20% 到 30%。如果發(fā)現(xiàn) HS 數(shù)據(jù)偶爾錯一兩個 bit先別懷疑數(shù)據(jù)通路把 LP 到 HS 的切換延時加大試試。3. FPGA 實現(xiàn) LP RX 的完整實操3.1 硬件連接與 IO 標準選擇用 FPGA 接 MIPI 屏或者 MIPI 信號源第一步是 IO 怎么接。MIPI 的 LP 信號是 0 到 1.2V 單端HS 是差分低壓。FPGA 的普通 bank 如果 VCCO 是 1.2V 或者 1.8VLP 信號可以直接進。但 HS 差分信號需要專門的差分輸入對而且共模電壓要匹配。紫光同創(chuàng)、Xilinx、Altera 的 FPGA 都有支持 MIPI 電平的 IO 標準比如 Xilinx 的 HP bank 可以設成 MIPI_DPHY 標準但那個主要是給 HS 用的。LP 接收我一般用普通 LVCMOS12 或者 LVCMOS18看 VCCO 電壓。如果 VCCO 是 1.8V而 LP 信號是 1.2V直接接可能高電平識別不到需要加電平轉換或者用帶施密特觸發(fā)的輸入。實際接線時Dp 和 Dn 各接一個 FPGA 引腳這兩個引腳最好在同一個 IO bank走線等長。LP 信號速率不高等長要求不嚴但 HS 對走線很敏感所以 PCB 上 LP 和 HS 是同一對差分線只是接收端分兩路進 FPGA。提示如果 FPGA bank 電壓和 MIPI LP 電平不匹配優(yōu)先考慮換 bank 電壓或者加電平轉換芯片別指望內(nèi)部上拉能解決。我見過用 3.3V bank 直接接 1.2V LP 信號的結果 LP-11 被識別成 LP-00狀態(tài)機直接跑飛。3.2 LP 狀態(tài)機的 Verilog 實現(xiàn)下面是一個簡化的 LP RX 狀態(tài)機核心代碼用 200MHz 采樣去抖計數(shù) 4。這段代碼可以直接在普通 FPGA 上跑不需要特殊 IP。module lp_rx ( input wire clk, // 200MHz 采樣時鐘 input wire rst_n, input wire dp, // Dp 單端輸入 input wire dn, // Dn 單端輸入 output reg lp11, output reg lp01, output reg lp10, output reg lp00, output reg enter_hs // 進入 HS 請求 ); // 同步打拍 reg dp_r1, dp_r2, dn_r1, dn_r2; always (posedge clk or negedge rst_n) begin if (!rst_n) begin dp_r1 1b1; dp_r2 1b1; dn_r1 1b1; dn_r2 1b1; end else begin dp_r1 dp; dp_r2 dp_r1; dn_r1 dn; dn_r2 dn_r1; end end // 去抖計數(shù) reg [2:0] cnt; reg dp_stable, dn_stable; always (posedge clk or negedge rst_n) begin if (!rst_n) begin cnt 3d0; dp_stable 1b1; dn_stable 1b1; end else if (dp_r2 ! dp_stable || dn_r2 ! dn_stable) begin if (cnt 3d3) begin dp_stable dp_r2; dn_stable dn_r2; cnt 3d0; end else begin cnt cnt 1b1; end end else begin cnt 3d0; end end // 狀態(tài)譯碼 always (posedge clk or negedge rst_n) begin if (!rst_n) begin lp11 1b1; lp01 1b0; lp10 1b0; lp00 1b0; enter_hs 1b0; end else begin lp11 dp_stable dn_stable; lp01 ~dp_stable dn_stable; lp10 dp_stable ~dn_stable; lp00 ~dp_stable ~dn_stable; // LP-00 之后請求進入 HS enter_hs (~dp_stable ~dn_stable); end end endmodule這段代碼的邏輯很直白先同步再去抖最后譯碼。去抖計數(shù) 4 意味著連續(xù) 4 個采樣點一致才更新狀態(tài)200MHz 下就是 20ns 的濾波窗口。對于大多數(shù) MIPI 鏈路LP 狀態(tài)最短也有 50ns20ns 窗口不會漏掉。3.3 從 LP 到 HS 的切換電路LP 狀態(tài)機輸出enter_hs之后需要延時一段時間再打開 HS 接收。下面是一個延時切換的示例module hs_switch ( input wire clk, input wire rst_n, input wire enter_hs, output reg hs_en ); reg [7:0] delay_cnt; parameter DELAY_TARGET 8d24; // 200MHz 下約 120ns always (posedge clk or negedge rst_n) begin if (!rst_n) begin delay_cnt 8d0; hs_en 1b0; end else if (enter_hs) begin if (delay_cnt DELAY_TARGET) begin hs_en 1b1; delay_cnt delay_cnt; end else begin delay_cnt delay_cnt 1b1; end end else begin delay_cnt 8d0; hs_en 1b0; end end endmoduleDELAY_TARGET取 24200MHz 下就是 120ns。規(guī)范要求 T HS-SETTLE 最小 85ns120ns 留了約 40% 余量。如果鏈路比較長或者經(jīng)過連接器可以加到 32 甚至 40。但也不能太大太大了 HS 同步序列可能已經(jīng)開始了會丟前導碼。3.4 實測波形與狀態(tài)跳變記錄調 LP RX 的時候光看代碼沒用必須抓波形。我用邏輯分析儀抓過一組典型的進入 HS 序列Dp/Dn 的跳變順序是LP-11 持續(xù)約 200nsLP-01 持續(xù)約 60nsLP-00 持續(xù)約 80nsHS-0 差分信號開始約 100ns 后 HS 同步序列出現(xiàn)對應到狀態(tài)機輸出lp11、lp01、lp00依次拉高enter_hs在 LP-00 期間拉高hs_en在 LP-00 結束后約 120ns 拉高。如果hs_en拉高時 HS 同步序列已經(jīng)過了前幾個 bit說明延時太小如果hs_en拉高后很久才看到 HS 數(shù)據(jù)說明延時太大。注意邏輯分析儀的采樣率要足夠高。LP 狀態(tài)最短可能 50ns采樣率至少 500MSa/s 才能看清。用 100MSa/s 的便宜分析儀LP-01 可能只采到一兩個點根本看不出順序。4. 常見問題與排查技巧實錄4.1 LP 狀態(tài)識別錯誤導致“沒信號”這是最典型的問題。現(xiàn)象是 HS 時鐘有但 DATA 不動或者屏完全沒反應。排查步驟先用示波器或者邏輯分析儀看 Dp/Dn 在復位后有沒有 LP-11。如果沒有說明發(fā)送端沒發(fā)或者線路斷了。如果有 LP-11看進入 HS 前有沒有 LP-01 和 LP-00。順序對不對。如果順序對看enter_hs有沒有拉高。沒拉高就是狀態(tài)機去抖參數(shù)或者采樣時鐘有問題。如果enter_hs拉高了但 HS 沒數(shù)據(jù)看hs_en的延時。加大延時試試。我遇到過一種情況LP-01 和 LP-00 之間只有 30ns去抖計數(shù) 4 在 200MHz 下是 20ns理論上夠但實際因為信號邊沿緩狀態(tài)機在 LP-01 只停留了 15ns 就跳到 LP-00結果 LP-01 沒被識別到。后來把去抖計數(shù)降到 2問題解決。所以去抖參數(shù)不是越大越好要看實際 LP 狀態(tài)的最短持續(xù)時間。4.2 橫向花屏與 LP RX 的關系搜索熱詞里有“mipi 液晶屏 橫向 花屏”這個現(xiàn)象和 LP RX 也有關系。橫向花屏通常是 HS 數(shù)據(jù)字節(jié)對齊錯了而字節(jié)對齊的起點是由 LP 到 HS 的切換時刻決定的。如果hs_en拉高太早HS 同步序列的前幾個 bit 被當成數(shù)據(jù)拉高太晚同步序列丟了接收端找不到字節(jié)邊界。兩種情況都會導致花屏但表現(xiàn)不同太早通常是整屏偏移幾個像素太晚可能是隨機花屏或者完全不出圖。調這個問題的技巧先把hs_en延時設成規(guī)范值然后以 4 個采樣時鐘為步進上下各調 3 檔看哪一檔花屏消失。找到最佳值后再在這個值上下各留 2 檔作為余量。如果最佳值范圍很窄說明鏈路信號質量差要查線長、連接器、終端匹配。4.3 FPGA 實現(xiàn) LP RX 的常見坑問題現(xiàn)象可能原因排查方法解決措施LP-11 識別不到IO 電平不匹配量 Dp/Dn 靜態(tài)電壓換 bank 電壓或加電平轉換LP-01/LP-00 順序錯去抖參數(shù)太大抓 LP 狀態(tài)持續(xù)時間減小去抖計數(shù)進入 HS 后無數(shù)據(jù)hs_en 延時不對抓 hs_en 和 HS 同步序列調整 DELAY_TARGET偶爾花屏采樣時鐘抖動大查時鐘源和約束用全局時鐘加時序約束狀態(tài)機跑飛異步信號未同步查同步打拍級數(shù)至少打兩拍加去抖還有一個坑是LP 和 HS 的引腳復用。有些 FPGA 方案為了省引腳LP 和 HS 共用一對差分輸入靠內(nèi)部模擬開關切換。這種方案對開關的切換速度要求很高切慢了會丟 HS 前導碼切快了會引入毛刺。如果非要用復用方案建議 LP 和 HS 分別用獨立的 FPGA 引腳PCB 上從同一對差分線分叉出來雖然多用了引腳但省心得多。4.4 與 RK3588、ST7701S 等具體平臺的配合RK3588 的 MIPI 輸入支持 1080i 信號這個場景下 LP RX 的挑戰(zhàn)在于隔行信號的行同步。1080i 的 MIPI 包里每行數(shù)據(jù)量不固定LP 狀態(tài)出現(xiàn)的頻率和位置跟逐行不一樣。如果 LP RX 狀態(tài)機對 LP 狀態(tài)的持續(xù)時間假設太死可能會在隔行信號里誤判。解決辦法是讓去抖參數(shù)自適應或者用更快的采樣時鐘把去抖窗口做小。ST7701S 是常見的 MIPI 屏驅動 IC它的初始化序列里有很多 LP 模式下的命令傳輸。如果 LP RX 識別不到命令屏就不會出圖。調 ST7701S 的時候我一般先用示波器確認 LP 命令有沒有發(fā)出來再看 FPGA 的 LP RX 狀態(tài)機有沒有正確譯碼。很多時候問題不在屏的初始化代碼而在 LP RX 的采樣和去抖。紫光同創(chuàng) FPGA 驅動 MIPI 的案例里LP RX 通常用普通 IO 加過采樣實現(xiàn)。紫光同創(chuàng)的 IO 延遲和 Xilinx 不太一樣同樣的去抖參數(shù)可能表現(xiàn)不同。建議在紫光同創(chuàng)上先把采樣時鐘降到 100MHz去抖計數(shù)設 2確認能識別 LP 狀態(tài)后再逐步提高采樣率。5. LP RX 調試的獨家經(jīng)驗與參數(shù)速查5.1 采樣率與去抖參數(shù)的搭配采樣率和去抖計數(shù)是一對需要一起調的參數(shù)。采樣率越高每個 LP 狀態(tài)采到的點越多去抖計數(shù)可以適當加大抗噪能力更強。但采樣率太高FPGA 時序壓力大功耗也高。我一般按 LP 狀態(tài)最短持續(xù)時間的 1/10 來選采樣周期。比如 LP 狀態(tài)最短 50ns采樣周期就選 5ns對應 200MHz。去抖計數(shù)取 4濾波窗口 20ns占 LP 狀態(tài)的 40%既能濾掉毛刺又不會漏掉狀態(tài)。如果 LP 狀態(tài)最短只有 30ns200MHz 采樣只能采到 6 個點去抖計數(shù)最多取 3。再大就可能漏狀態(tài)。這時候要么提高采樣率到 400MHz要么降低去抖計數(shù)。我傾向于提高采樣率因為去抖計數(shù)太小抗噪能力差。5.2 用眼圖輔助判斷 LP 信號質量LP 信號雖然是單端大信號但邊沿質量同樣重要。如果 LP 信號的上升沿和下降沿太緩狀態(tài)機在邊沿附近采到的值不確定去抖計數(shù)再大也沒用。用示波器看 LP 信號的眼圖重點看邊沿的單調性和過沖。如果邊沿有回溝或者振鈴說明阻抗不匹配要在發(fā)送端加串阻或者接收端加端接。LP 信號的擺幅也要看。規(guī)范要求 LP 高電平至少 0.88V低電平最多 0.3V。如果實測高電平只有 0.7V可能是驅動能力不夠或者線太長。FPGA 接收端如果 VCCO 是 1.8V0.7V 可能識別不到高電平需要加施密特觸發(fā)或者換 1.2V bank。5.3 常見 MIPI 數(shù)據(jù)率下的 LP 參數(shù)參考MIPI 數(shù)據(jù)率HS 時鐘頻率LP 狀態(tài)最短典型值推薦采樣率推薦去抖計數(shù)推薦 hs_en 延時500Mbps/lane250MHz50ns200MHz4120ns1Gbps/lane500MHz40ns300MHz3100ns1.5Gbps/lane750MHz35ns400MHz390ns2Gbps/lane1GHz30ns500MHz285ns這個表是我根據(jù)實際項目整理的不是規(guī)范原文。不同發(fā)送端和不同線長會有差異建議以實測為準。但大方向是數(shù)據(jù)率越高LP 狀態(tài)越短采樣率要越高去抖計數(shù)要越小hs_en 延時也要越小。5.4 一個容易被忽略的細節(jié)LP 狀態(tài)機的復位LP RX 狀態(tài)機在上電或者鏈路斷開后需要復位到 LP-11 空閑態(tài)。如果復位沒做好狀態(tài)機可能停在某個中間態(tài)導致后續(xù)無法進入 HS。我的做法是用一個超時計數(shù)器如果連續(xù) 1ms 沒有檢測到任何 LP 狀態(tài)跳變就強制復位狀態(tài)機到 LP-11。這個超時值要大于最長的 LP-11 空閑時間但小于鏈路重新初始化的時間。1ms 是個比較安全的經(jīng)驗值。另外復位信號要同步到采樣時鐘域。異步復位直接釋放可能導致狀態(tài)機在釋放瞬間采到亞穩(wěn)態(tài)。用兩級同步器把復位同步到采樣時鐘再釋放。5.5 從 LP RX 延伸到整個 MIPI 鏈路的調試思路LP RX 只是 MIPI 鏈路的第一關。過了這一關后面還有 HS 數(shù)據(jù)對齊、字節(jié)解析、包解碼。但 LP RX 調通了后面的問題就好定位了。我的調試順序是先確保 LP 狀態(tài)識別正確再確保 HS 進入時序正確然后看 HS 數(shù)據(jù)有沒有、對不對最后看包解析和圖像輸出。如果 LP RX 都沒調通別急著去改 HS 數(shù)據(jù)通路或者屏的初始化代碼。先把 LP 狀態(tài)抓出來確認狀態(tài)機工作正常。很多時候LP RX 調好了屏就亮了后面的問題根本不存在。提示調試 LP RX 時建議在 FPGA 里加一個狀態(tài)計數(shù)器記錄 LP-11、LP-01、LP-00 各出現(xiàn)了多少次。如果 LP-11 計數(shù)正常但 LP-01 和 LP-00 計數(shù)為 0說明發(fā)送端沒發(fā)進入 HS 的序列問題在發(fā)送端或者線路。如果 LP-01 有計數(shù)但 LP-00 沒有說明狀態(tài)機在 LP-01 卡住了去抖參數(shù)或者采樣時鐘有問題。我在實際項目里踩過最深的坑是 LP RX 狀態(tài)機在低溫下失效。常溫下一切正常零下 20 度就識別不到 LP-01。后來查出來是 FPGA 的 IO 輸入緩沖在低溫下閾值漂移LP 信號的邊沿又比較緩導致采樣點落在閾值附近。解決辦法是在 PCB 上給 LP 信號加了施密特觸發(fā)緩沖器問題解決。所以如果你的設備要在寬溫下工作LP RX 的輸入級要特別關注。