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

Subversion Repositories astron_filter

[/] [astron_filter/] [trunk/] [tb_fil_ppf_wide_file_data.vhd] - Rev 2

Compare with Previous | Blame | View Log

-- Author: Eric Kooistra    : kooistra at astron.nl: july 2016
--------------------------------------------------------------------------------
--
-- Copyright (C) 2016
-- ASTRON (Netherlands Institute for Radio Astronomy) <http://www.astron.nl/>
-- P.O.Box 2, 7990 AA Dwingeloo, The Netherlands
--
-- This program is free software: you can redistribute it and/or modify
-- it under the terms of the GNU General Public License as published by
-- the Free Software Foundation, either version 3 of the License, or
-- (at your option) any later version.
--
-- This program is distributed in the hope that it will be useful,
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
-- GNU General Public License for more details.
--
-- You should have received a copy of the GNU General Public License
-- along with this program.  If not, see <http://www.gnu.org/licenses/>.
--
--------------------------------------------------------------------------------
--
-- Purpose: Test bench for fil_ppf_wide.vhd using file data
--
--   The DUT fil_ppf_wide.vhd has wb_factor >= 1 and uses array types and
--   wb_factor instances of fil_ppf_single.vhd.
--
-- Usage:
--   The g_coefs_file_prefix dat-file and g_data_file dat-file are created by
--   the Matlab script:
--
--     $RADIOHDL_WORK/applications/apertif/matlab/run_pfir.m
--
--   yields:
--
--   . g_coefs_file_prefix : run_pfir_m_pfir_coeff_fircls1_16taps_128points_16b.dat
--   . g_data_file         : run_pfir_m_sinusoid_chirp_8b_16taps_128points_16b_16b.dat
--
--   The g_fil_ppf parameters nof_taps, nof_bands (= nof polyphase), c_in_dat_w,
--   out_dat_w and coef_dat_w must match the settings in run_pfir.m.
--
--   The g_fil_ppf.in_dat_w = 8 bit to fit run_pfir_m_sinusoid_chirp_wg_8b.dat. The
--   g_fil_ppf.backoff_w = 1 is necessary to accommodate the factor 2 overshoot that
--   the PFIR output can have.
--
--   The g_data_file contains a header followed by the PFIR coefficients, WG
--   data, PFIR data and PFFT data. The tb verifies that the PFIR coefficients
--   are the same as in the dat-fil indicated by g_coefs_file_prefix. The PFFT
--   data is not used in this tb.
--
--   The MIF files are generated from the g_coefs_file_prefix dat-file by
--   the Python script:
--
--     $RADIOHDL_WORK/libraries/dsp/filter/src/python/
--      python fil_ppf_create_mifs.py -f ../hex/run_pfir_m_pfir_coeff_fircls1_16taps_128points_16b.dat -t 16 -p 128 -w 1 -c 16
--      python fil_ppf_create_mifs.py -f ../hex/run_pfir_m_pfir_coeff_fircls1_16taps_128points_16b.dat -t 16 -p 128 -w 4 -c 16
--
--   yields:
--
--   . run_pfir_m_pfir_coeff_fircls1_16taps_128points_16b_1wb_#.mif, where # = 0:15
--   . run_pfir_m_pfir_coeff_fircls1_16taps_128points_16b_4wb_#.mif, where # = 0:64
--
--   The PFIR coefficient dat and mif files are kept in local ../hex
--   The input and expected output dat files are kept in local ../data.
--
--   The dat files that are created by Matlab first need to be copied manually
--   to these local directories and then the mif files need to be generated.
--   The modelsim_copy_files key in the hdllib.cfg will copy these files to the
--   build directory from where they are loaded by Modelsim.
--
--   > run -all
--   > testbench is selftesting.
--   > observe the *_scope as radix decimal, format analogue format signals
--     in the Wave window
--
library ieee, common_pkg_lib, dp_pkg_lib, astron_diagnostics_lib, astron_ram_lib, astron_mm_lib, astron_sim_tools_lib;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use IEEE.std_logic_textio.all;
use std.textio.all;
use common_pkg_lib.common_pkg.all;
use astron_ram_lib.common_ram_pkg.ALL;
use common_pkg_lib.common_lfsr_sequences_pkg.ALL;
use common_pkg_lib.tb_common_pkg.all;
use astron_mm_lib.tb_common_mem_pkg.ALL;
use dp_pkg_lib.dp_stream_pkg.ALL;
use work.fil_pkg.all;
 
