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

Subversion Repositories saturn

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

Details | Compare with Previous | View Log

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

powered by: WebSVN 2.1.0

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