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

📄 ofdm_kernel_tx_tb.vhd

📁 OFDM的fpga实现
💻 VHD
字号:
-- ================================================================================
-- (c) 2007 Altera Corporation. All rights reserved.
-- Altera products are protected under numerous U.S. and foreign patents, maskwork
-- rights, copyrights and other intellectual property laws.
-- These design examples may only be used within Altera Corporation devices and remain 
-- the property of Altera. They are being provided on "as-is" basis and as an accommodation; 
-- therefore, all warranties, representations, or guarantees of any kind (whether express, 
-- implied, or statutory) including, without limitation, warranties of merchantability,
-- non-infringement, or fitness for a particular purpose, are specifically disclaimed.
-- Altera expressly does not recommend, suggest, or require that these examples be used
-- in combination with any other product not provided by Altera.
-- ================================================================================
-- 
-- Filename    : ofdm_kernel_Tx_tb.vhd
--
-- Description : TestBench for OFDM Kernel Module.
--
--               Reads Input data from text files and applies to Module.
--               To test different FFT sizes, changes the FFT size and CP size
--               in the test vector.
-- ================================================================================

library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
use ieee.numeric_std.all;
use std.textio.all;


entity ofdm_kernel_Tx_tb is
end ofdm_kernel_Tx_tb;


architecture rtl of ofdm_kernel_Tx_tb is

  -----------------------------------------------------------------------------
  -- COMPONENT DECLARATIONS
  -----------------------------------------------------------------------------
  component ofdm_kernel_Tx
    generic
      (
        DFFTOUTWIDTH : natural := 31;
        DOUTWIDTH    : natural := 32;
        DFFTINWIDTH  : natural := 16;
        MWIDTH       : natural := 64;
        MADDR_WIDTH  : natural := 12;
        CPWIDTH      : natural := 10;
        NWIDTH       : natural := 11;
        MDEPTH       : natural := 4096
        );
    port
      (
        clk_f   : in std_logic;
        clk_s   : in std_logic;
        rst_f_n : in std_logic;
        rst_s_n : in std_logic;

        -- Control 
        L : in std_logic_vector (CPWIDTH - 1 downto 0);

        Lout : out std_logic_vector (CPWIDTH - 1 downto 0);

        N    : in  std_logic_vector (NWIDTH - 1 downto 0);
        Nout : out std_logic_vector(NWIDTH -1 downto 0);
        inv : in std_logic;
        
        -- Avalon Streaming Data Sink Input Interface
        din_valid : in  std_logic;
        din_real  : in  std_logic_vector (DFFTINWIDTH - 1 downto 0);
        din_imag  : in  std_logic_vector (DFFTINWIDTH - 1 downto 0);
        din_sop   : in  std_logic;
        din_eop   : in  std_logic;
        din_error : in  std_logic_vector(1 downto 0);
        din_ready : out std_logic;


        --Avalon Streaming Data Source Output Interface 
        dout_ready : in  std_logic;
        dout_valid : out std_logic;
        dout_sop   : out std_logic;
        dout_eop   : out std_logic;
        dout_real  : out std_logic_vector (DOUTWIDTH - 1 downto 0);
        dout_imag  : out std_logic_vector (DOUTWIDTH - 1 downto 0)

        );    
  end component;

  -----------------------------------------------------------------------------
  -- CONSTANT DECLARATIONS
  -----------------------------------------------------------------------------

  constant DFFTINWIDTH  : natural := 16;
  constant DOUTWIDTH    : natural := 32;
  constant CPWIDTH      : natural := 10;  -- Cyclic Prefix Size
  constant NWIDTH       : natural := 12;  -- this value must match FFT instantiation
  constant DFFTOUTWIDTH : natural := 31;  -- this value must match FFT output
                                          -- data width
  
  constant MWIDTH       : natural := 2*DOUTWIDTH;
  constant MDEPTH       : natural := 2**NWIDTH;  -- = 2*(2**(NWIDTH-1))=2**NWIDTH
  constant MADDR_WIDTH  : natural := NWIDTH;  -- = log2(MDEPTH)  

  constant HPERIOD_F : time := 5 ns;
  constant HPERIOD_S : time := 10 ns;
  constant RST_DELAY : time := 50 ns;

  constant NUM_FRAMES_c : natural := 7;

  signal clk_f   : std_logic := '0';
  signal clk_s   : std_logic := '0';
  signal rst_f_n : std_logic := '0';
  signal rst_s_n : std_logic := '0';

  signal N, Nout : std_logic_vector (NWIDTH - 1 downto 0);
  signal L, Lout : std_logic_vector(CPWIDTH - 1 downto 0);

  signal inv : std_logic := '0';
  
  signal sink_valid : std_logic;
  signal sink_sop   : std_logic;

  signal sink_eop     : std_logic;
  signal sink_error   : std_logic_vector(1 downto 0);
  signal sink_real    : std_logic_vector (DFFTINWIDTH - 1 downto 0);
  signal sink_imag    : std_logic_vector (DFFTINWIDTH - 1 downto 0);
  signal source_ready : std_logic;
  signal sink_ready   : std_logic;
  signal source_sop   : std_logic;
  signal source_sop_r : std_logic;
  signal source_eop   : std_logic;

  signal source_valid : std_logic;
  signal source_real  : std_logic_vector (DOUTWIDTH - 1 downto 0);
  signal source_imag  : std_logic_vector (DOUTWIDTH - 1 downto 0);

  -- for testing purposes, the input file contains 4128 random data symbols
  type fftpts_list_t is array (NUM_FRAMES_c - 1 downto 0) of natural;
  signal fftpts_array    : fftpts_list_t                   := (2048,64,256,128,128,1024,512);
  type cp_list_t is array (NUM_FRAMES_c - 1 downto 0) of natural;
  signal cp_array        : cp_list_t                       := (512,8,32,32,16,16,128);
  signal start           : std_logic;
  -- number of input frames
  signal frames_in_index : natural range 0 to NUM_FRAMES_c := 0;

  signal cnt        : natural range 0 to 2**(NWIDTH-1);
  signal end_test   : std_logic;
  -- signal the end of the input data stream and output data stream.
  signal end_input  : std_logic;


