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

Subversion Repositories uart_plb

[/] [uart_plb/] [trunk/] [pcores/] [uart_plb_v1_00_a/] [hdl/] [vhdl/] [rx.vhd] - Rev 2

Compare with Previous | Blame | View Log

-- $Id$
library IEEE;
use IEEE.STD_LOGIC_1164.ALL;
use IEEE.STD_LOGIC_ARITH.ALL;
use IEEE.STD_LOGIC_UNSIGNED.ALL;
 
-- Serial UART receiver
entity rcv is
    generic (DATA_BITS : integer);
    port (
        clk       : in  std_logic;  -- Clock
        rst       : in  std_logic;  -- Reset
        tick      : in  std_logic;  -- baudrate*16 tick
        sin       : in  std_logic;  -- Receiver serial input
        dout      : out std_logic_vector(DATA_BITS-1 downto 0);   -- Output data
        done      : out std_logic   -- Receiver operation finished
    );
end rcv;
 
architecture rtl of rcv is
 
    signal shift_reg      : std_logic_vector(DATA_BITS downto 0) := (others=>'1');
    signal shift_cnt      : std_logic_vector(DATA_BITS downto 0) := (others=>'1');
    signal baud_cnt       : std_logic_vector(3 downto 0);
    signal start_bit_cnt  : std_logic_vector(2 downto 0);
    signal start_rcv      : std_logic;
    signal baud_tick      : std_logic;
    signal shift_cnt_0_q  : std_logic;
 
begin
 
    dout  <= shift_reg (dout'range);
 
    process(clk)
    begin
        if rising_edge(clk) then
            if rst = '1' then
                shift_cnt_0_q <= '1';
                done <= '0';
            else
                shift_cnt_0_q <= shift_cnt(0);
                if (shift_cnt(0) = '1') and (shift_cnt_0_q <= '0') then
                    done <= '1';
                else
                    done <= '0';
                end if;
            end if;
        end if;
    end process;
 
    process(clk)
    begin
        if rising_edge(clk) then
            -- finished recv data and a start-bit comes in
            if (shift_cnt(0) = '1') and (sin = '0') then
                if (tick = '1') then
                    start_bit_cnt <= start_bit_cnt + 1;
                end if;
            else
                start_bit_cnt <= (others=>'0');
            end if;
        end if;
    end process;
 
    process(clk)
    begin
        if rising_edge(clk) then
            -- find the middle of start-bit
            if (start_bit_cnt = "111") and (tick = '1') then
                start_rcv <= '1';  -- start receiving data
            else
                start_rcv <= '0';
            end if;
        end if;
    end process;
 
    -- count baud_tick while receiving data, roll-over when overflowed
    process(clk)
    begin
        if rising_edge(clk) then
            if rst = '1' then
                baud_cnt <= (others=>'0');
            elsif (tick = '1') and (shift_cnt(0) = '0') then
                baud_cnt <= baud_cnt + 1;
            end if;
        end if;
    end process;
 
    -- generate baudrate tick from counting baud_tick 16 times
    -- to indicate it is time to receive a bit
    process(clk)
    begin
        if rising_edge(clk) then
            if (baud_cnt = "1111") and (tick = '1') then
                baud_tick <= '1';
            else
                baud_tick <= '0';
            end if;
        end if;
    end process;
 
    -- receive a bit
    process(clk)
    begin
        if rising_edge(clk) then
            if (baud_tick = '1') then
                shift_reg <= sin & shift_reg(shift_reg'left downto 1);
            end if;
        end if;
    end process;
 
    -- count how many bits have been received
    -- shift_cnt(0) will be '1' when all bits are received
    process(clk)
    begin
        if rising_edge(clk) then
            if (start_rcv = '1') then
                shift_cnt <= (others=>'0');
            elsif (baud_tick = '1') then
                shift_cnt <= '1' & shift_cnt(shift_reg'left downto 1);
            end if;
        end if;
    end process;
 
end rtl;
 

Compare with Previous | Blame | View Log

powered by: WebSVN 2.1.0

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