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
相关推荐
156082072191 天前
基于7VX690T FPGA实现万兆TCP/IP资源和性能测试
网络协议·tcp/ip·fpga开发
nuoxin1141 天前
GSV1011-富利威-HDMI芯片选型
arm开发·驱动开发·fpga开发·ffmpeg·射频工程
ChipCamp1 天前
FPGA开发入门----1. Mux的三种写法,RTL的认知大提升!
fpga开发·时序逻辑·组合逻辑
XINVRY-FPGA2 天前
XCVP1802-2MSILSVC4072 AMD Xilinx Versal Premium Adaptive SoC FPGA
人工智能·嵌入式硬件·fpga开发·数据挖掘·云计算·硬件工程·fpga
9527华安3 天前
国产安路FPGA开发设计培训课程,提供开发板+工程源码+视频教程+技术支持
fpga开发·fpga·安路·视频教程·培训·安路fpga
UVM_ERROR3 天前
硬件设计实战:解决Valid单拍采样失效问题(附非阻塞赋值与时序对齐核心要点)
驱动开发·fpga开发·github·芯片
brave and determined3 天前
可编程逻辑器件学习(day36):从沙粒到智能核心:芯片设计、制造与封装的万字全景解析
fpga开发·制造·verilog·fpga·芯片设计·硬件设计·芯片制造
步达硬件4 天前
【FPGA】FPGA开发流程
fpga开发
我爱C编程4 天前
【仿真测试】基于FPGA的完整16QAM通信链路实现,含频偏锁定,帧同步,定时点,Viterbi译码,信道,误码统计
fpga开发·16qam·帧同步·卷积编码·viterbi译码·维特比译码·频偏锁定
s09071365 天前
ZYNQ DMA to UDP 数据传输系统设计文档
网络协议·fpga开发·udp