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

Subversion Repositories saturn

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 DavidRAMBA
--============================================================================= 
2
--  TITRE : IF_PICPMP
3
--  DESCRIPTION : 
4
--       Assure l'interface avec le PIC32 à travers un lien PMP
5
--       Implémente les registres mémoires tels que définis dans le HSI
6
 
7
--  FICHIER :        if_picpmp.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 if_picpmp IS
23
   GENERIC (
24
      version : STD_LOGIC_VECTOR(7 DOWNTO 0) := x"10");  -- Version du FPGA
25
   PORT (
26
      -- Ports système
27
      clk_sys  : IN  STD_LOGIC;                       -- Clock système
28
      rst_n    : IN  STD_LOGIC;                       -- Reset général système
29
 
30
      -- Interface PMP (Interface PIC)
31
      pmd      : INOUT STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Bus parallèle multiplexé Adresse/data
32
      pmall    : IN STD_LOGIC;                        -- Latche des LSB des adresses
33
      pmalh    : IN STD_LOGIC;                        -- Latche des MSB des adresses
34
      pmrd     : IN STD_LOGIC;                        -- Signal de lecture
35
      pmwr     : IN STD_LOGIC;                        -- Signal d'écriture
36
 
37
      -- Interface avec les autres modules du FPGA
38
      -- Tous ces signaux sont synchrones de clk_sys
39
      -- Signaux de configurations
40
      iid          : IN  STD_LOGIC_VECTOR(63 DOWNTO 0);-- Identifiant IID du FPGA
41
      tid          : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);-- Identifiant TID du FPGA
42
      cpy1         : OUT STD_LOGIC;                   -- Autorise la recopie du port 1 sur port 2
43
      cpy2         : OUT STD_LOGIC;                   -- Autorise la recopie du port 2 sur port 1
44
      repli        : OUT STD_LOGIC;                   -- Indique que le module est en repli (gestion des LED)
45
      baudrate     : OUT STD_LOGIC_VECTOR(2 DOWNTO 0);-- Baudrate en mdoe maitre
46
      actif        : OUT STD_LOGIC;                   -- Indique que le concentrateur est actif
47
      topcyc       : OUT STD_LOGIC;                   -- Un pulse indique un début de cycle
48
      enafiltdble  : OUT STD_LOGIC;                   -- Autorise le filtrage des trames en double
49
 
50
      -- Interfaces de lecture des trames port 1
51
      l7_rx1       : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);-- Données reçues sur port 1
52
      l7_soc1      : IN  STD_LOGIC;                   -- Indique le début d'une trame
53
      l7_rd1       : OUT STD_LOGIC;                   -- Signal de lecture d'une donnée supplémentaire
54
      l7_comdispo1 : IN  STD_LOGIC;                   -- Indique qu'il y'a au moins une trame de dispo
55
      l7_newframe1 : IN  STD_LOGIC;                   -- Indique la réception d'une nouvelle trame
56
      l7_l2ok1     : IN  STD_LOGIC;                   -- Indique si la couche transport est bonne ou non
57
      l7_overflow1 : IN  STD_LOGIC;                   -- Indique un overflow sur réception
58
 
59
         -- Interfaces de lecture des trames port 2
60
      l7_rx2       : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);-- Données reçues sur port 2
61
      l7_soc2      : IN  STD_LOGIC;                   -- Indique le début d'une trame
62
      l7_rd2       : OUT STD_LOGIC;                   -- Signal de lecture d'une donnée supplémentaire
63
      l7_comdispo2 : IN  STD_LOGIC;                   -- Indique qu'il y'a au moins une trame de dispo
64
      l7_newframe2 : IN  STD_LOGIC;                   -- Indique la réception d'une nouvelle trame
65
      l7_l2ok2     : IN  STD_LOGIC;                   -- Indique si la couche transport est bonne ou non
66
      l7_overflow2 : IN  STD_LOGIC;                   -- Indique un overflow sur réception
67
 
68
      -- Interface d'écriture des trames
69
      tx_dat       : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);-- Données à transmettre sur les 2 ports
70
      val_txdat    : OUT STD_LOGIC;                   -- Validant de chaque octet
71
      tx_sof       : OUT STD_LOGIC;                   -- Indique le début d'une trame
72
      tx_eof       : OUT STD_LOGIC;                   -- Indique la fin d'une trame
73
      txdat_free   : IN  STD_LOGIC;                   -- Indique que la couche transport en tx est libre
74
      clr_fifo_tx  : OUT STD_LOGIC;                   -- Permet de purger les FIFO Tx
75
      stuf_phys    : OUT STD_LOGIC;                   -- Demande d'émettre uine série de stuffing sur le port RS
