+ Post New Thread
Results 1 to 9 of 9
  1. #1
    Newbie level 4
    Points: 1,382, Level: 8
    Achievements:
    7 years registered

    Join Date
    Dec 2010
    Posts
    7
    Helped
    0 / 0
    Points
    1,382
    Level
    8

    [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    Hello

    I'm trying to design a counter system on my FPGA board using VHDL. My design needs to receive some bytes as control signals like start, stop reset and measurement period info. For this purpose I have a UART module including both TX and RX serial lines and I'm also using a usb serial converter.

    For processing the commands I have used a case block. Depending on the received byte I want to perform different tasks as it is indicated as start, stop, reset and period. I' ve attached the test bench files which shows everything is fine. However, in reality when I send a command through my GUI on computer first it works but then the next received byte changes the previous. So I can' t handle each different bytes or commands successfully.

    How can I handle incoming bytes? Does anyone have any suggestion related to a modification or a different structure?

    Thanks in advance...

    stop_watch.vhd
    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    
    --==================================================================================
    --
    -- timer = 100.000.000)  ->  1/1     second
    -- timer =  50.000.000)  ->  1/2     second = 500 mili second
    -- timer =  25.000.000)  ->  1/4     second = 250 mili second
    -- timer =  10.000.000)  ->  1/10    second = 100 mili second
    -- timer =     100.000)  ->  1/1000  second =   1 mili second
    -- timer =      50.000)  ->  1/2000  second = 0.5 mili second = 500 micro second
     
    --===================================================================================
     
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    USE IEEE.NUMERIC_STD.ALL;
     
    entity Stop_Watch is
        Port (  clk                     : IN  STD_LOGIC ;   -- 100 MHz
                    OPERATION               : IN    STD_LOGIC ;
                    RESET                       : IN  STD_LOGIC ;
                    Period_Info             : IN    STD_LOGIC_VECTOR(3 DOWNTO 0) ;
                    SW_Period_Over_Flag     : OUT STD_LOGIC ;
                    Period                  : OUT INTEGER range 0 to 5*10E+3);
    end Stop_Watch;
     
    architecture Behavioral of Stop_Watch is
     
    signal s_clk                  : STD_LOGIC ;
    signal s_OPERATION            : STD_LOGIC ;
    signal s_RESET                    : STD_LOGIC ;
    signal s_SW_Period_Over_Flag : STD_LOGIC ;
    signal s_Period_Info              : STD_LOGIC_VECTOR(3 DOWNTO 0) ;
    signal i_Period               : INTEGER range 0 to 5*10E+3 := 0;
     
    begin
        
        s_clk           <= clk ;
        s_OPERATION     <= OPERATION ;
        s_RESET             <= RESET ;
        s_Period_Info   <=  Period_Info ;
        
        i_Period <= 1       when s_period_info = "0001" else    
                        5       when s_period_info = "0010" else    
                        10      when s_period_info = "0011" else    
                        30      when s_period_info = "0100" else    
                        60      when s_period_info = "0101" else    
                        300 when s_period_info = "0110" else    
                        600 when s_period_info = "0111" else    
                        1800    when s_period_info = "1000" else    
                        3600    when s_period_info = "1001" else    
                        1 ;
                         
                         
        process(s_clk, s_OPERATION, s_RESET, i_Period )
        variable v_timer                : integer range 0 to 5*100E+6 := 0;
        variable v_timer_seconds    : integer range 0 to 5*10E+3 := 0;
        begin
            if ( rising_edge( s_clk ) ) then
                if (s_OPERATION = '1') then
                    if ( s_RESET = '1' ) then
                        v_timer := 0 ;
                    else
                    
                        if ( v_timer =  5 ) then
                            v_timer := 0;
                            if ( v_timer_seconds = i_Period) then
                                v_timer_seconds := 0 ;
                                s_SW_Period_Over_Flag <= '1';
                            else
                                v_timer_seconds := v_timer_seconds + 1 ;
                                s_SW_Period_Over_Flag <= '0';
                            end if;                     
                        else                        
                            s_SW_Period_Over_Flag <= '0';
                            v_timer := v_timer + 1 ;
                        end if ;
                        
                    end if ;
                else
                    v_timer := 0 ;
                end if ;            
            end if ;
        end process ;
     
        SW_Period_Over_Flag <= s_SW_Period_Over_Flag ;
        Period <= i_Period ;
        
    end Behavioral;

    device_controller.vhd
    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    
    library IEEE;
    use IEEE.STD_LOGIC_1164.ALL;
    use IEEE.NUMERIC_STD.ALL;
     
     
    entity Device_Controller is
     
        Port(   clk             : IN   STD_LOGIC  ;
                CTRL_BYTE   : IN   STD_LOGIC_VECTOR(7 DOWNTO 0)  ;
                
                RESET       : OUT  STD_LOGIC  ;
                PERIOD      : OUT  STD_LOGIC_VECTOR(3 DOWNTO 0)  ;
                OPERATION   : OUT  STD_LOGIC );
                    
    end Device_Controller;
     
    architecture Behavioral of Device_Controller is
        
        signal s_clk            : STD_LOGIC ;
        signal s_RESET          : STD_LOGIC := '0';
        signal s_CTRL_BYTE  : STD_LOGIC_VECTOR(7 DOWNTO 0) ;
        signal s_PERIOD     : STD_LOGIC_VECTOR(3 DOWNTO 0) := "0001";
        SIGNAL s_OPERATION  : STD_LOGIC := '0';
        
    begin
     
        s_clk       <= clk ;
        RESET       <= s_RESET ;
        s_CTRL_BYTE <= CTRL_BYTE ;
        
        process(s_clk, s_CTRL_BYTE)
        begin
        
            if ( rising_edge(s_clk) ) then
                
                case s_CTRL_BYTE is
                    
                    when "01000001" =>      -- A start BYTE
                        s_OPERATION <= '1' ;
                        
                    when "01000010" =>      -- B stop BYTE
                        s_OPERATION <= '0' ;    
                        
                    ------ PERIOD --------------------------------------------- 
                    when "01000011" =>      -- C 1 sec BYTE
                        s_PERIOD <= "0001" ;
                        
                    when "01000100" =>      -- D 5sec  BYTE
                        s_PERIOD <= "0010" ;
                        
                    when "01000101" =>      -- E 10sec  BYTE
                        s_PERIOD <= "0011" ;
                        
                    when "01000110" =>      -- F 30sec  BYTE
                        s_PERIOD <= "0100" ;
                        
                    when "01000111" =>      -- G 1min  BYTE
                        s_PERIOD <= "0101" ;
                        
                    when "01001000" =>      -- H 5min  BYTE
                        s_PERIOD <= "0110" ;
                        
                    when "01001001" =>      -- I 10min  BYTE
                        s_PERIOD <= "0111" ;
                        
                    when "01001010" =>      -- J 30min  BYTE
                        s_PERIOD <= "1000" ;    
                        
                    when "01001011" =>      -- K 1 hour BYTE
                        s_PERIOD <= "1001" ;        
                        
                    ----------------------------------------------------------  
                    when "01001100" =>      -- L "set RESET" BYTE
                        s_RESET <= '1' ;        
                        
                    when "01001101" =>      -- M "reset RESET" BYTE
                        s_RESET <= '0' ;        
                        
                    when others =>
                        s_OPERATION <= '0' ;            
                    
                end case ;
                
            end if ;
            
        end process;
     
        OPERATION   <= s_OPERATION ; 
        PERIOD      <= s_PERIOD ;
     
    end Behavioral;

    tb_period_selection.vhd
    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    
    LIBRARY ieee;
    USE ieee.std_logic_1164.ALL;
    USE ieee.numeric_std.ALL;
     
    ENTITY TB_Period_Selection IS
    END TB_Period_Selection;
     
    ARCHITECTURE behavior OF TB_Period_Selection IS 
       
        -- Clock period definitions
       constant clk_period : time := 10 ns;   
        
        --Inputs
       signal clk               : std_logic := '0';
       signal s_CTRL_BYTE   : std_logic_vector(7 downto 0) ; --:= (others => '0');
        
        
        COMPONENT Device_Controller
        PORT(   clk             : IN   std_logic ;
                CTRL_BYTE   : IN   std_logic_vector(7 downto 0);
                
                RESET       : OUT  std_logic ;
                PERIOD      : OUT  std_logic_vector(3 downto 0);
                OPERATION   : OUT  std_logic );
        END COMPONENT;
        
        --Outputs and Inputs2
       signal s_RESET       : std_logic;
       signal s_PERIOD_info : std_logic_vector(3 downto 0);
       signal s_OPERATION   : std_logic;
        
        COMPONENT Stop_Watch
        Port(   clk                     : IN  STD_LOGIC ;   -- 100 MHz
                OPERATION               : IN    STD_LOGIC ;
                RESET                       : IN  STD_LOGIC ;
                Period_Info             : IN    STD_LOGIC_VECTOR(3 DOWNTO 0) ;
                
                SW_Period_Over_Flag     : OUT STD_LOGIC ;
                Period                  : OUT INTEGER range 0 to 5*10E+3);
        END COMPONENT;
        
        --Outputs2
       signal s_SW_Period_Over_Flag     : std_logic;
       signal s_Period      : integer range 0 to 5*10E+3 ;
     
     
     
    BEGIN
     
        -- Instantiate the Unit Under Test (UUT)
       uut: Device_Controller PORT MAP (
              clk           => clk ,
              CTRL_BYTE     => s_CTRL_BYTE ,
                 
              RESET         => s_RESET ,
              PERIOD        => s_PERIOD_info ,
              OPERATION     => s_OPERATION  );  
                 
        -- Instantiate the Unit Under Test (UUT)
       uut2: Stop_Watch PORT MAP (
              clk                       => clk ,
              OPERATION                 => s_OPERATION,
              RESET                     => s_RESET,
              Period_Info           => s_PERIOD_info,
                 
              SW_Period_Over_Flag => s_SW_Period_Over_Flag,
              Period                    => s_Period);
     
       -- Clock process definitions
       clk_process :process
       begin
            clk <= '0';
            wait for clk_period/2;
            clk <= '1';
            wait for clk_period/2;
       end process;
     
     
      -- Stimulus process
       stim_proc: process
       begin        
     
          wait for clk_period*2;
            
            ------------------------------------------
            
            s_CTRL_BYTE <= "01000101";  --  10 SEC      
          wait for clk_period*5;
            
            ------------------------------------------
            
            s_CTRL_BYTE <= "01000001";  -- START
          wait for clk_period*10;
            
            ------------------------------------------
            
            s_CTRL_BYTE <= "01000011";  -- 1 SEC    
          wait for clk_period*5;
            
            s_CTRL_BYTE <= "01001100";  -- set RESET        
          wait for clk_period*2;
            
            s_CTRL_BYTE <= "01001101";  -- reset RESET      
          wait for clk_period*2;
            
     
    --      
    --      s_CTRL_BYTE <= "01000111";  -- 1 MIN        
    --      wait for clk_period*2;
    --      
    --      s_CTRL_BYTE <= "01001011";  -- 1 HOUR       
    --      wait for clk_period*2;
    --      
    --      ------------------------------------------
    --      
            s_CTRL_BYTE <= "01000010";  -- STOP     
          wait for clk_period*5;
            
            ------------------------------------------
            
    --      s_CTRL_BYTE <= "01001100";  -- set RESET        
    --      wait for clk_period*2;
    --      
    --      s_CTRL_BYTE <= "01001101";  -- reset RESET      
    --      wait for clk_period*2;
            
          wait;
       end process;
     
    END;
    Last edited by ads-ee; 2nd April 2018 at 15:47. Reason: adding code for ease of reading

    •   AltAdvertisment

        
       

  2. #2
    Super Moderator
    Points: 61,937, Level: 60
    Achievements:
    7 years registered
    Awards:
    Most Frequent Poster 3rd Helpful Member

    Join Date
    Apr 2014
    Posts
    12,624
    Helped
    2928 / 2928
    Points
    61,937
    Level
    60

    Re: FPGA VHDL UART RX line how to handle incoming bytes?

    Hi,

    What's tlhe exact problem now?
    You tell a lot about your application, but forgot to focus on the real problem.

    Additionally.
    You posted in the PC programming section, but your headline talks about PLD programming.

    Klaus
    Please don´t contact me via PM, because there is no time to respond to them. No friend requests. Thank you.



  3. #3
    Newbie level 4
    Points: 1,382, Level: 8
    Achievements:
    7 years registered

    Join Date
    Dec 2010
    Posts
    7
    Helped
    0 / 0
    Points
    1,382
    Level
    8

    Re: [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    Hi KlausST,

    Sorry I missed the section part and thank you for moving to the correct place!

    Actually I don't know how I can define the problem different than below but maybe an example...

    Quote Originally Posted by macellan View Post
    when I send a command through my GUI on computer first it works but then the next received byte changes the previous. So I can' t handle each different bytes or commands successfully.
    How can I handle incoming bytes? Does anyone have any suggestion related to a modification or a different structure?
    For instance:
    A received byte ascii "E" means counting period of 10 secs. At first this is processed correct. Then when I transmit ascii "A" to FPGA (meaning start counting) it starts but the previous "E" is not valid anymore. Instead it counts for a different time period. So I couldn' t construct a successful two way communication link.

    Is it not good to use a case block then how it should be? or anyother suggestion will be very welcome...



  4. #4
    Super Moderator
    Points: 245,688, Level: 100
    Awards:
    1st Helpful Member

    Join Date
    Jan 2008
    Location
    Bochum, Germany
    Posts
    42,690
    Helped
    13008 / 13008
    Points
    245,688
    Level
    100

    Re: [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    Then when I transmit ascii "A" to FPGA (meaning start counting) it starts but the previous "E" is not valid anymore.
    Yes, but why is this so? Before you didn't manage to store internal states of your system in a reasonable way. Presently the only state variable you have is holding the present command, but none is remembering the period setting or start/stop state. Reconsider your design.



    •   AltAdvertisment

        
       

  5. #5
    Super Moderator
    Points: 29,150, Level: 41
    ads-ee's Avatar
    Join Date
    Sep 2013
    Location
    USA
    Posts
    6,721
    Helped
    1604 / 1604
    Points
    29,150
    Level
    41

    Re: [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    A reset buried inside an enable is not the standard template for a resetable flip-flop.
    Code VHDL - [expand]
    1
    2
    3
    4
    5
    
    if ( rising_edge( s_clk ) ) then
                if (s_OPERATION = '1') then
                    if ( s_RESET = '1' ) then
                        v_timer := 0 ;
                    else

    Given you are defining v_timer as 0 to 500,000,000 and only using it to count from 0 to 5 makes me wonder if you understand how VHDL translates into logic circuits. There seems to be a major disjoint between what you want your circuit to do and what the code you are writing does and unfortunately I can't tell what it is you actually need you circuit to do as the TB seems to test something that is completely different than your as written code, e.g. waiting for 50 ns to test a 10 second setting seems rather strange or maybe its the 100ns after you send "start"?



  6. #6
    Newbie level 4
    Points: 1,382, Level: 8
    Achievements:
    7 years registered

    Join Date
    Dec 2010
    Posts
    7
    Helped
    0 / 0
    Points
    1,382
    Level
    8

    Re: [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    Quote Originally Posted by ads-ee View Post
    Given you are defining v_timer as 0 to 500,000,000 and only using it to count from 0 to 5 ...
    Maybe I should ask if we are agree about something. If we want to design a i.e 1 minute timer using 100MHz clock, we need to count 60 times until 100M-1. Here for testbench instead of 100M-1 I count until 5 and then make v_timer_seconds +1. This is just for observing the signals in a reasonable time window. Real design counts 100M-1 and when I insert i.e 60 for i_Period it performs the measurements successfully.

    So far as I understand the problem is driving different signals in case statement. All example codes for case statement are like

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    
    case "control_signal" is                
                    when "case1" =>
                        signal_1 <= "0001";   
                     
                    when "case2" =>
                         signal_1 <= "0010";  
                    ...

    but I wish to drive signal_1 for first case, signal_2 for seconds case etc. and keep the previous signals stay at the same configuration until I do some modification.

    So when I work with case_2, why and how signal 1 changes ?
    Last edited by andre_teprom; 8th April 2018 at 21:39. Reason: added syntax tags



  7. #7
    Advanced Member level 3
    Points: 5,356, Level: 17

    Join Date
    Feb 2015
    Posts
    887
    Helped
    256 / 256
    Points
    5,356
    Level
    17

    Re: [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    The simulation doesn't show how CTRL_BYTE is received -- it is just generated in the simulation. If CTRL_BYTE is shifted 1 bit at a time from the uart, then you would need to have some enable signal to avoid interpreting intermediate results as commands.

    The case statement isn't special. Signals have the same behavior -- the last reached assignment in the process is the one that is used. If no assignment is made in the process then the value is retained. In the case of a clocked process, that would be a register. In the case of a non-clocked process, that would result in a latch. I didn't see anything wrong with the case statement, other than a possible lack of a clock enable.

    I'm also not sure why you take input ports and assign them to signals. You also include too many signals in the sensitivity list for the clocked processes.



  8. #8
    Newbie level 4
    Points: 1,382, Level: 8
    Achievements:
    7 years registered

    Join Date
    Dec 2010
    Posts
    7
    Helped
    0 / 0
    Points
    1,382
    Level
    8

    Re: [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    Hi vGoodtimes

    I made some trials but didn't succeeded yet. Here is the final version of UART RX. In case of applying a half received byte, I've located another FSM to transfer the complete byte after the receiving sequence completes. But what a pity It doesn't make any sense.

    why you take input ports and assign them to signals. You also include too many signals
    I actually don't have a specific reason for this. This is just because of the first examples that I used when started my designs on FPGA. I also think if it is good or not but so far I didn't have a problem.

    looking forward to your comments.

    Thanks ...

    Code VHDL - [expand]
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
    64
    65
    66
    67
    68
    69
    70
    71
    72
    73
    74
    75
    76
    77
    78
    79
    80
    81
    82
    83
    84
    85
    86
    87
    88
    89
    90
    91
    92
    93
    94
    95
    96
    97
    98
    99
    100
    101
    102
    103
    104
    105
    106
    107
    108
    109
    110
    111
    112
    113
    114
    115
    116
    117
    118
    119
    120
    121
    122
    123
    124
    125
    126
    127
    128
    129
    130
    131
    132
    133
    134
    135
    136
    137
    138
    139
    140
    141
    
    LIBRARY IEEE;
    USE IEEE.STD_LOGIC_1164.ALL;
    USE IEEE.NUMERIC_STD.ALL;
     
    entity RX_Serial_Link is
        generic( Baud_Match_Number : integer := 868 );
        port (  clk         : in  std_logic ;
                RX_Serial   : in  std_logic ;
    --          Link_Info   : out std_logic ;
                RX_Byte     : out std_logic_vector(7 downto 0) );
    end RX_Serial_Link;
     
    architecture Behavioral of RX_Serial_Link is
     
        signal s_clk : STD_LOGIC ;
     
        type  STATE is (ST_IDLE, ST_START_BIT, ST_DATA_BITS, ST_STOP_BITS, ST_CLEANUP);
        signal NEXT_STATE : STATE := ST_IDLE;
     
        signal s_RX_Serial_temp : std_logic ;
        signal s_RX_Serial      : std_logic ;
     
        signal Bit_Keep_Count   : integer range 0 to Baud_Match_Number := 0;
        signal Bit_Index        : integer range 0 to 7 := 0;        -- 8 Bits Total
        signal s_RX_Byte        : std_logic_vector(7 downto 0) := (others => '0');
        signal s_state_info     : std_logic := '0';
       
        type  STATE_BT is (ST_READ, ST_BYTE_HOLD); -- STATE_BT: State Byte Transfer
        signal NEXT_STATE_BT : STATE_BT := ST_READ;
        
    begin
     
        s_clk <= clk ;
     
      -- Purpose: Double-register the incoming data.
      -- This allows it to be used in the UART RX Clock Domain.
      -- (It removes problems caused by metastabiliy)
        p_SAMPLE : process (s_clk)
        begin
            if rising_edge(s_clk) then
                s_RX_Serial_temp    <= RX_Serial;
                s_RX_Serial         <= s_RX_Serial_temp;
            end if;
        end process p_SAMPLE;   
     
        -- Purpose: Control RX state machine
        p_UART_RX : process (s_clk)
        begin
            if rising_edge(s_clk) then          
                case NEXT_STATE is              
                    when ST_IDLE =>                 
                        s_state_info <= '0' ;                   
                        Bit_Keep_Count <=  0 ;
                        Bit_Index   <=  0 ;                 
                        if s_RX_Serial = '0' then       -- Start bit detected
                            NEXT_STATE <= ST_START_BIT;
                        else
                            NEXT_STATE <= ST_IDLE;
                        end if; 
                        
                    -- Check middle of start bit to make sure it's still low
                    when ST_START_BIT =>                    
                        s_state_info <= '1' ;                   
                        if Bit_Keep_Count = (Baud_Match_Number-1)/2 then                        
                            if s_RX_Serial = '0' then
                                Bit_Keep_Count  <= 0;  -- reset counter since we found the middle
                                NEXT_STATE      <= ST_DATA_BITS;
                            else
                                NEXT_STATE  <= ST_IDLE;
                            end if;
                        else
                            Bit_Keep_Count  <= Bit_Keep_Count + 1;
                            NEXT_STATE      <= ST_START_BIT;
                        end if; 
                        
                    -- Wait Baud_Match_Number-1 clock cycles to sample serial data
                    when ST_DATA_BITS =>                    
                        s_state_info <= '1' ;                   
                        if Bit_Keep_Count < Baud_Match_Number-1 then
                            Bit_Keep_Count <= Bit_Keep_Count + 1;
                            NEXT_STATE      <= ST_DATA_BITS;
                        else
                            Bit_Keep_Count              <= 0;
                            s_RX_Byte(Bit_Index)    <= s_RX_Serial; --Bitlerin yazildigi yer                        
                            -- Check if we have sent out all bits
                            if Bit_Index < 7 then
                                Bit_Index   <= Bit_Index + 1;
                                NEXT_STATE  <= ST_DATA_BITS;
                            else
                                Bit_Index   <= 0;
                                NEXT_STATE  <= ST_STOP_BITS;
                            end if;
                        end if;
                        
                    -- Receive Stop bit.  Stop bit = 1
                    when ST_STOP_BITS =>                    
                        s_state_info <= '1' ;                   
                        -- Wait Baud_Match_Number-1 clock cycles for Stop bit to finish
                        if Bit_Keep_Count < Baud_Match_Number-1 then
                            Bit_Keep_Count  <= Bit_Keep_Count + 1;
                            NEXT_STATE      <= ST_STOP_BITS;
                        else
                            Bit_Keep_Count <= 0 ;
                            NEXT_STATE      <= ST_CLEANUP;
                        end if;
                        
                    -- Stay here 1 clock
                    when ST_CLEANUP =>
                        s_state_info    <= '1';
                        NEXT_STATE      <= ST_IDLE;                 
                    when others =>
                        NEXT_STATE <= ST_IDLE ;                 
                end case;
            end if;
        end process p_UART_RX;
        
        -------- LATEST ADDITION --------------------------------------------
        process (s_clk, s_state_info)
        begin
            if (rising_edge(s_clk)) then            
                case NEXT_STATE_BT is       
                    when ST_BYTE_HOLD =>                    
                        RX_Byte <= s_RX_Byte ;                  
                        if ( s_state_info='0' ) then
                            NEXT_STATE_BT <= ST_BYTE_HOLD;
                        else
                            NEXT_STATE_BT <= ST_READ;
                        end if;             
                    when ST_READ =>                 
                        if ( s_state_info='1' ) then
                            NEXT_STATE_BT <=    ST_READ ;
                        else
                            NEXT_STATE_BT <=    ST_BYTE_HOLD ;
                        end if;             
                    when others =>
                        NEXT_STATE_BT <= ST_BYTE_HOLD ;                 
                end case;
            end if; 
        end process ;
                    
    end Behavioral;
    Last edited by FvM; 12th April 2018 at 09:09. Reason: Added syntax tags



    •   AltAdvertisment

        
       

  9. #9
    Advanced Member level 3
    Points: 5,356, Level: 17

    Join Date
    Feb 2015
    Posts
    887
    Helped
    256 / 256
    Points
    5,356
    Level
    17

    Re: [Moved] FPGA VHDL UART RX line how to handle incoming bytes?

    I didn't look over this too much. I suspect you are interpreting intermediate values as valid commands. Your sim doesn't show this as you expect the interface to change all bits at the same time. Try a sim where you get the data 1 bit at a time.
    --edit: keep in mind that you have a default statement that acts on invalid invalid inputs.



--[[ ]]--