Skip to content
code0.HDL

35Implementation

Extract a nested request payload

Problem

payloadOrZero receives a Packet, which is either a Data packet carrying a Request struct or a Flush packet with no payload. It must return the request's payload for Data and 8'h00 for Flush. The starter ignores its argument and always returns 8'h00, so the public run shows 00 for both packets instead of a5 for the data packet.

Edit only the body of payloadOrZero. Keep both type declarations, the function signature, and mkTop unchanged. Do not unpack the packet into raw bits; the exercise is about pattern matching on the typed shape.

Read and predict

  1. Read Packet first. It has two alternatives, and only Data carries a value.
  2. Read Request. The value inside Data has two fields, channel and payload, and only one of them matters for the result.
  3. Read the two calls in mkTop: one passes tagged Data request with payload 8'ha5, the other passes tagged Flush.

Before pressing Run, predict both lines for the starter. Both read 00, and only the data line is wrong. The code compiles because returning a constant is type-correct; this is a behavior defect.

Make the repair

Replace the constant return with a case ... matches that has one arm per alternative. Build the Data arm from the outside in: match the tag, then the struct, and only then introduce a name for the field you need. Fields that do not affect the result can be left out of the struct pattern.

Run again and check that the data line now shows a5 while the flush line stays 00. Then explain why the payload name can only exist inside the Data arm: outside it, there is no request to take a field from.

Completion contract

  • Every Data packet returns its own payload, including a payload of zero and any channel value.
  • Every Flush packet returns 8'h00.
  • The function uses pattern matching on the tagged union and the nested struct.
  • Returning 8'ha5 for the visible sample does not satisfy other payloads.

Progressive hints

Hint 1: match the shape of the type

Patterns nest the same way the data does. The outer pattern checks which tag is active; an inner struct pattern can then bind one field of the carried value.

Hint 2: start the data arm

The first arm begins with the Data tag and is followed by a pattern for the Request struct, not by a plain variable that holds the whole struct.

Hint 3: bind only what you return

Inside the struct pattern, name only the field that owns the result, using a pattern variable. The Flush arm needs no binding at all.

Transfer experiment

On paper, change the function so it returns the two-bit channel instead, widened to the same result type. Identify which parts of the pattern stay the same and which binding moves.

Review this concept
Ready
Main.bsv