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

Subversion Repositories sockit_owm

[/] [sockit_owm/] [trunk/] [hdl/] [onewire_tb.v] - Blame information for rev 3

Details | Compare with Previous | View Log

Line No. Rev Author Line
1 2 iztok
//////////////////////////////////////////////////////////////////////////////                                                                                          
2
//                                                                          //
3
//  Minimalistic 1-wire (onewire) master with Avalon MM bus interface       //
4
//  testbench                                                               //
5
//                                                                          //
6
//  Copyright (C) 2010  Iztok Jeras                                         //
7
//                                                                          //
8
//////////////////////////////////////////////////////////////////////////////
9
//                                                                          //
10
//  This RTL is free hardware: you can redistribute it and/or modify        //
11
//  it under the terms of the GNU Lesser General Public License             //
12
//  as published by the Free Software Foundation, either                    //
13
//  version 3 of the License, or (at your option) any later version.        //
14
//                                                                          //
15
//  This RTL is distributed in the hope that it will be useful,             //
16
//  but WITHOUT ANY WARRANTY; without even the implied warranty of          //
17
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the           //
18
//  GNU General Public License for more details.                            //
19
//                                                                          //
20
//  You should have received a copy of the GNU General Public License       //
21
//  along with this program.  If not, see <http://www.gnu.org/licenses/>.   //
22
//                                                                          //
23
//////////////////////////////////////////////////////////////////////////////
24
 
25
`timescale 1ns / 1ps
26
 
27
module onewire_tb;
28
 
29 3 iztok
localparam DEBUG = 1'b0;
30
 
31 2 iztok
// system clock parameters
32 3 iztok
localparam real FRQ = 6_000_000;      // frequency 6MHz
33
localparam real TCP = (10.0**9)/FRQ;  // time clock period in ns
34 2 iztok
 
35 3 iztok
`ifdef CDR_E
36
localparam CDR_E = 1;
37
`else
38
localparam CDR_E = 0;
39
`endif
40 2 iztok
 
41 3 iztok
`ifdef PRESET_50_10
42
localparam OVD_E = 1'b1;   // overdrive functionality enable
43
localparam BTP_N = "5.0";  // normal    mode
44
localparam BTP_O = "1.0";  // overdrive mode
45
`elsif PRESET_60_05
46
localparam OVD_E = 1'b1;   // overdrive functionality enable
47
localparam BTP_N = "6.0";  // normal    mode
48
localparam BTP_O = "0.5";  // overdrive mode
49
`elsif PRESET_75
50
localparam OVD_E = 1'b0;   // overdrive functionality enable
51
localparam BTP_N = "7.5";  // normal    mode
52
localparam BTP_O = "1.0";  // overdrive mode
53
`else // default
54
localparam OVD_E = 1'b1;   // overdrive functionality enable
55
localparam BTP_N = "5.0";  // normal    mode
56
localparam BTP_O = "1.0";  // overdrive mode
57
`endif
58 2 iztok
 
59 3 iztok
// port width parameters
60
`ifdef BDW_32
61
localparam BDW   = 32;     // 32bit bus data width
62
`elsif BDW_8
63
localparam BDW   =  8;     //  8bit bus data width
64
`else // default
65
localparam BDW   = 32;     //       bus data width
66
`endif
67 2 iztok
 
68 3 iztok
// number of wires
69
`ifdef OWN
70
localparam OWN   = `OWN;  // number of wires
71
`else
72
localparam OWN   =  3;    // slaves with different timing (min, typ, max)
73
`endif
74
 
75
// computed bus address port width
76
localparam BAW   = (BDW==32) ? 1 : 2;
77
 
78
// clock dividers for normal and overdrive mode
79
// NOTE! must be round integer values
80
`ifdef PRESET_60_05
81
// there is no way to cast a real value into an integer
82
localparam integer CDR_N = 45 - 1;
83
localparam integer CDR_O =  4 - 1;
84
`else
85
localparam integer CDR_N = ((BTP_N == "5.0") ?  5.0 : 7.5 ) * FRQ / 1_000_000 - 1;
86
localparam integer CDR_O = ((BTP_O == "1.0") ?  1.0 : 0.67) * FRQ / 1_000_000 - 1;
87
`endif
88
 
