FSM有限状态机(三段式)检测连续序列1101

一.FSM理论基础

  • 前期文章详细叙述了FSM,有需要的同学请访问链接:点击次数访问链接https://blog.csdn.net/weixin_42455055/article/details/119118162

二.连续序列1101检测案例

2.1 需求分析

  • (1) 检测任意数字序列,若连续出现1101则表示检测到目标序列命令,输出标识信号flag,此处以“11101101011010”为例,设计三段式FSM进行检测。
  • (2)其状态转移图如下所示,一共分为5个状态,IDEL下状态为xxxx未知态,同理S1:1xxx S2:11xx S3:110x S4:1101
  • (3)单次循环有四种链路传输状态:
  •    1)首先最简单的链路就是输入d_in连续检测成功,第一拍为d_in = 1'b1,依次分别为1'b1、1'b0、1'b1,进入S4后在下一拍检测到d_in = 1'b0,则返回IDEL准备新一轮检测。
       2)其次,有可能在S1和S3检测到d_in = 1'b0返回IDEL。
       3)最后,抵达S4后如果下一拍上升沿检测到d_in = 1’b1,则返回S2,当时状态为11xx。
    

在这里插入图片描述

2.2 Verilog实现

module FSM_1101(
	input						clk,
	input						rst_n,
	input 					FSM_1101_in,      //一位输入
	
	output reg 				Match_Flag			//1101检测成功标志信号
);
	//***********************parameter************************
	reg [2:0] next_state;			//下一拍执行状态
	reg [2:0] state;					//当前拍未执行最新状态
		
	localparam							//一共五个状态,使用Gray码提高翻转效率
		IDEL 	 = 3'b000,
		NUM_1xxx = 3'b001,
		NUM_11xx = 3'b011,
		NUM_110x = 3'b010,
		NUM_1101 = 3'b110;		  //110=>000翻转了两位,不够好
		
	//***********************FSM 1101************************
	//第一段 下一状态更新
	always@( posedge clk or negedge rst_n ) begin
		if( !rst_n )
			next_state <= IDEL;
		else
			next_state <= state;
	end
	
	//第二段 状态判断跳转
	always@(*) begin
		case(next_state)
			IDEL:	 begin
						if( FSM_1101_in == 1'b1 )
							state <= NUM_1xxx;
						else
							state <= IDEL;
					 end
			NUM_1xxx:begin
						if( FSM_1101_in == 1'b1 )
							state <= NUM_11xx;
						else
							state <= IDEL;
					 end
			NUM_11xx:begin
						if( FSM_1101_in == 1'b0 )
							state <= NUM_110x;
						else
							state <= NUM_11xx;
					 end
			NUM_110x:begin
						if( FSM_1101_in == 1'b1 )
							state <= NUM_1101;
						else
							state <= IDEL;
					 end
			NUM_1101:begin
						if( FSM_1101_in == 1'b1 )
							state <= NUM_11xx;
						else
							state <= IDEL;
					 end
			default:state <= IDEL;
		endcase
	end
	
	//第三段 标志信号输出
	always@( posedge clk or negedge rst_n ) begin
		if( !rst_n )
			Match_Flag <= 0;
		else if( next_state == NUM_1101 )
			Match_Flag <= 1'b1;
		else 
			Match_Flag <= 1'b0; 
	end
	
endmodule

2.3 仿真验证

`timescale 1ns/1ns
`define clock_period 20

module FSM_1101_tb();
	
	//参数
	reg clk;
	reg rst_n;
	reg FSM_1101_in;
	wire Match_Flag;

	//调用
	FSM_1101 FSM_1101
	(
		.clk(clk),
		.rst_n(rst_n),
		.FSM_1101_in(FSM_1101_in),      //一位输入
		
		.Match_Flag(Match_Flag)			//1101检测成功标志信号
	);

	//Initial
	initial 
		begin
			clk = 1;
			rst_n = 0;
			FSM_1101_in = 0;
		end
	
	//Clock
	always#(`clock_period/2) clk = ~clk;
	
	//1101101011010 Generate
	initial begin
		#( `clock_period*20 );
		rst_n = 1;
		#( `clock_period*20 + 1'b1 );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 0;
		#( `clock_period );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 0;
		#( `clock_period );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 0;
		#( `clock_period );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 0;
		#( `clock_period );
		FSM_1101_in = 1;
		#( `clock_period );
		FSM_1101_in = 0;
		
		#( `clock_period*50 );
		$stop;
	end
endmodule
仿真结果如下所示,输出正确:

请添加图片描述

  • 6
    点赞
  • 57
    收藏
    觉得还不错? 一键收藏
  • 4
    评论
好的,以下是一个使用三段式状态机检测连续输出010010的Verilog代码示例: ``` module fsm_010010 ( input clk, rst_n, data_in, output reg detected ); // 定义状态 typedef enum logic [1:0] { IDLE, S0, S1, S2, S3, S4, DONE } state_t; // 定义状态寄存器和当前状态变量 reg [1:0] state_reg, state_next; // 初始化状态 initial begin state_reg = IDLE; end // 更新状态 always @ (posedge clk or negedge rst_n) begin if (!rst_n) begin state_reg <= IDLE; end else begin state_reg <= state_next; end end // 定义状态转换逻辑 always @ (*) begin case (state_reg) IDLE: begin detected = 0; if (data_in == 0) begin state_next = S0; end else begin state_next = IDLE; end end S0: begin if (data_in == 1) begin state_next = IDLE; end else begin state_next = S1; end end S1: begin if (data_in == 0) begin state_next = S2; end else begin state_next = IDLE; end end S2: begin if (data_in == 0) begin state_next = S3; end else begin state_next = IDLE; end end S3: begin if (data_in == 1) begin state_next = S4; end else begin state_next = IDLE; end end S4: begin if (data_in == 0) begin detected = 1; state_next = DONE; end else begin state_next = IDLE; end end DONE: begin state_next = IDLE; end endcase end endmodule ``` 这个状态机有七个状态:IDLE、S0、S1、S2、S3、S4和DONE。在IDLE状态下,如果输入的data_in信号为0,那么状态会转换到S0;否则,状态会保持在IDLE状态。在S0状态下,如果data_in为1,则状态会转换回IDLE;否则,状态会转换到S1。在S1、S2、S3、S4状态下,分别检测data_in的值是否为010010对应的值,如果匹配,则状态会转换到DONE状态,并将输出信号detected设置为1;否则,状态会转换回IDLE状态。在DONE状态下,状态会转换回IDLE状态。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 4
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值