Practice
Synth Cutoff Dial
A music shop sells a build-it-yourself synthesizer kit. One knob sets the filter cutoff: turn it up and the sound gets brighter, turn it down and it goes dull. The panel chip reads the knob and hands this block an 8-bit value. The filter chip wants a smooth control voltage, not a number, so the board converts it with a PWM DAC. The block sends pulses: high for part of each period, low for the rest. An RC filter averages the pulses into a steady voltage, so a bigger value means a wider pulse and a higher voltage.
The first batch of kits had a fault. The old block copied each new knob value into its pulse logic right away, even in the middle of a period. The pulse under way changed width, and the filter voltage jumped instead of gliding. A slow turn of the knob played back as a row of soft clicks. Buyers called it zipper noise, and the kit's reviews turned sour.
Your task: build the PWM DAC block. Generate back-to-back periods of exactly 256 clock cycles each. Sample level once per period, at the period boundary, and hold the sampled value for the whole period. Drive pwm high for that many cycles at the start of the period, then low until the period ends. A sampled level of 0 keeps pwm low for the whole period. A sampled level of 255 is full scale: keep pwm high for the whole period.
Interface
| Port | Direction | Type | Description |
|---|---|---|---|
clk | in | 1 bit | System clock |
rst | in | 1 bit | Synchronous reset (active high) |
level | in | 8-bit vector | Requested output level |
pwm | out | 1 bit | Pulse output, to the board's RC filter |
Behavior
- Each period is exactly 256 clock cycles; periods run back to back with no gap
- Cycle numbering: cycle 0 is the first cycle of a period and cycle 255 is the last
- The
levelinput is sampled at the clock edge between cycle 255 and cycle 0 of the next period - The sampled value is fixed for the whole period it starts
- Changes on
levelin the middle of a period take effect at the next boundary, never inside the running period - For a sampled value L from 1 to 254,
pwmis high during cycles 0 to L-1 and low during cycles L to 255 - A sampled value of 0 keeps
pwmlow for the whole period - A sampled value of 255 is full scale:
pwmis high for all 256 cycles of the period - With this rule a duty of 255 out of 256 cannot occur; full scale buys a true always-high output instead
rsthigh at a rising clock edge restarts the period and clears the sampled value to 0- The first cycle after the last edge with
rsthigh is cycle 0 of a fresh period - The first period after reset runs with a sampled value of 0:
pwmstays low for that whole period
What the bench checks
- The testbench checks
pwmon every cycle of every period against the value sampled at that period's boundary - The testbench holds a nonzero
levelthrough reset and checks the first period after reset stays low - The testbench runs full periods at sampled values 0, 1, 64, 128, 165, 192, 254, and 255
- The testbench changes
levelin the middle of most periods and checks the running period never changes shape - The testbench raises
levelmid-period after the pulse has ended and checks no second pulse appears in that period - The testbench changes
leveltwice inside one period and checks the next period uses the value present at the boundary - The testbench asserts
rstin the middle of a high pulse and checkspwmis low on the next cycle - The testbench asserts
rston the exact edge where a period wraps, holds a nonzerolevel, and checks the next period stays low - The testbench counts cycles without a break across periods, so a period of 255 or 257 cycles fails
Constraints
everything is synchronous to clk; pwm changes only at clock edges.
this models the digital PWM generator only. The panel chip's knob reading, the RC filter, and the filter chip's analog side are out of scope.
Do not add ports.
Click Run to execute your code. Output will appear here.