entity tb_fil_ppf_wide_file_data is
  generic(
    -- generics for tb
    g_big_endian_wb_in  : boolean := true;
    g_big_endian_wb_out : boolean := true;
    g_fil_ppf_pipeline : t_fil_ppf_pipeline := (1, 1, 1, 1, 1, 1, 0);
      -- type t_fil_pipeline is record
      --   -- generic for the taps and coefficients memory
      --   mem_delay      : natural;  -- = 2
      --   -- generics for the multiplier in in the filter unit
      --   mult_input     : natural;  -- = 1
      --   mult_product   : natural;  -- = 1
      --   mult_output    : natural;  -- = 1
      --   -- generics for the adder tree in in the filter unit
      --   adder_stage    : natural;  -- = 1
      --   -- generics for the requantizer in the filter unit
      --   requant_remove_lsb : natural;  -- = 1
      --   requant_remove_msb : natural;  -- = 0
      -- end record;
    g_fil_ppf : t_fil_ppf := (4, 0, 128, 16, 2, 1, 8, 16, 16);
      -- type t_fil_ppf is record
      --   wb_factor      : natural; -- = 4, the wideband factor
      --   nof_chan       : natural; -- = default 0, defines the number of channels (=time-multiplexed input signals): nof channels = 2**nof_chan
      --   nof_bands      : natural; -- = 1024, the number of polyphase channels (= number of points of the FFT)
      --   nof_taps       : natural; -- = 16, the number of FIR taps per subband
      --   nof_streams    : natural; -- = 1, the number of streams that are served by the same coefficients.
      --   backoff_w      : natural; -- = 0, number of bits for input backoff to avoid output overflow
      --   in_dat_w       : natural; -- = 8, number of input bits per stream
      --   out_dat_w      : natural; -- = 16, number of output bits (per stream)
      --   coef_dat_w     : natural; -- = 16, data width of the FIR coefficients
      -- end record;
    g_coefs_file_prefix   : string := "hex/run_pfir_m_pfir_coeff_fircls1";
    g_data_file           : string := "data/run_pfir_m_sinusoid_chirp_8b_16taps_128points_16b_16b.dat";  -- coefs, input and output data for 1 stream
    g_data_file_nof_lines : natural := 25600;  -- number of lines with input data that is available in the g_data_file
 
    g_data_file_nof_read  : natural := 5000;   -- number of lines with input data to read and simulate, must be <= g_data_file_nof_lines
    g_enable_in_val_gaps  : boolean := FALSE
  );
end entity tb_fil_ppf_wide_file_data;
 
