// pipeline_reg.v - Single pipeline stage with valid/ready handshake // // valid_i && ready_o -> register data -> valid_o next cycle. // ready_o = !valid_o || ready_i. // // Parameters: // DW = data width (default 12) // // Interface: // clk, rst_n - clock, active-low reset // data_i, valid_i, ready_o - input side // data_o, valid_o, ready_i - output side module pipeline_reg #(parameter DW = 12) ( input clk, input rst_n, input [DW-1:0] data_i, input valid_i, output ready_o, output [DW-1:0] data_o, output valid_o, input ready_i ); reg valid_r; reg [DW-1:0] data_r; // ready_o: accept new data when output slot is free assign ready_o = !valid_r || ready_i; // Drive outputs from internal register assign valid_o = valid_r; assign data_o = data_r; always @(posedge clk or negedge rst_n) begin if (!rst_n) begin valid_r <= 1'b0; data_r <= {DW{1'b0}}; end else begin if (valid_r && ready_i) begin // Output consumed, clear valid valid_r <= 1'b0; end if (valid_i && ready_o) begin // Capture new data data_r <= data_i; valid_r <= 1'b1; end end end endmodule