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

Subversion Repositories saturn

[/] [saturn/] [trunk/] [FPGA Concentrateur SIL2/] [fpga_cosil2/] [memory_map.vhd] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 DavidRAMBA
--============================================================================= 
2
--  TITRE : MEMORY_MAP
3
--  DESCRIPTION : 
4
--        Mappe la zone mémoire du BAR accédée par le bus local sur les registres
5
--        internes et les DPRAM 
6
--        Les registres sont accesibles en RD / WR par le bus local. 
7
--        Les signaux discrets associés aux registres sortent/entrent directement.
8
--        Les zones mémoires utilisées pour stocker les commandes périodiques et 
9
--        apériodiques sont accessibles d'un coté par le bus local, de l'autre
10
--        par un bus dédié.
11
--
12
--          BUS LOCAL                                       Bus dédié
13
--        Mots de 32 bits                                Mots de 8 bits
14
--        -----------------|--------------------------|
15
--                         |0000h                     |
16
--              BAR 0      |    Registres             |   Pas d'accès
17
--                         |7FFFh                     |
18
--        -----------------|--------------------------|----------------------
19
--                         |8000h                0000h|
20
--                         |    Zone Tx Periodique    |
21
--                         |87FFh                1FFFh|
22
--                         |--------------------------|
23
--                         |8800h                2000h|
24
--                         |     Zone réservée        |
25
--                         |8FFFh                3FFFh|
26
--              BAR 1      |--------------------------|    Accés par addrr_tx
27
--              (RFU)      |9000h                4000h|
28
--                         |    Zone Tx Apériodique   |
29
--                         |97FFh                5FFFh|
30
--                         |--------------------------|
31
--                         |9800h                6000h|
32
--                         |     Zone réservée        |
33
--                         |9FFFh                7FFFh|
34
--        -----------------|--------------------------|---------------------
35
--                         |A000h                     |
36
--              BAR 1      |     Zone réservée        |   Pas d'accès
37
--                         |FFFFh                     |
38
--        -----------------|--------------------------|---------------------
39
--
40
--  Les DMA transfèrent les trames reçus Rx1, Rx2, et émises par le PIC Tx dans 3 zones de 32 buffers chacune.
41
--  L'adresse de ce transfert vaut @ = DMA_BASE_PA + ZON * 2000h + BUF * 100h
42
--  Avec :
43
--            ZON = 0, 1 ou 2 pour respectivement les zones Rx1, RX2 et Tx
44
--            BUF = poids du bit à ‘1’ choisi dans un des registres RX1_AVAI, RX2_AVAI ou TX_AVAI (de 0 à 31).
45
--
46
--  FICHIER :        memory_map.vhd 
47
--=============================================================================
48
--  CREATION 
49
--  DATE              AUTEUR    PROJET  REVISION 
50
--  10/04/2014  DRA        SATURN       V1.0 
51
--=============================================================================
52
--  HISTORIQUE  DES  MODIFICATIONS :
53
--  DATE              AUTEUR    PROJET  REVISION
54
--  03/03/2015 DRA      SATURN   V1.1 
55
--    Rajout du bit 7 au registre status 
56
--=============================================================================
57
 
58
LIBRARY IEEE;
59
USE IEEE.STD_LOGIC_1164.ALL;
60
USE IEEE.STD_LOGIC_ARITH.ALL;
61
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
62
 
63
LIBRARY work;
64
USE work.package_saturn.ALL;
65
 
66
ENTITY memory_map IS
67
   GENERIC (
68
      reg_version : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"10"   -- Version du firmware
69
      );
70
   PORT (
71
      clk_sys        : IN  STD_LOGIC;                       -- Clock général système à 62.5MHz issue du module IF_PCIE
72
      rst_n          : IN  STD_LOGIC;                       -- Reset général système
73
      iid            : IN  STD_LOGIC_VECTOR(63 DOWNTO 0);   -- iid du Cocentrateur
74
      actif_passifn  : IN  STD_LOGIC;                       -- Indique que le concentrateur est actif ou passif
75
 
76
      -- Signaux du bus Local Bus du PCIe
77
      rd_addr        : IN  STD_LOGIC_VECTOR(NBBIT_ADD_LOCAL-1 DOWNTO 0);
78
      rd_data        : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
79
      rd_be          : IN  STD_LOGIC_VECTOR(3 DOWNTO 0);
80
      rd_en          : IN  STD_LOGIC;
81
      wr_addr        : IN  STD_LOGIC_VECTOR(NBBIT_ADD_LOCAL-1 DOWNTO 0);
82
      wr_data        : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);
