Aktuální adresář: FITkit /
trunk /
fpga /
ctrls /
serial /
serial_rx.vhd
1 -- serial_rx.vhd : Receiver
2 -- Copyright (C) 2007 Brno University of Technology,
3 -- Faculty of Information Technology
4 -- Author(s): Zdenek Vasicek (xvasic11 AT stud.fit.vutbr.cz)
5 --
6 -- LICENSE TERMS
7 --
8 -- Redistribution and use in source and binary forms, with or without
9 -- modification, are permitted provided that the following conditions
10 -- are met:
11 -- 1. Redistributions of source code must retain the above copyright
12 -- notice, this list of conditions and the following disclaimer.
13 -- 2. Redistributions in binary form must reproduce the above copyright
14 -- notice, this list of conditions and the following disclaimer in
15 -- the documentation and/or other materials provided with the
16 -- distribution.
17 -- 3. All advertising materials mentioning features or use of this software
18 -- or firmware must display the following acknowledgement:
19 --
20 -- This product includes software developed by the University of
21 -- Technology, Faculty of Information Technology, Brno and its
22 -- contributors.
23 --
24 -- 4. Neither the name of the Company nor the names of its contributors
25 -- may be used to endorse or promote products derived from this
26 -- software without specific prior written permission.
27 --
28 -- This software or firmware is provided ``as is'', and any express or implied
29 -- warranties, including, but not limited to, the implied warranties of
30 -- merchantability and fitness for a particular purpose are disclaimed.
31 -- In no event shall the company or contributors be liable for any
32 -- direct, indirect, incidental, special, exemplary, or consequential
33 -- damages (including, but not limited to, procurement of substitute
34 -- goods or services; loss of use, data, or profits; or business
35 -- interruption) however caused and on any theory of liability, whether
36 -- in contract, strict liability, or tort (including negligence or
37 -- otherwise) arising in any way out of the use of this software, even
38 -- if advised of the possibility of such damage.
39 --
40 -- $Id$
41 --
42 --
43
44 library IEEE;
45 use IEEE.STD_LOGIC_1164.ALL;
46 use IEEE.STD_LOGIC_ARITH.ALL;
47 use IEEE.STD_LOGIC_UNSIGNED.ALL;
48 use work.serial_cfg.all;
49
50 entity serial_receiver is
51 generic (
52 SPEED : serial_speed := s460800Bd;
53 DATAWIDTH : serial_databit := 8;
54 STOPBITS : serial_stopbit := 1;
55 PARITY : serial_parity := sParityEven
56 );
57 port (
58 CLK : in std_logic;
59 RESET : in std_logic;
60
61 DATA_OUT : out std_logic_vector(DATAWIDTH-1 downto 0);
62 DATA_VLD : out std_logic;
63
64 BUSY : out std_logic;
65 ERR : out std_logic;
66 ERR_RST : in std_logic;
67
68 -- Serial interface
69 RXD : in std_logic
70 );
71 end serial_receiver;
72
73
74 architecture behavioral of serial_receiver is
75
76 type FSMstate is (SIdle, SWaitStartBit, SDataBits, SCheckParity);
77 signal pstate : FSMstate; -- actual state
78 signal nstate : FSMstate; -- next state
79
80 signal rx_en : std_logic;
81 signal rxd_reg : std_logic_vector(2 downto 0);
82 signal startbit : std_logic;
83
84 signal smplcnt_reg : std_logic_vector(3 downto 0) := (others => '0');
85 signal smplcnt_en : std_logic;
86 signal smplcnt_cmp : std_logic;
87 signal sample_en : std_logic;
88 signal sbit_reg : std_logic_vector(4 downto 0) := (others => '1');
89 signal sbit_majority : std_logic;
90 signal parity_reg : std_logic;
91 signal parity_rst : std_logic;
92
93 signal data_shreg : std_logic_vector(DATAWIDTH downto 0) := (others => '0');
94 signal bitcnt_reg : std_logic_vector(3 downto 0);
95 signal bitcnt_rst : std_logic;
96 signal bitcnt_cmp : std_logic;
97
98 signal err_reg : std_logic;
99 signal err_en : std_logic;
100
101 component serial_gen
102 generic (
103 SPEED : serial_speed;
104 FREQMULT : positive
105 );
106 port(
107 CLK : in std_logic;
108 RESET : in std_logic;
109 EN : in std_logic;
110
111 OUTPUT : out std_logic
112 );
113 end component;
114
115 component majority_five
116 port (
117 D : in std_logic_vector(4 downto 0);
118 Q : out std_logic
119 );
120 end component;
121
122 begin
123 -- ===========================================================================================================
124 -- Receiver
125 -- ===========================================================================================================
126 DATA_OUT <= data_shreg(DATAWIDTH-1 downto 0);
127
128 --Baudrate generator (8x faster than tx)
129 rxclk_gen: serial_gen
130 generic map (
131 SPEED => SPEED,
132 FREQMULT => 8
133 )
134 port map (
135 CLK => CLK,
136 RESET => RESET,
137 EN => '1',
138 OUTPUT => rx_en
139 );
140
141 -- rxd sample register
142 process (RESET, CLK)
143 begin
144 if (RESET = '1') then
145 rxd_reg <= (others => '1');
146 elsif (CLK'event) and (CLK = '1') then
147 rxd_reg <= rxd_reg(1 downto 0) & RXD;
148 end if;
149 end process;
150
151 -- start bit detector
152 startbit <= rxd_reg(2) and (not rxd_reg(1)) and (not rxd_reg(0));
153
154 -- Bit Sample counter
155 process (RESET, CLK)
156 begin
157 if (RESET = '1') then
158 smplcnt_reg <= (others => '0');
159 elsif (CLK'event) and (CLK = '1') then
160 if (smplcnt_en='1') and (rx_en='1') then
161 if (smplcnt_cmp='1') then
162 smplcnt_reg <= (others => '0');
163 else
164 smplcnt_reg <= smplcnt_reg + 1;
165 end if;
166 end if;
167 end if;
168 end process;
169 -- last sample
170 smplcnt_cmp <= '1' when (conv_integer(smplcnt_reg) = 7) else '0';
171 -- sample enabled
172 sample_en <= '0' when (conv_integer(smplcnt_reg) = 0) or (conv_integer(smplcnt_reg) = 1) or
173 (conv_integer(smplcnt_reg) = 7) else '1';
174
175 -- sample shift register (5 samples)
176 process (CLK)
177 begin
178 if (CLK'event) and (CLK = '1') then
179 if (sample_en='1') and (rx_en='1') then
180 sbit_reg <= sbit_reg(3 downto 0) & rxd_reg(2);
181 end if;
182 end if;
183 end process;
184
185 -- majority of five inputs
186 sbitmajority: majority_five
187 port map (
188 D => sbit_reg,
189 Q => sbit_majority
190 );
191
192 -- received data shift register
193 process (CLK)
194 begin
195 if (CLK'event) and (CLK = '1') then
196 if (smplcnt_cmp='1') and (rx_en='1') then
197 data_shreg <= sbit_majority & data_shreg(DATAWIDTH downto 1);
198 end if;
199 end if;
200 end process;
201
202 -- Parity register
203 process (CLK)
204 begin
205 if (CLK'event) and (CLK = '1') then
206 if (parity_rst='1') then
207 parity_reg <= '0';
208 elsif (smplcnt_cmp='1') and (rx_en='1') then
209 parity_reg <= parity_reg xor sbit_majority;
210 end if;
211 end if;
212 end process;
213
214 --Bit counter
215 process (CLK)
216 begin
217 if (CLK'event) and (CLK = '1') then
218 if (bitcnt_rst='1') then
219 bitcnt_reg <= (others => '0');
220 elsif (smplcnt_cmp='1') and (rx_en='1') then
221 bitcnt_reg <= bitcnt_reg + 1;
222 end if;
223 end if;
224 end process;
225
226 --all bits received comparator
227 bitcnt_cmp <= '1' when ((PARITY = sParityNone) and (conv_integer(bitcnt_reg) = DATAWIDTH-1)) or
228 ((PARITY /= sParityNone) and (conv_integer(bitcnt_reg) = DATAWIDTH)) else '0';
229
230 --Error register
231 error_reg: process (RESET, CLK)
232 begin
233 if (RESET = '1') then
234 err_reg <= '0';
235 elsif (CLK'event) and (CLK = '1') then
236 if (err_en='1') then
237 err_reg <= '1';
238 elsif (ERR_RST='1') then
239 err_reg <= '0';
240 end if;
241 end if;
242 end process;
243
244 ERR <= err_reg;
245
246 --Present State registr
247 pstatereg: process(RESET, CLK)
248 begin
249 if (RESET='1') then
250 pstate <= SIdle;
251 elsif (CLK'event) and (CLK='1') then
252 pstate <= nstate;
253 end if;
254 end process;
255
256 --Next State logic, Output logic
257 nstate_logic: process(pstate, startbit, smplcnt_cmp, rx_en, sbit_majority, bitcnt_cmp, parity_reg)
258 begin
259 nstate <= SIdle;
260 smplcnt_en <= '0';
261 bitcnt_rst <= '0';
262 DATA_VLD <= '0';
263 BUSY <= '1';
264 parity_rst <= '0';
265 err_en <= '0';
266
267 case pstate is
268 when SIdle =>
269 BUSY <= '0';
270 if (startbit='1') then
271 nstate <= SWaitStartBit;
272 end if;
273
274 -- Sample start bit
275 when SWaitStartBit =>
276 nstate <= SWaitStartBit;
277
278 smplcnt_en <= '1';
279 if (smplcnt_cmp='1') and (rx_en='1') then --first bit sampled
280 if (sbit_majority='0') then
281 nstate <= SDataBits;
282 bitcnt_rst <= '1';
283 parity_rst <= '1';
284 else
285 nstate <= SIdle;
286 end if;
287 end if;
288
289 -- Receive databits
290 when SDataBits =>
291 nstate <= SDataBits;
292 smplcnt_en <= '1';
293
294 if (smplcnt_cmp='1') and (rx_en='1') and (bitcnt_cmp='1') then
295 if (PARITY = sParityNone) then
296 nstate <= SIdle;
297 -- Received valid bits
298 DATA_VLD <= '1';
299 else
300 nstate <= SCheckParity;
301 end if;
302 end if;
303
304 -- Parity check
305 when SCheckParity =>
306 nstate <= SCheckParity;
307
308 smplcnt_en <= '1';
309 if ((PARITY = sParityEven) and (parity_reg='0')) or ((PARITY = sParityOdd) and (parity_reg='1')) then
310 nstate <= SIdle;
311 -- Received valid bits
312 DATA_VLD <= '1';
313 else
314 err_en <= '1';
315 nstate <= SIdle;
316 end if;
317
318 when others => null;
319 end case;
320 end process;
321
322 end behavioral;
323
324