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

Subversion Repositories ahbmaster

[/] [ahbmaster/] [trunk/] [test79_AHBmaster/] [component/] [work/] [top/] [CoreUARTapb_0/] [rtl/] [vhdl/] [core/] [Rx_async.vhd] - Rev 3

Compare with Previous | Blame | View Log

-- ********************************************************************
-- Actel Corporation Proprietary and Confidential
--  Copyright 2008 Actel Corporation.  All rights reserved.
--
-- ANY USE OR REDISTRIBUTION IN PART OR IN WHOLE MUST BE HANDLED IN
-- ACCORDANCE WITH THE ACTEL LICENSE AGREEMENT AND MUST BE APPROVED
-- IN ADVANCE IN WRITING.
--
-- Description: CoreUART/ CoreUARTapb UART core
--
--
--  Revision Information:
-- Date     Description
-- Jun09    Revision 4.1
-- Aug10    Revision 4.2
 
-- SVN Revision Information:
-- SVN $Revision: 8508 $
-- SVN $Date: 2009-06-15 16:49:49 -0700 (Mon, 15 Jun 2009) $
--
-- Resolved SARs
-- SAR      Date     Who   Description
-- 20741    2Sep10   AS    Increased baud rate by ensuring fifo ctrl runs off
--                         sys clk (not baud clock).  See note below.
 
-- Notes:
-- best viewed with tabstops set to "4"
LIBRARY IEEE;
USE IEEE.std_logic_1164.all;
USE IEEE.std_logic_arith.all;
USE IEEE.std_logic_unsigned.all;
 
ENTITY top_CoreUARTapb_0_Rx_async IS
   GENERIC ( SYNC_RESET      : integer := 0;
             -- RX Parameters
             RX_FIFO         :  integer := 0);    --  0=without rx fifo, 1=with rx fifo 
   PORT (
 
      clk                     : IN std_logic;   --   system clock
      baud_clock              : IN std_logic;   --   8x baud clock pulse
      reset_n                 : IN std_logic;   --   active low async reset  
      bit8                    : IN std_logic;   --   if set to one 8 data bits otherwise 7 data bits
      parity_en               : IN std_logic;   --   if set to one parity is enabled otherwise disabled
      odd_n_even              : IN std_logic;   --   if set to one odd parity otherwise even parity
      read_rx_byte            : IN std_logic;   --   read rx byte register
      clear_parity            : IN std_logic;   --   clear parity error 
      clear_framing_error     : IN std_logic;   --   clear framing error 
      rx                      : IN std_logic;   
      overflow                : OUT std_logic;   --   receiver overflow
      parity_err              : OUT std_logic;   --   parity error indicator on recieved data
      framing_error           : OUT std_logic;   --   framing error indicator (AS)
      rx_idle_out             : OUT std_logic;   --   used for framing error assignment (AS)
      stop_strobe             : OUT std_logic;   --   stop sync signal for RXRDY
      clear_framing_error_en  : OUT std_logic;   --  clear framing error enable
      clear_parity_en         : OUT std_logic;   --  clear parity error enable
      receive_full            : OUT std_logic;   --   receiver has a byte ready
      rx_byte                 : OUT std_logic_vector(7 DOWNTO 0);   
      fifo_write              : OUT std_logic);   
END ENTITY top_CoreUARTapb_0_Rx_async;
 
