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/] [hdl/] [dct_to_hibi_v2.vhd.bak] - Rev 145

Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- Title      : DCT to Hibi. Connects dctQidct block to HIBI Wrapper
-- Project    : 
-------------------------------------------------------------------------------
-- File       : dct_to_hibi_v2.vhd
-- Author     : rasmusa
-- Created    : 01.07.2006
-- Last update: 2006-08-22
--
-- Input:
-- 1. Two address to send the results to (one for quant, one for idct)
-- 2. Control word for the current macroblock
--    Control word structure: bit 6: chroma(1)/luma(0), 5: intra(1)/inter(0),
--                             4..0: quantizer parameter (QP)
-- 3. Then the DCT data ( 8x8x6 x 16-bit values = 384 x 16 bit )
--
-- Chroma/luma: 4 luma, 2 chroma
--
-- Outputs:
-- Outputs are 16-bit words which are packed up to hibi. If hibi width is
-- 32b, then 2 16-bit words are combined into one hibi word.
-- 01. quant results: 1. 8*8 x 16bit values to quant result address
-- 02. idct  results: 1. 8*8 x 16bit values to idct  result address  
-- 03. quant results: 2. 8*8 x 16bit values to quant result address
-- 04. idct  results: 2. 8*8 x 16bit values to idct  result address
-- 05. quant results: 3. 8*8 x 16bit values to quant result address
-- 06. idct  results: 3. 8*8 x 16bit values to idct  result address
-- 07. quant results: 4. 8*8 x 16bit values to quant result address
-- 08. idct  results: 4. 8*8 x 16bit values to idct  result address
-- 09. quant results: 5. 8*8 x 16bit values to quant result address
-- 10. idct  results: 5. 8*8 x 16bit values to idct  result address
-- 11. quant results: 6. 8*8 x 16bit values to quant result address
-- 12. quant results: 1 word with bits 5..0 determing if 8x8 quant blocks(1-6)
--                    has all values zeros (except dc-component in intra)
-- 13. idct  results: 6. 8*8 x 16bit values to idct  result address
-------------------------------------------------------------------------------
-- Total amount of 16-bit values is: 384 per result address + 1 hibi word to
-- quantization result address.
--
-- With default parameter:
-- Total of 193 words of data to quant address (if data_width_g = 32)
-- Total of 192 words of data to idct address (if data_width_g = 32)
-------------------------------------------------------------------------------
-- Copyright (c) 2005 
-------------------------------------------------------------------------------
-- Revisions  :
-- Date        Version  Author  Description
-- 01.07.2005  1.0      AK      Created
-- 11.08.2005  1.1      AK      all-zero quant result given
-- 16.05.2005  1.11     AK      chroma/luma bit
-- 17.07.2007  1.12i    AR      Major rewrite, IF changed to R4, ...
-------------------------------------------------------------------------------

library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
use ieee.std_logic_misc.all;

-- For or_reduce
use ieee.std_logic_misc.all;

entity dct_to_hibi is
  generic (
    data_width_g   : integer := 32;
    comm_width_g   : integer := 3;
    dct_width_g    : integer;           -- Incoming data width(9b)
    quant_width_g  : integer;           -- Quantizated data width(8b)
    idct_width_g   : integer;           -- Data width after IDCT(9b)
    use_self_rel_g : integer;           -- Does it release itself from RTM?
    own_address_g  : integer;           -- Used for self-release
    rtm_address_g  : integer;           -- Used for self-release
    debug_w_g      : integer := 1
    );

  port (
    clk   : in std_logic;
    rst_n : in std_logic;

    -- HIBI signals
    hibi_av_out   : out std_logic;
    hibi_data_out : out std_logic_vector (data_width_g-1 downto 0);
    hibi_comm_out : out std_logic_vector (comm_width_g-1 downto 0);
    hibi_we_out   : out std_logic;
    hibi_full_in  : in  std_logic;

    hibi_re_out   : out std_logic;
    hibi_av_in    : in  std_logic;
    hibi_data_in  : in  std_logic_vector (data_width_g-1 downto 0);
    hibi_comm_in  : in  std_logic_vector (comm_width_g-1 downto 0);
    hibi_empty_in : in  std_logic;

    -- DCT signals
    wr_dct_out          : out std_logic;
    quant_ready4col_out : out std_logic;
    idct_ready4col_out  : out std_logic;
    data_dct_out        : out std_logic_vector(dct_width_g-1 downto 0);
    intra_out           : out std_logic;
    loadQP_out          : out std_logic;
    QP_out              : out std_logic_vector (4 downto 0);
    chroma_out          : out std_logic;

    data_idct_in     : in  std_logic_vector(idct_width_g-1 downto 0);
    data_quant_in    : in  std_logic_vector(quant_width_g-1 downto 0);
    dct_ready4col_in : in  std_logic;
    wr_idct_in       : in  std_logic;
    wr_quant_in      : in  std_logic;
    debug_out        : out std_logic_vector(debug_w_g-1 downto 0)

    );