83
      wr_be          : IN  STD_LOGIC_VECTOR(3 DOWNTO 0);
84
      wr_en          : IN  STD_LOGIC;
85
      wr_busy        : OUT STD_LOGIC;
86
 
87
      -- Interface Main Process
88
      -- Controle général
89
      rst_regn       : OUT STD_LOGIC;                       -- Reset du FPGA par registre interne
90
      store_enable   : OUT STD_LOGIC;                       -- Autorise le stockage de trame dans la mémoire DMA
91
      dma_inprogress : IN  STD_LOGIC;                       -- Indique qu'un DMA est en cours
92
      update_ena     : IN  STD_LOGIC;                       -- Indique que les mémoires d'émission pridoique peuvent être modifiées
93
      rx_flushn      : OUT STD_LOGIC;                       -- Purge les mémoires de stockage destrames
94
      topcyc         : IN  STD_LOGIC;                       -- Un pulse indique un début de cycle
95
 
96
      -- Autorisation des buffers d'émission
97
      tx_ena_periodic: OUT STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Signale les buffers periodiques qui peuvent être émis
98
      tx_ena_aper    : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Signale les buffers aperiodiques qui peuvent être émis
99
      clr_txena_aper : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Indique les buffers aperiodiques qui ont été émis
100
 
101
      -- Paramètres DMA
102
      dma_base_pa    : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Adresse de base du DMA coté micro
103
      dma_timestamp  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);    -- LSB du numéro de cycle en cours
104
 
105
      -- Interfaces de gestion des buffers d'enregitrement des trames Rx et Tx
106
      bufferrx1_full : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Buffers non vides en réception coté port 1
107
      bufferrx2_full : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Buffers non vides en réception coté port 2
108
      buffertx_full  : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Buffers non vides des trames émises par le PIC
109
      newframe_rx1   : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Indique un(les) nouveau(x) buffer(s) Rx 1 rempli(s)
110
      newframe_rx2   : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Indique un(les) nouveau(x) buffer(s) Rx 2 rempli(s)
111
      newframe_tx    : IN  STD_LOGIC_VECTOR(31 DOWNTO 0);   -- Indique un(les) nouveau(x) buffer(s) Tx rempli(s)
112
      rx1_overflow   : IN  STD_LOGIC;                       -- Indique l'impossiblité de stocker une trame reçue sur Rx1
113
      rx2_overflow   : IN  STD_LOGIC;                       -- Indique l'impossiblité de stocker une trame reçue sur Rx2
114
      tx_overflow    : IN  STD_LOGIC;                       -- Indique l'impossiblité de stocker une trame Tx
115
      rx1_badformat  : IN  STD_LOGIC;                       -- Indique une erreur de fromat sur une trame de Rx1
116
      rx2_badformat  : IN  STD_LOGIC;                       -- Indique une erreur de fromat sur une trame de Rx2
117
                clk_96                  : IN  STD_LOGIC;                       -- Horloge 96MHz synhcrone des traitements LS1 et LS2               
118
                rd_force                        : IN  STD_LOGIC;                       -- Signal de lecture d'un octet dans la FIFO Force
119
                data_force              : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);    -- Donnée lue dans la FIFO Force
120
                empty_force             : OUT STD_LOGIC;                       -- Indique que la FIFO force est vide
121
 
122
      -- Accès en lecture à la mémoire de TX Periodic et Aperiodic(en Read) - RFU
123
      addrr_tx       : IN  STD_LOGIC_VECTOR(14 DOWNTO 0);   -- Bus d'addresse à la DPRAM de stockage des trames Tx
124
      data_tx        : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);    -- Donnée lue dans la DPRAM
125
      rd_datatx      : IN  STD_LOGIC;                       -- Signal de lecture dans la DPRAM
126
      testpoint      : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)     -- Signaux de tests généralistes
127
     );
128
END memory_map;
129
 
130
ARCHITECTURE rtl of memory_map is
131
   -- Définition des @ des registres sur le bus Local
132
   CONSTANT msb_addr       : INTEGER := 5;
133
   CONSTANT ad_iid1        : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000000";
134
   CONSTANT ad_iid2        : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000001";
135
   CONSTANT ad_controle    : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000010";
136
   CONSTANT ad_statut      : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000011";
137
   CONSTANT ad_statutrp    : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000100";
138
   CONSTANT ad_txenaper    : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000101";
139
   CONSTANT ad_txenaaper   : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000110";
140
   CONSTANT ad_rx1avai     : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "000111";
141
   CONSTANT ad_rx2avai     : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "001000";
142
   CONSTANT ad_txavai      : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "001001";
