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

Basic Pulse Width Modulator

EasyVerilog / SystemVerilogBuild

Digital control of analog systems like LEDs and motors relies on pulse width modulation (PWM) to approximate continuous voltage levels using discrete digital switching. A PWM generator translates a digital duty cycle value into a high-frequency switching signal, allowing a microcontroller to dim a light or control motor speed without a digital-to-analog converter.

The module maintains a free-running 8-bit internal counter that increments on every clock cycle. It compares this counter against the requested 8-bit duty cycle. When the counter is strictly less than the duty cycle, the output is driven high. When the counter reaches or exceeds the duty cycle, the output is driven low. To ensure true 0% and 100% states, a duty cycle of 8'd0 must force the output to 0 continuously, and a duty cycle of 8'd255 must force the output to 1 continuously.

Clock edge: posedge clk Reset type: Asynchronous Reset polarity: Active-low (rst_n) Output values on reset: The internal counter is cleared to 8'd0 and pwm_out is driven to 1'b0. Priority rules: Reset takes priority over all other operations. Both the internal counter and pwm_out are updated on the positive edge of clk. During this update, pwm_out is evaluated using the counter's value *before* it increments.

Worked Trace: Cycle 1: rst_n=0 → cnt=0, pwm_out=0 (async reset) Cycle 2: rst_n=1, duty=2 → cnt=1, pwm_out=1 (evaluates 0 < 2) Cycle 3: duty=2 → cnt=2, pwm_out=1 (evaluates 1 < 2) Cycle 4: duty=2 → cnt=3, pwm_out=0 (evaluates 2 >= 2) Cycle 5: duty=2 → cnt=4, pwm_out=0 (evaluates 3 >= 2)

{ "signal": [
  { "name": "clk",     "wave": "p........" },
  { "name": "rst_n",   "wave": "01......." },
  { "name": "duty",    "wave": "=========...", "data": ["2","2","2","2","2","2","2","2","2"] },
  { "name": "cnt",     "wave": "=.=.=.=.=.=.=.=.", "data": ["0","1","2","3","4","5","6","7"] },
  { "name": "pwm_out", "wave": "0.1...0........." }
], "head": { "text": "PWM generation with duty=2." } }

| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; clears counter and output to 0 | | duty | input | 8 | Desired duty cycle (0 to 255) | | pwm_out | output | 1 | Registered PWM output |

Constraints

  • clk is positive-edge triggered.
  • rst_n is asynchronous and active-low.
  • On reset, the internal counter must be 8'd0 and pwm_out must be 1'b0.
  • pwm_out must be a registered output, updating on the same clock edge that the counter increments.
  • If duty is 8'd0, pwm_out must remain 1'b0 continuously.
  • If duty is 8'd255, pwm_out must remain 1'b1 continuously.
  • The 8-bit counter naturally wraps from 255 to 0; no explicit reset of the counter is needed at 255.

Topics

CountersInterfacesPWM

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