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

仿真结果

在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值