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

Subversion Repositories hicovec

[/] [hicovec/] [trunk/] [cpu/] [units/] [rs232.vhd] - Rev 12

Compare with Previous | Blame | View Log

----------------------------------------------------------------------------------
-- Company:        Fachhochschule Augsburg - Fakultät für Informatik
-- Engineer:       Schäferling Michael
-- 
-- Create Date:    23:34:55 02/27/2007 
-- Design Name:    
-- Module Name:    rs232 - Behavioral 
-- Project Name:   
-- Target Devices: Xilinx
-- Tool versions:  
-- Description:    This module provides RS232 communication
--
-- Dependencies:   
--
-- Revision: 
-- Revision 0.01 - File Created
-- Additional Comments: 
--
----------------------------------------------------------------------------------
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
---- Uncomment the following library declaration if instantiating
---- any Xilinx primitives in this code.
--library UNISIM;
--use UNISIM.VComponents.all;
 
entity rs232 is
  generic(DATABITS:  integer:= 8;
			 STARTBITS: integer:= 1;
			 STOPBITS:  integer:= 1
  );
 
  port( -- HW signalling 
			CLK_50MHZ	 : in  std_logic;
			RS232_RXD: in  std_logic;
			RS232_TXD: out std_logic := '1';
 
		  -- internal DataCom
			DATA_TX		 : in  std_logic_vector(DATABITS-1 downto 0);
			TX_SEND_DATA : in  std_logic;
			TX_BUSY		 : out std_logic := '0';
 
			DATA_RX		 : out std_logic_vector(DATABITS-1 downto 0) := (others => '0');
			RX_DATA_RCVD : out std_logic := '0';
			RX_BUSY		 : out std_logic := '0'
  );
end rs232;
 
 
 
architecture Behavioral of rs232 is
 
type SER_STATES is (IDLE, SYN, B0, B1, B2, B3, B4, B5, B6, B7, VALID);
 
signal SER_STATE: SER_STATES := IDLE;
 
 
signal CLK_38400: std_logic := '0';
signal SIG_RST_TSER2: std_logic := '0';
signal SIG_TSER2: std_logic := '0';
 
signal SIG_RST_TSER: std_logic := '0';
signal SIG_TSER: std_logic := '0';
 
 
begin
 
 
 
-- Generate Signal for Serial Clock at 38400
P_GEN_CLK38400: process (CLK_50MHZ)
-- 1302 == 10100010110
constant CLK38400_MAX: std_logic_vector(10 downto 0) := "10100010110";
variable CLK38400_CUR: std_logic_vector(10 downto 0) := "00000000000";
begin
  if CLK_50MHZ'event AND CLK_50MHZ='1' then
  	 if CLK38400_CUR = CLK38400_MAX then
	   CLK38400_CUR := (others => '0');
		CLK_38400 <= '1';
	 else
	   CLK38400_CUR := CLK38400_CUR + "00000000001";
		CLK_38400 <= '0';
	 end if;
  end if;
end process P_GEN_CLK38400;
 
 
 
-- Generate Reset-driven Signal after Tser/2
P_GEN_SIG_TSER2: process (CLK_50MHZ)
-- 651 == 1010001011
constant TSER2_MAX: std_logic_vector(9 downto 0) := "1010001011";
variable TSER2_CUR: std_logic_vector(9 downto 0) := "0000000000";
begin
  if CLK_50MHZ'event AND CLK_50MHZ='1' then
  	 if SIG_RST_TSER2 = '1' then
		SIG_TSER2 <= '0';
	   TSER2_CUR := (others => '0');
	 elsif TSER2_CUR = TSER2_MAX then
	   SIG_TSER2 <= '1';
		TSER2_CUR := (others => '0');
	 else
		SIG_TSER2 <= '0';
	   TSER2_CUR := TSER2_CUR + "0000000001";
	 end if;
  end if;
end process P_GEN_SIG_TSER2;
 
 
 
-- Generate Reset-driven Signal after Tser
P_GEN_SIG_TSER: process (CLK_50MHZ)
constant TSER_MAX: std_logic_vector(10 downto 0) := "10100010110";
variable TSER_CUR: std_logic_vector(10 downto 0) := "00000000000";
begin
  if CLK_50MHZ'event AND CLK_50MHZ='1' then
  	 if SIG_RST_TSER = '1' then
		SIG_TSER <= '0';
	   TSER_CUR := (others => '0');
	 elsif TSER_CUR = TSER_MAX then
		SIG_TSER <= '1';
	   TSER_CUR := (others => '0');
	 else
		SIG_TSER <= '0';
	   TSER_CUR := TSER_CUR + "00000000001";
	 end if;
  end if;
