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

Subversion Repositories mkjpeg

[/] [mkjpeg/] [trunk/] [design/] [BufFifo/] [BUF_FIFO.vhd] - Rev 40

Go to most recent revision | Compare with Previous | Blame | View Log

-------------------------------------------------------------------------------
-- File Name : BUF_FIFO.vhd
--
-- Project   : JPEG_ENC
--
-- Module    : BUF_FIFO
--
-- Content   : Input FIFO Buffer
--
-- Description : 
--
-- Spec.     : 
--
-- Author    : Michal Krepa
--
-------------------------------------------------------------------------------
-- History :
-- 20090311: (MK): Initial Creation.
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
----------------------------------- LIBRARY/PACKAGE ---------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
 
-------------------------------------------------------------------------------
-- generic packages/libraries:
-------------------------------------------------------------------------------
library ieee;
  use ieee.std_logic_1164.all;
  use ieee.numeric_std.all;
 
-------------------------------------------------------------------------------
-- user packages/libraries:
-------------------------------------------------------------------------------
library work;
  use work.JPEG_PKG.all;
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
----------------------------------- ENTITY ------------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
entity BUF_FIFO is
  port 
  (
        CLK                : in  std_logic;
        RST                : in  std_logic;
        -- HOST PROG
        img_size_x         : in  std_logic_vector(15 downto 0);
        img_size_y         : in  std_logic_vector(15 downto 0);
        sof                : in  std_logic;
 
        -- HOST DATA
        iram_wren          : in  std_logic;
        iram_wdata         : in  std_logic_vector(23 downto 0);
        fifo_almost_full   : out std_logic;
 
        -- FDCT
        fdct_block_cnt     : in  std_logic_vector(12 downto 0);
        fdct_fifo_rd       : in  std_logic;
        fdct_fifo_empty    : out std_logic;
        fdct_fifo_q        : out std_logic_vector(23 downto 0);
        fdct_fifo_hf_full  : out std_logic
    );
end entity BUF_FIFO;
 
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
----------------------------------- ARCHITECTURE ------------------------------
-------------------------------------------------------------------------------
-------------------------------------------------------------------------------
architecture RTL of BUF_FIFO is
 
  constant C_NUM_SUBF      : integer := C_MAX_LINE_WIDTH/8;
  constant C_PIXEL_BITS    : integer := 24;
  constant C_SUBF_ADDRW    : integer := 7-C_MEMORY_OPTIMIZED;
  --constant C_LOG2_NUM_SUBF : integer := integer(log2(real(C_NUM_SUBF))); 
 
  type T_DATA_ARR is array (0 to C_NUM_SUBF-1) of std_logic_vector(23 downto 0);
  type T_CNT_ARR  is array (0 to C_NUM_SUBF-1) of 
    std_logic_vector(C_SUBF_ADDRW downto 0);
 
  type T_FIFO_RAMADDR     is array (0 to C_NUM_SUBF-1) of 
                            STD_LOGIC_VECTOR(C_SUBF_ADDRW-1 downto 0);
 
  signal fifo_rd          : std_logic_vector(C_NUM_SUBF-1 downto 0);
  signal fifo_wr          : std_logic_vector(C_NUM_SUBF-1 downto 0);
  signal fifo_data        : std_logic_vector(23 downto 0);
  signal fifo_data_d1     : std_logic_vector(23 downto 0);
  signal fifo_full        : std_logic_vector(C_NUM_SUBF-1 downto 0);
  signal fifo_empty       : std_logic_vector(C_NUM_SUBF-1 downto 0);
  signal fifo_half_full   : std_logic_vector(C_NUM_SUBF-1 downto 0);
  signal fifo_count       : T_CNT_ARR;
 
  signal pixel_cnt        : unsigned(15 downto 0);
  signal wblock_cnt       : unsigned(12 downto 0);
  signal last_idx         : unsigned(12 downto 0);
  signal idx_reg          : unsigned(log2(C_NUM_SUBF)-1 downto 0);
  signal wr_idx_reg       : unsigned(log2(C_NUM_SUBF)-1 downto 0);
 
  signal ramq             : STD_LOGIC_VECTOR(C_PIXEL_BITS-1 downto 0);
  signal ramd             : STD_LOGIC_VECTOR (C_PIXEL_BITS-1 downto 0);
  signal ramwaddr         : STD_LOGIC_VECTOR
                            (log2(C_NUM_SUBF)+C_SUBF_ADDRW-1 downto 0);
  signal ramwaddr_offset  : unsigned(C_SUBF_ADDRW-1 downto 0);
  signal ramwaddr_base    : unsigned(log2(C_NUM_SUBF)+C_SUBF_ADDRW downto 0);
  signal ramenw           : STD_LOGIC;
  signal ramenw_m1        : STD_LOGIC;
  signal ramenw_m2        : STD_LOGIC;
  signal ramraddr         : STD_LOGIC_VECTOR
                            (log2(C_NUM_SUBF)+C_SUBF_ADDRW-1 downto 0);
  signal ramraddr_base    : unsigned(log2(C_NUM_SUBF)+C_SUBF_ADDRW downto 0);
  signal ramraddr_offset  : unsigned(C_SUBF_ADDRW-1 downto 0);
  signal ramenr           : STD_LOGIC;
 
  signal fifo_ramwaddr    : T_FIFO_RAMADDR;
  signal fifo_ramenw      : STD_LOGIC_VECTOR(C_NUM_SUBF-1 downto 0);
  signal fifo_ramraddr    : T_FIFO_RAMADDR;
  signal fifo_ramenr      : STD_LOGIC_VECTOR(C_NUM_SUBF-1 downto 0);
 
  signal offset_ramwaddr  : STD_LOGIC_VECTOR(C_SUBF_ADDRW-1 downto 0);
