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

Subversion Repositories onewire

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

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 4 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: 10/13/2023
19
--  file: ds2405_sim.vhd
20
--  description: A simulation model for the DS2405 addressable switch
21
--
22
--  Generics are used to set the device ID and the timing model
23
--
24
--  This only simulates the SEARCH, ROM, SKIP, CONFIG, CONV, and READ commands
25
-----------------------------
26
 
27
library IEEE;
28
use IEEE.STD_LOGIC_1164.ALL;
29
 
30
-------------------------------------------------------------------------------------
31
-- Entity declaration
32
-------------------------------------------------------------------------------------
33
entity ds2405_sim is
34
  generic (
35
    timing : in string := "ave";
36
    devid  : in std_logic_vector(63 downto 0) := x"1234567123456705"
37
    );
38
  port (
39
    --global signals
40
    pio              : inout std_logic;
41
    dio              : inout std_logic  --synchronous reset
42
  );
43
end ds2405_sim;
44
 
45
 
46
--library unisim;
47
--use unisim.vcomponents.all;
48
library IEEE;
49
use IEEE.STD_LOGIC_1164.ALL;
50
use IEEE.numeric_std.all;
51
library work;
52
 
53
architecture sim of ds2405_sim is
54
 
55
  --low time to trigger a reaset
56
  constant tmin_rstl : time := 240 us;
57
  constant tave_rstl : time := 400 us;
58
  constant tmax_rstl : time := 480 us;
59
  signal trstl : time := tmin_rstl;
60
  --high time between reset pulse and presence pulse
61
  signal tpdih : time;
62
  constant tmin_pdih : time := 15 us;
63
  constant tave_pdih : time := 45 us;
64
  constant tmax_pdih : time := 60 us;
65
  --presence pulse low time
66
  signal tpdlo : time;
67
  constant tmin_pdlo : time := 60 us;
68
  constant tave_pdlo : time := 180 us;
69
  constant tmax_pdlo : time := 240 us;
70
  --write 0 low time
71
  signal tlow0 : time;
72
  constant tmin_low0 : time := 60 us;
73
  constant tave_low0 : time := 100 us;
74
  constant tmax_low0 : time := 120 us;
75
  --write 1 low time
76
  signal tlow1 : time;
77
  constant tmin_low1 : time := 1 us;
78
  constant tave_low1 : time := 10 us;
79
  constant tmax_low1 : time := 15 us;
80
  --master write data sample time
81
  signal tsamp : time := 1 us;
82
  constant tmin_samp : time := 15 us;
83
  constant tave_samp : time := 30 us;
84
  constant tmax_samp : time := 60 us;
85
  --slave read recovery time
86
  signal trec : time := 1 us;
87
  constant tmin_rec : time := 1 us;
88
  constant tave_rec : time := 3 us;
89
  constant tmax_rec : time := 6 us;
90
  --slave read data valid time
91
  signal trdv : time := 15 us;
92
  constant tmin_rdv : time := 15 us;
93
  constant tave_rdv : time := 30 us;
94
  constant tmax_rdv : time := 60 us;
95
 
96
  --recall from eeprom timing
97
  --note: dallas part does not spec this timing
98
  signal trecall : time := 100 us;
99
 
100
  signal tcopy : time := 1 us;
101
  constant tmax_copy : time := 10 ms;
102
  constant tave_copy : time := 2 ms;
103
  constant tmin_copy : time := 1 ms;
104
 
105
  signal clk10m   : std_logic;
106
  signal rstdet   : std_logic := '0';  --indicates a detected a reset pulse from the master
107
  signal trise : time := now;
108
  signal tfall : time := now;
109
  signal rstdly : std_logic := '1';
110
  --signal tdif : time;
111
  signal timertime : time;
112
  signal timer : unsigned(15 downto 0);
113
  signal timertrig : std_logic := '0';
114
  signal timerdone : std_logic := '1';
115
  signal switch : std_logic := '0';
116
 
117
 
118
 
119
  type state_type is (S_IDLE, S_RSTRESP,S_RSTRESP2,S_RSTRESP3,
120
        S_GETBYTE, S_GETBYTE2, S_PARSE,
121
        S_READROM, S_READROM2, S_SRCHROM, S_SRCHROMNOT, S_SRCHROMWR,
122
        S_MATCHROM, S_MATCHROM2, S_SRCHALARM, S_SKIPROM,
123
        S_PARSE2, S_READSW, S_WRITE1, S_WRITE2, S_WRITE3,
124
        S_READ, S_READRCVR, S_CRC);
