在线咨询
eetop公众号 创芯大讲堂 创芯人才网
切换到宽版

EETOP 创芯网论坛 (原名:电子顶级开发网)

手机号码,快捷登录

手机号码,快捷登录

找回密码

  登录   注册  

快捷导航
搜帖子
楼主: snowyd

谁会?

[复制链接]
发表于 2004-6-19 21:54:08 | 显示全部楼层

谁会?



下面引用由snowyd2004/06/19 06:02pm 发表的内容:
蝶形块想用一个用于旋转因子复数的乘法器,再加上一个加法和一个减法器!!
还没实现,更谈不上验证仿真!!!
关于蝶形计数,级数计数单元我弄出来了同样没有验证仿真!!!
时序部分用于控制蝶形运算的没有弄 ...

呵呵,还有复数乘法器没有实现,其实可以调用前面的乘法器:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;

entity complex_mult is
      generic(
             data1_width     : integer := 16;                                   -- Size of Data1 (bits)
             data2_width     : integer := 16);                                  -- Size of Data2 (bits)
      port   (
             data_rd        : in std_logic;                                     -- New Sample Read (This is the sampling clk Active High)
             data1_real     : in  std_logic_vector(data1_width-1 downto 0);     -- Data1 Real Value
             data1_imag     : in  std_logic_vector(data1_width-1 downto 0);     -- Data1 Imag Value            
             data2_real     : in  std_logic_vector(data2_width-1 downto 0);     -- Data2 Real Value
             data2_imag     : in  std_logic_vector(data2_width-1 downto 0);     -- Data2 Imag Value
             data_out_real  : out std_logic_vector(data2_width-1 downto 0);     -- Output Data Real Value
             data_out_imag  : out std_logic_vector(data2_width-1 downto 0)      -- Output Data Imag Value
             );
end complex_mult;

architecture rtl of complex_mult is
component Multiplier
generic(
             multiplier_width      : integer := 16;
             data_width            : integer := 16);
        port (
             load                  : in std_logic;
             mult1_data            : in std_logic_vector(data_width-1 downto 0);
             mult2_data            : in std_logic_vector(multiplier_width-1 downto 0);
             product               : out std_logic_vector(multiplier_width+data_width-2 downto (multiplier_width-1))   -- Output product
       );   
end component;
-------------------------------------------------------------------------------
signal last_data_rd             : std_logic;                                            -- Used to sample new data  
signal Mult_A_C_Out             : std_logic_vector(data2_width-1 downto 0);             -- Output from multiplier
signal Mult_A_D_Out             : std_logic_vector(data2_width-1 downto 0);             -- Output from multiplier
signal Mult_B_C_Out             : std_logic_vector(data2_width-1 downto 0);             -- Output from multiplier
signal Mult_B_D_Out             : std_logic_vector(data2_width-1 downto 0);             -- Output from multiplier
signal Out1_signed              : signed (data2_width-1 downto 0);                      -- Real result
signal Out2_signed              : signed (data2_width-1 downto 0);                      -- Imaginary result

begin
complex_mult: process(Mult_A_C_Out, Mult_A_D_Out, Mult_B_C_Out, Mult_B_D_Out)
-- Generate complex multiplier outputs
begin
  Out1_signed <= signed(Mult_A_C_Out) - signed(Mult_B_D_Out);
  Out2_signed <= signed(Mult_A_D_Out) + signed(Mult_B_C_Out);
end process complex_mult;

data_out_real <= std_logic_vector(Out1_signed);
data_out_imag <= std_logic_vector(Out2_signed);

A_C_Mult: Multiplier
generic map (
                  multiplier_width => data1_width,
                  data_width       => data2_width
                  )
         port map (
                  load             => data_rd,
                  mult1_data       => data1_real,
                  mult2_data       => data2_real,
                  product          => Mult_A_C_Out
                  );

A_D_Mult: Multiplier
generic map (
                  multiplier_width => data1_width,
                  data_width       => data2_width
                  )
         port map (
                  load             => data_rd,
                  mult1_data       => data1_real,
                  mult2_data       => data2_imag,
                  product          => Mult_A_D_Out
                  );

B_C_Mult: Multiplier
generic map (
                  multiplier_width => data1_width,
                  data_width       => data2_width
                  )
         port map (
                  load             => data_rd,
                  mult1_data       => data1_imag,
                  mult2_data       => data2_real,
                  product          => Mult_B_C_Out
                  );

B_D_Mult: Multiplier
generic map (
                  multiplier_width => data1_width,
                  data_width       => data2_width
                  )
         port map (
                  load             => data_rd,
                  mult1_data       => data1_imag,
                  mult2_data       => data2_imag,
                  product          => Mult_B_D_Out
                  );