ARCHITECTURE translated OF top_CoreUARTapb_0_Rx_async IS
 
   -- TYPE receive_states:
   type receive_states  is (rx_idle, rx_data_bits, rx_stop_bit, rx_wait_state);
 
   --  receive byte register
   SIGNAL rx_state                 :  receive_states;                -- receive state machine
   SIGNAL receive_count            :  std_logic_vector(3 DOWNTO 0);   --   counts bits received
   SIGNAL rx_filtered              :  std_logic;   --   filtered rx data
   SIGNAL rx_shift                 :  std_logic_vector(8 DOWNTO 0);   --   receive shift register
   SIGNAL rx_parity_calc           :  std_logic;   --   received parity, calculated
   SIGNAL rx_bit_cnt               :  std_logic_vector(3 DOWNTO 0);   --   count of received bits 
   SIGNAL receive_full_int         :  std_logic;   --   receiver has a byte ready
   SIGNAL samples                  :  std_logic_vector(2 DOWNTO 0);   
   SIGNAL overflow_int             :  std_logic;   
   SIGNAL shift_choice             :  std_logic_vector(1 DOWNTO 0);   
   SIGNAL parity_choice            :  std_logic_vector(1 DOWNTO 0);   
   -- ----------------------------------------------------------------------------
   SIGNAL last_bit                 :  std_logic_vector(3 DOWNTO 0);   
   -- ----------------------------------------------------------------------------
   --  receive state machine & byte register
   -- ----------------------------------------------------------------------------
   SIGNAL overflow_xhdl1           :  std_logic;   
   SIGNAL parity_err_xhdl2         :  std_logic;   
   SIGNAL framing_error_i          :  std_logic;
   SIGNAL framing_error_int        :  std_logic;
   SIGNAL stop_strobe_i            :  std_logic;
   SIGNAL clear_parity_en_xhdl3    :  std_logic;   
   SIGNAL clear_framing_error_en_i :  std_logic; -- AS: Added 07-29-09
   SIGNAL receive_full_xhdl4       :  std_logic;   
   SIGNAL rx_byte_xhdl5            :  std_logic_vector(7 DOWNTO 0);   
   SIGNAL last_bit_case            :  std_logic_vector(1 DOWNTO 0);   
   SIGNAL fifo_write_xhdl6         :  std_logic;   
   SIGNAL aresetn                  :  std_logic;
   SIGNAL sresetn                  :  std_logic;
 