125
  signal state : state_type := S_IDLE;
126
  signal nxt_state : state_type := S_IDLE;
127
  signal dout : std_logic := 'Z'; --read output bit from slave to master
128
  signal rstdout : std_logic := '1'; --read output bit from main process
129
  signal recalldout : std_logic := '1'; --read output bit from recall process
130
  signal copydout : std_logic := '1'; --read output bit from copy process
131
  signal convdout : std_logic := '1'; --read output bit from conv process
132
  signal readdout : std_logic := '1'; -- output data from read state machine
133
  signal din   : std_logic := '1'; --resolved input data bit
134
  --signal rstout : std_logic := 'Z';
135
  signal bitcnt : integer;
136
  signal shiftbyte : std_logic_vector(7 downto 0);
137
  signal shiftid : std_logic_vector(63 downto 0);
138
  signal busy : std_logic := '0';
139
 
140
  --These signals are for the read state machine
141
  signal bitout   : std_logic := '1';  --bit value to be read by master
142
  signal wrbitin : std_logic := '0'; -- the bit value written by the master
143
  signal wrbiterr : std_logic := '0'; -- indicates a master write pulse with an illegal timing
144
  signal writedet : std_logic := '0'; -- strobe indicating the master wrote a bit
145
  signal readen   : std_logic := '0'; --enables the slave responses to the master read pulses
146
  signal readdet : std_logic := '0'; -- strobe indicating the master read a bit
147
  signal readdly : std_logic := '0'; -- delayed version of din for detecting read strobes
148
  signal readbit : std_logic := '0'; -- data to output from read state machine
149
 
150
  signal crc : std_logic_vector(7 downto 0);
151
begin
152
  trstl <= tmin_rstl when timing = "MIN" else tave_rstl when timing = "AVE" else tmax_rstl;
153
  tpdih <= tmin_pdih when timing = "MIN" else tave_pdih when timing = "AVE" else tmax_pdih;
154
  tpdlo <= tmin_pdlo when timing = "MIN" else tave_pdlo when timing = "AVE" else tmax_pdlo;
155
  tsamp <= tmin_samp when timing = "MIN" else tave_samp when timing = "AVE" else tmax_samp;
156
  trdv <= tmin_rdv when timing = "MIN" else tave_rdv when timing = "AVE" else tmax_rdv;
157
 
158
  p_clk10m : process
159
  begin
160
    clk10m <= '0';
161
    wait for 50 ns;
162
    clk10m <= '1';
163
    wait for 50 ns;
164
  end process;
165
 
166
  p_edges : process
167
  begin
168
    wait until din = '0';
169
    tfall <= now;
170
    wait until din = '1';
171
    trise <= now;
172
  end process;
173
 
174
 
175
  --this handles the master reseting this slave
176
  rstdly <= transport din after trstl;
177
 
178
  p_rst : process
179
  begin
180
    wait until rstdly = '0';
181
    --if last transition was falling edge and it was long ago...
182
    if tfall > trise and now - tfall >= trstl then
183
      rstdet <= '1';
184
      wait until din <= '1';
185
      rstdet <= '0';
186
    end if;
187
  end process;
188
 
189
  --p_readstb and p_read - work together to facilitate a read
190
  --  readen is set high to enable a read, then if din is low for 1 us the readdet signal triggers
191
  --  which causes readout to be driven low for a bit time if shift(0) is low
192
  --  after the bit time expires, din returns high, causing readdet to go low, and cycle is complete
193
  readdly <= transport din after 1us;
194
  p_readstb : process
195
  begin
196
    wait until readdly = '0';
197
    if tfall > trise and now - tfall >= 1us and readen = '1' then
198
      readdet <= '1';
199
      wait until din <= '1';
200
      readdet <= '0';
201
    end if;
202
  end process;
203
 
204
  p_read : process
205
  begin
206
    wait until readdet = '1' and readen = '1';
207
    readdout <= readbit;
208
    wait for trdv;
209
    readdout <= '1';
210
  end process;
211
 
212
  --this handles the master writing bits to this slave
213
  p_write : process
214
  begin
215
    wait until din = '1';
216
    --dont detect writes during read operations
