Σχεδιασμός και Υλοποίηση Πρωτοκόλλου mac για Παθητικά Οπτικά Δίκτυα gpon




старонка17/25
Дата канвертавання24.04.2016
Памер2.32 Mb.
1   ...   13   14   15   16   17   18   19   20   ...   25

-- the core, afifo_dba. When compiling the wrapper file, be sure to

-- reference the XilinxCoreLib VHDL simulation library. For detailed

-- instructions, please refer to the "Coregen Users Guide".
-- The synopsys directives "translate_off/translate_on" specified

-- below are supported by XST, FPGA Express, Exemplar and Synplicity

-- synthesis tools. Ensure they are correct for your synthesis tool(s).
-- synopsys translate_off

LIBRARY ieee;

USE ieee.std_logic_1164.ALL;
Library XilinxCoreLib;

ENTITY afifo_dba IS

port (

din: IN std_logic_VECTOR(19 downto 0);



wr_en: IN std_logic;

wr_clk: IN std_logic;

rd_en: IN std_logic;

rd_clk: IN std_logic;

ainit: IN std_logic;

dout: OUT std_logic_VECTOR(19 downto 0);

full: OUT std_logic;

empty: OUT std_logic;

rd_ack: OUT std_logic;

wr_ack: OUT std_logic);

END afifo_dba;
ARCHITECTURE afifo_dba_a OF afifo_dba IS
component wrapped_afifo_dba

port (


din: IN std_logic_VECTOR(19 downto 0);

wr_en: IN std_logic;

wr_clk: IN std_logic;

rd_en: IN std_logic;

rd_clk: IN std_logic;

ainit: IN std_logic;

dout: OUT std_logic_VECTOR(19 downto 0);

full: OUT std_logic;

empty: OUT std_logic;

rd_ack: OUT std_logic;

wr_ack: OUT std_logic);

end component;


-- Configuration specification

for all : wrapped_afifo_dba use entity XilinxCoreLib.async_fifo_v4_0(behavioral)

generic map(

c_use_blockmem => 1,

c_rd_count_width => 2,

c_has_wr_ack => 1,

c_has_almost_full => 0,

c_has_wr_err => 0,

c_wr_err_low => 0,

c_wr_ack_low => 0,

c_data_width => 20,

c_enable_rlocs => 0,

c_rd_err_low => 0,

c_wr_count_width => 2,

c_rd_ack_low => 0,

c_has_rd_count => 0,

c_has_almost_empty => 0,

c_has_rd_ack => 1,

c_has_wr_count => 0,

c_fifo_depth => 127,

c_has_rd_err => 0);

BEGIN
U0 : wrapped_afifo_dba

port map (

din => din,

wr_en => wr_en,

wr_clk => wr_clk,

rd_en => rd_en,

rd_clk => rd_clk,

ainit => ainit,

dout => dout,

full => full,

empty => empty,

rd_ack => rd_ack,

wr_ack => wr_ack);

END afifo_dba_a;
-- synopsys translate_on

-------------------------------------------

-- GIANT Project

-- NTUA


-------------------------------------------

-- Date Start:

-------------------------------------------

-- Design Unit Name : multiplexer of flags for DBA

-- Purpose : This entity demultiplexes the output of the

-- DBA_Rx towards the TC3 and TC4 flag regions.

--

-- File Name : mux_dba.vhd



-------------------------------------------

-------------------------------------------

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

use ieee.std_logic_arith.all;


entity mux_dba is