BEGIN
   aresetn <= '1' WHEN (SYNC_RESET=1) ELSE reset_n;
   sresetn <= reset_n WHEN (SYNC_RESET=1) ELSE '1';
   stop_strobe <= stop_strobe_i;
   framing_error <= framing_error_i;
   overflow <= overflow_xhdl1;
   parity_err <= parity_err_xhdl2;
   clear_parity_en <= clear_parity_en_xhdl3;
   receive_full <= receive_full_xhdl4;
   rx_byte <= rx_byte_xhdl5;
   fifo_write <= fifo_write_xhdl6;
   rx_idle_out <= '1' when (rx_state = rx_idle) else '0';
   clear_framing_error_en <= clear_framing_error_en_i;
   last_bit_case <= bit8 & parity_en; 
 
   --  filter the receive data
   -- ----------------------------------------------------------------------------
   --  The receive data filter is a simple majority voter that accepts three
   --  samples of the "raw" data and reports the most populus result.  This
   --  provides a simple single-cycle glitch filter.
   --  This input needs to go to both the state machine start bit detector as
   --  well as the data shift register as this filter introduces a three-clock 
   --  delay and we need to keep the phases lined up.
   -- 
 
   majority : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         samples <= "111";    
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            samples <= "111";    
	     ELSE
            IF (baud_clock = '1') THEN
               samples(1 DOWNTO 0) <= samples(2 DOWNTO 1);    
               samples(2) <= rx;    
            END IF;
         END IF;
      END IF;
   END PROCESS majority;
 
   --  our voter
 
   PROCESS (samples)
   BEGIN
      CASE samples IS
         WHEN "000" =>
                  rx_filtered <= '0';    
         WHEN "001" =>
                  rx_filtered <= '0';    
         WHEN "010" =>
                  rx_filtered <= '0';    
         WHEN "011" =>
                  rx_filtered <= '1';    
         WHEN "100" =>
                  rx_filtered <= '0';    
         WHEN "101" =>
                  rx_filtered <= '1';    
         WHEN "110" =>
                  rx_filtered <= '1';    
         WHEN OTHERS  =>
                  rx_filtered <= '1';    
 
      END CASE;
   END PROCESS;
 
   -- ----------------------------------------------------------------------------
   --  receive bit counter
   -- ----------------------------------------------------------------------------
 
   rcv_cnt : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         receive_count <= "0000";    
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            receive_count <= "0000";  
	     ELSE
            IF (baud_clock = '1') THEN
               --  no start bit yet or begin sample period for data
 
               IF ((baud_clock = '1' AND rx_state = rx_idle AND (rx_filtered = '1' OR receive_count = "1000")) OR (rx_state = rx_wait_state AND (receive_count = "0110"))) THEN
                  receive_count <= "0000";    
               ELSE
                  receive_count <= receive_count + "0001";    
               END IF;
            END IF;
         END IF;
      END IF;
   END PROCESS rcv_cnt;
 
   -- ----------------------------------------------------------------------------
   --  registering of the overflow signal
   -- ----------------------------------------------------------------------------
 
   make_overflow : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         overflow_xhdl1 <= '0';    
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            overflow_xhdl1 <= '0'; 
	     ELSE
            IF (baud_clock = '1') THEN
               IF (overflow_int = '1') THEN
                  overflow_xhdl1 <= '1';    
               END IF;
            END IF;
            IF (read_rx_byte = '1') THEN
               overflow_xhdl1 <= '0';    
            END IF;
         END IF;
      END IF;
   END PROCESS make_overflow;
 
   -- ----------------------------------------------------------------------------
   --  registering of the framing_error signal
   -- ----------------------------------------------------------------------------
 
   make_framing_error : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         framing_error_i <= '0';    
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            framing_error_i <= '0'; 
	     ELSE
            IF (baud_clock = '1') THEN
               IF (framing_error_int = '1') THEN
                  framing_error_i <= '1';
               ELSIF (clear_framing_error = '1') THEN
                   framing_error_i <= '0';
               END IF;
            ELSIF (clear_framing_error = '1') THEN
               framing_error_i <= '0';
            ELSE
               framing_error_i <= framing_error_i;
            END IF;
         END IF;
      END IF;
   END PROCESS make_framing_error;
 
   make_last_bit : PROCESS (clk, aresetn)
   BEGIN
       IF(aresetn = '0') THEN
           last_bit <= "1001"; 
       ELSIF (clk'EVENT AND clk = '1') THEN
           IF(sresetn = '0') THEN
               last_bit <= "1001"; 
	       ELSE
               IF((baud_clock = '1') AND (rx_state = rx_idle) AND (receive_count = "1000")) THEN
                   CASE(last_bit_case) IS
                     WHEN "00" => last_bit <= "0111"; 
                     WHEN "01" => last_bit <= "1000";
                     WHEN "10" => last_bit <= "1000";
                     WHEN "11" => last_bit <= "1001";
                     WHEN OTHERS => last_bit <= "1001";
                   END CASE;
               ELSE
                   last_bit <= last_bit;
               END IF;
           END IF;
       END IF;
   END PROCESS; 
 
   rcv_sm : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         rx_state <= rx_idle;
         rx_byte_xhdl5 <= "00000000";    
         overflow_int <= '0';
         framing_error_int <= '0';
         stop_strobe_i <= '0';
      ELSIF (clk'EVENT AND clk = '1') THEN
          IF (sresetn = '0') THEN
             rx_state <= rx_idle;
             rx_byte_xhdl5 <= "00000000";    
             overflow_int <= '0';
             framing_error_int <= '0';
             stop_strobe_i <= '0';
	      ELSE
             IF (baud_clock = '1') THEN
                overflow_int <= '0';  
                framing_error_int <= '0';
                stop_strobe_i <= '0';
                CASE rx_state IS
                   WHEN rx_idle =>
                            IF (receive_count = "1000") THEN
                               rx_state <= rx_data_bits;
                            ELSE
                               rx_state <= rx_idle;
                            END IF;
                   WHEN rx_data_bits =>
                            IF (rx_bit_cnt = last_bit) THEN
                               --  last bit has been received
                               --  if receive_full is still active at this point, then overflow     
                               rx_state <= rx_stop_bit ;  
                               overflow_int <= receive_full_int;    
                               IF (receive_full_int = '0') THEN
                                  rx_byte_xhdl5 <= (bit8 AND rx_shift(7)) & rx_shift(6 DOWNTO 0);    
                               END IF;
                            ELSE
                               rx_state <= rx_data_bits;    --   still clocking in bits
                            END IF;
                   WHEN rx_stop_bit =>
                            IF (receive_count = "1110") THEN
                               IF (rx_filtered = '0') THEN
                                  framing_error_int <= '1';
                                END IF;
                            ELSIF (receive_count = "1111") THEN
                               stop_strobe_i <= '1';
                               rx_state <=  rx_wait_state; 
                            ELSE
                               rx_state <= rx_stop_bit;    
                            END IF;
                   WHEN rx_wait_state =>
                            IF ((rx_filtered = '1') OR (receive_count = "0110")) THEN
		    				    rx_state <=  rx_idle; 
		    				ELSE
		    				    rx_state <=  rx_wait_state; 
		    				END IF;
                   WHEN OTHERS  =>
                            rx_state <=  rx_idle;    
 
                END CASE;
             END IF;
          END IF;
      END IF;
   END PROCESS rcv_sm;
   -- ----------------------------------------------------------------------------
   --  receive shift register and parity calculation
   -- ----------------------------------------------------------------------------
   shift_choice <= bit8 & parity_en ;
 
   receive_shift : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         rx_shift(8 DOWNTO 0) <= "000000000";    
         rx_bit_cnt <= "0000";    
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            rx_shift(8 DOWNTO 0) <= "000000000";    
            rx_bit_cnt <= "0000";   
	     ELSE
            IF (baud_clock = '1') THEN
               IF (rx_state = rx_idle) THEN
                  rx_shift(8 DOWNTO 0) <= "000000000";    
                  rx_bit_cnt <= "0000";    
               ELSE
                  IF (receive_count = "1111") THEN
                     --  sample new data bit
 
                     rx_bit_cnt <= rx_bit_cnt + "0001";    
                     CASE shift_choice IS
                        WHEN "00" =>
                                 rx_shift(5 DOWNTO 0) <= rx_shift(6 DOWNTO 1);    
                                 rx_shift(6) <= rx_filtered;    
                        WHEN "11" =>
                                 rx_shift(7 DOWNTO 0) <= rx_shift(8 DOWNTO 1);    
                                 rx_shift(8) <= rx_filtered;    
                        WHEN OTHERS  =>
                                 rx_shift(6 DOWNTO 0) <= rx_shift(7 DOWNTO 1);    
                                 rx_shift(7) <= rx_filtered;    
 
                     END CASE;
                  END IF;
               END IF;
            END IF;
         END IF;
      END IF;
   END PROCESS receive_shift;
 
   -- ----------------------------------------------------------------------------
   --  receiver parity calculation
   -- ----------------------------------------------------------------------------
 
   rx_par_calc : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         rx_parity_calc <= '0';    
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            rx_parity_calc <= '0';    
	     ELSE
            IF (baud_clock = '1') THEN
               IF (receive_count = "1111" AND parity_en = '1') THEN
                  rx_parity_calc <= rx_parity_calc XOR rx_filtered;    
               END IF;
               IF ((rx_state =  rx_stop_bit)) THEN
                  rx_parity_calc <= '0';    
               END IF;
            END IF;
         END IF;
      END IF;
   END PROCESS rx_par_calc;
   -- ----------------------------------------------------------------------------
   --  latch parity error for even or odd parity
   -- ----------------------------------------------------------------------------
   parity_choice <= bit8 & odd_n_even ;
 
   make_parity_err : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         parity_err_xhdl2 <= '0';    
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            parity_err_xhdl2 <= '0';  
	     ELSE
            IF ((baud_clock = '1' AND parity_en = '1') AND receive_count = "1111") THEN
               CASE parity_choice IS
                  WHEN "00" =>
                           IF (rx_bit_cnt = "0111") THEN
                              parity_err_xhdl2 <= rx_parity_calc XOR rx_filtered;    
                           END IF;
                  WHEN "01" =>
                           IF (rx_bit_cnt = "0111") THEN
                              parity_err_xhdl2 <= NOT (rx_parity_calc XOR rx_filtered);    
                           END IF;
                  WHEN "10" =>
                           IF (rx_bit_cnt = "1000") THEN
                              parity_err_xhdl2 <= rx_parity_calc XOR rx_filtered;    
                           END IF;
                  WHEN "11" =>
                           IF (rx_bit_cnt = "1000") THEN
                              parity_err_xhdl2 <= NOT (rx_parity_calc XOR rx_filtered);    
                           END IF;
                  WHEN OTHERS  =>
                           parity_err_xhdl2 <= '0';    
 
               END CASE;
            END IF;
            -- if (read_rx_byte == 1'b1)
 
            IF (clear_parity = '1') THEN
               parity_err_xhdl2 <= '0';    
            END IF;
         END IF;
      END IF;
   END PROCESS make_parity_err;
 
   -- ----------------------------------------------------------------------------
   --  receive full indicator process
   -- ----------------------------------------------------------------------------
 
   receive_full_indicator : PROCESS (clk, aresetn)
   BEGIN
      IF (aresetn = '0') THEN
         receive_full_int <= '0';    
         fifo_write_xhdl6 <= '1';    
         clear_parity_en_xhdl3 <= '0';    
         clear_framing_error_en_i <= '0';
      ELSIF (clk'EVENT AND clk = '1') THEN
         IF (sresetn = '0') THEN
            receive_full_int <= '0';    
            fifo_write_xhdl6 <= '1';    
            clear_parity_en_xhdl3 <= '0';    
            clear_framing_error_en_i <= '0';
	     ELSE
            fifo_write_xhdl6 <= '1';    
            clear_parity_en_xhdl3 <= '0';  
            clear_framing_error_en_i <= '0';
            IF (baud_clock = '1') THEN
               --  last bit has been received 
 
               IF (bit8 = '1') THEN
                  IF (parity_en = '1') THEN
                     IF (rx_bit_cnt = "1001" AND rx_state = rx_data_bits) THEN
                        fifo_write_xhdl6 <= '0';    
                        clear_parity_en_xhdl3 <= '1';    
                        clear_framing_error_en_i <= '1';
                        IF (RX_FIFO = 2#0#) THEN
                           receive_full_int <= '1';    
                        END IF;
                     END IF;
                  ELSE
                     IF (rx_bit_cnt = "1000" AND rx_state = rx_data_bits) THEN
                        fifo_write_xhdl6 <= '0';    
                        clear_parity_en_xhdl3 <= '1';
                        clear_framing_error_en_i <= '1';
                        IF (RX_FIFO = 2#0#) THEN
                           receive_full_int <= '1';    
                        END IF;
                     END IF;
                  END IF;
               ELSE
                  IF (parity_en = '1') THEN
                     IF (rx_bit_cnt = "1000" AND rx_state = rx_data_bits) THEN
                        fifo_write_xhdl6 <= '0';    
                        clear_parity_en_xhdl3 <= '1';
                        clear_framing_error_en_i <= '1';
                        IF (RX_FIFO = 2#0#) THEN
                           receive_full_int <= '1';    
                        END IF;
                     END IF;
                  ELSE
                     IF (rx_bit_cnt = "0111" AND rx_state = rx_data_bits) THEN
                        fifo_write_xhdl6 <= '0';    
                        clear_parity_en_xhdl3 <= '1';
                        clear_framing_error_en_i <= '1';
                        IF (RX_FIFO = 2#0#) THEN
                           receive_full_int <= '1';    
                        END IF;
                     END IF;
                  END IF;
               END IF;
            END IF;
            IF (read_rx_byte = '1') THEN
               receive_full_int <= '0';    
            END IF;
         END IF;
      END IF;
   END PROCESS receive_full_indicator;
   receive_full_xhdl4 <= receive_full_int ;
 
END ARCHITECTURE translated;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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