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

Subversion Repositories gpib_controller

[/] [gpib_controller/] [trunk/] [vhdl/] [src/] [comm/] [Uart.vhd] - Rev 3

Go to most recent revision | Compare with Previous | Blame | View Log

--------------------------------------------------------------------------------
-- Entity: Uart
-- Date:2011-11-26  
-- Author: apaluch     
--
-- Description ${cursor}
--------------------------------------------------------------------------------
library ieee;
use ieee.std_logic_1164.all;
use ieee.std_logic_unsigned.all;
 
 
entity Uart is
	port (
		reset : in std_logic;
		clk : in std_logic;
		---------- UART ---------------
		RX : in std_logic;
		TX : out std_logic;
		---------- gpib ---------------
		data_out : out std_logic_vector(7 downto 0);
		data_out_ready : out std_logic;
		data_in : in std_logic_vector(7 downto 0);
		data_in_ready : in std_logic;
		ready_to_send : out std_logic
	);
end Uart;
 
architecture arch of Uart is
 
	constant BIT_TIME : integer :=
		-- 115200
		--572
		-- 921600
		72
		;
	constant HALF_BIT_TIME : integer := BIT_TIME / 2;
 
	type RX_STATES is (
		ST_RX_IDLE,
		ST_RX_HALF_START,
		ST_RX_RECEIVE_BITS,
		ST_RX_RECEIVE_STOP_BIT
	);
 
	type TX_STATES is (
		ST_TX_IDLE,
		ST_TX_SEND_BITS,
		ST_TX_SEND_STOP_BIT
	);
 
	signal syncRX : std_logic;
 
	signal rxState : RX_STATES;
	signal lastRx : std_logic;
	signal rxTimeCounter : integer range 0 to BIT_TIME;
	signal rxBitCounter : integer range 0 to 7;
	signal innerBuf : std_logic_vector(6 downto 0);
 
	signal txState : TX_STATES;
	signal lastData_in_ready : std_logic;
	signal txTimeCounter : integer range 0 to BIT_TIME;
	signal txBitCounter : integer range 0 to 8;
 
begin
 
	-- RX synchronizer
	process(clk, RX) begin
		if rising_edge(clk) then
			syncRX <= RX;
		end if;
	end process;
 
	-- RX
	process(reset, clk, syncRX) begin
		if reset = '1' then
			rxState <= ST_RX_IDLE;
			lastRx <= syncRX;
			data_out_ready <= '0';
		elsif rising_edge(clk) then
 
			lastRx <= syncRX;
 
			if rxTimeCounter < BIT_TIME then
				rxTimeCounter <= rxTimeCounter + 1;
			end if;
 
			case rxState is
				when ST_RX_IDLE =>
					if lastRx /= syncRX and syncRX = '0' then
						rxTimeCounter <= 1;
						rxState <= ST_RX_HALF_START;
					end if;
 
				when ST_RX_HALF_START =>
					if rxTimeCounter >= HALF_BIT_TIME then
						rxBitCounter <= 0;
						rxTimeCounter <= 1;
						rxState <= ST_RX_RECEIVE_BITS;
					end if;
 
				when ST_RX_RECEIVE_BITS =>
					if rxTimeCounter >= BIT_TIME then
 
						if rxBitCounter < 7 then
							innerBuf(rxBitCounter) <= syncRX;
							rxBitCounter <= rxBitCounter + 1;
							rxTimeCounter <= 1;
						elsif rxBitCounter = 7 then
							data_out(7) <= syncRX;
							data_out(6 downto 0) <= innerBuf;
							data_out_ready <= '0';
							rxTimeCounter <= 1;
 
							rxState <= ST_RX_RECEIVE_STOP_BIT;
						end if;
					end if;
 
				when ST_RX_RECEIVE_STOP_BIT =>
					if rxTimeCounter >= BIT_TIME then
						data_out_ready <= '1';
 
						rxState <= ST_RX_IDLE;
					end if;
 
				when others =>
					rxState <= ST_RX_IDLE;
			end case;
		end if;
	end process;
 
	-- TX
	process(reset, clk, data_in_ready) begin
		if reset = '1' then
			TX <= '1';
			ready_to_send <= '1';
			txState <= ST_TX_IDLE;
		elsif rising_edge(clk) then
 
			lastData_in_ready <= data_in_ready;
 
			if txTimeCounter < BIT_TIME then
				txTimeCounter <= txTimeCounter + 1;
			end if;
 
			case txState is
				when ST_TX_IDLE =>
					if lastData_in_ready /= data_in_ready and
							data_in_ready = '1' then
						TX <= '0';
						txTimeCounter <= 1;
						txBitCounter <= 0;
						ready_to_send <= '0';
 
						txState <= ST_TX_SEND_BITS;
					end if;
				when ST_TX_SEND_BITS =>
					if txTimeCounter >= BIT_TIME then
 
						if txBitCounter < 8 then
							TX <= data_in(txBitCounter);
							txBitCounter <= txBitCounter + 1;
							txTimeCounter <= 1;
						elsif txBitCounter = 8 then
							TX <= '1';
							txTimeCounter <= 1;
 
							txState <= ST_TX_SEND_STOP_BIT;
						end if;
					end if;
				when ST_TX_SEND_STOP_BIT =>
					if txTimeCounter >= BIT_TIME then
						ready_to_send <= '1';
 
						txState <= ST_TX_IDLE;
					end if;
				when others =>
					txState <= ST_TX_IDLE;
			end case;
		end if;
	end process;
 
end arch;
 
 

Go to most recent revision | 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.