Skip to content
code0.HDL

29Implementation

Latch a PWM duty at the period boundary

Problem

Intended behavior. PwmLatch produces a pulse-width modulated signal with a period of eight cycles. count runs 0 to 7 and wraps, and pwm is high while count < level. For level from 0 to 8, level is the number of high cycles in a period; any larger value also keeps pwm high for all eight cycles. level must not follow duty directly. It loads duty only at the edge that ends a period, where count goes from 7 back to 0, so a change of duty in the middle of a period takes effect from the next period. Reset clears both count and level.

Current behavior. The starter never updates level, so pwm stays low.

Your task. Replace the TODO line with the update for level. Keep the ports, count, last, the pwm line, and the public bench.

Read and predict

The public bench records a waveform. It pokes duty to 3, runs four periods while counting the high cycles of pwm in each, and changes duty to 6 in the middle of period 3. It prints one PERIOD line per period, then copies the VCD to dump.vcd, and the lab shows the waveform below the output.

Before running, predict the four PERIOD lines of a correct design. Period 1 needs care: decide what level holds during the first period after reset. Then run the starter and open the waveform.

Read the waveform

Look for count, last, level, io_duty, and io_pwm. Ports and retained internal signals appear in the VCD; a Scala val alone does not guarantee that a separate signal survives optimization. Check three points:

  • io_duty changes between rising edges, at the time of the poke, in the middle of period 3.
  • level may change only at the rising edge where count returns to 0, the edge that ends the cycle in which last is high.
  • For level from 1 to 7, io_pwm falls at the edge where count reaches level. At 0 it stays low; at 8 or above it stays high for the whole period.

In the starter, level is a flat line at 0. After your fix, compare where it moves with where io_duty moves.

Completion check

  • pwm is high for exactly level cycles of each period, counted from count = 0, for every duty from 0 to 8, and for the whole period above 8.
  • A duty change at any point inside a period affects only the next period. If duty changes several times in one period, only its value on the last cycle counts.
  • The first period after reset runs with level 0, and a reset clears level again.

Hints

Hint 1

The waveform already shows last, a signal that is high for exactly one cycle per period. Ask which edge ends that cycle.

Hint 2

Guard the update of level with last. A register assigned inside a when keeps its value on every other edge.

Concept

A shadow register that loads only at a boundary keeps each period consistent, whatever the input does in between. A waveform shows that property directly: the input moves in the middle of a period, while the register moves only at period boundaries.

Variation

Load level when count === 0.U instead. Predict the four PERIOD lines and the edges where level changes in the waveform, and explain why the first cycle of every period now uses the previous duty.

Review this concept
Ready

CheerpJ runs Chisel in your browser. A cold Run downloads about 14.5 MB of Java and 47 MB of JARs. Compilation can take a minute. Licenses

Main.scala