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
相关推荐
ARM+FPGA+AI工业主板定制专家3 小时前
基于ZYNQ的目标检测算法硬件加速器优化设计
人工智能·目标检测·计算机视觉·fpga开发·自动驾驶
cycf3 小时前
时钟特性约束(四)
fpga开发
江苏学蠡信息科技有限公司12 小时前
STM32中硬件I2C的时钟占空比
stm32·单片机·fpga开发
OliverH-yishuihan13 小时前
FPGA 入门 3 个月学习计划表
学习·fpga开发
FPGA狂飙16 小时前
传统FPGA开发流程的9大步骤是哪些?
fpga开发·verilog·fpga·vivado·xilinx
我爱C编程16 小时前
【硬件片内测试】基于FPGA的完整DQPSK链路测试,含频偏锁定,帧同步,定时点,Viterbi译码,信道,误码统计
fpga开发·帧同步·viterbi译码·dqpsk·频偏锁定·定时点
szxinmai主板定制专家18 小时前
【NI测试方案】基于ARM+FPGA的整车仿真与电池标定
arm开发·人工智能·yolo·fpga开发
爱吃汽的小橘1 天前
基于ads1256的ADC控制实现
fpga开发
易享电子2 天前
基于单片机车窗环境监测控制系统Proteus仿真(含全部资料)
单片机·嵌入式硬件·fpga开发·51单片机·proteus
cycf2 天前
系统同步接口输入延迟(五)
fpga开发