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

Subversion Repositories funbase_ip_library

[/] [funbase_ip_library/] [trunk/] [TUT/] [ip.hwp.accelerator/] [dct_to_hibi/] [1.0/] [tb/] [tb_dct_cpu.vhd] - Rev 168

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : Testbench for dct, CPU emulator
-- Project    : 
-------------------------------------------------------------------------------
-- File       : tb_dct_cpu.vhd
-- Author     : 
-- Company    : 
-- Created    : 2006-05-24
-- Last update: 2013-03-22
-- Platform   : 
-- Standard   : VHDL'87
-------------------------------------------------------------------------------
-- Description: CPU emulator
-------------------------------------------------------------------------------
-- Copyright (c) 2006 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 2006-05-24  1.0      rasmusa Created
-------------------------------------------------------------------------------
 
library IEEE;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_textio.all;
use ieee.std_logic_misc.all;
 
 
library std;
use std.textio.all;
use work.tb_dct_package.all;
 
library dct;
library idct;
library quantizer;
library dctQidct;
 
use dct.DCT_pkg.all;
use idct.IDCT_pkg.all;
use quantizer.Quantizer_pkg.all;
 
entity tb_dct_cpu is
 
  generic (
    data_width_g : integer := 32;
    comm_width_g : integer := 5);
  port (
    clk_dctqidct_fast : in std_logic;
    clk               : in std_logic;
    rst_n             : in std_logic;
 
    data_in  : in  std_logic_vector(data_width_g-1 downto 0);
    comm_in  : in  std_logic_vector(comm_width_g-1 downto 0);
    av_in    : in  std_logic;
    re_out   : out std_logic;
    empty_in : in  std_logic;
 
    data_out : out std_logic_vector(data_width_g-1 downto 0);
    comm_out : out std_logic_vector(comm_width_g-1 downto 0);
    av_out   : out std_logic;
    we_out   : out std_logic;
    full_in  : in  std_logic;
 
    dct_data_idct_in  : in std_logic_vector(IDCT_resultw_co-1 downto 0);
    dct_data_quant_in : in std_logic_vector(QUANT_resultw_co-1 downto 0);
    dct_wr_idct_in    : in std_logic;
    dct_wr_quant_in   : in std_logic;
    dct_wr_dct_in     : in std_logic;
    dct_data_dct_in   : in std_logic_vector(DCT_inputw_co-1 downto 0);
    dct_qp_in         : in std_logic_vector(4 downto 0);
    dct_intra_in      : in std_logic;
    dct_chroma_in     : in std_logic;
    dct_loadqp_in     : in std_logic
 
    );
 
end tb_dct_cpu;
 
architecture rtl of tb_dct_cpu is
 
  constant hibi_addr_cpu_q_c : integer := hibi_addr_cpu_c + 1;
  constant hibi_addr_cpu_i_c : integer := hibi_addr_cpu_c + 2;
 
  constant data_max_c : integer := 384;
  constant n_blocks_c : integer := 6;
  type     value_vect_type is array (0 to data_max_c-1) of std_logic_vector(16-1 downto 0);
  type     qp_vect_type is array (0 to n_blocks_c-1) of std_logic_vector(4 downto 0);
  constant qp_w_c     : integer := 5;
 
 
  type data_type is record
    original  : value_vect_type;
    dct_org   : value_vect_type;
    dct_idct  : value_vect_type;
    idct      : value_vect_type;
    dct_quant : value_vect_type;
    quant     : value_vect_type;
    qp        : qp_vect_type;
    chroma    : std_logic_vector(6-1 downto 0);
    intra     : std_logic_vector(6-1 downto 0);
  end record;
 
  constant qp_c : integer := 1;
 
  constant values_per_word_c : integer := data_width_g/16;
 
  signal data_counter_r : integer range 0 to data_max_c-1;
  signal rx_counter_r   : integer range 0 to 8*8-1;
 
  signal idle_counter_r : integer;
 
  signal data_r : data_type;
 
  signal q_counter_r : integer range 0 to data_max_c-1;
  signal i_counter_r : integer range 0 to data_max_c-1;
  signal d_counter_r : integer range 0 to data_max_c-1;
  signal qp_counter_r : integer range 0 to data_max_c-1;
 
  signal res_q_cnt_r : integer range 0 to data_max_c-1;
  signal res_i_cnt_r : integer range 0 to data_max_c-1;
 
  signal result_is_quant_r : std_logic;
  signal last_av_r : integer;
 
  signal wait_zero_r : std_logic;
 
  signal test_data_type : integer := 2;
 
  -- CONTROL WORD CONFIG
  signal intra : std_logic := '0';
