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

Subversion Repositories g729a_codec

[/] [g729a_codec/] [trunk/] [VHDL/] [G729A_codec_sdp.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 codec (Single Data Port)
---------------------------------------------------------------
 
---------------------------------------------------------------
-- Notes:
-- SDP version uses a single data port (DI_i/DO_o) to transfer
-- coder input/output data, decoder input/output data and
-- ASIP state data, and it therefore more suitable for systems
-- with a single main bus, possibly connected to an external
-- DRAM memory.
---------------------------------------------------------------
 
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_BASIC_PKG.all;
use WORK.G729A_ASIP_ARITH_PKG.all;
use WORK.G729A_ASIP_OP_PKG.all;
use WORK.G729A_ASIP_CFG_PKG.all;
use work.G729A_CODEC_INTF_PKG.all;
 
entity G729A_CODEC_SDP is
  generic(
    -- synthesis translate_off
    ST_FILE : string; 
    WB_FILE : string;
    -- synthesis translate_on
    REGISTER_INPUTS : std_logic := '0';
    REGISTER_OUTPUTS : std_logic := '0';
    USE_ROM_MIF : std_logic := '0';
    SIMULATION_ONLY : std_logic := '1'
  );
  port(
    CLK_i : in std_logic; -- clock
    RST_i : in std_logic; -- reset
    STRT_i : in std_logic; -- start
    OPS_i : in std_logic_vector(3-1 downto 0);
    RE_i : in std_logic; -- state read-enable
    WE_i : in std_logic; -- state write-enable
    DI_i : in std_logic_vector(SDLEN-1 downto 0); -- data-in
 
    BSY_o : out std_logic; -- busy
    DMAE_o : out std_logic; -- DMA enable
    STS_o : out std_logic_vector(3-1 downto 0); -- status
    DV_o : out std_logic; -- data-out valid
    DO_o : out std_logic_vector(SDLEN-1 downto 0) -- data-out
  );
end G729A_CODEC_SDP;
 
architecture ARC of G729A_CODEC_SDP is
 
  -- I/O transfer sub-programs starting address
  constant DATA_IN : natural := 7645;
  constant COD_DATA_OUT : natural := 8663;
  constant DEC_DATA_IN : natural := 8695;
  constant DEC_DATA_OUT : natural := 8679;
  constant STATE_IN : natural := 8719;
  constant STATE_OUT : natural := 8743;
 
  component G729A_ASIP_TOP_2W is
    generic(
      -- synthesis translate_off
      ST_FILE : string := "NONE";
      WB_FILE : string := "NONE";
      -- synthesis translate_on
      USE_ROM_MIF : std_logic := '0';
      SIMULATION_ONLY : std_logic := '1'
    );
    port(
      CLK_i : in std_logic; -- clock
      RST_i : in std_logic; -- reset
      STRT_i : in std_logic; -- start
      SADR_i : in std_logic_vector(ALEN-1 downto 0);
      SRST_i : in std_logic; -- soft_reset
      DIWE_i : in std_logic; -- data-in write-enable
      DI_i : in std_logic_vector(SDLEN-1 downto 0); -- data-in
      DORE_i : in std_logic; -- data-out read-enable
      CHK_ENB_i : in std_logic; -- check-enable
      XDMAE_i : in std_logic; -- DMA enable
      XWE_i : in std_logic; -- DMA write-enable
      XADR_i : in std_logic_vector(ALEN-1 downto 0);
      XDI_i : in std_logic_vector(SDLEN-1 downto 0); -- DMA data-in
 
      BSY_o : out std_logic; -- busy
      DIV_o : out std_logic; --
      DOV_o : out std_logic; --
      DO_o : out std_logic_vector(SDLEN-1 downto 0); -- data-out
      XDO_o : out std_logic_vector(SDLEN-1 downto 0) -- DMA data-out
    );
  end component;
 
  component G729A_ASIP_SPC is
    generic(
      SIMULATION_ONLY : std_logic := '1'
    );
    port(
      CLK_i : in std_logic;
      RST_i : in std_logic;
      STRT_i : in std_logic;
      OPS_i : in std_logic_vector(3-1 downto 0);
      A_BSY_i : in std_logic;
      D_BSY_i : in std_logic;
 
      SADR_o : out unsigned(ALEN-1 downto 0);
      A_STRT_o : out std_logic;
      A_DMAE_o : out std_logic;
      A_ADR_o : out unsigned(ALEN-1 downto 0);
      D_STRT_o : out std_logic;
      D_WE_o : out std_logic;
      ASEL_o : out std_logic_vector(3-1 downto 0);
      BLEN_o : out natural range 0 to 2048-1;
      BSY_o : out std_logic;
      STS_o : out std_logic_vector(3-1 downto 0);
      CHKE_o : out std_logic
    );
  end component;
 
  signal STRT_q : std_logic;
  signal OPS_q : std_logic_vector(3-1 downto 0);
  signal RE_q : std_logic;
  signal WE_q : std_logic;
  signal DI_q : std_logic_vector(SDLEN-1 downto 0);
  signal DO_q : std_logic_vector(SDLEN-1 downto 0);
  signal DV_q,DV_Q2 : std_logic;
 
  signal SRST : std_logic := '0';
  signal STRT : std_logic;
  signal SADR : unsigned(ALEN-1 downto 0);
  signal IO_DDATI : std_logic_vector(SDLEN-1 downto 0);
  signal ASIP_BSY : std_logic;
  signal IO_DIWE : std_logic;
  signal IO_DORE : std_logic;
  signal DADR_L,DADR_S : unsigned(ALEN-1 downto 0);
  signal IO_DDATO : std_logic_vector(SDLEN-1 downto 0);
  signal ASIP_DIV,ASIP_DOV : std_logic;
 
  signal SPC_D_WE : std_logic;
  signal SPC_CHKE : std_logic;
  signal SPC_BSY : std_logic;
  signal SPC_A_DMAE : std_logic;
  signal SPC_D_STRT : std_logic;
  signal SPC_A_STRT : std_logic;
  signal SPC_A_ADR : unsigned(ALEN-1 downto 0);
  signal SPC_BLEN : natural range 0 to 2048-1;
  signal SPC_SADR : unsigned(ALEN-1 downto 0);
  signal SPC_ASEL : std_logic_vector(3-1 downto 0);
 
  signal DMA_ENB : std_logic;
  signal DMA_BSY : std_logic;
  signal DMA_WE : std_logic;
  signal DMA_ADR : std_logic_vector(ALEN-1 downto 0);
  signal DMA_ADR_q,DMA_ADR_q2 : unsigned(ALEN-1 downto 0);
  signal DMA_DI,DMA_DI_q : std_logic_vector(SDLEN-1 downto 0);
  signal DMA_DO,DMA_DO_q : std_logic_vector(SDLEN-1 downto 0);
  signal DMA_CNT_q : unsigned(ALEN-1 downto 0);
  signal DMA_DEC : std_logic;
 
  signal ERROR_q : std_logic := '0';
  signal CHK : integer;
  signal VALID_OPS : std_logic;
 
begin
 
  ---------------------------------------------------
  -- I/O Interface signals (unused)
  ---------------------------------------------------
 
  IO_DIWE <= '0';
  IO_DDATI <= (others => '0');
  IO_DORE <= '0';
 
  ---------------------------------------------------
  -- Input signal registers
  ---------------------------------------------------
 
  -- Warning: registering RE_i adds an extra delay
  -- cycles between RE_i assertion and data output.
 
  G0_T : if (REGISTER_INPUTS = '1') generate
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        STRT_q <= '0';
        RE_q <= '0';
        WE_q <= '0';
      else
        STRT_q <= STRT_i;
        RE_q <= RE_i;
        WE_q <= WE_i;
      end if;
      OPS_q <= OPS_i;
      DI_q <= DI_i;
    end if;
  end process;
 
  end generate;
 
  G0_F : if (REGISTER_INPUTS = '0') generate
 
    STRT_q <= STRT_i;
    RE_q <= RE_i;
    WE_q <= WE_i;
    OPS_q <= OPS_i;
    DI_q <= DI_i;
 
  end generate;
 
  ---------------------------------------------------
  -- Output signal registers
  ---------------------------------------------------
 
  -- Note: only data-out signal DO_o needs to be
  -- explicitly registred, other output signals are
  -- already driven by registers.
 
  -- Warning: registering DO_o adds an extra delay
  -- cycles between RE_i assertion and data output.
 
  G1_T : if (REGISTER_OUTPUTS = '1') generate
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      DO_q <= DMA_DO;
    end if;
  end process;
 
  end generate;
 
  G1_F : if (REGISTER_OUTPUTS = '0') generate
 
    DO_q <= DMA_DO;
 
  end generate;
 
  ---------------------------------------------------
  -- Data(-out) valid flag
  ---------------------------------------------------
 
  -- this flag get asserted when valid data are available
  -- on DO_o in response to an assertion of RE_i.
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        DV_q <= '0';
      else
        DV_q <= (DMA_ENB and not(SPC_D_WE) and RE_q);
      end if;
    end if;
  end process;
 
  G2_T : if (REGISTER_OUTPUTS = '1') generate
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        DV_q2 <= '0';
      else
        DV_q2 <= DV_q;
      end if;
    end if;
  end process;
 
  end generate;
 
  ---------------------------------------------------
  -- DMA logic
  ---------------------------------------------------
 
  DMA_ENB <= SPC_A_DMAE;
 
  DMA_WE <= (SPC_D_WE and WE_q);
 
  DMA_DI <= DI_q;
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        DMA_CNT_q <= to_unsigned(0,ALEN);
      elsif(RST_i = '1' or SPC_D_STRT = '1') then
        DMA_CNT_q <= to_unsigned(SPC_BLEN - 1,ALEN);
      elsif(DMA_CNT_q > 0 and DMA_DEC = '1') then
        DMA_CNT_q <= DMA_CNT_q - 1;
      end if;
    end if;
  end process;
 
  DMA_DEC <= (SPC_D_WE and WE_q) or (not(SPC_D_WE) and RE_q);
 
  DMA_BSY <= '1' when DMA_CNT_q > 0 else '0';
 
  process(CLK_i)
  begin
    if(CLK_i = '1' and CLK_i'event) then
      if(RST_i = '1') then
        DMA_ADR_q <= to_unsigned(0,ALEN);
      elsif(RST_i = '1' or SPC_D_STRT = '1') then
        DMA_ADR_q <= SPC_A_ADR;
      elsif(DMA_CNT_q > 0 and DMA_DEC = '1') then
        DMA_ADR_q <= DMA_ADR_q + 1;
      end if;
    end if;
  end process;
 
  DMA_ADR <= to_std_logic_vector(DMA_ADR_q);
 
  ---------------------------------------------------
  -- ASIP Core Top module
  ---------------------------------------------------
 
  U_ASIP : G729A_ASIP_TOP_2W
    generic map(
      -- synthesis translate_off
      ST_FILE => ST_FILE,
      WB_FILE => WB_FILE,
      -- synthesis translate_on
      USE_ROM_MIF => USE_ROM_MIF,
      SIMULATION_ONLY => SIMULATION_ONLY
    )
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i, 
      STRT_i => SPC_A_STRT, 
      SADR_i => to_std_logic_vector(SPC_SADR), 
      SRST_i => SRST, -- inactive!
      DIWE_i => IO_DIWE,
      DI_i => IO_DDATI,
      DORE_i => IO_DORE,
      CHK_ENB_i => SPC_CHKE,
      XDMAE_i => DMA_ENB,
      XWE_i => DMA_WE,
      XADR_i => DMA_ADR,
      XDI_i => DMA_DI,
 
      BSY_o => ASIP_BSY,
      DIV_o => open, --ASIP_DIV, -- not used
      DOV_o => open, --ASIP_DOV, -- not used
      DO_o => open, --IO_DDATO,
      XDO_o => DMA_DO
    );
 
  ---------------------------------------------------
  -- ASIP Sub-program Controller
  ---------------------------------------------------
 
  U_SPC : G729A_ASIP_SPC
    generic map(
      SIMULATION_ONLY => SIMULATION_ONLY
    )
    port map(
      CLK_i => CLK_i,
      RST_i => RST_i, 
      STRT_i => STRT_q,
      OPS_i => OPS_q,
      A_BSY_i => ASIP_BSY,
      D_BSY_i => DMA_BSY,
 
      SADR_o => SPC_SADR,
      A_STRT_o => SPC_A_STRT, -- ASIP start
      A_DMAE_o => SPC_A_DMAE, -- ASIP DMA enable
      A_ADR_o => SPC_A_ADR, -- ASIP DMA adr.
      D_STRT_o => SPC_D_STRT, -- DMA start
      D_WE_o => SPC_D_WE, -- DMA write-enable
      ASEL_o => open, --SPC_ASEL, -- unused
      BLEN_o => SPC_BLEN, -- DMA burst len.
      BSY_o => SPC_BSY,
      STS_o => STS_o,
      CHKE_o => SPC_CHKE
    );
 
  ---------------------------------------------------
  -- Outputs
  ---------------------------------------------------
 
  DMAE_o <= DMA_ENB;
  BSY_o <= SPC_BSY;
 
  G3_T : if (REGISTER_OUTPUTS = '1') generate
  DV_o <= DV_q2;
  end generate;
 
  G3_F : if (REGISTER_OUTPUTS = '0') generate
  DV_o <= DV_q;
  end generate;
 
  DO_o <= DO_q;
 
  ---------------------------------------------------
  -- Checkers
  ---------------------------------------------------
 
  -- synthesis translate_off
 
  -- Check that STRT_i signal is either '0' or '1' on clock
  -- rising edge (ignore reset).
 
  assert not(not(STRT_i = '0' or STRT_i = '1') and RST_i = '0'
    and CLK_i = '1' and CLK_i'event) 
  report "STRT_i is not '0' or '1' on clock rising edge!"
  severity ERROR;
 
  -- Check that OPS_i has a valid value when STRT_i is asserted
  -- on a clock rising edge (ignore reset).
 
  VALID_OPS <= '1' when (
    OPS_i = INIT or
    OPS_i = SAVS or
    OPS_i = RSTS or
    OPS_i = RUNF or
    OPS_i = RUNC or
    OPS_i = RUND
  ) else '0';
 
  assert not(VALID_OPS = '0' and STRT_i = '1' and RST_i = '0' and
    CLK_i = '1' and CLK_i'event) 
  report "invalid OPS_i value when STRT_i asserted!"
  severity ERROR;
 
  -- Check that RE_i is asserted only in DMA mode (ignore reset).
 
  assert not(DMA_ENB = '0' and RE_i = '1' and RST_i = '0' and
    CLK_i = '1' and CLK_i'event) 
  report "RE_i asserted not in DMA mode!"
  severity ERROR;
 
  -- Check that RE_i is asserted only in DMA read mode (ignore reset).
 
  assert not(DMA_ENB = '1' and SPC_D_WE = '1' and RE_i = '1' and RST_i = '0' and
    CLK_i = '1' and CLK_i'event) 
  report "RE_i asserted in DMA write mode!"
  severity ERROR;
 
  -- Check that WE_i is asserted only in DMA mode (ignore reset).
 
  assert not(DMA_ENB = '0' and WE_i = '1' and RST_i = '0' and
    CLK_i = '1' and CLK_i'event) 
  report "WE_i asserted not in DMA mode!"
  severity ERROR;
 
  -- Check that WE_i is asserted only in DMA write mode (ignore reset).
 
  assert not(DMA_ENB = '1' and SPC_D_WE = '0' and WE_i = '1' and RST_i = '0' and
    CLK_i = '1' and CLK_i'event) 
  report "WE_i asserted in DMA read mode!"
  severity ERROR;
 
  -- synthesis translate_on
 
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.