FPGA——状态机

本文介绍了FPGA中状态机的作用,对比了摩尔型和米莉型状态机的区别,并通过Verilog代码实现了一个可乐机状态机示例。状态机采用独热码编码,以节省逻辑资源。同时,提供了测试激励和Modelsim仿真结果,展示状态机功能。
摘要由CSDN通过智能技术生成

状态机
首先得了解FPGA为什么需要状态机。FPGA的模块都是并行执行,那么如果需要处理具有前后顺序的事件,这里就要使用到状态机。
状态机分为摩尔型状态机(Moore)和米莉型状态机(mealy)。他们的共同点是状态的跳转和输入有关。区别就是当最后的输出是只与当前状态有关,与输入无关,则属于莫尔型状态机。若最后的输出不仅和当前状态有关还与输入有关,则是米莉型状态机。
这里我们用verilog实现一个可乐机。要求是可乐机每次只能投入一元,且每瓶可乐卖三元。
在这里插入图片描述
输入/输出
根据实验要求,可将状态机分为四个状态,ZERO,ONE,TWO,THREE。输入分为零元,一元。输出分为出可乐和不出可乐。初始状态为ZERO,当投入零元时,保持状态不变,当投入一元时,跳到ONE状态,以此类推,最后到THREE状态且输出可乐。由图可知,次状态机为摩尔型状态机,最终输出状态与输入无关。而米莉型状态机图片则如下图。
在这里插入图片描述
由图状态可知,当输出可乐时,不仅和当前状态有关,还与输入有关。这里就是两种状态机的区别。

RTL代码

module	coke_machine
(
	
	input	wire			sys_clk		,
	input	wire			sys_rst_n	,
	input	wire			money_in	,//投钱,1表示投入一元,0表示投入零元
	
	output	reg				coke		//1表示出可乐,0表示不出可乐
	
);


reg	[2:0]	state;
//这里采用独热码的编码方式表示三个状态
parameter		ZERO = 3'd100,
				ONE	= 3'd010,
				TWO = 3'd001;


always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		state <= ZERO;
	else	case(state)
		ZERO	:if(money_in == 1'b1)
					state <= ONE;
				else
					state <= ZERO;
		ONE		:if(money_in == 1'b1)
					state <= TWO;
				else
					state <= ONE;
		TWO		:if(money_in == 1'b1)
					state <= ZERO;
				else
					state <= TWO;
		default	:	state <= ZERO;
	endcase
	
always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		coke <= 1'b0;
	else	if(state == TWO && money_in == 1'b1)
		coke <= 1'b1;
	else	
		coke <= 1'b0;

				
				
endmodule

状态机视图
在这里插入图片描述
在编写代码过程中,这里采用了独热码来表示不同的状态。我们可以也可以采用二进制码或者格雷码。独热码,每个状态只有一个bit是高电平。二进制码就是00,01,10,11,换成十进制就是0,1,2,3,依次累加。格雷码在一组数的编码中,若任意两个相邻的代码只有一位二进制数不同,例如00,01,11,10。独热码因为每个状态只有 1bit 是不同的,在适合条件下综合时相对于其他编码会更加节省组合逻辑资源。因为FPGA中组合逻辑资源较少,比较宝贵。而寄存器资源多。
所以在不同条件下使用编码时,可以参考下图
在这里插入图片描述

testbench

`timescale 1ns/1ns 
module	tb_coke_machine();


reg			sys_clk;
reg			sys_rst_n;
reg			money_in;

wire		coke;


initial
	begin
		sys_clk = 1'b0;
		sys_rst_n <= 1'b0;
		#20
		sys_rst_n <= 1'b1;
	end
	
always	#10 sys_clk = ~sys_clk;

always@(posedge sys_clk or negedge sys_rst_n)
	if(sys_rst_n == 1'b0)
		money_in <= 1'b0;
	else
		money_in <= {$random} % 2;//随机产生一个二进制数


coke_machine	coke_machine_inst
(
	
	.sys_clk		(sys_clk),
	.sys_rst_n		(sys_rst_n),
	.money_in		(money_in),//投钱,1表示投入一元,0表示投入零元

	.coke			(coke)//1表示出可乐,0表示不出可乐
	
);


endmodule

modelsim仿真结果
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值