Add a few FFs on the RX input to avoid metastability issues
authorAnton Blanchard <anton@linux.ibm.com>
Sun, 19 Jan 2020 03:34:15 +0000 (14:34 +1100)
committerAnton Blanchard <anton@ozlabs.org>
Sun, 19 Jan 2020 11:34:24 +0000 (22:34 +1100)
Signed-off-by: Anton Blanchard <anton@linux.ibm.com>
fpga/pp_soc_uart.vhd

index 879ea268b4c908a739db4b070c2eaf3e83d57895..429bec4698ddd344f0aa0bdfed33a0e0edd0e8fc 100644 (file)
@@ -109,6 +109,8 @@ architecture behaviour of pp_soc_uart is
 
     signal wb_ack : std_logic; --! Wishbone acknowledge signal
 
+    signal rxd2 : std_logic := '1';
+    signal rxd3 : std_logic := '1';
 begin
 
     irq <= (irq_recv_enable and (not recv_buffer_empty))
@@ -118,6 +120,13 @@ begin
 
     recv_buffer_input <= rx_byte;
 
+    -- Add a few FFs on the RX input to avoid metastability issues
+    process (clk) is
+    begin
+        rxd3 <= rxd2;
+        rxd2 <= rxd;
+    end process;
+
     uart_receive: process(clk)
     begin
        if rising_edge(clk) then
@@ -131,7 +140,7 @@ begin
                        recv_buffer_push <= '0';
                    end if;
 
-                   if sample_clk = '1' and rxd = '0' then
+                   if sample_clk = '1' and rxd3 = '0' then
                        rx_sample_value <= rx_sample_counter;
                        rx_sample_delay <= 0;
                        rx_current_bit <= 0;
@@ -150,10 +159,10 @@ begin
                when RECEIVE =>
                    if sample_clk = '1' and rx_sample_counter = rx_sample_value then
                        if rx_current_bit /= 7 then
-                           rx_byte(rx_current_bit) <= rxd;
+                           rx_byte(rx_current_bit) <= rxd3;
                            rx_current_bit <= rx_current_bit + 1;
                        else
-                           rx_byte(rx_current_bit) <= rxd;
+                           rx_byte(rx_current_bit) <= rxd3;
                            rx_state <= STOPBIT;
                        end if;
                    end if;