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

Subversion Repositories onewire

[/] [onewire/] [trunk/] [HDL/] [ow_search.vhd] - Blame information for rev 4

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 skeptonomi
----------------------------------------------------------------------------------
2
--  <c>2018 william b hunter
3
--    This file is part of ow2rtd.
4
--
5
--    ow2rtd is free software: you can redistribute it and/or modify
6
--    it under the terms of the GNU Lessor General Public License as published by
7
--    the Free Software Foundation, either version 3 of the License, or
8
--    (at your option) any later version.
9
--
10
--    ow2rtd is distributed in the hope that it will be useful,
11
--    but WITHOUT ANY WARRANTY; without even the implied warranty of
12
--    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13
--    GNU General Public License for more details.
14
--
15
--    You should have received a copy of the GNU Lessor General Public License
16
--    along with ow2rtd.  If not, see <https://www.gnu.org/licenses/>.
17
-----------------------------------------------------------------------------------  
18
--  Create Date: 5/15/2018
19
--  file: ow_search.vhd
20
--  description: searches a one wire bus for up to 8 one wire devices, and reports
21
--    the 8 IDs. If there are more than 8 IDs or if a device disapears during the
22
--    search it will activate the err flag. Only DS1820 devices are supported
23
--
24
-----------------------------------------------------------------------------------  
25
 
26
library IEEE;
27
use IEEE.STD_LOGIC_1164.ALL;
28
use IEEE.numeric_std.all;
29
 
30
-------------------------------------------------------------------------------------
31
-- Entity declaration
32
-------------------------------------------------------------------------------------
33
entity ow_search is
34
  port (
35
    --global signals
36
    clk              : in    std_logic;
37
    srst             : in    std_logic;
38
    --signals to upper layer hierarchy
39
    start            : in    std_logic;
40
    busyin           : in    std_logic;  --busy signal from either ow_byte or ow_bit
41
    busy             : out   std_logic;  --busy indication to higher level modules
42
    error            : out   std_logic;  --indicates a problem on the bus
43
    --signals to lower layer hierarchy (ow_bit and ow_byte)
44
    rdbit            : out   std_logic;  --strobe to read a bit from ow_bit
45
    wrbit            : out   std_logic;  --strobe to write a bit to ow_bit
46
    zzbit            : out   std_logic;  --strobe to send/recieve init/response pulses
47
    obit             : out   std_logic;  --the bit to write in a wrbit command to ow_bit
48
    ibit             : in    std_logic;  --the data recieved from a rdbit command to the ow_bit
49
    wrbyte           : out   std_logic;  --strobe to wrte a byte to ow_byte
50
    obyte            : out   std_logic_vector(7 downto 0);  --data to write to the ow_byte
51
    --interface to id ram
52
    id_num           : out   std_logic_vector(4 downto 0); --index of the id to read or write
53
    id_bit           : out   std_logic_vector(5 downto 0); --index of the bit to read or write
54
    id_rbit          : in    std_logic;  --bit value of the currently indexed bit of the current rom
55
    id_wbit          : out   std_logic;  --bit value to write to the currently indexed bit
56
    id_we            : out   std_logic   --write the currently indexed bit
57
  );
58
end ow_search;
59
 
60
-------------------------------------------------------------------------------------
61
-- Architecture declaration
62
-------------------------------------------------------------------------------------
63
architecture rtl of ow_search is
64
 
65
 
66 4 skeptonomi
  type   h_state_type is (H_IDLE, H_RST, H_WRCMD, H_READBIT, H_READCMP, H_PARSE, H_INCLOOP, H_FILL, H_ERROR);
67 2 skeptonomi
  signal h_state : h_state_type := H_IDLE;
68
  type   f_state_type is (F_IDLE, F_FIND, F_INC);
69
  signal f_state : f_state_type := F_IDLE;
70
 
71
  signal idcnt : integer range 0 to 31;
72 4 skeptonomi
  signal lastfork : integer range 0 to 64;
73
  signal zerofork : integer range 0 to 64;
74 2 skeptonomi
  signal idbitnum : integer range 0 to 63;
75
        signal lastdev  : std_logic := '0';
76
        signal h_err    : std_logic := '0';
77
        signal f_err    : std_logic := '0';
78
        signal irdbit   : std_logic := '0';
79
  signal iwrbit   : std_logic := '0';
80
  signal iwe      : std_logic := '0';
81
  signal iobit    : std_logic := '0';
82
  signal iwrbyte  : std_logic := '0';
83
        signal izzbit   : std_logic := '0';
84
  signal rxpat    : std_logic_vector(1 downto 0);
85
        signal h_start  : std_logic := '0';
86
        signal restart  : std_logic := '0';
87
        signal h_busy   : std_logic := '0';
88
 
