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

Subversion Repositories versatile_fft

[/] [versatile_fft/] [trunk/] [multiple_units/] [src/] [fft_data_switch.vhd] - Rev 3

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : fft_top
-- Project    : Pipelined, DP RAM based FFT processor
-------------------------------------------------------------------------------
-- File       : fft_switch.vhd
-- Author     : Wojciech Zabolotny
-- Company    : 
-- Licanse    : BSD
-- Created    : 2014-01-18
-- Platform   : 
-- Standard   : VHDL'93
-------------------------------------------------------------------------------
-- Description: This file implements a data switching block connecting
--              consecutive stages of the FFT processor based on a dual
--              port RAM
-------------------------------------------------------------------------------
-- Copyright (c) 2014 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2014-01-18  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 work;
use work.icpx.all;
use work.fft_support_pkg.all;
 
entity fft_data_switch is
 
  generic (
    LOG2_FFT_LEN : integer := 4;
    STAGE        : integer := 2
    );
  port (
    in0    : in  icpx_number;
    in1    : in  icpx_number;
    out0   : out icpx_number;
    out1   : out icpx_number;
    enable : in  std_logic;
    rst_n  : in  std_logic;
    clk    : in  std_logic);
 
end fft_data_switch;
 
architecture fft_s_beh of fft_data_switch is
 
  constant LOG2_STAGE_N : integer := LOG2_FFT_LEN-STAGE-1;
  constant STAGE_N      : integer := 2 ** LOG2_STAGE_N;
  constant STAGE_N2     : integer := 2 ** (LOG2_STAGE_N-1);
  constant ADDR_WIDTH   : integer := LOG2_STAGE_N;
  constant STEP_LIMIT   : integer := 2**(LOG2_FFT_LEN-2-STAGE)-1;
  constant CYCLE_LIMIT  : integer := 2**STAGE-1;
 
  signal in0_del, in1_del      : icpx_number := icpx_zero;
  signal phase_del, phase_del2 : integer range 0 to 1;
 
  signal step, step_del : integer range 0 to STEP_LIMIT;
  signal phase          : integer range 0 to 1;
  signal cycle          : integer range 0 to CYCLE_LIMIT;
 
 
  component dp_ram_rbw_icpx
    generic (
      ADDR_WIDTH : integer);
    port (
      clk    : in  std_logic;
      we_a   : in  std_logic;
      addr_a : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
      data_a : in  icpx_number;
      q_a    : out icpx_number;
      we_b   : in  std_logic;
      addr_b : in  std_logic_vector(ADDR_WIDTH-1 downto 0);
      data_b : in  icpx_number;
      q_b    : out icpx_number);
  end component;
 
  signal dpr_wa, dpr_wb                 : std_logic                               := '0';
  signal dpr_aa, dpr_ab                 : std_logic_vector(ADDR_WIDTH-1 downto 0) := (others => '0');
  signal dpr_ia, dpr_ib, dpr_qa, dpr_qb : icpx_number;
 
begin  -- fft_top_beh
 
  dp_ram_1 : dp_ram_rbw_icpx
    generic map (
      ADDR_WIDTH => ADDR_WIDTH)
    port map (
      clk    => clk,
      we_a   => dpr_wa,
      addr_a => dpr_aa,
      data_a => dpr_ia,
      q_a    => dpr_qa,
      we_b   => dpr_wb,
      addr_b => dpr_ab,
      data_b => dpr_ib,
      q_b    => dpr_qb);
 
  dpr_aa <= std_logic_vector(to_unsigned(step, ADDR_WIDTH));
  -- It is important, that synthesis tool recognizes the addition below
  -- as a simple bit operation!
  dpr_ab <= std_logic_vector(to_unsigned(step+STAGE_N2, ADDR_WIDTH));
 
  -- Output values router.
  dr1 : process (dpr_qa, dpr_qb, in0_del, phase_del) is
  begin  -- process dr1
    if phase_del = 0 then
      out0 <= dpr_qb;
      out1 <= dpr_qa;
    else
      out1 <= in0_del;
      out0 <= dpr_qa;
    end if;
  end process dr1;
 
  -- purpose: main state machine
  -- type   : combinational
  st1 : process (in0, in1, phase) is
  begin  -- process st1
    dpr_wa <= '0';
    dpr_wb <= '0';
    dpr_ia <= icpx_zero;
    dpr_ib <= icpx_zero;
    if phase = 0 then
      dpr_ia <= in0;
      dpr_ib <= in1;
      dpr_wa <= '1';
      dpr_wb <= '1';
    else
      -- phase = 1
      dpr_ia <= in1;
      dpr_wa <= '1';
    end if;
  end process st1;
 
  -- We always access data on addresses:
  -- "step" and "step+N/2"
 
  -- Main process of our router
  -- This block always introduces latency of one cycle!
  process (clk, rst_n) is
  begin  -- process
    if rst_n = '0' then                 -- asynchronous reset (active low)
      in0_del    <= icpx_zero;
      in1_del    <= icpx_zero;
      phase_del  <= 0;
      phase_del2 <= 0;
      step_del   <= 0;
    elsif clk'event and clk = '1' then  -- rising clock edge
      -- prepare the delayed version of control signals
      in0_del    <= in0;
      in1_del    <= in1;
      phase_del  <= phase;
      phase_del2 <= phase_del;
      step_del   <= step;
    end if;
  end process;
 
  st2 : process (clk, rst_n) is
  begin  -- process st2
    if rst_n = '0' then                 -- asynchronous reset (active low)
      step  <= 0;
      phase <= 0;
      cycle <= 0;
    elsif clk'event and clk = '1' then  -- rising clock edge
      if enable = '1' then
        if step = STEP_LIMIT then
          step <= 0;
          if phase = 1 then
            phase <= 0;
            if cycle = CYCLE_LIMIT then
              cycle <= 0;
            else
              cycle <= cycle+1;
            end if;
          else
            phase <= 1;
          end if;
        else
          step <= step+1;
        end if;
      end if;
    end if;
  end process st2;
 
 
end fft_s_beh;
 

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.