当前位置:   article > 正文

FPGA学习(五)——状态机_fpga状态机状态为满足条件进入

fpga状态机状态为满足条件进入


状态机概念

状态机(State Machine)
有限状态机(Finite State Machine,简称 FSM)
在有限个状态之间按一定规律转换的时序电路。

状态机是包含有限个状态的概念化机器,由状态、转换和动作这3个元素组成的有向图,三者关系如下:

  • 动作是实现状态转换而执行的计算;
  • 事件是状态转换的原因;
  • 动作是转换的效果;
    在任何时候,状态机只能处于其中的一个状态,而状态的转换由输入事件引起,但状态机又可以响应或不响应事件,所以输出动作同样也是可以产生或不产生的,下一个状态取决于当前状态以及输入事件。

所有的状态机体系中,普遍的假设一个状态机在它能进行下一个事件处理完成对每个事件的处理,这个执行模型被称为"运行—到—完成模型"(Run-to-Completion Execution Model,RTC)。

状态机模型

在这里插入图片描述
状态寄存器由一组触发器组成,用来记忆状态机当前所处的状态,状态的改变只发生在时钟的跳变沿。

状态是否改变,如何改变,取决于组合逻辑F的输出,F是当前状态和输入信号的函数。

状态机的输出是由组合逻辑G提供的,G也是当前状态和输入信号的函数。

在这里插入图片描述

状态机设计

状态空间定义

//define state space
parameter SLEEP   = 4'b1000;
parameter STUDY   = 4'b0100;
parameter EAT     = 4'b0010;
parameter AMUSE   = 4'b0001;
// internal variable
reg [3:0] current_state;
reg [3:0] next_state;
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8

独热码:每个状态只有一个寄存器位置位,译码逻辑简单。

状态跳转

//transition
always @(posedge clk or negedge rst_n)beigin  //敏感列表:时钟信号以及复位信号边沿的触发方式
	if(!rst_n)
		current_state <= SLEEP;
	else 
		current_state <= next_state; //非阻塞赋值
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7

下个状态判断

//next state decision
always @(current_state or input_signal)beigin 
//敏感列表:所有的右边表达式中的变量以及if、case条件中的变量
	case (current_state)
		SLEEP: begin
			if(clock_alarm)
				next_state = STUDY;
			else
				next_state = SLEEP;  //阻塞赋值
			end
			SYUDY:begin
				if(lunch_time)
					next_state = EAT;
				else
					next_state = SYUDY;
			end
			EAT: .....;
			AMUSE:  .....;
			default: ...;
	endcase
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21

各个状态下的动作

//action
wire read_book;
assign read_book = (current_state == STUDY) ? 1'b1 : 1'b0;

always @(current_state)begin
	if(current_state == STUDY)
		read_book = 1;
	else
		read_book = 0;
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10

三段式状态机实例

module divider7_fsm(
//inout ports
input	sys_clk ,
input  sys_rst_n ,
//output ports
output reg  clk_divide_7
);

//reg define
reg [6:0]  curr_st ;
ref [6:0]  next_st;

//wire define

//parameter define
parameter WIDTH =1 ;

//one hot code design
parameter S0 = 7'b0000000;
parameter S1 = 7'b0000001;
parameter S2 = 7'b0000010;
parameter S3 = 7'b0000100;
parameter S4 = 7'b0001000;
parameter S5 = 7'b0010000;
parameter S6 = 7'b0100000;

always @(posedge sys_clk or negedge sys_rst_n)beigin
	if(sys_rst_n == 1'b0)
		curr_st <= 7'b0;
	else
		curr_st <= next_st;
end

//FSM state logic
always @(*)begin
	case (curr_st)
		S0:beigin
			next_st = S1;
			end
		S1:beigin
			next_st = S2;
			end
		S2:beigin
			next_st = S3;
			end
		S3:beigin
			next_st = S4;
			end
		S4:beigin
			next_st = S5;
			end
		S5:beigin
			next_st = S6;
			end
		S6:beigin
			next_st = S0;
			end
		default: next_st = S0;
	endcase
end

//control divede clock offset
always @(posedge sys_clk or negedge sys_rst_n)begin
	if(sys_rst_n == 1'b0)beigin
		clk_divide_7 <= 1'b0;
	end
	else if((curr_st == S0) | (curr_st == S1) | (curr_st == S2) |(curr_st == S3))
		clk_divide_7 <= 1'b0;
	else if(curr_st == S4) | (curr_st == S5) | (curr_st == S6) |(curr_st == S7))
		clk_divide_7 <=1;b1;
	else;
end
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
  • 49
  • 50
  • 51
  • 52
  • 53
  • 54
  • 55
  • 56
  • 57
  • 58
  • 59
  • 60
  • 61
  • 62
  • 63
  • 64
  • 65
  • 66
  • 67
  • 68
  • 69
  • 70
  • 71
  • 72

在这里插入图片描述
三段式可以在组合逻辑后再增加一级寄存器来实现时序逻辑输出:

  1. 可以有效第过滤去组合逻辑输出的毛刺;
  2. 可以有效地进行时序计算与约束;
  3. 另外对于总线形式的输出信号来说,容易使总线数据对齐,从而减小总线数据间的偏移,减小接收端数据采样出错的频率。
本文内容由网友自发贡献,转载请注明出处:https://www.wpsshop.cn/w/小舞很执着/article/detail/915472
推荐阅读
相关标签
  

闽ICP备14008679号