0
0
VerilogHow-ToBeginner · 4 min read

Verilog Code for Vending Machine FSM: Example and Syntax

A vending machine FSM in Verilog uses states to track inserted coins and dispense products. You define states with parameter, use a case statement inside an always block for transitions, and output signals based on the current state.
📐

Syntax

The vending machine FSM in Verilog typically uses parameter to define states, an always @(posedge clk or posedge reset) block for state transitions, and a case statement to handle each state. Outputs are assigned based on the current state and inputs.

  • parameter: Defines named states for clarity.
  • reg state, next_state: Hold current and next states.
  • always block: Updates state on clock or reset.
  • case statement: Controls transitions and outputs.
verilog
module vending_machine_fsm(
    input clk,
    input reset,
    input coin_5,
    input coin_10,
    output reg dispense,
    output reg [1:0] change
);

    // State encoding
    parameter S0 = 2'b00; // 0 cents
    parameter S5 = 2'b01; // 5 cents
    parameter S10 = 2'b10; // 10 cents
    parameter S15 = 2'b11; // 15 cents or more

    reg [1:0] state, next_state;

    // State register
    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= S0;
        else
            state <= next_state;
    end

    // Next state logic and output
    always @(*) begin
        dispense = 0;
        change = 2'b00;
        case(state)
            S0: begin
                if (coin_5)
                    next_state = S5;
                else if (coin_10)
                    next_state = S10;
                else
                    next_state = S0;
            end
            S5: begin
                if (coin_5)
                    next_state = S10;
                else if (coin_10)
                    next_state = S15;
                else
                    next_state = S5;
            end
            S10: begin
                if (coin_5) begin
                    dispense = 1;
                    change = 2'b00;
                    next_state = S0;
                end else if (coin_10) begin
                    dispense = 1;
                    change = 2'b01; // 5 cents change
                    next_state = S0;
                end else
                    next_state = S10;
            end
            S15: begin
                dispense = 1;
                change = 2'b10; // 10 cents change
                next_state = S0;
            end
            default: next_state = S0;
        endcase
    end

endmodule
💻

Example

This example shows a simple vending machine FSM that accepts 5 and 10 cent coins. It dispenses a product when 15 cents or more is reached and returns change if needed.

verilog
module vending_machine_fsm(
    input clk,
    input reset,
    input coin_5,
    input coin_10,
    output reg dispense,
    output reg [1:0] change
);

    parameter S0 = 2'b00;
    parameter S5 = 2'b01;
    parameter S10 = 2'b10;
    parameter S15 = 2'b11;

    reg [1:0] state, next_state;

    always @(posedge clk or posedge reset) begin
        if (reset)
            state <= S0;
        else
            state <= next_state;
    end

    always @(*) begin
        dispense = 0;
        change = 2'b00;
        case(state)
            S0: begin
                if (coin_5)
                    next_state = S5;
                else if (coin_10)
                    next_state = S10;
                else
                    next_state = S0;
            end
            S5: begin
                if (coin_5)
                    next_state = S10;
                else if (coin_10)
                    next_state = S15;
                else
                    next_state = S5;
            end
            S10: begin
                if (coin_5) begin
                    dispense = 1;
                    change = 2'b00;
                    next_state = S0;
                end else if (coin_10) begin
                    dispense = 1;
                    change = 2'b01;
                    next_state = S0;
                end else
                    next_state = S10;
            end
            S15: begin
                dispense = 1;
                change = 2'b10;
                next_state = S0;
            end
            default: next_state = S0;
        endcase
    end

endmodule
⚠️

Common Pitfalls

Common mistakes when coding a vending machine FSM in Verilog include:

  • Not resetting the state properly, causing undefined behavior.
  • Forgetting to assign outputs in all states, which can cause latches.
  • Mixing combinational and sequential logic incorrectly, leading to glitches.
  • Not handling invalid inputs or states explicitly.

Always use a reset signal to initialize the FSM and assign default values to outputs in the always @(*) block.

verilog
/* Wrong: Missing default output assignments causes latches */
always @(*) begin
    case(state)
        S0: dispense = 0;
        S10: dispense = 1;
        // Missing dispense assignment in other states
        default: dispense = 0;
    endcase
end

/* Right: Assign default output to avoid latches */
always @(*) begin
    dispense = 0;
    case(state)
        S0: dispense = 0;
        S10: dispense = 1;
        default: dispense = 0;
    endcase
end
📊

Quick Reference

Key tips for vending machine FSM in Verilog:

  • Use parameter to name states clearly.
  • Use synchronous reset to initialize state.
  • Assign default values to outputs in combinational blocks.
  • Use case statements for clear state transitions.
  • Test all input combinations to avoid unexpected states.

Key Takeaways

Define clear states using parameters for readability and maintenance.
Use synchronous reset to start the FSM in a known state.
Assign default output values in combinational logic to prevent latches.
Use case statements inside always blocks for clean state transitions.
Test your FSM thoroughly with all input combinations to ensure correct behavior.