Takes in a ready/valid handshake along with the associated data, and replicates that transaction to multiple outputs. The input can proceed to the next transaction once all outputs have finished their transactions. All input and output transactions complete simultaneously.
There is no buffering, so be careful of combinational paths. If you cannot avoid a long combination path (or worse, a loop), then you must use the Eager Pipeline Fork.
`default_nettype none module Pipeline_Fork_Lazy #( parameter WORD_WIDTH = 0, parameter OUTPUT_COUNT = 0, // Do not set at instantiation, except in IPI parameter TOTAL_WIDTH = WORD_WIDTH * OUTPUT_COUNT ) ( input wire input_valid, output reg input_ready, input wire [WORD_WIDTH-1:0] input_data, output reg [OUTPUT_COUNT-1:0] output_valid, input wire [OUTPUT_COUNT-1:0] output_ready, output reg [TOTAL_WIDTH-1:0] output_data ); localparam TOTAL_ZERO = {TOTAL_WIDTH{1'b0}}; localparam OUTPUT_ONES = {OUTPUT_COUNT{1'b1}}; localparam OUTPUT_ZERO = {OUTPUT_COUNT{1'b0}}; initial begin input_ready = 1'b0; output_valid = OUTPUT_ZERO; output_data = TOTAL_ZERO; end
If all outputs are ready, then signal ready to the input and pass the valid signal through to all outputs, so all transaction complete together.
reg output_valid_gated = 1'b0; always @(*) begin input_ready = (output_ready == OUTPUT_ONES); output_valid = {OUTPUT_COUNT{output_valid_gated}}; output_data = {OUTPUT_COUNT{input_data}}; end always @(*) begin output_valid_gated = (input_valid == 1'b1) && (input_ready == 1'b1); end endmodule