begin
  -----------------------------------------------------------------------------
  -- Generating Clk and reset
  -----------------------------------------------------------------------------
  process
  begin
    wait for HPERIOD_F;
    clk_f <= not(clk_f);
  end process;

  process
  begin
    wait for HPERIOD_S;
    clk_s <= not(clk_s);
  end process;

  process
  begin
    wait for RST_DELAY;
    wait until (clk_f = '1');
    rst_f_n <= '1';
    wait;
  end process;

  process
  begin
    wait for RST_DELAY;
    wait until (clk_s = '1');
    rst_s_n <= '1';
    wait;
  end process;
  
  -- for example purposes, the ready signal is always asserted.
  source_ready <= '1';

--  -- test source_ready; source_ready is a clk_s domain signal
--  source_ready_test : process
--  begin

--    source_ready <= '1';
--    wait for HPERIOD_S*300;
--    wait until (clk_s = '1');
--    source_ready <= '0';
--    wait for HPERIOD_S*10;
--    wait until (clk_s = '1');
--    source_ready <= '1';
--  end process source_ready_test;


  -- no input error
  sink_error <= (others => '0');

  -- start valid for first cycle to indicate that the file reading should start.
  start_p : process (clk_f, rst_f_n)
  begin
    if rst_f_n = '0' then
      start <= '1';
    elsif rising_edge(clk_f) then
      if sink_valid = '1' and sink_ready = '1' then
        start <= '0';
      end if;
    end if;
  end process start_p;


  -- sop and eop asserted in first and last sample of data
  cnt_p : process (clk_f, rst_f_n)
  begin
    if rst_f_n = '0' then
      cnt <= 0;
    elsif rising_edge(clk_f) then
      if sink_valid = '1' and sink_ready = '1' then
        if cnt = fftpts_array(frames_in_index) - 1 then
          cnt <= 0;
        else
          cnt <= cnt + 1;
        end if;
      end if;
    end if;
  end process cnt_p;

  N <= std_logic_vector(to_unsigned(fftpts_array(frames_in_index), NWIDTH));

  L <= std_logic_vector(to_unsigned(cp_array(frames_in_index), CPWIDTH));

  -- count the input frames and increment the index
  increment_index_p : process (clk_f, rst_f_n)
  begin
    if rst_f_n = '0' then
      frames_in_index <= 0;
    elsif rising_edge(clk_f) then
      if sink_eop = '1' and sink_valid = '1' and sink_ready = '1' then
        if frames_in_index < NUM_FRAMES_c - 1 then
          frames_in_index <= frames_in_index + 1;
        end if;
      end if;
    end if;
  end process increment_index_p;

  -- signal when all of the input data has been sent to the DUT
  end_input <= '1' when (sink_eop = '1' and sink_valid = '1' and (frames_in_index = NUM_FRAMES_c - 1)) else
               '0';


  -- generate start and end of packet signals
  sink_sop <= '1' when cnt = 0 else
              '0';

  sink_eop <= '1' when cnt = fftpts_array(frames_in_index) - 1 else
              '0';

  -- flag when done
  end_test_p : process (clk_f, rst_f_n)
  begin
    if rst_f_n = '0' then
      end_test <= '0';
    elsif rising_edge(clk_f) then
      source_sop_r <= source_sop;
      if end_input = '1' then
        end_test <= '1';
      end if;
    end if;
  end process end_test_p;

  -----------------------------------------------------------------------------------------------
  -- Read input data from files                                                                  
  -----------------------------------------------------------------------------------------------

  testbench_i : process(clk_f) is
    file r_file     : text open read_mode is "real_input.txt";
    variable data_r : integer;
    variable rdata  : line;
    file i_file     : text open read_mode is "imag_input.txt";
    variable idata  : line;
    variable data_i : integer;
  begin
    if(rst_f_n = '0') then
      sink_real  <= std_logic_vector(to_signed(0, 16));
      sink_imag  <= std_logic_vector(to_signed(0, 16));
      sink_valid <= '0';
    elsif rising_edge(clk_f) then

      -- send in NUM_FRAMES_c of data or until the end of the file
      if not endfile(r_file) and (end_input = '0' and end_test = '0') then
        if((sink_valid = '1' and sink_ready = '1') or
           (start = '1' and not (sink_valid = '1' and sink_ready = '0'))) then
          readline(r_file, rdata);
          read(rdata, data_r);
          readline(i_file, idata);
          read(idata, data_i);
          sink_valid <= '1';
          sink_real  <= std_logic_vector(to_signed(data_r, 16));
          sink_imag  <= std_logic_vector(to_signed(data_i, 16));
        else
          sink_valid <= '1';
          sink_real  <= sink_real;
          sink_imag  <= sink_imag;
        end if;
      else
        sink_valid <= '0';
        sink_real  <= std_logic_vector(to_signed(0, 16));
        sink_imag  <= std_logic_vector(to_signed(0, 16));
      end if;
