R3.1.1 An acknowledge that waits for the edge

EasyImplementIcarus Verilog + Yosys · serverReview the topic

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

SignalWidthRole
n4input of each check
script24input of each check
Full specification
The module (keep the name and the ports)
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
StateackbusyNext state at the edge
READY (after reset)00WORK if req is 1, else READY
WORK01DONE
DONE11READY
RuleDefinition
cycle cThe stretch just before edge c; cycle 0 follows reset release. A value "in cycle c" is the one edge c samples.
handshakeThe edge where req and ack are both 1. The requester drops req 1 ns after it.
moves inside a cycleA 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
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

One request

Input
request 1: 1 idle cycle first, raised early
Expected 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.

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

Icarus Verilog + Yosys · server