Design a modulo-N counter with an enable and a carry output, so that digits can be chained, for any N from 2 to 16.
Hardware context: One digit of a stopwatch: a modulo-N counter with an enable and a carry. Design the chainable modulo-N digit counter for any N from 2 to 16.
A stopwatch is a chain of digit counters: tenths, seconds (0 to 9), tens of seconds (0 to 5). Each digit counts when the digit before it carries. Write modn_en, one digit of the chain (lesson R2.4).
count runs 0, 1, ..., N-1 and then 0 again, and moves at a rising edge only when en is 1. carry tells the next digit that this one is about to wrap: it is 1 while en is 1 and count holds N-1, so the next digit's en can be this digit's carry.
Brief: parameter N from 2 to 16; ports clk, rst_n (asynchronous, active-low) and en in, count[$clog2(N)-1:0] and carry out; count is 0 after reset; one edge of latency; carry is combinational from en and count; corner cases: N a power of two, N = 2, en low at the last value. The tests run copies with N = 10, 6, 16 and 2. 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
| Signal | Width | Role |
|---|---|---|
ens | 16 | input of each check |
which | 2 | input of each check |
Full specification
module modn_en #(parameter int N = 10) (
input logic clk,
input logic rst_n, // asynchronous, active-low
input logic en,
output logic [$clog2(N)-1:0] count,
output logic carry
);
// your design
endmodule
| Inputs before the edge | count after the edge | carry before the edge |
|---|---|---|
| en = 0 | count (held) | 0 |
| en = 1, count < N-1 | count + 1 | 0 |
| en = 1, count = N-1 | 0 | 1 |
| rst_n = 0 (at any time) | 0 | per en and count |
The tests reset the counter and run 16 steps: en is driven, carry is sampled just before the edge, and count is sampled just after it. The result is carry_before_edges (the edges, 0 to 15, before which carry was 1) and count_e0 to count_e15, the count after each edge.
Examples
Example 1
N = 10, enabled every step- Input
N = 10, en per step: 1111111111111111
- Output
carry_before_edges = {9}, count_e0 = 1, count_e1 = 2, count_e2 = 3, count_e3 = 4, count_e4 = 5, count_e5 = 6, count_e6 = 7, count_e7 = 8, count_e8 = 9, count_e9 = 0, count_e10 = 1, count_e11 = 2, count_e12 = 3, count_e13 = 4, count_e14 = 5, count_e15 = 6
count is 1 to 9 after edges 0 to 8. carry is 1 before edge 9, where count holds 9 and en is 1, and that edge wraps count to 0.
Example 2
N = 6 with pauses- Input
N = 6, en per step: 1101110011110111
- Output
carry_before_edges = {8, 15}, count_e0 = 1, count_e1 = 2, count_e2 = 2, count_e3 = 3, count_e4 = 4, count_e5 = 5, count_e6 = 5, count_e7 = 5, count_e8 = 0, count_e9 = 1, count_e10 = 2, count_e11 = 3, count_e12 = 3, count_e13 = 4, count_e14 = 5, count_e15 = 0
Steps with en 0 hold the count (edges 2, 6, 7 and 12). count is 5 before edges 6, 7 and 8, but carry is 1 only before edge 8, the one where en is 1; it is 1 again before edge 15.
Example 3
N = 16- Input
N = 16, en per step: 1111111111111111
- Output
carry_before_edges = {15}, count_e0 = 1, count_e1 = 2, count_e2 = 3, count_e3 = 4, count_e4 = 5, count_e5 = 6, count_e6 = 7, count_e7 = 8, count_e8 = 9, count_e9 = 10, count_e10 = 11, count_e11 = 12, count_e12 = 13, count_e13 = 14, count_e14 = 15, count_e15 = 0
With N = 16 the last value is 15, the top of four bits: carry before edge 15, and the compare and the natural wrap agree.
Constraints and contract
- N is between 2 and 16; inputs are known 0/1 values.
- Keep the module name, the parameter N and the ports.
Hints
Hint 1
The register is $clog2(N) bits wide. The decision is what its next value is: hold, add one, or go back to 0.
Hint 2
Write carry first, as an assign from en and a compare with N-1. Then the next value is 0 when carry is 1, count + 1 when en is 1, and count otherwise.
Hint 3
Compare with N-1, not N: with N = 10 the last value is 9. A compare that waits for N gives eleven values, and with N = 16 the value 16 does not fit in four bits at all.
What the grader checks: Eight directed and eight seeded scripts of sixteen enable steps run on copies with N = 10, 6, 16 and 2; count after every edge and carry before every edge are compared with an independent model. Passing shows the counter on those four values of N; other N between 2 and 16 follow the same code but are not simulated. The synthesis check adds the latch count.
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.
16 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