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




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

-- 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;


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

entity gbw_ts is

port(

clk : IN std_logic;



rstn : IN std_logic;

fclk : IN std_logic;


--gbw_ti i/f

allocID_fetch : out std_logic; --timers fifo rd

allocID_valid : in std_logic;

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

fifo_empty : in std_logic; --inspection_completed

--bap & reqmat access

mem_req : out std_logic; --a request to bap_arbiter & reqmat_arbiter in the same time

mem_addr : out std_logic_vector(9 downto 0);


--bap i/f

bap_we : out std_logic;

bap_valid : in std_logic;

bap_param : in std_logic_vector(47 downto 0);


--reqmat i/f

reqmat_we : out std_logic;

reqmat_valid : in std_logic;

reqmat_param : in std_logic_vector(20 downto 0);


--ONU_service i/f

ONU_service_req : out std_logic; --if '1', a request for PLSu, PLOAM from ONU_service

--ONU_service_onuid is the same with GBWonuID

PLSu_PLOAM_valid : in std_logic;

PLSu_PLOAM_flags : in std_logic_vector(1 downto 0);
------ to update reqmat ----------------------------

allocation_bytes :out std_logic_vector(15 downto 0);

update_reqmat_cmd :out std_logic;

request :out std_logic_vector(20 downto 0);

t_cont :out std_logic_vector(1 downto 0);

--asp i/f

GBWstruct_RDY : out std_logic;

GBWstruct_allocid : out std_logic_vector(9 downto 0);

GBWonu_id : out std_logic_vector(7 downto 0);

GBWalloc_bytes : out std_logic_vector(15 downto 0);

GBWpcbu_fec : out std_logic_vector(5 downto 0); -- Unassigned (1) + NSR(1) + Whole ONU reports (1) + reporting mode(2) + FEC(1)

GBWplsu_PLOAM : out std_logic_vector(1 downto 0);

Available_bytes : in std_logic_vector(14 downto 0);

GBW_assigned : out std_logic --guaranteed bandwidth has been assigned, notify the access structure preparation entity

);

end entity gbw_ts;



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

architecture gbw_ts_a of gbw_ts is

type TStates is (IDLE,

FETCH_ALLOCID, --from fifo

RDY2ALLOC_GBW, --RDY2ALLOC_GBW=ready to allocate bandwidth

WAIT_MEM_RESPONSE, --obtaining and processing bap information

wait_PLSu_PLOAM,

PREPARE_GBWStruct, --preparing access structures

deliver_GBWstruct,

wait_new_frame,

close_gbw

);

signal current_state, next_state : TStates;



constant NSR_fixed_allocation : std_logic_vector(15 downto 0) := X"0040";

constant FEC_NSR_fixed_allocation : std_logic_vector(15 downto 0) := X"0050";

constant PLSu_length : std_logic_vector(15 downto 0) := X"0078";

constant PLOAM_length : std_logic_vector(15 downto 0) := X"000D";

constant DBRu_length : std_logic_vector(15 downto 0) := X"0002";

constant unassigned : std_logic_vector(9 downto 0) :="0011111111";

signal bap_param_reg : std_logic_vector(20 downto 0); --the width is not as long as bap info, since Max TB is not needed

signal reqmat_param_reg : std_logic_vector(20 downto 0);

signal bap_valid_flag, reqmat_valid_flag : std_logic;

signal GBWAlloc_bytes_int : std_logic_vector(15 downto 0);

signal NSR : std_logic;

signal GBW_assigned_int : std_logic;

signal fec_enabled : std_logic;

signal pbrep : std_logic;

begin

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



GBWAlloc_bytes<=GBWAlloc_bytes_int;

bap_we <= '0';

reqmat_we<= '0';

GBWonu_id(7)<='0';

request<=reqmat_param_reg;

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


process(clk, rstn) --process

begin


if rstn = '0' then

current_state <= IDLE;

elsif rising_edge(clk) then

current_state <= next_state;

end if;

end process;


gbwts_fsm_comb_pr: process(current_state, fclk, allocID_valid, PLSu_PLOAM_valid,

bap_valid_flag, fifo_empty, reqmat_valid_flag,

gbwalloc_bytes_int, available_bytes) is --process

begin


case current_state is

when IDLE =>

if fclk = '1' then

if fifo_empty='0' then

