Код
module adder_tree
#(
parameter int pDAT_W = 8 ,
parameter int pNUM = 16
)
(
iclk ,
iena ,
idat ,
oena ,
odat
);
//------------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------------
input logic iclk ;
input logic iena ;
input logic [pDAT_W-1 : 0] idat [0 : pNUM-1];
output logic oena ;
output logic [pDAT_W-1 : 0] odat ;
//------------------------------------------------------------------------------------------------------
//
//------------------------------------------------------------------------------------------------------
localparam int cADDER_NUM_PER_STAGE = pNUM/2;
localparam int cADDER_STAGE_NUM = clogb2(pNUM);
logic [pDAT_W-1 : 0] acc[0 : cADDER_STAGE_NUM-1][0 : cADDER_NUM_PER_STAGE-1];
logic ena[0 : cADDER_STAGE_NUM-1];
genvar i, stage;
generate
for (stage = 0; stage < cADDER_STAGE_NUM; stage++) begin : adder_stage_gen
always_ff @(posedge iclk) begin
ena[stage] <= (stage == 0) ? iena : ena[stage-1];
end
for (i = 0; i < (cADDER_NUM_PER_STAGE >> stage); i++) begin : adder_in_stage_gen
always_ff @(posedge iclk) begin
if (stage == 0) begin
if (iena)
acc[stage][i] <= idat[2*i] + idat[2*i+1];
end
else begin
if (ena[stage-1])
acc[stage][i] <= acc[stage-1][2*i] + acc[stage-1][2*i+1];
end
end
end // adder_in_stage_gen
end // adder_stage_gen
endgenerate
assign oena = ena[cADDER_STAGE_NUM-1];
assign odat = acc[cADDER_STAGE_NUM-1][0];
endmodule