Struct Array Pipeline
Processor pipelines move massive bundles of control, data, and metadata signals between stages on every clock cycle. Passing dozens of individual signals through multiple pipeline registers is error-prone, visually noisy, and difficult to maintain. By grouping related signals into SystemVerilog structs and instantiating them as arrays, hardware engineers can cleanly shift entire bundles of pipeline state in a single line of RTL.
The solution module implements a 4-stage synchronous pipeline. The inputs (valid_in, pc_in, and instr_in) enter the first stage and shift forward on each clock cycle. The outputs (valid_out, pc_out, and instr_out) continuously reflect the contents of the final (fourth) pipeline stage. The pipeline also supports global stall and flush operations. To pass this exercise, you must define a packed struct containing the valid, PC, and instruction fields, and instantiate an array of four such structs to serve as the internal pipeline registers.
Timing and reset rules: • Clock edge: All state updates occur on the positive edge of clk. • Reset: Asynchronous, active-low (rst_n). When asserted, all valid bits, pc values, and instr values in every pipeline stage must be cleared to 0. • Flush: Synchronous, active-high. When flush=1, all valid bits in the pipeline are cleared to 0 on the next clock edge. The pc and instr registers hold their current values and do not shift. • Stall: Synchronous, active-high. When stall=1 (and flush=0), the pipeline holds its current state. No data shifts forward. • Priority: flush has priority over stall. If both are asserted simultaneously, the flush operation executes.
Worked trace:
Cycle 1: rst_n=0 → all stages 0, valid_out=0
Cycle 2: rst_n=1, valid_in=1, pc_in=100 → (on posedge, data enters Stage 0)
Cycle 3: valid_in=1, pc_in=104 → (on posedge, 100 moves to Stage 1, 104 enters Stage 0)
Cycle 4: stall=1, valid_in=0 → (on posedge, pipeline holds state)
Cycle 5: stall=0 → (on posedge, 100 moves to Stage 2, 104 moves to Stage 1)
Cycle 6: normal operation → (on posedge, 100 moves to Stage 3)
Cycle 7: normal operation → valid_out=1, pc_out=100 (Stage 3 outputs visible){ "signal": [
{ "name": "clk", "wave": "p......" },
{ "name": "rst_n", "wave": "01....." },
{ "name": "valid_in", "wave": "0110..." },
{ "name": "pc_in", "wave": "x==x...", "data": ["100", "104"] },
{ "name": "stall", "wave": "0..10.." },
{},
{ "name": "valid_out", "wave": "0.....1" },
{ "name": "pc_out", "wave": "x.....=", "data": ["100"] }
], "head": { "text": "Pipeline trace showing injection, shift, and stall." } }| Signal | Direction | Width | Description | |--------|-----------|-------|-------------| | clk | input | 1 | Positive-edge triggered clock | | rst_n | input | 1 | Asynchronous active-low reset | | valid_in | input | 1 | Input valid flag | | pc_in | input | 32 | Input program counter | | instr_in | input | 32 | Input instruction word | | stall | input | 1 | Synchronous stall; holds pipeline state | | flush | input | 1 | Synchronous flush; clears all valid bits | | valid_out | output | 1 | Valid flag from the 4th pipeline stage | | pc_out | output | 32 | Program counter from the 4th pipeline stage | | instr_out | output | 32 | Instruction word from the 4th pipeline stage |
Constraints
- You must use a
typedef struct packedto group thevalid,pc, andinstrfields. - You must instantiate an array of 4 structs to represent the pipeline stages.
- The
flushsignal clears only thevalidbits;pcandinstrmust hold their previous values. flushhas strict priority overstall.- Outputs must be directly driven by the 4th pipeline stage (registered outputs).
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.