@@ -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; | |||||
@@ -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; |
@@ -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; |
@@ -0,0 +1,15 @@ | |||||
function gen_Wn_coeffs_5ndft(nb_inputs_tot, bitwidth, file) | |||||
coeff_format = 'library ieee;\nUSE ieee.std_logic_1164.all;\nUSE work.FIVEn_DFT_PKG.all;\npackage coeff is\n TYPE vect_cos_sin_k_pi_over_n_wb IS ARRAY (0 TO cst_nb_wn_coeffs-1) OF smpl_cos_sin_wb ;\n CONSTANT cos_k_pi_over_n_wb : vect_cos_sin_k_pi_over_n_wb := ("'; | |||||
for i = 0:nb_inputs_tot/2-2 | |||||
coeff_format = strcat(coeff_format, string(bin(fi(real(exp(-2*1i*pi*i/nb_inputs_tot)),1,bitwidth, bitwidth-2))), '","'); | |||||
end | |||||
coeff_format = strcat(coeff_format, string(bin(fi(real(exp(-2*1i*pi*(nb_inputs_tot/2-1)/nb_inputs_tot)),1,bitwidth, bitwidth-2))), '");\n CONSTANT sin_k_pi_over_n_wb : vect_cos_sin_k_pi_over_n_wb := ("'); | |||||
for i = 0:nb_inputs_tot/2-2 | |||||
coeff_format = strcat(coeff_format, string(bin(fi(imag(exp(-2*1i*pi*i/nb_inputs_tot)),1,bitwidth, bitwidth-2))), '","'); | |||||
end | |||||
coeff_format = strcat(coeff_format, string(bin(fi(imag(exp(-2*1i*pi*(nb_inputs_tot/2-1)/nb_inputs_tot)),1,bitwidth, bitwidth-2))), '");\nend package coeff;'); | |||||
fcoeff = fopen(file,'w'); | |||||
fprintf(fcoeff,coeff_format); | |||||
fclose(fcoeff); | |||||
end |
@@ -0,0 +1,64 @@ | |||||
LIBRARY ieee; | |||||
USE ieee.std_logic_1164.ALL; | |||||
USE ieee.numeric_std.ALL; | |||||
USE work.FIVEn_DFT_PKG.ALL; | |||||
-- purpose : deledate the multiplication and the addition witn the complex | |||||
-- exponential Wn to this bloc | |||||
ENTITY MULT_BLK_5nDFT IS | |||||
GENERIC( | |||||
w_in : natural; | |||||
w_mult : natural | |||||
); | |||||
PORT(i_clk : IN std_logic; | |||||
i_data_re : IN smpl_out_radix2; | |||||
i_data_im : IN smpl_out_radix2; | |||||
i_cos : IN smpl_cos_sin_wb; | |||||
i_sin : IN smpl_cos_sin_wb; | |||||
o_data_re : OUT smpl_out_radix2; | |||||
o_data_im : OUT smpl_out_radix2 | |||||
); | |||||
END MULT_BLK_5nDFT; | |||||
ARCHITECTURE Mult_Path OF MULT_BLK_5nDFT IS | |||||
SIGNAL data_mult_re_cos_signed : smpl_out_signed_radix2; -- intermediate result re*cos | |||||
SIGNAL data_mult_im_cos_signed : smpl_out_signed_radix2; -- intermediate result im*cos | |||||
SIGNAL data_mult_re_sin_signed : smpl_out_signed_radix2; -- intermediate result im*sin,!i*i=-1! | |||||
SIGNAL data_mult_im_sin_signed : smpl_out_signed_radix2; -- intermediate result re*sin | |||||
SIGNAL sin_signed : smpl_cos_sin_signed_wb; -- signed input sin | |||||
SIGNAL cos_signed : smpl_cos_sin_signed_wb; -- signed input cos | |||||
SIGNAL data_re_signed : smpl_out_signed_radix2; -- signed input data im | |||||
SIGNAL data_im_signed : smpl_out_signed_radix2; -- signed input data re | |||||
BEGIN | |||||
-- assign the signed signals before doing any operation | |||||
data_re_signed(w_in-1 DOWNTO 0) <= signed(i_data_re(w_in-1 DOWNTO 0)); | |||||
data_im_signed(w_in-1 DOWNTO 0) <= signed(i_data_im(w_in-1 DOWNTO 0)); | |||||
cos_signed <= signed(i_cos); | |||||
sin_signed <= signed(i_sin); | |||||
-- purpose: multiply the real and imag part with the cos ans isin part of the | |||||
-- exponential, and add the results of real parts and imag ones together. | |||||
-- Needs 2 clock edges to process the whole mult result | |||||
-- inputs: signed data(im & re), signed exponential (cos & sin) | |||||
-- outputs: o_data_re, o_data_im | |||||
mult : PROCESS(i_clk) | |||||
BEGIN | |||||
IF rising_edge(i_clk) THEN | |||||
data_mult_re_cos_signed(w_in+w_mult-1 DOWNTO 0) <= data_re_signed(w_in-1 DOWNTO 0) * cos_signed; | |||||
data_mult_im_cos_signed(w_in+w_mult-1 DOWNTO 0) <= data_im_signed(w_in-1 DOWNTO 0) * cos_signed; | |||||
data_mult_im_sin_signed(w_in+w_mult-1 DOWNTO 0) <= data_re_signed(w_in-1 DOWNTO 0) * sin_signed; | |||||
data_mult_re_sin_signed(w_in+w_mult-1 DOWNTO 0) <= data_im_signed(w_in-1 DOWNTO 0) * sin_signed; | |||||
o_data_re(w_in+w_mult DOWNTO 0) <= std_logic_vector(unsigned(signed(data_mult_re_cos_signed(w_in+w_mult-1)&data_mult_re_cos_signed(w_in+w_mult-1 DOWNTO 0)) - signed(data_mult_re_sin_signed(w_in+w_mult-1)&data_mult_re_sin_signed(w_in+w_mult-1 DOWNTO 0))));-- i*i=-1 | |||||
o_data_im(w_in+w_mult DOWNTO 0) <= std_logic_vector(unsigned(signed(data_mult_im_cos_signed(w_in+w_mult-1)&data_mult_im_cos_signed(w_in+w_mult-1 DOWNTO 0)) + signed(data_mult_im_sin_signed(w_in+w_mult-1)&data_mult_im_sin_signed(w_in+w_mult-1 DOWNTO 0)))); | |||||
END IF; | |||||
END PROCESS; | |||||
END Mult_Path; |
@@ -0,0 +1,9 @@ | |||||
function output = radix2(input, wn) | |||||
output = 0*input; | |||||
for i = 1:size(input,1)/2 | |||||
s1 = [input(i,:); input(i+(size(input,1)/2),:)*wn(i)]; | |||||
output(i,:) = s1(1,:)+s1(2,:); | |||||
output(i+(size(input,1)/2),:) = s1(1,:)-s1(2,:); | |||||
end | |||||
@@ -0,0 +1,97 @@ | |||||
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; | |||||
ENTITY radix_2_cell_winograd IS | |||||
GENERIC( | |||||
w_in : natural | |||||
); | |||||
PORT( | |||||
i_clk : std_logic; | |||||
i_cos : smpl_cos_sin_wb; | |||||
i_sin : smpl_cos_sin_wb; | |||||
i_data1_re : IN smpl_out_radix2; | |||||
i_data1_im : IN smpl_out_radix2; | |||||
i_data2_re : IN smpl_out_radix2; | |||||
i_data2_im : IN smpl_out_radix2; | |||||
o_data1_re : OUT smpl_out_radix2; | |||||
o_data1_im : OUT smpl_out_radix2; | |||||
o_data2_re : OUT smpl_out_radix2; | |||||
o_data2_im : OUT smpl_out_radix2 | |||||
); | |||||
END radix_2_cell_winograd; | |||||
ARCHITECTURE radix2 OF radix_2_cell_winograd IS | |||||
TYPE vect_result_multiply IS ARRAY (0 TO 1) OF std_logic_vector(w_in + cst_w_precision_radix2_coeffs_5ndft-2 DOWNTO 0); | |||||
SIGNAL signed_data_im : smpl_out_winograd5_signed_5ndft := (OTHERS => '0'); | |||||
SIGNAL signed_data_re : smpl_out_winograd5_signed_5ndft := (OTHERS => '0'); | |||||
SIGNAL multiply_by_2_power_cst_w_precision : std_logic_vector(cst_w_precision_radix2_coeffs_5ndft-3 DOWNTO 0) := (OTHERS => '0'); | |||||
SIGNAL data_matrix_im : matrix_radix2_cell := (OTHERS => (OTHERS => (OTHERS => '0'))); | |||||
SIGNAL data_matrix_re : matrix_radix2_cell := (OTHERS => (OTHERS => (OTHERS => '0'))); | |||||
SIGNAL data_vect_result_mult_re : vect_result_multiply := (OTHERS => (OTHERS => '0')); | |||||
SIGNAL data_vect_result_mult_im : vect_result_multiply := (OTHERS => (OTHERS => '0')); | |||||
BEGIN | |||||
-- assign block inputs and outputs their corresponding matrix columns | |||||
data_matrix_re(0)(0) <= i_data1_re; | |||||
data_matrix_re(1)(0) <= i_data2_re; | |||||
data_matrix_im(0)(0) <= i_data1_im; | |||||
data_matrix_im(1)(0) <= i_data2_im; | |||||
o_data1_re <= data_matrix_re(0)(3); | |||||
o_data2_re <= data_matrix_re(1)(3); | |||||
o_data1_im <= data_matrix_im(0)(3); | |||||
o_data2_im <= data_matrix_im(1)(3); | |||||
--instanciating the MULT_BLK_5nDFT(Mult_Path) | |||||
mult_inst1 : ENTITY work.MULT_BLK_5nDFT(Mult_Path) | |||||
GENERIC MAP( | |||||
w_in => w_in, | |||||
w_mult => cst_w_precision_radix2_coeffs_5ndft | |||||
) | |||||
PORT MAP(i_clk => i_clk, | |||||
i_data_re => data_matrix_re(1)(0), | |||||
i_data_im => data_matrix_im(1)(0), | |||||
i_cos => i_cos, | |||||
i_sin => i_sin, | |||||
o_data_re => data_matrix_re(1)(2), | |||||
o_data_im => data_matrix_im(1)(2) | |||||
); | |||||
-- purpose: calculating the multiplication and the 2 additions/substractions. | |||||
-- The multiplication per 1 in the top of the butterfly is replaced by a | |||||
-- shift with 0s towards the MSBs | |||||
-- inputs: data_matrix_im(x)(0), data_matrix_re(x)(0) | |||||
-- outputs: data_matrix_im(x)(3), data_matrix_re(x)(3) | |||||
radix2_structure : PROCESS(i_clk) | |||||
BEGIN | |||||
IF(rising_edge(i_clk)) THEN | |||||
-- mult per 1 (top) | |||||
data_matrix_im(0)(1)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0) <= data_matrix_im(0)(0)(w_in-1)&data_matrix_im(0)(0)(w_in-1)&data_matrix_im(0)(0)(w_in-1)&data_matrix_im(0)(0)(w_in-1 DOWNTO 0)&multiply_by_2_power_cst_w_precision; | |||||
data_matrix_re(0)(1)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0) <= data_matrix_re(0)(0)(w_in-1)&data_matrix_re(0)(0)(w_in-1)&data_matrix_re(0)(0)(w_in-1)&data_matrix_re(0)(0)(w_in-1 DOWNTO 0)&multiply_by_2_power_cst_w_precision; | |||||
data_matrix_im(0)(2) <= data_matrix_im(0)(1); | |||||
data_matrix_re(0)(2) <= data_matrix_re(0)(1); | |||||
-- mult (down) : see mult_blk instanciation | |||||
--add | |||||
data_matrix_re(0)(3)(w_in+cst_w_precision_radix2_coeffs_5ndft+1 DOWNTO 0) <= std_logic_vector(unsigned(signed(data_matrix_re(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_re(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0))+signed(data_matrix_re(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_re(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0)))); | |||||
data_matrix_re(1)(3)(w_in+cst_w_precision_radix2_coeffs_5ndft+1 DOWNTO 0) <= std_logic_vector(unsigned(signed(data_matrix_re(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_re(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0))-signed(data_matrix_re(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_re(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0)))); | |||||
data_matrix_im(0)(3)(w_in+cst_w_precision_radix2_coeffs_5ndft+1 DOWNTO 0) <= std_logic_vector(unsigned(signed(data_matrix_im(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_im(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0))+signed(data_matrix_im(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_im(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0)))); | |||||
data_matrix_im(1)(3)(w_in+cst_w_precision_radix2_coeffs_5ndft+1 DOWNTO 0) <= std_logic_vector(unsigned(signed(data_matrix_im(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_im(0)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0))-signed(data_matrix_im(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft)&data_matrix_im(1)(2)(w_in+cst_w_precision_radix2_coeffs_5ndft DOWNTO 0)))); | |||||
END IF; | |||||
END PROCESS; | |||||
END radix2; |
@@ -0,0 +1,13 @@ | |||||
LIBRARY ieee; | |||||
USE ieee.std_logic_1164.ALL; | |||||
USE ieee.numeric_std.ALL; | |||||
USE work.FIVEn_DFT_PKG.ALL; | |||||
PACKAGE simu_pkg IS | |||||
TYPE donnee_sortie IS ARRAY (0 TO 2*cst_nb_samples_in_5ndft-1) OF integer; | |||||
CONSTANT w_x_simu : natural := 8; | |||||
END; |
@@ -0,0 +1,239 @@ | |||||
clear all; | |||||
clear; | |||||
close all; | |||||
rng(1); % random seed | |||||
global ns average quantization Q1 Q2 Q3 fs M D sb_nbr Apass Astop dens | |||||
%% Parameter | |||||
ns = 2e6; % Number of Sample | |||||
fs = 40e9; % Sampling Frequency | |||||
M = 20; % Polyphase factor | |||||
D = 8; % Decimator | |||||
sb_nbr = 3; % Sub-band Number in OPFB : 1 -> M | |||||
average = 0; % PSD smoothing : 0 = OFF ; 1 = ON | |||||
quantization = 1; % 0 = OFF ; 1 = ON | |||||
Q1 = 6; % DG Quantization | |||||
Q2 = 8; % TAP Quantizantion | |||||
Q3 = 6; % PFB Quantization | |||||
Apass = 0.25; % Passband Ripple (dB) | |||||
Astop = 50; % Stopband Attenuation (dB) | |||||
dens = 50; % Density Factor | |||||
%% Input Signal | |||||
bw = fs/M; % OPFB Output Bandwidth | |||||
f1 = bw*(sb_nbr); | |||||
f2 = bw*(sb_nbr-0.625+0.25*mod(sb_nbr,M/gcd(M,D))); | |||||
t = 0:1/fs:(ns-1)/fs; | |||||
sw1 = 1*sin(2*pi*f1*t); | |||||
sw2 = 1*sin(2*pi*f1*t); | |||||
noise = randn([1 ns]); | |||||
nsw = noise+sw1+sw2; | |||||
% win = hanning(ns); | |||||
% if average == 0 | |||||
% [PSD, FREQ] = periodogram(nsw,win,ns,fs); | |||||
% else | |||||
% [PSD, FREQ] = pwelch(nsw,ns/100,[],ns,fs); | |||||
% end | |||||
% figure; | |||||
% MAX = max(10*log(PSD)); | |||||
% plot(FREQ/1e9, 10*log(PSD)-MAX); | |||||
% title('Real Input signal'); | |||||
% xlim([0,fs/1e9]); | |||||
% grid on; | |||||
%% Digitizer Anti-aliasing Filter | |||||
f = [0 0.1 0.9 1]; | |||||
m = [0 1 1 0]; | |||||
b = fir2(1000,f,m); | |||||
s_dg_real = conv(noise+sw1,b,'valid'); | |||||
s_dg_imag = conv(noise+sw2,b,'valid'); | |||||
s_dg_bb = 0*s_dg_real+1i*s_dg_imag; | |||||
ns_dg_bb = size(s_dg_bb,2); | |||||
if quantization == 1 | |||||
s_dg_bb_fi = fi(s_dg_bb,1,Q1,0); | |||||
s_dg_bb = s_dg_bb_fi.data; | |||||
end | |||||
win = hanning(ns_dg_bb); | |||||
if average == 0 | |||||
[PSD, FREQ] = periodogram(s_dg_bb,win,ns_dg_bb,fs); | |||||
else | |||||
[PSD, FREQ] = pwelch(s_dg_bb,ns_dg_bb/100,[],ns_dg_bb,fs); | |||||
end | |||||
figure; | |||||
MAX = max(10*log(PSD)); | |||||
plot(FREQ/1e9, 10*log(PSD)-MAX); | |||||
title('Dual complex input signal'); | |||||
xlim([0,fs/1e9]); | |||||
grid on; | |||||
%% Oversampled Polyphase Filter Bank | |||||
% All frequency values are in GHz. | |||||
Fs = fs/1e9; % Sampling Frequency | |||||
Fpass = (1-(1-D/M))*Fs/M; % Passband Frequency | |||||
Fstop = Fs/M; % Stopband Frequency | |||||
Dpass = 1-10^(-Apass/20); % Passband Ripple | |||||
Dstop = 10^(-Astop/20); % Stopband Attenuation | |||||
% Calculate the order from the parameters using FIRPMORD. | |||||
[N, Fo, Ao, W] = firpmord([Fpass, Fstop]/(Fs), [1 0], [Dpass, Dstop]); | |||||
Ndec0 = N; | |||||
if (mod(N,M) ~= M-1) | |||||
N = N + M-1 - mod(N,M); | |||||
end | |||||
% Calculate the coefficients using the FIRPM function. | |||||
Hdec0 = firpm(N, Fo, Ao, W, {dens}); | |||||
% Calculate polyphase filter | |||||
Hdec0 = fliplr(Hdec0); | |||||
len = length(Hdec0); | |||||
nrows = len/M; | |||||
Hdec0_pol = zeros(M,nrows); | |||||
for m=1:M | |||||
for i=1:nrows | |||||
Hdec0_pol(m,i)=Hdec0(1,(i-1)*M+m); | |||||
end | |||||
end | |||||
if quantization == 1 | |||||
Hdec0_pol_fi = fi(Hdec0_pol,1,Q2); | |||||
Hdec0_pol = Hdec0_pol_fi.data; | |||||
end | |||||
% Demux Input | |||||
ns_dg_rs1 = floor((ns_dg_bb-M)/D); | |||||
s_dg_rs1 = zeros(M,ns_dg_rs1); | |||||
for m=1:M | |||||
for i=1:ns_dg_rs1 | |||||
s_dg_rs1(m,i) = s_dg_bb(1,(i-1)*D+m); | |||||
end | |||||
end | |||||
s_dg_rs1 = flipud(s_dg_rs1); | |||||
% Circular shifting | |||||
s_dg_rs2 = s_dg_rs1; | |||||
ns_dg_rs2 = ns_dg_rs1; | |||||
% for i = 1:ns_dg_rs2 | |||||
% s_dg_rs2(:,i) = flip((s_dg_bb((i-1)*D+1:(i-1)*D+M))'); | |||||
% end | |||||
for i=1:ns_dg_rs2 | |||||
for m=1:M | |||||
s_dg_rs2(m,i) = s_dg_rs1(1+mod( (m-1) + mod((i-1)*D,M) ,M),i); | |||||
end | |||||
end | |||||
% Apply polyphase filter | |||||
ns_pol = ns_dg_rs2-(nrows-1); | |||||
s_pol = zeros(M,ns_pol); | |||||
for m=1:M | |||||
s_pol(m,:) = conv(s_dg_rs2(m,:),Hdec0_pol(m,:),'valid'); | |||||
end | |||||
s_pol(:,1:M) = 0*s_pol(:,1:M); | |||||
s_pol(10,1:10) = 1i; | |||||
s_pol_fi = fi(s_pol,1,19,10); | |||||
s_pol = s_pol_fi.data; | |||||
% DFT | |||||
s_pol_dft = zeros(M,ns_pol); | |||||
if M == 10 | |||||
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,:)]; | |||||
elseif M == 20 | |||||
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,:)]; | |||||
end | |||||
%% | |||||
for i = 1:M/5 | |||||
s_pol_dft(1+5*(i-1):5*i,:) = winograd5(s_pol_rearranged(1+5*(i-1):5*i,:), 8); | |||||
end | |||||
%F = fimath('RoundingMethod','Floor','ProductMode','KeepMSB', 'ProductFractionLength',6); | |||||
wn5 = fi(exp(-2*1i*pi*[0:4]/10), 1, 8, 6); | |||||
wn5 = wn5.data; | |||||
wn10 = fi(exp(-2*1i*pi*[0:9]/20), 1, 8, 6); | |||||
wn10 = wn10.data; | |||||
for i = 1:M/10 | |||||
s_pol_dft(1+10*(i-1):10*i, :) = radix2(s_pol_dft(1+10*(i-1):10*i, :), wn5); | |||||
end | |||||
if M == 20 | |||||
s_pol_dft = radix2(s_pol_dft, wn10); | |||||
end | |||||
% for i=1:ns_pol | |||||
% s_pol_dft(:,i) = fft(s_pol(:,i)); | |||||
% end | |||||
%s_pol_dft(2:end, :) = flip(s_pol_dft(2:end, :)); | |||||
% for i=1:ns_pol | |||||
% for p=1:M | |||||
% for m=1:M | |||||
% s_pol_dft(p,i) = s_pol_dft(p,i) + s_pol(m,i)*exponential(mod((m-1)*(p-1), M)+1); | |||||
% end | |||||
% end | |||||
% end | |||||
tb_input = s_pol_fi.data*2^s_pol_fi.FractionLength; | |||||
tb_input = [real(tb_input);imag(tb_input)]; | |||||
tb_input = reshape(tb_input, 1, size(tb_input,1)*size(tb_input,2)); | |||||
tb_output = fi(s_pol_dft,1,6,4); | |||||
tb_output = tb_output.data*2^(4); | |||||
tb_output = floor([real(tb_output);imag(tb_output)]); | |||||
tb_output = reshape(tb_output, 1, size(tb_output,1)*size(tb_output,2)); | |||||
%% Sub-band Selection | |||||
sb_nbr = 9; | |||||
% | |||||
% if sb_nbr < M/2 | |||||
% s_pol_sel = s_pol_dft(sb_nbr+1,:)+conj(s_pol_dft(M-sb_nbr+1,:)); | |||||
% elseif sb_nbr == M/2 | |||||
% s_pol_sel = s_pol_dft(sb_nbr+1,:); | |||||
% if sb_nbr < M | |||||
% s_pol_sel = -1i*s_pol_dft(sb_nbr+1,:)+conj(-1i*s_pol_dft(M-sb_nbr+1,:)); | |||||
% elseif sb_nbr == M | |||||
% s_pol_sel = s_pol_dft(1,:); | |||||
% end | |||||
s_pol_sel = s_pol_dft(sb_nbr,:); | |||||
% s_pol_sel = s_pol_dft(sb_nbr+1,:)+conj(s_pol_dft(M-sb_nbr+1,:)); | |||||
% s_pol_sel = -1i*s_pol_dft(sb_nbr+1,:)+conj(-1i*s_pol_dft(M-sb_nbr+1,:)); | |||||
s_pol_sel=s_pol_sel.*exp(-1i*pi*[1:ns_pol])/2; | |||||
win = hanning(ns_pol); | |||||
if average == 0 | |||||
[PSD, FREQ] = periodogram(s_pol_sel,win,ns_pol,(fs)/D); | |||||
else | |||||
[PSD, FREQ] = pwelch(s_pol_sel,floor(ns_pol/100),[],ns_pol,(fs)/D); | |||||
end | |||||
figure; | |||||
MAX = max(10*log(PSD)); | |||||
plot(FREQ/1e9, 10*log(PSD)-MAX); | |||||
title('Complex output signal'); | |||||
xlim([0,(fs)/D/1e9]); | |||||
grid on; | |||||
%% Printf | |||||
demux = M; | |||||
file_folder = 'D:/Stage/ALMA_OPFB/simu/kx5_DFT - tb_6b_coeffs/tb_txts_files'; | |||||
write_file(tb_input, strcat(file_folder, '/input.txt'), 2*M, ' %4d'); | |||||
write_file(tb_input, strcat(file_folder, '/output.txt'), 2*M, ' %10d'); | |||||
gen_Wn_coeffs_5ndft(M, 8, strcat(file_folder, '/coeffs.vhd')); |
@@ -0,0 +1,8 @@ | |||||
library ieee; | |||||
USE ieee.std_logic_1164.all; | |||||
USE work.FIVEn_DFT_PKG.all; | |||||
package coeff is | |||||
TYPE vect_cos_sin_k_pi_over_n_wb IS ARRAY (0 TO cst_nb_wn_coeffs-1) OF smpl_cos_sin_wb ; | |||||
CONSTANT cos_k_pi_over_n_wb : vect_cos_sin_k_pi_over_n_wb := ("01000000","00111101","00110100","00100110","00010100","00000000","11101100","11011010","11001100","11000011"); | |||||
CONSTANT sin_k_pi_over_n_wb : vect_cos_sin_k_pi_over_n_wb := ("00000000","11101100","11011010","11001100","11000011","11000000","11000011","11001100","11011010","11101100"); | |||||
end package coeff; |
@@ -0,0 +1,33 @@ | |||||
-- *********************** Divers fonction utiles *************************** | |||||
LIBRARY ieee; | |||||
USE ieee.std_logic_1164.ALL; | |||||
PACKAGE utils IS | |||||
PROCEDURE horloge ( SIGNAL h: OUT std_logic; th, tb : time); | |||||
PROCEDURE horloge_retard ( SIGNAL h : OUT std_logic; periode : time ; | |||||
retard : time); | |||||
END utils; | |||||
--------------------------------------------------- | |||||
PACKAGE BODY utils IS | |||||
PROCEDURE horloge ( SIGNAL h : OUT std_logic; th, tb : time) IS | |||||
BEGIN | |||||
LOOP | |||||
h <= '0', '1' AFTER tb; | |||||
WAIT FOR tb + th ; | |||||
END LOOP; | |||||
END; | |||||
PROCEDURE horloge_retard ( SIGNAL h : OUT std_logic; periode : time ; | |||||
retard : time) IS | |||||
BEGIN | |||||
h <= '0'; | |||||
WAIT FOR retard; | |||||
LOOP | |||||
h <= '1' , '0' AFTER periode/2 ; | |||||
WAIT FOR periode; | |||||
END LOOP; | |||||
END; | |||||
END utils; |
@@ -0,0 +1,18 @@ | |||||
function output = winograd55(input, w) | |||||
in = [input(1,:); input(4,:); input(5,:); input(3,:); input(2,:)]; | |||||
s1 = [in(1,:); in(2,:)+in(4,:); in(3,:)+in(5,:); in(2,:)-in(4,:); in(5,:)-in(3,:)]; | |||||
s2 = [s1(1,:); s1(2,:)+s1(3,:); s1(3,:)-s1(2,:); s1(4,:); s1(5,:); s1(4,:)+s1(5,:)]; | |||||
mult = [1 (cos(2*pi/5)+cos(4*pi/5))/2-1 (cos(2*pi/5)-cos(4*pi/5))/2 sin(2*pi/5)-sin(4*pi/5) sin(2*pi/5)+sin(4*pi/5) sin(4*pi/5)]; | |||||
mult = fi(mult, 1, w, w-2); | |||||
mult = mult.data; | |||||
s4 = [s2(1,:)+s2(2,:); s2(2,:)*mult(2); s2(3,:)*mult(3); s2(4,:)*1i*mult(4); s2(5,:)*1i*mult(5); s2(6,:)*1i*mult(6)]; | |||||
s5 = [s4(1,:); s4(1,:)+s4(2,:); s4(3,:); s4(4,:); s4(5,:); s4(6,:)]; | |||||
s6 = [s5(1,:); s5(2,:)-s5(3,:); s5(2,:)+s5(3,:); s5(4,:)+s5(6,:); s5(6,:)-s5(5,:)]; | |||||
output = [s6(1,:); s6(3,:)+s6(5,:); s6(2,:)-s6(4,:); s6(2,:)+s6(4,:); s6(3,:)-s6(5,:)]; | |||||
end | |||||
function output = radix2(input, w) | |||||
s1 = [input(1) input(2)*w]; | |||||
output = [s1(1)+s1(2) s1(1)-s1(2)]; | |||||
end |
@@ -0,0 +1,309 @@ | |||||
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; | |||||
ENTITY WINOGRAD5 IS | |||||
PORT( | |||||
i_clk : IN std_logic; | |||||
i_data_im : IN vect_input_winograd5_5ndft; | |||||
i_data_re : IN vect_input_winograd5_5ndft; | |||||
o_data_im : OUT vect_output_winograd5_5ndft; | |||||
o_data_re : OUT vect_output_winograd5_5ndft | |||||
); | |||||
END WINOGRAD5; | |||||
ARCHITECTURE Behavioral OF WINOGRAD5 IS | |||||
SIGNAL mult_factors : vect_mult_factors_32b := ("10110000000000000000000000000000", "00100011110001101110111100110111", "00010111001111111101011000011110", "01100010011111000110001000101111", "00100101100111100100011000001001"); | |||||
-- multipliers multiplied by 2^30 | |||||
SIGNAL mult_factor_w_multipliers : vect_mult_factor_w_multipliers := (OTHERS => (OTHERS => '0')); | |||||
--SIGNAL matrix_stages_signed_im : matrix_winograd5_generic_signed_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); | |||||
--SIGNAL matrix_stages_signed_re : matrix_winograd5_generic_signed_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); | |||||
SIGNAL matrix_stages_im : matrix_winograd5_generic_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); --matrix(x)(y) = matrix(stage)(layer) form | |||||
SIGNAL matrix_stages_re : matrix_winograd5_generic_stages := (OTHERS => (OTHERS => (OTHERS => '0'))); -- matrix(x)(y) = matrix(stage)(layer) form | |||||
SIGNAL multiply_by_2_power_cst_w_precision : std_logic_vector(cst_w_precision_winograd5_coeffs_5ndft-3 DOWNTO 0) := (OTHERS => '0'); | |||||
--SIGNAL in1, in2 : smpl_out_winograd5_5ndft; | |||||
--SIGNAL isigned : smpl_out_winograd5_signed_5ndft; | |||||
FUNCTION add_sub ( | |||||
w_smpl : IN natural; | |||||
sub : IN boolean; | |||||
in1, in2 : IN smpl_out_winograd5_5ndft) | |||||
RETURN smpl_out_winograd5_5ndft IS | |||||
VARIABLE smpl_stages_out : smpl_out_winograd5_5ndft := (OTHERS => '0'); | |||||
VARIABLE isigned : smpl_out_winograd5_signed_5ndft; | |||||
BEGIN | |||||
IF sub THEN | |||||
isigned(w_smpl DOWNTO 0) := signed(in1(w_smpl-1)&in1(w_smpl-1 DOWNTO 0))-signed(in2(w_smpl-1)&in2(w_smpl-1 DOWNTO 0)); | |||||
ELSE | |||||
isigned(w_smpl DOWNTO 0) := signed(in1(w_smpl-1)&in1(w_smpl-1 DOWNTO 0))+signed(in2(w_smpl-1)&in2(w_smpl-1 DOWNTO 0)); | |||||
END IF; | |||||
smpl_stages_out(w_smpl DOWNTO 0) := std_logic_vector(unsigned(isigned(w_smpl DOWNTO 0))); | |||||
RETURN smpl_stages_out; | |||||
END FUNCTION; | |||||
FUNCTION mult ( | |||||
w_smpl : IN natural; | |||||
cmplx : IN boolean; | |||||
w_coeff : IN natural; | |||||
input : IN smpl_out_winograd5_5ndft; | |||||
coeff : IN smpl_mult_factor_w_multipliers | |||||
) | |||||
RETURN std_logic_vector IS | |||||
VARIABLE smpl_signed : smpl_out_winograd5_signed_5ndft := (OTHERS => '0'); | |||||
VARIABLE smpl_out : smpl_out_winograd5_5ndft; | |||||
BEGIN -- FUNCTION mult | |||||
IF(cmplx) THEN | |||||
smpl_signed(w_smpl+w_coeff-1 DOWNTO 0) := signed(input(w_smpl-1 DOWNTO 0)) * (-signed(coeff)); | |||||
ELSE | |||||
smpl_signed(w_smpl+w_coeff-1 DOWNTO 0) := signed(input(w_smpl-1 DOWNTO 0)) * signed(coeff); | |||||
END IF; | |||||
smpl_out := std_logic_vector(unsigned(smpl_signed)); | |||||
RETURN smpl_out; | |||||
END FUNCTION mult; | |||||
FUNCTION smpl_copy ( | |||||
w_smpl : natural; | |||||
smpl_in : smpl_out_winograd5_5ndft) | |||||
RETURN std_logic_vector IS | |||||
VARIABLE smpl_out : smpl_out_winograd5_5ndft := (OTHERS => '0'); | |||||
BEGIN -- FUNCTION copy | |||||
smpl_out(w_smpl DOWNTO 0) := smpl_in(w_smpl-1)&smpl_in(w_smpl-1 DOWNTO 0); | |||||
RETURN smpl_out; --smpl_in(cst_winograd5_w_out_5ndft-1 DOWNTO w_smpl+1)&smpl_in(w_smpl-1)&smpl_in(w_smpl-1 DOWNTO 0);--smpl_out; | |||||
END FUNCTION smpl_copy; | |||||
BEGIN | |||||
fill_input_output_matrix_for : FOR i IN 0 TO 4 GENERATE | |||||
matrix_stages_im(0)(i)(cst_w_in_5ndft-1 DOWNTO 0) <= i_data_im(i)(cst_w_in_5ndft-1 DOWNTO 0); | |||||
matrix_stages_re(0)(i)(cst_w_in_5ndft-1 DOWNTO 0) <= i_data_re(i)(cst_w_in_5ndft-1 DOWNTO 0); | |||||
o_data_im(i) <= matrix_stages_im(7)(i); | |||||
o_data_re(i) <= matrix_stages_re(7)(i); | |||||
END GENERATE fill_input_output_matrix_for; | |||||
-- purpose: Rounds the data in 32bits into cst_w_precision_winograd5_coeffs_5ndft bits (round for | |||||
-- MSBs). Should run and cut before simulation and bitstream | |||||
-- inputs : the coeffs to be cut mult_factors | |||||
-- outputs: the cut coeffs mult_factor_w_multipliers | |||||
mult_coeffs_cut : PROCESS(mult_factors) | |||||
BEGIN | |||||
FOR i IN 1 TO 5 LOOP | |||||
mult_factor_w_multipliers(i) <= mult_factors(i)(31 DOWNTO 32-cst_w_precision_winograd5_coeffs_5ndft); | |||||
IF(mult_factors(i)(31-cst_w_precision_winograd5_coeffs_5ndft) = '1') THEN | |||||
mult_factor_w_multipliers(i) <= std_logic_vector(unsigned(signed(mult_factors(i)(31 DOWNTO 32-cst_w_precision_winograd5_coeffs_5ndft)) +1)); | |||||
END IF; | |||||
END LOOP; -- i | |||||
END PROCESS mult_coeffs_cut; | |||||
-- purpose: calculates each stage following the winograd5 schema | |||||
-- inputs: matrix_stages_im(0) | |||||
-- outputs: matrix_stages_im(7) | |||||
calculations_process : PROCESS(i_clk) | |||||
VARIABLE w_smpl : natural; | |||||
BEGIN | |||||
IF(rising_edge(i_clk)) THEN | |||||
-- stage 1 | |||||
-- w_smpl :=== cst_w_in_5ndft+1; | |||||
--data0 | |||||
matrix_stages_im(1)(0) <= smpl_copy(w_smpl => cst_w_in_5ndft, smpl_in => matrix_stages_im(0)(0)); | |||||
matrix_stages_re(1)(0) <= smpl_copy(w_smpl => cst_w_in_5ndft, smpl_in => matrix_stages_re(0)(0)); | |||||
-- data1 | |||||
matrix_stages_im(1)(1) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_im(0)(3), in2 => matrix_stages_im(0)(2)); | |||||
matrix_stages_re(1)(1) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_re(0)(3), in2 => matrix_stages_re(0)(2)); | |||||
--data2 | |||||
matrix_stages_im(1)(2) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_im(0)(4), in2 => matrix_stages_im(0)(1)); | |||||
matrix_stages_re(1)(2) <= add_sub (w_smpl => cst_w_in_5ndft, sub => false, in1 => matrix_stages_re(0)(4), in2 => matrix_stages_re(0)(1)); | |||||
--data3 | |||||
matrix_stages_im(1)(3) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_im(0)(3), in2 => matrix_stages_im(0)(2)); | |||||
matrix_stages_re(1)(3) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_re(0)(3), in2 => matrix_stages_re(0)(2)); | |||||
--data4 | |||||
matrix_stages_im(1)(4) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_im(0)(1), in2 => matrix_stages_im(0)(4)); | |||||
matrix_stages_re(1)(4) <= add_sub (w_smpl => cst_w_in_5ndft, sub => true, in1 => matrix_stages_re(0)(1), in2 => matrix_stages_re(0)(4)); | |||||
-- stage 2 | |||||
w_smpl := cst_w_in_5ndft+1; | |||||
-- data0,3,4 | |||||
matrix_stages_im(2)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(1)(0)); | |||||
matrix_stages_re(2)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(1)(0)); | |||||
matrix_stages_im(2)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(1)(3)); | |||||
matrix_stages_re(2)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(1)(3)); | |||||
matrix_stages_im(2)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(1)(4)); | |||||
matrix_stages_re(2)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(1)(4)); | |||||
--data1 | |||||
matrix_stages_im(2)(1) <= add_sub (w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(1)(1), in2 => matrix_stages_im(1)(2)); | |||||
matrix_stages_re(2)(1) <= add_sub (w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(1)(1), in2 => matrix_stages_re(1)(2)); | |||||
--data2 | |||||
matrix_stages_re(2)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(1)(2), in2 => matrix_stages_re(1)(1)); | |||||
matrix_stages_im(2)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(1)(2), in2 => matrix_stages_im(1)(1)); | |||||
--data5 | |||||
matrix_stages_re(2)(5) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(1)(3), in2 => matrix_stages_re(1)(4)); | |||||
matrix_stages_im(2)(5) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(1)(3), in2 => matrix_stages_im(1)(4)); | |||||
-- stage 3 | |||||
w_smpl := cst_w_in_5ndft+2; | |||||
--data1,2,3,4,5 | |||||
matrix_stages_im(3)(1) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(1)); | |||||
matrix_stages_re(3)(1) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(1)); | |||||
matrix_stages_im(3)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(2)); | |||||
matrix_stages_re(3)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(2)); | |||||
matrix_stages_im(3)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(3)); | |||||
matrix_stages_re(3)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(3)); | |||||
matrix_stages_im(3)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(4)); | |||||
matrix_stages_re(3)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(4)); | |||||
matrix_stages_im(3)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(2)(5)); | |||||
matrix_stages_re(3)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(2)(5)); | |||||
--data0 | |||||
matrix_stages_im(3)(0) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(2)(1), in2 => matrix_stages_im(2)(0)); | |||||
matrix_stages_re(3)(0) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(2)(1), in2 => matrix_stages_re(2)(0)); | |||||
-- stage 4, multiply | |||||
w_smpl := cst_w_in_5ndft+3; | |||||
--data0, multiply by 1 = copy | |||||
matrix_stages_im(4)(0)(w_smpl+cst_w_precision_winograd5_coeffs_5ndft-1 DOWNTO 0) <= matrix_stages_im(3)(0)(w_smpl-1)&matrix_stages_im(3)(0)(w_smpl-1)&matrix_stages_im(3)(0)(w_smpl-1 DOWNTO 0)&multiply_by_2_power_cst_w_precision; | |||||
matrix_stages_re(4)(0)(w_smpl+cst_w_precision_winograd5_coeffs_5ndft-1 DOWNTO 0) <= matrix_stages_re(3)(0)(w_smpl-1)&matrix_stages_re(3)(0)(w_smpl-1)&matrix_stages_re(3)(0)(w_smpl-1 DOWNTO 0)&multiply_by_2_power_cst_w_precision; | |||||
--data1 | |||||
matrix_stages_im(4)(1) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(1), coeff => mult_factor_w_multipliers(1)); | |||||
matrix_stages_re(4)(1) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(1), coeff => mult_factor_w_multipliers(1)); | |||||
--data2 | |||||
matrix_stages_im(4)(2) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(2), coeff => mult_factor_w_multipliers(2)); | |||||
matrix_stages_re(4)(2) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(2), coeff => mult_factor_w_multipliers(2)); | |||||
--data3 | |||||
matrix_stages_re(4)(3) <= mult (w_smpl => w_smpl, cmplx => true, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(3), coeff => mult_factor_w_multipliers(3)); | |||||
matrix_stages_im(4)(3) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(3), coeff => mult_factor_w_multipliers(3)); | |||||
--data4 | |||||
matrix_stages_re(4)(4) <= mult (w_smpl => w_smpl, cmplx => true, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(4), coeff => mult_factor_w_multipliers(4)); | |||||
matrix_stages_im(4)(4) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(4), coeff => mult_factor_w_multipliers(4)); | |||||
--data5 | |||||
matrix_stages_re(4)(5) <= mult (w_smpl => w_smpl, cmplx => true, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_im(3)(5), coeff => mult_factor_w_multipliers(5)); | |||||
matrix_stages_im(4)(5) <= mult (w_smpl => w_smpl, cmplx => false, w_coeff => cst_w_precision_winograd5_coeffs_5ndft, input => matrix_stages_re(3)(5), coeff => mult_factor_w_multipliers(5)); | |||||
-- stage 5 | |||||
w_smpl := cst_w_in_5ndft+3+cst_w_precision_winograd5_coeffs_5ndft; | |||||
--data0, 2, 3, 4, 5 | |||||
matrix_stages_im(5)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(0)); | |||||
matrix_stages_re(5)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(0)); | |||||
matrix_stages_im(5)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(2)); | |||||
matrix_stages_re(5)(2) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(2)); | |||||
matrix_stages_im(5)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(3)); | |||||
matrix_stages_re(5)(3) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(3)); | |||||
matrix_stages_im(5)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(4)); | |||||
matrix_stages_re(5)(4) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(4)); | |||||
matrix_stages_im(5)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(4)(5)); | |||||
matrix_stages_re(5)(5) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(4)(5)); | |||||
--data1 | |||||
matrix_stages_re(5)(1) <= add_sub(w_smpl => w_smpl, sub => false, IN1 => matrix_stages_re(4)(1), in2 => matrix_stages_re(4)(0)); | |||||
matrix_stages_im(5)(1) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(4)(1), in2 => matrix_stages_im(4)(0)); | |||||
-- stage 6 | |||||
w_smpl := cst_w_in_5ndft+3+cst_w_precision_winograd5_coeffs_5ndft+1; | |||||
--data0 | |||||
matrix_stages_im(6)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(5)(0)); | |||||
matrix_stages_re(6)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(5)(0)); | |||||
--data1 | |||||
matrix_stages_re(6)(1) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(5)(1), in2 => matrix_stages_re(5)(2)); | |||||
matrix_stages_im(6)(1) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(5)(1), in2 => matrix_stages_im(5)(2)); | |||||
--data2 | |||||
matrix_stages_re(6)(2) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(5)(1), in2 => matrix_stages_re(5)(2)); | |||||
matrix_stages_im(6)(2) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(5)(1), in2 => matrix_stages_im(5)(2)); | |||||
--data3 | |||||
matrix_stages_re(6)(3) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(5)(5), in2 => matrix_stages_re(5)(3)); | |||||
matrix_stages_im(6)(3) <= add_sub(w_smpl => w_smpl, sub => false, IN1 => matrix_stages_im(5)(5), in2 => matrix_stages_im(5)(3)); | |||||
--data4 | |||||
matrix_stages_re(6)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(5)(5), in2 => matrix_stages_re(5)(4)); | |||||
matrix_stages_im(6)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(5)(5), in2 => matrix_stages_im(5)(4)); | |||||
-- stage 7 | |||||
w_smpl := cst_w_in_5ndft+3+cst_w_precision_winograd5_coeffs_5ndft+2; | |||||
--data0 | |||||
matrix_stages_im(7)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_im(6)(0)); | |||||
matrix_stages_re(7)(0) <= smpl_copy(w_smpl => w_smpl, smpl_in => matrix_stages_re(6)(0)); | |||||
--data1 | |||||
matrix_stages_re(7)(1) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(6)(2), in2 => matrix_stages_re(6)(4)); | |||||
matrix_stages_im(7)(1) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(6)(2), in2 => matrix_stages_im(6)(4)); | |||||
--data2 | |||||
matrix_stages_re(7)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(6)(1), in2 => matrix_stages_re(6)(3)); | |||||
matrix_stages_im(7)(2) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(6)(1), in2 => matrix_stages_im(6)(3)); | |||||
--data3 | |||||
matrix_stages_re(7)(3) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_re(6)(1), in2 => matrix_stages_re(6)(3)); | |||||
matrix_stages_im(7)(3) <= add_sub(w_smpl => w_smpl, sub => false, in1 => matrix_stages_im(6)(1), in2 => matrix_stages_im(6)(3)); | |||||
--data4 | |||||
matrix_stages_re(7)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_re(6)(2), in2 => matrix_stages_re(6)(4)); | |||||
matrix_stages_im(7)(4) <= add_sub(w_smpl => w_smpl, sub => true, in1 => matrix_stages_im(6)(2), in2 => matrix_stages_im(6)(4)); | |||||
END IF; | |||||
END PROCESS calculations_process; | |||||
END Behavioral; |
@@ -0,0 +1,11 @@ | |||||
function write_file(input, file, nb_words_per_line, words_format) | |||||
input_format = ''; | |||||
for i=1:nb_words_per_line | |||||
input_format = strcat(input_format,words_format); | |||||
end | |||||
input_format = strcat(input_format,'\n'); | |||||
fin = fopen(file,'w'); | |||||
fprintf(fin,input_format,input); | |||||
fclose(fin); | |||||
end |