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.

[SOLVED] problem in RS232 vhdl code

Status
Not open for further replies.

vishy71

Full Member level 2
Joined
Dec 16, 2010
Messages
126
Helped
3
Reputation
6
Reaction score
3
Trophy points
1,298
Location
Iran
Activity points
2,296
Hi.I am so sorry because of my poor English speaking!
I am trying to write a simple code in VHDL for RS232 to receive data through a wire as you know.here is my code!
something is wrong! please help me to solve this challenge!thanks :)

modelsim.jpg

as you can see,bit_cnt pulsed twice!!!!!why? and number of "get" state must be 8 not 4!!!!
here is my code:
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity rcv is
	port(din,clk:in std_logic;dout:out std_logic_vector(7 downto 0);ready:out std_logic);
end entity;

architecture arch_rcv of rcv is
	type rcv_state is (idle,start,wt,plus,get,stop);
	signal curr_state,next_state:rcv_state;
	signal bit_cnt:unsigned(3 downto 0):="0000";
	signal clk_cnt:unsigned(15 downto 0):=x"0000";
	begin
	process(curr_state,din,clk)is
	  begin
		if(clk'event and clk='1') then
			curr_state<=next_state;
		elsif(din'event and din='0' and curr_state=idle)then
			next_state<=start;
		elsif(curr_state=idle)then
			bit_cnt<="0000";
			clk_cnt<=x"0000";
			ready<='1';
		elsif(curr_state=start)then
			ready<='0';
			if(clk_cnt=2600)then
				next_state<=wt;
				clk_cnt<=x"0000";
			else
				clk_cnt<=clk_cnt+1;
			end if;
		elsif(curr_state=wt)then
			if(clk_cnt=5200)then
				clk_cnt<=x"0000";
				next_state<=get;
			else
				clk_cnt<=clk_cnt+1;
			end if;
		elsif(curr_state=get)then
			if(bit_cnt=8)then
				next_state<=stop;
			else
				dout(to_integer(bit_cnt))<=din;
				bit_cnt<=bit_cnt+1;
				next_state<=wt;
			end if;
		elsif(curr_state=plus)then
				
		elsif(curr_state=stop)then
			if(clk_cnt=5200)then
				next_state<=idle;
			else
				clk_cnt<=clk_cnt+1;
			end if;
		end if;
	end process;
end arch_rcv;

also I try to make new state with "plus" name to increase bit_cnt but when I do that,it increased twice!!! for example : bit_cnt<="0000" and after bit_cnt<=bit_cnt+1 it was "0010"!!!!!!

thanks.
 

This is not the correct template for a state machine. You need either two separate process: one for registering the state, and another for decoding the outputs and next state.
Or use a single clocked process.

You should not be using else-ifs with a clock. It will not compile.
 

This is not the correct template for a state machine. You need either two separate process: one for registering the state, and another for decoding the outputs and next state.
Or use a single clocked process.

You should not be using else-ifs with a clock. It will not compile.

thanks.let me try it :)

- - - Updated - - -

whats wrong!

it dose not fill dout!!!!
Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity rcv is
	port(din,clk:in std_logic;dout:out std_logic_vector(7 downto 0);ready:out std_logic);
end entity;

architecture arch_rcv of rcv is
	type rcv_state is (idle,start,wt,plus,get,stop);
	signal curr_state,next_state:rcv_state:=idle;
	signal bit_cnt:unsigned(3 downto 0):="0000";
	signal clk_cnt:unsigned(15 downto 0):=x"0000";
	begin
	process(curr_state,din)is
	    begin
		if(curr_state=idle)then
			bit_cnt<="0000";
			clk_cnt<=x"0000";
			if(din='0')then
				next_state<=start;
			end if;
			ready<='1';
			clk_cnt<=x"0000";
		elsif(curr_state=start)then
			ready<='0';
			if(clk_cnt=2600)then
				next_state<=wt;
				clk_cnt<=x"0000";
			else
				clk_cnt<=clk_cnt+1;
			end if;
		elsif(curr_state=wt)then
			if(clk_cnt=5200)then
				clk_cnt<=x"0000";
				next_state<=get;
			else
				clk_cnt<=clk_cnt+1;
			end if;
		elsif(curr_state=get)then
			if(bit_cnt=8)then
				next_state<=stop;
			else
				dout(to_integer(bit_cnt))<=din;
				bit_cnt<=bit_cnt+1;
				next_state<=wt;
			end if;
		elsif(curr_state=plus)then
				
		elsif(curr_state=stop)then
			if(clk_cnt=5200)then
				next_state<=idle;
			else
				clk_cnt<=clk_cnt+1;
			end if;
		end if;
	end process;

	process(clk) is
		begin
		if(clk'event and clk='1') then
			curr_state<=next_state;
		end if;
	end process;
end arch_rcv;
 

Severl problems.
You cannot put a counter in an asynchronous process.
And you need to assing all signals in ALL cases in the async process. You cannot have en empty if branch either.
 

I solve it.thanks.

Code:
library ieee;
use ieee.std_logic_1164.all;
use ieee.numeric_std.all;
entity rcv is
	port(din,clk:in std_logic;dout:out std_logic_vector(7 downto 0);ready:out std_logic);
end entity;

architecture arch_rcv of rcv is
	type rcv_state is (idle,start,get,wt,stop);
	signal curr_state,next_state:rcv_state;
	signal clk_div_en,clk_div1,clk_div2:std_logic:='0';
	signal bit_cnt:unsigned(3 downto 0):="0000";
	signal clk_cnt1,clk_cnt2:unsigned(15 downto 0):=x"0000";
	begin
	process(clk)is
		begin
		if(clk'event and clk='1')then
			curr_state<=next_state;
			if(clk_div_en='1')then
				if(clk_cnt1=2600)then
					clk_div1<=not clk_div1;
				else
					clk_cnt1<=clk_cnt1+1;
				end if;
				if(clk_cnt2=5200)then
					clk_div2<=not clk_div2;
					clk_cnt2<=x"0000";
				else
					clk_cnt2<=clk_cnt2+1;
				end if;
			elsif(clk_div_en='0')then
				clk_cnt2<=x"0000";
			end if;
		end if;
	end process;
	process(din,curr_state,clk_div1,clk_div2)is
		begin
		if(curr_state=idle)then
			ready<='1';
			clk_div_en<='0';
			bit_cnt<="0000";
			if(din='0')then
				next_state<=start;
			end if;
		elsif(curr_state=start)then
			ready<='0';
			clk_div_en<='1';
			if(clk_div1='1')then
				next_state<=get;
			end if;
		elsif(curr_state=get)then
			if(clk_div2='1')then
				if(bit_cnt=8)then
					next_state<=stop;
				else
					dout(to_integer(bit_cnt))<=din;
					bit_cnt<=bit_cnt+1;
					next_state<=wt;
				end if;
			end if;
		elsif(curr_state=wt)then
			if(clk_div2='0')then
				next_state<=get;
			end if;
		elsif(curr_state=stop)then
			if(clk_div2='0')then
				next_state<=idle;
			end if;
		end if;
	end process;
end arch_rcv;
 

THis does not fix it. You still have a counter in the async process so you have signals missing from the sensitiivty list. This code will not work.
 

THis does not fix it. You still have a counter in the async process so you have signals missing from the sensitiivty list. This code will not work.

but it works :).you right but ISE will append missed signals to process ;-)
a have changed it but it was my first code for usart which works good.
 

but it works :)
How did you test the code? bit_cnt is implemented with unsafe latches, it's hard to imagine that bits are counted correctly.
 

Status
Not open for further replies.

Similar threads

Part and Inventory Search

Welcome to EDABoard.com

Sponsor

Back
Top