diff --git a/gen_Wn_coeffs_5ndft.m b/gen_Wn_coeffs_5ndft.m new file mode 100644 index 0000000..f1f642a --- /dev/null +++ b/gen_Wn_coeffs_5ndft.m @@ -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 \ No newline at end of file diff --git a/mult_blk_5ndft.vhd b/mult_blk_5ndft.vhd new file mode 100644 index 0000000..d55fd4c --- /dev/null +++ b/mult_blk_5ndft.vhd @@ -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; diff --git a/radix2.m b/radix2.m new file mode 100644 index 0000000..84a3d0c --- /dev/null +++ b/radix2.m @@ -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 + \ No newline at end of file diff --git a/radix_2_cell.vhd b/radix_2_cell.vhd new file mode 100644 index 0000000..1ab95bf --- /dev/null +++ b/radix_2_cell.vhd @@ -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; diff --git a/simu_pkg.vhd b/simu_pkg.vhd new file mode 100644 index 0000000..2a41454 --- /dev/null +++ b/simu_pkg.vhd @@ -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;