76
      acq_stuf     : IN  STD_LOGIC;                   -- Indique que la commande stuffing a été exécutée
77
 
78
      -- Gestion de l'interface SPI PROM
79
      txprom_dat   : OUT STD_LOGIC_VECTOR(7 downto 0);-- Donnée + commandes à écrire dans le module de reprog
80
      txprom_val   : OUT STD_LOGIC;                   -- Validant de txprom_data
81
      rxprom_dat   : IN  STD_LOGIC_VECTOR(7 downto 0);-- Donnée lue depuis le module de reprog
82
      rxprom_val   : IN  STD_LOGIC;                   -- Indique qu'il y a des données à lire dans le module de reprog
83
      rxprom_next  : OUT STD_LOGIC;                   -- Lit une donnée de plus sur txprom_dat
84
      prom_type_com: OUT STD_LOGIC;                   -- Type de commande à exécuter (RD ou WR)
85
      prom_exec_com: OUT STD_LOGIC;                   -- Lance une commande dans le module de reprog
86
      prom_busy    : IN  STD_LOGIC;                   -- Indique que le module de reprog est occupé
87
      prom_nbread  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);-- Nombre d'octet qu'il faut lire avec une commande de lecture
88
      prom_rstn    : OUT STD_LOGIC;                   -- Reset du module de reprog
89
 
90
      -- Interface de forçage (RFU)
91
                rd_force                 : OUT STD_LOGIC;                                                       -- Signalde lecture d'un octet dans la FIFO des I/O forcées
92
                data_force       : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);-- Octet lu dans la FIFO des I/O forcées
93
                empty_force      : IN  STD_LOGIC                                                        -- Indique que la FIFO des I/O forcées est vide
94
      );
95
END if_picpmp;
96
 
97
ARCHITECTURE rtl of if_picpmp is
98
   TYPE fsmtx_state IS (idle_st, senddat_st);
99
   SIGNAL fsm_tx  : fsmtx_state;
100
 
101
   TYPE fsmrx_state IS (idle_st, pump_st, recdat_st, waitnotempty_st);
102
   SIGNAL fsm_rx  : fsmrx_state;
103
 
104
   -- Définition du Mapping mémoire des registre PMP
105
   CONSTANT adreg_iid      : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(0, 7);
106
   CONSTANT adreg_tid      : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(8, 7);
107
   CONSTANT adreg_ctl      : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(9, 7);
108
   CONSTANT adreg_stat     : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(10, 7);
109
   CONSTANT adreg_rxsize1  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(11, 7);
110
   CONSTANT adreg_rxsize2  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(12, 7);
111
   CONSTANT adreg_txfree   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(13, 7);
112
   CONSTANT adreg_fiforx1  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(14, 7);
113
   CONSTANT adreg_fiforx2  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(15, 7);
114
   CONSTANT adreg_fifotx   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(16, 7);
115
   CONSTANT adreg_version  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(17, 7);
116
   CONSTANT adreg_confrp   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(18, 7);
117
   CONSTANT adreg_promtx   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(19, 7);
118
   CONSTANT adreg_promrx   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(20, 7);
119
   CONSTANT adreg_promctl  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(21, 7);
120
   CONSTANT adreg_promnbrd : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(22, 7);
121
   CONSTANT adreg_fifoforce: STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(23, 7);
122
 
123
   -- Déclaration des registres internes
124
   SIGNAL reg_tid       : STD_LOGIC_VECTOR(7 DOWNTO 0);
125
   SIGNAL reg_ctl       : STD_LOGIC_VECTOR(7 DOWNTO 0);
126
   SIGNAL reg_stat      : STD_LOGIC_VECTOR(7 DOWNTO 0);
127
   SIGNAL reg_rx1size   : STD_LOGIC_VECTOR(7 DOWNTO 0);
128
   SIGNAL reg_rx2size   : STD_LOGIC_VECTOR(7 DOWNTO 0);
129
   SIGNAL reg_txfree    : STD_LOGIC_VECTOR(7 DOWNTO 0);
130
   SIGNAL reg_fiforx1   : STD_LOGIC_VECTOR(7 DOWNTO 0);
131
   SIGNAL reg_fiforx2   : STD_LOGIC_VECTOR(7 DOWNTO 0);
132
   SIGNAL reg_confrp    : STD_LOGIC_VECTOR(7 DOWNTO 0);
133
   SIGNAL reg_promctl   : STD_LOGIC_VECTOR(7 DOWNTO 0);
134
   SIGNAL reg_promnbrd  : STD_LOGIC_VECTOR(7 DOWNTO 0);
135
 
136
   -- Signaux de gestion de l'interface PMP
