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

Subversion Repositories saturn

[/] [saturn/] [trunk/] [FPGA Concentrateur SIL4/] [fpga_cosil4/] [con_layer2_rx.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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