| 
						
						
							
								
							
						
						
					 | 
				
			
			 | 
			 | 
			
				@ -34,351 +34,353 @@ use ieee.numeric_std.all;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				--! - Bit 0: data received (receive buffer not empty)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				--! - Bit 1: ready to send data (transmit buffer empty)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				entity pp_soc_uart is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					generic(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						FIFO_DEPTH : natural := 64 --! Depth of the input and output FIFOs.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    generic(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					FIFO_DEPTH : natural := 64 --! Depth of the input and output FIFOs.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					port(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						clk : in std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						reset : in std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						-- UART ports:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						txd : out std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rxd : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						-- Interrupt signal:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						irq : out std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						-- Wishbone ports:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_adr_in  : in  std_logic_vector(11 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_dat_in  : in  std_logic_vector( 7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_dat_out : out std_logic_vector( 7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_we_in   : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_cyc_in  : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_stb_in  : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_ack_out : out std_logic
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    port(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					clk : in std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					reset : in std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- UART ports:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					txd : out std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					rxd : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- Interrupt signal:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					irq : out std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- Wishbone ports:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_adr_in  : in  std_logic_vector(11 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_dat_in  : in  std_logic_vector( 7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_dat_out : out std_logic_vector( 7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_we_in   : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_cyc_in  : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_stb_in  : in  std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_ack_out : out std_logic
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				end entity pp_soc_uart;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				architecture behaviour of pp_soc_uart is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					subtype bitnumber is natural range 0 to 7; --! Type representing the index of a bit.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    subtype bitnumber is natural range 0 to 7; --! Type representing the index of a bit.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- UART sample clock signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal sample_clk         : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal sample_clk_divisor : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal sample_clk_counter : std_logic_vector(sample_clk_divisor'range);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- UART sample clock signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal sample_clk         : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal sample_clk_divisor : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal sample_clk_counter : std_logic_vector(sample_clk_divisor'range);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- UART receive process signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					type rx_state_type is (IDLE, RECEIVE, STARTBIT, STOPBIT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal rx_state : rx_state_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal rx_byte : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal rx_current_bit : bitnumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- UART receive process signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    type rx_state_type is (IDLE, RECEIVE, STARTBIT, STOPBIT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal rx_state : rx_state_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal rx_byte : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal rx_current_bit : bitnumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					subtype rx_sample_counter_type is natural range 0 to 15;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal rx_sample_counter : rx_sample_counter_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal rx_sample_value   : rx_sample_counter_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    subtype rx_sample_counter_type is natural range 0 to 15;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal rx_sample_counter : rx_sample_counter_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal rx_sample_value   : rx_sample_counter_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					subtype rx_sample_delay_type is natural range 0 to 7;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal rx_sample_delay   : rx_sample_delay_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    subtype rx_sample_delay_type is natural range 0 to 7;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal rx_sample_delay   : rx_sample_delay_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- UART transmit process signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					type tx_state_type is (IDLE, TRANSMIT, STOPBIT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal tx_state : tx_state_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal tx_byte : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal tx_current_bit : bitnumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- UART transmit process signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    type tx_state_type is (IDLE, TRANSMIT, STOPBIT);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal tx_state : tx_state_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal tx_byte : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal tx_current_bit : bitnumber;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- UART transmit clock:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					subtype uart_tx_counter_type is natural range 0 to 15;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal uart_tx_counter : uart_tx_counter_type := 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal uart_tx_clk : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- UART transmit clock:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    subtype uart_tx_counter_type is natural range 0 to 15;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal uart_tx_counter : uart_tx_counter_type := 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal uart_tx_clk : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- Buffer signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal send_buffer_full, send_buffer_empty   : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal recv_buffer_full, recv_buffer_empty   : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal send_buffer_input, send_buffer_output : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal recv_buffer_input, recv_buffer_output : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal send_buffer_push, send_buffer_pop     : std_logic := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal recv_buffer_push, recv_buffer_pop     : std_logic := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- Buffer signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal send_buffer_full, send_buffer_empty   : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal recv_buffer_full, recv_buffer_empty   : std_logic;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal send_buffer_input, send_buffer_output : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal recv_buffer_input, recv_buffer_output : std_logic_vector(7 downto 0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal send_buffer_push, send_buffer_pop     : std_logic := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal recv_buffer_push, recv_buffer_pop     : std_logic := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- IRQ enable signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal irq_recv_enable, irq_tx_ready_enable : std_logic := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- IRQ enable signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal irq_recv_enable, irq_tx_ready_enable : std_logic := '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					-- Wishbone signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					type wb_state_type is (IDLE, WRITE_ACK, READ_ACK);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal wb_state : wb_state_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    -- Wishbone signals:
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    type wb_state_type is (IDLE, WRITE_ACK, READ_ACK);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal wb_state : wb_state_type;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					signal wb_ack : std_logic; --! Wishbone acknowledge signal
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    signal wb_ack : std_logic; --! Wishbone acknowledge signal
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					irq <= (irq_recv_enable and (not recv_buffer_empty))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						or (irq_tx_ready_enable and send_buffer_empty);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					---------- UART receive ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					recv_buffer_input <= rx_byte;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uart_receive: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								rx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								recv_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    irq <= (irq_recv_enable and (not recv_buffer_empty))
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					   or (irq_tx_ready_enable and send_buffer_empty);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ---------- UART receive ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    recv_buffer_input <= rx_byte;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    uart_receive: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						recv_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case rx_state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if recv_buffer_push = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							recv_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if sample_clk = '1' and rxd = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							rx_sample_value <= rx_sample_counter;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							rx_sample_delay <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							rx_current_bit <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							rx_state <= STARTBIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when STARTBIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if sample_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if rx_sample_delay = 7 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    rx_state <= RECEIVE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    rx_sample_value <= rx_sample_counter;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    rx_sample_delay <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								case rx_state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if recv_buffer_push = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											recv_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if sample_clk = '1' and rxd = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											rx_sample_value <= rx_sample_counter;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											rx_sample_delay <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											rx_current_bit <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											rx_state <= STARTBIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when STARTBIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if sample_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											if rx_sample_delay = 7 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												rx_state <= RECEIVE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												rx_sample_value <= rx_sample_counter;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												rx_sample_delay <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												rx_sample_delay <= rx_sample_delay + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									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_current_bit <= rx_current_bit + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												rx_byte(rx_current_bit) <= rxd;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												rx_state <= STOPBIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when STOPBIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if sample_clk = '1' and rx_sample_counter = rx_sample_value then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											rx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											if recv_buffer_full = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												recv_buffer_push <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    rx_sample_delay <= rx_sample_delay + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end process uart_receive;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					sample_counter: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								rx_sample_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							elsif sample_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if rx_sample_counter = 15 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									rx_sample_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									rx_sample_counter <= rx_sample_counter + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						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_current_bit <= rx_current_bit + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    rx_byte(rx_current_bit) <= rxd;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    rx_state <= STOPBIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end process sample_counter;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					---------- UART transmit ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when STOPBIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if sample_clk = '1' and rx_sample_counter = rx_sample_value then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							rx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					tx_byte <= send_buffer_output;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uart_transmit: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								txd <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								tx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								send_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								tx_current_bit <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								case tx_state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if send_buffer_empty = '0' and uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											txd <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											send_buffer_pop <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											tx_current_bit <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											tx_state <= TRANSMIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										elsif uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											txd <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when TRANSMIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if send_buffer_pop = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											send_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										elsif uart_tx_clk = '1' and tx_current_bit = 7 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											txd <= tx_byte(tx_current_bit);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											tx_state <= STOPBIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										elsif uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											txd <= tx_byte(tx_current_bit);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											tx_current_bit <= tx_current_bit + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when STOPBIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											txd <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											tx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if recv_buffer_full = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    recv_buffer_push <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process uart_receive;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    sample_counter: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						rx_sample_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    elsif sample_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rx_sample_counter = 15 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    rx_sample_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    rx_sample_counter <= rx_sample_counter + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end process uart_transmit;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					uart_tx_clock_generator: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								uart_tx_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								uart_tx_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if sample_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									if uart_tx_counter = 15 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										uart_tx_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										uart_tx_clk <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										uart_tx_counter <= uart_tx_counter + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										uart_tx_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									uart_tx_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process sample_counter;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ---------- UART transmit ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    tx_byte <= send_buffer_output;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    uart_transmit: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						txd <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						tx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						send_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						tx_current_bit <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case tx_state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if send_buffer_empty = '0' and uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							txd <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							send_buffer_pop <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							tx_current_bit <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							tx_state <= TRANSMIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    elsif uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							txd <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when TRANSMIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if send_buffer_pop = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							send_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    elsif uart_tx_clk = '1' and tx_current_bit = 7 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							txd <= tx_byte(tx_current_bit);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							tx_state <= STOPBIT;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    elsif uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							txd <= tx_byte(tx_current_bit);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							tx_current_bit <= tx_current_bit + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when STOPBIT =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if uart_tx_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							txd <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							tx_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process uart_transmit;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    uart_tx_clock_generator: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uart_tx_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						uart_tx_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if sample_clk = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if uart_tx_counter = 15 then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							uart_tx_counter <= 0;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							uart_tx_clk <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							uart_tx_counter <= uart_tx_counter + 1;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							uart_tx_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    uart_tx_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end process uart_tx_clock_generator;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					---------- Sample clock generator ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					sample_clock_generator: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								sample_clk_counter <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								sample_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								if sample_clk_divisor /= x"00" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									if sample_clk_counter = sample_clk_divisor then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										sample_clk_counter <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										sample_clk <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										sample_clk_counter <= std_logic_vector(unsigned(sample_clk_counter) + 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										sample_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process uart_tx_clock_generator;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ---------- Sample clock generator ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    sample_clock_generator: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						sample_clk_counter <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						sample_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if sample_clk_divisor /= x"00" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if sample_clk_counter = sample_clk_divisor then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							sample_clk_counter <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							sample_clk <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							sample_clk_counter <= std_logic_vector(unsigned(sample_clk_counter) + 1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							sample_clk <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end process sample_clock_generator;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					---------- Data Buffers ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					send_buffer: entity work.pp_fifo
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						generic map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							DEPTH => FIFO_DEPTH,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							WIDTH => 8
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						) port map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							clk => clk,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							reset => reset,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							full => send_buffer_full,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							empty => send_buffer_empty,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							data_in => send_buffer_input,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							data_out => send_buffer_output,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							push => send_buffer_push,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							pop => send_buffer_pop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process sample_clock_generator;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ---------- Data Buffers ----------
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    send_buffer: entity work.pp_fifo
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					generic map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    DEPTH => FIFO_DEPTH,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    WIDTH => 8
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    ) port map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						clk => clk,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						reset => reset,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						full => send_buffer_full,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						empty => send_buffer_empty,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						data_in => send_buffer_input,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						data_out => send_buffer_output,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						push => send_buffer_push,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						pop => send_buffer_pop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					recv_buffer: entity work.pp_fifo
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						generic map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							DEPTH => FIFO_DEPTH,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							WIDTH => 8
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						) port map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							clk => clk,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							reset => reset,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							full => recv_buffer_full,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							empty => recv_buffer_empty,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							data_in => recv_buffer_input,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							data_out => recv_buffer_output,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							push => recv_buffer_push,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							pop => recv_buffer_pop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    recv_buffer: entity work.pp_fifo
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					generic map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    DEPTH => FIFO_DEPTH,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    WIDTH => 8
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    ) port map(
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						clk => clk,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						reset => reset,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						full => recv_buffer_full,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						empty => recv_buffer_empty,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						data_in => recv_buffer_input,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						data_out => recv_buffer_output,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						push => recv_buffer_push,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						pop => recv_buffer_pop
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					---------- Wishbone Interface ---------- 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					wishbone: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_ack <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								send_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								recv_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								sample_clk_divisor <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								irq_recv_enable <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								irq_tx_ready_enable <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								case wb_state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if wb_cyc_in = '1' and wb_stb_in = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											if wb_we_in = '1' then -- Write to register
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												if wb_adr_in = x"000" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													send_buffer_input <= wb_dat_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													send_buffer_push <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												elsif wb_adr_in = x"018" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													sample_clk_divisor <= wb_dat_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												elsif wb_adr_in = x"020" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													irq_recv_enable <= wb_dat_in(0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													irq_tx_ready_enable <= wb_dat_in(1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												-- Invalid writes are acked and ignored.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												wb_state <= WRITE_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											else -- Read from register
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												if wb_adr_in = x"008" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													recv_buffer_pop <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												elsif wb_adr_in = x"010" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_dat_out <= x"0" & send_buffer_full & recv_buffer_full & send_buffer_empty & recv_buffer_empty;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												elsif wb_adr_in = x"018" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_dat_out <= sample_clk_divisor;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												elsif wb_adr_in = x"020" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_dat_out <= (0 => irq_recv_enable, 1 => irq_tx_ready_enable, others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_dat_out <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
													wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
												wb_state <= READ_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when WRITE_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										send_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if wb_stb_in = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											wb_ack <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											wb_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									when READ_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if recv_buffer_pop = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											recv_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											wb_dat_out <= recv_buffer_output;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										if wb_stb_in = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											wb_ack <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
											wb_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
										end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    ---------- Wishbone Interface ---------- 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    wb_ack_out <= wb_ack and wb_cyc_in and wb_stb_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    wishbone: process(clk)
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    begin
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					if rising_edge(clk) then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    if reset = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_ack <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						wb_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						send_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						recv_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						sample_clk_divisor <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						irq_recv_enable <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						irq_tx_ready_enable <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						case wb_state is
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when IDLE =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if wb_cyc_in = '1' and wb_stb_in = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							if wb_we_in = '1' then -- Write to register
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    if wb_adr_in = x"000" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								send_buffer_input <= wb_dat_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								send_buffer_push <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    elsif wb_adr_in = x"018" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								sample_clk_divisor <= wb_dat_in;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    elsif wb_adr_in = x"020" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								irq_recv_enable <= wb_dat_in(0);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								irq_tx_ready_enable <= wb_dat_in(1);
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    -- Invalid writes are acked and ignored.
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    wb_state <= WRITE_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							else -- Read from register
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    if wb_adr_in = x"008" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								recv_buffer_pop <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    elsif wb_adr_in = x"010" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_dat_out <= x"0" & send_buffer_full & recv_buffer_full &
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									      send_buffer_empty & recv_buffer_empty;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    elsif wb_adr_in = x"018" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_dat_out <= sample_clk_divisor;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    elsif wb_adr_in = x"020" then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_dat_out <= (0 => irq_recv_enable,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									       1 => irq_tx_ready_enable,
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
									       others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_dat_out <= (others => '0');
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
								wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							    wb_state <= READ_ACK;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end process wishbone;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when WRITE_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    send_buffer_push <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if wb_stb_in = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							wb_ack <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							wb_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						when READ_ACK =>
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if recv_buffer_pop = '1' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							recv_buffer_pop <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    else
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							wb_dat_out <= recv_buffer_output;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							wb_ack <= '1';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    if wb_stb_in = '0' then
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							wb_ack <= '0';
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
							wb_state <= IDLE;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
						end case;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					    end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
					end if;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				    end process wishbone;
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				
 
 | 
			
		
		
	
		
			
				 | 
				 | 
			
			 | 
			 | 
			
				end architecture behaviour;
 | 
			
		
		
	
	
		
			
				
					| 
						
						
						
					 | 
				
			
			 | 
			 | 
			
				
 
 |