From 73342a49be45b6dc7eefdf71a3d2e6bc672a36a6 Mon Sep 17 00:00:00 2001 From: Lilian RM Date: Wed, 29 Jul 2020 08:51:31 +0100 Subject: [PATCH] =?UTF-8?q?Transf=C3=A9rer=20les=20fichiers=20vers=20''?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- 5k_DFT_pkg.vhd | 71 ++++++++++++++ 5ndft_tb.vhd | 153 +++++++++++++++++++++++++++++ FFT_tree.vhd | 259 +++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 483 insertions(+) create mode 100644 5k_DFT_pkg.vhd create mode 100644 5ndft_tb.vhd create mode 100644 FFT_tree.vhd diff --git a/5k_DFT_pkg.vhd b/5k_DFT_pkg.vhd new file mode 100644 index 0000000..0606585 --- /dev/null +++ b/5k_DFT_pkg.vhd @@ -0,0 +1,71 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; +USE ieee.std_logic_unsigned.ALL; +USE ieee.std_logic_signed.ALL; + +-- NOTE: +-- The number of in/output samples must be a 2^n factor of 5, < 160 + +PACKAGE FIVEn_DFT_PKG IS + + CONSTANT cst_w_in_5ndft : natural := 19; -- input_bitwidth + CONSTANT cst_w_out_5ndft : natural := 6; -- output bitwidth, must be < 30 + + CONSTANT cst_nb_samples_in_5ndft : natural := 20; -- must be 5*n + + CONSTANT cst_w_precision_winograd5_coeffs_5ndft : natural := 8; -- must be <= 32 and >= 3, sign bit included. Ideal is >= 8 + CONSTANT cst_w_precision_radix2_coeffs_5ndft : natural := 8; -- must be <= 32 and >= 3, sign bit included. Ideal is >= 8 + -- CALCULATIONS -- + + CONSTANT cst_nb_parallel_winograd5 : natural := cst_nb_samples_in_5ndft/5; + + CONSTANT cst_log2_nb_parallel_winograd5 : natural := 2; -- = log2(cst_nb_parallel_winograd5) + CONSTANT cst_w_winograd_added : natural := cst_w_precision_winograd5_coeffs_5ndft+6; -- 6 is the number of addition stages in the winograd5 blk + CONSTANT cst_w_radix2_added : natural := cst_w_precision_radix2_coeffs_5ndft+2; + CONSTANT cst_dft_w_out_5ndft : natural := cst_w_in_5ndft+cst_w_winograd_added+(cst_log2_nb_parallel_winograd5*cst_w_radix2_added); + CONSTANT cst_winograd5_w_out_5ndft : natural := cst_w_in_5ndft+cst_w_winograd_added; -- 6 is the number of addition stages in the winograd5 blk + CONSTANT cst_nb_wn_coeffs : natural := cst_nb_samples_in_5ndft/2; + + -- TYPES -- + + SUBTYPE smpl_in_5ndft IS std_logic_vector(cst_w_in_5ndft-1 DOWNTO 0); + SUBTYPE smpl_out_5ndft IS std_logic_vector(cst_w_out_5ndft-1 DOWNTO 0); + + TYPE vect_dft_input IS ARRAY (0 TO cst_nb_samples_in_5ndft-1) OF smpl_in_5ndft; + TYPE vect_dft_output IS ARRAY (0 TO cst_nb_samples_in_5ndft-1) OF smpl_out_5ndft; + -- winograd5 + SUBTYPE smpl_out_winograd5_5ndft IS std_logic_vector(cst_winograd5_w_out_5ndft-1 DOWNTO 0); + SUBTYPE smpl_out_winograd5_signed_5ndft IS signed(cst_winograd5_w_out_5ndft-1 DOWNTO 0); + + TYPE vect_input_winograd5_5ndft IS ARRAY (0 TO 4) OF smpl_in_5ndft; + TYPE vect_output_winograd5_5ndft IS ARRAY (0 TO 4) OF smpl_out_winograd5_5ndft; + TYPE vect_total_output_winograd5_cells IS ARRAY (0 TO cst_nb_samples_in_5ndft-1) OF smpl_out_winograd5_5ndft; + + TYPE vect_winograd5_generic_stage IS ARRAY (0 TO 5) OF smpl_out_winograd5_5ndft; + TYPE matrix_winograd5_generic_stages IS ARRAY (0 TO 7) OF vect_winograd5_generic_stage; + + SUBTYPE smpl_mult_factor_w_multipliers IS std_logic_vector(cst_w_precision_winograd5_coeffs_5ndft-1 DOWNTO 0); + SUBTYPE smpl_mult_factor_w_multipliers_signed IS signed(cst_w_precision_winograd5_coeffs_5ndft-1 DOWNTO 0); + TYPE vect_mult_factors_32b IS ARRAY (1 TO 5) OF std_logic_vector(31 DOWNTO 0); + TYPE vect_mult_factor_w_multipliers IS ARRAY (1 TO 5) OF smpl_mult_factor_w_multipliers; + + --radix2 + SUBTYPE smpl_cos_sin_wb IS std_logic_vector(cst_w_precision_radix2_coeffs_5ndft-1 DOWNTO 0); + SUBTYPE smpl_cos_sin_signed_wb IS signed(cst_w_precision_radix2_coeffs_5ndft-1 DOWNTO 0); + TYPE vect_cos_sin_k_pi_over_5_32b IS ARRAY(0 TO 4) OF std_logic_vector(31 DOWNTO 0); + TYPE vect_cos_sin_k_pi_over_5_wb IS ARRAY(0 TO 4) OF smpl_cos_sin_wb; + TYPE vect_cos_sin_k_pi_over_80_32b IS ARRAY (0 TO cst_nb_wn_coeffs-1) OF std_logic_vector(31 DOWNTO 0); + + SUBTYPE smpl_out_radix2 IS std_logic_vector(cst_dft_w_out_5ndft-1 DOWNTO 0); + SUBTYPE smpl_out_signed_radix2 IS signed(cst_dft_w_out_5ndft-1 DOWNTO 0); + TYPE vect_radix2_fft_line IS ARRAY (0 TO cst_log2_nb_parallel_winograd5) OF smpl_out_radix2; + TYPE vect_radix2_line IS ARRAY (0 TO 3) OF smpl_out_radix2; + TYPE matrix_radix2_cell IS ARRAY (0 TO 1) OF vect_radix2_line; + + -- whole fft + TYPE matrix_fft_stages IS ARRAY (0 TO cst_nb_samples_in_5ndft-1) OF vect_radix2_fft_line; -- inputs and outputs of radix2 cells + +END; + + diff --git a/5ndft_tb.vhd b/5ndft_tb.vhd new file mode 100644 index 0000000..32736b7 --- /dev/null +++ b/5ndft_tb.vhd @@ -0,0 +1,153 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.numeric_std.ALL; +USE work.FIVEn_DFT_PKG.ALL; +USE work.simu_pkg.ALL; +USE work.utils.ALL; +LIBRARY std; +USE std.textio.ALL; + +ENTITY fivendft_tb IS + + GENERIC ( + demi_periode : time := 5 ns; +-- duree de la demi periode des horloges + test_e : string := "D:\Stage\ALMA_OPFB\simu\kx5_DFT - tb_6b\tb_txts_files\input.txt"; +-- fichier test contenant les echantillons d'entree + test_s : string := "D:\Stage\ALMA_OPFB\simu\kx5_DFT - tb_6b\tb_txts_files\output.txt" +-- fichier contenant les echantillons de sortie + + + ); + +END fivendft_tb; + +ARCHITECTURE beh OF fivendft_tb IS + TYPE input_vect IS ARRAY (0 TO 2*cst_nb_samples_in_5ndft-1) OF smpl_in_5ndft; + TYPE output_vect IS ARRAY (0 TO 2*cst_nb_samples_in_5ndft-1) OF std_logic_vector(5 DOWNTO 0); --smpl_out_5ndft; + TYPE verif_vect IS ARRAY (0 TO 2*cst_nb_samples_in_5ndft-1) OF integer; + --TYPE partial_input_vect IS ARRAY (0 TO 9) OF smpl_in_5ndft; + --TYPE partial_output_vect IS ARRAY (0 TO 9) OF smpl_in_5ndft; + --TYPE vect_from_matrix_fir_data_out IS ARRAY (0 TO cst_nb_subfilters*cst_nb_parallel_firs-1) OF smpl_fir_data_out; + FILE fichier_e : text IS IN test_e; + FILE fichier_s : text IS IN test_s; + --FILE fichier_c : text IS IN test_c; + + SIGNAL initialisation : std_logic; + SIGNAL h : std_logic; + SIGNAL entree_dft : input_vect := (OTHERS => (OTHERS => '0')); + SIGNAL sortie_dft : output_vect := (OTHERS => (OTHERS => '0')); + SIGNAL sortie_dft_sim : output_vect := (OTHERS => (OTHERS => '0')); + SIGNAL input_vect_re : vect_dft_input; + SIGNAL input_vect_im : vect_dft_input; + SIGNAL output_vect_re : vect_dft_output; + SIGNAL output_vect_im : vect_dft_output; + SIGNAL verif : verif_vect; + + +BEGIN -- ARCHITECTURE beh + + + fill_module : FOR i IN 0 TO cst_nb_samples_in_5ndft-1 GENERATE + input_vect_re(i) <= entree_dft(i); + input_vect_im(i) <= entree_dft(i+cst_nb_samples_in_5ndft); + sortie_dft_sim(i) <= output_vect_re(i); + sortie_dft_sim(i+cst_nb_samples_in_5ndft) <= output_vect_im(i); + END GENERATE fill_module; + + module_simu : ENTITY work.fft_tree(instanciating_cells) + PORT MAP(h, input_vect_re, input_vect_im, output_vect_re, output_vect_im); + + horloge_entree : horloge(h, demi_periode, demi_periode); + + --sortie_dft_sim_process : PROCESS(sortie_dft_sim) + -- VARIABLE mots_lignes : natural := 20; + --BEGIN + ----FOR k IN 0 TO mots_lignes-1 LOOP + ---- FOR j IN 0 TO cst_nb_subfilters-1 LOOP + ---- sortie_fir_sim_vect(k*mots_lignes+j) <= sortie_fir_sim(j)(k); + ---- END LOOP; + ----END LOOP; + --END PROCESS; + + source : PROCESS + CONSTANT header : natural := 1; -- nombre de ligne d'en tête + CONSTANT nbr_ech : natural := 400000; -- nombre d'echantillons d'entree dans le fichier test + CONSTANT mots_ligne : natural := 2*cst_nb_samples_in_5ndft; -- nombre de mots par ligne dans le ficher + VARIABLE nbr_ligne : natural := 10000; -- nombre de lignes restant à lire dans le fichier + VARIABLE i : natural := 1; + VARIABLE donnee : integer; + VARIABLE tempo : natural := 0; + VARIABLE ligne : line; + VARIABLE head : boolean := false; + + BEGIN -- PROCESS source + + WAIT UNTIL falling_edge(h); + + IF head = true THEN + head := false; + FOR i IN 0 TO header-1 LOOP + readline(fichier_e, ligne); + END LOOP; + END IF; + + IF tempo > 0 THEN -- temps de synchro + tempo := tempo -1; + + ELSIF nbr_ligne > 0 THEN + + readline(fichier_e, ligne); + nbr_ligne := nbr_ligne-1; + + FOR k IN 0 TO mots_ligne -1 LOOP + read(ligne, donnee); + entree_dft(k) <= std_logic_vector(to_signed(donnee, cst_w_in_5ndft)); + END LOOP; -- k + + END IF; + + END PROCESS source; + + + test : PROCESS + CONSTANT header : natural := 1; -- nombre de ligne d'en tête + CONSTANT nbr_ech : natural := 400000; --nombre d'echantillons d'entree dans le fichier test + CONSTANT mots_ligne : natural := 2*cst_nb_samples_in_5ndft; -- nombre de mots par ligne dans le ficher + VARIABLE nbr_ligne : natural := 10000; -- nombre de lignes restant à lire dans le fichier + VARIABLE i : natural; + VARIABLE donnee : donnee_sortie; + VARIABLE ligne : line; + VARIABLE tempo : natural := 14; + VARIABLE sortie : integer; + VARIABLE head : boolean := false; + BEGIN -- PROCESS test + + WAIT UNTIL falling_edge(h); + + + IF tempo > 0 THEN -- temps de synchro + tempo := tempo -1; + ASSERT false REPORT "Attente_2 ... " SEVERITY note; + + ELSIF nbr_ligne > 0 THEN + readline(fichier_s, ligne); + nbr_ligne := nbr_ligne-1; + + FOR k IN 0 TO mots_ligne-1 LOOP + read(ligne, donnee(k)); + sortie := to_integer(signed(sortie_dft_sim(k))); + sortie_dft(k) <= std_logic_vector(to_signed(donnee(k), 6)); + verif(k) <= sortie-donnee(k); + ASSERT verif(k) = 0 REPORT "Valeur dft fausse" + SEVERITY error; + --ASSERT sortie /= donnee(k) REPORT "OK" + -- SEVERITY note; + END LOOP; -- k + END IF; + + + + END PROCESS test; + +END ARCHITECTURE beh; diff --git a/FFT_tree.vhd b/FFT_tree.vhd new file mode 100644 index 0000000..f858aba --- /dev/null +++ b/FFT_tree.vhd @@ -0,0 +1,259 @@ +LIBRARY ieee; +USE ieee.std_logic_1164.ALL; +USE ieee.std_logic_signed.ALL; +USE ieee.numeric_std.ALL; +USE work.FIVEn_DFT_PKG.ALL; +USE work.coeff.ALL; + + +ENTITY FFT_tree IS + PORT( + i_clk : IN std_logic; + i_data_re : IN vect_dft_input; + i_data_im : IN vect_dft_input; + o_data_re : OUT vect_dft_output; + o_data_im : OUT vect_dft_output + ); +END FFT_tree; + +ARCHITECTURE instanciating_cells OF FFT_tree IS + + SIGNAL cos_k_pi_over_5 : vect_cos_sin_k_pi_over_5_32b := ("01000000000000000000000000000000", "00110011110001101110111100110111", "00010011110001101110111100110111", "11101100001110010001000011001001", "11001100001110010001000011001001"); -- coeffs multiplied by 2^30 + SIGNAL sin_k_pi_over_5 : vect_cos_sin_k_pi_over_5_32b := ("00000000000000000000000000000000", "11011010011000011011100111110111", "11000011001000011110001111011001", "11000011001000011110001111011001", "11011010011000011011100111110111"); -- coeffs multiplied by 2^30 + + -- purpose: give the proper arrangement for the winograd5 blks + -- the right order: even numbers then odd numbers. The even numbers are the + -- result of others even_odd order multiplied by 2, the odd numbers are the + -- result of others even_odd order multiplied by 2+1. + -- input: the nth winograd5 instance when sort + -- output: the corresponding winograd5 instance number when sort + FUNCTION rearrange ( + i : IN natural) + RETURN natural IS + TYPE vect_rearrange IS ARRAY (0 TO cst_nb_samples_in_5ndft) OF natural; + TYPE matrix_rearrange IS ARRAY (0 TO cst_log2_nb_parallel_winograd5) OF vect_rearrange; + VARIABLE matrix_affect_rearrange : matrix_rearrange := (OTHERS => (OTHERS => 0)); + BEGIN -- FUNCTION rearrange + IF cst_log2_nb_parallel_winograd5 > 0 THEN + matrix_affect_rearrange(1)(1) := 1; + FOR stage IN 2 TO cst_log2_nb_parallel_winograd5 LOOP + FOR i IN 0 TO 2**(stage-1)-1 LOOP + matrix_affect_rearrange(stage)(i) := matrix_affect_rearrange(stage-1)(i)*2; + matrix_affect_rearrange(stage)(i+2**(stage-1)) := matrix_affect_rearrange(stage-1)(i)*2+1; + END LOOP; -- i + END LOOP; -- stage + RETURN matrix_affect_rearrange(cst_log2_nb_parallel_winograd5)(i); + ELSE + RETURN 0; + END IF; + END FUNCTION rearrange; + + TYPE matrix_input_winograd5_5ndft IS ARRAY (0 TO cst_nb_parallel_winograd5-1) OF vect_input_winograd5_5ndft; + TYPE matrix_output_winograd5_5ndft IS ARRAY (0 TO cst_nb_parallel_winograd5-1) OF vect_output_winograd5_5ndft; + + SIGNAL cos_k_pi_over_5_wb : vect_cos_sin_k_pi_over_5_wb := (OTHERS => (OTHERS => '0')); + SIGNAL sin_k_pi_over_5_wb : vect_cos_sin_k_pi_over_5_wb := (OTHERS => (OTHERS => '0')); + + SIGNAL data_out_winograd5_re : vect_total_output_winograd5_cells := (OTHERS => (OTHERS => '0')); + SIGNAL data_out_winograd5_im : vect_total_output_winograd5_cells := (OTHERS => (OTHERS => '0')); + SIGNAL winograd_rearranged_input_re : vect_dft_input := (OTHERS => (OTHERS => '0')); + SIGNAL winograd_rearranged_input_im : vect_dft_input := (OTHERS => (OTHERS => '0')); + + SIGNAL matrix_inputs_outputs_radix2_cells_re : matrix_fft_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); + SIGNAL matrix_inputs_outputs_radix2_cells_im : matrix_fft_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); + + SIGNAL vect_input_1_cell_winograd5_re : matrix_input_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0'))); + SIGNAL vect_input_1_cell_winograd5_im : matrix_input_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0'))); + SIGNAL vect_output_1_cell_winograd5_re : matrix_output_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0'))); + SIGNAL vect_output_1_cell_winograd5_im : matrix_output_winograd5_5ndft := (OTHERS => (OTHERS => (OTHERS => '0'))); +BEGIN -- ARCHITECTURE instanciating_cells + + + + -- coeffs cut + + -- purpose: Rounds the data in 32bits into cst_w_precision_radix2_coeffs_5ndft bits (round for + -- MSBs). Should run and cut before simulation and bitstream + -- inputs : the coeffs to be cut sin_k_pi_over_5, cos_k_pi_over_5, sin_k_pi_over_80, cos_k_pi_over_80 + -- outputs: the cut coeffs cos_k_pi_over_5_wb, sin_k_pi_over_5_wb, sin_k_pi_over_80_wb, cos_k_pi_over_80_wb + mult_coeffs_cut : PROCESS(sin_k_pi_over_5, cos_k_pi_over_5) + BEGIN + FOR i IN 0 TO 4 LOOP + cos_k_pi_over_5_wb(i) <= cos_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft); + sin_k_pi_over_5_wb(i) <= sin_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft); + IF(cos_k_pi_over_5(i)(32-cst_w_precision_radix2_coeffs_5ndft-1) = '1') THEN + cos_k_pi_over_5_wb(i) <= std_logic_vector(unsigned(signed(cos_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft))+1)); + END IF; + IF(sin_k_pi_over_5(i)(32-cst_w_precision_radix2_coeffs_5ndft-1) = '1') THEN + sin_k_pi_over_5_wb(i) <= std_logic_vector(unsigned(signed(sin_k_pi_over_5(i)(31 DOWNTO 32-cst_w_precision_radix2_coeffs_5ndft))+1)); + END IF; + END LOOP; -- i + + END PROCESS mult_coeffs_cut; + + + + + + -- inputs rearranging + + -- purpose: affects inputs on their right way (cf. schema and explanations) + -- using the rearrange(i) function, which creates the right winograd + -- instances numbers order. Rearranging inputs order is equivalent to rearranging + -- winograd5 order. + -- inputs: i_data_re, i_data_im + -- outputs: winograd_rearranged_input_re, winograd_rearranged_input_im + rearrange_winograd_input : FOR i IN 0 TO cst_nb_parallel_winograd5-1 GENERATE + five_inputs : FOR j IN 0 TO 4 GENERATE + winograd_rearranged_input_re(rearrange(i => i)*5+j) <= i_data_re(j*cst_nb_parallel_winograd5+i); + winograd_rearranged_input_im(rearrange(i => i)*5+j) <= i_data_im(j*cst_nb_parallel_winograd5+i); + END GENERATE five_inputs; + END GENERATE rearrange_winograd_input; + + + + -- winograd instanciating + + -- purpose: wiring; instanciates the parallel winograd stage with their correct inputs and outputs + -- inputs: winograd_rearranged_input_im, winograd_rearranged_input_re (length + -- cst_nb_samples_in_5ndft each, cut then into subvectors of 5 inputs) + -- instances: WINOGRAD5(Behavioral) + -- outputs: vect_output_1_cell_winograd5_im, vect_output_1_cell_winograd5_re + -- (length cst_nb_samples_in_5ndft each, cut then into subvectors of 5 inputs) + winograd5_instances : FOR i IN 0 TO cst_nb_parallel_winograd5-1 GENERATE + fill_for : FOR j IN 0 TO 4 GENERATE + vect_input_1_cell_winograd5_im(i)(j) <= winograd_rearranged_input_im(j+5*i); + vect_input_1_cell_winograd5_re(i)(j) <= winograd_rearranged_input_re(j+5*i); + data_out_winograd5_im(j+5*i) <= vect_output_1_cell_winograd5_im(i)(j); + data_out_winograd5_re(j+5*i) <= vect_output_1_cell_winograd5_re(i)(j); + END GENERATE fill_for; + winograd5_inst : ENTITY work.WINOGRAD5(Behavioral) + PORT MAP( + i_clk => i_clk, + i_data_im => vect_input_1_cell_winograd5_im(i), + i_data_re => vect_input_1_cell_winograd5_re(i), + o_data_im => vect_output_1_cell_winograd5_im(i), + o_data_re => vect_output_1_cell_winograd5_re(i) + ); + END GENERATE winograd5_instances; + + + + -- winograd results + + -- purpose: fill the 0th stage (input stage) of the matrix instanciating the + -- butterfly (radix2) cells only. + -- inputs: data_out_winograd5_re, data_out_winograd5_im + -- outputs: matrix_inputs_outputs_radix2_cells_re(x)(0), matrix_inputs_outputs_radix2_cells_im(x)(0) + fill_radix2_cells_input_matrix : FOR i IN 0 TO cst_nb_samples_in_5ndft-1 GENERATE + matrix_inputs_outputs_radix2_cells_re(i)(0)(cst_winograd5_w_out_5ndft-1 DOWNTO 0) <= data_out_winograd5_re(i); + matrix_inputs_outputs_radix2_cells_im(i)(0)(cst_winograd5_w_out_5ndft-1 DOWNTO 0) <= data_out_winograd5_im(i); + END GENERATE fill_radix2_cells_input_matrix; + + + + -- purpose: instanciates the first butterfly cells stage (after the winograd + -- results). If there is only 1 parallel winograd5 cell, couple_winograd5_nb + -- will not be use between 0 and -1, so the FOR loop will no execute + -- inputs: matrix_inputs_outputs_radix2_cells_re(x)(0), matrix_inputs_outputs_radix2_cells_im(x)(0) + -- instances: radix_2_cell_winograd(radix2) + -- outputs: matrix_inputs_outputs_radix2_cells_re(x)(1), matrix_inputs_outputs_radix2_cells_im(x)(1) + radix2_cells_stage1 : FOR couple_winograd5_nb IN 0 TO cst_nb_parallel_winograd5/2-1 GENERATE + radix2_winograd_out : FOR i IN 0 TO 4 GENERATE + radix_2_out_winograd_inst : ENTITY work.radix_2_cell_winograd(radix2) + GENERIC MAP( + w_in => cst_winograd5_w_out_5ndft + ) + PORT MAP( + i_clk => i_clk, + i_cos => cos_k_pi_over_5_wb(i MOD 5), + i_sin => sin_k_pi_over_5_wb(i MOD 5), + i_data1_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i)(0), + i_data1_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i)(0), + i_data2_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i+5)(0), + i_data2_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i+5)(0), + o_data1_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i)(1), + o_data1_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i)(1), + o_data2_re => matrix_inputs_outputs_radix2_cells_re(couple_winograd5_nb*10+i+5)(1), + o_data2_im => matrix_inputs_outputs_radix2_cells_im(couple_winograd5_nb*10+i+5)(1) + ); + END GENERATE radix2_winograd_out; + END GENERATE radix2_cells_stage1; + + + + -- radix2 cells instanciation + + -- purpose: instanciates all the butterfly stages (except stage 1). The + -- stages are filled decrementing the stage number + -- inputs: matrix_inputs_outputs_radix2_cells_re(x)(1), matrix_inputs_outputs_radix2_cells_im(x)(1) + -- instances: radix_2_cell_winograd(radix2) + -- outputs: matrix_inputs_outputs_radix2_cells_re(x)(cst_log2_nb_parallel_winograd5), matrix_inputs_outputs_radix2_cells_im(x)(cst_log2_nb_parallel_winograd5) + stages_generation : FOR stage IN 1 TO cst_log2_nb_parallel_winograd5-1 GENERATE + k10_blocks : FOR cell_10_nb IN 1 TO 2**(stage-1) GENERATE + parallel_cells : FOR cell_nb IN (cst_nb_samples_in_5ndft/(2**stage))*(cell_10_nb-1) TO (cst_nb_samples_in_5ndft/(2**stage))*(cell_10_nb)-1 GENERATE + + radix_2_generic_inst : ENTITY work.radix_2_cell_winograd(radix2) + GENERIC MAP( + w_in => cst_winograd5_w_out_5ndft+(cst_log2_nb_parallel_winograd5-stage)*cst_w_radix2_added + ) + PORT MAP( + i_clk => i_clk, + i_cos => cos_k_pi_over_n_wb((cst_nb_wn_coeffs/10/(2**(cst_log2_nb_parallel_winograd5-stage-1))*cell_nb) MOD cst_nb_wn_coeffs), + i_sin => sin_k_pi_over_n_wb((cst_nb_wn_coeffs/10/(2**(cst_log2_nb_parallel_winograd5-stage-1))*cell_nb) MOD cst_nb_wn_coeffs), + i_data1_re => matrix_inputs_outputs_radix2_cells_re(cell_nb)(cst_log2_nb_parallel_winograd5-stage), + i_data1_im => matrix_inputs_outputs_radix2_cells_im(cell_nb)(cst_log2_nb_parallel_winograd5-stage), + i_data2_re => matrix_inputs_outputs_radix2_cells_re(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage), + i_data2_im => matrix_inputs_outputs_radix2_cells_im(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage), + o_data1_re => matrix_inputs_outputs_radix2_cells_re(cell_nb)(cst_log2_nb_parallel_winograd5-stage+1), + o_data1_im => matrix_inputs_outputs_radix2_cells_im(cell_nb)(cst_log2_nb_parallel_winograd5-stage+1), + o_data2_re => matrix_inputs_outputs_radix2_cells_re(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage+1), + o_data2_im => matrix_inputs_outputs_radix2_cells_im(cell_nb+(cst_nb_samples_in_5ndft/(2**stage)))(cst_log2_nb_parallel_winograd5-stage+1) + ); + + END GENERATE parallel_cells; + END GENERATE k10_blocks; + END GENERATE stages_generation; + + + + + + -- output results + + -- purpose: rounds the outputs to have cst_w_out_5ndft bits. Does not round + -- if cst_w_out_5ndft = cst_dft_w_out_5ndft + -- type : sequential + -- inputs : i_clk, matrix_inputs_outputs_radix2_cells_re, matrix_inputs_outputs_radix2_cells_im + -- outputs: o_data_re, i_data_im + output_rounding : PROCESS (i_clk) IS + BEGIN -- PROCESS output_rounding + IF rising_edge(i_clk) THEN -- rising clock edge + FOR i IN 0 TO cst_nb_samples_in_5ndft-1 LOOP + IF(matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24-cst_w_out_5ndft) = '1' AND cst_w_out_5ndft < cst_dft_w_out_5ndft) THEN + o_data_re(i) <= std_logic_vector(unsigned(signed(matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft))+1)); + ELSE + o_data_re(i) <= matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft); + END IF; + IF(matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24-cst_w_out_5ndft) = '1' AND cst_w_out_5ndft < cst_dft_w_out_5ndft) THEN + o_data_im(i) <= std_logic_vector(unsigned(signed(matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft))+1)); + ELSE + o_data_im(i) <= matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5)(cst_dft_w_out_5ndft-24 DOWNTO cst_dft_w_out_5ndft-23-cst_w_out_5ndft); + END IF; + END LOOP; -- i + END IF; + + END PROCESS output_rounding; + + + + -- if you prefer the whole result, uncomment this section and comment the + -- output_rounding process above. You should also change smpl_out_5ndft from + -- cst_w_out_5ndft to cst_dft_w_out_5ndft (line 32 in FIVEn_dft_pkg). + --fill_outputs : FOR i IN 0 TO cst_nb_samples_in_5ndft-1 GENERATE + -- o_data_re(i) <= matrix_inputs_outputs_radix2_cells_re(i)(cst_log2_nb_parallel_winograd5); + -- o_data_im(i) <= matrix_inputs_outputs_radix2_cells_im(i)(cst_log2_nb_parallel_winograd5); + --END GENERATE fill_outputs; + + +END ARCHITECTURE instanciating_cells;