FPGARelated.com
Forums

UART receiver

Started by Konstantin Dols December 12, 2004

Greetings !

I'm looking for a simple RS232 UART16550 receiver for my tiny cyclone board
for different baudrates, 8databits, 1stop&startbit and no(!) partity and  
handshake stuff.

I found several free VHDL implementations in the net but compared to what  
I need
they are to complicated and appear like shooting with missiles on birds ;-)



The entity might have a simple structure like this:

entity receiver is
	generic(	frequency	: integer := 10000000; -- e.g. for 10MHz
			baudrate	: integer := 9600	     -- e.g. for 9600bps
		 );

	port(	clk		: in  std_logic;	-- clockspeed is 'frequency'
		reset 	: in  std_logic;	-- resets the receiver
		receiver	: in  std_logic;	-- input from receive pin from RS232 connector

		char_avail	: out std_logic;	-- indicated that a valid char has beed  
received
		char		: out std_logic_vector(7 downto 0) -- received char, only   
available for one clock
	    );
end receiver;

The 'reciever' values are 'active high'...

This structure gives the responsibility for catching received data in time  
to the user
but surely allowes adding a FIFO.


Probably this question has been asked about 47283407239 times in this group
so please just send me a usefull link or code snippet...


Konstantin

-- 
Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
"Konstantin Dols" <Konstantin.Dols@rwth-aachen.de> wrote in message 
news:opsiv94toznxvpac@pc113...
> > > Greetings ! > > I'm looking for a simple RS232 UART16550 receiver for my tiny cyclone > board > for different baudrates, 8databits, 1stop&startbit and no(!) partity and > handshake stuff. > > I found several free VHDL implementations in the net but compared to what > I need > they are to complicated and appear like shooting with missiles on birds > ;-) >
www.opencores.org (but probably something you have already investigated). The UART "problem" seems to be a pretty common example in various VHDL books. I think Ben Cohen's book has an implementation as well as Navabi's. I can't comment on how or if they work (synthesis). Have you prowled around on the Xilinx web site. A quick search popped up lots of internal links, for example http://www.xilinx.com/bvdocs/appnotes/xapp699.pdf http://www.xilinx.com/bvdocs/appnotes/xapp223.pdf but these may be the "missles" you are refering to. xapp223.pdf does look promising however... If it was me, I'd start with one of the "missles" and start paring it down, removing features.
> > > The entity might have a simple structure like this: > > entity receiver is > generic( frequency : integer := 10000000; -- e.g. for 10MHz > baudrate : integer := 9600 -- e.g. for 9600bps > ); > > port( clk : in std_logic; -- clockspeed is 'frequency' > reset : in std_logic; -- resets the receiver > receiver : in std_logic; -- input from receive pin from RS232 connector > > char_avail : out std_logic; -- indicated that a valid char has beed > received > char : out std_logic_vector(7 downto 0) -- received char, only available > for one clock > ); > end receiver; > > The 'reciever' values are 'active high'... > > This structure gives the responsibility for catching received data in time > to the user > but surely allowes adding a FIFO. > > > Probably this question has been asked about 47283407239 times in this > group > so please just send me a usefull link or code snippet... > > > Konstantin > > -- > Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
Hello:

 At www.opencores.org you can find many uarts, for a very simple UART I 
recommend you to use the miniUART project, if you need a complete 16650 
UART use UART16550 project.

Best Regards

Javier Castillo
jcastillo@opensocdesign.com
www.opensocdesign.com


"Konstantin Dols" <Konstantin.Dols@rwth-aachen.de> wrote in
news:opsiv94toznxvpac@pc113: 

> > > Greetings ! > > I'm looking for a simple RS232 UART16550 receiver for my tiny cyclone > board for different baudrates, 8databits, 1stop&startbit and no(!) > partity and handshake stuff. > > I found several free VHDL implementations in the net but compared to > what I need > they are to complicated and appear like shooting with missiles on > birds ;-) > > > > The entity might have a simple structure like this: > > entity receiver is > generic( frequency : integer := 10000000; -- e.g. for > 10MHz > baudrate : integer := 9600 -- e.g. for > 9600bps > ); > > port( clk : in std_logic; -- clockspeed is > 'frequency' > reset : in std_logic; -- resets the receiver > receiver : in std_logic; -- input from receive pin > from RS232 connector > > char_avail : out std_logic; -- indicated that a > valid char has beed > received > char : out std_logic_vector(7 downto 0) -- received > char, only > available for one clock > ); > end receiver; > > The 'reciever' values are 'active high'... > > This structure gives the responsibility for catching received data in > time to the user > but surely allowes adding a FIFO. > > > Probably this question has been asked about 47283407239 times in this > group so please just send me a usefull link or code snippet... > > > Konstantin >
Konstantin Dols wrote:
> > > Greetings ! > > I'm looking for a simple RS232 UART16550 receiver for my tiny cyclone board > for different baudrates, 8databits, 1stop&startbit and no(!) partity > and handshake stuff. > > I found several free VHDL implementations in the net but compared to > what I need > they are to complicated and appear like shooting with missiles on birds ;-) >
> > Konstantin >
I am currently working on an implementation of such a controller for my semester project. So I will let you have a look to my code when I have finished it. Greetz :) Gr&#4294967295;gory Mermoud gregory.mermoud@epfl.ch Swiss Federal Institute of Technology - Lausanne Computer Science Departement
This is a multi-part message in MIME format.
--------------010900080100040806070409
Content-Type: text/plain; charset=us-ascii; format=flowed
Content-Transfer-Encoding: 7bit

Hi,

in the attachement you'll find something you could use. I've used it on a 
cyclone to do some ASCII communication (giving commands and sending/receiving 
data to/from the system). I'm just in the middle of updating the things so it's 
possible you have to mess around with some libs (or change the libs to 'work').

I've added some functions to convert a 4 bit hex 'string' into a 7 bit char 'string.

kind regards,
Jan


