- Project Overview
- Key Specifications
- Features
- Architecture
- State Machine Design
- Repository Structure
- Simulation
- FPGA Implementation Results
- Usage
- Design Highlights
- Author
This project implements a fully synthesizable vending machine controller using Verilog HDL, designed as a Mealy Finite State Machine (FSM). The controller manages coin acceptance, change calculation, and transaction cancellation with robust state management and clean RTL design principles.
Parameter | Value / Type |
---|---|
Item Price | 15 cents |
Accepted Coins | Nickel (5Β’), Dime (10Β’) |
FSM Architecture | 3-State Mealy Machine |
State Bits | 2 ([1:0] ) |
Reset Type | Active-Low Asynchronous |
HDL Standard | Verilog-2001 |
- High Performance: The Mealy FSM architecture ensures a minimal latency of a single clock cycle for all outputs.
- Robust & Synthesizable: Written in a strict two-process style with default assignments to guarantee a latch-free, reliable synthesis result for both FPGAs and ASICs.
- Intelligent Change Calculation: The logic automatically handles all overpayment scenarios and dispenses the correct change.
- Full User Control: A dedicated
cancel
input allows the user to abort the transaction and receive a full refund at any point. - Comprehensive Verification: The design is validated by a self-checking testbench that covers all state transitions and edge cases.
module vending_machine_mealy(
input wire clk, // System clock
input wire rst, // Active-low async reset
input wire nickel, // 5Β’ coin insert signal
input wire dime, // 10Β’ coin insert signal
input wire cancel, // Transaction cancel
output reg vend, // Item dispense signal
output reg change_5C, // 5Β’ change return
output reg change_10C // 10Β’ change return
);
The design follows industry-standard two-process FSM methodology:
- Sequential Process: State register updates on clock edge
- Combinational Process: Next-state and output logic computation
- Default Assignments: Prevents unintended latch synthesis
- Complete Case Coverage: Ensures deterministic behavior
State | Encoding | Amount | Description |
---|---|---|---|
S_0C |
2'b00 |
0Β’ | Initial/Idle state |
S_5C |
2'b01 |
5Β’ | Five cents accumulated |
S_10C |
2'b10 |
10Β’ | Ten cents accumulated |
stateDiagram-v2
direction TB
[*] --> S_0C : !rst
S_0C --> S_5C : N/000
S_0C --> S_10C : D/000
S_0C --> S_0C : C/000
S_5C --> S_10C : N/000
S_5C --> S_0C : D/100
S_5C --> S_0C : C/010
S_10C --> S_0C : N/100
S_10C --> S_0C : D/110
S_10C --> S_0C : C/001
Present State | Inputs | Next State | Outputs |
---|---|---|---|
ps[1:0] | {dime, nickel, cancel} | ns[1:0] | {vend, change_5C, change_10C} |
2'b00 (S_0C) |
3'b000 (none) |
2'b00 (S_0C) |
3'b000 |
2'b00 (S_0C) |
3'b001 (cancel) |
2'b00 (S_0C) |
3'b000 |
2'b00 (S_0C) |
3'b010 (nickel) |
2'b01 (S_5C) |
3'b000 |
2'b00 (S_0C) |
3'b100 (dime) |
2'b10 (S_10C) |
3'b000 |
2'b01 (S_5C) |
3'b000 (none) |
2'b01 (S_5C) |
3'b000 |
2'b01 (S_5C) |
3'b001 (cancel) |
2'b00 (S_0C) |
3'b010 |
2'b01 (S_5C) |
3'b010 (nickel) |
2'b10 (S_10C) |
3'b000 |
2'b01 (S_5C) |
3'b100 (dime) |
2'b00 (S_0C) |
3'b100 |
2'b10 (S_10C) |
3'b000 (none) |
2'b10 (S_10C) |
3'b000 |
2'b10 (S_10C) |
3'b001 (cancel) |
2'b00 (S_0C) |
3'b001 |
2'b10 (S_10C) |
3'b010 (nickel) |
2'b00 (S_0C) |
3'b100 |
2'b10 (S_10C) |
3'b100 (dime) |
2'b00 (S_0C) |
3'b110 |
2'b11 (Unused) |
3'bxxx |
2'b00 (S_0C) |
3'b000 |
*Note: The table assumes only one input is active at a time.
Output format: {vend, change_5C, change_10C}
vending-machine-rtl/
β
βββ π vending_machine_mealy.v # Main RTL module
βββ π vending_machine_mealy_tb.v # Comprehensive testbench
βββ π constraints.xdc # Timing constraints file
βββ π rtl_schematic.pdf # RTL schematic view
βββ π synthesized_schematic.pdf # Post-synthesis schematic
βββ π Power_Analysis_Result.png # Power consumption report
βββ π Behavioral_Simulation.png # Simulation waveforms
βββ π fpga_floorplan_overview.png # Complete FPGA floorplan
βββ π fpga_floorplan_detailed.png # Detailed placement view
βββ π fpga_slice_implementation.png # Slice-level implementation
βββ π README.md # This documentation
The testbench validates critical operational scenarios:
Test # | Description | Input Sequence | Expected Output |
---|---|---|---|
1 | Exact payment (N+D) | 5Β’ β 10Β’ | Vend item |
2 | Exact payment (D+N) | 10Β’ β 5Β’ | Vend item |
3 | Overpayment | 10Β’ β 10Β’ | Vend + 5Β’ change |
4 | Cancel after nickel | 5Β’ β Cancel | Return 5Β’ |
5 | Cancel after dime | 10Β’ β Cancel | Return 10Β’ |
=== Vending Machine Test Started ===
Item Price: 15 cents
Test 1: Nickel + Dime = 15 cents
<>Inserting Nickel (5c)...
Time=35 | State=01 | vend=0 change_5C=0 change_10C=0
<>Inserting Dime (10c)...
Time=55 | State=00 | vend=1 change_5C=0 change_10C=0
>>> Item dispensed
Test 3: Dime + Dime = 20 cents (expect 5c change)
<>Inserting Dime (10c)...
Time=135 | State=10 | vend=0 change_5C=0 change_10C=0
<>Inserting Dime (10c)...
Time=155 | State=00 | vend=1 change_5C=1 change_10C=0
>>> Item dispensed with 5c change
Resource | Used | Available | Utilization % |
---|---|---|---|
Slice LUTs | 5 | 20,800 | 0.024% |
Slice Registers | 2 | 41,600 | 0.005% |
Bonded IOB | 8 | 106 | 7.55% |
BUFGCTRL | 1 | 32 | 3.13% |
Parameter | Value | Status |
---|---|---|
Target Frequency | 100 MHz | β Met |
Setup Slack (WNS) | +0.592 ns | β Positive |
Hold Slack (WHS) | +0.146 ns | β Positive |
Parameter | Value |
---|---|
Total On-Chip Power | 72 mW |
Dynamic Power | 2 mW (3%) |
Static Power | 70 mW (97%) |
Junction Temperature | 25.4Β°C |
- RTL/Synthesized Schematics: Show the logical design structure and gate-level implementation
- Power Analysis: Demonstrates ultra-low power operation (72mW total) suitable for battery-powered applications
- FPGA Floorplan: Physical placement visualization on Artix-7 device showing efficient resource utilization
- Slice Implementation: Detailed view of actual LUT and flip-flop usage at the hardware level
- Verilog simulator (Icarus Verilog, ModelSim, Vivado, VCS)
- GTKWave or similar waveform viewer (optional)
- Synthesis tool for FPGA/ASIC implementation (optional)
# Clone the repository
git clone https://github.com/AyushVerma17/vending-machine-rtl.git
(Make sure you are in the same directory in which the project is)
# Compile the design
iverilog -o vend_mealy vending_machine_mealy.v vending_machine_mealy_tb.v
# Run simulation
vvp vend_mealy
# View waveforms (optional)
gtkwave vending_machine.vcd &
# Create work library
vlib work
# Compile sources
vlog vending_machine_mealy.v vending_machine_mealy_tb.v
# Start simulation
vsim -novopt work.vending_machine_mealy_tb
# Add signals to waveform
add wave -recursive *
# Run simulation
run -all
# π Create project
create_project -> vending_machine(Project_name) -> RTL Project (Do not specify resources at this time)
Parts -> category (General Purpose) -> Family(Artix-7) -> Package(cpg236) -> Speed(-1) -> xc7a35tcpg236-1
# β Add sources
Add Sources -> Add or create design sources -> Add_files -> vending_machine_mealy.v -> Save
Add Sources -> Add or create simulation sources -> Add_files -> vending_machine_mealy_tb.v -> Save
Add Sources -> Add or create constraints -> Create File -> constraints.xdc -> Add timing constraints
# π Add timing constraints to constraints.xdc file:
create_clock -period 10.0 -name sys_clk [get_ports clk]
set_input_delay -clock sys_clk 2.0 [get_ports {rst nickel dime cancel}]
set_output_delay -clock sys_clk 2.0 [get_ports {vend change_5C change_10C}]
# ποΈ RTL_View
RTL ANALYSIS -> Open Elaborated Design
# βΆοΈ Run simulation
SIMULATION -> Run Simulation -> Run Behavioral Simulation -> Check waveform window
# π§ Complete FPGA Implementation Flow
SYNTHESIS -> Run Synthesis -> Wait for completion
IMPLEMENTATION -> Run Implementation -> Wait for completion
# π Generate comprehensive reports
Reports -> Implementation -> Report Timing Summary -> Generate timing analysis
Reports -> Implementation -> Report Utilization -> Generate resource usage report
Reports -> Implementation -> Report Power -> Configure power settings -> Generate power report
# πΊοΈ View physical implementation
Layout -> Device -> View FPGA floorplan and placement
Layout -> Floorplanning -> Zoom in for detailed slice implementation
# π Key reports to check:
- Timing: Setup/Hold slack should be positive
- Utilization: Verify efficient resource usage
- Power: Check total on-chip power consumption
- Implementation: Confirm "All user specified timing constraints are met"
Target Specifications:
- Target frequency: 100 MHz (10ns period)
- Timing constraints: Defined in constraints.xdc
- Verified platform: Artix-7 xc7a35tcpg236-1
- Process corner: Commercial grade (-1 speed)
Validation Results:
- β No latch inference
- β Complete case statements
- β Synchronous design principles
- β Timing closure achieved (+0.592ns setup slack)
- β Hold timing met (+0.146ns hold slack)
- β All user-specified constraints satisfied
- Clean Coding Style: Follows industry-standard RTL coding guidelines
- Robust Design: Handles all edge cases with proper default assignments
- Maintainable: Well-commented code with clear separation of concerns
- Testable: Comprehensive testbench with task-based testing methodology
- Synthesizable: Optimized for both FPGA and ASIC implementation
- No Implicit Latches: Default assignments in combinational blocks
- Timing-Safe: Registered outputs prevent glitches
- Resource Efficient: Minimal state encoding (2 bits for 3 states)
- Scalable: Easy to extend for additional coin denominations
Ayush Verma B.Tech ECE, VIT
ayushverma.ayuv@gmail.com