--  signal intra_old_r : std_logic;
  signal qp    : std_logic_vector(qp_w_c-1 downto 0) := std_logic_vector(to_unsigned(qp_c, qp_w_c));
 
  type   send_control_type is (idle, send_av, send_ret_addr_q, send_ret_addr_i, send_control, send_data);
  signal send_ctrl,send_ctrl_old : send_control_type;
 
  signal free_r : std_logic;
  signal new_req_r  : std_logic;
 
  function generate_data (
    constant test_data_type : integer )
    return value_vect_type is
    variable ret_v : value_vect_type;
  begin  -- generate_data
    for i in 0 to data_max_c-1 loop
      if test_data_type = 0 then
        ret_v(i) := std_logic_vector(resize(to_signed( 0, DCT_inputw_co), 16));
      elsif test_data_type = 1 then
        ret_v(i) := std_logic_vector(resize(to_signed( 28, DCT_inputw_co), 16));     
      elsif test_data_type = 2 then        
        ret_v(i) := std_logic_vector(resize(to_signed( ((i*4) mod (i+1))*7, DCT_inputw_co), 16));        
      end if;
    end loop;  -- i
    return ret_v;
  end generate_data;
 
 
begin  -- rtl
 
  re_out <= not empty_in;
 
  process (clk, rst_n)
    variable zero_vect_v : std_logic_vector(data_width_g-qp_w_c-1-1 downto 0) := (others => '0');
  begin  -- process
 
    if rst_n = '0' then                 -- asynchronous reset (active low)
      send_ctrl       <= idle;
      free_r          <= '1';
      data_r.original <= generate_data(test_data_type);
      send_ctrl <= idle;
      idle_counter_r <= 0;
    elsif clk'event and clk = '1' then  -- rising clock edge
 
      send_ctrl_old <= send_ctrl;
      if send_ctrl_old /= send_ctrl then
        idle_counter_r <= 0;
      else
        idle_counter_r <= idle_counter_r + 1;
      end if;
 
      assert idle_counter_r < 20000 report "IDLE TIME EXCEEDED" severity failure;
 
      case send_ctrl is
 
        when idle =>
          if full_in = '0' then
            we_out   <= '0';
            data_out <= (others => '0');
            comm_out <= (others => '0');
 
            if free_r = '1' or new_req_r = '1' then
              send_ctrl <= send_av;
              free_r    <= '0';
            end if;
 
          end if;
 
 
        when send_av =>
          av_out    <= '1';
          data_out  <= std_logic_vector(to_unsigned(hibi_addr_dct_c, data_width_g));
          we_out    <= '1';
          comm_out  <= "00010";
          send_ctrl <= send_ret_addr_q;
 
        when send_ret_addr_q =>
          if full_in = '0' then
            av_out    <= '0';
            data_out  <= std_logic_vector(to_unsigned(hibi_addr_cpu_q_c, data_width_g));
            we_out    <= '1';
            send_ctrl <= send_ret_addr_i;
          end if;
 
        when send_ret_addr_i =>
          if full_in = '0' then
            data_out  <= std_logic_vector(to_unsigned(hibi_addr_cpu_i_c, data_width_g));
            we_out    <= '1';
            send_ctrl <= send_control;
          end if;
 
        when send_control =>
          if full_in = '0' then
            data_out  <= zero_vect_v & intra & qp;
            we_out    <= '1';
            send_ctrl <= send_data;
            assert false report "REQUEST SENT" severity note;
          end if;
 
        when send_data =>
          if full_in = '0' then
            we_out <= '1';
 
            for i in 0 to values_per_word_c-1 loop
              data_out((i+1)*16-1 downto i*16) <= data_r.original(data_counter_r + i);
            end loop;  -- i           
 
            if data_counter_r = data_max_c-values_per_word_c then
              send_ctrl      <= idle;
              data_counter_r <= 0;
              assert false report "Data sent!" severity note;          
            else
              data_counter_r <= data_counter_r + values_per_word_c;
            end if;
 
          end if;
 
        when others => null;
      end case;
 
 
    end if;
  end process;
 
  re_out <= not empty_in;
 
  rx_proc : process (clk, rst_n)
    variable or_v : std_logic_vector(5 downto 0);
  begin  -- process rx_proc
    if rst_n = '0' then                 -- asynchronous reset (active low)
      rx_counter_r      <= 0;
      result_is_quant_r <= '1';
      res_q_cnt_r       <= 0;
      res_i_cnt_r       <= 0;
      new_req_r <= '0';
      wait_zero_r <= '0';
 
    elsif clk'event and clk = '1' then  -- rising clock edge
 
      new_req_r <= '0';
 
      if empty_in = '0' and av_in = '1' then
        last_av_r <= to_integer(unsigned(data_in));
      end if;
 
      if empty_in = '0' and av_in = '1' and data_in = std_logic_vector(to_unsigned(hibi_addr_cpu_rtm_c+2,data_width_g)) then
       assert false report "Got release!" severity note;
       new_req_r <= '1';
       end if;
 
      if res_q_cnt_r /= 0 and wait_zero_r = '0' then
        wait_zero_r <= '1';
      end if;
 
      if res_q_cnt_r = 0 and empty_in = '0' and av_in = '0' and wait_zero_r = '1' and (last_av_r = hibi_addr_cpu_q_c ) then
        or_v := (others => '0');
 
        for j in 0 to 5 loop
          for i in j*64 to (j+1)*64-1 loop
            if intra = '0' or i mod 64 /= 0 then
              or_v(j) := or_v(j) or or_reduce( data_r.quant(i) );
            end if;
          end loop;  -- i          
        end loop;  -- j
 
 
