A SystemVerilog implementation of a clock frequency divider that divides the input clock by 3 while maintaining a 50% duty cycle output.
- Overview
- Features
- Architecture
- Getting Started
- Simulation Results
- File Structure
- Usage
- Verification
- Contributing
- License
This project implements a digital clock divider that converts an input clock frequency to 1/3 of the original frequency while maintaining a precise 50% duty cycle. The design uses a dual counter architecture to achieve the desired timing characteristics.
Key Specifications:
- Input Frequency: Any frequency (tested with 100 MHz)
- Output Frequency: Input frequency Γ· 3 (33.33 MHz for 100 MHz input)
- Duty Cycle: 50% Β±1%
- Resource Usage: 4 flip-flops + combinational logic
- Precise Frequency Division: Exact 1:3 frequency ratio
- 50% Duty Cycle: Maintains equal high and low periods
- Low Resource Usage: Only 4 flip-flops required
- Robust Design: Includes proper reset handling and safe defaults
- Comprehensive Verification: Full testbench with automated testing
The design uses a dual counter architecture to achieve 50% duty cycle:
βββββββββββββββ
clk βββΊβ Counter 1 ββββ
β (pos edge) β β
βββββββββββββββ β
βββ OR βββΊ y (output)
βββββββββββββββ β
clk βββΊβ Counter 2 ββββ
β (neg edge) β
βββββββββββββββ
- Counter 1: Triggered on positive clock edges, cycles through states 0β1β2β0
- Counter 2: Triggered on negative clock edges, cycles through states 1β2β0β1 (180Β° offset)
- Output Generation: OR gate combines both counter outputs
- Result: 50% duty cycle at 1/3 input frequency
The following diagram illustrates the divide-by-3 operation with 50% duty cycle:
Hand-drawn timing diagram showing input clock cycles 1-12 and the resulting output with 50% duty cycle
RTL schematic showing the dual counter implementation with state machines, registers, and output logic
- Vivado 2020.1 or later (or any SystemVerilog-compatible simulator)
- SystemVerilog support
- Basic knowledge of digital design
-
Clone the repository:
git clone https://github.com/kamberasaf/divide-by-3-clock-divider.git cd divide-by-3-clock-divider
-
Open in Vivado:
- Create new project
- Add
src/top.sv
as design source - Add
sim/tb.sv
as simulation source
-
Run Simulation:
- Set simulation runtime to at least 2ms (Vivado defaults to 1000ns)
- Run behavioral simulation
- Observe test results in console
The testbench performs comprehensive verification:
-----------------------------------------
FREQUENCY TEST
-----------------------------------------
Sample Time: 500 ns
Edges Counted: 17
Expected Freq: 33.33 MHz
Measured Freq: 34.00 MHz
Error: 2.00%
Result: β PASS
-----------------------------------------
DUTY CYCLE TEST
-----------------------------------------
Measuring over 10 periods...
Periods Measured: 10
Total High Time: 150 ns
Total Period Time: 300 ns
Expected Duty Cycle: 50.0%
Measured Duty Cycle: 50.00%
Error: 0.00%
Result: β PASS
divide-by-3-clock-divider/
βββ README.md # This file
βββ LICENSE # License file
βββ docs/ # Documentation
β βββ architecture.md # Detailed architecture documentation
βββ src/ # Source files
β βββ top.sv # Main design module
βββ sim/ # Simulation files
β βββ tb.sv # Comprehensive testbench
βββ scripts/ # Automation scripts
β βββ run_sim.tcl # Vivado simulation script
βββ images/ # Documentation images
βββ timing_diagram.jpg # Hand-drawn timing explanation
βββ rtl_schematic.png # Vivado synthesized schematic
βββ simulation_waveform.png # Vivado simulation results
dev_3 my_divider (
.clk(input_clock), // Input clock (any frequency)
.rst(reset_signal), // Active high reset
.y(divided_clock) // Output: f_in/3, 50% duty cycle
);
- Input Clock: Any frequency up to device limits
- Reset: Active high, synchronous release
- Output: Frequency = f_input/3, Duty cycle = 50%
The project includes comprehensive verification:
- Frequency Measurement: Verifies 1:3 frequency division
- Duty Cycle Analysis: Confirms 50% duty cycle over multiple periods
- Reset Functionality: Tests proper reset behavior
- Error Tolerance: Configurable pass/fail criteria
- β Frequency division accuracy
- β Duty cycle precision
- β Reset synchronization
- β State machine transitions
- β Output generation logic
# In Vivado Tcl Console
source scripts/run_sim.tcl
Contributions are welcome! Please feel free to submit a Pull Request.
- Follow existing code style and formatting
- Add appropriate comments and documentation
- Include test cases for new features
- Update README.md if needed
This project is licensed under the MIT License - see the LICENSE file for details.
Asaf Kamber
- GitHub: @kamberasaf
- Thanks to the digital design community for best practices
- Inspired by classic frequency divider architectures
β Star this repository if you find it helpful!