143
   CONSTANT ad_dmabasepa   : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "001010";
144
   CONSTANT ad_timestamp   : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "001011";
145
   CONSTANT ad_fifoforce   : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "001100";
146
   CONSTANT ad_testpoint   : STD_LOGIC_VECTOR(msb_addr DOWNTO 0) := "001101";
147
 
148
   CONSTANT vec_null : STD_LOGIC_VECTOR(31 DOWNTO 0) := x"00000000";
149
 
150
   -- Signaux temporaires de constitution des bus adresse et data (RFU)
151
   SIGNAL wea_periodic     : STD_LOGIC_VECTOR(3 DOWNTO 0);  -- Pour écrire les 4 fois 8 bits de la DPRAM périodique
152
   SIGNAL addra_periodic   : STD_LOGIC_VECTOR(8 DOWNTO 0);  -- Bus d'addresse coté A de la DPRAM périodique
153
   SIGNAL addrb_periodic   : STD_LOGIC_VECTOR(10 DOWNTO 0); -- Bus d'addresse coté B de la DPRAM périodique
154
   SIGNAL rd_data_periodic : STD_LOGIC_VECTOR(31 DOWNTO 0); -- signal de relecture (coté A) dans la DPRAM périodique
155
   SIGNAL wea_aper         : STD_LOGIC_VECTOR(3 DOWNTO 0);  -- Pour écrire les 4 fois 8 bits de la DPRAM apériodique
156
   SIGNAL addra_aper       : STD_LOGIC_VECTOR(10 DOWNTO 0); -- Bus d'addresse coté A de la DPRAM apériodique
157
   SIGNAL rd_data_aper     : STD_LOGIC_VECTOR(31 DOWNTO 0); -- signal de lecture dans la DPRAM apériodique
158
   SIGNAL addrr_tx14_r     : STD_LOGIC;                     -- Pour latcher le bit de poids 14 du bius addresse
159
   SIGNAL rd_dataperiodictx: STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Donnée lue (coté B) dans la DPRAM périodique
160
   SIGNAL rd_dataapertx    : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Donnée lue (coté B) dans la DPRAM apériodique
161
   SIGNAL rd_data_int      : STD_LOGIC_VECTOR(31 DOWNTO 0); -- Pour passer le bus data read du local bus de Little à Big Endian
162
   SIGNAL wr_data_int      : STD_LOGIC_VECTOR(31 DOWNTO 0); -- Pour passer le bus data write du local bus de Little à Big Endian
163
   SIGNAL rd_reg           : STD_LOGIC_VECTOR(31 DOWNTO 0); -- Signal multiplexé de lecture des registres
164
   SIGNAL mem_rxflush      : STD_LOGIC;                     -- Pour gérer l'ordre de flush des mémories Rx
165
        SIGNAL we_force                 : STD_LOGIC;                      -- Signal d'écriture dans la FIFO de forçage
166
 
167
   -- Registres internes
168
   SIGNAL reg_iid          : STD_LOGIC_VECTOR(63 DOWNTO 0);
169
   SIGNAL reg_ctl          : STD_LOGIC_VECTOR(31 DOWNTO 0);
170
   SIGNAL reg_status       : STD_LOGIC_VECTOR(31 DOWNTO 0);
171
   SIGNAL reg_statutrp     : STD_LOGIC_VECTOR(31 DOWNTO 0);
172
   SIGNAL reg_txena_per    : STD_LOGIC_VECTOR(31 DOWNTO 0);
173
   SIGNAL reg_txena_aper   : STD_LOGIC_VECTOR(31 DOWNTO 0);
174
   SIGNAL reg_rx1avai      : STD_LOGIC_VECTOR(31 DOWNTO 0);
175
   SIGNAL reg_rx2avai      : STD_LOGIC_VECTOR(31 DOWNTO 0);
176
   SIGNAL reg_txavai       : STD_LOGIC_VECTOR(31 DOWNTO 0);
177
   SIGNAL reg_dmabasepa    : STD_LOGIC_VECTOR(31 DOWNTO 0);
178
   SIGNAL reg_timestamp    : STD_LOGIC_VECTOR(31 DOWNTO 0);
179
   SIGNAL reg_testpoint    : STD_LOGIC_VECTOR(31 DOWNTO 0);
180
 
181
   -- Compteurs de satut
182
   SIGNAL cpt_badfmt1      : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Compteur de trame reçue avec un mauvais FCS sur port 1
183
   SIGNAL cpt_badfmt2      : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Compteur de trame reçue avec un mauvais FCS sur port 2
184
 
