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




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

6. Παράρτημα


Στο τέλος της διπλωματικής αυτής εργασίας παρατίθενται οι κώδικες, σε γλώσσα υλικού (VHDL), με τους οποίους κατασκευάσαμε τον ελεγκτή.
-------------------------------------------

-- GIANT Project

-- NTUA

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



-- Date Start: 26/8/03

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

-- Design Unit Name : SPI to Parallel converter

-- Purpose : Interface between the OBC (Motorola MPC860) that uses SPI interface

-- and the MAC OBC I/F

--

-- File Name : spi2parallel.vhd



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

-- Assumptions ----------------------

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

--

-- 1. When the MAC_cs becomes zero the circuit starts to "read" the incoming data



-- 2. Every time that the MAC_CS becomes zero, first the codeword is received,

-- second the register address and last the register data.

-- 3. Codeword=X"03" indicates write action while codeword= X"02" indicates the read ------- action.

-- If it has no data to send then it will send aces "1"

-- 4. The data is synchronized with the SPI_CLK at 12.5MHz

-- 5. Transmition IS DONE MSB first to LSB

--

-- Design note:



-- 1. Signals MAC_cs and MAC_mosi are passed through 2 FF sampled with clk (internal --- FPGA clock).

-- MAC_CS => MAC_cs_sync => MAC_cs_int

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

library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

use IEEE.std_logic_arith.all;
-------------------------------------------

entity spi2parallel is

port (

clk : in std_logic; --FPGA's clock



rstn : in std_logic; --Active Low Reset

--SPI i/f

spi_clk : in std_logic; --spi_clk

MAC_mosi : in std_logic; --spi_mosi

MAC_miso : out std_logic; --spi_miso

MAC_cs : in std_logic; --spi_sel

--parallel bus i/f

par_cs : out std_logic;

par_we : out std_logic;

par_addr : out std_logic_vector (7 downto 0); --Parallel address

par_data : out std_logic_vector (7 downto 0); --Parallel data

par2spi_addr : in std_logic_vector (7 downto 0); --Parallel address

par2spi_data : in std_logic_vector (7 downto 0) -- Parallel data

);

end entity spi2parallel;


architecture spi2parallel_a of spi2parallel is
--------------------declarations of internal signals used---------------------

signal position_counter : integer range 0 to 23; --serial2parallel counter

signal parallel_register : std_logic_vector(23 downto 0); --serial2parallel register

signal p2s_position_counter : integer range 0 to 23; --parallel to serial counter

signal p2s_parallel_register : std_logic_vector (23 downto 0); --parallel to serial register

signal spi_clk_sync : std_logic;

signal spi_clk_sync_d : std_logic;

signal MAC_cs_sync : std_logic;

signal MAC_MOSI_sync : std_logic;

signal MAC_cs_int : std_logic;

signal MAC_mosi_int : std_logic;

begin
-----------unconditional assignment of internal to external signals-----------

par_addr (7 downto 0) <= parallel_register (15 downto 8); --Parallel Address gets value

par_data (7 downto 0) <= parallel_register (7 downto 0); --Parallel Data get value


p2s_parallel_register (23 downto 8) <= X"02" & par2spi_addr (7 downto 0); --P2S parallel register gets value from addr

p2s_parallel_register (7 downto 0) <= par2spi_data (7 downto 0); --P2S parallel register gets value from data

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

-----------------------------Synchronize MAC_clk with SPI_clk-----------------

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

syncrhonize_SPI_clk_2_MAC_clk : process (clk,rstn) is

begin

if (rstn = '0') then



spi_clk_sync <='0';

spi_clk_sync_d<='0';

MAC_cs_sync <='1';

MAC_MOSI_sync <='0';

MAC_cs_int <='1';

MAC_mosi_int <='0';

elsif rising_edge(clk) then

spi_clk_sync <=spi_clk;

spi_clk_sync_d<=spi_clk_sync;

MAC_cs_sync <=MAC_cs;

MAC_MOSI_sync <=MAC_mosi;

MAC_cs_int <=MAC_cs_sync;

MAC_mosi_int<=MAC_mosi_sync;
end if;

end process;


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

serial2parallel : process (clk,rstn) is

begin

if rstn = '0' then --perform reset actions



position_counter <= 23;

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


elsif rising_edge(clk) then
if spi_clk_sync_d='1' and spi_clk_sync='0' and MAC_cs_int='0' then

parallel_register(position_counter)<=MAC_mosi_int;

end if;

if MAC_cs_int='0' then



if spi_clk_sync_d='1' and spi_clk_sync='0' then

