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

Subversion Repositories saturn

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 DavidRAMBA
--============================================================================= 
2
--  TITRE : CON_LAYER2_TX
3
--  DESCRIPTION : 
4
--       Encapsule la trame applicative dans une trame Layer2
5
--       Ajoute les fanions de début et de fin, effectue le byte stuffing 
6
--       et calcule le CRC
7
--  FICHIER :        layer2_tx.vhd 
8
--=============================================================================
9
--  CREATION 
10
--  DATE              AUTEUR    PROJET  REVISION 
11
--  10/04/2014  DRA        SATURN       V1.0 
12
--=============================================================================
13
--  HISTORIQUE  DES  MODIFICATIONS :
14
--  DATE              AUTEUR    PROJET  REVISION 
15
--  27/04/15   DRA      SATURN   V1.1
16
--    Suppression du test de FIFO vide dans l'état waitendsend_st. Ce temps
17
--    permettait de laisser un blanc sur la ligne pour laisser le temps 
18
--    à un noeud d'insérer sa réponse, mais la stratégie de priorité à l'anneau
19
--    fait que ce n'est plus utile
20
--=============================================================================
21
 
22
LIBRARY IEEE;
23
USE IEEE.STD_LOGIC_1164.ALL;
24
USE IEEE.STD_LOGIC_ARITH.ALL;
25
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
26
 
27
entity con_layer2_tx is
28
   PORT (
29
      -- Ports système
30
      clk_sys  : IN  STD_LOGIC;                    -- Clock système
31
      rst_n    : IN  STD_LOGIC;                    -- Reset général système
32
      stuf_phys: IN  STD_LOGIC;                    -- Ordre d'émission de caractères 7F sur la ligne
33
      acq_stuf : OUT STD_LOGIC;                    -- Indique que le stuff est fini
34
 
35
      -- Interfaces vers le module d'interface du PIC
36
      dat_in   : IN  STD_LOGIC_VECTOR(7 DOWNTO 0); -- Flux de données applicatives à émettre
37
                                                   -- La première donnée du flux qui suit le sof est l'@ de destination
38
      val_in   : IN  STD_LOGIC;                    -- validant du bus dat_in
39
      sof      : IN  STD_LOGIC;                    -- Indique le début d'une trame à émettre (non synchrone de la 1ère donnée)
40
      eof      : IN STD_LOGIC;                     -- Indique le dernier octet de la trame à émettre
41
      datin_free: OUT  STD_LOGIC;                  -- Indique que le module layer2_tx est prêt à recevoir 1 octet suivant
42
 
43
      -- Interfaces vers les FIFO de transmissions
44
      dat_out  : OUT  STD_LOGIC_VECTOR(7 downto 0);-- Flux de données Layer2 à stocker dans les FIFO Tx
45
      val_out  : OUT  STD_LOGIC;                   -- Validant du bus dat_out
46
      clr_fifo : IN   STD_LOGIC;                   -- Signal de reset des FIFO Tx
47
      progfull1: IN   STD_LOGIC;                   -- Indique la FIFO Tx1 est presque pleine
48
      progfull2: IN   STD_LOGIC;                   -- Indique la FIFO Tx2 est presque pleine
49
      full1    : IN   STD_LOGIC;                   -- Indique la FIFO Tx1 est pleine
50
      empty1   : IN   STD_LOGIC;                   -- Indique la FIFO Tx1 est vide
51
      full2    : IN   STD_LOGIC;                   -- Indique la FIFO Tx2 est pleine
52
      empty2   : IN   STD_LOGIC                    -- Indique la FIFO Tx2 est vide
53
      );
54
end con_layer2_tx;
55
 
56
architecture  rtl of con_layer2_tx is
57
   SIGNAL   crc      : STD_LOGIC_VECTOR(15 downto 0); -- Valeur dynamique du crc
58
   SIGNAL   val_crc  : STD_LOGIC;                     -- Validant du CCRC