217
    if readen = '0' and readdet = '0' then
218
      if now - tfall > tmin_low0 and now-tfall < tmax_low0 then
219
        wrbitin <= '0';
220
        writedet <= '1';
221
        wrbiterr <= '0';
222
      elsif now - tfall > tmin_low1 and now-tfall < tmax_low1 then
223
        wrbitin <= '1';
224
        writedet <= '1';
225
        wrbiterr <= '0';
226
      elsif now - tfall < trstl then
227
        wrbiterr <= '1';
228
      end if;
229
    end if;
230
    wait until din = '0';
231
    writedet <= '0';
232
  end process;
233
 
234
 
235
  p_timer : process(clk10m)
236
  begin
237
    if rising_edge(clk10m) then
238
      if timertrig = '1' then
239
        timer <= to_unsigned(integer(timertime/100 ns),16);
240
        timerdone <= '0';
241
      elsif timer > 1 then
242
        timer <= timer -1;
243
      else
244
        timerdone <= '1';
245
      end if;
246
    end if;
247
  end process;
248
 
249
  --this handles the master reading a bit from this slave
250
  --dout <= '0' when rdbiten = '1' and dout = '0' and now-tfall < trdv else '1';
251
 
252
  p_state :process(clk10m)
253
  begin
254
    if rising_edge (clk10m) then
255
      if rstdet = '1' then
256
        state <= S_RSTRESP;
257
        rstdout <= '1';
258
        readen <= '0';
259
      else
260
        case state is
261
          when S_IDLE =>
262
            rstdout <= '1';
263
            readen <= '0';
264
            bitcnt <= 0;
265
            shiftbyte <= x"00";
266
            shiftid <= devid;
267
          when S_RSTRESP =>
268
            readen <= '0';
269
            bitcnt <= 0;
270
            rstdout <= '1';
271
            shiftbyte <= x"00";
272
            shiftid <= devid;
273
            if timertrig = '0' and din = '1' then
274
              timertime <= tpdih;
275
              timertrig <= '1';
276
            elsif timertrig = '1' then
277
              timertrig <= '0';
278
              state <= S_RSTRESP2;
279
            end if;
280
          when S_RSTRESP2 =>
281
            if timertrig = '0' and timerdone = '1' then
282
              rstdout <= '0';
283
              timertime <= tpdlo;
284
              timertrig <= '1';
285
            elsif timertrig = '1' then
286
              timertrig <= '0';
287
              state <= S_RSTRESP3;
288
            end if;
289
          when S_RSTRESP3 =>
290
            if timerdone = '1' then
291
              rstdout <= '1';
292
              state <= S_GETBYTE;
293
              nxt_state <= S_PARSE;
294
            end if;
295
          when S_GETBYTE =>
296
            if writedet = '0' then
297
              state <= S_GETBYTE2;
298
            end if;
299
          when S_GETBYTE2 =>
300
            if writedet  = '1' then
301
              shiftbyte <= wrbitin & shiftbyte(7 downto 1);
302
              if bitcnt < 7 then
303
                bitcnt <= bitcnt + 1;
304
                state <= S_GETBYTE;
305
              else
306
                bitcnt <= 0;
307
                state <= nxt_state;
308
              end if;
309
            end if;
310
          when S_PARSE =>
311
            shiftid <= devid;
312
            case shiftbyte is
313
              when x"33" =>         --read the rom id from the device, can only be used on single device bus
314
                state <= S_READROM;
315
              when x"55" =>         --match rom, used to address a single device on the bus
316
                state <= S_MATCHROM;
317
              when x"F0" =>         --use to find the devices on a multiple device bus
318
                state <= S_SRCHROM;
319
              when x"EC" =>         --search alarm, used to find devices that have the pio line pulled low
320
                if pio = '0' then
321
                  state <= S_SRCHROM;
322
                else
323
                  state <= S_IDLE;
324
                end if;
325
              when x"CC" =>         --skip rom, skips rom addressing, for single device busses or broadcast commands
326
                state <= S_GETBYTE;
327
                nxt_state <= S_PARSE2;
328
              when others =>
329
                state <= S_IDLE;
330
            end case;
331
          when S_READROM =>
332
            readen <= '1';
333
            if readdet = '1' then
334
              shiftid <= shiftid(0) & shiftid(63 downto 1);
335
              if bitcnt < 55 then
336
                bitcnt <= bitcnt + 1;
