4.5.1 Safe downcast

EasyImplementVerilator · local serverReview the topic

Use the function form of $cast and its result before touching any write-only field.

Hardware context: Typed optional extensions in a hardware transaction pipeline. Safely access a supported transaction subtype after a checked downcast.

A coverage collector ignored the result of $cast. When an ordinary read arrived, the cast failed and left the handle pointing at the previous write, and that write was counted again: 40 error samples from 12 error transactions.

Write inspect_write(item). Packets arrive as bus_packet handles. If item is null, return status 1. If it cannot be cast to write_packet, return status 2. Otherwise return status 0 with its uid, address, data and strobes. A diagnostic_write is a write_packet too, so it succeeds.

Decide by the cast’s result, never by field values: a read can have the same address as a write, and a write can have zero strobes.

Signals in the timeline

SignalWidthRole
kind3input of each check
identifier8input of each check
address16input of each check
data16input of each check
strobes2input of each check
Full specification
The supplied classes
class bus_packet;
  byte unsigned uid;logic[15:0] address;
  function new(input int identifier,addr);uid=8'(identifier);address=16'(addr);endfunction
endclass
class write_packet extends bus_packet;
  logic[15:0] data;logic[1:0] strobes;
  function new(input int identifier,addr,value,lanes);super.new(identifier,addr);data=16'(value);strobes=2'(lanes);endfunction
endclass
class read_packet extends bus_packet;
  byte unsigned beats;
  function new(input int identifier,addr,length);super.new(identifier,addr);beats=8'(length);endfunction
endclass
class diagnostic_write extends write_packet;
  byte unsigned diagnostic_tag;
  function new(input int identifier,addr,value,lanes);super.new(identifier,addr,value,lanes);diagnostic_tag=8'hd7;endfunction
endclass
What you write
function automatic logic [63:0] inspect_write(input bus_packet item);
// returns {status[7:0], uid[7:0], address[15:0], data[15:0], strobes[7:0], 8'b0}

On status 1 or 2 every field other than status is 0. Do not change the object.

Examples

Example 1

Writes and their subclass
Input
a write (uid 17, address 0024, data ABCD, strobes 11)
then a diagnostic_write (uid 18, address 0026, data 5500, strobes 00)
Output
status = OK (0), uid = 17, address = 0x24, data = 0xabcd, strobes = 'b11
status = OK (0), uid = 18, address = 0x26, data = 0x5500, strobes = 'b00

Both casts succeed. Zero strobes is still a write.

Example 2

A read is not a write
Input
a read (uid 23, address 0028, 4 beats)
Output
status = NOT_A_WRITE (2), uid = 0, address = 0x0, data = 0x0, strobes = 'b00

The cast fails: status NOT_A_WRITE and every field 0.

Example 3

Null first
Input
a null handle
Output
status = NULL (1), uid = 0, address = 0x0, data = 0x0, strobes = 'b00

Status NULL, checked before any cast.

Constraints and contract

  • item may be null or any of the four classes.
  • Use the function form of $cast and test its result.
  • Keep the function signature.

Hints

Hint 1

What happens to a handle when $cast fails, and how do you find out that it failed?

Hint 2

Handle null before anything else: you cannot ask a null handle what type it is.

Hint 3

Return 2 as soon as the cast reports failure; read the write fields only from the handle the cast filled in.

What this judge verifies: Your function is called with null, plain, read, write and diagnostic packets with seeded fields, including zero strobes and reads that look like writes. Passing shows the cast result decides every answer.

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

Writes and their subclass

Input
a write (uid 17, address 0024, data ABCD, strobes 11)
then a diagnostic_write (uid 18, address 0026, data 5500, strobes 00)
Expected output
status = OK (0), uid = 17, address = 0x24, data = 0xabcd, strobes = 'b11
status = OK (0), uid = 18, address = 0x26, data = 0x5500, strobes = 'b00

Both casts succeed. Zero strobes is still a write.

Run samples executes all 4 example checks. Check all tests runs 164 checks.

Verilator · local server