if position_counter=0 then

position_counter<=23;

else


position_counter<=position_counter-1;

end if;


end if;

else


position_counter<=23;

end if;


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

parallel2serial : process (spi_clk_sync_d,rstn) is

begin

if rstn = '0' then



p2s_position_counter <=23;

MAC_miso <= '0';


elsif rising_edge(spi_clk_sync_d) and (MAC_cs = '0') then
MAC_miso <= p2s_parallel_register(p2s_position_counter);

if p2s_position_counter = 0 then

p2s_position_counter <= 23;

else


p2s_position_counter <= position_counter - 1;

end if;


end if;

end process;


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

------------------ Generation of CS and WE signals towards parallel_bus ------

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

cs_we_proc: process (clk,rstn) is

begin

if (rstn = '0') then



par_cs <= '0';

par_we <= '0';

elsif rising_edge(clk) then
if MAC_cs_int='0' and MAC_cs_sync='1' then

par_cs <= '1'; --select parallel entity for use...

if parallel_register (23 downto 16) = "00000010" then --X"02"

par_we <= '0';

elsif parallel_register (23 downto 16) = "00000011" then --X"03"

par_we <= '1'; --activate write

end if;

else


par_cs <= '0';

par_we <= '0';

end if;

end if;


end process;
end architecture spi2parallel_a;

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

-- GIANT Project

-- NTUA


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

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

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

-- Design Unit Name :parallel_bus

-- Purpose : This entity maintains the registers that the OBC controls.

-- It also trigers the mem_initialiser and the gbw_ti when a new

-- AllocID is activated which means that all the relevant

-- information has been received.

-- File Name : parallel_bus_040206.vhd

--

-- Notes



-- PLOAM interval: in reset it should go to 40ms.

-- Regular ranging can go to '1' at reset with a low value for regular ranging

-- intrerval, if we want the GMAC to exit the initialisation state in few

-- frames during functional debugging.

-----------------------------------------------------------------------
library ieee;

use ieee.std_logic_1164.all;

use ieee.std_logic_unsigned.all;

use ieee.std_logic_arith.all;


use work.cons_pkg.ALL;
entity parallel_bus is

generic (

allocID_gen : positive := 10;

TB_gen : positive := 16;

SDI_gen : positive := 13

);
port (

clk :in std_logic; --system clock

rstn :in std_logic; --reset negative

--SPI2Par interface

cs : in std_logic; --chip select

we : in std_logic; --Write Enable

addr : in std_logic_vector(7 downto 0); --epilogh tou register pou 8elw na diabasw

din : in std_logic_vector(7 downto 0);

addr2spipar : out std_logic_vector(7 downto 0);

dout : out std_logic_vector(7 downto 0);

--mem_initializer i/f

allocID_valid :out std_logic; --Shkwnetai otan diabasw tous

--registers efoson ACT/DEACT = 1

allocID :out std_logic_vector(10 downto 0); --0001

MaxTB :out std_logic_vector(15 downto 0); --0010

MinTB :out std_logic_vector(15 downto 0); --0011

MaxSDI :out std_logic_vector(12 downto 0); --0100

MinSDI :out std_logic_vector(12 downto 0); --0101

ResONU :out std_logic_vector(15 downto 0); --ResONU(8)+NSR + TCONT(3)+FEC_enable(1)+piggybacked (1)+Report_mode(2) --0110

ONU_info :out std_logic_vector (9 downto 0); --act/deact + onuID --0111

ONU_valid :out std_logic;

--onu_service i/f

PLOAMint :out std_logic_vector (12 downto 0); -- interval + enable --1000


--bwmap_forwarder i/f

Ranging_delay :out std_logic_vector (15 downto 0); --1001

MAC_control :out std_logic_vector (4 downto 0) --1010

);

end entity parallel_bus;


architecture struct of parallel_bus is
-- declarations of internal signals used

signal allocID_s : std_logic_vector (11 downto 0);

signal MaxTB_s : std_logic_vector (15 downto 0);

signal MinTB_s : std_logic_vector (15 downto 0);

signal MaxSDI_s : std_logic_vector (15 downto 0);

signal MinSDI_s : std_logic_vector (15 downto 0);

signal ResONU_s : std_logic_vector (15 downto 0);

signal allocID_valid_s : std_logic;

signal allocID_flag : std_logic;

signal MaxTB_flag : std_logic;

signal MinTB_flag : std_logic;

signal MaxSDI_flag : std_logic;

signal MinSDI_flag : std_logic;

signal ResONU_flag : std_logic;

