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

Subversion Repositories g729a_codec

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

Go to most recent revision | 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 CPU module
---------------------------------------------------------------
 
library IEEE;
use IEEE.std_logic_1164.all;
use IEEE.numeric_std.all;
use STD.textio.all;
 
library work;
use work.G729A_ASIP_PKG.all;
use work.G729A_ASIP_IDEC_2W_PKG.all;
use WORK.G729A_ASIP_BASIC_PKG.all;
use WORK.G729A_ASIP_ARITH_PKG.all;
use WORK.G729A_ASIP_OP_PKG.all;
 
entity G729A_ASIP_CPU_2W is
  generic(
    -- synthesis translate_off
    ST_FILENAME : string := "NONE";
    WB_FILENAME : string := "NONE";
    -- synthesis translate_on
    SIMULATION_ONLY : std_logic := '1'
  );
  port(
    CLK_i : in std_logic;
    RST_i : in std_logic;
    STRT_i : in std_logic;
    SADR_i : in unsigned(ALEN-1 downto 0);
    -- instruction memory interface
    INSTR_i : in std_logic_vector(ILEN*2-1 downto 0); -- two instructions!
    -- data memory interface
    DDAT0_i : in std_logic_vector(SDLEN-1 downto 0);
    DDAT1_i : in std_logic_vector(SDLEN-1 downto 0);
    -- check interface
    CHK_ENB_i : in std_logic;
 
    BSY_o : out std_logic;
    -- instruction memory interface
    IADR_o : out unsigned(ALEN-2 downto 0);
    -- data memory interface
    DRE_o : out std_logic_vector(2-1 downto 0);
    DWE0_o : out std_logic;
    DADR0_o : out unsigned(ALEN-1 downto 0);
    DADR1_o : out unsigned(ALEN-1 downto 0);
    DDAT0_o : out std_logic_vector(SDLEN-1 downto 0)
  );
end G729A_ASIP_CPU_2W;
 
