Rules | Recent posts | topic RSS | Search | Register  | Log in

RS-232 interfacing with FPGA

 
Post new topic  Reply to topic    EDAboard.com Forum Index -> PLD, SPLD, GAL, CPLD, FPGA Design
Author Message
dadda007



Joined: 22 Nov 2007
Posts: 8


Post19 Aug 2008 18:26   RS-232 interfacing with FPGA

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;

Back to top
FvM



Joined: 22 Jan 2008
Posts: 2635
Helped: 431
Location: Bochum, Germany


Post19 Aug 2008 20:44   Re: RS-232 interfacing with FPGA

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.
Back to top
dadda007



Joined: 22 Nov 2007
Posts: 8


Post20 Aug 2008 17:45   Re: RS-232 interfacing with FPGA

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 !!!!!
Back to top
j_andr



Joined: 30 Mar 2008
Posts: 90
Helped: 15
Location: europe


Post21 Aug 2008 8:01   Re: RS-232 interfacing with FPGA

dadda007 wrote:
....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;
---
Back to top
Post new topic  Reply to topic    EDAboard.com Forum Index -> PLD, SPLD, GAL, CPLD, FPGA Design
Page 1 of 1 All times are GMT + 1 Hour


Abuse
Administrator
Moderators
topic RSS 
sitemap