--      testsig <= endfile(r_file);
    end if;
    
  end process testbench_i;

  ---------------------------------------------------------------------------------------------
  -- Write Real and Imginary Components to Files                                               
  ---------------------------------------------------------------------------------------------

  testbench_o : process(clk_s, rst_s_n) is
    file ro_file    : text open write_mode is "real_output_vhd.txt";
    variable rdata  : line;
    variable data_r : integer;
    file io_file    : text open write_mode is "imag_output_vhd.txt";
    variable idata  : line;
    variable data_i : integer;
  begin
    if rising_edge(clk_s) and rst_s_n = '1' then
--      if(source_valid = '1' and source_ready = '1') then
      if(source_valid = '1') then       -- removed source_ready since output
                                        -- ready latency is 4
        data_r := to_integer(signed(source_real));
        data_i := to_integer(signed(source_imag));
        write(rdata, data_r);
        writeline(ro_file, rdata);
        write(idata, data_i);
        writeline(io_file, idata);
      end if;
    end if;
  end process testbench_o;

  -----------------------------------------------------------------------------
  -- Write the blocks sizes and CP sizes generated to files
  -----------------------------------------------------------------------------
  blksize_report_o : process(clk_f) is
    file blk_file     : text open write_mode is "blksize_report.txt";
    variable blkdata  : line;
    variable data_blk : integer;
    file inv_file     : text open write_mode is "inverse_report.txt";
    variable invdata  : line;
    variable data_inv : bit;
    file cp_file : text open write_mode is "cpsize_report.txt";
    variable cpdata : line;
    variable data_cp : integer;
  begin
    if rising_edge(clk_f) then
      if(sink_valid = '1' and sink_ready = '1' and sink_sop = '1') then
        data_blk := to_integer(unsigned(N));
        write(blkdata, data_blk);
        writeline(blk_file, blkdata);
        data_cp := to_integer(unsigned(L));
        write(cpdata, data_cp);
        writeline(cp_file, cpdata);        
        data_inv := to_bit(inv);
        write(invdata, data_inv);
        writeline(inv_file, invdata);
     end if;
    end if;
  end process blksize_report_o;  
  ---------------------------------------------------------------------------------------------
  -- Kernel Component Instantiation                                                               
  ---------------------------------------------------------------------------------------------
  kernel_Tx_inst : ofdm_kernel_Tx
    generic map
    (
      DFFTOUTWIDTH => DFFTOUTWIDTH,
      DFFTINWIDTH  => DFFTINWIDTH,
      DOUTWIDTH    => DOUTWIDTH,
      MDEPTH       => MDEPTH,
      NWIDTH       => NWIDTH,
      MWIDTH       => MWIDTH,
      CPWIDTH      => CPWIDTH,
      MADDR_WIDTH  => MADDR_WIDTH
      )
    port map (
      clk_f      => clk_f,
      clk_s      => clk_s,
      rst_f_n    => rst_f_n,
      rst_s_n    => rst_s_n,
      L          => L,
      Lout       => Lout,
      N          => N,
      Nout       => Nout,
      inv => inv,
      din_valid  => sink_valid,
      din_sop    => sink_sop,
      din_eop    => sink_eop,
      din_real   => sink_real,
      din_imag   => sink_imag,
      din_error  => sink_error,
      dout_ready => source_ready,
      din_ready  => sink_ready,
      dout_sop   => source_sop,
      dout_eop   => source_eop,
      dout_valid => source_valid,
      dout_real  => source_real,
      dout_imag  => source_imag);


end rtl;

⌨️ 快捷键说明

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