185
   -- Pour détecter un front sur Top_cyc
186
   SIGNAL top_cyc_r        : STD_LOGIC_VECTOR(2 DOWNTO 0);
187
   SIGNAL front_topcyc     : STD_LOGIC;
188
 
189
   COMPONENT dpram_periodic
190
   PORT (
191
      clka     : IN STD_LOGIC;
192
      wea      : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
193
      addra    : IN STD_LOGIC_VECTOR(8 DOWNTO 0);
194
      dina     : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
195
      douta    : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
196
      clkb     : IN STD_LOGIC;
197
      enb      : IN STD_LOGIC;
198
      web      : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
199
      addrb    : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
200
      dinb     : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
201
      doutb    : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
202
   );
203
   END COMPONENT;
204
 
205
   COMPONENT dpram_aper
206
   PORT (
207
      clka     : IN STD_LOGIC;
208
      wea      : IN STD_LOGIC_VECTOR(3 DOWNTO 0);
209
      addra    : IN STD_LOGIC_VECTOR(10 DOWNTO 0);
210
      dina     : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
211
      douta    : OUT STD_LOGIC_VECTOR(31 DOWNTO 0);
212
      clkb     : IN STD_LOGIC;
213
      enb      : IN STD_LOGIC;
214
      web      : IN STD_LOGIC_VECTOR(0 DOWNTO 0);
215
      addrb    : IN STD_LOGIC_VECTOR(12 DOWNTO 0);
216
      dinb     : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
217
      doutb    : OUT STD_LOGIC_VECTOR(7 DOWNTO 0)
218
   );
219
   END COMPONENT;
220
 
221
        COMPONENT fifo_force
222
        PORT (
223
                rst             : IN STD_LOGIC;
224
                wr_clk  : IN STD_LOGIC;
225
                rd_clk  : IN STD_LOGIC;
226
                din             : IN STD_LOGIC_VECTOR(31 DOWNTO 0);
227
                wr_en   : IN STD_LOGIC;
228
                rd_en   : IN STD_LOGIC;
229
                dout            : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
230
                full            : OUT STD_LOGIC;
231
                empty   : OUT STD_LOGIC
232
        );
233
        END COMPONENT;
234
 
235
 
236
BEGIN
237
   wr_busy <= '0';         -- Aucune opération de WR sur le bus local ne dure plus d'un cycle de clk_sys
238
   -- Swap des octets des mots de 32 bits (little endian <-> big endian) 
239
   wr_data_int <= wr_data( 7 DOWNTO  0) & wr_data(15 DOWNTO  8) &
240
                  wr_data(23 DOWNTO 16) & wr_data(31 DOWNTO 24);
241
   rd_data <= rd_data_int( 7 DOWNTO  0) & rd_data_int(15 DOWNTO  8) &
242
              rd_data_int(23 DOWNTO 16) & rd_data_int(31 DOWNTO 24);
243
 
244
   reg_iid <= iid;         -- Affectation de l'IID du module
245
 
246
   -- Affectation des sorties de controle général
247
   store_enable <= reg_ctl(0);   -- Autorise le stockage des trames pour transfert DMA
248
 
249
   -- Affectation des sorties d'autorisation à émettre des buffers (RFU)
250
   tx_ena_periodic <= reg_txena_per;
251
   tx_ena_aper     <= reg_txena_aper;
252
 
253
   -- Affectation des sorties de gestion des buffers de réception
254
   bufferrx1_full <= reg_rx1avai;
255
   bufferrx2_full <= reg_rx2avai;
256
   buffertx_full  <= reg_txavai;
257
 
258
   -- Affectation de l'adresse de base du DMA
259
   dma_base_pa <= reg_dmabasepa;
260
   dma_timestamp <= reg_timestamp(7 DOWNTO 0);
261
 
262
   testpoint <= reg_testpoint(7 DOWNTO 0);
263
 
264
   -- Process pour assurer que le reset interne piloté par registre dure un clk
265
   proc_rstreg : PROCESS(clk_sys)
266
   BEGIN
