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

Subversion Repositories saturn

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 DavidRAMBA
--============================================================================= 
2
--  TITRE : IF_PICSPI
3
--  DESCRIPTION : 
4
--       Assure l'interface avec le PIC21 à travers un lien SPI
5
--       Implémente les registres mémoires tels que définis dans le HSI
6
 
7
--  FICHIER :        if_picspi.vhd 
8
--=============================================================================
9
--  CREATION 
10
--  DATE        AUTEUR  PROJET  REVISION 
11
--  29/02/2012  DRA     CONCERTO        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
 
23
 
24
-- Uncomment the following library declaration if instantiating
25
-- any Xilinx primitives in this code.
26
--library UNISIM;
27
--use UNISIM.VComponents.all;
28
 
29
ENTITY if_picspi IS
30
   GENERIC (
31
      version : STD_LOGIC_VECTOR(7 DOWNTO 0));
32
   PORT (
33
      -- Ports système
34
      clk_sys  : IN  STD_LOGIC;  -- Clock système
35
      rst_n    : IN  STD_LOGIC;  -- Reset génrél système
36
 
37
      -- Interface SPI
38
      sclk     : IN  STD_LOGIC;  -- Clock SPI
39
      sdi      : IN  STD_LOGIC;  -- Bit IN SPI
40
      sdo      : OUT STD_LOGIC;  -- Bit OUT SPI
41
      ssn      : IN  STD_LOGIC;  -- CSn SPI
42
 
43
      -- Interface avec les autres modules du FPGA
44
      -- Tous ces signaux sont synchrones de clk_sys
45
         -- Signaux de configurations
46
      iid      : IN  STD_LOGIC_VECTOR(63 DOWNTO 0);   -- Identifiant IID du FPGA
47
      tid      : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);    -- Identifiant TID du FPGA
48
      cpy1     : OUT STD_LOGIC;                       -- Autorise la recopie du port 1 sur port 2
49
      cpy2     : OUT STD_LOGIC;                       -- Autorise la recopie du port 2 sur port 1
50
      repli    : OUT STD_LOGIC;                       -- Indique que le module est en repli (gestion des LED)
51
 
52
      -- Interfaces de lecture des trames port 1
53
      l7_rx1       : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);-- Données reçues sur port 1
54
      l7_soc1      : IN  STD_LOGIC;                   -- Indique le début d'une trame
55
      l7_rd1       : OUT STD_LOGIC;                   -- Signal de lecture d'une donnée supplémentaire
56
      l7_comdispo1 : IN  STD_LOGIC;                   -- Indique qu'il y'a au moins une trame de dispo
57
      l7_newframe1 : IN  STD_LOGIC;                   -- Indique la réception d'une nouvelle trame
58
      l7_l2ok1     : IN  STD_LOGIC;                   -- Indique si la couche transport est bonne ou non
59
      l7_overflow1 : IN  STD_LOGIC;                   -- Indique un overflow sur réception
60
 
61
         -- Interfaces de lecture des trames port 2
62
      l7_rx2       : IN  STD_LOGIC_VECTOR(7 DOWNTO 0);-- Données reçues sur port 2
63
      l7_soc2      : IN  STD_LOGIC;                   -- Indique le début d'une trame
64
      l7_rd2       : OUT STD_LOGIC;                   -- Signal de lecture d'une donnée supplémentaire
65
      l7_comdispo2 : IN  STD_LOGIC;                   -- Indique qu'il y'a au moins une trame de dispo
66
      l7_newframe2 : IN  STD_LOGIC;                   -- Indique la réception d'une nouvelle trame
67
      l7_l2ok2     : IN  STD_LOGIC;                   -- Indique si la couche transport est bonne ou non
68
      l7_overflow2 : IN  STD_LOGIC;                   -- Indique un overflow sur réception
69
 
70
      -- Interface d'écriture des trames
71
      tx_dat       : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);-- Données à transmettre sur les 2 ports
72
      val_txdat    : OUT STD_LOGIC;                   -- Validant de chaque octet
73
      tx_sof       : OUT STD_LOGIC;                   -- Indique le début d'une trame
74
      tx_eof       : OUT STD_LOGIC;                   -- Indique la fin d'une trame
75
      txdat_free   : IN  STD_LOGIC;                   -- Indique que la couche transport en tx est libre
76
      clr_fifo_tx  : OUT STD_LOGIC;                   -- Permet de purger les FIFO Tx
77
 
78
      -- Gestion de l'interface SPI PROM
79
      txprom_dat   : OUT STD_LOGIC_VECTOR(7 downto 0);
80
      txprom_val   : OUT STD_LOGIC;
81
      rxprom_dat   : IN  STD_LOGIC_VECTOR(7 downto 0);
82
      rxprom_val   : IN  STD_LOGIC;