architecture tb of tb_fil_ppf_wide_file_data is
 
  constant c_clk_period          : time := 10 ns;
  constant c_sclk_period         : time := c_clk_period / g_fil_ppf.wb_factor;
 
  constant c_diff_margin         : integer := 0;  -- maximum difference between PFIR HDL output and expected output (> 0 to allow minor rounding differences)
 
  constant c_nof_channels        : natural := 2**g_fil_ppf.nof_chan;
  constant c_nof_coefs           : natural := g_fil_ppf.nof_taps * g_fil_ppf.nof_bands;       -- nof PFIR coef
  constant c_nof_data_per_block  : natural := g_fil_ppf.nof_bands * c_nof_channels;           -- 1 block corresponds to 1 tap
  constant c_nof_valid_per_block : natural := c_nof_data_per_block / g_fil_ppf.wb_factor;
 
  constant c_rnd_factor          : natural := sel_a_b(g_enable_in_val_gaps, 3, 1);
  constant c_dut_block_latency   : natural := 2;
  constant c_dut_clk_latency     : natural := c_nof_valid_per_block * c_dut_block_latency * c_rnd_factor;  -- worst case
 
  -- input/output data width
  constant c_in_dat_w            : natural := g_fil_ppf.in_dat_w;
  constant c_out_dat_w           : natural := g_fil_ppf.out_dat_w;
 
  -- PFIR coefficients file access
  constant c_coefs_dat_file_prefix    : string  := g_coefs_file_prefix & "_" & integer'image(g_fil_ppf.nof_taps) & "taps" &
                                                                         "_" & integer'image(g_fil_ppf.nof_bands) & "points" &
                                                                         "_" & integer'image(g_fil_ppf.coef_dat_w) & "b";
  constant c_coefs_mif_file_prefix    : string  := c_coefs_dat_file_prefix & "_" & integer'image(g_fil_ppf.wb_factor) & "wb";
 
  -- Data file access
  constant c_nof_lines_pfir_coefs  : natural := c_nof_coefs;
  constant c_nof_lines_wg_dat      : natural := g_data_file_nof_lines;
  constant c_nof_lines_pfir_dat    : natural := c_nof_lines_wg_dat;
  constant c_nof_lines_header      : natural := 4;
  constant c_nof_lines_header_wg   : natural := c_nof_lines_header + c_nof_lines_pfir_coefs;
  constant c_nof_lines_header_pfir : natural := c_nof_lines_header + c_nof_lines_pfir_coefs + c_nof_lines_wg_dat;
 
  -- signal definitions
  signal tb_end            : std_logic := '0';
  signal tb_end_almost     : std_logic := '0';
  signal clk               : std_logic := '0';
  signal sclk              : std_logic := '1';
  signal rst               : std_logic := '0';
  signal random            : std_logic_vector(15 DOWNTO 0) := (OTHERS=>'0');  -- use different lengths to have different random sequences
 
  signal coefs_dat_arr     : t_integer_arr(c_nof_coefs-1 downto 0) := (OTHERS=>0);           -- = PFIR coef for all taps as read from via c_coefs_dat_file_prefix
  signal coefs_ref_arr     : t_integer_arr(c_nof_coefs-1 downto 0) := (OTHERS=>0);           -- = PFIR coef for all taps as read from via g_data_file
 
  signal expected_data_arr : t_integer_arr(0 to g_data_file_nof_read-1) := (OTHERS=>0);
  signal input_data_arr    : t_integer_arr(0 to g_data_file_nof_read-1) := (OTHERS=>0);
  signal input_data        : std_logic_vector(g_fil_ppf.wb_factor*c_in_dat_w-1 DOWNTO 0);
  signal input_data_scope  : integer;
 
  signal in_dat_arr        : t_fil_slv_arr(g_fil_ppf.wb_factor*g_fil_ppf.nof_streams-1 downto 0);  -- = t_slv_32_arr fits g_fil_ppf.in_dat_w <= 32
  signal in_val            : std_logic;
  signal in_val_cnt        : natural := 0;
  signal in_sub_val        : std_logic;
  signal in_sub_val_cnt    : natural := 0;
  signal in_gap            : std_logic := '0';
 
  signal tsub              : integer := 0;  -- subband time counter
  signal exp_data          : std_logic_vector(g_fil_ppf.wb_factor*c_out_dat_w-1 DOWNTO 0);
  signal exp_data_scope    : integer;
  signal diff_data_scope   : integer;
  signal output_data_scope : integer;
  signal output_data       : std_logic_vector(g_fil_ppf.wb_factor*c_out_dat_w-1 DOWNTO 0);
  signal out_dat_arr       : t_fil_slv_arr(g_fil_ppf.wb_factor*g_fil_ppf.nof_streams-1 downto 0);  -- = t_slv_32_arr fits g_fil_ppf.out_dat_w <= 32
  signal out_val           : std_logic;
  signal out_val_cnt       : natural := 0;
  signal out_sub_val       : std_logic;
  signal out_sub_val_cnt   : natural := 0;
 