267
      IF (clk_sys'event AND clk_sys = '1') THEN
268
         -- Gestion du reset interne piloté par registre
269
         rst_regn <= NOT(reg_ctl(1));
270
      END IF;
271
   END PROCESS;
272
 
273
   ---------------------------------------------
274
   -- Process de gestion des écritures dans les registres
275
   -- Une écriture est efefctive lorsque le signal WR_EN est actif
276
   -- et que le vecteur WR_ADDR désigne une adresse valable dans le BAR0
277
   -- L'adresse du registre dans le BAR0 est définie par:
278
   --   @ BAR0 + Offset_registre ce qui équivaut à @BAR OR Offset_registre
279
   -- car l'@BAR0 est forcément aligné sur une adresse multiple de la taille du BAR0 (i.e. les LSB sont nuls)
280
   ---------------------------------------------
281
   proc_writereg : PROCESS(clk_sys, rst_n)
282
   BEGIN
283
      IF (rst_n = '0') THEN
284
         reg_ctl        <= x"00000000";
285
         reg_txena_per  <= x"00000000";
286
         reg_txena_aper <= x"00000000";
287
         reg_rx1avai    <= x"00000000";
288
         reg_rx2avai    <= x"00000000";
289
         reg_txavai     <= x"00000000";
290
         reg_dmabasepa  <= x"00000000";
291
         reg_testpoint  <= x"00000000";
292
      ELSIF (clk_sys'event AND clk_sys = '1') THEN
293
         IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_controle, NBBIT_ADD_LOCAL))) THEN
294
            reg_ctl <= wr_data_int;
295
         END IF;
296
         IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_txenaper, NBBIT_ADD_LOCAL))) THEN
297
            reg_txena_per <= wr_data_int;
298
         END IF;
299
         -- Gestion du registre d'émission apériodique
300
         loop_txenaaper : FOR i IN 0 TO 31 LOOP
301
            IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_txenaaper, NBBIT_ADD_LOCAL))) THEN
302
            -- Si on est en train d'accéder en WR au registre TX_ENA_APER
303
               IF (wr_data_int(i) = '1') THEN
304
               -- Chaque bit de la donnée à écrire à 1
305
                  reg_txena_aper(i) <= '1';  -- Place le bit correspondant à 1
306
               ELSIF (clr_txena_aper(i) = '1') THEN
307
               -- Si le bit à écrire correspondant est 0 et qu'on reçoit un clear du module de transmission
308
                  reg_txena_aper(i) <= '0';
309
               END IF;
310
            ELSE
311
            -- Il n'y a pas d'écriture en cours
312
               IF (clr_txena_aper(i) = '1') THEN
313
               -- Le registre est inchangé tnat qu'on en reçoit pas un clear du module d'émission
314
                  reg_txena_aper(i) <= '0';
315
               END IF;
316
            END IF;
317
         END LOOP;
318
         -- Gestion du registre de statuts du buffer DMA pour Rx1
319
         loop_rx1full : FOR i IN 0 TO 31 LOOP
320
            IF (mem_rxflush = '1') THEN
321
               reg_rx1avai(i) <= '0';
322
            ELSIF (newframe_rx1(i) = '1') THEN
323
            -- Lorsqu'une nouvelle trame est envoyée par DMA
324
               reg_rx1avai(i) <= '1';     -- On positionne le bit correspondant
325
            ELSE
326
               IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_rx1avai, NBBIT_ADD_LOCAL))) THEN
327
               -- Sur un WR au registre de RX1_AVAI
328
                  IF (wr_data_int(i) = '1') THEN
329
                  -- Seul un '1' cleare le registre
330
                     reg_rx1avai(i) <= '0';
331
                  END IF;
332
               END IF;
333
            END IF;
334
         END LOOP;
335
         -- Gestion du registre de statuts du buffer DMA pour Rx2
336
         loop_rx2full : FOR i IN 0 TO 31 LOOP
337
         -- Idem pour RX1_AVAI
338
            IF (mem_rxflush = '1') THEN
339
               reg_rx2avai(i) <= '0';
340
            ELSIF (newframe_rx2(i) = '1') THEN
341
               reg_rx2avai(i) <= '1';
342
            ELSE
343
               IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_rx2avai, NBBIT_ADD_LOCAL))) THEN
344
                  IF (wr_data_int(i) = '1') THEN
345
                     reg_rx2avai(i) <= '0';
346
                  END IF;
347
               END IF;
348
            END IF;
349
         END LOOP;
350
         -- Gestion du registre de statuts du buffer DMA pour Tx
351
         loop_txfull : FOR i IN 0 TO 31 LOOP
352
         -- Idem pour RX2_AVAI
353
            IF (mem_rxflush = '1') THEN
354
               reg_txavai(i) <= '0';
355
            ELSIF (newframe_tx(i) = '1') THEN
356
               reg_txavai(i) <= '1';
357
            ELSE
358
               IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_txavai, NBBIT_ADD_LOCAL))) THEN
359
                  IF (wr_data_int(i) = '1') THEN
360
                     reg_txavai(i) <= '0';
361
                  END IF;
362
               END IF;
363
            END IF;
364
         END LOOP;