89
  constant scan_cmd  : std_logic_vector(7 downto 0) := x"f0";
90
 
91
 
92
  attribute mark_debug : string;
93
  attribute mark_debug of f_state : signal is "true";
94
  attribute mark_debug of h_state : signal is "true";
95
        attribute mark_debug of idbitnum  : signal is "true";
96
  attribute mark_debug of lastfork  : signal is "true";
97 4 skeptonomi
  attribute mark_debug of zerofork  : signal is "true";
98 2 skeptonomi
  attribute mark_debug of rxpat     : signal is "true";
99
  attribute mark_debug of iwrbyte   : signal is "true";
100
  attribute mark_debug of irdbit    : signal is "true";
101
  attribute mark_debug of iwrbit    : signal is "true";
102
  attribute mark_debug of iwe       : signal is "true";
103
  attribute mark_debug of iobit     : signal is "true";
104
  attribute mark_debug of id_rbit   : signal is "true";
105
  attribute mark_debug of obyte     : signal is "true";
106
  attribute mark_debug of lastdev     : signal is "true";
107
  attribute mark_debug of start     : signal is "true";
108
  attribute mark_debug of busyin     : signal is "true";
109
 
110
begin
111
 
112
  ------------------------------------------------------
113
  --    HUNT - search for the next device on bus     ---
114
  ------------------------------------------------------
115
  --p_hunt - hunts for the next device using the algorithm described in Maxim (Analog Devices) app note APP187
116
        -- the app note is modified slightly for optimization in VHDL
117 4 skeptonomi
        -- the algorithm works by taking successive passes through the address field with each pass revealing the next device
118
        --  address in alphabetic order. The first pass takes the 0 path at each conflicting address bit (or fork). By keeping
119
        --  track of the last conflicting bit in variable zerofork/lastfork, the algorithm knows were to deviate from the
120
        --  present address on the next pass. On subsequent passes, for all conflicts up to the lastfork,
121
        --  the same fork is taken as was taken on the previous pass, which could be a 1 or 0. At the fork at the lastfork,
122
        --  the 1 path is taken, because the 0 path was taken in the previous pass. The variable zerofork is used to keep track
123
        --  of the last fork for this pass at which a zero path was taken, and lastfork is the zerofork from the previous pass.
124
        --  zerofork and lastfork are set to 64 if there are no zero forks taken.
125
        --  If no zero forks were taken, then the last device was found and the lastdev is set, afterwhich the FILL state
126
        --  is used to zero out the remaining unused ID memeory locations 
127
        -- 
128 2 skeptonomi
  p_hunt : process (clk)
129
  begin
130
    if rising_edge(clk) then
131
      if srst = '1' or restart = '1' then
132 4 skeptonomi
        --Start a new search, put all signals into default state, and start in H_IDLE state
133 2 skeptonomi
        h_state <= H_IDLE;
134
        idbitnum  <= 0;
135 4 skeptonomi
                                lastfork <= 64;
136
                                zerofork <= 64;
137 2 skeptonomi
                                lastdev <= '0';
138
                                rxpat   <= "00";
139
                                h_err <= '0';
140
                                iwrbyte <= '0';
141
                                izzbit <= '0';
142
                                irdbit <= '0';
143
                                iwrbit <= '0';
144
                                iwe <= '0';
145
                                iobit <= '0';
146
                          obyte <= x"00";
147
      else
148
        case h_state is
149
                                        when H_IDLE =>
150 4 skeptonomi
                                                --when in idle, all signals in default state
151
            idbitnum  <= 0;
152
                                          zerofork <= 64;
153 2 skeptonomi
                                          rxpat   <= "00";
154
                                          iwrbyte <= '0';
155
                                          irdbit <= '0';
156
                                          iwrbit <= '0';
157
                              iwe <= '0';
158
            iobit <= '0';
159
            obyte <= x"00";
160
                                                if h_start = '1' then
161 4 skeptonomi
                                                  --detected command to search for next onewire device
162 2 skeptonomi
                                                  if lastdev = '0' then
163 4 skeptonomi
                --first time thorough, reset the one-wire bus
164 2 skeptonomi
                h_state <= H_RST;
165 4 skeptonomi
                izzbit <= '1';  --send reset signal
166 2 skeptonomi
                h_err <= '0';
167
              else
168
                h_state <= H_FILL;
169
                iwe <= '1';
170
                iobit <= '0';
171
              end if;
172
            else
173
              izzbit <= '0';
174
                                                end if;
175
                                        when H_RST =>
176 4 skeptonomi
                                                --reset the bus at start of each pass, all devices are activated
177 2 skeptonomi
                                                if izzbit = '1' then
178 4 skeptonomi
                                                        izzbit <= '0';  --terminate the reset request
179 2 skeptonomi
                                                elsif busyin = '0' then
