Packed Struct Instruction Decoder
Processor pipelines receive raw 32-bit instruction words from memory that must be routed to various execution units. Manually slicing instruction bits using hardcoded indices litters the codebase with magic numbers and invites off-by-one errors. A robust RTL design avoids manual slicing by casting raw bit vectors into strongly typed packed structs.
This module accepts a 32-bit raw RISC-V R-type instruction and extracts its constituent fields. Instead of manual slicing, you must cast the input into a SystemVerilog packed struct. The extracted fields are then registered on the clock edge before being driven to the outputs.
Clock edge: posedge Reset type: Asynchronous, active-low Reset behavior: All outputs reset to 0 when rst_n is 0. Priority rules: On posedge clk, if valid_in is 1, the module decodes instr_in and registers the fields to the outputs, setting valid_out to 1. If valid_in is 0, valid_out becomes 0, but all other decoded field outputs must hold their previous values.
Cycle 1: rst_n=0 → valid_out=0, opcode=0, rd=0 (all fields 0)
Cycle 2: rst_n=1, valid_in=1, instr_in=32'h0000_0033 → valid_out=1, opcode=51, rd=0, funct3=0, rs1=0, rs2=0
Cycle 3: valid_in=1, instr_in=32'h40A4_84B3 → valid_out=1, opcode=51, rd=9, funct3=0, rs1=9, rs2=10
Cycle 4: valid_in=0 → valid_out=0, opcode=51, rd=9, funct3=0, rs1=9, rs2=10 (fields hold){ "signal": [
{ "name": "clk", "wave": "p......" },
{ "name": "rst_n", "wave": "01....." },
{ "name": "valid_in", "wave": "x1.0..." },
{ "name": "instr_in", "wave": "x34x...", "data": ["00000033", "40A484B3"] },
{},
{ "name": "valid_out", "wave": "0.1.0.." },
{ "name": "opcode", "wave": "0.3...=", "data": ["51"] },
{ "name": "rd", "wave": "0.34..=", "data": ["0", "9"] },
{ "name": "rs2", "wave": "0.34..=", "data": ["0", "10"] }
], "head": { "text": "Valid fields are registered and held when valid_in drops." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset | | valid_in | input | 1 | Indicates instr_in is valid | | instr_in | input | 32 | Raw 32-bit RISC-V instruction | | opcode | output | 7 | Decoded opcode field | | rd | output | 5 | Decoded destination register | | funct3 | output | 3 | Decoded function 3 field | | rs1 | output | 5 | Decoded source 1 register | | rs2 | output | 5 | Decoded source 2 register | | valid_out| output | 1 | High if the outputs reflect a valid instruction this cycle |
Constraints
- The module must handle asynchronous active-low reset.
valid_outmust immediately reflect the registered validity of the current cycle.- Data fields must hold their previous values when
valid_inis 0. - You must use a
typedef struct packedto decode the instruction; manual bit slicing is strictly prohibited.
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.