//
// Common useful functions
//

// ceil(ilog2(a))
function int ilog2c(int a);
   int b;
   b = 0;
   while ((1 << b) < a)
     b++;
   ilog2c = b;
endfunction // ilog2c

// floor(ilog2(a))
function int ilog2f(int a);
  ilog2f = ilog2c(a+1)-1;
endfunction // ilog2f

function int max(int a, int b);
  max = a > b ? a : b;
endfunction // max

function int max3(int a, int b, int c);
  max3 = max(max(a,b),c);
endfunction // max3

function int max4(int a, int b, int c, int d);
  max4 = max(max(a,b),max(c,d));
endfunction // max4

function int min(int a, int b);
  min = a < b ? a : b;
endfunction // min

function int min3(int a, int b, int c);
  min3 = min(min(a,b),c);
endfunction // min3

function int min4(int a, int b, int c, int d);
  min4 = min(min(a,b),min(c,d));
endfunction // min4

// Quartus doesn't support $sformatf() for synthesis, sigh...
// This is highly useful to create synthetic attribute strings;
// the rather clumsy design is specifically in order to be handled
// correctly by synthesis.
function string tostr(input integer i);
   if (i < 0)
     tostr = {"-",tostr(-i)};
   else if (i >= 10)
     tostr = {tostr(i/10), tostr(i%10)};
   else if (i == 0)
     tostr = "0";
   else if (i == 1)
     tostr = "1";
   else if (i == 2)
     tostr = "2";
   else if (i == 3)
     tostr = "3";
   else if (i == 4)
     tostr = "4";
   else if (i == 5)
     tostr = "5";
   else if (i == 6)
     tostr = "6";
   else if (i == 7)
     tostr = "7";
   else if (i == 8)
     tostr = "8";
   else
     tostr = "9";
endfunction

function longint unsigned
  round_div(input longint unsigned num, input longint unsigned den);
   round_div = (num + (den >> 1))/den;
endfunction // round_div
