OpenCores
URL https://opencores.org/ocsvn/rs232_with_buffer_and_wb/rs232_with_buffer_and_wb/trunk

Subversion Repositories rs232_with_buffer_and_wb

[/] [rs232_with_buffer_and_wb/] [trunk/] [rtl/] [uart_rx.vhd] - Diff between revs 27 and 38

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 27 Rev 38
Line 1... Line 1...
 
library IEEE;
 
use IEEE.STD_LOGIC_1164.ALL;
 
use IEEE.STD_LOGIC_ARITH.ALL;
 
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
 
 No newline at end of file
 No newline at end of file
 
entity rx_func is
 
        port(   clk, reset, rx_enable : in std_logic;
 
                        rx : in std_logic;
 
 
 
                        word_width : in std_logic_vector(3 downto 0);
 
                        baud_period : in std_logic_vector(15 downto 0);
 
                        use_parity_bit, parity_type : in std_logic;
 
                        stop_bits : in std_logic_vector(1 downto 0);
 
                        idle_line_lvl : in std_logic;
 
 
 
                        start_samples : in std_logic_vector(3 downto 0); --How many correct samples should give a start bit
 
                        line_samples : in std_logic_vector(3 downto 0);          --How many samples should tip the internal rx value
 
 
 
                        data            : out std_logic_vector(7 downto 0);
 
                        data_ready      : out std_logic;
 
                        parity_error :  out std_logic;
 
                        stop_bit_error : out std_logic);
 
end entity rx_func;
 
 
 
architecture behaviour of rx_func is
 
        type state_type is (idle, data_bit0, data_bit1, data_bit2, data_bit3, data_bit4, data_bit5, data_bit6, data_bit7, parity_bit, stop_bit1, stop_bit2, data_check, data_rdy);
 
        signal current_state : state_type := idle;
 
        signal next_state, next_state_rst : state_type;
 
        signal next_state_from_data_bit4 : state_type;
 
        signal next_state_from_data_bit5 : state_type;
 
        signal next_state_from_data_bit6 : state_type;
 
        signal next_state_from_data_bit7 : state_type;
 
        signal next_state_from_stop_bit1 : state_type;
 
 
 
        signal sampled_data : std_logic_vector(9 downto 0);-- := "0000000000";
 
 
 
        signal period_count_enable : std_logic;
 
        signal period_count_q : std_logic_vector(15 downto 0);-- := "0000000000000000";
 
        signal period_count_d : std_logic_vector(15 downto 0);
 
        signal baud_tick : std_logic;
 
        signal period16_count_q : std_logic_vector(11 downto 0);-- := "000000000000";
 
        signal period16_count_d : std_logic_vector(11 downto 0);
 
        signal sample_tick : std_logic;
 
        signal sample_reg_q, sample_reg_start_bit_q : std_logic_vector(3 downto 0);-- := "0000";
 
        signal sample_reg_start_bit_d, sample_reg_d : std_logic_vector(3 downto 0);
 
        signal rx_sampled_q : std_logic;-- := '0';
 
        signal rx_sampled_d : std_logic;
 
        signal xored_sampled_data_bit_q : std_logic;-- := '0';
 
        signal xored_sampled_data_bit_d : std_logic;
 
 
 
begin
 
-------------------------
 
-- Combinational logic --
 
-------------------------
 
 
 
--State Logic
 
        next_state                                      <=      idle when reset = '1' else
 
                                                                        next_state_rst;
 
        with current_state select
 
                next_state_rst                  <=      data_bit0                                       when idle,              --Identifying start bit
 
                                                                        data_bit1                                       when data_bit0,
 
                                                                        data_bit2                                       when data_bit1,
 
                                                                        data_bit3                                       when data_bit2,
 
                                                                        data_bit4                                       when data_bit3,
 
                                                                        next_state_from_data_bit4       when data_bit4,
 
                                                                        next_state_from_data_bit5       when data_bit5,
 
                                                                        next_state_from_data_bit6       when data_bit6,
 
                                                                        next_state_from_data_bit7       when data_bit7,
 
                                                                        stop_bit1                                       when parity_bit,
 
                                                                        next_state_from_stop_bit1       when stop_bit1,
 
                                                                        data_check                                      when stop_bit2,
 
                                                                        data_rdy                                        when data_check,
 
                                                                        idle                                            when data_rdy,
 
                                                                        idle                                            when others;
 
 
 
        next_state_from_data_bit4 <=    parity_bit      when word_width = "0101" and use_parity_bit = '1' else
 
                                                                        stop_bit1       when word_width = "0101" and use_parity_bit = '0' else
 
                                                                        data_bit5;
 
 
 
        next_state_from_data_bit5 <=    parity_bit      when word_width = "0110" and use_parity_bit = '1' else
 
                                                                        stop_bit1       when word_width = "0110" and use_parity_bit = '0' else
 
                                                                        data_bit6;
 
 
 
        next_state_from_data_bit6 <=    parity_bit      when word_width = "0111" and use_parity_bit = '1' else
 
                                                                        stop_bit1       when word_width = "0111" and use_parity_bit = '0' else
 
                                                                        data_bit7;
 
 
 
        next_state_from_data_bit7 <=    parity_bit      when use_parity_bit = '1' else
 
                                                                        stop_bit1;
 
 
 
        next_state_from_stop_bit1 <=    stop_bit2       when stop_bits = "10" else
 
                                                                        data_check;
 
 
 
 
 
