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

Subversion Repositories saturn

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 DavidRAMBA
--============================================================================= 
2
--  TITRE : serial_rx
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 3 échantillons consécutifs de part et d'autre
9
--        du milieu du bit à échantilloner. Si la somme est >=2 => bit à 1
10
--        sinon bit à 0 
11
--  FICHIER :        serial_rx.vhd 
12
--=============================================================================
13
--  CREATION 
14
--  DATE        AUTEUR  PROJET  REVISION 
15
--  29/02/2012  DRA     CONCERTO        V1.0 
16
--  14/01/2013 DRA   Modificiation pour échantillonner 3 fois et rendre plus robuste
17
--                   en environnement bruité
18
--=============================================================================
19
--  HISTORIQUE  DES  MODIFICATIONS :
20
--  DATE        AUTEUR  PROJET  REVISION 
21
--=============================================================================
22
 
23
LIBRARY IEEE;
24
USE IEEE.STD_LOGIC_1164.ALL;
25
USE IEEE.STD_LOGIC_ARITH.ALL;
26
USE IEEE.STD_LOGIC_UNSIGNED.ALL;
27
 
28
 
29
 
30
-- Uncomment the following library declaration if instantiating
31
-- any Xilinx primitives in this code.
32
--library UNISIM;
33
--use UNISIM.VComponents.all;
34
 
35
ENTITY serial_rx IS
36
   GENERIC (
37
      nbbit_div : INTEGER := 10); -- Nombre de bits pour coder le diviseur d'horloge
38
   PORT (
39
      -- Ports système
40
      clk_sys  : IN  STD_LOGIC;  -- Clock système
41
      rst_n    : IN  STD_LOGIC;  -- Reset génrél système
42
      baud_lock: IN  STD_LOGIC;  -- Indique que le baudrate est calé
43
 
44
      -- Interface série
45
      tc_divclk: IN  STD_LOGIC_VECTOR (nbbit_div-1 DOWNTO 0); -- Diviseur de l'horloge système pour le baudrate
46
      tx       : OUT  STD_LOGIC;    -- Re transmission série
47
      rx       : IN STD_LOGIC;      -- Port de réception série
48
 
49
      -- Interface parallèle
50
      busy     : OUT STD_LOGIC;     -- Indique qu'une réception est en cours
51
      val      : OUT STD_LOGIC;     -- rx_dat contient la dernière donnée reçu
52
      rx_dat   : OUT  STD_LOGIC_VECTOR (7 DOWNTO 0)  -- Donnée reçue (synchrone de val)
53
      );
54
END serial_rx;
55
 
56
ARCHITECTURE rtl of serial_rx is
57
   SIGNAL rx_r             : STD_LOGIC_VECTOR(1 DOWNTO 0);   -- Délai pour détecter le front descendant
58
   SIGNAL sumrx            : STD_LOGIC_VECTOR(1 DOWNTO 0);   -- Pour additionner 3 échantillons consécutifs
59
   SIGNAL front_des_rx_c   : STD_LOGIC;   -- Un pulse de clk_sys sur front descendant de rx
60
 
61
   SIGNAL cptbit_rx        : STD_LOGIC_VECTOR(3 downto 0);  -- Compteur de bits dans un caractère en réception
62
   SIGNAL divclk_rx        : STD_LOGIC_VECTOR(nbbit_div-1 downto 0);  -- Diviseur d'horloge pour mesurer un bit en réception
63
   SIGNAL rx_encours       : STD_LOGIC;                     -- Indique qu'un caractère est en cours de réception
64
   SIGNAL shifter_rx       : STD_LOGIC_VECTOR(7 downto 0);  -- Registre à décalage de réception
65
 
66
BEGIN
67
   --------------------------------------------
68
   -- Détection du front descendant sur rx
69
   --------------------------------------------
70
   -- rx_r(1) & rx_r(0) & rx représente un registre à décalage du flux rx
71
   front_rx : PROCESS(clk_sys, rst_n)
72
   BEGIN
