状态机练习

一、相关原理

写在前面的一些个人理解在我看来,状态机就是一个描述处于不同情况下代码运行哪些部分的块,可以把它理解为C语言中的swich选择语句,只是选择的条件要更为复杂一些。(个人理解,有待加深)

1.有限状态机

状态机由状态寄存器和组合逻辑电路构成,能够根据控制信号按照预先设定的状态进行状态转移,是协调相关信号动作、完成特定操作的控制中心。有限状态机简写为FSM(Finite State Machine),主要分为2大类:Moore状态机和Mealy状态机

2.Moore状态机

摩尔状态机:当输出(output)只与当前状态有关时,所描述的状态机称为Moore型状态机。

3.Mealy状态机

米利状态机:当输出(output)不仅与当前状态有关而且与输入(inputs)有关时,所描述的状态机称为Mealy型状态机。

4.状态机描述方法

一段式
只有一个always块,把所有的逻辑(输入、输出、状态)都在一个always块的时序逻辑中实现。这种写法看起来很简洁,但是不利于维护,如果状态复杂一些容易出错。

两段式
有两个always 块,把时序逻辑和组合逻辑分隔开来。时序逻辑里进行当前状态和下一状态的切换,组合逻辑实现各个输入、输出以及状态判断。这种写法不仅便于阅读、理解、维护,而且利于综合器优化代码,利于用户添加合适的时序约束条件,利于布局布线器实现设计。在两段式描述中,当前状态的输出用组合逻辑实现,可能存在竞争和冒险,产生毛刺。

三段式
有三个always块,一个采用同步时序的方式描述状态转移,一个采用组合逻辑的方式判断状态转移条件、描述状态转移规律,第三个always使用同步时序的方式描述每个状态的输出。
代码容易维护,时序逻辑的输出解决了两段式组合逻辑的毛刺问题,但是从资源消耗的角度上看,三段式的资源消耗多一些。

5.状态机标准评判标准

好的状态机的标准很多,最重要的几个方面如下:
第一,状态机要安全,是指FSM不会进入死循环,特别是不会进入非预知的状态,而且由于某些扰动进入非设计状态,也能很快的恢复到正常的状态循环中来。这里面有两层含义:其一要求该FSM的综合实现结果无毛刺等异常扰动;其二要求FSM要完备,即使受到异常扰动进入非设计状态,也能很快恢复到正常状态。
第二,状态机的设计要满足设计的面积和速度的要求。
第三,状态机的设计要清晰易懂、易维护。

二、核心代码

module test(
     input  wire         clk,
	 input  wire         rst_n,
	 
	 output wire  [3:0]  led
);
parameter   MAX_NUM = 26'd49_999_999;//记最大数,时间1s
parameter   C0 = 5'd5;//5s
parameter   C1 = 5'd20;//20s
parameter   C2 = 5'd18;//18s
parameter   C3 = 5'd25;//25s
parameter   C4 = 5'd14;//14s
parameter   C5 = 5'd8;//8s

//状态空间
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  [4:0]  number;//每个模块计数
reg  [25:0] cnt;//计数寄存器
reg  [4:0]  state_time;//每个状态记录时
reg  [2:0]  flag;//状态标志

reg [2:0]   cstate;//现态
reg [3:0]   led_r;
//1秒钟计数器
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)  begin                          //按下复位键
	     cnt<=26'd0; 		  //计数器清零
    end
    else if(cnt == MAX_NUM)begin
        cnt <= 26'd0;
    end
    else begin
        cnt <= cnt + 1'd1;
	 end
end

//各模块计数器
always@(posedge clk or negedge rst_n)begin
    if(!rst_n)  begin   	 //按下复位键
	    state_time <= 1'd0;
	 end
	 else if(cnt == MAX_NUM)begin
	     state_time <=  state_time + 1'd1;
	 end
	 else if(state_time == number)begin
	     state_time <=  1'd0;
	 end
	 else begin
	     state_time <=  state_time;
	 end
end