port(
--dba_report_rx i/f

cs : in std_logic;

we : in std_logic;

ack : out std_logic;

addr : in std_logic_vector(5 downto 0);

data_to_flags : in std_logic_vector (15 downto 0);

data_from_flags : out std_logic_vector (15 downto 0);

selection : in std_logic; --'0' for tcont3 region

--'1' for tcont4 region

--tcont3_flags region i/f

cs_flags3 : out std_logic;

we_flags3 : out std_logic;

ack_flags3 : in std_logic;

addr_flags3 : out std_logic_vector(5 downto 0);

data_to_flags3 : out std_logic_vector(15 downto 0);

data_from_flags3: in std_logic_vector(15 downto 0);

--tcont4_flags region i/f

cs_flags4 : out std_logic;

we_flags4 : out std_logic;

ack_flags4 : in std_logic;

addr_flags4 : out std_logic_vector(5 downto 0);

data_to_flags4 : out std_logic_vector(15 downto 0);

data_from_flags4: in std_logic_vector(15 downto 0)

);

end entity;


architecture mux_dba_a of mux_dba is
begin
main_proc : process(selection, cs, we, ack_flags3, addr, data_to_flags,

data_from_flags3, ack_flags4, data_from_flags4) is

begin

we_flags3 <= we;



we_flags4 <= we;

ack <= ack_flags3 or ack_flags4;

addr_flags3 <= addr;

addr_flags4 <= addr;

data_to_flags3 <= data_to_flags;

data_to_flags4 <= data_to_flags;

cs_flags3 <= cs and (not selection);

cs_flags4 <= cs and selection;

if selection='1' then

data_from_flags <= data_from_flags4;

else

data_from_flags <= data_from_flags3;



end if;

end process main_proc;

end architecture mux_dba_a;

------------------------------------------

-- GIANT Project

-- NTUA


-------------------------------------------

-------------------------------------------

-- Design Unit Name : sbw_ti

-- Purpose : Inspects the T-CONT 3 and 4 requests and checks the relevant minSDI timer to decide whether an

-- AllocID of TCONT 3 or 4 type is eligible for surplus bandwidth assignment.

--

-- File Name : sbw_ti.vhd



-------------------------------------------

-------------------------------------------

-- Description

-----------------------------------------

-- This entity scans the T-CONT 3 flags (indicating existence of pending requests) in a round robin way and when all T-CONT 3 requests have been inspected the

-- it starts scanning the T-CONT 4 flags. For each risen flag detected, the repsective minSDI value is checked. It this is equal to zero, the relevant AllocID is forwarded

-- to sbw_ts for service, and the relevant min sDI value is set equal to the min SDI parameter of the ALlocID.

-------------------------------------------

-- Design note:

-- 1. This entity starts working when the sbw_tu entity has completed the update of the min SDI timers, and the

-- "fclk" called here have both been asserted. It is stressed that the fclk is not connected to the GMAC Fclk signal

-- but to a signal of the asp indicating that the surplus allocation can start.

-- 2. Stall inspection signal indicates that the sbw_ts is servicing an ALlocID and cannot receive request for

-- another AllocID. Stall inspection will remain high, if the frame bytes have been exhausted and no more AllocIDs

-- can be assigned surplus bandwidth.

--

----------------------------------------------------------------------------



-----------------------------------------------------------------------

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_arith.all;

use IEEE.std_logic_unsigned.all;
entity sbw_ti is

port(


clk : in std_logic;

rstn : in std_logic;


--asp i/f

fclk : in std_logic; --this comes from "asp" entity, and may be renamed to "trigger_sbw" in general

--tcont3_flags i/f

tcont3_we : out std_logic;

tcont3_en : out std_logic;

tcont3_addr : out std_logic_vector(5 downto 0);

tcont3_din : in std_logic_vector(15 downto 0);

tcont3_dout : out std_logic_vector(15 downto 0);

tcont3_rdy : in std_logic;

--tcont4_flags i/f

tcont4_we : out std_logic;

tcont4_en : out std_logic;

tcont4_addr : out std_logic_vector(5 downto 0);

tcont4_din : in std_logic_vector(15 downto 0);

tcont4_dout : out std_logic_vector(15 downto 0);

tcont4_rdy : in std_logic;


--- sbw tu i/f

SDItimers_updated: in std_logic;

--minsdi mem a i/f

mema_addr : out std_logic_vector(9 downto 0);

mema_en : out std_logic;

mema_we : out std_logic;

mema_din : in std_logic_vector(14 downto 0); --input from memory 1

mema_dout : out std_logic_vector(14 downto 0); --output to memory 1

--minsdi mem b i/f

memb_addr : out std_logic_vector(9 downto 0);

memb_en : out std_logic;

memb_din : in std_logic_vector(14 downto 0);

--sbw_ts i/f

allocID_valid : out std_logic;

allocID : out std_logic_vector(9 downto 0);

stall_inspection : in std_logic;

flags_inspected : out std_logic
);

