篇12:miniLVDS与FPGA实现------屏幕内部的信号暗线
前一篇我们详细讲解了标准LVDS接口------它是主板到屏幕之间的高速差分总线。但当你再往屏幕内部走一步,会发现一个更有趣的事实: 屏幕内部的时序控制器(TCON)到源极驱动IC之间,用的并不是标准LVDS,而是一种更紧凑、更省电的变种------miniLVDS 。
这一篇,我们揭开miniLVDS的神秘面纱。你会学到:为什么需要它?它和标准LVDS有什么异同?串行化因子(7:1/8:1/10:1)如何选择?最重要的是, 如何用FPGA的ISERDESE2原语接收miniLVDS信号 ,并完成bitslip字对齐和时钟恢复。这是FPGA驱动LCD的"终极内功",也是本系列最核心的工程深度内容。
一、为什么需要miniLVDS?
1.1 从TCON到源极驱动:最后几厘米的挑战
在上一篇的LVDS方案中,信号从FPGA(或主板)经过FPC排线到达屏幕的逻辑板。逻辑板上有一颗 时序控制器(TCON) ,它解析LVDS信号,恢复出RGB数据和行/场时序,然后需要将这些数据 再次分发给分布在面板边缘的多个源极驱动IC (Source Driver IC)。
这部分走线是在玻璃基板 或柔性薄膜(COF) 上实现的,面临严苛限制:
- 走线密度极高 :一块4K面板需要3840×3=11520条数据线,但源极IC只有几百个输出引脚,必须在玻璃上扇出。
- 功耗敏感 :玻璃上的金属线电阻较大,高摆幅信号会显著发热。
- EMI要求 :面板靠近用户,电磁辐射必须极低。
标准LVDS(摆幅350mV,共模1.2V)仍然偏大 ,而且线数偏多。因此业界发展出 miniLVDS :更低的摆幅(200~300mV)、更小的共模电压(约0.9V)、更紧凑的时序,以及更高的串行化因子(10:1、14:1),以进一步减少玻璃上的走线数量。
1.2 miniLVDS vs 标准LVDS:异同点
| 特性 | 标准LVDS | miniLVDS |
|---|---|---|
| 应用场景 | 主板 → 屏逻辑板(排线) | 屏内TCON → 源极IC(玻璃或COF) |
| 差分摆幅 | 250~450mV(典型350mV) | 150~300mV(典型200mV) |
| 共模电压 | 1.2V | 0.9V 或 1.0V |
| 终端电阻 | 100Ω(外部) | 通常集成在源极IC内部(50~100Ω) |
| 串行化因子 | 7:1(主流) | 7:1、8:1、10:1、14:1(根据分辨率选择) |
| 时钟通道 | 单独的差分时钟对 | 可有独立时钟,也可嵌入数据(CDR) |
| 数据速率 | 最高约1Gbps | 最高可达1.5Gbps以上 |
核心区别 :miniLVDS不是标准规范,而是一类技术的总称。不同面板厂商(如奇美、友达、LG)可能有自己的实现细节,但电气层基本兼容------都可以用FPGA的差分IO接收。
二、串行化因子:带宽与线数的权衡
miniLVDS的一个重要维度是 串行化因子 (Serialization Factor,简称SF),定义为:
SF=每条数据线上串行传输的比特数每个像素时钟周期SF =每个像素时钟周期每条数据线上串行传输的比特数****对于TCON → 源极IC,需要传输的数据包括:
- 每个像素的RGB数据(6/8/10 bit per color)
- 控制信号(如极性POL、数据锁存LOAD等)
假设面板分辨率为1920×1080,刷新率60Hz,RGB888(24位),一行有效像素1920,总像素(含消隐)约2200,则每行有效数据量 = 1920 × 24 = 46080 bits。每行时间约15.4μs,所以所需数据速率 = 46080 / 15.4μs ≈ 2.99 Gbps。
如果使用SF=7:1,每条数据线速率 = 像素时钟(PCLK) × 7。PCLK ≈ 总像素×刷新率 = 2200×1080×60 ≈ 142.6 MHz,则串行速率 ≈ 1 GHz。用4对数据线,总带宽 = 4×1Gbps = 4Gbps,满足2.99Gbps要求。
如果希望减少数据线对数(比如玻璃上走线困难),可以使用更高的SF:10:1时,相同PCLK下每条线速率更高,但线对数可以减少。例如SF=10:1,4对线总带宽 = 4 × (PCLK×10) = 40×PCLK,比SF=7:1的28×PCLK高出43%,但要求IO速率也相应提高(1.4GHz vs 1GHz)。
常见选择 :
- SF=7:1 :最普遍,兼容性好,FPGA容易实现(OSERDES/ISERDES支持7位)。
- SF=8:1 :少部分日系屏使用。
- SF=10:1 :高端4K屏、高刷新率屏(如120Hz),需要更高速的SerDes。
- SF=14:1 :超高清(8K)或极窄边框设计。
工程提示 :拿到屏的规格书,必须确认TCON输出的miniLVDS的串行化因子和通道数。然后据此设计FPGA接收侧的配置。
三、FPGA接收miniLVDS:ISERDESE2与bitslip
在调试或开发TCON替代方案时,我们可能需要用FPGA直接接收来自源极IC的miniLVDS信号(比如抓取时序分析),或者模拟TCON输出miniLVDS。本篇重点讲解 接收端 ,因为接收比发送更复杂------需要处理时钟恢复和字对齐。
3.1 整体架构
text
miniLVDS差分对(数据 + 时钟)
│
▼
IBUFDS(差分转单端)
│
▼
ISERDESE2(串转并,并行宽度=SF)
│
▼
Bitslip调整(对齐字边界)
│
▼
并行数据(RGB + 控制信号)
3.2 差分输入:IBUFDS
verilog
IBUFDS #(.DIFF_TERM("TRUE"), .IOSTANDARD("LVDS_25")) ibufds_data0 (
.I(minilvds_data0_p),
.IB(minilvds_data0_n),
.O(data0_in)
);
注意:miniLVDS的电平标准通常也是LVDS类,FPGA的LVDS_25接收器可以正常工作(共模电压略有偏差但仍在范围内)。如果共模电压低于0.9V,可尝试LVDS_25或自定义DIFF_TERM。
3.3 核心:ISERDESE2配置
ISERDESE2是Xilinx 7系列中的串并转换器,支持DDR模式,最大数据宽度8位(通过两个级联可扩展至10或14位)。
对于 SF=7 ,我们可以使用单个ISERDESE2配置为 DATA_WIDTH=7 ,但ISERDESE2原生支持的最大宽度是8(DDR模式下实际是4位?需要澄清)。实际上,ISERDESE2在DDR模式下,每个CLK周期采样2个bit,因此要得到7位并行数据,需要设置DATA_WIDTH=7,并让内部逻辑处理奇偶位。
更简单的方法 :使用两个ISERDESE2级联(Master+Slave)实现7:1解串。或者,如果SF=8,直接用单个ISERDESE2配置为8位(但需注意DDR与SDR的区别)。
以下是SF=7,使用Master+Slave的配置代码(Xilinx推荐方式):
verilog
ISERDESE2 #(
.DATA_RATE("DDR"), // 双沿采样
.DATA_WIDTH(7), // 7位并行输出
.INTERFACE_TYPE("NETWORKING"),
.SERDES_MODE("MASTER"),
.NUM_CE(1)
) iserdes_master (
.CLK(serial_clk), // 串行时钟(与数据同步,由外部提供)
.CLKB(~serial_clk),
.CLKDIV(pclk), // 分频时钟(串行时钟/SF)
.D(data_in),
.DDLY(1'b0),
.OCLK(1'b0),
.SHIFTIN1(slave_shiftout1),
.SHIFTIN2(slave_shiftout2),
.BITSLIP(bitslip), // bitslip脉冲
.CE1(1'b1),
.CE2(1'b1),
.RST(rst),
.Q1(q1), .Q2(q2), .Q3(q3), .Q4(q4),
.Q5(q5), .Q6(q6), .Q7(q7), .Q8(q8) // 只有Q1~Q7有效
);
ISERDESE2 #(
.DATA_RATE("DDR"),
.DATA_WIDTH(7),
.INTERFACE_TYPE("NETWORKING"),
.SERDES_MODE("SLAVE"),
.NUM_CE(1)
) iserdes_slave (
.CLK(serial_clk),
.CLKB(~serial_clk),
.CLKDIV(pclk),
.D(1'b0), // 从机不接输入
.SHIFTOUT1(slave_shiftout1),
.SHIFTOUT2(slave_shiftout2),
.BITSLIP(bitslip),
.CE1(1'b1),
.CE2(1'b1),
.RST(rst),
.Q1(), .Q2(), .Q3(), .Q4(),
.Q5(), .Q6(), .Q7(), .Q8()
);
3.4 时钟恢复:从数据还是从独立时钟?
miniLVDS通常 提供独立的差分时钟对 (与标准LVDS类似),所以我们不需要CDR,直接使用这个时钟作为ISERDESE2的CLK输入即可。时钟频率 = 串行比特率 = PCLK × SF。
注意 :这个时钟与数据是源同步的,相位关系由TCON保证。FPGA只需将其直接接入全局时钟网络(BUFG)或区域时钟,作为高速采样时钟。
3.5 Bitslip:找到字边界
由于串行数据流没有起始位,ISERDESE2输出的7位并行数据的边界是 随机的 ------可能是正确的字节对齐,也可能是偏移1~6位。我们需要动态调整,直到检测到特定的 同步字 (例如TCON输出的固定训练序列或VSYNC/HSYNC的特定模式)。
Bitslip操作 :每给出一个bitslip脉冲,ISERDESE2会将并行输出的比特位 循环左移1位 (相当于延迟一个串行bit)。重复bitslip直到接收到的同步字与预期匹配。
实现步骤 :
- 等待串行时钟稳定。
- 连续接收并行数据。
- 检测同步模式(例如:连续收到3个0x55或0xAA,或者检测到HSYNC/VSYNC的特定边沿)。
- 如果模式不匹配,拉高bitslip一个时钟周期(CLKDIV域)。
- 重复直到对齐。
- 锁定对齐状态,停止bitslip。
Verilog实现示例 (状态机):
verilog
localparam IDLE = 0, ALIGN = 1, LOCK = 2;
reg [1:0] state;
reg [7:0] align_cnt;
reg bitslip_reg;
// 假设同步字为并行数据[6:0] = 7'b1010101(示例)
wire sync_detected = (rx_data == 7'b1010101);
always @(posedge pclk or posedge rst) begin
if (rst) begin
state <= IDLE;
bitslip_reg <= 0;
end else case (state)
IDLE: begin
align_cnt <= 0;
if (sync_detected) state <= LOCK;
else state <= ALIGN;
end
ALIGN: begin
if (align_cnt < 32) begin // 最多尝试32次
bitslip_reg <= 1; // 产生一个脉冲
align_cnt <= align_cnt + 1;
state <= ALIGN; // 等待下一个时钟再次检测
end else begin
// 对齐失败,报错
state <= IDLE;
end
end
LOCK: begin
bitslip_reg <= 0;
// 定期检查同步字,如果丢失则重新对齐
if (!sync_detected) state <= ALIGN;
end
endcase
end
// bitslip信号需要展宽到至少一个CLKDIV周期
reg bitslip_q;
always @(posedge pclk) bitslip_q <= bitslip_reg;
wire bitslip_pulse = bitslip_reg & ~bitslip_q;
注意 :bitslip操作会在几个时钟周期后生效,且会暂时打乱输出数据。因此需要在bitslip之后等待稳定再检测。
四、完整miniLVDS接收器设计(Vivado工程结构)
4.1 顶层模块
verilog
module minilvds_rx (
input wire clk_50m, // 板载参考时钟
input wire rst_n,
// miniLVDS 差分输入
input wire clk_p, clk_n, // 差分时钟
input wire [3:0] data_p, data_n,// 4对差分数据
// 输出并行数据
output wire pclk, // 恢复出的像素时钟
output wire [23:0] rgb,
output wire hs, vs, de,
output wire locked // 字对齐锁定
);
// PLL:将差分时钟转换成单端时钟,并产生所需的时钟域
wire serial_clk, serial_clk_bufg;
IBUFDS #(.DIFF_TERM("TRUE")) ibufds_clk (
.I(clk_p), .IB(clk_n), .O(serial_clk_in)
);
BUFG bufg_clk (.I(serial_clk_in), .O(serial_clk));
// 产生分频时钟 pclk = serial_clk / SF
// 使用PLL或MMCM
wire pll_locked;
clk_divider u_pll (
.clk_in(serial_clk),
.clk_out(pclk), // 频率 = serial_clk / 7
.locked(pll_locked)
);
// 每个数据通道一个ISERDES + bitslip逻辑
wire [6:0] ch0_data, ch1_data, ch2_data, ch3_data;
wire [3:0] bitslip_en;
wire [3:0] ch_locked;
genvar i;
generate
for (i=0; i<4; i=i+1) begin : rx_ch
minilvds_channel u_ch (
.clk_serial(serial_clk),
.clk_div(pclk),
.rst(~pll_locked),
.data_in(data_in[i]), // 来自IBUFDS
.bitslip_en(bitslip_en[i]),
.parallel_data({ch_data[i]}),
.locked(ch_locked[i])
);
end
endgenerate
// 将4个通道的7位数据组合成RGB + 同步信号(依据TCON的映射表)
// 映射规则随屏而异,此处仅示例
assign {vs, hs, de, ...} = {ch3_data[5:3], ...};
assign rgb = {ch0_data[6:0], ch1_data[6:0], ch2_data[6:0]}; // 简化
// 只有当所有通道都锁定时,整体locked有效
assign locked = &ch_locked;
endmodule
4.2 单个通道的子模块
verilog
module minilvds_channel (
input wire clk_serial,
input wire clk_div,
input wire rst,
input wire data_in,
input wire bitslip_en,
output wire [6:0] parallel_data,
output wire locked
);
wire [7:0] q;
wire bitslip_pulse;
// ISERDESE2 master+slave 配置(代码如前所述)
// 输出 q1~q7 作为 parallel_data
// 同步字检测和bitslip控制
reg [6:0] align_pattern = 7'b1010101; // 根据规格书设置
wire pattern_match = (parallel_data == align_pattern);
// 简单状态机,同3.5节
// ...
endmodule
五、硬件陷阱与工程经验
5.1 共模电压漂移
miniLVDS的共模电压可能低至0.9V,而FPGA的LVDS接收器通常设计为1.2V共模。如果差异较大,可能造成接收器失调。解决方案:
- 使用AC耦合电容(100nF串接在差分线上),再在FPGA端重建共模(通过电阻分压到0.9V)。但AC耦合会丢失直流平衡信息,适用于数据有DC平衡编码(如8b/10b)的场景。miniLVDS通常不带编码,因此AC耦合不可行。
- 更可靠:选用支持更宽共模范围的FPGA Bank(如Xilinx HP Bank),或者使用外部LVDS接收器(如SN65LVDS32)做电平转换。
5.2 终端电阻
miniLVDS的终端电阻通常集成在源极IC内部,但在FPGA接收端,我们 不应该再加100Ω终端 ,否则会并联导致电阻减半,摆幅异常。如果FPGA作为接收器,应设置IBUFDS的DIFF_TERM = "FALSE",并依赖外部源极IC的内部端接。
5.3 信号完整性
miniLVDS速率可高达1.5Gbps,对PCB走线要求极高:
- 差分对间距至少为线宽的3倍(减少串扰)
- 长度匹配:对内<1mm,对间<5mm
- 避免在差分线下有分割的参考平面
- 使用0.1uF电容对共模噪声滤波(跨接在差分对上,但不影响差模信号)
5.4 调试方法
- 示波器 :使用差分探头测量眼图。注意探头电容要小(<1pF)。
- 码型生成 :如果TCON不工作,可以用FPGA自己产生miniLVDS发送信号(使用OSERDES),自收自发调试。
- 低速测试 :降低PCLK频率(如降至10MHz),此时串行时钟降低,更容易捕获波形。
六、实战:抓取液晶面板内部的miniLVDS信号
假设你要调试一块某品牌液晶屏,它的TCON输出miniLVDS到源极IC。你可以用FPGA开发板搭一个监听器:
- 在TCON和源极IC之间的FPC排线上,用精细焊接引出miniLVDS测试点(非常困难,建议用专用夹具)。
- 将信号连接到FPGA的LVDS输入引脚。
- 配置ISERDES和bitslip逻辑。
- 观察输出并行数据,看是否能解析出RGB和同步信号。
注意事项 :
- 监听时不能影响原电路,所以FPGA输入阻抗必须很高(高阻模式)。
- 使用IBUFDS时,设置DIFF_TERM = "FALSE",并确保终端电阻已经在源极IC内部。
- 由于miniLVDS电压低,长引线会引入噪声,尽量缩短引线长度。
七、☕ 工程师私房话
面试题:miniLVDS的bitslip操作为什么有时需要多个时钟周期才能稳定?
答案 :bitslip通过调整ISERDES内部的采样相位,实际是串行延迟链的抽头选择。切换抽头时,可能产生毛刺或中间态,因此需要等待几个串行时钟周期让新的对齐稳定。通常设计会在bitslip后等待至少2个并行时钟周期再检测同步字。
设计经验:如果TCON不提供独立时钟怎么办?
有些miniLVDS实现使用 嵌入式时钟 (CDR),数据流中不包含独立时钟对。这时FPGA端需要用高速收发器(GT)或外部CDR芯片恢复时钟,难度大幅增加。这种情况极少见于标准LCD模组,更多出现在MIPI DSI中。
冷知识:miniLVDS的命名来源
"mini"主要指摆幅小 和 线数少 ,并非物理尺寸。最早由TI和NS(美国国家半导体)推广,后来成为面板厂事实标准。与之竞争的技术还有 RSDS (Reduced Swing Differential Signaling),摆幅更低(150mV),但速率不如miniLVDS,现已淘汰。