FPGA学习实现可乐机

可乐售货机

状态转换图

在这里插入图片描述

代码

可乐机代码

module vent (
    input wire clk,
    input wire rst_n,
    input wire [1:0]in_money,
    output reg [2:0]out_money,
    output reg out_cola
);
    
parameter IDLE = 4'b0000,
          S0 = 4'b0001,
          S1 = 4'b0011,
          S2 = 4'b0010,
          S3 = 4'b0110,
          S4 = 4'b0111,
          S5 = 4'b0101,
          S6 = 4'b0100;

reg [31:0]state;

//状态转移,可乐价格为3.5元
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        state <= IDLE;
    end
    else case (state)
        IDLE:begin
            if (in_money == 2'b00) begin
                state <= S0;
            end
            else if (in_money == 2'd01) begin
                state <= S1;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end 
        S0:begin
            if (in_money == 2'b00) begin
                state <= S1;
            end
            else if (in_money == 2'd01) begin
                state <= S2;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end 
        S1:begin
            if (in_money == 2'b00) begin
                state <= S2;
            end
            else if (in_money == 2'd01) begin
                state <= S3;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end 
        S2:begin
            if (in_money == 2'b00) begin
                state <= S3;
            end
            else if (in_money == 2'd01) begin
                state <= S4;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end
        S3:begin
            if (in_money == 2'b00) begin
                state <= S4;
            end
            else if (in_money == 2'd01) begin
                state <= S5;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end
        S4:begin
            if (in_money == 2'b00) begin
                state <= S5;
            end
            else if (in_money == 2'd01) begin
                state <= S6;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end
        S5:begin
            if (in_money == 2'b00) begin
                state <= S6;
            end
            else if (in_money == 2'd01) begin
                state <= S6;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end
        S6:begin
            if (in_money == 2'b00) begin
                state <= S0;
            end
            else if (in_money == 2'd01) begin
                state <= S1;
            end
            else if (in_money == 2'd11) begin
                state <= IDLE;
            end
            else begin
                state <= state;
            end
        end
        default: state <= IDLE;
    endcase
end

//结果输出
always @(posedge clk or negedge rst_n) begin
    if (~rst_n) begin
        out_money <= 3'd0;//有7种退钱可能,用3位表示
        out_cola <= 1'b0;
    end
    else case (state)
        IDLE:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end 
        S0:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd1;//退0.5
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end 
        S1:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd2;//退1
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end 
        S2:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd3;//退1.5
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end
        S3:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd4;//退2
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end
        S4:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd5;//退2.5
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end
        S5:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b1;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd1;//退0.5
                out_cola <= 1'b1;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd6;//退3
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end
        S6:begin
            if (in_money == 2'b00) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd01) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else if (in_money == 2'd11) begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
            else begin
                out_money <= 3'd0;
                out_cola <= 1'b0;
            end
        end
        default: begin
            out_money <= 3'd0;
            out_cola <= 1'b0;
        end
    endcase
end
endmodule

tb文件

`timescale 1ns/1ps

module vent_tb ();
    
reg clk;
reg rst_n;
reg [1:0]in_money;
wire [2:0]out_money;
wire out_cola;

initial begin
    clk = 1'b0;
    rst_n = 1'b0;
    in_money = 2'b11;
    #2
    rst_n = 1'b1;
end

always #10 clk = ~clk;
always #20.1 in_money = {$random} % 4;

defparam vent_1.IDLE = "IDLE";
defparam vent_1.S0 = "S0";
defparam vent_1.S1 = "S1";
defparam vent_1.S2 = "S2";
defparam vent_1.S3 = "S3";
defparam vent_1.S4 = "S4";
defparam vent_1.S5 = "S5";
defparam vent_1.S6 = "S6";



vent vent_1(
    .clk(clk),
    .rst_n(rst_n),
    .in_money(in_money),
    .out_money(out_money),
    .out_cola(out_cola)
);

endmodule

仿真结果

在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
实现自动售货(Vending Machine)的主要任务是在用户按下按钮并投入硬币或代币后,选择商品并将其吐出。以下是一种基本的 FPGA(Field Programmable Gate Array)实现自动售货的概念介绍。 FPGA是一个可编程的硬件设备,允许开发人员根据特定需求设计和实现逻辑电路。自动售货FPGA 实现主要涉及到以下几个关键部分: 1. **硬件接口**:这部分主要负责与用户交互,包括按钮识别和硬币或代币的投入检测。这些通常通过模拟电路实现,如光耦和电阻网络。 2. **计数器**:用于跟踪投入的硬币或代币的数量。这可以通过 FPGA 的计数器模块实现。 3. **商品选择逻辑**:这部分负责根据用户投入的硬币或代币的数量和种类,选择相应的商品。这通常涉及到一系列的逻辑门和查找表。 4. **出货制**:这部分负责将选定的商品吐出。这可能涉及到 FPGA 的 D/A 转换器和输出驱动器模块。 5. **状态指示**:通过 LED 或 LCD 显示当前的状态,如是否有商品可选,以及选定的商品等信息。 具体的实现会根据自动售货的具体需求和设计规范有所不同。在 FPGA实现自动售货需要硬件设计和编程技能,以及对自动售货的深入理解。此外,还需要考虑一些额外的因素,如硬币或代币的防伪措施、故障保护等。 值得注意的是,FPGA 是一种非常强大的工具,但也需要一定的时间和资源来设计和实现。对于初学者来说,可能需要从更简单的项目开始,逐步提高难度。 最后,实现自动售货是一个复杂的过程,需要硬件设计、软件编程、电子工程和市场营销等多方面的知识和技能。如果你对此有兴趣,我建议你查阅相关的专业书籍和在线资源,以获取更多的信息和指导。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值