180 4 skeptonomi
                                                  --reset is completed, the devices should have responded
181 2 skeptonomi
                                                        if ibit = '1' then
182 4 skeptonomi
                                                          --no response, no devices on bus, so error out
183 2 skeptonomi
                                                                h_state <= H_ERROR;
184
                                                        else
185 4 skeptonomi
                --send "search rom" command
186 2 skeptonomi
                                                                obyte <= x"f0";
187
                                                                iwrbyte <= '1';
188 4 skeptonomi
                                                                h_state <= H_WRCMD;
189 2 skeptonomi
                                                        end if;
190
                                                end if;
191 4 skeptonomi
                                        when H_WRCMD =>
192
                                                --waits for end write command byte, then reads a response bit
193 2 skeptonomi
                                                if iwrbyte = '1' then
194 4 skeptonomi
                                                        iwrbyte <= '0';  --terminate write "search rom" command request
195 2 skeptonomi
                                                elsif busyin = '0' then
196 4 skeptonomi
                                                  -- when the write command is completed
197
              -- read a bit, this will be the AND of the 
198
              -- first address bit of all devices on the bus
199 2 skeptonomi
                                                        irdbit <= '1';
200
                                                        h_state <= H_READBIT;
201
                                                end if;
202
                                        when H_READBIT =>
203 4 skeptonomi
                                          --reads the address bit
204 2 skeptonomi
                                                if irdbit = '1' then
205 4 skeptonomi
                                                        irdbit <= '0';  --terminate the read bit request
206 2 skeptonomi
                                                elsif busyin = '0' then
207 4 skeptonomi
                                                        --wait until bit is read
208
                                                        --save the AND of the address bit of all devices
209
              rxpat(1) <= ibit;
210
              --and read the AND of the compliment of the address bit of all devices
211 2 skeptonomi
                                                        irdbit <= '1';
212
                                            h_state <= H_READCMP;
213
                                                end if;
214
                                        when H_READCMP =>
215 4 skeptonomi
                                          --reads the complement of the address bit
216 2 skeptonomi
                                                if irdbit = '1' then
217 4 skeptonomi
                                                        irdbit <= '0'; --terminate the read complement bit request
218 2 skeptonomi
                                                elsif busyin = '0' then
219 4 skeptonomi
              --when bit is read,
220
              --save the AND of the complimented address bit of all devices
221 2 skeptonomi
                                                        rxpat(0) <= ibit;
222
                                                        h_state <= H_PARSE;
223
                                                end if;
224
                                        when H_PARSE =>
225 4 skeptonomi
            --with the AND of the address bit and the AND of the complimented address bit
226
            --  decide how to proceed (see APP note)
227 2 skeptonomi
                                                case rxpat is
228
                                                        when "11" =>
229 4 skeptonomi
                --no device responded
230 2 skeptonomi
                                                                h_state <= H_ERROR;
231
                                                        when "00" =>
232 4 skeptonomi
                --00 indicates a conflict, devices disagree on this bit
233 2 skeptonomi
                                                                if idbitnum = lastfork then
234
                                                                        --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
235
                                                                        --new_romid(63 downto 0) <= '1' & new_romid(63 downto 1);
236
                                                                        iobit <= '1';
237
                                                        iwrbit <= '1';
238
                              iwe <= '1';
239
                                                                        h_state <= H_INCLOOP;
240
                                                                elsif idbitnum > lastfork then
241
                                                                        --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
242
                                                                        --new_romid(63 downto 0) <= '0' & new_romid(63 downto 1);
243
                  iobit <= '0';
244
                                                                        iwrbit <= '1';
245
                              iwe <= '1';
246 4 skeptonomi
                                                                        zerofork <= idbitnum;
247 2 skeptonomi
                                                                        h_state <= H_INCLOOP;
248
                                                                else
249
                                                                        --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
250
                                                                        --new_romid(63 downto 0) <= last_romid(0) & new_romid(63 downto 1);
251
                                                                        iobit <= id_rbit;
252
                                                                        iwrbit <= '1';
253
                              iwe <= '1';
254
                                                                        if id_rbit = '0' then
255 4 skeptonomi
                                                                                zerofork <= idbitnum;
256 2 skeptonomi
                                                                        end if;
257
                                                                        h_state <= H_INCLOOP;
258
                                                                end if;
259
                                                        when others =>
260
                                                                --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
261
                                                                --new_romid(63 downto 0) <= rxpat(1) & new_romid(63 downto 1);
262
                                                                iobit <= rxpat(1);
263
                                                                iwrbit <= '1';
264
                            iwe <= '1';
265
                                                                h_state <= H_INCLOOP;
266
                                                end case;
267
                                        when H_INCLOOP =>
268 4 skeptonomi
                                          --increments the search to the next bit and terminates when all bits are finished