end rtl;
发表于 2004-6-19 21:55:59 | 显示全部楼层

谁会?



下面引用由spark2004/06/19 09:33pm 发表的内容:
www.opencores.org 上有个fft的core是cfft,我觉得写的简单清楚,模块很少,比较好看懂,而且不用乘法器和rom,任意点数。

对啊,opencores上的资源也可以利用一下,看看是不是满足要求。
发表于 2004-6-19 22:00:30 | 显示全部楼层

谁会?

--写一个4点的FFT吧,代码可以短一些。
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;
entity fft is
       generic(
              coeff_width : integer := 16;
              data_width  : integer := 16;
              fft_length  : integer := 4);
       port   (
              reset       : in  std_logic;                               -- Power on reset (Active Low)
              clk         : in  std_logic;                               -- Input clock
              data_rd     : in  std_logic;                               -- New Sample Read (Active High Sampling Clock)
              data_in_r   : in  std_logic_vector(Data_width-1 downto 0); -- Input real data
              data_in_i   : in  std_logic_vector(Data_width-1 downto 0); -- Input imaginary data
              address     : in  std_logic_vector(2 downto 0);            -- Address bus for accessing output results array
              data_out_r  : out std_logic_vector(Data_width-1 downto 0); -- Output real data
              data_out_i  : out std_logic_vector(Data_width-1 downto 0); -- Output imaginary data
              res_valid   : out std_logic                                -- Indicates that results are now valid
              );
end fft;
architecture fft_architecture of fft is

component dual_port_ram
      generic(
             data_width     : integer := 16;
             ram_length     : integer := 64);
      port   (
             data_in        : in  std_logic_vector(data_width-1 downto 0);-- Input Data
             data_out1      : out std_logic_vector(data_width-1 downto 0);-- Output Data1
             data_out2      : out std_logic_vector(data_width-1 downto 0);-- Output Data2
             clk            : in std_logic;                               -- Input Clock
             en             : in std_logic;                               -- Ram Enable
             we             : in std_logic;                               -- Write Enable...Active Low
             address1       : in std_logic_vector(2 downto 0);            -- Ram Address1
             address2       : in std_logic_vector(2 downto 0)             -- Ram Address2
             );
end component;

component stg1_butterfly
      generic(
             data_width     : integer := 16;                                  -- No of Data bits
             int_data_width : integer := 16;                                  -- Size of internal data bus after multiplication and truncation
             tw_fact_width  : integer := 16);                                 -- No of Twiddle Factor bits
      port   (
             reset          : in std_logic;                                   -- Reset
             clk            : in std_logic;                                   -- Input Clock
             data_rd        : in std_logic;                                   -- New Sample Read (This is the sampling clk Active High)
             data1_r_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data1 Real
             data1_i_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data1 Imag
             data2_r_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data2 Real
             data2_i_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data2 Real
             tf1_r          : in  std_logic_vector(tw_fact_width-1 downto 0); -- Twiddle Factor1 Real Data
             data1_r_out    : out std_logic_vector(int_data_width-1 downto 0);-- Output Data1 Real
             data1_i_out    : out std_logic_vector(int_data_width-1 downto 0);-- Output Data1 Imag
             data2_r_out    : out std_logic_vector(int_data_width-1 downto 0);-- Output Data2 Real
             data2_i_out    : out std_logic_vector(int_data_width-1 downto 0) -- Output Data2 Imag
             );
end component;

component butterfly
      generic(
             data_width     : integer := 16;                                  -- Size of Data (bits)
             tw_fact_width  : integer := 16);                                 -- Size of Twiddle Factor (bits)
      port   (
             reset          : in std_logic;                                   -- Reset
             clk            : in std_logic;                                   -- Input Clock
             data_rd        : in std_logic;                                   -- New Sample Read (This is the sampling clk Active High)
             data1_r_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data1 Real
             data1_i_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data1 Imag
             data2_r_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data2 Real
             data2_i_in     : in  std_logic_vector(data_width-1 downto 0);    -- Input Data2 Real
             tf1_r          : in  std_logic_vector(tw_fact_width-1 downto 0); -- Twiddle Factor1 Real Data
             tf1_i          : in  std_logic_vector(tw_fact_width-1 downto 0); -- Twiddle Factor1 Imag Data
             data1_r_out    : out std_logic_vector(data_width-1 downto 0);    -- Output Data1 Real
             data1_i_out    : out std_logic_vector(data_width-1 downto 0);    -- Output Data1 Imag
             data2_r_out    : out std_logic_vector(data_width-1 downto 0);    -- Output Data2 Real
             data2_i_out    : out std_logic_vector(data_width-1 downto 0)     -- Output Data2 Imag
             );
