Write a three-state Moore controller whose acknowledge comes from the state alone, so it changes only at a clock edge however late the request arrives.
Hardware context: A request/acknowledge controller whose acknowledge another block samples at its clock edge. Write the Moore controller whose acknowledge changes only at a clock edge.
A block in another team samples your acknowledge at its clock edge, so the acknowledge must change only at edges, never in the middle of a cycle when a request arrives late (lesson R3.1). Each request also needs one cycle of work before it is acknowledged.
Write ack_ctl, a Moore machine with three states. READY waits for req; a request seen at an edge moves it to WORK; WORK lasts one cycle; DONE lasts one cycle, with ack = 1, and returns to READY whether or not req is still high. busy is 1 in WORK and DONE.
Brief: ports clk, rst_n, req in; ack, busy out. Rising-edge clock; rst_n asynchronous and active-low, to READY. ack is 1 for exactly one cycle per request, two cycles after the edge that sees the request, and it and busy come from the state only. The requester holds req until it samples ack = 1 at an edge and drops it 1 ns later; it may raise req early or late in a cycle, and again in the cycle right after a handshake. No latch.
Signals in the timeline
| Signal | Width | Role |
|---|---|---|
n | 4 | input of each check |
script | 24 | input of each check |
Full specification
module ack_ctl (
input logic clk,
input logic rst_n, // asynchronous, active-low
input logic req,
output logic ack,
output logic busy
);
// your design
endmodule
| State | ack | busy | Next state at the edge |
|---|---|---|---|
| READY (after reset) | 0 | 0 | WORK if req is 1, else READY |
| WORK | 0 | 1 | DONE |
| DONE | 1 | 1 | READY |
| Rule | Definition |
|---|---|
| cycle c | The stretch just before edge c; cycle 0 follows reset release. A value "in cycle c" is the one edge c samples. |
| handshake | The edge where req and ack are both 1. The requester drops req 1 ns after it. |
| moves inside a cycle | A change of ack at any time other than a rising edge of clk. The Moore answer is 0. |
The result is {served[3:0], moved[3:0], busy_cycles[23:0], ack_cycles[23:0]}: the handshakes completed in 24 cycles, the number of times ack changed between edges, and the sets of cycles in which busy and ack were 1.
Synthesis check: the design must build on the site's synthesis flow with no latch.
Examples
Example 1
One request- Input
request 1: 1 idle cycle first, raised early
- Output
served = 1, ack_moves_inside_cycle = 0, busy_cycles = {2, 3}, ack_cycles = {3}
req rises 2 ns into cycle 1. Edge 1 sees it, so cycle 2 is WORK and cycle 3 is DONE with ack = 1; the handshake is edge 3. ack changed only at edges.
Example 2
A late request- Input
request 1: 1 idle cycle first, raised late
- Output
served = 1, ack_moves_inside_cycle = 0, busy_cycles = {2, 3}, ack_cycles = {3}
The same request raised 6 ns into cycle 1 gets the same answer, because the edge samples req wherever in the cycle it rose. An ack computed from req would have risen 6 ns into cycle 1 instead.
Example 3
Back to back- Input
request 1: 0 idle cycles first, raised early; request 2: 0 idle cycles first, raised early; request 3: 0 idle cycles first, raised late
- Output
served = 3, ack_moves_inside_cycle = 0, busy_cycles = {1, 2, 4, 5, 7, 8}, ack_cycles = {2, 5, 8}
Each request is raised again in the cycle after its handshake, so the controller serves one every three cycles: ack in cycles 2, 5 and 8, busy in every cycle but the READY ones, 0, 3 and 6.
Constraints and contract
- Each case resets the controller, then runs 24 cycles; requests may stay unserved at the end.
- Keep the module name and the ports.
Hints
Hint 1
Draw the three states and the one arc that reads req. Every other arc is taken at the next edge, whatever the inputs are.
Hint 2
An output that is a function of the state alone cannot change between edges, because the state changes only at edges. Check that no output equation names req.
Hint 3
Two always blocks and two assigns are enough: the state register with its asynchronous reset, a next-state case with a stay default, and ack and busy decoded from st_q.
What the grader checks: Eight directed and eight seeded request scripts drive the controller for 24 cycles each, with requests raised early or late in a cycle; the handshakes, the cycles where ack and busy are 1 and every change of ack between edges are compared with an independent model of the three-state machine. A zero-delay simulation shows when ack moves, not whether a real receiver meets its setup time.
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