FPGA即插即用Verilog驱动系列——串口数据、命令解析

实现功能:

  1. 指定命令长度和帧头帧尾
  2. 以设置DDS的命令为例
cpp 复制代码
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
//
// 模块名: uart_frame_parser (已升级支持谐波模式)
// 日期:   2025-08-02
// 描述:
//   - **完全兼容原始协议**: 保持对指令类型 0x01, 0x02, 0x03 的支持。
//   - **新增谐波指令解析**:
//     - 类型 0x10-0x15: 分别设置谐波0-5的频率字 (Fword)。
//     - 类型 0x20-0x25: 分别设置谐波0-5的幅度字 (Aword)。
//   - **无冲突输出**: 为原始指令和新增的谐波指令提供独立的有效信号,
//     确保新功能不会干扰现有逻辑。
//
//////////////////////////////////////////////////////////////////////////////////
module uart_frame_parser(
    input           sys_clk,
    input           rst_n,
    input   [7:0]   rx_byte_in,
    input           rx_byte_valid,

    // =================== 原始指令输出 (保持不变) ===================
    output reg          data_valid,         // 原始指令有效脉冲
    output reg  [1:0]   op_mode,            // 来自类型0x03
    output reg  [31:0]  target_fword,       // 来自类型0x01
    output reg  [13:0]  target_aword,       // 来自类型0x02

    // =================== 新增: 谐波指令输出 ===================
    output reg          harmonic_data_valid,    // 谐波指令有效脉冲
    output reg  [7:0]   harmonic_cmd_type,      // 谐波指令类型 (0x10-0x25)
    output reg  [31:0]  harmonic_data_payload   // 谐波指令的4字节数据
);

    // 状态机状态定义
    localparam S_IDLE        = 3'd0; // 等待帧头
    localparam S_RECV_TYPE   = 3'd1; // 接收数据类型
    localparam S_RECV_DATA   = 3'd2; // 接收数据负载
    localparam S_RECV_FOOTER = 3'd3; // 接收帧尾

    // 内部寄存器
    reg [2:0] state;
    reg [2:0] byte_count;
    reg [7:0] data_type;
    reg [7:0] data_buffer [0:3];

    always @(posedge sys_clk or negedge rst_n) begin
        if (!rst_n) begin
            // 复位逻辑
            state                 <= S_IDLE;
            byte_count            <= 0;
            data_valid            <= 0;
            op_mode               <= 2'b0;
            target_fword          <= 0;
            target_aword          <= 0;
            harmonic_data_valid   <= 0;
            harmonic_cmd_type     <= 0;
            harmonic_data_payload <= 0;
        end else begin
            // 每个时钟周期默认将有效信号拉低,使其成为单周期脉冲
            data_valid <= 0;
            harmonic_data_valid <= 0;

            if (rx_byte_valid) begin
                case (state)
                    S_IDLE: begin
                        if (rx_byte_in == 8'hAA) begin
                            state <= S_RECV_TYPE;
                        end
                    end

                    S_RECV_TYPE: begin
                        data_type  <= rx_byte_in;
                        state      <= S_RECV_DATA;
                        byte_count <= 0;
                    end

                    S_RECV_DATA: begin
                        data_buffer[byte_count] <= rx_byte_in;
                        byte_count <= byte_count + 1;
                        if (byte_count == 3) begin
                            state <= S_RECV_FOOTER;
                        end
                    end

                    S_RECV_FOOTER: begin
                        if (rx_byte_in == 8'h55) begin
                            // 帧尾校验成功,根据data_type解析数据
                            case (data_type)
                                // ========== 原始指令处理 ==========
                                8'h01: begin
                                    target_fword <= {data_buffer[3], data_buffer[2], data_buffer[1], data_buffer[0]};
                                    data_valid   <= 1'b1; // 触发原始指令有效信号
                                end
                                8'h02: begin
                                    target_aword <= {data_buffer[1][5:0], data_buffer[0]};
                                    data_valid   <= 1'b1; // 触发原始指令有效信号
                                end
                                8'h03: begin
                                    op_mode    <= data_buffer[0][1:0];
                                    data_valid <= 1'b1; // 触发原始指令有效信号
                                end

                                // ========== 新增: 谐波指令处理 ==========
                                8'h10, 8'h11, 8'h12, 8'h13, 8'h14, 8'h15,
                                8'h20, 8'h21, 8'h22, 8'h23, 8'h24, 8'h25: begin
                                    harmonic_cmd_type     <= data_type;
                                    harmonic_data_payload <= {data_buffer[3], data_buffer[2], data_buffer[1], data_buffer[0]};
                                    harmonic_data_valid   <= 1'b1; // 触发谐波指令有效信号
                                end

                                default: begin
                                    // 未知指令类型,不执行任何操作
                                end
                            endcase
                        end
                        // 无论帧尾是否正确,都返回IDLE状态,准备接收下一帧
                        state <= S_IDLE;
                    end

                    default: state <= S_IDLE;
                endcase
            end
        end
    end
endmodule
相关推荐
智塑未来1 天前
FPGA开发板怎么选?先看资质、案例与研发底盘
fpga开发
minglie12 天前
黑金AX301的SDRAM
fpga开发
hahaha60162 天前
HLS高层次综合设计技巧--高层次综合设计探讨
fpga开发
minglie12 天前
黑金AX301的EEPROM 24LC04
fpga开发
Hello-FPGA2 天前
量子计算滨松c15550-22up单光子相机与PCIe1004采集卡
人工智能·计算机视觉·fpga开发
9527华安2 天前
FPGA实现CameraLink转SFP光口,基于GT Transceivers Wizard Aurora8B10B编解码架构,提供4套工程源码和技术支持
fpga开发·sfp·cameralink·aurora8b10b·transceivers
ALINX技术博客3 天前
【期刊共读】如何应对 FPGA 短缺常态?
嵌入式硬件·fpga开发·fpga
156082072193 天前
短波接收机灵敏度测试
fpga开发
Riwuarua4 天前
从近似0基础开始FPGA开发 -- part.6 逻辑设计与状态机
fpga开发
LCG元4 天前
【实战】Vivado FPGA 从零实现 UART 串口收发:波特率生成、状态机设计与仿真调试
fpga开发