OpenCores
URL https://opencores.org/ocsvn/versatile_fft/versatile_fft/trunk

Subversion Repositories versatile_fft

[/] [versatile_fft/] [trunk/] [single_unit/] [src/] [fft_engine_tb.vhd] - Rev 3

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : Testbench for design "fft_engine"
-- Project    : 
-------------------------------------------------------------------------------
-- File       : fft_engine_tb.vhd
-- Author     : Wojciech Zabolotny wzab01<at>gmail.com
-- Company    :
-- License    : BSD
-- Created    : 2014-01-25
-- Last update: 2014-02-05
-- Platform   : 
-- Standard   : VHDL'93
-------------------------------------------------------------------------------
-- Description: 
-------------------------------------------------------------------------------
-- Copyright (c) 2014 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2014-01-25  1.0      wzab    Created
-------------------------------------------------------------------------------
 
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.math_real.all;
use ieee.math_complex.all;
library std;
use std.textio.all;
 
library work;
use work.fft_len.all;
use work.icpx.all;
-------------------------------------------------------------------------------
 
entity fft_engine_tb is
 
end fft_engine_tb;
 
-------------------------------------------------------------------------------
 
architecture beh1 of fft_engine_tb is
  -- constant LOG2_FFT_LEN : integer := 8;
  -- FFT_LEN will be read from the fft_len package,
  -- generated by the Octave or MAtlab script
  -- together with the test data
  constant ADDR_WIDTH : integer := LOG2_FFT_LEN;
  constant FFT_LEN    : integer := 2 ** LOG2_FFT_LEN;
 
  component fft_engine
    generic (
      LOG2_FFT_LEN : integer);
    port (
      din       : in  icpx_number;
      addr_in   : in  integer;
      wr_in     : in  std_logic;
      dout      : out icpx_number;
      addr_out  : in  integer;
      ready     : out std_logic;
      busy      : out std_logic;
      start     : in  std_logic;
      rst_n     : in  std_logic;
      syn_rst_n : in  std_logic;
      clk       : in  std_logic);
  end component;
 
  signal end_sim : boolean := false;
 
  -- component ports
  signal din       : icpx_number := icpx_zero;
  signal addr_in   : integer     := 0;
  signal wr_in     : std_logic   := '0';
  signal dout      : icpx_number := icpx_zero;
  signal addr_out  : integer     := 0;
  signal ready     : std_logic   := '0';
  signal start     : std_logic   := '0';
  signal busy      : std_logic   := '0';
  signal rst_n     : std_logic   := '0';
  signal syn_rst_n : std_logic   := '0';
 
  type cplx_vector is array (0 to FFT_LEN-1) of complex;
 
  -- Function for easy conversion of integer indices
  -- std_logic_vectors used to address the memory
  function i2a (
    constant ia : integer)
    return std_logic_vector is
    variable res : std_logic_vector(ADDR_WIDTH-1 downto 0);
  begin  -- i2a
    res := std_logic_vector(to_unsigned(ia, ADDR_WIDTH));
    return res;
  end i2a;
 
  -- Function reversing the std_logic_vector was written
  -- by Jonathan Bromley and published on comp.lang.vhdl
  -- Thread: Slicing of an array: wrong direction
  -- https://groups.google.com/forum/#!msg/comp.lang.vhdl/eBZQXrw2Ngk/4H7oL8hdHMcJ
  function rev_slv (a : in std_logic_vector)
    return std_logic_vector is
    variable result : std_logic_vector(a'range);
    alias aa        : std_logic_vector(a'reverse_range) is a;
  begin
    for i in aa'range loop
      result(i) := aa(i);
    end loop;
    return result;
  end;  -- function rev_slv
 
  -- clock
  signal Clk : std_logic := '1';
 
 
 
begin  -- beh1
 
  -- component instantiation
  DUT : fft_engine
    generic map (
      LOG2_FFT_LEN => LOG2_FFT_LEN)
    port map (
      din       => din,
      addr_in   => addr_in,
      wr_in     => wr_in,
      dout      => dout,
      addr_out  => addr_out,
      ready     => ready,
      busy      => busy,
      start     => start,
      rst_n     => rst_n,
      syn_rst_n => syn_rst_n,
      clk       => clk);
 
  -- clock generation
  Clk <= not Clk after 10 ns when end_sim = false else '0';
 
  -- purpose: synchronization of reset
  process (clk, rst_n)
  begin  -- process
    if rst_n = '0' then                 -- asynchronous reset (active low)
      syn_rst_n <= '0';
    elsif clk'event and clk = '1' then  -- rising clock edge
      syn_rst_n <= rst_n;
    end if;
  end process;
 
  -- waveform generation
  WaveGen_Proc : process
 
    file data_in         : text open read_mode is "data_in.txt";
    variable input_line  : line;
    file data_out        : text open write_mode is "data_out.txt";
    variable output_line : line;
    variable tre, tim    : real;
    constant sep         : string := " ";
  begin
    -- insert signal assignments here
 
    wait until Clk = '1';
    wait for 15 ns;
    -- End of reset
    rst_n <= '1';
    -- wait until the FFT engine is ready after reset
    wait until ready = '1';
    wait until Clk = '0';
    -- Now we read data from the input file
    -- and put the data to the input memory
    for i in 0 to FFT_LEN-1 loop
      readline(data_in, input_line);
      read(input_line, tre);
      read(input_line, tim);
      addr_in <= i;
      din     <= cplx2icpx(cmplx(tre, tim));
      wr_in   <= '1';
      wait until Clk = '1';
      wait until Clk = '0';
    end loop;  -- i
    -- stop writing of data
    wr_in <= '0';
    -- wait one clock period to finish writing
    wait until Clk = '1';
    wait until Clk = '0';
    -- start processing
    start <= '1';
    wait until Clk = '1';
    wait until Clk = '0';
    -- swith off the start signal, so that the FFT
    -- engine will not start processing again
    start <= '0';
    -- wait until the FFT engine is ready
    wait until ready = '1';
    -- wait one clock (is it necessary?)
    wait until Clk = '1';
    wait until Clk = '0';
    -- rad the data, and write them to the output file
    for i in 0 to FFT_LEN-1 loop
      -- Data after FFT are scrambled, we need to reverse
      -- order of address bits!
      addr_out <= to_integer(unsigned(rev_slv(i2a(i))));
      -- we use a synchronous memory, so data can be read after
      -- the next clock pulse
      wait until Clk = '1';
      wait until Clk = '0';
      -- write data
      write(output_line, integer'image(to_integer(dout.re)));
      write(output_line, sep);
      write(output_line, integer'image(to_integer(dout.im)));
      writeline(data_out, output_line);
    end loop;  -- i
    -- signal end of the simulation
    end_sim <= true;
    wait;
  end process WaveGen_Proc;
 
 
 
end beh1;
 
-------------------------------------------------------------------------------
 
configuration fft_engine_tb_beh1_cfg of fft_engine_tb is
  for beh1
  end for;
end fft_engine_tb_beh1_cfg;
 
-------------------------------------------------------------------------------
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.