1.4.1 Safe opcode decoder

EasyImplementIcarus Verilog · browserReview the topic

Turn three raw opcode bits into an enum only when they hold a legal code, and say so with a valid bit.

Hardware context: Command decoder and control-state machine for a transaction engine. Decode a raw hardware opcode into a typed operation with explicit validity.

A bus monitor converted its opcode with a static cast. When the DUT started sending a reserved code, the cast accepted it, coverage still looked complete, and nobody noticed the illegal traffic.

This engine knows three operations: READ = 3'b001, WRITE = 3'b100 and FENCE = 3'b110. Write decode_opcode(raw), which returns a valid bit and an operation.

For a legal, fully known code, return valid = 1 and that operation. For anything else, a reserved code or any x or z bit, return valid = 0 with the operation set to OP_READ, so the result is always known. The valid bit, not the operation, tells the next stage whether to act.

For raw = 3'b1x0 the bits could mean WRITE or FENCE. That is not a legal code, so valid is 0.

Signals in the timeline

SignalWidthRole
raw3input of each check
Full specification
Given types and signature (keep them)
typedef enum logic [2:0] {OP_READ = 3'b001, OP_WRITE = 3'b100, OP_FENCE = 3'b110} opcode_t;
function automatic logic [3:0] decode_opcode(input logic [2:0] raw);   // returns {valid, op}
rawvalidop
3'b0011OP_READ
3'b1001OP_WRITE
3'b1101OP_FENCE
any other known code0OP_READ
any code with an x or z bit0OP_READ

All 64 combinations of 0, 1, x and z in the three bits are tested. The returned four bits are always known.

Examples

Example 1

A legal write
Input
raw = 3'b100
Output
valid = yes, op = OP_WRITE ('b100)

100 is WRITE, so valid = 1 and op = OP_WRITE.

Example 2

A reserved code
Input
raw = 3'b010
Output
valid = no, op = OP_READ ('b001)

010 has no label. valid = 0, and op falls back to OP_READ so the result stays known.

Example 3

An unknown bit changes the meaning
Input
raw = 3'b1x0
Output
valid = no, op = OP_READ ('b001)

1x0 could be 100 (WRITE) or 110 (FENCE). It is not a legal code, so valid = 0.

Constraints and contract

  • raw may hold x or z in any bit.
  • The result is always known: no x or z in valid or op.
  • Keep opcode_t and the function signature.

Hints

Hint 1

A cast copies any value into an enum, even one with no label. What must you check before you trust the bits as an opcode?

Hint 2

Some ways of matching treat x or z as "don't care". Which kind of matching keeps an unknown bit from looking like a legal code?

Hint 3

Start from the invalid answer, {1'b0, OP_READ}, and change it only when raw exactly matches one of the three labels.

What this judge verifies: Your decoder is called on all 64 combinations of 0, 1, x and z in the three opcode bits. Passing shows every legal code is accepted and every other input is rejected with a known result.

67 checks on Icarus Verilog · browser. 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 5 steps and the final capstone
Your code SystemVerilogSaved locally
Ln 1, Col 1Tab indents · Ctrl/⌘ + Enter runs samples
Not run yet

A legal write

Input
raw = 3'b100
Expected output
valid = yes, op = OP_WRITE ('b100)

100 is WRITE, so valid = 1 and op = OP_WRITE.

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

Icarus Verilog · browser