Browse Source

Transférer les fichiers vers ''

testing
Lilian RM 3 years ago
parent
commit
73342a49be
3 changed files with 483 additions and 0 deletions
  1. +71
    -0
      5k_DFT_pkg.vhd
  2. +153
    -0
      5ndft_tb.vhd
  3. +259
    -0
      FFT_tree.vhd

+ 71
- 0
5k_DFT_pkg.vhd View File

@@ -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;

+ 153
- 0
5ndft_tb.vhd View File

@@ -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;

+ 259
- 0
FFT_tree.vhd View File

@@ -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;

Loading…
Cancel
Save