当前位置:网站首页>状态机练习
状态机练习
2022-07-17 21:46:00 【狴鲲】
一、相关原理
写在前面的一些个人理解在我看来,状态机就是一个描述处于不同情况下代码运行哪些部分的块,可以把它理解为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秒钟计数器 [email protected](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
//各模块计数器
[email protected](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 //状态切换 [email protected](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灯状态 [email protected](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
[email protected](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 [email protected](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
//密码切换
[email protected](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
[email protected](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选择语句,只是选择的条件要更为复杂一些。
参考链接
边栏推荐
- 滑动窗口最大值问题
- Redis source code and design analysis -- 1 Simple dynamic string
- Redis源码与设计剖析 -- 3.字典
- 树与二分图【思维】
- Is it true that tongdaxin opens an account? Is it safe for tongdaxin to open an account?
- Deep understanding of transaction isolation levels
- The bill module of freeswitch
- STM32 positioning hardfault location method and encountered situation in keil environment
- Rotation formula of coordinate simulation matrix
- Opencv template
猜你喜欢

敏捷的第一步:把 “迭代” 变为 “冲刺” 开始!

Classes abstraites et dérivées

Which company is better in data filling and report presentation? Yixin ABI gives you the answer

MySQL read / write separation

The manual is not complete. How to manually dig out the monitoring information of tongweb?

Authing practice | unified management solution for manufacturing identity authentication

CF 807 E. Mark and Professor Koro(权值线段树)

Can ping command still play like this?

Redis源码与设计剖析 -- 2.链表

si446使用记录(三):MATCH功能
随机推荐
Configure spectrum navigation for Huawei wireless devices
Redis源码与设计剖析 -- 2.链表
Opencv template
C语音 杨氏矩阵 · 左旋字符串 · 判断字符串是否旋转
Huawei wireless device configuration user CAC
Explain the operation of C language file in detail
深入理解事务隔离级别
常见的内置函数、可迭代对象、迭代器对象、异常捕获、异常捕获的用途、生成器对象、模块、绝对导入与相对导入、包的概念、模块
End repeated development and personalize the login system in twoorthree times
LabVIEW uses multithreading. Will the program run faster
Encrypt Ogg users
06--- characteristics of light in media
si446使用记录(三):MATCH功能
The bill module of freeswitch
[Luogu p3220] and not (construction) (digit DP) (inference)
学习记录[email protected]之moveActivityIdTo任务回退特殊案例分析
Luo Gu: p3092 [usaco13nov]no change G
44、使用OrienMask进行实例分割目标检测,并进行mnn部署和ncnn部署
Redis源码与设计剖析 -- 4.跳跃表
C speech Young's matrix · left-hand string · judge whether the string is rotated