--        for i in 0 to data_max_c-1 loop
--          if intra = '1' then
--            if i mod 64 /= 0 then
--              or_v := or_v or or_reduce(data_r.quant(i));              
--            end if;
--          else
--            or_v := or_v or or_reduce(data_r.quant(i));
--          end if;
--        end loop;  -- i
 
        assert false report "Got zero bit" severity note;
        assert or_v = data_in(5 downto 0) report "Zero bits do not match!" severity failure;
 
 
        wait_zero_r <= '0';
        data_r.quant <= (others => (others => '0'));
 
 
      elsif empty_in = '0' and av_in = '0' and (last_av_r = hibi_addr_cpu_i_c or last_av_r = hibi_addr_cpu_q_c) then
 
        if result_is_quant_r = '1' then
 
          for i in 0 to values_per_word_c-1 loop
            assert data_in((i+1)*16-1 downto i*16) = data_r.dct_quant(res_q_cnt_r+i) report "Result data mismatch in QUANT" severity failure;
            data_r.quant(res_q_cnt_r+i) <= data_in((i+1)*16-1 downto i*16);
          end loop;  -- i
 
          if res_q_cnt_r = data_max_c-values_per_word_c then
            res_q_cnt_r <= 0;
            assert false report "QUANT Data received!" severity note;
          else
            res_q_cnt_r <= res_q_cnt_r + values_per_word_c;
          end if;
 
        else
          for i in 0 to values_per_word_c-1 loop
            assert data_in((i+1)*16-1 downto i*16) = data_r.dct_idct(res_i_cnt_r+i) report "Result data mismatch in IDCT" severity failure;
            data_r.idct(res_i_cnt_r+i) <= data_in((i+1)*16-1 downto i*16);
          end loop;  -- i
 
          --res_i_cnt_r <= res_i_cnt_r + values_per_word_c;
 
          if res_i_cnt_r = data_max_c-values_per_word_c then
            res_i_cnt_r <= 0;
            data_r.idct <= (others => (others => '0'));
            assert false report "IDCT Data received!" severity note;
            --new_req_r <= '1';           -- LM to no self 
          else
            res_i_cnt_r <= res_i_cnt_r + values_per_word_c;
          end if;
 
        end if;
 
        if rx_counter_r = 8*8-values_per_word_c then
          rx_counter_r      <= 0;
          result_is_quant_r <= not result_is_quant_r;
        else
          rx_counter_r <= rx_counter_r + values_per_word_c;
        end if;
 
      end if;
    end if;
  end process rx_proc;
 
 
  ref_storing : process (clk_dctqidct_fast, rst_n)
    variable dct_data_v : std_logic_vector(16-1 downto 0);
  begin  -- process result_storing
    if rst_n = '0' then                 -- asynchronous reset (active low)
      q_counter_r <= 0;
      i_counter_r <= 0;
      d_counter_r <= 0;
 
 
    elsif clk_dctqidct_fast'event and clk_dctqidct_fast = '1' then  -- rising clock edge
 
 
      if dct_wr_idct_in = '1' then
 
        data_r.dct_idct(i_counter_r) <= std_logic_vector(resize(signed(dct_data_idct_in), 16));
 
        if i_counter_r = data_max_c-1 then
          i_counter_r <= 0;          
        else
          i_counter_r <= i_counter_r + 1;
        end if;
 
      end if;
 
      if dct_wr_quant_in = '1' then
 
        if q_counter_r mod 64 = 0 and intra = '1' then
          data_r.dct_quant(q_counter_r) <= std_logic_vector(resize(unsigned(dct_data_quant_in), 16));
        else          
          data_r.dct_quant(q_counter_r) <= std_logic_vector(resize(signed(dct_data_quant_in), 16));          
        end if;
 
        if q_counter_r = data_max_c-1 then
          q_counter_r <= 0;
        else
          q_counter_r <= q_counter_r + 1;
        end if;
 
      end if;
 
      if dct_wr_dct_in = '1' then
        dct_data_v := std_logic_vector(resize(signed(dct_data_dct_in), 16));
 
        assert dct_data_v = data_r.original(d_counter_r) report "DCT Input MISMATCH" severity failure;
        data_r.dct_org(d_counter_r) <= dct_data_v;
 
 
        if d_counter_r = data_max_c-1 then
          d_counter_r <= 0;
        else
          d_counter_r <= d_counter_r + 1;
        end if;
 
      end if;
 
      if dct_loadqp_in = '1' then
 
        assert dct_chroma_in = '1' or ( qp_counter_r /= 4 and qp_counter_r /= 5 ) report "CHROMA FAILURE" severity failure;
 
        assert dct_intra_in = intra report "INTRA FAILURE" severity failure;
        assert dct_qp_in = qp report "QP FAILURE" severity failure;
 
        data_r.chroma( qp_counter_r ) <= dct_chroma_in;
        data_r.intra ( qp_counter_r ) <= dct_intra_in;
        data_r.qp( qp_counter_r ) <= dct_qp_in;
 
 
        if qp_counter_r = n_blocks_c-1 then
          qp_counter_r <= 0;
          assert false report "All QPs went right!" severity note;
        else
          qp_counter_r <= qp_counter_r + 1;
        end if;
 
      end if;
 
 
    end if;
  end process ref_storing;
 
end rtl;
 

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.