//状态切换
always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
       cstate <= S0;
		 number <= C0;
		 flag <= 1'd0;
	end	
	else begin
	  case(cstate)
	    S0:begin
		   if(state_time == 3'd5&&(!flag))begin
			   cstate <= S1;
			   number <= C1;
			   flag <= flag + 1'd1;
		   end
			else begin
			   cstate <= S0;
			end
		 end
		 S1:begin
		   if(state_time == 5'd20&&(flag == 1))begin
		      cstate <= S2;
			   number <= C2;
			   flag <= flag + 1'd1;
			end
			else begin
			   cstate <= S1;
			end
		 end
		 S2:begin
		   if(state_time == 5'd18&&(flag == 2))begin
			   cstate <=S3;
			   number <= C3;
			   flag <= flag + 1'd1;
		   end
			else begin
			   cstate <= S2;
			end
		 end
		 S3:begin
		   if(state_time == 5'd25&&(flag == 3))begin
			   cstate <=S4;
			   number <= C4;
			   flag <= flag + 1'd1;
			end
			else begin
			  cstate <= S3;
			end
		 end
		 S4:begin
		   if(state_time == 5'd14&&(flag == 4))begin
			   cstate <=S5;
			   number <= C5;
			   flag <= flag + 1'd1;
			end
			else begin
			   cstate <= S4;
			end
		 end
		  S5:begin
		   if(state_time == 5'd8 &&(flag == 5))begin
			   cstate <=S0;
			   number <= C0;
			   flag <= 1'd0;
			end
			else begin
			   cstate <= S5;
			end
		 end
		 default:begin 
		      cstate <=S0;
			   number <= C0;
				flag <= 1'd0;
		 end
	  endcase
   end
end
//led灯状态
always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
      led_r <= 4'b0000;
	end
	else begin
	   case(cstate)
		  S0:  led_r <= 4'b0001;
		  S1:  led_r <= 4'b0011;
		  S2:  led_r <= 4'b0111;
		  S3:  led_r <= 4'b1111;
		  S4:  begin
		         if(cnt == MAX_NUM)begin
					  led_r <= ~led_r;
					 end
					 else begin
					  led_r <= led_r ;
					 end
		       end
		 S5:  led_r <=4'b0000;
		 default:led_r <= 4'b0000;
		endcase
	end
end
assign led = led_r;
endmodule

三、检测10010串的状态

在这里插入图片描述
代码
状态处理模块

//状态识别:10010
module deal(
    input   wire       clk, 
	 input   wire       rst_n,
    input   wire [1:0] key,
    output  wire [3:0] led 
);  
parameter MAX_NUM =26'd49_999_999;
parameter CNT_02 =24'd9_999_999;
//状态空间
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]   cstate;
reg [25:0]  cnt_1s;
reg [23:0]  cnt_200ms;
reg [3:0]   led_r;

//计数器1s
always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
	  cnt_1s <= 26'd0;
	end
	else if(cnt_1s == MAX_NUM)begin
	  cnt_1s <= 26'd0;
	end
	else begin
	  cnt_1s <= cnt_1s + 1'd1;
	end
end

//计数器0.2s
always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
	  cnt_200ms <= 24'd0;
	end
	else if(cnt_200ms == CNT_02)begin
	  cnt_200ms <= 24'd0;
	end
	else begin
	  cnt_200ms <= cnt_200ms + 1'd1;
	end
end

//密码切换
always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
      cstate <= S0;
	end	
	else begin
	  case(cstate)
	    S0:begin
		   if(key[1])begin
			  cstate <=S1;
		   end
			else if (key[0])begin
			  cstate <= S0;
			end
			else begin
			  cstate <= S0;
			end
		 end
		 S1:begin
		   if(key[0])begin
			  cstate <=S2;
		   end
			else if (key[1])begin
			  cstate <= S0;
			end
			else begin
			  cstate <= S1;
			end
		 end
		 S2:begin
		   if(key[0])begin
			  cstate <=S3;
		   end
			else if (key[1])begin
			  cstate <= S1;
			end
			else begin
			  cstate <= S2;
			end
		 end
		 S3:begin
		   if(key[1])begin
			  cstate <=S4;
		   end
			else if (key[0])begin
			  cstate <= S2;
			end
			else begin
			  cstate <= S3;
			end
		 end
		 S4:begin
		   if(key[0])begin
			  cstate <=S5;
		   end
			else if (key[1])begin
			  cstate <= S3;
			end
			else begin
			  cstate <= S4;
			end
		 end
		 S5:begin
		    if(cnt_1s == MAX_NUM)begin
	        cstate <= S0;
			 end
			else begin
			  cstate <= S5;
			end
		  end
		 default:cstate <= S0;
	  endcase
	end
end

always@(posedge clk or negedge rst_n)begin
   if(!rst_n)begin
      led_r <= 4'b0000;
	end
	else begin
	   case(cstate)
		  S0:  led_r <= 4'b0000;
		  S1:  led_r <= 4'b0001;
		  S2:  led_r <= 4'b0011;
		  S3:  led_r <= 4'b0111;
		  S4:  led_r <= 4'b1111;
		  S5:  begin
		         if(cnt_200ms == CNT_02)begin
					  led_r <= ~led_r;
					 end
					 else begin
					  led_r <= led_r ;
					 end
		       end
		  default:led_r <= 4'b0000;
		endcase
	end
end
assign led = led_r;
endmodule

四、总结

在我看来,状态机就是一个描述处于不同情况下代码运行哪些部分的块,可以把它理解为C语言中的swich选择语句,只是选择的条件要更为复杂一些。

参考链接

https://blog.csdn.net/weixin_43828944/article/details/122079158?ops_request_misc=%257B%2522request%255Fid%2522%253A%2522165175176816781683953876%2522%252C%2522scm%2522%253A%252220140713.130102334.pc%255Fblog.%2522%257D&request_id=165175176816781683953876&biz_id=0&utm_medium=distribute.pc_search_result.none-task-blog-2blogfirst_rank_ecpm_v1~rank_v31_ecpm-1-122079158.nonecase&utm_term=%E7%8A%B6%E6%80%81%E6%9C%BA&spm=1018.2226.3001.4450

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: 状态机实验平台是一个用于学习和实践状态机概念和原理的在线教育平台。该平台提供了一个交互式学习环境,帮助学生通过实际操作和练习掌握状态机的设计和应用。 在状态机实验平台上,用户可以创建自己的状态机模型,并定义状态、事件和转换条件。通过图形化的界面,用户可以直观地设计状态机状态转换图,并设置每个状态之间的转换规则。 通过实验平台,用户可以学习状态机的基本原理和概念,包括状态、事件、转换、动作等概念的定义和理解。用户可以通过实际操作和实验来加深对状态机的理解和应用,提高自己在状态机设计和开发上的能力。 实验平台还提供了一些经典的状态机案例,供用户学习和借鉴。用户可以通过这些案例来理解状态机在实际应用中的作用和价值,同时也可以通过修改和扩展这些案例来实践自己的状态机设计能力。 通过状态机实验平台,用户可以进行实时的调试和检测,查看状态机的运行状态和输出结果,及时发现和解决问题。用户还可以将自己的状态机模型导出为可执行代码,进一步应用到实际项目中。 总之,状态机实验平台是一个通过实践来学习状态机设计和应用的在线教育平台。通过该平台,用户可以系统地学习和练习状态机的相关知识和技能,提高自己在状态机设计和开发上的水平。 ### 回答2: 状态机实验是一种通过描述和控制对象的状态变化来设计和实现程序的方法。而10001 cg平台则是一个提供计算机图形学相关实验的平台。 在状态机实验中,我们首先需要定义对象可能的不同状态,然后通过状态之间的转移关系和特定条件来描述状态变化的过程。在10001 cg平台上,我们可以使用编程语言(如C++或Python)来实现状态机,并且可以利用平台提供的图形学库来显示和控制对象的状态变化。 在实践中,我们可以选择一个合适的案例来进行状态机实验,如一个简单的游戏中的角色状态变化。我们可以定义角色的不同状态,如“闲置”、“行走”、“攻击”、“受伤”等,然后通过状态之间的转移关系来描述角色在不同操作下的状态变化。在10001 cg平台上,我们可以使用平台提供的图形库来显示角色的状态图和状态变化过程,从而更直观地理解和控制状态机的实现。 通过状态机实验,我们可以提高对程序的整体设计和实现的抽象思维能力。在10001 cg平台上进行状态机实验,不仅可以学习和了解状态机的原理和用法,还可以通过实践掌握图形学相关的编程和应用技巧。同时,这也是一种锻炼逻辑思考和问题解决能力的有效方法。 ### 回答3: 状态机实验10001 CG(Computer Graphics)平台是一个用于进行状态机实验的计算机图形平台。状态机是计算机科学中的一个重要概念,常用于描述程序或系统的行为和状态转换。该平台通过可视化方式展现状态机的运行过程,使得状态机实验更加直观和易于理解。 在状态机实验10001 CG平台中,用户可以创建、编辑和调试自己设计的状态机。首先,用户可以使用平台提供的图形界面工具绘制状态图,包括状态节点、转换条件和转换动作等。用户可以自定义每个状态的属性、转换条件和动作,以及状态机的初始状态。通过拖拽和连接节点,用户可以创建自己期望的状态转换逻辑。 一旦状态机被创建并配置好,用户就可以通过平台提供的调试功能来测试状态机的运行。平台会显示当前状态和可用的转换条件,用户可以手动执行状态转换,并观察状态机的行为和输出。通过调试功能,用户可以发现状态机中可能存在的问题,如死锁、状态转换错误等,并进行修正。 除了调试功能外,状态机实验10001 CG平台还提供了性能分析工具,用于评估状态机的运行效率和资源消耗。用户可以根据性能分析结果,优化状态机的设计,以提高系统的响应速度和效率。 综上所述,状态机实验10001 CG平台为用户提供了一个方便、直观的方式来设计、调试和优化状态机。通过这个平台,用户可以更好地理解状态机的原理和应用,从而在软件开发和系统设计中更好地运用状态机
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值