365
         IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_dmabasepa, NBBIT_ADD_LOCAL))) THEN
366
            reg_dmabasepa <= wr_data_int;
367
         END IF;
368
         IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_testpoint, NBBIT_ADD_LOCAL))) THEN
369
            reg_testpoint <= wr_data_int;
370
         END IF;
371
      END IF;
372
   END PROCESS;
373
 
374
   -------------------------------------
375
   -- Process de gestion du registre STATUT
376
   -------------------------------------
377
   proc_status : PROCESS(clk_sys, rst_n)
378
   BEGIN
379
      IF (rst_n = '0') THEN
380
         reg_status   <= x"00000000";
381
      ELSIF (clk_sys'event AND clk_sys = '1') THEN
382
         IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_statut, NBBIT_ADD_LOCAL))) THEN
383
         -- Remise à '0' des bits en Write One Clear
384
         -- Un registre n'est remis à '0' sur WOC que si l'évènement corrspondant n'est pas actif
385
            IF (wr_data_int(0) = '1') THEN
386
               reg_status(0)  <= front_topcyc;
387
            END IF;
388
            IF (wr_data_int(1) = '1') THEN
389
               reg_status(1)  <= rx1_overflow;
390
            END IF;
391
            IF (wr_data_int(2) = '1') THEN
392
               reg_status(2) <= rx2_overflow;
393
            END IF;
394
            IF (wr_data_int(3) = '1') THEN
395
               reg_status(3)  <= tx_overflow;
396
            END IF;
397
            IF (wr_data_int(4) = '1') THEN
398
               reg_status(4) <= rx1_badformat;
399
            END IF;
400
            IF (wr_data_int(5) = '1') THEN
401
               reg_status(5) <= rx2_badformat;
402
            END IF;
403
         ELSE
404
            IF (front_topcyc = '1') THEN
405
               reg_status(0)  <= '1';
406
            END IF;
407
            IF (rx1_overflow = '1') THEN
408
               reg_status(1)  <= '1';
409
            END IF;
410
            IF (rx2_overflow = '1') THEN
411
               reg_status(2) <= '1';
412
            END IF;
413
            IF (tx_overflow = '1') THEN
414
               reg_status(3)  <= '1';
415
            END IF;
416
            IF (rx1_badformat = '1') THEN
417
               reg_status(4)  <= '1';
418
            END IF;
419
            IF (rx2_badformat = '1') THEN
420
               reg_status(5)  <= '1';
421
            END IF;
422
         END IF;
423
         reg_status(6) <= update_ena;
424
         reg_status(7) <= actif_passifn;
425
         reg_status(23 DOWNTO 8) <= (OTHERS => '0');
426
         reg_status(31 DOWNTO 24) <= reg_version;
427
      END IF;
428
   END PROCESS;
429
 
430
   ---------------------------------------------
431
   -- Process de gestion des registres particuliers
432
   ---------------------------------------------
433
   proc_spec : PROCESS(clk_sys, rst_n)
434
   BEGIN
435
      IF (rst_n = '0') THEN
436
         mem_rxflush <= '1';
437
         rx_flushn   <= '0';  -- Pour faire un Reset au démarrage