architecture ARC of G729A_ASIP_CPU_2W is
 
  constant LCSTK_DEPTH : natural := 4;
  constant SZERO : SDWORD_T := (others => '0');
  constant LZERO : LDWORD_T := (others => '0');
 
  constant NW : natural := 2;
  constant NWX2M1 : natural := NW*2-1;
 
  component 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(16-1 downto 0); -- loop count
      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); -- IX1 program counter
      PCX1_i : in unsigned(ALEN-1 downto 0); -- IX1 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 component;
 
  component 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 component;
 
  component G729A_ASIP_IFQ is
    port(
      CLK_i : in std_logic;
      RST_i : in std_logic;
      ID_HALT_i : in std_logic;
      IX_BJX_i : in std_logic;
      ID_ISSUE_i : in std_logic_vector(2-1 downto 0);
      IF_V_i : in std_logic_vector(2-1 downto 0);
      IF_PC0_i : in unsigned(ALEN-1 downto 0);
      IF_PC1_i : in unsigned(ALEN-1 downto 0);
      IF_INSTR0_i : in std_logic_vector(ILEN-1 downto 0);
      IF_INSTR1_i : in std_logic_vector(ILEN-1 downto 0);
      IF_DEC_INSTR0_i : in DEC_INSTR_T;
      IF_DEC_INSTR1_i : in DEC_INSTR_T;
      IF_IMM0_i : in std_logic;
      IF_IMM1_i : in std_logic;
      IF_OPB0_i : in LDWORD_T;
      IF_OPB1_i : in LDWORD_T;
 
      PSTALL_o : out std_logic;
      ID_V_o : out std_logic_vector(2-1 downto 0);
      ID_PC0_o : out unsigned(ALEN-1 downto 0);
      ID_PC1_o : out unsigned(ALEN-1 downto 0);
      ID_INSTR0_o : out std_logic_vector(ILEN-1 downto 0);
      ID_INSTR1_o : out std_logic_vector(ILEN-1 downto 0);
      ID_DEC_INSTR0_o : out DEC_INSTR_T;
      ID_DEC_INSTR1_o : out DEC_INSTR_T;
      ID_IMM0_o : out std_logic;
      ID_IMM1_o : out std_logic;
      ID_OPB0_o : out LDWORD_T;
      ID_OPB1_o : out LDWORD_T
    );
  end component;
 
  component G729A_ASIP_IDEC1_2W is
    port(
      INSTR_i : in std_logic_vector(ILEN-1 downto 0);
 
      OPB_IMM_o : out std_logic;
      OPB_o : out LDWORD_T;
      DEC_INSTR_o : out DEC_INSTR_T
    );
  end component;
 
  component G729A_ASIP_IDEC2 is
    port(
      INSTR_i : in std_logic_vector(ILEN-1 downto 0);
      DRA_i : in std_logic_vector(LDLEN-1 downto 0);
      DRB_i : in std_logic_vector(LDLEN-1 downto 0);
      PCP1_i : in std_logic_vector(ALEN-1 downto 0);
      OPB_IMM_i : in std_logic;
      OPB_i : in LDWORD_T;
      ID_V_i : in std_logic;
 
      OPA_o : out LDWORD_T;
      OPB_o : out LDWORD_T;
      OPC_o : out SDWORD_T;
      IMM_o : out SDWORD_T;
      JL_o : out std_logic;
      HALT_o : out std_logic
    );
  end component;
 
  component G729A_ASIP_PSTLLOG_2W is
    generic(
      SIMULATION_ONLY : std_logic := '0'
    );
    port(
      CLK_i : in std_logic;
      ID_INSTR_i : in DEC_INSTR_T;
      ID_V_i : in std_logic;
      IX1_INSTR0_i : in DEC_INSTR_T;
      IX1_INSTR1_i : in DEC_INSTR_T;
      IX1_V_i : in std_logic_vector(2-1 downto 0);
      IX1_FWDE_i : in std_logic_vector(2-1 downto 0);
      IX2_INSTR0_i : in DEC_INSTR_T;
      IX2_INSTR1_i : in DEC_INSTR_T;
      IX2_V_i : in std_logic_vector(2-1 downto 0);
      IX2_FWDE_i : in std_logic_vector(2-1 downto 0);
 
      PSTALL_o : out std_logic
    );
  end component;
 
  component G729A_ASIP_PSTLLOG_2W_P6 is
    generic(
      SIMULATION_ONLY : std_logic := '0'
    );
    port(
      CLK_i : in std_logic;
      ID_INSTR_i : in DEC_INSTR_T;
      ID_V_i : in std_logic;
      IX1_INSTR0_i : in DEC_INSTR_T;
      IX1_INSTR1_i : in DEC_INSTR_T;
      IX1_V_i : in std_logic_vector(2-1 downto 0);
      IX1_FWDE_i : in std_logic_vector(2-1 downto 0);
      IX2_INSTR0_i : in DEC_INSTR_T;
      IX2_INSTR1_i : in DEC_INSTR_T;
      IX2_V_i : in std_logic_vector(2-1 downto 0);
      IX2_FWDE_i : in std_logic_vector(2-1 downto 0);
      IX3_INSTR0_i : in DEC_INSTR_T;
      IX3_INSTR1_i : in DEC_INSTR_T;
      IX3_V_i : in std_logic_vector(2-1 downto 0);
      IX3_FWDE_i : in std_logic_vector(2-1 downto 0);
 
      PSTALL_o : out std_logic
    );
  end component;
 
  component G729A_ASIP_PXLOG is
    port(
      ID_INSTR0_i : in DEC_INSTR_T;
      ID_INSTR1_i : in DEC_INSTR_T;
      ID_V_i : in std_logic_vector(2-1 downto 0);
      ID_FWDE_i : in std_logic_vector(2-1 downto 0);
 
      PXE1_o : out std_logic
    );
  end component;
 
 
  component G729A_ASIP_PIPE_A_DEC_2W is
    port(
      INSTR_i : in DEC_INSTR_T;
 
      FWDE_o : out std_logic;
      SEL_o :  out std_logic_vector(7-1 downto 0)
    );
  end component;
 
  component G729A_ASIP_FWDLOG_2W is
    port(
      ID_RX_i : in RID_T;
      ID_RRX_i : in std_logic;
      IX1_INSTR0_i : in DEC_INSTR_T;
      IX2_INSTR0_i : in DEC_INSTR_T;
      IX1_INSTR1_i : in DEC_INSTR_T;
      IX2_INSTR1_i : in DEC_INSTR_T;
      IX1_PA_RES0_i : in SDWORD_T;
      IX1_PA_RES1_i : in SDWORD_T;
      IX2_PA_RES0_i : in LDWORD_T;
      IX2_PA_RES1_i : in LDWORD_T;
      ID_OPX_NOFWD_i : in LDWORD_T;
      IX1_V_i : in std_logic_vector(2-1 downto 0);
      IX2_V_i : in std_logic_vector(2-1 downto 0);
      IX1_FWDE_i : in std_logic_vector(2-1 downto 0);
      IX2_FWDE_i : in std_logic_vector(2-1 downto 0);
 
      ID_OPX_o : out LDWORD_T
    );
  end component;
 
  component G729A_ASIP_FWDLOG_2W_P6 is
    port(
      ID_RX_i : in RID_T;
      ID_RRX_i : in std_logic;
      IX1_INSTR0_i : in DEC_INSTR_T;
      IX2_INSTR0_i : in DEC_INSTR_T;
      IX3_INSTR0_i : in DEC_INSTR_T;
      IX1_INSTR1_i : in DEC_INSTR_T;
      IX2_INSTR1_i : in DEC_INSTR_T;
      IX3_INSTR1_i : in DEC_INSTR_T;
      IX1_PA_RES0_i : in SDWORD_T;
      IX1_PA_RES1_i : in SDWORD_T;
      IX2_PA_RES0_i : in LDWORD_T;
      IX2_PA_RES1_i : in LDWORD_T;
      IX3_PA_RES0_i : in LDWORD_T;
      IX3_PA_RES1_i : in LDWORD_T;
      ID_OPX_NOFWD_i : in LDWORD_T;
      IX1_V_i : in std_logic_vector(2-1 downto 0);
      IX2_V_i : in std_logic_vector(2-1 downto 0);
      IX3_V_i : in std_logic_vector(2-1 downto 0);
      IX1_FWDE_i : in std_logic_vector(2-1 downto 0);
      IX2_FWDE_i : in std_logic_vector(2-1 downto 0);
      IX3_FWDE_i : in std_logic_vector(2-1 downto 0);
      NOREGS_i : in std_logic;
      NOREGD_i : in LDWORD_T;
 
      ID_OPX_o : out LDWORD_T
    );
  end component;
 
  component G729A_ASIP_PIPE_A_2W is
    port(
      CLK_i : in std_logic;
      SEL_i :  in std_logic_vector(7-1 downto 0);
      OPA_i : in SDWORD_T;
      OPB_i : in SDWORD_T;
      ACC_i : in LDWORD_T;
      LDAT_i : in std_logic_vector(SDLEN-1 downto 0);
 
      RES_1C_o : out SDWORD_T; --  port #0 1-cycle result
      RES_o : out LDWORD_T; -- port #0 result
      ACC_o : out LDWORD_T; -- updated accumulator
      OVF_o : out std_logic -- port #0 overflow flag
    );
  end component;
 
  component G729A_ASIP_PIPE_B is
    port(
      CLK_i : in std_logic;
      OP_i :  in ALU_OP_T;
      OPA_i : in LDWORD_T;
      OPB_i : in LDWORD_T;
      OVF_i : in std_logic;
      ACC_i : in LDWORD_T;
 
      RES_o : out LDWORD_T;
      OVF_o : out std_logic
    );
  end component;
 
  component G729A_ASIP_BJXLOG is
    port(
      CLK_i : in std_logic;
      RST_i : in std_logic;
      BJ_OP : in BJ_OP_T;
      PC0P1_i : in unsigned(ALEN-1 downto 0);
      PC1P1_i : in unsigned(ALEN-1 downto 0);
      PC0_i : in unsigned(ALEN-1 downto 0);
      PCSEL_i : in std_logic;
      OPA_i : in LDWORD_T;
      OPB_i : in LDWORD_T;
      OPC_i : in SDWORD_T;
      IV_i : in std_logic;
      LLCRX_i : in std_logic;
      FSTLL_i : in std_logic;
 
      BJX_o : out std_logic;
      BJTA_o : out unsigned(ALEN-1 downto 0)
    );
  end component;
 
  component G729A_ASIP_LSU is
    port(
      IV_i : in std_logic;
      LS_OP_i : in LS_OP_T;
      OPA_i : in LDWORD_T;
      OPB_i : in LDWORD_T;
      OPC_i : in SDWORD_T;
 
      DRE_o : out std_logic;
      DWE_o : out std_logic;
      DADR_o : out unsigned(ALEN-1 downto 0);
      DDAT_o : out std_logic_vector(SDLEN-1 downto 0)
    );
  end component;
 
  component G729A_ASIP_LU is
    port(
      IV_i : in std_logic;
      LS_OP_i : in LS_OP_T;
      OPA_i : in LDWORD_T;
      OPB_i : in LDWORD_T;
 
      DRE_o : out std_logic;
      DADR_o : out unsigned(ALEN-1 downto 0)
    );
  end component;
 
  component G729A_ASIP_LCSTKLOG_IX is
    port(
      IX_V_i : in std_logic;
      IX_INSTR_i : in DEC_INSTR_T;
      IX_OPA_i : in LDWORD_T;
 
      SRST_o : out std_logic;
      LLBRX_o : out std_logic; -- llbri eXecute flag
      LLERX_o : out std_logic; -- lleri eXecute flag
      LLCRX_o : out std_logic; -- llcnt/llcnti eXecute flag
      IMM_o : out unsigned(ALEN-1 downto 0) -- loop count
    );
  end component;
 
  component G729A_ASIP_REGFILE_16X16_2W is
    port(
      CLK_i : in std_logic;
      RA0_i : in RID_T;
      RA1_i : in RID_T;
      RA2_i : in RID_T;
      RA3_i : in RID_T;
      WA0_i : in RID_T;
      WA1_i : in RID_T;
      LR0_i : in std_logic;
      LR1_i : in std_logic;
      LR2_i : in std_logic;
      LR3_i : in std_logic;
      LW0_i : in std_logic;
      LW1_i : in std_logic;
      WE0_i : in std_logic;
      WE1_i : in std_logic;
      D0_i : in std_logic_vector(LDLEN-1 downto 0);
      D1_i : in std_logic_vector(LDLEN-1 downto 0);
 
      Q0_o : out std_logic_vector(LDLEN-1 downto 0);
      Q1_o : out std_logic_vector(LDLEN-1 downto 0);
      Q2_o : out std_logic_vector(LDLEN-1 downto 0);
      Q3_o : out std_logic_vector(LDLEN-1 downto 0)
    );
  end component;
 
  component G729A_ASIP_STATS is
    port(
      CLK_i : in std_logic;
      RST_i : in std_logic;
      ID_V_i : in std_logic_vector(2-1 downto 0);
      ID_PS_i : in std_logic_vector(2-1 downto 0);
      ID_PXE1_i : std_logic;
      IX2_V_i : in std_logic_vector(2-1 downto 0);
      STRT_i : in std_logic;
      HALT_i : in std_logic
    );
  end component;
 
  function to_unsigned(S : signed) return unsigned is
    variable U : unsigned(S'high downto S'low);
  begin
    for i in S'low to S'high loop
      U(i) := S(i);
    end loop;
    return(U);
  end function;
 
  function to_signed(U : unsigned) return signed is
    variable S : signed(U'high downto U'low);
  begin
    for i in U'low to U'high loop
      S(i) := U(i);
    end loop;
    return(S);
  end function;
 
  function EXTS16(V : std_logic_vector) return signed is
    variable S : signed(SDLEN-1 downto 0);
  begin
    S(V'HIGH downto 0) := to_signed(V);
    S(SDLEN-1 downto V'HIGH+1) := (others => V(V'HIGH));
    return(S);
  end function;
 
  function EXTS32(S : signed) return signed is
    variable XS : signed(LDLEN-1 downto 0);
  begin
    XS(S'HIGH downto 0) := S;
    XS(LDLEN-1 downto S'HIGH+1) := (others => S(S'HIGH));
    return(XS);
  end function;
 
  type DEC_INSTR_VEC_T is array (natural range<>) of DEC_INSTR_T;
  type LDWORD_VEC_T is array (natural range<>) of LDWORD_T;
  subtype ADR_T is unsigned(ALEN-1 downto 0);
  type ADR_VEC_T is array (natural range<>) of ADR_T;
 
  signal ZERO : std_logic := '0';
  signal ONE : std_logic := '1';
 
  signal IF_INSTR0,IF_INSTR1 : std_logic_vector(ILEN-1 downto 0);
  signal IF_INSTR_q : std_logic_vector(ILEN*NW-1 downto 0);
  signal IF_V,IF_V_q : std_logic_vector(NW-1 downto 0);
  signal IF_V_KLL1 : std_logic_vector(NW-1 downto 0);
  signal IF_V_q2 : std_logic_vector(NW-1 downto 0);
  signal IF_PC0,IF_PC1 : ADR_T;
  signal IF_PC_q : ADR_VEC_T(NW-1 downto 0);
  signal IF_PC_q2 : ADR_VEC_T(NW-1 downto 0);
  signal IF_KLL1 : std_logic;
  signal IF_LBX : std_logic;
  signal IF_LBTA : unsigned(ALEN-1 downto 0);
  signal IF_DEC_INSTR0,IF_DEC_INSTR1 : DEC_INSTR_T;
  signal IF_DEC_INSTR_q : DEC_INSTR_VEC_T(NW-1 downto 0);
  signal IF_OPB_IMM0,IF_OPB_IMM1 : std_logic;
  signal IF_OPB_IMM_q : std_logic_vector(NW-1 downto 0);
  signal IF_OPB0,IF_OPB1 : LDWORD_T;
  signal IF_OPB_q : LDWORD_VEC_T(NW-1 downto 0);
 
  signal ID_INSTR0,ID_INSTR1 : DEC_INSTR_T;
  signal ID_INSTR_q : DEC_INSTR_VEC_T(NW-1 downto 0);
  signal ID_IMM0,ID_IMM1 : signed(SDLEN-1 downto 0);
  signal ID_V,ID_V_q : std_logic_vector(NW-1 downto 0);
  signal ID_ISSUE : std_logic_vector(NW-1 downto 0);
  signal ID_PC_q : ADR_VEC_T(NW-1 downto 0);
  signal ID_PCP1_q : ADR_VEC_T(NW-1 downto 0);
  signal ID_OPA0,ID_OPA0_q : LDWORD_T;
  signal ID_OPB0,ID_OPB0_q : LDWORD_T;
  signal ID_OPA1,ID_OPA1_q : LDWORD_T;
  signal ID_OPB1,ID_OPB1_q : LDWORD_T;
  signal ID_OPC0,ID_OPC0_q : SDWORD_T;
  signal ID_HALT0,ID_HALT1,ID_HALT : std_logic;
  signal ID_PSTALL : std_logic;
  signal ID_PS0,ID_PS1 : std_logic;
  signal ID_PXE1 : std_logic;
  signal ID_JLRA0,ID_JLRA1 : unsigned(ALEN-1 downto 0);
  signal ID_JLRA0_S,ID_JLRA1_S : LDWORD_T;
  signal ID_FWDE : std_logic_vector(NW-1 downto 0);
  signal ID_FWDE_q : std_logic_vector(NW-1 downto 0);
  signal ID_PASEL0,ID_PASEL1 :  std_logic_vector(7-1 downto 0);
  signal ID_PASEL0_q,ID_PASEL1_q :  std_logic_vector(7-1 downto 0);
  signal ID_JL0,ID_JL1 : std_logic;
 
  signal IX1_INSTR0_q,IX1_INSTR1_q : DEC_INSTR_T;
  signal IX1_SRST : std_logic;
  signal IX1_LLBR,IX1_LLER,IX1_LLCR : std_logic;
  signal IX1_BJX : std_logic;
  signal IX1_BJTA : unsigned(ALEN-1 downto 0);
  signal IX1_IMM : unsigned(ALEN-1 downto 0);
  signal IX1_ALUV : std_logic;
  signal IX1_ALUOVF : std_logic;
  signal IX1_LDV : std_logic;
  signal IX1_DWE : std_logic;
  signal IX1_DDATO : std_logic_vector(SDLEN-1 downto 0);
  signal IX1_DADR : unsigned(ALEN-1 downto 0);
  signal UNUSED1 : std_logic := '0';
  signal IX1_MC : MUL_CTRL;
  signal IX1_V,IX1_V_q : std_logic_vector(NW-1 downto 0);
  signal IX1_FWDE_q : std_logic_vector(NW-1 downto 0);
  signal IX1_PA0_RES : SDWORD_T;
  signal IX1_PA1_RES : SDWORD_T;
  signal IX1_LEND : std_logic;
  signal IX1_LEIS : std_logic;
  signal IX1_PCLN : std_logic;
  signal IX1_PCLN_PC : unsigned(ALEN-1 downto 0);
 
  signal IX2_OVF0 : std_logic;
  signal IX2_OVF1 : std_logic;
  signal IX2_DRD0,IX2_DRD1 : signed(LDLEN-1 downto 0);
  signal IX2_PA0_RES : LDWORD_T;
  signal IX2_PA1_RES : LDWORD_T;
  signal IX2_PA0_OVF : std_logic;
  signal IX2_PA1_OVF : std_logic;
  signal IX2_PB0_RES : LDWORD_T;
  signal IX2_PB0_OVF : std_logic;
 
  signal IX2_INSTR0_q,IX2_INSTR1_q : DEC_INSTR_T;
  signal IX2_DRD0_q,IX2_DRD1_q : signed(LDLEN-1 downto 0);
  signal IX3_DRD0,IX3_DRD1 : signed(LDLEN-1 downto 0);
  signal IX2_OVF0_q,IX2_OVF1_q : std_logic;
  signal IX3_OVF0,IX3_OVF1 : std_logic;
  signal IX2_V_q : std_logic_vector(NW-1 downto 0);
  signal IX2_FWDE : std_logic_vector(NW-1 downto 0);
  signal IX2_FWDE_q : std_logic_vector(NW-1 downto 0);
 
  signal WB_WE0,WB_WE1 : std_logic;
  signal WB_WA1 : RID_T;
  signal WB_RDA0,WB_RDB0 : std_logic_vector(LDLEN-1 downto 0);
  signal WB_RDA1,WB_RDB1 : std_logic_vector(LDLEN-1 downto 0);
  signal WB_OVF,WB_OVF_q : std_logic;
  signal WB_ACC_q : signed(LDLEN-1 downto 0);
  signal WB_PXE_q : std_logic;
 
  -- debug-only signals
 
  component G729A_ASIP_ST_CHECKER is
    generic(
      ST_FILENAME : string := "NONE"
    );
    port(
      CLK_i : in std_logic;
    ENB_i : in std_logic;
      DWE_i : in std_logic;
      DADR_i : in unsigned(ALEN-1 downto 0);
      DDATO_i : in std_logic_vector(SDLEN-1 downto 0)
    );
  end component;
 
  component G729A_ASIP_WB_CHECKER is
    generic(
      WB_FILENAME : string := "NONE"
    );
    port(
      CLK_i : in std_logic;
      ENB_i : in std_logic;
      WE0_i : in std_logic;
      WE1_i : in std_logic;
      IX_INSTR0_i : in DEC_INSTR_T; 
      IX_INSTR1_i : in DEC_INSTR_T;
      IX_DRD0_i : in LDWORD_T;
      IX_DRD1_i : in LDWORD_T 
    );
  end component;
 
