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
相关推荐
ThreeYear_s6 小时前
基于FPGA实现数字QAM调制系统
fpga开发
小飞侠学FPGA8 小时前
VIVADO的IP核 DDS快速使用——生成正弦波,线性调频波
fpga开发·vivado·dds
博览鸿蒙13 小时前
成为一个年薪30W+的FPGA工程师是一种什么体验?
fpga开发
喜欢丸子头1 天前
xilinx vivado fir ip(FIR Compiler)核 ADC高采样率,FPGA工作时钟为采样率的1/4,同一个时钟周期来四个数据。
fpga开发
璞致电子1 天前
【PZ-AU15P】璞致fpga开发板 Aritx UltraScalePlus PZ-AU15P 核心板与开发板用户手册
嵌入式硬件·fpga开发·fpga·fpga开发板·xilinx开发板
红糖果仁沙琪玛1 天前
fpga iic协议
fpga开发
嵌入式-老费1 天前
Zynq开发实践(FPGA之pwm输出)
fpga开发
hexiaoyan8272 天前
光纤加速的板卡设计原理图:基于6U VPX XCVU9P+XCZU7EV的双FMC信号处理板卡
嵌入式硬件·fpga开发·光纤加速板卡·国产化板卡·xcvu9p板卡·xcvu9p
XiaoChaoZhiNeng2 天前
Altera Quartus17.1 Modelsim 库编译与仿真
fpga开发
燎原星火*3 天前
FPGA复位
fpga开发