end entity;


architecture sbw_ti_a of sbw_ti is
type TStates is (IDLE,

TC3_FLAGS_FETCH, TC3_FLAGS_STORE, TC3_FLAGS_INSPECTION, TC3_FLAGS_NEXT,

TC4_FLAGS_FETCH, TC4_FLAGS_STORE, TC4_FLAGS_INSPECTION, TC4_FLAGS_NEXT,

FETCH_MINSDI, WAIT_TIMERS, STORE_MINSDI, CHECK_MINSDI,

RELEASE_ALLOCID, extra_release, check_inspection,

STALLED);

signal current_state, next_state : TStates;

signal tcont3_addr_s : std_logic_vector(5 downto 0);

signal tcont3_addr_start : std_logic_vector(5 downto 0);

signal tcont4_addr_s : std_logic_vector(5 downto 0);

signal tcont4_addr_start : std_logic_vector(5 downto 0);

signal allocID_reg : std_logic_vector(9 downto 0);

signal tcont_data_temp_reg : std_logic_vector(15 downto 0);

signal tc3_tc4 : std_logic_vector(1 downto 0); --if "10" then we have tc3 inspection, else "01"

signal mema_minsdi_reg : std_logic_vector(14 downto 0);

signal memb_minsdi_reg : std_logic_vector(14 downto 0);

signal pending_allocId : std_logic;

signal start : std_logic;

signal enable : std_logic_vector(1 downto 0);
begin

---- unconditional assignments -----------------------------

tcont3_we <= '0';

tcont3_dout <= (others => '0');

tcont4_we <= '0';

tcont4_dout <= (others => '0');


----------------------------------------------------------------------

process (clk, rstn) is

begin
if rstn = '0' then

current_state <= IDLE;

elsif rising_edge(clk) then

current_state <= next_state;

end if;

end process;



----------------------------------------------------------------------

tc_fsm_proc: process( current_state, start, fclk,

tcont3_rdy,tcont4_rdy,

tcont_data_temp_reg, tcont3_addr_s,

tcont4_addr_s,

tc3_tc4,

mema_minsdi_reg, memb_minsdi_reg,

pending_allocId,

stall_inspection,

tcont3_addr_start, tcont4_addr_start

) is

begin


case current_state is

when IDLE =>

if start='1' then

next_state <= TC3_FLAGS_FETCH;

else

next_state <= IDLE;



end if;

-------------------- T CONT 3 -------------------------

when TC3_FLAGS_FETCH =>

next_state <= TC3_FLAGS_STORE;

when TC3_FLAGS_STORE =>

if tcont3_rdy = '1' then

next_state <= TC3_FLAGS_INSPECTION;

else


next_state <= TC3_FLAGS_STORE;

end if;


when TC3_FLAGS_INSPECTION =>

for i in 0 to 15 loop

if tcont_data_temp_reg(i) = '1' then

next_state <= FETCH_MINSDI;

exit;

else


next_state <= TC3_FLAGS_NEXT;

end if;


end loop;

when TC3_FLAGS_NEXT =>

if tcont3_addr_s = tcont3_addr_start then

next_state <= TC4_FLAGS_FETCH;

else

next_state <= TC3_FLAGS_FETCH;



end if;

-------------------- T CONT 4 -------------------------

when TC4_FLAGS_FETCH =>

next_state <= TC4_FLAGS_STORE;

