axi返回转uart

module mdio_rsp_to_uart_tx #(
    parameter [15:0] TC_HEADER = 16'h5418,
    parameter [7:0]  RD_RSP = 8'h01,
    parameter [7:0]  WR_RSP = 8'h02,
    parameter [7:0]  WR_OK     = 8'h55,
    parameter [7:0]  WR_ERR    = 8'hAA
)(
    input  wire        sys_clk,
    input  wire        sys_rst,          // 同步高有效

    input  wire        rd_rsp_valid_i,   // 读返回有效
    input  wire [15:0] rd_addr_i,        // 读地址
    input  wire [15:0] rd_data_i,        // 读数据
    output wire        rd_rsp_ready_o,   // 读返回接收

    input  wire        wr_rsp_valid_i,   // 写返回有效
    input  wire        wr_rsp_err_i,     // 写返回错误
    output wire        wr_rsp_ready_o,   // 写返回接收

    output reg         uart_tx_valid_o,  // 串口发送valid
    input  wire        uart_tx_ready_i,  // 串口发送ready
    output reg  [7:0]  uart_tx_data_o,   // 串口发送数据
    output reg         uart_tx_last_o    // 串口发送最后1字节
);

localparam [3:0] ST_IDLE = 4'b0001,
                 ST_SEND = 4'b0010,
                 ST_DONE = 4'b0100;

localparam [7:0] RD_LEN = 8'd11;
localparam [7:0] WR_LEN = 8'd8;

reg [3:0]  state_r, state_n;             // 状态
reg        is_rd_r, is_rd_n;             // 当前为读响应
reg [15:0] addr_r,  addr_n;              // 地址锁存
reg [15:0] data_r,  data_n;              // 数据锁存
reg        err_r,   err_n;               // 错误锁存
reg [3:0]  byte_cnt_r, byte_cnt_n;       // 发送字节计数
reg [15:0] sum_r, sum_n;                 // 校验和

wire uart_handshake = uart_tx_valid_o & uart_tx_ready_i;
wire idle_accept_rd = (state_r == ST_IDLE) & rd_rsp_valid_i;
wire idle_accept_wr = (state_r == ST_IDLE) & (~rd_rsp_valid_i) & wr_rsp_valid_i;

assign rd_rsp_ready_o = (state_r == ST_IDLE);
assign wr_rsp_ready_o = (state_r == ST_IDLE) & (~rd_rsp_valid_i);

// 时序
always @(posedge sys_clk) begin
    if (sys_rst) begin
        state_r    <= ST_IDLE;
        is_rd_r    <= 1'b0;
        addr_r     <= 16'd0;
        data_r     <= 16'd0;
        err_r      <= 1'b0;
        byte_cnt_r <= 4'd0;
        sum_r      <= 16'd0;
    end else begin
        state_r    <= state_n;
        is_rd_r    <= is_rd_n;
        addr_r     <= addr_n;
        data_r     <= data_n;
        err_r      <= err_n;
        byte_cnt_r <= byte_cnt_n;
        sum_r      <= sum_n;
    end
end

// 状态切换
always @(*) begin
    state_n = state_r;

    case (state_r)
        ST_IDLE: begin
            if (rd_rsp_valid_i | wr_rsp_valid_i)
                state_n = ST_SEND;
        end

        ST_SEND: begin
            if (uart_handshake && uart_tx_last_o)
                state_n = ST_DONE;
        end

        ST_DONE: begin
            state_n = ST_IDLE;
        end

        default: begin
            state_n = ST_IDLE;
        end
    endcase
end

// 数据锁存与计数
always @(*) begin
    is_rd_n    = is_rd_r;
    addr_n     = addr_r;
    data_n     = data_r;
    err_n      = err_r;
    byte_cnt_n = byte_cnt_r;
    sum_n      = sum_r;

    if (state_r == ST_IDLE) begin
        byte_cnt_n = 4'd0;
        sum_n      = 16'd0;

        if (idle_accept_rd) begin
            is_rd_n = 1'b1;
            addr_n  = rd_addr_i;
            data_n  = rd_data_i;
            err_n   = 1'b0;
        end else if (idle_accept_wr) begin
            is_rd_n = 1'b0;
            addr_n  = 16'd0;
            data_n  = 16'd0;
            err_n   = wr_rsp_err_i;
        end
    end else if (state_r == ST_SEND && uart_handshake) begin
        byte_cnt_n = byte_cnt_r + 1'b1;

        if (!uart_tx_last_o && byte_cnt_r >= 4'd2)
            sum_n = sum_r + uart_tx_data_o;
    end
end

// 输出数据
always @(*) begin
    uart_tx_valid_o = (state_r == ST_SEND);
    uart_tx_data_o  = 8'd0;
    uart_tx_last_o  = 1'b0;

    if (is_rd_r) begin
        case (byte_cnt_r)
            4'd0: uart_tx_data_o = TC_HEADER[15:8];
            4'd1: uart_tx_data_o = TC_HEADER[7:0];
            4'd2: uart_tx_data_o = 8'h00;
            4'd3: uart_tx_data_o = 8'h05;
            4'd4: uart_tx_data_o = RD_RSP_TY;
            4'd5: uart_tx_data_o = addr_r[15:8];
            4'd6: uart_tx_data_o = addr_r[7:0];
            4'd7: uart_tx_data_o = data_r[15:8];
            4'd8: uart_tx_data_o = data_r[7:0];
            4'd9: uart_tx_data_o = sum_r[15:8];
            4'd10: begin
                uart_tx_data_o = sum_r[7:0];
                uart_tx_last_o = 1'b1;
            end
            default: uart_tx_data_o = 8'd0;
        endcase
    end else begin
        case (byte_cnt_r)
            4'd0: uart_tx_data_o = TC_HEADER[15:8];
            4'd1: uart_tx_data_o = TC_HEADER[7:0];
            4'd2: uart_tx_data_o = 8'h00;
            4'd3: uart_tx_data_o = 8'h02;
            4'd4: uart_tx_data_o = WR_RSP_TY;
            4'd5: uart_tx_data_o = err_r ? WR_ERR : WR_OK;
            4'd6: uart_tx_data_o = sum_r[15:8];
            4'd7: begin
                uart_tx_data_o = sum_r[7:0];
                uart_tx_last_o = 1'b1;
            end
            default: uart_tx_data_o = 8'd0;
        endcase
    end
end

endmodule
posted @ 2026-06-10 10:12  Oppenic  阅读(7)  评论(0)    收藏  举报