首页 >> 大全

投币可乐-状态机

2023-08-12 大全 26 作者:考证青年

可乐售货机–状态

状态机引入的原因:FPGA 是并行执行的,如果我们想要处理具有前后顺序的事件,这时就需要引入状态机。

背景:可乐定价为 2.5 元一瓶,可投入 0.5 元、1 元硬币,投币不够 2.5 元需要按复位键退回钱款,投币超过 2.5 元需找零。状态转移图的三要素–输入、输出、状态

FPGA为什么大多使用独热码?

独热码,每个编码只有 1 比特为 1,其余比特都为 0。对于几个状态则需要几个比特位。

为什么例子中我们使用的是独热码而非二进制码或格雷码呢?那就要从每种编码的特性上说起了,首先独热码因为每个状态只有 1bit 是不同的,因为只有 1 比特为 1,所以综合器会进行智能优化,这就相当于把之前 a比特的比较器变为了 1 比特的比较器,大大节省了组合逻辑资源,但是付出的代价就是状态变量的位宽需要的比较多,而我们 FPGA 中组合逻辑资源相对较少,所以比较宝贵,而寄存器资源较多,所以很完美。

而二进制编码恰恰相反,虽然使用了较少的寄存器,但比较器无法优化,使用的组合逻辑资源较多,而FPGA器件组合逻辑资源多,寄存器资源较少,所以用独热码更合适。

徐州有开心淘宝儿童投币机吗__投币机识别原理

另外,用独热码编码的状态机可以在高速系统上运行,其原因是多比特的比较器每个比特到达比较器的时间可能会因为布局布线的走线长短而导致路径延时的不同,这样在高速系统下,就会导致采集到不稳定的状态,导致比较后的结果产生一个时钟的毛刺,使输出不稳定,而单比特的比较器就不用考虑这种问题。

用独热码编码虽然好处多多,但是如果状态数非常多的话即使是 FPGA 也吃不消独热码对寄存器的消耗,所以当状态数特别多的时候可以使用格雷码对状态进行编码。格雷码虽然也是和二进制编码一样使用的寄存器资源少,组合逻辑资源多,但是其相邻状态转换时只有一个状态发生翻转,这样不仅能消除状态转换时由多条信号线的传输延迟所造成的毛刺,又可以降低功耗,所以要优于二进制码的方式,相当于是独热码和二进制编码的折中。

状态转移图(Melay型)

输入有多少种情况,每个状态的跳转就有多少种情况,这样根据输入来确定状态的跳转就能够保证我们不漏掉任何一种状态跳转。

有Moore 型状态机和 Mealy 型状态机,其共同点是:状态的跳转都只和输入有关。区别主要

_投币机识别原理_徐州有开心淘宝儿童投币机吗

是在最后输出的时候:若最后的输出只和当前状态有关而与输入无关则称为 Moore 型状态机;

若最后的输出不仅和当前状态有关还和输入有关则称为 Mealy 型状态机。

代码


module complex_fsm
(input	wire	sys_clk		,input	wire	sys_rst_n	,input	wire	one			,input	wire	half		,output	reg		out_money	,output	reg		cola_out
);parameter	IDLE = 5'b00000;
parameter	HALF = 5'b00010;
parameter	ONE = 5'b00100;
parameter	ONE_HALF = 5'b01000;
parameter	TWO = 5'b10000;reg		[4:0]	state;
wire	[1:0]	in_money;assign	in_money = {one, half};always@(posedge	sys_clk or negedge	sys_rst_n)if (sys_rst_n == 0 )state <= IDLE;else	case(state)IDLE: 	if (in_money == 2'b01)state <= HALF;else if (in_money == 2'b10)state <= ONE;elsestate <= IDLE;HALF:	if (in_money == 2'b01)state <= ONE;else if (in_money == 2'b10)state <= ONE_HALF;elsestate <= HALF;ONE: 	if (in_money == 2'b01)state <= ONE_HALF;else if (in_money == 2'b10)state <= TWO;else state <= ONE;ONE_HALF: 	if (in_money == 2'b01)state <= TWO;else if (in_money == 2'b10)state <= IDLE;elsestate <= ONE_HALF;TWO	: 	if (in_money == 2'b01 || in_money == 2'b10)state <= IDLE;else state <= TWO;default:	state <= IDLE;endcasealways@(posedge	sys_clk or negedge	sys_rst_n)if (sys_rst_n == 0 )cola_out <= 1'b0;else	if ((state == TWO && (in_money == 2'b01 || in_money == 2'b10) )|| (state == ONE_HALF && in_money == 2'b10))cola_out <= 1'b1;elsecola_out <= 1'b0;
always@(posedge	sys_clk or negedge	sys_rst_n)if (sys_rst_n == 0 )out_money <= 1'b0;else	if (state == TWO &&  in_money == 2'b10 )out_money <= 1'b1;else		out_money <= 1'b0;endmodule

仿真代码与结果

`timescale 1ns / 1ns// Create Date: 2022/07/16 17:36:16
module tb_complex_fsm();reg		sys_clk		;
reg		sys_rst_n	;
reg		one			;	
reg		half		;	
wire	out_money	;	
wire	cola_out	;	initial beginsys_clk = 1'b1;sys_rst_n <= 1'b0;#20sys_rst_n <= 1'b1;end//sys_clk:模拟系统时钟,每 10ns 电平翻转一次,周期为 20ns,频率为 50MHz
always #10 sys_clk = ~sys_clk;//pi_money:产生输入随机数,模拟投币 1 元的情况
always@(posedge sys_clk or negedge sys_rst_n)if(sys_rst_n == 1'b0){one, half} <= 2'b0;else{one, half} <= {$random} % 3; //取模求余数,产生非负随机数 0、1、2
//------------------------complex_fsm_inst------------------------
complex_fsm complex_fsm_inst(.sys_clk (sys_clk ), //input sys_clk.sys_rst_n (sys_rst_n ), //input sys_rst_n.one 		(one ), .half 		(half),.out_money	(out_money),.cola_out (cola_out ) //output po_cola
);endmodule

结果:

关于我们

最火推荐

小编推荐

联系我们


版权声明:本站内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容, 请发送邮件至 88@qq.com 举报,一经查实,本站将立刻删除。备案号:桂ICP备2021009421号
Powered By Z-BlogPHP.
复制成功
微信号:
我知道了