学fpga(状态机)

Posted 费晓行

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了学fpga(状态机)相关的知识,希望对你有一定的参考价值。

【 声明:版权所有,欢迎转载,请勿用于商业用途。 联系信箱:feixiaoxing @163.com】

        软件开发中也用状态机,但软件开发除了状态机,还有多线程、网络、并发、数据库、GUI、线程互斥等很多东西。而fpga的状态机则使用的纯粹的多,范围也广的多。一个复杂的功能,如果没有模块的切分,没有状态机的设计,大概率是没有办法完整跑起来的。

        可以用一个范例来说明状态机。假设有一个自动贩卖机。贩卖机有两个入口,两个出口。两个入口中,一个是投币入口,一个取消入口。两个出口,一个代表出货的出口,另外一个代表退币的出口。我们可以画一个图表示一下。

       可以继续假设我们有一个商品,比如说是一瓶可乐,三块。一次投币只能投一块钱。连续投三次之后,就可以从出货口那里得到商品。在这过程中,如果按下了quit,那么就会吐出之前所有的硬币,重新开始。大家可以思考一下,这中间会有几个状态,

         一开始没有硬币的时候,可以默认为idle状态。后面慢慢投币了,那么就有coin1、coin2、coin3三种状态。idle、coin1、coin2有两个输入,即投币和取消。而coin3只是一个过渡状态,在这个状态,输出商品后,马上就恢复到idle状态了。

        状态机设计好了,下面就是进行verilog模块切分了,这里投币和取消的输入,我们可以用key来代替。

         从上面的图形中,可以发现整个系统有3个模块组成。两个按键模块,一个状态机模块。按键模块主要是同一个模块实例化两次,再设计一个状态机模块就可以了。目前状态机模块主要采用的方法是三段论,第一个是状态切换,第二个是状态判断,第三个不同状态下的输入输出判断。


always@(posedge clk or posedge rst)
	if(rst)
		state <= IDLE_STATE;
	else
		state <= next_state;

always @(*)
	next_state = IDLE_STATE;
	
	case state
		IDLE_STATE:
			if(flag1)
				next_state = COIN1_STATE;
			else
				next_state = state;
		COIN1_STATE:
			if(flag1)
				next_state = COIN2_STATE;
			else if(flag2)
				next_state = IDLE_STATE;
			else
				next_state = state;
		COIN2_STATE:
			if(flag1)
				next_state = COIN3_STATE;
			else if(flag2)
				next_state = IDLE_STATE;
			else
				next_state = state;
		COIN3_STATE:
			next_state = IDLE_STATE;
		
		default:
			next_state = IDLE_STATE;
		

        有了状态,不管是输出商品,还是退币处理,这就好办了。

always @(posedge clk or posedge rst)
	if(rst)
		product <= 1'b0;
	else if(state == COIN3_STATE)
		product <= 1'b1;
	else 
		product <= 1'b0;
		
always @(posedge clk or posedge rst)
	if(rst)
		coin <= 1'b0;
	else if(flag2 && (state == COIN1_STATE || state == COIN2_STATE)
		coin <= 1'b1;
	else
		coin <= 1'b0;

        上面这两部分就是完整的状态机处理流程,剩下来的就是集成工作。有兴趣的同学可以把这段代码port到fpga开发板上面,实际测试一下。


module store(clk, rst, key1, key2, product, coin)

input clk;
input rst;
input key1;
input key2;
output produt;
output coin;

wire clk;
wire rst;
wire key1;
wire key2;
reg product;
reg coin;

wire flag1;
wire flag2;

key key1(
	.clk(clk),
	.rst(rst),
	.key(key1),
	.flag(flag1)
	);
	
key key2(
	.clk(clk),
	.rst(rst),
	.key(key2),
	.flag(flag2)
	);

state_machine sm(

	.clk(clk),
	.rst(rst),
	.flag1(flag1),
	.flag2(flag2),
	.product(product),
	.coin(coin)
	);

endmodule();

以上是关于学fpga(状态机)的主要内容,如果未能解决你的问题,请参考以下文章

FPGA学习之 状态机实现数码管的数字时钟

FPGA学习之 状态机实现数码管的数字时钟

FPGA学习之 状态机实现数码管的数字时钟

FPGA 状态机????

fpga状态机详解

FPGA 串口通信