end component;
发表于 2004-6-19 22:04:20 | 显示全部楼层

谁会?

--接上贴,继续
constant int_data_width: INTEGER := 16;                                         -- Defining constant for internal data width
subtype data_value is std_logic_vector(data_width-1 downto 0);                  -- Defining subtype for Data Values
subtype int_data_value is std_logic_vector(int_data_width-1 downto 0);          -- Defining subtype for Internal Data Values
subtype coeff_value is std_logic_vector(coeff_width-1 downto 0);                -- Defining subtype for twiddle factor coefficients
type TF_R_Array is array (0 to fft_length-1) of coeff_value;                    -- Defining array type to contain real part of twiddle factors
type TF_I_Array is array (0 to fft_length-1) of coeff_value;                    -- Defining array type to contain imaginary part of twiddle factors
type FFT_Data_Array is array (0 to ((2*fft_length)-1)) of data_value;           -- Defining array type to contain real and imaginary parts of input data
type Stage_Result_Values is array (0 to ((2*fft_length)-1)) of int_data_value;  -- Defining array type to contain real and imaginary values for each butterfly stage
type FFT_Magnitude_Array is array (0 to fft_length-1) of data_value;            -- Defining array type to contain FFT magnitude values           

signal TWF_R                             : TF_R_Array;                                  -- Storage for real part of twiddle factor coefficients
signal TWF_I                             : TF_I_Array;                                  -- Storage for imaginary part of twiddle factor coefficients
signal last_data_rd                      : std_logic;                                   -- Used to indicate rising edge of sampling input signal
signal Input_data_ram1                   : std_logic_vector(data_width-1 downto 0);     -- Input data to Ram1
signal Input_data_ram2                   : std_logic_vector(data_width-1 downto 0);     -- Input data to Ram2
signal Ram1_real_input_data_sum          : signed(data_width+1 downto 0);               -- The sum of all Ram1 real data values
signal Ram1_imag_input_data_sum          : signed(data_width+1 downto 0);               -- The sum of all Ram1 imaginary data values
signal Ram1_real_input_data_average      : signed(data_width-1 downto 0);               -- Average of Ram1 real input data
signal Ram1_imag_input_data_average      : signed(data_width-1 downto 0);               -- Average of Ram1 imaginary input data
signal Ram2_real_input_data_sum          : signed(data_width+1 downto 0);               -- The sum of all Ram2 real data values
signal Ram2_imag_input_data_sum          : signed(data_width+1 downto 0);               -- The sum of all Ram2 imaginary data values
signal Ram2_real_input_data_average      : signed(data_width-1 downto 0);               -- Average of Ram2 real input data
signal Ram2_imag_input_data_average      : signed(data_width-1 downto 0);               -- Average of Ram2 imaginary input data
signal Ram1_Address                      : integer range 0 to fft_length;               -- Address range for Ram1
signal Ram2_Address                      : integer range 0 to fft_length;               -- Address range for Ram2
signal Std_l_Ram1_Address                : std_logic_vector(2 downto 0);                -- Used for address reversal for data input to Ram1
signal Std_l_Ram1_Address_Tmp            : std_logic_vector(2 downto 0);                -- Used for address reversal for data input to Ram1
signal Std_l_Ram2_Address                : std_logic_vector(2 downto 0);                -- Used for address reversal for data input to Ram2
signal Std_l_Ram2_Address_Tmp            : std_logic_vector(2 downto 0);                -- Used for address reversal for data input to Ram2
signal Std_l_FFTRam_Address              : std_logic_vector(2 downto 0);                -- Address range used to read data from Ram1 and Ram2 into FFT Data Array
signal Ram1_Address_Count                : integer range 0 to fft_length;               -- Keeps track of current location in Ram1
signal Ram2_Address_Count                : integer range 0 to fft_length;               -- Keeps track of current location in Ram2
signal reverse_shift_count               : integer range 0 to ((2*fft_length)+1);       -- Counts the number of shift operations to complete address reversal
signal reverse_flag                      : std_logic;                                   -- Signals when address reversal can begin
signal bit_reversal_complete_flag        : std_logic;                                   -- Flag to indicate address reversal completion
signal last_bit_reversal_complete_flag   : std_logic;                                   -- Used with signal above to indicate address reversal
signal Ram1_we                           : std_logic;                                   -- Ram1 write enable
signal Ram2_we                           : std_logic;                                   -- Ram2 write enable
signal FFTRam_we                         : std_logic;                                   -- Used to indicate when we can write data from Ram1 and Ram2 into FFT Data Array
signal last_FFTRam_we                    : std_logic;                                   -- Used to detect falling edge of FFTRam_we
signal Ram1_full                         : std_logic;                                   -- Ram1 Full indicator
signal Ram2_full                         : std_logic;                                   -- Ram2 Full indicator
signal FFTRam_full_Ram1_Data             : std_logic;                                   -- Indicates FFT Array full of Ram1 data
signal FFTRam_full_Ram2_Data             : std_logic;                                   -- Indicates FFT Array full of Ram2 data
signal final_stage_count                 : integer range 0 to 10;                       -- Used to calculate when output results are valid
signal Ram1_data_out_to_FFT_Ram          : std_logic_vector(data_width-1 downto 0);     -- Data output from Ram1 to FFT Data Array
signal Ram2_data_out_to_FFT_Ram          : std_logic_vector(data_width-1 downto 0);     -- Data output from Ram2 to FFT Data Array
signal FFT_Data                          : FFT_Data_Array;                              -- Array of FFT input data from Ram1 and Ram2
signal Stage1Result                      : Stage_Result_Values;                         -- Array to contain Stage1 Butterfly Results
signal Stage2Result                      : Stage_Result_Values;                         -- Array to contain Stage2 Butterfly Results
signal FFTRam_Write_Address              : std_logic_vector(2 downto 0);                -- Write address for FFT Data Array
signal FFTRam_Copy_R_I_Select            : std_logic;                                   -- Determines whether the Real or Imag part of the number is input during data copy
发表于 2004-6-19 22:09:44 | 显示全部楼层

