⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 tb_xfft16_fio.vhd

📁 一个用FPGA实现的16FFT,仅供参考不作为工程文件
💻 VHD
字号:
--
-- Filename:  tb_xfft16_fio.vhd
--
--
-- NOTE:  This test bench must be compiled as VHDL-93
--
-- ************************************************************************************************

-- ==========
-- Test Bench
-- ========== 

library ieee;
   use ieee.std_logic_1164.all;
   use ieee.std_logic_arith.all;                            --
   use ieee.std_logic_unsigned.all;                         -- for conv_integer()
   use std.textio.all;                                      -- For File I/O

Entity tb_xfft16_fio is
End tb_xfft16_fio;

Architecture Test_Bench of tb_xfft16_fio is
 
    Signal RS           : std_logic;
    Signal DR           : std_logic_vector(15 downto 0 );
    Signal DI           : std_logic_vector(15 downto 0 );
    Signal START        : std_logic;
    Signal CE           : std_logic;
    Signal CLK          : std_logic;
    Signal FRAME        : std_logic;
    Signal XK_R         : std_logic_vector(15 downto 0 );
    Signal XK_I         : std_logic_vector(15 downto 0 );
    Signal ce_i         : std_logic;                        -- unbuffered CE
    Signal init         : std_logic;                        -- initialization complete signal
--
-- Test Bench Signals
--
    Signal ckper                 : time := 40 ns;           -- temporary tester clock period
    Signal fin                   : real;                    -- Input Data to be sampled
    Signal fs                    : real;                    -- Input Sample Frequency
    Signal rd                    : real;                    -- real data      (real)
    Signal id                    : real;                    -- imaginary data (real)
    Signal i                     : integer;                 -- sample number
    Signal j                     : integer;                 -- data index var
    Signal frame_count           : integer;                 -- number of frames elapsed
    Shared Variable result_frame : integer;                 -- result frame to capture
    Signal output_capture_count  : integer;                 -- count # of words captured in selected frame
    Signal output_capture_flag   : boolean;                 -- capture words 2  - 16 flag

    type output_storage is array (1 to 16) of std_logic_vector(15 downto 0);
    type input_storage is array (1 to 16) of std_logic_vector(15 downto 0);
    signal fft_real_result  : output_storage;
    signal fft_imag_result  : output_storage;
    signal fft_real_in      : input_storage;
    signal fft_imag_in      : input_storage;

--
-- Dr. Dicks' FFT16 Design
--
Component xfft16
    Port (
          RS           :    in  std_logic                     ;   -- master reset  
          DR           :    in  std_logic_vector(15 downto 0 );   -- real data in
          DI           :    in  std_logic_vector(15 downto 0 );   -- imaginary data in
          START        :    in  std_logic                     ;   -- fft start control
          CE           :    in  std_logic                     ;   -- clock enable
          CLK          :    in  std_logic                     ;   -- clock input
          FRAME        :   out  std_logic                     ;   -- transform complet strobe
          XK_R         :   out  std_logic_vector(15 downto 0 );   -- real data out
          XK_I         :   out  std_logic_vector(15 downto 0 )    -- imaginary data out
         ); -- (end of port)

End component; -- xfft16

procedure l2str (l        : inout line ; 
                 result   : out string ) is

 variable j    : integer   := 0;
 variable ch   : character;
begin
   for i in 1 to l'right loop
      read(l, ch);
      result(i) := ch;
      j := i;
   end loop;
   result(j+1) := NUL;        -- terminate the string
end;

procedure calculate_magnitude_phase 
   (r : in std_logic_vector(15 downto 0) ;   -- real data,        2's complement form
    i : in std_logic_vector(15 downto 0) ;   -- imaginary data,   2's complement form
    magnitude : out integer ;
    phase : out integer) is

   variable ri, ii : integer; 
   variable rr, ir : real;
begin
  ri := conv_integer(r);            -- real data,       integer type
  ii := conv_integer(i);            -- imaginary data,  integer type

  if (ri > 32767) then              -- 2's comp to integer
     ri := ri + (-65536);
  end if;
  if (ii > 32767) then              -- 2's comp to integer
     ii := ii + (-65536);
  end if;

  magnitude    := ri; 
  phase        := ii; 
end;


-- Syntax below is : Entity pin name => Actual schematic signal name.

Begin

U2 : xfft16
   Port Map (
              RS           => RS,
              DR           => DR,
              DI           => DI,
              START        => START,
              CE           => CE,
              CLK          => CLK,
              FRAME        => FRAME,
              XK_R         => XK_R,
              XK_I         => XK_I
             ); -- end port map

TB : Block

Begin

ce <= ce_i;             -- old bufgs

--
-- This process will create the main clock
--
p_clock : process  -- make tester clock
begin
  clk <='1';
  wait for ckper /2 ;
  clk <='0';          
  wait for ckper / 2;
end process p_clock; 

-- 
-- This process will apply the real and imaginary input data on the negative edge of the clock
--
apply_input_data : process (clk, rs)

   variable ird, iid : integer;
   variable std_logic_xnr: std_logic_vector(15 downto 0);
   variable std_logic_xni: std_logic_vector(15 downto 0);
