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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_asip_ftchlog_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 Instruction Fecthing Logic
---------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
 
library work;
use work.G729A_ASIP_PKG.all;
use work.G729A_ASIP_CFG_PKG.all;
 
entity G729A_ASIP_FTCHLOG_2W is
  port(
    CLK_i : in std_logic;
    RST_i : in std_logic;
    STRT_i : in std_logic;
    HALT_i : in std_logic;
    SADR_i : in unsigned(ALEN-1 downto 0);
    BJX_i : in std_logic;
    BJTA_i : in unsigned(ALEN-1 downto 0);
    LBX_i : in std_logic;
    LBTA_i : in unsigned(ALEN-1 downto 0);
    PSTALL_i : in std_logic;
 
    IFV_o : out std_logic_vector(2-1 downto 0);
    IADR0_o : out unsigned(ALEN-1 downto 0);
    IADR1_o : out unsigned(ALEN-1 downto 0);
    BSY_o : out std_logic
  );
end G729A_ASIP_FTCHLOG_2W;
 
architecture ARC of G729A_ASIP_FTCHLOG_2W is
 
  component G729A_ASIP_ADDERU is
    generic(
      WIDTH : integer := 16
    );
    port(
      OPA_i : in unsigned(WIDTH-1 downto 0);
      OPB_i : in unsigned(WIDTH-1 downto 0);
      CI_i : in std_logic;
 
      SUM_o : out unsigned(WIDTH-1 downto 0)
    );
  end component;
 
  component G729A_ASIP_ADDER_F is
    generic(
      LEN1 : integer := 16;
      LEN2 : integer := 16
    );
    port(
      OPA_i : in signed(LEN1+LEN2-1 downto 0);
      OPB_i : in signed(LEN1+LEN2-1 downto 0);
      CI_i : in std_logic;
 
      SUM_o : out signed(LEN1+LEN2-1 downto 0)
    );
  end component;
 
  signal SZERO : unsigned(ALEN-1 downto 0) := (others => '0');
  signal ONE : std_logic := '1';
  signal PC,PC_q : unsigned(ALEN-2 downto 0);
  signal PC_NS : unsigned(ALEN-2 downto 0);
  signal PCP1,PCP1_q : unsigned(ALEN-2 downto 0);
  signal HALT_q : std_logic;
  signal EVEN_PC : std_logic;
  signal EVEN_PC_NS : std_logic;
 
begin
 
  -- Halt flag register
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1' or HALT_i = '1') then
        HALT_q <= '1';
      elsif(STRT_i = '1') then
        HALT_q <= '0';
      end if;
    end if;
  end process;
 
  BSY_o <= not(HALT_q);
 
  -- Fetched instruction #0 is always valid, unless processor is
  -- halted or fetch address is odd.
 
  IFV_o(0) <= (not(HALT_q) or STRT_i) and EVEN_PC;
 
  -- Fetched instruction #1 is always valid, unless processor is
  -- halted.
 
  IFV_o(1) <= (not(HALT_q) or STRT_i);
 
  -- Program Counter register
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        PC_q <= (others => '0');
        PCP1_q <= (1 => '1',others => '0');
      elsif(PC_q < ((IMEM_SIZE/2)-2) or STRT_i = '1') then
        PC_q <= PC;
        PCP1_q <= PCP1;
      end if;
    end if;
  end process;
 
  PCP1 <= PC_NS + 1 when (PSTALL_i = '0') else PCP1_q;
 
  -- Note: a branch/jump in IX stage is older than a loop closing
  -- instruction in IF stage and therefore takes priority over it.
 
  -- PC is a double word address, and therefore is one bit shorter
  -- than actual fetch addresses.
 
  process(STRT_i,BJX_i,BJTA_i,LBX_i,SADR_i,LBTA_i,PCP1_q)
  begin
    if(BJX_i = '1') then -- and PSTALL_i = '0') then
      PC_NS <= BJTA_i(ALEN-1 downto 1);
      EVEN_PC_NS <= not(BJTA_i(0));
    elsif(LBX_i = '1') then --  and PSTALL_i = '0') then
      PC_NS <= LBTA_i(ALEN-1 downto 1);
      EVEN_PC_NS <= not(LBTA_i(0));
    elsif(STRT_i = '1') then
      PC_NS <= SADR_i(ALEN-1 downto 1);
      EVEN_PC_NS <= not(SADR_i(0));
    else
      PC_NS <= PCP1_q;
      EVEN_PC_NS <= '1';
    end if;
  end process;
 
  PC <= PC_NS when (PSTALL_i = '0') else PC_q;
  EVEN_PC <= EVEN_PC_NS when (PSTALL_i = '0') else '1';
 
  -- Fetch addresses
 
  -- instruction #0 address is always an even address, while
  -- instruction #1 address is always an odd one.
 
  IADR0_o <= PC & '0';
  IADR1_o <= PC & '1';
 
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.