谁会?

--接上贴,继续
begin

TWF_R(0) <= "0111111111111111";-- 1.0000000000000000
TWF_R(1) <= "0000000000000000";-- -0.0000000232051033
TWF_I(0) <= "0000000000000000";-- -0.0000000000000000
TWF_I(1) <= "1000000000000010";-- -0.9999999999999998

data_average: process(reset, clk)
-- Sums all the input data values before transferral into
-- Ram1 and Ram2 and calculates average value (DC component)
begin
      if reset = '0' then
           Ram1_real_input_data_sum <= (others => '0');                                                   -- Initialization on reset
           Ram1_imag_input_data_sum <= (others => '0');
           Ram1_real_input_data_average <= (others => '0');
           Ram1_imag_input_data_average <= (others => '0');
           Ram2_real_input_data_sum <= (others => '0');
           Ram2_imag_input_data_sum <= (others => '0');
           Ram2_real_input_data_average <= (others => '0');
           Ram2_imag_input_data_average <= (others => '0');
      elsif rising_edge(clk) then
           if (reverse_flag = '1' and Ram2_full = '1') then                                               -- Sum input data for Ram1
               if (bit_reversal_complete_flag = '1' and last_bit_reversal_complete_flag = '0') then       -- Update on Rising Edge only
                  Ram1_real_input_data_sum <= Ram1_real_input_data_sum + signed(data_in_r);               -- Sum the real values
                  Ram1_imag_input_data_sum <= Ram1_imag_input_data_sum + signed(data_in_i);               -- Sum the imaginary values
               end if;
           end if;
           if (Ram1_full = '1') then
                  Ram1_real_input_data_average <= Ram1_real_input_data_sum((data_width + 1) downto 2);    -- Same as shifting right to divide by FFT length
                  Ram1_imag_input_data_average <= Ram1_imag_input_data_sum((data_width + 1) downto 2);    -- Do same to obtain imaginary data average
           end if;                                                                                        -- Final DC value is now calculated
           if (FFTRam_full_Ram1_Data = '1') then
               Ram1_real_input_data_sum <= (others => '0');                                               -- Reset summation value for Ram1 real data
               Ram1_imag_input_data_sum <= (others => '0');                                               -- Reset summation value for Ram1 imag data
           end if;
           if (reverse_flag = '1' and Ram1_full = '1') then                                               -- Sum input data for Ram2
               if (bit_reversal_complete_flag = '1' and last_bit_reversal_complete_flag = '0') then       -- Update on Rising Edge only
                  Ram2_real_input_data_sum <= Ram2_real_input_data_sum + signed(data_in_r);               -- Sum the real values
                  Ram2_imag_input_data_sum <= Ram2_imag_input_data_sum + signed(data_in_i);               -- Sum the imaginary values
               end if;
           end if;                                                                                    
           if (Ram2_full = '1') then
                  Ram2_real_input_data_average <= Ram2_real_input_data_sum((data_width + 1) downto 2);    -- Same as shifting right to divide by FFT length
                  Ram2_imag_input_data_average <= Ram2_imag_input_data_sum((data_width + 1) downto 2);    -- Do same to obtain imaginary data average
           end if;                                                                                        -- Final DC value is now calculated
           if (FFTRam_full_Ram2_Data = '1') then
               Ram2_real_input_data_sum <= (others => '0');                                               -- Reset summation value for Ram2 real data
               Ram2_imag_input_data_sum <= (others => '0');                                               -- Reset summation value for Ram2 imag data
           end if;
           last_bit_reversal_complete_flag <= bit_reversal_complete_flag;
     end if;