137
   SIGNAL buswrite         : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Donnée à écrire depuis le bus
138
   SIGNAL busread          : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Donnée lue sur le bus
139
   SIGNAL adreg            : STD_LOGIC_VECTOR(6 DOWNTO 0);  -- Bus d'adresse d'accès des registres PMP
140
   SIGNAL wr_reg           : STD_LOGIC;                     -- 1 Pulse pour ecrire le registre buswrite
141
   SIGNAL rd_reg           : STD_LOGIC;                     -- 1 pulse pour lire le registre busread
142
   SIGNAL pmrd_r           : STD_LOGIC_VECTOR(2 DOWNTO 0);  -- Pour le front du signal pmrd
143
   SIGNAL pmwr_r           : STD_LOGIC_VECTOR(2 DOWNTO 0);  -- Pour le front du signal pmwr
144
   SIGNAL pmall_r          : STD_LOGIC_VECTOR(2 DOWNTO 0);  -- Pour le front du signal pmall
145
   SIGNAL pulse_pmall      : STD_LOGIC;                     -- 1 pulse sur front de pmall
146
 
147
   -- Signaux de gestion interne
148
   SIGNAL bfo1    : STD_LOGIC;                           -- 1 pulse pour une trame reçue avec un format format sur port 1
149
   SIGNAL bfo2    : STD_LOGIC;                           -- 1 pulse pour une trame reçue avec un format format sur port 2
150
 
151
   SIGNAL difftx_free   : STD_LOGIC_VECTOR(11 DOWNTO 0); -- Pour calculer le nombre d'octets libres dans la FIFO Tx
152
   SIGNAL fifotx_datacnt: STD_LOGIC_VECTOR(11 DOWNTO 0); -- Nombre d'octets stockés dans la FIFO Tx
153
   SIGNAL wr_datatx     : STD_LOGIC;                     -- Signal d'écriture dans la FIFO Tx
154
   SIGNAL rd_datatx     : STD_LOGIC;                     -- Signal de lecture dans la FIFO Tx
155
   SIGNAL datatx_rd     : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Flux lu dans la FIFO Tx
156
   SIGNAL fifotx_empty  : STD_LOGIC;                     -- FIFO Tx vide
157
   SIGNAL rst_fifotx    : STD_LOGIC;                     -- Pour clearer la FIFO Tx
158
   SIGNAL cpt_tx        : STD_LOGIC_VECTOR(7 DOWNTO 0);  -- Compteur d'octets à transmettre
159
   SIGNAL start_tx      : STD_LOGIC;                     -- Déclenche l'émission de la trame stockée dans la FIFO Tx
160
   SIGNAL clr_starttx   : STD_LOGIC;                     -- Reset de la commande d'émission
161
   SIGNAL mem_stuf      : STD_LOGIC;                     -- Mémorise la demande d'émission de caractères 7Eh
162
 
163
   SIGNAL fiforx_datacnt1: STD_LOGIC_VECTOR(10 DOWNTO 0);-- Nombre d 'octets dans la FIFO Rx1
164
   SIGNAL rd_datarx1     : STD_LOGIC;                    -- Lecture d'un octet dans la FIFO Rx1
165
   SIGNAL fiforx_empty1  : STD_LOGIC;                    -- FIFO Rx1 vide
166
 
167
   SIGNAL fiforx_datacnt2: STD_LOGIC_VECTOR(10 DOWNTO 0);-- Nombre d 'octets dans la FIFO Rx2
168
   SIGNAL rd_datarx2     : STD_LOGIC;                    -- Lecture d'un octet dans la FIFO Rx2
169
   SIGNAL fiforx_empty2  : STD_LOGIC;                    -- FIFO Rx2 vide
170
 
171
   SIGNAL l7_rd          : STD_LOGIC;           -- Signal de lecture dans le buffer applicatif Rx1 ou Rx2
172
   SIGNAL l7_rd1buf      : STD_LOGIC;           -- Signal de lecture dans la buffer applciatif Rx1      
173
   SIGNAL l7_rd2buf      : STD_LOGIC;           -- Signal de lecture dans la buffer applciatif Rx2
174
   SIGNAL sel_voie       : STD_LOGIC;           -- Sélection de la voie 1 ou 1
175
   SIGNAL frm2           : STD_LOGIC;           -- Indique une trame dispo dans le buffer Rx1
176
   SIGNAL frm1           : STD_LOGIC;           -- Indique une trame dispo dans le buffer Rx2
177
   SIGNAL comdispo       : STD_LOGIC;           -- Au moins une trame dispo dans le buffer sélectionné
