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

Subversion Repositories onewire

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

Go to most recent revision | 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
  type   h_state_type is (H_IDLE, H_RST, H_SKIP, H_READBIT, H_READCMP, H_PARSE, H_INCLOOP, H_FILL, H_ERROR);
67
  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
  signal lastfork : integer range 0 to 63;
73
  signal lastzero : integer range 0 to 63;
74
  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
  attribute mark_debug of lastzero  : signal is "true";
98
  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
        -- "restart" resets all parameters to rediscover all ROM iDs
118
        -- "hunt" searches for the next ROM ID in the sort order
119
  p_hunt : process (clk)
120
  begin
121
    if rising_edge(clk) then
122
      if srst = '1' or restart = '1' then
123
        h_state <= H_IDLE;
124
        idbitnum  <= 0;
125
                                lastfork <= 0;
126
                                lastdev <= '0';
127
                                rxpat   <= "00";
128
                                h_err <= '0';
129
                                iwrbyte <= '0';
130
                                izzbit <= '0';
131
                                irdbit <= '0';
132
                                iwrbit <= '0';
133
                                iwe <= '0';
134
                                iobit <= '0';
135
                          obyte <= x"00";
136
      else
137
        case h_state is
138
                                        when H_IDLE =>
139
                                                idbitnum  <= 0;
140
                                          lastzero <= 0;
141
                                          rxpat   <= "00";
142
                                          iwrbyte <= '0';
143
                                          irdbit <= '0';
144
                                          iwrbit <= '0';
145
                              iwe <= '0';
146
            iobit <= '0';
147
            obyte <= x"00";
148
                                                if h_start = '1' then
149
                                                  if lastdev = '0' then
150
                h_state <= H_RST;
151
                izzbit <= '1';
152
                h_err <= '0';
153
              else
154
                h_state <= H_FILL;
155
                iwe <= '1';
156
                iobit <= '0';
157
              end if;
158
            else
159
              izzbit <= '0';
160
                                                end if;
161
                                        when H_RST =>
162
                                                if izzbit = '1' then
163
                                                        izzbit <= '0';
164
                                                elsif busyin = '0' then
165
                                                        if ibit = '1' then
166
                                                                h_state <= H_ERROR;
167
                                                        else
168
                                                                obyte <= x"f0";
169
                                                                iwrbyte <= '1';
170
                                                                h_state <= H_SKIP;
171
                                                        end if;
172
                                                end if;
173
                                        when H_SKIP =>
174
                                                if iwrbyte = '1' then
175
                                                        iwrbyte <= '0';
176
                                                elsif busyin = '0' then
177
                                                        irdbit <= '1';
178
                                                        h_state <= H_READBIT;
179
                                                end if;
180
                                        when H_READBIT =>
181
                                                if irdbit = '1' then
182
                                                        irdbit <= '0';
183
                                                elsif busyin = '0' then
184
                                                        rxpat(1) <= ibit;
185
                                                        irdbit <= '1';
186
                                            h_state <= H_READCMP;
187
                                                end if;
188
                                        when H_READCMP =>
189
                                                if irdbit = '1' then
190
                                                        irdbit <= '0';
191
                                                elsif busyin = '0' then
192
                                                        rxpat(0) <= ibit;
193
                                                        h_state <= H_PARSE;
194
                                                end if;
195
                                        when H_PARSE =>
196
                                                case rxpat is
197
                                                        when "11" =>
198
                                                                h_state <= H_ERROR;
199
                                                        when "00" =>
200
                                                                if idbitnum = lastfork then
201
                                                                        --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
202
                                                                        --new_romid(63 downto 0) <= '1' & new_romid(63 downto 1);
203
                                                                        iobit <= '1';
204
                                                        iwrbit <= '1';
205
                              iwe <= '1';
206
                                                                        h_state <= H_INCLOOP;
207
                                                                elsif idbitnum > lastfork then
208
                                                                        --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
209
                                                                        --new_romid(63 downto 0) <= '0' & new_romid(63 downto 1);
210
                  iobit <= '0';
211
                                                                        iwrbit <= '1';
212
                              iwe <= '1';
213
                                                                        lastzero <= idbitnum;
214
                                                                        h_state <= H_INCLOOP;
215
                                                                else
216
                                                                        --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
217
                                                                        --new_romid(63 downto 0) <= last_romid(0) & new_romid(63 downto 1);
218
                                                                        iobit <= id_rbit;
219
                                                                        iwrbit <= '1';