end process data_average;
发表于 2004-6-19 22:49:34 | 显示全部楼层

谁会?

--接上贴,继续,
--由于没有速度要求,只是为了实现fft,假设clk=5M,Sampling Freq=0.5M
reverse_address: process(reset, clk)
-- Sets flag to indicate address reversal can begin
-- after new input data has been sampled
begin
      if reset = '0' then                                          -- Initialization on reset
           reverse_flag <= '0';
           last_data_rd <= '0';
      elsif rising_edge(clk) then
           if (data_rd = '1' and last_data_rd = '0') then          -- Data sampled on rising edge
              reverse_flag <= '1';                                 -- New data sampled so set bit reversal flag
           end if;
           if (reverse_shift_count = 14) then
              reverse_flag <= '0';                                 -- Bit reversal now complete so reset flag
           end if;  
        last_data_rd <= data_rd;                                   -- Ready for new data sample
     end if;
end process reverse_address;

reverse_bits: process(reset, clk)
-- Reverses the data storage address and controls the
-- writing of data to the correct location in Ram1 and Ram2
begin
      if reset = '0' then                                                                  -- Initialization on reset
           Ram1_Address <= 0;
           Ram2_Address <= 0;
           Ram1_full <= '0';
           Ram2_full <= '1';
           FFTRam_full_Ram1_Data <= '0';
           FFTRam_full_Ram2_Data <= '0';
           Ram1_we <= '1';
           Ram2_we <= '1';
           FFTRam_we <= '1';
           bit_reversal_complete_flag <= '0';
           reverse_shift_count <= 0;
           Std_l_Ram1_Address_Tmp <= (others => '0');
           Std_l_Ram1_Address <= (others => '0');
           Std_l_Ram2_Address_Tmp <= (others => '0');
           Std_l_Ram2_Address <= (others => '0');
       elsif rising_edge(clk) then
           if (reverse_flag = '1' and Ram2_full = '1') then                                -- Begin bit reversal
              if (bit_reversal_complete_flag = '0') then
              Std_l_Ram1_Address_Tmp <= std_logic_vector(to_unsigned(Ram1_Address, 3));
              Std_l_Ram1_Address(0) <= Std_l_Ram1_Address_Tmp(2);
              Std_l_Ram1_Address(1) <= Std_l_Ram1_Address_Tmp(1);
              Std_l_Ram1_Address(2) <= Std_l_Ram1_Address_Tmp(0);
              end if;
              reverse_shift_count <= reverse_shift_count + 1;
              if reverse_shift_count = 5 then
                 bit_reversal_complete_flag <= '1';                                        -- Address bits have been reversed
                 Input_data_ram1 <= data_in_r;                                             -- Real input data loaded
                 Ram1_we <= '0';                                                           -- Input data can now be written to Ram1
              elsif reverse_shift_count = 9 then
                 Std_l_Ram1_Address <= std_logic_vector(unsigned(Std_l_Ram1_Address)+1);   -- Increment the Ram1 address for imaginary input data
                 Input_data_ram1 <= data_in_i;                                             -- Imag input data loaded and written to Ram1
              elsif reverse_shift_count = 13 then
                 bit_reversal_complete_flag <= '0';                                        -- Reset flag
                 Ram1_Address <= Ram1_Address + 1;                                         -- Increment Ram address for new data sample
                 Ram1_we <= '1';                                                           -- Clear the Ram1 write enable
              elsif reverse_shift_count = 15 then
                 reverse_shift_count <= 0;                                                 -- Reset count
              end if;
              if Ram1_Address = fft_length then                                            -- Check if we have got our required fft sample
                 Ram1_full <= '1';                                                         -- Signal Ram1 now full
                 Ram2_full <= '0';                                                         -- Ram2 ready for writing to
                 FFTRam_full_Ram2_Data <= '0';                                             -- Allow summation of input data to Ram2 to calculate dc value
                 FFTRam_we <= '0';                                                         -- Now we can write Ram1 data into FFT Ram
                 Ram1_Address <= 0;                                                        -- Reset Ram1 address to zero
               end if;
           end if;
           if Ram2_Address = 6 then
               FFTRam_we <= '1';                                                          -- FFT Ram should now be full of Ram1 Data
               FFTRam_full_Ram1_Data <= '1';                                              -- so we initialise it for FFT operation
           end if;                                                                        -- Indicator to reset sum of Ram1 input data to zero
           if (reverse_flag = '1' and Ram1_full = '1' ) then                              -- Begin bit reversal for Ram2
              if (bit_reversal_complete_flag = '0') then
              Std_l_Ram2_Address_Tmp <= std_logic_vector(to_unsigned(Ram2_Address, 3));
              Std_l_Ram2_Address(0) <= Std_l_Ram2_Address_Tmp(2);
              Std_l_Ram2_Address(1) <= Std_l_Ram2_Address_Tmp(1);
              Std_l_Ram2_Address(2) <= Std_l_Ram2_Address_Tmp(0);
              end if;
              reverse_shift_count <= reverse_shift_count + 1;
              if reverse_shift_count = 5 then
                 bit_reversal_complete_flag <= '1';                                       -- Address bits have been reversed
                 Input_data_ram2 <= data_in_r;                                            -- Real input data loaded
                 Ram2_we <= '0';                                                          -- Real input data can now be written to Ram2
              elsif reverse_shift_count = 9 then
                 Std_l_Ram2_Address <= std_logic_vector(unsigned(Std_l_Ram2_Address)+1);  -- Increment the Ram2 address for imaginary input data
                 Input_data_ram2 <= data_in_i;                                            -- Imag input data loaded and written to Ram2
              elsif reverse_shift_count = 13 then
                 bit_reversal_complete_flag <= '0';                                       -- Reset flag
                 Ram2_Address <= Ram2_Address + 1;                                        -- Increment Ram address for new data sample
                 Ram2_we <= '1';                                                          -- Clear the Ram2 write enable
              elsif reverse_shift_count = 15 then
                 reverse_shift_count <= 0;                                                -- Reset count
              end if;
              if Ram2_Address = fft_length then                                           -- Check if we have got our required fft sample
                 Ram2_full <= '1';                                                        -- Signal Ram2 now full
                 Ram1_full <= '0';                                                        -- Ram1 ready for writing to
                 FFTRam_full_Ram1_Data <= '0';                                            -- Allow summation of input data to Ram1 to calculate dc value
                 FFTRam_we <= '0';                                                        -- Now we can write Ram2 data into FFT Ram
                 Ram2_Address <= 0;
              end if;
           end if;
           if Ram1_Address = 6 then
               FFTRam_we <= '1';                                                          -- FFT Ram should now be full of Ram2 Data                                                         
               FFTRam_full_Ram2_Data <= '1';                                              -- so we initialise it for FFT operation                                             
           end if;                                                                        -- Indicator to reset sum of Ram2 input data to zero
     end if;