begin
 
  sclk <= (not sclk) or tb_end after c_sclk_period/2;
  clk <= (not clk) or tb_end after c_clk_period/2;
  rst <= '1', '0' after c_clk_period*7;
  random <= func_common_random(random) WHEN rising_edge(clk);
  in_gap <= random(random'HIGH) WHEN g_enable_in_val_gaps=TRUE ELSE '0';
 
  ---------------------------------------------------------------
  -- DATA INPUT
  ---------------------------------------------------------------
  --
  -- In this testbench use:
  --
  --              parallel                 serial             type
  --   in_dat_arr [wb_factor][nof_streams] [t][nof_channels]  int
  -- 
  -- The time to wb_factor mapping for the fil_ppf_wide is big endian,
  -- so [3:0] = [t0,t1,t2,t3], when g_big_endian_wb_in = TRUE.
  -- When wb_factor = 4 and nof_streams = 2 then the mapping is as
  -- follows (S = stream index, P = wideband factor index):
  --
  --     t      P S   
  --     0      3 0
  --     0      3 1
  --     1      2 0
  --     1      2 1
  --     2      1 0
  --     2      1 1
  --     3      0 0
  --     3      0 1
  p_input_stimuli : process
    variable vP : natural;
  begin
    -- read input data from file
    proc_common_read_integer_file(g_data_file, c_nof_lines_header_wg, g_data_file_nof_read, 1, input_data_arr);
    wait for 1 ns;
    tb_end <= '0';
    in_dat_arr <= (others=>(others=>'0'));
    in_val <= '0';
    proc_common_wait_until_low(clk, rst);         -- Wait until reset has finished
    proc_common_wait_some_cycles(clk, 10);        -- Wait an additional amount of cycles
 
    -- apply stimuli
    for I in 0 to g_data_file_nof_read/g_fil_ppf.wb_factor-1 loop  -- serial
      for K in 0 to c_nof_channels-1 loop  -- serial
        for P in 0 to g_fil_ppf.wb_factor-1 loop  -- parallel
          if g_big_endian_wb_in=TRUE then
            vP := g_fil_ppf.wb_factor-1-P;        -- time to wideband big endian
          else
            vP := P;                              -- time to wideband little endian
          end if;
          for S in 0 to g_fil_ppf.nof_streams-1 loop  -- parallel
            if S=1 then
              -- if present then stream 1 carries zero data to be able to recognize the stream order in the wave window
              in_dat_arr(vP*g_fil_ppf.nof_streams + S) <= (OTHERS=>'0');
            else
              -- stream 0 and if present the other streams >= 2 carry the same input reference data to verify the filter function
              in_dat_arr(vP*g_fil_ppf.nof_streams + S) <= TO_SVEC(input_data_arr(I*g_fil_ppf.wb_factor + P), c_fil_slv_w);
            end if;
            in_val <= '1';
          end loop;
        end loop;
        in_val <= '1';
        proc_common_wait_some_cycles(clk, 1);
        if in_gap='1' then
          in_val <= '0';
          proc_common_wait_some_cycles(clk, 1);
        end if;
      end loop;
    end loop;
 
    -- Wait until done
    in_val <= '0';
    proc_common_wait_some_cycles(clk, c_dut_clk_latency);  -- wait for at least PPF latency of 1 tap
    tb_end_almost <= '1';
    proc_common_wait_some_cycles(clk, 100);
    tb_end <= '1';
    wait;
  end process;
 
  ---------------------------------------------------------------
  -- DUT = Device Under Test
  ---------------------------------------------------------------
  u_dut : entity work.fil_ppf_wide
  generic map (
    g_big_endian_wb_in  => g_big_endian_wb_in,
    g_big_endian_wb_out => g_big_endian_wb_out,
    g_fil_ppf           => g_fil_ppf,
    g_fil_ppf_pipeline  => g_fil_ppf_pipeline,
    g_coefs_file_prefix => c_coefs_mif_file_prefix
  )
  port map (
    dp_clk         => clk,
    dp_rst         => rst,
    mm_clk         => clk,
    mm_rst         => rst,
    ram_coefs_mosi => c_mem_mosi_rst,
    ram_coefs_miso => OPEN,
    in_dat_arr     => in_dat_arr,
    in_val         => in_val,
    out_dat_arr    => out_dat_arr,
    out_val        => out_val
  );
 
  ---------------------------------------------------------------
  -- Verify PFIR coefficients
  ---------------------------------------------------------------
  p_verify_pfir_coefs_files : PROCESS
  begin
    -- Verify that the PFIR coefficients in g_data_file are the same as those in c_coefs_dat_file_prefix.dat
    -- Just assume that the c_coefs_dat_file_prefix.dat is the same as the PFIR coefficients that are loaded via the MIFs,
    -- so do not read back the PFIR coefficients via MM.
    proc_common_read_integer_file(c_coefs_dat_file_prefix & ".dat", 0, c_nof_coefs, 1, coefs_dat_arr);
    proc_common_read_integer_file(g_data_file, c_nof_lines_header, c_nof_coefs, 1, coefs_ref_arr);
    wait for 1 ns;
    -- Wait until tb_end_almost to avoid that the Error message gets lost in earlier messages
    proc_common_wait_until_high(clk, tb_end_almost);
    assert coefs_dat_arr = coefs_ref_arr report "Unexpected PFIR coefficients." severity error;
    wait;
  end process;
 
  ---------------------------------------------------------------
  -- VERIFY OUTPUT
  ---------------------------------------------------------------
  p_verify_out_val_cnt : process
  begin
    -- Wait until tb_end_almost
    proc_common_wait_until_high(clk, tb_end_almost);
    -- The filter has a latency of 1 tap, so there remains in_dat for tap in the filter
    assert in_val_cnt > 0                                 report "Test did not run, no valid input data" severity error;
    assert out_val_cnt = in_val_cnt-c_nof_valid_per_block report "Unexpected number of valid output data" severity error;
    wait;
  end process;
 
  tsub <= tsub+1 when rising_edge(clk) and in_sub_val='1' and in_sub_val_cnt > 0 and (in_sub_val_cnt MOD c_nof_valid_per_block = 0);
 
  in_sub_val  <= '1' when in_val='1'  and (in_val_cnt  mod c_nof_channels)=0 else '0';
  out_sub_val <= '1' when out_val='1' and (out_val_cnt mod c_nof_channels)=0 else '0';
  in_sub_val_cnt  <= in_val_cnt/c_nof_channels;
  out_sub_val_cnt <= out_val_cnt/c_nof_channels;
 
  in_val_cnt  <= in_val_cnt+1  when rising_edge(clk) and in_val='1'  else in_val_cnt;
  out_val_cnt <= out_val_cnt+1 when rising_edge(clk) and out_val='1' else out_val_cnt;
 
  p_expected_output : process
  begin
    -- read expected output data from file
    proc_common_read_integer_file(g_data_file, c_nof_lines_header_pfir, g_data_file_nof_read, 1, expected_data_arr);
    wait;
  end process;
 
  p_verify_output : process(clk)
    variable vI            : natural := 0;
    variable vK            : natural := 0;
    variable vP            : natural;
    variable v_out_dat     : integer;
    variable v_exp_dat     : integer;
  begin
    if rising_edge(clk) then
      if out_val='1' then
        for P in 0 to g_fil_ppf.wb_factor-1 loop  -- parallel
          if g_big_endian_wb_out=true then
            vP := g_fil_ppf.wb_factor-1-P;        -- time to wideband big endian
          else
            vP := P;                              -- time to wideband little endian
          end if;
          for S in 0 to g_fil_ppf.nof_streams-1 loop  -- parallel
            v_out_dat := TO_SINT(out_dat_arr(vP*g_fil_ppf.nof_streams + S));
            if S=1 then
              -- stream 1 carries zero data
              v_exp_dat := 0;
              assert v_out_dat = v_exp_dat report "Output data error (stream 1 not zero)" severity error;
            else
              -- stream 0 and all other streams >= 2 carry the same data
              v_exp_dat := expected_data_arr(vI*g_fil_ppf.wb_factor + P);
              assert v_out_dat <= v_exp_dat + c_diff_margin and
                     v_out_dat >= v_exp_dat - c_diff_margin report "Output data error" severity error;
            end if;
          end loop;
        end loop;
        if vK < c_nof_channels-1 then  -- serial
          vK := vK + 1;
        else
          vK := 0;
          vI := vI + 1;
        end if;
      end if;
    end if;
  end process;
 
  ---------------------------------------------------------------
  -- DATA SCOPES
  ---------------------------------------------------------------
  p_input_data : process(in_dat_arr)
    constant cS : natural := 0;  -- tap the input_data from stream 0
  begin
    for P in 0 to g_fil_ppf.wb_factor-1 loop
      input_data((P+1)*c_in_dat_w-1 downto P*c_in_dat_w) <= in_dat_arr(P*g_fil_ppf.nof_streams + cS)(c_in_dat_w-1 downto 0);
    end loop;
  end process;
 
  p_output_data : process(out_dat_arr)
    variable cS : natural;  -- tap the output_data from stream 0
  begin
    for P in 0 to g_fil_ppf.wb_factor-1 loop
      output_data((P+1)*c_out_dat_w-1 DOWNTO P*c_out_dat_w) <= out_dat_arr(P*g_fil_ppf.nof_streams + cS)(c_out_dat_w-1 downto 0);
    end loop;
  end process;
 
  p_exp_data : process(expected_data_arr, out_sub_val_cnt)
    variable vP : natural;
  begin
    for P in 0 to g_fil_ppf.wb_factor-1 loop
      if g_big_endian_wb_out=true then
        vP := g_fil_ppf.wb_factor-1-P;
      else
        vP := P;
      end if;
      exp_data((vP+1)*c_out_dat_w-1 DOWNTO vP*c_out_dat_w) <= TO_SVEC(expected_data_arr(out_sub_val_cnt*g_fil_ppf.wb_factor + P), c_out_dat_w);
    end loop;
  end process;
 
  u_input_data_scope : entity astron_sim_tools_lib.common_wideband_data_scope
  generic map (
    g_sim                 => TRUE,
    g_wideband_factor     => g_fil_ppf.wb_factor,  -- Wideband rate factor = 4 for dp_clk processing frequency is 200 MHz frequency and SCLK sample frequency Fs is 800 MHz
    g_wideband_big_endian => g_big_endian_wb_in,   -- When true in_data[3:0] = sample[t0,t1,t2,t3], else when false : in_data[3:0] = sample[t3,t2,t1,t0]
    g_dat_w               => c_in_dat_w            -- Actual width of the data samples
  )
  port map (
    -- Sample clock
    SCLK      => sclk,  -- sample clk, use only for simulation purposes
 
    -- Streaming input data
    in_data   => input_data,
    in_val    => in_val,
 
    -- Scope output samples
    out_dat   => OPEN,
    out_int   => input_data_scope
  );
 
  u_exp_data_scope : entity astron_sim_tools_lib.common_wideband_data_scope
  generic map (
    g_sim                 => TRUE,
    g_wideband_factor     => g_fil_ppf.wb_factor,  -- Wideband rate factor = 4 for dp_clk processing frequency is 200 MHz frequency and SCLK sample frequency Fs is 800 MHz
    g_wideband_big_endian => g_big_endian_wb_out,  -- When true in_data[3:0] = sample[t0,t1,t2,t3], else when false : in_data[3:0] = sample[t3,t2,t1,t0]
    g_dat_w               => c_out_dat_w            -- Actual width of the data samples
  )
  port map (
    -- Sample clock
    SCLK      => sclk,  -- sample clk, use only for simulation purposes
 
    -- Streaming input data
    in_data   => exp_data,
    in_val    => out_val,
 
    -- Scope output samples
    out_dat   => OPEN,
    out_int   => exp_data_scope
  );
 
  u_output_data_scope : entity astron_sim_tools_lib.common_wideband_data_scope
  generic map (
    g_sim                 => TRUE,
    g_wideband_factor     => g_fil_ppf.wb_factor,  -- Wideband rate factor = 4 for dp_clk processing frequency is 200 MHz frequency and SCLK sample frequency Fs is 800 MHz
    g_wideband_big_endian => g_big_endian_wb_out,  -- When true in_data[3:0] = sample[t0,t1,t2,t3], else when false : in_data[3:0] = sample[t3,t2,t1,t0]
    g_dat_w               => c_out_dat_w            -- Actual width of the data samples
  )
  port map (
    -- Sample clock
    SCLK      => sclk,  -- sample clk, use only for simulation purposes
 
    -- Streaming input data
    in_data   => output_data,
    in_val    => out_val,
 
    -- Scope output samples
    out_dat   => OPEN,
    out_int   => output_data_scope
  );
 
  diff_data_scope <= exp_data_scope - output_data_scope;
 
  -- Equivalent to p_verify_output, but using the sclk scope data
  p_verify_data_scope : process(sclk)
  begin
    if rising_edge(clk) then
      assert diff_data_scope <=  c_diff_margin and
             diff_data_scope >= -c_diff_margin report "Output data scope error" severity error;
    end if;
  end process;
 
end tb;
 

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.