signal ONU_info_s : std_logic_vector (9 downto 0);

signal ONU_valid_s : std_logic;

signal PLOAMint_s : std_logic_vector (12 downto 0);

signal Ranging_delay_s : std_logic_vector (15 downto 0);

signal MAC_control_s : std_logic_vector (4 downto 0);

signal DarkPeriod_DUR_s : std_logic_vector (2 downto 0);

signal ONU_valid_flag : std_logic;

signal activate : std_logic;

signal MAC_soft_reset:std_logic;

begin


----unconditional assignment of internal to external signals------

allocID_valid <= allocID_valid_s;

allocID(10) <= activate;

allocID(9 downto 0) <= allocID_s(9 downto 0);

MaxTB <= MaxTB_s;

MinTB <= MinTB_s;

MaxSDI <= MaxSDI_s(12 downto 0);

MinSDI <= MinSDI_s(12 downto 0);

ResONU <= ResONU_s;

addr2spipar <= addr;

ONU_info <= ONU_info_s;

ONU_valid <= ONU_valid_s;

PLOAMint <= PLOAMint_s;

Ranging_delay <= Ranging_delay_s;

MAC_control(3 downto 0) <= MAC_control_s(3 downto 0);

MAC_control(4) <=MAC_soft_reset;


--------------------------------------------------------------------
Generate_new_allocID_proc: process(clk, rstn) is

begin


if rstn = '0' then
allocID_valid_s <= '0';
elsif rising_edge(clk) then

if allocid_flag='1' and (activate='0' or

(activate='1' and MaxTB_flag = '1' and MinTB_flag = '1' and

MaxSDI_flag = '1' and MinSDI_flag = '1' and ResONU_flag = '1')) then

allocID_valid_s <= '1';

else


allocID_valid_s <= '0';

end if;


end if;

end process Generate_new_allocID_proc;

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

Generate_ONU_valid: process (clk, rstn) is

begin
if rstn = '0' then

ONU_valid_s <= '0';

elsif rising_edge(clk) then

if ONU_valid_flag = '1' then

ONU_valid_s <= '1';

else


ONU_valid_s <= '0';

end if;


end if;

end process Generate_ONU_valid;


------------------Write of internal registers--------------------

reg_write_proc: process(clk, rstn) is

begin
if (rstn = '0') then

--perform reset actions

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

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

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

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

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

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

activate <='0';

allocID_flag <= '0';

MaxTB_flag <= '0';

MinTB_flag <= '0';

MaxSDI_flag <= '0';

MinSDI_flag <= '0';

ResONU_flag <= '0';

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

ONU_valid_flag <= '0';

PLOAMint_s(0) <= '1';

PLOAMint_s(12 downto 1)<= "000000000101"; --"000101000000";

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

Ranging_delay_s(11 downto 0) <="000000000000"; -- "000101000000";

Ranging_delay_s(12) <='1';

Ranging_delay_s(15 downto 13)<="000";

MAC_control_s(4 downto 3) <= "01";

MAC_control_s(2 downto 0) <= (others => '0');

elsif rising_edge(clk) then


if (cs = '1') and (we = '1') then

-- Chip Select and Write Enable active low

case addr is

when "00000000" => --Dark Period(3)

DarkPeriod_DUR_s <= din(2 downto 0);

when "00000001" => --Act/deact(1) + AllocID(10)

activate <= din(7);

allocID_s(11 downto 5)<= din(6 downto 0);

when "00000010" =>

allocID_s(4 downto 0)<= din (7 downto 3);

allocID_flag <= '1';

when "00000011" => --Max TB(16)

MaxTB_s(15 downto 8) <= din;

when "00000100" =>

MaxTB_s(7 downto 0)<= din ;

MaxTB_flag <= '1';

when "00000101" => --Min TB(16)

MinTB_s(15 downto 8)<= din ;

when "00000110" =>

MinTB_s(7 downto 0)<= din ;

MinTB_flag <= '1';

when "00000111" => --Max SDI(16)

MaxSDI_s(15 downto 8) <= din ;

when "00001000" =>

MaxSDI_s(7 downto 0) <= din ;

MaxSDI_flag <= '1';

when "00001001" => --Min SDI(16)

MinSDI_s(15 downto 8) <= din ;

when "00001010" =>

MinSDI_s(7 downto 0) <= din ;

MinSDI_flag <= '1';

when "00001011" => --ResONU(8) + NSR(1) + TC_type(3) +

ResONU_s(15 downto 8) <= din ; -- FEC(1) + Piggy(1) + Report.Mode(2)

when "00001100" =>

