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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_lcstklog_2w.vhd] - Rev 2

Compare with Previous | Blame | View Log

-----------------------------------------------------------------
--                                                             --
-----------------------------------------------------------------
--                                                             --
-- Copyright (C) 2013 Stefano Tonello                          --
--                                                             --
-- This source file may be used and distributed without        --
-- restriction provided that this copyright statement is not   --
-- removed from the file and that any derivative work contains --
-- the original copyright notice and the associated disclaimer.--
--                                                             --
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY         --
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED   --
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS   --
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR      --
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,         --
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES    --
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE   --
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR        --
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF  --
-- LIABILITY, WHETHER IN  CONTRACT, STRICT LIABILITY, OR TORT  --
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT  --
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE         --
-- POSSIBILITY OF SUCH DAMAGE.                                 --
--                                                             --
-----------------------------------------------------------------
 
---------------------------------------------------------------
-- G.729a ASIP loop control stack management logic
---------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
library WORK;
use WORK.G729A_ASIP_PKG.all;
 
entity G729A_ASIP_LCSTKLOG_2W is
  generic(
    DEPTH : natural
  );
  port(
    CLK_i : in std_logic;
    RST_i : in std_logic;
    SRST_i : in std_logic;
    LLBRX_i : in std_logic; -- llbri eXecute flag
    LLERX_i : in std_logic; -- lleri eXecute flag
    LLCRX_i : in std_logic; -- llcnt/llcnti eXecute flag
    IMM_i : in unsigned(ALEN-1 downto 0); -- loop begin address
    PCF0_i : in unsigned(ALEN-1 downto 0); -- IF program counter
    PCF1_i : in unsigned(ALEN-1 downto 0); -- IF program counter
    PCX0_i : in unsigned(ALEN-1 downto 0); -- IX program counter
    PCX1_i : in unsigned(ALEN-1 downto 0); -- IX program counter
    IXV_i : in std_logic_vector(2-1 downto 0);
 
    KLL1_o : out std_logic;
    LEND_o : out std_logic;
    LEIS_o : out std_logic;
    LBX_o : out std_logic; -- loop-back jump eXecute flag
    LBTA_o : out unsigned(16-1 downto 0) -- loop-back target address
  );
end G729A_ASIP_LCSTKLOG_2W;
 
architecture ARC of G729A_ASIP_LCSTKLOG_2W is
 
  component G729A_ASIP_LCSTK is
    generic(
      DEPTH : natural
    );
    port(
      CLK_i : in std_logic;
      RST_i : in std_logic;
      SRST_i : in std_logic;
      PUSH_i : in std_logic;
      POP_i : in std_logic;
      DECR_i : in std_logic;
      LBADR_i : in unsigned(ALEN-1 downto 0); -- loop begin address
      LEADR_i : in unsigned(ALEN-1 downto 0); -- loop end address
      LCNT_i : in unsigned(16-1 downto 0); -- loop count
 
      SE_o : out std_logic;
      SF_o : out std_logic;
      LBADR_o : out unsigned(ALEN-1 downto 0); -- loop begin address
      LEADR_o : out unsigned(ALEN-1 downto 0); -- loop end address
      LCNT_o : out unsigned(16-1 downto 0) -- loop count
    );
  end component;
 
  type STK_ENTRY_T is record
    LBADR : unsigned(ALEN-1 downto 0);
    LEADR : unsigned(ALEN-1 downto 0);
    LCNT : unsigned(16-1 downto 0);
  end record;
 
  signal PUSH,POP,DECR,SE,SF : std_logic;
  signal LLBRX,LLERX : std_logic;
  signal STK_LBADR : unsigned(ALEN-1 downto 0);
  signal STK_LEADR : unsigned(ALEN-1 downto 0);
  signal STK_LCNT : unsigned(16-1 downto 0);
  signal LBADR_q : unsigned(ALEN-1 downto 0);
  signal LEADR_q : unsigned(ALEN-1 downto 0);
  signal LCNT : unsigned(16-1 downto 0);
  signal PCF_MTCH,PCX_MTCH : std_logic;
 
begin
 
  -- The loop control stack is composed of DEPTH entries, each
  -- one consisting of 3 fields:
  -- 1) loop begin address (specified by llbri instruction)
  -- 2) loop end address (specified by lleri instruction)
  -- 3) loop iterations count (specified by llcnt/llcnti instruction)
 
  -- When a llbri/lleri instruction is executed, the related operand
  -- is saved into a temporary register.
  -- When a llcnt/llcnti instruction is executed, the related operand
  -- plus the saved operands of most recent llbri and lleri instructions
  -- are pushed on the stack.
  -- Note: instruction execution is used to trigger saving/pushing, 
  -- rather than fetching, to avoid issues with instructions laying
  -- in the 'shadow' of a branch/jump.
 
  U_STK : G729A_ASIP_LCSTK
    generic map(
      DEPTH => 2 --DEPTH
    )
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i,
      SRST_i => SRST_i,
      PUSH_i => PUSH,
      POP_i => POP,
      DECR_i => DECR,
      LBADR_i => LBADR_q,
      LEADR_i => LEADR_q,
      LCNT_i => LCNT,
 
      SE_o => SE,
      SF_o => SF,
      LBADR_o => STK_LBADR,
      LEADR_o => STK_LEADR,
      LCNT_o => STK_LCNT
    );
 
  LCNT <= (IMM_i - 1);
 
  -- llbri, lleri and llcr* instructions can issued only to pipe #0.
  LLBRX <= (LLBRX_i and IXV_i(0));
  LLERX <= (LLERX_i and IXV_i(0));
 
  -- IX PC match flag
  PCX_MTCH <= '1' when (
    ((IXV_i(0) = '1') and (PCX0_i = STK_LEADR)) or
    ((IXV_i(1) = '1') and (PCX1_i = STK_LEADR))
  ) else '0';
 
  -- Stack push flag (stack is pushed whenever a llcnt/llcnti
  -- instruction is executed).
 
  PUSH <= LLCRX_i;
 
  -- Stack pop flag (stack is popped whenever loop closing
  -- instruction is executed and loop count is zero). 
 
  POP <= ((not SE) and PCX_MTCH) when (STK_LCNT = 0) else '0'; 
 
  -- loop end
 
  LEND_o <= POP;
 
  LEIS_o <= '1' when ((IXV_i(1) = '1') and (PCX1_i = STK_LEADR) and (STK_LCNT = 0)) else '0';
 
  -- Loop count is decremented when loop closing instruction is executed
 
  DECR <= PCX_MTCH when (STK_LCNT > 0)  else '0'; 
 
  -- loop begin/end address temporary registers
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(LLBRX = '1') then
        LBADR_q <= IMM_i;
      end if;
      if(LLERX = '1') then
        LEADR_q <= IMM_i;
      end if;
    end if;
  end process;
 
  -- IF PC match flag
  PCF_MTCH <= '1' when ((PCF0_i = STK_LEADR) or (PCF1_i = STK_LEADR)) else '0';
 
  -- loop-back flag
  LBX_o <= not(SE) when ((PCF_MTCH = '1') and (STK_LCNT > 0)) else '0';
 
  -- loop-back target address
  LBTA_o <= STK_LBADR;
 
  -- Kill-instruction-in-slot-#1 flag
  KLL1_o <= '1' when (PCF0_i = STK_LEADR) else '0';
 
end ARC;

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.