Continue to Site

Welcome to EDAboard.com

Welcome to our site! EDAboard.com is an international Electronics Discussion Forum focused on EDA software, circuits, schematics, books, theory, papers, asic, pld, 8051, DSP, Network, RF, Analog Design, PCB, Service Manuals... and a whole lot more! To participate you need to register. Registration is free. Click here to register now.

RS-232 interfacing with FPGA

Status
Not open for further replies.

dadda007

Newbie level 5
Joined
Nov 22, 2007
Messages
8
Helped
0
Reputation
0
Reaction score
0
Trophy points
1,281
Activity points
1,357
related:www.edn.com/article/ca47273.html

I have written a code to take in serial data from a RS-232 link and store it in a register. I intend to generate 2 signals , one signal ack1 which goes high after a valid start bit has been obtained and another signal ack2 after all the 8 data bits have been received correctly. To check the validity i have used an oversampling clock which samples each bit duration at 16 times the baud rate clock and uses maximal logic for evaluating the same. However after simulation i was getting no value into the register and also faulty value for ack1 and ack2 ....please help !!!!!

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;

entity rs232_lport is 

port (

		data : in BIT;
		clk_rs232 : inout STD_LOGIC;
		baudrate : in STD_LOGIC;
--		lport_clk : out BIT:='0';
		ack1 : out BIT;
		ack2 : out BIT;
--		check : out BIT;
--		lport_data : out BIT_VECTOR(3 downto 0);
		input_reg : buffer BIT_VECTOR(7 downto 0):="00000000");
		
end entity;

architecture rs232_lport_behav of rs232_lport is 

shared variable med,med1 : BIT_VECTOR(4 downto 0);
shared variable i,lcount_16,dcount,nos_0,nos_1 : integer;
shared variable big,big1,dbit : bit;
shared variable first_4,last_4 : BIT_VECTOR(3 downto 0);

type state_rs232 is (s0,s1,s2);
type state_lport is (idle,f4,l4);
signal l_state : state_lport;
signal rs_state : state_rs232; --Initial state is s0.


begin

  process(data)

	begin 
	
		case rs_state is
		
			when s0=>					-- Idle state of state machine
			
				if(data='1') then 		-- If data is one then set all parameters to zero.
					
					ack1<='0';
					rs_state<=s0;		-- Back to idle state .....
								
				else 
				
					rs_state<=s1;		-- If data line is zero then go to state s1.
				
				end if;
				
			when s1=>					-- Checks the validity of start bit.
			
--				check<='1';
			
				
				for lcount_16 in 1 to 16 loop 	-- checks the value of the first start bit.
				
					ack2<='0';
					ack1<='0';
					
					if (clk_rs232'event )and (clk_rs232='1') and (clk_rs232'last_value='0')then
					
								if(lcount_16=7) then 
									med(0):=data;
								end if;
					
					
								if(lcount_16=8) then 
									med(1):=data;
								end if;
								
								if(lcount_16=9) then 
									med(2):=data;
								end if;
								
								if(lcount_16=10) then 
									med(3):=data;
								end if;
								
								if(lcount_16=11) then 
									med(4):=data;
								end if;
							
					end if;
							
				end loop;
				
								
							 for i in 0 to 4 loop	-- checks the value of start bit using maximal logic.
							
								if(med(i)='0') then 
								nos_0:=nos_0+1;
								end if;
								
							end loop;
							
							for i in 0 to 4 loop
							
								if(med(i)='1') then 
								nos_1:=nos_1+1;
								end if;
								
							end loop;
				
					if(nos_1>nos_0) then 
						big:='1';
					else 
						big:='0';
					end if;
						
					if(big='0') then	-- If the value of the start bit is zero then set the value of the ack1 bit to one .....
						ack1<='1';
					rs_state<=s2;		-- Go to state s2
																		
					else 
						
					   ack1<='0';
					   rs_state<=s0;	-- If start bit is 1 goto idle state.
																		
					end if;
					
			when s2=>		-- This state takes in the value into the register and keeps shifting it.
			
					