ResONU_s(7 downto 0) <= din ;

ResONU_flag <= '1';

when "00001101" => --Act/deact(1) + ONU ID(8)

ONU_info_s(9 downto 2) <= din(7 downto 0);

when "00001110" =>

ONU_info_s(1 downto 0) <= din (7 downto 6);

ONU_valid_flag <= '1';

when "00001111" => --PLOAM_int(12) + RegPLOAM_en(1)

PLOAMint_s(12 downto 5) <= din(7 downto 0);

when "00010000" =>

PLOAMint_s(4 downto 0) <= din(7 downto 3);

when "00010001" => --Ranging_delay(3) + RegRanging_en(1)

-- + Ranging_distance(12)

Ranging_delay_s(15 downto 8) <= din(7 downto 0);

when "00010010" =>

Ranging_delay_s(7 downto 0) <= din(7 downto 0);

when "00010011" =>

MAC_control_s(4 downto 0) <= din(7 downto 3);

--check_reset <='1';

when others =>

null;

end case;



elsif (allocID_valid_s = '1') then --reset the registers

allocID_flag <= '0';

MaxTB_flag <= '0';

MinTB_flag <= '0';

MaxSDI_flag <= '0';

MinSDI_flag <= '0';

ResONU_flag <= '0';

else


null;

end if;
if (ONU_valid_s = '1') then

ONU_valid_flag <= '0';

end if;


end if;
end process reg_write_proc;

------------------Read of internal registers----------------------

reg_read_proc: process(clk, rstn) is

begin


if rstn ='0' then

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

elsif rising_edge(clk) then

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

case addr is

when "00000000" => --Dark Period(3)

dout <= "00000" & DarkPeriod_DUR_s;

when "00000001" => --Act/deact(1) + AllocID(10)

dout(7) <= activate;

dout(6 downto 0)<=allocID_s(11 downto 5);


when "00000010" =>

dout <= allocID_s(4 downto 0) & "000";

when "00000011" => --Max TB(16)

dout <= MaxTB_s(15 downto 8);

when "00000100" =>

dout <= MaxTB_s(7 downto 0);

when "00000101" => --Min TB(16)

dout <= MinTB_s(15 downto 8);

when "00000110" =>

dout <= MinTB_s(7 downto 0);

when "00000111" => --Max SDI(16)

dout <= MaxSDI_s(15 downto 8);

when "00001000" =>

dout <= MaxSDI_s(7 downto 0);

when "00001001" => --Min SDI(16)

dout <= MinSDI_s(15 downto 8);

when "00001010" =>

dout <= MinSDI_s(7 downto 0);

when "00001011" => --ResONU(8) + NSR(1) + TC_type(3) +

dout <= ResONU_s(15 downto 8); --FEC(1)+ Piggy(1) + Report.Mode(2)

when "00001100" =>

dout <= ResONU_s(7 downto 0);

when "00001101" => --Act/deact(1) + ONU ID(8)

dout <= ONU_info_s(9 downto 2);

when "00001110" =>

dout <= ONU_info_s(1 downto 0) & "000000";

when "00001111" => --PLOAM_int(12) + RegPLOAM_en(1)

dout <= PLOAMint_s(12 downto 5);

when "00010000" =>

dout <= PLOAMint_s(4 downto 0) & "000";

when "00010001" => --Ranging_delay(3) + RegRanging_en(1) + Ranging_distance(12)

dout <= Ranging_delay_s(15 downto 8);

when "00010010" =>

dout <= Ranging_delay_s(7 downto 0);

when "00010011" =>

dout <= MAC_control_s(4 downto 0) & "000";

when others =>

null;


end case;

end if;


end process;
soft_rst: process(clk, rstn) is

begin


if rstn ='0' then

MAC_soft_reset<='0';

elsif rising_edge(clk) then
if (cs = '1') and (we = '1') and addr ="00010011" then

MAC_soft_reset<= (din(7));

else

MAC_soft_reset<='0';



end if;

end if;


end process;

end architecture struct;

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

-- GIANT Project

-- NTUA

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



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

-- Design Unit Name : mem_initialiser

-- Purpose : Maintenance of Bandwidth Allocation Parameters (BAP) memory

-- and minSDI values memory.

--

-- File Name : mem_initialiser.vhd



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

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

-- Description

-- This entity is triggered by the parallel_bus whenever

-- 1. an AllocID has been activated. In this case, the relevant information

-- is stored in the bap and the minSDI parameters memory is written.

-- 2. an AllocID has been deactivated. In this case, the minSDI parameters

-- memory is updated.

