FPGA系统性学习笔记连载_Day18【线性系列机】之【Hello 通讯协议特定帧头检测实验】
本系列为FPGA系统性学习学员学习笔记整理分享,如有学习或者购买开发板意向,可加交流群联系群主。
连载《叁芯智能fpga设计与研发-第18天》 【线性系列机】之【Hello 通讯协议特定帧头检测实验】
原创作者:紫枫术河 转载请联系群主授权,否则追究责任
本实验实现,检测ascii的通信协议中,特定的帧头,检测到特定帧头“Hello”,输出该帧头信息。
一、状态机
检测 Hello 字符串的状态机
各个状态之间的转换条件如下图
二、verilog代码实现
代码语言:javascript复制module FSM_char_seqence_check(
input clk,
input rst_n,
input [7:0] char,
output reg [39:0] str_out
);
parameter S0 = 3'd0;
parameter S1 = 3'd1;
parameter S2 = 3'd2;
parameter S3 = 3'd3;
parameter S4 = 3'd4;
parameter S5 = 3'd5;
reg [2:0] status;
always@(posedge clk,negedge rst_n)begin
if(!rst_n)
begin
status <= 0;
str_out = {8'd0,8'd0,8'd0,8'd0,8'd0};
end
else
begin
case(status)
S0:
begin
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
if(char == 72) //H
status <= S1;
else
status <= S0;
end
S1:
begin
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
if(char == 72) //H
status <= S1;
else if(char == 101) //e
status <= S2;
else
status <= S0;
end
S2:
begin
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
if(char == 72) //H
status <= S1;
else if(char == 108) //l
status <= S3;
else
status <= S0;
end
S3:
begin
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
if(char == 72) //H
status <= S1;
else if(char == 108) //l
status <= S4;
else
status <= S0;
end
S4:
begin
if(char == 72) //H
begin
status <= S1;
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
end
else if(char == 111) //o
begin
status <= S5;
//Hello
str_out <= {8'd72,8'd101,8'd108,8'd108,8'd111};
end
else
begin
status <= S0;
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
end
end
S5:
begin
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
if(char == 72) //H
status <= S1;
else
status <= S0;
end
default:
begin
status <= S0;
str_out <= {8'd0,8'd0,8'd0,8'd0,8'd0};
end
endcase
end
end
endmodule
三、代码仿真
代码语言:javascript复制`timescale 1ns/1ps
module FSM_char_seqence_check_tb;
reg clk;
reg rst_n;
reg [7:0] char;
reg [7:0] temp;
wire [39:0] str_out;
FSM_char_seqence_check FSM_char_seqence_check_inst(
.clk (clk),
.rst_n (rst_n),
.char (char),
.str_out (str_out)
);
always #10 clk = ~clk;
initial begin
clk = 0;
rst_n =0;
char = 0;
#10;
rst_n = 1;
repeat (10000)begin
temp = {$random} %6;
char = ((temp >=65) && (temp<=122))?temp:0;
#20;
end
#50000;
char = 0;
#50000;
char = 72;
#20;
char = 101;
#20;
char = 108;
#20;
char = 108;
#20;
char = 111;
#20;
char = 0;
#50000;
repeat (10000)begin
temp = {$random} %6;
char = ((temp >=65) && (temp<=122))?temp:0;
#20;
end
end
initial begin
#500000;
#500000;
#500000;
$stop;
end
endmodule