269 2 skeptonomi
                                                if iwrbit = '1' or iwe = '1' then
270 4 skeptonomi
                                                  --terminate the write request of the current bit
271 2 skeptonomi
                                                  iwrbit <= '0';
272
                          iwe <= '0';
273
                                                elsif busyin = '0' then
274
                                                        if idbitnum = 63 then
275 4 skeptonomi
                                                          --at end of the address, go back to idle, and move lastzero to lastfork
276 2 skeptonomi
                                                                h_state <= H_IDLE;
277 4 skeptonomi
                                                                lastfork <= zerofork;
278
                                                                if zerofork = 64 then
279
                                                                        lastdev <= '1'; --make last device if there no zero forks were taken
280 2 skeptonomi
                                                                end if;
281
                                                        else
282 4 skeptonomi
                                                          -- continue on with next bit by requesting a read of the next address bit
283 2 skeptonomi
                                                                idbitnum <= idbitnum + 1;
284
                                                                irdbit <= '1';
285
                                                                h_state <= H_READBIT;
286
                                                        end if;
287
                                                end if;
288
                                        when H_FILL =>
289 4 skeptonomi
                                          --this fills the unused address feilds with zeros after the last device is found.
290 2 skeptonomi
            if iwe = '1' then
291
              iwe <= '0';
292
            elsif idbitnum = 63 then
293
              h_state <= H_IDLE;
294
            else
295
              idbitnum <= idbitnum + 1;
296
              iobit <= '0';
297
              iwe <= '1';
298
            end if;
299
                        when others =>
300
                                                h_err <= '1';
301
                                                h_state <= H_IDLE;
302
                                end case;
303
                        end if;
304
    end if;
305
  end process p_hunt;
306
 
307
  h_busy <= '0' when h_state = H_IDLE and h_start = '0' else '1';
308
 
309
  ------------------------------------------------------
310
  --    FINDALL - find all devices, one by one       ---
311
  ------------------------------------------------------
312
  --p_findall - finds all (at least up to 8) of the roms on the bus
313
  -- this process initiates up to 8 searches, each finds the next device
314
  -- in the sorted (by device ID) order.
315
        p_findall : process(clk)
316
        begin
317
          if rising_edge(clk) then
318
                  if srst = '1' then
319
                          idcnt <= 0;
320
                                f_state <= F_IDLE;
321 4 skeptonomi
                    h_start <= '0';
322 2 skeptonomi
                                restart <= '0';
323 4 skeptonomi
                                f_err <= '0';
324 2 skeptonomi
                        else
325
                          case f_state is
326 4 skeptonomi
          when F_IDLE =>
327 2 skeptonomi
                                          if start = '1' then
328
                                                  restart <= '1';
329
                                          elsif restart = '1' then
330
                                            restart <= '0';
331
                                                  h_start <= '1';
332 4 skeptonomi
                    f_state <= F_FIND;
333 2 skeptonomi
                                                        idcnt <= 0;
334
                                                        f_err <= '0';
335
                                                end if;
336
                                        when F_FIND =>
337 4 skeptonomi
                                          --terminate the h_start and wait for hunt state to finish
338
            if h_start = '1' then
339 2 skeptonomi
                                                  h_start <= '0';
340
                                                elsif h_busy = '0' then
341 4 skeptonomi
                                                  --hunt is finished, go to inc state if no error
342
              --error also indicates there are no more one-wire devices
343
              if h_err = '1' then
344 2 skeptonomi
                                                          f_state <= F_IDLE;
345
                                                                f_err <= '1';
346
                                                        else
347
                                                                f_state <= F_INC;
348
                                                        end if;
349
                                                end if;
350
                                        when F_INC =>
351
            if idcnt = 31 then
352
              idcnt <= 0;
353
              f_state <= F_IDLE;
354
            else
355
              idcnt <= idcnt + 1;
356
              f_state <= F_FIND;
357
              h_start <= '1';
358
            end if;
359
                                end case;
360
                        end if;
361
                end if;
362
        end process p_findall;
363
 
364
  ------------------------------------------------------
365
  --                External Signals                 ---
366
  ------------------------------------------------------
367
 
368
  id_num <= std_logic_vector(to_unsigned(idcnt,5));
369
  id_bit <= std_logic_vector(to_unsigned(idbitnum,6));
370
  id_we <= iwe;
371
  id_wbit <= iobit;
372
 
373
        rdbit <= irdbit;
374
        wrbit <= iwrbit;
375
        zzbit <= izzbit;
376
  obit <= iobit;
377
        wrbyte <= iwrbyte;
378
 
379
  busy <= '0' when f_state = F_IDLE and h_state = H_IDLE and start = '0' and restart = '0' else '1';
380
  error <= f_err;
381
 
382
end rtl;

powered by: WebSVN 2.1.0

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