end process reverse_bits;
发表于 2004-6-19 22:51:42 | 显示全部楼层

谁会?

[这个贴子最后由serene在 2004/06/19 10:53pm 第 1 次编辑]

--接上贴,继续
FFTRam_Data_Select: process(reset, clk)
-- Selects the real or the imaginary parts of the input data
-- to be written from Ram1 and Ram2 into the FFT array
begin
     if reset = '0' then                                                                  -- Initialization on reset
          FFT_Data <= (others => (others => '0'));
     elsif Rising_Edge(clk) then
          if (Ram1_full = '1' and FFTRam_we = '0' and Ram1_Address_Count < fft_length) then
              if FFTRam_Copy_R_I_Select = '1' then                                        -- Copy in the real part of the number minus the dc component
                 FFT_Data(To_Integer(unsigned(FFTRam_Write_Address))) <= std_logic_vector(signed(Ram1_data_out_to_FFT_Ram) - Ram1_real_input_data_average);  
              else                                                                        -- Copy in the imag part of the number minus the dc component
                 FFT_Data(To_Integer(unsigned(FFTRam_Write_Address))) <= std_logic_vector(signed(Ram1_data_out_to_FFT_Ram) - Ram1_imag_input_data_average);  
              end if;   
          end if;
          if (Ram2_full = '1' and FFTRam_we = '0'  and Ram2_Address_Count < fft_length) then
              if FFTRam_Copy_R_I_Select = '1' then                                        -- Copy in the real part of the number minus the dc component
                 FFT_Data(To_Integer(unsigned(FFTRam_Write_Address))) <= std_logic_vector(signed(Ram2_data_out_to_FFT_Ram) - Ram2_real_input_data_average);  
              else                                                                        -- Copy in the imag part of the number minus the dc component
                 FFT_Data(To_Integer(unsigned(FFTRam_Write_Address))) <= std_logic_vector(signed(Ram2_data_out_to_FFT_Ram) - Ram2_imag_input_data_average);
              end if;
         end if;
     end if;
