1. A requirement answers six questions before you write a line
Every chapter so far handed you code and asked you to predict it. This one hands you two requirements and no code. The skill is not new syntax; it is reading the requirement into the six decisions the code will have to make, in this order.
| Question | What to extract | Where it goes in the code |
|---|---|---|
| Ports | every input and output, by name and direction | the port list |
| Widths | the range each value must hold | [N-1:0] on each port and register |
| Mapping | for a selector, what each code means | the case labels or ?: chain |
| Priority | when two inputs are active at one edge, which wins | the order of the if/else if chain |
| Sampling time | what the testbench prints and when | how you read the trace, not the design |
| Boundaries | largest value, wrap, reset in the middle, both inputs at once | the cases you check by hand |
Write the six answers down before opening the editor. A design that compiles but fails grading has almost always skipped one of them.
2. A combinational mapping becomes a case with every code covered
The first problem, select-op, describes a module that chooses an operation on its inputs by a
select code. Its table of codes is the requirement. Each code must produce exactly one result, and
every code the width allows must appear somewhere: a 2-bit select has four codes whether the table
lists four or three. The missing one gets the default branch, or the final : of a ?: chain, as
Nets, variables and the combinational always
required.
Width is the second trap. If an operation is an addition, decide where its carry goes: into a wider result port, or dropped on purpose because the requirement says so. Literals, signed values and expression width decides that for you, once you know what the requirement wants.
Check
A select input is declared [1:0]. How many codes must the design give a result for?
Check
The requirement lists three operations for a 2-bit select. What handles the fourth code?
3. A sequential contract becomes a chain in priority order
The checkpoint problem, clear-enable-counter, states a contract for every rising edge: when
clear is 1 the count becomes 0; otherwise when enable is 1 the count increases by one, wrapping
after 15; otherwise the count holds. Read that sentence as the chain from
Reset, enable and priority: the first condition
is tested first, the second only when the first is false, and holding is the absence of an
assignment. The browser model counter4 is this contract. Fill in the table before you write the
code; both inputs are the values sampled at the edge that ends each cycle, and q is the value after
that edge.
Predict, then compare · counter4
Fill in each cell before comparing. Empty cells count as a mismatch.
| Cycle | clearinputs sampled at the edge | enableinputs sampled at the edge | qafter the edge |
|---|---|---|---|
| 0 | 1 | 0 | |
| 1 | 0 | 1 | |
| 2 | 0 | 1 | |
| 3 | 1 | 1 | |
| 4 | 0 | 1 | |
| 5 | 0 | 0 | |
| 6 | 0 | 1 |
Check
q is 15, enable is 1 and clear is 0 at the edge. What is q after the edge?
Carry the table's clear-while-enabled and hold cases into the problem. Also check the wrap from 15 to 0: the short input sequence above never reaches 15, so the table does not test that boundary.
4. Read the testbench before you read the trace
The design is only half of what the grader runs. The public testbench below the marker in each
problem decides what is printed and when, and
Register stages, observation and waveforms
showed that this decides which value you see. A $display inside always @(posedge clock) shows
the value from before that edge; a print on the falling edge, or after #1, shows the value after
it. Find the print statement, decide which view it gives, and write your expected trace in that view
before you run.
Check
The testbench prints count with $display inside always @(posedge clock). Each line shows the value from…
5. Check the way the grader checks
The public testbench prints a few rows. The grader drives more patterns and compares every one, so
the rows you can see are a start, not a proof. Before you press Submit, walk your code by hand through
the boundary cases from section 1: the largest value, the wrap, both inputs active at once, and the
first edge after reset. Each should be one line of reasoning, not a guess. If a row disagrees with
your prediction, decide first whether the design or your reading of the sampling time is wrong; the
observation table in
Register stages, observation and waveforms
settles the second case without touching the code.
6. Go
Open select-op first and write the combinational module from its table. Then open
clear-enable-counter, the checkpoint, and write the counter from the contract you just predicted.
No solution code appears in this chapter on purpose; everything the two designs need is in the
earlier chapters of this course, from vectors and operators to register stages and observation.
7. Summary
| Element | Meaning |
|---|---|
| ports, widths | the port list and every [N-1:0] |
| mapping | case with a default, every code assigned |
| priority | the order of the if/else if chain; hold is no assignment |
| sampling time | decides what the trace shows, not what the design does |
| boundaries | the cases you check by hand before grading |
This is the last chapter of the Verilog course. The rules behind every step are in the chapters before it, and the BSV and Chisel courses build these same circuits in two other languages.