饮料售卖机FSM

状态机的类型

mealy

输出与当前状态及输入有关
本状态机应该就属于mealy状态机

moore

输出只与当前状态有关
目前还没遇到这种状态机,我认为应该就是只有状态的转换吧,不考虑输入。

状态编码

我们知道有三种编吗方式;
1.binary编码:状态描述简洁,占用较少寄存器资源,是比较常用的状态机编码方式;
2.gray编码
3.one hot编码:占用更多寄存器资源,时序性能更好,适用于逻辑复杂的状态机设计:

要求

请设计一个状态机模拟饮料售卖机,接受1元, 2元, 5元的零钱,饮料为5元,并可以找零。

状态图

在这里插入图片描述

代码

\\top.v
`timescale 1ns / 1ps
               
module fsm(
		input wire sclk,
		input wire rst_n,
		input wire [2:0]pi_money,
		output reg	[2:0]po_cola,
		output reg  [2:0]po_money
);

reg [5:0] state;
parameter IDLE	   =6'b000001;
parameter S1	   =6'b000010;
parameter S2 	   =6'b000100; 
parameter S3      =6'b001000;
parameter S4	   =6'b010000;
parameter S5	   =6'b100000;

always@(posedge sclk or negedge rst_n)
		if(!rst_n)
		state<=IDLE;
		else case(state)
			IDLE:	if(pi_money == 2'b01)
			     state <= S1;
					else if(pi_money == 2'b10)
						state<=S2;
					else if(pi_money == 3'b101)
                          state<=S5;                         	
					else state <= IDLE;
			S1:	if(pi_money == 2'b01)
					   state<=S2;
					else if(pi_money == 2'b10)
                            state<=S3;
                    else if(pi_money == 3'b101)
                           state<=S5;    
                    else state <= S1;
			S2:	if(pi_money == 2'b01)
					   state <= S3;
					else if(pi_money == 2'b10)
                        state<=S4;
                    else if(pi_money == 3'b101)
                            state<=S5;    
                    else state <= S2;
			S3:	if(pi_money == 2'b00)
						state<=S3;
				else if(pi_money == 2'b01)
                        state<=S4;
                else state <= S5;
			S4:	if(pi_money == 2'b00)
					state<=S4;			    
                else state <= S5;	
            S5: if(pi_money == 2'b01)
                   state<=S1;
                else if(pi_money == 2'b10)
                    state<=S2;
                else if(pi_money == 3'b101)
                     state<=S5;
                else state <= IDLE; 			
			default:state<=IDLE;	
			endcase
			
always@(posedge sclk or negedge rst_n)
	if(!rst_n)
		po_cola<=1'b0;
		else if((state == S3&&pi_money==2'b10)||(pi_money== 3'b101))
			po_cola<=1'b1;
		//else if(state == S5 && pi_money == 3'b101)
		//	po_cola=2'b10;			
		else
			po_cola<=1'b0;   //
			
always@(posedge sclk or negedge rst_n)
		if(!rst_n)
		po_money<=1'b0;
		else if((state == S1&&pi_money == 3'b101)||(state == S4&&pi_money == 3'b10))
			po_money<=1'b1;	
		else if((state == S2&&pi_money == 3'b101))
             po_money<=2'b10;
        else if(state == S3&&pi_money == 3'b101)
              po_money<=2'b11;
        else if(state == S4&&pi_money == 3'b101)
             po_money<=3'b100;                            
		else po_money<=1'b0;
endmodule
\\testbench
`timescale 1ns / 1ps
//
// Company: 
// Engineer: 
// 
// Create Date: 2019/03/29 20:46:57
// Design Name: 
// Module Name: tb
// Project Name: 
// Target Devices: 
// Tool Versions: 
// Description: 
// 
// Dependencies: 
// 
// Revision:
// Revision 0.01 - File Created
// Additional Comments:
// 
//
`timescale 1ns/1ns
module	tb();
		reg 	sclk;
		reg 	rst_n;
		reg 	[2:0]pi_money;
		wire	[2:0]po_cola;
		wire  	[2:0]po_money;

initial
		begin
			sclk=0;
			rst_n=1;
			pi_money=0;
			#20
			rst_n=0;
			#20
            rst_n=1;
			#20
			pi_money=0;
			#20
            pi_money=1;
            #20
            pi_money=2;
            #20
            pi_money=2;
            #20
            pi_money=5;
            #20
            pi_money=1;
            #20
            pi_money=5;
            #20
            pi_money=2;
            #20
            pi_money=5;
            #20
            pi_money=0;                                                                                    
		end
		
always # 10 sclk=~sclk;
//always # 50 pi_money={$random}%8;

fsm fsm_cola_ctrl_inst(
		.sclk			(sclk		),
		.rst_n			(rst_n		),
		.pi_money		(pi_money	),
		              
		.po_cola		(po_cola	),
		. po_money      ( po_money  )
);
endmodule

仿真结果

在这里插入图片描述由于我用的
仿真是正确的

总结

虽然我这里写了三个always,但我觉得这仍然是两段式,一个描述状态转移及转移条件,一个描述输出结果,也就是逻辑组合。
但我总觉得自己的写法很繁琐,本来S5的状态转移是

S5<=IDLE;

但是仿真结果显示,不能在S5的状态下判断付的钱,从而不能正确输出,所以改成了上面的代码
如果错误,希望大家批评指正。
多多交流哦~

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值