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

Subversion Repositories saturn

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

powered by: WebSVN 2.1.0

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