【FPGA入门】第四篇、有限状态机

目录

第一部分、一个关于有限状态机的例子

第二部分、学会有限状态机的准备知识

1、什么是有限状态机?

2、为什么需要状态机?

3、什么是竞争冒险?

3.1、什么情况下会发生竞争冒险?

3.2、为什么组合逻辑电路会产生竞争和冒险?

3.3、那什么是竞争?什么是冒险?

3.4、怎样降低竞争冒险?

4、关于状态编码问题

第三部分、二段式状态机的编写

第四部分、仿真效果

第五部分、总结


第一部分、一个关于有限状态机的例子

        啥时候需要用到状态机,首先我们来看一个例子。有一个自动饮料售货机,里面的货物3元一件,每次投币只能投1元。

        由数电的知识,我们将这个过程转换为状态转移图,如下:

【FPGA入门】第四篇、有限状态机_第1张图片

        接着问题就是,如何用verilog把这个售货机买东西的这个程序给设计出来???

第二部分、学会有限状态机的准备知识

1、什么是有限状态机?

        有限状态机(Finite State Meachine,FSM)简称状态机。我的理解是:它是去描述一个过程,也就是完成某一件事必须有几个步骤,只有完成这几个步骤才能到达终点,这个终点也是起点,是一个闭环的过程,经过几次状态跳转后总会回到起点。

2、为什么需要状态机?

        因为FPGA内部的Verilog HDL 的语句块都是并行执行的, 当我们希望执行按照顺序的方式进行时,引入状态机就可以很好的实现顺序执行。

3、什么是竞争冒险?

        在学会状态机怎么写之前,首先你要了解一个模电的基本常识,那就是竞争与冒险。

        3.1、什么情况下会发生竞争冒险?

        竞争和冒险主要发生在组合逻辑电路中。

        3.2、为什么组合逻辑电路会产生竞争和冒险?

        因为每个逻辑单元都会存在延迟问题,这可能和器件的制作工艺,材料有关系,我们设计时不可能保证信号经过每个逻辑器件的时间都是一致的,因次当两个信号再次汇聚时,总有一个先,一个后。

        3.3、那什么是竞争?什么是冒险?

        上面说到了,两个信号在电路的某一点汇聚时,顺序有限有后。

        那我们假设现在有一个与门,输入为a,b,输出为c。当前状态下 a = 0,b = 1,c = 0。此刻,我同时对a,b输入信号进行取反,这是 a = 1 ,b = 0;若a = 1的信号比b = 0的信号先到与门,那么c就会有那么一瞬间c = 1,进而就有一个尖峰脉冲。  

        如下图:

【FPGA入门】第四篇、有限状态机_第2张图片

        3.4、怎样降低竞争冒险?

        想降低竞争冒险那就应避免使用组合逻辑,多使用时序逻辑。那为啥时序逻辑就能降低竞争冒险现象呢?

       首先FPGA内部时钟一般是50M,1/50M = 20ns,也就是一个周期是20ns,而竞争冒险一般只有几个纳秒。

       而clk 的上升沿/下降沿采集到毛刺的概率就非常低。正常情况下,clk的沿都采集不到该毛刺,如下图:

【FPGA入门】第四篇、有限状态机_第3张图片

4、关于状态编码问题

        独热编码注意:多少个状态,对应的state状态一定有多少位;其次在modelsim一定要以二进制的方式检查state独热码的位数)。即 One-Hot 编码,一位有效编码,其方法是使用N位状态寄存器来对N个状态进行编码,(3个状态3位,4个状态4位)每个状态都由他独立的寄存器位,并且在任意时候,其中只有一位有效。

        优点:每一个独热码的数据位只有一个为1,其它全为0,因此独热码的变化只需要一位转变即可。

        因此使用独热码可以提高运行速度。在高速系统中,无论个数均推荐使用独热码。

第三部分、二段式状态机的编写

        了解了什么是有限状态机,以及竞争冒险,那么采用的两个时序逻辑 always 块,不仅可以描述清楚状态转移和数据输出,又能消除组合逻辑带来的毛刺。

        售货机示例代码:

// -----------------------------------------------------------------------------
// Copyright (c) 2014-2023 All rights reserved
// -----------------------------------------------------------------------------
// Author : BigFartPeach
// CSDN   : 大屁桃
// E-mail : [email protected]
// File   : fsm.v
// Create : 2023-04-12 17:01:02
// -----------------------------------------------------------------------------
module fsm(
	input wire clk,
	input wire rst_n,
	input wire pi_money,
	output reg po_drink
	);
//状态名称定义(独热码)
parameter IDLE = 3'b001;
parameter ONE  = 3'b010;
parameter TWO  = 3'b100; 

reg [2:0] state;
//状态转移
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		state <= IDLE;
	end
	else begin
		case(state)
		IDLE:
			if(pi_money == 1'b1)begin//疑问,随机数来代替pi_money,如果一致为1怎么解决?
				state <= ONE; 
			end

		ONE:
			if(pi_money == 1'b1)begin
				state <= TWO;
			end

		TWO:
			if(pi_money == 1'b1)begin
				state <= IDLE;
			end
		default:
			state <= IDLE;
		endcase
	end
end


//状态输出(多个输出,用多个always语句块)
always @(posedge clk or negedge rst_n) begin
	if (rst_n == 1'b0) begin
		po_drink <= 1'b0;
	end
	else if (state == TWO && pi_money == 1'b1) begin
		po_drink <= 1'b1;
	end
	else begin
		po_drink <= 1'b0;
	end
end

endmodule

第四部分、仿真效果

        仿真结果如下图,符合设计逻辑。

第五部分、总结

        本章内容参考了以下资料:首先是这篇博客:http://t.csdn.cn/F3QAK;其次是V3学院的培训课程和指导手册。

        最后,希望我的总结对你有帮助,看到这里了,要不点个赞,意思一下?

        

你可能感兴趣的:(FPGA的学习之旅,fpga开发)