73
      IF (rst_n = '0') THEN
74
         rx_r <= (OTHERS => '1');
75
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
76
         rx_r <= rx_r(0) & rx;
77
      END IF;
78
   END PROCESS;
79
   front_des_rx_c <= NOT(rx_r(0)) AND rx_r(1);  -- Détection du front descendant
80
   sumrx <= CONV_STD_LOGIC_VECTOR(rx_r(0), 2) + CONV_STD_LOGIC_VECTOR(rx_r(1), 2) +
81
            CONV_STD_LOGIC_VECTOR(rx, 2); -- On compte les 3 échantillons consécutif
82
 
83
   --------------------------------------------
84
   -- Déserialisateur des données reçues sur rx 
85
   -- et remise en forme (retaillage des durée de bit) pour la recopie
86
   --------------------------------------------
87
   deser_shaper : PROCESS(clk_sys, rst_n)
88
   BEGIN
89
      IF (rst_n = '0') THEN
90
         cptbit_rx <= (OTHERS => '0');
91
         divclk_rx <= (OTHERS => '0');
92
         rx_encours <= '0';
93
         tx <= '1';
94
         val <= '0';
95
      ELSIF (clk_sys'EVENT and clk_sys = '1') THEN
96
         IF (rx_encours = '0') THEN
97
         -- Si on est pas déjà en train de sérialiser un car
98
            val <= '0';    -- On s'assure que l'écriture dans la FIFO de réception ne dure qu'un pulse
99
            IF (front_des_rx_c = '1') THEN
100
            -- Sur détection du front descendant (le Start bit)
101
               cptbit_rx <= (OTHERS => '0');
102
               -- on initialise le diviseur d'horloge à la motié de tc pour échantilloner au milieu du bit
103
               -- on rajoute 2 pour compenser le retard de détection du front descendant
104
               divclk_rx <= ('0' & tc_divclk(tc_divclk'LEFT downto 1))+2;
105
               rx_encours <= '1';
106
            END IF;
107
            tx <= '1';
108
         ELSE
109
         -- Si on est en train de recevoir un car
110
            IF (divclk_rx = tc_divclk) THEN
111
            -- Si on atteind le terminal count (TC) du diviseur d'horloge
112
               divclk_rx <= (OTHERS => '0');
113
               cptbit_rx <= cptbit_rx + 1;                  -- Un bit de plus reçu
114
               -- Si la somme des 3 echantillons est >= 2 (i.e. le MSB est à 1) -> le bit est à 1
115
               shifter_rx <= sumrx(1) & shifter_rx(7 downto 1);   -- On garde le bit LSB first
116
               IF (baud_lock = '0') THEN
117
               -- Tant que l'algo d'Autobaudrate n'a pas convergé
118
                  tx <= '1';                                -- On ne recopie rien
119
               ELSE
120
                  tx <= sumrx(1);                           -- On échantillonne rx pour la recopie
121
               END IF;
122
               IF (cptbit_rx = "1000") then                 -- On est en train de recevoir le 9ème bit (Start + 8 data)
123
                  val <= '1';                               -- On valide la donnée
124
               ELSIF (cptbit_rx = "1001") then              -- Au 10 ème bit reçu
125
               -- Il faut attendre le 10ème bit pour garantir qu'en recopie, le 8ème bit utile (i.e. le 9ème) dure le bon temps
126
                  rx_encours <= '0';                        -- On arrête la réception
127
                  val <= '0';                               -- On s'assure que le signal dure 1 pulse
128
               END IF;
129
            ELSE
130
               divclk_rx <= divclk_rx + 1;         -- En cours de réception on mesure la durée d'un bit
131
               val <= '0';                         -- On s'assure que le signal dure 1 pulse
132
            END IF;
133
         END IF;
134
      END IF;
135
   END PROCESS;
136
   rx_dat <= shifter_rx;         -- La data reçue correspond au registre à décalage lorsque val = '1'
137
   busy <= rx_encours;
138
END rtl;
139
 

powered by: WebSVN 2.1.0

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