CodiodeCodiode
Home
Problem Solving
Skill Tracks
My Assignments
Contests
Leaderboard
Community
Settings
Codiode/Problems/Sequential Logic

Packed Struct Instruction Decoder

MediumVerilog / SystemVerilogBuild

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_out must immediately reflect the registered validity of the current cycle.
  • Data fields must hold their previous values when valid_in is 0.
  • You must use a typedef struct packed to decode the instruction; manual bit slicing is strictly prohibited.

Topics

SystemVerilogStructsType CastingRISC-V

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.

Sign in to solveSee what Pro unlocks

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.

Related problems

  • Basic D Flip FlopEasy
  • Debug: Missing Edge in Sensitivity ListMedium
  • Read After Write Hazard DetectionEasy
  • Parameterized Interface with ModportsHard
  • Struct Array PipelineHard
  • T Flip Flop from D Flip Flop TemplateEasy
  • Recursive Generate Reduction TreeHard
  • Four Stage Shift RegisterEasy

Browse all problems · Learning tracks