438
      ELSIF (clk_sys'event AND clk_sys = '1') THEN
439
         IF (wr_en = '1' AND wr_addr = (ADD_BASE_BAR0 OR EXT(ad_controle, NBBIT_ADD_LOCAL)) AND
440
             wr_data_int(7) = '1') THEN
441
         -- Si on écrit un '1' dans le bit 7 du registre de controle
442
            mem_rxflush <= '1';  -- on mémorise la commande 
443
         ELSIF (dma_inprogress = '0') THEN
444
            mem_rxflush <= '0';  -- la commande reste active jusqu'à la fin d'un DMA
445
         END IF;
446
         -- le reset du module DMA ne survient que si un DMA n'est pas en cours.
447
         -- la condition sur mem_rxflush fait en sorte que le rx_flush ne dure qu'1 cycle
448
         rx_flushn    <= NOT(mem_rxflush) OR dma_inprogress;
449
      END IF;
450
   END PROCESS;
451
 
452
   --------------------------------------------------
453
   -- Process de gestion des compteurs de trame avec un mauvais format
454
   --------------------------------------------------
455
   proc_fmt : PROCESS(clk_sys, rst_n)
456
   BEGIN
457
      IF (rst_n = '0') THEN
458
         cpt_badfmt1 <= (OTHERS => '0');
459
         cpt_badfmt2 <= (OTHERS => '0');
460
      ELSIF (clk_sys'event AND clk_sys = '1') THEN
461
         IF (rd_en = '1' AND rd_addr = (ADD_BASE_BAR0 OR EXT(ad_statutrp, NBBIT_ADD_LOCAL))) THEN
462
         -- Les compteurs sont remis à 0 sur un RD du registre. Si l'évènement est actif à ce moment là
463
         -- on remet pas à 0 mais à 1 -> LSB = évènement
464
            cpt_badfmt1 <= "0000000" & rx1_badformat;
465
            cpt_badfmt2 <= "0000000" & rx2_badformat;
466
         ELSE
467
            IF (rx1_badformat = '1') THEN
468
               IF (cpt_badfmt1 /= x"FF") THEN
469
                  cpt_badfmt1 <= cpt_badfmt1 + 1;
470
               END IF;
471
            END IF;
472
            IF (rx2_badformat = '1') THEN
473
               IF (cpt_badfmt2 /= x"FF") THEN
474
                  cpt_badfmt2 <= cpt_badfmt2 + 1;
475
               END IF;
476
             END IF;
477
         END IF;
478
      END IF;
479
   END PROCESS;
480
 
481
   reg_statutrp   <= x"0000" & cpt_badfmt2 & cpt_badfmt1;
482
 
483
   ---------------------------------------------
484
   -- Process de gestion d'un free compteur de cycle indiquant le timestamp
485
   ---------------------------------------------
486
   front_topcyc <= NOT(top_cyc_r(2)) AND top_cyc_r(1);
487
   proc_tmstmp : PROCESS(clk_sys, rst_n)
488
   BEGIN
489
      IF (rst_n = '0') THEN
490
         reg_timestamp <= (OTHERS => '0');
491
         top_cyc_r <= "000";
492
      ELSIF (clk_sys'event AND clk_sys = '1') THEN
493
         top_cyc_r <= top_cyc_r(1 DOWNTO 0) & topcyc; -- Pour détecter un front montant de top_cyc qu est généré à 96MHz
494
         IF (front_topcyc = '1') THEN
495
            reg_timestamp <= reg_timestamp + 1;
496
         END IF;
497
      END IF;
498
   END PROCESS;
499
 
500
   ---------------------------------------------
501
   -- Multiplexage du bus de donnée local en lecture
502
   ---------------------------------------------
503
   -- Sélection entre registres ou mémoires internes selon MSB du bus local
504
   rd_data_int <=
505
      rd_data_periodic      WHEN (rd_addr(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4) = ADD_BASE_TXPER(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4)) ELSE
506
      rd_data_aper          WHEN (rd_addr(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4) = ADD_BASE_TXAPER(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4)) ELSE
507
      rd_reg;
508
 
509
   -- Multiplexage des registres en lecture
510
   proc_readreg : PROCESS(clk_sys, rst_n)
511
   BEGIN
512
      IF (rst_n = '0') THEN
513
         rd_reg     <= (OTHERS => '0');
514
      ELSIF (clk_sys'event AND clk_sys = '1') THEN
515
         CASE rd_addr(msb_addr DOWNTO 0) IS
516
            WHEN ad_iid1 =>
517
               rd_reg <= reg_iid(31 DOWNTO  0);
518
            WHEN ad_iid2 =>
519
               rd_reg <= reg_iid(63 DOWNTO 32);
520
            WHEN ad_controle =>
521
               rd_reg <= reg_ctl;
522
            WHEN ad_statut =>
523
               rd_reg <= reg_status;
524
            WHEN ad_statutrp =>
525
               rd_reg <= reg_statutrp;
526
            WHEN ad_txenaper =>
527
               rd_reg <= reg_txena_per;
528
            WHEN ad_txenaaper =>
529
               rd_reg <= reg_txena_aper;
530
            WHEN ad_rx1avai =>
531
               rd_reg <= reg_rx1avai;
532
            WHEN ad_rx2avai =>
533
               rd_reg <= reg_rx2avai;
534
            WHEN ad_txavai =>
535
               rd_reg <= reg_txavai;
536
            WHEN ad_dmabasepa =>
537
               rd_reg <= reg_dmabasepa;
538
            WHEN ad_timestamp =>
539
               rd_reg <= reg_timestamp;
540
            WHEN ad_testpoint =>
541
               rd_reg <= reg_testpoint;
542
            WHEN OTHERS =>
543
               rd_reg <= reg_status;
544
         END CASE;
545
      END IF;
546
   END PROCESS;
547
 
548
   --------------------------------------------
549
   -- Gestion du bloc mémoire de transmission APERIODIC
550
   --------------------------------------------
551
   we_force   <= wr_en WHEN wr_addr = (ADD_BASE_BAR0 OR EXT(ad_fifoforce, NBBIT_ADD_LOCAL)) ELSE '0';
552
 
553
        inst_force : fifo_force
554
        PORT MAP(
555
                rst             => front_topcyc,
556
                wr_clk  => clk_sys,
557
                rd_clk  => clk_96,
558
                din             => wr_data_int,
559
                wr_en   => we_force,
560
                rd_en   => rd_force,
561
                dout            => data_force,
562
                full            => OPEN,
563
                empty   => empty_force
564
        );
565
 
566
   --------------------------------------
567
   -- Mémorisation du MSB de addrr_tx pour savoir quelle zone est lue (périodique ou apériodique)
568
   -- Lorsqu'un module de transmission lit une mémoire APER ou PER
569
   -- La donnée est dispo un cycle après. On mémorise le MSB de l'adresse pour savoir quelle
570
   -- zone a été addressée
571
   --------------------------------------
572
   lat_addr14 : PROCESS(clk_sys, rst_n)
573
   BEGIN
574
      IF (rst_n = '0') THEN
575
         addrr_tx14_r <= '0';
576
      ELSIF (clk_sys'event AND clk_sys = '1') THEN
577
         addrr_tx14_r <= addrr_tx(14);
578
      END IF;
579
   END PROCESS;
580
   data_tx <= rd_dataperiodictx WHEN (addrr_tx14_r = '0') ELSE rd_dataapertx;
581
 
582
   --------------------------------------------
583
   -- Gestion du bloc mémoire de transmission PERIODIC (RFU)
584
   --------------------------------------------
585
   -- Le bloc periodic fait 32 zones de 256 octets mais seuls les 64 premiers octets de chaque zone sont mappés
586
   -- Arrangement des bits d'adresses pour le bus spécifique
587
   addrb_periodic <= addrr_tx(12 DOWNTO 8) & addrr_tx(5 DOWNTO 0);
588
   -- Multiplexage et arrangement des bits d'adresses pour le bus local
589
   addra_periodic <= (wr_addr(10 DOWNTO 6) & wr_addr(3 DOWNTO 0)) WHEN (wr_en = '1') ELSE
590
                     (rd_addr(10 DOWNTO 6) & rd_addr(3 DOWNTO 0));
591
   -- Génération des signaux de WR dans la zone Périodique
592
   wea_periodic   <= (wr_be(3 DOWNTO 0) AND (wr_en & wr_en & wr_en & wr_en)) WHEN
593
                     (wr_addr(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4) = ADD_BASE_TXPER(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4)) ELSE "0000";
594
   dpr_periodic : dpram_periodic
595
   PORT MAP(
596
      clka     => clk_sys,
597
      wea      => wea_periodic,
598
      addra    => addra_periodic,
599
      dina     => wr_data_int,
600
      douta    => rd_data_periodic,
601
      clkb     => clk_sys,
602
      enb      => rd_datatx,
603
      web      => vec_null(0 DOWNTO 0),
604
      addrb    => addrb_periodic,
605
      dinb     => vec_null(7 DOWNTO 0),
606
      doutb    => rd_dataperiodictx
607
   );
608
 
609
   --------------------------------------------
610
   -- Gestion du bloc mémoire de transmission APERIODIC (RFU)
611
   --------------------------------------------
612
   -- Multiplexage des bits d'adresse pour le bus local
613
   addra_aper <= wr_addr(10 DOWNTO 0) WHEN (wr_en = '1') ELSE rd_addr(10 DOWNTO 0);
614
   -- Génération des signaux de WR dans la zone Apériodique
615
   wea_aper   <= (wr_be(3 DOWNTO 0) AND (wr_en & wr_en & wr_en & wr_en)) WHEN
616
                 (wr_addr(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4) = ADD_BASE_TXAPER(NBBIT_ADD_LOCAL-1 DOWNTO NBBIT_ADD_LOCAL-4)) ELSE "0000";
617
   dpr_aper : dpram_aper
618
   PORT MAP(
619
      clka     => clk_sys,
620
      wea      => wea_aper,
621
      addra    => addra_aper,
622
      dina     => wr_data_int,
623
      douta    => rd_data_aper,
624
      clkb     => clk_sys,
625
      enb      => rd_datatx,
626
      web      => vec_null(0 DOWNTO 0),
627
      addrb    => addrr_tx(12 DOWNTO 0),
628
      dinb     => vec_null(7 DOWNTO 0),
629
      doutb    => rd_dataapertx
630
   );
631
 
632
END rtl;
633
 

powered by: WebSVN 2.1.0

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