-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
-- --
|
-- --
|
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
-- --
|
-- --
|
-- Copyright (C) 2013 Stefano Tonello --
|
-- Copyright (C) 2013 Stefano Tonello --
|
-- --
|
-- --
|
-- This source file may be used and distributed without --
|
-- This source file may be used and distributed without --
|
-- restriction provided that this copyright statement is not --
|
-- restriction provided that this copyright statement is not --
|
-- removed from the file and that any derivative work contains --
|
-- removed from the file and that any derivative work contains --
|
-- the original copyright notice and the associated disclaimer.--
|
-- the original copyright notice and the associated disclaimer.--
|
-- --
|
-- --
|
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY --
|
-- THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY --
|
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --
|
-- EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED --
|
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --
|
-- TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS --
|
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR --
|
-- FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL THE AUTHOR --
|
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --
|
-- OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, --
|
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES --
|
-- INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES --
|
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE --
|
-- (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE --
|
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR --
|
-- GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR --
|
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --
|
-- BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF --
|
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
-- LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT --
|
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT --
|
-- (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT --
|
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --
|
-- OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE --
|
-- POSSIBILITY OF SUCH DAMAGE. --
|
-- POSSIBILITY OF SUCH DAMAGE. --
|
-- --
|
-- --
|
-----------------------------------------------------------------
|
-----------------------------------------------------------------
|
|
|
---------------------------------------------------------------
|
---------------------------------------------------------------
|
-- G.729a ASIP Sub-Program Controller
|
-- G.729a ASIP Sub-Program Controller
|
---------------------------------------------------------------
|
---------------------------------------------------------------
|
|
|
library IEEE;
|
library IEEE;
|
use IEEE.std_logic_1164.all;
|
use IEEE.std_logic_1164.all;
|
use IEEE.numeric_std.all;
|
use IEEE.numeric_std.all;
|
|
|
library work;
|
library work;
|
use work.G729A_ASIP_PKG.all;
|
use work.G729A_ASIP_PKG.all;
|
use work.G729A_CODEC_INTF_PKG.all;
|
use work.G729A_CODEC_INTF_PKG.all;
|
|
|
entity G729A_ASIP_SPC is
|
entity G729A_ASIP_SPC is
|
generic(
|
generic(
|
SIMULATION_ONLY : std_logic := '1'
|
SIMULATION_ONLY : std_logic := '1'
|
);
|
);
|
port(
|
port(
|
CLK_i : in std_logic;
|
CLK_i : in std_logic;
|
RST_i : in std_logic;
|
RST_i : in std_logic;
|
STRT_i : in std_logic;
|
STRT_i : in std_logic;
|
OPS_i : in std_logic_vector(3-1 downto 0);
|
OPS_i : in std_logic_vector(3-1 downto 0);
|
A_BSY_i : in std_logic;
|
A_BSY_i : in std_logic;
|
D_BSY_i : in std_logic;
|
D_BSY_i : in std_logic;
|
|
|
SADR_o : out unsigned(ALEN-1 downto 0);
|
SADR_o : out unsigned(ALEN-1 downto 0);
|
A_STRT_o : out std_logic;
|
A_STRT_o : out std_logic;
|
A_DMAE_o : out std_logic;
|
A_DMAE_o : out std_logic;
|
A_ADR_o : out unsigned(ALEN-1 downto 0);
|
A_ADR_o : out unsigned(ALEN-1 downto 0);
|
D_STRT_o : out std_logic;
|
D_STRT_o : out std_logic;
|
D_WE_o : out std_logic;
|
D_WE_o : out std_logic;
|
ASEL_o : out std_logic_vector(3-1 downto 0);
|
ASEL_o : out std_logic_vector(3-1 downto 0);
|
BLEN_o : out natural range 0 to 2048-1;
|
BLEN_o : out natural range 0 to 2048-1;
|
BSY_o : out std_logic;
|
BSY_o : out std_logic;
|
STS_o : out std_logic_vector(3-1 downto 0);
|
STS_o : out std_logic_vector(3-1 downto 0);
|
CHKE_o : out std_logic
|
CHKE_o : out std_logic
|
);
|
);
|
end G729A_ASIP_SPC;
|
end G729A_ASIP_SPC;
|
|
|
architecture ARC of G729A_ASIP_SPC is
|
architecture ARC of G729A_ASIP_SPC is
|
|
|
-- sub-program starting addresses
|
-- sub-program starting addresses
|
|
|
constant INIT_DEC : natural := 2412;
|
constant INIT_DEC : natural := 2412;
|
constant DECOD_LD8A_LOOPINIT : natural := 2971;
|
constant DECOD_LD8A_LOOPINIT : natural := 2971;
|
constant DECOD_LD8A_LOOPUPDT : natural := 3001;
|
constant DECOD_LD8A_LOOPUPDT : natural := 3001;
|
constant DECOD_LD8A_LOOPEND : natural := 3005;
|
constant DECOD_LD8A_LOOPEND : natural := 3005;
|
constant DECOD_LD8A_LOOPBODY : natural := 3015;
|
constant DECOD_LD8A_LOOPBODY : natural := 3015;
|
constant MAIN_DEC1 : natural := 3361;
|
constant MAIN_DEC1 : natural := 3361;
|
constant MAIN_DEC3 : natural := 3374;
|
constant MAIN_DEC3 : natural := 3374;
|
constant INIT_COD : natural := 3455;
|
constant INIT_COD : natural := 3455;
|
constant MAIN_COD1 : natural := 8459;
|
constant MAIN_COD1 : natural := 8459;
|
constant BIG_LOOP_INIT : natural := 5140;
|
constant BIG_LOOP_INIT : natural := 5140;
|
constant BIG_LOOP_UPDT : natural := 5146;
|
constant BIG_LOOP_UPDT : natural := 5146;
|
constant BIG_LOOP : natural := 5155;
|
constant BIG_LOOP : natural := 5155;
|
constant UPDATE : natural := 5495;
|
constant UPDATE : natural := 5495;
|
constant MAIN_COD3 : natural := 8644;
|
constant MAIN_COD3 : natural := 8644;
|
constant DATA_IN : natural := 7645;
|
constant DATA_IN : natural := 7645;
|
constant DEC_DATA_IN : natural := 8695;
|
constant DEC_DATA_IN : natural := 8695;
|
constant COD_DATA_OUT : natural := 8663;
|
constant COD_DATA_OUT : natural := 8663;
|
constant DEC_DATA_OUT : natural := 8679;
|
constant DEC_DATA_OUT : natural := 8679;
|
constant STATE_IN : natural := 8719;
|
constant STATE_IN : natural := 8719;
|
constant STATE_OUT : natural := 8743;
|
constant STATE_OUT : natural := 8743;
|
|
|
-- operation I/O type
|
-- operation I/O type
|
|
|
constant IO_NONE : std_logic_vector(2-1 downto 0) := "00";
|
constant IO_NONE : std_logic_vector(2-1 downto 0) := "00";
|
constant IO_READ : std_logic_vector(2-1 downto 0) := "01";
|
constant IO_READ : std_logic_vector(2-1 downto 0) := "01";
|
constant IO_WRITE : std_logic_vector(2-1 downto 0) := "10";
|
constant IO_WRITE : std_logic_vector(2-1 downto 0) := "10";
|
|
|
|
constant MAX_IO_COUNT : natural := 2048;
|
|
|
-- sequencer "instruction" type
|
-- sequencer "instruction" type
|
|
|
type PROG_T is record
|
type PROG_T is record
|
-- sub-program starting address
|
-- sub-program starting address
|
SADR : natural range 0 to 65536-1;
|
SADR : natural range 0 to 65536-1;
|
-- I/O mode selector
|
-- I/O mode selector
|
IO_MODE : std_logic_vector(2-1 downto 0);
|
IO_MODE : std_logic_vector(2-1 downto 0);
|
-- number of words to transfer when in read/write mode
|
-- number of words to transfer when in read/write mode
|
IO_COUNT : natural range 0 to 2048-1;
|
IO_COUNT : natural range 0 to MAX_IO_COUNT-1;
|
-- I/O address selector
|
-- I/O address selector
|
IO_ASEL : std_logic_vector(3-1 downto 0);
|
IO_ASEL : std_logic_vector(3-1 downto 0);
|
-- halt when sub-program ends
|
-- halt when sub-program ends
|
HALT : std_logic;
|
HALT : std_logic;
|
end record;
|
end record;
|
|
|
-- sequencer "program" type
|
-- sequencer "program" type
|
|
|
type PROG_SEQ_T is array (integer range <>) of PROG_T;
|
type PROG_SEQ_T is array (integer range <>) of PROG_T;
|
|
|
-- sequencer "program" list
|
-- sequencer "program" list
|
|
|
-- The following sub-programs are available:
|
-- The following sub-programs are available:
|
-- a) "init only" initializes channel state.
|
-- a) "init only" initializes channel state.
|
-- b) "restore state" restore channel state from ext. memory.
|
-- b) "restore state" restore channel state from ext. memory.
|
-- c) "run decoding only" performs encoding/decoding of a single packet,
|
-- c) "run decoding only" performs encoding/decoding of a single packet,
|
-- and save channel state to ext. memory.
|
-- and save channel state to ext. memory.
|
-- d) "run encoding only" performs encoding/decoding of a single packet,
|
-- d) "run encoding only" performs encoding/decoding of a single packet,
|
-- and save channel state to ext. memory.
|
-- and save channel state to ext. memory.
|
-- e) "run" performs encoding/decoding of a single packet,
|
-- e) "run" performs encoding/decoding of a single packet,
|
-- and save channel state to ext. memory.
|
-- and save channel state to ext. memory.
|
-- f) "save state" save channel state to ext. memory.
|
-- f) "save state" save channel state to ext. memory.
|
--
|
--
|
-- Sub-programs "a" and "b" are mutually exclusive: "a" must
|
-- Sub-programs "a" and "b" are mutually exclusive: "a" must
|
-- be used before encoding/decoding the first packet of a
|
-- be used before encoding/decoding the first packet of a
|
-- conversation, while "b" must be used on following packets.
|
-- conversation, while "b" must be used on following packets.
|
|
|
constant PROG_SEQ_q : PROG_SEQ_T(0 to 40-1) := (
|
constant MAX_PROG : natural := 40;
|
|
|
|
constant PROG_SEQ_q : PROG_SEQ_T(0 to MAX_PROG-1) := (
|
--
|
--
|
-- "init only" sub-program
|
-- "init only" sub-program
|
--
|
--
|
(INIT_DEC,IO_NONE,0,"000",'0'),
|
(INIT_DEC,IO_NONE,0,"000",'0'),
|
(INIT_COD,IO_NONE,0,"000",'1'),
|
(INIT_COD,IO_NONE,0,"000",'1'),
|
--
|
--
|
-- "restore state" sub-program
|
-- "restore state" sub-program
|
--
|
--
|
(STATE_IN,IO_WRITE,1679,"100",'1'), -- write-in channel state
|
(STATE_IN,IO_WRITE,1679,"100",'1'), -- write-in channel state
|
--
|
--
|
-- "run decoding-only" sub-program
|
-- "run decoding-only" sub-program
|
--
|
--
|
(DEC_DATA_IN,IO_WRITE,5,"010",'0'), -- write-in encoded frame
|
(DEC_DATA_IN,IO_WRITE,5,"010",'0'), -- write-in encoded frame
|
(MAIN_DEC1,IO_NONE,0,"000",'0'),
|
(MAIN_DEC1,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPINIT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPINIT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPUPDT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPUPDT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPEND,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPEND,IO_NONE,0,"000",'0'),
|
(MAIN_DEC3,IO_NONE,0,"000",'0'),
|
(MAIN_DEC3,IO_NONE,0,"000",'0'),
|
(DEC_DATA_OUT,IO_READ,80,"011",'1'), -- read-out output samples
|
(DEC_DATA_OUT,IO_READ,80,"011",'1'), -- read-out output samples
|
--
|
--
|
-- "run encoding-only" sub-program
|
-- "run encoding-only" sub-program
|
--
|
--
|
(DATA_IN,IO_WRITE,80,"000",'0'), -- write-in input samples
|
(DATA_IN,IO_WRITE,80,"000",'0'), -- write-in input samples
|
(MAIN_COD1,IO_NONE,0,"000",'0'),
|
(MAIN_COD1,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_INIT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_INIT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_UPDT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_UPDT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(UPDATE,IO_NONE,0,"000",'0'),
|
(UPDATE,IO_NONE,0,"000",'0'),
|
(MAIN_COD3,IO_NONE,0,"000",'0'),
|
(MAIN_COD3,IO_NONE,0,"000",'0'),
|
(COD_DATA_OUT,IO_READ,5,"001",'1'), -- read-out encoded frame
|
(COD_DATA_OUT,IO_READ,5,"001",'1'), -- read-out encoded frame
|
--
|
--
|
-- "run" sub-program
|
-- "run" sub-program
|
--
|
--
|
(DEC_DATA_IN,IO_WRITE,5,"010",'0'), -- write-in encoded frame
|
(DEC_DATA_IN,IO_WRITE,5,"010",'0'), -- write-in encoded frame
|
(MAIN_DEC1,IO_NONE,0,"000",'0'),
|
(MAIN_DEC1,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPINIT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPINIT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPUPDT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPUPDT,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPBODY,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPEND,IO_NONE,0,"000",'0'),
|
(DECOD_LD8A_LOOPEND,IO_NONE,0,"000",'0'),
|
(MAIN_DEC3,IO_NONE,0,"000",'0'),
|
(MAIN_DEC3,IO_NONE,0,"000",'0'),
|
(DEC_DATA_OUT,IO_READ,80,"011",'0'), -- read-out output samples
|
(DEC_DATA_OUT,IO_READ,80,"011",'0'), -- read-out output samples
|
(DATA_IN,IO_WRITE,80,"000",'0'), -- write-in input samples
|
(DATA_IN,IO_WRITE,80,"000",'0'), -- write-in input samples
|
(MAIN_COD1,IO_NONE,0,"000",'0'),
|
(MAIN_COD1,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_INIT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_INIT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_UPDT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP_UPDT,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(BIG_LOOP,IO_NONE,0,"000",'0'),
|
(UPDATE,IO_NONE,0,"000",'0'),
|
(UPDATE,IO_NONE,0,"000",'0'),
|
(MAIN_COD3,IO_NONE,0,"000",'0'),
|
(MAIN_COD3,IO_NONE,0,"000",'0'),
|
(COD_DATA_OUT,IO_READ,5,"001",'1'), -- read-out encoded frame
|
(COD_DATA_OUT,IO_READ,5,"001",'1'), -- read-out encoded frame
|
--
|
--
|
-- "save state" sub-program
|
-- "save state" sub-program
|
--
|
--
|
(STATE_OUT,IO_READ,1679,"100",'1') -- read-out channel state
|
(STATE_OUT,IO_READ,1679,"100",'1') -- read-out channel state
|
);
|
);
|
|
|
-- ASIP memory data-in/out and state buffers address
|
-- ASIP memory data-in/out and state buffers address
|
constant STATE_ADR : natural := 0;
|
constant STATE_ADR : natural := 0;
|
constant DEC_SADR : natural := 1692; -- dec_datain
|
constant DEC_SADR : natural := 1692; -- dec_datain
|
constant DEC_DADR : natural := 1547; -- dec_synth
|
constant DEC_DADR : natural := 1547; -- dec_synth
|
constant COD_SADR : natural := 160; -- new_speech
|
constant COD_SADR : natural := 160; -- new_speech
|
constant COD_DADR : natural := 1692; -- dec_datain
|
constant COD_DADR : natural := 1692; -- dec_datain
|
|
|
-- Controller state type
|
-- Controller state type
|
|
|
type TEST_STATE_T is (
|
type TEST_STATE_T is (
|
TS_IDLE,
|
TS_IDLE,
|
TS_NEXT,
|
TS_NEXT,
|
TS_WAIT1,
|
TS_WAIT1,
|
TS_READ,
|
TS_READ,
|
TS_WRITE,
|
TS_WRITE,
|
TS_RUN,
|
TS_RUN,
|
TS_WAIT2,
|
TS_WAIT2,
|
TS_WAIT3,
|
TS_WAIT3,
|
TS_WAIT4,
|
TS_WAIT4,
|
TS_WAIT5,
|
TS_WAIT5,
|
TS_WAIT6
|
TS_WAIT6
|
);
|
);
|
|
|
signal TS,TS_q : TEST_STATE_T;
|
signal TS,TS_q : TEST_STATE_T;
|
signal PROG_CNT_q : natural;
|
signal PROG_CNT_q : natural range 0 to MAX_PROG-1;
|
signal PROG_FIRST : natural;
|
signal PROG_FIRST : natural range 0 to MAX_PROG-1;
|
signal PROG_NEXT : std_logic;
|
signal PROG_NEXT : std_logic;
|
signal PROG_LAST : std_logic;
|
signal PROG_LAST : std_logic;
|
signal IO_MODE : std_logic_vector(2-1 downto 0);
|
signal IO_MODE : std_logic_vector(2-1 downto 0);
|
signal IO_COUNT : natural;
|
signal IO_COUNT : natural range 0 to MAX_IO_COUNT-1;
|
signal IO_ASEL : std_logic_vector(3-1 downto 0);
|
signal IO_ASEL : std_logic_vector(3-1 downto 0);
|
signal A_STRT,A_STRT_q : std_logic;
|
signal A_STRT,A_STRT_q : std_logic;
|
signal D_STRT,D_STRT_q : std_logic;
|
signal D_STRT,D_STRT_q : std_logic;
|
signal BSY,BSY_q : std_logic;
|
signal BSY,BSY_q : std_logic;
|
signal D_WE : std_logic;
|
signal D_WE : std_logic;
|
signal A_DMAE : std_logic;
|
signal A_DMAE : std_logic;
|
signal A_ADR : unsigned(ALEN-1 downto 0);
|
signal A_ADR : unsigned(ALEN-1 downto 0);
|
signal PROG_SUB : PROG_T;
|
signal PROG_SUB : PROG_T;
|
signal STS,STS_q : std_logic_vector(3-1 downto 0);
|
signal STS,STS_q : std_logic_vector(3-1 downto 0);
|
|
|
begin
|
begin
|
|
|
---------------------------------------------------
|
---------------------------------------------------
|
-- Control FSM
|
-- Control FSM
|
---------------------------------------------------
|
---------------------------------------------------
|
|
|
process(CLK_i)
|
process(CLK_i)
|
begin
|
begin
|
if(CLK_i = '1' and CLK_i'event) then
|
if(CLK_i = '1' and CLK_i'event) then
|
if(RST_i = '1') then
|
if(RST_i = '1') then
|
TS_q <= TS_IDLE;
|
TS_q <= TS_IDLE;
|
A_STRT_q <= '0';
|
A_STRT_q <= '0';
|
D_STRT_q <= '0';
|
D_STRT_q <= '0';
|
BSY_q <= '0';
|
BSY_q <= '0';
|
STS_q <= STS_IDLE;
|
STS_q <= STS_IDLE;
|
else
|
else
|
TS_q <= TS;
|
TS_q <= TS;
|
A_STRT_q <= A_STRT;
|
A_STRT_q <= A_STRT;
|
D_STRT_q <= D_STRT;
|
D_STRT_q <= D_STRT;
|
BSY_q <= BSY;
|
BSY_q <= BSY;
|
STS_q <= STS;
|
STS_q <= STS;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
process(TS_q,STRT_i,A_BSY_i,PROG_LAST,D_BSY_i,IO_MODE,IO_ASEL)
|
process(TS_q,STRT_i,A_BSY_i,PROG_LAST,D_BSY_i,IO_MODE,IO_ASEL)
|
begin
|
begin
|
|
|
A_STRT <= '0';
|
A_STRT <= '0';
|
D_STRT <= '0';
|
D_STRT <= '0';
|
PROG_NEXT <= '0';
|
PROG_NEXT <= '0';
|
BSY <= '1';
|
BSY <= '1';
|
STS <= STS_IDLE;
|
STS <= STS_IDLE;
|
|
|
case TS_q is
|
case TS_q is
|
|
|
-- wait for a new packet to be processed
|
-- wait for a new packet to be processed
|
when TS_IDLE =>
|
when TS_IDLE =>
|
if(STRT_i = '1') then
|
if(STRT_i = '1') then
|
TS <= TS_WAIT4;
|
TS <= TS_WAIT4;
|
else
|
else
|
-- do nothing
|
-- do nothing
|
BSY <= '0';
|
BSY <= '0';
|
TS <= TS_IDLE;
|
TS <= TS_IDLE;
|
end if;
|
end if;
|
|
|
-- 1-cycle delay to init. sub-program counter
|
-- 1-cycle delay to init. sub-program counter
|
when TS_WAIT4 =>
|
when TS_WAIT4 =>
|
TS <= TS_WAIT5;
|
TS <= TS_WAIT5;
|
|
|
-- 1-cycle delay to read sub-prog. ROM
|
-- 1-cycle delay to read sub-prog. ROM
|
when TS_WAIT5 =>
|
when TS_WAIT5 =>
|
-- check if first sub-prog. is of I/O-type
|
-- check if first sub-prog. is of I/O-type
|
if(IO_MODE /= IO_NONE) then
|
if(IO_MODE /= IO_NONE) then
|
-- start avalon data port operations
|
-- start avalon data port operations
|
D_STRT <= '1';
|
D_STRT <= '1';
|
else
|
else
|
-- start ASIP execution
|
-- start ASIP execution
|
A_STRT <= '1';
|
A_STRT <= '1';
|
end if;
|
end if;
|
TS <= TS_WAIT1;
|
TS <= TS_WAIT1;
|
|
|
-- start next sub-program execution
|
-- start next sub-program execution
|
when TS_NEXT =>
|
when TS_NEXT =>
|
if(IO_MODE /= IO_NONE) then
|
if(IO_MODE /= IO_NONE) then
|
-- start avalon data port operations
|
-- start avalon data port operations
|
D_STRT <= '1';
|
D_STRT <= '1';
|
else
|
else
|
-- start ASIP execution
|
-- start ASIP execution
|
A_STRT <= '1';
|
A_STRT <= '1';
|
end if;
|
end if;
|
TS <= TS_WAIT1;
|
TS <= TS_WAIT1;
|
|
|
-- it takes one cycle to get info about
|
-- it takes one cycle to get info about
|
-- sub-program to be executed, so that
|
-- sub-program to be executed, so that
|
-- checks are delayed to TS_WAIT1 state.
|
-- checks are delayed to TS_WAIT1 state.
|
|
|
-- check I/O mode
|
-- check I/O mode
|
when TS_WAIT1 =>
|
when TS_WAIT1 =>
|
if(IO_MODE = IO_READ) then
|
if(IO_MODE = IO_READ) then
|
-- sub-program is of READ type
|
-- sub-program is of READ type
|
TS <= TS_READ;
|
TS <= TS_READ;
|
elsif(IO_MODE = IO_WRITE) then
|
elsif(IO_MODE = IO_WRITE) then
|
-- sub-program is of WRITE type
|
-- sub-program is of WRITE type
|
TS <= TS_WRITE;
|
TS <= TS_WRITE;
|
else
|
else
|
-- sub-program is if computing type
|
-- sub-program is if computing type
|
TS <= TS_WAIT3;
|
TS <= TS_WAIT3;
|
end if;
|
end if;
|
|
|
when TS_WAIT3 =>
|
when TS_WAIT3 =>
|
TS <= TS_RUN;
|
TS <= TS_RUN;
|
|
|
-- read data out of ASIP memory
|
-- read data out of ASIP memory
|
when TS_READ =>
|
when TS_READ =>
|
if(D_BSY_i = '0') then
|
if(D_BSY_i = '0') then
|
TS <= TS_WAIT2;
|
TS <= TS_WAIT2;
|
else
|
else
|
if(IO_ASEL = "001") then
|
if(IO_ASEL = "001") then
|
STS <= STS_COD_DOUT;
|
STS <= STS_COD_DOUT;
|
elsif(IO_ASEL = "011") then
|
elsif(IO_ASEL = "011") then
|
STS <= STS_DEC_DOUT;
|
STS <= STS_DEC_DOUT;
|
else
|
else
|
STS <= STS_STT_DOUT;
|
STS <= STS_STT_DOUT;
|
end if;
|
end if;
|
TS <= TS_READ;
|
TS <= TS_READ;
|
end if;
|
end if;
|
|
|
-- write data into ASIP memory
|
-- write data into ASIP memory
|
when TS_WRITE =>
|
when TS_WRITE =>
|
if(D_BSY_i = '0') then
|
if(D_BSY_i = '0') then
|
TS <= TS_WAIT2;
|
TS <= TS_WAIT2;
|
else
|
else
|
if(IO_ASEL = "000") then
|
if(IO_ASEL = "000") then
|
STS <= STS_COD_DIN;
|
STS <= STS_COD_DIN;
|
elsif(IO_ASEL = "010") then
|
elsif(IO_ASEL = "010") then
|
STS <= STS_DEC_DIN;
|
STS <= STS_DEC_DIN;
|
else
|
else
|
STS <= STS_STT_DIN;
|
STS <= STS_STT_DIN;
|
end if;
|
end if;
|
TS <= TS_WRITE;
|
TS <= TS_WRITE;
|
end if;
|
end if;
|
|
|
-- run sub-program not performing I/O
|
-- run sub-program not performing I/O
|
when TS_RUN =>
|
when TS_RUN =>
|
if(A_BSY_i = '0') then
|
if(A_BSY_i = '0') then
|
TS <= TS_WAIT2;
|
TS <= TS_WAIT2;
|
else
|
else
|
STS <= STS_PRUN;
|
STS <= STS_PRUN;
|
TS <= TS_RUN;
|
TS <= TS_RUN;
|
end if;
|
end if;
|
|
|
when TS_WAIT2 =>
|
when TS_WAIT2 =>
|
PROG_NEXT <= '1';
|
PROG_NEXT <= '1';
|
if(PROG_LAST = '1') then
|
if(PROG_LAST = '1') then
|
TS <= TS_IDLE;
|
TS <= TS_IDLE;
|
else
|
else
|
TS <= TS_WAIT6;
|
TS <= TS_WAIT6;
|
end if;
|
end if;
|
|
|
when TS_WAIT6 =>
|
when TS_WAIT6 =>
|
TS <= TS_NEXT;
|
TS <= TS_NEXT;
|
|
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
---------------------------------------------------
|
---------------------------------------------------
|
-- Program sequencer
|
-- Program sequencer
|
---------------------------------------------------
|
---------------------------------------------------
|
|
|
-- index of first sub-program to be executed
|
-- index of first sub-program to be executed
|
-- (used to initialize sub-program counter).
|
-- (used to initialize sub-program counter).
|
|
|
process(OPS_i)
|
process(OPS_i)
|
begin
|
begin
|
case OPS_i is
|
case OPS_i is
|
when INIT => PROG_FIRST <= 0;
|
when INIT => PROG_FIRST <= 0;
|
when RUND => PROG_FIRST <= 3;
|
when RUND => PROG_FIRST <= 3;
|
when RUNC => PROG_FIRST <= 12;
|
when RUNC => PROG_FIRST <= 12;
|
when RUNF => PROG_FIRST <= 21;
|
when RUNF => PROG_FIRST <= 21;
|
when SAVS => PROG_FIRST <= 39;
|
when SAVS => PROG_FIRST <= 39;
|
when others => PROG_FIRST <= 2;
|
when others => PROG_FIRST <= 2;
|
end case;
|
end case;
|
end process;
|
end process;
|
|
|
-- sub-program counter
|
-- sub-program counter
|
process(CLK_i)
|
process(CLK_i)
|
begin
|
begin
|
if(CLK_i = '1' and CLK_i'event) then
|
if(CLK_i = '1' and CLK_i'event) then
|
if(RST_i = '1') then
|
if(RST_i = '1') then
|
PROG_CNT_q <= 0;
|
PROG_CNT_q <= 0;
|
elsif(STRT_i = '1') then
|
elsif(STRT_i = '1') then
|
PROG_CNT_q <= PROG_FIRST;
|
PROG_CNT_q <= PROG_FIRST;
|
elsif(PROG_NEXT = '1' and PROG_LAST = '0') then
|
elsif(PROG_NEXT = '1' and PROG_LAST = '0') then
|
PROG_CNT_q <= PROG_CNT_q + 1;
|
PROG_CNT_q <= PROG_CNT_q + 1;
|
end if;
|
end if;
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- "program" memory is used as a sync. ROM indexed
|
-- "program" memory is used as a sync. ROM indexed
|
-- by sub-program counter.
|
-- by sub-program counter.
|
|
|
process(CLK_i)
|
process(CLK_i)
|
begin
|
begin
|
if(CLK_i = '1' and CLK_i'event) then
|
if(CLK_i = '1' and CLK_i'event) then
|
PROG_SUB <= PROG_SEQ_q(PROG_CNT_q);
|
PROG_SUB <= PROG_SEQ_q(PROG_CNT_q);
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- extract sub-program info
|
-- extract sub-program info
|
|
|
process(PROG_SUB)
|
process(PROG_SUB)
|
begin
|
begin
|
SADR_o <= to_unsigned(PROG_SUB.SADR,ALEN);
|
SADR_o <= to_unsigned(PROG_SUB.SADR,ALEN);
|
IO_MODE <= PROG_SUB.IO_MODE;
|
IO_MODE <= PROG_SUB.IO_MODE;
|
IO_COUNT <= PROG_SUB.IO_COUNT;
|
IO_COUNT <= PROG_SUB.IO_COUNT;
|
IO_ASEL <= PROG_SUB.IO_ASEL;
|
IO_ASEL <= PROG_SUB.IO_ASEL;
|
PROG_LAST <= PROG_SUB.HALT;
|
PROG_LAST <= PROG_SUB.HALT;
|
if(PROG_SUB.IO_MODE = IO_WRITE) then
|
if(PROG_SUB.IO_MODE = IO_WRITE) then
|
D_WE <= '1';
|
D_WE <= '1';
|
else
|
else
|
D_WE <= '0';
|
D_WE <= '0';
|
end if;
|
end if;
|
if(PROG_SUB.IO_MODE /= IO_NONE) then
|
if(PROG_SUB.IO_MODE /= IO_NONE) then
|
A_DMAE <= '1';
|
A_DMAE <= '1';
|
else
|
else
|
A_DMAE <= '0';
|
A_DMAE <= '0';
|
end if;
|
end if;
|
end process;
|
end process;
|
|
|
-- burst length (for ASIP DMA operations)
|
-- burst length (for ASIP DMA operations)
|
BLEN_o <= IO_COUNT;
|
BLEN_o <= IO_COUNT;
|
|
|
-- address selector (for ASIP DMA operations)
|
-- address selector (for ASIP DMA operations)
|
ASEL_o <= IO_ASEL;
|
ASEL_o <= IO_ASEL;
|
|
|
-- check enable flag (for ASIP)
|
-- check enable flag (for ASIP)
|
CHKE_o <= SIMULATION_ONLY when (IO_MODE = IO_NONE) else '0';
|
CHKE_o <= SIMULATION_ONLY when (IO_MODE = IO_NONE) else '0';
|
|
|
D_WE_o <= D_WE;
|
D_WE_o <= D_WE;
|
|
|
-- DMA-enable flag
|
-- DMA-enable flag
|
A_DMAE_o <= A_DMAE;
|
A_DMAE_o <= A_DMAE;
|
|
|
-- select source/destination (ASIP memory) address for DMA transfers
|
-- select source/destination (ASIP memory) address for DMA transfers
|
process(PROG_SUB)
|
process(PROG_SUB)
|
variable N : natural;
|
variable N : natural;
|
begin
|
begin
|
case PROG_SUB.IO_ASEL is
|
case PROG_SUB.IO_ASEL is
|
when "000" => N := COD_SADR;
|
when "000" => N := COD_SADR;
|
when "001" => N := COD_DADR;
|
when "001" => N := COD_DADR;
|
when "010" => N := DEC_SADR;
|
when "010" => N := DEC_SADR;
|
when "011" => N := DEC_DADR;
|
when "011" => N := DEC_DADR;
|
when others => N := STATE_ADR;
|
when others => N := STATE_ADR;
|
end case;
|
end case;
|
A_ADR <= to_unsigned(N,ALEN);
|
A_ADR <= to_unsigned(N,ALEN);
|
end process;
|
end process;
|
|
|
---------------------------------------------------
|
---------------------------------------------------
|
-- outputs
|
-- outputs
|
---------------------------------------------------
|
---------------------------------------------------
|
|
|
A_STRT_o <= A_STRT_q;
|
A_STRT_o <= A_STRT_q;
|
A_ADR_o <= A_ADR;
|
A_ADR_o <= A_ADR;
|
D_STRT_o <= D_STRT_q;
|
D_STRT_o <= D_STRT_q;
|
BSY_o <= BSY_q;
|
BSY_o <= BSY_q;
|
STS_o <= STS_q;
|
STS_o <= STS_q;
|
|
|
end ARC;
|
end ARC;
|
|
|