VHDL implementation of a polyphase filter bank with polyphase filter and 5ndft
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

250 lines
7.1KB

  1. clear all;
  2. clear;
  3. close all;
  4. rng(1); % random seed
  5. global ns average quantization Q1 Q2 Q2_1 Q2_2 Q3 fs M D sb_nbr Apass Astop dens
  6. %% Parameter
  7. ns = 2e6; % Number of Sample
  8. fs = 40e9; % Sampling Frequency
  9. M = 20; % Polyphase factor
  10. D = 8; % Decimator
  11. sb_nbr = 3; % Sub-band Number in OPFB : 1 -> M
  12. average = 0; % PSD smoothing : 0 = OFF ; 1 = ON
  13. quantization = 1; % 0 = OFF ; 1 = ON
  14. Q1 = 6; % DG Quantization
  15. Q2 = 8; % PF coefficients Quantization
  16. Q2_1 = 8; % TAP Winograd Quantizantion
  17. Q2_2 = 8; % TAP radix2 Quantization
  18. Q3 = 6; % PFB final Quantization
  19. Apass = 0.25; % Passband Ripple (dB)
  20. Astop = 50; % Stopband Attenuation (dB)
  21. dens = 50; % Density Factor
  22. %% Input Signal
  23. bw = fs/M; % OPFB Output Bandwidth
  24. f1 = bw*(sb_nbr);
  25. f2 = bw*(sb_nbr-0.625+0.25*mod(sb_nbr,M/gcd(M,D)));
  26. t = 0:1/fs:(ns-1)/fs;
  27. sw1 = 1*sin(2*pi*f1*t);
  28. sw2 = 1*sin(2*pi*f1*t);
  29. noise = randn([1 ns]);
  30. nsw = noise+sw1+sw2;
  31. % win = hanning(ns);
  32. % if average == 0
  33. % [PSD, FREQ] = periodogram(nsw,win,ns,fs);
  34. % else
  35. % [PSD, FREQ] = pwelch(nsw,ns/100,[],ns,fs);
  36. % end
  37. % figure;
  38. % MAX = max(10*log(PSD));
  39. % plot(FREQ/1e9, 10*log(PSD)-MAX);
  40. % title('Real Input signal');
  41. % xlim([0,fs/1e9]);
  42. % grid on;
  43. %% Digitizer Anti-aliasing Filter
  44. f = [0 0.1 0.9 1];
  45. m = [0 1 1 0];
  46. b = fir2(1000,f,m);
  47. s_dg_real = conv(noise+sw1,b,'valid');
  48. s_dg_imag = conv(noise+sw2,b,'valid');
  49. s_dg_bb = 0*s_dg_real+1i*s_dg_imag;
  50. ns_dg_bb = size(s_dg_bb,2);
  51. if quantization == 1
  52. s_dg_bb_fi = fi(s_dg_bb,1,Q1,0);
  53. s_dg_bb = s_dg_bb_fi.data;
  54. end
  55. win = hanning(ns_dg_bb);
  56. if average == 0
  57. [PSD, FREQ] = periodogram(s_dg_bb,win,ns_dg_bb,fs);
  58. else
  59. [PSD, FREQ] = pwelch(s_dg_bb,ns_dg_bb/100,[],ns_dg_bb,fs);
  60. end
  61. figure;
  62. MAX = max(10*log(PSD));
  63. plot(FREQ/1e9, 10*log(PSD)-MAX);
  64. title('Dual complex input signal');
  65. xlim([0,fs/1e9]);
  66. grid on;
  67. %% Oversampled Polyphase Filter Bank
  68. % All frequency values are in GHz.
  69. Fs = fs/1e9; % Sampling Frequency
  70. Fpass = (1-(1-D/M))*Fs/M; % Passband Frequency
  71. Fstop = Fs/M; % Stopband Frequency
  72. Dpass = 1-10^(-Apass/20); % Passband Ripple
  73. Dstop = 10^(-Astop/20); % Stopband Attenuation
  74. % Calculate the order from the parameters using FIRPMORD.
  75. [N, Fo, Ao, W] = firpmord([Fpass, Fstop]/(Fs), [1 0], [Dpass, Dstop]);
  76. Ndec0 = N;
  77. if (mod(N,M) ~= M-1)
  78. N = N + M-1 - mod(N,M);
  79. end
  80. % Calculate the coefficients using the FIRPM function.
  81. Hdec0 = firpm(N, Fo, Ao, W, {dens});
  82. % Calculate polyphase filter
  83. Hdec0 = fliplr(Hdec0);
  84. len = length(Hdec0);
  85. nrows = len/M;
  86. Hdec0_pol = zeros(M,nrows);
  87. for m=1:M
  88. for i=1:nrows
  89. Hdec0_pol(m,i)=Hdec0(1,(i-1)*M+m);
  90. end
  91. end
  92. if quantization == 1
  93. Hdec0_pol_fi = fi(Hdec0_pol,1,Q2);
  94. Hdec0_pol = Hdec0_pol_fi.data;
  95. end
  96. tb_coeff = reshape(Hdec0_pol*2^(Hdec0_pol_fi.FractionLength), 1, size(Hdec0_pol,1)*size(Hdec0_pol,2));
  97. % Demux Input
  98. ns_dg_rs1 = floor((ns_dg_bb-M)/D);
  99. s_dg_rs1 = zeros(M,ns_dg_rs1);
  100. for m=1:M
  101. for i=1:ns_dg_rs1
  102. s_dg_rs1(m,i) = s_dg_bb(1,(i-1)*D+m);
  103. end
  104. end
  105. s_dg_rs1 = flipud(s_dg_rs1);
  106. % Circular shifting
  107. s_dg_rs2 = s_dg_rs1;
  108. ns_dg_rs2 = ns_dg_rs1;
  109. % for i = 1:ns_dg_rs2
  110. % s_dg_rs2(:,i) = flip((s_dg_bb((i-1)*D+1:(i-1)*D+M))');
  111. % end
  112. for i=1:ns_dg_rs2
  113. for m=1:M
  114. s_dg_rs2(m,i) = s_dg_rs1(1+mod( (m-1) + mod((i-1)*D,M) ,M),i);
  115. end
  116. end
  117. % Apply polyphase filter
  118. ns_pol = ns_dg_rs2-(nrows-1);
  119. s_pol = zeros(M,ns_pol);
  120. for m=1:M
  121. s_pol(m,:) = conv(s_dg_rs2(m,:),Hdec0_pol(m,:),'valid');
  122. end
  123. s_pol = s_pol(:,5:end); % to fit with the VHDL sim vector
  124. ns_pol = ns_pol-4;
  125. s_pol_fi = fi(s_pol,1,19,10+floor(M/20)); % attention, M=20 => 11, M=10 => 10
  126. s_pol = s_pol_fi.data;
  127. % DFT
  128. s_pol_dft = zeros(M,ns_pol);
  129. if M == 10
  130. s_pol_rearranged = [s_pol(1,:); s_pol(3,:); s_pol(5,:); s_pol(7,:); s_pol(9,:); s_pol(2,:); s_pol(4,:); s_pol(6,:); s_pol(8,:); s_pol(10,:)];
  131. elseif M == 20
  132. s_pol_rearranged = [s_pol(1,:); s_pol(5,:); s_pol(9,:); s_pol(13,:); s_pol(17,:); s_pol(3,:); s_pol(7,:); s_pol(11,:); s_pol(15,:); s_pol(19,:); s_pol(2,:); s_pol(6,:); s_pol(10,:); s_pol(14,:); s_pol(18,:); s_pol(4,:); s_pol(8,:); s_pol(12,:); s_pol(16,:); s_pol(20,:)];
  133. end
  134. %%
  135. for i = 1:M/5
  136. s_pol_dft(1+5*(i-1):5*i,:) = winograd5(s_pol_rearranged(1+5*(i-1):5*i,:), 8);
  137. end
  138. wn5 = fi(exp(-2*1i*pi*[0:4]/10), 1, Q2_1, Q2_1-2);
  139. wn5 = wn5.data;
  140. wn10 = fi(exp(-2*1i*pi*[0:9]/20), 1, Q2_2, Q2_2-2);
  141. wn10 = wn10.data;
  142. for i = 1:M/10
  143. s_pol_dft(1+10*(i-1):10*i, :) = radix2(s_pol_dft(1+10*(i-1):10*i, :), wn5);
  144. end
  145. if M == 20
  146. s_pol_dft = radix2(s_pol_dft, wn10);
  147. end
  148. % for i=1:ns_pol
  149. % s_pol_dft(:,i) = fft(s_pol(:,i));
  150. % end
  151. %s_pol_dft(2:end, :) = flip(s_pol_dft(2:end, :));
  152. % for i=1:ns_pol
  153. % for p=1:M
  154. % for m=1:M
  155. % s_pol_dft(p,i) = s_pol_dft(p,i) + s_pol(m,i)*exponential(mod((m-1)*(p-1), M)+1);
  156. % end
  157. % end
  158. % end
  159. tb_input_temp = s_dg_bb*2^s_dg_bb_fi.FractionLength;
  160. tb_input_temp = imag(tb_input_temp(:,M+1:end));
  161. tb_input = zeros(1, length(tb_input_temp));
  162. for i = 1:length(tb_input_temp)
  163. % tb_input(2*i-1) = real(tb_input_temp(i));
  164. tb_input(i) = tb_input_temp(i);
  165. end
  166. tb_output_temp1 = fi(s_pol_dft,1,Q3,Q3-2, 'RoundingMethod', 'Floor');
  167. tb_output_temp = tb_output_temp1.data*2^(tb_output_temp1.FractionLength);
  168. tb_output_temp = reshape(tb_output_temp(6,:), 1, size(tb_output_temp(1,:),1)*size(tb_output_temp(1,:),2));
  169. tb_output = zeros(1, 2*length(tb_output_temp));
  170. for i = 1:length(tb_output_temp)
  171. tb_output(2*i-1) = real(tb_output_temp(i));
  172. tb_output(2*i) = imag(tb_output_temp(i));
  173. end
  174. %% Sub-band Selection
  175. sb_nbr = 9;
  176. %
  177. % if sb_nbr < M/2
  178. % s_pol_sel = s_pol_dft(sb_nbr+1,:)+conj(s_pol_dft(M-sb_nbr+1,:));
  179. % elseif sb_nbr == M/2
  180. % s_pol_sel = s_pol_dft(sb_nbr+1,:);
  181. % if sb_nbr < M
  182. % s_pol_sel = -1i*s_pol_dft(sb_nbr+1,:)+conj(-1i*s_pol_dft(M-sb_nbr+1,:));
  183. % elseif sb_nbr == M
  184. % s_pol_sel = s_pol_dft(1,:);
  185. % end
  186. s_pol_sel = s_pol_dft(sb_nbr,:);
  187. % s_pol_sel = s_pol_dft(sb_nbr+1,:)+conj(s_pol_dft(M-sb_nbr+1,:));
  188. % s_pol_sel = -1i*s_pol_dft(sb_nbr+1,:)+conj(-1i*s_pol_dft(M-sb_nbr+1,:));
  189. s_pol_sel=s_pol_sel.*exp(-1i*pi*[1:ns_pol])/2;
  190. win = hanning(ns_pol);
  191. if average == 0
  192. [PSD, FREQ] = periodogram(s_pol_sel,win,ns_pol,(fs)/D);
  193. else
  194. [PSD, FREQ] = pwelch(s_pol_sel,floor(ns_pol/100),[],ns_pol,(fs)/D);
  195. end
  196. figure;
  197. MAX = max(10*log(PSD));
  198. plot(FREQ/1e9, 10*log(PSD)-MAX);
  199. title('Complex output signal');
  200. xlim([0,(fs)/D/1e9]);
  201. grid on;
  202. %% Printf
  203. demux = M;
  204. file_folder = strcat(pwd, '/tb_txts_files');
  205. write_file(tb_input, strcat(file_folder, '/input.txt'), 80, ' %3d');
  206. write_file(tb_output, strcat(file_folder, '/output.txt'), 20, ' %3d');
  207. gen_Wn_coeffs_5ndft(M, Q2_2, strcat(file_folder, '/coeffs_dft.vhd'));
  208. write_polyfir_coeffs(strcat(file_folder, '/coeffs_fir.vhd'), tb_coeff);