89 2 iztok
// Avalon MM parameters
90 3 iztok
localparam AAW = BAW;    // address width
91
localparam ADW = BDW;    // data width
92 2 iztok
localparam ABW = ADW/8;  // byte enable width
93
 
94
// system_signals
95
reg            clk;  // clock
96
reg            rst;  // reset (asynchronous)
97
// Avalon MM interface
98
reg            avalon_read;
99
reg            avalon_write;
100
reg  [AAW-1:0] avalon_address;
101
reg  [ABW-1:0] avalon_byteenable;
102
reg  [ADW-1:0] avalon_writedata;
103
wire [ADW-1:0] avalon_readdata;
104
wire           avalon_waitrequest;
105
wire           avalon_interrupt;
106
 
107
// Avalon MM local signals
108
wire           avalon_transfer;
109 3 iztok
reg  [BDW-1:0] data;
110 2 iztok
 
111
// onewire
112
wire [OWN-1:0] owr;     // bidirectional
113
wire [OWN-1:0] owr_p;   // output power enable from master
114
wire [OWN-1:0] owr_e;   // output pull down enable from master
115
wire [OWN-1:0] owr_i;   // input into master
116
 
117 3 iztok
// slave conviguration
118
reg            slave_ena;    // slave enable (connect/disconnect from wire)
119
reg      [3:0] slave_sel;    // 1-wire slave select
120
reg            slave_ovd;    // overdrive mode enable
121
reg            slave_dat_r;  // read  data
122
wire [OWN-1:0] slave_dat_w;  // write data
123
 
124
// error checking
125
integer        error;
126
integer        n;
127
 
128
// overdrive enable loop
129
integer        i;
130
 
131
//////////////////////////////////////////////////////////////////////////////
132
// configuration printout and waveforms
133
//////////////////////////////////////////////////////////////////////////////
134
 
135 2 iztok
// request for a dumpfile
136
initial begin
137
  $dumpfile("onewire.vcd");
138
  $dumpvars(0, onewire_tb);
139
end
140
 
141 3 iztok
// print configuration
142
initial begin
143
  $display ("NOTE: Ports : BDW=%0d, BAW=%0d, OWN=%0d", BDW, BAW, OWN);
144
  $display ("NOTE: Clock : FRQ=%3.2fMHz, TCP=%3.2fns", FRQ/1_000_000.0, TCP);
145
  $display ("NOTE: Divide: CDR_E=%0b, CDR_N=%0d, CDR_O=%0d", CDR_E, CDR_N, CDR_O);
146
  $display ("NOTE: Config: OVD_E=%0b, BTP_N=%1.2fus, BTP_O=%1.2fus",
147
                           OVD_E, (CDR_N+1)*1_000_000/FRQ, (CDR_O+1)*1_000_000/FRQ);
148
end
149
 
150 2 iztok
//////////////////////////////////////////////////////////////////////////////
151
// clock and reset
152
//////////////////////////////////////////////////////////////////////////////
153
 
154
// clock generation
155 3 iztok
initial         clk = 1'b1;
156
always #(TCP/2) clk = ~clk;
157 2 iztok
 
158
// reset generation
159
initial begin
160
  rst = 1'b1;
161
  repeat (2) @(posedge clk);
162
  rst = 1'b0;
163
end
164
 
165
//////////////////////////////////////////////////////////////////////////////
166
// Avalon write and read transfers
167
//////////////////////////////////////////////////////////////////////////////
168
 
169
initial begin
170 3 iztok
  // reset error counter
171
  error = 0;
172
 
173 2 iztok
  // Avalon MM interface is idle
174
  avalon_read  = 1'b0;
175
  avalon_write = 1'b0;
176
 
