可乐售卖机——手撕代码

目录

1 mealy与moore区分

2 Moore型状态机

3 Mealy型:


1 mealy与moore区分

问题:可乐机每次只能投入 1 枚 1 元硬币,且每瓶可乐卖 3 元钱,即投入 3 个硬币就可以让可乐机出可 乐,如果投币不够 3 元想放弃投币需要按复位键,否则之前投入的钱不能退回。

2 Moore型状态机

//==================================================================
//-- 3段式状态机(Moore)
//==================================================================
//------------<模块及端口声明>----------------------------------------
module FSM_Moore_3(
input sys_clk , //输入系统时钟、50M
input sys_rst_n , //复位信号、低电平有效
input money , //投币输入,高电平有效
output reg cola //可乐输出,高电平有效
);
//------------<状态机参数定义>------------------------------------------
localparam IDLE = 4'b0001,
ONE = 4'b0010,
TWO = 4'b0100,
THREE = 4'b1000;
//------------<reg定义>-------------------------------------------------
reg [3:0] cur_state; //定义现态寄存器
reg [3:0] next_state; //定义次态寄存器
//-----------------------------------------------------------------------
//--状态机第一段:同步时序描述状态转移
//-----------------------------------------------------------------------
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cur_state <= IDLE; //复位初始状态
    else
        cur_state <= next_state; //次态转移到现态
    end
//-----------------------------------------------------------------------
//--状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
//-----------------------------------------------------------------------
always@(*)begin
    case(cur_state) //组合逻辑
//根据当前状态、输入进行状态转换判断
        IDLE:begin
            if(money)
                next_state = ONE; //投币1元,则状态转移到ONE
            else
                next_state = IDLE; //没有投币,则状态保持
            end
        ONE:begin
            if(money)
                next_state = TWO; //投币1元,则状态转移到TWO
            else
                next_state = ONE; //没有投币,则状态保持
            end
        TWO:begin
            if(money)
                next_state = THREE; //投币1元,则状态转移到THREE
            else
                next_state = TWO; //没有投币,则状态保持
            end
        THREE:begin
            if(money)
                next_state = ONE; //投币1元,则状态转移到ONE
            else
                next_state = IDLE; //没有投币,则状态保持
            end
        default:begin //默认状态同IDLE
            if(money)
                next_state = ONE;
            else
                next_state = IDLE;
            end
        endcase
end
//-----------------------------------------------------------------------
//--状态机第三段:时序逻辑描述输出
//-----------------------------------------------------------------------
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cola <= 1'b0; //复位、初始状态
    else
        case(cur_state) //根据当前状态进行输出
            IDLE: cola <= 1'b0; //无可乐输出
            ONE: cola <= 1'b0; //无可乐输出
            TWO: cola <= 1'b0; //无可乐输出
            THREE: cola <= 1'b1; //输出可乐
            default:cola <= 1'b0; //默认无可乐输出
        endcase
    end
endmodule    

3 Mealy型:

//==================================================================
//-- 3段式状态机(Mealy)
//==================================================================
//------------<模块及端口声明>----------------------------------------
module FSM_Mealy_3(
input sys_clk , //输入系统时钟、50M
input sys_rst_n , //复位信号、低电平有效
input money , //投币输入,高电平有效
output reg cola //可乐输出,高电平有效
);
//------------<状态机参数定义>------------------------------------------
localparam IDLE = 3'b0001,
ONE = 3'b0010,
TWO = 3'b0100;
//------------<reg定义>-------------------------------------------------
reg [3:0] cur_state; //定义现态寄存器
reg [3:0] next_state; //定义次态寄存器
//-----------------------------------------------------------------------
//--状态机第一段:同步时序描述状态转移
//-----------------------------------------------------------------------
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cur_state <= IDLE; //复位初始状态
    else
        cur_state <= next_state; //次态转移到现态
    end
//-----------------------------------------------------------------------
//--状态机第二段:组合逻辑判断状态转移条件,描述状态转移规律以及输出
//-----------------------------------------------------------------------
always@(*)begin
    case(cur_state) //组合逻辑
//根据当前状态、输入进行状态转换判断
        IDLE:begin
            if(money)
                next_state = ONE; //投币1元,则状态转移到ONE
            else
                next_state = IDLE; //没有投币,则状态保持
            end
        ONE:begin
            if(money)
                next_state = TWO; //投币1元,则状态转移到TWO
            else
                next_state = ONE; //没有投币,则状态保持
            end
        TWO:begin
            if(money)
                next_state = IDLE; //投币1元,则状态转移到IDLE
            else
                next_state = TWO; //没有投币,则状态保持
            end
        default:begin //默认状态同IDLE
            if(money)
                next_state = ONE;
            else
                next_state = IDLE;
            end
        endcase
end
//-----------------------------------------------------------------------
//--状态机第三段:时序逻辑描述输出
//-----------------------------------------------------------------------
always@(posedge sys_clk or negedge sys_rst_n)begin
    if(!sys_rst_n)
        cola <= 1'b0; //复位、初始状态
    else
        case(cur_state) //根据当前状态进行输出
            IDLE: cola <= 1'b0; //无可乐输出(因为输入不管是0、1都是输出0,所以省
略写法)
            ONE: cola <= 1'b0; //无可乐输出(因为输入不管是0、1都是输出0,所以省
略写法)
            TWO:begin
                if(money)
                    cola <= 1'b1; //如果输入1,则输出可乐
                else
                    cola <= 1'b0; //如果输入0,则无可乐输出
                end
            default:cola <= 1'b0; //默认无可乐输出
        endcase
    end
endmodule

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值