2. JESD204C 链路初始化状态机建模

任务目标

用可综合的 Verilog 实现一个 JESD204C 链路初始化状态机,覆盖四个阶段:复位(RESET)、同步请求(SYNC_REQ)、参数交换(PARAM_EXCH)、链路建立(LINK_UP)。状态机接收外部触发与握手信号,输出当前状态与各阶段完成标志,便于在 FPGA 中驱动 204C 链路控制逻辑。

状态与信号约定

  • rst_n:异步低有效复位,回到 RESET。
  • start:从 RESET 进入 SYNC_REQ 的启动脉冲。
  • sync_ack:SYNC_REQ 阶段收到对端同步应答后置 1,进入 PARAM_EXCH。
  • param_done:参数交换完成(如配置字已写入/读回校验通过),进入 LINK_UP。
  • link_fail:任一阶段检测到错误,回到 RESET。
  • 输出 state(3 位编码)、sync_req(同步请求有效)、link_up(链路建立完成)。
RESET SYNC_REQ sync_req=1 PARAM_EXCH 参数交换 LINK_UP link_up=1 start sync_ack param_done link_fail

完整实现(link_init_fsm.v)

module link_init_fsm (
    input  wire clk,
    input  wire rst_n,
    input  wire start,
    input  wire sync_ack,
    input  wire param_done,
    input  wire link_fail,
    output reg  [2:0] state,
    output reg  sync_req,
    output reg  link_up
);

    localparam S_RESET      = 3'd0,
               S_SYNC_REQ   = 3'd1,
               S_PARAM_EXCH = 3'd2,
               S_LINK_UP    = 3'd3;

    always @(posedge clk or negedge rst_n) begin
        if (!rst_n) begin
            state    <= S_RESET;
            sync_req <= 1'b0;
            link_up  <= 1'b0;
        end else if (link_fail) begin
            state    <= S_RESET;
            sync_req <= 1'b0;
            link_up  <= 1'b0;
        end else begin
            case (state)
                S_RESET: begin
                    sync_req <= 1'b0;
                    link_up  <= 1'b0;
                    if (start) state <= S_SYNC_REQ;
                end
                S_SYNC_REQ: begin
                    sync_req <= 1'b1;
                    if (sync_ack) begin
                        sync_req <= 1'b0;
                        state    <= S_PARAM_EXCH;
                    end
                end
                S_PARAM_EXCH: begin
                    if (param_done) state <= S_LINK_UP;
                end
                S_LINK_UP: begin
                    link_up <= 1'b1;
                end
                default: state <= S_RESET;
            endcase
        end
    end

endmodule

最小验证(link_init_fsm_tb.v)

module link_init_fsm_tb;
    reg clk = 0, rst_n = 0, start = 0, sync_ack = 0, param_done = 0, link_fail = 0;
    wire [2:0] state;
    wire sync_req, link_up;

    link_init_fsm dut (.clk(clk), .rst_n(rst_n), .start(start),
        .sync_ack(sync_ack), .param_done(param_done), .link_fail(link_fail),
        .state(state), .sync_req(sync_req), .link_up(link_up));

    always #5 clk = ~clk;

    initial begin
        #12 rst_n = 1;          // 复位释放,应处于 RESET(0)
        #10 start = 1; #10 start = 0;   // 进入 SYNC_REQ(1),sync_req=1
        #20 sync_ack = 1; #10 sync_ack = 0; // 进入 PARAM_EXCH(2)
        #20 param_done = 1; #10 param_done = 0; // 进入 LINK_UP(3),link_up=1
        #20 link_fail = 1; #10 link_fail = 0;   // 回到 RESET(0)
        #20 $finish;
    end

    initial $monitor("t=%0t state=%0d sync_req=%b link_up=%b", $time, state, sync_req, link_up);
endmodule

运行与验证

iverilog -o fsm_tb link_init_fsm.v link_init_fsm_tb.v
vvp fsm_tb

观察 $monitor 输出:复位释放后 state=0;start 后 state=1 且 sync_req=1;sync_ack 后 state=2;param_done 后 state=3 且 link_up=1;link_fail 后回到 state=0。若状态序列与标志位完全一致,则状态机建模通过。