
This project implements a programmable clock generator that produces a wide range of output frequencies from a fixed 50 MHz input clock.
The output frequency is controlled using two inputs:
ui_in[3:0]): selects a multiplier value from 1 to 9ui_in[5:4]): selects the frequency range
00 → 100 Hz base (output: 100 Hz – 900 Hz)01 → 1 kHz base (output: 1 kHz – 9 kHz)10 → 10 kHz base (output: 10 kHz – 90 kHz)11 → 100 kHz base (output: 100 kHz – 900 kHz)Based on these inputs, a precomputed division factor N is selected using combinational logic. N represents the number of input clock cycles per half-period of the output clock.
The output frequency is:
f_out = f_in / (2 × N)
where N is precomputed as:
N = 50,000,000 / (2 × radix × scale_base)
To ensure glitch-free operation during dynamic changes:
N_next) is computed continuously in combinational logicN_reg) only when the counter resets to zero, ensuring updates happen only at a safe half-period boundaryAn 18-bit counter increments every clock cycle:
N_reg - 1, it resets to zeroThis generates a stable 50% duty-cycle square wave output.
Key features:
The TinyTapeout top module maps:
ui_in[3:0] → radixui_in[5:4] → scaleuo_out[0] → clock outputAll unused IOs are safely tied off.
Apply clock and reset:
clkrst_n = 0 to reset (counter, clk_out, and N_reg all cleared)rst_n = 1 to startSet control inputs:
ui_in[3:0]ui_in[5:4]Observe output:
uo_out[0]Verify behavior:
Vivado simulation results confirming that the generated output frequencies closely match the expected values across all radix–scale combinations.
All 36 radix–scale combinations were verified using simulation at 50 MHz input clock.
The measured frequencies closely match expected values, with errors under 1%, confirming accurate and stable operation.
No external hardware is required.
| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | radix 0 | clock | |
| 1 | radix 1 | ||
| 2 | radix 2 | ||
| 3 | radix 3 | ||
| 4 | scale 0 | ||
| 5 | scale 1 | ||
| 6 | |||
| 7 |