220
                              iwe <= '1';
221
                                                                        if id_rbit = '0' then
222
                                                                                lastzero <= idbitnum;
223
                                                                        end if;
224
                                                                        h_state <= H_INCLOOP;
225
                                                                end if;
226
                                                        when others =>
227
                                                                --last_romid(63 downto 0) <= last_romid(0) & last_romid(63 downto 1);
228
                                                                --new_romid(63 downto 0) <= rxpat(1) & new_romid(63 downto 1);
229
                                                                iobit <= rxpat(1);
230
                                                                iwrbit <= '1';
231
                            iwe <= '1';
232
                                                                h_state <= H_INCLOOP;
233
                                                end case;
234
                                        when H_INCLOOP =>
235
                                                if iwrbit = '1' or iwe = '1' then
236
                                                  iwrbit <= '0';
237
                          iwe <= '0';
238
                                                elsif busyin = '0' then
239
                                                        if idbitnum = 63 then
240
                                                                h_state <= H_IDLE;
241
                                                                lastfork <= lastzero;
242
                                                                if lastzero = 0 then
243
                                                                        lastdev <= '1';
244
                                                                end if;
245
                                                        else
246
                                                                idbitnum <= idbitnum + 1;
247
                                                                irdbit <= '1';
248
                                                                h_state <= H_READBIT;
249
                                                        end if;
250
                                                end if;
251
                                        when H_FILL =>
252
            if iwe = '1' then
253
              iwe <= '0';
254
            elsif idbitnum = 63 then
255
              h_state <= H_IDLE;
256
            else
257
              idbitnum <= idbitnum + 1;
258
              iobit <= '0';
259
              iwe <= '1';
260
            end if;
261
                        when others =>
262
                                                h_err <= '1';
263
                                                h_state <= H_IDLE;
264
                                end case;
265
                        end if;
266
    end if;
267
  end process p_hunt;
268
 
269
  h_busy <= '0' when h_state = H_IDLE and h_start = '0' else '1';
270
 
271
  ------------------------------------------------------
272
  --    FINDALL - find all devices, one by one       ---
273
  ------------------------------------------------------
274
  --p_findall - finds all (at least up to 8) of the roms on the bus
275
  -- this process initiates up to 8 searches, each finds the next device
276
  -- in the sorted (by device ID) order.
277
        p_findall : process(clk)
278
        begin
279
          if rising_edge(clk) then
280
                  if srst = '1' then
281
                          idcnt <= 0;
282
                                f_state <= F_IDLE;
283
                                restart <= '0';
284
                        else
285
                          case f_state is
286
                                  when F_IDLE =>
287
                                          if start = '1' then
288
                                                  restart <= '1';
289
                                          elsif restart = '1' then
290
                                            restart <= '0';
291
                                                  h_start <= '1';
292
                                                        f_state <= F_FIND;
293
                                                        idcnt <= 0;
294
                                                        f_err <= '0';
295
                                                end if;
296
                                        when F_FIND =>
297
                                          if h_start = '1' then
298
                                                  h_start <= '0';
299
                                                elsif h_busy = '0' then
300
                                                  if h_err = '1' then
301
                                                          f_state <= F_IDLE;
302
                                                                f_err <= '1';
303
                                                        else
304
                                                                f_state <= F_INC;
305
                                                        end if;
306
                                                end if;
307
                                        when F_INC =>
308
            if idcnt = 31 then
309
              idcnt <= 0;
310
              f_state <= F_IDLE;
311
            else
312
              idcnt <= idcnt + 1;
313
              f_state <= F_FIND;
314
              h_start <= '1';
315
            end if;
316
                                end case;
317
                        end if;
318
                end if;
319
        end process p_findall;
320
 
321
  ------------------------------------------------------
322
  --                External Signals                 ---
323
  ------------------------------------------------------
324
 
325
  id_num <= std_logic_vector(to_unsigned(idcnt,5));
326
  id_bit <= std_logic_vector(to_unsigned(idbitnum,6));
327
  id_we <= iwe;
328
  id_wbit <= iobit;
329
 
330
        rdbit <= irdbit;
331
        wrbit <= iwrbit;
332
        zzbit <= izzbit;
333
  obit <= iobit;
334
        wrbyte <= iwrbyte;
335
 
336
  busy <= '0' when f_state = F_IDLE and h_state = H_IDLE and start = '0' and restart = '0' else '1';
337
  error <= f_err;
338
 
339
end rtl;

powered by: WebSVN 2.1.0

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