--Sample logic
 
        period16_count_d                <=      period16_count_q + 1 when reset = '0' and period16_count_q /= baud_period(15 downto 4) else
 
                                                                "000000000001";
 
        sample_tick                     <=      '1' when period16_count_q = baud_period(15 downto 4) else
 
                                                                '0';
 
 
 
--Baud logic
 
        with current_state select
 
                period_count_enable             <=      '0' when idle,
 
                                                                        '0' when data_check,
 
                                                                        '0' when data_rdy,
 
                                                                        '1' when others;
 
        period_count_d                  <=      period_count_q + 1 when reset = '0' and period_count_q /= baud_period else
 
                                                                "0000000000000001";
 
        baud_tick                               <=      '1' when period_count_q = baud_period else
 
                                                                '0';
 
 
 
--RX sampled, by saturation counter
 
        sample_reg_d                    <=      sample_reg_q + 1        when reset = '0' and rx = '1' and sample_reg_q /= line_samples else
 
                                                                sample_reg_q - 1        when reset = '0' and rx = '0' and sample_reg_q /= "0000" else
 
                                                                sample_reg_q            when reset = '0' else
 
                                                                "0000";
 
 
 
        rx_sampled_d                    <=  '1' when reset = '0' and sample_reg_q = line_samples else
 
                                                                '0' when reset = '0' and sample_reg_q = "0000" else
 
                                                                rx_sampled_q;
 
 
 
        sample_reg_start_bit_d  <=      sample_reg_start_bit_q + 1      when reset = '0' and rx /= idle_line_lvl and sample_reg_start_bit_q /= start_samples else
 
                                                                sample_reg_start_bit_q - 1      when reset = '0' and rx  = idle_line_lvl and sample_reg_start_bit_q /= "0000" else
 
                                                                sample_reg_start_bit_q          when reset = '0' else
 
                                                                "0000";
 
 
 
--Parity bit
 
        with current_state select
 
                xored_sampled_data_bit_d        <=      '0' when idle,
 
                                                                                xored_sampled_data_bit_q when stop_bit1,
 
                                                                                xored_sampled_data_bit_q when stop_bit2,
 
                                                                                xored_sampled_data_bit_q when data_check,
 
                                                                                xored_sampled_data_bit_q xor rx_sampled_q when others;
 
 
 
--Reciving status signals
 
        data_ready <=           '1' when current_state = data_rdy else
 
                                                '0';
 
        parity_error    <=      '1' when xored_sampled_data_bit_q /= parity_type and current_state = data_check else
 
                                                '0';
 
        stop_bit_error  <=      '1' when current_state = data_check and (sampled_data(8) /= idle_line_lvl or (sampled_data(9) /= idle_line_lvl and stop_bits = "10")) else
 
                                                '0';
 
 
 
 
 
--------------------
 
-- Register logic --
 
--------------------
 
        register_logic : process(clk, reset, rx_enable, period_count_enable, sample_tick, baud_tick, current_state, use_parity_bit)
 
        begin
 
                if rising_edge(clk) then
 
                        --sample counter
 
                        if rx_enable = '1' or reset = '1' then
 
                                period16_count_q        <= period16_count_d;
 
                        end if;
 
 
 
                        --baud counter
 
                        if period_count_enable = '1' or reset = '1' then
 
                                period_count_q          <= period_count_d;
 
                        end if;
 
 
 
                        if sample_tick = '1' then
 
                                sample_reg_q                    <= sample_reg_d;
 
                                rx_sampled_q                    <= rx_sampled_d;
 
                                sample_reg_start_bit_q  <= sample_reg_start_bit_d;
 
                        end if;
 
 
 
                        if baud_tick = '1' or (current_state = idle and sample_reg_start_bit_q = start_samples) or current_state = data_check or current_state = data_rdy then
 
                                current_state <= next_state;
 
                        end if;
 
 
 
                        if baud_tick = '1' and current_state = data_bit0 then
 
                                sampled_data(0) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = data_bit1 then
 
                                sampled_data(1) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = data_bit2 then
 
                                sampled_data(2) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = data_bit3 then
 
                                sampled_data(3) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = data_bit4 then
 
                                sampled_data(4) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = data_bit5 then
 
                                sampled_data(5) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = data_bit6 then
 
                                sampled_data(6) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = data_bit7 then
 
                                sampled_data(7) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = stop_bit1 then
 
                                sampled_data(8) <= rx_sampled_q;
 
                        end if;
 
                        if baud_tick = '1' and current_state = stop_bit2 then
 
                                sampled_data(9) <= rx_sampled_q;
 
                        end if;
 
 
 
                        if current_state = data_check then
 
                                data <= sampled_data(7 downto 0);
 
                        end if;
 
 
 
                        if baud_tick = '1' and use_parity_bit = '1' then
 
                                xored_sampled_data_bit_q <= xored_sampled_data_bit_d;
 
                        end if;
 
                end if;
 
        end process register_logic;
 
 
 
end architecture behaviour;
 No newline at end of file
 No newline at end of file

powered by: WebSVN 2.1.0

© copyright 1999-2024 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.