end process P_GEN_SIG_TSER;
 
 
 
-- RX / TX Process
P_RX_TX: process (CLK_50MHZ) 
constant TOKENSIZE: integer:= STARTBITS + DATABITS + STOPBITS;
 
-- variables for RX
variable BYTE_RX: std_logic_vector(7 downto 0);
  -- for testing
variable signcount: std_logic_vector(3 downto 0) := "0000";
 
-- variables for TX
variable SEND_TOKEN: std_logic := '0';
variable TOKEN_OUT: std_logic_vector(TOKENSIZE-1 downto 0); 
variable COUNT: std_logic_vector(3 downto 0) := "0000";
 
begin
  if CLK_50MHZ'event AND CLK_50MHZ='1' then
 -- RX
	 RX_BUSY <= '1';
    case SER_STATE is
	   when IDLE =>   if RS232_RXD = '0' then 
								SIG_RST_TSER2 <= '1';
								SER_STATE <= SYN;
								RX_DATA_RCVD <= '0';
							else 
								RX_BUSY <= '0';
								SIG_RST_TSER2 <= '0';
								SER_STATE <= IDLE;
								RX_DATA_RCVD <= '0';
							end if;
		when SYN  =>   if SIG_TSER2 = '1' then
								SIG_RST_TSER2 <= '0';
								SIG_RST_TSER <= '1';
								SER_STATE <= B0;
							else 
								SIG_RST_TSER2 <= '0';
								SIG_RST_TSER <= '0';
								SER_STATE <= SYN;
							end if;
		when B0   =>   if SIG_TSER = '1' then
								SIG_RST_TSER <= '0';
								SER_STATE <= B1;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else 
								SIG_RST_TSER <= '0';
								SER_STATE <= B0;
							end if;
		when B1   =>   if SIG_TSER = '1' then
								SER_STATE <= B2;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else SER_STATE <= B1;
							end if;
		when B2   =>   if SIG_TSER = '1' then
								SER_STATE <= B3;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else SER_STATE <= B2;
							end if;
		when B3   =>   if SIG_TSER = '1' then
								SER_STATE <= B4;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else SER_STATE <= B3;
							end if;
		when B4   =>   if SIG_TSER = '1' then
								SER_STATE <= B5;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else SER_STATE <= B4;
							end if;
		when B5   =>   if SIG_TSER = '1' then
								SER_STATE <= B6;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else SER_STATE <= B5;
							end if;
		when B6   =>   if SIG_TSER = '1' then
								SER_STATE <= B7;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else SER_STATE <= B6;
							end if;
		when B7   =>   if SIG_TSER = '1' then
								SER_STATE <= VALID;
								BYTE_RX := RS232_RXD & BYTE_RX(7 downto 1);
							else SER_STATE <= B7;
							end if;
		when VALID =>  if SIG_TSER = '1' then
								if RS232_RXD = '1' then
									DATA_RX <= BYTE_RX;
									RX_DATA_RCVD <= '1';
								else 
								   DATA_RX <= (others => '0');
									RX_DATA_RCVD <= '0';
								end if;
								SER_STATE <= IDLE;
							else
								SER_STATE <= VALID;
							end if;
		end case;
 
 
 -- TX
		TX_BUSY <= '0';
      if TX_SEND_DATA = '1' AND SEND_TOKEN = '0' then
		  TOKEN_OUT := '1' & DATA_TX & '0';
		  SEND_TOKEN := '1';
		end if;
 
		if SEND_TOKEN = '1' then
			TX_BUSY <= '1';
			if CLK_38400 = '1' then
		      if COUNT < TOKENSIZE then
		         --TX_BUSY <= '1';
		         COUNT := COUNT + "0001";
					-- send from right to left (LSB first)
               RS232_TXD <= TOKEN_OUT(0);
	            TOKEN_OUT(TOKENSIZE-1 downto 0) := TOKEN_OUT(0) & TOKEN_OUT(TOKENSIZE-1 downto 1);
	         else
		         COUNT := "0000";
					SEND_TOKEN := '0';
					--TX_BUSY <= '0';
	         end if;
			end if;
		--else
			--TX_BUSY <= '0';
	   end if;
   end if;
end process P_RX_TX;
 
end Behavioral;
 

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.