title: UART communication between computer and BASYS 3 FPGA
body: <p>I have a project in which I need to send data from a Windows 10 computer to a BASYS 3 board(ARTIX7 FPGA). I use UART to do so. The data to send is entered in a PuTTY serial console.</p>
  
  <p>For testing purposes, I decided to display the received data using 8 LEDs on the board.</p>
  
  <p>I am using Vivado 2016.4.</p>
  
  <p>The problem I have is that the data I get on the LEDs is totally different from what it should be. I suppose it's a problem of synchronization between PuTTY's baud rate and my VHDL module.</p>
  
  <p>Please find hereafter the .vhd file and the .xdc file of this project :</p>
  
  <p>The .vhd is based on a finite state machine (FSM), and there are two signals allowing the synchronization :</p>
  
  <p>tick_UART : it ticks every 10417 clock period. Since the clock period is 10 ns, tick_UART rises 9600 times per second (I intend a use at 9600 bauds).</p>
  
  <p>double_tick_UART : twice the frequency of tick_UART, used to sample the bits in the middle.</p>
  
  <pre><code>    library IEEE;
  use IEEE.STD_LOGIC_1164.ALL;
  use IEEE.NUMERIC_STD.ALL;
  
  
  entity UART_RX is
      Port ( RxD : in  STD_LOGIC;
             clk : in  STD_LOGIC;
                RAZ : in  STD_LOGIC;
             data_out : out  STD_LOGIC_VECTOR (7 downto 0));
  end UART_RX;
  
  architecture Behavioral of UART_RX is
  
      signal tick_UART : STD_LOGIC;                                                       -- Signal "top" passage d'un état à l'autre selon vitesse connexion série
      signal double_tick_UART : STD_LOGIC;                                                -- Signal précédent, fréquence * 2
      signal compteur_tick_UART : integer range 0 to 10420;                           -- Compteur pour tick_UART 
      signal double_compteur_tick_UART : integer range 0 to 5210;                 -- Compteur pour demi-périodes 
      type state_type is (idle, start, demiStart, b0, b1, b2, b3, b4, b5, b6, b7, stop);  -- Etats de la FSM
      signal state :state_type := idle;                                                   -- Etat par défaut
      signal RAZ_tick_UART : STD_LOGIC;                                                   -- RAZ du signal tick_UART;
  
  begin
  
  process(clk, RAZ, state, RAZ_tick_UART) -- Compteur classique (tick_UART)
  begin
      if (raz='1') or (state = idle) or (RAZ_tick_UART = '1') then
          compteur_tick_UART &lt;= 0;
          tick_UART &lt;= '0';
      elsif clk = '1' and clk'event then
              if compteur_tick_UART = 10417 then
                  tick_UART &lt;= '1';
                  compteur_tick_UART &lt;= 0;
              else
                  compteur_tick_UART &lt;= compteur_tick_UART + 1;
                  tick_UART &lt;= '0';
              end if;
      end if;
  end process;
  
  process(clk, RAZ, state) -- Compteur demi-périodes (double_tick_UART car fréquence double)
  begin
      if (raz='1') or (state = idle) then
          double_compteur_tick_UART &lt;= 0;
          double_tick_UART &lt;= '0';
      elsif clk = '1' and clk'event then
              if double_compteur_tick_UART = 5209 then
                  double_tick_UART &lt;= '1';
                  double_compteur_tick_UART &lt;= 0;
              else
                  double_compteur_tick_UART &lt;= double_compteur_tick_UART + 1;
                  double_tick_UART &lt;= '0';
              end if;
      end if;
  end process;
  
  fsm:process(clk, RAZ)   -- Machine à état
  begin
      if (RAZ = '1') then
          state &lt;= idle;
          data_out &lt;= "00000000";
          RAZ_tick_UART &lt;= '1';
      elsif clk = '1' and clk'event then
          case state is
              when idle =&gt; if RxD = '0' then  -- Si front descendant de RxD et en idle
                                  state &lt;= start;
                              RAZ_tick_UART &lt;= '1';
                              end if;
              when start =&gt;   if double_tick_UART = '1' then
                                      state &lt;= demiStart;
                                      RAZ_tick_UART &lt;= '0';
                                  end if;
                              data_out &lt;= "00000000";
              when demiStart =&gt; if tick_UART = '1' then
                                          state &lt;= b0;
                                          RAZ_tick_UART &lt;= '0';
                                      end if;
                              data_out(0) &lt;= RxD; -- Acquisition bit 0
              when b0 =&gt;  if tick_UART = '1' then
                                  state &lt;= b1;
                              end if;
                              data_out(1) &lt;= RxD; -- Acquisition bit 1
              when b1 =&gt;  if tick_UART = '1' then
                                  state &lt;= b2;
                              end if;
                              data_out(2) &lt;= RxD; -- Acquisition bit 2
              when b2 =&gt;  if tick_UART = '1' then
                                  state &lt;= b3;
                              end if;
                              data_out(3) &lt;= RxD; -- Acquisition bit 3
              when b3 =&gt;  if tick_UART = '1' then
                                  state &lt;= b4;
                              end if;
                              data_out(4) &lt;= RxD; -- Acquisition bit 4
              when b4 =&gt;  if tick_UART = '1' then
                                  state &lt;= b5;
                              end if;
                              data_out(5) &lt;= RxD; -- Acquisition bit 5
              when b5 =&gt;  if tick_UART = '1' then
                                  state &lt;= b6;
                              end if;
                              data_out(6) &lt;= RxD; -- Acquisition bit 6
              when b6 =&gt;  if tick_UART = '1' then
                                  state &lt;= b7;    
                              end if;
                              data_out(7) &lt;= RxD; -- Acquisition bit 7
              when b7 =&gt;  if tick_UART = '1' then
                                  state &lt;= stop;
                              end if;
              when stop =&gt; if tick_UART = '1' then
                                  state &lt;= idle;      -- Renvoi en idle
                              end if;
          end case;
      end if;
  end process;
  
  
  end Behavioral;
  </code></pre>
  
  <p>XDC file :</p>
  
  <pre><code>## Clock signal
  set_property PACKAGE_PIN W5 [get_ports clk]                         
      set_property IOSTANDARD LVCMOS33 [get_ports clk]
      create_clock -add -name sys_clk_pin -period 10.00 -waveform {0 5} [get_ports clk]
  
  ## LEDs
  set_property PACKAGE_PIN U16 [get_ports data_out[0]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[0]]
  set_property PACKAGE_PIN E19 [get_ports data_out[1]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[1]]
  set_property PACKAGE_PIN U19 [get_ports data_out[2]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[2]]
  set_property PACKAGE_PIN V19 [get_ports data_out[3]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[3]]
  set_property PACKAGE_PIN W18 [get_ports data_out[4]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[4]]
  set_property PACKAGE_PIN U15 [get_ports data_out[5]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[5]]
  set_property PACKAGE_PIN U14 [get_ports data_out[6]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[6]]
  set_property PACKAGE_PIN V14 [get_ports data_out[7]]                    
      set_property IOSTANDARD LVCMOS33 [get_ports data_out[7]]
  
  ##Buttons
  set_property PACKAGE_PIN T18 [get_ports RAZ]                        
      set_property IOSTANDARD LVCMOS33 [get_ports RAZ]
  
  ##USB-RS232 Interface
  set_property PACKAGE_PIN B18 [get_ports RxD]                        
      set_property IOSTANDARD LVCMOS33 [get_ports RxD]
  </code></pre>
  
  <p>Do you spot any mistake ?</p>
  
  <p>I also tried to use another .vhd (not written by myself and supposed to work).
  This didn't work either: <a href="https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html" rel="nofollow noreferrer">https://www.nandland.com/vhdl/modules/module-uart-serial-port-rs232.html</a>
  (I well modified the generic g_CLKS_PER_BIT in accordance with my clock &amp; baud rate)</p>
  
  <p>The issue could come from PuTTY but I've set a baud rate of 9600 baud, 8 data bits, 1 stop bit, no parity, so I don't see what could be wrong !</p>
  
  <p>If you have further ideas / comments, because I can't find what's wrong !</p>
  
  <p>Thank you very much !</p>
  
  <hr>
  
  <p><strong>EDIT March 16, 2017 :</strong></p>
  
  <p><strong>Following @J.H.Bonarius &amp; @user1155120 recommandations, I added a 2 stage flip flop synchronizer to synchronize the RxD incoming signal with my 100 MHz clock domain.</strong></p>
  
  <p>I also modified modified some asynchronous resets.
  Nevertheless, I still have the same issue (LEDs not corresponding to what's sent via PuTTY).</p>
  
  <p>Find hearafter the new .vhd code:</p>
  
  <pre><code>    library IEEE;
  use IEEE.STD_LOGIC_1164.ALL;
  use IEEE.NUMERIC_STD.ALL;
  
  
  entity UART_RX is
      Port ( RxD_in : in  STD_LOGIC;
             clk : in  STD_LOGIC;
             RAZ : in  STD_LOGIC;
             data_out : out  STD_LOGIC_VECTOR (7 downto 0));
  end UART_RX;
  
  architecture Behavioral of UART_RX is
  
      signal tick_UART : STD_LOGIC;                                                        -- Signal "top" passage d'un état à l'autre selon vitesse connexion série
      signal double_tick_UART : STD_LOGIC;                                                 -- Signal précédent, fréquence * 2
      signal compteur_tick_UART : integer range 0 to 10420;                                -- Compteur pour tick_UART 
      signal double_compteur_tick_UART : integer range 0 to 5210;                          -- Compteur pour demi-périodes 
      type state_type is (idle, start, demiStart, b0, b1, b2, b3, b4, b5, b6, b7);         -- Etats de la FSM 
      signal state :state_type := idle;                                                    -- Etat par défaut
      signal RAZ_tick_UART : STD_LOGIC;                                                    -- RAZ du signal tick_UART;
      signal RxD_temp : STD_LOGIC;                                                         -- RxD provisoire entre deux FF
      signal RxD_sync : STD_LOGIC;                                                         -- RxD synchronisé sur l'horloge
  
  begin
  
  D_flip_flop_1:process(clk)  -- Clock crossing 
  begin
      if clk = '1' and clk'event then
          RxD_temp &lt;= RxD_in;
      end if;
  end process;
  
  D_flip_flop_2:process(clk)  -- Clock crossing
  begin
      if clk = '1' and clk'event then
          RxD_sync &lt;= RxD_temp;
      end if;
  end process;
  
  tickUART:process(clk, RAZ, state, RAZ_tick_UART) -- Compteur classique (tick_UART)
  begin
      if clk = '1' and clk'event then
         if (RAZ='1') or (state = idle) or (RAZ_tick_UART = '1') then
              compteur_tick_UART &lt;= 0;
              tick_UART &lt;= '0';
         elsif compteur_tick_UART = 10417 then
              tick_UART &lt;= '1';
              compteur_tick_UART &lt;= 0;
          else
              compteur_tick_UART &lt;= compteur_tick_UART + 1;
              tick_UART &lt;= '0';
          end if;
      end if;
  end process;
  
  doubleTickUART:process(clk, RAZ, state) -- Compteur demi-périodes (double_tick_UART car fréquence double)
  begin
      if clk = '1' and clk'event then
         if (RAZ='1') or (state = idle) then
              double_compteur_tick_UART &lt;= 0;
              double_tick_UART &lt;= '0';
         elsif double_compteur_tick_UART = 5209 then
              double_tick_UART &lt;= '1';
              double_compteur_tick_UART &lt;= 0;
         else
              double_compteur_tick_UART &lt;= double_compteur_tick_UART + 1;
              double_tick_UART &lt;= '0';
         end if;
      end if;
  end process;
  
  fsm:process(clk, RAZ)   -- Machine à état
  begin
      if (RAZ = '1') then
          state &lt;= idle;
          data_out &lt;= "00000000";
          RAZ_tick_UART &lt;= '1';
      elsif clk = '1' and clk'event then
          case state is
              when idle =&gt; if RxD_sync = '0' then         -- Si front descendant de RxD (= bit de start) et en idle
                              state &lt;= start;
                              RAZ_tick_UART &lt;= '1';
                           end if;
              when start =&gt;if double_tick_UART = '1' then -- Demi période écoulée (pour échantillonage)
                              state &lt;= demiStart;
                              RAZ_tick_UART &lt;= '0';       -- Le compteur tick_UART commence à compter
                          end if;
                          data_out &lt;= "00000000";         -- Reset des anciennes données          
              when demiStart =&gt; if tick_UART = '1' then
                                  state &lt;= b0;
                                  RAZ_tick_UART &lt;= '0';
                              end if;
                              data_out(0) &lt;= RxD_sync;    -- Acquisition bit 0
              when b0 =&gt;  if tick_UART = '1' then
                              state &lt;= b1;
                          end if;
                          data_out(1) &lt;= RxD_sync;    -- Acquisition bit 1
              when b1 =&gt;  if tick_UART = '1' then
                              state &lt;= b2;
                          end if;
                          data_out(2) &lt;= RxD_sync;    -- Acquisition bit 2
              when b2 =&gt;  if tick_UART = '1' then
                              state &lt;= b3;
                          end if;
                          data_out(3) &lt;= RxD_sync;    -- Acquisition bit 3
              when b3 =&gt;  if tick_UART = '1' then
                                  state &lt;= b4;
                              end if;
                              data_out(4) &lt;= RxD_sync;    -- Acquisition bit 4
              when b4 =&gt;  if tick_UART = '1' then
                              state &lt;= b5;
                          end if;
                          data_out(5) &lt;= RxD_sync;    -- Acquisition bit 5
              when b5 =&gt;  if tick_UART = '1' then
                              state &lt;= b6;
                          end if;
                          data_out(6) &lt;= RxD_sync;    -- Acquisition bit 6
              when b6 =&gt;  if tick_UART = '1' then
                              state &lt;= b7;    
                          end if;
                          data_out(7) &lt;= RxD_sync;    -- Acquisition bit 7
              when b7 =&gt;  if tick_UART = '1' then
                              state &lt;= idle;   -- state &lt;= stop;
                          end if;
          end case;
      end if;
  end process;
  end Behavioral;
  </code></pre>
  
  <p>Do you have any idea about the origin of my problem ?
  Thank you very much !</p>