83
      rxprom_next  : OUT STD_LOGIC;
84
      prom_type_com: OUT STD_LOGIC;
85
      prom_exec_com: OUT STD_LOGIC;
86
      prom_busy    : IN  STD_LOGIC;
87
      prom_nbread  : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
88
      prom_rstn    : OUT STD_LOGIC
89
      );
90
END if_picspi;
91
 
92
ARCHITECTURE rtl of if_picspi is
93
   TYPE fsmtx_state IS (idle_st, senddat_st);
94
   SIGNAL fsm_tx  : fsmtx_state;
95
 
96
   TYPE fsmrx_state IS (idle_st, pump_st, recdat_st, waitnotempty_st);
97
   SIGNAL fsm_rx  : fsmrx_state;
98
 
99
   -- Définition du Mapping mémoire des registre SPI
100
   CONSTANT adreg_iid      : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(0, 7);
101
   CONSTANT adreg_tid      : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(8, 7);
102
   CONSTANT adreg_ctl      : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(9, 7);
103
   CONSTANT adreg_stat     : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(10, 7);
104
   CONSTANT adreg_rxsize1  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(11, 7);
105
   CONSTANT adreg_rxsize2  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(12, 7);
106
   CONSTANT adreg_txfree   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(13, 7);
107
   CONSTANT adreg_fiforx1  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(14, 7);
108
   CONSTANT adreg_fiforx2  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(15, 7);
109
   CONSTANT adreg_fifotx   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(16, 7);
110
   CONSTANT adreg_version  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(17, 7);
111
   CONSTANT adreg_promtx   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(18, 7);
112
   CONSTANT adreg_promrx   : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(19, 7);
113
   CONSTANT adreg_promctl  : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(20, 7);
114
   CONSTANT adreg_promnbrd : STD_LOGIC_VECTOR(6 DOWNTO 0) := CONV_STD_LOGIC_VECTOR(21, 7);
115
 
116
   -- Définition des registres internes
117
   SIGNAL reg_tid_spi      : STD_LOGIC_VECTOR(7 DOWNTO 0);
118
   SIGNAL reg_ctl_spi      : STD_LOGIC_VECTOR(7 DOWNTO 0);
119
   SIGNAL reg_stat_spi     : STD_LOGIC_VECTOR(7 DOWNTO 0);
120
   SIGNAL reg_rx1size_spi  : STD_LOGIC_VECTOR(7 DOWNTO 0);
121
   SIGNAL reg_rx2size_spi  : STD_LOGIC_VECTOR(7 DOWNTO 0);
122
   SIGNAL reg_txfree_spi   : STD_LOGIC_VECTOR(7 DOWNTO 0);
123
   SIGNAL reg_fiforx1_spi  : STD_LOGIC_VECTOR(7 DOWNTO 0);
124
   SIGNAL reg_fiforx2_spi  : STD_LOGIC_VECTOR(7 DOWNTO 0);
125
 
126
   -- Signaux de gestion de l'interface SPI
127
   SIGNAL cpt_bitspi       : STD_LOGIC_VECTOR(2 DOWNTO 0); -- Compte le nombre de bits sur un cycle SPI
128
   SIGNAL adrd_spi         : STD_LOGIC_VECTOR(6 DOWNTO 0); -- Bus d'adresse d'accès des registres SPI en rd
129
   SIGNAL adwr_spi         : STD_LOGIC_VECTOR(6 DOWNTO 0); -- Bus d'adresse d'accès des registres SPI en wr
130
   SIGNAL rwn_spi          : STD_LOGIC;                    -- Mémorise le type d'accès SPI R/Wn
131
   SIGNAL dat_adn          : STD_LOGIC;          -- Indique si l'octet en cours sur SPI est une data ou l'adresse
132
   SIGNAL shifter_spirx    : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Registre à déclage de réception SPI
133
   SIGNAL shifter_spitx    : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Registre à déclage d'émission SPI
134
   SIGNAL spi_encours      : STD_LOGIC;
135
   SIGNAL data_rdspi       : STD_LOGIC_VECTOR(7 DOWNTO 0); -- Donnée lue à l'adresse adrd_spi
136
   SIGNAL wr_reg           : STD_LOGIC;               -- 1 Pulse pour lire le registre adwr_spi
137
   SIGNAL rd_reg           : STD_LOGIC;               -- 1 pulse pour écrire le registre adrd_spi
138
 
139
   -- Signaux de gestion interne et changement d'horloge
140
   SIGNAL bfo1    : STD_LOGIC;
141
   SIGNAL bfo2    : STD_LOGIC;
142
   SIGNAL ovf1_spi: STD_LOGIC;
143
   SIGNAL ovf2_spi: STD_LOGIC;
144
   SIGNAL bfo1_spi: STD_LOGIC;
145
   SIGNAL bfo2_spi: STD_LOGIC;
146
 
147
   SIGNAL cpy1_reg : STD_LOGIC;
148
   SIGNAL cpy2_reg : STD_LOGIC;
149
   SIGNAL tid_reg  : STD_LOGIC_VECTOR(7 DOWNTO 0);
150
   SIGNAL repli_reg: STD_LOGIC;
151
 
152
   SIGNAL difftx_free   : STD_LOGIC_VECTOR(10 DOWNTO 0);
153
   SIGNAL fifotx_datacnt: STD_LOGIC_VECTOR(10 DOWNTO 0);
154
   SIGNAL wr_datatx_spi : STD_LOGIC;
155
   SIGNAL rd_datatx_sys : STD_LOGIC;
156
   SIGNAL datatx_rd_sys : STD_LOGIC_VECTOR(7 DOWNTO 0);
157
   SIGNAL fifotx_empty  : STD_LOGIC;
158
   SIGNAL rst_fifotx    : STD_LOGIC;
159
   SIGNAL cpt_tx        : STD_LOGIC_VECTOR(7 DOWNTO 0);
160
 
161
   SIGNAL fiforx_datacnt1: STD_LOGIC_VECTOR(10 DOWNTO 0);
162
   SIGNAL rd_datarx_spi1 : STD_LOGIC;
163
   SIGNAL fiforx_empty1  : STD_LOGIC;
164
   SIGNAL firx_e1_r1     : STD_LOGIC;
165
   SIGNAL firx_e1_r2     : STD_LOGIC;
166
 
167
   SIGNAL fiforx_datacnt2: STD_LOGIC_VECTOR(10 DOWNTO 0);
168
   SIGNAL rd_datarx_spi2 : STD_LOGIC;
169
   SIGNAL fiforx_empty2  : STD_LOGIC;
170
   SIGNAL firx_e2_r1     : STD_LOGIC;
171
   SIGNAL firx_e2_r2     : STD_LOGIC;
172
 
173
   SIGNAL l7_rd          : STD_LOGIC;
174
   SIGNAL l7_rd1buf      : STD_LOGIC;
175
   SIGNAL l7_rd2buf      : STD_LOGIC;
176
   SIGNAL sel_voie       : STD_LOGIC;
177
   SIGNAL frm2           : STD_LOGIC;
178
   SIGNAL frm2_r1        : STD_LOGIC;
179
   SIGNAL frm2_r2        : STD_LOGIC;
180
   SIGNAL frm1           : STD_LOGIC;
181
   SIGNAL frm1_r1        : STD_LOGIC;
182
   SIGNAL frm1_r2        : STD_LOGIC;
183
   SIGNAL comdispo       : STD_LOGIC;
184
   SIGNAL soc            : STD_LOGIC;
185
 
186
   SIGNAL reg_promctl    : STD_LOGIC_VECTOR(7 DOWNTO 0);
187
   SIGNAL reg_promnbrd   : STD_LOGIC_VECTOR(7 DOWNTO 0);
188
 
189
   COMPONENT jk_chgclk
190
   PORT (
191
      rstn     : IN  STD_LOGIC;  -- Reset général
192
      clk1     : IN  STD_LOGIC;  -- Horloge principale 1
193
      clk2     : IN  STD_LOGIC;  -- Horloge principale 2
194
      pulsein  : IN  STD_LOGIC;  -- Signal synchronie de clk1 à prendre en compte avec clk2
195
      pulseout : OUT STD_LOGIC   -- Pulse sur clk2 sur front montant de pulse1
196
      );
197
   END COMPONENT;
198
 
199
   COMPONENT fifotx_spi
200
   PORT (
201
      rst      : IN STD_LOGIC;
202
      wr_clk   : IN STD_LOGIC;
203
      rd_clk   : IN STD_LOGIC;
204
      din      : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
205
      wr_en    : IN STD_LOGIC;
206
      rd_en    : IN STD_LOGIC;
207
      dout     : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
208
      full     : OUT STD_LOGIC;
209
      empty    : OUT STD_LOGIC;
210
      wr_data_count : OUT STD_LOGIC_VECTOR(10 DOWNTO 0)
211
      );
212
   END COMPONENT;
213
 
214
   COMPONENT fiforx_spi
215
   PORT (
216
      rst      : IN STD_LOGIC;
217
      wr_clk   : IN STD_LOGIC;
218
      rd_clk   : IN STD_LOGIC;
219
      din      : IN STD_LOGIC_VECTOR(7 DOWNTO 0);
220
      wr_en    : IN STD_LOGIC;
221
      rd_en    : IN STD_LOGIC;
222
      dout     : OUT STD_LOGIC_VECTOR(7 DOWNTO 0);
223
      full     : OUT STD_LOGIC;
224
      empty    : OUT STD_LOGIC;
225
      rd_data_count : OUT STD_LOGIC_VECTOR(10 DOWNTO 0)
226
      );
227
   END COMPONENT;
228
 
229
BEGIN
230
   --------------------------------------------
231
   -- Process de gestion du SPI
232
   --------------------------------------------
233
   sdo <= shifter_spitx(7);
234
   rd_reg <= (dat_adn AND rwn_spi AND NOT(ssn)) WHEN (cpt_bitspi = "111" AND spi_encours = '1') ELSE
235
             NOT(ssn) WHEN spi_encours = '0' ELSE
236
             '0';
237
   wr_reg <= (spi_encours AND dat_adn AND NOT(rwn_spi)) WHEN (cpt_bitspi = "111") ELSE '0';
238
 
239
   serrx_spi : PROCESS(sclk, rst_n)
240
   BEGIN
241
      IF (rst_n = '0') THEN
242
         cpt_bitspi  <= (OTHERS => '0');
243
         adrd_spi    <= (OTHERS => '0');
244
         adwr_spi    <= (OTHERS => '0');
245
         rwn_spi     <= '0';
246
         dat_adn     <= '0';
247
         shifter_spirx  <= (OTHERS => '0');
248
         spi_encours    <= '0';
249
      ELSIF (sclk'EVENT and sclk = '1') THEN
250
         IF (spi_encours = '1' AND ssn = '0') THEN
251
         -- Si une transaction SPI est en cours et temps qu'elle est en cours (ssn = '0')
252
            cpt_bitspi <= cpt_bitspi + 1;                      -- On comtpe librement le nombre de bits de 0 à 7
253
            shifter_spirx <= shifter_spirx(6 DOWNTO 0) & sdi;  -- On déserailsie tout le temps
254
            IF (cpt_bitspi = "110") THEN
255
            -- Si on a déjà reçu 7 bits, le prochain front montant est pour le 8ème en réception
256
               IF (dat_adn = '0') THEN
257
               -- Si c'est le 1er octet de la trame SPI
258
                  IF (sdi = '1') THEN
259
                     dat_adn <= '1';            -- On mémorise le fait qu'on a eu l'@
260
                  END IF;
261
                  rwn_spi <= sdi;            -- On mémorise si c'est un Rd ou un Wr
262
                  adrd_spi  <= shifter_spirx(6 DOWNTO 0);  -- On mémorise l'adresse d'accès
263
               ELSE
264
                  adwr_spi <= adrd_spi;
265
                  IF (adrd_spi /= adreg_fiforx1 AND
266
                      adrd_spi /= adreg_fiforx2 AND
267
                      adrd_spi /= adreg_fifotx  AND
268
                      adrd_spi /= adreg_promtx  AND
269
                      adrd_spi /= adreg_promrx) THEN
270
                  -- Si on accède à un registre qui n'est pas une FIFO, on incrémente le pointeur d'@
271
                     adrd_spi <= adrd_spi + 1;
272
                  END IF;
273
               END IF;
274
            ELSIF (cpt_bitspi = "111") THEN
275
            -- Si on est au 8ème coup d'horloge
276
               dat_adn <= '1';
277
            END IF;
278
         ELSE
279
         -- Si une transaction n'est pas en cours
280
            IF (ssn = '0') THEN
281
            -- Au début d'une transaction
282
               spi_encours <= '1';              -- Pour détecter le front descendant de ssn
283
               dat_adn <= '0';                  -- Le prochain octet sera celui de l'adresse
284
               cpt_bitspi <= (OTHERS => '0');   -- On va comtper de 0 à 7 le nombre de bits
285
               shifter_spirx(0) <= sdi;         -- Sur ce front on échantillone le premier bit
286
            ELSE
287
               spi_encours <= '0';              -- Pour détecter le front descendant de ssn
288
               adrd_spi <= adreg_stat;
289
            END IF;
290
         END IF;
291
      END IF;
292
   END PROCESS;
293
 
294
   sertx_spi : PROCESS(sclk, rst_n)
295
   BEGIN
296
      IF (rst_n = '0') THEN
297
         shifter_spitx  <= (OTHERS => '0');
298
      ELSIF (sclk'EVENT and sclk = '0') THEN
299
         IF (spi_encours = '1' AND ssn = '0') THEN
300
         -- Si une transaction SPI est en cours et temps qu'elle est en cours (ssn = '0')
301
            IF (cpt_bitspi = "111") THEN
302
            -- Si on est au 8ème coup d'horloge
303
               shifter_spitx <= data_rdspi;   -- On initialise le déserailsiateur avec la donnée lue
304
            ELSE
305
               -- Pour tous les autres bits, on sérialise
306
               shifter_spitx <= shifter_spitx(6 DOWNTO 0) & '0';
307
            END IF;
308
         ELSE
309
         -- Si une transaction n'est pas en cours
310
            IF (ssn = '0') THEN
311
               shifter_spitx <= reg_stat_spi;   -- Il faut sortir le registre de stutut comme 1er donnée
312
            END IF;
313
         END IF;
314
      END IF;
315
   END PROCESS;
316
 
317
   --------------------------------------------
318
   -- Process Combinatoire de gestion du Read (MUX)
319
   --------------------------------------------
320
   mux_read: PROCESS(adrd_spi, iid, reg_tid_spi, reg_ctl_spi, reg_stat_spi, reg_rx1size_spi, reg_rx2size_spi,
321
                     reg_txfree_spi, reg_fiforx1_spi, reg_fiforx2_spi, rxprom_val, reg_promnbrd, rxprom_dat, reg_promctl)
322
   BEGIN
323
      CASE adrd_spi IS
324
         WHEN adreg_iid    => data_rdspi <= iid(63 DOWNTO 56);
325
         WHEN adreg_iid+1  => data_rdspi <= iid(55 DOWNTO 48);
326
         WHEN adreg_iid+2  => data_rdspi <= iid(47 DOWNTO 40);
327
         WHEN adreg_iid+3  => data_rdspi <= iid(39 DOWNTO 32);
328
         WHEN adreg_iid+4  => data_rdspi <= iid(31 DOWNTO 24);
329
         WHEN adreg_iid+5  => data_rdspi <= iid(23 DOWNTO 16);
330
         WHEN adreg_iid+6  => data_rdspi <= iid(15 DOWNTO 8);
331
         WHEN adreg_iid+7  => data_rdspi <= iid(7 DOWNTO 0);
332
         WHEN adreg_tid    => data_rdspi <= reg_tid_spi;
333
         WHEN adreg_ctl    => data_rdspi <= reg_ctl_spi;
334
         WHEN adreg_stat   => data_rdspi <= reg_stat_spi;
335
         WHEN adreg_rxsize1=> data_rdspi <= reg_rx1size_spi;
336
         WHEN adreg_rxsize2=> data_rdspi <= reg_rx2size_spi;
337
         WHEN adreg_txfree => data_rdspi <= reg_txfree_spi;
338
         WHEN adreg_fiforx1=> data_rdspi <= reg_fiforx1_spi;
339
         WHEN adreg_fiforx2=> data_rdspi <= reg_fiforx2_spi;
340
         -- WHEN adreg_fifotx => data_rdspi <= dummy  -- Ce registre est Write Only
341
         WHEN adreg_version=> data_rdspi <= version;
342
         WHEN adreg_promctl=> data_rdspi <= rxprom_val & reg_promctl(6 DOWNTO 4) & prom_busy & reg_promctl(2 DOWNTO 0);
343
         WHEN adreg_promnbrd=>data_rdspi <= reg_promnbrd;
344
         -- WHEN adreg_promtx => data_rdspi <= dummy  -- Ce registre est Write Only
345
         WHEN adreg_promrx=> data_rdspi <= rxprom_dat;
346
         WHEN OTHERS       => data_rdspi <= reg_stat_spi;
347
      END CASE;
348
   END PROCESS;
349
 
350
   --------------------------------------------
351
   -- Process de gestion des écritures dans les registres
352
   --------------------------------------------
353
   write_reg : PROCESS(sclk, rst_n)
354
   BEGIN
355
      IF (rst_n = '0') THEN
356
         reg_tid_spi <= x"8F";
357
         reg_ctl_spi <= x"87";
358
      ELSIF (sclk'EVENT and sclk = '1') THEN
359
         IF (wr_reg = '1') THEN
360
            CASE adwr_spi IS
361
               WHEN adreg_tid  => reg_tid_spi <= shifter_spirx;
362
               WHEN adreg_ctl  => reg_ctl_spi <= shifter_spirx;
363
               WHEN OTHERS =>
364
            END CASE;
365
         END IF;
366
      END IF;
367
   END PROCESS;
368
   rst_fifotx <= reg_ctl_spi(2);
369
 
370
   --------------------------------------------
371
   -- Process de gestion du registre de status
372
   --------------------------------------------
373
   gest_stat : PROCESS(sclk, rst_n)
374
   BEGIN
375
      IF (rst_n = '0') THEN
376
         reg_stat_spi(7 DOWNTO 2) <= (OTHERS => '0');
377
         frm1_r1 <= '0';
378
         frm1_r2 <= '0';
379
         frm2_r1 <= '0';
380
         frm2_r2 <= '0';
381
      ELSIF (sclk'EVENT and sclk = '1') THEN
382
         frm1_r1 <= frm1;              -- Passe les signaux Frame dispo de clk_sys à sclk
383
         frm1_r2 <= frm1_r1;
384
         frm2_r1 <= frm2;
385
         frm2_r2 <= frm2_r1;
386
         IF (bfo1_spi = '1') THEN
387
            reg_stat_spi(2) <= '1';
388
         ELSIF (wr_reg = '1' AND adwr_spi = adreg_stat) THEN
389
            reg_stat_spi(2) <= reg_stat_spi(2) AND NOT(shifter_spirx(2));
390
         END IF;
391
         IF (bfo2_spi = '1') THEN
392
            reg_stat_spi(3) <= '1';
393
         ELSIF (wr_reg = '1' AND adwr_spi = adreg_stat) THEN
394
            reg_stat_spi(3) <= reg_stat_spi(3) AND NOT(shifter_spirx(3));
395
         END IF;
396
         IF (ovf1_spi = '1') THEN
397
            reg_stat_spi(4) <= '1';
398
         ELSIF (wr_reg = '1' AND adwr_spi = adreg_stat) THEN
399
            reg_stat_spi(4) <= reg_stat_spi(4) AND NOT(shifter_spirx(4));
400
         END IF;
401
         IF (ovf2_spi = '1') THEN
402
            reg_stat_spi(5) <= '1';
403
         ELSIF (wr_reg = '1' AND adwr_spi = adreg_stat) THEN
404
            reg_stat_spi(5) <= reg_stat_spi(5) AND NOT(shifter_spirx(5));
405
         END IF;
406
      END IF;
407
   END PROCESS;
408
   reg_stat_spi(1 DOWNTO 0) <= frm2_r2 & frm1_r2;
409
 
410
   --------------------------------------------
411
   -- Process de gestion des changement d'horloge
412
   --------------------------------------------
413
   bfo1 <= l7_newframe1 AND NOT(l7_l2ok1);   -- Définition d'une mauvaise trame sur port 1
414
   bfo2 <= l7_newframe2 AND NOT(l7_l2ok2);   -- Définition d'une mauvaise trame sur port 2
415
 
416
   clkovf1 : jk_chgclk PORT MAP(rst_n, clk_sys, sclk, l7_overflow1, ovf1_spi);
417
   clkovf2 : jk_chgclk PORT MAP(rst_n, clk_sys, sclk, l7_overflow2, ovf2_spi);
418
   clkobfo1: jk_chgclk PORT MAP(rst_n, clk_sys, sclk, bfo1, bfo1_spi);
419
   clkobfo2: jk_chgclk PORT MAP(rst_n, clk_sys, sclk, bfo2, bfo2_spi);
420
 
421
   to_clk_sys : PROCESS(clk_sys, rst_n)
422
   BEGIN
423
      IF (rst_n = '0') THEN
424
         cpy1_reg <= '1';
425
         cpy2_reg <= '1';
426
         repli_reg <= '1';
427
         cpy1 <= '1';
428
         cpy2 <= '1';
429
         repli <= '1';
430
      ELSIF (clk_sys'event AND clk_sys ='1') THEN
431
         cpy1_reg <= reg_ctl_spi(0);
432
         cpy2_reg <= reg_ctl_spi(1);
433
         tid_reg  <= reg_tid_spi;
434
         repli_reg<= reg_ctl_spi(7);
435
         cpy1 <= cpy1_reg;
436
         cpy2 <= cpy2_reg;
437
         tid  <= tid_reg;
438
         repli<= repli_reg;
439
      END IF;
440
   END PROCESS;
441
 
442
   --------------------------------------------
443
   -- Process de gestion de la FIFO Tx
444
   --------------------------------------------
445
   difftx_free <= "10000000001" - fifotx_datacnt; -- Calcul du nombre d'octets dispo dans la FIFO 257-cnt
446
   reg_txfree_spi <= x"FF" WHEN difftx_free(10 DOWNTO 8) /= "000" ELSE  -- Si txfree >=256 on tronque le résultat
447
                     difftx_free(7 DOWNTO 0);              -- Sinon on donne le résultat
448
 
449
   -- Condition d'écriture d'un octet dans la FIFO TX
450
   wr_datatx_spi <= '1' WHEN (wr_reg = '1' AND adwr_spi = adreg_fifotx) ELSE '0';
451
 
452
   clr_fifo_tx <= '0';              -- Spare pour l'instant on ne fait pas de clear de la fifo tx aval
453
 
454
   -- On lit un octet dans la FIFO TX au début lorsuq'on détecte qu'elle n'est plus vide
455
   -- ou bien en cours de transfert lorsque le module suivant est dispo
456
   rd_datatx_sys <= '1' WHEN ((fsm_tx = idle_st AND fifotx_empty = '0') OR
457
                              (fsm_tx = senddat_st AND txdat_free = '1' AND fifotx_empty = '0')) ELSE
458
                    '0';
459
 
460
   val_txdat <= NOT(fifotx_empty);
461
   tx_dat <= datatx_rd_sys;
462
   tx_eof <= txdat_free AND NOT(fifotx_empty) WHEN (fsm_tx = senddat_st AND cpt_tx = "00000001") ELSE '0';
463
 
464
   gest_fsm_tx : PROCESS(clk_sys, rst_n)
465
   BEGIN
466
      IF (rst_n = '0') THEN
467
         fsm_tx <= idle_st;
468
         tx_sof    <= '0';
469
         cpt_tx    <= (OTHERS => '0');
470
 
471
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
472
         CASE fsm_tx IS
473
            WHEN idle_st  =>
474
            -- Etat d'attente de données dans la FIFO TX
475
               IF (fifotx_empty = '0') THEN
476
               -- Si il y'a des données dans la FIFO TX
477
                  cpt_tx <= datatx_rd_sys;   -- On initialise le compteur avec la longueur de la trame
478
                  fsm_tx <= senddat_st;      -- On va transmettre des données
479
                  tx_sof <= '1';             -- On active le sof pour signaler un début de trame
480
               END IF;
481
 
482
            WHEN senddat_st =>
483
            -- Etat de transfert d'une donnée
484
               IF (txdat_free = '1' AND fifotx_empty = '0') THEN
485
               -- Les données restent sur le bus tx_dat tant que le module suivant n'est pas libre
486
               -- i.e. tant qu'il a pas platché la donnée actuelle
487
                  cpt_tx <= cpt_tx - 1;         -- Dans ce cas on enregistre une donnee de moins
488
                  tx_sof <= '0';                -- On peut annuler le sof car on est sur que le module suivant l'a pris en comtpe
489
                  IF (cpt_tx = "00000001") THEN -- Lors du dernier octet à transmettre
490
                     fsm_tx <= idle_st;         -- On a fini
491
                  END IF;
492
               END IF;
493
 
494
            WHEN OTHERS =>
495
               fsm_tx <= idle_st;
496
         END CASE;
497
      END IF;
498
   END PROCESS;
499
 
500
   inst_fiftx : fifotx_spi
501
   PORT MAP (
502
      rst      => rst_fifotx,
503
      wr_clk   => sclk,
504
      rd_clk   => clk_sys,
505
      din      => shifter_spirx,
506
      wr_en    => wr_datatx_spi,
507
      rd_en    => rd_datatx_sys,
508
      dout     => datatx_rd_sys,
509
      full     => OPEN,
510
      empty    => fifotx_empty,
511
      wr_data_count => fifotx_datacnt
512
   );
513
 
514
   --------------------------------------------
515
   -- Process de gestion des FIFO Rx
516
   --------------------------------------------
517
   rd_datarx_spi1 <= '1' WHEN (rd_reg = '1' AND adrd_spi = adreg_fiforx1) ELSE '0';
518
   rd_datarx_spi2 <= '1' WHEN (rd_reg = '1' AND adrd_spi = adreg_fiforx2) ELSE '0';
519
 
520
   l7_rd1buf <= (l7_rd AND NOT(sel_voie) AND comdispo AND NOT(soc)) WHEN (fsm_rx = recdat_st) ELSE
521
                (l7_rd AND NOT(sel_voie));
522
   l7_rd1 <= l7_rd1buf;
523
   l7_rd2buf <= (l7_rd AND sel_voie AND comdispo AND NOT(soc)) WHEN (fsm_rx = recdat_st) ELSE
524
                (l7_rd AND sel_voie);
525
   l7_rd2 <= l7_rd2buf;
526
 
527
   comdispo <= l7_comdispo1 WHEN (sel_voie = '0') ELSE l7_comdispo2;
528
   soc <= l7_soc1 WHEN (sel_voie = '0') ELSE l7_soc2;
529
 
530
   gest_fsm_rx : PROCESS(clk_sys, rst_n)
531
   BEGIN
532
      IF (rst_n = '0') THEN
533
         l7_rd <= '0';
534
         sel_voie <= '0';
535
         fsm_rx <= idle_st;
536
         frm2 <= '0';
537
         frm1 <= '0';
538
         firx_e1_r1 <= '0';
539
         firx_e1_r2 <= '0';
540
         firx_e2_r1 <= '0';
541
         firx_e2_r2 <= '0';
542
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
543
         firx_e1_r1 <= fiforx_empty1;     -- Passe les FIFO empty sur la clok_sys
544
         firx_e1_r2 <= firx_e1_r1;
545
         firx_e2_r1 <= fiforx_empty2;
546
         firx_e2_r2 <= firx_e2_r1;
547
         CASE fsm_rx IS
548
            WHEN idle_st  =>
549
               frm1 <= NOT(firx_e1_r2);
550
               frm2 <= NOT(firx_e2_r2);
551
               IF ((l7_comdispo1 = '1' AND firx_e1_r2 = '1') AND
552
                   (l7_comdispo2 = '0' OR  firx_e2_r2 = '0' OR sel_voie = '1')) THEN
553
                  sel_voie <= '0';
554
                  l7_rd <= '1';
555
                  fsm_rx <= pump_st;
556
               ELSIF (l7_comdispo2 = '1' AND firx_e2_r2 = '1') THEN
557
                  sel_voie <= '1';
558
                  l7_rd <= '1';
559
                  fsm_rx <= pump_st;
560
               ELSE
561
                  l7_rd <= '0';
562
               END IF;
563
 
564
            WHEN pump_st =>
565
               fsm_rx <= recdat_st;
566
 
567
            WHEN recdat_st =>
568
               IF (soc = '1' OR comdispo = '0') THEN
569
                  l7_rd <= '0';
570
                  fsm_rx <= waitnotempty_st;
571
               END IF;
572
 
573
            WHEN waitnotempty_st =>
574
            -- Etat d'attente que la FIFO soit indiquée comme non vide
575
            -- Necessaire du fait de la latence entre sclk et clk_sys
576
               IF ((firx_e1_r2 = '0' AND sel_voie = '0') OR
577
                  (firx_e2_r2 = '0' AND sel_voie = '1')) THEN
578
                  frm1 <= NOT(sel_voie);
579
                  frm2 <= sel_voie;
580
                  fsm_rx <= idle_st;
581
               END IF;
582
 
583
            WHEN OTHERS =>
584
               fsm_rx <= idle_st;
585
         END CASE;
586
      END IF;
587
   END PROCESS;
588
 
589
   inst_fifrx1 : fiforx_spi
590
   PORT MAP (
591
      rst      => NOT(rst_n),
592
      wr_clk   => clk_sys,
593
      rd_clk   => sclk,
594
      din      => l7_rx1,
595
      wr_en    => l7_rd1buf,
596
      rd_en    => rd_datarx_spi1,
597
      dout     => reg_fiforx1_spi,
598
      full     => OPEN,
599
      empty    => fiforx_empty1,
600
      rd_data_count => fiforx_datacnt1
601
   );
602
   -- Taille de la trame dans la FIFO : 255 si >= 256, sinon Nb octets dans la FIFO
603
   reg_rx1size_spi <= x"FF" WHEN fiforx_datacnt1(10 DOWNTO 8) /= "000" ELSE
604
                      fiforx_datacnt1(7 DOWNTO 0);
605
 
606
   inst_fifrx2 : fiforx_spi
607
   PORT MAP (
608
      rst      => NOT(rst_n),
609
      wr_clk   => clk_sys,
610
      rd_clk   => sclk,
611
      din      => l7_rx2,
612
      wr_en    => l7_rd2buf,
613
      rd_en    => rd_datarx_spi2,
614
      dout     => reg_fiforx2_spi,
615
      full     => OPEN,
616
      empty    => fiforx_empty2,
617
      rd_data_count => fiforx_datacnt2
618
   );
619
   -- Taille de la trame dans la FIFO : 255 si >= 256, sinon Nb octets dans la FIFO
620
   reg_rx2size_spi <= x"FF" WHEN fiforx_datacnt2(10 DOWNTO 8) /= "000" ELSE
621
                      fiforx_datacnt2(7 DOWNTO 0);
622
 
623
   -------------------------------------------------
624
   -- Signaux de gestion de l'I/F SPI vers la PROM
625
   -------------------------------------------------
626
      --------------------------------------------
627
   -- Process de gestion des écritures dans les registres
628
   --------------------------------------------
629
   write_regpromctl : PROCESS(sclk, rst_n)
630
   BEGIN
631
      IF (rst_n = '0') THEN
632
         reg_promctl <= x"00";
633
         reg_promnbrd <= x"00";
634
      ELSIF (sclk'EVENT and sclk = '1') THEN
635
         IF (wr_reg = '1' AND adwr_spi = adreg_promctl) THEN
636
            reg_promctl <= shifter_spirx;
637
         ELSE
638
            reg_promctl(3) <= '0';
639
         END IF;
640
         IF (wr_reg = '1' AND adwr_spi = adreg_promnbrd) THEN
641
            reg_promnbrd <= shifter_spirx;
642
         END IF;
643
      END IF;
644
   END PROCESS;
645
 
646
   txprom_dat     <= shifter_spirx;
647
   txprom_val     <= wr_reg WHEN (adwr_spi =  adreg_promtx) ELSE '0';
648
   rxprom_next    <= rd_reg WHEN (adrd_spi =  adreg_promrx) ELSE '0';
649
   prom_type_com  <= reg_promctl(0);
650
   prom_exec_com  <= reg_promctl(3);
651
   prom_rstn      <= reg_promctl(4);
652
   prom_nbread    <= reg_promnbrd;
653
 
654
END rtl;
655
 

powered by: WebSVN 2.1.0

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