Aktuální adresář: FITkit /
trunk /
apps /
communication /
ds18b20 /
fpga /
one_wire.vhd
1 -- onewire.vhd: 1-wire
2 -- Copyright (C) 2009 Brno University of Technology,
3 -- Faculty of Information Technology
4 -- Author(s): Zdenek Vasicek <vasicek AT 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 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.math_pack.all;
49
50 entity onewire is
51 generic (
52 CLK_DIV : integer := 250 -- 50MHz CLK (5*50), 40MHz CLK (5*40), 20 MHZ CLK (5*20)
53 );
54 port (
55 CLK : in std_logic;
56 RESET : in std_logic;
57
58
59 CMD : in std_logic_vector(1 downto 0);
60 CMD_WE : in std_logic;
61
62 DATA_IN : in std_logic_vector(7 downto 0);
63 DATA_OUT : out std_logic_vector(7 downto 0);
64 PRESENCE : out std_logic;
65
66 BUSY : out std_logic;
67 DQ : inout std_logic
68 );
69 end onewire;
70
71
72 architecture beh of onewire is
73 signal dqclk : std_logic;
74 signal clk_cntr : std_logic_vector(log2(CLK_DIV)-1 downto 0);
75
76 signal cmd_reg : std_logic_vector(1 downto 0);
77 signal din_shreg : std_logic_vector(7 downto 0);
78 signal din_shen : std_logic;
79 signal dout_shreg : std_logic_vector(7 downto 0);
80 signal dout_shen : std_logic;
81 signal presence_reg : std_logic;
82 signal presence_we : std_logic;
83
84 signal bit_cntr : std_logic_vector(2 downto 0);
85 signal bitcntr_cmp : std_logic;
86 signal bitcntr_zero : std_logic;
87
88 type FSMstate is (SInit, SCLKWait, SReset1, SReset2, SReset3, SWrite1, SWrite2, SWrite3, SRead1, SRead2a,SRead2, SRead3);
89 signal pstate : FSMstate; -- actual state
90 signal nstate : FSMstate; -- next state
91
92 signal cntr : std_logic_vector(6 downto 0);
93 signal cntr_rst : std_logic;
94 signal cntr_en : std_logic;
95 signal cmp_100 : std_logic;
96 signal cmp_14 : std_logic;
97
98 signal dq_reg1 : std_logic;
99 signal dq_reg2 : std_logic;
100 begin
101 -- CLOCK divider (200 kHz signal)
102 -- ----------------------------------------------------------
103 dqclk <= '1' when conv_integer(clk_cntr) = CLK_DIV else '0';
104
105 freqdv: process (RESET, CLK)
106 begin
107 if (RESET = '1') then
108 clk_cntr <= (others => '0');
109 elsif (CLK'event) and (CLK = '1') then
110 if (dqclk = '1') then
111 clk_cntr <= (others => '0');
112 else
113 clk_cntr <= clk_cntr + 1;
114 end if;
115 end if;
116 end process;
117
118 -- Cycle counter
119 -- ----------------------------------------------------------
120 process (RESET, CLK)
121 begin
122 if (RESET = '1') then
123 cntr <= (others => '0');
124 elsif (CLK'event) and (CLK = '1') then
125 if (cntr_rst = '1') then
126 cntr <= (others => '0');
127 elsif (cntr_en = '1') and (dqclk = '1') then
128 cntr <= cntr + 1;
129 end if;
130 end if;
131 end process;
132 cmp_100 <= '1' when conv_integer(cntr) = 100 else '0';
133 cmp_14 <= '1' when conv_integer(cntr) = 14 else '0';
134
135 -- Data registers
136 -- ----------------------------------------------------------
137 process (RESET, CLK)
138 begin
139 if (CLK'event) and (CLK = '1') then
140 if (DQ='0') then
141 dq_reg1 <= '0';
142 else
143 dq_reg1 <= '1';
144 end if;
145 dq_reg2 <= dq_reg1;
146 end if;
147 end process;
148
149 -- CMD register
150 process (RESET, CLK)
151 begin
152 if (RESET = '1') then
153 cmd_reg <= (others => '0');
154 elsif (CLK'event) and (CLK = '1') then
155 if (CMD_WE='1') then
156 cmd_reg <= cmd;
157 end if;
158 end if;
159 end process;
160
161 -- DATA (out) shift register
162 process (RESET, CLK)
163 begin
164 if (RESET = '1') then
165 dout_shreg <= (others => '0');
166 elsif (CLK'event) and (CLK = '1') then
167 if (dout_shen = '1') then
168 dout_shreg <= dq_reg2 & dout_shreg(7 downto 1);
169 end if;
170 end if;
171 end process;
172
173 -- DATA (in) shift register
174 process (RESET, CLK)
175 begin
176 if (RESET = '1') then
177 din_shreg <= (others => '0');
178 elsif (CLK'event) and (CLK = '1') then
179 if (CMD_WE='1') then
180 din_shreg <= DATA_IN;
181 elsif (din_shen = '1') then
182 din_shreg <= '0' & din_shreg(7 downto 1);
183 end if;
184 end if;
185 end process;
186
187 -- bit counter
188 bitcntr_cmp <= '1' when conv_integer(bit_cntr) = 7 else '0';
189 bitcntr_zero <= '1' when conv_integer(bit_cntr) = 0 else '0';
190
191 process (RESET, CLK)
192 begin
193 if (RESET = '1') then
194 bit_cntr <= (others => '0');
195 elsif (CLK'event) and (CLK = '1') then
196 if (din_shen = '1') or (dout_shen='1') then
197 if (bitcntr_cmp = '1') then
198 bit_cntr <= (others => '0');
199 else
200 bit_cntr <= bit_cntr + 1;
201 end if;
202 end if;
203 end if;
204 end process;
205
206 process (RESET, CLK)
207 begin
208 if (RESET = '1') then
209 presence_reg <= '0';
210 elsif (CLK'event) and (CLK = '1') then
211 if (presence_we = '1') then
212 presence_reg <= not dq_reg2;
213 end if;
214 end if;
215 end process;
216
217 PRESENCE <= presence_reg;
218
219 DATA_OUT <= dout_shreg;
220
221 -- FSM
222 -- ----------------------------------------------------------
223 --Present State registr
224 pstatereg: process(RESET, CLK)
225 begin
226 if (RESET='1') then
227 pstate <= SInit;
228 elsif (CLK'event) and (CLK='1') then
229 pstate <= nstate;
230 end if;
231 end process;
232
233 --Next State logic
234 nstate_logic: process(pstate, CMD_WE, cmd_reg, dqclk, cmp_100, cmp_14, bitcntr_zero, din_shreg)
235 begin
236 cntr_rst <= '0';
237 cntr_en <= '0';
238 presence_we <= '0';
239 din_shen <= '0';
240 dout_shen <= '0';
241 BUSY <= '1';
242 DQ <= 'Z';
243
244 nstate <= SInit;
245 case pstate is
246 when SInit =>
247 BUSY <= '0';
248
249 nstate <= SInit;
250 if (CMD_WE='1') then
251 nstate <= SCLKWait;
252 end if;
253
254 when SCLKWait =>
255 cntr_rst <= '1';
256
257 nstate <= SCLKWait;
258 if (dqclk = '1') then
259 if (cmd_reg = "00") then
260 nstate <= SReset1;
261 elsif (cmd_reg = "01") then
262 nstate <= SWrite1;
263 elsif (cmd_reg = "10") then
264 nstate <= SRead1;
265 else
266 nstate <= SInit;
267 end if;
268 end if;
269 ----------------- Reset ------------------
270 when SReset1 =>
271 DQ <= '0';
272 cntr_en <= '1';
273
274 nstate <= SReset1;
275 if (cmp_100 = '1') then
276 cntr_rst <= '1';
277 nstate <= SReset2;
278 end if;
279
280 when SReset2 =>
281 cntr_en <= '1';
282
283 nstate <= SReset2;
284 if (cmp_14 = '1') then
285 presence_we <= '1';
286 nstate <= SReset3;
287 end if;
288
289 when SReset3 =>
290 cntr_en <= '1';
291
292 nstate <= SReset3;
293 if (cmp_100 = '1') then
294 nstate <= SInit;
295 end if;
296
297 ----------------- Write ------------------
298 when SWrite1 =>
299 cntr_en <= '1';
300 DQ <= '0';
301
302 nstate <= SWrite1;
303 if (dqclk = '1') then
304 nstate <= SWrite2;
305 end if;
306
307 when SWrite2 =>
308 cntr_en <= '1';
309 DQ <= din_shreg(0); --Data, ktera se maji zapsat
310
311 nstate <= SWrite2;
312 if (cmp_14 = '1') then
313 nstate <= SWrite3;
314 din_shen <= '1';
315 end if;
316
317 when SWrite3 =>
318 cntr_rst <= '1';
319
320 nstate <= SWrite3;
321 if (dqclk = '1') then
322 if (bitcntr_zero = '1') then
323 nstate <= SInit;
324 else
325 nstate <= SWrite1;
326 end if;
327 end if;
328
329 ----------------- Read ------------------
330 when SRead1 =>
331 cntr_en <= '1';
332 DQ <= '0';
333
334 nstate <= SRead1;
335 if (dqclk = '1') then
336 nstate <= SRead2;
337 end if;
338
339 when SRead2 =>
340 cntr_en <= '1';
341
342 nstate <= SRead2;
343 if (dqclk = '1') then
344 nstate <= SRead2a;
345 end if;
346
347 when SRead2a =>
348 --vzorkovani DQ
349 dout_shen <= '1';
350 cntr_en <= '1';
351 nstate <= SRead3;
352
353 when SRead3 =>
354 cntr_en <= '1';
355
356 nstate <= SRead3;
357 if (cmp_14 = '1') then
358 cntr_rst <= '1';
359 if (bitcntr_zero = '1') then
360 nstate <= SInit;
361 else
362 nstate <= SRead1;
363 end if;
364 end if;
365
366 when others => null;
367 end case;
368 end process;
369
370 end beh;
371
372