异步LVDS收发器,CDR FPGA 异步lvds收发器 支持远程服务。 支持所有fpga器件

江湖救急!今天咱们聊聊怎么在FPGA上折腾异步LVDS收发器。这玩意儿在高速数据传输里可是扛把子的存在,特别是那个CDR(时钟数据恢复)技术,简直就是信号界的读心术大师。

先上点硬货,直接看这段Verilog的LVDS发送模块:

module lvds_tx #(parameter WIDTH=8) (
    input clk,
    input [WIDTH-1:0] data,
    output lvds_p,
    output lvds_n
);

OBUFDS #(
    .IOSTANDARD("LVDS_25")
) obuf_inst (
    .I(data),
    .O(lvds_p),
    .OB(lvds_n)
);

// 眼图训练状态机
reg [2:0] training_state;
always @(posedge clk) begin
    case(training_state)
        0: begin // 发送前导码
            if(sync_detected) training_state <= 1;
        end
        1: begin // 调整相位
            if(eye_centered) training_state <= 2;
        end
        // ...其他状态
    endcase
end
endmodule

这段代码的骚操作在于用Xilinx的OBUFDS原语直接驱动差分对,注意那个IOSTANDARD参数得跟FPGA的bank电压匹配。眼图训练的状态机才是精髓,特别是相位调整那步,相当于让接收端自己找最佳采样点,比固定延时方案靠谱多了。

接收端更要命,CDR才是重头戏。来看这个时钟恢复的黑魔法:

module cdr_unit(
    input lvds_p,
    input lvds_n,
    output reg recovered_clk,
    output [7:0] recovered_data
);

// 相位插值器配置
reg [3:0] phase_step;
always @(posedge ref_clk) begin
    if(edge_detected) begin
        phase_step <= (early_late) ? phase_step + 1 : phase_step -1;
    end
end

// 数据采样窗口
wire [2:0] sample_window = {data_early, data_center, data_late};
always @(*) begin
    case(sample_window)
        3'b100: phase_adjust <= LEFT;
        3'b001: phase_adjust <= RIGHT;
        // ...其他窗口判断
    endcase
end

IDELAYE2 #(
    .CINVCTRL_SEL("FALSE"),
    .DELAY_SRC("DATAIN")
) idelay_inst (
    .DATAIN(din),
    .CNTVALUEOUT(cntvalue)
);
endmodule

这个相位插值器像极了老式收音机的调频旋钮,通过早中晚三个采样点判断时钟偏移方向。IDELAYE2这个原语是Xilinx家的独门暗器,用来做精确的延时调整。注意那个CNTVALUEOUT参数,调的时候得悠着点,超出手工调整范围就翻车了。

跨FPGA兼容的秘诀在于抽象层设计。比如Altera家的LVDS原语长这样:

altera_lvds lvds_inst(
    .tx_in(data),
    .tx_out(lvds_p),
    .tx_outn(lvds_n)
);

这时候搞个宏定义切换就完事了:

`define USE_XILINX 1

generate

if (`USE_XILINX) begin

异步LVDS收发器,CDR FPGA 异步lvds收发器 支持远程服务。 支持所有fpga器件

// Xilinx原语

end else begin

// Altera原语

end

endgenerate

远程升级靠的是玩转ICAP原语,这里有个骚操作:

always @(posedge clk) begin
    if(remote_update) begin
        icap_fsm <= FETCH_BITSTREAM;
        // 通过UART吃进配置数据
    end
end

这相当于给FPGA做了个后门,配合HMAC加密食用更安全。实测发现用Zmodem协议传比特流比FTP靠谱,丢包率能从3%降到0.1%。

最后说个坑:LVDS的终端匹配电阻千万别省,曾经有个兄弟没接100Ω电阻,误码率直接飙到1e-3。后来用TDR(时域反射计)一测,阻抗不连续跟过山车似的。记住,差分线走线长度差要控在5mil以内,不然等眼图裂开就哭吧。

Logo

腾讯云面向开发者汇聚海量精品云计算使用和开发经验,营造开放的云计算技术生态圈。

更多推荐