Konstantin Dols wrote:
> > > Greetings ! > > I'm looking for a simple RS232 UART16550 receiver for my tiny cyclone board > for different baudrates, 8databits, 1stop&startbit and no(!) partity > and handshake stuff. > > I found several free VHDL implementations in the net but compared to > what I need > they are to complicated and appear like shooting with missiles on birds ;-) > > > > The entity might have a simple structure like this: > > entity receiver is > generic( frequency : integer := 10000000; -- e.g. for 10MHz > baudrate : integer := 9600 -- e.g. for 9600bps > ); > > port( clk : in std_logic; -- clockspeed is 'frequency' > reset : in std_logic; -- resets the receiver > receiver : in std_logic; -- input from receive pin from > RS232 connector > > char_avail : out std_logic; -- indicated that a valid char > has beed received > char : out std_logic_vector(7 downto 0) -- received char, > only available for one clock > ); > end receiver; > > The 'reciever' values are 'active high'... > > This structure gives the responsibility for catching received data in > time to the user > but surely allowes adding a FIFO. > > > Probably this question has been asked about 47283407239 times in this group > so please just send me a usefull link or code snippet... > > > Konstantin >
--------------010900080100040806070409 Content-Type: text/plain; name="Buffer_procedures.vhd" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="Buffer_procedures.vhd" -- -- ***Author*** -- Jan De Ceuster -- -- *** File *** -- Buffer_procedures.vhd -- -- *** Procedures *** -- -- *** Functions *** -- -- *** Description *** -- -- *** History *** -- 001 initial library ieee; use ieee.std_logic_1164.all; package Buffer_procedures is procedure ShiftL2H_p(input : in std_logic; shiftvector_in : in std_logic_vector; signal shiftvector_out : out std_logic_vector); procedure ShiftL2H_p(input : in std_logic; signal shiftvector : inout std_logic_vector); function ShiftL2H_f(input : in std_logic; shiftvector_in : in std_logic_vector) return std_logic_vector; end package; package body Buffer_procedures is procedure ShiftL2H_p(input : in std_logic; shiftvector_in : in std_logic_vector; signal shiftvector_out : out std_logic_vector) is begin shiftvector_out(shiftvector_out'low) <= input; -- always shift from low towards high if shiftvector_out'high = shiftvector_out'right then shiftvector_out(shiftvector_out'low+1 to shiftvector_out'high) <= shiftvector_in(shiftvector_in'low to shiftvector_in'high-1); else shiftvector_out(shiftvector_out'high downto shiftvector_out'low+1) <= shiftvector_in(shiftvector_in'high-1 downto shiftvector_in'low); end if; end procedure; procedure ShiftL2H_p(input : in std_logic; signal shiftvector : inout std_logic_vector) is begin shiftvector(shiftvector'low) <= input; if shiftvector'high = shiftvector'right then shiftvector(shiftvector'low+1 to shiftvector'high) <= shiftvector(shiftvector'low to shiftvector'high-1); else shiftvector(shiftvector'high downto shiftvector'low+1) <= shiftvector(shiftvector'high-1 downto shiftvector'low); end if; end procedure; function ShiftL2H_f(input : in std_logic; shiftvector_in : in std_logic_vector) return std_logic_vector is variable shiftvector_out : std_logic_vector(shiftvector_in'range); begin shiftvector_out(shiftvector_in'low) := input; -- always shift from low towards high if shiftvector_in'high = shiftvector_in'right then shiftvector_out(shiftvector_in'low+1 to shiftvector_in'high) := shiftvector_in(shiftvector_in'low to shiftvector_in'high-1); else shiftvector_out(shiftvector_in'high downto shiftvector_in'low+1) := shiftvector_in(shiftvector_in'high-1 downto shiftvector_in'low); end if; return shiftvector_out; end function; end Buffer_procedures; --------------010900080100040806070409 Content-Type: text/plain; name="ASCII_functions.vhd" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ASCII_functions.vhd" -- -- ***Author*** -- Jan De Ceuster -- -- *** File *** -- ASCII_functions.vhd -- -- *** Functions *** -- ASCII2HEX_f -- input : std_logic_vector of size n*7 -- return : std_logic_vector of size n*4 (n*4-1 downto 0) -- -- HEX2ASCII_f -- input : std_logic_vector of size n*4 -- return : std_logic_vector of size n*7 (n*7-1 downto 0) -- -- HEX2ASCII_f -- input : std_logic_vector of size n*4 -- return : string of size n (1 to n) -- -- *** Description *** -- -- *** History *** -- 001 initial library ieee; use ieee.std_logic_1164.all; library nicethings; use nicethings.ASCII_constants.all; package ASCII_functions is function ASCII2HEX_f(ASCII : std_logic_vector) return std_logic_vector; function ASCII2HEX_f(ASCII : std_logic_vector; size : integer) return std_logic_vector; function HEX2ASCII_f(HEX : std_logic_vector) return std_logic_vector; function HEX2ASCII_f(HEX : std_logic_vector; size : integer) return std_logic_vector; function HEX2ASCII_f(HEX : std_logic_vector) return string; end package; package body ASCII_functions is function ASCII2HEX_f(ASCII : std_logic_vector) return std_logic_vector is begin return ASCII2HEX_f(ASCII,7); end function; function ASCII2HEX_f(ASCII : std_logic_vector; size : integer) return std_logic_vector is constant length : integer := (ASCII'high - ASCII'low + 1)/7; variable HEXoffset, ASCIIoffset : integer; variable HEX : std_logic_vector(length*4-1 downto 0); variable temp : std_logic_vector(4 downto 0); begin for count in length-1 downto 0 loop HEXoffset := count*4; ASCIIoffset := count*size; temp := ASCII(ASCIIoffset+4+ASCII'low downto ASCIIoffset+ASCII'low); case temp is when C_ASCII_0x0 => HEX(HEXoffset+3 downto HEXoffset) := "0000"; when C_ASCII_0x1 => HEX(HEXoffset+3 downto HEXoffset) := "0001"; when C_ASCII_0x2 => HEX(HEXoffset+3 downto HEXoffset) := "0010"; when C_ASCII_0x3 => HEX(HEXoffset+3 downto HEXoffset) := "0011"; when C_ASCII_0x4 => HEX(HEXoffset+3 downto HEXoffset) := "0100"; when C_ASCII_0x5 => HEX(HEXoffset+3 downto HEXoffset) := "0101"; when C_ASCII_0x6 => HEX(HEXoffset+3 downto HEXoffset) := "0110"; when C_ASCII_0x7 => HEX(HEXoffset+3 downto HEXoffset) := "0111"; when C_ASCII_0x8 => HEX(HEXoffset+3 downto HEXoffset) := "1000"; when C_ASCII_0x9 => HEX(HEXoffset+3 downto HEXoffset) := "1001"; when C_ASCII_0xA => HEX(HEXoffset+3 downto HEXoffset) := "1010"; when C_ASCII_0xB => HEX(HEXoffset+3 downto HEXoffset) := "1011"; when C_ASCII_0xC => HEX(HEXoffset+3 downto HEXoffset) := "1100"; when C_ASCII_0xD => HEX(HEXoffset+3 downto HEXoffset) := "1101"; when C_ASCII_0xE => HEX(HEXoffset+3 downto HEXoffset) := "1110"; when C_ASCII_0xF => HEX(HEXoffset+3 downto HEXoffset) := "1111"; when others => HEX(HEXoffset+3 downto HEXoffset) := "----"; end case; end loop; return HEX; end function; function HEX2ASCII_f(HEX : std_logic_vector) return std_logic_vector is begin return HEX2ASCII_f(HEX,7); end function; function HEX2ASCII_f(HEX : std_logic_vector; size : integer) return std_logic_vector is constant length : integer := (HEX'high - HEX'low + 1)/4; variable ASCII : std_logic_vector(length*7-1 downto 0) := (others => '0'); variable ASCIIoffset, HEXoffset : integer; variable temp : std_logic_vector(3 downto 0); begin for count in length-1 downto 0 loop ASCIIoffset := count*size; HEXoffset := count*4; temp := HEX(HEXoffset+3+HEX'low downto HEXoffset+HEX'low); case temp is when "0000" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_0; when "0001" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_1; when "0010" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_2; when "0011" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_3; when "0100" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_4; when "0101" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_5; when "0110" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_6; when "0111" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_7; when "1000" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_8; when "1001" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_9; when "1010" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_A; when "1011" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_B; when "1100" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_C; when "1101" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_D; when "1110" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_E; when "1111" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_F; when others => ASCII(ASCIIoffset+6 downto ASCIIoffset) := "-------"; end case; end loop; return ASCII; end function; function HEX2ASCII_f(HEX : std_logic_vector) return string is constant size : integer := HEX'high - HEX'low + 1; variable ASCII : string(1 to size/4); variable offset,offset2 : integer; variable temp : std_logic_vector(3 downto 0); begin for count in size/4-1 downto 0 loop offset := size/4-count; offset2 := count*4; temp := HEX(offset2+3+HEX'low downto offset2+HEX'low); case temp is when "0000" => ASCII(offset) := '0'; when "0001" => ASCII(offset) := '1'; when "0010" => ASCII(offset) := '2'; when "0011" => ASCII(offset) := '3'; when "0100" => ASCII(offset) := '4'; when "0101" => ASCII(offset) := '5'; when "0110" => ASCII(offset) := '6'; when "0111" => ASCII(offset) := '7'; when "1000" => ASCII(offset) := '8'; when "1001" => ASCII(offset) := '9'; when "1010" => ASCII(offset) := 'A'; when "1011" => ASCII(offset) := 'B'; when "1100" => ASCII(offset) := 'C'; when "1101" => ASCII(offset) := 'D'; when "1110" => ASCII(offset) := 'E'; when "1111" => ASCII(offset) := 'F'; when others => ASCII(offset) := '?'; end case; end loop; return ASCII; end function; end ASCII_functions; --------------010900080100040806070409 Content-Type: text/plain; name="ASCII_constants.vhd" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="ASCII_constants.vhd" -- -- ***Author*** -- Jan De Ceuster -- -- *** File *** -- ASCII_constants.vhd -- -- *** Entity *** -- -- *** Port list *** -- -- *** Description *** -- -- *** History *** -- library ieee; use ieee.std_logic_1164.all; package ASCII_constants is -- TAPState constants, used for synthesis purposes constant C_ASCII_nul : std_logic_vector(6 downto 0) := "0000000"; constant C_ASCII_soh : std_logic_vector(6 downto 0) := "0000001"; constant C_ASCII_stx : std_logic_vector(6 downto 0) := "0000010"; constant C_ASCII_etx : std_logic_vector(6 downto 0) := "0000011"; constant C_ASCII_eot : std_logic_vector(6 downto 0) := "0000100"; constant C_ASCII_enq : std_logic_vector(6 downto 0) := "0000101"; constant C_ASCII_ack : std_logic_vector(6 downto 0) := "0000110"; constant C_ASCII_bel : std_logic_vector(6 downto 0) := "0000111"; constant C_ASCII_bs : std_logic_vector(6 downto 0) := "0001000"; constant C_ASCII_ht : std_logic_vector(6 downto 0) := "0001001"; constant C_ASCII_lf : std_logic_vector(6 downto 0) := "0001010"; constant C_ASCII_vt : std_logic_vector(6 downto 0) := "0001011"; constant C_ASCII_np : std_logic_vector(6 downto 0) := "0001100"; constant C_ASCII_cr : std_logic_vector(6 downto 0) := "0001101"; constant C_ASCII_so : std_logic_vector(6 downto 0) := "0001110"; constant C_ASCII_si : std_logic_vector(6 downto 0) := "0001111"; constant C_ASCII_dle : std_logic_vector(6 downto 0) := "0010000"; constant C_ASCII_dc1 : std_logic_vector(6 downto 0) := "0010001"; constant C_ASCII_dc2 : std_logic_vector(6 downto 0) := "0010010"; constant C_ASCII_dc3 : std_logic_vector(6 downto 0) := "0010011"; constant C_ASCII_dc4 : std_logic_vector(6 downto 0) := "0010100"; constant C_ASCII_nak : std_logic_vector(6 downto 0) := "0010101"; constant C_ASCII_syn : std_logic_vector(6 downto 0) := "0010110"; constant C_ASCII_etb : std_logic_vector(6 downto 0) := "0010111"; constant C_ASCII_can : std_logic_vector(6 downto 0) := "0011000"; constant C_ASCII_em : std_logic_vector(6 downto 0) := "0011001"; constant C_ASCII_sub : std_logic_vector(6 downto 0) := "0011010"; constant C_ASCII_esc : std_logic_vector(6 downto 0) := "0011011"; constant C_ASCII_fs : std_logic_vector(6 downto 0) := "0011100"; constant C_ASCII_gs : std_logic_vector(6 downto 0) := "0011101"; constant C_ASCII_rs : std_logic_vector(6 downto 0) := "0011110"; constant C_ASCII_us : std_logic_vector(6 downto 0) := "0011111"; constant C_ASCII_sp : std_logic_vector(6 downto 0) := "0100000"; constant C_ASCII_exclamationmark : std_logic_vector(6 downto 0) := "0100001"; constant C_ASCII_quotationmark : std_logic_vector(6 downto 0) := "0100010"; constant C_ASCII_number : std_logic_vector(6 downto 0) := "0100011"; constant C_ASCII_dollar : std_logic_vector(6 downto 0) := "0100100"; constant C_ASCII_percent : std_logic_vector(6 downto 0) := "0100101"; constant C_ASCII_ampersand : std_logic_vector(6 downto 0) := "0100110"; constant C_ASCII_apstrophe : std_logic_vector(6 downto 0) := "0100111"; constant C_ASCII_lparenthesis : std_logic_vector(6 downto 0) := "0101000"; constant C_ASCII_rparenthesis : std_logic_vector(6 downto 0) := "0101001"; constant C_ASCII_astrix : std_logic_vector(6 downto 0) := "0101010"; constant C_ASCII_plus : std_logic_vector(6 downto 0) := "0101011"; constant C_ASCII_comma : std_logic_vector(6 downto 0) := "0101100"; constant C_ASCII_minus : std_logic_vector(6 downto 0) := "0101101"; constant C_ASCII_fullstop : std_logic_vector(6 downto 0) := "0101110"; constant C_ASCII_slash : std_logic_vector(6 downto 0) := "0101111"; constant C_ASCII_0 : std_logic_vector(6 downto 0) := "0110000"; constant C_ASCII_1 : std_logic_vector(6 downto 0) := "0110001"; constant C_ASCII_2 : std_logic_vector(6 downto 0) := "0110010"; constant C_ASCII_3 : std_logic_vector(6 downto 0) := "0110011"; constant C_ASCII_4 : std_logic_vector(6 downto 0) := "0110100"; constant C_ASCII_5 : std_logic_vector(6 downto 0) := "0110101"; constant C_ASCII_6 : std_logic_vector(6 downto 0) := "0110110"; constant C_ASCII_7 : std_logic_vector(6 downto 0) := "0110111"; constant C_ASCII_8 : std_logic_vector(6 downto 0) := "0111000"; constant C_ASCII_9 : std_logic_vector(6 downto 0) := "0111001"; constant C_ASCII_colon : std_logic_vector(6 downto 0) := "0111010"; constant C_ASCII_semicolon : std_logic_vector(6 downto 0) := "0111011"; constant C_ASCII_lessthan : std_logic_vector(6 downto 0) := "0111100"; constant C_ASCII_equal : std_logic_vector(6 downto 0) := "0111101"; constant C_ASCII_greaterthan : std_logic_vector(6 downto 0) := "0111110"; constant C_ASCII_questionmark : std_logic_vector(6 downto 0) := "0111111"; constant C_ASCII_at : std_logic_vector(6 downto 0) := "1000000"; constant C_ASCII_CAPITAL_A : std_logic_vector(6 downto 0) := "1000001"; constant C_ASCII_CAPITAL_B : std_logic_vector(6 downto 0) := "1000010"; constant C_ASCII_CAPITAL_C : std_logic_vector(6 downto 0) := "1000011"; constant C_ASCII_CAPITAL_D : std_logic_vector(6 downto 0) := "1000100"; constant C_ASCII_CAPITAL_E : std_logic_vector(6 downto 0) := "1000101"; constant C_ASCII_CAPITAL_F : std_logic_vector(6 downto 0) := "1000110"; constant C_ASCII_CAPITAL_G : std_logic_vector(6 downto 0) := "1000111"; constant C_ASCII_CAPITAL_H : std_logic_vector(6 downto 0) := "1001000"; constant C_ASCII_CAPITAL_I : std_logic_vector(6 downto 0) := "1001001"; constant C_ASCII_CAPITAL_J : std_logic_vector(6 downto 0) := "1001010"; constant C_ASCII_CAPITAL_K : std_logic_vector(6 downto 0) := "1001011"; constant C_ASCII_CAPITAL_L : std_logic_vector(6 downto 0) := "1001100"; constant C_ASCII_CAPITAL_M : std_logic_vector(6 downto 0) := "1001101"; constant C_ASCII_CAPITAL_N : std_logic_vector(6 downto 0) := "1001110"; constant C_ASCII_CAPITAL_O : std_logic_vector(6 downto 0) := "1001111"; constant C_ASCII_CAPITAL_P : std_logic_vector(6 downto 0) := "1010000"; constant C_ASCII_CAPITAL_Q : std_logic_vector(6 downto 0) := "1010001"; constant C_ASCII_CAPITAL_R : std_logic_vector(6 downto 0) := "1010010"; constant C_ASCII_CAPITAL_S : std_logic_vector(6 downto 0) := "1010011"; constant C_ASCII_CAPITAL_T : std_logic_vector(6 downto 0) := "1010100"; constant C_ASCII_CAPITAL_U : std_logic_vector(6 downto 0) := "1010101"; constant C_ASCII_CAPITAL_V : std_logic_vector(6 downto 0) := "1010110"; constant C_ASCII_CAPITAL_W : std_logic_vector(6 downto 0) := "1010111"; constant C_ASCII_CAPITAL_X : std_logic_vector(6 downto 0) := "1011000"; constant C_ASCII_CAPITAL_Y : std_logic_vector(6 downto 0) := "1011001"; constant C_ASCII_CAPITAL_Z : std_logic_vector(6 downto 0) := "1011010"; constant C_ASCII_lsquarebracket : std_logic_vector(6 downto 0) := "1011011"; constant C_ASCII_backslash : std_logic_vector(6 downto 0) := "1011100"; constant C_ASCII_rsquarebracket : std_logic_vector(6 downto 0) := "1011101"; constant C_ASCII_circumflex : std_logic_vector(6 downto 0) := "1011110"; constant C_ASCII_underscore : std_logic_vector(6 downto 0) := "1011111"; constant C_ASCII_grave : std_logic_vector(6 downto 0) := "1100000"; constant C_ASCII_a : std_logic_vector(6 downto 0) := "1100001"; constant C_ASCII_b : std_logic_vector(6 downto 0) := "1100010"; constant C_ASCII_c : std_logic_vector(6 downto 0) := "1100011"; constant C_ASCII_d : std_logic_vector(6 downto 0) := "1100100"; constant C_ASCII_e : std_logic_vector(6 downto 0) := "1100101"; constant C_ASCII_f : std_logic_vector(6 downto 0) := "1100110"; constant C_ASCII_g : std_logic_vector(6 downto 0) := "1100111"; constant C_ASCII_h : std_logic_vector(6 downto 0) := "1101000"; constant C_ASCII_i : std_logic_vector(6 downto 0) := "1101001"; constant C_ASCII_j : std_logic_vector(6 downto 0) := "1101010"; constant C_ASCII_k : std_logic_vector(6 downto 0) := "1101011"; constant C_ASCII_l : std_logic_vector(6 downto 0) := "1101100"; constant C_ASCII_m : std_logic_vector(6 downto 0) := "1101101"; constant C_ASCII_n : std_logic_vector(6 downto 0) := "1101110"; constant C_ASCII_o : std_logic_vector(6 downto 0) := "1101111"; constant C_ASCII_p : std_logic_vector(6 downto 0) := "1110000"; constant C_ASCII_q : std_logic_vector(6 downto 0) := "1110001"; constant C_ASCII_r : std_logic_vector(6 downto 0) := "1110010"; constant C_ASCII_s : std_logic_vector(6 downto 0) := "1110011"; constant C_ASCII_t : std_logic_vector(6 downto 0) := "1110100"; constant C_ASCII_u : std_logic_vector(6 downto 0) := "1110101"; constant C_ASCII_v : std_logic_vector(6 downto 0) := "1110110"; constant C_ASCII_w : std_logic_vector(6 downto 0) := "1110111"; constant C_ASCII_x : std_logic_vector(6 downto 0) := "1111000"; constant C_ASCII_y : std_logic_vector(6 downto 0) := "1111001"; constant C_ASCII_z : std_logic_vector(6 downto 0) := "1111010"; constant C_ASCII_lcurlybracket : std_logic_vector(6 downto 0) := "1111011"; constant C_ASCII_verticalbar : std_logic_vector(6 downto 0) := "1111100"; constant C_ASCII_rcurlybracket : std_logic_vector(6 downto 0) := "1111101"; constant C_ASCII_tilde : std_logic_vector(6 downto 0) := "1111110"; constant C_ASCII_del : std_logic_vector(6 downto 0) := "1111111"; constant C_ASCII_0x0 : std_logic_vector(4 downto 0) := "10000"; constant C_ASCII_0x1 : std_logic_vector(4 downto 0) := "10001"; constant C_ASCII_0x2 : std_logic_vector(4 downto 0) := "10010"; constant C_ASCII_0x3 : std_logic_vector(4 downto 0) := "10011"; constant C_ASCII_0x4 : std_logic_vector(4 downto 0) := "10100"; constant C_ASCII_0x5 : std_logic_vector(4 downto 0) := "10101"; constant C_ASCII_0x6 : std_logic_vector(4 downto 0) := "10110"; constant C_ASCII_0x7 : std_logic_vector(4 downto 0) := "10111"; constant C_ASCII_0x8 : std_logic_vector(4 downto 0) := "11000"; constant C_ASCII_0x9 : std_logic_vector(4 downto 0) := "11001"; constant C_ASCII_0xA : std_logic_vector(4 downto 0) := "00001"; constant C_ASCII_0xB : std_logic_vector(4 downto 0) := "00010"; constant C_ASCII_0xC : std_logic_vector(4 downto 0) := "00011"; constant C_ASCII_0xD : std_logic_vector(4 downto 0) := "00100"; constant C_ASCII_0xE : std_logic_vector(4 downto 0) := "00101"; constant C_ASCII_0xF : std_logic_vector(4 downto 0) := "00110"; end ASCII_constants; package body ASCII_constants is end ASCII_constants; --------------010900080100040806070409 Content-Type: text/plain; name="EIA232_RX_bridge.vhd" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="EIA232_RX_bridge.vhd" -- -- ***Author*** -- Jan De Ceuster -- -- *** File *** -- EIA232_RX_bridge.vhd -- -- *** Entity *** -- EIA232_RX_bridge -- -- *** Port list *** -- nrst (in, 1) Active low reset -- clk (in, 1) System Clock -- -- EIA232_RXD (out, 1) EIA232 Transmit Serial Data to PC -- EIA232_RTS (in, 1) EIA232 Stop Sending -- -- ParallelOUT_Data (in, 8) ParallelOUT sends the data to EIA232 interface. -- ParallelOUT_Ack (out, 1) protocol: synchronous Full Handshake, device is slave -- ParallelOUT_Req (in, 1) -- -- *** Description *** -- This block will translate the parallel data from a generic interface to -- a serial output according the EIA232 standard with RXD and RTS. -- The size of the parallel data (generic paramter DATA_SIZE) can be anything -- from 5 to 8. This is also as specified in the EIA232 standard. -- One start and stopbit is provided. -- The generic parameter CLK_DIV is used to set the correct baudrate: -- baudrate = inputfreq/CLK_DIV -- -- *** History *** -- 001 27-06-2003 Initial version -- Fully tested and optimized library ieee; use ieee.std_logic_1164.all, ieee.std_logic_arith.all; library buffers; use buffers.shift_registers.all; entity EIA232_RX_bridge is generic ( DATA_SIZE : in integer := 8; -- size can be anything from 5 to 8 CLK_FREQ : in integer := 33000000; -- clock frequency in Hz BAUDRATE : in integer := 115200 ); port ( nrst : in std_logic; clk : in std_logic; EIA232_RXD : out std_logic; EIA232_RTS : in std_logic; ParallelOUT_Data : in std_logic_vector(DATA_SIZE-1 downto 0); ParallelOUT_Req : in std_logic; ParallelOUT_Ack : out std_logic ); end EIA232_RX_bridge; architecture RTL of EIA232_RX_bridge is constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1; signal timecounter : integer range 0 to TIMECOUNTER_SIZE; signal bitcounter : integer range 0 to DATA_SIZE; signal EIA232ShiftRegister : std_logic_vector(1 to DATA_SIZE); signal EIA232State, nextEIA232State : EIA232State_type; signal StartSending : std_logic; signal timecounter_pulse : std_logic; signal sync_EIA232_RTS : std_logic_vector(3 downto 1); begin -- The EIA232State statemachine controls the correct flow for the start, data -- and stop bit(s). process (EIA232State, StartSending, bitcounter) begin nextEIA232State <= EIA232State; case EIA232State is when E_EIA232State_Waiting => -- Req for sending data received. if StartSending = '1' then nextEIA232State <= E_EIA232State_Start; end if; when E_EIA232State_Start => nextEIA232State <= E_EIA232State_Data; when E_EIA232State_Data => -- Last databit send. if bitcounter = DATA_SIZE and StartSending = '0' then nextEIA232State <= E_EIA232State_Waiting; end if; when others => nextEIA232State <= (others => '-'); end case; end process; -- Generate a pulse when timecounter is 0. timecounter_pulse <= '1' when timecounter = 0 else '0'; -- Sample the inputsignal from physical EIA232 interface into a flipflop. process (clk) begin if rising_edge(clk) then ShiftL2H_p(EIA232_RTS,sync_EIA232_RTS); end if; end process; process (clk,nrst) begin if nrst = '0' then timecounter <= TIMECOUNTER_SIZE; ParallelOUT_Ack <= '0'; StartSending <= '0'; EIA232ShiftRegister <= (others => '1'); elsif rising_edge(clk) then ParallelOUT_Ack <= '0'; -- Counter to devide the clk input. if timecounter_pulse = '1' then timecounter <= TIMECOUNTER_SIZE; else timecounter <= timecounter - 1; end if; case EIA232State is when E_EIA232State_Waiting => -- Req received and ready to transmit data. if StartSending = '0' and ParallelOUT_Req = '1' and sync_EIA232_RTS(sync_EIA232_RTS'high) = '0' then -- Load the shiftregister EIA232ShiftRegister(1 to DATA_SIZE) <= ParallelOUT_Data; ParallelOUT_Ack <= '1'; StartSending <= '1'; end if; when E_EIA232State_Start | E_EIA232State_Data => StartSending <= '0'; -- The shiftregister can shift every timecounter_pulse. -- This register runs on clk because it must be possible to load -- external data assynchronous to timecounter_pulse. if timecounter_pulse = '1' then ShiftL2H_p('1',EIA232ShiftRegister); end if; when others => StartSending <= '0'; end case; end if; end process; process (clk,nrst) begin if nrst = '0' then EIA232_RXD <= '1'; EIA232State <= E_EIA232State_Waiting; bitcounter <= 0; elsif rising_edge(clk) then if timecounter_pulse = '1' then EIA232State <= nextEIA232State; case nextEIA232State is when E_EIA232State_Waiting => EIA232_RXD <= '1'; when E_EIA232State_Start => EIA232_RXD <= '0'; when E_EIA232State_Data => EIA232_RXD <= EIA232ShiftRegister(DATA_SIZE); if bitcounter = DATA_SIZE then bitcounter <= 0; else bitcounter <= bitcounter + 1; end if; when others => end case; end if; end if; end process; end RTL; --------------010900080100040806070409 Content-Type: text/plain; name="EIA232_TX_bridge.vhd" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="EIA232_TX_bridge.vhd" -- -- ***Author*** -- Jan De Ceuster -- -- *** File *** -- EIA232_TX_bridge.vhd -- -- *** Entity *** -- EIA232_TX_bridge -- -- *** Port list *** -- nrst (in, 1) Active low reset -- clk (in, 1) System Clock -- -- EIA232_TXD (in, 1) EIA232 Receive Serial Data from PC -- EIA232_CTS (out, 1) EIA232 Stop Receiving -- -- ParallelIN_Data (out, 8) ParallelIN sends the data from EIA232 interface. -- ParallelIN_Ack (out, 1) protocol: synchronous Full Handshake, device -- ParallelIN_Req (in, 1) is slave. library ieee; use ieee.std_logic_1164.all, ieee.std_logic_arith.all; library buffers; use buffers.shift_registers.all; entity EIA232_TX_bridge is generic ( DATA_SIZE : in integer := 8; CLK_FREQ : in integer := 33000000; -- clock frequency in Hz BAUDRATE : in integer := 115200 ); port ( nrst : in std_logic; clk : in std_logic; EIA232_TXD : in std_logic; EIA232_CTS : out std_logic; ParallelIN_Data : out std_logic_vector(DATA_SIZE-1 downto 0); ParallelIN_Req : in std_logic; ParallelIN_Ack : out std_logic ); end EIA232_TX_bridge; architecture RTL of EIA232_TX_bridge is constant BITCOUNTER_SIZE : integer := DATA_SIZE - 1; constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1; constant HALF_TIMECOUNTER_SIZE : integer := TIMECOUNTER_SIZE/2 - 1; signal timecounter : integer range 0 to TIMECOUNTER_SIZE; signal bitcounter : integer range 0 to DATA_SIZE-1; signal ParallelIN_Data_reg : std_logic_vector(1 to DATA_SIZE); signal EIA232State, nextEIA232State : EIA232State_type; signal timecounter_pulse : std_logic; signal StartReceive : std_logic; signal sync_EIA232_TXD : std_logic_vector(2 downto 1); signal faling_edge_EIA232_TXD : boolean; signal buffer_empty : boolean; begin process (EIA232State, StartReceive, bitcounter) begin nextEIA232State <= EIA232State; case EIA232State is when E_EIA232State_Waiting => if StartReceive = '1' then nextEIA232State <= E_EIA232State_Start; end if; when E_EIA232State_Start => nextEIA232State <= E_EIA232State_Data; when E_EIA232State_Data => if bitcounter = 0 then nextEIA232State <= E_EIA232State_Stop; end if; when E_EIA232State_Stop => nextEIA232State <= E_EIA232State_Waiting; when others => nextEIA232State <= (others => '-'); end case; end process; -- sample signal into flipflops process (clk) begin if rising_edge(clk) then ShiftL2H_p(EIA232_TXD,sync_EIA232_TXD); end if; end process; faling_edge_EIA232_TXD <= sync_EIA232_TXD(sync_EIA232_TXD'high-1) = '0' and sync_EIA232_TXD(sync_EIA232_TXD'high) = '1'; timecounter_pulse <= '1' when timecounter = 0 else '0'; process (clk, nrst) begin if nrst = '0' then timecounter <= TIMECOUNTER_SIZE; StartReceive <= '0'; elsif rising_edge(clk) then -- endless timer with conditional preload (when detecting a startbit) -- StartReceive indicates the detection of the startbit if faling_edge_EIA232_TXD -- faling edge TXD, and nextEIA232State = E_EIA232State_Waiting then -- detect start bit timecounter <= HALF_TIMECOUNTER_SIZE; StartReceive <= '1'; elsif timecounter = 0 then -- counter reset timecounter <= TIMECOUNTER_SIZE; StartReceive <= '0'; else timecounter <= timecounter - 1; -- count down end if; end if; end process; process (clk, nrst) begin if nrst = '0' then EIA232State <= E_EIA232State_Waiting; ParallelIN_Data_reg <= (others => '-'); bitcounter <= BITCOUNTER_SIZE; elsif rising_edge(clk) then if timecounter_pulse = '1' then EIA232State <= nextEIA232State; bitcounter <= BITCOUNTER_SIZE; -- shift register ShiftL2H_p(sync_EIA232_TXD(sync_EIA232_TXD'high),ParallelIN_Data_reg); if EIA232State = E_EIA232State_Start or EIA232State = E_EIA232State_Data then -- counter for the shiftregister if bitcounter = 0 then bitcounter <= BITCOUNTER_SIZE; else bitcounter <= bitcounter - 1; end if; end if; end if; end if; end process; process (clk, nrst) begin if nrst = '0' then buffer_empty <= TRUE; EIA232_CTS <= '1'; ParallelIN_Ack <= '0'; elsif rising_edge(clk) then if buffer_empty then EIA232_CTS <= '0'; else EIA232_CTS <= '1'; end if; if EIA232State = E_EIA232State_Data then buffer_empty <= FALSE; end if; -- Output the shiftregister directly. if timecounter_pulse = '1' and EIA232State = E_EIA232State_Stop then ParallelIN_Data <= ParallelIN_Data_reg; end if; -- The shiftregister now contains the received byte. -- => give an ack for 1 clock cycle (done with timecounter_pulse) if ParallelIN_REQ = '1' and not buffer_empty and EIA232State = E_EIA232State_Waiting then ParallelIN_Ack <= '1'; buffer_empty <= TRUE; else ParallelIN_Ack <= '0'; end if; end if; end process; end RTL; --------------010900080100040806070409 Content-Type: text/plain; name="EIA232_package.vhd" Content-Transfer-Encoding: 7bit Content-Disposition: inline; filename="EIA232_package.vhd" -- -- ***Author*** -- Jan De Ceuster -- -- *** File *** -- EIA232_constants.vhd -- -- *** Entity *** -- -- *** Port list *** -- -- *** Description *** -- -- *** History *** -- library ieee; use ieee.std_logic_1164.all; package EIA232 is -- constants -- enumerations type EIA232State_type is (E_EIA232State_Waiting, E_EIA232State_Start, E_EIA232State_Data, E_EIA232State_Stop); -- functions -- procedures -- components component EIA232_TX_bridge -- receive data via a FullHndshk protocol -- bridge is master on EIA232 lines generic ( DATA_SIZE : in integer := 8; -- size can be anything from 5 to 8 CLK_FREQ : in integer := 33000000; -- clock frequency in Hz BAUDRATE : in integer := 115200 ); port ( nrst : in std_logic; clk : in std_logic; EIA232_TXD : in std_logic; EIA232_CTS : out std_logic; ParallelIN_Data : out std_logic_vector(DATA_SIZE-1 downto 0); ParallelIN_Req : in std_logic; ParallelIN_Ack : out std_logic ); end component; component EIA232_RX_bridge -- send data via a FullHndshk protocol -- bridge is master on EIA232 lines generic ( DATA_SIZE : in integer := 8; -- size can be anything from 5 to 8 CLK_FREQ : in integer := 33000000; -- clock frequency in Hz BAUDRATE : in integer := 115200 ); port ( nrst : in std_logic; clk : in std_logic; EIA232_RXD : out std_logic; EIA232_RTS : in std_logic; ParallelOUT_Data : in std_logic_vector(DATA_SIZE-1 downto 0); ParallelOUT_Req : in std_logic; ParallelOUT_Ack : out std_logic ); end component; end EIA232; package body EIA232 is end EIA232; --------------010900080100040806070409--
damn, posted on the newsgroups instead of private message...
oh well, it's free anyway but these versions are quite buggy. There goes my 
reputation... :D