59
   SIGNAL   init_crc : STD_LOGIC;                     -- Initialise le calcul du CRC
60
   SIGNAL   dat_crc  : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Donnée à prendre en compte pour le calcul du CRC
61
   SIGNAL   last_char: STD_LOGIC;                     -- Pour mémoriser le eof au cas ou il y'ait du stuffing sur le dernier char
62
   SIGNAL   cpt_stuf : STD_LOGIC_VECTOR(9 DOWNTO 0);  -- Pour compter les octets de stuff de ligne envoyés
63
   SIGNAL   acq_stuf_buf : STD_LOGIC;                 -- Pour indiquer la focntion de stuff en cours
64
   SIGNAL   empty1_r1, empty1_r2: STD_LOGIC;          -- Pour changer empty1 d'horloge
65
   SIGNAL   empty2_r1, empty2_r2: STD_LOGIC;          -- Pour changer empty2 d'horloge
66
 
67
   -- Machine d'état de gestion du module
68
   TYPE layer2_tx_type IS (idle_st, addest_st, data_st, fifo_full_st, stuf5E_st, stuf5D_st,
69
                           waitcrc_st, crc1_st, stufcrc1_st, crc2_st, stufcrc2_st, fanionfin_st, waitendsend_st, stuf_st, wait_stuf_st);
70
   SIGNAL fsm_layer2_tx       : layer2_tx_type;
71
 
72
   -- Module de calcul du CRC16
73
        COMPONENT crc16