next_state <= FETCH_ALLOCID;

else


next_state <= close_gbw;

end if;


else

next_state <= IDLE;

end if;

when FETCH_ALLOCID =>



next_state <= RDY2ALLOC_GBW;

when RDY2ALLOC_GBW =>

if allocID_valid = '1' then

next_state <= WAIT_MEM_RESPONSE;

else

next_state <= RDY2ALLOC_GBW;



end if;

when WAIT_MEM_RESPONSE =>

if bap_valid_flag = '1' and reqmat_valid_flag = '1' then

next_state <= wait_PLSu_PLOAM;

else

next_state <= WAIT_MEM_RESPONSE;



end if;

when wait_PLSu_PLOAM =>

if PLSu_PLOAM_valid='1' then

next_state <=PREPARE_GBWStruct;

else

next_state <= wait_PLSu_PLOAM;



end if;

when PREPARE_GBWStruct =>

next_state <= deliver_GBWstruct;

when DELIVER_GBWSTRUCT =>

if (not (gbwalloc_bytes_int

next_state<=WAIT_NEW_FRAME;

elsif fifo_empty='1' then

next_state <= CLOSE_GBW;

else

next_state<=FETCH_ALLOCID;



end if;

when CLOSE_GBW=>

next_state<=IDLE;

when WAIT_NEW_FRAME =>

if fclk='1' then

next_state<=DELIVER_GBWSTRUCT;

else

next_state<=WAIT_NEW_FRAME;



end if;

when OTHERS =>

next_state <= IDLE;

end case;

end process;
output_proc:process(clk, rstn) is --process

begin


if rstn = '0' then

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

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

bap_valid_flag <= '0';

reqmat_valid_flag <= '0';

GBWstruct_RDY <= '0';

update_reqmat_cmd <= '0';

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

GBWonu_id(6 downto 0)<= (others => '0');

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

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

GBW_assigned <= '0';

ONU_service_req <= '0';

allocID_fetch <= '0';

GBWplsu_PLOAM <="00";

NSR <='0';

FEC_enabled <='0';

PBrep <='0';

GBW_assigned_int <='0';

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

mem_req <= '0';

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

t_cont <="01";

elsif rising_edge(clk) then

GBW_assigned <= GBW_assigned_int;

GBW_assigned_int <= '0';

GBWstruct_RDY <= '0';

update_reqmat_cmd <= '0';

ONU_service_req <= '0';

allocID_fetch <= '0';

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

mem_req <= '0';

case current_state is

when IDLE =>


when FETCH_ALLOCID =>

allocID_fetch <= '1';

when RDY2ALLOC_GBW =>

if allocID_valid = '1' then

GBWstruct_allocid <= allocid;

mem_addr <= allocid;

mem_req <= allocID_valid;

if allocID=unassigned then

GBWpcbu_fec(5)<='1';

else


GBWpcbu_fec(5)<='0';

end if;


end if;

when WAIT_MEM_RESPONSE =>

if bap_valid = '1' then

bap_param_reg <=bap_param(37 downto 33) & bap_param(15 downto 0);

PBrep <= bap_param(47);

NSR <= bap_param(39);

FEC_enabled <= bap_param(33);

GBWpcbu_fec(0) <= bap_param(33);

T_cont<=bap_param(37 downto 36);

GBWpcbu_fec(4)<= bap_param(39);

GBWonu_id (6 downto 0)<= bap_param(46 downto 40);

if bap_param(47)='0' then

GBWpcbu_fec(3)<=bap_param(35); -- whole ONU reporting AllocId

else


GBWpcbu_fec(3)<='0';

end if;


end if;

if reqmat_valid = '1' then

reqmat_param_reg <= reqmat_param;

end if;


if reqmat_valid = '1' then

reqmat_valid_flag <= '1';

elsif bap_valid_flag = '1' and reqmat_valid_flag = '1' then

reqmat_valid_flag <= '0';

end if;

if bap_valid = '1' then



bap_valid_flag <= '1';

elsif bap_valid_flag = '1' and reqmat_valid_flag = '1' then

bap_valid_flag <= '0';

end if;
------------- gbw allocation bytes based on AllocId parameters and requests

if bap_valid_flag = '1' and reqmat_valid_flag = '1' then

if bap_param_reg(20 downto 19) ="01" then --tcont1

gbwalloc_bytes_int <= bap_param_reg(15 downto 0); -- min TB

else -- all other T-CONTs

if NSR='1' then

if (not (reqmat_param_reg(20 downto 16)= "00000")) or (bap_param_reg(15 downto 0) < reqmat_param_reg(15 downto 0)) then -- minTB_bytes < requested_bytes

gbwalloc_bytes_int <= bap_param_reg(15 downto 0);

else -- Recall that only two request values for NSR AllocIds exist, full and zero

if FEC_enabled ='0' then

gbwalloc_bytes_int<=NSR_fixed_allocation;

else

gbwalloc_bytes_int<=FEC_NSR_fixed_allocation;



end if;

end if;


else

if (not (reqmat_param_reg(20 downto 16)= "00000")) or bap_param_reg(15 downto 0) < reqmat_param_reg(15 downto 0) then -- minTB_bytes < requested_bytes

gbwalloc_bytes_int <= bap_param_reg(15 downto 0);

else


if PBrep ='1' then --- DBRu ='1' then

if reqmat_param_reg(15 downto 0)>0 then

if FEC_enabled='1' and reqmat_param_reg(15 downto 0)<16 then

gbwalloc_bytes_int<= reqmat_param_reg(15 downto 0)+DBRu_length+16;

else

gbwalloc_bytes_int<= reqmat_param_reg(15 downto 0)+DBRu_length;



end if;

else


if FEC_enabled='0' then

gbwalloc_bytes_int<=DBRu_length;

else

gbwalloc_bytes_int<=DBRu_length+16;



end if;

end if;


else

if FEC_enabled='1' and (reqmat_param_reg(15 downto 0)<16 and reqmat_param_reg(15 downto 0)>0) then

gbwalloc_bytes_int<= reqmat_param_reg(15 downto 0)+16;

else


gbwalloc_bytes_int<= reqmat_param_reg(15 downto 0);

end if;


end if; -- PB

end if; -- relation between Min TB and request

end if; -- NSR

end if; -- T-CONTs

end if;
if bap_valid_flag = '1' and reqmat_valid_flag = '1' then

ONU_service_req <= '1';

else

ONU_service_req <= '0';



end if;

when wait_PLSu_PLOAM => -- calculation of PLSu and PLOAM bytes overhead

if PLSu_PLOAM_valid='1' then

GBWplsu_PLOAM <= PLSu_PLOAM_flags;

case PLSu_PLOAM_flags is

when "01" =>

gbwalloc_bytes_int<=gbwalloc_bytes_int+PLOAM_length;

when "10" =>

gbwalloc_bytes_int<=gbwalloc_bytes_int+PLSu_length;

when "11" =>

gbwalloc_bytes_int<=gbwalloc_bytes_int+PLSu_length+PLOAM_length;

when others =>

null;

end case;



end if;

when DELIVER_GBWSTRUCT =>

if PBrep='1' then

GBWpcbu_fec(2 downto 1)<=bap_param_reg(18 downto 17);

else

GBWpcbu_fec(2 downto 1)<="00";



end if;

if gbwalloc_bytes_int < available_bytes then

if gbwalloc_bytes_int /="0000000000000000" then

GBWstruct_RDY <= '1';

else

GBWstruct_RDY <= '0';



end if;

GBW_assigned_int<='0';

else -- the prepared allocation does not fit in the frame

GBWstruct_RDY <= '0';

GBW_assigned_int<='1';

end if;


if ((gbwalloc_bytes_int < available_bytes) and NSR='0' and (not (bap_param_reg(20 downto 19)="01"))) AND reqmat_param_reg /= "000000000000000000000" then

update_reqmat_cmd<='1';

else

update_reqmat_cmd<='0';



end if;

when CLOSE_GBW =>

GBW_assigned_int<='1';

when OTHERS =>

null;

end case;



if current_state=wait_PLSu_PLOAM and PLSu_PLOAM_valid ='0' then

if PBrep ='1' then

allocation_bytes <= gbwalloc_bytes_int-2;

else


allocation_bytes <= gbwalloc_bytes_int;

end if;


end if;
end if;
end process output_proc;

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

end architecture gbw_ts_a;

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

-- GIANT Project

-- NTUA


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

-- Design Unit Name : arbiter = bap & request matrix & flags memory arbiter

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

-- Purpose : Arbitrates the access to the memory in a priotirized way

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

-- File Name : arbiter_040206.vhd

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

-- A S S U M P T I O N S

-- 1.The A, B, C, D are assumed to be kept at the same value until the

-- requested access is completed, to avoid duplicating registers

-- A is surplus bandwitdth allocation unit

-- B is timer service unit

-- C is access structure preparation unit

-- D is dba report receiver unit

-- E is obc controller (not yet implemented)

-- 2. The A_req, Br, Cr, Dr are assumed to be active for 1 clk

-- 3. Assuming that the output data of the BAP memory are valid one clk period

-- after the request, it asserts an acknowledgement signal towards

-- the entity whose the action is executed.

-- All the X_ack signals will be activated for one clk period.

-- 4. The priorities are:

-- 1. GBW_TS

-- 2. SBW_TS

-- 3. ASP

-- 4. DBA_Rx

-- 5. OBC server

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

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

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

entity arbiter is

generic(

addr_gen : positive := 12;

mem_width_gen : positive := 48

);

port(



clk : in std_logic;

rstn : in std_logic;


--A i/f

A_addr : in std_logic_vector(addr_gen - 1 downto 0);

A_we : in std_logic;

A_req : in std_logic;

A_ack : out std_logic;

A_din : in std_logic_vector(mem_width_gen - 1 downto 0);

A_dout : out std_logic_vector(mem_width_gen - 1 downto 0);
--B i/f

B_addr : in std_logic_vector(addr_gen - 1 downto 0);

B_we : in std_logic;

B_req : in std_logic;

B_ack : out std_logic;

B_din : in std_logic_vector(mem_width_gen - 1 downto 0);

B_dout : out std_logic_vector(mem_width_gen - 1 downto 0);
--C i/f

C_addr : in std_logic_vector(addr_gen - 1 downto 0);

C_we : in std_logic;

C_req : in std_logic;

C_ack : out std_logic;

C_din : in std_logic_vector(mem_width_gen - 1 downto 0);

C_dout : out std_logic_vector(mem_width_gen - 1 downto 0);
--D i/f

D_addr : in std_logic_vector(addr_gen - 1 downto 0);

D_we : in std_logic;

D_req : in std_logic;

D_ack : out std_logic;

D_din : in std_logic_vector(mem_width_gen - 1 downto 0);

D_dout : out std_logic_vector(mem_width_gen - 1 downto 0);

--memory i/f

mem_addr : out std_logic_vector(addr_gen - 1 downto 0);

mem_en : out std_logic;

mem_we : out std_logic;

mem_dout : out std_logic_vector(mem_width_gen - 1 downto 0);

mem_din : in std_logic_vector(mem_width_gen - 1 downto 0)

);

end entity arbiter;



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

architecture arbiter_a of arbiter is


type TStates is (IDLE_state,A_state, B_state, C_state, D_state,

WAIT_mem_response );

signal current_state, next_state : TStates;

signal pending_req : std_logic_vector(3 downto 0);

signal A_addr_s, B_addr_s, C_addr_s, D_addr_s : std_logic_vector(addr_gen - 1 downto 0);

signal a_we_s, b_we_s, c_we_s, d_we_s : std_logic;

signal a_din_s, b_din_s, c_din_s, d_din_s : std_logic_vector(mem_width_gen - 1 downto 0);

signal a_service, b_service, c_service, d_service : std_logic;

signal mem_addr_s : std_logic_vector(addr_gen - 1 downto 0);

signal mem_we_s : std_logic;


begin


mem_addr <= mem_addr_s;

mem_we <= mem_we_s;

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

------------ STATE INITIALIZATION --------------------------

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

process(clk, rstn) is

begin
if rstn = '0' then

current_state <= IDLE_state;

elsif rising_edge(clk) then

current_state <= next_state;

end if;
end process;
------------------------------------------------------------

------------ FINITE STATE MACHINE --------------------------

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

state_proc : process(current_state, A_req, B_req, C_req, D_req, pending_req) is

begin
case current_state is

when IDLE_state =>

if pending_req(3) = '1' then

next_state <= A_state;

elsif pending_req(2) = '1' then

next_state <= B_state;

elsif pending_req(1) = '1' then

next_state <= C_state;

elsif pending_req(0) = '1' then

next_state <= D_state;

else

next_state <= IDLE_state;



end if;
when A_state =>

next_state <= WAIT_mem_response;

when B_state =>

next_state <= WAIT_mem_response;

when C_state =>

next_state <= WAIT_mem_response;

when D_state =>

next_state <= WAIT_mem_response;

when WAIT_mem_response =>

next_state <= IDLE_state;

when others =>

next_state <= IDLE_state;

end case;

end process state_proc;


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

------------ OUTPUT PROCESS --------------------------------

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

output_proc:process(clk,rstn) is

begin

if rstn = '0' then


pending_req <= (others => '0');
A_din_s <= (others => '0');

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

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

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


a_ack <= '0';

b_ack <= '0';

c_ack <= '0';

d_ack <= '0';

a_service <= '0';

b_service <= '0';

c_service <= '0';

d_service <= '0';


a_we_s <= '0';

b_we_s <= '0';

c_we_s <= '0';

d_we_s <= '0';

-- e_we_s <= '0';
A_addr_s <= (others => '0');

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

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

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


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

mem_en <= '0';

mem_we_s <= '0';

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


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

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

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

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


elsif rising_edge(clk) then

if A_req = '1' then

A_addr_s <= A_addr;

A_we_s <= A_we;

A_din_s <= A_din;

pending_req(3) <= '1';

end if;
if B_req = '1' then

B_addr_s <= B_addr;

B_we_s <= B_we;

B_din_s <= B_din;

pending_req(2) <= '1';

end if;
if C_req = '1' then

C_addr_s <= C_addr;

C_we_s <= C_we;

C_din_s <= C_din;

pending_req(1) <= '1';

end if;
if D_req = '1' then

D_addr_s <= D_addr;

D_we_s <= D_we;

D_din_s <= D_din;

pending_req(0) <= '1';

end if;
mem_en <= '0';

mem_we_s <= '0';

a_ack <='0';

b_ack <= '0';

c_ack <= '0';

d_ack <= '0';

case current_state is

when IDLE_state =>

scanning:for I in 3 downto 0 loop

if I = 3 and pending_req(I) = '1' then

mem_addr_s <= A_addr_s;

mem_we_s <= A_we_s;

mem_dout <= A_din_s;

mem_en <= '1';

exit scanning;

elsif I = 2 and pending_req(I) = '1' then

mem_addr_s <= B_addr_s;

mem_we_s <= B_we_s;

mem_dout <= B_din_s;

mem_en <= '1';

exit scanning;

elsif I = 1 and pending_req(I) = '1' then

mem_addr_s <= C_addr_s;

mem_we_s <= C_we_s;

mem_dout <= C_din_s;

mem_en <= '1';

exit scanning;

elsif I = 0 and pending_req(I) = '1' then

mem_addr_s <= D_addr_s;

mem_we_s <= D_we_s;

mem_dout <= D_din_s;

mem_en <= '1';

next;


end if;

end loop scanning;

when A_state =>

pending_req(3) <= '0';

a_service <= '1';

when B_state =>

pending_req(2) <= '0';

b_service <= '1';

when C_state =>

pending_req(1) <= '0';

c_service <= '1';

when D_state =>

pending_req(0) <= '0';

d_service <= '1';

when WAIT_mem_response =>

A_dout <= mem_din;

B_dout <= mem_din;

C_dout <= mem_din;

D_dout <= mem_din;

if a_service = '1' then

a_service <= '0';

a_ack<='1';

elsif b_service = '1' then

b_service <= '0';

b_ack<='1';

elsif c_service = '1' then

c_service <= '0';

c_ack<='1';

elsif d_service = '1' then

d_service <= '0';

d_ack<='1';

end if;


when others =>

null;


end case;

end if;


end process output_proc;

--

--



end architecture arbiter_a;

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

-- This file is owned and controlled by Xilinx and must be used

-- solely for design, simulation, implementation and creation of

-- design files limited to Xilinx devices or technologies. Use

-- with non-Xilinx devices or technologies is expressly prohibited

-- and immediately terminates your license.

--


-- XILINX IS PROVIDING THIS DESIGN, CODE, OR INFORMATION "AS IS"

-- SOLELY FOR USE IN DEVELOPING PROGRAMS AND SOLUTIONS FOR

1   ...   11   12   13   14   15   16   17   18   ...   25


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

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