begin
   if (rs = '1') then
       DR   <= "0000000000000000" ; 
       DI   <= "0000000000000000" ; 
       i    <= 0;
       j    <= 1;
   elsif (clk'event and clk = '0') then      -- negative edge of clock
       if (init = '1') then
	  if (j < 16) then
	      j <= j+1;
	  end if;
	  std_logic_xnr := fft_real_in(j);
	  std_logic_xni := fft_imag_in(j);
          DR   <=    std_logic_xnr; --conv_std_logic_vector(ird,16);    -- integer to std_logic_vector;
          DI   <=    std_logic_xni; --conv_std_logic_vector(iid,16);    -- integer to std_logic_vector;
          --DR <= fft_real_in(i);
	  --DI <= fft_imag_in(i);
          i    <=    i + 1;
       else
          DR   <=    "0000000000000000" ; 
          DI   <=    "0000000000000000" ; 
       end if;
   end if;     
end process;

-- 
-- This process will capture the 16 pair (real and imaginary) of output data from the 
-- fft engine for (frame number = frame_count) and store it in a temporary array
-- 

capture_output_data : process (clk, rs)
    File outfile_dsp       : text;                             -- Output File file variable
    file fft_xk_file       : text;
    Variable result_mag    : integer;
    Variable result_phase  : integer;
    Variable bin_frequency : real;
    Variable bin_number    : integer;
    Variable oline         : line;                    		-- output line
    variable ixkr,ixki     : integer; 
begin
   if (rs = '1') then
      frame_count           <= 1;            -- number of frames elapsed
      output_capture_count  <= 1;            -- count # of words captured in selected frame
      output_capture_flag   <= false;        -- capture words 2  - 16 flag
   elsif (clk'event and clk = '1') then      -- positive edge of clock
       if ( (frame_count = result_frame) and frame = '1')  then
          fft_real_result(1) <= xk_r;
          fft_imag_result(1) <= xk_i;
          output_capture_count <= output_capture_count + 1;
          output_capture_flag <= true;
       elsif (output_capture_flag = true) then
          fft_real_result(output_capture_count) <= xk_r;
          fft_imag_result(output_capture_count) <= xk_i;
          output_capture_count <= output_capture_count + 1;
          if (output_capture_count = 16) then
             frame_count <= frame_count + 1;
             output_capture_flag <= false;
          end if;
       elsif (output_capture_flag = false) and (output_capture_count = 17) then
          --
          -- requested frame data has been captured and is written to the output file "fft16xk.dat"
          --
      	    file_open(fft_xk_file, "fft16xk.dat", write_mode);   
          -- write input samples
          for index in 1 to 16 loop
              calculate_magnitude_phase(fft_real_result(index), fft_imag_result(index), 
                   result_mag, result_phase);
              write(oline,result_mag);
              writeline(fft_xk_file, oline);  
              write(oline,result_phase);
              writeline(fft_xk_file, oline);  
              assert false report (LF &
                  "       x(k):  " & integer'image(index) & " " & integer'image(result_mag) &
                  " " & integer'image(result_phase)
                  ) severity Note;
          end loop;
          file_close(fft_xk_file);
            
          
          
          output_capture_count <= output_capture_count + 1;       -- increment so not execute this elsif section again

       elsif (frame = '1') then
          frame_count <= frame_count + 1;
       end if;
   end if;          
end process;
                        
--
-- Main Test Bench Process
--

p_main : process  -- Main test bench process
   Variable l1                      : line;                    -- pointer to a string
   Variable rfs, rfin               : real;
   Variable str_fs, str_fin         : string(1 to 10);
   Variable str_xnr, str_xni        : string(1 to 4);
   Variable str_frame, ckper_time   : string(1 to 10);
   Variable ckper_time1             : string(1 to 13);
   Variable ckper_timer             : real;
   Variable line_descriptor         : string(1 to 2);
   Variable len1                    : integer;
   Variable sch                     : string(1 to 1);          -- required for fscan
   Variable ls                      : string(1 to 132);
   File s_file                      : text;  			-- Input parameter File file variable
   File fft_in_file     	    : text;	          
   type integer_file is file of integer;
   file fft_in_file_txt             : text;            		-- FFT input data file (integer vals)
   variable open_status		    : file_open_status;
   variable rxnr,rxni               : real;
   variable ixnr,ixni               : integer;
begin                                       
    ckper <= 25.000 ns; 
    result_frame := 1;
          
    -- read FFT input vector
    
   file_open(open_status, fft_in_file, "xin.dat", read_mode);   
   for index in 1 to 16 loop
       readline(fft_in_file, l1);  
       read(l1,ixnr);
       fft_real_in(index) <= conv_std_logic_vector(ixnr,16);
       readline(fft_in_file, l1);  
       read(l1,ixni);
       fft_imag_in(index) <= conv_std_logic_vector(ixni,16);
           assert false report (LF &
                  "       x(n):  " & integer'image(index) & " " & integer'image(ixnr) &
                  " " & integer'image(ixni)
                  ) severity Note;
   end loop;
   file_close(fft_in_file);
      
    -- Initialize all signals               
    RS          <= '1' ; 
    START       <= '0' ; 
    CE_i        <= '0' ; 
    init        <= '0';
    wait for (ckper * 2);

    ---  now start stimulus ---

    CE_i       <= '1';        -- enable core
    wait for ckper;
    rs         <= '0';        -- release reset
    wait for ckper;
    start      <= '1';        -- start fft processing
    wait for ckper / 2;
    init       <= '1';
    wait for ckper / 2;
    start      <= '0';        -- set start inactive
    wait for ckper;              

    wait;

end process p_main;

End Block TB;

End Test_Bench;

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -