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

Subversion Repositories saturn

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 DavidRAMBA
--============================================================================= 
2
--  TITRE : serial_rx2
3
--  DESCRIPTION : 
4
--        Déserialisateur des données reçues sur rx et remet en forme
5
--        le signal (retaillage des durée de bit) pour la recopie 
6
--        La durée d'un bit est égale à tc_divclk+1 pulse de clk_sys    
7
--        
8
--        On additionne les tc_divclk+1 échantillons de chaque bit
9
--        Si la somme est > tc_divclk/2, c'est un '1', sinon, c'est un '0'
10
--  FICHIER :        serial_rx2.vhd 
11
--=============================================================================
12
--  CREATION 
13
--  DATE              AUTEUR    PROJET  REVISION 
14
--  10/04/2014  DRA        SATURN       V1.0 
15
--=============================================================================
16
--  HISTORIQUE  DES  MODIFICATIONS :
17
--  DATE              AUTEUR    PROJET  REVISION 
18
--=============================================================================
19
 
20
LIBRARY IEEE;
21
USE IEEE.STD_LOGIC_1164.ALL;
22
USE IEEE.STD_LOGIC_ARITH.ALL;
23
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
24
 
25
ENTITY serial_rx2 IS
26
   GENERIC (
27
      nbbit_div : INTEGER := 10); -- Nombre de bits pour coder le diviseur d'horloge
28
   PORT (
29
      -- Ports système
30
      clk_sys  : IN  STD_LOGIC;  -- Clock système
31
      rst_n    : IN  STD_LOGIC;  -- Reset général système
32
      baud_lock: IN  STD_LOGIC;  -- Indique que le baudrate est calé
33
 
34
      -- Interface série
35
      tc_divclk: IN  STD_LOGIC_VECTOR (nbbit_div-1 DOWNTO 0); -- Diviseur de l'horloge système pour le baudrate
36
      tx       : OUT  STD_LOGIC;    -- Re transmission série
37
      rx       : IN STD_LOGIC;      -- Port de réception série
38
 
39
      -- Interface parallèle
40
      busy     : OUT STD_LOGIC;     -- Indique qu'une réception est en cours
41
      val      : OUT STD_LOGIC;     -- Indique que rx_dat contient la dernière donnée reçu
42
      rx_dat   : OUT  STD_LOGIC_VECTOR (7 DOWNTO 0)  -- Donnée reçue (synchrone de val)
43
      );
44
END serial_rx2;
45
 
46
ARCHITECTURE rtl of serial_rx2 is
47
   SIGNAL rx_r             : STD_LOGIC;   -- Délai pour détecter le front descendant
48
   SIGNAL sumrx            : STD_LOGIC_VECTOR(nbbit_div-1 DOWNTO 0);   -- Pour additionner N échantillons consécutifs
49
 
50
   SIGNAL cptbit_rx        : STD_LOGIC_VECTOR(3 downto 0);  -- Compteur de bits dans un caractère en réception
51
   SIGNAL divclk_rx        : STD_LOGIC_VECTOR(nbbit_div-1 downto 0);  -- Diviseur d'horloge pour mesurer un bit en réception
52
   SIGNAL rx_encours       : STD_LOGIC;                     -- Indique qu'un caractère est en cours de réception
53
   SIGNAL shifter_rx       : STD_LOGIC_VECTOR(7 downto 0);  -- Registre à décalage de désrialisation
54
   SIGNAL consol_bit       : STD_LOGIC;                     -- Bit consolidé après sur-échantillonnage
55
 
56
BEGIN
57
   --------------------------------------------
58
   -- Détection du front descendant sur rx
59
   --------------------------------------------
60
   front_rx : PROCESS(clk_sys, rst_n)
61
   BEGIN
62
      IF (rst_n = '0') THEN
63
         rx_r <= '1';
64
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
65
         rx_r <= rx;
66
      END IF;
67
   END PROCESS;
68
 
69
   -- Si on a compté des '1' plus de la moitié du temps, on considère un '1' sinon un '0'
70
   consol_bit <= '1' WHEN (('0' & sumrx) + rx) > ("00" & tc_divclk(nbbit_div-1 DOWNTO 1)) ELSE '0';
71
 
72
   --------------------------------------------
73
   -- Déserialisateur des données reçues sur rx 
74
   -- et remise en forme (retaillage des durée de bit) pour la recopie
75
   --------------------------------------------
76
   deser_shaper : PROCESS(clk_sys, rst_n)
77
   BEGIN
78
      IF (rst_n = '0') THEN
79
         cptbit_rx <= (OTHERS => '0');
80
         divclk_rx <= (OTHERS => '0');
81
         rx_encours <= '0';
82
         tx <= '1';
83
         val <= '0';
84
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
85
         IF (rx_encours = '0') THEN
86
         -- Si on est pas déjà en train de sérialiser un car
87
            val <= '0';    -- On s'assure que l'écriture dans la FIFO de réception ne dure qu'un pulse
88
            IF (rx = '0' and rx_r = '1') THEN
89
            -- Sur détection du front descendant (le Start bit)
90
               cptbit_rx <= (OTHERS => '0');    -- On initialise le compteur de bits
91
               -- on initialise le diviseur d'horloge à la fin du tc 
92
               -- on rajoute 1 pour compenser le retard de détection du front descendant
93
               -- Donc on initialise à 0
94
               divclk_rx <= (others => '0');
95
               sumrx <= (others => '0');        -- On init la somme des sur-echantillonnages
96
               rx_encours <= '1';               -- On indique qu'on est en réception
97
            END IF;
98
            tx <= '1';                          -- Idle de la ligne Tx
99
         ELSE
100
         -- Si on est en train de recevoir un car
101
            IF (divclk_rx = tc_divclk) THEN
102
            -- Si on atteind le terminal count (TC) du diviseur d'horloge
103
            -- On va traiter un bit de plus
104
               divclk_rx <= (OTHERS => '0');                -- re init du diviseur d'horloge
105
               sumrx <= (others => '0');                    -- re init de la somme
106
               cptbit_rx <= cptbit_rx + 1;                  -- Un bit de plus reçu
107
               shifter_rx <= consol_bit & shifter_rx(7 downto 1);   -- On considère un nouveau bit LSB first
108
               IF (baud_lock = '0') THEN
109
               -- Tant que l'algo d'Autobaudrate n'a pas convergé
110
                  tx <= '1';                                -- On ne recopie rien
111
               ELSE
112
                  tx <= consol_bit;                         -- On recopie le bit consolidé
113
               END IF;
114
               IF (cptbit_rx = "1000") then                 -- On est en train de recevoir le 9ème bit (Start + 8 data)
115
                  val <= '1';                               -- On valide la donnée
116
                  rx_encours <= '0';                        -- On arrête la réception et on va attendre le prochain start
117
               ELSIF (cptbit_rx = "0000") AND (consol_bit = '1') THEN
118
               -- Si on est au premier bit et que c'est pas un '0' (bit de START)
119
                  rx_encours <= '0';                        -- On arrête la réception
120
               END IF;
121
            ELSE
122
               divclk_rx <= divclk_rx + 1;         -- En cours de réception on mesure la durée d'un bit
123
               sumrx <= sumrx + rx;                -- On somme les sur-échantillonnages
124
               val <= '0';                         -- On s'assure que le signal dure 1 pulse
125
            END IF;
126
         END IF;
127
      END IF;
128
   END PROCESS;
129
   rx_dat <= shifter_rx;         -- La data reçue correspond au registre à décalage lorsque val = '1'
130
   busy <= rx_encours;
131
END rtl;
132
 

powered by: WebSVN 2.1.0

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