337
                state <= S_READRCVR;
338
                nxt_state <= S_READROM;
339
              else
340
                state <= S_CRC;
341
                nxt_state <= S_READROM2;
342
                shiftid <= x"00000000000000" & crc;
343
              end if;
344
            end if;
345
          when S_READROM2 =>
346
            state <= S_GETBYTE;
347
            nxt_state <= S_PARSE2;
348
          when S_MATCHROM =>
349
            if writedet = '0' then
350
              state <= S_MATCHROM2;
351
            end if;
352
          when S_MATCHROM2 =>
353
            if writedet = '1' then
354
              if  wrbitin /= shiftid(0) then
355
                state <= S_IDLE;  --this part is removed from search, goto idle, wait for rstdet
356
              else
357
                shiftid <= shiftid(0) & shiftid(63 downto 1);
358
                if bitcnt < 63 then
359
                  bitcnt <= bitcnt + 1;
360
                  state <= S_MATCHROM;
361
                else
362
                  bitcnt <= 0;
363
                  switch <= not switch;
364
                  state <= S_READSW;
365
                end if;
366
              end if;
367
            end if;
368
          when S_READSW =>
369
            shiftid <= x"000000000000000" & "000" & pio;
370
            readen <= '1';
371
            if readdet = '1' then
372
                state <= S_READRCVR;
373
                nxt_state <= S_READSW;
374
            end if;
375
          when S_SRCHROM =>
376
            readen <= '1';
377
            readbit <= shiftid(0);
378
            if readdet = '1' then
379
              state <= S_READRCVR;
380
              nxt_state <= S_SRCHROMNOT;
381
            end if;
382
          when S_SRCHROMNOT =>
383
            readen <= '1';
384
            readbit <= not shiftid(0);
385
            if readdet = '1' then
386
              state <= S_READRCVR;
387
              nxt_state <= S_SRCHROMWR;
388
            end if;
389
          when S_SRCHROMWR =>
390
            readen <= '0';
391
            if writedet = '1' then
392
              if  wrbitin /= shiftid(0) then
393
                state <= S_IDLE;  --this part is removed from search, goto idle, wait for rstdet
394
              else
395
                shiftid <= shiftid(0) & shiftid(63 downto 1);
396
                if bitcnt < 63 then
397
                  bitcnt <= bitcnt + 1;
398
                  state <= S_SRCHROM;
399
               else
400
                  bitcnt <= 0;
401
                  state <= S_READSW;
402
                end if;
403
              end if;
404
            end if;
405
          when S_READRCVR =>
406
            readen <= '0';
407
            if readdet = '0' then
408
              state <= nxt_state;
409
            end if;
410
          when S_CRC =>
411
            readen <= '1';
412
            if readdet = '1' then
413
              shiftid <= shiftid(0) & shiftid(63 downto 1);
414
              if bitcnt < 7 then
415
                bitcnt <= bitcnt + 1;
416
                state <= S_READRCVR;
417
                nxt_state <= S_READ;
418
              else
419
                state <= S_READRCVR;
420
                nxt_state <= S_IDLE;
421
                bitcnt <= 0;
422
                shiftid <= x"00000000000000" & crc;
423
              end if;
424
            end if;
425
          when others =>
426
            state <= S_IDLE;
427
        end case;
428
      end if;
429
    end if;
430
        end process;
431
 
432
        p_crc : process
433
        begin
434
          crc <= x"00";
435
          wait until state = S_READ or state = S_READROM;
436
            crc <= x"00";
437
          while state = S_READ or state = S_READROM loop
438
            wait until din = '0' or (state /= S_READ and state /= S_READROM);
439
            if din = '0' then
440
              if (crc(0) xor shiftid(0)) = '1' then
441
                crc <= ('0' & crc(7 downto 1)) xor x"8c";
442
              else
443
                crc <= ('0' & crc(7 downto 1));
444
              end if;
445
            end if;
446
          end loop;
447
        end process;
448
 
449
 
450
        din <= '0' when dio = '0' else '1';
451
        dout <= rstdout and copydout and convdout and recalldout and readdout;
452
        dio <= '0' when dout = '0' else 'Z';
453
  pio <= '0' when switch = '0' else 'H';
454
        busy <= '0' when state = S_IDLE else '1';
455
 
456
end sim;

powered by: WebSVN 2.1.0

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