-------------------------------------------------------------------------------
-- Architecture: begin
-------------------------------------------------------------------------------
begin
 
  -------------------------------------------------------------------
  -- SUB_FIFOs
  -------------------------------------------------------------------
  G_SUB_FIFO : for i in 0 to C_NUM_SUBF-1 generate
 
    U_SUB_FIFO : entity work.SUB_FIFO   
    generic map
    (
          DATA_WIDTH        => C_PIXEL_BITS,
          ADDR_WIDTH        => C_SUBF_ADDRW
    )
    port map 
    (        
          rst               => RST,
          clk               => CLK,
          rinc              => fifo_rd(i),
          winc              => fifo_wr(i),
 
          fullo             => fifo_full(i),
          emptyo            => fifo_empty(i),
          count             => fifo_count(i),
 
          ramwaddr          => fifo_ramwaddr(i),
          ramenw            => fifo_ramenw(i),
          ramraddr          => fifo_ramraddr(i),
          ramenr            => fifo_ramenr(i)
    );
  end generate G_SUB_FIFO;
 
  -------------------------------------------------------------------
  -- RAM for SUB_FIFOs
  -------------------------------------------------------------------
  U_SUB_RAMZ : entity work.SUB_RAMZ
  generic map 
  (
           RAMADDR_W => log2(C_NUM_SUBF)+C_SUBF_ADDRW,
           RAMDATA_W => C_PIXEL_BITS        
  )   
  port map 
  (      
        d            => ramd,               
        waddr        => ramwaddr,     
        raddr        => ramraddr,     
        we           => ramenw,     
        clk          => clk,     
 
        q            => ramq     
  ); 
 
  -------------------------------------------------------------------
  -- FIFO almost full
  -------------------------------------------------------------------
  p_fifo_almost_full : process(CLK, RST)
  begin
    if RST = '1' then
      fifo_almost_full   <= '1';
      last_idx           <= (others => '0');
    elsif CLK'event and CLK = '1' then
      if img_size_x = (img_size_x'range => '0') then
        last_idx <= (others => '0');
      else
        last_idx <= unsigned(img_size_x(15 downto 3))-1;
      end if;      
 
      if C_MEMORY_OPTIMIZED = 0 then
        if unsigned(fifo_count(to_integer(wblock_cnt))) > to_unsigned(128-2*8,8) then
          fifo_almost_full <= '1';
        else
          fifo_almost_full <= '0';
        end if;
      else
        if unsigned(fifo_count(to_integer(wblock_cnt))) >= to_unsigned(62,8) then
          fifo_almost_full <= '1';
        -- due to FIFO full latency next subFIFO is in danger of being
        -- overwritten thus its fifo full must be checked ahead
        else
          -- next=0 when current is last
          if wblock_cnt = last_idx then
            -- latency from FIFO full till it is recognized by Host is 2T (64-2)=62
            if unsigned(fifo_count(0)) >= to_unsigned(62,8) then
              fifo_almost_full <= '1';
            else
              fifo_almost_full <= '0';
            end if;
          -- next is just current+1
          else
            -- latency from FIFO full till it is recognized by Host is 2T (64-2)=62
            if unsigned(fifo_count(to_integer(wblock_cnt)+1)) >= to_unsigned(62,8) then
              fifo_almost_full <= '1';
            else
              fifo_almost_full <= '0';
            end if;
          end if;
        end if;
 
      end if;      
    end if;
  end process;
 
  -------------------------------------------------------------------
  -- pixel_cnt
  -------------------------------------------------------------------
  p_pixel_cnt : process(CLK, RST)
  begin
    if RST = '1' then
      pixel_cnt   <= (others => '0');
    elsif CLK'event and CLK = '1' then
      if iram_wren = '1' then
        if pixel_cnt = unsigned(img_size_x)-1 then
          pixel_cnt <= (others => '0');
        else
          pixel_cnt <= pixel_cnt + 1;
        end if;  
      end if;
 
      if sof = '1' then
        pixel_cnt <= (others => '0');
      end if;
    end if;
  end process;
 
  wblock_cnt <= pixel_cnt(pixel_cnt'high downto 3);
 
  -------------------------------------------------------------------
  -- FIFO half full
  -------------------------------------------------------------------
  p_half_full : process(CLK, RST)
  begin
    if RST = '1' then
      for i in 0 to C_NUM_SUBF-1 loop
        fifo_half_full(i) <= '0';
      end loop;
    elsif CLK'event and CLK = '1' then
      for i in 0 to C_NUM_SUBF-1 loop
        if C_MEMORY_OPTIMIZED = 0 then
          if unsigned(fifo_count(i)) >= 64 then
            fifo_half_full(i) <= '1';
          else
            fifo_half_full(i) <= '0';
          end if;
        else
          fifo_half_full(i) <= fifo_full(i);
        end if;
      end loop;
    end if;
  end process;
 
  -------------------------------------------------------------------
  -- Mux1
  -------------------------------------------------------------------
  p_mux1 : process(CLK, RST)
  begin
    if RST = '1' then
      for i in 0 to C_NUM_SUBF-1 loop
        fifo_wr(i) <= '0';
      end loop;
    elsif CLK'event and CLK = '1' then
      for i in 0 to C_NUM_SUBF-1 loop
        if wblock_cnt(log2(C_NUM_SUBF)-1 downto 0) = i then
          fifo_wr(i) <= iram_wren;
        else
          fifo_wr(i) <= '0';
        end if;
      end loop;
    end if;
  end process;
 
  -------------------------------------------------------------------
  -- Mux2
  -------------------------------------------------------------------
  p_mux2 : process(CLK, RST)
  begin
    if RST = '1' then
      for i in 0 to C_NUM_SUBF-1 loop
        fifo_rd(i)      <= '0';
      end loop;
      fdct_fifo_empty   <= '0';
      fdct_fifo_hf_full <= '0';
      idx_reg           <= (others => '0');
    elsif CLK'event and CLK = '1' then
      idx_reg <= unsigned(fdct_block_cnt(log2(C_NUM_SUBF)-1 downto 0));
 
      for i in 0 to C_NUM_SUBF-1 loop
        if idx_reg = i then
          fifo_rd(i) <= fdct_fifo_rd;
        else
          fifo_rd(i) <= '0';
        end if;
      end loop;
 
      fdct_fifo_empty   <= fifo_empty(to_integer(idx_reg));
      fdct_fifo_hf_full <= fifo_half_full(to_integer(idx_reg));
    end if;
  end process;
 
  fdct_fifo_q  <= ramq;
 
  -------------------------------------------------------------------
  -- Mux3
  -------------------------------------------------------------------
  p_mux3 : process(CLK, RST)
  begin
    if RST = '1' then
      ramwaddr         <= (others => '0');
      ramwaddr_offset  <= (others => '0');
      ramwaddr_base    <= (others => '0');
      ramenw           <= '0';
      ramenw_m1        <= '0';
      wr_idx_reg       <= (others => '0');
      ramd             <= (others => '0');
      fifo_data        <= (others => '0');
      fifo_data_d1     <= (others => '0');
    elsif CLK'event and CLK = '1' then
      wr_idx_reg    <= unsigned(wblock_cnt(log2(C_NUM_SUBF)-1 downto 0));
 
      fifo_data    <= iram_wdata;
      fifo_data_d1 <= fifo_data;
      ramd         <= fifo_data_d1;
 
      ramenw_m1 <= fifo_ramenw(to_integer(wr_idx_reg));
      ramenw    <= ramenw_m1;
 
      ramwaddr_offset <= unsigned(fifo_ramwaddr(to_integer(wr_idx_reg)));
      ramwaddr_base   <= to_unsigned(2**C_SUBF_ADDRW, C_SUBF_ADDRW+1) *
                         wr_idx_reg;
      ramwaddr  <= std_logic_vector(ramwaddr_base(ramwaddr'range) + 
                  resize(ramwaddr_offset, ramwaddr'length));
    end if;
  end process;
 
  -------------------------------------------------------------------
  -- Mux4
  -------------------------------------------------------------------
  p_mux4 : process(CLK, RST)
  begin
    if RST = '1' then
      ramraddr          <= (others => '0');
      ramraddr_base     <= (others => '0');
      ramraddr_offset   <= (others => '0');
    elsif CLK'event and CLK = '1' then
      ramraddr_offset <= unsigned(fifo_ramraddr(to_integer(idx_reg)));
      ramraddr_base   <= to_unsigned(2**C_SUBF_ADDRW, C_SUBF_ADDRW+1) *
                         idx_reg;
      ramraddr <= std_logic_vector(ramraddr_base(ramraddr'range) + 
                  resize(unsigned(ramraddr_offset), ramraddr'length));
    end if;
  end process;
 
end architecture RTL;
-------------------------------------------------------------------------------
-- Architecture: end
-------------------------------------------------------------------------------

Go to most recent revision | 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.