when TC4_FLAGS_STORE =>

if tcont4_rdy = '1' then

next_state <= TC4_FLAGS_INSPECTION;

else


next_state <= TC4_FLAGS_STORE;

end if;


when TC4_FLAGS_INSPECTION =>

for i in 0 to 15 loop

if tcont_data_temp_reg(i) = '1' then

next_state <= FETCH_MINSDI;

exit;

else


next_state <= TC4_FLAGS_NEXT;

end if;


end loop;

when TC4_FLAGS_NEXT =>

if tcont4_addr_s = tcont4_addr_start then

next_state <= IDLE;

else

next_state <= TC4_FLAGS_FETCH;



end if;

----------------- MIN SDI -------------------------

when FETCH_MINSDI =>

next_state<=WAIT_TIMERS;

when WAIT_TIMERS =>

next_state <= STORE_MINSDI;

when STORE_MINSDI =>

next_state <= CHECK_MINSDI;

when CHECK_MINSDI =>

if stall_inspection = '1' then

next_state <= STALLED;

else


if mema_minsdi_reg(12 downto 0) = "0000000000000" and memb_minsdi_reg(14 downto 13)="11" then

next_state <= RELEASE_ALLOCID;

else

if tc3_tc4 = "10" then



next_state <= TC3_FLAGS_INSPECTION;

else


next_state <= TC4_FLAGS_INSPECTION;

end if;


end if;

end if;
-------------------- OUTPUT -------------------------

when RELEASE_ALLOCID =>

next_state<=extra_release;

when extra_release =>

next_state<=check_inspection;

when check_inspection =>

if fclk='1' then -- previous frame bytes were exhausted, hence new frame enables the sbw ti operation

next_state<=idle;

elsif stall_inspection = '1' then --- wait until sbw_ts finishes its operation

next_state <= check_inspection; -- STALLED;

else -- sbw_ts finished its operation

if tc3_tc4 = "10" then

next_state <= TC3_FLAGS_INSPECTION;

else

next_state <= TC4_FLAGS_INSPECTION;



end if;

end if;


-------------------- STALLED -------------------------

when STALLED =>

if fclk='1' then

next_state<=idle;

elsif stall_inspection = '0' then -- this should never happen

if tc3_tc4 = "10" then

next_state <= TC3_FLAGS_INSPECTION;

else


next_state <= TC4_FLAGS_INSPECTION;

end if;


else

next_state<=stalled;

end if;

when OTHERS =>



next_state <= IDLE;

end case;

end process tc_fsm_proc;

----------------------------------------------------------------------


tc_out_proc: process(clk, rstn) is

begin
if rstn = '0' then

tcont3_en <= '0';

tcont3_addr <= (others => '0');

tcont3_addr_s <= (others => '0');

tcont3_addr_start <= (others => '0');

tcont4_en <= '0';

tcont4_addr <= (others => '0');

tcont4_addr_s <= (others => '0');

tcont4_addr_start <= (others => '0');

tcont_data_temp_reg <= (others => '0');

allocID_reg <= (others => '0');

tc3_tc4 <= "00";

mema_minsdi_reg <= (others => '0');

memb_minsdi_reg <= (others => '0');

mema_en <= '0';

memb_en <= '0';

mema_we <= '0';

mema_addr <= (others => '0');

memb_addr <= (others => '0');

mema_dout <= (others => '0');

allocID_valid <= '0';

allocID <= (others => '0');

flags_inspected <= '0';

pending_allocId<='0';
elsif rising_edge(clk) then

flags_inspected <= '0';

allocID_valid <= '0';

-- for the initialisation of the round robin in every frame --------

if fclk='1' then

if pending_allocID='0' then

tcont3_addr_start <= tcont3_addr_s;

tcont4_addr_start <= tcont4_addr_s;

else

if tc3_tc4="10" then



tcont3_addr_start <= tcont3_addr_s-1;

tcont4_addr_start <= tcont4_addr_s;

