The name isnt too important, but the formula is priceless.
Im using it like shown below in order to handle a varable width structure
////////////////////////////////////
// General functions //
// f_GetPipelineVectorSize //
// f_GetPipelineDepthStartAddress //
// f_GetPipelineDepthEndAddress //
// f_GetPipelineDepthSize //
// f_GetPipelineDepth //
//
// returns the total size of continually reducing pipeline vector.
// <2> <1> <0>
// <4> <3>
// <5>
// base:3 total_units: 6
function automatic integer f_GetPipelineVectorSize;
input integer base, unit_width;
f_GetPipelineVectorSize = (base * ( base + 1 ) / 2) * unit_width;
endfunction
// initial begin:test_SumOfSubtrahend integer idx;for(idx=0;idx<5;idx=idx+1)begin $display("f_GetPipelineVectorSize(%1d):%1d",idx,f_GetPipelineVectorSize(idx, 1));end end
// returns the start address of a level of a continually reducing vector
// level 0: <2> <1> <0>
// level 1: <4> <3>
// level 2: <5>
// base:3 unit_width:1
// request_depth:0 returns 0
// request_depth:1 returns 3
// request_depth:2 returns 5
// request_depth:3 returns -1. error out of bounds. invalid depth
function automatic integer f_GetPipelineDepthStartAddress;
input integer base, unit_width, request_depth;
begin
if( request_depth >= base) begin
f_GetPipelineDepthStartAddress = ~0;
end else begin
f_GetPipelineDepthStartAddress = ( f_GetPipelineVectorSize(base, 1) - f_GetPipelineVectorSize(base-request_depth, 1) ) * unit_width;
end
end
endfunction
// initial begin:test_GetPipeLineDepthStartAddress integer idx;for(idx=0;idx<5;idx=idx+1)begin $display("f_GetPipelineDepthStartAddress( 3, 1, %1d ):%1d",idx,f_GetPipelineDepthStartAddress(3,1, idx));end end
// returns the end address of a level of a continually reducing vector
// level 0: <2> <1> <0>
// level 1: <4> <3>
// level 2: <5>
// base:3 unit_width:1
// request_depth:0 returns 2
// request_depth:1 returns 4
// request_depth:2 returns 5
// request_depth:3 returns -1. error out of bounds. invalid depth
function automatic integer f_GetPipelineDepthEndAddress;
input integer base, unit_width, request_depth;
begin
if( request_depth >= base) begin
f_GetPipelineDepthEndAddress = ~0;
end else begin
f_GetPipelineDepthEndAddress = f_GetPipelineDepthStartAddress(base, 1, request_depth) + (base - request_depth - 1) * unit_width;
end
end
endfunction
// initial begin:test_GetPipelineDepthEndAddress integer idx;for(idx=0;idx<5;idx=idx+1)begin $display("f_GetPipelineDepthEndAddress( 3, 1, %1d ):%1d",idx,f_GetPipelineDepthEndAddress(3,1, idx));end end
// returns the size of a level of a continually reducing vector
function automatic integer f_GetPipelineDepthSize;
input integer base, unit_width, request_depth;
begin
if( request_depth >= base) begin
f_GetPipelineDepthSize = ~0;
end else begin
f_GetPipelineDepthSize = f_GetPipelineDepthEndAddress(base, unit_width, request_depth) - f_GetPipelineDepthStartAddress(base, unit_width, request_depth) + unit_width;
end
end
endfunction
// initial begin:test_GetPipelineDepthSize integer idx;for(idx=0;idx<5;idx=idx+1)begin $display("f_GetPipelineDepthSize( 3, 1, %1d ):%1d",idx,f_GetPipelineDepthSize(3,1, idx));end end
function automatic integer f_GetPipelineDepth;
input integer input_count;
f_GetPipelineDepth = input_count - 1;
endfunction