177
  // long delay to skip presence pulse
178 3 iztok
  slave_ena = 1'b0;
179 2 iztok
  #1000_000;
180
 
181 3 iztok
  // set clock divider ratios
182
  if (CDR_E) begin
183
    if (BDW==32) begin
184
      avalon_cycle (1, 1, 4'hf, {   16'h0001,    16'h0001}, data);
185
      avalon_cycle (1, 1, 4'hf, {CDR_O[15:0], CDR_N[15:0]}, data);
186
    end else if (BDW==8) begin
187
      avalon_cycle (1, 2, 1'b1,      8'h01, data);
188
      avalon_cycle (1, 3, 1'b1,      8'h01, data);
189
      avalon_cycle (1, 2, 1'b1, CDR_N[7:0], data);
190
      avalon_cycle (1, 3, 1'b1, CDR_O[7:0], data);
191
    end
192
  end
193 2 iztok
 
194 3 iztok
  // test with slaves with different timing (each slave one one of the wires)
195
  for (slave_sel=0; slave_sel<OWN; slave_sel=slave_sel+1) begin
196 2 iztok
 
197 3 iztok
    // select normal/overdrive mode
198
    //for (slave_ovd=0; slave_ovd<(OVD_E?2:1); slave_ovd=slave_ovd+1) begin
199
    for (i=0; i<(OVD_E?2:1); i=i+1) begin
200 2 iztok
 
201 3 iztok
      slave_ovd = i[0];
202 2 iztok
 
203 3 iztok
      // testbench status message 
204
      $display("NOTE: Loop: speed=%s, ovd=%b, BTP=\"%s\")", (slave_sel==0) ? "typ" : (slave_sel==1) ? "min" : "max", slave_ovd, slave_ovd ? BTP_O : BTP_N);
205 2 iztok
 
206 3 iztok
      // generate a reset pulse
207
      slave_ena   = 1'b0;
208
      slave_dat_r = 1'b1;
209
      avalon_request (16'd0, slave_sel, {slave_ovd, 2'b10});
210
      avalon_polling (8, n);
211
      // expect no response
212
      if (data[0] !== 1'b1) begin
213
        error = error+1;
214
        $display("ERROR: (t=%0t)  Wrong presence detect responce ('1' expected).", $time);
215
      end
216 2 iztok
 
217 3 iztok
      // generate a reset pulse
218
      slave_ena   = 1'b1;
219
      slave_dat_r = 1'b1;
220
      avalon_request (16'd0, slave_sel, {slave_ovd, 2'b10});
221
      avalon_polling (8, n);
222
      // expect presence response
223
      if (data[0] !== 1'b0) begin
224
        error = error+1;
225
        $display("ERROR: (t=%0t)  Wrong presence detect response ('0' expected).", $time);
226
      end
227
 
228
      // write '0'
229
      slave_ena   = 1'b1;
230
      slave_dat_r = 1'b1;
231
      avalon_request (16'd0, slave_sel, {slave_ovd, 2'b00});
232
      avalon_polling (8, n);
233
      // check if '0' was written into the slave
234
      if (slave_dat_w[slave_sel] !== 1'b0) begin
235
        error = error+1;
236
        $display("ERROR: (t=%0t)  Wrong write data for write '0'.", $time);
237
      end
238
      // check if '0' was read from the slave
239
      if (data[0] !== 1'b0) begin
240
        error = error+1;
241
        $display("ERROR: (t=%0t)  Wrong read  data for write '0'.", $time);
242
      end
243
 
244
      // write '1', read '1'
245
      slave_ena   = 1'b1;
246
      slave_dat_r = 1'b1;
247
      avalon_request (16'd0, slave_sel, {slave_ovd, 2'b01});
248
      avalon_polling (8, n);
249
      // check if '0' was written into the slave
250
      if (slave_dat_w[slave_sel] !== 1'b1) begin
251
        error = error+1;
252
        $display("ERROR: (t=%0t)  Wrong write data for write '1', read '1'.", $time);
253
      end
254
      // check if '1' was read from the slave
255
      if (data[0] !== 1'b1) begin
256
        error = error+1;
257
        $display("ERROR: (t=%0t)  Wrong read  data for write '1', read '1'.", $time);
258
      end
259
 
260
      // write '1', read '0'
261
      slave_ena   = 1'b1;
262
      slave_dat_r = 1'b0;
263
      avalon_request (16'd0, slave_sel, {slave_ovd, 2'b01});
264
      avalon_polling (8, n);
265
      // check if '0' was written into the slave
266
      if (slave_dat_w[slave_sel] !== 1'b0) begin
267
        error = error+1;
268
        $display("ERROR: (t=%0t)  Wrong write data for write '1', read '0'.", $time);
269
      end
270
      // check if '0' was read from the slave
271
      if (data[0] !== 1'b0) begin
272
        error = error+1;
273
        $display("ERROR: (t=%0t)  Wrong read  data for write '1', read '0'.", $time);
274
      end
275
 
276
    end  // slave_ovd
277
 
278
  end  // slave_sel
279
 
280
  // test power supply on a typical normal mode slave
281
  slave_sel = 0;
282
 
283
  // generate a delay pulse (1ms) with power supply enabled
284
  avalon_request (16'd1, slave_sel, 3'b011);
285
  avalon_polling (1, n);
286
  // check if '1' was read from the slave
287
  if ((data[0] !== 1'b1) & ~slave_ovd) begin
288
    error = error+1;
289
    $display("ERROR: (t=%0t)  Wrong presence detect response (power expected).", $time);
290
  end
291
  // check if power is present
292
  if (owr_p[slave_sel] !== 1'b1) begin
293
    error = error+1;
294
    $display("ERROR: (t=%0t)  Wrong line power state", $time);
295
  end
296
  // check the time to run a delay cycle
297
  if ((n-1)*2 != FRQ/1000) begin
298
    $display("WARNING: (t=%0t)  Non ideal cycle time (%0dus), should be around 1ms.", $time, 2*(n-1)*1_000_000/FRQ);
299
  end
300
 
301
  // generate a idle pulse (0ms) with power supply enabled
302
  avalon_request (16'd1, slave_sel, 3'b111);
303
  avalon_polling (1, n);
304
  // check if power is present
305
  if (owr_p[slave_sel] !== 1'b1) begin
306
    error = error+1;
307
    $display("ERROR: (t=%0t)  Wrong line power state", $time);
308
  end
309
  // check the time to run an idle cycle
310
  if (n>1) begin
311
    $display("ERROR: (t=%0t)  Non ideal idle cycle time, should be around zero.", $time);
312
  end
313
 
314
  // generate a delay pulse and break it with an idle pulse, before it finishes
315 2 iztok
  repeat (10) @(posedge clk);
316 3 iztok
  avalon_request (16'd0, 4'h0, 3'b011);
317 2 iztok
  repeat (10) @(posedge clk);
318 3 iztok
  avalon_request (16'd0, 4'h0, 3'b111);
319 2 iztok
 
320
  // wait a few cycles and finish
321
  repeat (10) @(posedge clk);
322
  $finish();
323
end
324
 
325 3 iztok
// avalon request cycle
326
task avalon_request (
327
  input [15:0] pwr,  // power enable
328
  input  [3:0] sel,  // onewire slave select
329
  input  [2:0] cmd   // command {ovd, rst, dat}
330
);
331
  reg [BDW-1:0] data;  // read data
332 2 iztok
begin
333 3 iztok
  if (BDW==32) begin
334
    avalon_cycle (1, 0, 4'hf, {pwr<<sel, 4'h0, sel, 3'b000, pwr[0], 1'b1, cmd}, data);
335
  end else begin
336
    avalon_cycle (1, 1, 1'b1, {pwr[3:0]<<sel, 2'h0, sel[1:0]}, data);
337
    avalon_cycle (1, 0, 1'b1, {    3'b000, pwr[0], 1'b1, cmd}, data);
338 2 iztok
  end
339
end endtask
340
 
341 3 iztok
// wait for the onewire cycle completion
342
task avalon_polling (
343
  input  integer dly,
344
  output integer n
345
); begin
346
  // set cycle counter to zero
347
  n = 0;
348
  // poll till owr_cyc ends
349
  if (BDW==32) begin
350
    data = 32'h08;
351
    while (data & 32'h08) begin
352
      repeat (dly) @ (posedge clk);
353
      avalon_cycle (0, 0, 4'hf, 32'hxxxx_xxxx, data);
354
      n = n + 1;
355
    end
356
  end else begin
357
    data = 8'h08;
358
    while (data & 8'h08) begin
359
      repeat (dly) @ (posedge clk);
360
      avalon_cycle (0, 0, 1'b1, 8'hxx, data);
361
      n = n + 1;
362
    end
363
  end
364
end endtask
365
 
366 2 iztok
//////////////////////////////////////////////////////////////////////////////
367
// Avalon transfer cycle generation task
368
//////////////////////////////////////////////////////////////////////////////
369
 
370
task automatic avalon_cycle (
371
  input            r_w,  // 0-read or 1-write cycle
372
  input  [AAW-1:0] adr,
373
  input  [ABW-1:0] ben,
374
  input  [ADW-1:0] wdt,
375
  output [ADW-1:0] rdt
376
);
377
begin
378 3 iztok
  if (DEBUG) $display ("Avalon MM cycle start: T=%10tns, %s address=%08x byteenable=%04b writedata=%08x", $time/1000.0, r_w?"write":"read ", adr, ben, wdt);
379 2 iztok
  // start an Avalon cycle
380
  avalon_read       <= ~r_w;
381
  avalon_write      <=  r_w;
382
  avalon_address    <=  adr;
383
  avalon_byteenable <=  ben;
384
  avalon_writedata  <=  wdt;
385
  // wait for waitrequest to be retracted
386
  @ (posedge clk); while (~avalon_transfer) @ (posedge clk);
387
  // end Avalon cycle
388
  avalon_read       <= 1'b0;
389
  avalon_write      <= 1'b0;
390
  // read data
391
  rdt = avalon_readdata;
392 3 iztok
  if (DEBUG) $display ("Avalon MM cycle end  : T=%10tns, readdata=%08x", $time/1000.0, rdt);
393 2 iztok
end
394
endtask
395
 
396
// avalon cycle transfer cycle end status
397
assign avalon_transfer = (avalon_read | avalon_write) & ~avalon_waitrequest;
398
 
399
assign avalon_waitrequest = 1'b0;
400
 
401
//////////////////////////////////////////////////////////////////////////////
402
// RTL instance
403
//////////////////////////////////////////////////////////////////////////////
404
 
405
sockit_owm #(
406 3 iztok
  .OVD_E    (OVD_E),
407
  .CDR_E    (CDR_E),
408
  .BDW      (BDW  ),
409
  .BAW      (BAW  ),
410
  .OWN      (OWN  ),
411
  .BTP_N    (BTP_N),
412
  .BTP_O    (BTP_O),
413
  .CDR_N    (CDR_N),
414
  .CDR_O    (CDR_O)
415 2 iztok
) onewire_master (
416
  // system
417 3 iztok
  .clk      (clk),
418
  .rst      (rst),
419 2 iztok
  // Avalon
420 3 iztok
  .bus_ren  (avalon_read),
421
  .bus_wen  (avalon_write),
422
  .bus_adr  (avalon_address),
423
  .bus_wdt  (avalon_writedata),
424
  .bus_rdt  (avalon_readdata),
425
  .bus_irq  (avalon_interrupt),
426 2 iztok
  // onewire
427 3 iztok
  .owr_p    (owr_p),
428
  .owr_e    (owr_e),
429
  .owr_i    (owr_i)
430 2 iztok
);
431
 
432 3 iztok
// pullup
433 2 iztok
pullup onewire_pullup [OWN-1:0] (owr);
434
 
435 3 iztok
// tristate buffers
436
bufif1 onewire_buffer [OWN-1:0] (owr, owr_p, owr_e | owr_p);
437 2 iztok
 
438 3 iztok
// read back
439
assign owr_i = owr;
440
 
441 2 iztok
//////////////////////////////////////////////////////////////////////////////
442 3 iztok
// Verilog onewire slave models
443 2 iztok
//////////////////////////////////////////////////////////////////////////////
444
 
445 3 iztok
`ifdef OWN
446
 
447
// fast slave device
448
onewire_slave_model onewire_slave [OWN-1:0] (
449
  // configuration
450
  .ena    (slave_ena),
451
  .ovd    (slave_ovd),
452
  .dat_r  (slave_dat_r),
453
  .dat_w  (slave_dat_w),
454
  // 1-wire signal
455
  .owr    (owr)
456
);
457
 
458
`else
459
 
460
// Verilog onewire slave models for normal mode
461
 
462
// typical slave device
463 2 iztok
onewire_slave_model #(
464 3 iztok
  .TS     (30)
465
) onewire_slave_n_typ (
466
  // configuration
467
  .ena    (slave_ena & (slave_ovd==0)),
468
  .ovd    (slave_ovd     ),
469
  .dat_r  (slave_dat_r   ),
470
  .dat_w  (slave_dat_w[0]),
471
  // 1-wire signal
472
  .owr    (owr[0])
473 2 iztok
);
474
 
475 3 iztok
// fast slave device
476
onewire_slave_model #(
477
  .TS     (15 + 0.1)
478
) onewire_slave_n_min (
479
  // configuration
480
  .ena    (slave_ena & (slave_ovd==0)),
481
  .ovd    (slave_ovd     ),
482
  .dat_r  (slave_dat_r   ),
483
  .dat_w  (slave_dat_w[1]),
484
  // 1-wire signal
485
  .owr    (owr[1])
486
);
487
 
488
onewire_slave_model #(
489
  .TS     (60 - 0.1)
490
) onewire_slave_n_max (
491
  // configuration
492
  .ena    (slave_ena & (slave_ovd==0)),
493
  .ovd    (slave_ovd     ),
494
  .dat_r  (slave_dat_r   ),
495
  .dat_w  (slave_dat_w[2]),
496
  // 1-wire signal
497
  .owr    (owr[2])
498
);
499
 
500
// Verilog onewire slave models for overdrive mode
501
 
502
// typical slave device
503
onewire_slave_model #(
504
  .TS     (30)
505
) onewire_slave_o_typ (
506
  // configuration
507
  .ena    (slave_ena & (slave_ovd==1)),
508
  .ovd    (slave_ovd     ),
509
  .dat_r  (slave_dat_r   ),
510
  .dat_w  (slave_dat_w[0]),
511
  // 1-wire signal
512
  .owr    (owr[0])
513
);
514
 
515
// fast slave device
516
onewire_slave_model #(
517
  .TS     (16)
518
) onewire_slave_o_min (
519
  // configuration
520
  .ena    (slave_ena & (slave_ovd==1)),
521
  .ovd    (slave_ovd     ),
522
  .dat_r  (slave_dat_r   ),
523
  .dat_w  (slave_dat_w[1]),
524
  // 1-wire signal
525
  .owr    (owr[1])
526
);
527
 
528
onewire_slave_model #(
529
  .TS     (47)
530
) onewire_slave_o_max (
531
  // configuration
532
  .ena    (slave_ena & (slave_ovd==1)),
533
  .ovd    (slave_ovd     ),
534
  .dat_r  (slave_dat_r   ),
535
  .dat_w  (slave_dat_w[2]),
536
  // 1-wire signal
537
  .owr    (owr[2])
538
);
539
 
540
`endif
541
 
542 2 iztok
endmodule

powered by: WebSVN 2.1.0

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