Parameterized Struct Widths
Reusable IP blocks for network-on-chip (NoC) routers require data structures that scale seamlessly with system parameters. When payload sizes vary between different routing tiers, hardcoding bit widths in packet parsers leads to brittle designs that fail when reused. A robust approach uses parameterized packed structs to dynamically adjust field widths during synthesis while maintaining a clean, readable codebase.
The packet_parser module receives a flattened packet bitstream and extracts its fields. The module must define an internal struct packed containing four fields in this exact order from most-significant to least-significant bit: a 1-bit valid flag, an 8-bit dest_id, a parameterized payload (width defined by PAYLOAD_W), and a 16-bit crc. The module unpacks the incoming flat vector into this struct. If the packet is marked valid and its destination ID matches the module's LOCAL_ID parameter, the module captures the payload and asserts a valid output flag on the next clock cycle. If the packet is invalid or destined for a different ID, the outputs are cleared to zero on the next clock cycle.
- Clock edge:
posedge clk - Reset type: Asynchronous active-low
rst_n - Reset polarity: All outputs go to 0 when
rst_nis 0 - Registered outputs:
valid_outandpayload_outmust update precisely on the positive clock edge following the input presentation
Worked Trace (assuming PAYLOAD_W=32, LOCAL_ID=8'hA5): Cycle 1: rst_n=0 → valid_out=0, payload_out=0 Cycle 2: rst_n=1, packet_in={valid=1, dest=8'hA5, payload=32'h12345678, crc=16'hFFFF} → valid_out=0, payload_out=0 (inputs present at port) Cycle 3: packet_in={valid=1, dest=8'hB0, payload=32'h99999999, crc=16'h0000} → valid_out=1, payload_out=32'h12345678 (Cycle 2 data registered) Cycle 4: packet_in=0 → valid_out=0, payload_out=0 (Cycle 3 mismatched ID, outputs clear)
{ "signal": [
{ "name": "clk", "wave": "p........." },
{ "name": "rst_n", "wave": "01........" },
{ "name": "packet_in", "wave": "x=...=..=.", "data": ["Match A5", "Mismatch B0", "Invalid"] },
{},
{ "name": "valid_out", "wave": "0.1..0...." },
{ "name": "payload_out", "wave": "=.=..=....", "data": ["0", "12345678", "0"] }
], "head": { "text": "Pipeline behavior showing the one-cycle delay for registered outputs." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset; drives all outputs to 0 | | packet_in | input | 25+PAYLOAD_W | Flattened packet bit vector | | valid_out | output | 1 | Asserted high one cycle after a valid packet matching LOCAL_ID is received | | payload_out | output | PAYLOAD_W | Extracted payload from the matched packet; 0 otherwise |
| Parameter | Type | Default | Description | |-----------|------|---------|-------------| | PAYLOAD_W | integer | 32 | Width of the payload field in bits | | LOCAL_ID | integer | 8'hA5 | The 8-bit identifier for this specific node |
Constraints
- The module must trigger all sequential logic on
posedge clk - The reset must be asynchronous and active-low
- The struct fields must map to
packet_infrom MSB to LSB strictly as:valid,dest_id,payload,crc - If a packet does not match
LOCAL_IDor hasvalidset to 0,valid_outandpayload_outmust be driven to 0 on the next clock cycle - The total width of
packet_inis exactly25 + PAYLOAD_Wbits
Topics
Solve this problem
Write the module in Verilog, SystemVerilog or VHDL. Your submission is compiled and simulated against a real testbench — you get the waveform back, not a stored answer.
This problem is part of Codiode Pro. The statement above is free to read.
The circuit builder and code editor need a desktop screen. On a phone, read the problem here and open it on a laptop to solve.