end dct_to_hibi;

architecture rtl of dct_to_hibi is

  -- How many 8x8 blocks are sent after a request
  -- (4 x luma + 2 x chroma = a 16x16 macroblock )
  constant n_blocks_per_req_c : integer := 6;

  -- Incoming value width
  constant dct_word_width_in_bus_c : integer := 16;

  -- Result value width
  constant output_word_width_c : integer := 16;

  constant rx_elements_c : integer := 8*8*n_blocks_per_req_c;

  -- How many 16-bit values in a hibi word
  constant tx_fifo_value_sel_max_c : integer := data_width_g/output_word_width_c;

  -- Because dctQidct pushes out 8 values at a time, fifo must be:
  constant tx_fifo_depth_c : integer := 8/tx_fifo_value_sel_max_c;

  -- /tx_fifo_value_sel_max_c because multiple values in a word
  constant n_values_in_block_c : integer := 8*8/tx_fifo_value_sel_max_c;

  -- Input data (received from the dct's point of view )
  signal rx_counter_r : integer range 0 to rx_elements_c-1;

  -- tx from the dct's point of view ( actually results )
  -- Signals for quant result fifo
  signal tx_q_fifo_full        : std_logic;
  signal tx_q_fifo_empty       : std_logic;
  signal tx_q_fifo_re          : std_logic;
  signal tx_q_fifo_we          : std_logic;
  signal tx_q_fifo_data_from   : std_logic_vector(data_width_g-1 downto 0);
  signal tx_q_fifo_data_to_r   : std_logic_vector(data_width_g-1 downto 0);
  signal tx_q_fifo_value_sel_r : integer range 0 to tx_fifo_value_sel_max_c-1;

  -- Signals for idct result fifo
  signal tx_i_fifo_full        : std_logic;
  signal tx_i_fifo_empty       : std_logic;
  signal tx_i_fifo_re          : std_logic;
  signal tx_i_fifo_we          : std_logic;
  signal tx_i_fifo_data_from   : std_logic_vector(data_width_g-1 downto 0);
  signal tx_i_fifo_data_to_r   : std_logic_vector(data_width_g-1 downto 0);
  signal tx_i_fifo_value_sel_r : integer range 0 to tx_fifo_value_sel_max_c-1;

  -- Signals for tx fifo (muxed to either to q or i fifo)
  signal tx_fifo_full      : std_logic;
  signal tx_fifo_empty     : std_logic;
  signal tx_fifo_re        : std_logic;
  signal tx_fifo_re_r      : std_logic;
  signal tx_fifo_data_from : std_logic_vector(data_width_g-1 downto 0);
  signal tx_data_counter_r : integer range 0 to n_values_in_block_c-1;

  -- n_blocks_per_req_c result blocks of a kind (quant and idct). Sum is 2*n_blocks_per_req_c
  constant result_block_count_c   : integer := n_blocks_per_req_c*2;
  signal   result_block_counter_r : integer range 0 to result_block_count_c-1;

  component fifo
    generic (
      data_width_g : integer;
      depth_g      : integer);
    port (
      clk       : in  std_logic;
      rst_n     : in  std_logic;
      data_in   : in  std_logic_vector (data_width_g-1 downto 0);
      we_in     : in  std_logic;
      one_p_out : out std_logic;
      full_out  : out std_logic;
      data_out  : out std_logic_vector (data_width_g-1 downto 0);
      re_in     : in  std_logic;
      empty_out : out std_logic;
      one_d_out : out std_logic);
  end component;


  -- Originally Ari's counter which tells if current block is luma or chroma.
  component cl_cnt
    generic (
      n_luma_g   : integer;
      n_chroma_g : integer);
    port (
      clk    : in  std_logic;
      rst_n  : in  std_logic;
      ena_in : in  std_logic;
      cl_out : out std_logic);
  end component;


  type main_state_type is (idle, wait_quant_addr, wait_idct_addr, wait_control, wait_data, write_data);
  type result_send_type is (idle, send_av, send_data, send_last, send_rel_av, send_rel);

  -- States (results is quant is kind of state too )
  signal main_state        : main_state_type;
  signal result_send_state : result_send_type;
  signal result_is_quant_r : std_logic;

  -- Signals related to control word
  signal control_word_r : std_logic_vector(data_width_g-1 downto 0);
  alias intra_r         : std_logic is control_word_r(5);
  alias quant_param_r   : std_logic_vector(4 downto 0) is control_word_r(4 downto 0);
  signal loadQP_r       : std_logic;

  -- Some internal hibi signals
  signal hibi_re_i   : std_logic;
  signal hibi_re_r   : std_logic;
  signal hibi_we_i   : std_logic;
  signal hibi_we_r   : std_logic;
  signal hibi_av_r   : std_logic;
  signal hibi_data_r : std_logic_vector(data_width_g-1 downto 0);

  -- Signals to handle sending self release to rtm
  signal send_release_r : std_logic;
  signal release_sent_r : std_logic;

  -- Signals releated to fifos which store the result addresses
  signal addr_fifos_re_r    : std_logic;
  signal addr_fifo_q_we     : std_logic;
  signal addr_fifo_i_we     : std_logic;
  signal addr_ret_for_quant : std_logic_vector(data_width_g-1 downto 0);
  signal addr_ret_for_idct  : std_logic_vector(data_width_g-1 downto 0);
  signal addr_ret           : std_logic_vector(data_width_g-1 downto 0);


  -- For determing if a 8x8 block has only zeros ( skip 1st value of intra block )
  signal first_of_a_block_r : std_logic;
  signal quant_or_r         : std_logic_vector(n_blocks_per_req_c-1 downto 0);
  signal intra_old_r        : std_logic;
  signal send_or_value_r    : std_logic;

  -- For signalling dctQidct if we are ready to receive results or not
  signal ready_for_q_col_r : std_logic;
  signal ready_for_i_col_r : std_logic;
  
begin  -- rtl

  -----------------------------------------------------------------------------
  
  intra_out  <= intra_r;
  QP_out     <= quant_param_r;
  loadQP_out <= loadQP_r;

  -----------------------------------------------------------------------------

  cl_cnt_1 : cl_cnt
    generic map (
      n_luma_g   => 4,
      n_chroma_g => 2)
    port map (
      clk    => clk,
      rst_n  => rst_n,
      ena_in => loadQP_r,
      cl_out => chroma_out
      );

  -----------------------------------------------------------------------------

  fifo_tx_i : fifo
    generic map (
      data_width_g => data_width_g,
      depth_g      => tx_fifo_depth_c
      )
    port map (
      clk       => clk,
      rst_n     => rst_n,
      data_in   => tx_i_fifo_data_to_r,
      we_in     => tx_i_fifo_we,
      full_out  => tx_i_fifo_full,
      data_out  => tx_i_fifo_data_from,
      re_in     => tx_i_fifo_re,
      empty_out => tx_i_fifo_empty
      );

  -----------------------------------------------------------------------------

  fifo_tx_q : fifo
    generic map (
      data_width_g => data_width_g,
      depth_g      => tx_fifo_depth_c
      )
    port map (
      clk       => clk,
      rst_n     => rst_n,
      data_in   => tx_q_fifo_data_to_r,
      we_in     => tx_q_fifo_we,
      full_out  => tx_q_fifo_full,
      data_out  => tx_q_fifo_data_from,
      re_in     => tx_q_fifo_re,
      empty_out => tx_q_fifo_empty
      );

  addr_fifo_q : fifo
    generic map (
      data_width_g => data_width_g,
      depth_g      => 2  -- two addresses in mem (new and current)
      )
    port map (
      clk      => clk,
      rst_n    => rst_n,
      data_in  => hibi_data_in,
      we_in    => addr_fifo_q_we,
--      full_out  => tx_q_fifo_full,
      data_out => addr_ret_for_quant,
      re_in    => addr_fifos_re_r
--      empty_out => tx_q_fifo_empty
      );

  addr_fifo_i : fifo
    generic map (
      data_width_g => data_width_g,
      depth_g      => 2  -- two addresses in mem (new and current)
      )
    port map (
      clk      => clk,
      rst_n    => rst_n,
      data_in  => hibi_data_in,
      we_in    => addr_fifo_i_we,
--      full_out  => tx_q_fifo_full,
      data_out => addr_ret_for_idct,
      re_in    => addr_fifos_re_r
--      empty_out => tx_q_fifo_empty
      );

  -----------------------------------------------------------------------------

  quant_ready4col_out <= ready_for_q_col_r;  --2.8.
  idct_ready4col_out  <= ready_for_i_col_r;  --2.8.

  addr_fifo_q_we <= '1' when hibi_empty_in = '0' and hibi_av_in = '0' and main_state = wait_quant_addr
                    else '0';
  addr_fifo_i_we <= '1' when hibi_empty_in = '0' and hibi_av_in = '0' and main_state = wait_idct_addr
                    else '0';

  -----------------------------------------------------------------------------

-- This process handles the incoming requests and stores the data to fifo  
-- for the dct
  main : process (clk, rst_n)
    variable value_sel_v : integer range 0 to data_width_g/dct_word_width_in_bus_c-1;
  begin  -- process main
    if rst_n = '0' then                 -- asynchronous reset (active low)
      control_word_r <= (others => '0');
      wr_dct_out     <= '0';
      hibi_re_r      <= '0';
      data_dct_out   <= (others => '0');
      loadQP_r       <= '0';
      main_state     <= idle;
      send_release_r <= '0';
      rx_counter_r   <= 0;
      
    elsif clk'event and clk = '1' then  -- rising clock edge

      loadQP_r <= '0';

      if release_sent_r = '1' then
        send_release_r <= '0';
      end if;

      case main_state is

        when idle =>
          wr_dct_out <= '0';
          hibi_re_r  <= '1';
          if hibi_empty_in = '0' and hibi_av_in = '1' then
            main_state <= wait_quant_addr;
          end if;

        when wait_quant_addr =>
          
          if hibi_empty_in = '0' and hibi_av_in = '0' then
            main_state <= wait_idct_addr;
          end if;

        when wait_idct_addr =>
          if hibi_empty_in = '0' and hibi_av_in = '0' then
            main_state <= wait_control;
          end if;

        when wait_control =>
          if hibi_empty_in = '0' and hibi_av_in = '0' then
            control_word_r <= hibi_data_in;
            hibi_re_r      <= '0';
            main_state     <= wait_data;
          end if;

        when wait_data =>
          wr_dct_out <= '0';
          hibi_re_r  <= '0';
          if dct_ready4col_in = '1' then
            main_state <= write_data;
          end if;

        when write_data =>
          wr_dct_out <= '0';
          hibi_re_r  <= '0';

          value_sel_v := rx_counter_r mod (data_width_g/dct_word_width_in_bus_c);

          if hibi_empty_in = '0' and hibi_av_in = '1' and hibi_re_r = '0' then
            hibi_re_r <= '1';
          end if;

          if hibi_empty_in = '0' and hibi_av_in = '0' and (value_sel_v /= data_width_g/dct_word_width_in_bus_c-1 or hibi_re_i = '1') then
            
            wr_dct_out <= '1';

            for i in 0 to data_width_g/dct_word_width_in_bus_c-1 loop
              if i = value_sel_v then
                data_dct_out <= hibi_data_in(i*dct_word_width_in_bus_c+dct_width_g-1 downto i*dct_word_width_in_bus_c);
              end if;
            end loop;

            if data_width_g/dct_word_width_in_bus_c = 1 then
              hibi_re_r <= '1';
            else

              if value_sel_v = data_width_g/dct_word_width_in_bus_c-1-1 then
                hibi_re_r <= '1';
              end if;
              
            end if;

            if rx_counter_r mod 8 = 7 then
              main_state <= wait_data;
            end if;

            if rx_counter_r mod 64 = 63 then
              loadQP_r <= '1';
            end if;

            if rx_counter_r = rx_elements_c-1 then
              rx_counter_r   <= 0;
              send_release_r <= '1';
              main_state     <= idle;
            else
              rx_counter_r <= rx_counter_r + 1;
            end if;

            --        else
--            hibi_re_r <= '1';
          end if;
          
      end case;
      
    end if;
  end process main;

  -----------------------------------------------------------------------------

  hibi_re_i   <= hibi_re_r and (not hibi_empty_in);
  hibi_re_out <= hibi_re_i;

  -----------------------------------------------------------------------------


  -------------------------------------------------------------------------------
  -- Process which handles the result idct data writing to corresponding tx fifo
  -------------------------------------------------------------------------------  
  output_to_fifo_i : process (clk, rst_n)
  begin  -- process dct_to_fifo
    if rst_n = '0' then                 -- asynchronous reset (active low)

      tx_i_fifo_value_sel_r <= 0;
      tx_i_fifo_data_to_r   <= (others => '0');
      tx_i_fifo_we          <= '0';

    elsif clk'event and clk = '1' then  -- rising clock edge

      tx_i_fifo_we <= '0';
      if wr_idct_in = '1' then
        
        tx_i_fifo_we <= '0';
        assert tx_i_fifo_full = '0' report "TX I FIFO FULL!" severity failure;

        for i in 0 to tx_fifo_value_sel_max_c-1 loop
          if i = tx_i_fifo_value_sel_r then
            tx_i_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(signed(data_idct_in), output_word_width_c));
          end if;
        end loop;


        if tx_i_fifo_value_sel_r = tx_fifo_value_sel_max_c-1 then
          tx_i_fifo_value_sel_r <= 0;
          tx_i_fifo_we          <= '1';
        else
          tx_i_fifo_value_sel_r <= tx_i_fifo_value_sel_r + 1;
        end if;
        
      end if;

    end if;
  end process output_to_fifo_i;

  -------------------------------------------------------------------------------
  -- Process which handles the result quant data writing to corresponding tx fifo
  -------------------------------------------------------------------------------
  output_to_fifo_q : process (clk, rst_n)
    variable intra_v : std_logic;
  begin  -- process dct_to_fifo
    if rst_n = '0' then                 -- asynchronous reset (active low)

      tx_q_fifo_value_sel_r <= 0;
      tx_q_fifo_data_to_r   <= (others => '0');
      tx_q_fifo_we          <= '0';

    elsif clk'event and clk = '1' then  -- rising clock edge

      tx_q_fifo_we <= '0';
      if wr_quant_in = '1' then
        
        tx_q_fifo_we <= '0';
        assert tx_q_fifo_full = '0' report "TX Q FIFO FULL!" severity failure;


        -- The following if statement is also in the zero check process
        if result_block_counter_r = 0 then
          intra_v := intra_r;
          -- Commented out intra_old <= intra_r assignment because
          -- it is in the zero check process
        else
          intra_v := intra_old_r;
        end if;


        for i in 0 to tx_fifo_value_sel_max_c-1 loop
          if i = tx_q_fifo_value_sel_r then
            -- Lets treat the first coeff of an intra block as a unsigned
            -- (1-254 according to the quant specs found in IQuant.vhd)
            if (first_of_a_block_r = '1' and intra_v = '1') then
              tx_q_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(unsigned(data_quant_in), output_word_width_c));
            else
              tx_q_fifo_data_to_r((i+1)*output_word_width_c-1 downto i*output_word_width_c) <= std_logic_vector(resize(signed(data_quant_in), output_word_width_c));
            end if;
          end if;
        end loop;

        if tx_q_fifo_value_sel_r = tx_fifo_value_sel_max_c-1 then
          tx_q_fifo_value_sel_r <= 0;
          tx_q_fifo_we          <= '1';
        else
          tx_q_fifo_value_sel_r <= tx_q_fifo_value_sel_r + 1;
        end if;
        
      end if;

    end if;
  end process output_to_fifo_q;


  -----------------------------------------------------------------------------
  -- Depending on the result_is_quant_r signal, tx_fifo signals are connected
  -- to either of the two transmit fifos (quant or idct)
  -----------------------------------------------------------------------------

  q_i_fifo_mux_demux : process (tx_i_fifo_full, tx_q_fifo_full, tx_q_fifo_empty, tx_i_fifo_empty, tx_fifo_re, tx_q_fifo_data_from, tx_i_fifo_data_from, result_is_quant_r, addr_ret_for_idct, addr_ret_for_quant)
  begin  -- process q_i_fifo_mux
    tx_q_fifo_re <= '0';
    tx_i_fifo_re <= '0';

    if result_is_quant_r = '1' then
      tx_q_fifo_re <= tx_fifo_re;

      tx_fifo_full      <= tx_q_fifo_full;
      tx_fifo_empty     <= tx_q_fifo_empty;
      tx_fifo_data_from <= tx_q_fifo_data_from;

      addr_ret <= addr_ret_for_quant;
    else
      tx_i_fifo_re <= tx_fifo_re;

      tx_fifo_data_from <= tx_i_fifo_data_from;
      tx_fifo_full      <= tx_i_fifo_full;
      tx_fifo_empty     <= tx_i_fifo_empty;

      addr_ret <= addr_ret_for_idct;
    end if;

  end process q_i_fifo_mux_demux;

  -----------------------------------------------------------------------------

  hibi_we_i   <= hibi_we_r and (not hibi_full_in) and ((not tx_fifo_empty) or release_sent_r or send_or_value_r);
  hibi_we_out <= hibi_we_i;

  hibi_av_out <= hibi_av_r;

  tx_fifo_re <= tx_fifo_re_r and (not hibi_full_in) and (not tx_fifo_empty);

  -- Choose hibi_data_out depending on the state and hibi_av_out (_r)
  tx_fifo_read : process (result_send_state, hibi_data_r, tx_fifo_data_from, hibi_av_r)
  begin  -- process tx_fifo_i_read
    if (result_send_state = send_data) and hibi_av_r = '0' then
      hibi_data_out <= tx_fifo_data_from;
    else
      hibi_data_out <= hibi_data_r;
    end if;
  end process tx_fifo_read;

  -----------------------------------------------------------------------------
  -- ZERO CHECK PROCESS
  -- Determine if incoming quant data has only zeros or not
  -----------------------------------------------------------------------------
  zero_check : process (clk, rst_n)
    variable intra_v : std_logic;
  begin  -- process zero_check
    if rst_n = '0' then                 -- asynchronous reset (active low)
      quant_or_r         <= (others => '0');
      first_of_a_block_r <= '1';
      intra_old_r        <= '0';
    elsif clk'event and clk = '1' then  -- rising clock edge

      intra_v := '0';

      if wr_quant_in = '1' then


        -- These same if-statements are also in quant result write process
        if result_block_counter_r = 0 then
          intra_v     := intra_r;
          intra_old_r <= intra_r;
        else
          intra_v := intra_old_r;
        end if;

        if not (first_of_a_block_r = '1' and intra_v = '1') then
          quant_or_r(0) <= quant_or_r(0) or or_reduce(data_quant_in);
        end if;

        if first_of_a_block_r = '1' then
          first_of_a_block_r <= '0';
        end if;

      end if;

      if result_send_state = send_last and result_is_quant_r = '1' then
        first_of_a_block_r <= '1';
        quant_or_r         <= quant_or_r(n_blocks_per_req_c-2 downto 0) & '0';
      end if;
      
      
    end if;
  end process zero_check;

  -----------------------------------------------------------------------------
  -- SEND RESULTS OVER HIBI 
  -----------------------------------------------------------------------------
  hibi_send_proc : process (clk, rst_n)
  begin  -- process hibi_send_proc
    if rst_n = '0' then                 -- asynchronous reset (active low)
      hibi_data_r            <= (others => '0');
      hibi_comm_out          <= std_logic_vector(to_unsigned(0, comm_width_g));
      hibi_we_r              <= '0';
      hibi_av_r              <= '0';
      tx_fifo_re_r           <= '0';
      tx_data_counter_r      <= 0;
      release_sent_r         <= '0';
      result_is_quant_r      <= '1';
      addr_fifos_re_r        <= '0';
      send_or_value_r        <= '0';
      result_send_state      <= idle;
      result_block_counter_r <= 0;
      ready_for_q_col_r      <= '1';
      ready_for_i_col_r      <= '1';
      
    elsif clk'event and clk = '1' then  -- rising clock edge

      addr_fifos_re_r <= '0';

      -- If incoming data from dctQidct, let's set the ready signals low
      if wr_quant_in = '1' then
        ready_for_q_col_r <= '0';
      end if;
      if wr_idct_in = '1' then
        ready_for_i_col_r <= '0';
      end if;


      case result_send_state is

        -- Do nothing unless there is something in transmit fifo or release is
        -- requested
        when idle =>
          if tx_fifo_empty = '0' then
            result_send_state <= send_av;
          end if;

          if send_release_r = '1' and use_self_rel_g /= 0 then
            result_send_state <= send_rel_av;
          end if;

          -- Send self release address valid (+2 for release to rtm)
        when send_rel_av =>
          release_sent_r    <= '1';
          hibi_av_r         <= '1';
          hibi_we_r         <= '1';
          hibi_comm_out     <= std_logic_vector(to_unsigned(3, comm_width_g));
          hibi_data_r       <= std_logic_vector(to_unsigned(rtm_address_g+2, data_width_g));
          result_send_state <= send_rel;

          -- Send self release data (own address)
        when send_rel =>
          if hibi_we_i = '1' then
            hibi_av_r   <= '0';
            hibi_data_r <= std_logic_vector(to_unsigned(own_address_g, data_width_g));
            if hibi_av_r = '0' then
              hibi_data_r       <= (others => '0');
              hibi_we_r         <= '0';
              hibi_comm_out     <= (others => '0');
              release_sent_r    <= '0';
              result_send_state <= idle;
            end if;
          end if;

          -- Send address valid in the beginning of every 8x8 block
        when send_av =>
          hibi_av_r     <= '1';
          hibi_we_r     <= '1';
          hibi_comm_out <= std_logic_vector(to_unsigned(2, comm_width_g));
          hibi_data_r   <= addr_ret;

          result_send_state <= send_data;
          
        when send_data =>

          -- If last sending was ok.
          if hibi_we_i = '1' then
            tx_fifo_re_r <= '1';
            hibi_av_r    <= '0';

            -- If address is sent
            if hibi_av_r = '0' then

              -- If 8x8 block sending is ready
              if tx_data_counter_r = n_values_in_block_c-1 then  -- 0..31
                tx_data_counter_r <= 0;

                -- If we are finished sending the last 8x8 block (idct in fact)
                if result_block_counter_r = result_block_count_c-1 then  --0..11
                  result_block_counter_r <= 0;
                  addr_fifos_re_r        <= '1';
                else
                  result_block_counter_r <= result_block_counter_r + 1;
                end if;

                hibi_av_r       <= '0';
                hibi_comm_out   <= (others => '0');
                hibi_we_r       <= '0';
                hibi_data_r     <= (others => '0');
                tx_fifo_re_r    <= '0';
                send_or_value_r <= '0';

                -- If we are finished sending the last QUANT block,
                -- let's send the OR-value which determines if QUANT blocks
                -- has zeros.
                if result_block_counter_r = result_block_count_c-2 then
                  hibi_we_r                                  <= '1';
                  send_or_value_r                            <= '1';
                  hibi_data_r(n_blocks_per_req_c-1 downto 0) <= quant_or_r;
                  hibi_comm_out                              <= std_logic_vector(to_unsigned(2, comm_width_g));
                end if;

                result_send_state <= send_last;

              else
                tx_data_counter_r <= tx_data_counter_r + 1;
              end if;

              -- After every 8 values, we set the ready signal back on
              if tx_data_counter_r mod (8/tx_fifo_value_sel_max_c) = (8/tx_fifo_value_sel_max_c)-1 then
                if result_is_quant_r = '1' then
                  ready_for_q_col_r <= '1';
                else
                  ready_for_i_col_r <= '1';
                end if;
              end if;
              
            end if;
            
          end if;

          -- In this state, the or word is being sent, if send_or_value_r is high.
        when send_last =>
          if send_or_value_r = '0' or hibi_we_i = '1' then
            send_or_value_r   <= '0';
            hibi_we_r         <= '0';
            hibi_data_r       <= (others => '0');
            hibi_comm_out     <= (others => '0');
            result_is_quant_r <= not result_is_quant_r;
            result_send_state <= idle;
          end if;
          
      end case;

    end if;
  end process hibi_send_proc;

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.