Jan De Ceuster wrote:
> Hi, > > in the attachement you'll find something you could use. I've used it on > a cyclone to do some ASCII communication (giving commands and > sending/receiving data to/from the system). I'm just in the middle of > updating the things so it's possible you have to mess around with some > libs (or change the libs to 'work'). > > I've added some functions to convert a 4 bit hex 'string' into a 7 bit > char 'string. > > kind regards, > Jan > > > Konstantin Dols wrote: > >> >> >> Greetings ! >> >> I'm looking for a simple RS232 UART16550 receiver for my tiny cyclone >> board >> for different baudrates, 8databits, 1stop&startbit and no(!) partity >> and handshake stuff. >> >> I found several free VHDL implementations in the net but compared to >> what I need >> they are to complicated and appear like shooting with missiles on >> birds ;-) >> >> >> >> The entity might have a simple structure like this: >> >> entity receiver is >> generic( frequency : integer := 10000000; -- e.g. for 10MHz >> baudrate : integer := 9600 -- e.g. for 9600bps >> ); >> >> port( clk : in std_logic; -- clockspeed is 'frequency' >> reset : in std_logic; -- resets the receiver >> receiver : in std_logic; -- input from receive pin from >> RS232 connector >> >> char_avail : out std_logic; -- indicated that a valid >> char has beed received >> char : out std_logic_vector(7 downto 0) -- received >> char, only available for one clock >> ); >> end receiver; >> >> The 'reciever' values are 'active high'... >> >> This structure gives the responsibility for catching received data in >> time to the user >> but surely allowes adding a FIFO. >> >> >> Probably this question has been asked about 47283407239 times in this >> group >> so please just send me a usefull link or code snippet... >> >> >> Konstantin >> > > ------------------------------------------------------------------------ > > -- > -- ***Author*** > -- Jan De Ceuster > -- > -- *** File *** > -- Buffer_procedures.vhd > -- > -- *** Procedures *** > -- > -- *** Functions *** > -- > -- *** Description *** > -- > -- *** History *** > -- 001 initial > > library ieee; > use ieee.std_logic_1164.all; > > package Buffer_procedures is > procedure ShiftL2H_p(input : in std_logic; > shiftvector_in : in std_logic_vector; > signal shiftvector_out : out std_logic_vector); > procedure ShiftL2H_p(input : in std_logic; > signal shiftvector : inout std_logic_vector); > > function ShiftL2H_f(input : in std_logic; > shiftvector_in : in std_logic_vector) > return std_logic_vector; > end package; > > package body Buffer_procedures is > procedure ShiftL2H_p(input : in std_logic; > shiftvector_in : in std_logic_vector; > signal shiftvector_out : out std_logic_vector) is > begin > shiftvector_out(shiftvector_out'low) <= input; > -- always shift from low towards high > if shiftvector_out'high = shiftvector_out'right then > shiftvector_out(shiftvector_out'low+1 to shiftvector_out'high) > <= shiftvector_in(shiftvector_in'low to shiftvector_in'high-1); > else > shiftvector_out(shiftvector_out'high downto shiftvector_out'low+1) > <= shiftvector_in(shiftvector_in'high-1 downto shiftvector_in'low); > end if; > end procedure; > > procedure ShiftL2H_p(input : in std_logic; > signal shiftvector : inout std_logic_vector) is > begin > shiftvector(shiftvector'low) <= input; > if shiftvector'high = shiftvector'right then > shiftvector(shiftvector'low+1 to shiftvector'high) > <= shiftvector(shiftvector'low to shiftvector'high-1); > else > shiftvector(shiftvector'high downto shiftvector'low+1) > <= shiftvector(shiftvector'high-1 downto shiftvector'low); > end if; > end procedure; > > function ShiftL2H_f(input : in std_logic; > shiftvector_in : in std_logic_vector) > return std_logic_vector is > variable shiftvector_out : std_logic_vector(shiftvector_in'range); > begin > shiftvector_out(shiftvector_in'low) := input; > -- always shift from low towards high > if shiftvector_in'high = shiftvector_in'right then > shiftvector_out(shiftvector_in'low+1 to shiftvector_in'high) > := shiftvector_in(shiftvector_in'low to shiftvector_in'high-1); > else > shiftvector_out(shiftvector_in'high downto shiftvector_in'low+1) > := shiftvector_in(shiftvector_in'high-1 downto shiftvector_in'low); > end if; > return shiftvector_out; > end function; > end Buffer_procedures; > > > ------------------------------------------------------------------------ > > -- > -- ***Author*** > -- Jan De Ceuster > -- > -- *** File *** > -- ASCII_functions.vhd > -- > -- *** Functions *** > -- ASCII2HEX_f > -- input : std_logic_vector of size n*7 > -- return : std_logic_vector of size n*4 (n*4-1 downto 0) > -- > -- HEX2ASCII_f > -- input : std_logic_vector of size n*4 > -- return : std_logic_vector of size n*7 (n*7-1 downto 0) > -- > -- HEX2ASCII_f > -- input : std_logic_vector of size n*4 > -- return : string of size n (1 to n) > -- > -- *** Description *** > -- > -- *** History *** > -- 001 initial > > library ieee; > use ieee.std_logic_1164.all; > > library nicethings; > use nicethings.ASCII_constants.all; > > package ASCII_functions is > function ASCII2HEX_f(ASCII : std_logic_vector) > return std_logic_vector; > function ASCII2HEX_f(ASCII : std_logic_vector; size : integer) > return std_logic_vector; > function HEX2ASCII_f(HEX : std_logic_vector) > return std_logic_vector; > function HEX2ASCII_f(HEX : std_logic_vector; size : integer) > return std_logic_vector; > function HEX2ASCII_f(HEX : std_logic_vector) > return string; > end package; > > package body ASCII_functions is > function ASCII2HEX_f(ASCII : std_logic_vector) > return std_logic_vector is > begin > return ASCII2HEX_f(ASCII,7); > end function; > > function ASCII2HEX_f(ASCII : std_logic_vector; size : integer) > return std_logic_vector is > constant length : integer := (ASCII'high - ASCII'low + 1)/7; > variable HEXoffset, ASCIIoffset : integer; > variable HEX : std_logic_vector(length*4-1 downto 0); > variable temp : std_logic_vector(4 downto 0); > begin > for count in length-1 downto 0 loop > HEXoffset := count*4; > ASCIIoffset := count*size; > temp := ASCII(ASCIIoffset+4+ASCII'low downto ASCIIoffset+ASCII'low); > case temp is > when C_ASCII_0x0 => HEX(HEXoffset+3 downto HEXoffset) := "0000"; > when C_ASCII_0x1 => HEX(HEXoffset+3 downto HEXoffset) := "0001"; > when C_ASCII_0x2 => HEX(HEXoffset+3 downto HEXoffset) := "0010"; > when C_ASCII_0x3 => HEX(HEXoffset+3 downto HEXoffset) := "0011"; > when C_ASCII_0x4 => HEX(HEXoffset+3 downto HEXoffset) := "0100"; > when C_ASCII_0x5 => HEX(HEXoffset+3 downto HEXoffset) := "0101"; > when C_ASCII_0x6 => HEX(HEXoffset+3 downto HEXoffset) := "0110"; > when C_ASCII_0x7 => HEX(HEXoffset+3 downto HEXoffset) := "0111"; > when C_ASCII_0x8 => HEX(HEXoffset+3 downto HEXoffset) := "1000"; > when C_ASCII_0x9 => HEX(HEXoffset+3 downto HEXoffset) := "1001"; > when C_ASCII_0xA => HEX(HEXoffset+3 downto HEXoffset) := "1010"; > when C_ASCII_0xB => HEX(HEXoffset+3 downto HEXoffset) := "1011"; > when C_ASCII_0xC => HEX(HEXoffset+3 downto HEXoffset) := "1100"; > when C_ASCII_0xD => HEX(HEXoffset+3 downto HEXoffset) := "1101"; > when C_ASCII_0xE => HEX(HEXoffset+3 downto HEXoffset) := "1110"; > when C_ASCII_0xF => HEX(HEXoffset+3 downto HEXoffset) := "1111"; > when others => HEX(HEXoffset+3 downto HEXoffset) := "----"; > end case; > end loop; > return HEX; > end function; > > function HEX2ASCII_f(HEX : std_logic_vector) > return std_logic_vector is > begin > return HEX2ASCII_f(HEX,7); > end function; > > function HEX2ASCII_f(HEX : std_logic_vector; size : integer) > return std_logic_vector is > constant length : integer := (HEX'high - HEX'low + 1)/4; > variable ASCII : std_logic_vector(length*7-1 downto 0) := (others => '0'); > variable ASCIIoffset, HEXoffset : integer; > variable temp : std_logic_vector(3 downto 0); > begin > for count in length-1 downto 0 loop > ASCIIoffset := count*size; > HEXoffset := count*4; > temp := HEX(HEXoffset+3+HEX'low downto HEXoffset+HEX'low); > case temp is > when "0000" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_0; > when "0001" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_1; > when "0010" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_2; > when "0011" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_3; > when "0100" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_4; > when "0101" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_5; > when "0110" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_6; > when "0111" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_7; > when "1000" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_8; > when "1001" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_9; > when "1010" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_A; > when "1011" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_B; > when "1100" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_C; > when "1101" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_D; > when "1110" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_E; > when "1111" => ASCII(ASCIIoffset+6 downto ASCIIoffset) := C_ASCII_CAPITAL_F; > when others => ASCII(ASCIIoffset+6 downto ASCIIoffset) := "-------"; > end case; > end loop; > return ASCII; > end function; > > function HEX2ASCII_f(HEX : std_logic_vector) > return string is > constant size : integer := HEX'high - HEX'low + 1; > variable ASCII : string(1 to size/4); > variable offset,offset2 : integer; > variable temp : std_logic_vector(3 downto 0); > begin > for count in size/4-1 downto 0 loop > offset := size/4-count; > offset2 := count*4; > temp := HEX(offset2+3+HEX'low downto offset2+HEX'low); > case temp is > when "0000" => ASCII(offset) := '0'; > when "0001" => ASCII(offset) := '1'; > when "0010" => ASCII(offset) := '2'; > when "0011" => ASCII(offset) := '3'; > when "0100" => ASCII(offset) := '4'; > when "0101" => ASCII(offset) := '5'; > when "0110" => ASCII(offset) := '6'; > when "0111" => ASCII(offset) := '7'; > when "1000" => ASCII(offset) := '8'; > when "1001" => ASCII(offset) := '9'; > when "1010" => ASCII(offset) := 'A'; > when "1011" => ASCII(offset) := 'B'; > when "1100" => ASCII(offset) := 'C'; > when "1101" => ASCII(offset) := 'D'; > when "1110" => ASCII(offset) := 'E'; > when "1111" => ASCII(offset) := 'F'; > when others => ASCII(offset) := '?'; > end case; > end loop; > return ASCII; > end function; > end ASCII_functions; > > > ------------------------------------------------------------------------ > > -- > -- ***Author*** > -- Jan De Ceuster > -- > -- *** File *** > -- ASCII_constants.vhd > -- > -- *** Entity *** > -- > -- *** Port list *** > -- > -- *** Description *** > -- > -- *** History *** > -- > > library ieee; > use ieee.std_logic_1164.all; > > package ASCII_constants is > -- TAPState constants, used for synthesis purposes > constant C_ASCII_nul : std_logic_vector(6 downto 0) := "0000000"; > constant C_ASCII_soh : std_logic_vector(6 downto 0) := "0000001"; > constant C_ASCII_stx : std_logic_vector(6 downto 0) := "0000010"; > constant C_ASCII_etx : std_logic_vector(6 downto 0) := "0000011"; > constant C_ASCII_eot : std_logic_vector(6 downto 0) := "0000100"; > constant C_ASCII_enq : std_logic_vector(6 downto 0) := "0000101"; > constant C_ASCII_ack : std_logic_vector(6 downto 0) := "0000110"; > constant C_ASCII_bel : std_logic_vector(6 downto 0) := "0000111"; > constant C_ASCII_bs : std_logic_vector(6 downto 0) := "0001000"; > constant C_ASCII_ht : std_logic_vector(6 downto 0) := "0001001"; > constant C_ASCII_lf : std_logic_vector(6 downto 0) := "0001010"; > constant C_ASCII_vt : std_logic_vector(6 downto 0) := "0001011"; > constant C_ASCII_np : std_logic_vector(6 downto 0) := "0001100"; > constant C_ASCII_cr : std_logic_vector(6 downto 0) := "0001101"; > constant C_ASCII_so : std_logic_vector(6 downto 0) := "0001110"; > constant C_ASCII_si : std_logic_vector(6 downto 0) := "0001111"; > constant C_ASCII_dle : std_logic_vector(6 downto 0) := "0010000"; > constant C_ASCII_dc1 : std_logic_vector(6 downto 0) := "0010001"; > constant C_ASCII_dc2 : std_logic_vector(6 downto 0) := "0010010"; > constant C_ASCII_dc3 : std_logic_vector(6 downto 0) := "0010011"; > constant C_ASCII_dc4 : std_logic_vector(6 downto 0) := "0010100"; > constant C_ASCII_nak : std_logic_vector(6 downto 0) := "0010101"; > constant C_ASCII_syn : std_logic_vector(6 downto 0) := "0010110"; > constant C_ASCII_etb : std_logic_vector(6 downto 0) := "0010111"; > constant C_ASCII_can : std_logic_vector(6 downto 0) := "0011000"; > constant C_ASCII_em : std_logic_vector(6 downto 0) := "0011001"; > constant C_ASCII_sub : std_logic_vector(6 downto 0) := "0011010"; > constant C_ASCII_esc : std_logic_vector(6 downto 0) := "0011011"; > constant C_ASCII_fs : std_logic_vector(6 downto 0) := "0011100"; > constant C_ASCII_gs : std_logic_vector(6 downto 0) := "0011101"; > constant C_ASCII_rs : std_logic_vector(6 downto 0) := "0011110"; > constant C_ASCII_us : std_logic_vector(6 downto 0) := "0011111"; > constant C_ASCII_sp : std_logic_vector(6 downto 0) := "0100000"; > constant C_ASCII_exclamationmark : std_logic_vector(6 downto 0) := "0100001"; > constant C_ASCII_quotationmark : std_logic_vector(6 downto 0) := "0100010"; > constant C_ASCII_number : std_logic_vector(6 downto 0) := "0100011"; > constant C_ASCII_dollar : std_logic_vector(6 downto 0) := "0100100"; > constant C_ASCII_percent : std_logic_vector(6 downto 0) := "0100101"; > constant C_ASCII_ampersand : std_logic_vector(6 downto 0) := "0100110"; > constant C_ASCII_apstrophe : std_logic_vector(6 downto 0) := "0100111"; > constant C_ASCII_lparenthesis : std_logic_vector(6 downto 0) := "0101000"; > constant C_ASCII_rparenthesis : std_logic_vector(6 downto 0) := "0101001"; > constant C_ASCII_astrix : std_logic_vector(6 downto 0) := "0101010"; > constant C_ASCII_plus : std_logic_vector(6 downto 0) := "0101011"; > constant C_ASCII_comma : std_logic_vector(6 downto 0) := "0101100"; > constant C_ASCII_minus : std_logic_vector(6 downto 0) := "0101101"; > constant C_ASCII_fullstop : std_logic_vector(6 downto 0) := "0101110"; > constant C_ASCII_slash : std_logic_vector(6 downto 0) := "0101111"; > constant C_ASCII_0 : std_logic_vector(6 downto 0) := "0110000"; > constant C_ASCII_1 : std_logic_vector(6 downto 0) := "0110001"; > constant C_ASCII_2 : std_logic_vector(6 downto 0) := "0110010"; > constant C_ASCII_3 : std_logic_vector(6 downto 0) := "0110011"; > constant C_ASCII_4 : std_logic_vector(6 downto 0) := "0110100"; > constant C_ASCII_5 : std_logic_vector(6 downto 0) := "0110101"; > constant C_ASCII_6 : std_logic_vector(6 downto 0) := "0110110"; > constant C_ASCII_7 : std_logic_vector(6 downto 0) := "0110111"; > constant C_ASCII_8 : std_logic_vector(6 downto 0) := "0111000"; > constant C_ASCII_9 : std_logic_vector(6 downto 0) := "0111001"; > constant C_ASCII_colon : std_logic_vector(6 downto 0) := "0111010"; > constant C_ASCII_semicolon : std_logic_vector(6 downto 0) := "0111011"; > constant C_ASCII_lessthan : std_logic_vector(6 downto 0) := "0111100"; > constant C_ASCII_equal : std_logic_vector(6 downto 0) := "0111101"; > constant C_ASCII_greaterthan : std_logic_vector(6 downto 0) := "0111110"; > constant C_ASCII_questionmark : std_logic_vector(6 downto 0) := "0111111"; > constant C_ASCII_at : std_logic_vector(6 downto 0) := "1000000"; > constant C_ASCII_CAPITAL_A : std_logic_vector(6 downto 0) := "1000001"; > constant C_ASCII_CAPITAL_B : std_logic_vector(6 downto 0) := "1000010"; > constant C_ASCII_CAPITAL_C : std_logic_vector(6 downto 0) := "1000011"; > constant C_ASCII_CAPITAL_D : std_logic_vector(6 downto 0) := "1000100"; > constant C_ASCII_CAPITAL_E : std_logic_vector(6 downto 0) := "1000101"; > constant C_ASCII_CAPITAL_F : std_logic_vector(6 downto 0) := "1000110"; > constant C_ASCII_CAPITAL_G : std_logic_vector(6 downto 0) := "1000111"; > constant C_ASCII_CAPITAL_H : std_logic_vector(6 downto 0) := "1001000"; > constant C_ASCII_CAPITAL_I : std_logic_vector(6 downto 0) := "1001001"; > constant C_ASCII_CAPITAL_J : std_logic_vector(6 downto 0) := "1001010"; > constant C_ASCII_CAPITAL_K : std_logic_vector(6 downto 0) := "1001011"; > constant C_ASCII_CAPITAL_L : std_logic_vector(6 downto 0) := "1001100"; > constant C_ASCII_CAPITAL_M : std_logic_vector(6 downto 0) := "1001101"; > constant C_ASCII_CAPITAL_N : std_logic_vector(6 downto 0) := "1001110"; > constant C_ASCII_CAPITAL_O : std_logic_vector(6 downto 0) := "1001111"; > constant C_ASCII_CAPITAL_P : std_logic_vector(6 downto 0) := "1010000"; > constant C_ASCII_CAPITAL_Q : std_logic_vector(6 downto 0) := "1010001"; > constant C_ASCII_CAPITAL_R : std_logic_vector(6 downto 0) := "1010010"; > constant C_ASCII_CAPITAL_S : std_logic_vector(6 downto 0) := "1010011"; > constant C_ASCII_CAPITAL_T : std_logic_vector(6 downto 0) := "1010100"; > constant C_ASCII_CAPITAL_U : std_logic_vector(6 downto 0) := "1010101"; > constant C_ASCII_CAPITAL_V : std_logic_vector(6 downto 0) := "1010110"; > constant C_ASCII_CAPITAL_W : std_logic_vector(6 downto 0) := "1010111"; > constant C_ASCII_CAPITAL_X : std_logic_vector(6 downto 0) := "1011000"; > constant C_ASCII_CAPITAL_Y : std_logic_vector(6 downto 0) := "1011001"; > constant C_ASCII_CAPITAL_Z : std_logic_vector(6 downto 0) := "1011010"; > constant C_ASCII_lsquarebracket : std_logic_vector(6 downto 0) := "1011011"; > constant C_ASCII_backslash : std_logic_vector(6 downto 0) := "1011100"; > constant C_ASCII_rsquarebracket : std_logic_vector(6 downto 0) := "1011101"; > constant C_ASCII_circumflex : std_logic_vector(6 downto 0) := "1011110"; > constant C_ASCII_underscore : std_logic_vector(6 downto 0) := "1011111"; > constant C_ASCII_grave : std_logic_vector(6 downto 0) := "1100000"; > constant C_ASCII_a : std_logic_vector(6 downto 0) := "1100001"; > constant C_ASCII_b : std_logic_vector(6 downto 0) := "1100010"; > constant C_ASCII_c : std_logic_vector(6 downto 0) := "1100011"; > constant C_ASCII_d : std_logic_vector(6 downto 0) := "1100100"; > constant C_ASCII_e : std_logic_vector(6 downto 0) := "1100101"; > constant C_ASCII_f : std_logic_vector(6 downto 0) := "1100110"; > constant C_ASCII_g : std_logic_vector(6 downto 0) := "1100111"; > constant C_ASCII_h : std_logic_vector(6 downto 0) := "1101000"; > constant C_ASCII_i : std_logic_vector(6 downto 0) := "1101001"; > constant C_ASCII_j : std_logic_vector(6 downto 0) := "1101010"; > constant C_ASCII_k : std_logic_vector(6 downto 0) := "1101011"; > constant C_ASCII_l : std_logic_vector(6 downto 0) := "1101100"; > constant C_ASCII_m : std_logic_vector(6 downto 0) := "1101101"; > constant C_ASCII_n : std_logic_vector(6 downto 0) := "1101110"; > constant C_ASCII_o : std_logic_vector(6 downto 0) := "1101111"; > constant C_ASCII_p : std_logic_vector(6 downto 0) := "1110000"; > constant C_ASCII_q : std_logic_vector(6 downto 0) := "1110001"; > constant C_ASCII_r : std_logic_vector(6 downto 0) := "1110010"; > constant C_ASCII_s : std_logic_vector(6 downto 0) := "1110011"; > constant C_ASCII_t : std_logic_vector(6 downto 0) := "1110100"; > constant C_ASCII_u : std_logic_vector(6 downto 0) := "1110101"; > constant C_ASCII_v : std_logic_vector(6 downto 0) := "1110110"; > constant C_ASCII_w : std_logic_vector(6 downto 0) := "1110111"; > constant C_ASCII_x : std_logic_vector(6 downto 0) := "1111000"; > constant C_ASCII_y : std_logic_vector(6 downto 0) := "1111001"; > constant C_ASCII_z : std_logic_vector(6 downto 0) := "1111010"; > constant C_ASCII_lcurlybracket : std_logic_vector(6 downto 0) := "1111011"; > constant C_ASCII_verticalbar : std_logic_vector(6 downto 0) := "1111100"; > constant C_ASCII_rcurlybracket : std_logic_vector(6 downto 0) := "1111101"; > constant C_ASCII_tilde : std_logic_vector(6 downto 0) := "1111110"; > constant C_ASCII_del : std_logic_vector(6 downto 0) := "1111111"; > > constant C_ASCII_0x0 : std_logic_vector(4 downto 0) := "10000"; > constant C_ASCII_0x1 : std_logic_vector(4 downto 0) := "10001"; > constant C_ASCII_0x2 : std_logic_vector(4 downto 0) := "10010"; > constant C_ASCII_0x3 : std_logic_vector(4 downto 0) := "10011"; > constant C_ASCII_0x4 : std_logic_vector(4 downto 0) := "10100"; > constant C_ASCII_0x5 : std_logic_vector(4 downto 0) := "10101"; > constant C_ASCII_0x6 : std_logic_vector(4 downto 0) := "10110"; > constant C_ASCII_0x7 : std_logic_vector(4 downto 0) := "10111"; > constant C_ASCII_0x8 : std_logic_vector(4 downto 0) := "11000"; > constant C_ASCII_0x9 : std_logic_vector(4 downto 0) := "11001"; > constant C_ASCII_0xA : std_logic_vector(4 downto 0) := "00001"; > constant C_ASCII_0xB : std_logic_vector(4 downto 0) := "00010"; > constant C_ASCII_0xC : std_logic_vector(4 downto 0) := "00011"; > constant C_ASCII_0xD : std_logic_vector(4 downto 0) := "00100"; > constant C_ASCII_0xE : std_logic_vector(4 downto 0) := "00101"; > constant C_ASCII_0xF : std_logic_vector(4 downto 0) := "00110"; > end ASCII_constants; > > package body ASCII_constants is > end ASCII_constants; > > > ------------------------------------------------------------------------ > > -- > -- ***Author*** > -- Jan De Ceuster > -- > -- *** File *** > -- EIA232_RX_bridge.vhd > -- > -- *** Entity *** > -- EIA232_RX_bridge > -- > -- *** Port list *** > -- nrst (in, 1) Active low reset > -- clk (in, 1) System Clock > -- > -- EIA232_RXD (out, 1) EIA232 Transmit Serial Data to PC > -- EIA232_RTS (in, 1) EIA232 Stop Sending > -- > -- ParallelOUT_Data (in, 8) ParallelOUT sends the data to EIA232 interface. > -- ParallelOUT_Ack (out, 1) protocol: synchronous Full Handshake, device is slave > -- ParallelOUT_Req (in, 1) > -- > -- *** Description *** > -- This block will translate the parallel data from a generic interface to > -- a serial output according the EIA232 standard with RXD and RTS. > -- The size of the parallel data (generic paramter DATA_SIZE) can be anything > -- from 5 to 8. This is also as specified in the EIA232 standard. > -- One start and stopbit is provided. > -- The generic parameter CLK_DIV is used to set the correct baudrate: > -- baudrate = inputfreq/CLK_DIV > -- > -- *** History *** > -- 001 27-06-2003 Initial version > -- Fully tested and optimized > > library ieee; > use ieee.std_logic_1164.all, ieee.std_logic_arith.all; > > library buffers; > use buffers.shift_registers.all; > > entity EIA232_RX_bridge is > generic ( > DATA_SIZE : in integer := 8; -- size can be anything from 5 to 8 > CLK_FREQ : in integer := 33000000; -- clock frequency in Hz > BAUDRATE : in integer := 115200 > ); > > port ( > nrst : in std_logic; > clk : in std_logic; > > EIA232_RXD : out std_logic; > EIA232_RTS : in std_logic; > > ParallelOUT_Data : in std_logic_vector(DATA_SIZE-1 downto 0); > ParallelOUT_Req : in std_logic; > ParallelOUT_Ack : out std_logic > ); > end EIA232_RX_bridge; > > architecture RTL of EIA232_RX_bridge is > constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1; > > signal timecounter : integer range 0 to TIMECOUNTER_SIZE; > signal bitcounter : integer range 0 to DATA_SIZE; > signal EIA232ShiftRegister : std_logic_vector(1 to DATA_SIZE); > signal EIA232State, nextEIA232State : EIA232State_type; > signal StartSending : std_logic; > signal timecounter_pulse : std_logic; > signal sync_EIA232_RTS : std_logic_vector(3 downto 1); > > begin > -- The EIA232State statemachine controls the correct flow for the start, data > -- and stop bit(s). > process (EIA232State, StartSending, bitcounter) > begin > nextEIA232State <= EIA232State; > > case EIA232State is > when E_EIA232State_Waiting => > -- Req for sending data received. > if StartSending = '1' then > nextEIA232State <= E_EIA232State_Start; > end if; > > when E_EIA232State_Start => > nextEIA232State <= E_EIA232State_Data; > > when E_EIA232State_Data => > -- Last databit send. > if bitcounter = DATA_SIZE and StartSending = '0' then > nextEIA232State <= E_EIA232State_Waiting; > end if; > > when others => > nextEIA232State <= (others => '-'); > end case; > end process; > > -- Generate a pulse when timecounter is 0. > timecounter_pulse <= '1' when timecounter = 0 else '0'; > > -- Sample the inputsignal from physical EIA232 interface into a flipflop. > process (clk) > begin > if rising_edge(clk) then > ShiftL2H_p(EIA232_RTS,sync_EIA232_RTS); > end if; > end process; > > process (clk,nrst) > begin > if nrst = '0' then > timecounter <= TIMECOUNTER_SIZE; > ParallelOUT_Ack <= '0'; > StartSending <= '0'; > EIA232ShiftRegister <= (others => '1'); > elsif rising_edge(clk) then > ParallelOUT_Ack <= '0'; > > -- Counter to devide the clk input. > if timecounter_pulse = '1' then > timecounter <= TIMECOUNTER_SIZE; > else > timecounter <= timecounter - 1; > end if; > > case EIA232State is > when E_EIA232State_Waiting => > -- Req received and ready to transmit data. > if StartSending = '0' and ParallelOUT_Req = '1' > and sync_EIA232_RTS(sync_EIA232_RTS'high) = '0' then > -- Load the shiftregister > EIA232ShiftRegister(1 to DATA_SIZE) <= ParallelOUT_Data; > ParallelOUT_Ack <= '1'; > StartSending <= '1'; > end if; > > when E_EIA232State_Start | E_EIA232State_Data => > StartSending <= '0'; > -- The shiftregister can shift every timecounter_pulse. > -- This register runs on clk because it must be possible to load > -- external data assynchronous to timecounter_pulse. > if timecounter_pulse = '1' then > ShiftL2H_p('1',EIA232ShiftRegister); > end if; > > when others => > StartSending <= '0'; > end case; > end if; > end process; > > > process (clk,nrst) > begin > if nrst = '0' then > EIA232_RXD <= '1'; > EIA232State <= E_EIA232State_Waiting; > bitcounter <= 0; > elsif rising_edge(clk) then > if timecounter_pulse = '1' then > EIA232State <= nextEIA232State; > > case nextEIA232State is > when E_EIA232State_Waiting => > EIA232_RXD <= '1'; > > when E_EIA232State_Start => > EIA232_RXD <= '0'; > > when E_EIA232State_Data => > EIA232_RXD <= EIA232ShiftRegister(DATA_SIZE); > if bitcounter = DATA_SIZE then > bitcounter <= 0; > else > bitcounter <= bitcounter + 1; > end if; > > when others => > end case; > end if; > end if; > end process; > end RTL; > > > ------------------------------------------------------------------------ > > -- > -- ***Author*** > -- Jan De Ceuster > -- > -- *** File *** > -- EIA232_TX_bridge.vhd > -- > -- *** Entity *** > -- EIA232_TX_bridge > -- > -- *** Port list *** > -- nrst (in, 1) Active low reset > -- clk (in, 1) System Clock > -- > -- EIA232_TXD (in, 1) EIA232 Receive Serial Data from PC > -- EIA232_CTS (out, 1) EIA232 Stop Receiving > -- > -- ParallelIN_Data (out, 8) ParallelIN sends the data from EIA232 interface. > -- ParallelIN_Ack (out, 1) protocol: synchronous Full Handshake, device > -- ParallelIN_Req (in, 1) is slave. > > > library ieee; > use ieee.std_logic_1164.all, ieee.std_logic_arith.all; > > library buffers; > use buffers.shift_registers.all; > > entity EIA232_TX_bridge is > generic ( > DATA_SIZE : in integer := 8; > CLK_FREQ : in integer := 33000000; -- clock frequency in Hz > BAUDRATE : in integer := 115200 > ); > > port ( > nrst : in std_logic; > clk : in std_logic; > > EIA232_TXD : in std_logic; > EIA232_CTS : out std_logic; > > ParallelIN_Data : out std_logic_vector(DATA_SIZE-1 downto 0); > ParallelIN_Req : in std_logic; > ParallelIN_Ack : out std_logic > ); > end EIA232_TX_bridge; > > architecture RTL of EIA232_TX_bridge is > constant BITCOUNTER_SIZE : integer := DATA_SIZE - 1; > constant TIMECOUNTER_SIZE : integer := CLKFREQ/BAUDRATE-1; > constant HALF_TIMECOUNTER_SIZE : integer := TIMECOUNTER_SIZE/2 - 1; > > signal timecounter : integer range 0 to TIMECOUNTER_SIZE; > signal bitcounter : integer range 0 to DATA_SIZE-1; > signal ParallelIN_Data_reg : std_logic_vector(1 to DATA_SIZE); > signal EIA232State, nextEIA232State : EIA232State_type; > signal timecounter_pulse : std_logic; > signal StartReceive : std_logic; > signal sync_EIA232_TXD : std_logic_vector(2 downto 1); > signal faling_edge_EIA232_TXD : boolean; > signal buffer_empty : boolean; > > begin > process (EIA232State, StartReceive, bitcounter) > begin > nextEIA232State <= EIA232State; > > case EIA232State is > when E_EIA232State_Waiting => > if StartReceive = '1' then > nextEIA232State <= E_EIA232State_Start; > end if; > > when E_EIA232State_Start => > nextEIA232State <= E_EIA232State_Data; > > when E_EIA232State_Data => > if bitcounter = 0 then > nextEIA232State <= E_EIA232State_Stop; > end if; > > when E_EIA232State_Stop => > nextEIA232State <= E_EIA232State_Waiting; > > when others => > nextEIA232State <= (others => '-'); > end case; > end process; > > -- sample signal into flipflops > process (clk) > begin > if rising_edge(clk) then > ShiftL2H_p(EIA232_TXD,sync_EIA232_TXD); > end if; > end process; > > faling_edge_EIA232_TXD <= sync_EIA232_TXD(sync_EIA232_TXD'high-1) = '0' > and sync_EIA232_TXD(sync_EIA232_TXD'high) = '1'; > timecounter_pulse <= '1' when timecounter = 0 else '0'; > > process (clk, nrst) > begin > if nrst = '0' then > timecounter <= TIMECOUNTER_SIZE; > StartReceive <= '0'; > elsif rising_edge(clk) then > -- endless timer with conditional preload (when detecting a startbit) > -- StartReceive indicates the detection of the startbit > if faling_edge_EIA232_TXD -- faling edge TXD, > and nextEIA232State = E_EIA232State_Waiting then -- detect start bit > timecounter <= HALF_TIMECOUNTER_SIZE; > StartReceive <= '1'; > elsif timecounter = 0 then -- counter reset > timecounter <= TIMECOUNTER_SIZE; > StartReceive <= '0'; > else > timecounter <= timecounter - 1; -- count down > end if; > end if; > end process; > > process (clk, nrst) > begin > if nrst = '0' then > EIA232State <= E_EIA232State_Waiting; > ParallelIN_Data_reg <= (others => '-'); > bitcounter <= BITCOUNTER_SIZE; > elsif rising_edge(clk) then > if timecounter_pulse = '1' then > EIA232State <= nextEIA232State; > bitcounter <= BITCOUNTER_SIZE; > > -- shift register > ShiftL2H_p(sync_EIA232_TXD(sync_EIA232_TXD'high),ParallelIN_Data_reg); > > if EIA232State = E_EIA232State_Start > or EIA232State = E_EIA232State_Data then > -- counter for the shiftregister > if bitcounter = 0 then > bitcounter <= BITCOUNTER_SIZE; > else > bitcounter <= bitcounter - 1; > end if; > end if; > end if; > end if; > end process; > > process (clk, nrst) > begin > if nrst = '0' then > buffer_empty <= TRUE; > EIA232_CTS <= '1'; > ParallelIN_Ack <= '0'; > elsif rising_edge(clk) then > if buffer_empty then > EIA232_CTS <= '0'; > else > EIA232_CTS <= '1'; > end if; > > if EIA232State = E_EIA232State_Data then > buffer_empty <= FALSE; > end if; > > -- Output the shiftregister directly. > if timecounter_pulse = '1' and EIA232State = E_EIA232State_Stop then > ParallelIN_Data <= ParallelIN_Data_reg; > end if; > > -- The shiftregister now contains the received byte. > -- => give an ack for 1 clock cycle (done with timecounter_pulse) > if ParallelIN_REQ = '1' and not buffer_empty and EIA232State = E_EIA232State_Waiting then > ParallelIN_Ack <= '1'; > buffer_empty <= TRUE; > else > ParallelIN_Ack <= '0'; > end if; > end if; > end process; > > end RTL; > > > ------------------------------------------------------------------------ > > -- > -- ***Author*** > -- Jan De Ceuster > -- > -- *** File *** > -- EIA232_constants.vhd > -- > -- *** Entity *** > -- > -- *** Port list *** > -- > -- *** Description *** > -- > -- *** History *** > -- > > library ieee; > use ieee.std_logic_1164.all; > > package EIA232 is > -- constants > -- enumerations > type EIA232State_type is (E_EIA232State_Waiting, E_EIA232State_Start, > E_EIA232State_Data, E_EIA232State_Stop); > -- functions > -- procedures > -- components > component EIA232_TX_bridge > -- receive data via a FullHndshk protocol > -- bridge is master on EIA232 lines > generic ( > DATA_SIZE : in integer := 8; -- size can be anything from 5 to 8 > CLK_FREQ : in integer := 33000000; -- clock frequency in Hz > BAUDRATE : in integer := 115200 > ); > port ( > nrst : in std_logic; > clk : in std_logic; > > EIA232_TXD : in std_logic; > EIA232_CTS : out std_logic; > > ParallelIN_Data : out std_logic_vector(DATA_SIZE-1 downto 0); > ParallelIN_Req : in std_logic; > ParallelIN_Ack : out std_logic > ); > end component; > > component EIA232_RX_bridge > -- send data via a FullHndshk protocol > -- bridge is master on EIA232 lines > generic ( > DATA_SIZE : in integer := 8; -- size can be anything from 5 to 8 > CLK_FREQ : in integer := 33000000; -- clock frequency in Hz > BAUDRATE : in integer := 115200 > ); > port ( > nrst : in std_logic; > clk : in std_logic; > > EIA232_RXD : out std_logic; > EIA232_RTS : in std_logic; > > ParallelOUT_Data : in std_logic_vector(DATA_SIZE-1 downto 0); > ParallelOUT_Req : in std_logic; > ParallelOUT_Ack : out std_logic > ); > end component; > end EIA232; > > package body EIA232 is > end EIA232;
On Mon, 13 Dec 2004 17:20:58 +0100, Gr&#4294967295;gory Mermoud  
<gregory.mermoud@epfl.ch> wrote:

> I am currently working on an implementation of such a controller for my > semester project. So I will let you have a look to my code when I have > finished it. > > Greetz :) > > Gr&#4294967295;gory Mermoud > gregory.mermoud@epfl.ch > Swiss Federal Institute of Technology - Lausanne > Computer Science Departement
Yeah that would be great ! Thanks ! Konstantin -- Using M2, Opera's revolutionary e-mail client: http://www.opera.com/m2/
test...