--			if(ack1='1') then
				
					
					for dcount in 0 to 7 loop 
							
							if(baudrate'event and baudrate='1') then
					 

							dbit:=data;
							input_reg<='0'&input_reg(7 downto 1);
							input_reg(7)<=dbit;
							
							end if;
							
					end loop;
							
			ack2<='1'; 	-- After all the 8 bits have been shifted set the value of ack2 bit high.
						
			rs_state<=s0;	-- Go to state s0 , i.e. the idle state .....
									
	end case;

  end process;
	
end rs232_lport_behav;
 

I suggest to use an existing UART receiver design as template. Regarding the present code, I'm unable to forsee it's behaviour. Using a clock sensitive expression inside an iteration loop is beyond my horizon, and completely unsynthesizable I think. A simulator may luckily accept it without errors, but that doesn't necessarily give a sense to the code.

It's generally instructive to write such designs from the scratch. But you should follow usual design rules for synchronous designs with state machines. Compiling the design with a FPGA tool early can help in identifying unsynthesizable constructs.
 

Thanks for the reply , I tried out the following code but with little outcome ....

Code:
library IEEE;
use IEEE.STD_LOGIC_1164.all;	--Header file declaration

entity rs232_lport is 

	port(
			data : in BIT;	-- Input RS-232 serial data
			clk_rs232 : in STD_LOGIC;	-- Latching clock
			baudrate : in STD_LOGIC;	-- Bit rate 
			ack : out STD_LOGIC:='0';	-- Acknoledge goes high when 8 data bits arrive
			input_reg : inout BIT_VECTOR(7 downto 0):="00000000");	-- Input register stores the serial data 
			
end entity;

architecture rs232_lport_behav of rs232_lport is 

type state_rs232 is (s0,s1,s2);	-- The 3 states of receiever fsm
type state_lport is (idle,f4,l4);
signal l_state : state_lport;
signal rs_state : state_rs232; --Initial state is s0.

shared variable i,lcount_16,dcount,nos_0,nos_1 : integer:=0;
shared variable med,med1 : bit;	--Stores the center sample.
signal	rst : STD_LOGIC:='1';
--shared variable ack_v : STD_LOGIC;

begin 

	rxclk : process(clk_rs232,rst)	-- This process uses a RS-232 clock and a rst signal to generate a receiver clock.

		begin
		
		if(rst='0') then

			if(clk_rs232'event and clk_rs232='1') then 	-- Generates a counter which keeps on counting during the time duration of latching clock.

				if (lcount_16=15) then 

					lcount_16:=0;
					
				else 
			
					lcount_16:=lcount_16+1;
		
				end if;

			end if;
			
		else 

			lcount_16:=0;
			
		end if;
		
end process;

rx_fsm : process(clk_rs232,rst)	-- FSM for receiver module.

	begin 

		case rs_state is 

			when s0=>			-- Idle state 

				if(data='1') then 

					rst<='1';
					dcount:=0;
					input_reg<="00000000";
					rs_state<=s0;
				
				else 
	
					rs_state<=s1;
			
				end if;

			when s1=>	--	This state checks the validity of start bit.

				rst<='0';
				
				if(lcount_16=8) then 
					med:=data;
				end if;
				
				if(med='0') then	-- If the start bit is valid.
					rst<='1';
					rs_state<=s2;
				else				-- If not go to idle state.
					rs_state<=s0;
				end if;

			when s2=>	--This state keeps on shifting the data bits into an input register.

				rst<='0';
				
				if(dcount<8)  then	-- Repeat 8 times , i.e. till all the data bits have been received.
				
					if(lcount_16=8) then 	-- Take the middle sample
						med1:=data;
					end if;

					if(lcount_16=15) then 	-- At the end of each bit duration shift the data value into the register.
						input_reg<='0' & input_reg(7 downto 1);
						input_reg(7)<=med1;
						dcount:=dcount+1;	-- Increment the count.
						rs_state<=s2;	-- Go back to state s2 , i.e. go back to state which keeps on shifting the data value into the register.
					end if;
				
				end if;
				
				if(dcount=8) then	-- After all the 8 data bits have been shifted go back to idle state.
				
					ack<='1';		-- Sets ack signal high after all the 8 data bits have been received.
					rst<='1';
					rs_state<=s0;
									
				end if;
				
		end case;

  end process;
	
end rs232_lport_behav;

My intention is the same as was specified in my previous post ... I am a newbbie in this field so plz help !!!!!
 

dadda007 said:
....please help
as my knowledge of vhdl is rather passive I can't help you
with the code, but may be a piece of advice will be helpful;
start once again from scratch and build a small part of your rtl;
then look at the schematic view what you got, simulate it;
then add next small piece and repeat the procedure;
if you have many errors in a code their combined effect
is usually very misleading;
---
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top