使用状态机解析收到的数据帧,利用状态机判断帧头,16'h5555,16'h5555,16'h5500,16'hAA12,提取特定的参数上报或者进行其他操作。
代码:
`timescale 1ns / 1ps
//////////////////////////////////////////////////////////////////////////////////
// Company:
// Engineer:
//
// Create Date: 2024/10/23 17:24:46
// Design Name:
// Module Name: parameter_extraction
// Project Name:
// Target Devices:
// Tool Versions:
// Description:
//
// Dependencies:
//
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
//
//////////////////////////////////////////////////////////////////////////////////
module parameter_extraction (
input wire clk, // 时钟信号
input wire rst_n, // 复位信号,低电平有效
input wire [15:0] data_in, // 输入数据
input wire data_in_ena, // 输入数据使能
output reg [7:0] data_out, // 输出数据(低8位加0x03)
output reg data_out_ena // 输出使能信号
);
// 定义 Gray code 状态机状态
localparam IDLE = 3'b000, // Gray code: 000
HEAD_1 = 3'b001, // Gray code: 001
HEAD_2 = 3'b011, // Gray code: 011
HEAD_3 = 3'b010, // Gray code: 010
HEAD_4 = 3'b110, // Gray code: 110
DATA = 3'b111; // Gray code: 111
reg [2:0] state, next_state;
// 计数器,统计当前的word数
reg [9:0] word_count;
// 状态机
always @(posedge clk or negedge rst_n) begin
if (!rst_n) begin
state <= IDLE;
word_count <= 0;
data_out <= 0;
data_out_ena <= 0;
end else begin
state <= next_state;
if (state == DATA && word_count == 50) begin
data_out <= data_in[7:0]+8'h03; // 提取低8位加0x03
data_out_ena <= 1'b1;
end else begin
data_out_ena <= 1'b0;
end
end
end
// 状态转移逻辑
always @(*) begin
next_state = state;
case (state)
IDLE: begin
if (data_in_ena && data_in == 16'h5555) begin
next_state = HEAD_1;
end
end
HEAD_1: begin
if (data_in_ena && data_in == 16'h5555) begin
next_state = HEAD_2;
end else begin
next_state = IDLE;
end
end
HEAD_2: begin
if (data_in_ena && data_in == 16'h5500) begin
next_state = HEAD_3;
end else begin
next_state = IDLE;
end
end
HEAD_3: begin
if (data_in_ena && data_in == 16'hAA34) begin
next_state = HEAD_4;
end else begin
next_state = IDLE;
end
end
HEAD_4: begin
if (data_in_ena) begin
next_state = DATA;
end else begin
next_state = IDLE;
end
end
DATA: begin
if (data_in_ena) begin
if (word_count == 50) begin
next_state = IDLE;
end else begin
word_count = word_count + 1;
next_state = DATA;
end
end else begin
word_count<=0;
word_count<=0;
next_state = DATA;
end
end
endcase
end
endmodule
测试代码:
`timescale 1ns / 1ps
module rom_tb;
reg clk;
reg rst_n;
wire [15:0] q;
initial begin
clk = 0;
rst_n = 0;
#40;
rst_n = 1;
#10000;
$stop;
end
always #10 clk = ~clk;
rom rom_inst(
.clk (clk ),
.rst_n (rst_n ),
.q (q )
);
endmodule