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

Subversion Repositories saturn

[/] [saturn/] [trunk/] [IPCommunication/] [layer2_rx.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 DavidRAMBA
--============================================================================= 
2
--  TITRE : LAYER2_RX
3
--  DESCRIPTION : 
4
--       Analyse les trames reçues sur le port rx
5
--       Décapsule la partie Layer 2 et calcule le CRC
6
--       Note : les fanions, et l'adresse TID ne sont pas envoyées
7
--       dans le flux de sortie mais le CRC oui
8
--       Limitation : Il faut au moins 1 pulse de clk_sys au niveau '0' entre 2 
9
--       pulses de clk_sys à 1 du validant de donnée entrante val_in
10
 
11
--  FICHIER :        layer2_rx.vhd 
12
--=============================================================================
13
--  CREATION 
14
--  DATE              AUTEUR    PROJET  REVISION 
15
--  10/04/2014  DRA        SATURN       V1.0 
16
--=============================================================================
17
--  HISTORIQUE  DES  MODIFICATIONS :
18
--  DATE              AUTEUR    PROJET  REVISION 
19
--=============================================================================
20
 
21
LIBRARY IEEE;
22
USE IEEE.STD_LOGIC_1164.ALL;
23
USE IEEE.STD_LOGIC_ARITH.ALL;
24
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
25
 
26
entity layer2_rx is
27
   GENERIC (
28
      nbbit_div : INTEGER := 10);   -- Nombre de bits pour coder le diviseur d'horloge 
29
   PORT (
30
      -- Ports système
31
      clk_sys  : IN  STD_LOGIC;                    -- Clock système
32
      rst_n    : IN  STD_LOGIC;                    -- Reset général système
33
      ad_mio   : IN  STD_LOGIC_VECTOR(7 DOWNTO 0); -- Adresse logique du MIO (TID)
34
 
35
      -- Interfaces ves le module SWITCH
36
      sw_ena   : OUT  STD_LOGIC;                   -- Indique qu'on est entre 2 trames (autorise le switch du tx)
37
      dat_in   : IN  STD_LOGIC_VECTOR(7 DOWNTO 0); -- Donnée parallélisée reçue sur port rx
38
      val_in   : IN  STD_LOGIC;                    -- validant du bus dat_in
39
      tc_divclk: IN  STD_LOGIC_VECTOR (nbbit_div-1 DOWNTO 0);  -- Diviseur d'horloge pour la durée d'un bit série
40
 
41
      -- Interfaces vers le module FRAME_STORE
42
      sof      : OUT  STD_LOGIC;                   -- Indique au module suivant le début d'une trame en réception
43
      eof      : OUT  STD_LOGIC;                   -- Indique au module suivant la fin d'une trame en réception
44
      l2_ok    : OUT  STD_LOGIC;                   -- Indique que la trame reçue est correcte d'un point de vue layer 2
45
      dat_out  : OUT  STD_LOGIC_VECTOR(7 downto 0);-- Données de la couche applicative (épurée de la couche layer 2)
46
      val_out  : OUT  STD_LOGIC                    -- Validant du bus dat_out
47
      );
48
end layer2_rx;
49
 
50
architecture  rtl of layer2_rx is
51
   -- Buffer prenant la valeur du flux de sortie
52
   SIGNAL   dat_out_buf: STD_LOGIC_VECTOR(7 downto 0);
53
 
54
   -- Timer de réception entre 2 mots reçus. Le compteur doit pouvoir mesurer 16 bits. 
55
   -- La durée de 1 bit est codé sur nbbit_div
56
   SIGNAL   cpt_timer: STD_LOGIC_VECTOR(nbbit_div+4-1 DOWNTO 0);
57
   SIGNAL   timeout  : STD_LOGIC;                  -- Indique que la timer s'est écoulé
58
 
59
   SIGNAL   fanion_recu : STD_LOGIC;                  -- A 1 pour mémoriser qu'on a reçu un fanion
60
   SIGNAL   rec_encours : STD_LOGIC;                  -- A 1 pour indiquer qu'une trame est en cours d'analyse          
61
   SIGNAL   crc      : STD_LOGIC_VECTOR(15 downto 0); -- Valeur dynamique du crc
62
   SIGNAL   val_crc  : STD_LOGIC;                     -- Validant pour mettre à jour le CCRC
63
   SIGNAL   init_crc : STD_LOGIC;                     -- Initialise le calcul du CRC
64
 
65
   SIGNAL   cpt_byt  : STD_LOGIC_VECTOR(1 downto 0);  -- Pour comtper les premiers octets reçus dans la trame
66
   SIGNAL   adest_ok : STD_LOGIC;                     -- A 1 lorsque la trame s'adresse à ce MIO
67
 
68
   -- Machine d'état de gestion du module
69
   TYPE layer2_rx_type IS (idle_st, rec_st, destuf_st, endnok_st, endok_st, newdat_st);
70
   SIGNAL fsm_layer2_rx       : layer2_rx_type;
71
 
72
   -- Module de calcul du CRC16
73
        COMPONENT crc16
74
   GENERIC (
75
      poly : STD_LOGIC_VECTOR(15 downto 0) := x"1021"   -- CCITT16 par défaut
76
      );
77
        PORT(
78
                clk_sys  : IN std_logic;
79
                rst_n    : IN std_logic;
80
                data     : IN std_logic_vector(7 downto 0);
81
                val      : IN std_logic;
82
                init     : IN std_logic;
83
                crc      : OUT std_logic_vector(15 downto 0)
84
                );
85
        END COMPONENT;
86
 
87
BEGIN
88
   --------------------------------------------
89
   -- Timer entre la réception de 2 mots consécutifs
90
   --------------------------------------------
91
   timer : PROCESS(clk_sys, rst_n)
92
   BEGIN
93
      IF (rst_n = '0') THEN
94
         cpt_timer <= (others => '0');
95
         timeout <= '0';
96
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
97
         IF (val_in = '1') THEN
98
         -- Pour chaque mot reçu
99
            cpt_timer <= (others => '0');
100
            timeout <= '0';
101
         ELSE
102
         -- Entre 2 mots reçus
103
            cpt_timer <= cpt_timer + 1;      -- On compte les clk_sys écoulés
104
            IF (cpt_timer = (tc_divclk & "0000")) THEN
105
            -- Lorsque le comtpeur a mesuré un temps équivalent à 16 bits
106
               timeout <= '1';               -- On déclare un timeout (la trame en cours de réception doit être annumée)
107
            END IF;
108
         END IF;
109
      END IF;
110
   END PROCESS;
111
 
112
   --------------------------------------------
113
   -- Machine d'état d'analyse du flux
114
   --------------------------------------------
115
   -- Le déclenchement du timeout annule la réception d'une trame 
116
   man_fsm : PROCESS(clk_sys, rst_n)
117
   BEGIN
118
      IF (rst_n = '0') THEN
119
         fsm_layer2_rx <= idle_st;
120
         init_crc <= '1';
121
         val_crc <= '0';
122
         val_out <= '0';
123
         cpt_byt <= "00";
124
         eof <= '0';
125
         sof <= '0';
126
         l2_ok <= '0';
127
         adest_ok <= '0';
128
         rec_encours <= '0';
129
         dat_out_buf <= (others => '0');
130
 
131
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
132
         CASE fsm_layer2_rx IS
133
            WHEN idle_st =>
134
            -- Etat transitoire de remise à 0
135
               init_crc <= '1';
136
               val_crc <= '0';
137
               val_out <= '0';
138
               cpt_byt <= "00";
139
               eof <= '0';
140
               sof <= '0';
141
               l2_ok <= '0';
142
               adest_ok <= '0';
143
               rec_encours <= '0';
144
               fanion_recu <= '0';
145
               fsm_layer2_rx <= rec_st;
146
 
147
            WHEN rec_st =>
148
            -- Etat d'attente des caractères
149
               val_out <= '0';            -- On s'assure que les validants ne dure qu'1 pulse
150
               sof <= '0';
151
               val_crc <= '0';
152
               init_crc <= '0';
153
               IF (val_in = '1') THEN
154
               -- Sur chaque donnée reçue
155
                  IF (dat_in = x"7E") THEN
156
                  -- Si on a reçu un fanion
157
                     fanion_recu <= '1';        -- On mémorise le fait d'avori reçu un fanion
158
                     IF (rec_encours = '1') THEN
159
                     -- Si on reçoit un fanion et qu'on est en réception de trame, alors c'est le fanion de fin de trame
160
                        IF (crc(15 downto 0) = x"470F") THEN
161
                        -- Si le crc est égal au magic number, on valide la trame
162
                           fsm_layer2_rx <= endok_st;
163
                        ELSE
164
                        -- Sinon on annule la trame
165
                           fsm_layer2_rx <= endnok_st;
166
                        END IF;
167
                     -- Tant qu'on a reçu aucun octet, on ne considère pas les fanions
168
                     END IF;
169
                  ELSIF (fanion_recu = '1') THEN
170
                  -- Si on recoit une donnée autre qu'un fanion et qu'on a déjà reçu un fanion, c'est une donnée utile
171
                     rec_encours <= '1';              -- On est au milieu d'une trame
172
                     IF (dat_in = x"7D") THEN
173
                     -- Si c'est un mot de bourage, on va attendre le mot suivant
174
                        fsm_layer2_rx <= destuf_st;
175
                     ELSE
176
                     -- Si c'est une donnée normale, on la traite
177
                        dat_out_buf <= dat_in;     -- On mémorise la donnée à traiter pour l'état suivant
178
                        fsm_layer2_rx <= newdat_st;
179
                     END IF;
180
                  END IF;
181
               ELSIF (timeout = '1') THEN
182
               -- S'il s'est écoulé plus de 16 bits depuis le dernier mot reçu
183
                  IF (rec_encours = '1') THEN
184
                  -- Si on était en cours de réception de trame
185
                     fsm_layer2_rx <= endnok_st;      -- On va traiter une erreur
186
                  ELSIF (fanion_recu = '1') THEN
187
                  -- Si on avait juste reçu des fanions, 
188
                     fsm_layer2_rx <= idle_st;        -- On réinit la machine
189
                  END IF;
190
                  -- Si ona rien reçu, on reste dans cet état
191
               END IF;
192
 
193
            WHEN newdat_st =>
194
            -- Etat de traitement d'un nouveau caractère reçu (hors Fanion)
195
               IF (timeout = '1') THEN
196
               -- En cas de timeout ici on va gérer l'erreur
197
                  fsm_layer2_rx <= endnok_st;
198
               ELSE
199
                  fsm_layer2_rx <= rec_st;     -- Quand on aura fini de traiter on ira attendre le mot suivant
200
                  val_crc <= '1';              -- La valeur reçues doit être prise en comtpe dans le CRC
201
                  val_out <= adest_ok;         -- On n'envoie pas l'@. On n'envoie rien si le MIO n'est pas concerné
202
 
203
                  IF (cpt_byt = "01") THEN     -- On n'envoie au module suivant que le flux à partir du 2 ème octet
204
                     sof <= adest_ok;          -- Le premier octet indique également le début de trame au module suivant
205
                  END IF;
206
                  IF (cpt_byt /= "10") THEN
207
                  -- On ne compte que les 2 premiers octets
208
                     cpt_byt <= cpt_byt + 1;
209
                  END IF;
210
                  IF (cpt_byt = "00") THEN     -- Le premier octet indique l'adresse de destination de la trame
211
                     IF ((dat_out_buf = ad_mio) OR (dat_out_buf = x"90") OR (dat_out_buf = x"FF")) THEN
212
                     -- Le MIO peut être adressé directement (ad_mio) ou bien en multicast (90h ou FFh)
213
                        adest_ok <= '1';
214
                     ELSE
215
                        adest_ok <=  '0';
216
                     END IF;
217
                  END IF;
218
               END IF;
219
 
220
            WHEN destuf_st =>
221
            -- Etat de gestion du destuffing. On a reçu un caratère 7Dh
222
               IF (timeout = '1') THEN
223
                  fsm_layer2_rx <= endnok_st;
224
               ELSE
225
                  IF (val_in = '1') THEN
226
                  -- On attend le caractère suivant. On fonction du stuffing on fourni la bonne donnée
227
                     IF (dat_in = x"5E") THEN
228
                     -- Si l'octet de stfuffing est 5E
229
                        dat_out_buf <= x"7E";         -- La donnée utile est 7E
230
                        fsm_layer2_rx <= newdat_st;   -- On va la traiter
231
                     ELSIF (dat_in = x"5D") THEN
232
                     -- Si l'octet de stfuffing est 5E
233
                        dat_out_buf <= x"7D";         -- La donnée utile est 7D
234
                        fsm_layer2_rx <= newdat_st;   -- On va la traiter
235
                     ELSE
236
                     -- Si le stuffing est ni 5E ni 5D, c'est un cas d'erreur
237
                        fsm_layer2_rx <= endnok_st;
238
                     END IF;
239
                  END IF;
240
               END IF;
241
 
242
            WHEN endnok_st =>
243
            -- Cas de réception d'une mauvaise trame
244
               eof <= '1';          -- On indique la fin de réception au module suivant pour que l'information trame erronée soit
245
                                    -- reportée pour comptage
246
               l2_ok <= '0';        -- On indique qu'il y'a eu un problème
247
               rec_encours <= '0';  -- On est plus en réception de trame
248
               fanion_recu <= '0';
249
               fsm_layer2_rx <= idle_st;
250
 
251
            WHEN endok_st =>
252
            -- Cas de réception d'une bonne trame
253
               eof <= '1';          -- On indique la fin de réception (l'information bonne trame est
254
                                    -- aussi utilisée pour vérouiller l'autobaudrate)
255
               l2_ok <= '1';        -- On indique que la trame est bonne
256
               rec_encours <= '0';  -- On est plus en réception de trame
257
               fanion_recu <= '0';
258
               fsm_layer2_rx <= idle_st;
259
 
260
            WHEN OTHERS =>
261
               fsm_layer2_rx <= idle_st;
262
         END CASE;
263
      END IF;
264
   END PROCESS;
265
   dat_out <= dat_out_buf;       -- Flux de données déstuffé vers le module suivant
266
   sw_ena <=  NOT(rec_encours OR fanion_recu);   -- Le switch est autorisé entre 2 trames (i.e. lorsqu'une réception n'est pas en cours)
267
 
268
   --------------------------------------------
269
   -- Calcul du crc16
270
   --------------------------------------------
271
        inst_crc16: crc16
272
   GENERIC MAP (
273
      poly => x"1021"   -- CCITT16
274
      )
275
   PORT MAP(
276
                clk_sys => clk_sys,
277
                rst_n => rst_n,
278
                data => dat_out_buf,
279
                val => val_crc,
280
                init => init_crc,
281
                crc => crc
282
        );
283
 
284
end rtl;
285
 

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.