else

tcont3_addr_start <= tcont3_addr_s;



tcont4_addr_start <= tcont4_addr_s-1;

end if;


end if;

end if;


if current_state = CHECK_MINSDI and stall_inspection = '1' then

pending_allocId<='1';

elsif stall_inspection = '0' then

pending_allocId<='0';

end if;

case current_state is



when IDLE =>

tc3_tc4 <= "10";

-------------------- T CONT 3 -------------------------

when TC3_FLAGS_FETCH =>

tcont3_en <= '1';

tcont3_addr <= tcont3_addr_s;

when TC3_FLAGS_STORE =>

tcont3_en <= '0';

if tcont3_rdy = '1' then

tcont_data_temp_reg <= tcont3_din;

tcont3_addr_s <=tcont3_addr_s+1;

end if;


when TC3_FLAGS_INSPECTION =>

mema_en <= '0';

memb_en <= '0';

mema_we <= '0';

memb_addr <= (others =>'0'); -- to avoid conflict with mem initialiser

for i in 0 to 15 loop

if tcont_data_temp_reg(i) = '1' then

allocID_reg(3 downto 0) <= conv_std_logic_vector(i, 4);

allocID_reg(9 downto 4) <= tcont3_addr_s-1;

tcont_data_temp_reg(i) <= '0';

exit;

else


null;

end if;


end loop;

when TC3_FLAGS_NEXT =>

if tcont3_addr_s = tcont3_addr_start then

tc3_tc4 <= "01";

end if;

-------------------- T CONT 4 -------------------------



when TC4_FLAGS_FETCH =>

tcont4_en <= '1';

tcont4_addr <= tcont4_addr_s;

tcont4_we <= '0';

when TC4_FLAGS_STORE =>

tcont4_en <= '0';

if tcont4_rdy = '1' then

tcont_data_temp_reg <= tcont4_din;

tcont4_addr_s<=tcont4_addr_s+1;

end if;


when TC4_FLAGS_INSPECTION =>

mema_en <= '0';

memb_en <= '0';

mema_we <= '0';

memb_addr <= (others =>'0'); -- to avoid conflict with mem initialiser

for i in 0 to 15 loop

if tcont_data_temp_reg(i) = '1' then

allocID_reg(3 downto 0) <= conv_std_logic_vector(i, 4);

allocID_reg(9 downto 4) <= tcont4_addr_s-1;

tcont_data_temp_reg(i) <= '0';

exit;

else


null;

end if;


end loop;

when TC4_FLAGS_NEXT =>

if tcont4_addr_s = tcont4_addr_start then

tc3_tc4 <= "10";

flags_inspected <= '1';

end if;


-------------------- MIN SDI -------------------------

when FETCH_MINSDI =>

mema_en <= '1';

mema_we <= '0';

memb_en <= '1';

memb_addr <= allocID_reg;

mema_addr <= allocID_reg;

when WAIT_TIMERS =>

mema_en <= '0';

memb_en <= '0';

memb_addr <= (others =>'0'); -- to avoid conflict with mem initialiser

when STORE_MINSDI =>

mema_minsdi_reg <= mema_din;

memb_minsdi_reg <= memb_din;

when CHECK_MINSDI =>

if stall_inspection = '0' then

if mema_minsdi_reg(12 downto 0) = "0000000000000" and memb_minsdi_reg(14 downto 13)="11" then

allocID_valid <= '1';

mema_en <= '1';

mema_we <= '1';

mema_dout <= memb_minsdi_reg;

allocID <= allocID_reg;

end if;

end if;


when RELEASE_ALLOCID =>

allocID_valid <= '0';

mema_we<='0';

mema_en <='0';

allocID <= (others => '0');

when STALLED =>

if fclk='1' then

tc3_tc4 <= "10";

if pending_allocID='1' then

if tc3_tc4="10" then

tcont3_addr_s<=tcont3_addr_s-1;

else


tcont4_addr_s<=tcont4_addr_s-1;

