/**
|
/**
|
* Library: cic_functions
|
* Library: cic_functions
|
*
|
*
|
* library with functions for calculating parameters for CIC filter and Hogenauer pruning
|
* library with functions for calculating parameters for CIC filter and Hogenauer pruning
|
*/
|
*/
|
`ifndef _CIC_FUNCTIONS_VH_
|
`ifndef _CIC_FUNCTIONS_VH_
|
`define _CIC_FUNCTIONS_VH_
|
`define _CIC_FUNCTIONS_VH_
|
`define M_PI 3.14159265359 // not all simulator defines PI
|
`define M_PI 3.14159265359 // not all simulator defines PI
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function reg unsigned [127 : 0] nchoosek; ///< Binomial coefficient
|
function reg unsigned [127 : 0] nchoosek; ///< Binomial coefficient
|
input integer n;
|
input integer n;
|
input integer k;
|
input integer k;
|
reg unsigned [127:0] tmp;
|
reg unsigned [127:0] tmp;
|
integer i;
|
integer i;
|
begin
|
begin
|
tmp = 1.0;
|
tmp = 1.0;
|
for (i = 1; i <= (n - k); i = i + 1)
|
for (i = 1; i <= (n - k); i = i + 1)
|
tmp = tmp * (k + i) / i;
|
tmp = tmp * (k + i) / i;
|
nchoosek = tmp;
|
nchoosek = tmp;
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function integer clog2_l;
|
function integer clog2_l;
|
input reg unsigned [127:0] depth;
|
input reg unsigned [127:0] depth;
|
reg unsigned [127:0] i;
|
reg unsigned [127:0] i;
|
begin
|
begin
|
clog2_l = 0;
|
clog2_l = 0;
|
if (depth > 0) begin
|
if (depth > 0) begin
|
i = depth - 1; // with "- 1" clog2(2^N) will be N, not N + 1
|
i = depth - 1; // with "- 1" clog2(2^N) will be N, not N + 1
|
for(clog2_l = 0; i > 0; clog2_l = clog2_l + 1)
|
for(clog2_l = 0; i > 0; clog2_l = clog2_l + 1)
|
i = i >> 1;
|
i = i >> 1;
|
end else
|
end else
|
clog2_l = -1;
|
clog2_l = -1;
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function integer B_max_calc;
|
function integer B_max_calc;
|
input integer N;
|
input integer N;
|
input integer R;
|
input integer R;
|
input integer M;
|
input integer M;
|
input integer INP_DW;
|
input integer INP_DW;
|
reg unsigned [127:0] RMpN;
|
reg unsigned [127:0] RMpN;
|
begin
|
begin
|
RMpN = (R * M) ** N;
|
RMpN = (R * M) ** N;
|
B_max_calc = clog2_l(RMpN) + INP_DW - 1;
|
B_max_calc = clog2_l(RMpN) + INP_DW - 1;
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function integer B_out_calc;
|
function integer B_out_calc;
|
input integer N;
|
input integer N;
|
input integer R;
|
input integer R;
|
input integer M;
|
input integer M;
|
input integer INP_DW;
|
input integer INP_DW;
|
input integer OUT_DW;
|
input integer OUT_DW;
|
begin
|
begin
|
B_out_calc = B_max_calc(N, R, M, OUT_DW) - B(2 * N, R, M, N, INP_DW, OUT_DW) + 1;
|
B_out_calc = B_max_calc(N, R, M, OUT_DW) - B(2 * N, R, M, N, INP_DW, OUT_DW) + 1;
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function integer flog2_l;
|
function integer flog2_l;
|
input reg unsigned [127:0] depth;
|
input reg unsigned [127:0] depth;
|
reg unsigned [127:0] i;
|
reg unsigned [127:0] i;
|
begin
|
begin
|
i = depth;
|
i = depth;
|
for(flog2_l = 0; i > 1; flog2_l = flog2_l + 1)
|
for(flog2_l = 0; i > 1; flog2_l = flog2_l + 1)
|
i = i >> 1;
|
i = i >> 1;
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function reg signed [127:0] h;
|
function reg signed [127:0] h;
|
input integer j;
|
input integer j;
|
input integer k;
|
input integer k;
|
input integer R;
|
input integer R;
|
input integer M;
|
input integer M;
|
input integer N;
|
input integer N;
|
integer c_stop;
|
integer c_stop;
|
integer i;
|
integer i;
|
reg signed [127:0] tmp;
|
reg signed [127:0] tmp;
|
reg signed [127:0] prod_1;
|
reg signed [127:0] prod_1;
|
reg signed [127:0] prod_2;
|
reg signed [127:0] prod_2;
|
reg signed [127:0] summ;
|
reg signed [127:0] summ;
|
begin
|
begin
|
c_stop = k / (R * M);
|
c_stop = k / (R * M);
|
if ((j >= 1)&&( j<=N )) begin
|
if ((j >= 1)&&( j<=N )) begin
|
tmp = 0;
|
tmp = 0;
|
for (i = 0; i <= c_stop; i = i + 1) begin
|
for (i = 0; i <= c_stop; i = i + 1) begin
|
prod_1 = nchoosek(N, i);
|
prod_1 = nchoosek(N, i);
|
prod_2 = nchoosek(N - j + k - R * M * i, k - R * M * i);
|
prod_2 = nchoosek(N - j + k - R * M * i, k - R * M * i);
|
summ = prod_1 * prod_2;
|
summ = prod_1 * prod_2;
|
if (i % 2) summ = -summ;
|
if (i % 2) summ = -summ;
|
tmp = tmp + summ;
|
tmp = tmp + summ;
|
end
|
end
|
end
|
end
|
else begin
|
else begin
|
tmp = nchoosek(2 * N + 1 - j, k);
|
tmp = nchoosek(2 * N + 1 - j, k);
|
if (k % 2) tmp = -tmp;
|
if (k % 2) tmp = -tmp;
|
end
|
end
|
h = tmp;
|
h = tmp;
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function reg signed [127:0] F_sq; ///< F()**2
|
function reg signed [127:0] F_sq; ///< F()**2
|
input integer j;
|
input integer j;
|
input integer R;
|
input integer R;
|
input integer M;
|
input integer M;
|
input integer N;
|
input integer N;
|
integer c_stop;
|
integer c_stop;
|
reg signed [127:0] tmp;
|
reg signed [127:0] tmp;
|
integer i;
|
integer i;
|
reg signed [127:0] h_jk;
|
reg signed [127:0] h_jk;
|
begin
|
begin
|
tmp = 0;
|
tmp = 0;
|
if (j <= N)
|
if (j <= N)
|
c_stop = (((R * M -1 ) * N) + j - 1);
|
c_stop = (((R * M -1 ) * N) + j - 1);
|
else
|
else
|
c_stop = 2 * N + 1 - j;
|
c_stop = 2 * N + 1 - j;
|
for (i = 0;i <= c_stop; i = i + 1) begin
|
for (i = 0;i <= c_stop; i = i + 1) begin
|
h_jk = h(j, i, R, M, N);
|
h_jk = h(j, i, R, M, N);
|
tmp = tmp + h_jk ** 2;
|
tmp = tmp + h_jk ** 2;
|
end
|
end
|
F_sq = tmp;
|
F_sq = tmp;
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
function integer B;
|
function integer B;
|
input integer j;
|
input integer j;
|
input integer R;
|
input integer R;
|
input integer M;
|
input integer M;
|
input integer N;
|
input integer N;
|
input integer dw_in;
|
input integer dw_in;
|
input integer dw_out;
|
input integer dw_out;
|
integer B_max;
|
integer B_max;
|
reg signed [127:0] sigma_T_2Np1_sq;
|
reg signed [127:0] sigma_T_2Np1_sq;
|
reg signed [127:0] B_2Np1;
|
reg signed [127:0] B_2Np1;
|
reg signed [127:0] B_exp_real;
|
reg signed [127:0] B_exp_real;
|
integer B_out;
|
integer B_out;
|
reg signed [127:0] F_sq_j;
|
reg signed [127:0] F_sq_j;
|
reg signed [127:0] F_sq_2Np1;
|
reg signed [127:0] F_sq_2Np1;
|
begin
|
begin
|
B_max = B_max_calc(N, R, M, dw_in);
|
B_max = B_max_calc(N, R, M, dw_in);
|
if (j == 2 * N + 1) begin
|
if (j == 2 * N + 1) begin
|
B = B_max - dw_out + 1;
|
B = B_max - dw_out + 1;
|
end else begin
|
end else begin
|
B_2Np1 = B_max - dw_out + 1;
|
B_2Np1 = B_max - dw_out + 1;
|
F_sq_j = F_sq(j, R, M, N);
|
F_sq_j = F_sq(j, R, M, N);
|
F_sq_2Np1 = F_sq(2 * N + 1, R, M, N);
|
F_sq_2Np1 = F_sq(2 * N + 1, R, M, N);
|
sigma_T_2Np1_sq = (128'b1 << (2 * B_2Np1)) * F_sq_2Np1 / 12;
|
sigma_T_2Np1_sq = (128'b1 << (2 * B_2Np1)) * F_sq_2Np1 / 12;
|
B_exp_real = (sigma_T_2Np1_sq / F_sq_j * 6 / N);
|
B_exp_real = (sigma_T_2Np1_sq / F_sq_j * 6 / N);
|
B_out = flog2_l(B_exp_real) / 2;
|
B_out = flog2_l(B_exp_real) / 2;
|
B = B_out;
|
B = B_out;
|
end
|
end
|
end
|
end
|
endfunction
|
endfunction
|
/*********************************************************************************************/
|
/*********************************************************************************************/
|
|
|
`endif
|
`endif
|
|
|
|
|