CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Sequential Logic

Glitch Free PWM with Shadow Register

MediumVerilog / SystemVerilogBuild

Motor controllers and LED drivers rely on Pulse Width Modulation (PWM) to regulate power delivery. If a host processor updates the duty cycle configuration register exactly when the PWM counter is in the middle of a period, the comparator can produce a runt pulse or an unpredictable glitch, potentially damaging downstream power electronics.

A glitch-free PWM generator solves this by buffering the requested duty cycle in a shadow register. The module maintains a 4-bit free-running counter that increments every clock cycle. When the host provides a new duty cycle alongside a valid signal, the shadow register captures this value immediately. However, the active comparison register driving the PWM output only updates from the shadow register at the exact moment the counter rolls over from 15 to 0. This ensures the duty cycle only changes at the boundaries of the PWM period.

The module operates on the positive edge of clk and uses an asynchronous active-low reset rst_n. On reset, the counter, shadow register, and active register all clear to 0, resulting in a 0 output. The pwm_out signal is evaluated combinationally and is driven high strictly when the counter is less than the active duty cycle register.

Cycle 1: rst_n=0 → cnt=0, duty_shadow=0, duty_active=0, pwm_out=0 Cycle 2: rst_n=1, duty_valid=1, duty_in=3 → duty_shadow=3, duty_active=0, cnt=1, pwm_out=0 Cycle 3: duty_valid=0 → cnt=2, duty_shadow=3, duty_active=0, pwm_out=0 ... Cycle 16: cnt=15, duty_shadow=3, duty_active=0 → pwm_out=0 Cycle 17: cnt=0, duty_shadow=3, duty_active=3 → pwm_out=1 Cycle 18: cnt=1, duty_shadow=3, duty_active=3 → pwm_out=1 Cycle 19: cnt=2, duty_shadow=3, duty_active=3 → pwm_out=1 Cycle 20: cnt=3, duty_shadow=3, duty_active=3 → pwm_out=0

{ "signal": [
  { "name": "clk", "wave": "p...|....." },
  { "name": "rst_n", "wave": "01..|....." },
  { "name": "duty_valid", "wave": "010.|....." },
  { "name": "duty_in", "wave": "x3x.|....." },
  { "name": "cnt", "wave": "=.=.|..=..", "data": ["0", "1", "15", "0", "1", "2"] },
  { "name": "duty_shadow", "wave": "0.3.|....." },
  { "name": "duty_active", "wave": "0...|..3.." },
  { "name": "pwm_out", "wave": "0...|..1.." }
], "head": { "text": "Duty cycle updates at counter rollover" } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; all internal registers go to 0 | | duty_in | input | 4 | Requested duty cycle value | | duty_valid | input | 1 | When 1, captures duty_in into the shadow register on posedge clk | | pwm_out | output | 1 | Combinational output; 1 when cnt < duty_active, else 0 |

Constraints

  • The clock is positive-edge triggered and reset is asynchronous active-low.
  • The internal counter must be exactly 4 bits wide, rolling over from 15 to 0.
  • The active duty cycle register must only update from the shadow register on the exact clock edge where the counter transitions from 15 to 0.
  • pwm_out must be evaluated combinationally as cnt < duty_active.
  • If duty_valid and reset are asserted simultaneously, reset takes priority.

Topics

Sequential LogicRegistersInterfacesPWM

Solve this problem

Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.

This problem is part of Codiode Pro. The statement above is free to read.

Sign in to solveSee what Pro unlocks

The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.

Related problems

  • Basic D Flip FlopEasy
  • Debug: Missing Edge in Sensitivity ListMedium
  • Read After Write Hazard DetectionEasy
  • Parameterized Interface with ModportsHard
  • Struct Array PipelineHard
  • T Flip Flop from D Flip Flop TemplateEasy
  • Recursive Generate Reduction TreeHard
  • Four Stage Shift RegisterEasy

Browse all problems · Learning tracks