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] - Blame information for rev 2

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 gavinux
-- $Id$
2
library IEEE;
3
use IEEE.STD_LOGIC_1164.ALL;
4
use IEEE.STD_LOGIC_ARITH.ALL;
5
use IEEE.STD_LOGIC_UNSIGNED.ALL;
6
 
7
-- Serial UART receiver
8
entity rcv is
9
    generic (DATA_BITS : integer);
10
    port (
11
        clk       : in  std_logic;  -- Clock
12
        rst       : in  std_logic;  -- Reset
13
        tick      : in  std_logic;  -- baudrate*16 tick
14
        sin       : in  std_logic;  -- Receiver serial input
15
        dout      : out std_logic_vector(DATA_BITS-1 downto 0);   -- Output data
16
        done      : out std_logic   -- Receiver operation finished
17
    );
18
end rcv;
19
 
20
architecture rtl of rcv is
21
 
22
    signal shift_reg      : std_logic_vector(DATA_BITS downto 0) := (others=>'1');
23
    signal shift_cnt      : std_logic_vector(DATA_BITS downto 0) := (others=>'1');
24
    signal baud_cnt       : std_logic_vector(3 downto 0);
25
    signal start_bit_cnt  : std_logic_vector(2 downto 0);
26
    signal start_rcv      : std_logic;
27
    signal baud_tick      : std_logic;
28
    signal shift_cnt_0_q  : std_logic;
29
 
30
begin
31
 
32
    dout  <= shift_reg (dout'range);
33
 
34
    process(clk)
35
    begin
36
        if rising_edge(clk) then
37
            if rst = '1' then
38
                shift_cnt_0_q <= '1';
39
                done <= '0';
40
            else
41
                shift_cnt_0_q <= shift_cnt(0);
42
                if (shift_cnt(0) = '1') and (shift_cnt_0_q <= '0') then
43
                    done <= '1';
44
                else
45
                    done <= '0';
46
                end if;
47
            end if;
48
        end if;
49
    end process;
50
 
51
    process(clk)
52
    begin
53
        if rising_edge(clk) then
54
            -- finished recv data and a start-bit comes in
55
            if (shift_cnt(0) = '1') and (sin = '0') then
56
                if (tick = '1') then
57
                    start_bit_cnt <= start_bit_cnt + 1;
58
                end if;
59
            else
60
                start_bit_cnt <= (others=>'0');
61
            end if;
62
        end if;
63
    end process;
64
 
65
    process(clk)
66
    begin
67
        if rising_edge(clk) then
68
            -- find the middle of start-bit
69
            if (start_bit_cnt = "111") and (tick = '1') then
70
                start_rcv <= '1';  -- start receiving data
71
            else
72
                start_rcv <= '0';
73
            end if;
74
        end if;
75
    end process;
76
 
77
    -- count baud_tick while receiving data, roll-over when overflowed
78
    process(clk)
79
    begin
80
        if rising_edge(clk) then
81
            if rst = '1' then
82
                baud_cnt <= (others=>'0');
83
            elsif (tick = '1') and (shift_cnt(0) = '0') then
84
                baud_cnt <= baud_cnt + 1;
85
            end if;
86
        end if;
87
    end process;
88
 
89
    -- generate baudrate tick from counting baud_tick 16 times
90
    -- to indicate it is time to receive a bit
91
    process(clk)
92
    begin
93
        if rising_edge(clk) then
94
            if (baud_cnt = "1111") and (tick = '1') then
95
                baud_tick <= '1';
96
            else
97
                baud_tick <= '0';
98
            end if;
99
        end if;
100
    end process;
101
 
102
    -- receive a bit
103
    process(clk)
104
    begin
105
        if rising_edge(clk) then
106
            if (baud_tick = '1') then
107
                shift_reg <= sin & shift_reg(shift_reg'left downto 1);
108
            end if;
109
        end if;
110
    end process;
111
 
112
    -- count how many bits have been received
113
    -- shift_cnt(0) will be '1' when all bits are received
114
    process(clk)
115
    begin
116
        if rising_edge(clk) then
117
            if (start_rcv = '1') then
118
                shift_cnt <= (others=>'0');
119
            elsif (baud_tick = '1') then
120
                shift_cnt <= '1' & shift_cnt(shift_reg'left downto 1);
121
            end if;
122
        end if;
123
    end process;
124
 
125
end rtl;

powered by: WebSVN 2.1.0

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