end process FFTRam_Data_Select;

FFTRam_copy: process(reset, clk)
-- Writes the real and imaginary data from Ram1 and Ram2
-- into the FFT array for processing
begin
     if reset = '0' then                                                                                 -- Initialization on reset
          FFTRam_Copy_R_I_Select <= '0';
          Ram1_Address_Count <= 0;
          Ram2_Address_Count <= 0;
          Std_l_FFTRam_Address <= (others => '0');
          FFTRam_Write_Address <= (others => '0');
     elsif Rising_Edge(clk) then
           FFTRam_Copy_R_I_Select <= not (FFTRam_Copy_R_I_Select);
           if (FFTRam_we = '0' and Ram1_full = '1' and Ram1_Address_Count < fft_length) then             -- Copy Ram1 data into FFT ram
                  Ram2_Address_Count <= 0;                                                               -- Reset Ram2 Address counters
                  if FFTRam_Copy_R_I_Select = '0' then                                                   -- Copy in the real part of the number
                     Std_l_FFTRam_Address <= std_logic_vector(to_unsigned((2*Ram1_Address_Count), 3));
                     FFTRam_Write_Address <= std_logic_vector(to_unsigned((2*Ram1_Address_Count), 3));
                  else
                     Std_l_FFTRam_Address <= std_logic_vector(to_unsigned(((2*Ram1_Address_Count)+1), 3));       -- Set up the correct address for the imaginary part
                     FFTRam_Write_Address <= std_logic_vector(to_unsigned(((2*Ram1_Address_Count)+1), 3));
                     Ram1_Address_Count <= Ram1_Address_Count + 1;
                  end if;
           end if;
           if (FFTRam_we = '0' and Ram2_full = '1' and Ram2_Address_Count < fft_length) then             -- Copy Ram2 data into FFT ram
                  Ram1_Address_Count <= 0;                                                               -- Reset Ram1 Address counter
                  if FFTRam_Copy_R_I_Select = '0' then                                                   -- Copy in the real part of the number
                     Std_l_FFTRam_Address <= std_logic_vector(to_unsigned((2*Ram2_Address_Count), 3));
                     FFTRam_Write_Address <= std_logic_vector(to_unsigned((2*Ram2_Address_Count), 3));
                  else
                     Std_l_FFTRam_Address <= std_logic_vector(to_unsigned(((2*Ram2_Address_Count)+1), 3));       -- Set up the correct address for the imaginary part
                     FFTRam_Write_Address <= std_logic_vector(to_unsigned(((2*Ram2_Address_Count)+1), 3));
                     Ram2_Address_Count <= Ram2_Address_Count + 1;
                  end if;                 
           end if;
end if;
end process FFTRam_copy;

completion_indication: process(reset, clk)
-- Sets flag to indicate that all calculations are
-- complete and results are now valid
begin
      if reset = '0' then                                              -- Initialization on reset
           res_valid <= '0';
           final_stage_count <= 0;
           last_FFTRam_we <= '0';
      elsif rising_edge(clk) then
           if (FFTRam_we = '0'and last_FFTRam_we = '1') then           -- Reset results valid output
               res_valid <= '0';                                       -- and counter on falling edge
               final_stage_count <= 0;                                 -- of FFTRam_we
           end if;
           if (data_rd = '1' and last_data_rd = '0') then
               if (final_stage_count <=  8) then
                  final_stage_count <= final_stage_count + 1;          -- Increment counter
                  res_valid <= '0';                                    -- Resullts still not valid
               else
                  res_valid <= '1';                                    -- Results valid now                                   
               end if;                                                         
           end if;
           last_FFTRam_we <= FFTRam_we;                                -- Update signal to ensure edge detection
      end if;
end process completion_indication;

-- Output Results
data_out_r <= Stage2Result(To_Integer(unsigned(address)))(15 downto 0);
data_out_i <= Stage2Result((To_Integer(unsigned(address)))+1)(15 downto 0);
发表于 2004-6-19 22:55:25 | 显示全部楼层

谁会?

--接上贴,继续
-- Component Instantiations
-- Ram1
Ram1 : dual_port_ram
       generic map(
                  data_width => 16,
                  ram_length => 8
                  )
       port map   (
                  data_in    => Input_data_ram1,              -- Input Data
                  data_out1  => open,                         -- Not Used
                  data_out2  => Ram1_data_out_to_FFT_Ram,     -- Ram1 Data to FFT array
                  clk        => clk,                          -- Input Clock
                  we         => Ram1_we,                      -- Write Enable...Active Low
                  en         => '1',                          -- Ram1 always enabled
                  address1   => Std_l_Ram1_Address,           -- Ram1 Write Address
                  address2   => Std_l_FFTRam_Address          -- Ram1 Read Address
                  );