178
   SIGNAL soc            : STD_LOGIC;           -- Indique un début de trame sur la voie sélectionnée
179
 
180
   COMPONENT fifotx_pmp
181
   PORT (
182
      rst      : IN STD_LOGIC;
183
      clk      : IN STD_LOGIC;
184
      din      : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
185
      wr_en    : IN STD_LOGIC;
186
      rd_en    : IN STD_LOGIC;
187
      dout     : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
188
      full     : OUT STD_LOGIC;
189
      empty    : OUT STD_LOGIC;
190
      data_count : OUT STD_LOGIC_VECTOR(11 DOWNTO 0)
191
      );
192
   END COMPONENT;
193
 
194
   COMPONENT fiforx_pmp
195
   PORT (
196
      rst      : IN STD_LOGIC;
197
      clk      : IN STD_LOGIC;
198
      din      : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
199
      wr_en    : IN STD_LOGIC;
200
      rd_en    : IN STD_LOGIC;
201
      dout     : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
202
      full     : OUT STD_LOGIC;
203
      empty    : OUT STD_LOGIC;
204
      data_count : OUT STD_LOGIC_VECTOR(10 DOWNTO 0)
205
      );
206
   END COMPONENT;
207
 
208
BEGIN
209
   --------------------------------------------
210
   -- Process de gestion du PMP
211
   --------------------------------------------
212
   pmd <= busread WHEN pmrd = '1' ELSE (OTHERS => 'Z');  -- On place une donnée sur le bus synchrone à pmrd
213
 
214
   getadd : PROCESS(pmall)
215
   BEGIN