begin
 
  ----------------------------------------------------
  -- Notes:
  ----------------------------------------------------
 
  -- *** Pipeline ***
  -- ASIP employs the following 7-stage pipeline:
  -- 1) Instruction Fetch (IF1)
  -- 2) Instruction Fetch (IF2)
  -- 3) Instruction Decode (ID)
  -- 4) Instruction Execute (IX1)
  -- 5) Instruction Execute (IX2)
  -- 6) Instruction Execute (IX3)
  -- 7) Write Back (WB)
 
  -- *** Branch processing ***
  -- There's no branch prediction: branches are processed
  -- in IX1 stage, like other instructions, as a consequence
  -- there's a fixed branch penalty of 2 cycles.
 
  -- *** Loop Control Stack management ***
  -- 1) Loop control stack is pushed when a llcnt/llcnti
  -- instruction enters IX1 stage. 
  -- 2) Loop count is decremented
  -- every time the first loop instruction enters IX1 stage.
  -- 3) loop-back implicit jump is performed when last
  -- loop instruction is fetched, in order to avoid the
  -- 2-cycle penalty imposed by the pipeline. First/last
  -- loop instruction CAN'T be a conditionally executed
  -- instruction!
 
  ----------------------------------------------------
  -- IF1 Stage:
  ----------------------------------------------------
 
  -- Loop Control Stack Logic
 
  U_LCSTK : G729A_ASIP_LCSTKLOG_2W
    generic map(
      DEPTH => LCSTK_DEPTH
    )
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i,
      SRST_i => IX1_SRST,
      LLBRX_i => IX1_LLBR,
      LLERX_i => IX1_LLER,
      LLCRX_i => IX1_LLCR,
      IMM_i => IX1_IMM,
      PCF0_i => IF_PC_q(0),
      PCF1_i => IF_PC_q(1),
      PCX0_i => ID_PC_q(0),
      PCX1_i => ID_PC_q(1),
      IXV_i => ID_V_q,
 
      KLL1_o => IF_KLL1,
      LEND_o => IX1_LEND,
      LEIS_o => IX1_LEIS,
      LBX_o => IF_LBX,
      LBTA_o => IF_LBTA
    );
 
  -- Instruction Fetch Logic 
 
  -- This logic fetches instruction pairs, so that
  -- fetch address LSb is always zero
 
  U_FTCH : G729A_ASIP_FTCHLOG_2W
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i,
      STRT_i => STRT_i,
      HALT_i => ID_HALT,
      SADR_i => SADR_i,
      BJX_i => IX1_BJX,
      BJTA_i => IX1_BJTA,
      LBX_i => IF_LBX,
      LBTA_i => IF_LBTA,
      PSTALL_i => ID_PSTALL,
 
      IFV_o => IF_V,
      IADR0_o => IF_PC0,
      IADR1_o => IF_PC1,
      BSY_o => BSY_o
    );
 
  -- Instruction memory address is a two-word address and
  -- therefore is one bit-shorter than individual instruction
  -- addresses.
 
  IADR_o <= IF_PC0(ALEN-1 downto 1);
 
  -- Pipeline Registers
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
 
      if(RST_i = '1') then
        IF_V_q <= "00";
      elsif(ID_HALT = '1') then
        IF_V_q <= "00";
      elsif(ID_PSTALL = '0') then
        IF_V_q <= IF_V;
      end if;
 
      IF_PC_q(0) <= IF_PC0;
      IF_PC_q(1) <= IF_PC1;
 
    end if;
  end process;
 
  ----------------------------------------------------
  -- IF2 Stage
  ----------------------------------------------------
 
  -- Split instruction memory output into two individual instructions
 
  IF_INSTR0 <= INSTR_i(ILEN*1-1 downto ILEN*0);
  IF_INSTR1 <= INSTR_i(ILEN*2-1 downto ILEN*1);
 
  -- Pre-decode individual instructions
 
  U_IDEC10 : G729A_ASIP_IDEC1_2W
    port map(
      INSTR_i => IF_INSTR0,
 
      OPB_IMM_o => IF_OPB_IMM0,
      OPB_o => IF_OPB0,
      DEC_INSTR_o => IF_DEC_INSTR0
    );
 
  U_IDEC11 : G729A_ASIP_IDEC1_2W
    port map(
      INSTR_i => IF_INSTR1,
 
      OPB_IMM_o => IF_OPB_IMM1,
      OPB_o => IF_OPB1,
      DEC_INSTR_o => IF_DEC_INSTR1
    );
 
  -- IF2 stage instruction valid flags (accounting for KILL flag).
  -- Instruction slot #1 gets "killed" (invalidated) if slot #0
  -- instruction is a B/J one.
 
  IF_V_KLL1 <= ((IF_V_q(1) and not (IF_KLL1 and IF_LBX)) & IF_V_q(0));
 
  -- Instruction queue
 
  -- Note: IFQ includes pipeline registers between IF2 and ID stages.
 
  U_IFQ : G729A_ASIP_IFQ
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i,
      ID_HALT_i => ID_HALT,
      IX_BJX_i => IX1_BJX,
      ID_ISSUE_i => ID_ISSUE, 
      IF_V_i => IF_V_KLL1, --IF_V_q,
      IF_PC0_i => IF_PC_q(0),
      IF_PC1_i => IF_PC_q(1),
      IF_INSTR0_i => IF_INSTR0,
      IF_INSTR1_i => IF_INSTR1,
      IF_DEC_INSTR0_i => IF_DEC_INSTR0,
      IF_DEC_INSTR1_i => IF_DEC_INSTR1,
      IF_IMM0_i => IF_OPB_IMM0,
      IF_IMM1_i => IF_OPB_IMM1,
      IF_OPB0_i => IF_OPB0,
      IF_OPB1_i => IF_OPB1,
 
      PSTALL_o => ID_PSTALL,
      ID_V_o => IF_V_q2,
      ID_PC0_o => IF_PC_q2(0),
      ID_PC1_o => IF_PC_q2(1),
      ID_INSTR0_o => IF_INSTR_q(ILEN*1-1 downto ILEN*0),
      ID_INSTR1_o => IF_INSTR_q(ILEN*2-1 downto ILEN*1),
      ID_DEC_INSTR0_o => IF_DEC_INSTR_q(0),
      ID_DEC_INSTR1_o => IF_DEC_INSTR_q(1),
      ID_IMM0_o => IF_OPB_IMM_q(0),
      ID_IMM1_o => IF_OPB_IMM_q(1),
      ID_OPB0_o => IF_OPB_q(0),
      ID_OPB1_o => IF_OPB_q(1)
    );
 
  ----------------------------------------------------
  -- ID Stage
  ----------------------------------------------------
 
  -- jump & link instructions return address
 
  ID_JLRA0 <= IF_PC_q2(1);
  ID_JLRA1 <= (IF_PC_q2(1) + 1);
 
  -- If there's a taken branch, or a jump, in IX1,
  -- instructions in ID are nullified.
 
  ID_V(0) <= IF_V_q2(0) and not(IX1_BJX) and ID_ISSUE(0);
  ID_V(1) <= IF_V_q2(1) and not(IX1_BJX) and ID_ISSUE(1);
 
  -- Instruction Decoder
 
  U_IDEC20 : G729A_ASIP_IDEC2
    port map(
      INSTR_i => IF_INSTR_q(ILEN*1-1 downto ILEN*0),
      DRA_i => WB_RDA0,
      DRB_i => WB_RDB0,
      PCP1_i => to_std_logic_vector(ID_JLRA0),
      OPB_IMM_i => IF_OPB_IMM_q(0),
      OPB_i => IF_OPB_q(0),
      ID_V_i => ID_V(0),
 
      OPA_o => open, --ID_OPA0_NOFWD,
      OPB_o => open, --ID_OPB0_NOFWD,
      OPC_o => ID_OPC0,
      IMM_o => ID_IMM0,
      JL_o => ID_JL0,
      HALT_o => ID_HALT0
    );
 
  U_IDEC21 : G729A_ASIP_IDEC2
    port map(
      INSTR_i => IF_INSTR_q(ILEN*2-1 downto ILEN*1),
      DRA_i => WB_RDA1,
      DRB_i => WB_RDB1,
      PCP1_i => to_std_logic_vector(ID_JLRA1),
      OPB_IMM_i => IF_OPB_IMM_q(1),
      OPB_i => IF_OPB_q(1),
      ID_V_i => ID_V(1),
 
      OPA_o => open, --ID_OPA1_NOFWD,
      OPB_o => open, --ID_OPB1_NOFWD,
      OPC_o => open, --ID_OPC1,
      IMM_o => ID_IMM1,
      JL_o => ID_JL1,
      HALT_o => ID_HALT1
    );
 
  -- execution must be halted if either instr. #0 or instr. #1 is a halt
  ID_HALT <= (ID_HALT0 or ID_HALT1);
 
  -- update decoded instr. immediate field
 
  process(IF_DEC_INSTR_q,ID_IMM0,ID_IMM1)
    variable TMP : DEC_INSTR_T;
  begin
 
    TMP := IF_DEC_INSTR_q(0);
    TMP.IMM := ID_IMM0;
    ID_INSTR0 <= TMP;
 
    TMP := IF_DEC_INSTR_q(1);
    TMP.IMM := ID_IMM1;
    ID_INSTR1 <= TMP;
 
  end process;
 
  -- Pipeline stall logic
 
  U_PSTL0 : G729A_ASIP_PSTLLOG_2W_P6
    generic map(
      SIMULATION_ONLY => '1'
    )
    port map(
      CLK_i => CLK_i,
      ID_INSTR_i => ID_INSTR0,
      ID_V_i => IF_V_q2(0),
      IX1_INSTR0_i => ID_INSTR_q(0),
      IX1_INSTR1_i => ID_INSTR_q(1),
      IX1_V_i => ID_V_q,
      IX1_FWDE_i => ID_FWDE_q,
      IX2_INSTR0_i => IX1_INSTR0_q,
      IX2_INSTR1_i => IX1_INSTR1_q,
      IX2_V_i => IX1_V_q,
      IX2_FWDE_i => IX1_FWDE_q,
      IX3_INSTR0_i => IX2_INSTR0_q,
      IX3_INSTR1_i => IX2_INSTR1_q,
      IX3_V_i => IX2_V_q,
      IX3_FWDE_i => IX2_FWDE_q,
 
      PSTALL_o => ID_PS0
    );
 
  U_PSTL1 : G729A_ASIP_PSTLLOG_2W_P6
    generic map(
      SIMULATION_ONLY => '1'
    )
    port map(
      CLK_i => CLK_i,
      ID_INSTR_i => ID_INSTR1,
      ID_V_i => IF_V_q2(1),
      IX1_INSTR0_i => ID_INSTR_q(0),
      IX1_INSTR1_i => ID_INSTR_q(1),
      IX1_V_i => ID_V_q,
      IX1_FWDE_i => ID_FWDE_q,
      IX2_INSTR0_i => IX1_INSTR0_q,
      IX2_INSTR1_i => IX1_INSTR1_q,
      IX2_V_i => IX1_V_q,
      IX2_FWDE_i => IX1_FWDE_q,
      IX3_INSTR0_i => IX2_INSTR0_q,
      IX3_INSTR1_i => IX2_INSTR1_q,
      IX3_V_i => IX2_V_q,
      IX3_FWDE_i => IX2_FWDE_q,
 
      PSTALL_o => ID_PS1
    );
 
  -- Parallel eXecution logic
 
  U_PXLOG : G729A_ASIP_PXLOG
    port map(
      ID_INSTR0_i => IF_DEC_INSTR_q(0), 
      ID_INSTR1_i => IF_DEC_INSTR_q(1), 
      ID_V_i => IF_V_q2(2-1 downto 0),
      ID_FWDE_i => ID_FWDE, 
 
      PXE1_o => ID_PXE1
    );
 
  -- Instruction issue flags
 
  -- instr. #0 is issued if there's no stall due to a data dependency.
 
  ID_ISSUE(0) <=
     not(ID_PS0); -- instr. #0 can be issued
 
  -- instr. #1 is issued if:
  -- 1) there's no stall due to data dependency AND
  -- 2) isntr. #0 is isseud too (in-order issue rule)
  -- AND instr #1 can execute in parallel with instr. #1.
 
  --ID_ISSUE(1) <= 
  --   not(ID_PS1) and -- instr. #1 can be issued
  --   not(ID_PS0) and -- instr. #0 is issued too (in-order issue)
  --   ID_PXE1 and  -- instr. #1 can execute in parallel with #0
  --   WB_PXE_q; -- parallel execution is enabled
 
  -- ...same code of above, but restructured to improve timing.
  ID_ISSUE(1) <= (ID_PXE1 and WB_PXE_q) when
    (ID_PS1 = '0' and ID_PS0 = '0') else '0';
 
  -- Extend Jump & Link instruction return address to 32 bits.
  ID_JLRA0_S <= EXTS32(to_signed(ID_JLRA0));
  ID_JLRA1_S <= EXTS32(to_signed(ID_JLRA1));
 
  -- Instruction #0 Operand A forward logic
 
  U_FWDLOGA0 : G729A_ASIP_FWDLOG_2W_P6
    port map(
      ID_RX_i => ID_INSTR0.RA,
      ID_RRX_i => ID_INSTR0.RRA,
      IX1_INSTR0_i => ID_INSTR_q(0),
      IX2_INSTR0_i => IX1_INSTR0_q,
      IX3_INSTR0_i => IX2_INSTR0_q,
      IX1_INSTR1_i => ID_INSTR_q(1),
      IX2_INSTR1_i => IX1_INSTR1_q,
      IX3_INSTR1_i => IX2_INSTR1_q,
      IX1_PA_RES0_i => IX1_PA0_RES, 
      IX1_PA_RES1_i => IX1_PA1_RES,
      IX2_PA_RES0_i => IX2_PA0_RES,
      IX2_PA_RES1_i => IX2_PA1_RES,
      IX3_PA_RES0_i => IX3_DRD0,
      IX3_PA_RES1_i => IX3_DRD1,
      ID_OPX_NOFWD_i => to_signed(WB_RDA0), --ID_OPA0_NOFWD,
      IX1_V_i => ID_V_q,
      IX2_V_i => IX1_V_q,
      IX3_V_i => IX2_V_q,
      IX1_FWDE_i => ID_FWDE_q,
      IX2_FWDE_i => IX1_FWDE_q,
      IX3_FWDE_i => IX2_FWDE_q,
      NOREGS_i => ID_JL0,
      NOREGD_i => ID_JLRA0_S,
 
      ID_OPX_o => ID_OPA0
    );
 
  -- Instruction #1 Operand A forward logic
 
  U_FWDLOGA1 : G729A_ASIP_FWDLOG_2W_P6
    port map(
      ID_RX_i => ID_INSTR1.RA,
      ID_RRX_i => ID_INSTR1.RRA,
      IX1_INSTR0_i => ID_INSTR_q(0),
      IX2_INSTR0_i => IX1_INSTR0_q,
      IX3_INSTR0_i => IX2_INSTR0_q,
      IX1_INSTR1_i => ID_INSTR_q(1),
      IX2_INSTR1_i => IX1_INSTR1_q,
      IX3_INSTR1_i => IX2_INSTR1_q,
      IX1_PA_RES0_i => IX1_PA0_RES, 
      IX1_PA_RES1_i => IX1_PA1_RES,
      IX2_PA_RES0_i => IX2_PA0_RES,
      IX2_PA_RES1_i => IX2_PA1_RES,
      IX3_PA_RES0_i => IX3_DRD0,
      IX3_PA_RES1_i => IX3_DRD1,
      ID_OPX_NOFWD_i => to_signed(WB_RDA1), --ID_OPA1_NOFWD,
      IX1_V_i => ID_V_q,
      IX2_V_i => IX1_V_q,
      IX3_V_i => IX2_V_q,
      IX1_FWDE_i => ID_FWDE_q,
      IX2_FWDE_i => IX1_FWDE_q,
      IX3_FWDE_i => IX2_FWDE_q,
      NOREGS_i => ID_JL1,
      NOREGD_i => ID_JLRA1_S,
 
      ID_OPX_o => ID_OPA1
    );
 
  -- Instruction #0 Operand B forward logic
 
  U_FWDLOGB0 : G729A_ASIP_FWDLOG_2W_P6
    port map(
      ID_RX_i => ID_INSTR0.RB,
      ID_RRX_i => ID_INSTR0.RRB,
      IX1_INSTR0_i => ID_INSTR_q(0),
      IX2_INSTR0_i => IX1_INSTR0_q,
      IX3_INSTR0_i => IX2_INSTR0_q,
      IX1_INSTR1_i => ID_INSTR_q(1),
      IX2_INSTR1_i => IX1_INSTR1_q,
      IX3_INSTR1_i => IX2_INSTR1_q,
      IX1_PA_RES0_i => IX1_PA0_RES, 
      IX1_PA_RES1_i => IX1_PA1_RES,
      IX2_PA_RES0_i => IX2_PA0_RES,
      IX2_PA_RES1_i => IX2_PA1_RES,
      IX3_PA_RES0_i => IX3_DRD0,
      IX3_PA_RES1_i => IX3_DRD1,
      ID_OPX_NOFWD_i => to_signed(WB_RDB0), --ID_OPB0_NOFWD,
      IX1_V_i => ID_V_q,
      IX2_V_i => IX1_V_q,
      IX3_V_i => IX2_V_q,
      IX1_FWDE_i => ID_FWDE_q,
      IX2_FWDE_i => IX1_FWDE_q,
      IX3_FWDE_i => IX2_FWDE_q,
      NOREGS_i => IF_OPB_IMM_q(0),
      NOREGD_i => IF_OPB_q(0),
 
      ID_OPX_o => ID_OPB0
    );
 
  -- Instruction #1 Operand B forward logic
 
  U_FWDLOGB1 : G729A_ASIP_FWDLOG_2W_P6
    port map(
      ID_RX_i => ID_INSTR1.RB,
      ID_RRX_i => ID_INSTR1.RRB,
      IX1_INSTR0_i => ID_INSTR_q(0),
      IX2_INSTR0_i => IX1_INSTR0_q,
      IX3_INSTR0_i => IX2_INSTR0_q,
      IX1_INSTR1_i => ID_INSTR_q(1),
      IX2_INSTR1_i => IX1_INSTR1_q,
      IX3_INSTR1_i => IX2_INSTR1_q,
      IX1_PA_RES0_i => IX1_PA0_RES, 
      IX1_PA_RES1_i => IX1_PA1_RES,
      IX2_PA_RES0_i => IX2_PA0_RES,
      IX2_PA_RES1_i => IX2_PA1_RES,
      IX3_PA_RES0_i => IX3_DRD0,
      IX3_PA_RES1_i => IX3_DRD1,
      ID_OPX_NOFWD_i => to_signed(WB_RDB1), --ID_OPB1_NOFWD,
      IX1_V_i => ID_V_q,
      IX2_V_i => IX1_V_q,
      IX3_V_i => IX2_V_q,
      IX1_FWDE_i => ID_FWDE_q,
      IX2_FWDE_i => IX1_FWDE_q,
      IX3_FWDE_i => IX2_FWDE_q,
      NOREGS_i => IF_OPB_IMM_q(1),
      NOREGD_i => IF_OPB_q(1),
 
      ID_OPX_o => ID_OPB1
    );
  -- Pipeline-A (dedicated) pre-decoder
 
  U_PADEC0 : G729A_ASIP_PIPE_A_DEC_2W
    port map(
      INSTR_i => ID_INSTR0,
 
      FWDE_o => ID_FWDE(0),
      SEL_o => ID_PASEL0
    );
 
  U_PADEC1 : G729A_ASIP_PIPE_A_DEC_2W
    port map(
      INSTR_i => ID_INSTR1,
 
      FWDE_o => ID_FWDE(1),
      SEL_o => ID_PASEL1
    );
 
  -- Pipeline Registers
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        ID_V_q <= "00";
      else
        ID_V_q(0) <= ID_V(0) and not(ID_HALT0);
        ID_V_q(1) <= ID_V(1) and not(ID_HALT);
      end if;
      ID_PC_q <= IF_PC_q2(2-1 downto 0);      
      ID_INSTR_q(0) <= ID_INSTR0;      
      ID_INSTR_q(1) <= ID_INSTR1;      
      ID_OPA0_q <= ID_OPA0;
      ID_OPB0_q <= ID_OPB0;
      ID_OPA1_q <= ID_OPA1;
      ID_OPB1_q <= ID_OPB1;
      ID_OPC0_q <= ID_OPC0;
      --ID_OPC1_q <= ID_OPC1;
      ID_FWDE_q <= ID_FWDE;
      ID_PASEL0_q <= ID_PASEL0;
      ID_PASEL1_q <= ID_PASEL1;
 
      ID_PCP1_q <= (IF_PC_q2(1) + 1,IF_PC_q2(0) + 1);      
 
    end if;
  end process;
 
  ----------------------------------------------------
  -- IX1 Stage
  ----------------------------------------------------
 
  -- Pipeline-A
 
  U_PIPEA0 : G729A_ASIP_PIPE_A_2W
    port map(
      CLK_i => CLK_i,
      SEL_i => ID_PASEL0_q,
      OPA_i => ID_OPA0_q(SDLEN-1 downto 0),
      OPB_i => ID_OPB0_q(SDLEN-1 downto 0),
      ACC_i => WB_ACC_q,
      LDAT_i => DDAT0_i,
 
      RES_1C_o => IX1_PA0_RES,
      RES_o => IX2_PA0_RES,
      ACC_o => open, --IX2_PA0_ACC,
      OVF_o => IX2_PA0_OVF
    );
 
  U_PIPEA1 : G729A_ASIP_PIPE_A_2W
    port map(
      CLK_i => CLK_i,
      SEL_i => ID_PASEL1_q,
      OPA_i => ID_OPA1_q(SDLEN-1 downto 0),
      OPB_i => ID_OPB1_q(SDLEN-1 downto 0),
      ACC_i => WB_ACC_q,
      LDAT_i => DDAT1_i,
 
      RES_1C_o => IX1_PA1_RES,
      RES_o => IX2_PA1_RES,
      ACC_o => open, --IX2_PA1_ACC,
      OVF_o => IX2_PA1_OVF
    );
 
  U_PIPEB : G729A_ASIP_PIPE_B
    port map(
      CLK_i => CLK_i,
      OP_i => ID_INSTR_q(0).ALU_OP,
      OPA_i => ID_OPA0_q,
      OPB_i => ID_OPB0_q,
      OVF_i => WB_OVF_q,
      ACC_i => WB_ACC_q,
 
      RES_o => IX2_PB0_RES,
      OVF_o => IX2_PB0_OVF
    );
 
  -- Pipe-A/B result selection
 
  IX2_DRD0 <= IX2_PA0_RES when IX1_FWDE_q(0) = '1' else IX2_PB0_RES;
  IX2_OVF0 <= IX2_PA0_OVF when IX1_FWDE_q(0) = '1' else IX2_PB0_OVF;
 
  IX2_DRD1 <= IX2_PA1_RES;
  IX2_OVF1 <= IX2_PA1_OVF;
 
  -- Branch/Jump processing logic (pipe #0)
 
  -- Note: loop count setting instructions (LLCR*) are handled
  -- like un-conditional jumps to the following instruction.
  -- This is needed because LLCR* are processed in IX1 stage
  -- when some instruction affecting loop count may have been
  -- already fetched and improperly processed by loop stack
  -- logic.
  -- Loop last instruction is treated in the following way,
  -- to nullify any loop instruction which may be have been
  -- fetched incorrectly.
 
  IX1_PCLN <= IX1_LLCR or IX1_LEND;
 
  U_BJXLOG : G729A_ASIP_BJXLOG
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i,
      BJ_OP => ID_INSTR_q(0).BJ_OP,
      PC0P1_i => ID_PCP1_q(0),
      PC1P1_i => ID_PCP1_q(1),
      PC0_i => ID_PC_q(0),
      PCSEL_i => IX1_LEIS,
      OPA_i => ID_OPA0_q,
      OPB_i => ID_OPB0_q,
      OPC_i => ID_OPC0_q,
      IV_i => ID_V_q(0),
      LLCRX_i => IX1_PCLN,
      FSTLL_i => ID_PSTALL,
 
      BJX_o => IX1_BJX,
      BJTA_o => IX1_BJTA
    );
 
  IX1_V(0) <= ID_V_q(0);
 
  -- Instr. #1 must be invalidated when:
  -- 1) instr. #0 is a regular branch/jump, OR
  -- 2) instr. #0 is a loop closing instruction.
  --
  -- Both cases trigger IV1_BJX and therefore are distinguished
  -- by checking loop-end instruction selector IX1_LEIS).
 
  IX1_V(1) <= '0' when (
    (IX1_BJX = '1') and not(IX1_LEIS = '1')
  ) else ID_V_q(1);
 
  -- Load/Store logic
 
  U_LSU0 : G729A_ASIP_LSU
    port map(
      IV_i => ID_V_q(0),
      LS_OP_i => ID_INSTR_q(0).LS_OP,
      OPA_i => ID_OPA0_q,
      OPB_i => ID_OPB0_q,
      OPC_i => ID_OPC0_q,
 
      DRE_o => DRE_o(0),
      DWE_o => IX1_DWE,
      DADR_o => IX1_DADR,
      DDAT_o => IX1_DDATO
    );
 
  DWE0_o <= IX1_DWE;
  DADR0_o <= IX1_DADR;
  DDAT0_o <= IX1_DDATO;
 
  U_LU1 : G729A_ASIP_LU
    port map(
      IV_i => ID_V_q(1),
      LS_OP_i => ID_INSTR_q(1).LS_OP,
      OPA_i => ID_OPA1_q,
      OPB_i => ID_OPB1_q,
 
      DRE_o => DRE_o(1),
      DADR_o => DADR1_o
    );
 
  ----------------------------------------------------
  -- Store Checker
  ----------------------------------------------------
 
  -- synthesis translate_off
 
  G_ST : if(SIMULATION_ONLY = '1') generate
 
  U_STCHK : G729A_ASIP_ST_CHECKER
    generic map(
      ST_FILENAME => ST_FILENAME
    )
    port map(
      CLK_i => CLK_i,
      ENB_i => CHK_ENB_i,
      DWE_i => IX1_DWE,
      DADR_i => IX1_DADR,
      DDATO_i => IX1_DDATO
    );
 
  end generate;
 
  -- synthesis translate_on
 
  -- Loop Stack control logic
 
  U_LCSTK_IX : G729A_ASIP_LCSTKLOG_IX
    port map(
      IX_V_i => ID_V_q(0), 
      IX_INSTR_i => ID_INSTR_q(0),
      IX_OPA_i => ID_OPA0_q,
 
      SRST_o => IX1_SRST,
      LLBRX_o => IX1_LLBR,
      LLERX_o => IX1_LLER,
      LLCRX_o => IX1_LLCR,
      IMM_o => IX1_IMM
    );
 
  -- Overflow result selection
  -- 1) OVF_q or (instruction #0 OVF) or (instruction #1 OVF)
  -- 2) OVF_q or (instruction #0 OVF)
  -- 3) OVF_q or (instruction #1 OVF)
  -- 4) (instruction #1 OVF)
  -- 5) OVF_q
 
  -- Pipeline Registers
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        IX1_V_q <= "00";
      else
        IX1_V_q <= IX1_V;
      end if;
      IX1_INSTR0_q <= ID_INSTR_q(0);      
      IX1_INSTR1_q <= ID_INSTR_q(1);      
      IX1_FWDE_q <= ID_FWDE_q;
    end if;
  end process;
 
  ----------------------------------------------------
  -- IX3 Stage
  ----------------------------------------------------
 
  IX2_FWDE(0) <= '1'; 
  IX2_FWDE(1) <= IX1_FWDE_q(1); 
 
  -- Pipeline Registers
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        IX2_V_q <= "00";
      else
        IX2_V_q <= IX1_V_q;
      end if;
      IX2_INSTR0_q <= IX1_INSTR0_q;      
      IX2_INSTR1_q <= IX1_INSTR1_q;      
      IX2_FWDE_q <= IX2_FWDE;
      IX2_DRD0_q <= IX2_DRD0;
      IX2_DRD1_q <= IX2_DRD1;
      IX2_OVF0_q <= IX2_OVF0;
      IX2_OVF1_q <= IX2_OVF1;
    end if;
  end process;
 
  IX3_DRD0 <= IX2_DRD0_q;
  IX3_DRD1 <= IX2_DRD1_q;
  IX3_OVF0 <= IX2_OVF0_q;
  IX3_OVF1 <= IX2_OVF1_q;
 
  ----------------------------------------------------
  -- WB Stage
  ----------------------------------------------------
 
  -- Register File
 
  WB_WE0 <= IX2_V_q(0) and IX2_INSTR0_q.WRD;
  WB_WE1 <= IX2_V_q(1) and IX2_INSTR1_q.WRD;
 
  U_REGF : G729A_ASIP_REGFILE_16X16_2W
    port map(
      CLK_i => CLK_i,
      RA0_i => ID_INSTR0.RA,
      RA1_i => ID_INSTR0.RB,
      RA2_i => ID_INSTR1.RA,
      RA3_i => ID_INSTR1.RB,
      WA0_i => IX2_INSTR0_q.RD,
      WA1_i => IX2_INSTR1_q.RD,
      LR0_i => ID_INSTR0.LA,
      LR1_i => ID_INSTR0.LB,
      LR2_i => ID_INSTR1.LA,
      LR3_i => ID_INSTR1.LB,
      LW0_i => IX2_INSTR0_q.LD,
      LW1_i => IX2_INSTR1_q.LD,
      WE0_i => WB_WE0,
      WE1_i => WB_WE1,
      D0_i => to_std_logic_vector(IX3_DRD0),
      D1_i => to_std_logic_vector(IX3_DRD1),
 
      Q0_o => WB_RDA0,
      Q1_o => WB_RDB0,
      Q2_o => WB_RDA1,
      Q3_o => WB_RDB1
    );
 
  -- Overflow register
 
  -- It's allowed to execute in parallel two instructions
  -- writing overflow register.
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        WB_OVF_q <= '0';
      elsif(IX2_INSTR0_q.WOVF = '1' and IX2_INSTR0_q.WOVF = '1') then
        -- both instr. #0 and #1 write OVF flag
        if(IX2_INSTR0_q.IMNMC = IM_COVF) then
          -- instr. #0 is covf
          WB_OVF_q <= IX3_OVF1;
        else
          WB_OVF_q <= WB_OVF_q or IX3_OVF0 or IX3_OVF1;
        end if;
      elsif(IX2_INSTR0_q.WOVF = '1') then
        -- only instr. #0 write OVF flag
        if(IX2_INSTR0_q.IMNMC = IM_COVF) then
          -- instr. #0 is covf
          WB_OVF_q <= '0';
        else
          WB_OVF_q <= WB_OVF_q or IX3_OVF0;
        end if;
      elsif(IX2_INSTR1_q.WOVF = '1') then
        -- only instr. #1 write OVF flag
        WB_OVF_q <= WB_OVF_q or IX3_OVF1;
      end if;
    end if;
  end process;
 
  -- Accumulator register
 
  -- WARNING: it's not possible to execute in parallel two
  -- instructions writing accumulator register!
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        WB_ACC_q <= to_signed(0,LDLEN);
      elsif(IX1_V_q(0) = '1' and IX1_INSTR0_q.WACC = '1') then
        WB_ACC_q <= IX2_DRD0;
      elsif(IX1_V_q(1) = '1' and IX1_INSTR1_q.WACC = '1') then
        WB_ACC_q <= IX2_DRD1;
      end if;
    end if;
  end process;
 
  -- Parallel eXecution Enable register
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        WB_PXE_q <= '1'; -- PXE is on at reset
      elsif(IX2_V_q(0) = '1' and IX2_INSTR0_q.IMNMC = IM_PXON) then
        WB_PXE_q <= '1';
      elsif(
        (IX2_V_q(0) = '1' and IX2_INSTR0_q.IMNMC = IM_PXOFF) or
        (IX2_V_q(1) = '1' and IX2_INSTR1_q.IMNMC = IM_PXOFF)
      ) then
        WB_PXE_q <= '0';
      end if;
    end if;
  end process;
 
  ----------------------------------------------------
  -- Write-Back Checker
  ----------------------------------------------------
 
  -- synthesis translate_off
 
  G_WB : if(SIMULATION_ONLY = '1') generate
 
  U_WBCHK : G729A_ASIP_WB_CHECKER
    generic map(
      WB_FILENAME => WB_FILENAME
    )
    port map(
      CLK_i => CLK_i,
      ENB_i => CHK_ENB_i,
      WE0_i => WB_WE0,
      WE1_i => WB_WE1,
      IX_INSTR0_i => IX2_INSTR0_q,
      IX_INSTR1_i => IX2_INSTR1_q,
      IX_DRD0_i => IX3_DRD0,
      IX_DRD1_i => IX3_DRD1
    );
 
  end generate;
 
  -- synthesis translate_on
 
  ----------------------------------------------------
  -- Statistics
  ----------------------------------------------------
 
  G_STAT : if(SIMULATION_ONLY = '1') generate
 
  U_STAT : G729A_ASIP_STATS
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i,
      ID_V_i => IF_V_q2,
      ID_PS_i(0) => ID_PS0,
      ID_PS_i(1) => ID_PS1,
      ID_PXE1_i => ID_PXE1,
      IX2_V_i => IX2_V_q,
      STRT_i => STRT_i,
      HALT_i => ID_HALT
    );
 
  end generate;
 
end ARC;
 

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.