-- 3. an ONU is activated or deactivated. In this case, the active_ONUs

-- vector is updated as well as the FEC FEC_enabled_ONUs vector. These two

-- vectors indicated the active and FEC enabled ONUs respectively.

-- 4. It generates the fclk signal. This is a signal that indicated the start

-- of a new frame, hence it is active for one clock period every 125us.

-- Design note:

--

-- 1. The access to the BAP memory is arbitrated by the bap_arbiter.



-- 2. The sdi_mem_parameters memory is accessed by the mem_intialiser and the

-- sbw_ti entities. The sbw_ti has priority in accessing the memory, hence,

-- to avoid conflicts the mem_initialiser checks whether the sbw_ti is

-- accessing the memory, checking the sbw_ti_mem_addr. When this is zero,

-- the sbw_ti is not using the memory. The latter accesses the min sdi

-- memory only when a pending request has been detected. In which case, the

-- address is different than zero for 3 clock periods. Hence, the minSDI

-- timer will be written by mem initialiser 3 clock periods latter. This is

-- of no harm, since due to the spi clock frequency, no register can change

-- in this timespan.

-- 3. The timers memories includes 2 bits indicating whether the respective

-- AllocID is active and 13 bits for the timer.

--

-- Recommended design improvement:



-- In general, this arbitration could be done through a dedicated entity.

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


library IEEE;

use IEEE.std_logic_1164.all;

use IEEE.std_logic_unsigned.all;

use IEEE.std_logic_arith.all;


use work.cons_pkg.ALL;

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

entity mem_initializer is

generic (

allocID_gen : positive := 10;

TB_gen : positive := 16;

SDI_gen : positive := 13;

sdi_mem_gen : positive := 15

);
port(

clk : in std_logic;

rstn : in std_logic;
---- Parallel bus i/f ----

AllocID_valid : in std_logic;

AllocId : in std_logic_vector (allocID_gen downto 0);

maxTB : in std_logic_vector (TB_gen - 1 downto 0);

minTB : in std_logic_vector (TB_gen - 1 downto 0);

maxSDI : in std_logic_vector (SDI_gen - 1 downto 0);

minSDI : in std_logic_vector (SDI_gen - 1 downto 0);

resONU : in std_logic_vector (15 downto 0); --ResONU(8)+ NSR(1) +

-- TCONT(3)+FEC_enable(1)+ DBA_reporting(1)+Report_Mode(2)

frame_duration : in std_logic_vector (13 downto 0); -- fixed to 9720

ONU_info : in std_logic_vector (9 downto 0); -- FEC_enabled +

-- act/deact + onuID --0111

ONU_valid : in std_logic;

--ONU service i/f

active_ONUs_ID : out std_logic_vector(127 downto 0);

FEC_enabled_ONUs: out std_logic_vector(127 downto 0);

--mem b port b i/f

sbw_memb_addrb : out std_logic_vector(allocID_gen - 1 downto 0);

sbw_memb_dinb : out std_logic_vector(sdi_mem_gen - 1 downto 0);

sbw_memb_enb : out std_logic;

sbw_memb_web : out std_logic;

----- sbw ti i/f

sbwti_addr : in std_logic_vector(allocID_gen - 1 downto 0);

--bap memory i/f

bap_en : out std_logic;

bap_we : out std_logic;

bap_addr : out std_logic_vector(allocID_gen - 1 downto 0);

bap_douta : out std_logic_vector(47 downto 0);

--to all other components

frame_number :out std_logic_vector(15 downto 0);

fclk : out std_logic

);

end entity mem_initializer;



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

architecture mem_initializer_a of mem_initializer is


constant TCONT3_con : std_logic_vector(2 downto 0) := "011";

constant TCONT4_con : std_logic_vector(2 downto 0) := "000";

constant zeros : std_logic_vector(3 downto 0) := "0000";

signal cnt : integer range 1 to 65535;

signal frame_number_s : integer range 0 to 65535;

signal fclk_int : std_logic;

signal activate : std_logic;

signal FEC_enabled_ONUs_int: std_logic_vector(127 downto 0);

signal wait_access_op : std_logic;

begin


--------------- unconditional assignments ------------------------------------
frame_number <=conv_std_logic_vector(frame_number_s, 16);

activate <=allocID(allocID_gen);

FEC_enabled_ONUs<=FEC_enabled_ONUs_int;

fclk <=fclk_int;

sbw_memb_addrb <= allocID(9 downto 0); -- allocID is the output of a register implemented in parallel bus

1   ...   9   10   11   12   13   14   15   16   ...   25


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

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