74
   GENERIC (
75
      poly : STD_LOGIC_VECTOR(15 downto 0) := x"1021"
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
   acq_stuf <= acq_stuf_buf;
89
   --------------------------------------------
90
   -- Machine d'état de génération du flux et d'écriture dans la FIFO Tx
91
   --       Les FIFO Tx font 512 octet mais leur 'prog_full' est calé à 495 octets
92
   --       En testant le prog_full, on a donc toujours au moins 15 octets de libre
93
   --       On ne teste donc le prog_full que quand on écrit des donées utiles de la trame
94
   --       Lorsqu'on écrit l'entête ou le CRC ou du stuffing, il n 'y a pas besoin de tester
95
   --       le niveau de remplissage
96
   --------------------------------------------
97
   -- La donnée entrante est prise en compte que si on est dans l'état data_st ou addest_st
98
   -- Autrement dit, le module est dipos pour une nouvelle donnée dans ces cas là
99
   datin_free <= '1' WHEN (fsm_layer2_tx = data_st OR fsm_layer2_tx = addest_st) ELSE '0';
100
   man_fsm : PROCESS(clk_sys, rst_n)
101
   BEGIN
102
      IF (rst_n = '0') THEN
103
         fsm_layer2_tx <= idle_st;
104
         init_crc <= '1';
105
         val_crc <= '0';
106
         val_out <= '0';
107
         last_char <= '0';
108
         acq_stuf_buf <= '0';
109
         empty1_r1 <= '0';
110
         empty1_r2 <= '0';
111
         empty2_r1 <= '0';
112
         empty2_r2 <= '0';
113
         dat_out <= (others => '0');
114
         dat_crc <= (others => '0');
115
 
116
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
117
         empty1_r1 <= empty1;       -- Changement d'horloge de empty1
118
         empty1_r2 <= empty1_r1;
119
         empty2_r1 <= empty2;       -- Changement d'horloge de empty2
120
         empty2_r2 <= empty2_r1;
121
         CASE fsm_layer2_tx IS
122
            WHEN idle_st =>
123
            -- Etat d'attente du signal sof ou d'un ordre de de stuf de la ligne physique
124
               IF (stuf_phys = '1' AND acq_stuf_buf = '0') THEN
125
               -- Si on reçoit un ordre de stuf de la ligne physique et que ce n'est pas l'ordre précédent pas encore effacé
126
                  dat_out <= x"7E";             -- On n'envoie que des fanions 
127
                  init_crc <= '0';              -- On annule le reset du CRC
128
                  val_crc <= '0';               -- L'octet qu'on va sortir ne compte pas dans le calcul du crc
129
                  val_out <= '1';               -- On l'écrit dans la FIFO
130
                  cpt_stuf <= (OTHERS => '0');
131
                  fsm_layer2_tx <= stuf_st;     -- On va générer cpt_stuf fanions sur la ligne
132
               ELSIF (sof = '1' AND full1 = '0' AND full2 = '0' AND clr_fifo = '0') THEN
133
               -- Si on commence une trame et que le processus de clr est terminé
134
               -- Lors d'un reset de fifo, le flag full reste actif durant quelques cycle après 
135
               -- le relachement du clr_fifo
136
                  dat_out <= x"7E";             -- On envoie le fanion de début 
137
                  init_crc <= '0';              -- On annule le reset du CRC
138
                  val_crc <= '0';               -- L'octet qu'on va sortir ne compte pas dans le calcul du crc
139
                  val_out <= '1';               -- On l'écrit dans la FIFO
140
                  fsm_layer2_tx <= addest_st;   -- On va générer l'octet de commande
141
               ELSE
142
               -- Si pas de début de trame
143
                  init_crc <= '1';              -- On initialise le CRC
144
                  val_crc <= '0';               -- On fait rien
145
                  val_out <= '0';
146
               END IF;
147
               acq_stuf_buf <= '0';
148
 
149
            WHEN addest_st =>
150
               IF (val_in = '1') THEN
151
               -- La première donnée de la trmae est l'@ destination. Elle ne peut pas être stuffée car 7E et 7D sont interdites
152
                  val_out <= '1';            -- Quelle que soit la donnée on la prend en compte dans le calcul du CRC
153
                  val_crc <= '1';            -- Elle compte dans le calcul du CRC
154
                  dat_out <= dat_in;         -- On la fournit à la FIFO
155
                  dat_crc <= dat_in;         -- On la forunit au CRC
156
                  fsm_layer2_tx <= data_st;  -- On va traiter l'octet suivant
157
               ELSE
158
               -- Tant qu'on recoit pas de donnée
159
                  val_out <= '0';            -- Rien dans le FIFO
160
                  val_crc <= '0';            -- CRC inchangé
161
               END IF;
162
 
163
            WHEN data_st =>
164
            -- On attend une donnée disponible sur le bus d'entrée
165
               IF (val_in = '1') THEN
166
               -- Si il y'a une donnée sur le bus
167
                  val_crc <= '1';            -- Quelle que soit la donnée on la prend en compte dans le calcul du CRC
168
                  dat_crc <= dat_in;
169
                  val_out <= '1';            -- Quelle que soit la donnée on va écrire quelque chose dans la FIFO
170
                  IF (dat_in = x"7E") THEN
171
                     dat_out <= x"7D";          -- Si c'est un 7E il doit être remplacé par la séquence 7D 5E
172
                     last_char <= eof;          -- On mémorise s'il s'agit du dernier char de la trame
173
                     fsm_layer2_tx <= stuf5E_st;-- On va insérer le code 5E dans le flux
174
                  ELSIF (dat_in = x"7D") THEN
175
                     dat_out <= x"7D";          -- Si c'est un 7D il doit être remplacé par la séquence 7D 5D
176
                     last_char <= eof;          -- On mémorise s'il s'agit du dernier char de la trame
177
                     fsm_layer2_tx <= stuf5D_st;-- On va insérer le code 5D dans le flux
178
                  ELSE
179
                  -- Si c'est une donnée normale
180
                     dat_out <= dat_in;         -- On la met dans le flux
181
                     IF (eof = '1') THEN        -- Si c'est la dernière donnée de la trame
182
                        fsm_layer2_tx <= waitcrc_st;  -- On va attendre que le CRC soit prêt
183
                     ELSIF (progfull1 = '1' OR progfull2 = '1') THEN
184
                     -- Si une des 2 FIFO en écriture est presque pleine
185
                        fsm_layer2_tx <= fifo_full_st;   -- On va attendre
186
                     END IF;
187
                  END IF;
188
               ELSE
189
               -- Si il n'y a pas de nouvelle donnée sur le bus
190
                  val_crc <= '0';               -- On fait rien
191
                  val_out <= '0';
192
               END IF;
193
 
194
            WHEN fifo_full_st =>
195
            -- Etat d'attente qu'il y'ait de la place dans les FIFO en écriture
196
               val_crc <= '0';               -- On fait rien
197
               val_out <= '0';
198
               IF (progfull1 = '0' AND progfull2 = '0') THEN
199
               -- On attend que les 2 FIFO ne soient plus pleines
200
                  fsm_layer2_tx <= data_st;
201
               END IF;
202
 
203
 
204
            WHEN stuf5E_st =>
205
            -- Etat d'insertion du char 5E dans le flux
206
               dat_out <= x"5E";
207
               val_crc <= '0';                  -- Le CRC ne doit pa sêtre mis à jour avec l'octet de bourrage
208
               val_out <= '1';                  -- On l'écrit dans la FIFO
209
               IF (last_char = '1') THEN        -- Si c'était le dernier octet, on va insérer le CRC 
210
                  fsm_layer2_tx <= crc1_st;
211
               ELSE
212
                  fsm_layer2_tx <= data_st;
213
               END IF;
214
 
215
            WHEN stuf5D_st =>
216
            -- Etat d'insertion du char 5D dans le flux
217
               dat_out <= x"5D";
218
               val_crc <= '0';                  -- Le CRC ne doit pa sêtre mis à jour avec l'octet de bourrage
219
               val_out <= '1';                  -- On l'écrit dans la FIFO
220
               IF (last_char = '1') THEN        -- Si c'était le dernier octet, on va insérer le CRC
221
                  fsm_layer2_tx <= crc1_st;
222
               ELSE
223
                  fsm_layer2_tx <= data_st;
224
               END IF;
225
 
226
            WHEN waitcrc_st =>
227
            -- On attend un cycle que le CRC soit à jour avec la dernière donnée
228
               val_crc <= '0';
229
               val_out <= '0';
230
               fsm_layer2_tx <= crc1_st;        -- On va traiter les 8 MSB du CRC
231
 
232
            WHEN crc1_st =>
233
            -- Etat de traitement des 8 MSB du CRC
234
               val_crc <= '0';                  -- On doit pas modifier le CRC
235
               val_out <= '1';                  -- On va écrire une donnée en FIFO
236
               IF (crc(15 downto 8) = x"7E" OR crc(15 downto 8) = x"7D") THEN
237
               -- Si les 8 MSB sont une donnée à stuffer
238
                  dat_out <= x"7D";             -- On écrit le code de stuffing
239
                  fsm_layer2_tx <= stufcrc1_st; -- On va traiter le stuf
240
               ELSE
241
               -- Si les 8 MSB ne sont pas à stuffer
242
                  dat_out <= crc(15 downto 8);  -- On les met tel quel dans le flux
243
                  fsm_layer2_tx <= crc2_st;     -- On va traiter les 8 LSB du CRC
244
               END IF;
245
 
246
            WHEN stufcrc1_st =>
247
            -- Etat de gestion du stuffing des 8 MSB du CRC
248
               val_crc <= '0';
249
               val_out <= '1';
250
               IF (crc(15 downto 8) = x"7E") THEN
251
               -- Selon la valeur à stuffer
252
                  dat_out <= x"5E";             -- On envoie le bon code
253
               ELSE
254
                  dat_out <= x"5D";
255
               END IF;
256
               fsm_layer2_tx <= crc2_st;        -- On va traiter les 8 LSB du CRC 
257
 
258
            WHEN crc2_st =>
259
            -- Etat de traitement des 8 LSB du CRC
260
               val_crc <= '0';
261
               val_out <= '1';
262
               IF (crc(7 downto 0) = x"7E" OR crc(7 downto 0) = x"7D") THEN
263
               -- Si les 8 LSB sont une donnée à stuffer
264
                  dat_out <= x"7D";
265
                  fsm_layer2_tx <= stufcrc2_st;
266
               ELSE
267
               -- Si les 8 MSB ne sont pas à stuffer
268
                  dat_out <= crc(7 downto 0);
269
                  fsm_layer2_tx <= fanionfin_st;   -- On va insérer le fanion de fin dans le flux
270
               END IF;
271
 
272
            WHEN stufcrc2_st =>
273
            -- Etat de gestion du stuffing des 8 LSB du CRC
274
               val_crc <= '0';
275
               val_out <= '1';
276
               IF (crc(7 downto 0) = x"7E") THEN
277
                  dat_out <= x"5E";
278
               ELSE
279
                  dat_out <= x"5D";
280
               END IF;
281
               fsm_layer2_tx <= fanionfin_st;
282
 
283
            WHEN fanionfin_st =>
284
            -- On envoie le fanion de fin
285
               dat_out <= x"7E";
286
               val_crc <= '0';
287
               init_crc <= '1';
288
               val_out <= '1';
289
               fsm_layer2_tx <= waitendsend_st; -- On va attendre la fin des transmission
290
 
291
            WHEN waitendsend_st =>
292
               -- Etat d'annulation de l'émission
293
               val_out <= '0';
294
               fsm_layer2_tx <= idle_st;
295
 
296
            WHEN stuf_st =>
297
            -- Envoie cpt_stuf fanion sur la ligne
298
               IF (cpt_stuf = CONV_STD_LOGIC_VECTOR(800, cpt_stuf'LENGTH)) THEN
299
               -- Si on a émis tous les fanions
300
                  fsm_layer2_tx <= wait_stuf_st;
301
                  val_out <= '0';      -- On n'écrit plus rien dans la FIFO
302
               ELSE
303
               -- Tant qu'il faut émettre
304
                  IF (progfull1 = '1' OR progfull2 = '1') THEN
305
                  -- Si une des 2 FIFO Tx est pleine
306
                     val_out <= '0';      -- On attend sans ecrire
307
                  ELSE
308
                     val_out <= '1';      -- Chaque octet écrit est décompté
309
                     cpt_stuf <= cpt_stuf + 1;
310
                  END IF;
311
               END IF;
312
 
313
            WHEN wait_stuf_st =>
314
            -- Etat d'attente que les mots de stuff soit tous partis
315
               IF (empty1_r2 = '1' AND empty2_r2 = '1') THEN
316
               -- Si les 2 FIFO Tx sont vides
317
                  acq_stuf_buf <= '1'; -- On signale que l'opération est finie
318
                  fsm_layer2_tx <= idle_st;
319
               END IF;
320
 
321
            WHEN OTHERS =>
322
               fsm_layer2_tx <= idle_st;
323
 
324
         END CASE;
325
      END IF;
326
   END PROCESS;
327
 
328
   --------------------------------------------
329
   -- Calcul du crc16
330
   --------------------------------------------
331
        inst_crc16: crc16
332
   GENERIC MAP (
333
      poly => x"1021"   -- CCITT16
334
      )
335
   PORT MAP(
336
                clk_sys => clk_sys,
337
                rst_n => rst_n,
338
                data => dat_crc,         -- Dans le calcul du CRC, on prend en compte le flux déstuffé
339
                val => val_crc,
340
                init => init_crc,
341
                crc => crc
342
        );
343
 
344
end rtl;
345
 

powered by: WebSVN 2.1.0

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