216
      IF (pmall'EVENT AND pmall = '1') THEN
217
      -- On latche les LSB du bus d'address
218
         adreg <= pmd(6 DOWNTO 0);
219
      END IF;
220
   END PROCESS;
221
 
222
   getdat : PROCESS(pmwr)
223
   BEGIN
224
      IF (pmwr'EVENT AND pmwr = '0') THEN
225
      -- On latche la donnée à écrire sur front descendant de pmwr
226
         buswrite <= pmd;
227
      END IF;
228
   END PROCESS;
229
 
230
   -- Gestion de la metastabiltié des signaux pmall, pmrd et pmwr pour passsage à clk_sys
231
   front_sig : PROCESS(clk_sys, rst_n)
232
   BEGIN
233
      IF (rst_n = '0') THEN
234
         pmall_r <= (OTHERS => '0');
235
         pmrd_r  <= (OTHERS => '0');
236
         pmwr_r  <= (OTHERS => '0');
237
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
238
         pmall_r <= pmall_r(1 DOWNTO 0) & pmall;
239
         pmrd_r <= pmrd_r(1 DOWNTO 0) & pmrd;
240
         pmwr_r <= pmwr_r(1 DOWNTO 0) & pmwr;
241
      END IF;
242
   END PROCESS;
243
   pulse_pmall <= NOT(pmall_r(2)) AND pmall_r(1);  -- Front montant de pmall
244
   rd_reg <= NOT(pmrd_r(2)) AND pmrd_r(1);         -- Front montant de pmrd
245
   wr_reg <= pmwr_r(2) AND NOT(pmwr_r(1));         -- Front descendant de pmwr
246
 
247
 
248
   --------------------------------------------
249
   -- Process de gestion du Read en focntion de l'adresse(MUX)
250
   --------------------------------------------
251
   mux_read: PROCESS(clk_sys, rst_n)
252
   BEGIN
253
      IF (rst_n = '0') THEN
254
         busread <= (OTHERS => '0');
255
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
256
         IF (pulse_pmall = '1') THEN
257
         -- Sur front montant de pmall (l'adresse a été latchée)
258
            CASE adreg IS
259
               WHEN adreg_iid    => busread <= iid(63 DOWNTO 56);
260
               WHEN adreg_iid+1  => busread <= iid(55 DOWNTO 48);
261
               WHEN adreg_iid+2  => busread <= iid(47 DOWNTO 40);
262
               WHEN adreg_iid+3  => busread <= iid(39 DOWNTO 32);
263
               WHEN adreg_iid+4  => busread <= iid(31 DOWNTO 24);
264
               WHEN adreg_iid+5  => busread <= iid(23 DOWNTO 16);
265
               WHEN adreg_iid+6  => busread <= iid(15 DOWNTO 8);
266
               WHEN adreg_iid+7  => busread <= iid(7 DOWNTO 0);
267
               WHEN adreg_tid    => busread <= reg_tid;
268
               WHEN adreg_ctl    => busread <= reg_ctl(7 DOWNTO 6) & mem_stuf & reg_ctl(4 DOWNTO 0);
269
               WHEN adreg_stat   => busread <= reg_stat;
270
               WHEN adreg_rxsize1=> busread <= reg_rx1size;
271
               WHEN adreg_rxsize2=> busread <= reg_rx2size;
272
               WHEN adreg_txfree => busread <= reg_txfree;
273
               WHEN adreg_fiforx1=> busread <= reg_fiforx1;
274
               WHEN adreg_fiforx2=> busread <= reg_fiforx2;
275
               -- WHEN adreg_fifotx => busread <= dummy  -- Ce registre est Write Only
276
               WHEN adreg_version=> busread <= version;
277
               WHEN adreg_confrp => busread <= reg_confrp;
278
               WHEN adreg_promctl=> busread <= rxprom_val & reg_promctl(6 DOWNTO 4) & prom_busy & reg_promctl(2 DOWNTO 0);
279
               WHEN adreg_promnbrd=>busread <= reg_promnbrd;
280
               -- WHEN adreg_promtx => data_rdspi <= dummy  -- Ce registre est Write Only
281
               WHEN adreg_promrx=>  busread <= rxprom_dat;
282
               WHEN adreg_fifoforce=> busread <= data_force;
283
               WHEN OTHERS       => busread <= reg_stat;
284
            END CASE;
285
         END IF;
286
      END IF;
287
   END PROCESS;
288
   rd_force <= '1' WHEN (rd_reg = '1' AND adreg = adreg_fifoforce) ELSE '0';
289
 
290
   --------------------------------------------
291
   -- Process de gestion des écritures dans les registres
292
   --------------------------------------------
293
   write_reg : PROCESS(clk_sys, rst_n)
294
   BEGIN
295
      IF (rst_n = '0') THEN
296
         reg_tid <= x"8F";
297
         reg_ctl <= x"84";
298
         reg_confrp <= x"00";
299
         reg_promctl <= x"00";
300
         reg_promnbrd <= x"00";
301
         mem_stuf <= '0';
302
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
303
         IF (wr_reg = '1') THEN
304
         -- Sur front descendant de pmwr (la donnée a été latchée dans buswrite)
305
            CASE adreg IS
306
               WHEN adreg_tid =>
307
                  reg_tid    <= buswrite;
308
               WHEN adreg_ctl =>
309
                  reg_ctl(7 DOWNTO 4)    <= buswrite(7 DOWNTO 4);
310
                  reg_ctl(2 DOWNTO 0)    <= buswrite(2 DOWNTO 0);
311
               WHEN adreg_confrp =>
312
                  reg_confrp <= buswrite;
313
               WHEN adreg_promnbrd =>
314
                  reg_promnbrd <= buswrite;
315
               WHEN OTHERS =>
316
            END CASE;
317
         END IF;
318
         IF (clr_starttx = '1') THEN
319
         -- Condition de reset du start_tx
320
            reg_ctl(3) <= '0';
321
         ELSE
322
            IF (wr_reg = '1') AND (adreg = adreg_ctl) AND (buswrite(3) = '1') THEN
323
            -- On ne peut écrire qu'un '1' dans le registre start_tx
324
               reg_ctl(3) <= '1';
325
            END IF;
326
         END IF;
327
         IF (acq_stuf = '1') THEN
328
         -- condition de reset de l'ordre de stuffing
329
            mem_stuf <= '0';
330
         ELSE
331
            IF (wr_reg = '1') AND (adreg = adreg_ctl) AND (buswrite(5) = '1') THEN
332
            -- On ne peut écrire qu'un '1' dans le registre stuf_phys
333
               mem_stuf <= '1';
334
            END IF;
335
         END IF;
336
         IF (wr_reg = '1' AND adreg = adreg_promctl) THEN
337
            reg_promctl <= buswrite;
338
         ELSE
339
         -- Le bit 3 ne doit durer qu'un seul coup de clk_sys
340
            reg_promctl(3) <= '0';
341
         END IF;
342
      END IF;
343
   END PROCESS;
344
   -- Affectation des bits de controle et de configuration
345
   cpy1        <= reg_ctl(0);
346
   cpy2        <= reg_ctl(1);
347
   rst_fifotx  <= reg_ctl(2);
348
   start_tx    <= reg_ctl(3);
349
   topcyc      <= reg_ctl(4);
350
   enafiltdble <= reg_ctl(6);
351
   repli       <= reg_ctl(7);
352
   actif       <= reg_confrp(0);
353
   baudrate    <= reg_confrp(3 DOWNTO 1);
354
   tid         <= reg_tid;
355
   stuf_phys   <= mem_stuf;
356
 
357
   --------------------------------------------
358
   -- Process de gestion du registre de status
359
   --------------------------------------------
360
   bfo1 <= l7_newframe1 AND NOT(l7_l2ok1);   -- Définition d'une mauvaise trame sur port 1
361
   bfo2 <= l7_newframe2 AND NOT(l7_l2ok2);   -- Définition d'une mauvaise trame sur port 2
362
 
363
   gest_stat : PROCESS(clk_sys, rst_n)
364
   BEGIN
365
      IF (rst_n = '0') THEN
366
         reg_stat(7 DOWNTO 2) <= (OTHERS => '0');
367
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
368
      -- Les bits passent à '1' sur évènement et sont remis à '0' par un WOC
369
         IF (bfo1 = '1') THEN
370
         -- Si l'évènement est actif (plus prioritaire que le WOC) on le mémorise
371
            reg_stat(2) <= '1';
372
         ELSIF (wr_reg = '1' AND adreg = adreg_stat) THEN
373
         -- Si on écrit dans le registre
374
            reg_stat(2) <= reg_stat(2) AND NOT(buswrite(2));-- Un '1' dans le registre force à '0'. Un '0' laisse inchangé
375
         END IF;
376
         IF (bfo2 = '1') THEN
377
            reg_stat(3) <= '1';
378
         ELSIF (wr_reg = '1' AND adreg = adreg_stat) THEN
379
            reg_stat(3) <= reg_stat(3) AND NOT(buswrite(3));
380
         END IF;
381
         IF (l7_overflow1 = '1') THEN
382
            reg_stat(4) <= '1';
383
         ELSIF (wr_reg = '1' AND adreg = adreg_stat) THEN
384
            reg_stat(4) <= reg_stat(4) AND NOT(buswrite(4));
385
         END IF;
386
         IF (l7_overflow2 = '1') THEN
387
            reg_stat(5) <= '1';
388
         ELSIF (wr_reg = '1' AND adreg = adreg_stat) THEN
389
            reg_stat(5) <= reg_stat(5) AND NOT(buswrite(5));
390
         END IF;
391
                        reg_stat(6) <= NOT(fifotx_empty);
392
                        reg_stat(7) <= NOT(empty_force);
393
      END IF;
394
   END PROCESS;
395
   reg_stat(1 DOWNTO 0) <= frm2 & frm1;
396
 
397
   -------------------------------------------------
398
   -- Signaux de gestion de l'I/F SPI vers la PROM
399
   -------------------------------------------------
400
   txprom_dat     <= buswrite;    -- Le registre est géré par le module PROM (affectation combinatoire)
401
   -- Le validant correspondant à un ordre d'écriture valide
402
   txprom_val     <= wr_reg WHEN (adreg =  adreg_promtx) ELSE '0';
403
   -- On récupère une donnée de plus dans la FIFO PROM avec une elcture valide
404
   rxprom_next    <= rd_reg WHEN (adreg =  adreg_promrx) ELSE '0';
405
   -- Affectation des signaux de controle
406
   prom_type_com  <= reg_promctl(0);
407
   prom_exec_com  <= reg_promctl(3);
408
   prom_rstn      <= reg_promctl(4);
409
   prom_nbread    <= reg_promnbrd;
410
 
411
   --------------------------------------------
412
   -- Process de gestion de la FIFO Tx
413
   --------------------------------------------
414
   difftx_free <= "100000000001" - fifotx_datacnt; -- Calcul du nombre d'octets dispo dans la FIFO 257-cnt
415
   reg_txfree <= x"FF" WHEN difftx_free(11 DOWNTO 8) /= "000000" ELSE  -- Si txfree >=256 on tronque le résultat
416
                     difftx_free(7 DOWNTO 0);              -- Sinon on donne le résultat
417
 
418
   -- Condition d'écriture d'un octet dans la FIFO TX
419
   wr_datatx <= '1' WHEN (wr_reg = '1' AND adreg = adreg_fifotx) ELSE '0';
420
 
421
   clr_fifo_tx <= '0';              -- Spare pour l'instant on ne fait pas de clear de la fifo tx aval
422
 
423
   -- On lit un octet dans la FIFO TX au début lorsqu'on détecte qu'elle n'est plus vide
424
   -- ou bien en cours de transfert lorsque le module suivant est dispo
425
   rd_datatx <= '1' WHEN ((fsm_tx = idle_st AND fifotx_empty = '0' AND start_tx = '1') OR
426
                          (fsm_tx = senddat_st AND txdat_free = '1' AND fifotx_empty = '0')) ELSE
427
                    '0';
428
 
429
   val_txdat <= NOT(fifotx_empty) WHEN (fsm_tx = idle_st) ELSE '1';
430
   tx_dat <= datatx_rd;    -- Flux de donnée à transmettre lu dans la FIFO Tx
431
   -- Le EOF es tsynchrone de la dernière donnée transmise
432
   tx_eof <= txdat_free WHEN (fsm_tx = senddat_st AND cpt_tx = "00000001") ELSE '0';
433
 
434
   -------------------------------------------
435
   -- Machine d'état de gestion de la transmission
436
   -- Attend l'ordre de transmission start_tx
437
   -- Lit la taille de la trame à transmettre (1er octet)
438
   -- Emet les octets qui suivent
439
   -------------------------------------------
440
   gest_fsm_tx : PROCESS(clk_sys, rst_n)
441
   BEGIN
442
      IF (rst_n = '0') THEN
443
         fsm_tx <= idle_st;
444
         tx_sof    <= '0';
445
         cpt_tx    <= (OTHERS => '0');
446
         clr_starttx <= '0';
447
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
448
         CASE fsm_tx IS
449
            WHEN idle_st  =>
450
            -- Etat d'attente de données dans la FIFO TX
451
               IF (fifotx_empty = '0' AND start_tx = '1') THEN
452
               -- Si il y'a des données dans la FIFO TX et qu'on reçoit l'ordre d'émettre
453
                  cpt_tx <= datatx_rd;       -- On initialise le compteur avec la longueur de la trame
454
                  fsm_tx <= senddat_st;      -- On va transmettre des données
455
                  tx_sof <= '1';             -- On active le sof pour signaler un début de trame
456
                  clr_starttx <= '1';        -- Indique qu'on a pris en compte l'ordre de transmission
457
               END IF;
458
 
459
            WHEN senddat_st =>
460
            -- Etat de transfert d'une donnée
461
               clr_starttx <= '0';           -- On annule le clear du start_tx pour permettre au soiftde le remettre 
462
               IF (txdat_free = '1') THEN
463
               -- Les données restent sur le bus tx_dat tant que le module suivant n'est pas libre
464
               -- i.e. tant qu'il a pas latché la donnée actuelle
465
                  cpt_tx <= cpt_tx - 1;         -- Dans ce cas on enregistre une donnee de moins
466
                  tx_sof <= '0';                -- On peut annuler le sof car on est sur que le module suivant l'a pris en comtpe
467
                  IF (cpt_tx = "00000001") THEN -- Lors du dernier octet à transmettre
468
                     fsm_tx <= idle_st;         -- On a fini
469
                  END IF;
470
               END IF;
471
 
472
            WHEN OTHERS =>
473
               fsm_tx <= idle_st;
474
         END CASE;
475
      END IF;
476
   END PROCESS;
477
 
478
   inst_fiftx : fifotx_pmp
479
   PORT MAP (
480
      rst      => rst_fifotx,
481
      clk      => clk_sys,
482
      din      => buswrite,
483
      wr_en    => wr_datatx,
484
      rd_en    => rd_datatx,
485
      dout     => datatx_rd,
486
      full     => OPEN,
487
      empty    => fifotx_empty,
488
      data_count => fifotx_datacnt
489
   );
490
 
491
   --------------------------------------------
492
   -- Process de gestion des FIFO Rx
493
   --------------------------------------------
494
   -- On lit la bonne FIFO selon l'adresse du registre
495
   rd_datarx1 <= '1' WHEN (rd_reg = '1' AND adreg = adreg_fiforx1) ELSE '0';
496
   rd_datarx2 <= '1' WHEN (rd_reg = '1' AND adreg = adreg_fiforx2) ELSE '0';
497
 
498
   -- Odre de lecture dans le bon buffer selon la voie sélectionnée
499
   l7_rd1buf <= (l7_rd AND NOT(sel_voie) AND comdispo AND NOT(soc)) WHEN (fsm_rx = recdat_st) ELSE
500
                (l7_rd AND NOT(sel_voie));
501
   l7_rd1 <= l7_rd1buf;
502
   l7_rd2buf <= (l7_rd AND sel_voie AND comdispo AND NOT(soc)) WHEN (fsm_rx = recdat_st) ELSE
503
                (l7_rd AND sel_voie);
504
   l7_rd2 <= l7_rd2buf;
505
 
506
   -- Dispo des trames en fonction de la voie sélectionnée
507
   comdispo <= l7_comdispo1 WHEN (sel_voie = '0') ELSE l7_comdispo2;
508
   -- Début de trame en fonction de la voie sélectionnée
509
   soc <= l7_soc1 WHEN (sel_voie = '0') ELSE l7_soc2;
510
 
511
   ----------------------------------
512
   -- Machine d'état de récupération des trames dans le buffer applicatif
513
   -- et stockage dans la FIFO correspondante
514
   -- Les trames sont remontées une par une en alternant voie 1 / voie 2
515
   ----------------------------------
516
   gest_fsm_rx : PROCESS(clk_sys, rst_n)
517
   BEGIN
518
      IF (rst_n = '0') THEN
519
         l7_rd <= '0';
520
         sel_voie <= '0';
521
         fsm_rx <= idle_st;
522
         frm2 <= '0';
523
         frm1 <= '0';
524
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
525
         CASE fsm_rx IS
526
            WHEN idle_st  =>
527
               frm1 <= NOT(fiforx_empty1);      -- On échantillonne la présence de trames pour être sur 
528
               frm2 <= NOT(fiforx_empty2);      -- qu'on ne traite que des trames entières
529
               IF ((l7_comdispo1 = '1' AND fiforx_empty1 = '1') AND
530
                   (l7_comdispo2 = '0' OR  fiforx_empty2 = '0' OR sel_voie = '1')) THEN
531
               -- Si on a des trames en voie1 et qu'il n'y en a pas déjà une dans la FIFO
532
               -- Et que soit on peut traiter la voie 2 (pas de trame ou FIFO non vide) soit
533
               -- on a traité la voie 2 au coup d'avant
534
                  sel_voie <= '0';              -- On va traiter la voie 1
535
                  l7_rd <= '1';                 -- On lit en continu
536
                  fsm_rx <= pump_st;
537
               ELSIF (l7_comdispo2 = '1' AND fiforx_empty2 = '1') THEN
538
               -- si on peut traiter la voie 2
539
                  sel_voie <= '1';
540
                  l7_rd <= '1';
541
                  fsm_rx <= pump_st;
542
               ELSE
543
                  l7_rd <= '0';
544
               END IF;
545
 
546
            WHEN pump_st =>
547
            -- Etat d'attente pour amorcer la lecture de la mémoire applicative
548
               fsm_rx <= recdat_st;
549
 
550
            WHEN recdat_st =>
551
            -- Etat d'écriture des données jusqu'à ce que la mémoire applicative soit vide
552
            -- ou qu'on rencontre un début de trame
553
               IF (soc = '1' OR comdispo = '0') THEN
554
                  l7_rd <= '0';
555
                  fsm_rx <= waitnotempty_st;
556
               END IF;
557
 
558
            WHEN waitnotempty_st =>
559
            -- Etat d'attente que la FIFO soit indiquée comme non vide
560
            -- pour ne pas être rerentrant dans l'algo
561
               IF ((fiforx_empty1 = '0' AND sel_voie = '0') OR
562
                  (fiforx_empty2 = '0' AND sel_voie = '1')) THEN
563
                  frm1 <= NOT(sel_voie);
564
                  frm2 <= sel_voie;
565
                  fsm_rx <= idle_st;
566
               END IF;
567
 
568
            WHEN OTHERS =>
569
               fsm_rx <= idle_st;
570
         END CASE;
571
      END IF;
572
   END PROCESS;
573
 
574
   inst_fifrx1 : fiforx_pmp
575
   PORT MAP (
576
      rst      => NOT(rst_n),
577
      clk      => clk_sys,
578
      din      => l7_rx1,
579
      wr_en    => l7_rd1buf,
580
      rd_en    => rd_datarx1,
581
      dout     => reg_fiforx1,
582
      full     => OPEN,
583
      empty    => fiforx_empty1,
584
      data_count => fiforx_datacnt1
585
   );
586
   -- Taille de la trame dans la FIFO : 255 si >= 256, sinon Nb octets dans la FIFO
587
   reg_rx1size <= x"FF" WHEN fiforx_datacnt1(10 DOWNTO 8) /= "000" ELSE
588
                      fiforx_datacnt1(7 DOWNTO 0);
589
 
590
   inst_fifrx2 : fiforx_pmp
591
   PORT MAP (
592
      rst      => NOT(rst_n),
593
      clk      => clk_sys,
594
      din      => l7_rx2,
595
      wr_en    => l7_rd2buf,
596
      rd_en    => rd_datarx2,
597
      dout     => reg_fiforx2,
598
      full     => OPEN,
599
      empty    => fiforx_empty2,
600
      data_count => fiforx_datacnt2
601
   );
602
   -- Taille de la trame dans la FIFO : 255 si >= 256, sinon Nb octets dans la FIFO
603
   reg_rx2size <= x"FF" WHEN fiforx_datacnt2(10 DOWNTO 8) /= "000" ELSE
604
                      fiforx_datacnt2(7 DOWNTO 0);
605
 
606
END rtl;
607
 

powered by: WebSVN 2.1.0

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