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
相关推荐
FPGA_ADDA12 小时前
基于 AMDXCVU47P HBM2 FPGA 的 2 路 100G 光纤 PCIe 高性能计算加速卡
fpga开发·vu47p·100g光纤pcie·高性能计算加速卡
霖0013 小时前
高级项目——基于FPGA的串行FIR滤波器
人工智能·经验分享·matlab·fpga开发·信息与通信·信号处理
I'm a winner14 小时前
FPGA+护理:跨学科发展的探索(四)
笔记·fpga开发
霖0015 小时前
FPGA的PS基础1
数据结构·人工智能·windows·git·算法·fpga开发
燎原星火*17 小时前
FPGA信号处理实战
fpga开发
ShiMetaPi2 天前
紫光同创Logos2+RK3568JHF开发板:国产异构计算平台的破局者
嵌入式硬件·fpga开发·鸿蒙系统·树莓派
范纹杉想快点毕业2 天前
C 语言主控开发与显控开发能力体系及技术栈详解,STM32、QT、嵌入式、边缘系统显示
stm32·单片机·tcp/ip·microsoft·fpga开发·51单片机·wpf
秋风战士2 天前
通信算法之306:精通FPGA-笔记核心
笔记·fpga开发
微小冷2 天前
OV5640 相机开发流程
fpga开发·verilog·ov5640·双目相机·相机开发