
We gratefully acknowledge the Center of Excellence (CoE) in Integrated Circuits and Systems (ICAS) and the Department of Electronics and Communication Engineering (ECE) for providing the necessary resources and guidance. Special thanks to Dr. K R Usha Rani (Associate Dean - PG), Dr. H V Ravish Aradhya (HOD-ECE), Dr. K. S. Geetha (Vice Principal) and Dr. K. N. Subramanya (Principal) for their constant encouragement and support to carry out this Tiny Tapeout SKY25A submission.
The tt_um_pwe module is a Pulse Width Encoder (PWE) designed to generate a digital pulse of programmable width based on user-controlled input signals. This module receives a 4-bit width value along with control signals (start and enable) and responds by generating a pulse_out signal that remains high for the specified number of clock cycles. Upon completion, it raises a done flag for one clock cycle to indicate the end of the pulse generation sequence.
At the heart of the module is a Finite State Machine (FSM) that coordinates the pulse generation sequence across three well-defined states: IDLE, COUNTING, and DONE. This enables the design to operate predictably and synchronously, even when integrated into larger digital systems. The design is clock-driven and fully synchronous, with a global asynchronous active-low reset (rst_n) to initialize the internal states.
ui_in (8 bits):
ui_in[0] - start: Initiates the pulse generation cycle when high.ui_in[1] - enable: Must be high in conjunction with start to trigger the pulse.ui_in[5:2] - data_in: 4-bit value specifying the pulse width (in clock cycles).ui_in[6], ui_in[7] - Unused; internally tied off to suppress lint warnings.uio_in (8 bits): General-purpose I/O input (not used in this design).
clk - Clock signal for all sequential logic.
rst_n - Active-low asynchronous reset.
uo_out (8 bits):
uo_out[0] - pulse_out: High during the pulse generation phase.uo_out[1] - done: High for one cycle after the pulse completes.uo_out[7:2] - Unused; set to zero.uio_out, uio_oe (8 bits each): Not used; tied to zero to act as high-impedance inputs.
The FSM governs the behavior of the module with the following states:
IDLE:
start and enable signals.data_in and stores it in the internal counter.COUNTING state.COUNTING:
pulse_out high.counter on each clock cycle.counter reaches zero, transitions to the DONE state.DONE:
pulse_out and sets done high for a single clock cycle.IDLE.This sequencing ensures precise pulse generation, avoids glitches, and guarantees a clean done signal after pulse completion.
data_in determines the number of clock cycles the pulse_out remains high.counter register is initialized with data_in and decremented every cycle in the COUNTING state.clk signal.rst_n is low:
IDLE.counter, pulse_width, pulse_out, and done are cleared to zero.uio_in, ui_in[6], ui_in[7]) are logically consumed using a bitwise AND expression to suppress unused signal warnings.uio_out, uio_oe) are set to zero.To validate the tt_um_pwe design, a testbench (tt_um_pwe_tb.v) is used to simulate various scenarios where different pulse widths are provided. The testbench monitors the outputs pulse_out and done and checks their timing against the expected behavior.
| Time (ns) | ui_in[5:2] (Pulse Width) | start | enable | Expected Behavior |
|---|---|---|---|---|
| 0 – 10 | 0000 (0) | 0 | 0 | No operation |
| 10 – 30 | 0100 (4) | 1 | 1 | 4-cycle pulse, then done |
| 30 – 60 | 0011 (3) | 1 | 1 | 3-cycle pulse, then done |
| 60 – 90 | 0001 (1) | 1 | 1 | 1-cycle pulse, then done |
| 90 – 100 | 0000 | 0 | 0 | Remains in IDLE |
During each simulation cycle:
pulse_out should remain high for data_in number of clock cycles.done should pulse high for exactly one cycle after pulse_out deasserts.During simulation, real-time debugging and waveform inspection help verify that the FSM and counter logic work as intended.
Use the following $monitor statement in the testbench:
initial begin
$monitor("Time=%0t | start=%b enable=%b data_in=%b | pulse_out=%b done=%b",
$time, ui_in[0], ui_in[1], ui_in[5:2], pulse_out, done);
end
| # | Input | Output | Bidirectional |
|---|---|---|---|
| 0 | ui_in[0] | uo_out[0] | |
| 1 | ui_in[1] | uo_out[1] | |
| 2 | ui_in[2] | ||
| 3 | ui_in[3] | ||
| 4 | ui_in[4] | ||
| 5 | ui_in[5] | ||
| 6 | |||
| 7 |