1 | library ieee;
|
2 | use ieee.std_logic_1164.all;
|
3 | use ieee.std_logic_unsigned.all;
|
4 | use ieee.std_logic_arith.all;
|
5 |
|
6 |
|
7 | entity uart is
|
8 |
|
9 | port (
|
10 | clk : in std_logic;
|
11 | reset : in std_logic;
|
12 | seriell_in : in std_logic;
|
13 | seriell_out : out std_logic_vector(7 downto 0) := (others => '0');
|
14 | seriell_ctr_out : out std_logic := '0';
|
15 | test_out : out std_logic_vector(7 downto 0):= (others => '0'));
|
16 |
|
17 | end uart;
|
18 |
|
19 |
|
20 | architecture rtl of uart is
|
21 |
|
22 | --type and signal for the finit state machine
|
23 | type t_state is (IDLE, START, DATS, PARITY, STOP);
|
24 | signal presentstate : t_state;
|
25 | signal nextstate : t_state;
|
26 |
|
27 | --Signal for the prescaler
|
28 | signal precount : std_logic := '0';
|
29 |
|
30 | --Signal for puffering the input
|
31 | signal mem_input : std_logic_vector(7 downto 0) := (others => '0');
|
32 |
|
33 | --constant for the baudrate
|
34 | constant baudrate : std_logic_vector(5 downto 0) := conv_std_logic_vector(13,6);--baudrate = 8*460,8kBit/s
|
35 |
|
36 | begin -- rtl
|
37 |
|
38 | -- purpose: Prescaler for the uart
|
39 | -- type : sequential
|
40 | -- inputs : clk48, reset_n
|
41 | -- outputs: precount
|
42 | Prescaler: process (clk, reset)
|
43 | variable count : std_logic_vector(5 downto 0) := (others => '0');
|
44 | begin -- process Prescaler
|
45 | if reset = '0' then -- asynchronous reset (active low)
|
46 | count := (others => '0');
|
47 | presentstate <= IDLE;
|
48 | elsif clk'event and clk = '1' then -- rising clock edge
|
49 | presentstate <= nextstate; -- set the presentstate to the nextstate
|
50 | precount <= '0'; -- reset of the variable precount
|
51 | count := count + 1;
|
52 | if count = baudrate then
|
53 | count := (others => '0');
|
54 | precount <= '1'; --set of the variable precount
|
55 | end if;
|
56 |
|
57 | end if;
|
58 | end process Prescaler;
|
59 |
|
60 |
|
61 | -- purpose: Sequential Process for the fsm
|
62 | -- type : sequential
|
63 | -- inputs : clk48, reset_n
|
64 | -- outputs: presentstate
|
65 | seqfsm2: process (clk, reset)
|
66 |
|
67 | variable count : std_logic_vector(3 downto 0) := (others => '0');
|
68 | variable dat1 : std_logic_vector(2 downto 0) := (others => '0');
|
69 | variable dat0 : std_logic_vector(2 downto 0) := (others => '1');
|
70 | variable pos : integer range 0 to 8 := 0;
|
71 |
|
72 | begin -- process seqfsm2
|
73 | if reset = '0' then -- asynchronous reset (active low)
|
74 |
|
75 | elsif clk'event and clk = '1' then -- rising clock edge
|
76 | seriell_ctr_out <= '0';
|
77 | if precount = '1' then
|
78 | case presentstate is
|
79 | -------------------------------------------------------------------------------
|
80 | -- IDLE State
|
81 | -------------------------------------------------------------------------------
|
82 | when IDLE =>
|
83 | mem_input <= (others => '0');
|
84 | if seriell_in = '0' then -- if seriell_in = 0 the receiving starts
|
85 | nextstate <= START;
|
86 | end if;
|
87 | -------------------------------------------------------------------
|
88 | -- START State
|
89 | -------------------------------------------------------------------
|
90 | when START =>
|
91 | pos := 0;
|
92 | if seriell_in = '0' then
|
93 | count := count + 1;
|
94 | if count = conv_std_logic_vector(7,4) then -- when there were 8 zeros the startbit is finished
|
95 | nextstate <= DATS;
|
96 | dat1 := (others => '0') ;
|
97 | dat0 := (others => '1');
|
98 | count := (others => '0');
|
99 | end if;
|
100 | else
|
101 | nextstate <= IDLE; -- when there is a error bei the startbis change back to IDLE Mode
|
102 | end if;
|
103 | ---------------------------------------------------------------------
|
104 | -- DATS State
|
105 | ---------------------------------------------------------------------
|
106 | when DATS =>
|
107 | if seriell_in = '0' then
|
108 | dat0 := dat0 - 1;
|
109 | count := count + 1;
|
110 | end if;
|
111 | if seriell_in = '1' then
|
112 | dat1 := dat1 + 1;
|
113 | count := count + 1;
|
114 | end if;
|
115 |
|
116 | if count = conv_std_logic_vector(5,4) and dat1 = conv_std_logic_vector(5,3) then
|
117 | mem_input(pos) <= '1'; --when ther were five times a one the Bitis set to 1
|
118 | end if;
|
119 | if count = conv_std_logic_vector(5,4) and dat0 = conv_std_logic_vector(2,3) then
|
120 | mem_input(pos) <= '0'; --when there were five times a zero the Bit is set to 0
|
121 | end if;
|
122 |
|
123 | if count = conv_std_logic_vector(8,4) then
|
124 | pos := pos + 1;
|
125 | dat1 := (others => '0');
|
126 | dat0 := (others => '1');
|
127 | count := (others => '0');
|
128 | if pos = 8 then -- if 8 Bits are received he change to the STOP State
|
129 | nextstate <= PARITY;
|
130 | end if;
|
131 | end if;
|
132 | ---------------------------------------------------------------------
|
133 | -- PARITY State
|
134 | ---------------------------------------------------------------------
|
135 | when PARITY =>
|
136 | --In this state you have the possibility to control the message
|
137 | --with the parity bit.
|
138 | count := count + 1;
|
139 | if count = conv_std_logic_vector(8,4) then --if he received the Stopbit he change to the IDLE State
|
140 | nextstate <= STOP;
|
141 | count := (others => '0');
|
142 | end if;
|
143 | ---------------------------------------------------------------------
|
144 | -- STOP State
|
145 | ---------------------------------------------------------------------
|
146 | when STOP => -- STOP State
|
147 | if seriell_in = '1' then
|
148 | count := count + 1;
|
149 | if count = conv_std_logic_vector(8,4) then --if he received the Stopbit he change to the IDLE State
|
150 | nextstate <= IDLE;
|
151 | count := (others => '0');
|
152 | dat1 := (others => '0');
|
153 | dat0 := (others => '1');
|
154 | seriell_out <= mem_input;
|
155 | test_out <= mem_input;
|
156 | seriell_ctr_out <= '1';
|
157 | end if;
|
158 | end if;
|
159 | when others => nextstate <= IDLE; --if there is an error the fsm go
|
160 | --back to the IDLE state
|
161 | end case;
|
162 | end if;
|
163 | end if;
|
164 | end process seqfsm2;
|
165 |
|
166 |
|
167 | end rtl;
|