-- Ram2
Ram2 : dual_port_ram
       generic map(
                  data_width => 16,
                  ram_length => 8
                  )
       port map   (
                  data_in    => Input_data_ram2,              -- Input Data
                  data_out1  => open,                         -- Not Used
                  data_out2  => Ram2_data_out_to_FFT_Ram,     -- Ram2 Data to FFT array  
                  clk        => clk,                          -- Input Clock
                  we         => Ram2_we,                      -- Write Enable...Active Low
                  en         => '1',                          -- Ram always enabled
                  address1   => Std_l_Ram2_Address,           -- Ram Write Address
                  address2   => Std_l_FFTRam_Address          -- Ram Read Address
                  );

-- Stage1 Butterflys
BF_STG1:for I in 0 to 1 generate
Stg1_bf1: stg1_butterfly
       generic map(
                  data_width     => data_width,                                 
                  int_data_width => int_data_width,
                  tw_fact_width  => coeff_width                                 
                  )
       port map   (
                  reset          => reset,                                   
                  clk            => clk,                                   
                  data_rd        => data_rd,
                  data1_r_in     => FFT_Data(4*I),
                  data1_i_in     => FFT_Data((4*I)+1),
                  data2_r_in     => FFT_Data((4*I)+2),
                  data2_i_in     => FFT_Data((4*I)+3),
                  tf1_r          => TWF_R(0),
                  data1_r_out    => Stage1Result(4*I),
                  data1_i_out    => Stage1Result((4*I)+1),
                  data2_r_out    => Stage1Result((4*I)+2),
                  data2_i_out    => Stage1Result((4*I)+3)
                  );
end generate BF_STG1;
-- Stage2 Butterflys
BF_STG2:for I in 0 to 0 generate
Stg2bf1: butterfly
       generic map(
                  data_width     => int_data_width,
                  tw_fact_width  => coeff_width                                 
                  )
       port map   (
                  reset          => reset,                                   
                  clk            => clk,
                  data_rd        => data_rd,      
                  data1_r_in     => Stage1Result((8*I)+0),
                  data1_i_in     => Stage1Result((8*I)+1),
                  data2_r_in     => Stage1Result((8*I)+4),
                  data2_i_in     => Stage1Result((8*I)+5),
                  tf1_r          => TWF_R(0),
                  tf1_i          => TWF_I(0),
                  data1_r_out    => Stage2Result((8*I)+0),
                  data1_i_out    => Stage2Result((8*I)+1),
                  data2_r_out    => Stage2Result((8*I)+4),
                  data2_i_out    => Stage2Result((8*I)+5)
                  );
Stg2bf2: butterfly
       generic map(
                  data_width     => int_data_width,
                  tw_fact_width  => coeff_width                                 
                  )
       port map   (
                  reset          => reset,                                   
                  clk            => clk,
                  data_rd        => data_rd,      
                  data1_r_in     => Stage1Result((8*I)+2),
                  data1_i_in     => Stage1Result((8*I)+3),
                  data2_r_in     => Stage1Result((8*I)+6),
                  data2_i_in     => Stage1Result((8*I)+7),
                  tf1_r          => TWF_R(1),
                  tf1_i          => TWF_I(1),
                  data1_r_out    => Stage2Result((8*I)+2),
                  data1_i_out    => Stage2Result((8*I)+3),
                  data2_r_out    => Stage2Result((8*I)+6),
                  data2_i_out    => Stage2Result((8*I)+7)
                  );
end generate BF_STG2;

end;
发表于 2004-6-19 23:01:44 | 显示全部楼层

谁会?

呵呵,4点的代码就这么长了。用quartus ii编译已经可以通过了(不加约束条件下)。
不过有没有bug就不清楚了,楼主自己检查吧,估计会有错误存在的。
发表于 2004-6-20 09:11:43 | 显示全部楼层

谁会?

serene 真是个大好人
您需要登录后才可以回帖 登录 | 注册

本版积分规则

关闭

站长推荐 上一条 /1 下一条


小黑屋| 手机版| 关于我们| 联系我们| 在线咨询| 隐私声明| EETOP 创芯网
( 京ICP备:10050787号 京公网安备:11010502037710 )

GMT+8, 2024-11-8 14:09 , Processed in 0.026736 second(s), 6 queries , Gzip On, Redis On.

eetop公众号 创芯大讲堂 创芯人才网
快速回复 返回顶部 返回列表