end if;


end if;

end if;


when OTHERS =>

null;


end case;

end if;
end process tc_out_proc;


----------------------------------------------------------------------

----------------------------------------------------------------------

sbw_ti_enable_proc: process (clk, rstn) is

begin
if rstn = '0' then

enable<="00";

start<='0';

elsif rising_edge(clk) then

if fclk='1' then

enable(1)<='1';

elsif current_state=TC3_FLAGS_FETCH then

enable(1)<='0';

end if;


if SDItimers_updated='1' then

enable(0)<='1';

elsif current_state=TC3_flags_fetch then

enable(0)<='0';

end if;
if enable="11" then

start<='1';

else

start<='0';



end if;

end if;


end process;

----------------------------------------------------------------------

end architecture sbw_ti_a;

-------------------------------------------

-- GIANT Project

-- NTUA


-------------------------------------------

--------------------------------------------------------------------

-- Design Unit Name : sbw_ts

-- Purpose : This entity is responsible to service the AllocID of TC3 or TC4 type

-- that previously has been detected by "sbw_ti" entity (This means that

-- pending requests for this AllocID exist.)

--

-- File Name : sbw_ts.vhd



--------------------------------------------------------------------

-- Description

-- The operation is similar to that of the gbw_ts. The difference are:

-- 1. The ALlocIDs to be serviced are delivered by the sbw_ti and are not found in a FIFO.

-- 2. The ONU service is not triggered to see whether a PLOAM has to be assigned.

-- 3. It stalls sbw_ti until it is checked that unassigned bytes exist in the frame.

--

---------------------------------------------------------------------------------------



-- IMPORTANT NOTE

-- In case that an AllocId should be assigned a bytes but less bytes are available in the frame, then

-- if the available bytes are more than a minimum_surplus_allocation (which is a constant), then the AllocID

-- is assigned the available bytes. If not, it will be serviced in the next frame that more available bytes

-- will exist.

--

--------------------------------------------------------------------------



-- Design notes

-- 1. The access of BAP and REQUEST MATRIX are made in parallel

--------------------------------------------------------------------

-- Design improvement

-- The calculation of the Allocation bytes requires a huge combinatorial circuit. Hence, it the design

-- is to be accelerated or to support higher clock frequency this should be revisited.

--------------------------------------------------------------------

--------------------------------------------------------------------

-- BW_Allocation_Parameters table format ( B A P )

-- __________________________________________________________________________________

-- | PB reports: Residence_ONU : NSR : T-CONT : PCBu : FEC : AllocID activated : MaxTB : MinTB|

--(bits)| 1 :______7________|______ |____3___|___2__|__1__|_________1_________|___16__|___16_|

-- | 47 |46 40|39 |38 36|35 34| 33 | 32 |31 16|15 0|

-- |____________|_______________|_______|________|______|_____|___________________|_______|______|

--------------------------------------------------------------------

-- Format of Access Structure

--

-- bits 12 12 16 16 8



-- ______________________________________

-- | AllocID | Flags| Start | Stop | CRC |

-- |__________|______|_ptr___|_ptr__|_____| Flags = PLSu(1) + PLOAM(1) + FEC(1) + PCBu(2) + Rsv(7) = 12

-- |63 52|51 40|39 24|23 8|7 0|

----------------------------------------------------------------------

----------------------------------------------------------------------

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

use IEEE.std_logic_arith.all;


----------------------------

entity sbw_ts is

port(

clk : IN std_logic;



rstn : IN std_logic;

fclk : IN std_logic;

ts_enable : IN std_logic; --from asp entity
--SBW_ti i/f

allocID_valid : in std_logic;

allocID : in std_logic_vector(9 downto 0); --allocid from sbw timer_inspection entity

1   ...   13   14   15   16   17   18   19   20   ...   25


База данных защищена авторским правом ©shkola.of.by 2016
звярнуцца да адміністрацыі

    Галоўная старонка