R2.3.1 The accumulator that added twice

EasyFixIcarus Verilog + Yosys · serverReview the topic

Fix an accumulator whose clock is gated with an AND, so that it takes each sample exactly once with the clock untouched and the enable inside the register.

Hardware context: A 12-bit accumulator of ADC samples with an enable. Fix the accumulator on an AND-gated clock that adds a sample twice.

An accumulator sums 8-bit samples from an ADC: ports clk, rst_n (asynchronous, active-low), en and din[7:0] in, sum[11:0] out. At every rising edge of clk where en is 1, din is added to sum. en and din come from flops clocked by clk, so they change just after a rising edge, while clk is still high. To save power the designer stopped the clock with an AND gate whenever there was nothing to add. In the lab the first sample of every burst was counted twice (lesson R2.3).

This is a Fix problem: the design below works except for one defect. Find it so that sum takes each sample exactly once, with one clock reaching the register.

Brief: one clock, clk, reaching every flop untouched; sum is 0 after reset and adds din at each edge where en is 1, one cycle of latency; corner cases: en rising while clk is high, en held for several edges, a step with en low. No latch. Synthesis check: the design must build on the site's synthesis flow with no latch. The cell and level counts come from an open-source flow and are a proxy for area and depth, not a foundry result.

Signals in the timeline

SignalWidthRole
script54input of each check
Full specification
The module (keep the name and the ports)
module acc12 (
  input  logic        clk,
  input  logic        rst_n,      // asynchronous, active-low
  input  logic        en,
  input  logic [7:0]  din,
  output logic [11:0] sum
);
  // your fix
endmodule
At a rising edge of clksum becomes
en is 1sum + din
en is 0sum (held)
rst_n is 0 (at any time)0

The tests reset the accumulator, then drive six steps of (en, din), each 1 ns after a rising edge while clk is high; step k is taken at the next edge. The result is sum after each step is taken: sum_after_step0 to sum_after_step5.

Examples

Example 1

Three samples in a row
Input
add 10, add 20, add 30, skip 0, skip 0, skip 0
Output
sum_after_step0 = 10, sum_after_step1 = 30, sum_after_step2 = 60, sum_after_step3 = 60, sum_after_step4 = 60, sum_after_step5 = 60

Each enabled step adds its sample once: 10, 30, 60, and the three skipped steps hold 60. The shipped accumulator adds the first 10 twice, once when en rises while clk is high and once at the edge, and reads 20, 40, 70.

Example 2

Samples with gaps
Input
add 5, skip 99, add 7, skip 99, skip 99, add 100
Output
sum_after_step0 = 5, sum_after_step1 = 5, sum_after_step2 = 12, sum_after_step3 = 12, sum_after_step4 = 12, sum_after_step5 = 112

The skipped samples (99) are never added: 5, 5, 12, 12, 12, 112. Every step where en goes from 0 to 1 is one where the shipped design adds twice.

Example 3

Starts idle
Input
skip 50, skip 60, add 1, add 2, skip 0, add 255
Output
sum_after_step0 = 0, sum_after_step1 = 0, sum_after_step2 = 1, sum_after_step3 = 3, sum_after_step4 = 3, sum_after_step5 = 258

Nothing is added while en is 0. Then 1, 2 and 255 add up to 258, which a 12-bit sum holds.

Constraints and contract

  • Samples never make sum overflow in the tests (at most six samples of 255).
  • Keep the module name and the ports.

Hints

Hint 1

Draw gclk for a step where en goes from 0 to 1 while clk is high. How many rising edges does the register see for that sample?

Hint 2

A register that should hold its value does not need its clock stopped: it needs its next value to be its old value.

Hint 3

Clock the register with clk and put en in the decision inside the clocked block: an enabled flop, built with a mux, not a gate in the clock.

What the grader checks: Seven directed and eight seeded scripts of six (en, din) steps are driven 1 ns after each rising edge, while clk is high, and sum is compared after every step with a model that adds each enabled sample once. The tests show the register takes each sample once with inputs that change as flop outputs do; a gate in the clock that happened to survive this timing is not ruled out by simulation, which is why the brief asks for one clock reaching every flop.

The submitted design must synthesize with 0 latches and no combinational loop. Counts come from the pinned open-source synthesis flow. They are proxies for logic size and depth, not physical area or timing.

15 checks on Icarus Verilog + Yosys · server. Run the examples first, then check the full regression. The suite is local and inspectable. A passing result establishes the tested cases, not a proof for all possible inputs.

See all 1 steps and the final capstone
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

Three samples in a row

Input
add 10, add 20, add 30, skip 0, skip 0, skip 0
Expected output
sum_after_step0 = 10, sum_after_step1 = 30, sum_after_step2 = 60, sum_after_step3 = 60, sum_after_step4 = 60, sum_after_step5 = 60

Each enabled step adds its sample once: 10, 30, 60, and the three skipped steps hold 60. The shipped accumulator adds the first 10 twice, once when en rises while clk is high and once at the edge, and reads 20, 40, 70.

Run samples executes all 3 example checks. Check all tests runs 15 checks.

Icarus Verilog + Yosys · server